Python中模块(Module)和包(Package)的区别
<h4 id="1-模块module">1. 模块(Module)</h4><p>在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。</p>
<p>为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个<code>.py</code>文件就称之为一个<em>模块(Module)</em>。</p>
<p><strong>使用模块有什么好处?</strong></p>
<p>最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。</p>
<p>使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。</p>
<p>你也许还想到,如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为<em>包(Package)</em>。</p>
<p>举个例子,一个<code>abc.py</code>的文件就是一个名字叫<code>abc</code>的模块,一个<code>xyz.py</code>的文件就是一个名字叫<code>xyz</code>的模块。</p>
<p>现在,假设我们的<code>abc</code>和<code>xyz</code>这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如<code>mycompany</code>,按照如下目录存放</p>
<pre><code>mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py
</code></pre>
<p> 引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,<code>abc.py</code>模块的名字就变成了<code>mycompany.abc</code>,类似的,<code>xyz.py</code>的模块名变成了<code>mycompany.xyz</code>。</p>
<p>请注意,每一个包目录下面都会有一个<code>__init__.py</code>的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。<code>__init__.py</code>可以是空文件,也可以有Python代码,因为<code>__init__.py</code>本身就是一个模块,而它的模块名就是mycompany。</p>
<p>类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:</p>
<pre><code>mycompany
├─ web
│├─ __init__.py
│├─ utils.py
│└─ www.py
├─ __init__.py
├─ abc.py
└─ xyz.py
</code></pre>
<p>文件<code>www.py</code>的模块名就是<code>mycompany.web.www</code></p>
<p>Notes: 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。</p>
<h4 id="2-使用模块">2. 使用模块</h4>
<p>Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。</p>
<p>我们以内建的<code>sys</code>模块为例,编写一个<code>hello</code>的模块:</p>
<pre><code>
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'Michael Liao'
import sys
def test():
args = sys.argv # argv参数用列表存储命令行的所有参数
if len(args)==1:# 当列表长度为1时即只有一个参数时
print('Hello, world!')
elif len(args)==2: # 当命令行有两个参数时
print('Hello, %s!' % args)
else:
print('Too many arguments!')
if __name__=='__main__':
test()
</code></pre>
<p>第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;</p>
<p>第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;</p>
<p>第6行使用<code>__author__</code>变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;</p>
<p>以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。</p>
<p>后面开始就是真正的代码部分。</p>
<p>你可能注意到了,使用<code>sys</code>模块的第一步,就是导入该模块:</p>
<pre><code>import sys
</code></pre>
<p>导入<code>sys</code>模块后,我们就有了变量<code>sys</code>指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。</p>
<p><code>sys</code>模块有一个<code>argv</code>变量,用<code>list</code>存储了命令行的所有参数。<code>argv</code>至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:</p>
<p>运行<code>python3 hello.py</code>获得的<code>sys.argv</code>就是<code>['hello.py']</code>,注意这里<code>python3</code>不算是参数;</p>
<p>运行<code>python3 hello.py Michael</code>获得的<code>sys.argv</code>就是<code>['hello.py', 'Michael]</code>。</p>
<p>最后,注意到这两行代码:</p>
<pre><code>if __name__=='__main__':
test()
</code></pre>
<p>当我们在命令行运行<code>hello</code>模块文件时,Python解释器把一个特殊变量<code>__name__</code>置为<code>__main__</code>,而如果在其他地方导入该<code>hello</code>模块时,<code>if</code>判断将失败,因此,这种<code>if</code>测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。</p>
<p>我们可以用命令行运行<code>hello.py</code>看看效果:</p>
<pre><code>$ python3 hello.py
Hello, world!
$ python hello.py Michael
Hello, Michael!
</code></pre>
<p>如果启动Python交互环境,再导入<code>hello</code>模块:</p>
<pre><code>>>> import hello
>>>
</code></pre>
<p>导入时,没有打印<code>Hello, word!</code>,因为没有执行<code>test()</code>函数。</p>
<p>调用<code>hello.test()</code>时,才能打印出<code>Hello, word!</code>:</p>
<pre><code>>>> hello.test()
Hello, world!
</code></pre><br><br>
来源:https://www.cnblogs.com/xxpythonxx/p/11311900.html
頁:
[1]