是的,您需要一个元类,因为如果您
__getattribute__在Debug类中定义(请注意,它必须是一个新式类),Python将针对Debug实例调用该属性以进行属性查找,而不针对Debug自身进行属性查找。
这是有道理的,因为它
Debug.__getattribute__被定义为在Debug实例上运行,而不是在Debug类上运行。(您可以想象定义一个classmethod
__getattribute__,但是我找不到任何证据表明Python有任何可以调用这种方法的机器。)
我在这里想到的第一件事是添加另一
__getattribute__处Python将在其中查找Debug类属性查找的地方,即在Debug类是其实例的类中:
Debug.__class__.__getattribute__。
它确实存在并且按您期望的那样工作:
>>> Debug.__class__.__getattribute__(Debug, 'Draw')True>>> Debug.__class__.__getattribute__(Debug, 'Bogus')Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in __getattribute__AttributeError: 'DebugType' object has no attribute 'Bogus'
但这是不可修改的:
>>> Debug.__class__.__getattribute__ = Debug.__getattribute__Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can't set attributes of built-in/extension type 'type'
这似乎只是Python实现的事实。尽管存在该概念,但不允许您修改内置类型的属性,因此该方法将行不通。
但是,元类可以解救。您可能已经知道如何执行此 *** 作,但是对于其他读者,我将举一个示例(此答案中还有另一个示例,我的欠了它一些债务)。
_debug = True>>> class DebugType(type):... def __getattribute__(self, name):... print 'attr lookup for %s' % str(name)... return _debug and object.__getattribute__(self, name)... >>> class Debug(object):... Draw = True... __metaclass__ = DebugType... >>> _debugFalse>>> Debug.Drawattr lookup for DrawFalse>>> _debug = True>>> Debug.Drawattr lookup for DrawTrue
因此,归根结底,类的默认类实现为
type,因此类属性的默认属性looker-
upper为
type.__getattribute__,您不能
type.__getattribute__直接修改或替换,但可以
type使用元类机制进行替换,并且如上例所示,与子类取代它的
type是有
__getattribute__你想要的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)