我正在构建一个利用属性链的Python类。我试图弄清楚是否有一种方法可以确定何时调用链的最终属性并在该点执行某些处理代码。在调用最终的链接属性之后,我想处理收集的数据。我意识到可以在链的末尾显式调用处理属性,但是如果可能的话我想避免这种情况。
例如:
o = ObjectInstance()
# Note that the attribute calling order is subjective
o('data').method_a('other data').method_c('other_data') #o.process() is called here automatically
- 更新 -
我找到了一种特定于我的情况的解决方法,但它没有回答基本问题。
对于我的特定情况,我打算用单个实例分别处理多个链。通过覆盖我的类的__call__
属性,我可以检查前一个链是否已被处理,并做出相应的反应。我已经计划在处理完所有链之后,有一个单独的渲染方法---它也可以处理前一个链,因此它适用于我的特定场景。
该课程类似于:
class Chainable:
current_chain_data = None
processed_chains = list()
def __call__(self, data):
if self.current_chain_data:
self.process()
#Some logic
self.current_chain_data = data
return self
def method_a(self, data):
#Some logic
self.current_chain_data = data
return self
def method_b(self, data):
#...
def process(self, data):
#do stuff
self.processed_chains.append(self.current_chain_data)
self.current_chain_data = None
def render(self):
if self.current_chain_data:
self.process()
for c in self.processed_chains:
output += c
return output
可以像:
一样使用c = Chainable()
# do some chaining
c('data').method_a('other_data').method_c('other_data')
# previous chain is processed here, new chain started
c('additional_data').method_b('other_data') #...
# previous chain is processed here, output rendered
c.render()
答案 0 :(得分:1)
无法识别“最后”调用,因为“链”不是语言构造,而是统一语法的结果与您自己(好)从非返回相同对象的实践相结合功能方法。
您的选择是:
我建议选项1,除非选项2自然不产生性能损失,如果没有其他原因导致复杂性最小,而显式通常优于隐式。
您的覆盖__call__
的解决方案有几个缺点:它可能会让您的用户感到困惑,因为它不均匀;如果在调用c
之前有人在c
上调用了另一种方法,则行为可能会让他们感到惊讶(链接继续);最后,你仍然需要一个最后的render
调用来关闭最后一个链,这将使这些代码比必要的更脆弱。
答案 1 :(得分:0)
class DataObject:
def __init__(self, data):
self.data = data
def method_a(self, data):
self.data += data
return self
def method_c(self, data):
self.data += data
return self
def process(self):
print self.data
if __name__ == "__main__":
o = DataObject('data')
o.method_a('other data').method_c('other_data').process()