我有一个基于Python 2.3的大型安装,具有200k LOC。作为迁移项目的一部分,我需要拦截所有旧式类的所有属性查找。
旧遗留代码:
class Foo(Bar):
...
我的想法是注入一个像
这样的常见mixin类class Foo(Bar, Mixin):
...
class Mixin:
def __getattr__(self, k)
print repr(self), k
return Foo.__getattr__(self, k)
然而,由于Foo.__getattr__
解析,我总是在递归中运行
到Mixin.__getattr__
。
有没有办法修复Python 2.3旧式类的代码?
答案 0 :(得分:0)
如果您已经注入mixins,为什么不将object
添加为父级,以使其成为新风格
class Foo(Mixin, Bar, object):
...
然后使用super
class Mixin(object):
def __getattr__(self, k)
print repr(self), k
return super(Mixin, self).__getattr__(k)
答案 1 :(得分:0)
假设您的代码库中没有类实现__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]
示例:
class Foo(Mixin):
def __init__(self):
self.x = 1
然后
>>> Foo().x
<__main__.Foo instance at 0x10c4dad88> x
显然,如果您的Foo
个类自己实现__setattr__
或__getattr__
,这将无效。