简体   繁体   English

在Python的自定义类上挂钩__dict__?

[英]Hook __dict__ on custom class in python?

I want to execute a method before anything is read from my class in a transparent way (so that the caller does not have to make the call before writing to the class instance). 我想在以透明方式从类中读取任何内容之前执行一个方法(这样,调用方不必在写入类实例之前进行调用)。 Hooking __getattr__ is easy, but I cannot figure out how to hook __dict__ since object does not have the __dict__ attribute. 挂钩__getattr__很容易,但是我无法弄清楚如何挂钩__dict__因为object没有__dict__属性。

super().__dict__ gives 'super' object has no attribute '__dict__' super().__dict__给出'super' object has no attribute '__dict__'

Maybe there is something else I should do to accomplish this? 也许我还需要做些其他的事情来完成这个任务?

You don't want to use the class's __dict__ at all, in most cases (it's shared between all instances, remember), and you almost certainly never want the supertype's __dict__ , given that (as you have just discovered) it needn't necessarily have one. 在大多数情况下,您根本不想使用该类的__dict__ (记住,它在所有实例之间共享),并且几乎可以肯定不希望使用超类的__dict__ ,因为(您刚刚发现的)它不一定有一个。

>>> class One:
...     def __init__(self):
...         print(super().__dict__)
...
>>> one = One()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
AttributeError: 'super' object has no attribute '__dict__'

As you report, object has no __dict__ of its own. 在您报告时, object本身没有__dict__ That's because object instances, being built-in types, aren't allowed to acquire additional attributes so object is hard-coded to disallow it: 这是因为object实例是内置类型,不允许获取其他属性,因此object被硬编码以禁止使用:

>>> object().someattr = "hello"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'someattr'
>>>

When you create a subclass of object in your program, however, its instances can take arbitrary attributes, which are stored in the instance __dict__ . 但是,在程序中创建对象的子类时,其实例可以采用任意属性,这些属性存储在实例__dict__

>>> class Two:
...     def __init__(self):
...         print(self.__dict__)
...
>>> two = Two()
{}
>>> two.someattr = "hello"
>>> two.__dict__
{'someattr': 'hello'}
>>>

Note that the inheritance mechanism makes the Two class appear to have all of the attributes of object . 注意,继承机制使Two类看起来具有object所有属性。 The dir() function lets you look at an object's namespace as modified by inheritance: dir()函数使您可以查看通过继承修改的对象的名称空间:

>>> dir(Two)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__', '__weakref__']

Picking a random attribute, we can verify that the methods present on Two are actually inherited from object : 选择一个随机属性,我们可以验证Two上存在的方法实际上是从object继承的:

>>> Two.__delattr__ is object.__delattr__
True
>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM