我发现通过从str
派生并覆盖__new__
,您可以覆盖字符串。你知道任何可以创建一个懒惰的初始化字符串的魔法吗?
因此
def f(a, b):
print("f called")
return a+b
s=f("a", "b")
print("Starting")
print(s)
如何在函数f
中添加一个装饰器,以便在打印“Starting”后(仅在第一次访问时)仅执行此功能?看起来很棘手...... :)
我可以在返回对象时执行此操作,因为我会拦截属性访问。但是,字符串不使用属性访问?
答案 0 :(得分:3)
您要查找的属性为__str__()
,__repr__()
和__unicode__()
。
答案 1 :(得分:3)
可能有更简单的方法来做你想做的事 - 但是,我曾经写过一个通用的"懒惰的装饰者"对于完全符合您要求的通用函数 - 感知它更复杂,因为它几乎适用于函数返回的任何类型的对象。
基本思想是:对于给定的现有对象,Python实际上并没有使用"它的价值,但是对于那些“dunder' (魔术双" __")对象类中的方法 -
是为了表示它(调用__repr__ __str__ __unicode__
)从中获取属性,进行调用,将它作为算术运算中的运算符等等。
所以,这个装饰器在调用函数时,基本上存储参数并等待调用这些魔术方法中的任何一个,然后它确实调用originall调用并缓存返回值 -
soruce代码在这里:
https://bitbucket.org/jsbueno/metapython/src/f48d6bd388fd/lazy_decorator.py
答案 2 :(得分:1)
尝试使用stringlike中的LazyString
类,就像这样
from stringlike.lazy import LazyString
def f(a, b):
print("f called")
return a+b
s = LazyString(lambda: f("a", "b"))
print("Starting")
print(s)