我想遍历类中的方法,或者根据当前方法不同地处理类或实例对象。如何获得类方法的列表?
另请参阅:
binding工作原理是:stackoverflow.com/a/46041480/1959808
                [f for f in dir(ClassName) if not f.startswith('_')]或仅dir(ClassName)用于一切
                我想遍历类中的方法,或者根据当前方法不同地处理类或实例对象。如何获得类方法的列表?
另请参阅:
binding工作原理是:stackoverflow.com/a/46041480/1959808
                [f for f in dir(ClassName) if not f.startswith('_')]或仅dir(ClassName)用于一切
                Answers:
一个示例(列出了 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)
...inspect.isroutine可能是一个更合适的谓词;inspect.ismethod不适用于所有对象的方法。
                    假设您想知道与列表类关联的所有方法Just Type下面
 print (dir(list))以上将为您提供列表类的所有方法
print([ m for m in dir(my_class) if not m.startswith('__')])
                    您还可以从类型中导入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__和私有方法的信息。
                    import的FunctionType使用一次性拉姆达与type():type(lambda:0)
                    isinstance会比type(y) == FunctionType这里更好。
                    这也适用:
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.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
有这种方法:
[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规范……这在将来仍然可能会成为一个挑剔的灵魂。
我将其保留在那里,因为评分最高的答案尚不清楚。
这是一个简单的测试,不是基于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()提供完整可靠的结果为什么选票如此错误?而我错了?还有哪些人的答案这么低呢?
如果您的方法是“常规”方法,而不是statimethod,classmethod等等。
我想出了一点技巧-
for k, v in your_class.__dict__.items():
    if "function" in str(v):
        print(k)通过相应地改变if条件中的“功能”,可以将其扩展到其他类型的方法。
在python 2.7上测试。
您可以使用以下代码列出python类中的所有方法
dir(className)这将返回该类中所有方法名称的列表
我知道这是一篇旧文章,但是只是编写了此函数,如果有人偶然发现答案,它将留在这里:
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))这只是一个观察。“编码”似乎是字符串对象的一种方法
str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'但是,如果检查str1中的方法,则返回一个空列表
inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []因此,也许我错了,但是问题似乎并不简单。
'a'是一个对象,其类型为str。您可以通过运行看到这一点type('a')。inspect.getmember()具有类型参数,因此您需要调用inspect.getmember(str)以查看期望的内容。
                    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__)