问题:如何获取Python类中的方法列表?
我想遍历类中的方法,或者根据当前方法不同地处理类或实例对象。如何获得类方法的列表?
另请参阅:
I want to iterate through the methods in a class, or handle class or instance objects differently based on the methods present. How do I get a list of class methods?
Also see:
回答 0
一个示例(列出了 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)
...
An example (listing the methods of the optparse.OptionParser
class):
>>> 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)
...
Notice that getmembers
returns a list of 2-tuples. The first item is the name of the member, the second item is the value.
You can also pass an instance to getmembers
:
>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...
回答 1
有 dir(theobject)
方法可以列出对象的所有字段和方法(以元组的形式),而检查模块(以codeape编写方式)可以列出带有其文档的字段和方法(在““”中)。
因为所有内容(甚至字段)都可能在Python中调用,所以我不确定是否有内置函数仅列出方法。您可能想尝试一下该对象你打通dir
是调用与否。
There is the dir(theobject)
method to list all the fields and methods of your object (as a tuple) and the inspect module (as codeape write) to list the fields and methods with their doc (in “””).
Because everything (even fields) might be called in Python, I’m not sure there is a built-in function to list only methods. You might want to try if the object you get through dir
is callable or not.
回答 2
没有外部库的Python 3.x答案
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]
dunder排除的结果:
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]
Python 3.x answer without external libraries
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]
dunder-excluded result:
method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]
回答 3
假设您想知道与列表类关联的所有方法Just Type下面
print (dir(list))
以上将为您提供列表类的所有方法
Say you want to know all methods associated with list class
Just Type The following
print (dir(list))
Above will give you all methods of list class
回答 4
Try the property __dict__
.
回答 5
您还可以从类型中导入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']
you can also import the FunctionType from types and test it with the 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']
回答 6
请注意,您需要考虑是否要从基类中继承(但不重写)的方法包含在结果中。在dir()
和inspect.getmembers()
操作做包括基类的方法,但使用的__dict__
属性没有。
Note that you need to consider whether you want methods from base classes which are inherited (but not overridden) included in the result. The dir()
and inspect.getmembers()
operations do include base class methods, but use of the __dict__
attribute does not.
回答 7
这也适用:
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', 'bar']
从python文档中:
inspect.isroutine(对象)
Return true if the object is a user-defined or built-in function or method.
This also works:
mymodule.py
def foo(x)
return 'foo'
def bar()
return 'bar'
In another file
import inspect
import mymodule
method_list = [ func[0] for func in inspect.getmembers(mymodule, predicate=inspect.isroutine) if callable(getattr(mymodule, func[0])) ]
output:
['foo', 'bar']
From the python docs:
inspect.isroutine(object)
Return true if the object is a user-defined or built-in function or method.
回答 8
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')
Think Python页面210
def find_defining_class(obj, meth_name):
for ty in type(obj).mro():
if meth_name in ty.__dict__:
return ty
So
print find_defining_class(car, 'speedometer')
Think Python page 210
回答 9
有这种方法:
[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]
当处理一个类实例时,最好返回一个带有方法引用的列表,而不仅仅是名称¹。如果那是您的目标,以及
- 不使用
import
__init__
从列表中排除私有方法(例如)
它可能有用。简而言之,对于像
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是一个遥不可及的梦想。
认为我应该对所有方法进行一次测试,因此我进行了上述迭代。
尽管我意识到我反而应该将代码本身重构为符合DRY规范……这在将来仍然可能会成为一个挑剔的灵魂。
There’s this approach:
[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]
When dealing with a class instance, perhaps it’d be better to return a list with the method references instead of just names¹. If that’s your goal, as well as
- Using no
import
- Excluding private methods (e.g.
__init__
) from the list
It may be of use. In a nutshell, for a class like
class Ghost:
def boo(self, who):
return f'Who you gonna call? {who}'
We could check instance retrieval with
>>> 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 ...>>]
So you can call it right away:
>>> for method in methods:
... print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS
¹ An use case:
I used this for unit testing. Had a class where all methods performed variations of the same process – which led to lengthy tests, each only a tweak away from the others. DRY was a far away dream.
Thought I should have a single test for all methods, so I made the above iteration.
Although I realized I should instead refactor the code itself to be DRY-compliant anyway… this may still serve a random nitpicky soul in the future.
回答 10
我将其保留在那里,因为评分最高的答案尚不清楚。
这是一个简单的测试,不是基于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()
提供完整可靠的结果
为什么选票如此错误?而我错了?还有哪些人的答案这么低呢?
I just keep this there, because top rated answers are not clear.
This is simple test with not usual class based on 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) )
And this is output results.
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>]
So what we have:
dir
provide not complete data
inspect.getmembers
provide not complete data and provide internal keys that are not accessible with getattr()
__dict__.keys()
provide complete and reliable result
Why are votes so erroneous? And where i’m wrong? And where wrong other people which answers have so low votes?
回答 11
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]
给出与
methods = inspect.getmembers(o, predicate=inspect.ismethod)
做。
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]
gives an identical list as
methods = inspect.getmembers(o, predicate=inspect.ismethod)
does.
回答 12
如果您的方法是“常规”方法,而不是statimethod
,classmethod
等等。
我想出了一点技巧-
for k, v in your_class.__dict__.items():
if "function" in str(v):
print(k)
通过相应地改变if
条件中的“功能”,可以将其扩展到其他类型的方法。
在python 2.7上测试。
If your method is a “regular” method and not a statimethod
, classmethod
etc.
There is a little hack I came up with –
for k, v in your_class.__dict__.items():
if "function" in str(v):
print(k)
This can be extended to other type of methods by changing “function” in the if
condition correspondingly.
Tested on python 2.7.
回答 13
您可以使用以下代码列出python类中的所有方法
dir(className)
这将返回该类中所有方法名称的列表
You can list all methods in a python class by using the following code
dir(className)
This will return a list of all the names of the methods in the class
回答 14
我知道这是一篇旧文章,但是只是编写了此函数,如果有人偶然发现答案,它将留在这里:
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))
I know this is an old post, but just wrote this function and will leave it here is case someone stumbles looking for an answer:
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))
回答 15
这只是一个观察。“编码”似乎是字符串对象的一种方法
str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'
但是,如果检查str1中的方法,则返回一个空列表
inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []
因此,也许我错了,但是问题似乎并不简单。
This is just an observation. “encode” seems to be a method for string objects
str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'
However, if str1 is inspected for methods, an empty list is returned
inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []
So, maybe I am wrong, but the issue seems to be not simple.
回答 16
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>)]
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('__')])
output
[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]
回答 17
如果您只想列出python类的方法
import numpy as np
print(np.random.__all__)
If you want to list only methods of a python class
import numpy as np
print(np.random.__all__)