我正在解决 the python koans . 直到 34 号我才遇到任何真正的问题。
问题是:
Project: Create a Proxy Class
In this assignment, create a proxy class (one is started for you below). You should be able to initialize the proxy object with any object. Any attributes called on the proxy object should be forwarded to the target object. As each attribute call is sent, the proxy should record the name of the attribute sent.
The proxy class is started for you. You will need to add a method missing handler and any other supporting methods. The specification of the Proxy class is given in the AboutProxyObjectProject koan.
Note: This is a bit trickier that it's Ruby Koans counterpart, but you can do it!
这是我到目前为止的解决方案:
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
在这次测试之前一直有效:
def test_proxy_records_messages_sent_to_tv(self):
tv = Proxy(Television())
tv.power()
tv.channel = 10
self.assertEqual(['power', 'channel='], tv.messages())
其中 tv.messages() 是 ['power'] 因为 tv.channel=10 被代理对象获取而不是电视对象。
我试图操纵 __setattr__ 方法,但我总是以无限循环结束。
编辑1:
我正在尝试这个:
def __setattr__(self, name, value):
if hasattr(self, name):
object.__setattr__(self,name,value)
else:
object.__setattr__(self._obj, name, value)
但是我在最后一个条目的循环中得到了这个错误:
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:
循环在 __getattr__ 中。
请您参考如下方法:
您在 __setattr__ 中使用 hasattr 来决定您应该写入本地对象还是代理对象。这适用于除一种情况之外的所有情况。
在您的 __init__ 中,您有以下行:
self._count = {}
此调用 __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)
