使用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允许用户定义一个非常简单的自定义表单结构类(如上所述),然后用它来构建一个新的字段生成类时 not 实例化的类。
我已经阅读了许多关于类工厂和元类的教程,并且普遍的共识是避免使用元类并使用类装饰器之类的东西。问题是教程要么开始导入额外的库,例如:import six
,将不同Python版本的解释混合在一起,使用过于复杂的示例或建议不要使用元类。
有人可以提供一个非常简单的解释(对于Python 3),如何使用简单的类定义(如上面的WTForms示例)和元类来定制类的全新构造,而不实际实例化类时构造
编辑:抱歉发现很难解释我的最终目标是什么,但是由于我已经完成了教程,因此不清楚是否有类装饰器,元类,魔术方法(调用,新, init )或其中的组合是我实现可视化所需的内容,或者我可视化的内容是错误的做法的东西。不幸的是,如果不能理解实现它所需的机制,似乎无法判断我的目标是否错误。我已经意识到元类是要走的路,只需要指向一个非常简单的元类例子来完成Python 3.x方式。
答案 0 :(得分:3)
您可以动态创建类 - 没有自定义元类,也没有装饰器,只需将程序员视为简单的函数调用。
只需使用三个参数调用Python的内置type
:
类的名称,带有基数的元组,以及带有命名空间的映射对象(即包含通常在类主体上定义的属性和方法的字典)。
def __init__(self):
...
namespace = {
'__init__': init,
'name': 'default name'
}
MyClass = type("MyClass", (object,), namespace)
由于编译器在构建类体内声明的函数期间执行了一些特殊操作,因此您放弃了一些唯一可能的功能 - 主要是能够使用无参数super
并命名以{{1但是就是这样。
那说应该注意这不是“没有元类”。 “type”本身就是一个元类 - 所有对象的默认Python元类 - 并且正在调用一个创建类的元类。没有其他方法可以创建一个类。 “类装饰器”只是一种可以在创建类对象后对其进行更改的方法。
任何产生新的动态类的函数或方法都会在其中调用__
或其他元类。同样的情绪,“元类”本身不会创建动态类 - 它需要在类主体声明中使用,或者使用(至少)调用type
时使用的相同参数调用。
至于“类装饰器”而不是元类的建议,我不确定是否正确(超出“类装饰器”无法自动动态创建类的事实):它们的主要缺点是那里对于装饰类的子类来说,父类的类装饰器是自动应用于自身的,而不继承元类,这并不是普通的方式。
在Python 3.6中你有type
协议,是的,它可以避免很多传统的元类用法(但是,它仍然不会“动态创建类” - 调用__init_subclass__
那样做。)