关于Introspection :查找Python对象的方法

Finding what methods a Python object has

对于任何类型的python对象,是否有一种简单的方法来获取这个对象拥有的所有方法的列表?

或者,

如果这不可能,是否至少有一种简单的方法来检查它是否有一个特定的方法,而不是简单地检查在调用方法时是否发生错误?


似乎您可以使用此代码,将"object"替换为您感兴趣的对象:

1
2
object_methods = [method_name for method_name in dir(object)
                  if callable(getattr(object, method_name))]

我在这个地方发现的。希望这能提供更多的细节!


您可以使用内置的dir()函数来获取模块具有的所有属性的列表。在命令行中试试这个,看看它是如何工作的。

1
2
>>> import moduleName
>>> dir(moduleName)

此外,还可以使用hasattr(module_name,"attr_name")函数来确定模块是否具有特定属性。

有关更多信息,请参阅《Python自省指南》。


最简单的方法是使用dir(objectname)。它将显示该对象可用的所有方法。酷把戏。


检查是否有特殊方法:

1
hasattr(object,"method")


我相信你想要的是这样的:

a list of attributes from an object

在我看来,内置功能dir()可以为您完成这项工作。从python shell上的help(dir)输出中获取:

dir(...)

1
dir([object]) -> list of strings

If called without an argument, return the names in the current scope.

Else, return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it.

If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:

  • for a module object: the module's attributes.
  • for a class object: its attributes, and recursively the attributes of its bases.
  • for any other object: its attributes, its class's attributes, and
    recursively the attributes of its class's base classes.

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type"help","copyright","credits" or"license" for more information.

>>> a ="I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
'translate', 'upper', 'zfill']

在我检查您的问题时,我决定用更好的格式来演示我的思路,即dir()的输出。

dir_attributes.py(python 2.7.6)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output."""

__author__ ="ivanleoncz"

obj ="I am a string."
count = 0

print"
Object Data: %s"
% obj
print"Object Type: %s
"
% type(obj)

for method in dir(obj):
    # the comma at the end of the print, makes it printing
    # in the same line, 4 times (count)
    print"| {0: <20}".format(method),
    count += 1
    if count == 4:
        count = 0
        print

dir_attributes.py(python 3.4.3)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output."""

__author__ ="ivanleoncz"

obj ="I am a string."
count = 0

print("
Object Data:"
, obj)
print("Object Type:", type(obj),"
"
)

for method in dir(obj):
    # the end="" at the end of the print statement,
    # makes it printing in the same line, 4 times (count)
    print("|    {:20}".format(method), end="")
    count += 1
    if count == 4:
        count = 0
        print("")

希望我有所贡献:)。


除了更直接的答案,如果我不提到伊普生,我会很不小心。点击"tab"查看可用的方法和自动完成功能。

一旦你找到了一个方法,尝试:

1
help(object.method)

查看pydocs、方法签名等。

啊…雷普尔


如果您特别需要方法,那么应该使用inspect.ismethod。

对于方法名称:

1
2
import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]

对于方法本身:

1
2
import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]

有时,inspect.isroutine也很有用(对于内置的、C扩展、没有"绑定"编译器指令的cython)。


打开bash shell(ubuntu上的ctrl+alt+t)。启动里面的python3 shell。创建对象以观察的方法。只需在其后面加一个点,然后按两次"tab",就会看到如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 user@note:~$ python3
 Python 3.4.3 (default, Nov 17 2016, 01:08:31)
 [GCC 4.8.4] on linux
 Type"help","copyright","credits" or"license" for more information.
 >>> import readline
 >>> readline.parse_and_bind("tab: complete")
 >>> s ="Any object. Now it's a string"
 >>> s. # here tab should be pressed twice
 s.__add__(           s.__rmod__(          s.istitle(
 s.__class__(         s.__rmul__(          s.isupper(
 s.__contains__(      s.__setattr__(       s.join(
 s.__delattr__(       s.__sizeof__(        s.ljust(
 s.__dir__(           s.__str__(           s.lower(
 s.__doc__            s.__subclasshook__(  s.lstrip(
 s.__eq__(            s.capitalize(        s.maketrans(
 s.__format__(        s.casefold(          s.partition(
 s.__ge__(            s.center(            s.replace(
 s.__getattribute__(  s.count(             s.rfind(
 s.__getitem__(       s.encode(            s.rindex(
 s.__getnewargs__(    s.endswith(          s.rjust(
 s.__gt__(            s.expandtabs(        s.rpartition(
 s.__hash__(          s.find(              s.rsplit(
 s.__init__(          s.format(            s.rstrip(
 s.__iter__(          s.format_map(        s.split(
 s.__le__(            s.index(             s.splitlines(
 s.__len__(           s.isalnum(           s.startswith(
 s.__lt__(            s.isalpha(           s.strip(
 s.__mod__(           s.isdecimal(         s.swapcase(
 s.__mul__(           s.isdigit(           s.title(
 s.__ne__(            s.isidentifier(      s.translate(
 s.__new__(           s.islower(           s.upper(
 s.__reduce__(        s.isnumeric(         s.zfill(
 s.__reduce_ex__(     s.isprintable(      
 s.__repr__(          s.isspace(

这里指出的所有方法的问题是,您不能确定某个方法不存在。

在python中,您可以通过__getattr____getattribute__截获点调用,从而可以"在运行时"创建方法。

例:

1
2
3
4
5
class MoreMethod(object):
    def some_method(self, x):
        return x
    def __getattr__(self, *args):
        return lambda x: x*2

如果执行它,可以调用对象字典中不存在的方法…

1
2
3
4
5
6
7
>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10

这就是为什么在Python中使用请求宽恕比使用许可范例更容易的原因。


获取任何对象方法列表的最简单方法是使用help()命令。

1
%help(object)

它将列出与该对象关联的所有可用/重要方法。

例如:

1
help(str)

没有可靠的方法列出所有对象的方法。dir(object)通常是有用的,但在某些情况下,它可能不会列出所有的方法。根据dir()文档:"使用参数,尝试返回该对象的有效属性列表。"

如前所述,可以通过callable(getattr(object, method))来检查方法是否存在。


可以创建一个getAttrs函数,该函数将返回对象的可调用属性名。

1
2
3
4
def getAttrs(object):
  return filter(lambda m: callable(getattr(object, m)), dir(object))

print getAttrs('Foo bar'.split(' '))

那会回来

1
2
3
4
5
6
7
8
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
 '__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__',
 '__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__',
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
 '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',
 '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
 'remove', 'reverse', 'sort']

...is there at least an easy way to check if it has a particular method other than simply checking if an error occurs when the method is called

虽然"请求宽恕比允许更容易"当然是Python式的方式,但你可能正在寻找的是:

1
2
3
4
d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
    d.get('foo')
# OUT: 'bar'

为了在整个模块中搜索特定的方法

1
2
3
4
for method in dir(module) :
  if"keyword_of_methode" in method :
   print(method, end="
"
)

以列表为对象

1
obj = []

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

你得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']