[英]Intercepting __getattr__ in a Python 2.3 old-style mixin class?
I have a large Python 2.3 based installation with 200k LOC. 我有一个基于Python 2.3的大型安装,具有200k LOC。 As part of a migration project I need to intercept all attribute lookups of all old-style class. 作为迁移项目的一部分,我需要拦截所有旧类的所有属性查找。
Old legacy code: 旧的旧版代码:
class Foo(Bar):
...
My idea is to inject a common mixin class like 我的想法是注入像
class Foo(Bar, Mixin):
...
class Mixin:
def __getattr__(self, k)
print repr(self), k
return Foo.__getattr__(self, k)
However I am running always into a recursion because Foo.__getattr__
resolves to Mixin.__getattr__
. 但是,由于Foo.__getattr__
解析为Mixin.__getattr__
所以我总是遇到递归Mixin.__getattr__
。
Is there any way to fix the code for Python 2.3 old-style classes? 有什么方法可以修复Python 2.3旧式类的代码吗?
If you are already injecting mixins, why not add object
as parent, to make them new style 如果您已经在注入mixin,为什么不添加object
作为父object
,以使其具有新样式
class Foo(Mixin, Bar, object):
...
And then use super
然后用super
class Mixin(object):
def __getattr__(self, k)
print repr(self), k
return super(Mixin, self).__getattr__(k)
Assuming that none of the classes in your code base implement __setattr__
or __getattr__
then one approach is to intercept __setattr__
in your Mixin, writing the value to another reserved attribute, then read it back in __getattr__
假设您的代码库中没有一个类实现__setattr__
或__getattr__
则一种方法是在Mixin中拦截__setattr__
,将值写入另一个保留属性,然后在__getattr__
读回
class Mixin:
def __setattr__(self, attr, value):
# write the value into some special reserved space
namespace = self.__dict__.setdefault("_namespace", {})
namespace[attr] = value
def __getattr__(self, attr):
# reject special methods so e.g. __repr__ can't recurse
if attr.startswith("__") and attr.endswith("__"):
raise AttributeError
# do whatever you wish to do here ...
print repr(self), attr
# read the value from the reserved space
namespace = self.__dict__.get("_namespace", {})
return namespace[attr]
Example: 例:
class Foo(Mixin):
def __init__(self):
self.x = 1
Then 然后
>>> Foo().x
<__main__.Foo instance at 0x10c4dad88> x
Clearly this won't work if any of your Foo
classes implement __setattr__
or __getattr__
themselves. 显然,如果您的任何Foo
类自己实现__setattr__
或__getattr__
则将无法使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.