Python,当类型(a)仍然是A时如何处理A(a)

标签 python class idempotent

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

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

相关文章:

python - Django 中属性的 bool 组合

apache-kafka - Kafka 主题和微服务的多个实例

javascript - JS函数 "not defined"

api - 如何在同时接收具有相同 ID 的多个请求时保持 API 幂等?

使用文件模块幂等改变权限

python - 分别对 numpy 数组中的所有偶数列和奇数列求和

Python:匹配 BeautifulSoup 文本中的正则表达式

python - R - 通过 Reticulate 解析 Python NLTK 树

javascript - 使用 John Resig 的 "simple JavaScript inheritance"如何调用 super 方法以及方法中的额外代码?

java - Java中从主类向其他类传递值