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'>
相关推荐
utmhikari几秒前
【Python随笔】如何用pyside6开发并部署简单的postman工具
python·postman·pyqt·pyside6·桌面工具
碧水澜庭1 分钟前
django中cookie与session的使用
python·django
鬼义II虎神15 分钟前
将Minio设置为Django的默认Storage(django-storages)
python·django·minio·django-storages
数据小爬虫@21 分钟前
Python爬虫抓取数据,有哪些常见的问题?
开发语言·爬虫·python
Byron Loong34 分钟前
Python+OpenCV系列:【打卡系统-工具模块设计】工具模块深度揭秘,考勤智能化的核心秘籍!
python·opencv·webpack
漫无目的行走的月亮39 分钟前
基于Python Scrapy的豆瓣Top250电影爬虫程序
爬虫·python·scrapy
这里有鱼汤39 分钟前
数据分析从入门到放飞:Python三大金刚来助阵!
后端·python
算法哥1 小时前
解决Jupyter默认打开C盘的问题
ide·python·jupyter
小墨&晓末1 小时前
【PythonGui实战】自动摇号小程序
python·算法·小程序·系统安全
海棠AI实验室1 小时前
机器学习基础算法 (一)-线性回归
人工智能·python·机器学习