0
继答案从this previous question约默认memoizing所有的类的方法,我使用这个元类:应用一个装饰的属性的getter
from inspect import isfunction
class Immutable(type):
def __new__(cls, name, bases, dct):
for key, val in dct.items():
# Look only at methods/functions; ignore those with
# "special" names (starting with an underscore)
if isfunction(val) and val.__name__[0] != '_':
dct[key] = memoized(val)
elif hasattr(val, 'fget'):
# It's a property; we currently can't memoize these
pass
return type.__new__(cls, name, bases, dct)
此元类具有应用装饰memoized
到的效果班级中的所有功能和方法。唯一的问题是它不适用于属性。 (使用此元类的类都被视为不可变的,所以我只担心只读属性在这里。)如果我尝试做一些像
from time import sleep
class Foo(object):
__metaclass__ = Immutable
@property
def slow_calculation(self):
sleep(5) # simulate an intensive calculation
return 4
然后slow_calculation
不memoized,有一个五秒钟的延迟每次它被叫,不只是第一次。
问题是property()
返回一个property
对象,而不是一个函数,因此元类__new__
中的isfunction
测试不会捕获属性。正如你所看到的,我添加了一个可以找到属性的测试,但是我不知道如何将memoized
装饰器应用到属性获取器fget
。我想也许我可以说
elif hasattr(val, 'fget'):
val.fget = memoized(val.fget)
dct[key] = val
但在这种情况下,我得到
Traceback (most recent call last):
[...]
File "utils.py", line 54, in __new__
val.fget = memoized(val.fget)
TypeError: Error when calling the metaclass bases
readonly attribute
是否有一个装饰应用到属性的getter一些其他的方式?
这样做。谢谢! – bdesham