Python 中是否有允许拦截对对象的访问的机制?
Is there a mechanism in Python, which would allow to intercept access to an object?
我想控制变量被访问。我试图在 pyjack 模块的帮助下实现它,但是方法 pyjack.connect(my_str, proxyfn=my_proxyfn) 抛出异常 ...type '<type 'str'>' not supported
.
这是我想要的示例:
>>> 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.
更新:对象保留其类型很重要。
继续示例:
>>> import json
>>>
>>> json.dumps(s)
object with id=4559856664 has been requested
'"some string"'
如果不创建某种包装器 class 来委托对底层 "tracked" 对象的调用,就无法做到这一点。
对一个对象的每一个操作最终都是通过使用它的命令来控制的。 print
,例如调用__str__
,s + '.'
先调用__add__
,下标调用__getitem__
。您需要在这些函数中定义 "on access" 行为 。
介绍您示例中的功能的快速基本说明可能如下所示:
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()
在全局范围内绑定该参数.
此外,您可以创建一个元class,它会根据类型自动为您生成类似的 dunder 方法。
要点是,没有内置方法可以做到这一点,您需要自己以一些乏味的方式来完成。
我想控制变量被访问。我试图在 pyjack 模块的帮助下实现它,但是方法 pyjack.connect(my_str, proxyfn=my_proxyfn) 抛出异常 ...type '<type 'str'>' not supported
.
这是我想要的示例:
>>> 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.
更新:对象保留其类型很重要。
继续示例:
>>> import json
>>>
>>> json.dumps(s)
object with id=4559856664 has been requested
'"some string"'
如果不创建某种包装器 class 来委托对底层 "tracked" 对象的调用,就无法做到这一点。
对一个对象的每一个操作最终都是通过使用它的命令来控制的。 print
,例如调用__str__
,s + '.'
先调用__add__
,下标调用__getitem__
。您需要在这些函数中定义 "on access" 行为 。
介绍您示例中的功能的快速基本说明可能如下所示:
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()
在全局范围内绑定该参数.
此外,您可以创建一个元class,它会根据类型自动为您生成类似的 dunder 方法。
要点是,没有内置方法可以做到这一点,您需要自己以一些乏味的方式来完成。