在Python 3中使用属性时范围如何工作?

时间:2018-04-19 02:03:42

标签: python python-3.x

关于范围的新手问题:在以下示例中,property如何能够访问getxsetx等。也就是说,为什么这些名称不必是例如,用C.getx限定?代码直接来自python docs(https://docs.python.org/3/library/functions.html#property):

class C:
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x

    def setx(self, value):
        self._x = value

    def delx(self):
        del self._x

    x = property(getx, setx, delx, "I'm the 'x' property.")

更新:根据评论

相反,如果我有这样的课程

class A:
    def foo(self):
        print("foo")

    def bar(self):
        foo(self)

这会失败。这是因为CPython在我实际尝试运行它之前不知道bar中的内容是什么(此时我们不再在类范围内)?

2 个答案:

答案 0 :(得分:3)

在完成之前,类是它自己的命名空间,因此在类定义期间不需要限定它内部的名称。 (事实上​​,它们不可能:类没有名称,因此无法指定名称所在的命名空间。)

class C:
    a = 0
    b = a + 1   # uses a from preceding line

在您的班级定义中,getxsetxdelx可以使用不合格,因为在课程定义期间会执行property(...)调用。

在完成类之后,该类具有名称,对于在实例上调用的方法,该实例具有名称(传统上为self)。此时访问属性和方法需要使用类或实例引用(例如C.fooself.foo)来限定名称。

答案 1 :(得分:0)

那是因为有两个不同的范围。一个是Class,一个是function

在类中定义函数时,该函数在Class范围内定义。您可以构建一个最小的示例:

class A:
    a = 1
    b = a + 1
    pass

您可以看到,在定义b时,我们可以直接访问变量a,因为它们位于同一范围A Class中。

但是当你在函数中使用Class范围变量时,那是另一个范围function。因此,在这种情况下,您需要手动指定范围。

实际上,这种行为因语言而异。