题
我想知道在元类上声明的方法会发生什么情况。我预计,如果您在元类上声明一个方法,它将最终成为一个类方法,但是,行为是不同的。例子
>>> class A(object):
... @classmethod
... def foo(cls):
... print "foo"
...
>>> a=A()
>>> a.foo()
foo
>>> A.foo()
foo
但是,如果我尝试定义一个元类并给它一个方法 foo,它似乎对类(而不是实例)起作用。
>>> class Meta(type):
... def foo(self):
... print "foo"
...
>>> class A(object):
... __metaclass__=Meta
... def __init__(self):
... print "hello"
...
>>>
>>> a=A()
hello
>>> A.foo()
foo
>>> a.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'foo'
这究竟是怎么回事?
编辑:提出问题
解决方案
您养好点。
下面是一个很好的参考以获得更好的理解关系对象,类和元类之间:
我还发现这个参考上的描述符以相当启发有关的在python查找机制
但我不能说我明白了为什么当a.foo
成功A.foo
失败。看来,当你看到了一个对象的属性,而Python没有找到它,它的不完全的查找在类的属性,因为如果它这样做,它会发现A.foo
。
编辑:
哦!我想我得到了它。这是因为继承是如何工作的。如果考虑由上述链接提供的架构,它看起来像这样:
示意性地,它归结为:
type -- object
| |
Meta -- A -- a
去左意味着要对类的给定实例的。去向上的装置要在父的
现在的继承机制使得查询机制做出的右转的在上面的架构。它去a → A → object
。它必须以遵循继承规则这样做!为了明确这一点,搜索路径是:
object
^
|
A <-- a
然后,清楚地,属性foo
不会被发现。
在查找在foo
属性A
,但是,它的是发现,因为查找路径是:
type
^
|
Meta <-- A
这一切是有道理的,当一个人认为继承是如何工作的。
其他提示
的规则是这样的:对于一个对象的属性进行搜索时,该对象的类与它的父类是考虑。对象的类的元类,但是,是不的考虑。当你访问一个类的属性,类的类是元类,所以它的是的考虑。从物体到其类回退不会对类触发一个“正常”属性查找:例如,描述符被称为属性不同是否是在一个实例或它的类访问
方法是被调用(并有__get__
方法,使“自我”被自动传递。)这使得它,以便在元类方法是一样classmethods如果你给他们打电话的类属性,而不是可在实例
我理解的方式是,元是一个类,并且A是它的一个实例。因此,当你调用A.foo(),它通过检查对象和它的类。所以,试图A.foo时,它首先通过方法的本身持有,然后将其类,梅塔的方法。作为A保持没有方法foo本身,它使用元中的一个,并因此确实执行Meta.foo(A)。
类似地,当a.foo试图,它首先通过一个样子。作为一个拥有无foo方法,它会去翻A.但A也没有保持foo方法,如foo是梅塔举行。由于既没有,也不是持有富,这将引发AttributeError。
我试图与一个变量以及函数,投入到类元的txt =“TXT”的属性,而这也为访问由A,但不是一个。所以,我倾向于认为我是对的,我理解,但我只是猜测。
已接受答案中的链接已经消失,至少对我来说是这样。所以我想补充一下:
3.数据模型 — object.__getattribute__
并给出我认为的两个要点:
object.__getattribute__
控制实例的属性访问。type.__getattribute__
控制类的属性访问。