我想知道在元类上声明的方法会发生什么情况。我预计,如果您在元类上声明一个方法,它将最终成为一个类方法,但是,行为是不同的。例子

>>> 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__ 控制类的属性访问。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top