如何获取对象的方法和属性的完整列表? [复制]
Posted
技术标签:
【中文标题】如何获取对象的方法和属性的完整列表? [复制]【英文标题】:How to get a complete list of object's methods and attributes? [duplicate] 【发布时间】:2010-09-16 12:02:39 【问题描述】:dir(re.compile(pattern))
不返回模式作为列表的元素之一。即它返回:
['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']
根据手册,它应该包含
对象的属性名称, 其类属性的名称,以及 递归地对其属性 类的基类。
它也说
列表不一定完整。
有没有办法获得完整的列表?我一直认为 dir 返回一个完整的列表,但显然它没有......
另外:有没有办法只列出属性?还是只有方法?
编辑:这实际上是 python 中的一个错误 -> 据说它已在 3.0 分支中修复(可能也在 2.6 中)
【问题讨论】:
使用dir()
或检查模块通常是正确的方法。你是用re
模块作为例子还是你想达到一个特殊的目标?
您确定该模式在编译后实际上保留为数据吗?我的印象是编译模式的目的是生成解析给定模式所必需的有限状态自动机。
@hop 不能被类规避?例如,他们可以在__dir__()
ytpillai:正确,但仅在 Python 3 中。即便如此,问题是这样的类是否属于“一般情况”
【参考方案1】:
对于完整属性列表,简短的回答是:不。问题是属性实际上被定义为getattr
内置函数接受的参数。由于用户可以重新实现__getattr__
,突然允许任何类型的属性,没有可能的通用方法来生成该列表。 dir
函数返回 __dict__
属性中的键,即如果未重新实现 __getattr__
方法,则所有可访问的属性。
对于第二个问题,它并没有真正的意义。实际上,方法是可调用的属性,仅此而已。您可以过滤可调用属性,并使用inspect
模块确定类方法、方法或函数。
【讨论】:
inpect.getmembers(re.compile(pattern)) 也不会产生模式作为成员,所以它可能在内部使用 dir ......这很糟糕! 我也可以使用 callable 来检查它们是否是方法,但这不是重点...重点是我不能相信 dir 甚至可以返回实际上公开可见的属性列表。 . inspect 意味着“至少和 dir() 一样”值得信赖。另一方面,re 是一个非常复杂的模块 你对“公开可见”的定义是什么?如果您的意思是“可以访问”,那么由于给出的原因,这是一个失败的原因。否则,'dir' 总是返回可通过 getattr 的默认实现访问的属性列表。 dir(my_class) 返回与 my_class.__dict__.keys() 不同的内容。前者还输出类的方法,如 init 和 doc【参考方案2】:这就是为什么在 python 2.6 中添加了新的__dir__()
方法
见:
http://docs.python.org/whatsnew/2.6.html#other-language-changes(向下滚动一点) http://bugs.python.org/issue1591665【讨论】:
我收到此错误:>> dir__(pyrenderdoc) Traceback(最近一次调用最后一次):文件“__dir
__() 是对象上的方法,而不是函数 - 请阅读答案中的链接和this
单行打印所有属性及其值:pprint(k:getattr(ojb,k) for k in obj.__dir__())
【参考方案3】:
这里是 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()
的结果似乎相同,而对于旧样式类,@987654329 的主要补充@输出似乎是__class__
属性。)
【讨论】:
【参考方案4】:仅作补充:
dir()
是最强大/基本的工具。 (最推荐)
dir()
以外的解决方案仅提供他们的方式 处理dir()
的输出。
是否列出二级属性,重要的是自己进行筛选,因为有时您可能希望筛选出带有前导下划线__
的内部变量,但有时您可能需要__doc__
doc-string .
__dir__()
和 dir()
返回相同的内容。
__dict__
和 dir()
是不同的。 __dict__
返回不完整的内容。
重要提示:__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)
TypeError:'object'
对象的描述符 __dir__
需要一个参数
PyTorch 的作者将__dir__()
方法修改为需要参数的东西。此修改使dir()
失败。
【讨论】:
【参考方案5】:我就是这样做的,这对于您不断添加属性的简单自定义对象很有用:
给定一个使用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
【讨论】:
Python 3.x 中所有属性的列表: key: value for key, value in obj.__dict__.items() if not key.startswith("__")['_declared_fields'] .keys()以上是关于如何获取对象的方法和属性的完整列表? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
Javascript:如何使用字符串数组获取对象属性? [复制]