我正在Python3.8.2上开发一个Python库,出于测试目的,我想运行一个模块作为main。当我尝试时,我得到一个ModuleNotFound错误
以下是我的库结构:
.
├── foo
│ ├── __init__.py
│ ├── bar.py
│ └── quux
│ ├── __init__.py
│ ├── corge.py
│ └── garply.py
├── main.py
bary.py:
def baz():
print("baz")
柯基·皮
from foo.quux.garply import *
def grault():
waldo()
print("grault")
if __name__ == '__main__':
grault()
garply.py
def waldo():
print("waldo")
main.py
from foo.bar import *
from foo.quux.corge import *
if __name__ == '__main__':
baz()
grault()
(所有__init__.py
文件均为空)
当我运行main.py
时,它会工作
$ python main.py
baz
waldo
grault
如果尝试运行corge.py
,则会出现以下错误:
$ python foo/quux/corge.py
Traceback (most recent call last):
File "foo/quux/corge.py", line 1, in <module>
from foo.quux.garply import *
ModuleNotFoundError: No module named 'foo'
不管我当前的工作目录是什么,它总是给出这个错误
$ cd foo/quux/
$ python corge.py
Traceback (most recent call last):
File "corge.py", line 1, in <module>
from foo.quux.garply import *
ModuleNotFoundError: No module named 'foo'
在进行测试时,我使用PyCharm 2020.1创建了一个新的PyCharm项目,并实现了我描述的结构。令我惊讶的是,它与默认检测到的运行配置配合使用
我尝试使用PyCharm自动创建的venv,但仍然不起作用。如果我直接复制/粘贴该命令并使用其CWD,则该命令不起作用。它不适用于PyCharm内置的终端。它仅与PyCharm Run按钮配合使用
我的模块结构是否有问题?如果是这样的话,PyCharm可以做些什么来实现这一目标?如果不是,为什么它不在PyCharm之外工作
Python需要知道
foo
所在的目录才能导入它sys.path
列出python将在其中搜索的目录当你安装一个软件包时,安装程序会担心这样做——通常是将模块放在一个已知的目录中,或者将安装程序包路径添加到
sys.path
当您运行脚本时,python会自动将该脚本的路径添加到
sys.path
,因此当您运行main.py
时,您会发现foo
如何作为模块运行
__main__
一个选项是使包可安装(setup.py、wheels等),并使用开发模式("pip install editable ./" vs "python setup.py develop"进行一些讨论)。这就是我在开发我计划提供给他人的东西时所做的
另一种方法是将您的目录添加到PYTHONPATH,甚至在您运行该程序时。在linux上,这将是
还有一个,我也这么做了,就是破解模块本身的路径
__file__
给出相对于当前工作目录的文件名,您知道自己在包层次结构中的位置有多深。因此,您只需将__file__
设为绝对值,并去掉几个目录名即可柯基·皮
最后,一开始不要这样做。当您将
corge.py
作为脚本运行时,它会得到一个不同于作为模块导入的__main__
的命名空间。它的全局变量/类/函数被加载两次,根据您是通过__main__
名称空间还是foo.bar.corge
调用它们,可以得到不同的变量/类/函数最好是将任何您想放在} subcommands 可用于此
corge.py
中的内容放在一个main中,使它们成为单独的脚本。例如,您可以将def main()
添加到模块中。在main.py
中,您可以添加一个选项run foo.bar.corge
,告诉main导入corge.py
并运行其main()
^{对
main.py
的调用是有效的,因为Python将在直接子目录中查找模块。任何其他位置中想要导入foo.yadda.whatever
的任何模块都必须通过搜索您的PYTHONPATH
来查找foo
。因此,您需要将foo
的父目录添加到PYTHONPATH
相关问题 更多 >
编程相关推荐