Get complete list of all possible Class Attributes
对于一个简单的类,有没有一种方法可以为它输出所有可能的属性?标准属性如
考虑到一个类最简单的情况:
1 2 | class myClass: pass |
1 2 3 4 5 6 7 8 | 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'} |
根据添加的一个类似问题,这是不可能的。如果目前仍然不可能,那么"隐藏"某些属性(如
如何获得对象方法和属性的完整列表?
This is the most likely to be labeled as a duplicate, but, it is old and mostly regarding
Python 2.x . The accepted answer is that there isn't a way but it was provided in 08'. The most recent answer in 12' suggestsdir() for new style classes.打印python类的所有属性
Similar title, different content.
获取类的属性
Offers
dir() andinspect solutions.获取python中的所有对象属性?
Again, proposing
dir() .
Pypy对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
由于每个类基本上都继承自
1 2 3 4 5 | >>> class A(object): pass ... >>> set(dir(A)) == set(list(object.__dict__) + list(A.__dict__)) True |
Now what about
__bases__ and other missing items?
首先,
1 2 3 4 5 6 7 8 9 10 11 12 | >>> 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'>] |
因此,
1 2 | >>> 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__'] |
因此,当我们进行
1 2 3 4 | >>> A.__bases__ (<type 'object'>,) >>> type(A).__dict__['__bases__'].__get__(A, type) (<type 'object'>,) |
因此,由于
1 2 3 4 5 6 7 8 9 10 | >> class A(object): ... spam = 'eggs' ... >>> a = A() >>> a.foo = 100 >>> a.bar = 200 >>> a.__dict__ {'foo': 100, 'bar': 200} >>> A.__dict__ dict_proxy({'__dict__': , '__module__': '__main__', '__weakref__': , '__doc__': None, 'spam': 'eggs'}) |
由于
1 2 | >>> set(dir(type)) - set(type.__dict__) set(['__reduce_ex__', '__str__', '__format__', '__reduce__', '__class__', '__subclasshook__', '__sizeof__']) |