python koans:类代理

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__方法,但我总是以无限循环结束.

编辑1:

我正在尝试这个:

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__.

Fre*_*oth 5

您正在使用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)