是否有从协程端点返回值的标准方法

科林

我的问题:

我想知道Python中是否存在从协程终结点(也称为“接收器”或“消费者”)返回值的“最佳实践”模式。一般来说,您将如何处理以下情况?

我的情况:

我有(producer) > (filter) > (consumer)协程管道来处理基于文本的表并从中构建字典列表。我希望将内置的对象consumer返回给的原始调用方producer

我的方法:

我的方法是设置每个协程检查的独特的后处理信号。如果它听到信号,则将信号传递给它的子信号并产生返回值。consumer刚刚产生的电流值。

替代方法:

我考虑过:

  • 使用全局来保存要“返回”给调用者的所需对象。
  • 具有常规子例程的基于类的方法。

我为什么应该为我的情况重新考虑这些原因也将受到欢迎。

我的实现:

这是我所做工作的简化版本,包括所有关键组件。

import uuid

FINISH_PROCESSING_SIGNAL = uuid.uuid4()

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr
    return start


# Sink
@coroutine
def list_builder():
    # accepts objects and adds them to a list
    _list = []
    try:
        while True:
            data = (yield)
            if data is FINISH_PROCESSING_SIGNAL:
                yield _list
                break
            _list.append(data)
    except GeneratorExit:
        pass

# Filter
@coroutine
def user_data_filter(target=None):

    if target is None:
        target = list_builder()

    header = "-+-"
    footer = "Transfer Packets"
    username = "User Name"
    fullname = "Full Name"
    note = "Description"

    try:
        while True:
            user = {}
            data = (yield)
            if data is FINISH_PROCESSING_SIGNAL:
                yield target.send(FINISH_PROCESSING_SIGNAL)
                break
            line = data
            if header in line:
                while True:
                    line = (yield)
                    if footer in line:
                        target.send(user)
                        break
                    elif username in line:
                        user["username"] = line.split('|')[1]
                    elif fullname in line:
                        user["fullname"] = line.split('|')[1]
                    elif note in line:
                        user["note"] = line.split('|')[1]

    except GeneratorExit:
        target.close()

# Producer
def process_users_table(table, target=None):

    if target is None:
        target = user_data_filter()

    lines = table.split('\r\n')
    for line in lines:
        target.send(line)
    processed_data = target.send(FINISH_PROCESSING_SIGNAL)
    return processed_data



if __name__ == '__main__':

    test_users_table = \
    """
    Item            |Value\r\n
    ----------------+-----------------------\r\n
    User Name       |alice\r\n
    Full Name       |Alice Doe\r\n
    Description     |\r\n
    Transfer Packets|0\r\n
    ----------------+-----------------------\r\n
    User Name       |bob\r\n
    Full Name       |Bob Tables\r\n
    Description     |\r\n
    Transfer Packets|0\r\n
    """

    users = process_users_table(test_users_table)
    print users
算了吧

用信号通知使用者终止的方法很好,并且与使用多处理或线程化队列时的操作保持一致。但是,生成器还可以抛出异常(而不是发送值),并且的目的throw正是向生成器发出事件或状态更改的信号。此外,当将异常抛出给生成器时

[i] f生成器捕获异常并产生另一个值,即g.throw()的返回值。

这似乎非常适合您的用例。除了发送FINISH_PROCESSING_SIGNAL值外,还可以引发FINISH_PROCESSING_SIGNALException并使用它try..except来产生最终值。

class FINISH_PROCESSING_SIGNAL(Exception): pass

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr
    return start


# Sink
@coroutine
def list_builder():
    # accepts objects and adds them to a list
    _list = []
    try:
        while True:
            data = (yield)
            _list.append(data)
    except FINISH_PROCESSING_SIGNAL:
        yield _list

# Filter
@coroutine
def user_data_filter(target=list_builder()):
    header = "-+-"
    footer = "Transfer Packets"
    username = "User Name"
    fullname = "Full Name"
    note = "Description"
    try:
        while True:
            user = {}
            data = (yield)
            line = data
            if header in line:
                while True:
                    line = (yield)
                    if footer in line:
                        target.send(user)
                        break
                    elif username in line:
                        user["username"] = line.split('|')[1]
                    elif fullname in line:
                        user["fullname"] = line.split('|')[1]
                    elif note in line:
                        user["note"] = line.split('|')[1]
    except FINISH_PROCESSING_SIGNAL as err:
        # Pass along the Exception to the target, and yield its result back
        # to the caller
        yield target.throw(err)

