Hib*_*u57 72 python import module package
已经使用扁平包,我没想到我遇到嵌套包的问题.这是…
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
Run Code Online (Sandbox Code Playgroud)
这两个package/__init__.py和package/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...
Run Code Online (Sandbox Code Playgroud)
test.py(3个版本)# file test.py
from package.subpackage.module import *
print attribute1 # OK
Run Code Online (Sandbox Code Playgroud)
这是导入东西的不良和不安全的方式(大量导入),但它有效.
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
Run Code Online (Sandbox Code Playgroud)
一种更安全的导入方式,逐项导入,但失败了,Python不希望这样:失败并显示消息:"没有模块命名模块".但是......
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
Run Code Online (Sandbox Code Playgroud)
......说<module 'package.subpackage.module' from '...'>.这是一个模块,但那不是模块/ -P 8-O ......呃
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
Run Code Online (Sandbox Code Playgroud)
这个工作.所以你要么被迫一直使用overkill前缀,要么使用版本#1中的不安全方式,而Python不允许使用安全方便的方法?更好的方法是安全并避免不必要的长前缀是Python拒绝的唯一方法吗?这是因为它喜欢import *还是因为它喜欢过长的前缀(这无助于强制执行这种做法)?
很抱歉这些难以理解的话,但那是两天我试图解决这种类似愚蠢的行为.除非我在某个地方完全错了,否则这会让我觉得Python的包和子包模型确实破坏了一些东西.
笔记
sys.path,避免全球副作用,也不想依赖*.pth文件,这只是另一种sys.path与同样的全球效应相关的方式.为了使解决方案清洁,它必须是本地的.要么Python能够处理子包,要么不是,但它不应该需要使用全局配置来处理本地的东西.package/subpackage/__init__.py,但它没有解决任何问题,它做同样的事情,并且抱怨subpackage不是一个已知的模块,print subpackage而是说它是一个模块(怪异的行为,再次).可能是我完全错了(我更喜欢的选项),但这让我对Python感到很失望.
除了三个我试过的其他任何已知的方法?我不知道的事情?
(叹)
-----%<-----编辑----->%-----
Python中没有像真正的子包一样,因为所有包引用只转到全局词典,这意味着没有本地词典,这意味着无法管理本地包引用.
您必须使用完整前缀或短前缀或别名.如:
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Run Code Online (Sandbox Code Playgroud)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
Run Code Online (Sandbox Code Playgroud)
或者,以上的变化.
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
Run Code Online (Sandbox Code Playgroud)
如果您不介意批量导入多个实体,您可以:
from package.subpackage.module import attribute1, attribute2
# and etc.
Run Code Online (Sandbox Code Playgroud)
不是我最喜欢的口味(我更喜欢每个导入的实体有一个导入语句),但可能是我个人喜欢的.
更新(2012-09-14):
最后在实践中似乎没问题,除了对布局的评论.而不是上述,我用过:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.
Run Code Online (Sandbox Code Playgroud)
Bre*_*arn 58
您似乎误解了如何import搜索模块.当您使用import语句时,它总是搜索实际的模块路径(和/或sys.modules); 它不会使用由于先前导入而存在的本地命名空间中的模块对象.当你这样做时:
import package.subpackage.module
from package.subpackage import module
from module import attribute1
Run Code Online (Sandbox Code Playgroud)
第二行查找名为的包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
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢打字package.subpackage两次,你可以手动创建对attribute1的本地引用:
from package.subpackage import module
attribute1 = module.attribute1
attribute1 # works
module.someOtherAttribute #also works
Run Code Online (Sandbox Code Playgroud)
#2失败的原因是因为sys.modules['module']不存在(导入例程有自己的作用域,并且看不到module本地名称),并且module磁盘上没有模块或包.请注意,您可以用逗号分隔多个导入的名称.
from package.subpackage.module import attribute1, attribute2, attribute3
Run Code Online (Sandbox Code Playgroud)
也:
from package.subpackage import module
print module.attribute1
Run Code Online (Sandbox Code Playgroud)