的Python:导入子包或子模块(Python: importing a sub‑package o

2019-06-17 23:57发布

在已经使用扁平封装,我没想到我有嵌套包中遇到的问题。 这是…

目录布局

dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py

初始化的.py内容

这两种package/__init__.pypackage/subpackage/__init__.py是空的。

内容module.py

# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...

内容test.py (3版)

第1版

# file test.py
from package.subpackage.module import *
print attribute1 # OK

这是进口的东西(导入所有的散装)的糟糕和不安全的方式,但它的作品。

第2版

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1

一个更安全的方式,通过项目导入,项目,但它失败,Python不想这样:失败的消息:“无模块命名模块”。 然而...

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here

......说<module 'package.subpackage.module' from '...'> 。 所以这是一个模块,但是这不是一个模块/ -P 8-O ...呃

第3版

# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK

这一个工程。 所以,你要么被迫使用矫枉过正前缀所有的时间,或使用不安全的方式在版本#1和不允许通过Python的使用安全方便的方法? 更好的方法,是一种安全,避免不必要的长的前缀是唯一一个Python的拒绝? 这是因为它喜欢import *或因为爱超长前缀(这不利于执行这种做法)?

很抱歉的狠话,但是这两天,我试图解决这个愚蠢的行为。 除非我完全错了地方,这会让我有一种感觉的东西在包和子包的Python的模式是真正打破。

笔记

  • 我不想依靠sys.path ,以避免全球性的副作用,也没有对*.pth文件,这只是另一种方式玩sys.path具有相同的全局effets。 该解决方案是干净的,它只能是局部的。 无论是Python是能够处理子包,无论是不是,但它不应该要求与全局配置发挥到能够处理本地的东西。
  • 我也尝试过使用进口package/subpackage/__init__.py ,但它解决了什么,它做的一样,并且抱怨subpackage是不是一个已知的模块,而print subpackage说,这是一个模块(怪异的行为,再次)。

可能我是完全错误的强硬(选择我宁愿),但是这让我觉得有很多失望的Python。

三我试过的身边任何其他已知的方法是什么? 一些我不知道的吗?

(叹)

-----%<-----编辑----->%-----

结论到目前为止(人的意见后)

有没有像真正的子包在Python中,所有包的引用都到了全球dictionnary,只是,这意味着没有本地词典,这意味着有没有办法来管理本地包参考。

你必须要么使用全前缀或短的前缀或别名。 如:

完整版的前缀

from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)

短的前缀版本(但反复前缀)

from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

否则,在上述的变型。

from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context

分比式版本

如果你不介意在一个批次一次性导入多个实体,您可以:

from package.subpackage.module import attribute1, attribute2
# and etc.

不是我的第一爱好的味道(我更喜欢有每个导入实体一个import语句),但可能是一个我会亲自青睐。

更新(2012年9月14日):

最后似乎是好的实践中,除了与有关布局的注释。 取而代之的是上面的,我用:

from package.subpackage.module import (

    attribute1, 
    attribute2,
    attribute3,
    ...)  # and etc.

Answer 1:

你似乎是误解如何import搜索模块。 当您使用import语句总是搜索实际模块路径(和/或sys.modules ); 它不使用本地名称空间中存在因为以前进口的模块对象 。 当你这样做:

import package.subpackage.module
from package.subpackage import module
from module import attribute1

第二行寻找了一个叫做package.subpackage进口module从包。 该行对第三行没有任何影响。 第三行只是寻找一个模块调用module并没有找到一个。 它没有“再利用”的对象叫做module ,你从上面的线了。

换句话说from someModule import ...不“从我前面导入...模块称为someModule”的意思是“来自你找到sys.path中......模块命名someModule”的意思。 有没有办法通过进口,导致其包装为“逐步”建立一个模块的路径。 你总是有导入时要参考整个模块的名称。

目前尚不清楚你想要达到的目标。 如果你只想要导入的特定对象ATTRIBUTE1,只是做from package.subpackage.module import attribute1并用它做。 你再也不必担心长时间package.subpackage.module一旦你输入你从它想要的名字。

如果想访问该模块后访问其他的名字,那么你可以做from package.subpackage import module ,正如你已经看到了,那么你可以做module.attribute1等等,就像你喜欢。

如果你想 ---也就是说,如果你想attribute1可直接访问你想要module访问的,只是做上述两种的:

from package.subpackage import module
from package.subpackage.module import attribute1
attribute1 # works
module.someOtherAttribute # also works

如果你不喜欢打字package.subpackage甚至两次,你可以手动创建一个本地引用ATTRIBUTE1:

from package.subpackage import module
attribute1 = module.attribute1
attribute1 # works
module.someOtherAttribute #also works


Answer 2:

原因#2失败,是因为sys.modules['module']不存在(进口程序有它自己的范围,并不能看到的module本地名称),而且也没有module在磁盘上的模块或组件。 请注意,您可以用逗号分隔的多个导入的名称。

from package.subpackage.module import attribute1, attribute2, attribute3

也:

from package.subpackage import module
print module.attribute1


Answer 3:

如果你正在试图做的一切都是为了让ATTRIBUTE1在全局命名空间,版本3似乎就好了。 为什么是矫枉过正的前缀?

在2版本,而不是,

from module import attribute1

你可以做

attribute1 = module.attribute1


文章来源: Python: importing a sub‑package or sub‑module