在 __init__() 之后覆盖类方法例如 __setattr__

问题描述

因此,我最近在尝试实现某种 DotDict 时想出了一个拙劣的可憎的类:

  • 启用键值点访问。
  • 接受 defaults Namespace/Dataclass 作为包含认值的额外参数。
  • 在点访问时执行修改get(),通过检查是否可以在 defaults 中找到认值,否则返回 None

此外,该类应在初始化时将其值中找到的任何 dict 递归转换为 Dotdict,并将每个新值转换为 class DotDict(dict): def __init__(self,base_dict=None,defaults=None): self.defaults = defaults if defaults is not None else SimpleNamespace() base_dict = base_dict if base_dict is not None else {} super().__init__(**base_dict) for key,value in base_dict.items(): self[key] = self._convert(value) def __getattr__(self,key): if key in self: return self[key] elif hasattr(self.defaults,key): return getattr(self.defaults,key) else: return None def __setattr__(self,key,value): self[key] = value def __delattr__(self,key): try: del self[key] except KeyError as error: raise AttributeError(error) def _convert(self,element): if isinstance(element,dict): return DotDict( {key: self._convert(value) for key,value in element.items()},defaults=self.defaults,) elif isinstance(element,list): return [self._convert(subelement) for subelement in element] else: return element

外观如下:

default

尽管它可能违背了所有常识和大约十几种最佳实践,但这种方法确实有效 - 除了一个细节:我还没有找到一种方法来分配 de items() 属性而不将其添加到实例的 __setattr__。这是有道理的,因为 __setattr__ 方法会立即被其点访问版本覆盖。

为清晰起见进行了编辑

上面的段落措辞非常糟糕,以至于实际上问错了问题。我知道有几种方法可以在不诉诸类自己的 user2357112 supports Monica 的情况下分配属性,正如 {{1}} 所指出的那样,确实可以解决这个特定问题。

上面描述的代码是为了说明导致我问自己这篇文章的实际问题的过程。现在以全新的眼光阅读整件事让我意识到最初问题的大部分细节充其量是不必要的,并且可能会令人困惑。我会把它留给透明,但如果我要从头开始重写这个问题,那就是:

有没有办法在实例初始化之后覆盖任何方法

解决方法

如果要使用标准的__setattr__,只需使用标准的__setattr__

object.__setattr__(self,'defaults',defaults)

其他选项包括使用 super 通过 super().__setattr__('defaults',defaults) 调用它或使用 self.__dict__ 手动将属性粘贴到 self.__dict__['defaults'] = defaults 中。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...