我想通过类中的方法进行迭代,或者根据目前的方法不同地处理类或实例对象。我如何获得类方法的列表?
还看到:
方法中的方法如何列出 Python 2.5模块? 循环在 Python / IronPython对象 方法 找到方法 对象有 我怎么看里面 Python对象? 我该怎么做 中对对象进行内省 Python 2. x ? 如何获得 对象的方法和的完整列表 属性? 找出 函数可以从类中获得 实例在python中?
我想通过类中的方法进行迭代,或者根据目前的方法不同地处理类或实例对象。我如何获得类方法的列表?
还看到:
方法中的方法如何列出 Python 2.5模块? 循环在 Python / IronPython对象 方法 找到方法 对象有 我怎么看里面 Python对象? 我该怎么做 中对对象进行内省 Python 2. x ? 如何获得 对象的方法和的完整列表 属性? 找出 函数可以从类中获得 实例在python中?
当前回答
一个示例(列出了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)
...
其他回答
试一试 print(帮助(名称)) 它输出类的方法
你可以使用我创建的函数。
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']
我只是把这个放在那里,因为排名靠前的答案不清楚。
这是一个简单的测试,不常用类基于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提供的数据不完整 检查。Getmembers提供不完整的数据,并提供getattr()无法访问的内部键。 __dict__.keys()提供完整可靠的结果
为什么投票如此错误?我错在哪里?其他答案的得票这么低的人哪里错了?
一个示例(列出了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)
...
有这样一种方法:
[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]
在处理类实例时,也许返回一个包含方法引用的列表,而不是仅仅返回名称¹会更好。如果这是你的目标,还有
使用不导入 从列表中排除私有方法(例如__init__)
这可能会有用。你可能还想确保它是可调用的(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是一个遥远的梦想。
我想我应该有一个单一的测试所有的方法,所以我做了上面的迭代。
尽管我意识到我应该重构代码本身,无论如何都是符合dry的…这可能在未来仍然服务于一个随机的挑剔的灵魂。