Python的"__get*__"和"_del*__"方法有什么区别?

Zea*_*rin 25 python accessor standard-library getter-setter

几个月前我刚刚开始学习Python,我试图理解不同__get*__方法之间的差异:

__get__
__getattr__
__getattribute__
__getitem___
Run Code Online (Sandbox Code Playgroud)

他们的__del*__等价物:

__del__
__delattr__
__delete__
__delitem__
Run Code Online (Sandbox Code Playgroud)

这些有什么区别?我什么时候应该使用另一个?是否有一个特定的原因,为什么大多数__get*__方法都有__set*__等价物,但没有__setattribute__

Rik*_*ggi 34

您可以从文档索引轻松访问列出的每种方法的文档.

无论如何,这可能是一个小扩展参考:

__get__,__set__并且__del__是描述符

"简而言之,描述符是一种自定义在模型上引用属性时会发生什么的方法." [官方文档链接]

他们周围都有很好的解释,所以这里有一些参考:

__getattr__,__getattribute__,__setattr__,__delattr__

是否可以定义x.name 方法来自定义类实例的属性访问(使用,赋值或删除)的含义.[官方文档链接]

例1:

class Foo:
    def __init__(self):
        self.x = 10
    def __getattr__(self, name):
        return name

f = Foo()
f.x    # -> 10
f.bar   # -> 'bar'
Run Code Online (Sandbox Code Playgroud)

例2:

class Foo:
    def __init__(self):
        self.x = 10
    def __getattr__(self,name):
        return name
    def __getattribute__(self, name):
        if name == 'bar':
            raise AttributeError
        return 'getattribute'

f = Foo()
f.x    # -> 'getattribute'
f.baz    # -> 'getattribute'
f.bar    # -> 'bar'
Run Code Online (Sandbox Code Playgroud)

__getitem__,__setitem__,__delitem__

是否可以定义实现容器对象的方法. [官方文档链接]

例:

class MyColors:
    def __init__(self):
        self._colors = {'yellow': 1, 'red': 2, 'blue': 3}
    def __getitem__(self, name):
        return self._colors.get(name, 100)

colors = MyColors()
colors['yellow']   # -> 1
colors['brown']    # -> 100
Run Code Online (Sandbox Code Playgroud)

我希望这足以给你一个大致的想法.

  • @RikPoggi 你实际上不是在说,当我们有 `__getattr__` 或反之亦然时,为什么要使用 `__get__`。你提到的答案都是一样的 (2认同)