草根学Python(八) 模块与包

前言

以前的文章都是使用Sublime Text来编写 Python 的,主要是为了更好的熟悉和了解 Python ,但是开发效率不高,也不方便,从这章开始,改成使用 Pycharm 了,在以前的篇节集成开发环境(IDE): PyCharm中介绍了 PyCharm ,若是如要激活软件能够经过受权服务器来激活,具体看这个网址。JetBrains激活(http://www.imsxm.com/jetbrains-license-server.html)固然你也能够尝试破解, Pycharm2017.1.1破解方式,不过对于软件的升级不方便。html

目录

草根学Python(八)  模块与包
草根学Python(八) 模块与包

1、Python 模块简介

在开发过程当中,随着程序代码越写越多,在一个文件里代码就会愈来愈长,愈来愈不容易维护。python

为了编写可维护的代码,咱们把不少函数分组,分别放到不一样的文件里,这样,每一个文件包含的代码就相对较少,不少编程语言都采用这种组织代码的方式。在 Python 中,一个 .py 文件就称之为一个模块(Module)。android

以前咱们学习过函数,知道函数是实现一项或多项功能的一段程序 。其实模块就是函数功能的扩展。为何这么说呢?那是由于模块其实就是实现一项或多项功能的程序块。编程

经过上面的定义,不难发现,函数和模块都是用来实现功能的,只是模块的范围比函数广,在模块中,能够有多个函数。服务器

居然了解了什么是模块了,那么为何须要模块呢?居然有了函数,那为啥那须要模块?微信

最大的好处是大大提升了代码的可维护性。其次,编写代码没必要从零开始。当一个模块编写完毕,就能够被其余地方引用。咱们在编写程序的时候,也常常引用其余模块,包括 Python 内置的模块和来自第三方的模块。编程语言

使用模块还能够避免函数名和变量名冲突。相同名字的函数和变量彻底能够分别存在不一样的模块中,所以,咱们本身在编写模块时,没必要考虑名字会与其余模块冲突。可是也要注意,尽可能不要与内置函数名字冲突。函数

Python 自己就内置了不少很是有用的模块,只要安装完毕,这些模块就能够马上使用。咱们能够尝试找下这些模块,好比个人 Python 安装目录是默认的安装目录,在 C:\Users\Administrator\AppData\Local\Programs\Python\Python36 ,而后找到 Lib 目录,就能够发现里面所有都是模块,没错,这些 .py 文件就是模块了。性能

python36bin目录
python36bin目录

其实模块能够分为标准库模块和自定义模块,而刚刚咱们看到的 Lib 目录下的都是标准库模块。学习

2、模块的使用

一、import

Python 模块的使用跟其余编程语言也是相似的。你要使用某个模块,在使用以前,必需要导入这个模块。导入模块咱们使用关键字 import

import 的语法基本以下:

import module1[, module2[,... moduleN]复制代码

好比咱们使用标准库模块中的 math 模块。当解释器遇到 import 语句,若是模块在当前的搜索路径就会被导入。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import math

_author_ = '两点水'

print(math.pi)复制代码

输出的结果:

3.141592653589793复制代码

一个模块只会被导入一次,无论你执行了多少次 import。这样能够防止导入模块被一遍又一遍地执行。

当咱们使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?

这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量,事实上,也能够经过定义环境变量的方式来肯定搜索路径。搜索路径是在 Python 编译或安装的时候肯定的,安装新的库应该也会修改。搜索路径被存储在sys 模块中的 path 变量 。

所以,咱们能够查一下路径:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import sys

print(sys.path)复制代码

输出结果:

['C:\\Users\\Administrator\\Desktop\\Python\\Python8Code', 'G:\\PyCharm 2017.1.4\\helpers\\pycharm', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\Desktop\\Python\\Python8Code\\com\\Learn\\module\\sys']复制代码

二、from···import

有没有想过,怎么直接导入某个模块中的属性和方法呢?

Python 中,导入一个模块的方法咱们使用的是 import 关键字,这样作是导入了这个模块,这里须要注意了,这样作只是导入了模块,并无导入模块中具体的某个属性或方法的。而咱们想直接导入某个模块中的某一个功能,也就是属性和方法的话,咱们可使用 from···import 语句。

语法以下:

from modname import name1[, name2[, ... nameN]]复制代码

看完简介后可能会想, from···importimport 方法有啥区别呢?

想知道区别是什么,观察下面两个例子:

import 导入 sys 模块,而后使用 version 属性

from···import和 import的区别1
from···import和 import的区别1

from···import 直接导入 version 属性

from···import和 import的区别2
from···import和 import的区别2

三、from ··· import *

经过上面的学习,咱们知道了 from sys import version 能够直接导入 version 属性。可是若是咱们想使用其余的属性呢?好比使用 sys 模块中的 executable ,难道又要写多一句 from sys import executable ,两个还好,若是三个,四个呢?难道要一直这样写下去?

这时候就须要 from ··· import * 语句了,这个语句能够把某个模块中的全部方法属性都导入。好比:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

from sys import *

print(version)
print(executable)复制代码

输出的结果为:

3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)]
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe复制代码

注意:这提供了一个简单的方法来导入一个模块中的全部方法属性。然而这种声明不应被过多地使用。

3、主模块和非主模块

一、主模块和非主模块的定义

在 Python 函数中,若是一个函数调用了其余函数完成一项功能,咱们称这个函数为主函数,若是一个函数没有调用其余函数,咱们称这种函数为非主函数。主模块和非主模块的定义也相似,若是一个模块被直接使用,而没有被别人调用,咱们称这个模块为主模块,若是一个模块被别人调用,咱们称这个模块为非主模块。

二、name 属性

在 Python 中,有主模块和非主模块之分,固然,咱们也得区分他们啊。那么怎么区分主模块和非主模块呢?

这就须要用到 __name__ 属性了,这个 ——name—— 属性值是一个变量,且这个变量是系统给出的。利用这个变量能够判断一个模块是不是主模块。若是一个属性的值是 __main__ ,那么就说明这个模块是主模块,反之亦然。可是要注意了: 这个 __main__ 属性只是帮助咱们判断是不是主模块,并非说这个属性决定他们是不是主模块,决定是不是主模块的条件只是这个模块有没有被人调用

具体看示例:

首先建立了模块 lname ,而后判断一下是不是主模块,若是是主模块就输出 main 不是,就输出 not main ,首先直接运行该模块,因为该模块是直接使用,而没有被人调用,因此是主模块,所以输出了 main ,具体看下图:

name属性区分模块1
name属性区分模块1

而后又建立一个 user_lname 模块,里面只是简单的导入了 lname 模块,而后执行,输出的结果是 not main ,由于 lname 模块被该模块调用了,因此不是主模块,输出结果如图:

name属性区分模块2
name属性区分模块2

4、包

包,其实在上面的一些例子中,都建立了不一样的包名了,具体能够仔细观察。在一开始模块的简介中提到,使用模块能够避免函数名和变量名冲突。相同名字的函数和变量彻底能够分别存在不一样的模块中,所以,咱们本身在编写模块时,没必要考虑名字会与其余模块冲突。可是也要注意,尽可能不要与内置函数名字冲突。可是这里也有个问题,若是不一样的人编写的模块名相同怎么办?为了不模块名冲突,Python 又引入了按目录来组织模块的方法,称为包(Package)。

好比最开始的例子,就引入了包,这样子作就算有相同的模块名,也不会形成重复,由于包名不一样,其实也就是路径不一样。以下图,引入了包名后, lname.py 其实变成了 com.Learn.module.nameattributes.lname

Python 包
Python 包

仔细观察的人,基本会发现,每个包目录下面都会有一个 __init__.py 的文件,为何呢?

由于这个文件是必须的,不然,Python 就把这个目录当成普通目录,而不是一个包 。 __init__.py 能够是空文件,也能够有Python代码,由于 __init__.py 自己就是一个模块,而它对应的模块名就是它的包名。

5、做用域

学习过 Java 的同窗都知道,Java 的类里面能够给方法和属性定义公共的( public )或者是私有的 ( private ),这样作主要是为了咱们但愿有些函数和属性能给别人使用或者只能内部使用。 经过学习 Python 中的模块,其实和 Java 中的类类似,那么咱们怎么实如今一个模块中,有的函数和变量给别人使用,有的函数和变量仅仅在模块内部使用呢?

在 Python 中,是经过 _ 前缀来实现的。正常的函数和变量名是公开的(public),能够被直接引用,好比:abc,ni12,PI等;相似__xxx__这样的变量是特殊变量,能够被直接引用,可是有特殊用途,好比上面的 __name__ 就是特殊变量,还有 __author__ 也是特殊变量,用来标明做者。注意,咱们本身的变量通常不要用这种变量名;相似 _xxx__xxx 这样的函数或变量就是非公开的(private),不该该被直接引用,好比 _abc__abc 等;

注意,这里是说不该该,而不是不能。由于 Python 种并无一种方法能够彻底限制访问 private 函数或变量,可是,从编程习惯上不该该引用 private 函数或变量。

好比:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

def _diamond_vip(lv):
    print('尊敬的钻石会员用户,您好')
    vip_name = 'DiamondVIP' + str(lv)
    return vip_name


def _gold_vip(lv):
    print('尊敬的黄金会员用户,您好')
    vip_name = 'GoldVIP' + str(lv)
    return vip_name


def vip_lv_name(lv):
    if lv == 1:
        print(_gold_vip(lv))
    elif lv == 2:
        print(_diamond_vip(lv))


vip_lv_name(2)复制代码

输出的结果:

尊敬的钻石会员用户,您好
DiamondVIP2复制代码

在这个模块中,咱们公开 vip_lv_name 方法函数,而其余内部的逻辑分别在 vip_lv_namevip_lv_name private 函数中实现,由于是内部实现逻辑,调用者根本不须要关心这个函数方法,它只需关心调用 vip_lv_name 的方法函数,因此用 private 是很是有用的代码封装和抽象的方法

通常状况下,外部不须要引用的函数所有定义成 private,只有外部须要引用的函数才定义为 public。


最后扯淡,欢迎加我微信:androidwed,进入微信Python讨论群,一块儿学习讨论。如今微信群只有50几我的.

相关文章
相关标签/搜索