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

28 篇文章 0 订阅
24 篇文章 1 订阅

1.模块

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

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

       

          

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

def add(x,y):
    return x+y
def subtract(x,y):
    return x-y
def mul(x,y):
    return x*y
def divide(x,y):
    return x/y

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

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

      打印结果如下:

      

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

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

def add(x,y):
    return x+y
def subtract(x,y):
    return x-y
def mul(x,y):
    return x*y
def divide(x,y):
    return x/y
print(mul(5,6))

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

import operator
print(operator.add(2,3))
     先看下打印结果,如下:

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

import operator
        打印结果如下:

         

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

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

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

        

def add(x,y):
    return x+y
def subtract(x,y):
    return x-y
def mul(x,y):
    return x*y
def divide(x,y):
    return x/y
print("operator-name:",__name__)
         

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

       

import operator
print("main:",__name__)
       打印结果如下:

        

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

       

def add(x,y):
    return x+y
def subtract(x,y):
    return x-y
def mul(x,y):
    return x*y
def divide(x,y):
    return x/y
if __name__=='__main__':
    print(mul(5,6))

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

       

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

       执行结果如下:

       

            

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

 2.Python中模块的调用顺序

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

        打印结果如下:

        


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

          

def capitalize(x):
    return 'hello world'

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

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

           

import str
s="zhangsan"
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中的代码如下:

          

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

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

          方法有三种。

           方法一:

           

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

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

打印结果如下:

            

            方法二:

            

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

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

            

           方法三:

            

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

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

                 

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值