Bienvenue sur IndexError.

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

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 (1,192 points)
sélectionné 2-Mar-2017 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.

...