属性错误,使用属性方法

时间:2017-09-26 02:43:57

标签: python python-2.7 python-3.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 = 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的方法是使用属性方法,因此我仍然有痒,即使我有一个工作代码,有人可以向我解释为什么 - 为什么我有这样的错误。

2 个答案:

答案 0 :(得分:1)

self.x中调用__init__时,控件(通过描述符)移动到x的设置器,其执行:

self._x = self._instance.x

反过来调用试图执行的getter:

return self._x 

在设置self._x之前。 _y存在类似的情况。

我认为你不希望人们改变xy的价值,如果是这样的话,请将它们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

Try it online!