如果我将python getter和setter的值存储在dict中,会出现什么问题?

如果我将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

我使用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像普通的日常属性一样工作,只是每次有人设置或读取它时,它都会执行打印语句:

>>> 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>之外似乎是正确的方法?