如何创建与另一个对象相同类的新实例?
假设你有一个对象 x
,它是某个类的实例。现在你想创建一个和 x
一样类型的新实例,但又不想导入所有可能的类,也不想用 isinstance
来判断类型该怎么做。
比如说,如果 x
是一个小数:
>>> from decimal import Decimal
>>> x = Decimal('3')
>>> x
Decimal('3')
那么你该怎么创建一个新的 Decimal
实例呢?我觉得比较明显的做法是这样:
>>> type(x)('22')
Decimal('22')
>>> x.__class__('22')
Decimal('22')
但是要注意,__class__
在 int
上是不能用的:
>>> 1.__class__
File "<stdin>", line 1
1.__class__
那么使用 type
来实现这个目标是否是个好主意?或者说还有其他方法,或者在使用这种方法创建新对象时需要注意什么?
注意:
之前有一个回答被删掉了,里面提到了一种正确的方法来获取 int
的 __class__
。
>>> (1).__class__
<type 'int'>
使用场景
这个问题主要是理论上的,但我现在在用 Qt 的时候正好用到了这种方法来创建新的 QEvent
实例。比如说,QEvent
对象会被应用程序的事件处理器消耗,以便将事件发送到 QStateMachine
。如果不创建事件的新实例,就会出现运行时错误,因为底层的 C++ 对象会被删除。
而且因为我使用的是自定义的 QEvent
子类,它们都共享同一个基类,所以这些对象接受相同的一组预定义参数。
1 个回答
调用 type(x)
确实是创建一个和 x
完全相同类型的新实例的标准方法。不过,传给这个调用的参数并不是固定的,因为不同类型的“签名”(也就是需要传入的参数数量和类型)是不同的;所以,如果你对类型一无所知,就需要更多的检查来确定该传什么参数(还有一些规则或经验法则来决定你想传哪些参数,比如你可能需要传0到3个参数,且可选的/关键字参数的名字是'y'、'z'、't'……显然,在这里建立一个通用的规则是不可能的!)。
所以,请你澄清一下(当要实例化的类型很容易确定时;-))你打算如何处理你问题中那些困难的部分,而你甚至没有提到?你能对类型的签名做出什么假设?你需要对这些进行一些合理性检查吗,还是说直接因为传入错误类型或数量的参数导致 TypeError
是可以接受的?等等……没有更多这方面的信息,你的问题就很难得到一个在现实中可以使用的答案!-)