Python学习(15)--包和模块

简介: Python学习(15)--包和模块 1.模块 为了更好的组织代码,以及让用户更方便的调用所提供的内置函数,Python将相关代码封装到了模块中,那么什么是模块呢?其实就是我们平时编写Python代码时写的后缀为py的文件。

Python学习(15)--包和模块

1.模块

为了更好的组织代码,以及让用户更方便的调用所提供的内置函数,Python将相关代码封装到了模块中,那么什么是模块呢?其实就是我们平时编写Python代码时写的后缀为py的文件。比如,Python为我们提供的有关字符串处理的函数就封装在string这个模块中,对应到Python中的代码文件就是string.py。

Python为我们提供模块都在安装目录下的lib文件夹下,如下:

通过截图可以看到lib文件夹下的.py文件,这些文件都是Python提供的供我们调用的模块。当然用户也可以使用自己定义的模块,如下我在我的项目文件下编写了一个模块文件,operator.py,模块名为operator,模块为我们提供了4个运算函数,分别实现运算数的加减乘除操作,operator.py的代码如下:

[python] view plain copy

  1. <span style="font-size:24px;">def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y</span>

那么写好模块之后又如何使它呢?使用模块之前需要导入模块,导入模块方法为import 模块名。调用模块中的函数方法为:模块名.函数名。具体代码例子如下:

[python] view plain copy

  1. <span style="font-size:24px;">import operator
  2. print(operator.add(2,3))</span>

打印结果如下:

如上先导入模块operator,之后再调用模块operator为我们提供的方法add(x,y)。

下面我们来对operator.py做一些修改。如下:

[python] view plain copy

  1. <span style="font-size:24px;">def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. print(mul(5,6))</span>

如上所示,我们在文件最后调用函数mul(x,y),并打印返回结果。然后我们再次调用operator模块,调用代码如下:

[python] view plain copy

  1. <span style="font-size:24px;">import operator
  2. print(operator.add(2,3))</span>

先看下打印结果,如下:


可以看到和之前相同的调用operator模块的代码,打印结果却和之前不一样,先打印了30,才打印出调用模块时代码执行的结果。那么打印结果30是怎么来的呢?其实这是调用模块operator执行其中的代码导致的结果。之前我们修改了operator中的代码,在最后加了一句print(mul(5,6)),在调用operator执行了这段代码,于是打印出了30。怎么证明这个30就是因为调用operator模块打印出来的呢?下面我们直接调用operator模块,并不做其他操作,只是导入模块。如下:

[python] view plain copy

  1. <span style="font-size:24px;">import operator</span>

打印结果如下:

我们只是导入operator模块就打印了30,从而以上的叙述得到证明。然而我们在调用模块时,有时候并不希望执行被调用模块中的代码,因为这最后得到的结果可能会干扰我们对主模块结果的分析。

那么如何避免正在执行的主模块在调用其他模块时,可以不用执行被调用的模块中的相关代码呢?一个比较笨的办法就是把那些代码全部删除,但是被调用的模块之前可能也是一个主模块,这样做如果之后再次用到这个模块中的代码必须得重写,比较麻烦。下面介绍利用内置属性__name__来解决这一问题。

前面我们介绍过Python为我们提供的各种内置函数,同样也为我们提供了内置属性,可以把它理解为一个Python为我们提供的一个全局变量。内置属性__name__表示当前模块的模块名,如果是正在执行的主模块,那么__name__='__main__';如果是被调用模块那么__name__=模块名 下面我们再修改下operator.py中的代码,如下:

 

[python] view plain copy

  1. def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. print("operator-name:",__name__)

 

在最后我们添加了一句,print("operator-name:",name),即打印当前模块的内置属性__name__,主模块代码如下:

 

[python] view plain copy

  1. import operator
  2. print("main:",__name__)

打印结果如下:

可以看到当调用模块operator时,执行了我们修改之后添加的语句print("operator-name:",__name__),打印出来的模块operator的__name__属性值为'operator',即模块名。主调用模块的__name__=='__main__',可见可以通过__name__属性来区分一个模块是主模块还是被调用模块。既然能够区分两者,那么通过判断__name__属性值,如果一个模块是被调用模块的话,相关代码就不执行,修改operator.py的代码如下:

 

[python] view plain copy

  1. def add(x,y):
  2.     return x+y
  3. def subtract(x,y):
  4.     return x-y
  5. def mul(x,y):
  6.     return x*y
  7. def divide(x,y):
  8.     return x/y
  9. if __name__=='__main__':
  10.     print(mul(5,6))

 

如上通过判断operator模块的内置属性是否为"__main__",如果是则表示operator为当前正在执行的主模块,可以执行operator模块中的相关代码;否则就是被调用模块,不执行相关代码。主调用模块代码如下:

 

[python] view plain copy

  1. import operator
  2. print(operator.add(2,3))

 

执行结果如下:

 

通过打印结果可以看到,在主模块中调用operator模块时并没有执行operator模块中的相关代码,以上问题得到解决。

 2.Python中模块的调用顺序

      当我们调用一个模块时,Python会首先检查当前模块是否为用户自定义的模块,即在当前项目路径下是否存在该模块,如果没有,Python会在lib文件夹下搜索该模块,如果还没有,则报错该模块没有定义。
       下面以字符串处理函数capitalize(x)为例,这是模块str提供的一个内置函数,之前我们介绍过,功能为将字符串x首字母小写变大写。代码例子如下:

[python] view plain copy

  1. s="zhangsan"
  2. print(str.capitalize(s))

打印结果如下:

下面我们在项目路径下定义一个与Python中str模块重名的模块,str.py。在这个自定义模块str中,我们定义一个函数capitalize(x),如下:

 

[python] view plain copy

  1. def capitalize(x):
  2.     return 'hello world'

 

自定义模块str中的capitalize(x)函数很简单,只是返回一个字符串"hello world".

下面是调用这个自定义str模块的代码:

 

[python] view plain copy

  1. import str
  2. s="zhangsan"
  3. print(str.capitalize(s))

 

打印结果如下:

通过打印结果发现,Python调用的函数实质上是我们自定义模块str中的capitalize(x)函数,而不是Python中的内置函数capitalize(x),这其实与Python调用模块的顺序有关。

在Python中调用一个模块时,Python会先检查该模块是否是用户自定义的模块,如上我们自定义了一个模块str,这个模块与Python中lib文件夹下的str模块重名,可以说是因为重名,我们的自定义模块把Python中的预定义str模块给覆盖住了,所以最终调用的函数是自定义模块str中的capitalize(x)函数,这也提醒我们在自定义模块时不要与系统的预定义模块重名,以免引起不必要的麻烦。

3.包

      在Python中,包其实就是模块的集合,一个包可以包含许多模块,也可以包含其他的包。对应的文件结构就是,一个文件夹中包含其他的文件夹或者若干的.py文件,包含的其他文件夹又可以包含其他文件夹或者若干的.py文件,是一个层层迭代的树形结构。
        下面我们来介绍下如何建一个自定义的包,如下:
         第一步,在项目路径下新建一个文件夹,文件夹的名字就是包名;
         第二步,在刚才的新建文件夹下,新建__init__.py文件,这个文件包含了包的一些信息,可以什么都不写,但必须要有;
         第三步,最后就可以在文件夹下新建其他包(文件夹),或者模块(.py文件)了。
         我使用Python集成开发环境是pycharm。可以看到文件结构如下:
         

可以看到,我们自定义了一个名为data的包,包下有一个模块food,food.py中的代码如下:

 

[python] view plain copy

  1. def eat(x):
  2.     print('I like to eat',x)

 

新建完包及包内模块后,那么如何调用模块中为我们提供的功能函数呢?

方法有三种。

方法一:

 

[python] view plain copy

  1. import data.food
  2. data.food.eat('rice')

 

方法一,先导入模块,再调用模块中的函数;导入模块的方式为,包名.模块名,如data.food;调用函数的方式为包名.模块名.函数名,如data.food.eat("rice")。

打印结果如下:

方法二:

 

[python] view plain copy

  1. import data.food as food
  2. food.eat('apple')

 

有时候我们在引入一个模块的时候,由于包的层层嵌套的问题,被引入模块可能要经过很多个包才能被被导入,比如data.fooddata.likefood.food,引入food这个模块经过了data,fooddata,likefood多个包,在调用模块food提供的函数时,也要写这么一大串,程序写起来很不方便,可读性也比较差。为了方便,我们可以为被导入模块起一个别名,如上import data.food as food 就是为被导入模块data.food起别名为food,调用函数的方法为模块别名.函数,如food.eat("apple"),程序打印结果如下:

方法三:

 

[python] view plain copy

  1. from data.food import eat
  2. eat('barbecue')

 

有时候为了方便调用模块为我们提供的函数,也可以直接把函数引入,引入方法为from 包名.模块名 import 函数名,如from data.food import eat;这样就可以直接调用函数,而不需要在函数之前指定包名或模块名.更加方面可读.代码打印结果如下:

以上就是引入模块的三种方法,熟练使用它们可以方便高效的编写代码.

下一节我们将介绍正则表达式,敬请期待。

原文地址http://www.bieryun.com/2341.html

相关文章
|
1天前
|
运维 Shell Python
Shell和Python学习教程总结
Shell和Python学习教程总结
|
1天前
|
Python
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
|
1天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
1天前
|
数据采集 数据可视化 数据处理
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
|
1天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
2天前
|
开发者 Python
Python的os模块详解
Python的os模块详解
15 0
|
5天前
|
数据挖掘 API 数据安全/隐私保护
python请求模块requests如何添加代理ip
python请求模块requests如何添加代理ip
|
7天前
|
测试技术 Python
Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘
Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘
|
7天前
|
Serverless 开发者 Python
《Python 简易速速上手小册》第3章:Python 的函数和模块(2024 最新版)
《Python 简易速速上手小册》第3章:Python 的函数和模块(2024 最新版)
39 1
|
1月前
|
Python
python中导入模块/包的几种方式
python中导入模块/包的几种方式
25 0

热门文章

最新文章