gpt4 book ai didi

python - 获取所有可能的类属性的完整列表

转载 作者:太空狗 更新时间:2023-10-30 02:58:47 27 4
gpt4 key购买 nike

有没有办法,给定一个简单的类,输出它所有可能的属性?标准属性,如 __class____doc__ and special read only attributes__mro__, __bases__ 等。通常,所有 都存在属性?

考虑类最简单的情况:

class myClass:
pass

dir()vars()inspect.getmembers() 都排除了某些内置 属性.最完整的列表是通过使用 myClass.__dir__(MyClass) 提供的,它在添加内置属性时排除了 MyClass 的用户定义属性,例如:

In [3]: set(MyClass.__dir__(MyClass)) - set(dir(MyClass))
Out[3]:
{'__abstractmethods__', '__base__', '__bases__',
'__basicsize__', '__call__', '__dictoffset__',
'__flags__', '__instancecheck__', '__itemsize__',
'__mro__', '__name__', '__prepare__', '__qualname__',
'__subclasscheck__', '__subclasses__', '__text_signature__',
'__weakrefoffset__', 'mro'}

根据添加的类似问题之一,这是不可能的。如果目前仍然不可能,那么“隐藏”某些 属性(如 __bases__(从标准调用到 dir()、vars() 和 inspect 而不是像 __name__ 这样的?


类似问题:

最佳答案

dir()基本上是一种方便的方法,它不应该返回所有内容,它基本上所做的是递归地返回在类及其基类的字典中找到的所有内容。

PyPy's implementation of dir()很容易理解:

def dir(*args):
...
elif isinstance(obj, (types.TypeType, types.ClassType)):
# Don't look at __class__, as metaclass methods would be confusing.
return sorted(_classdir(obj))
...

def _classdir(klass):
"""Return a set of the accessible attributes of class/type klass.

This includes all attributes of klass and all of the base classes
recursively.
"""
names = set()
ns = getattr(klass, '__dict__', None)
if ns is not None:
names.update(ns)
bases = getattr(klass, '__bases__', None)
if bases is not None:
# Note that since we are only interested in the keys, the order
# we merge classes is unimportant
for base in bases:
names.update(_classdir(base))
return names

由于每个类基本上都继承自 object,您会看到包含一些 dunder 方法,因为它们实际上是 object 字典的一部分:

>>> class A(object):
pass
...
>>> set(dir(A)) == set(list(object.__dict__) + list(A.__dict__))
True

Now what about __bases__ and other missing items?

首先 object 本身就是一个实例,well it's bit of a mess actually :

>>> isinstance(type, object)
True
>>> isinstance(object, type)
True
>>> issubclass(type, object)
True
>>> issubclass(object, type)
False
>>> type.mro(object)
[<type 'object'>]
>>> type.mro(type)
[<type 'type'>, <type 'object'>]

因此,所有的属性,如 __bases____ge__ 等实际上都是 type 的一部分:

>>> list(type.__dict__)
['__module__', '__abstractmethods__', '__getattribute__', '__weakrefoffset__', '__dict__', '__lt__', '__init__', '__setattr__', '__subclasses__', '__new__', '__base__', '__mro__', 'mro', '__dictoffset__', '__call__', '__itemsize__', '__ne__', '__instancecheck__', '__subclasscheck__', '__gt__', '__name__', '__eq__', '__basicsize__', '__bases__', '__flags__', '__doc__', '__delattr__', '__le__', '__repr__', '__hash__', '__ge__']

因此,当我们执行 A.__bases__ 时,我们实际上是在查找 descriptor on type of A ,即 type:

>>> A.__bases__
(<type 'object'>,)
>>> type(A).__dict__['__bases__'].__get__(A, type)
(<type 'object'>,)

因此,由于 Atype 的实例,因此这些方法不是其自身字典的一部分,而是其类型字典的一部分。

>> class A(object):
... spam = 'eggs'
...
>>> a = A()
>>> a.foo = 100
>>> a.bar = 200
>>> a.__dict__
{'foo': 100, 'bar': 200}
>>> A.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, 'spam': 'eggs'})

由于 typeobject 的子类,dir()type 的调用将包含一些来自 object 的项目:

>>> set(dir(type)) - set(type.__dict__)
set(['__reduce_ex__', '__str__', '__format__', '__reduce__', '__class__', '__subclasshook__', '__sizeof__'])

关于python - 获取所有可能的类属性的完整列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33087797/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com