如何动态获取 Python 类实例中的方法?

103 阅读1分钟

在 Python 中,我们经常会遇到需要动态获取类实例中的方法的情况。例如,我们可能想根据用户输入的不同值来调用不同的方法。或者,我们可能想从其他模块或函数中调用一个类中的方法,但我们不知道该类的名称或方法的名称。

2、解决方案

Python 中有许多方法可以动态获取类实例中的方法。其中一种方法是使用 inspect 模块。

inspect 模块提供了一系列函数来检查和操纵 Python 对象。其中一个函数是 getmembers(),它可以返回一个对象的所有成员的列表。

以下代码展示了如何使用 inspect 模块来获取类实例中的方法:

import inspect

class A(object):
    def methodA(self, intA=1):
        pass

    def methodB(self, strB):
        pass

a = A()

print(inspect.getmembers(a))

输出结果:

[('__class__', <class '__main__.A'>),
 ('__delattr__', <method-wrapper '__delattr__' of A object at 0xb77d48ac>),
 ('__dict__', {}),
 ('__doc__', None),
 ('__getattribute__',
  <method-wrapper '__getattribute__' of A object at 0xb77d48ac>),
 ('__hash__', <method-wrapper '__hash__' of A object at 0xb77d48ac>),
 ('__init__', <method-wrapper '__init__' of A object at 0xb77d48ac>),
 ('__module__', '__main__'),
 ('__new__', <built-in method __new__ of type object at 0x8146220>),
 ('__reduce__', <built-in method __reduce__ of A object at 0xb77d48ac>),
 ('__reduce_ex__', <built-in method __reduce_ex__ of A object at 0xb77d48ac>),
 ('__repr__', <method-wrapper '__repr__' of A object at 0xb77d48ac>),
 ('__setattr__', <method-wrapper '__setattr__' of A object at 0xb77d48ac>),
 ('__str__', <method-wrapper '__str__' of A object at 0xb77d48ac>),
 ('__weakref__', None),
 ('methodA', <bound method A.methodA of <__main__.A object at 0xb77d48ac>>),
 ('methodB', <bound method A.methodB of <__main__.A object at 0xb77d48ac>>)]

从输出结果中,我们可以看到类实例 a 中有 methodA()methodB() 两个方法。

另一种方法是使用 getattr() 函数。getattr() 函数可以获取对象的属性或方法。以下代码展示了如何使用 getattr() 函数来获取类实例中的方法:

class A(object):
    def methodA(self, intA=1):
        pass

    def methodB(self, strB):
        pass

a = A()

print(getattr(a, 'methodA'))
print(getattr(a, 'methodB'))

输出结果:

<bound method A.methodA of <__main__.A object at 0xb77d48ac>>
<bound method A.methodB of <__main__.A object at 0xb77d48ac>>

从输出结果中,我们可以看到类实例 a 中有 methodA()methodB() 两个方法。

3、代码例子

import inspect

class A(object):
    def methodA(self, intA=1):
        pass

    def methodB(self, strB):
        pass

a = A()

print(inspect.getmembers(a))

输出结果:

[('__class__', <class '__main__.A'>),
 ('__delattr__', <method-wrapper '__delattr__' of A object at 0xb77d48ac>),
 ('__dict__', {}),
 ('__doc__', None),
 ('__getattribute__',
  <method-wrapper '__getattribute__' of A object at 0xb77d48ac>),
 ('__hash__', <method-wrapper '__hash__' of A object at 0xb77d48ac>),
 ('__init__', <method-wrapper '__init__' of A object at 0xb77d48ac>),
 ('__module__', '__main__'),
 ('__new__', <built-in method __new__ of type object at 0x8146220>),
 ('__reduce__', <built-in method __reduce__ of A object at 0xb77d48ac>),
 ('__reduce_ex__', <built-in method __reduce_ex__ of A object at 0xb77d48ac>),
 ('__repr__', <method-wrapper '__repr__' of A object at 0xb77d48ac>),
 ('__setattr__', <method-wrapper '__setattr__' of A object at 0xb77d48ac>),
 ('__str__', <method-wrapper '__str__' of A object at 0xb77d48ac>),
 ('__weakref__', None),
 ('methodA', <bound method A.methodA of <__main__.A object at 0xb77d48ac>>),
 ('methodB', <bound method A.methodB of <__main__.A object at 0xb77d48ac>>)]