![](/img/trans.png)
[英]How the class are behaving in python - difference between normal class function and class inside class declaration function?
[英]How does the function that is called inside the class declaration?
有这个代码:
>>> class Foo:
... zope.interface.implements(IFoo)
...
... def __init__(self, x=None):
... self.x = x
...
... def bar(self, q, r=None):
... return q, r, self.x
...
... def __repr__(self):
... return "Foo(%s)" % self.x
显然, zope.interface.implements
的调用以某种方式改变了类Foo
的属性和行为。
这是怎么发生的? 如何在我的代码中使用此方法?
示例代码是zope.interface模块的一部分。
zope.interface.implements()
函数检查帧堆栈并改变构造类的locals()
命名空间(python dict
)。 python中的一个class
语句中的所有内容都在该命名空间中执行,结果形成了类主体。
该函数为类名称空间__implements_advice_data__
添加了一个额外的值, __implements_advice_data__
包含一些数据(您传递给函数的接口,以及可调用的classImplements
,稍后将使用的东西)。
然后,通过在命名空间中添加(或更改预先存在的) __metaclass__
键,可以在相关类的元类中添加或链接。 这样可以确保将来每次创建类的实例时,都会首先调用现在安装的元类。
事实上,这个元类(班级顾问)有点狡猾; 它在您第一次创建实例后再次自行删除 。 它简单地调用__implements_advice_data__
指定的回调以及传递给原始的implements()
函数的接口,在它从类中删除__metaclass__
键之后,或者用原始的__metaclass__
替换它(它调用它来创建第一个)类实例)。 回调自行清理,它从类中删除__implements_advice_data__
属性。
总之, zope.interface.implements()
所有工作都是:
__implements_advice_data__
)。 最后,它是道德等同于定义你的接口,如下所示:
class Foo:
def __init__(self, x=None):
self.x = x
def bar(self, q, r=None):
return q, r, self.x
def __repr__(self):
return "Foo(%s)" % self.x
zope.interface.classImplements(Foo, IFoo)
除了最后一次调用被推迟,直到你第一次创建一个Foo
实例。
当zope.interface
最初开发时,Python还没有类装饰器。
zope.interface.classImplements()
需要在创建类之后作为函数单独调用,并且类体内的zope.interface.implements()
调用提供了有关类实现的接口的更好文档。 您可以将它放在类声明的顶部,每个人在查看课程时都可以看到这条重要的信息。 在类声明之后定位的classImplements()
调用几乎不可见且清晰,对于长类定义,它很容易被完全遗漏。
PEP 3129最终确实为该语言添加了类装饰器,并将它们添加到python 2.6和3.0中; zope.interface
最初是在python 2.3(IIRC)时代开发的。
现在我们已经有了类装饰器, zope.interface.implements()
已被弃用,您可以使用zope.interface.implementer
类装饰器代替:
@zope.interface.implementer(IFoo)
class Foo:
def __init__(self, x=None):
self.x = x
def bar(self, q, r=None):
return q, r, self.x
def __repr__(self):
return "Foo(%s)" % self.x
阅读来源,卢克 :
http://svn.zope.org/zope.interface/trunk/src/zope/interface/declarations.py?rev=124816&view=markup
def _implements(name, interfaces, classImplements): frame = sys._getframe(2) locals = frame.f_locals # Try to make sure we were called from a class def. In 2.2.0 we can't # check for __module__ since it doesn't seem to be added to the locals # until later on. if (locals is frame.f_globals) or ( ('__module__' not in locals) and sys.version_info[:3] > (2, 2, 0)): raise TypeError(name+" can be used only from a class definition.") if '__implements_advice_data__' in locals: raise TypeError(name+" can be used only once in a class definition.") locals['__implements_advice_data__'] = interfaces, classImplements addClassAdvisor(_implements_advice, depth=3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.