Python | 结合动态加载importlib模块来理解inspect模块的使用

inspect

    • inspect功能介绍
      • [1. `inspect.getsource(object)`](#1. inspect.getsource(object))
      • [2. `inspect.getdoc(object)`](#2. inspect.getdoc(object))
      • [3. `inspect.getmembers(object, predicate=None)`⭐⭐](#3. inspect.getmembers(object, predicate=None)⭐⭐)
      • [4. `inspect.signature(object)`](#4. inspect.signature(object))
      • [5. `inspect.getfile(object)`](#5. inspect.getfile(object))
      • [6. `inspect.getmodule(object)`](#6. inspect.getmodule(object))
      • [7. `inspect.isclass(object)`, `inspect.isfunction(object)`, `inspect.ismethod(object)`, 等](#7. inspect.isclass(object), inspect.isfunction(object), inspect.ismethod(object), 等)
    • 实战
  • 使用场景
    头一次遇到inspect模块是在importlib模块进行动态加载其他模块的时候遇到的,很神奇的一个第三方工具,因此写一篇基础的使用案例来记录可能会遇到的使用方法

inspect功能介绍

Python 的 inspect 模块提供了许多有用的函数,允许你在运行时检查 Python 对象(如函数、方法、类等)的详细信息。这个模块可以用来获取对象的源代码、文档字符串、参数列表等信息,常用于调试、分析代码结构或构建依赖于反射的高级工具。

以下是 inspect 模块中一些常用功能的简要概述和示例代码:

1. inspect.getsource(object)

获取对象的源代码。

python 复制代码
# -*- coding: utf-8 -*-
import inspect

def example_function(name,age):
    '''

    :param name: input a name str
    :param age: input a age int
    :return:
    '''
    print("Hello, World!")


# 获取函数的源代码
source_code = inspect.getsource(example_function)

print(source_code)

2. inspect.getdoc(object)

获取对象的文档字符串。

python 复制代码
# 获取函数的文档字符串
doc_string = inspect.getdoc(example_function)
print(doc_string)  # 输出: 这是一个示例函数。

3. inspect.getmembers(object, predicate=None)⭐⭐

获取对象的所有成员,包括方法、属性等。

python 复制代码
class ExampleClass:
    def __init__(self):
        self.name='test'
        self.age=3
    def test(self):
        pass

# 获取类的成员
members = inspect.getmembers(ExampleClass)
for name, member in members:
    print(f"{name}: {member}")
predicate参数
python 复制代码
import inspect

class MyClass:
    def method1(self):
        pass

    def method2(self):
        pass

    @property
    def prop(self):
        pass

# 定义一个 predicate 函数,只返回方法
def is_method(member):
    # member 是一个元组,第一个元素是名称,第二个元素是值
    return inspect.isfunction(member) or inspect.ismethod(member)

# 使用 getmembers 获取 MyClass 的所有成员,并使用 predicate 过滤
members = inspect.getmembers(MyClass, predicate=is_method)

# 打印结果
for name, member in members:
    print(f"{name}: {member}")

4. inspect.signature(object)

获取对象(函数、方法等)的参数签名。

python 复制代码
import inspect

def example_function(a, b, *args, c, d=None):
    pass

# 获取函数的参数签名
signature = inspect.signature(example_function)
print(signature)

5. inspect.getfile(object)

获取定义对象的文件名。

python 复制代码
import inspect

def example_function():
    pass

# 获取函数定义的文件名
file_name = inspect.getfile(example_function)
print(file_name)

就是获取当前函数所在文件的路径 绝对路径

E:\pythonProject\PythonProject\Dynamic\inspect_example.py

6. inspect.getmodule(object)

获取定义对象的模块。

python 复制代码
import inspect

def example_function():
    pass

# 获取函数所属的模块
module = inspect.getmodule(example_function)
print(module)

<module 'main' from 'E:\pythonProject\PythonProject\Dynamic\inspect_example.py'>

7. inspect.isclass(object), inspect.isfunction(object), inspect.ismethod(object), 等

检查对象是否是特定的类型。

python 复制代码
import inspect

def example_function():
    pass

class ExampleClass:
    pass

# 检查是否是函数
is_function = inspect.isfunction(example_function)
print(is_function)  # 输出: True

# 检查是否是类
is_class = inspect.isclass(ExampleClass)
print(is_class)  # 输出: True

inspect 模块的功能非常强大,可以帮助你深入了解 Python 对象的内部结构和行为。这些功能在开发调试工具、代码分析工具或需要动态调用和检查对象属性的应用程序时尤其有用。

实战

  • 结构

    用到两个文件
  1. temp.py
  2. testinspect.py

temp.py

python 复制代码
def func1():
    print('func1 is called.')
def func2():
    print('func2 is called.')
def func3():
    print('func3 is called.')

class A:
    A=1
    def __init__(self,name='A'):
        self.name=name

    def _say(self,msg):
        print(msg)

    def sayhello(self):
        print('hello,i am {}'.format(self.__class__))

class B:
    B=2
    def __init__(self,name='B'):
        self.name=name
    def _do_work(self):
        print('Do some work.')
    def greet(self):
        print('hello,i am {}'.format(self.name))

testinspect.py

python 复制代码
import inspect
import importlib
def get_attrs_of_module(module_name='temp'):
    # module=__import__(module_name)#动态引入模块(temp.py文件)
    module  = importlib.import_module(module_name)

    print('module:',module)  # module: <module 'temp' from 'D:\\PythonProject\\Dynamic\\temp.py'>

    for name,cls in inspect.getmembers(module,inspect.isclass):
        print('name:',name)
        print('cls:',cls)

    print('*' * 80)
    #用inspect.getmembers获取模块中的类
    # classes=[(clsname,fullname) for (clsname,fullname) in inspect.getmembers(module,inspect.isclass)]
    classes = [clsname for (clsname,fullname) in inspect.getmembers(module,inspect.isclass)]

    print('classes:',classes) #classes: ['A', 'B']
    print('*' * 80)
    fun  = [clsname for (clsname,fullname) in inspect.getmembers(module,inspect.isfunction)]

    print('fun:',fun) #classes: ['A', 'B']


    dic_cls_methods={}
    for clsname in classes:
        #用python内置的getattr()方法获取模块的类,inspect.isfunction()方法过滤出该类的方法

        print('getattr :',getattr(module,clsname)) # getattr : <class 'temp.A'>
        print('*'*40)
        print('inspect+getattr',inspect.getmembers(getattr(module,clsname))) # inspect.isfunction会限制输出
        print('*'*40)
        print('inspect+getattr+isfunction',inspect.getmembers(getattr(module,clsname),inspect.isfunction)) # inspect.isfunction会限制输出  获取类clsname中的所有函数成员
        print('*'*40)

        modules = [method_name for (method_name, method) in inspect.getmembers(getattr(module, clsname), inspect.isfunction)]

        dic_cls_methods[clsname]=modules

    print(dic_cls_methods)

get_attrs_of_module()
  • 参数解释
  1. import 和 importlib.import_module 作用相同 都是动态引入模块
python 复制代码
module=__import__(module_name)#动态引入模块(temp.py文件)
print('__import__ module:',module) 

module  = importlib.import_module(module_name)
print('importlib.import_module module:',module)  
  1. getattr(module,clsname)

用python内置的getattr()方法获取模块的类,inspect.isfunction()方法过滤出该类的方法

python 复制代码
print('getattr :',getattr(module,clsname))
bash 复制代码
getattr : <class 'temp.A'>
getattr : <class 'temp.B'>
相关推荐
一行玩python10 分钟前
SQLAlchemy,ORM的Python标杆!
开发语言·数据库·python·oracle
数据小爬虫@1 小时前
利用Python爬虫获取淘宝店铺详情
开发语言·爬虫·python
编程修仙2 小时前
Collections工具类
linux·windows·python
芝麻团坚果2 小时前
对subprocess启动的子进程使用VSCode python debugger
linux·ide·python·subprocess·vscode debugger
EterNity_TiMe_2 小时前
【论文复现】神经网络的公式推导与代码实现
人工智能·python·深度学习·神经网络·数据分析·特征分析
Stara05113 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
hence..3 小时前
Vscode写markdown快速插入python代码
ide·vscode·python
DanielYQ4 小时前
LCR 001 两数相除
开发语言·python·算法
vener_4 小时前
LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)
javascript·后端·python·websocket·django·luckysheet
封步宇AIGC5 小时前
量化交易系统开发-实时行情自动化交易-4.2.3.指数移动平均线实现
人工智能·python·机器学习·数据挖掘