【问题标题】:What are the differences amongst Python's "__get*__" and "_del*__" methods?Python 的“__get*__”和“_del*__”方法有什么区别?
【发布时间】:2012-01-28 20:22:49
【问题描述】:

几个月前我刚开始学习 Python,我正在尝试了解不同 __get*__ 方法之间的区别:

__get__
__getattr__
__getattribute__
__getitem___

还有他们的__del*__ 等价物:

__del__
__delattr__
__delete__
__delitem__

它们之间有什么区别?我什么时候应该使用其中一种?大多数__get*__ 方法都有__set*__ 等价物,但没有__setattribute__,是否有特定原因?

【问题讨论】:

  • 文档没有像“水平”那样“并排”列出它们,但它确实将它们全部放在一个页面上,除了{get,set}item 之外的所有内容(其中脱颖而出以item为特色)在两个小部分中垂直相邻。其中一些名称太简洁/相似,但并不像你说的那么糟糕。
  • 是的,大约 20 分钟前我意识到它们实际上都在一页上。对不起——我的错。 但是:我仍然很困惑。我以为我已经阅读了文档,但我仍然无法在特殊方法名称之间做出清晰的定义。

标签: python getter-setter standard-library accessor


【解决方案1】:

您列出的每种方法的文档都可以从documentation index 轻松获得。

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

__get____set____del__ 是描述符

“简而言之,描述符是一种自定义引用模型上的属性时发生的情况的方法。” [official doc link]

他们已经很好地解释了,所以这里有一些参考:

__getattr__, __getattribute__, __setattr__, __delattr__

是否可以定义方法来自定义类实例的属性访问(x.name 的使用、分配或删除)的含义。 [official doc link]

示例 1:

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

f = Foo()
f.x    # -> 10
f.bar   # -> 'bar'

示例 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'

__getitem__, __setitem__, __delitem__

可以定义实现容器对象的方法。[official doc link]

例子:

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

我希望这足以让您大致了解一下。

【讨论】:

  • (1) 在我找到您的答案之前大约 25 分钟,我意识到这些实际上都记录在一个页面上。对不起,我原来的问题中的那个错误。 (2) 谢谢!! Marty Alchin 的文章写得非常好。他们澄清了一些我没有得到的巨大信息——__get____set__ 应该定义在属性中,而不是在类中!我仍然认为我原来帖子中的所有方法都可以使用更多可区分的名称,但我突然觉得不那么不知所措了。谢谢你。 ☺
  • @Zearin:有一篇关于Python Attributes and Methods 的好文章也许你会感兴趣。 (固定链接)
  • @RikPoggi 你实际上并没有说,为什么__get__ 我们有__getattr__ 或反之亦然。你提到的两个答案都是一样的
  • 感谢示例和文档链接。很高兴明确提及我们如何在# comment 中从AttributeError__getattr__,也许还有,与__setattr____getattribute__ 不同,__getattr__ 仅在未定义名称时调用,或通过AttributeError。至少这是我的理解。
猜你喜欢
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2019-05-16
相关资源
最近更新 更多