在处理数据库连接时,我使用了单例模式,原因很明显。为了简化目的,我简化了类定义,问题仍然是一样的。
班级:
class Point(object):
_instance = None
def __new__(cls, x, y):
if Point._instance is None:
Point._instance = object.__new__(cls)
Point._instance.x = x
Point._instance.y = y
return Point._instance
def __init__(self, x, y):
self.x = x
self.y = y
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = self._instance.x
@property
def y(self):
return self._y
@y.setter
def y(self, y):
self._y = self._instance.y
def __str__(self):
return 'x: {}, y: {} id.x: {}'.format(self.x, self.y, id(self.x))
它会产生以下错误:
AttributeError: 'Point' object has no attribute '_x'
我找到了以下解决方法:
class Point(object):
_instance = None
def __new__(cls, x, y):
if Point._instance is None:
Point._instance = object.__new__(cls)
Point._instance.x = x
Point._instance.y = y
return Point._instance
def __init__(self, x, y):
self.x = self._instance.x
self.y = self._instance.y
pythonic的方法是使用属性方法,因此我仍然有痒,即使我有一个工作代码,有人可以向我解释为什么 - 为什么我有这样的错误。
答案 0 :(得分:1)
在self.x
中调用__init__
时,控件(通过描述符)移动到x
的设置器,其执行:
self._x = self._instance.x
反过来调用试图执行的getter:
return self._x
在设置self._x
之前。 _y
存在类似的情况。
我认为你不希望人们改变x
和y
的价值,如果是这样的话,请将它们read-only properties。< / p>
作为附录,我没有理由在x
中设置值y
和__new__
,您可以在__init__
中设置它们。
答案 1 :(得分:1)
虽然我不确定为什么你会这样做,但你可以尝试:
_instance = None
def Point(x,y):
class _Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return 'x: {}, y: {} id.x: {}'.format(self.x, self.y, id(self.x))
global _instance
if _instance is None:
_instance = _Point(x,y)
return _instance
p1 = Point(1,2)
print "p1", p1
p2 = Point(3,4)
p2.x = 10
print "p2", p2
print "p1", p1
输出
p1 x: 1, y: 2 id.x: 94912852734312
p2 x: 10, y: 2 id.x: 94912852734096
p1 x: 10, y: 2 id.x: 94912852734096