答案 0 :(得分:2)
每次调用Contact()
时,即使您传递了相同的args,也会创建一个新实例。 Python如何知道您希望具有相同args的联系人实际上是同一个对象?一般来说,这是不可取的。如果您想为同一个实例使用两个名称,只需执行一个简单的赋值,例如
c1 = Contact('647-000-000', 'Andy')
c2 = c1
如果确实希望对具有相同args的Contact()
进行两次(或更多次)调用以返回相同的对象,则可以为__new__
构造函数提供缓存,例如{ {3}}。这是一个简短的演示。
from functools import lru_cache
class Contact:
@lru_cache(None)
def __new__(cls, *args):
return super().__new__(cls)
def __init__(self, phone, name):
self.phone = phone
self.name = name
def __str__(self):
return f'Contact({self.phone}, {self.name})'
c1 = Contact('647-000-000', 'Andy')
c2 = Contact('647-000-001', 'Amos')
c3 = Contact('647-000-000', 'Andy')
for c in (c1, c2, c3):
print(c, repr(c))
<强>输出强>
Contact(647-000-000, Andy) <__main__.Contact object at 0xb7285d4c>
Contact(647-000-001, Amos) <__main__.Contact object at 0xb7285dac>
Contact(647-000-000, Andy) <__main__.Contact object at 0xb7285d4c>
当您调用Contact
时,将调用其__new__
方法来构造新的实例对象。然后将该对象传递给__init__
以进行初始化。在大多数类中,__new__
方法尚未定义,因此调用父类的__new__
方法,通常是从{继承的默认__new__
方法。 {1}}基类。
在上面的代码中,我们定义object
并使用__new__
进行装饰。因此,当我们调用lru_cache
Contact()
类型时,Contact
会处理任何其他args,它会维护我们创建的所有lru_cache
个实例的不可见字典,并通过args键入到Contact
(包括__new__
类型)。如果该密钥在dict中,则Contact
返回相应的实例。否则,会分配一个新的__new__
并将其添加到Contact
。在任何一种情况下,实例都会传递给dict
进行初始化。
以上代码是概念证明。我不建议在实际代码中执行此操作。由__init__
维护的不可见dict
会保留对您创建的每个联系人的引用,因此当它们(似乎)超出范围时,即使您将它们传递给{{1},它们也不会被删除直到程序终止。要强制删除联系人,您需要从缓存中清除它,您可以使用:
lru_cache
但当然会清除整个缓存。
答案 1 :(得分:-1)
通过实施__eq__
(文档链接)来定义对象的等效性(<div class="container">
<div class="row">
<div id="content" class="col-lg-4 col-lg-push-4 col-sm-12 ">
<h2></h2>
<p></p>
</div>
<div id="sidebar-left" class="col-lg-4 col-sm-6 col-lg-pull-4">
<h2></h2>
<p></p>
</div>
<div id="sidebar-right" class="col-lg-4 col-sm-6">
<h2></h2>
<p></p>
</div>
</div>
</div>
)非常简单:
==
这里,class Contact:
def __init__(self, phone, name):
self.phone = phone
self.name = name
def __eq__(self, other):
return (self.phone == other.phone) and (self.name == other.name)
c1 = Contact('647-000-000', 'Andy')
print(c1 == Contact('647-000-000', 'Andy')) # True
是一个接受一个参数的方法(它与之比较的东西)并且应该返回__eq__
或True
(或者可以强制转换为布尔值的东西)。这是一个非常简单和“脆弱”的实现,因为False
之类的东西会引发错误,但它证明了这个想法。
但是,您无法实现定义引用相等性(c1 == "string"
)的魔术方法。通常,您应该考虑使用is
来测试它们是否完全相同的对象,并使用is
来测试这两个对象是否等效
[1]是的,尽管如此,它仍然可以缓存并使用元类或==
,
答案 2 :(得分:-1)
好吧基本上Python有别名。并检查两个对象是否是您编写的别名
obj1 is obj2
如果返回True,则它们是别名。好吧,基本上Python检查两个对象id。以上陈述相当于:
id(obj1) == id(obj2)
id(object)
用于评估内存中对象的地址。
写作时b is Contact('647-000-000', 'Andy')
b已经在内存中找到了一个地址但是当你将它与Contact('647-000-000', 'Andy')
进行比较时,Contact('647-000-000', 'Andy')
在内存中有一个不同的地址。
我不明白为什么要比较整个班级而不是属性。
b.number == '647-000-000'
和b.name == 'Andy'
将解决您的问题。