我正在使用python getter和setter,但我不喜欢使用虚拟变量来存储值。例如,python中的一个简单的getter和setter可能是这样定义的:
class Foo(object):
def get_bar(self):
print('getting bar')
return self._bar
def set_bar(self,variable):
print('setting bar')
self._bar = variable
bar = property(get_bar,set_bar)
这使得bar像普通的日常属性一样工作,除了每次有人设置或读取它时它都会执行print语句:
>>> my_fave_foo = Foo()
>>> my_fave_foo.bar = 5
setting bar
>>> print(my_fave_foo.bar)
getting bar
5
直到,也就是说,未来我决定使用内省来查看我最喜欢的Foo的属性:
>>> print(my_fave_foo.__dict__)
{'_bar': 5}
这让我感到困惑,尽管我知道这不是一个大问题,所以我这样做了 -
class Foo(object):
def get_bar(self):
print('getting bar')
return self.__dict__['bar']
def set_bar(self,variable):
print('setting bar')
self.__dict__['bar'] = variable
bar = property(get_bar,set_bar)
哪个有预期的行为
>>> my_fave_foo = Foo()
>>> my_fave_foo.bar = 5
setting bar
>>> my_fave_foo.bar
getting bar
5
>>> print(my_fave_foo.__dict__)
{'bar': 5}
我的问题是:为什么这是一个坏主意?其他人,例如回答这个问题:
What's the Pythonic way to use Getters and Setters?
推荐下划线公约。我觉得我做的事情有问题,但我不知道它是什么。所以请告诉我,这会出什么问题?
我会很快注意到这是一个玩具示例,在我的实际代码中,有一个真正的理由是使用getter和setter。
我正在使用python getter和setter,但我不喜欢使用虚拟变量来存储值。
为什么不?值必须存在于某个地方,并且它在逻辑上是一个实例变量。 Python没有公共/私有。
直到,也就是说,未来我决定使用内省来查看我最喜欢的Foo的属性:
那不要那样做。 We are all responsible users。
所以我[将实例变量命名为与属性相同]。为什么这是一个坏主意?
现在,您依赖于属性优先于字典项以了解此代码的事实。如果字典项和属性具有不同的名称,那么对于内省用户来说,将调用一些特殊行为是显而易见的。
这会出什么问题?
您的代码具有误导性,下次您查看时会让您感到困惑。
如果你愿意,你可以使用self.__bar
作为内部状态,将名称变为self._Foo__bar
,这是对子类引起的冲突的防御。见The Python Tutorial / Private Variables。