非常容易复制的问题。我当前的设置是:
package/
__init__.py
run.py
在我的__init.py__
中,我有:
blah = 4
在我的run.py
中,我有:
from package import blah
if __name__ == '__main__':
print(blah)
我只是用python run.py
运行它。但是我得到ImportError: cannot import name 'blah'
。
为什么无法从包中导入变量?我知道如何解决这个问题,我很想知道错误的原因。
答案 0 :(得分:1)
我假设您正在目录python run.py
中运行package
。然后,Python在该目录中查找名为“ package” inside 的软件包(目录)或模块(.py
文件),但都不存在。由于无法导入符号blah
,因此会引发ImportError
。
答案 1 :(得分:1)
您显然试图将其作为软件包执行,但是您正在运行“ run.py”,就好像它是标准的python脚本一样。就您尝试如何运行而言,run.py
没有module
的概念。您需要在这里重新设计您的设计。 module
run.py
包中的一个模块将是一个模块(这些是您的命名约定)。因此module
是包,run.py
是模块。然后,您需要__main__.py
才能将其作为包执行,并且需要更改run.py:
run.py
:
#!/usr/bin/env python3
from module1 import blah
def run():
print(blah)
__main__.py
:
#!/usr/bin/env python3
from module1 import run
def main():
run.run() # run is the module name, and run is also the function name so we execute with run.run
main()
__init__.py
:
blah = 4
目录结构:
模块1 /
-__init__.py
-__main__.py
-run.py
要执行(在module1
之外):
[dkennetz@nodem103 fun]$ python3.5 -m module1
4
如果您不想将其打包,只需创建一个名为package
的目录,然后在其中创建run.py
和variables.py
。
variables.py:
blah=4
blahblah=8
blahblahblah=12
run.py:
from variables import blah
print(blah)
打印4
如果将run.py更改为:
from variables import blah, blahblah
print(blah)
print(blahblah)
[dkennetz@nodem103 package]$ python3.5 run.py
4
8
或者您可以通过将run.py更改为以下内容来导入所有变量:
from variables import *
print(blah)
print(blahblah)
print(blahblahblah) # if this was added to variables.py as 12
它返回:
[dkennetz@nodem103 package]$ python3.5 run.py
4
8
12
答案 2 :(得分:0)
您的问题是您正在尝试从所在的模块中导入。
这是我的结构
[syspath]
$ tree
.
├── mod
│ ├── __init__.py
│ └── run.py
└── orun.py
1 directory, 3 files
[syspath]
$ cat mod/run.py
#from mod import blah
from . import blah
print(blah)
[syspath]
$ cat orun.py
from mod import blah
print(blah)
[syspath]
$ python3 orun.py
4
[syspath]
$ python3 -m mod.run
4
在module
目录中,您实际上是模块的一部分,无法导入,但是您可以将其引用为同级,但只有当您作为模块的一部分运行时,在python3 -m mod.run
中,-m
作为模块 运行。
更多理解,python import
查找sys.path
中可用的条目,
以下是sys.path
(在模块外部)和模块内的orun.py
中的mod/run.py
。
[syspath]
$ python3 orun.py
['~/syspath',
'/usr/lib/python37.zip',
'/usr/lib/python3.7',
'/usr/lib/python3.7/lib-dynload',
'~/.local/lib/python3.7/site-packages',
'/usr/local/lib/python3.7/dist-packages',
'/usr/lib/python3/dist-packages']
[syspath]
$ python3 mod/run.py
['~/syspath/mod',
'/usr/lib/python37.zip',
'/usr/lib/python3.7',
'/usr/lib/python3.7/lib-dynload',
'~/.local/lib/python3.7/site-packages',
'/usr/local/lib/python3.7/dist-packages',
'/usr/lib/python3/dist-packages']
如您所见,当您位于mod
内时,您将在其中找不到另一个mod。
尝试在目录中添加一个具有相同名称module.py
的新文件,并为blah
输入一个不同的值,您将看到代码使用该值执行。
[syspath]
$ tree
.
├── mod
│ ├── __init__.py
│ ├── mod.py
│ └── run.py
└── orun.py
1 directory, 4 files
[syspath]
$ cat mod/mod.py
blah = 40
[syspath]
$ python3 mod/run.py
40
答案 3 :(得分:0)
在python中,包和模块是两个不同的概念。模块是单个py文件,程序包必须是必须包含__init__.py
的目录。
__init__.py
用于packages
,当您在程序包目录中运行run.py时,程序包目录不能视为a package
,而程序包目录当然不是{{1} }。因此它引发了错误:module
。
导入常规包后,将
ModuleNotFoundError: No module named xxxx
文件被隐式执行,并将其定义的对象绑定到包命名空间中的名称。