在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"'
答
有没有办法做到这一点,而无需创建某种形式的包装类的各位代表调用底层的“追踪”对象。
对象的每个操作最终都是通过使用它的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方法。
要点是,没有内置的方式来做到这一点,你需要自己做一些乏味的方式。
你能更好地定义什么和不算作“访问”? – wim
是的,我不认为你发布的例子使你的问题清晰。 –
看起来你只是想要一个函数包装器。 'def s():print'access';返回'一些字符串'。 – TigerhawkT3