【发布时间】:2012-03-17 17:14:12
【问题描述】:
我正在构建一个使用属性链的 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()
【问题讨论】:
-
“如果可能的话,我想避免这种情况。”请不要。显式优于隐式。
-
我知道您来自哪里,对于我在上面发布的简单示例,我完全同意。然而,就我的使用而言,关键目标是保持(尽可能准确)非 Python 脚本语言的熟悉语法。
-
我建议您的解决方案可能会使您的用户感到困惑,因为它是不统一的。如果有人在调用
c之前调用c上的另一个方法会发生什么?您的用户会期待这种行为吗? -
另外,您现在需要将 render 作为最后一个方法调用,否则您的最后一个链永远不会被处理。