Python 'vars(self)`的响应缺少属性
我已经定义了一个类,需要将它的大部分属性交给函数进行处理。所以我想,与其制造一个巨大的混乱,把它们全部命名,不如自己处理一些东西,交给一本包含所有属性和值的好词典 但是我发现几乎所有的属性都丢失了 我已停止调试器中的代码,并运行了一些测试:Python 'vars(self)`的响应缺少属性,python,python-3.x,slots,Python,Python 3.x,Slots,我已经定义了一个类,需要将它的大部分属性交给函数进行处理。所以我想,与其制造一个巨大的混乱,把它们全部命名,不如自己处理一些东西,交给一本包含所有属性和值的好词典 但是我发现几乎所有的属性都丢失了 我已停止调试器中的代码,并运行了一些测试: >>> vars(self).keys() dict_keys(['date_expire', 'tokenUrl', 'settings', 'requestSession', 'ttlDays']) 这些是5个。虽然我预计大约有20个
>>> vars(self).keys()
dict_keys(['date_expire', 'tokenUrl', 'settings', 'requestSession', 'ttlDays'])
这些是5个。虽然我预计大约有20个属性,但根据我的类在这里的定义:
__slots__ = (
'token', # the invitation-token to load the username with
'request', # the http-request which is currently being serviced
'inhibit',
#... many lines deleted
'templateObj', # an instance of myMail.template.Template
'emailBody', # what will be sent via SMTP
'warningsAr', # messages for the client
)
我可以在调试器窗口中看到属性,并可以直接访问它们。我已经阅读了,但找不到任何开关。有趣的是,dirself显示所有属性名称,但不显示任何值。所以我不能用这个。但我认为vars和dir应该显示相同的值
我想我会建立一个解决方案,但我真的想了解这里发生了什么。您能提供帮助吗?vars将返回实例的uu dict_u_u_u______名称空间。但是_插槽_属性不存储在_dict__名称空间中。这就是他们的全部观点
相反,Python在实例内存结构中为每个值创建专用指针槽,并使用类对象上的描述符检索这些值。因此inst.attr被转换为typeinst.attr.\uu获取\uu inst以返回该值
从:
_u slots_uu声明接受一系列实例变量,并在每个实例中保留足够的空间来保存每个变量的值。由于没有为每个实例创建_dict,因此节省了空间
[……]
__插槽通过为每个变量名创建描述符在类级别实现。
请注意,无论如何都有一个uuu dict uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。正确使用_插槽_应导致实例没有_dict__名称空间;他们的目标是通过避免dict所需的稀疏哈希表(这可能会浪费空间)来减少内存
再次从文档中:
当从没有uuu插槽的类继承时,该类的uu dict_uu属性将始终是可访问的,因此子类中的uuu插槽定义没有意义。
[……]
______________________________________。因此,子类将有一个_dict _,除非它们还定义了_slots _,它必须只包含任何附加slots的名称。
如果要列出所有可用的实例字段,则必须包括类中的_slots______)枚举,而不仅仅是查看变量:
有道理。我不知道为什么dir的行为如此不同,给了我所有的变量。非常感谢。认可的!stamp@Chris:dir是一种完全不同的野兽,请参见
from itertools import chain
def slots_for_instance(inst):
def _slots_for_class(c):
slots = getattr(c, '__slots__', ())
if isinstance(slots, str):
# __slots__ can be a string naming a single attribute
slots = (slots,)
return set(chain.from_iterable(
getattr(_slots_for_class(c) for c in type(inst).__mro__))