代码之家  ›  专栏  ›  技术社区  ›  Bartosz Radaczyński

如何获得对象的方法和属性的完整列表?[副本]

  •  250
  • Bartosz Radaczyński  · 技术社区  · 17 年前
    dir(re.compile(pattern)) 
    

    不将模式作为列表的元素之一返回。也就是说,它返回:

    ['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']
    

    根据手册,它应该包含

    对象的属性名称 其类属性的名称,以及 递归地分析其属性 阶级的基础阶级。

    它还说

    这份清单不一定完整。

    有没有办法得到 完成 列表?我一直认为dir返回一个完整的列表,但显然不是。..

    还有:有没有一种方法可以只列出属性?还是只有方法?

    编辑:这实际上是python中的一个bug->假设它在3.0分支中是固定的(也许在2.6中也是如此)

    5 回复  |  直到 11 年前
        1
  •  145
  •   Jonathan Drake PierreBdR    14 年前

    对于 完成 属性列表,简短的答案是:否。问题是,属性实际上被定义为 getattr 内置功能。因为用户可以重新实现 __getattr__ ,突然允许任何类型的属性,就没有可能的通用方法来生成该列表。这个 dir 函数返回 __dict__ 属性,即所有可访问的属性,如果 __吉塔特__ 方法未重新实现。

    对于第二个问题,这真的没有意义。实际上,方法是可调用的属性,仅此而已。您可以过滤可调用属性,并使用 inspect 模块决定类的方法、方法或函数。

        2
  •  60
  •   Moe    17 年前

    这就是为什么新 __dir__() python 2.6中添加了方法

    参见:

        3
  •  21
  •   wjandrea sebs    7 年前

    以下是对PierreBdR和Moe答案的实用补充:

    • 对于Python>=2.6和 新式班级 , dir() 似乎已经足够了。
    • 旧式课程 ,我们至少可以做什么 standard module 支持制表符补全:除了 dir() ,寻找 __class__ ,然后去它的 __bases__ :

      # code borrowed from the rlcompleter module
      # tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) \n[GCC 4.4.3]' )
      
      # or: from rlcompleter import get_class_members
      def get_class_members(klass):
          ret = dir(klass)
          if hasattr(klass,'__bases__'):
              for base in klass.__bases__:
                  ret = ret + get_class_members(base)
          return ret
      
      
      def uniq( seq ): 
          """ the 'set()' way ( use dict when there's no set ) """
          return list(set(seq))
      
      
      def get_object_attrs( obj ):
          # code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
          ret = dir( obj )
          ## if "__builtins__" in ret:
          ##    ret.remove("__builtins__")
      
          if hasattr( obj, '__class__'):
              ret.append('__class__')
              ret.extend( get_class_members(obj.__class__) )
      
              ret = uniq( ret )
      
          return ret
      

    (为简洁起见,删除了测试代码和输出,但基本上对于新型对象,我们似乎得到了相同的结果 get_object_attrs() 至于 dir() ,对于旧式课程,主要补充 dir() 输出似乎是 __班级__ 属性。)

        4
  •  10
  •   wjandrea sebs    7 年前

    仅作为补充:

    1. dir() 最多 强大/基本的工具。 ( 最推荐 )
    2. 其他解决方案 dir() 仅提供 路上 交易 输出 dir() .

      无论是否列出二级属性,亲自进行筛选都很重要,因为有时您可能想筛选出带有前导下划线的内部变量 __ ,但有时你可能需要 __doc__ doc字符串。

    3. __dir__() dir() 返回相同的内容。
    4. __dict__ dir() 是不同的。 字典 返回不完整的内容。
    5. 重要的 : __dir__() 有时可以由作者出于任何目的用函数、值或类型覆盖。

      以下是一个示例:

      \\...\\torchfun.py in traverse(self, mod, search_attributes)
      445             if prefix in traversed_mod_names:
      446                 continue
      447             names = dir(m)
      448             for name in names:
      449                 obj = getattr(m,name)
      

      类型错误:描述符 __dir__ 属于的 'object' 对象需要一个参数

      PyTorch的作者修改了 __dir__() 方法来处理需要论证的事情。此修改使 dir() 失败。

    6. 如果你想要一个 可信赖的 遍历对象所有属性的方案,请记住每个python标准 可以被覆盖,可能无法保持 ,而且每种惯例都可能不可靠。

        5
  •  6
  •   Brian Burns Yugansh    8 年前

    我是这样做的,对于您不断添加属性的简单自定义对象很有用:

    给定一个用以下方式创建的对象 obj = type("Obj",(object,),{}) ,或简单地:

    class Obj: pass
    obj = Obj()
    

    添加一些属性:

    obj.name = 'gary'
    obj.age = 32
    

    然后,要获得仅具有自定义属性的字典:

    {key: value for key, value in obj.__dict__.items() if not key.startswith("__")}
    
    # {'name': 'gary', 'age': 32}