本文介绍了在类声明中如何调用函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有此代码:

>>> 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的属性和行为.

Obviously, the call of zope.interface.implements in some way alters the properties and behavior of the class Foo.

这是怎么发生的?如何在我的代码中使用这种方法?

How does this happen? How do I use this approach in my code?

示例代码是 zope.interface 的一部分>模块.

Example code is the part of zope.interface module.

推荐答案

详细的会发生什么"

zope.interface.implements()函数检查框架堆栈并更改构造类的locals()名称空间(python dict). python class语句中的所有内容都在该命名空间中执行,结果形成类主体.

The detailed "what happens"

The zope.interface.implements() function inspects the frame stack and alters the locals() namespace (a python dict) of the class-in-construction. Everything within a class statement in python is executed in that namespace, and the result forms the class body.

该函数为类命名空间__implements_advice_data__添加了额外的值,其中包含一些数据(您已传递给该函数的接口以及classImplements可调用的对象,这些将在以后使用.)

The function adds an extra value to the class namespace, __implements_advice_data__ with some data (the interfaces you've passed to the function, and the classImplements callable, something that'll be used later on.

然后,通过在命名空间中添加(或更改先前存在的)__metaclass__键,在有关类的元类中添加或链接.这样可以确保将来每次创建该类的实例时,都将首先调用现在安装的元类.

It then either adds or chains in a metaclass for the class in question, by adding the (or altering a pre-existing) __metaclass__ key in the namespace. This ensures that in the future, every time you create an instance of the class, the metaclass now installed will be called first.

实际上,这个元类(类顾问)有点曲解.首次创建实例后,它会再次删除本身.它只是在__implements_advice_data__中指定的回调函数以及您传递给原始implements()函数的接口一起调用,之后立即从类中删除__metaclass__键,或将其替换为原始的__metaclass__(它被调用以创建第一个类实例).回调会在其自身之后清除,它将从类中删除__implements_advice_data__属性.

In fact, this metaclass (the class advisor) is a little devious; it removes itself again after the first time you create an instance. It simply calls the callback specified in the __implements_advice_data__ together with the interfaces you passed to the original implements() function, right after it either deletes the __metaclass__ key from the class, or replaces it with the original __metaclass__ (which it called to create the first class instance). The callback cleans up after itself, it removes the __implements_advice_data__ attribute from the class.

总而言之,zope.interface.implements()所做的全部工作是:

In summary, all the work zope.interface.implements() does is:

  • 添加传递的接口以及对类(__implements_advice_data__)中特殊属性的回调.
  • 确保使用特殊的元类在首次创建实例时调用该回调.
  • Add the passed interfaces, together with a callback to a special attribute in the class (__implements_advice_data__).
  • Ensures that the callback is called the first time you create an instance, using a special metaclass.

最后,在道德上等同于定义这样的接口:

In the end, it's the moral equivalent of defining your interfaces like this:

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的实例之外.

except that the last call is postponed until you first create an instance of Foo.

zope.interface最初开发时,Python还没有类装饰器.

When zope.interface was first developed, Python did not yet have class decorators.

zope.interface.classImplements()作为函数,并且zope.interface.implements()调用 in 类类提供了关于类实现什么接口的更好文档.您可以将其放在类声明的顶部,并且每个人在查看该类时都可以看到这一重要信息.在 之后放置classImplements()调用时,类声明几乎不那么清晰可见,对于长类定义而言,很容易将其完全遗漏掉.

zope.interface.classImplements() needs to be called separately, as a function, after the class has been created, and a zope.interface.implements() call within the class body provides better documentation about what interfaces a class implements. You can place it right at the top of a class declaration, and everyone can see this important piece of information when looking at the class. Having a classImplements() call located after the class declaration is not nearly as visible and clear, and for long class definitions it is easily going to be missed altogether.

PEP 3129 确实向该语言添加了类装饰器,他们被添加到python 2.6和3.0; zope.interface最早是在python 2.3(IIRC)时代开发的.

PEP 3129 finally did add class decorators to the language, and they were added to python 2.6 and 3.0; zope.interface was first developed back in the days of python 2.3 (IIRC).

现在我们要做有类修饰符,zope.interface.implements()已被弃用,您可以改用zope.interface.implementer类修饰符:

Now that we do have class decorators, zope.interface.implements() has been deprecated, and you can use the zope.interface.implementer class decorator instead:

@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

这篇关于在类声明中如何调用函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 15:16
查看更多