我是Python新手。所以,如果这是一个基本问题,请原谅我。我在互联网和SO上研究了这个主题,但我找不到解释。我正在使用 Anaconda 3.6 发行版。
我正在尝试为属性创建一个简单的 getter 和 setter。我将引导您解决我遇到的错误。
class Person:
def __init__(self,name):
self.name=name
bob = Person('Bob Smith')
print(bob.name)
这打印了我同意我没有覆盖的第一个名字print
or getattribute
方法。而且,这里没有房产。这是为了测试基本代码是否有效。
让我们修改代码以添加属性:
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 中编写上述代码时,我会看到一个黄色灯泡图标,表明该变量必须是私有的。我不明白其中的道理。
忽略上面的内容,如果我运行上面的代码,我会得到:
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
现在,我研究了这个主题,发现有两个修复(不知道为什么会这样):
Fix #1:改变变量name
to _name
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)
这很有效,因为它可以正确打印输出。
Fix #2:将属性名称更改为 fromname(self)
to _name(self)
并恢复变量名称_name
to name
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)
现在,该作品按预期打印。
作为下一步,我创建了setter
, getter
, and deleter
使用装饰器的属性。它们遵循如上所述的类似命名约定,即任一前缀_
变量名或方法名:
@_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 强制添加_
变量名或方法名。
As per 具有公共 getter 和私有 setter 的 Python 属性 https://stackoverflow.com/questions/42137210/python-property-with-public-getter-and-private-setter, python属性前后带下划线有什么区别 https://stackoverflow.com/questions/14671487/what-is-the-difference-in-python-attributes-with-underscore-in-front-and-back, and https://www.python.org/dev/peps/pep-0008/#naming-conventions https://www.python.org/dev/peps/pep-0008/#naming-conventions,下划线前缀对用户来说是一个弱指示,表明该变量是私有变量,但没有额外的机制(通过 Python,类似于 Java 所做的)来检查或纠正这种行为。
所以,眼前的一个大问题是,为什么我需要使用下划线来处理属性?我相信这些下划线前缀只是为了让用户知道这是一个私有变量。
我正在使用Lutz的书来学习Python,上面的例子是受到他的书的启发。