# Producer
def process_users_table(table, target=user_data_filter()):
    lines = table.split('\r\n')
    for line in lines:
        target.send(line)
    processed_data = target.throw(FINISH_PROCESSING_SIGNAL)
    # processed_data = target.close()
    return processed_data



if __name__ == '__main__':

    test_users_table = \
    """
    Item            |Value\r\n
    ----------------+-----------------------\r\n
    User Name       |alice\r\n
    Full Name       |Alice Doe\r\n
    Description     |\r\n
    Transfer Packets|0\r\n
    ----------------+-----------------------\r\n
    User Name       |bob\r\n
    Full Name       |Bob Tables\r\n
    Description     |\r\n
    Transfer Packets|0\r\n
    """

    users = process_users_table(test_users_table)
    print users

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

是否有从协程端点返回值的标准方法

来自分类Dev

如何从协程范围返回值

来自分类Dev

如何等待并正确从异步协程返回值

来自分类Dev

要求提供示例代码以了解协程中throw()的返回值,该协程返回值

来自分类Dev

Unity-仅在协程完成后才需要返回值

来自分类Dev

如何由于超时而从已取消的python asyncio协程返回值

来自分类Dev

如何从异步协程作用域(例如ViewModelScope)返回值到UI?

来自分类Dev

关于asyncio模块,如何获取子协程的返回值?

来自分类Dev

协程恢复后,`co_yield`可以从调用者返回值吗?

来自分类Dev

C ++标准是否保证函数返回值具有恒定地址?

来自分类Dev

C ++标准是否保证函数返回值具有恒定地址?

来自分类Dev

Kotlin协程列表返回空值

来自分类Dev

静态方法缓存是否返回值?

来自分类Dev

限制返回值数量的SQL标准方法是什么?

来自分类Dev

Python:表示返回值和参数类型的标准方法

来自分类Dev

如何返回依赖于方法中启动的协程结果的值?(C#)

来自分类Dev

是否有可能直接分配给一个变量的方法的返回值?

来自分类Dev

对于用作表达式的 Kotlin 函数,是否有操作和返回值的简洁方法?

来自分类Dev

使用协程使函数返回在回调中获得的值

来自分类Dev

从方法返回值

来自分类Dev

从方法返回值

来自分类Dev

协程扩展方法

来自分类Dev

是否有C ++函数的默认返回值?

来自分类Dev

如何检查所有代码路径是否返回值

来自分类Dev

malloc()是否具有最大返回值?

来自分类Dev

JsRuntime.InvokeAsync是否有返回值大小限制?

来自分类Dev

Unix / Linux命令是否有返回值?

来自分类Dev

如何检查所有代码路径是否返回值

来自分类Dev

回调返回值是否有意义?

Related 相关文章

  1. 1

    是否有从协程端点返回值的标准方法

  2. 2

    如何从协程范围返回值

  3. 3

    如何等待并正确从异步协程返回值

  4. 4

    要求提供示例代码以了解协程中throw()的返回值,该协程返回值

  5. 5

    Unity-仅在协程完成后才需要返回值

  6. 6

    如何由于超时而从已取消的python asyncio协程返回值

  7. 7

    如何从异步协程作用域(例如ViewModelScope)返回值到UI?

  8. 8

    关于asyncio模块,如何获取子协程的返回值?

  9. 9

    协程恢复后,`co_yield`可以从调用者返回值吗?

  10. 10

    C ++标准是否保证函数返回值具有恒定地址?

  11. 11

    C ++标准是否保证函数返回值具有恒定地址?

  12. 12

    Kotlin协程列表返回空值

  13. 13

    静态方法缓存是否返回值?

  14. 14

    限制返回值数量的SQL标准方法是什么?

  15. 15

    Python:表示返回值和参数类型的标准方法

  16. 16

    如何返回依赖于方法中启动的协程结果的值?(C#)

  17. 17

    是否有可能直接分配给一个变量的方法的返回值?

  18. 18

    对于用作表达式的 Kotlin 函数,是否有操作和返回值的简洁方法?

  19. 19

    使用协程使函数返回在回调中获得的值

  20. 20

    从方法返回值

  21. 21

    从方法返回值

  22. 22

    协程扩展方法

  23. 23

    是否有C ++函数的默认返回值?

  24. 24

    如何检查所有代码路径是否返回值

  25. 25

    malloc()是否具有最大返回值?

  26. 26

    JsRuntime.InvokeAsync是否有返回值大小限制?

  27. 27

    Unix / Linux命令是否有返回值?

  28. 28

    如何检查所有代码路径是否返回值

  29. 29

    回调返回值是否有意义?

热门标签

归档