簡體   English   中英

Python類方法鏈接

[英]Python class method chaining

為了避免迷失在架構決策中,我會用一個類似的例子來問這個問題:

假設我想要一個像這樣的Python類模式:

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

這里的問題是如何讓設計成為一個類,以便某些方法可以以這種方式“鏈接”。

task()需要訪問queue類實例屬性, task的操作取決於region()的輸出。

我看到SQLalchemy做了這個(見下文),但我很難深入挖掘他們的代碼並隔離這種模式。

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

SQLAlchemy在這些調用上生成一個克隆,請參閱Generative._generate()方法 ,該方法只返回當前對象的克隆。

在每個生成方法調用(例如.filter() .orderby()等)上,返回一個新的克隆,並更改特定的方面(例如擴展的查詢樹等)。

SQLAlchemy使用@_generative裝飾器標記必須操作的方法並在此返回克隆,為生成的克隆交換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))

每次調用.task() .region().task()現在都會產生一個克隆,通過改變狀態來更新裝飾方法。 然后返回克隆,保持原始實例對象不變。

只需從region方法返回當前對象,就像這樣

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

由於region返回具有task功能的當前對象,因此現在可以進行鏈接。

注意:

正如@chepner 在評論部分中提到的那樣 ,確保該region對對象self進行更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM