当前位置: 首页 > article >正文

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

inspect

    • inspect功能介绍
      • 1. `inspect.getsource(object)`
      • 2. `inspect.getdoc(object)`
      • 3. `inspect.getmembers(object, predicate=None)`⭐⭐
        • predicate参数
      • 4. `inspect.signature(object)`
      • 5. `inspect.getfile(object)`
      • 6. `inspect.getmodule(object)`
      • 7. `inspect.isclass(object)`, `inspect.isfunction(object)`, `inspect.ismethod(object)`, 等
    • 实战
      • temp.py
      • testinspect.py

  • 使用场景
    头一次遇到inspect模块是在importlib模块进行动态加载其他模块的时候遇到的,很神奇的一个第三方工具,因此写一篇基础的使用案例来记录可能会遇到的使用方法

inspect功能介绍

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

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

1. inspect.getsource(object)

获取对象的源代码。

# -*- 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)

获取对象的文档字符串。

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

在这里插入图片描述

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

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

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参数
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)

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

import inspect

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

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

在这里插入图片描述

5. inspect.getfile(object)

获取定义对象的文件名。

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)

获取定义对象的模块。

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), 等

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

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

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

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 作用相同 都是动态引入模块
module=__import__(module_name)#动态引入模块(temp.py文件)
print('__import__ module:',module) 

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

在这里插入图片描述
2. getattr(module,clsname)

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

print('getattr :',getattr(module,clsname))
getattr : <class 'temp.A'>
getattr : <class 'temp.B'>

http://www.kler.cn/a/404064.html

相关文章:

  • 05_Spring JdbcTemplate
  • C++和js对比
  • 极客时间《Redis核心技术与实战》开篇词 知识点总结
  • Kafka 到 Kafka 数据同步
  • 进程间通信的信号艺术:机制、技术与实战应用深度剖析
  • 低速接口项目之串口Uart开发(一)——串口UART
  • Vue项目部署至服务器后报404错误的原因分析及解决方案
  • Dubbo HTTP接入架构
  • 丹摩征文活动 | SD3+ComfyUI:图文部署新境界,2合1效率提升,简化步骤对抗传统挑战!
  • UniApp在Vue3下使用setup语法糖创建和使用自定义组件
  • C++桥接模式在使用时需要注意什么
  • 算法定制LiteAIServer检测算法入侵检测算法平台部署:危险区域人员闯入治理
  • Python中Tushare(金融数据库)入门详解
  • 【pytorch-02】:张量的索引、形状操作和常见运算函数
  • 2024强网杯--babyheap house of apple2解法
  • Unity3d场景童话梦幻卡通Q版城镇建筑植物山石3D模型游戏美术素材
  • 细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
  • SAP Ariba Contracts 基本介绍
  • 知识见闻 - 数学: 均方根误差和标准差
  • 密码学之柯克霍夫原则(Kerckhoff原则)
  • 美创科技入选2024数字政府解决方案提供商TOP100!
  • jmeter常用配置元件介绍总结之监听器
  • C++编程玩转物联网:用树莓派Pico实现流水灯
  • react中useMemo的使用场景
  • vue学习11.21
  • 多模态大模型(4)--InstructBLIP