繁体   English   中英

foo和_foo-关于类中的变量

[英]foo and _foo - about variables inside a class

class ClassName(object):
    """
    """    
    def __init__(self, foo, bar):
        """
        """
        self.foo = foo # read-write property
        self.bar = bar # simple attribute

    def _set_foo(self, value):
        self._foo = value

    def _get_foo(self):
        return self._foo

    foo = property(_get_foo, _set_foo)

a = ClassName(1,2)
#a._set_foo(3)
print a._get_foo()

当我打印a._get_foo()时,函数_get_foo将打印变量self._foo。 但是它是从哪里来的呢? self._foo和self.foo不同,不是吗?

编辑:问题是我仍然不明白什么财产。 给我一些时间。

property文档说明了应如何使用它。 这些行之间没有区别:

self.foo = foo # read-write property

a.foo = 3

您也不应手动调用设置方法和获取方法。

eta :如果您在查看文档中提供的示例并阅读了我们的答案后仍不了解该property作用,则也许应该放弃使用它。 实际上,这并不是Python功能的最基本要素。 您可能想从一个简单的例子开始,这个例子很容易理解:

>>> class ClassName(object):
    def __init__(self, foo):
        self.foo = foo


>>> a = ClassName(1, 2)
>>> a.foo
1
>>> a.foo = 42
>>> a.foo
42

我真的推荐这个网站:

http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

对属性函数的很好解释。

您将foo定义为具有getter和setter的属性。

这些getter和setter使用变量self._foo ,因为您是通过以下方式进行编码的:

def _set_foo(self, value):
  self._foo = value

如果您的实现稍有不同,您会遇到问题:

class ClassName(object):
    """
    """    
    def __init__(self,):
        """
        """
        pass

    def _set_foo(self, value):
        self._foo = value

    def _get_foo(self):
        return self._foo

    foo = property(_get_foo, _set_foo)


 a = ClassName()
 print a.foo
 -> AttributeError

 b = ClassName()
 b.foo = 1 # implicitely sets self._foo !
 print b.foo
 >> OK, this is 1

因为它发生,你的确应该设置self.foo__init__ ,因为setter创建self._foo (或者直接在__init__初始化self._foo )。

那么,self.foo和self._foo从何而来? 它在代码中是明确的。 self.foo是一个属性,而self._foo是决定保留该属性值的变量。

self._fooself.foo将有所不同,只不过您已将创建的属性分配给名称foofoo = property(_get_foo, _set_foo)

因此,现在您有两个名称定义为foo ,这是根据_set_foo_get_foo方法定义的属性。 您还定义了名称_foo但这与_set_foo_get_foo以及属性foo中使用的属性相同。

因此,您有两个名字,但只有一个对象。

        foo
        /\
       /  \
_set_foo  _get_foo
       \   /
        \ /
       _foo --> object

注意:对于您使用Python的示例,这是过大的了,除非使用getter和setter方法,否则它们将不需要业务逻辑。 只需使用一个名为foo的属性,如果事实证明您需要在访问该属性时需要一些技巧,将来就可以将其包装在一个属性中而不会影响客户端代码。

将您的代码更改为:

class ClassName(object): 
    def __init__(self, foo, bar):
    self.foo = foo # read-write property
    self.bar = bar # simple attribute

foobar都是可读写的,如果您需要更好的控制,则可以考虑使用属性。

根据您的代码,它“来自” _set_foo。 在您的init中,当您执行self.foo = foo时,它将调用_set_foo(1),该函数将执行self._foo = 1。

如果在_set_foo()中添加打印语句,则可以更清楚地看到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM