Python类方法链接

2024-04-29 09:45:50 发布

您现在位置:Python中文网/ 问答频道 /正文

为了避免在架构决策中迷失方向,我将用一个类似的例子来问:

假设我想要这样的Python类模式:

queue = TaskQueue(broker_conn)
queue.region("DFW").task(fn, "some arg") 

这里的问题是如何让一个设计类能够以这种方式“链接”某些方法。在

task()需要访问queue类实例属性,task的操作依赖于region()的输出。在

我看到SQLalchemy做到了这一点(见下文),但在挖掘他们的代码和隔离这个模式方面有困难。在

^{pr2}$

Tags: taskqueue架构方式模式argsomebroker
2条回答

只需从region方法返回当前对象,如下所示

def region(self, my_string):
    ...
    ...
    return self

由于region返回具有task函数的当前对象,现在可以进行链接。在

注意:

作为@chepnermentioned in the comments section,请确保region对对象{}进行了更改。在

SQLAlchemy在这种调用上生成一个克隆,参见^{} method,它只返回当前对象的一个克隆。在

在每次生成方法调用(例如.filter().orderby()等)时,都会返回一个新的克隆,并更改特定的方面(例如展开的查询树等)。在

SQLAlchemy使用^{} decorator标记必须操作的方法并在此处返回一个克隆,用self替换生成的克隆。在

在自己的代码中使用此模式非常简单:

from functools import wraps

class GenerativeBase(object):
    def _generate(self):
        s = self.__class__.__new__(self.__class__)
        s.__dict__ = self.__dict__.copy()
        return s

def _generative(func):
    @wraps(func)
    def decorator(self, *args, **kw):
        new_self = self._generate()
        func(new_self, *args, **kw)
        return new_self
    return decorator


class TaskQueue(GenerativeBase):
    @_generative
    def region(self, reg_id):
        self.reg_id = reg_id

    @_generative
    def task(self, callable, *args, **kw):
        self.tasks.append((callable, args, kw))

.region().task()的每次调用都将生成一个克隆,修饰方法通过改变状态来更新克隆。然后返回克隆,保留原始实例对象不变。在

相关问题 更多 >