零基础入门学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却说我们未定义,具体原因我们稍后再进行解释。
命名空间(Namespace)表示标识符(identifier)的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。
在Python中,每个模块都会维护一个独立的命名空间,我们应该将模块名加上,才能够正常使用模块中的函数:
>>> hello.hi()
Hello, Python!
下面介绍一下几种导入模块的方法。新建一个名为interconversion_Celsius_Fahrenheit.py
的文件,用于计算摄氏度和华氏度的相互转换:
def c2f(cel):
fah = cel * 1.8 + 32
return fah
def f2c(fah):
cel = (fah - 32)/ 1.8
return cel
-
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摄氏度 -
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 *
但是强烈要求大家不要使用这种方法,因为这样做会使得命名空间的优势荡然无存,一不小心还会陷入名字混乱的局面。 -
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摄氏度
模块的主要作用:
- 封装组织Python的代码;
- 实现代码的重用。
当我们在阅读别人代码时,会发现很多代码中都有_ _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()
函数。
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华氏度
包是把模块分门别类地存放在不同的文件夹,然后把各个文件夹的位置告诉Python。创建一个包的具体操作如下:
- 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字;
- 在文件夹中创建一个
_ _init_ _.py
的模块文件,内容可以为空; - 将相关的模块放入文件夹中。
注意第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摄氏度
>>>