我需要创建一个模仿这种行为的类(在数学中,我们说 list、dict 是“幂等的”):
>>> list(list([3,4]))
[3, 4]
>>> dict({'a':1,'b':2})
{'a':1,'b':2}
所以,如果 A 是我的类(class),我想写
>>> a = A(1)
>>> b = A(a)
>>> b == a
True
我想我的 A 类应该是这样的:
class A(object):
def __init__(self,x):
if isinstance(x, A) :
self = x
else :
self.x = x
self.y = 'hello'
我试试
>>> A(1).x
1
>>> A(A(1)).x
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'A' object has no attribute 'x'
它不起作用!
我不想在self中复制x属性,我只是想让self成为x或“点”x
一些想法? 谢谢
最佳答案
您正在寻找的是 __new__()
方法,该方法在构造类的之前 运行,而不是 __init__()
,后者发生在之后。使用 __new__()
,您可以 Hook 并替换正在创建的对象。
def __new__(cls, x):
if isinstance(x, A):
return x
else:
return object.__new__(cls, x)
您不能在 __init__()
中执行此操作,因为该对象已经创建。更改 self
只会更改局部变量的值,不会影响对象。
同样值得注意的是,类型检查在 Python 中几乎总是错误的做法。相反,检查该类是否具有您需要的信息/属性。这样,其他人就可以创建一个像您的类一样使用您的代码的类。
作为警告的最后一句话,这是非常令人困惑的行为 - 人们不会期望您的类(class)会这样做,而且这通常不是一个好主意。您的 list()
和 dict()
示例与您在这里所做的不准确,因为 list(some_list)
没有给出some_list
,它给出了一个新列表,它是 some_list
的副本 - dict()
也是如此:
>>> x = [1, 2, 3]
>>> list(x) is x
False
当您调用构造函数时,很自然地会期待一个新对象,而不是对现有对象的引用。我建议制作 A(some_a)
复制 some_a
,并重构您的调用代码,使其不依赖于 A(some_a) is some_a
)。
关于Python,当类型(a)仍然是A时如何处理A(a),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13419340/