在Python中是否有一种机制可以拦截对象的访问?

问题描述:

我想控制被访问的变量。我试图在pyjack模块的帮助下实现它,但方法pyjack.connect(my_str,proxyfn = my_proxyfn)抛出异常...type '<type 'str'>' not supported在Python中是否有一种机制可以拦截对象的访问?

这里是我想要的一个例子:

>>> def on_access(obj): 
... print 'object with id=%d has been requested' % id(obj) 
... 
>>> s = 'some string' 
>>> 
>>> foo(s, handler=on_access) 
>>> 
>>> print s 
object with id=4559856664 has been requested 
some string 
>>> 
>>> s + '.' 
object with id=4559856664 has been requested 
some string. 

UPD:这是很重要的对象保留其类型。

在实例的后续:

>>> import json 
>>> 
>>> json.dumps(s) 
object with id=4559856664 has been requested 
'"some string"' 
+1

你能更好地定义什么和不算作“访问”? – wim

+0

是的,我不认为你发布的例子使你的问题清晰。 –

+0

看起来你只是想要一个函数包装器。 'def s():print'access';返回'一些字符串'。 – TigerhawkT3

有没有办法做到这一点,而无需创建某种形式的包装类的各位代表调用底层的“追踪”对象。

对象的每个操作最终都是通过使用它的dunders来控制的。例如,print,呼叫__str__,s + '.'第一呼叫__add__,下标呼叫__getitem__。您需要在这些函数中定义您的“访问”行为

快速基本写了呈现在你的例子的功能看起来是这样的:

class Wrap(object): 

    access_str = "object with id={} has been accessed" 

    def __init__(self, obj): 
     self._obj = obj 

    def __add__(self, v): 
     print(self.access_str.format(self._obj)) 
     # If you want the result to be tracked 
     # return Wrap(self._obj + v) 
     return self._obj + v 


    def __repr__(self): 
     print(self.access_str.format(self._obj)) 
     return repr(self._obj) 

    def __str__(self): 
     print(self.access_str.format(self._obj)) 
     return str(self._obj) 

这显然是缺乏所需的方法,其余但是这东西,如果你去,你应该做的沿着这条路线。

现在你与它进行交互,你会与任何字符串:

>>> s = Wrap("Hello World") 
>>> print(s) 
object with id=140023929394880 has been accessed 
Hello World 
>>> s + '.' 
object with id=140023929394880 has been accessed 
'Hello World.' 

这可以明显地改变,例如在__init__你可以强制要求为name参数,该参数你然后在绑定全球范围通过使用globals()

此外,您可以创建一个元类,根据类型为您自动生成类似的dunder方法。

要点是,没有内置的方式来做到这一点,你需要自己做一些乏味的方式。