看到这个标题猜想大家内心OS: 什么辣鸡水文,划走划走~







别急有干货!

  • 静态导入(照顾新人)

    假设现在有两个文件a,b在不同目录,b文件想引用a文件中的函数:
# test_module/sub_module_a/a.py

def a():
print(f"i`m function a") #################################################
# test_module/sub_module_b/b.py def b():
print("i`m function b")

三种比较常规的方法:

  1. from xx_module import xx_function
 # test_module/sub_module_b/b.py
from sub_module_a.a import a # 从sub_module_a/a.py 导入function a def b():
a() # 导入后就可以直接用function a了
print("i`m function b")
  1. 临时添加模块的绝对路径:

    可以临时将所需模块路径添加到 sys.path 变量中
# test_module/sub_module/b.py
import sys
# 向sys.path中追加a模块所在的绝对路径
sys.path.append('/Users/mac/Desktop/test_module/sub_module_a') from a import a # 从a.py 导入 function a def b():
a()
print("i`m function b") if __name__ == '__main__':
b()
# 输出:
# i`m function a
# i`m function b
  1. 将模块保存到扩展包下, 如: lib\site-packages

    Python解释器在执行代码遇到import时查找模块名是在sys.path中查找, 如果找不到则抛异常ModuleNotFoundError
# test_module/sub_module_b/b.py
import sys print(sys.path)
import a def b():
a.a()
print("i`m function b") if __name__ == '__main__':
b()



可以将所需的模块放入上图的任意一个路径下再使用import语句则可正常导入

比如我们可以将上文的a.py放到父级目录也就是test_module下再在b.py中进行引用



或者放到lib/site-packages(默认扩展包路径)下面, 如:

  • ️动态导入

    假设现有文件结构为:
 	├── debugs
│ ├── __init__.py
│ ├── a.py
│ └── b.py
└── main.py

文件a和b中假设有相同的函数test(),但内部实现逻辑不一致; 我们在main模块中根据用户传入的参数来决定调用a模块或者b模块的test()函数

a.py

# test_module/debug/a.py

def test():
print(f"i`m in a.py")

b.py

# test_module/debug/b.py

def test():
print(f"i`m in b.py")

常规操作main的写法:

def main(arg):
if arg == 'a':
from debug.a import test
elif arg == 'b':
from debug.a import test
test() main('b') # i`m in b.py

假设用动态导入可以写成:

  1. exec方法
def main(arg):
exec(f'from debug.{arg} import test') # 利用exec可执行字符串的逻辑导入模块
locals().get('test')() #locals()和globals()保存了当前的所有变量 if __name__ == '__main__':
main('b') # i`m in b.py
  1. importlib模块的import_module方法
import importlib

def main(arg):
module = importlib.import_module(f'debug.{arg}') # 绝对导入
module.test()
module2 = importlib.import_module(f'.{arg}', package='debug') # 相对导入
module2.test()
getattr(module, 'test')() # 也可以利用反射机制,这个很重要!!!是动态导入的绝佳搭配 if __name__ == '__main__':
main('b') # 会输出3遍 i`m in b.py
  • ️案例!

    博主开发了一个web的丐版postman,其中支持pre request script脚本隔离;模板变量参数化时就需要用到动态导入+反射

    整个项目部分结构为:
│── debugtalks # 配置文件
│ ├── __init__.py
│ ├── cur_bc_id_1.py
│ └── cur_bc_id_2.py
└── view # 视图函数
│ ├── __init__.py
│ └── PreReqeustHandle.py # 前置处理模板变量

其中部分测试内容为:

cur_bc_id_1.py

# cur_bc_id_1.py
# dependence:需要引用的第三方依赖模块
dependence = []
variable=1 def func(arg1,arg2):
return arg1+arg2

PreReqeustHandle.py部分源码为

def request_temp(module, data):
if not isinstance(data, (dict, list, tuple)):
pass
elif isinstance(data, (list, tuple)):
for index in data:
request_temp(module, index)
elif isinstance(data, dict):
for k, v in data.items():
if isinstance(v, str):
regex_result = re.findall(r"^.*\$\{([^}]+)}.*$", str(v))
if regex_result:
try:
if not str(regex_result[0]).endswith(')'):
data[k] = getattr(module, regex_result[0])
else:
params = re.findall(r"^.*\(([^}]+)\).*$", str(regex_result[0]))
func_name = str(regex_result[0]).split('(')[0]
if not params:
data[k] = getattr(module, func_name)()
else:
variables = str(params[0]).split(',')
param = {data.split("=")[0]: eval(data.split("=")[1]) for data in variables}
data[k] = getattr(module, func_name)(**param) except Exception as e:
data[k] = f"{regex_result[0]} 参数化引用失败,{e} 请检查是否有误!"
else:
request_temp(module, v)
return data

