def Private(*privates):
def onDecorator(aClass):
class onInstance:
def __init__(self, aClass,*args):
print("onInstance init")
self.aClass=aClass
print("onInstance init over")
def __call__(self, *args, **kargs):
print("call")
self.wrapped = self.aClass(*args, **kargs)
def __getattr__(self, attr):
if attr in privates:
raise TypeError('private attribute fetch: ' + attr)
else:
print("getarrt")
return getattr(self.wrapped, attr)
return onInstance
return onDecorator
if name == 'main':
@Private('data', 'size')
class Doubler:
def __init__(self, label, start):
print("Doubler init")
self.label = label
self.data = start
X = Doubler('X is', [1, 2, 3])
print("X.label1=",X.label)
上面的程序输出如下:
onInstance init
onInstance init over
getarrt
getarrt #后续跟着无数个 getarrt,出现死循环
但是如果把__call__方法删除,并对__init__方法修改成如下后,就不会出现 print("getarrt")语句的死循环了:
def Private(*privates):
def onDecorator(aClass):
class onInstance:
def __init__(self, *args,**kargs):
print("onInstance init")
self.wrapped=aClass(*args,**kargs)
print("onInstance init over")
def __getattr__(self, attr):
if attr in privates:
raise TypeError('private attribute fetch: ' + attr)
else:
print("getarrt")
return getattr(self.wrapped, attr)
return onInstance
return onDecorator
if name == 'main':
@Private('data', 'size')
class Doubler:
def __init__(self, label, start):
print("Doubler init")
self.label = label
self.data = start
X = Doubler('X is', [1, 2, 3])
print("X.label1=",X.label)
输出如下:
onInstance init
Doubler init
onInstance init over
getarrt
X.label1= X is
我的问题如下:
1、第一段代码会导致反复打印"getarrt"是 getattr(self.wrapped, attr) 这个语句中的 self.wrapped 导致的对吧, 但是 self.wrapped 在__call__方法中是有声明的,虽然__call__方法还未得到执行,这样也会被__getattr__视作未定义的属性而捕获么?
2、第二段代码做了修改后,为何 getattr(self.wrapped, attr)不会导致对__getattr_的递归调用了?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.