繁体   English   中英

Python,从同一模块导入:ImportError:无法导入名称'blah',__name__ =='__main__'

[英]Python, importing from same module: ImportError: cannot import name 'blah', __name__ == '__main__'

复制非常容易的问题。 我当前的设置是:

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'

为什么无法从包中导入变量? 我知道如何解决它,我很想知道错误的原因。

我假设您正在目录package中运行python run.py 然后,Python 该目录中查找名为“ package”的包(目录)或模块( .py文件),但都不存在。 由于无法导入符号blah ,因此引发了ImportError

您显然试图将其作为一个程序包执行,但是您正在运行“ run.py”,就好像它是标准的python脚本一样。 在您尝试运行module的方式上, 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.pyvariables.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

您的问题是您正在尝试从所在的模块中导入。

这是我的结构

[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可用的条目,
这是在orun.py (模块外部)和mod/run.py内的mod/run.py找到的sys.path

[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

在python中,包和模块是两个不同的概念。 模块是单个py文件,包必须是必须包含__init__.py的目录。

__init__.py用于packages ,当您在程序包目录中运行run.py时,程序包目录不能视为a package ,而程序包目录当然不是module 因此它引发了错误: ModuleNotFoundError: No module named xxxx

导入常规程序包时,将隐式执行此__init__.py文件,并将其定义的对象绑定到程序包名称空间中的名称。

5.导入系统-Python 3.7.4rc1文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM