是否可以使用类型正确复制类

Mad*_*ist 5 python types metaclass

根据这个答案,cls可以复制一个类对象

cls_copy = type('cls_copy', cls.__bases__, dict(cls.__dict__))
Run Code Online (Sandbox Code Playgroud)

这适用于大多数正常情况.它并没有在元类的工作cls是不是type.我最初的天真修复就是做

cls_copy = type(cls)('cls_copy', cls.__bases__, dict(cls.__dict__))
Run Code Online (Sandbox Code Playgroud)

然而,这简直是毫无意义.有没有办法知道元类做什么,因为这个答案对一个相关的问题指出,它是如何将输入的字典,它需要什么额外的关键词等

最初的使用type几乎是足够好的,有几个小的例外:

  1. __dict__通过不最终调用创建的元类type.__new__也可以是不同类型的不是通常的代理对象.
  2. 扩展副本的类将没有正确的元类,这可能会导致意外行为.
  3. 原始元类中定义的任何属性或其他数据描述符将不再在类对象上可用.

我愿意忽略第1项.如果我找到其他项目的可行解决方案,那么我愿意记录下来.如果可以更改副本的元类,则可以解决项目#2和#3.我试过(再一次,天真地)

cls_copy = type('cls_copy', cls.__bases__, dict(cls.__dict__),
                metaclass=type(cls))
Run Code Online (Sandbox Code Playgroud)

这只是提出了一个TypeError,正如可以预料的那样:

TypeError: __init_subclass__() takes no keyword arguments
Run Code Online (Sandbox Code Playgroud)

根据文档,这是有道理的:

与其身份一样,对象的类型也是不可更改的.1

但是,脚注说明了这一点

可能在某些情况下更改对象的类型,在某些控制的条件.但它通常不是一个好主意,因为如果处理不当会导致一些非常奇怪的行为.

有哪些条件可以更改对象的类型,特别是类的类型?这是其中一个案例,如果是这样,怎么样?

注意

我知道,copy.deepcopy继承是可行的替代方案.出于这个问题的目的,我希望忽略这些替代方案并坚持使用type相关技术.

int*_*ser 4

你可以使用type.__new__(type(cls), cls.__name__, cls.__bases__, dict(cls.__dict__)). 这使用正常的type创建过程,但创建一个实例type(cls)而不是type

至于__metaclass__问题,我认为这是因为__metaclass__通常被称为,所以type不能使用它。