【问题标题】:`object.__setattr__(self, ..., ...)` instead of `setattr(self, ..., ...)`?`object.__setattr__(self, ..., ...)` 而不是`setattr(self, ..., ...)`?
【发布时间】:2015-10-09 15:01:59
【问题描述】:

以下是werkzeug 库中Local 类的__init__ 方法:

def __init__(self):
    object.__setattr__(self, '__storage__', {})
    object.__setattr__(self, '__ident_func__', get_ident)

我不明白这段代码有两点:

  1. 他们为什么写作

    object.__setattr__(self, '__storage__', {})
    

    而不是简单

    `setattr(self, '__storage__', {})`
    
  2. 如果可以简单地写,他们为什么还要使用__setattr__

    self.__storage__ = {}
    

【问题讨论】:

    标签: python class methods


    【解决方案1】:

    这可确保使用默认的 Python 定义 __setattr__。如果该类已覆盖 __setattr__ 以执行非标准行为,但您仍希望访问原始 __setattr__ 行为,则通常使用它。

    对于 werkzeug,如果您查看 Local 类,您会看到 __setattr__ 的定义如下:

    def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}
    

    不是在对象的字典中设置属性,而是在之前初始化的__storage__ 字典中设置属性。为了完全设置__storage__ 属性(以便以后可以像self.__storage__ 一样访问它),必须使用__setattr__ from object 的原始定义,这就是为什么在构造函数中使用笨拙的符号的原因。

    【讨论】:

    • 我只是补充一点,虽然它在源代码中看起来很尴尬,但它为该类的用户提供了一个很好的界面。
    【解决方案2】:

    他们想显式地使用基本的object.__setattr__ 实现,而不是继承链中其他地方可能被覆盖的方法实例方法。 Local 实现了自己的 __setattr__,因此可以避免这种情况。

    【讨论】:

      【解决方案3】:

      因为同一个类定义了__setattr__,这需要绕过它,因为第一行说self.__ident_func__(),这还行不通。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-05
        • 2011-11-25
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        • 2023-04-01
        • 1970-01-01
        相关资源
        最近更新 更多