2017-09-16 69 views
0

我使用PyCharm和Python 3,我有下一个文件夹蟒布局:举止怪异(仅大写的工作,不能与亲人)Python的进口

src/ 
    __init__.py 
    command/ 
     __init__.py 
     simpleremote/ 
      __init__.py 
      Command.py 
      GarageDoor.py 
      GarageDoorOpenCommand.py 
      Light.py 
      LightOffCommand.py 
      LightOnCommand.py 
      RemoteControlTest.py 
      SimpleRemoteControl.py 

我创建的包,你可以看到。与main方法的文件是RemoteControlTest.py与这些进口的工作完美:

from pythonDesignPatterns.src.command.simpleremote.GarageDoor import GarageDoor 
from pythonDesignPatterns.src.command.simpleremote.GarageDoorOpenCommand import GarageDoorOpenCommand 
from pythonDesignPatterns.src.command.simpleremote.Light import Light 
from pythonDesignPatterns.src.command.simpleremote.command import LightOnCommand 
from pythonDesignPatterns.src.command.simpleremote.SimpleRemoteControl import SimpleRemoteControl 

上创建初始化的包.py文件,我试图用相对进口,而不是以前的人,例如

from .command import LightOnCommand 

,但它给了我一个错误(将称之为情况A):

​​

所以摆弄周围,我发现,这个工作对于同一行:

from command.simpleremote.Command import LightOnCommand 

和程序成功地再次执行,但如果我用的是“重构”选项从IDE(PyCharm)和重命名“命令“到 ”命令“,写这行:

from command.simpleremote.command import LightOnCommand 

突然显示错误(情况B):

ImportError: No module named 'command.simpleremote'; 'command' is not a package 

在每种情况下(A和B)哪个是问题?我不明白为什么它会在从command.simpleremote导入的每个案例之间起作用。为什么没有一个级别越来越靠近?为什么它使用大写'C'而不是'c'?这是否区分大小写?

我看过官方的Python文档(和PEP302,PEP328和PEP420的网页),但对于我来说这太复杂了。任何人都可以通过一种更简单的方式来理解它(或者告诉我一个我可以阅读的关于这个简单解释的资源)?

在此先感谢

回答

1

我猜你直接运行RemoteControlTest.py

情况A

Python的进口商不能去父母如果模块作为脚本直接运行它获得通过封装结构去代替。

Python的设计者大概不想让子模块直接作为脚本调用,所以没有真正的好解决方案。主要可以

  1. 运行与python -m command.simpleremote.RemoteControlTest脚本时src要么是当前目录或PYTHONPATH
  2. 使用一个测试框架,它确实在呼唤你。

有关可能的解决方案的更详细的讨论可以在Relative imports in Python 3找到。

情况B

直接启动的一个后果是, “src/command/simpleremote” 是module search path。 “src”似乎也被添加到路径中,但在“src/command/simpleremote”之后。

from command...情况B之前的进口机制没有找到“command”,在“src/command/simpleremote”匹配,继续寻找在“src”里被发现command包 - >成功。

如果B发现command.py在“src/command/simpleremote”这不是一个包 - >错误。

+0

关于答:对于相对导入并且通过包结构是不够的将__init__.py文件放在每个文件夹中? 关于B:我在阅读关于模块搜索路径链接来测试这一点。 PyCharm做了一个我认为可能相关的sys.path.exy.tend。 – madtyn

+0

@madtyn关于A:不,对于直接启动的脚本例如'__package__'属性是空的。如果模块通过包加载,'__package__'包含包名称。 –

+0

我一直在阅读这些日子。 Python文档和PEP366,它推荐了一个双线工作。我已经尝试了'__package__'中的几个值,但始终显示'父模块'package.value'未加载,无法执行相对导入 ' – madtyn