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是不同的,不是吗?
编辑:问题是我仍然不明白属性是做什么的。给我一些时间。
答案 0 :(得分:2)
Docs for property
解释它应该如何使用。这些行之间没有区别:
self.foo = foo # read-write property
和
a.foo = 3
你也不应该手动调用setter和getter。
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
答案 1 :(得分:2)
答案 2 :(得分:1)
您将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__
,因为设置者创建了self._foo
。 (或者直接在self._foo
初始化__init__
)。
那么,self.foo和self._foo来自哪里?它在代码中是明确的。 self.foo是一个属性,self._foo是你决定保留该属性值的变量。
答案 3 :(得分:1)
self._foo
和self.foo
会有所不同,只是您已将自己创建的媒体资源分配给名称foo
:foo = 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
foo
和bar
都是读写,如果你需要更好的控制,你可以考虑使用属性。
答案 4 :(得分:0)
根据你的代码,它“来自”_set_foo。在你的init中,当你执行self.foo = foo时,调用_set_foo(1),执行self._foo = 1.
如果在_set_foo()中添加print语句,则可以更清楚地看到这一点。