在python3中,getter和setter是方法,而getter和seter是属性



如果我的理解是正确的,那么属性用于getter和setter。用@property修饰getter或setter可以让我们修改、使用它等,就好像它是一个属性一样,所以与其做MyClass.foo()之类的事情,不如做MyClass.foo。我读到这样做是为了让代码更加干净并提高可读性。使用@property装饰getter和setter还有其他原因吗?我在某个地方读到,当想要进行更改时,最好使用属性来避免破坏代码,我不明白为什么当你有不是属性的getter和setter方法时,你会需要属性。

正如您在评论中链接的文章所说:

Python属性的主要优点是,它们允许您将属性作为公共API的一部分公开。如果你需要更改底层实现,然后可以打开属性在任何时候进入一处房产都不会有太多痛苦。

这里的关键字是";暴露你的属性";。

假设您有一个具有实例属性weight的类Object,您最初将其作为API的一部分公开,并允许最终用户自由修改:

class Object:
def __init__(self):
self.weight = 0

但您后来发现,一些最终用户正在用负值设置weight,这应该被视为无效:

o = Object()
o.weight = -1

因此,您可以通过添加getter和setter方法来修改类,并使用_前缀重命名原始属性以隐藏它:

class Object:
def __init__(self):
self._weight = 0
def get_weight(self):
return self._weight
def set_weight(self, value):
assert value >= 0 # validate that weight is not negative
self._weight = value

但是,您需要对您公开的API进行更改,并告诉最终用户在他们的终端上进行相应的更改:

o = Object()
o.set_weight(-1) # now this will be properly disallowed and raise an exception

这对您(必须更改公开的API文档(和最终用户(必须更改他们使用API的方式(来说都很麻烦。

现在,通过将weight属性转换为属性:

class Object:
def __init__(self):
self._weight = 0
@property
def weight(self):
return self._weight
@weight.setter
def weight(self, value):
assert value >= 0 # validate that weight is not negative
self._weight = value

最终用户可以继续使用他们现有的代码:

o = Object()
o.weight = -1 # raises an exception

他们现在可以获得对weight进行适当验证的好处,而不需要知道底层实现已经从属性变为setter方法。

没错,@property类似于getter/setter,但在调用时表现略有不同。

当使用普通的getter/setter时,例如:

class Foo:
def getFoo():
# ...
def setFoo(foo):
# ...
my_foo = Foo()
# print foo value
print(my_foo.getFoo())
# set foo to 100
my_foo.setFoo(100)

正如你所看到的,这有点难看。所以Python有@property装饰器来解决这个问题:

class Foo:
def __init__(self):
self.inner_foo = 1
@property
def foo(self):
return self.inner_foo
@foo.setter
def foo(self, value):
self.inner_foo = value
foo = Foo()
print(foo.foo)
foo.foo = 100
print(foo.foo)

现在,foo属性在使用时就像一个普通属性一样,使您的代码更加简洁。

相关内容

  • 没有找到相关文章

最新更新