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 对象的内部结构和行为。这些功能在开发调试工具、代码分析工具或需要动态调用和检查对象属性的应用程序时尤其有用。
实战
- 结构
用到两个文件
- temp.py
- 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()
- 参数解释
- __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'>