在使用属性装饰器之后,python对象有两个非常相似的属性(foo.bar和foo.\u bar)。可以吗?
因此,我正在重构我的代码,使之更具Pythonic风格——特别是我已经了解到,使用显式getter和setter应该被@property取代。我的情况是,我有一个在使用属性装饰器之后,python对象有两个非常相似的属性(foo.bar和foo.\u bar)。可以吗?,python,python-3.x,properties,decorator,Python,Python 3.x,Properties,Decorator,因此,我正在重构我的代码,使之更具Pythonic风格——特别是我已经了解到,使用显式getter和setter应该被@property取代。我的情况是,我有一个示例类,它具有初始化的条属性(初始化帮助我知道用户设置了条): 运行foo=Example()。另外,当我运行foo.bar='changedValue'或foo.\u bar='changedValue'时,它们都会更改为'changedValue'。为什么有两个属性?这不是多余的吗?我想我理解为什么会有\u bar属性-我在@bar
示例
类,它具有初始化的条
属性(初始化帮助我知道用户设置了条
):
运行
foo=Example()。另外,当我运行foo.bar='changedValue'
或foo.\u bar='changedValue'
时,它们都会更改为'changedValue'
。为什么有两个属性?这不是多余的吗?我想我理解为什么会有\u bar
属性-我在@bar.setter
中添加了它,但是为什么会有bar
作为字符串属性呢?bar
不应该是一种导致bar
的方法吗?这很好。请记住,bar
不是实例属性,而是类属性。由于它具有type属性
,因此它实现了描述符协议,以便从实例访问时其行为不同。如果e
是Example
的实例,则e.bar
不会提供分配给Example.bar
的属性的实例;它给出了Example.bar.\uuuu-get\uuuu(e,Example)
(在本例中,它恰好是Example.bar.fget(e)
,其中fget
是由@property
修饰的原始函数)
简言之,每个实例都有自己的\u bar
属性,但对该属性的访问是通过class属性Example.bar
来实现的
如果您编写这个最小(而且足够,因为在本例中,getter和setter都不需要def
语句)定义,那么更容易看出bar
是一个类属性
class Example:
def __init__(self):
self.bar = "initalizedValue"
bar = property(lambda self: self._bar, lambda self, b: setattr(self, '_bar', b))
或者更一般地说
def bar_getter(self):
return self._bar
def bar_setter(self, b):
self._bar = b
class Example:
def __init__(self):
self.bar = "initalizedValue"
bar = property(bar_getter, bar_setter)
很好。请记住,bar
不是实例属性,而是类属性。由于它具有type属性
,因此它实现了描述符协议,以便从实例访问时其行为不同。如果e
是Example
的实例,则e.bar
不会提供分配给Example.bar
的属性的实例;它给出了Example.bar.\uuuu-get\uuuu(e,Example)
(在本例中,它恰好是Example.bar.fget(e)
,其中fget
是由@property
修饰的原始函数)
简言之,每个实例都有自己的\u bar
属性,但对该属性的访问是通过class属性Example.bar
来实现的
如果您编写这个最小(而且足够,因为在本例中,getter和setter都不需要def
语句)定义,那么更容易看出bar
是一个类属性
class Example:
def __init__(self):
self.bar = "initalizedValue"
bar = property(lambda self: self._bar, lambda self, b: setattr(self, '_bar', b))
或者更一般地说
def bar_getter(self):
return self._bar
def bar_setter(self, b):
self._bar = b
class Example:
def __init__(self):
self.bar = "initalizedValue"
bar = property(bar_getter, bar_setter)