简体   繁体   English

python子文件夹导入混乱

[英]python subfolder import chaos

suppose I have a folder structure that looks like this: 假设我有一个看起来像这样的文件夹结构:

.
├── A
│   ├── a.py
│   └── b.py
└── main.py

The files have the following content: 这些文件具有以下内容:

b.py: b.py:

class BClass:
    pass

a.py: a.py:

from b import BClass

main.py: main.py:

from A import a

If I run python3.3 A/a.py or python3.3 B/b.by , there are no errors. 如果我运行python3.3 A/a.pypython3.3 B/b.by ,则没有错误。 However, if I run python3.3 main.py , the following error occurs: 但是,如果我运行python3.3 main.py ,则会发生以下错误:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    from A import a
  File "/tmp/python_imports/A/a.py", line 1, in <module>
    from b import BClass
ImportError: No module named 'b'

Changing the import-line in a.py to import Ab works, but obviously python3.3 A/a.py will fail then. 更改a.py中的import-line可以import Ab ,但是显然python3.3 A/a.py将会失败。 I am not actually interested in running python3.3 A/a.py but I want the module to be importable from multiple locations. 我实际上对运行python3.3 A/a.py并不感兴趣,但是我希望该模块可从多个位置导入。 Therefore a.py should import b.py regardless of where a.py is imported. 因此,无论a.py导入到哪里,a.py都应该导入b.py。

How can this issue be resolved? 该问题如何解决?

Besides the __init__.py I mentioned in my comment which is mandatory for packages, you need to import the sibling module relatively: 除了我在注释中提到的__init__.py这是软件包必需的)外,您还需要相对导入同级模块:

from .b import BClass

Then it also works in Python 3. 然后它也可以在Python 3中使用。

Alternatively you can of course import the full name: 另外,您当然可以导入全名:

from A.b import BClass

But then your module isn't relocatable as easily within your package tree. 但是,在包树中无法轻松重定位模块。

In neither way, though, you are able to use a.py as a standalone. 但是,无论a.py方式,您都可以将a.py用作独立版本。 To achieve this you would need to surround the import statement with try / except and try a different version in case the first one fails: 为此,您需要在import语句周围使用try / except并在第一个失败的情况下尝试使用其他版本:

try:
  from .b import BClass
except ValueError:
  from b import BClass

But that is understandable. 但这是可以理解的。 In a larger system, modules might depend on other modules somewhere in the package, otherwise they maybe should not be part of a package but standalone. 在一个大的系统,模块可能依赖于某处包等模块,否则他们也许不应该是一个包,但独立的部分。 And if there are such dependencies, using a module as if it was a standalone will of course be a problem. 而且,如果存在此类依赖关系,那么像使用独立模块一样使用模块当然会成为问题。

You need an __init__.py file (empty will be just fine) in the A directory. 您需要在A目录中有一个__init__.py文件(空就可以了)。 Otherwise, python won't recognize it as a package. 否则,python不会将其识别为包。

Now you're A is a package, you should use either absolute imports or explicit relative imports. 现在您是A包,您应该使用绝对导入或显式相对导入。 In this case, in A/a.py either use from Ab import BClass or from .b import BClass . 在这种情况下,在A/a.py可以from Ab import BClassfrom .b import BClass

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

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