除了types.new_class在创建类时定义关键字参数的能力.这两种方法之间是否存在重大差异?
import types
First = type('First',(object,),{'asd':99})
k = First()
Second = types.new_class('Second',(object,),{},lambda x:x)
x = Second()
Run Code Online (Sandbox Code Playgroud)
是的。答案涉及一个称为“元类”的概念。
[元类] 是比 99% 的用户应该担心的更深层次的魔法。如果您想知道是否需要它们,则不需要(真正需要它们的人肯定知道他们需要它们,并且不需要解释原因)。? Tim Peters,Python Zen of Python 的作者(来源)
如果您认为自己已经达到了 99%,那么就不要再读下去了,可以随意使用type. types.new_class除了在您使用元类的罕见情况下,它也一样好。
如果您想了解有关元类的更多信息,我建议您查看发布在“ Python 中的元类是什么? ”的一些高质量答案。(我推荐这个。)
一旦你理解了元类是什么,答案就显而易见了。由于type是一个特定的元类,因此只有当您想创建将其用作元类的类时,它才会起作用。
但是,如果您想使用非默认元类
class MySimpleMeta(type):
pass
Run Code Online (Sandbox Code Playgroud)
和静态类不会做
class MyStaticClass(object, metaclass=MySimpleMeta):
pass
Run Code Online (Sandbox Code Playgroud)
然后你可以使用 types.new_class
import types
MyStaticClass = types.new_class("MyStaticClass", (object,), {"metaclass": MyMeta}, lambda ns: ns)
# this is equivalent to the above class.
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,它需要一个可调用的(例如lambda ns: ns)而不是字典的原因是因为元类可以关心定义属性的顺序。)
我意识到这已经晚了,因此您可能已经自己回答了这个问题。
首先,你似乎误解kwds了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}
Run Code Online (Sandbox Code Playgroud)
类似于(没有打印)
SomeCls = types.new_class("SomeCls", (), {'debug':True})
Run Code Online (Sandbox Code Playgroud)
这些元参数在配置元类时非常有用。
我不太确定为什么new_class设计为直接接受可调用与字典,但我怀疑这是为了避免不相互继承的“新”类之间的隐式共享状态。
| 归档时间: |
|
| 查看次数: |
868 次 |
| 最近记录: |