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

问题:如何获取Python类中的方法列表?


回答 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

尝试属性__dict__

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

当处理一个类实例时,最好返回一个带有方法引用的列表,而不仅仅是名称¹。如果那是您的目标,以及

  1. 不使用 import
  2. __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

  1. Using no import
  2. 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

如果您的方法是“常规”方法,而不是statimethodclassmethod等等。
我想出了一点技巧-

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__)