零基础入门学Python(十三)—— 模块

零基础入门学Python系列内容的学习目录 → \rightarrow →零基础入门学Python系列内容汇总

  需要学习的基础知识有:模块、命名空间、导入模块、搜索路径、包等。

1. 模块就是程序

  模块可以看作是更高级的封装。谈及封装:

  • 容器,例如列表、元组、字符串、字典等,是对数据的封装;
  • 函数,是对语句的封装;
  • ,是对方法和属性的封装,也就是对函数和数据的封装。

  模块也可以说就是程序。我们平时写的任何代码,保存的每一个.py结尾的文件,都是一个独立的模块。例如我们在Python的安装目录下创建一个叫hello.py的文件,代码如下:

def hi():
    print("Hello, Python!")

  当我们把这个文件保存起来的时候,它就是一个独立的Python模块了(注意:为了让默认的IDLE可以找到这个模块,需要把文件放在Python的安装目录下)。
  这时就可以在IDLE中导入模块了:

  >>> import hello
  接下来试试调用一下hello模块中的hi函数:
  >>> hi()
  Traceback(most recent call last):
   File"<pyshell#1>", line 1, in< module >
    hi()
  NameBrror:name ‘hi’ is not defined

  出错的原因是Pyhon找不到hi()这个函数。为什么会这样呢?明明我们在hello.py文件中已经定义了hi()函数,这里Pyhon却说我们未定义,具体原因我们稍后再进行解释。

2. 命名空间

  命名空间(Namespace)表示标识符(identifier)的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。
  在Python中,每个模块都会维护一个独立的命名空间,我们应该将模块名加上,才能够正常使用模块中的函数:

  >>> hello.hi()
  Hello, Python!

3. 导入模块

  下面介绍一下几种导入模块的方法。新建一个名为interconversion_Celsius_Fahrenheit.py的文件,用于计算摄氏度和华氏度的相互转换:

def c2f(cel):
    fah = cel * 1.8 + 32
    return fah

def f2c(fah):
    cel = (fah - 32)/ 1.8
    return cel
  1. import模块名
      直接import,在调用模块中的函数的时候需要加上模块的命名空间。
      import模块名导入模块:
      >>> import interconversion_Celsius_Fahrenheit
      >>> print(“32摄氏度 = %.2f华氏度” % interconversion_Celsius_Fahrenheit.c2f(32))
      32摄氏度 = 89.60华氏度
      >>> print(“99华氏度 = %.2f摄氏度” % interconversion_Celsius_Fahrenheit.f2c(99))
      99华氏度 = 37.22摄氏度

  2. from 模块名 import 函数名
      这种导入方法会直接将模块的命名空间覆盖进来,所以调用的时候也就不需要再加上命名空间了。
      from 模块名 import 函数名导入模块:
      >>> from interconversion_Celsius_Fahrenheit import c2f, f2c
      >>> print(“32摄氏度 = %.2f华氏度” % c2f(32))
      32摄氏度 = 89.60华氏度
      >>> print(“99华氏度 = %.2f摄氏度” % f2c(99))
      99华氏度 = 37.22摄氏度
      这里还可以使用通配符星号(*)来导入模块中所有的命名空间:
      >>> from interconversion_Celsius_Fahrenheit import *
      但是强烈要求大家不要使用这种方法,因为这样做会使得命名空间的优势荡然无存,一不小心还会陷入名字混乱的局面。

  3. import 模块名 as 新名字
      这种方法是极力推崇的,我们可以用这种方法给导入的命名空间替换一个新的名字。
      import 模块名 as 新名字导入模块:
      >>> import interconversion_Celsius_Fahrenheit as tc
      >>> print(“32摄氏度 = %.2f华氏度” % tc.c2f(32))
      32摄氏度 = 89.60华氏度
      >>> print(“99华氏度 = %.2f摄氏度” % tc.f2c(99))
      99华氏度 = 37.22摄氏度

4. _ _ name _ _ = ‘_ _ main _ _’

  模块的主要作用:

  1. 封装组织Python的代码;
  2. 实现代码的重用。

  当我们在阅读别人代码时,会发现很多代码中都有_ _name_ _ = '_ _main_ _'这么一行语句,它的作用下面为大家揭晓。
  先举个例子(新建文件interconversion_Celsius_Fahrenheit.py),一般写完代码要先测试下:

def c2f(cel):
    fah = cel * 1.8 + 32
    return fah

def f2c(fah):
    cel = (fah - 32)/1.8
    return cel

def test():
    print("测试,0摄氏度 = %.2f华氏度" % c2f(0))
    print("测试,0华氏度 = %.2f摄氏度" % f2c(0))

test()

  我们单独运行它是没问题的:
  >>>
  测试,0摄氏度 = 32.00华氏度
  测试,0华氏度 = -17.78摄氏度
  >>>

  但如果是在另一个文件中导入后再调用:

