Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Récupérer la dernière valeur d'une coroutine

+4 votes

J'essaie d'écrire une coroutine qui correspondrait à ce générateur

def tokenize(gene):
stock = ""
for i in gene:
    if i in OPERATORS.keys():
        if stock:
            yield stock
        yield i
        stock = ""
    elif i == " ":
        pass
    else:
        stock += str(i)
if stock:
    yield stock

Ce qui me permet de faire

>>> e = "12.3+3+13"
>>> tokenize_e = list(tokenize(e))
>>> tokenize_e
['12.3', '+', '3', '+', '13']

Voici où j'en suis

@coroutine
def tokenize(target):
    target_ = target()
    stock = None
    new = (yield target_.send(stock))
    while True:
        if new in OPERATORS.keys():
            to_send = stock
            stock = new
        elif stock is None:
            stock = str(new)
            to_send = None
        else:
            if stock in OPERATORS.keys():
                to_send = stock
                stock = ""
            else:
                to_send = None
            stock += str(new)
        new = (yield target_.send(to_send))

Qui marche presque

@coroutine
def list_sink():
    ans = list()
    while True:
        c = (yield ans)
        if c is not None:
            ans.append(c)

to_token = tokenize(list_sink)
for i in '12+3+234':
    a = to_token.send(i)

>>> a
['12', '+', '3', '+']

Mais je ne vois pas comment récupérer le dernier nombre (234).
Il faudrait que je ferme la coroutine mais je n'arrive pas à récupérer une valeur avec close()

demandé 18-Dec-2016 par sPaz (306 points)

1 Réponse

+3 votes
 
Meilleure réponse

Ça devrait le faire en modifiant un chouilla tokenize() :

@coroutine
def tokenize(target):
    target_ = target()
    stock = None
    new = yield target_.send(stock)
    while True:
        if new in OPERATORS.keys():
            to_send = stock
            stock = new
        elif stock is None:
            stock = str(new)
            to_send = None
        else:
            if stock in OPERATORS.keys():
                to_send = stock
                stock = ''
            else:
                if new is None:
                    to_send = stock
                else:
                    to_send = None
            stock += str(new)
        new = yield target_.send(to_send)

Et il faut envoyer None pour clôturer le tout :

to_token = tokenize(list_sink)
next(to_token)

for i in '12+3+234':
    a = to_token.send(i)
next(to_token)

>>> a
['12', '+', '3', '+', '234']
répondu 20-Dec-2016 par Tiger-222 (492 points)
sélectionné 2-Mar par sPaz

Ok top merci.
J'ai quand même une dernière question pour la culture.
Dans l'article sur les coroutines de S&M, ils racontent que les coroutines sont des choses que l'on peut fermer. Est-ce qu'il ne serait pas possible plutôt que d'envoyer un None à la fin, avoir un résultat similaire avec un .close()?

J'ai modifié en utilisant des next() mais je sèche un peu. Peut-être que quelqu'un d'autre aura une meilleure alternative.

...