我想知道在元类上声明的方法会发生什么.我希望如果你在元类上声明一个方法,它最终将成为一个类方法,但是,行为是不同的.例
>>> class A(object):
... @classmethod
... def foo(cls):
... print "foo"
...
>>> a=A()
>>> a.foo()
foo
>>> A.foo()
foo
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试定义一个元类并给它一个方法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'
Run Code Online (Sandbox Code Playgroud)
这到底发生了什么?
编辑:碰撞问题
Oli*_*ier 15
你提出了一个好点.
这是一个很好的参考,可以更好地理解对象,类和元类之间的关系:
我也发现这个关于描述符的引用对于 python中的查找机制非常有启发性.
但我不能说我理解为什么a.foo
在A.foo
成功时失败.看起来,当你查找一个对象的属性,并且python在那里找不到它时,它并没有完全查找类中的属性,因为如果它确实,它会找到它A.foo
.
编辑:
哦! 我想我明白了.这是由于继承如何工作.如果您考虑上述链接提供的架构,它看起来像这样:
替代文字http://www.cafepy.com/article/python_types_and_objects/images/types_map.png
原理上,它归结为:
type -- object
| |
Meta -- A -- a
Run Code Online (Sandbox Code Playgroud)
去左手段要去类的指定实例.去了手段去的家长.
现在,继承机制使查找机制在上面的模式中向右转.它去了a ? A ? object
.它必须这样做才能遵循继承规则!为清楚起见,搜索路径是:
object
^
|
A <-- a
Run Code Online (Sandbox Code Playgroud)
然后,显然,foo
将找不到该属性.
但是,当您查找属性foo
时A
,会找到它,因为查找路径是:
type
^
|
Meta <-- A
Run Code Online (Sandbox Code Playgroud)
当人们想到继承如何运作时,这一切都是有道理的.
规则是这样的:当在对象上搜索属性时,也考虑对象的类及其父类.但是,不考虑对象的类的元类.当你访问一个类的属性,类的类是元类,所以它被认为是.从对象到其类的回退不会触发对类的"正常"属性查找:例如,无论是在实例上还是在其类上访问属性,都会以不同方式调用描述符.
方法是可调用的属性(并且具有__get__
使'self'自动传递的方法.)这使得如果在类上调用它们,但在实例上不可用,则元类上的方法就像classmethods.
归档时间: |
|
查看次数: |
718 次 |
最近记录: |