我有两种对象:
class A(object):
def __init__(self, name):
self.name = name
self.x = 0
self.y = 0
def __eq__(self, other):
return isinstance(other, self.__class__) and self.name == other.name
def __hash__(self):
return hash(self.name)
我有另一个用两个对象定义的对象A:
class B(object):
def __init__(self, objectA1, objectA2):
self.objectA1 = objectA1
self.objectA2 = objectA2
我的问题是,如果我这样做:
a = A("name")
b = B(A("name"), A("other"))
然后两个A("名称")相等(根据我定义的相等)但不指向同一个对象:我有
b.objectA1 is a == False
这是一个问题,因为我想访问b.objectA1.x和b.objectA1.y,我希望它们是a的x和y。
我知道这是一个参考问题,但我不知道如何修复它以获得我想要的东西,即
A("name") is A("name") == True
始终,即使A用B定义。
精度:一切都是从tkinter接口定义的,带有字符串。 我想我可以做一个字典d,其中键是字符串(对象A的名称),以及哪些值是关联对象A. 然后我会定义:
b = B(d["s1"], d["s2"])
然而,它看起来很难看,而且我正在寻找pythonic方法(我对OOP不是很熟悉)
由于
答案 0 :(得分:2)
我不确定这是否是一个好主意,但您可能会混淆__new__
方法,并检查之前是否创建了具有相同参数的实例:
class A(object):
pool = {}
def __new__(cls, *args, **kwargs):
key = tuple(args)
if key not in A.pool:
A.pool[key] = super(A, cls).__new__(cls)
return A.pool[key]
# rest is the same as in your class
示例:
>>> A("foo") is A("bar")
False
>>> A("foo") is A("foo")
True
请注意,此仍然为从__init__
检索到的对象调用pool
,因此会初始化两次。此外,这仅在对象不可变时才有效;如果在初始化后两个实例等于,它们将保持不同的实例。
答案 1 :(得分:2)
如果您不熟悉Python的OOP,那么像元类这样的东西对您来说有点好笑,那么接受tobias_k建议:使用工厂。它可以是这样简单的功能:
class A(object):
def __init__(self, name):
self.name = name
def factory(name, pool={}):
if name not in pool:
pool[name] = A(name)
return pool[name]
a = factory("foo")
b = factory("bar")
c = factory("foo")
assert a is a
assert a is not b
assert a is c
另外,我刚刚看到你对更多Pythonic方式的评论,然后将对象存储在字典中。运营商"是"比较两个对象的id()返回值。在CPython中,它对于每个对象都是唯一的,而不是在对象的生命周期中改变。你能得到的最好的方法是在某处存储实例。