元類在這裏沒有幫助;儘管在當前對象的類型上查找了特殊的方法(所以類爲實例),但這樣做時可能不會查詢__getattribute__
或__getattr__
(可能是因爲它們本身就是特殊方法)。所以要趕上全部 dunder方法,你不得不創建它們全部。
您可以通過枚舉operator
module得到所有操作特殊的方法相當不錯的列表(__pow__
,__gt__
等):
import operator
operator_hooks = [name for name in dir(operator) if name.startswith('__') and name.endswith('__')]
武裝與列表中的類裝飾可能是:
def instrument_operator_hooks(cls):
def add_hook(name):
operator_func = getattr(operator, name.strip('_'), None)
existing = getattr(cls, name, None)
def op_hook(self, *args, **kw):
print "Hooking into {}".format(name)
self._function = operator_func
self._params = (args, kw)
if existing is not None:
return existing(self, *args, **kw)
raise AttributeError(name)
try:
setattr(cls, name, op_hook)
except (AttributeError, TypeError):
pass # skip __name__ and __doc__ and the like
for hook_name in operator_hooks:
add_hook(hook_name)
return cls
然後應用,爲您的類:
@instrument_operator_hooks
class CatchAll(object):
pass
演示:
>>> c = CatchAll()
>>> c ** 2
Hooking into __pow__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in op_hook
AttributeError: __pow__
>>> c._function
<built-in function pow>
>>> c._params
((2,), {})
所以,儘管我們班沒有定義__pow__
明確,我們還是迷上了進去。
那些不委託給dunder方法的函數呢? – delnan 2013-05-04 08:28:02
你可能想看看類裝飾器和元類。 – 2013-05-04 08:37:09
@delnan我想,這些也是可以的,因爲在我的情況下,這些函數正在尋找別的東西,一個值或一個方法來調用。 – 2013-05-04 08:37:49