import interconversion_Celsius_Fahrenheit as tc
print("32摄氏度 = %.2f华氏度" % tc.c2f(32))
print("99华氏度 = %.2f摄氏度" % tc.f2c(99))

  就会出现问题:
  >>>
  测试,0摄氏度 = 32.00华氏度
  测试,0华氏度 = -17.78摄氏度
  32摄氏度 = 89.60华氏度
  99华氏度 = 37.22摄氏度
  >>>

  Python把模块(interconversion_Celsius_Fahrenheit.py)中的测试函数也一块儿执行了,避免这种情况的关键在于:让Python知道该模块是作为程序运行还是导入到其他程序中。为了实现这一点,需要使用模块的_ _name_ _属性:

  >>> _ _ name _ _
  ‘_ _ main _ _’
  >>> tc. _ _ name _ _
  ‘interconversion_Celsius_Fahrenheit’

  在作为程序运行的时候,_ _name_ _属性的值是'_ _main_ _',而作为模块导入的时候,这个值就是该模块的名字了。因此,就不难理解if _ _name_ _ = '_ _main_ _'这句代码的意思了。

def c2f(cel):
    fah = cel * 1.8 + 32
    return fah

def f2c(fah):
    cel = (fah - 32)/1.8
    return cel

def test():
    print("测试,0摄氏度 = %.2f华氏度" % c2f(0))
    print("测试,0华氏度 = %.2f摄氏度" % f2c(0))

if __name__ == '__main__':
    test()

  上面的代码if _ _name_ _ = '_ _main_ _'确保只有在单独运行上面Python文件时,才会执行test()函数。

5. 搜索路径

  Python模块的导入需要一个路径搜索的过程。就是说,我们导入一个叫作hello的模块,那么Python会在预定义好的搜索路径中寻找一个叫作hello.py的模块文件——如果有,则导入模块;如果没有,则导入失败。而搜索路径就是一组目录,可以通过sys模块中的path变量显示出来(不同的机器上显示的路径信息可能不一样):

  >>> import sys
  >>> sys.path
  [‘C:\ \Users\ \Administrator\ \Desktop’, ‘D:\ \programming\ \Python37\ \Lib\ \idlelib’,
  ‘D:\ \programming\ \Python37\ \python37.zip’, ‘D:\ \programming\ \Python37\ \DLLs’,
  ‘D:\ \programming\ \Python37\ \lib’, ‘D:\ \programming\ \Python37’, ‘D:\ \programming\
  Python37\ \lib\ \site-packages’, ‘D:\ \programming\ \Python37\ \lib\ \site-packages\
  easygui-0.98.0_unreleased-py3.7.egg’]

  列出的这些路径都是Python在导入模块操作时会去搜索的,尽管这些模块都可以使用,但site-packages目录是最佳的选择,因为它就是用来做这些事情的。
  当然我们也可以告诉Python我们的模块文件在哪里找,Python在导入模块的时候就能正确地找到它:

  >>> # 假如存放模块(interconversion_Celsius_Fahrenheit.py)的位置是:C: \ \ test
  >>> import interconversion_Celsius_Fahrenheit
  Traceback(most recent call last):
   File"<pyshell#2>",line 1,in< module >
    import interconversion_Celsius_Fahrenheit
  ImportError:No module named ‘interconversion_Celsius_Fahrenheit’

  >>> # 直接导入会出错,因为搜索路径并不包含模块所在的位置
  >>> # 需要把模块所在的位置添加到搜索路径中:
  >>> sys.path.append(“C:\ \ test”)
  >>> sys.path
  [‘C:\ \Users\ \Administrator\ \Desktop’, ‘D:\ \programming\ \Python37\ \Lib\ \idlelib’,
  ‘D:\ \programming\ \Python37\ \python37.zip’, ‘D:\ \programming\ \Python37\ \DLLs’,
  ‘D:\ \programming\ \Python37\ \lib’, ‘D:\ \programming\ \Python37’, ‘D:\ \programming\
  Python37\ \lib\ \site-packages’, ‘D:\ \programming\ \Python37\ \lib\ \site-packages\
  easygui-0.98.0_unreleased-py3.7.egg’, ‘C:\ \ test’]
  >>> import interconversion_Celsius_Fahrenheit as tc
  >>> print(“32摄氏度 = %.2f华氏度” % tc.c2f(32))
  32摄氏度 = 89.60华氏度

6. 包

  包是把模块分门别类地存放在不同的文件夹,然后把各个文件夹的位置告诉Python。创建一个包的具体操作如下:

  1. 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字;
  2. 在文件夹中创建一个_ _init_ _.py的模块文件,内容可以为空;
  3. 将相关的模块放入文件夹中。

  注意第2步,必须要在每一个包目录下建立一个_ _init_ _.py的模块,可以是空文件,也可以写一些初始化代码。这个是Python的规定,用来告诉Python将该目录当成一个包来处理。
  接下来就是在程序中导入包的模块(包名.模块名):

# 将interconversion_Celsius_Fahrenheit.py放在文件夹M1中
import M1.interconversion_Celsius_Fahrenheit as tc

print("32摄氏度 = %.2f华氏度" % tc.c2f(32))
print("99华氏度 = %.2f摄氏度" % tc.f2c(99))

  程序正常执行:
  >>>
  32摄氏度 = 89.60华氏度
  99华氏度 = 37.22摄氏度
  >>>

上一篇:浙大版《C语言程序设计(第3版)》题目集 练习2-4 温度转换 (5 分)


下一篇:PTA团体程序设计天梯赛-练习集——L1-004 计算摄氏温度 (5 分)