我想知道Python如何处理用户定义的对象。所以这是场景:
我创建了自己的类,名为 MyClass:
class MyClass():
def __init__(self):
# some code here
class MyClassContainer():
def __init__(self):
self.container = [] # will store MyClass object instances.
def Add(self, object):
self.container.append(object)
def Remove(self, object):
self.container.remove(object)
example = MyClassContainer()
myclass1 = MyClass()
example.Add(myclass1)
myclass2 = MyClass()
example.Add(myclass2)
example.Remove(myclass1)
那么问题来了,python的remove函数能够区分同一类的不同对象实例吗?是否有任何极端情况无法唯一标识我要删除的对象实例?
一种可能的情况是这样的:
myclass1 = MyClass(5)
example.Add(myclass1)
myclass1 = MyClass(3)
example.Add(myclass1)
example.Remove(myclass1)
哪个对象实例将被删除?我猜是 3 的通过了,但是有没有一条规则说,python 唯一标识同一类的对象实例?
最佳答案
list.remove()
删除第一个测试等于的对象。来自 documentation :
s.remove(x)
remove the first item from s wheres[i] == x
默认情况下,自定义类的实例仅在它们是完全相同的对象时才测试相等;如果 s[i] is x
返回 true,则 s[i] == x
也返回 true。
定义实例的不是变量名;在第二个示例中,将从列表中删除 MyClass(3)
实例,因为它是一个唯一的对象,与 MyClass(5)
不同您之前创建并添加的实例。您可以使用 id()
function 检查这一点,在 CPython 上基本上返回当前内存地址:
>>> myclass1 = MyClass(5)
>>> id(myclass1)
4349144816
>>> example.Add(myclass1)
>>> myclass1 = MyClass(3)
>>> id(myclass1)
4349145040
>>> example.Add(myclass1)
>>> example.container
[<__main__.MyClass object at 0x1033aaef0>, <__main__.MyClass object at 0x1033aafd0>]
>>> hex(id(myclass1))
'0x1033aafd0'
>>> myclass1 is example.container[1]
True
>>> example.Remove(myclass1)
>>> example.container
[<__main__.MyClass object at 0x1033aaef0>]
请注意,自定义类的默认表示形式包括十六进制的 id()
值!
您可以通过覆盖 object.__eq__()
method 来改变此行为;让它根据您自己的条件返回 True
或 False
,或者如果其他对象不是您的类支持的类型,则返回 NotImplemented
单例相比(这样Python可以委托(delegate)给另一个对象)。
例如,如果您的实例在 number
属性相等时应被视为相等,则可以按如下方式实现:
class MyClass():
def __init__(self, number):
self.number = number
def __eq__(self, other):
if not isinstance(other, MyClass):
return NotImplemented
return self.number == other.number
通过此更改,您可以执行以下操作:
example.Add(MyClass(42))
example.Add(MyClass(81))
example.Remove(MyClass(42))
这将删除 number
设置为 42
的实例。
关于python - Python 对象实例是该语言中唯一的对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33619225/