Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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_Python 3.x_Python Decorators_Metaclass_Class Factory - Fatal编程技术网

Python 动态创建一个类而不实例化它-没有元类?

Python 动态创建一个类而不实例化它-没有元类?,python,python-3.x,python-decorators,metaclass,class-factory,Python,Python 3.x,Python Decorators,Metaclass,Class Factory,以WTForms表单定义类为例: class RegistrationForm(Form): username = StringField('Username', [validators.Length(min=4, max=25)]) email = StringField('Email Address', [validators.Length(min=6, max=35)]) accept_rules = BooleanField('I accep

以WTForms表单定义类为例:

class RegistrationForm(Form):
    username     = StringField('Username', [validators.Length(min=4, max=25)])
    email        = StringField('Email Address', [validators.Length(min=6, max=35)])
    accept_rules = BooleanField('I accept the site rules', [validators.InputRequired()])
从库的源代码来看,WTForms似乎允许用户定义自定义表单结构的一个非常简单的类(如上所述),然后使用该类来构造一个新的字段类,该字段类在生成类时不会实例化

我已经阅读了很多关于类工厂和元类的教程,普遍的共识是避免使用元类,而是使用类装饰器之类的东西。问题是教程要么开始导入额外的库,例如:
importsix
,将不同Python版本的解释混合在一起,使用过于复杂的示例,要么建议根本不要使用元类

请有人提供一个非常简单的解释(针对Python3),说明如何使用简单的类定义(如上面的WTForms示例)和元类来定制一个全新的类构造,而不在构造时实际实例化该类


编辑:很抱歉,我发现很难解释我的最终目标是什么,但由于我已经阅读了教程,不清楚类装饰器、元类、魔法方法(调用新建初始化)或这些方法的组合是实现我想象的目标所需要的,或者我想象的是错误的做事方式。不幸的是,如果不了解实现目标所需的机制,就无法判断我的目标是否错误。我已经意识到元类是一条路要走,只需要为一个非常简单的元类示例指明正确的方向,它是用Python3.x的方式完成的。

您可以动态创建类-没有自定义元类,也没有对程序员来说是简单函数调用的修饰符

只需使用三个参数调用Python的内置
type
: 类的名称、元组及其基、映射对象及其命名空间(即包含通常在类主体上定义的属性和方法的字典)

由于编译器在构建类主体中声明的函数时做了一些特殊的事情,您失去了一些可能的特性—主要是能够使用无参数的
super
和以
\uuu
开头的属性名称混乱,但仅此而已

也就是说,应该注意的是,这并不是“没有元类”。“type”本身就是一个元类——所有对象的默认Python元类——并且正在调用一个创建类的元类。没有其他方法可以创建类。“类装饰器”只是一种方法,可以在类对象创建后对其进行更改

任何产生一个新的动态类的函数或方法,在某一点上都会在其内部调用
type
或其他元类。在同样的情况下,“元类”本身并不创建动态类——它需要在类主体声明中使用,或者使用(至少)用于调用
type
的相同参数来调用

至于建议使用“类装饰器”而不是元类,我不确定这是否正确(事实上,“类装饰器”无法自行动态创建类):它们的主要缺点是,在继承元类的同时,修饰类的子类没有普通的方法自动将父类的类修饰器应用于它们自己


在Python3.6中,您有
\uuuuu init\u subclass\uuuuu
协议,它可以避免元类的许多传统用法(但它仍然不会“动态创建类”-调用
type
可以做到这一点)。

为什么您正在阅读的教程告诉您使用元类是不好的做法?元类有完全有效的用例。如果这就是所有的教程所说的,依我看,他们是错的。如果你能更具体地说明你想要完成什么,参考你读到的内容,说明元类是错误的,等等,这会有所帮助。你能提供一个例子链接来解释为什么不应该使用元类吗?这似乎不太正确。我有点怀疑导师们实际上说的是“在你达到元类之前,考虑你的元编程问题不能用更简单、更受限的技术比如装饰者来解决”。而不是“不要使用元类来制作calasse”。此外,我真的检查了类装饰所涵盖的“90%”用例(或者说99%,它只是在飞机上以任何方式制作的)。我不得不在“现实生活项目”中创建一些元类,我认为只有一次类装饰就足够了。答案非常清楚,非常感谢。令人惊讶的是,有多少指南使用两段文字来解释“类型是一个类中的一个类”等,而仅仅是“类型本身就是一个元类”这句话就帮了大忙。这当然解释了我需要专注于学习的内容,以及我可以留到以后再做的事情。再次感谢@jsbueno
def __init__(self):
    ...

namespace = {
   '__init__': init,
   'name': 'default name'
}

MyClass = type("MyClass", (object,), namespace)