博主是用flask开发的项目所以在before_request中对每次请求进来的根据参数cur_bc_id=xx,再去相应debugtalks下面利用动态导入+PreReqeustHandle里的反射将模板变量(规则为:"${function(arg=value)}"或"${variable}")替换成cur_bc_id_xx.py的引用对象,然后再请求具体接口



由用户在线编辑python代码保存后,请求体内即可引用;也可在线调试自己的代码下方展示区显示运行结果

Python之模块导入(不看会后悔系列)的更多相关文章

  1. [python]关于在python中模块导入问题追加总结

    [背景] 最近在写程序时,我使用的eclipse编辑器运行都没有问题,然后部署到自动化环境上却偏偏报找不到相应模块问题,现在对该问题在之前的贴子上追加总结 原帖子:[python]关于python中模 ...

  2. python random模块导入及用法

    random是程序随机数,很多地方用到,验证码,图片上传的图片名称等,下面说说python random模块导入及用法 1,模块导入 import random 2,random用法 random.r ...

  3. python Calendar 模块导入及用法

    Calendar 是python 日历模块,此模块的函数都是日历相关的,例如打印某月的字符月历,星期之类的模块,下面剖析python Calendar 模块导入及用法. 1,python导入日历模块 ...

  4. python中模块导入问题(已解决)

    想在python中导入request包: 无此模块,于是先安装requests包: 但是提示"Requirement already satisfied".在提示的相应目录里,找到 ...

  5. python自定义模块导入方法,文件夹,包的区别

    python模块导入,网上介绍的资料很多,方法也众说纷纭.根据自己的实践,感觉这个方法最简单直接,而且可以与主流的python ide生成的工程是一样的. 规则只有三条 1.      严格区分包和文 ...

  6. python的模块导入机制

    在python中用import或者from...import来导入相应的模块. 模块(Module)其实就是一些函数和类的集合文件,它能实现一些相应的功能,当我们需要使用这些功能的时候,直接把相应的模 ...

  7. python之模块导入和包

    一.何为模块 1.一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2.模块目的和函数,对象等一样,是为了代码的复用性而存在的.即一个py程序写了很多功能,也可 ...

  8. Python之模块导入

    import sys #import module (.py)import functools #名词空间 functoolsprint(functools) print("-------- ...

  9. python之模块导入和重载

    模块导入和重载 模块导入通过import语句实现,但是在同一次会话中只运行一次. 若想要再次运行文件,调用imp标准库中的reload函数: >>> from imp import ...

随机推荐

  1. 配置php redis 扩展

    参照runoob:PHP 使用 Redis Windows: - 假设redis已经安装好 服务启动 - xampp (php 7.1 x86 windows) 查看phpinfo (php 7.1 ...

  2. 启动springboot出现错误 Caused by: java.net.BindException: Address already in use: bind

    如果运行过程中出现端口被占用 抛出了这个异常 首先可以在cmd中调出命令窗口然后 执行命令 netstat -ano  可以查看所有活动的连接  找到你被占用的端口 可以看到我被占用的端口的进程是 4 ...

  3. vue 主次页面区分

    1.路由设定,增加meta参数 { path: '/', name: 'Home', component: Home, meta: { index: 0, showFooter: true //由这个 ...

  4. P7737-[NOI2021]庆典【tarjan,虚树】

    正题 题目链接:https://www.luogu.com.cn/problem/P7737 题目大意 给出一张无向图满足若\(x\Rightarrow z,y\Rightarrow z\)那么有\( ...

  5. P7276-送给好友的礼物【dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7276?contestId=39577 题目大意 \(n\)个点的一棵树,\(k\)个关键点,两个人从根出发分别走 ...

  6. AT3950-[AGC022E]Median Replace【贪心,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/AT3950 题目大意 一个包含\(?,0,1\)的长度为奇数的序列,把\(?\)替换为\(0/1\).每次可以选择三 ...

  7. Maccms8.x(苹果cms)命令执行漏洞

    getshell payload(a): http://0-sec.org/index.php?m=vod-search&wd={if-A:assert($_POST[a])}{endif-A ...

  8. redux搭配react-redux进行跨组件通信开发

    Redux API 作用 createStore 用于创建一个store对象 bindActionCreators 用于简化操作,不用开发者手动触发dispatch React-redux API 作 ...

  9. 新版发布|ShardingSphere 5.0.0-beta 来了!

    Apache ShardingSphere 5.0.0-beta 版在经过长达半年的筹备后,终于将在近期正式 Release! 本文将带领大家一同预览新版本即将带来哪些重大亮点功能. 作者介绍 潘娟 ...

  10. Windows使用Git的vim编辑器编译运行程序

    Windows配置gcc 新建一个main.c $ touch main.c #在当前目录下创建main.c $ mkdir folder #在当前目录下创建folder文件夹 $ rm main.c ...