如何在Python类中获取方法列表?

25个回答

441

一个例子(列出optparse.OptionParser类的方法):

>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
 ('add_option', <unbound method OptionParser.add_option>),
 ('add_option_group', <unbound method OptionParser.add_option_group>),
 ('add_options', <unbound method OptionParser.add_options>),
 ('check_values', <unbound method OptionParser.check_values>),
 ('destroy', <unbound method OptionParser.destroy>),
 ('disable_interspersed_args',
  <unbound method OptionParser.disable_interspersed_args>),
 ('enable_interspersed_args',
  <unbound method OptionParser.enable_interspersed_args>),
 ('error', <unbound method OptionParser.error>),
 ('exit', <unbound method OptionParser.exit>),
 ('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
 ...
 ]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...

请注意getmembers返回一个由2元组组成的列表,第一个元素是成员的名称,第二个元素是其值。

你也可以将实例传递给getmembers

>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...

5
完美,谓词部分很关键,否则你得到的就是带有额外元数据的__dict__一样的东西。谢谢。 - Purrell
2
这会产生一个包含该类中所有方法的列表吗(包括从其他类继承的方法),还是只列出在该类中明确定义的方法? - Anderson Green
16
inspect.isroutine可能是更合适的谓词; inspect.ismethod不适用于所有对象的方法。 - Gavin S. Yancey
3
在Python 3.7中,至少这个不起作用,你必须实例化该类。 - kederrac
5
Python 3 中不存在未绑定方法。在 3.7 版本中,您可以使用以下代码获取 OptionsParser 类的所有函数成员:inspect.getmembers(OptionsParser, predicate=inspect.isfunction) - codeape
显示剩余5条评论

292

有一个dir(theobject)方法可以列出您的对象的所有字段和方法(作为元组),还有inspect模块(如codeape所写)可以列出带有其文档的字段和方法(在""中)。

因为在Python中可以调用任何东西(甚至是字段),我不确定是否有内置函数仅列出方法。您可能需要尝试通过dir获取的对象是否callable


216

不使用外部库的Python 3.x答案

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]

dunder-excluded结果:

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]

这太棒了,而且也适用于MicroPython! - leosok
1
很酷,但它不包括使用@property@property.setter修饰的getter-setter方法。 - leonard vertighel

62

假设你想知道与列表类相关联的所有方法,请键入以下命令

 print (dir(list))

以上将为您提供所有列表类的方法


5
print([ m for m in dir(my_class) if not m.startswith('__')]) - Evhz

38

尝试使用属性 __dict__


21
我认为你的意思是__dict__。但那列出的是实例的属性,而不是方法。 - me_and
3
那对我也没用。经过查阅Markdown语法,我认为我指的是__dict__。 - me_and
4
你可能正在使用"self.dict"或者更通用地,调用实例版本的__dict__。然而,类也有一个__dict__,应该显示类方法 :) - Seaux

32

你还可以从types模块导入FunctionType,并使用class.__dict__测试它:

from types import FunctionType

class Foo:
    def bar(self): pass
    def baz(self): pass

def methods(cls):
    return [x for x, y in cls.__dict__.items() if type(y) == FunctionType]

methods(Foo)  # ['bar', 'baz']

这对我很有效。我在列表推导式的末尾添加了 and not x.startswith('_'),以便忽略 __init__ 和私有方法。 - Christopher Pearson
2
你可以使用一个临时的lambda表达式和type()来摆脱FunctionType的导入:type(lambda:0) - Tersosauros
在这里使用isinstancetype(y) == FunctionType更好。 - Gloweye
对于可调用函数,您可以将开头的 x 替换为 y(使用 [y for x, y in cls.__dict__.items() if type(y) == FunctionType])。 - matan h

28
您可以使用以下代码列出Python类中的所有方法。
dir(className)
这将返回类中所有方法名称的列表。

3
这也报告非方法类属性。 - chepner

15

请注意,您需要考虑是否希望将继承的(但未被覆盖)基类方法包含在结果中。 dir()inspect.getmembers()操作确实包括基类方法,但使用__dict__属性则不包括。


9
如果您的方法是“普通”方法而不是staticmethodclassmethod
我想到了一个小技巧 -
for k, v in your_class.__dict__.items():
    if "function" in str(v):
        print(k)

这可以通过相应地更改“function”在if条件中来扩展到其他类型的方法。
在Python 2.7和Python 3.5中进行了测试。

3
不确定为什么这个被踩了……它确实解决了我遇到的问题。 - redspidermkv
4
如果使用 types.FunctionTypes 判断变量 v 是否为函数类型会更简洁。你还可以扩展这个方法来检查是否为 classmethodstaticmethod 类型的属性。 - chepner
chepner 建议中有错别字。请使用 if isinstance(v, types.FunctionType) - srgsanky

9

尝试使用 print(help(类名)) 命令,可以打印出该类的方法。


太棒了!我学到了新东西。不幸的是,这并没有列出类的staticmethod:我想知道是否可能。 - mike rodent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接