4

我需要创建一个模仿这种行为的类(在数学中,我们说listdict是“幂等的”):

>>> list(list([3,4]))
[3, 4]
>>> dict({'a':1,'b':2})
{'a':1,'b':2}

所以,如果A是我的班级,我想写

>>> 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

一些想法?谢谢

4

1 回答 1

11

您正在寻找的是__new__()方法,它在类构建之前__init__()运行,而不是在之后运行。您可以使用__new__()并替换正在创建的对象。

def __new__(cls, x):
    if isinstance(x, A):
        return x
    else:
        return object.__new__(cls, x)

您不能这样做,__init__()因为该对象已经创建。更改self只是更改局部变量的值,它不会影响对象。

还值得注意的是,在 Python 中类型检查几乎总是错误的事情。相反,请检查该类是否具有您需要的信息/属性。这样,某人可以创建一个行为类似于您的类并使用您的代码。

作为最后的警告,这是非常令人困惑的行为——人们不会期望你的班级会这样做,而且这通常不是一个好主意。您的 and 示例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)。

于 2012-11-16T15:15:44.167 回答