Variables starting with underscore for property decorator
我是Python的新手。所以,如果这是一个基本问题,请原谅我。我在网上研究过这个话题,但找不到解释。我用的是Python3.6分布。
我正在尝试为属性创建一个简单的getter和setter。我会带你经历我所犯的错误。
1 2 3 4 5 6 | class Person: def __init__(self,name): self.name=name bob = Person('Bob Smith') print(bob.name) |
这打印了我同意的第一个名字,我没有重写
让我们修改代码以添加属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person: def __init__(self,name): self.name=name @property def name(self): "name property docs" print('fetch...') return self.name bob = Person('Bob Smith') print(bob.name) |
号
一旦我用pycharm编写上述代码,就会得到一个黄色的灯泡图标,说明变量必须是私有的。我不明白理由。
忽略上面的内容,如果我运行上面的代码,我会得到:
1
2
3
4 Traceback (most recent call last): File"C:\..., in run_code
exec(code_obj, self.user_global_ns, self.user_ns) File"<ipython-input-25-62e9a426d2a9>", line 2, in <module>
bob = Person('Bob Smith') File"<ipython-input-24-6c55f4b7326f>", line 4, in __init__
self.name=name AttributeError: can't set attribute
号
现在,我研究了这个主题,发现有两个修复方法(不知道为什么这样做有效):
修正1:将变量
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person: def __init__(self,name): self._name=name #Changed name to _name @property def name(self): "name property docs" print('fetch...') return self._name #Changed name to _name bob = Person('Bob Smith') print(bob.name) |
这很好地工作,因为它正确地打印输出。
修正2:将属性名从
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Person: def __init__(self,name): self.name=name #changed to name @property def _name(self): #Changed to _name "name property docs" print('fetch...') return self.name #changed to name bob = Person('Bob Smith') print(bob.name) |
。
现在,这项工作按预期打印。
作为下一步,我使用decorator创建了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @_name.setter def _name(self,value): "name property setter" print('change...') self.name=value @_name.deleter def _name(self): print('remove') del self.name bob = Person('Bob Smith') print(bob.name) bob.name = 'Bobby Smith' print(bob.name) del bob.name |
问题:我不太清楚为什么python 3.x强制向变量名或方法名添加
根据带有public getter和private setter的python属性,前面和后面带有下划线的python属性有什么区别,以及https://www.python.org/dev/peps/pep-0008/命名约定,下划线前缀对于用户来说是一个弱指标,即该变量是一个私有变量,但是没有额外的机制(通过pyTHON,类似于Java所做的那样来检查或纠正这种行为。
所以,现在最大的问题是,为什么我需要用下划线来处理属性?我相信这些下划线前缀只是为了让用户知道这是一个私有变量。
我正在用卢茨的书来学习Python,上面的例子是从他的书中得到启发的。
让我们看一下代码修复1:
1 2 3 4 5 6 7 8 9 10 11 12 | class Person: def __init__(self,name): self._name=name #Changed name to _name @property def name(self): "name property docs" print('fetch...') return self._name #Changed name to _name bob = Person('Bob Smith') print(bob.name) |
- 定义
self._name = name —这是您的支持字段。 - 您定义了一个方法
def name(self) ,并将其属性为@property 。 - 通过
bob = Person('Bob Smith') 创建类的实例
那你就去做
您的变量称为
如果你定义了:
1 2 3 4 5 | def tata(self): print(self.name) # also no () after self.name bob = Person('Bob Smith') bob.tata() |
号
它还将调用@property方法,因为您可以通过
因此,如果您从
这是纯粹的观察——如果你想知道到底发生了什么,你必须检查