Skip to main content
 首页 » 编程设计

python 公案 : class proxy

2025年05月04日9虾米哥

我正在解决 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)