官方文档says:
如果对象具有名为
__dir__()
的方法,则将调用此方法 并且必须返回属性列表。这允许对象 实现自定义__getattr__()
或__getattribute__()
功能 自定义dir()
报告其属性的方式。
如果自定义__dir__
已实施,则由另一个功能inspect.getmembers()
返回的结果也会受到影响。
例如:
class С(object):
__slots__ = ['atr']
def __dir__(self):
return ['nothing']
def method(self):
pass
def __init__(self):
self.atr = 'string'
c = C()
print dir(f) #If we try this - well get ['nothing'] returned by custom __dir__()
print inspect.getmembers(f) #Here we get []
print f.__dict__ #And here - exception will be raised because of __slots__
在这种情况下,如何获取对象名称列表?
答案 0 :(得分:4)
inspect.getmembers()
使用像__dir__()
这样的dir()
吗?以下是inspect.getmembers()
的源代码,因此我们可以看到它的确在做什么:
def getmembers(object, predicate=None):
"""Return all members of an object as (name, value) pairs sorted by name.
Optionally, only return members that satisfy a given predicate."""
results = []
for key in dir(object):
try:
value = getattr(object, key)
except AttributeError:
continue
if not predicate or predicate(value):
results.append((key, value))
results.sort()
return results
从此我们看到 使用dir()
,只是过滤了一些结果。
__dir__()
获取属性?根据this answer,不可能始终获得完整的属性列表,但我们仍然可以在某些情况下获得它们/得到足够的有用。
来自the docs:
如果对象未提供
__dir__()
,则该函数会尝试最佳 从对象的__dict__
属性收集信息,如果 定义,并从其类型对象。结果列表不是 必须完成,并且当对象具有时可能不准确 自定义__getattr__()
。
因此,如果您没有使用__slots__
,您可以查看对象的__dict__
(以及它的类型对象),以获得dir()
通常会给您的相同信息。因此,就像使用dir()
一样,您必须使用更严格的方法来获取元类方法。
如果您使用的是__slots__
,那么获取类属性在某种程度上会更简单一些。是的,没有字典,但有__slots__
本身,其中包含所有属性的名称。例如,将print c.__slots__
添加到示例代码中会产生['atr']
。 (同样,需要更严格的方法来获取超类的属性。)
根据用例,您可能需要不同的解决方案,但如果您只想轻松找到方法,则只需使用内置help()
。
dir()
以上是上述部分内容的替代方法:要获取忽略用户定义的dir()
方法的__dir__
版本,您只需dir()
__dir__
和{{1}}删除引用{{1}}方法的部分。
答案 1 :(得分:0)
正如Matthew在另一个答案中所指出的那样,getmembers
显然会返回属于实际属性的dir
结果的子集。
>>> class C:
>>> def foo(self):
>>> pass
>>> def __dir__(self):
>>> return ['test']
>>>
>>> import inspect
>>> c = C()
>>> dir(c)
['test']
>>> inspect.getmembers(c)
[]