Python 类方法链接 [英] Python class method chaining

查看:52
本文介绍了Python 类方法链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To avoid getting lost in architectural decisions, I'll ask this with an analogous example:

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

lets say I wanted a Python class pattern like this:

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

这里的问题是我如何设计一个类,以便可以以这种方式链接"某些方法.

The question here is how do I get a design a class such that certain methods can be "chained" in this fashion.

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

task() would require access to the queue class instance attributes and the operations of task depends on the output of region().

我看到 SQLalchemy 这样做(见下文),但我很难深入挖掘他们的代码并隔离这种模式.

I see SQLalchemy does this (see below) but am having difficulty digging through their code and isolating this pattern.

query = db.query(Task).filter(Task.objectid==10100) 

推荐答案

SQLAlchemy 对此类调用生成克隆,请参阅 Generative._generate() 方法,它只返回当前对象的克隆.

SQLAlchemy produces a clone on such calls, see Generative._generate() method which simply returns a clone of the current object.

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

On each generative method call (such as .filter(), .orderby(), etc.) a new clone is returned, with a specific aspect altered (such as the query tree expanded, etc.).

SQLAlchemy 使用 装饰器 标记必须操作的方法,并在此处返回一个克隆,将 self 替换为生成的克隆.

SQLAlchemy uses a @_generative decorator to mark methods that must operate and return a clone here, swapping out self for the produced clone.

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

Using this pattern in your own code is quite simple:

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() 的每次调用现在都会产生一个克隆,装饰方法通过改变状态来更新它.然后返回克隆,保持原始实例对象不变.

Each call to .region() or .task() will now produce a clone, which the decorated method updates by altering the state. The clone is then returned, leaving the original instance object unchanged.

这篇关于Python 类方法链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