搞懂Python包之后,感觉学Python轻松多了1.前言2.Python包3.包初始化4.Importing * From a Package5.子包( 二 )
importpkg.mod1,pkg.mod2
然后当你执行importpkg , 模块mod1和mod2自动导入:
>>>importpkg
Invoking__init__.pyforpkg
>>>pkg.mod1.foo()
[mod1]foo()
>>>pkg.mod2.bar()
[mod2]bar()
注意:大部分Python文档都声明在创建包时必须在包目录中存在__init__.py文件 。 这曾经是必须的 。 过去 , __init__.py的存在对Python来说意味着正在定义一个包 。 该文件可以包含初始化代码 , 甚至可以为空 , 但它必须存在 。 从Python3.3开始 , 引入了隐式命名空间包 。 这些允许创建一个没有任何__init__.py文件的包 。 当然 , 如果需要包初始化 , 它仍然可以存在 。 但现在不再是必须的了 。 4.Importing*FromaPackage为了以下讨论的目的 , 先前定义的包被扩展以包含一些额外的模块:
pkg
├──mod1.py
├──mod2.py
├──mod3.py
└──mod4.py
pkg目录中现在定义了四个模块 。 其内容如下:
mod1.py
deffoo():
print('[mod1]foo()')
classFoo:
pass
mod2.py
defbar():
print('[mod2]bar()')
classBar:
pass
mod3.py
defbaz():
print('[mod3]baz()')
classBaz:
pass
mod4.py
defqux():
print('[mod4]qux()')
classQux:
pass
正如你所看到 , 当import*用于一个模块时 , 该模块中的所有对象都被导入到本地符号表中 , 除了那些名称以下划线开头的对象:
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__']
>>>frompkg.mod3import*
>>>dir()
['Baz','__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__','baz']
>>>baz()
[mod3]baz()
>>>Baz
<class'pkg.mod3.Baz'>
一个包的类似声明是这样的:
from<package_name>import*
这行代码做了什么呢?
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__']
>>>frompkgimport*
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__']
嗯 。 好像什么也没做 。 你可能期望Python会深入到包目录中 , 找到它所能找到的所有模块 , 并将它们全部导入 。 但正如你所看到的 , 默认情况下并不是这样的 。
相反 , Python遵循以下约定:如果包目录中的__init__.py文件包含名为__all__的列表 , 当遇到import*语句时 , 它将被视为应该导入的模块列表 。
对于现在的例子 , 假设你像这样在pkg目录中创建一个__init__.py:
pkg/__init__.py
__all__=[
'mod1',
'mod2',
'mod3',
'mod4'
]
现在用import*导入所有四个模块:
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__']
>>>frompkgimport*
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__','mod1','mod2','mod3','mod4']
>>>mod2.bar()
[mod2]bar()
>>>mod4.Qux
<class'pkg.mod4.Qux'>
使用import*仍然不被认为是很好的形式 , 无论是对包还是模块来说都是如此 。 但是这个功能至少让包的创建者对指定import*时发生的事情有一定的控制 。 (事实上 , 它提供了完全禁止它的能力 , 只要拒绝定义__all__就行了 。 如你所见 , 包的默认行为是不导入任何内容 。 )
顺便说一下 , __all__也可以在模块中定义 , 并达到同样的目的:控制import*导入的内容 。 例如 , 修改mod1.py如下:pkg/mod1.py
__all__=['foo']
deffoo():
print('[mod1]foo()')
classFoo:
pass
现在 , pkg.mod1中的import*语句只会导入包含在__all__中的内容:
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__']
>>>frompkg.mod1import*
>>>dir()
['__annotations__','__builtins__','__doc__','__loader__','__name__',
'__package__','__spec__','foo']
>>>foo()
[mod1]foo()
>>>Foo
Traceback(mostrecentcalllast):
File"<pyshell#37>",line1,in<module>
Foo
NameError:name'Foo'isnotdefined
foo()(函数)现在定义在本地命名空间中 , 但foo(类)没有定义 , 因为后者不在__all__中 。
总之 , 当import*被指定时 , __all__会被包和模块用来控制导入的内容 。 但是默认行为是不同的:
对于一个包:当__all__没有定义,import*不导入任何东西 。 对于一个模块:当__all__没有定义,import*导入所有内容(除了以下划线开头的名称) 。
5.子包包可以包含任意深度的嵌套子包 。 例如 , 让我们对示例包目录再做一个修改 , 如下所示:
- Python各种进制之间的转换方法
- 继语音包之后张大仙再获特权,率先体验露娜新皮肤,官方给足牌面
- 还没搞懂数据挖掘?一款易学易用的工具来帮你!
- 终于有人把Python讲清楚了!
- 手机最强 Python 编程神器,Android、IOS 都可以!
- SQL Server 2014+MongoDB+Python数据库技术及应用(教学大纲)
- 许愿神器来了 ,30行Python打造了一款许愿墙,希望能追到女神!
- Python被称作“数据分析之王”的原因
- Python30岁,先驱:没想到Python这么流行
- Python 的类其实是一个特殊的对象
