gpt4 book ai didi

python - 为什么 getter/setter 方法必须与原始属性的名称相同?

转载 作者:行者123 更新时间:2023-12-05 01:39:46 27 4
gpt4 key购买 nike

我不明白为什么 getter/setter 方法的名称必须与属性具有相同的名称。

我试过阅读 Aaron Hall 的回答 here , 但我仍然找不到(或错过)关于为什么我们必须使用各自名称的解释。

class Car(object):
def __init__(self, color='blue'):
self.color = color
self.current_model = 'Opel'

@property
def model(self, new_model):
return self.current_model


@model.setter
def model(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model

# model = model.setter(models) but doing this works

@model.getter
def model(self):
return self.current_model

编辑:我感到困惑的是,如果我将我的方法重命名为:

@model.setter
def model_new(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model

然后我尝试运行:

audi = Car()
audi.model = 'BMW' # will get AttributeError: can't set attribute

我预计这不会起作用,因为 getter、setter 和 deleter 方法会创建属性的副本,并且更改方法的名称就像修改不同属性的属性一样。这就像做:models = model.setter(models)。

但我不确定我是否理解正确

最佳答案

函数名称需要相同,因为 @model.setter 不会更新现有属性;它用基于现有属性的新属性替换它。当您将属性方法用作装饰器时,属性的名称是最后装饰的函数的名称。

记住,

@model.setter
def model(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model

大致相当于

def tmp(self, new_model): 
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model

model = model.setter(tmp)

也就是说,由def 语句绑定(bind)的名称(model)改为绑定(bind)到model.setter 的结果。如果您使用不同的名称,那么您已经更改了属性的名称。


最直接的方法是同时提供 getter(以及可选的 setter 和 deleter):

def foo_get(self):
...

def foo_set(self, v):
...

foo = property(foo_get, foo_set)

由于创建属性只需要 getter,您可以单独指定它,然后将旧属性与 setter 组合起来创建一个新属性。

foo = property(foo_get)
foo = foo.setter(foo_set)

装饰器语法允许您跳过显式命名 getter 和 setter:

# Instead of foo = property(foo_get), define a function named foo,
# pass it to property, and rebind the name foo to the new property
@property
def foo(self):
...

# Instead of foo.setter(foo_set), define *another* function named foo,
# pass it too foo.setter, and rebind the name foo to the new, augmented property. Note that this works because Python will evaluate `@foo.setter` to
# get a reference to the bound property method
# before it evaluates the following def statement.
@foo.setter
def foo(self, v):
...

关于python - 为什么 getter/setter 方法必须与原始属性的名称相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57658859/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com