如何在pytest中导入名称含连字符的Python 2.x脚本函数
解决Python 2.x中导入带连字符脚本的测试问题
遇到带连字符的脚本确实头疼,毕竟Python的模块命名规则不允许用连字符,常规import根本行不通。结合你的项目结构(package/tests/下写测试,package/bin/let-me-out是目标脚本),给你几个实用的解决方案:
方法1:用__import__动态导入(最直接)
Python内置的__import__函数可以接受字符串形式的模块名,完美绕过连字符的限制。不过首先得把bin目录加到Python的搜索路径里,让它能找到你的脚本:
import sys import os # 把bin目录的绝对路径加入sys.path # 假设测试文件在package/tests/下,这样能定位到上级的bin目录 bin_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'bin') sys.path.insert(0, bin_dir) # 动态导入脚本,把模块赋值给一个合法变量名 let_me_out = __import__('let-me-out') # 现在就能调用目标函数了 let_me_out.master_disaster()
方法2:用imp.load_source直接加载文件
Python 2.x里的imp模块提供了load_source方法,可以直接加载指定路径的Python文件,不需要修改sys.path也能搞定:
import imp import os # 计算目标脚本的绝对路径 script_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'bin', 'let-me-out') # 加载脚本,第一个参数是给这个模块起的别名(只要合法就行) let_me_out = imp.load_source('let_me_out_alias', script_path) # 调用函数 let_me_out.master_disaster()
方法3:创建软链接(可选,适合不想改代码的情况)
如果你的环境支持软链接,可以在bin目录里给let-me-out创建一个不带连字符的别名,比如:
cd package/bin ln -s let-me-out let_me_out.py
之后在测试文件里就能用常规导入了:
from bin import let_me_out let_me_out.master_disaster()
不过这个方法需要修改项目目录结构(加了软链接),如果团队协作的话要记得同步这个操作。
注意事项
- 脚本开头的shebang行(比如
#!/usr/bin/env python)不会影响导入,Python会自动忽略这一行,不用担心。 - 路径计算尽量用绝对路径,避免因为测试运行的工作目录不同导致找不到文件。
内容的提问来源于stack exchange,提问作者wizofe
相关产品推荐
相关产品推荐

