[英]__getattr__ of meta class not being called
As the title says. 如标题所示。 It seems no matter what I do, __getattr__
will not be called. 看来无论我做什么,都不会调用__getattr__
。 I also tried it for instance (absurd, I know), with predictably no response. 例如,我也尝试过(很奇怪,我知道),但是没有反应。 As if __getattr__
was banned in meta classes. 好像__getattr__
在元类__getattr__
被禁止。
I'd appreciate any pointer to documentation about this. 我会很高兴有任何有关此文档的指针。
The code: 编码:
class PreinsertMeta(type):
def resolvedField(self):
if isinstance(self.field, basestring):
tbl, fld = self.field.split(".")
self.field = (tbl, fld)
return self.field
Field = property(resolvedField)
def __getattr__(self, attrname):
if attrname == "field":
if isinstance(self.field, basestring):
tbl, fld = self.field.split(".")
self.field = (tbl, fld)
return self.field
else:
return super(PreinsertMeta, self).__getattr__(attrname)
def __setattr__(self, attrname, value):
super(PreinsertMeta, self).__setattr__(attrname, value)
class Test(object):
__metaclass__ = PreinsertMeta
field = "test.field"
print Test.field # Should already print the tuple
Test.field = "another.field" # __setattr__ gets called nicely
print Test.field # Again with the string?
print Test.Field # note the capital 'F', this actually calls resolvedField() and prints the tuple
Thanks to BrenBarn, here's the final working implementation: 感谢BrenBarn,这是最终的工作实现:
class PreinsertMeta(type):
def __getattribute__(self, attrname):
if attrname == "field" and isinstance(object.__getattribute__(self, attrname), basestring):
tbl, fld = object.__getattribute__(self, attrname).split(".")
self.field = (tbl, fld)
return object.__getattribute__(self, attrname)
As documented , __getattr__
is only called if the attribute does not exist. 如文档所述 ,仅在属性不存在时才调用__getattr__
。 Since your class has a field
attribute, that blocks __getattr__
. 由于您的课程有一个field
属性,因此会阻塞__getattr__
。 You can use __getattribute__
if you really want to intercept all attribute access, although it's not clear from your example why you need to do this. 如果您确实想拦截所有属性访问,则可以使用__getattribute__
,尽管从示例中尚不清楚为什么需要这样做。 Note that this has nothing to do with metaclasses; 注意,这与元类无关。 you would see the same behavior if you created an instance of an ordinary class and gave it some attribute. 如果创建一个普通类的实例并为其赋予一些属性,您将看到相同的行为。
Even assuming you used __getattribute__
, so it was called when the attribute exists, your implementation doesn't make much sense. 即使假设您使用了__getattribute__
,当属性存在时也被调用了,您的实现也没有多大意义。 Inside __getattr__
you try to get a value for self.field
. 在__getattr__
内部,您尝试获取self.field
的值。 But if __getattribute__
was called in the first place, it will be called again for this access, creating an infinite recursion: in order to get self.field
, it has to call __getattribute__
, which again tries to get self.field
, which again calls __getattribute__
, etc. See the documentation for __getattribute__
for how to get around this. 但是,如果首先调用__getattribute__
,则将为此访问再次调用__getattribute__
,从而创建无限递归:为了获取self.field
,它必须调用__getattribute__
,它再次尝试获取self.field
,然后再次调用__getattribute__
等见文档的__getattribute__
如何来解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.