获取所有可能的类属性的完整列表 [英] Get complete list of all possible Class Attributes

查看:185
本文介绍了获取所有可能的类属性的完整列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个简单的Class,是否有一种方法可以输出所有可能的属性? __class____doc__ 等标准属性特殊只读属性,例如__mro____bases__等.通常, 所有 是否显示属性?

Is there a way, given a simple Class, to output all the possible attributes for it? Standard attributes like __class__ and __doc__ and special read only attributes like __mro__, __bases__ et al. Generally, all present attributes?

考虑类的最简单情况:

class myClass:
    pass

dir()vars()inspect.getmembers()均排除某些builtin属性.使用myClass.__dir__(MyClass)可以提供最完整的列表,该列表在添加内置属性时会排除用户定义的MyClass属性,例如:

The dir(), vars() and inspect.getmembers() all exclude certain builtin attributes. The most complete list is offered by using myClass.__dir__(MyClass) which, while adding built in attributes, excludes user defined attributes of MyClass, for example:

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__的那些))背后的原理是什么?

According to one of the added similar questions, this is not possible. If presently still not possible, what is the rationale behind "hiding" certain attributes like __bases__ (from standard calls to dir(), vars() & inspect and not ones like __name__?

这是最有可能被标记为重复的内容, 但是 ,它很旧,并且大多与Python 2.x有关.可以接受的答案是,没有办法,但是它是在08'中提供的. 12'中的最新答案建议dir()用于新样式类.

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' suggests dir() for new style classes.

  • 打印Python类的所有属性

    相似的标题,不同的内容.

    Similar title, different content.

  • 获取类的属性

    提供dir()inspect解决方案.

  • 获取Python中的所有对象属性?

    同样,提出dir().

  • 推荐答案

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

    dir() is basically a convenience method, it is not supposed to return everything, what it basically does is that it recursively returns everything found in the dictionary of a class and its bases.

    PyPy's implementation of dir() is quite easy to understand:

    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词典的一部分:

    As each class basically inherits from object you will see some dunder methods included because they are actually part of object's dictionary:

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


    现在__bases__和其他遗失物品怎么办?

    Now what about __bases__ and other missing items?

    首先object本身是某物的一个实例,嗯,实际上有点混乱:

    First of all object itself is an instance of something, 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的一部分:

    So, all of the attributes like __bases__, __ge__ etc are actually part of 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__时,实际上是在查找

    Hence when we do A.__bases__ we are actually looking up a descriptor on type of A, i.e type:

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

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

    So, as A is an instance of type these methods are not part of its own dictionary but its type's dictionary.

    >> 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的子类,对typedir()调用将包含object中的某些项目:

    As, type is a subclass of object, the dir() call on type will contain some items from object:

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

    这篇关于获取所有可能的类属性的完整列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