示例(列出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返回一个二元组列表。第一项是成员的名称,第二项是值。

你也可以将一个实例传递给getmembers:

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

尝试属性__dict__

dir(theobject)方法列出对象的所有字段和方法(作为元组),inspect模块(作为codeape编写)列出字段和方法及其文档(在"""中)。

因为在Python中可能调用所有内容(甚至字段),所以我不确定是否有一个内置函数只列出方法。你可能想试试你通过dir得到的对象是不是可调用的

注意,您需要考虑是否希望结果中包含继承(但不重写)基类的方法。dir()inspect.getmembers()操作包含基类方法,但使用__dict__属性不包含。

def find_defining_class(obj, meth_name):
for ty in type(obj).mro():
if meth_name in ty.__dict__:
return ty

所以

print find_defining_class(car, 'speedometer')

Python第210页

我知道这是一篇旧文章,但只是写了这个函数,并将它留在这里,以防有人跌跌撞撞地寻找答案:

def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True):


def acceptMethod(tup):
#internal function that analyzes the tuples returned by getmembers tup[1] is the
#actual member object
is_method = inspect.ismethod(tup[1])
if is_method:
bound_to = tup[1].im_self
internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__'
if internal and exclude_internal:
include = False
else:
include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only)
else:
include = False
return include
#uses filter to return results according to internal function and arguments
return filter(acceptMethod,inspect.getmembers(the_class))

你也可以从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']

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("__")]

如果你的方法是“常规的”;方法,而不是staticmethodclassmethod等 有一个小hack我想出了-

for k, v in your_class.__dict__.items():
if "function" in str(v):
print(k)

这可以通过改变“function”扩展到其他类型的方法;对应的if条件。
在Python 2.7和Python 3.5中测试

说你想知道所有与list类相关的方法 只需键入以下

 print (dir(list))

上面给出了list类的所有方法

这也是可行的:

mymodule.py:

def foo(x):
return 'foo'
def bar():
return 'bar'

在另一个文件中:

import inspect
import mymodule
method_list = [ func[0] for func in inspect.getmembers(mymodule, predicate=inspect.isroutine) if callable(getattr(mymodule, func[0])) ]

输出:

(“foo”、“酒吧”)

来自Python文档:

inspect.isroutine(object)

如果对象是用户定义的或内置的函数或方法,则返回true。

class CPerson:
def __init__(self, age):
self._age = age


def run(self):
pass


@property
def age(self): return self._age


@staticmethod
def my_static_method(): print("Life is short, you need Python")


@classmethod
def say(cls, msg): return msg




test_class = CPerson
# print(dir(test_class))  # list all the fields and methods of your object
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ == 'function' and not name.startswith('__')])
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ != 'function' and not name.startswith('__')])


输出

[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]

如果你只想列出一个python类的方法

import numpy as np
print(np.random.__all__)
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]

给出一个相同的列表

methods = inspect.getmembers(o, predicate=inspect.ismethod)

所做的事。

这只是一种观察。"encode"似乎是一个字符串对象的方法

str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'

但是,如果在str1中检查方法,则返回一个空列表

inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []

所以,也许我错了,但问题似乎并不简单。

有这样一种方法:

[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]

在处理类实例时,也许返回一个包含方法引用的列表,而不仅仅是名称¹会更好。如果这是你的目标,还有

  1. 没有使用import
  2. 从列表中排除私有方法(例如__init__)

这可能会有用。你可能还想确保它是callable(getattr(obj, m)),因为dir返回obj中的所有属性,而不仅仅是方法。

简而言之,对于一个班级来说

class Ghost:
def boo(self, who):
return f'Who you gonna call? {who}'

我们可以检查实例检索

>>> g = Ghost()
>>> methods = [getattr(g, m) for m in dir(g) if not m.startswith('__')]
>>> print(methods)
[<bound method Ghost.boo of <__main__.Ghost object at ...>>]

所以你可以马上调用它:

>>> for method in methods:
...     print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS

¹一个用例:

我将此用于单元测试。有一个类,其中所有方法都执行相同过程的变体——这导致了冗长的测试,每个方法与其他方法之间只有细微的差别。是一个遥远的梦想。

我想我应该有一个单一的测试所有的方法,所以我做了上面的迭代。

尽管我意识到我应该重构代码本身以兼容dry…这可能在未来仍然服务于一个随机的挑剔的灵魂。

我只是把它放在那里,因为排名靠前的答案并不清楚

这是一个简单的测试,不常用类基于Enum。

# -*- coding: utf-8 -*-
import sys, inspect
from enum import Enum


class my_enum(Enum):
"""Enum base class my_enum"""
M_ONE = -1
ZERO = 0
ONE = 1
TWO = 2
THREE = 3


def is_natural(self):
return (self.value > 0)
def is_negative(self):
return (self.value < 0)


def is_clean_name(name):
return not name.startswith('_') and not name.endswith('_')
def clean_names(lst):
return [ n for n in lst if is_clean_name(n) ]
def get_items(cls,lst):
try:
res = [ getattr(cls,n) for n in lst ]
except Exception as e:
res = (Exception, type(e), e)
pass
return res




print( sys.version )


dir_res = clean_names( dir(my_enum) )
inspect_res = clean_names( [ x[0] for x in inspect.getmembers(my_enum) ] )
dict_res = clean_names( my_enum.__dict__.keys() )


print( '## names ##' )
print( dir_res )
print( inspect_res )
print( dict_res )


print( '## items ##' )
print( get_items(my_enum,dir_res) )
print( get_items(my_enum,inspect_res) )
print( get_items(my_enum,dict_res) )

这是输出结果。

3.7.7 (default, Mar 10 2020, 13:18:53)
[GCC 9.2.1 20200306]
## names ##
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO']
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO', 'name', 'value']
['is_natural', 'is_negative', 'M_ONE', 'ZERO', 'ONE', 'TWO', 'THREE']
## items ##
[<my_enum.M_ONE: -1>, <my_enum.ONE: 1>, <my_enum.THREE: 3>, <my_enum.TWO: 2>, <my_enum.ZERO: 0>]
(<class 'Exception'>, <class 'AttributeError'>, AttributeError('name'))
[<function my_enum.is_natural at 0xb78a1fa4>, <function my_enum.is_negative at 0xb78ae854>, <my_enum.M_ONE: -1>, <my_enum.ZERO: 0>, <my_enum.ONE: 1>, <my_enum.TWO: 2>, <my_enum.THREE: 3>]

所以我们有:

  • dir提供不完整的数据
  • inspect.getmembers提供不完整的数据,并提供getattr()无法访问的内部键
  • __dict__.keys()提供结果完整可靠

为什么投票如此错误?我错在哪里?其他答案的得票这么低的人哪里错了?

可以使用以下代码列出python类中的所有方法

dir(className)

这将返回类中所有方法名称的列表

要生成一个方法列表,请将方法名称放在一个列表中,不使用通常的括号。删除名称并附加圆括号,这将调用该方法。

    def methodA():
print("@ MethodA")


def methodB():
print("@ methodB")


a = []
a.append(methodA)
a.append(methodB)
for item in a:
item()

你可以使用我创建的函数。

def method_finder(classname):


non_magic_class = []


class_methods = dir(classname)


for m in class_methods:


if m.startswith('__'):


continue


else:


non_magic_class.append(m)


return non_magic_class








method_finder(list)

输出:

['append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
< p >试 print(help(ClassName)) 它输出

类的方法

以上这些方法对我都没用。

我在编写pytests时遇到过这个问题。

我找到的唯一解决办法是:

1-创建另一个目录,把我所有的。py文件放在那里

2-为我的pytests创建一个单独的目录,然后导入我感兴趣的类

这允许我在类中获得最新的方法——你可以更改方法名,然后使用print(dir(class))来确认它。

使用检查。Ismethod, dir和getattr

 import inspect
class ClassWithMethods:
    

def method1(self):
print('method1')
def method2(self):
print('method2')


obj=ClassWithMethods()


method_names = [attr for attr in dir(obj) if inspect.ismethod(getattr(obj,attr))


print(method_names)

输出:

[[('method1', <bound method ClassWithMethods.method1 of <__main__.ClassWithMethods object at 0x00000266779AF388>>), ('method2', <bound method ClassWithMethods.method2 of <__main__.ClassWithMethods object at 0x00000266779AF388>>)]]

就像这样

pprint.pprint([x for x in dir(list) if not x.startswith("_")])

对于我的用例,我需要区分类方法、静态方法、属性和实例方法。inspect模块有点混淆这个问题(特别是类方法和实例方法),所以我根据这个SO问题的注释使用了vars。基本要点是使用vars获取类的__dict__属性,然后根据各种isinstance检查进行筛选。对于实例方法,我检查它是callable而不是类方法。一个警告:这种方法使用__ABC0(或__ABC2)不能与__slots__一起工作。使用Python 3.6.9(因为它是我作为解释器使用的Docker映像):

class MethodAnalyzer:


class_under_test = None


@classmethod
def get_static_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, staticmethod)
}
return {}


@classmethod
def get_class_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, classmethod)
}
return {}


@classmethod
def get_instance_methods(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if callable(v) and not isinstance(v, classmethod)
}
return {}


@classmethod
def get_properties(cls):
if cls.class_under_test:
return {
k for k, v in vars(cls.class_under_test).items()
if isinstance(v, property)
}
return {}

为了查看它的运行情况,我创建了这个小测试类:

class Foo:


@staticmethod
def bar(baz):
print(baz)


@property
def bleep(self):
return 'bloop'


@classmethod
def bork(cls):
return cls.__name__


def flank(self):
return 'on your six'

那时:

MethodAnalyzer.class_under_test = Foo
print(MethodAnalyzer.get_instance_methods())
print(MethodAnalyzer.get_class_methods())
print(MethodAnalyzer.get_static_methods())
print(MethodAnalyzer.get_properties())

的输出

{'flank'}
{'bork'}
{'bar'}
{'bleep'}

在这个例子中,我放弃了实际的方法,但如果你需要保留它们,你可以使用字典理解式而不是集合理解式:

{
k, v for k, v in vars(cls.class_under_test).items()
if callable(v) and not isinstance(v, classmethod)
}