如果我将python getter和setter的值存储在dict中,会出现什么问题?
我使用python的getter和setter,但我不喜欢使用伪变量来存储值。例如,python中一个简单的getter和setter可以这样定义:如果我将python getter和setter的值存储在dict中,会出现什么问题?,python,getter-setter,magic-methods,Python,Getter Setter,Magic Methods,我使用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._ba
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像普通的日常属性一样工作,只是每次有人设置或读取它时,它都会执行打印语句:
>>> my_fave_foo = Foo()
>>> my_fave_foo.bar = 5
setting bar
>>> print(my_fave_foo.bar)
getting bar
5
直到,也就是说,future me决定使用内省来查看我最喜欢的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}
我的问题是:为什么这是个坏主意?其他人,例如在回答这个问题时:
建议使用下划线约定。我觉得我所做的有些不对劲,但我不知道是什么。所以请告诉我,这会出什么问题?
我会很快注意到,这是一个玩具示例,在我的实际代码中,使用getter和setter有一个真正的原因
我使用python的getter和setter,但我不喜欢使用伪变量来存储值
为什么不呢?该值必须位于某个位置,并且在逻辑上是一个实例变量。Python没有public/private
直到,也就是说,future me决定使用内省来查看我最喜欢的Foo的属性:
>>> print(my_fave_foo.__dict__)
{'_bar': 5}
那就别那么做
因此我[将实例变量命名为与属性相同]。为什么这是个坏主意
现在,为了理解这段代码,您依赖于属性优先于字典项这一事实。如果字典项和属性具有不同的名称,那么内省用户显然会调用某些特殊行为
这会出什么问题
您的代码具有误导性,下次查看时会使您感到困惑
如果愿意,可以使用
self.\uuuu bar
作为内部状态,这会将名称更改为self.\ufoo\uu bar
,这是防止子类引起冲突的一种保护措施。请参阅。如果没有所有的getter/setter,您就不能简单地使用self.bar
吗?我不会确切地将在构造函数中对类进行变异称为“简单”的示例…您的缩进有点过了。。。您是否在\uuuu init\uuuu
中执行setattr
?通常,这在类级别完成一次,而不是每个实例。向getter和setter添加打印。您将看到,一旦执行my_fave\u boo.bar=5
,实例名称空间现在有一个名为bar
的局部变量引用整数,并且不再调用getter和setter。@tdelaney,我是在\uuu init\uuu
中执行的-将语法更改为bar=property(…,…)
在\uuuuu init\uuuuu>之外似乎是正确的方法?