分发带多个模块的Python命令行程序
我正在尝试把一个用Python写的命令行程序发布给大家,但在此之前我想先测试一下,确保这个程序能正常工作。为此,我创建了一个简单的wheel
格式的程序包,然后在另一个文件夹里创建了一个virtualenv
环境,并把这个wheel
安装到这个环境里。听起来很简单,对吧?
其实并没有那么简单。
当我在测试环境中尝试运行这个程序时,出现了这个错误信息:
Traceback (most recent call last):
File "~/testing/bin/leprechaun", line 7, in <module>
from leprechaun.main import main
File "~/testing/lib/python3.4/site-packages/leprechaun/main.py", line 8, in <module>
import generator
ImportError: No module named 'generator'
看起来是generator.py
这个文件没有被导入,原因不明。不过奇怪的是,generator.py
和main.py
(程序的主要入口)是在同一个文件夹里的。
为了让大家更清楚,这里是我项目的目录结构:
├── leprechaun
│ ├── data
│ │ └── A bunch of text files that aren't important
│ ├── db.py
│ ├── generator.py
│ ├── __init__.py
│ ├── main.py
│ └── rainbow.py
├── LICENSE.txt
├── MANIFEST.in
├── README.rst
└── setup.py
另外,我的setup.py
脚本是这样的:
#!/usr/bin/env python3
import re
from setuptools import setup, find_packages
version = re.search("^__version__\s*=\s*\"(.*)\"$",
open("leprechaun/__init__.py").read(), re.M).group(1)
setup(
name='leprechaun',
version=version,
description="A simple rainbow table generator",
long_description=open("README.rst", encoding="utf-8").read(),
author="My Name",
author_email="My Email",
url="https://github.com/zcdziura/leprechaun",
license="MIT",
packages=find_packages(),
package_data={
"leprechaun": ["data/wordlist*"]
},
entry_points={
"console_scripts": [
"leprechaun = leprechaun.main:main"
]
}
)
我原以为生成的入口脚本会直接调用我包里的main
函数,这样就能从同一个目录导入模块了。但看起来并不是这样。
那我该怎么解决这个问题呢?
1 个回答
1
你遇到的问题是关于绝对导入的。你可以看看这个PEP,了解一下背后的原因。
简单来说,现在你每次写的导入语句都会在sys.path
中查找。而在Python 2.x中,你可以直接用import generator
,它会在当前目录里找,但在Python 3.x中,它需要在指定的路径中查找。所以如果你改成from leprechaun import generator
或者from . import generator
,就能解决这个问题。