为了账号安全,请及时绑定邮箱和手机立即绑定

Python:导入子包或子模块

Python:导入子包或子模块

小怪兽爱吃肉 2019-08-31 16:41:09
已经使用扁平包,我没想到我遇到嵌套包的问题。这是…目录布局dir | +-- test.py | +-- package      |      +-- __init__.py      |      +-- subpackage           |           +-- __init__.py           |           +-- module.pyinit .py的内容这两个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...内容test.py(3个版本)版本1# file test.pyfrom package.subpackage.module import *print attribute1 # OK这是导入东西的不良和不安全的方式(大量导入),但它有效。版本2# file test.pyimport package.subpackage.modulefrom package.subpackage import module # Alternativefrom module import attribute1一种更安全的导入方式,逐项导入,但失败了,Python不希望这样:失败并显示消息:“没有模块命名模块”。但是......# file test.pyimport package.subpackage.modulefrom package.subpackage import module # Alternativeprint module # Surprise here......说<module 'package.subpackage.module' from '...'>。这是一个模块,但那不是模块/ -P 8-O ......呃版本3# file test.py v3from package.subpackage.module import attribute1print attribute1 # OK这个有效。所以你要么被迫一直使用overkill前缀,要么使用版本#1中的不安全方式而Python不允许使用安全方便的方法?更好的方法是安全并避免不必要的长前缀是Python拒绝的唯一方法吗?这是因为它喜欢import *还是因为它喜欢过长的前缀(这无助于强制执行这种做法)?很抱歉这些难以理解的话,但那是两天我试图解决这种类似愚蠢的行为。除非我在某个地方完全错了,否则这会让我觉得Python的包和子包模型确实破坏了一些东西。笔记我不想依赖sys.path,避免全球副作用,也不想依赖*.pth文件,这只是另一种sys.path与同样的全球效应相结合的方式。为了使解决方案清洁,它必须是本地的。要么Python能够处理子包,要么不是,但它不应该需要使用全局配置来处理本地的东西。我也试过使用import package/subpackage/__init__.py,但它没有解决任何问题,它做同样的事情,并且抱怨subpackage不是一个已知的模块,print subpackage而是说它是一个模块(怪异的行为,再次)。可能是我完全错了(我更喜欢的选项),但这让我对Python感到很失望。除了三个我试过的其他任何已知的方法?我不知道的事情?
查看完整描述

3 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

您似乎误解了如何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


查看完整回答
反对 回复 2019-08-31
?
慕森王

TA贡献1777条经验 获得超3个赞

#2失败的原因是因为sys.modules['module']不存在(导入例程有自己的作用域,并且看不到module本地名称),并且module磁盘上没有模块或包。请注意,您可以用逗号分隔多个导入的名称。


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

也:


from package.subpackage import module

print module.attribute1


查看完整回答
反对 回复 2019-08-31
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

如果您要做的就是在全局命名空间中获取attribute1,那么版本3似乎没问题。为什么它是过度杀伤前缀?


在版本2中,而不是


from module import attribute1

你可以做


attribute1 = module.attribute1


查看完整回答
反对 回复 2019-08-31
  • 3 回答
  • 0 关注
  • 1053 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信