gpt4 book ai didi

扩展构建器模式的 Pythonic 方式

转载 作者:行者123 更新时间:2023-12-04 14:47:40 27 4
gpt4 key购买 nike

考虑以下 CDK Python 中的示例(对于这个问题,不需要 AWS 知识,这应该对基本上任何构建器模式都有效,我只是在这个示例中使用 CDK,因为我使用这个库遇到了这个问题。):

from aws_cdk import aws_stepfunctions as step_fn
from aws_cdk import core

app = core.App()
state_machine = step_fn.Chain.start(
step_fn.Pass(app, 'start')
).next(
step_fn.Pass(app, 'foo1')
).next(
step_fn.Pass(app, 'foo2')
).next(
step_fn.Pass(app, 'bar')
)
现在,如果我需要重用构造
.next(
step_fn.Pass(app, 'foo1')
).next(
step_fn.Pass(app, 'foo2')
)
多次,我可以想出这些方法。
  • 将代码包装在方法中
  • def foo(chain: step_fn.Chain) -> step_fn.Chain:
    return chain.next(
    step_fn.Pass(app, 'foo1')
    ).next(
    step_fn.Pass(app, 'foo2')
    )


    # This works but it destroys the readability of the chain as the calling order is inverted.
    state_machine = foo(
    step_fn.Chain.start(
    step_fn.Pass(app, 'start')
    )
    ).next(
    step_fn.Pass(app, 'bar')
    )

    # This is against the builder design to wrap mutability in the builder classes.
    state_machine = step_fn.Chain.start(
    step_fn.Pass(app, 'start')
    )
    state_machine = foo(state_machine)
    state_machine = state_machine.next(
    step_fn.Pass(app, 'bar')
    )
  • 猴子补丁

  • 虽然语法看起来不错,但当应用于多人使用存储库的真实项目时,这似乎容易出错并且是可维护性的噩梦:
    step_fn.Chain.foo = foo
    state_machine = step_fn.Chain.start(
    step_fn.Pass(app, 'start')
    ).foo().next(
    step_fn.Pass(app, 'bar')
    )
    我试图查看是否有任何方法可以为 Python 对象实现类型类,但找不到任何东西。我找到了 dry-python但不确定它是否可以用于类方法。在 Scala 中, implicit classes可用于拥有流畅的构建器语法,而无需更改任何全局状态。是否有任何 Pythonic 方法可以实现相同的目标?
    编辑:后来发现 CDK 链支持添加解决此特定问题的其他链。一般来说,如果能影响到builder的设计,大概最好加个方法 extend等等,允许向构建器添加另一个构建器,这使得在这种场景中很容易重用。

    最佳答案

    您可以将整个内容包装在一个类中:

    class ChainHelper:
    def __init__(self, app: core.App, chain: step_fn.Chain):
    self._app = app
    self._chain = chain
    这允许您为操作提供描述性名称并允许更多重用:
    class ChainHelper:
    def __init__(self, app: core.App, chain: step_fn.Chain):
    self._app = app
    self._chain = chain

    def pass_arg(self, arg: str):
    self._chain = self._chain.next(step_fn.Pass(self._app, arg))
    return self

    def pass_foo(self):
    self._chain = self._chain \
    .next(step_fn.Pass(self._app, 'foo1')) \
    .next(step_fn.Pass(self._app, 'foo2'))
    return self
    用法:
    state_machine = ChainHelper(app=core.App(), chain=step_fn.Chain) \
    .pass_arg('start') \
    .pass_foo() \
    .pass_arg('bar')

    关于扩展构建器模式的 Pythonic 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69725214/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com