Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python元类的用途是什么?_Python_Class_Decorator_Metaclass - Fatal编程技术网

Python元类的用途是什么?

Python元类的用途是什么?,python,class,decorator,metaclass,Python,Class,Decorator,Metaclass,对于不能以任何其他方式使用的元类,可以做什么 Alex Martelli告诉我们,如果没有元类,有些任务是无法完成的 我想知道哪些是?为您的编程增加额外的灵活性: 但根据这一点,您可能还不需要它们 元类比99%的用户应该担心的更神奇。如果你想知道你是否需要它们,你不需要(真正需要它们的人肯定知道他们需要它们,也不需要解释原因) --巨蟒大师蒂姆·彼得斯 它们很少需要,但在您希望将行为添加到对象的基本行为的地方非常有用——比较面向方面的编程或在持久性框架(如Hibernate)中完成的工具 例如,

对于不能以任何其他方式使用的元类,可以做什么

Alex Martelli告诉我们,如果没有元类,有些任务是无法完成的
我想知道哪些是?

为您的编程增加额外的灵活性:

但根据这一点,您可能还不需要它们

元类比99%的用户应该担心的更神奇。如果你想知道你是否需要它们,你不需要(真正需要它们的人肯定知道他们需要它们,也不需要解释原因)

--巨蟒大师蒂姆·彼得斯


它们很少需要,但在您希望将行为添加到对象的基本行为的地方非常有用——比较面向方面的编程或在持久性框架(如Hibernate)中完成的工具


例如,您可能需要一个持久化或记录每个新对象的类。

如果您正在寻找使用元类机制的示例,您可以阅读的源代码


表单定义的声明式风格是通过元类实现的。

可能没有什么可以只用元类来完成的,但是对某些人(包括我的)来说,它是一个可以使用的有趣工具。只是小心不要滥用,因为这可能很棘手

例如,我在最近的一个项目中使用了元编程。这是一个OpenOffice计算表,它使用一些pyUNO宏生成一些包含信息的文件。有一张表向用户提供了要填写的信息,其他的可以用来描述元素的种类及其属性。然后,用户可以选择元素的数量和类型,并生成文件。 宏将根据每张工作表上的配置,通过元编程创建一个类。然后,用户可以实例化每个类并生成对象


这可以不用元编程来完成,但对我来说,使用元编程功能来完成似乎很自然。

看看Django源代码,例如元类用于生成模型

在内部,Django使用元类 基于您创建的类创建模型 在源代码中提供。没有 太多细节了,那 意思是说,而不是你的班级 作为实际模型,Django 收到您的班级描述, 它用于在其 地点


我经常使用元类,它们是工具箱中非常强大的工具。有时候,有了它们,你的问题解决方案可能会更优雅,代码更少

我发现自己最常使用元类的事情是在类创建期间对类属性进行后处理。例如,在适当的位置(例如Django ORM的工作方式)在对象上设置
name
属性:

如果您将此作为工具,并且您使用的类必须知道其
名称才能
执行某些操作()

它可以使代码的其余部分在以下方面有所不同:

class Bar(object):
    myfoo1 = Foo('myfoo1')
    myfoo2 = Foo('myfoo2')
    myfoo3 = Foo('myfoo3')
这是:

class Baaz(Autonamer):
    myfoo1 = Foo()
    myfoo2 = Foo()
    myfoo3 = Foo()

这样可以减少重复(以及变量名和分配的名称可能不同步的可能性)。

如果您想让类对象(与类对象的实例相反)配备“特殊定制行为”,元类是必不可少的,因为对象的行为取决于对象的类型的特殊方法,而类对象的类型正是元类的同义词

例如,如果您希望类对象X“print X”发出“Time is now 8:46am”(在8:46am,或者更一般地说,是当前时间),那么这必须意味着
type(X)
(又名X的元类)有一个特殊的自定义
\uu str\uuuuu
方法——同样地(使用各种适用的特殊方法)如果您想给表达式赋予意义,例如
X+Y
,其中X和Y都是类对象,或者
X[23]
(其中X也是类对象),等等

现在(在Python2.6或更高版本中)大多数其他定制任务都更容易通过类装饰器实现,它可以在
class
语句结束后立即更改类对象。还有一些情况下,这是不可行的,因为如果更改要产生任何效果,必须在很早之前进行更改(例如,设置或更改
\uuuuuuuuuuuuuuuuu插槽


在Python3中,元类还有一点用处:元类现在可以选择指定在执行
语句体期间填充的映射对象(默认情况下,它是一个普通的
dict
)。这允许保留和使用类主体中名称绑定的顺序(而正常的
dict
失去顺序),当类必须具有特定顺序的“字段”时(例如,将1:1映射到C
结构、CSV文件或DB表中的行等),这有时是很好的--在Python 2中。*这必须被冗余地指定(通常带有一个额外的类属性,它是一个序列,因此不保留顺序),Python3元类的这一特性允许删除冗余。

第一位评论员指出,元类的使用是一块“宝石”,帮助他追踪(许多)“天”以来一直发生的意外错误

我记得我在某个地方读到过类似这样的关于元类的文章,松散地引用:“如果你不得不问它们有什么用处,那就意味着你不需要它们。”+1,有趣的问题。我不确定“不能以任何其他方式完成”是一个有用的标准。几乎每件事都可以用许多不同的方式来完成,这完全取决于它有多容易/自然。应该有一种——最好只有一种——显而易见的方式来完成它。:)@胡安乔·康蒂:你是对的,但我想说的是,很多时候,语法只是为了让
class Bar(object):
    myfoo1 = Foo('myfoo1')
    myfoo2 = Foo('myfoo2')
    myfoo3 = Foo('myfoo3')
class Baaz(Autonamer):
    myfoo1 = Foo()
    myfoo2 = Foo()
    myfoo3 = Foo()