Python中@property与@property.getter的区别

6
我正在编写一个Python类,并使用@property装饰器为该类创建属性。
在文档中,我没有找到有关此装饰器的详细信息,但从Stack Overflow和Python linter的说明中可以了解到:使用property装饰器创建的属性可以采用以下格式:定义、getter、setter、deleter,如下所示:
@property
def name(self):
    return self.__name

@name.getter
def name(self):
    return self.__name

@name.setter
def name(self, value):
    self.__name=value

@name.deleter
def name(self):
    del self.__name

我不完全确定第一个块的用途。它内部的代码与 getter 函数完全相同。

第一个块是干什么用的?它与 getter 块有何不同,如果没有,我可以删除其中之一吗?


4
你在哪里看到需要使用 @name.getter?实际上你不需要它,而且它也没有在文档中提到。 - DeepSpace
1
不需要getter部分。@property部分充当getter。 - Klaus D.
@DeepSpace 就像我说的,我只是在周围看到过。当我输入 @name. 时,VSCode会在下拉菜单中给我选项,而像这个问题这样的随机问题中有 .getter。 - Nat Riddle
1个回答

13

您的代码是一样的,因为@name.getter的代码与@property的代码相同。

@property是必需的,因为它定义了属性。

如果您尝试:

class MyClass:
    @name.getter
    def name(self):
        return self.__name

您将会收到错误信息:
Traceback (most recent call last):
  File "/path/to/my/code/prop.py", line 1, in <module>
    class MyClass:
  File "/path/to/my/code/prop.py", line 3, in MyClass
    @name.getter
NameError: name 'name' is not defined

因此,在创建属性时,您始终从以下内容开始:
@property
def name(self):
    return self.__name

这将创建属性name,并且还会创建该属性的getter。您可以在此处查看:

class MyClass:
    @property
    def name(self):
        return self.__name

print(MyClass.name)    # Note: we didn't create any objects
print(MyClass.name.getter)

输出结果将是:
<property object at 0x10beee050>
<built-in method getter of property object at 0x10beee050>

如果添加了getter,这将覆盖原始的getter
在您的情况下,两个getter是相同的,因此没有更改。但是尝试更改代码,使新的getter不同:
class MyClass:
    @property
    def name(self):  # property and original getter
        print('This one will never get called')
        return self.__name 

    @name.getter
    def name(self):  # redefined getter
        return 'hello '+self.__name

现在这个类有一个新的getter,如果你创建一个对象obj并使用obj.name,那么新的getter将被调用,而不是原来的。


1
非常感谢您详细并且格式良好的解释! - Nat Riddle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接