kur*_*shi 1 python proxy-classes setattr
我正在解决蟒蛇的问题.直到第34天我才有任何实际问题.
这就是问题:
项目:创建代理类
在此分配中,创建一个代理类(下面将为您启动一个代理类).您应该能够使用任何对象初始化代理对象.应将代理对象上调用的任何属性转发到目标对象.在发送每个属性调用时,代理应记录发送的属性的名称.
代理类是为您启动的.您将需要添加方法缺少处理程序和任何其他支持方法.Proxy类的规范在AboutProxyObjectProject koan中给出.
注意:这有点棘手,它是Ruby Koans的对应物,但你可以做到!
这是我的解决方案,直到现在:
class Proxy(object):
def __init__(self, target_object):
self._count = {}
#initialize '_obj' attribute last. Trust me on this!
self._obj = target_object
def __setattr__(self, name, value):pass
def __getattr__(self, attr):
if attr in self._count:
self._count[attr]+=1
else:
self._count[attr]=1
return getattr(self._obj, attr)
def messages(self):
return self._count.keys()
def was_called(self, attr):
if attr in self._count:
return True
else: False
def number_of_times_called(self, attr):
if attr in self._count:
return self._count[attr]
else: return False
Run Code Online (Sandbox Code Playgroud)
它适用于此测试:
def test_proxy_records_messages_sent_to_tv(self):
tv = Proxy(Television())
tv.power()
tv.channel = 10
self.assertEqual(['power', 'channel='], tv.messages())
Run Code Online (Sandbox Code Playgroud)
这里tv.messages()是['power']因为tv.channel=10采取的是代理对象,而不是电视对象.
我试图操纵这个__setattr__方法,但我总是以无限循环结束.
我正在尝试这个:
def __setattr__(self, name, value):
if hasattr(self, name):
object.__setattr__(self,name,value)
else:
object.__setattr__(self._obj, name, value)
Run Code Online (Sandbox Code Playgroud)
但是后来我在最后一个条目的循环中得到了这个错误:
RuntimeError: maximum recursion depth exceeded while calling a Python object
File "/home/kurojishi/programmi/python_koans/python 2/koans/about_proxy_object_project.py", line 60, in test_proxy_method_returns_wrapped_object
tv = Proxy(Television())
File "/home/kurojishi/programmi/python_koans/python 2/koans/about_proxy_object_project.py", line 25, in __init__
self._count = {}
File "/home/kurojishi/programmi/python_koans/python 2/koans/about_proxy_object_project.py", line 33, in __setattr__
object.__setattr__(self._obj, name, value)
File "/home/kurojishi/programmi/python_koans/python 2/koans/about_proxy_object_project.py", line 36, in __getattr__
if attr in self._count:
Run Code Online (Sandbox Code Playgroud)
循环在__getattr__.
您正在使用hasattrin __setattr__来决定是否应该写入本地或代理对象.这适用于除一个案例以外的所有案例.
在你的__init__,你有下面这行:
self._count = {}
Run Code Online (Sandbox Code Playgroud)
这就要求__setattr__用'_count'不在该点存在,因此(因此hasattr返回False)被转发到代理对象.
如果你想使用你的方法,你必须写__init__这样的:
def __init__(self, target_object):
object.__setattr__(self, '_count', {})
#initialize '_obj' attribute last. Trust me on this!
object.__setattr__(self, '_obj', target_object)
Run Code Online (Sandbox Code Playgroud)