我现在在几个不同的主要第三方库和框架中都遇到了这个问题。让我尝试将其归结为要点:
因此,我想绑定x
作为一个论点modify
, per Python 参数绑定器。问题是,它还不存在,因为我仍在调用构造函数:
>>> from functools import partial
>>> x = Example(callback=partial(modify, x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
当然,我可以避免NameError
通过允许lambda
稍后查找名称:
>>> x = Example(callback=lambda: modify(x))
但是这个是后期绑定,所以它不能正常工作,如果例如我陷入了循环并且instance是迭代变量, or if instance
稍后因任何其他原因重新分配。
我怎样才能完成早期绑定instance
到它自己的回调?
一般来说,您可以尝试以下任何一种方法:
- 仔细检查 API 是否允许您稍后设置回调(两阶段构造):
from functools import partial
instance = Example()
# Read the documentation and see if Example provides something like:
instance.callback = partial(modify, instance)
# or possibly they didn't think of using a decorator for their validation logic:
instance.set_callback(partial(modify, instance))
- 对该示例进行子类化,以便它从自己的方法调用回调,并调整构造参数以将该方法用作包装器:
from functools import partial
class ContextProvidingExample(Example):
def __init__(self, *args, **kwargs):
try:
my_callback = kwargs['callback']
kwargs['callback'] = partial(my_callback, self)
except KeyError:
pass
super().__init__(*args, **kwargs)
这个想法归功于@tdelaneyhere.
- 如果不需要灵活性,
modify
逻辑可以直接集成到子类中:class SelfModifyingExample(Example):
def __init__(self, *args, **kwargs):
if 'callback' in kwargs.keys():
raise ValueError('cannot override callback')
kwargs['callback'] = self._modify
super().__init__(*args, **kwargs)
def _modify(self):
self.enabled = True
self.visible = True
try:
self.paint('black')
except AProblemComesAlong:
self.whip()
- 作为最后的手段,在字典中注册实例,并安排回调按名称查找它们:
from functools import partial
hey_you = {} # say my name...
def modify_by_name(name):
modify(hey_you[name]) # call modify() maybe?
# Let's use a simple wrapper to make sure instances get registered.
def stand_up(name):
result = Example(callback=partial(modify_by_name, name))
hey_you[name] = result
return result
who = what = stand_up('slim shady')
这种方式有点笨拙,但您可能会发现实例的字符串名称在代码的其他地方很有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)