阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

这三个关于Python包导入的知识点你知道吗?

78次阅读
没有评论

共计 1766 个字符,预计需要花费 5 分钟才能阅读完成。

导读 使用 from module import * 默认情况下会导入 module 里的所有变量,若你只想从模块中导入其中几个变量,可以在 module 中使用 __all__ 来控制想要被其他模块导入的变量。

这三个关于 Python 包导入的知识点你知道吗?

1. 使用 __all__ 控制可被导入的变量

使用 from module import * 默认情况下会导入 module 里的所有变量,若你只想从模块中导入其中几个变量,可以在 module 中使用 __all__ 来控制想要被其他模块导入的变量。

# profile.py 
name='小明' 
age=18 
 
__all__=['name']

打开 python console 验证一下

>>> from profile import * 
>>> print(name) 
小明 
>>> print(age) 
Traceback (most recent call last): 
  File "", line 1, in  
NameError: name 'age' is not defined 
__all__ 仅对于使用 from module import * 这种情况适用。

它经常在一个包的 __init__.py 中出现。

2. 命名空间包的神奇之处

命名空间包,对于不少人来说,可能是一个陌生的名字。

与我们熟悉的常规包不同的是,它没有 __init__.py 文件。

更为特殊的是,它可以跨空间地将两个不相邻的子包,合并成一个虚拟机的包,我们将其称之为 命名空间包。

例如,一个项目的部分代码布局如下

foo-package/ 
    spam/ 
        blah.py 
 
bar-package/ 
    spam/ 
        grok.py

在这 2 个目录里,都有着共同的命名空间 spam。在任何一个目录里都没有__init__.py 文件。

让我们看看,如果将 foo-package 和 bar-package 都加到 python 模块路径并尝试导入会发生什么?

>>> import sys 
>>> sys.path.extend(['foo-package', 'bar-package']) 
>>> import spam.blah 
>>> import spam.grok 
>>>

当一个包为命名空间包时,他就不再和常规包一样具有 __file_ 属性,取而代之的是 __path__

>>> import sys 
>>> sys.path.extend(['foo-package', 'bar-package']) 
>>> import spam.blah 
>>> import spam.grok 
>>>spam.__path__ 
_NamespacePath(['foo-package/spam', 'bar-package/spam']) 
>>> spam.__file__ 
Traceback (most recent call last): 
    File "", line 1, in  
AttributeError: 'module' object has no attribute '__file__' 
3. 模块重载中的一个坑

由于有 sys.modules 的存在,当你导入一个已导入的模块时,实际上是没有效果的。

为了达到模块的重载,有的人会将已导入的包从 sys.modules 中移除后再导入

就像下面这样子

>>> import foo.bar 
successful to be imported 
>>> 
>>> import foo.bar 
>>> 
>>> import sys 
>>> sys.modules['foo.bar'] 
 
>>> del sys.modules['foo.bar'] 
>>> 
>>> import foo.bar 
successful to be imported 

上面的例子里我使用的是 import foo.bar,如果你使用的是 from foo import bar 这种导入形式,会发现重载是同样是无效的。

这应该算是一个小坑,不知道的人,会掉入坑中爬不出来。

>>> import foo.bar 
successful to be imported 
>>> 
>>> import foo.bar 
>>> 
>>> import sys 
>>> del sys.modules['foo.bar'] 
>>> from foo import bar 
>>>

因此,在生产环境中可能需要避免重新加载模块。而在调试模式中,它会提供一定的便利,但你要知道这个重载的弊端,以免掉入坑里。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-25发表,共计1766字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中