除了types.new_class
在创建类时定义关键字参数的能力。这两种方法之间是否存在重大差异?
import types
First = type('First',(object,),{'asd':99})
k = First()
Second = types.new_class('Second',(object,),{},lambda x:x)
x = Second()
答案 0 :(得分:2)
是。答案涉及一个称为“ metaclasses”的概念。
[Metaclasses]比99%的用户应有的魔力深 永远担心。如果您想知道是否需要它们,则不需要 实际需要他们的人肯定知道他们需要他们,并且 不需要解释为什么)。 ⸺Tim Peters,Python的Zen(source)的作者
如果您认为自己处于99%的水平,则无需进一步阅读,可以随时使用type
。除了在极少数情况下使用元类的情况之外,它与types.new_class
一样好。
如果您想了解有关元类的更多信息,建议您查看发布到“ What are metaclasses in Python?”的一些高质量答案。(我建议this one )
一旦理解了元类是什么,答案就很不言而喻了。由于type
是特定的元类,因此只有在要创建将其用作其元类的类时,它才有效。
但是,如果要使用非默认元类
class MySimpleMeta(type):
pass
静态类不会
class MyStaticClass(object, metaclass=MySimpleMeta):
pass
然后您可以使用types.new_class
import types
MyStaticClass = types.new_class("MyStaticClass", (object,), {"metaclass": MyMeta}, lambda ns: ns)
# this is equivalent to the above class.
(简单地说,它需要可调用(例如lambda ns: ns
)而不是字典的原因是because metaclasses are allowed to care about the order in which the attributes are defined.)
答案 1 :(得分:0)
我意识到这已经很晚了,因此你已经可以自己回答这个问题了。
首先,您似乎误解了kwds
的{{1}}论点;它是类关键字参数,例如
types.new_class
类似于(没有印刷品)
class MyMeta(type):
def __new__(metacls, name, bases, attrs, **config):
print(config)
return super().__new__(metacls, name, bases, attrs)
def __init__(cls, name, bases, attrs, **config):
super().__init__(name, bases, attrs)
class SomeCls(metaclass=MyMeta, debug=True):
pass
>> {'debug': True}
这些元参数在配置元类时很有用。
我不确定为什么SomeCls = types.new_class("SomeCls", (), {'debug':True})
被设计为直接接受可调用vs dict,但我怀疑它是为了避免" new"之间的隐式共享状态。不相互继承的类。