Python_模块

1. 基本概念和import 导入复习

Python_模块

 

针对学习过的模块给做一个扩展,模块的概念,Python中的模块是什么?在Python中,每一个独立的源文件就是一个模块儿, 文件的文件名,就是模块的名称,同时, 模块名同样也是一个标识符,因此在给文件起名的时候,必须要符合标识符的命名规则.

标识符的命名规则有 ,必须以数字, 字母和下划线组成,同时标识符不能以数字开头, 因此啊,给Python的源文件起名的时候,必须要符合标识符的命名规则.

模块就好比一个工具包, 模块可以向外界提供工具,那在模块中可以向外界提供哪些工具呢?现在学习的全局变量也好,函数也好,类也好,都是由模块可以向外界提供的工具.

在其他的位置想要使用模块中的工具应该先要导入这个模块,之前我们学习了使用import的这种方式可以导入一个模块,在import后面跟上模块的名称就可以.

如果希望一下导入多个模块,可以在import关键字后面,跟上多个模块的名称, 并且使用逗号进行分隔,

Python_模块

但是注意这种方式是不推荐使用的,因为按照PEP-8, Python的编码规范要求,在导入模块的时候,每一个模块都应该独占一行. 也就是如果需要导入多个模块,应该按照下方这种写法, 虽然可以使用import一次性导入多个模块,但是注意PEP-8要求在导入模块时, 每一个导入都应该独占1行,这个是导入模块的语法.

Python_模块

当导入了一个模块之后,怎么样可以使用到模块中的工具啊,可以使用模块名点的方式, 就可以使用到模块中提供的工具了,而模块向外界提供的工具,包括有全局变量, 函数以及类.

Python_模块

 

准备了一个测试模块1,在这个文件中准备了一个全局变量title,定义了一个say_hello的函数,定义了一个狗类Dog().

然后呢,还准备了一个测试模块2,测试模块2中定义了一个全局变量title,一个函数say_hello以及一个猫类Cat().

现在就把文件切换到import导入模块,

Python_模块

导入这两个模块,并且使用模块中提供的工具,老师先使用import关键字来导入hm01_测试模块1,然后再使用import关键字来导入hm02_测试模块2,两个模块导入之后,就可以直接使用模块中提供的工具了.

Python_模块

 

譬要调用模块1中的say_hello()方法,就可以先选中模块的名字,然后敲一个点,再选中,

Python_模块

 两个函数调用完成,先来执行一下程序,控制台输出,我是模块1,我是模块2,

Python_模块

 一个是模块1中的say_hello()方法,一个是模块二中的say_hello()方法.

再来尝试一下使用模块1中定义的的类来创建一个狗对象,在使用模块二中定义的类来创建一个猫对象.

先来创建一个狗对象,使用模块1中定义的狗类来创建一个对象,狗对象创建完成,就使用print函数把狗对象做个输出,

Python_模块

 

紧接着在使用模块2中定义的猫类来创建一个猫对象,猫对象创建完成,

Python_模块 

再执行一下程序走,控制台输出了狗对象所在的内存地址以及猫对象所在的内存地址.

Python_模块

 

hm_01_测试模块1

# hm_01_测试模块1
# 全局变量
title = "模块1"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass


hm_02_测试模块2

# hm_02_测试模块2
# 全局变量
title = "模块2"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass

hm_03_import导入模块

# hm_03_import导入模块
import hm_01_测试模块1
import hm_02_测试模块2

hm_01_测试模块1.say_hello()
hm_02_测试模块2.say_hello()

dog = hm_01_测试模块1.Dog()
print(dog)

cat = hm_02_测试模块2.Cat()
print(cat)

2.import 导入时指定别名

在开发时,如果某一个模块的名称太长或者非常不好识别,在导入模块的时候呢,就可以使用as这个关键字,给模块起个别名,所谓别名啊,就是给这个模块起个好记忆的名字,这样呢可以方便后续的代码编写来.

先看一下语法,要给模块起别名,同样使用import关键字,同样来指定要导入的模块名,然后呢,在模块名后面跟上一个as关键字,在as后面来指定一下模块的别名就可以, 指定了别名之后,如果在下方的代码再想访问的模块中提供的工具,就可以直接通过好记忆的别名来访问.

Python_模块

 

而不再需要通过不好记的模块名来访问了,这个就是模块别名的好处以及定义的方式,同时注意在给模块起别名的时候,模块的别名应该符合大驼峰命名法.

所谓大驼峰命名法,就是每一个单词的首字母应该大写,单词与单词之间不需要下划线,这个就是大驼峰命名法.

现在这份代码在阅读的时候,有一种怪怪的感觉,这个模块名既有字母,又有数字还有中文,唉,这种代码在阅读的时候会让人有一种非常奇怪的感觉.

Python_模块

 

通过模块的别名来改善一下代码的质量,仍然使用import关键字来导入一下测试模块1, 现在老师就写上as这个关键字,给测试模块1起个别名,测试模块1中定义了一个狗类,因此啊给他起个DogModule的别名, 狗模块.

Python_模块

 

导入一下测试模块2,现在再给他起个别名,CatModule,因为在测试模块二中提供了一个猫类,现在导入两个模块的时候, 分别指定了一个狗模块和猫模块的别名,那现在就来通过别名访问一下模块中提供的工具.如果要调用函数,就敲一个DogModule然后点,然后来找一下say_hello这个方法.

Python_模块

 

两个函数调用完成,先来执行一下, 我是模块一,我是模块2, 同样可以输出. 

Python_模块

 

那现在再来利用别名创建两个对象,先敲一个dog,现在一个狗对象创建完成,就使用print做个输出,

Python_模块

 

再运行一下程序,控制台又输出了狗对象和猫对象,

Python_模块

 

但是注意在控制台输入的狗类前面模块名仍然是文件名,而在导入模块时给模块起的别名仅仅用于在当前这个文件中,要使用模块时可以简化文化名的编写, 模块本质上还是原有的模块名.

hm_01_测试模块1

# hm_01_测试模块1
# 全局变量
title = "模块1"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass


hm_02_测试模块2

# hm_02_测试模块2
# 全局变量
title = "模块2"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass

hm_04_import同时指定别名

# import 导入时指定模块别名

import hm_01_测试模块1 as DogModule
import hm_02_测试模块2 as CatModule

DogModule.say_hello()
CatModule.say_hello()

dog = DogModule.Dog()
print(dog)

cat = CatModule.Cat()
print(cat)

3.from import 局部导入

另外一种导入模块的方式,叫做from import.

Python_模块

 

在开发时, 会有一种情况,就是只需要从某一个模块中倒入一部分工具,只需要把某一个模块中部分工具导入到当前文件,而不是把这个模块中所有的工具导入到当前文件,就可以使用from import 这种方式来导入模块了.

先看一下语法,如果只希望导入一部分工具,先使用from这个关键字,from 有从的意思,在from关键字后面跟上要导入的模块名,然后呢,跟上 import这个关键字, 在import后面, 跟上要导入的工具就可以,这句代码从字面上可以把它理解成从哪一个模块导入哪一个工具.

Python_模块

 

这种导入方式的好处是, 如果只是从某一个模块中导入了某一个工具,那么在下方编写代码的时候,要使用这个工具是不需要通过模块名点的方式,而是可以直接来使用这个工具的,譬如导入的全局变量也好,函数也好, 类也好,都可以直接使用,而不需要通过模块名点的方式来使用.

Python_模块

准备的两个模块中都有全局变量,有函数, 有类, 那现在就在一个全新的空白文件,从两个模块中分别导入部分工具,先使用from关键字,从01这个测试模块中来导入一个狗类.

再使用from 关键字,从02测试模块中, 来导入一个say_hello的函数,现在分别从两个不同的模块中导入了一个类,导入了一个函数,那紧接着就在当前这个文件中,来调用一下函数,并且使用这个类来创建一个对象. 现在如果要调用say_hello的函数,在调用这个函数时不需要指定模块名, 让运行一下程序,

 Python_模块

控制台输出了,我是模块2,因为say_hello这个函数是从模块2中导入进来的, 那现在再使用模块1中的狗类来创建一个狗对象,先给狗对象起个名字叫旺财,同时在使用这个类时,同样也不需要指定模块名.那现在就使用print函数,把旺财做一个输出,

Python_模块

 

运行一下程序,控制台输出了一个使用模块1的狗类创建的对象, 内存地址6b38,

Python_模块

 

这个就是使用from import,从某一个模块中导入部分工具的方式.

hm_01_测试模块1

# hm_01_测试模块1
# 全局变量
title = "模块1"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass


hm_02_测试模块2

# hm_02_测试模块2
# 全局变量
title = "模块2"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass

from import 局部导入

# from import 局部导入
from hm_01_测试模块1 import Dog
from hm_02_测试模块2 import say_hello

say_hello()

wangcai = Dog()
print(wangcai)

4. from import 导入同名工具

使用from import在导入模块时的注意事项,使用from可以从某一个模块中导入指定的工具,而且导致之后再使用这个工具时,并不需要通过模块名点的方式,这种导入方式还是比较方便的.

但是在开发中有一种情况,如果从两个不同的模块中导入了同名的函数,在Python中要调用函数,通过函数名的方式来调用,但是呢,如果从两个不同的模块中导入了相同名字的函数,那么在使用函数名调用函数时会执行哪个模块中定义的函数呢?

Python_模块

 

在两个测试模块中都有一个say_hello的函数,那现在就在这个新的空白文件使用时,from import从两个不同的模块中导入say_hello这个函数,来验证一下到底会执行哪一个模块中的函数,先使用from关键字,从01的模块中的say_hello函数做个导入,

Python_模块

 

两个函数导入完成,就使用函数的名称来调用一下函数,会执行哪个模块中的函数呢?看模块2的代码被高亮了,

Python_模块

 

运行验证一下,控制台输出了,我是模块2呢,

Python_模块

 

就是模块2中定义的say_hello这个函数,但是现在把第1行的导入代码注释一下,然后把光标放在第3行,在第3行,再使用from这个关键字,从模块1把say_hello做个导入,这次是先导入模块2再导入模块1,现在第3行代码被高亮了,第2行代码呢,唉又变灰了,

Python_模块

 

那现在猜猜在运行程序的时候会执行哪一个模块中的say hello呢,运行验证一下,这次执行的是模块1中的say hello,

Python_模块

 

为什么会出现这种情况呢?在这里画一个示意图,Python解释器在执行代码时, 是从上向下顺序执行的, 当来到第2行是需要从模块2中导入一个say_hello的函数,那么Python解释器,就会把模块二中的say_hello 这个函数导入到当前这个文件中,但是呢,导入进来之后, Python解释器会继续向下执行,当Python解释器从模块1中say_hello之后,say_hello这个函数名叫做say_hello, 而之前已经导入了一个say_hello,那么Python解释器啊,再从模块1导入这个函数时,就会把之前导入的say_hello直接覆盖掉,覆盖之后, 现在这个say_hello就变成了模块1中的say_hello,因此呢,在程序中调用say_hello这个函数时, 就会执行模块1中的函数,而不会执行模块2的函数.

Python_模块

 

通过这个简单的示意图,当使用from import, 从不同的模块中导入相同的函数时,后导入的函数会把之前导入的函数覆盖掉,

在开发时,务必要养成一个习惯,就是需要把所有导入的代码统一都写在代码顶部,统一写在代码顶部,有一个好处,如果在编写导入代码时,一旦发现报两个模块都有say hello,这个时候就可以及时的发现错误,及时的解决问题. 如果这两个导入代码,一个写在第2行, 一个写在第200行, 这种问题就很难发现了. 因此要养成一个习惯,把所有导入的代码统一写在文件的顶部,一旦发现冲突就可以及时的解决了.

如果在开发中就想从两个不同的模块导入相同的函数,那应该怎么解决呢?之前学习过一个起别名的关键字,as关键字,那如果发现了两个函数名产生了冲突, 就可以使用as这个关键字给其中一个函数起个别名,现在就给模块2的say_hello,起个别名,给他起个名字, module2_say_hello,别名起完之后, 现在就把光标放在第6行,来试一下能不能通过别名调到这个函数,

Python_模块

运行程序, 控制台输出了,我是模块一,我是模块二,

Python_模块

两个原本名字相同的函数,通过一个别名就可以把两个同名的函数加以区分,这样呢,如果想调用模块1中的函数,直接使用函数名,想调用模块2中的函数,就通过别名来调用就可以.

hm_01_测试模块1

# hm_01_测试模块1
# 全局变量
title = "模块1"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass


hm_02_测试模块2

# hm_02_测试模块2
# 全局变量
title = "模块2"

# 函数
def say_hello():
    print("我是 %s" % title)

# 类
class Cat(object):
    pass

from_import_注意事项>导入同名工具

# hm_06_from_import_注意事项

# from hm_01_测试模块1 import say_hello
from hm_02_测试模块2 import say_hello as module2_say_hello
from hm_01_测试模块1 import say_hello

say_hello()
module2_say_hello()

5. from import 导入所有工具

一种导入模块的方式from import* ,使用from这个关键字可以从一个模块中导入指定的工具,那在开发中啊,如果希望从这个模块中一次性把所有的工具全部导入,就可以在import关键字后面跟上一个 * 就可以,这种方式同样也可以一次性把模块中所有工具全部导入.

Python_模块

 

之前介绍过import 模块名,可以一次性把所有工具导入,但是使用import模块名这种方式,导入之后, 要想使用工具,必须要通过模块名点或者别名点的方式来使用这些工具,from import*同样也可以把模块中所有工具全部导入,但是呢,这种导入方式, 在使用工具时,并不需要通过模块名点的方式,而可以直接使用导入进来的工具.

使用from这个关键字,先从01的模块中来导入一下所有的工具,导入完成, 就使用print函数模块中的title 做一个输出,然后再来调用一下say_hello这个函数,然后呢,再创建一个旺财的狗对象,使用到Dog()类创建一个旺财,并且使用print函数做个输出,

Python_模块 

导入之后全局变量也好,

Python_模块

函数也好,

Python_模块

类也好,都可以直接使用,

Python_模块

而且呢,不需要使用模块名点的方式,那现在运行一下程序,

模块1, 我是模块1, 狗对象, 通通在控制台输出了,这个就是使用from import* 的好处,但是这种方式虽然方便,但是呢,是开发中不推荐使用的.  

当导入同名函数时候导入的模块会把之前导入的模块进行覆盖,而如果使用from import* ,在导入多个模块时, 多个模块中存在相同的内容,这个时候在排查错误的时候就会非常麻烦.

从模块1中导入了所有工具,但是在模块2中同样定义了一个title的全局变量,同样有一个say_hello的函数,如果现在的程序在运行时, 会输出模块1,我是模块1,以及狗对象. 那如果再使用from import* 把模块2中所有工具全部倒入,只是增加了一句导入的代码,

Python_模块

 

运行验证一下,控制台输出模块2, 我是模块2, 然后模块1中的狗对象,全局变量也好,函数也好,通通背后导入的覆盖掉了,

Python_模块

 

这个时候单纯从代码上,如果想要排错并不容易,所以啊,from import*这个知识点,只是做一个科普,知道这种方式就可以, 但是当走到工作岗位后,真正要开发公司中的项目,千万不要使用这种方式来导入模块,因为这种方式一旦出现重名,在排查问题的时候非常的麻烦啊.
 

6. 模块搜索顺序

做个小科普,介绍一下Python解释器在导入模块时是按照什么样的顺序来搜索模块文件的.

Python_模块

 

在开发时可以使用from或者import来导入一个模块,而Python解释器在导入模块时啊,会首先在当前工作目录下来搜索指定名称的模块文件,如果找到这个模块就会直接导入,那如果没有找到呢,Python解释器才会去Python的系统目录来搜索指定名称的模块文件,这样就是Python解释器在导入模块时, 对模块文件的一个搜索顺序.

在开发时, 给一个文件起名时一定要注意,不要和系统的模块文件重名,一旦出现这种情况,可能呢,就会导致原本能够正常执行的程序,突然没有办法执行了.

看一下下面这个示例代码,在这个代码中, 首先使用import导入了一个random模块,random模块可以生成随机数,在代码的第2行使用random模块提供的randint,生成一个0~10的随机数,然后把生成的随机数做了一个输出.

这三行代码在下面的情况下不能正常执行, 首先导入一下random模块,导入之后呢,来定一个变量叫做rand,然后使用random模块调用一下提供的randint函数,来生成一个0~10的随机数,使用print函数,把生成的随机数做一个输出,三行简单的代码写完, 现在运行一下程序,

Python_模块

 控制台输出了一个9, 如果再运行呢,现在随机输出了一个6,

但是第1行代码在导入random这个模块, Python解释器在导入模块时, 会首先搜索哪一个目录, 会首先搜索当前的工作目录,那如果在当前的工作目录下再新建一个python文件,同时给这个文件也起个名字,叫做random, 建立了一个空白文件.

Python_模块

现在再回到刚刚的代码,但是现在randint这个函数名下方有个深黄色的颜色,

Python_模块

这个颜色在暗示什么呢?运行程序,刚刚还能够执行的程序,新建了一个空白文件之后,这个程序就无法正常执行了,同时在程序执行时告诉我们,第3行出错了,出错内容呢,random这个模块没有提供randint的函数,

Python_模块

 

为什么会出现这种情况,因为Python解释器在导入模块时,会首先在当前工作目录来搜索指定名称的模块,

Python_模块

 

一旦找到就直接导入,就不会去系统目录下导入这个模块了,因此就会导致原本能够正常执行的程序,现在就不能正常执行了.

在python中, 针对每个模块都提供有一个内置属性__file__,使用这个内置属性__file__就可以查看到当前导入的模块对应的完整文件路径,把刚刚错误的两行代码先注释一下,

Python_模块

然后把光标放在第3行,使用print函数做一个输出,输出一下导入的random这个模块的内置属性, 把这个内置属性啊,做一个输出,

Python_模块

 

控制台输出了,告诉当前加载的random模块保存位置是

Python_模块

 

这个是不是就是当前工作目录下的这个random文件.

那现在就选中这个文件,

Python_模块

 

点击右键,来选择一下删除,

Python_模块

 

把这个添乱的random文件删掉,再看一下输出的内置属性是什么路径,点击OK,

Python_模块 

点击OK之后会提示一个信息,

Python_模块

 

告诉random.py 已经被其他文件导入了,是否确定要删除,那么就点击Delete Anyway,

Python_模块

现在再来运行一下程序,

Python_模块 

看看__file__这个内置属性输出的目录有没有变化, 这次输出的目录就是Python_模块

因为当前使用的是Python3的解释器,Python3.5下面的random.py.

如果现在把下方的两行代码注释打开, 程序能正常运行.

Python_模块

 

验证一下,这次又随机生成了一个1,

Python_模块

 

这个就是Python解释器在导入模块时对模块文件的搜索目录,一句话讲, 会首先在当前工作目录下来搜索指定名称的模块文件,如果找到就直接导入,如果没有找到才会去python 系统目录来搜索指定名称的模块文件.

之所以要科普这个知识点,重要的是在开发时给文件起名,千万不要跟系统的模块文件重名,因为一旦出现这种情况,可能呢就会导致原本能够正常执行的程序,突然就无法正常执行了.

import random

print(random.__file__)

# rand = random.randint(0, 10)
#
# print(rand)

Python_模块
 

import random

print(random.__file__)

rand = random.randint(0, 10)

print(rand)

 Python_模块

 

7.开发原则以及导入文件时会执行没有缩进的代码

介绍一个开发原则,就是每一个开发出来的Python文件都应该是可以被导入的,每一个独立的Python文件就是一个模块,既然是模块, 理所当然可以被导入.

如果在工作中每开发完一个文件,这个文件呢,还可以被当做模块导入到其他的文件中被重复的使用,这样可以大大的提高工作效率.

先针对导入文件的一个细节强调一下,当某一个Python文件被当做模块导入到其他另外一个文件时,这个Python文件中啊,所有没有任何缩进的代码都会被执行一遍唉。验证一下,准备了两个文件,一个文件用来模拟开发的模块,另外一个文件用来导入开发的模块,那现在就选中模块文件,假设这个模块是小明开发的,就先使用print函数做个输出,写完之后,

Python_模块 

假设开发已经告一段落,现在就可以切换到另外一个文件来导入模块编写代码,那现在就使用import关键字来导入一下这个模块文件,然后呢使用print函数做个输出,在这个文件中输出一个分隔线,一个简单的代码写完,现在这个程序中。真正执行的代码就是在打印分隔线,但是如果现在执行这个程序,会看到控制台输出了,

Python_模块

   

虽然把分隔线打印出来,但是小明开发的模块是在之前这个模块文件中, 第1句代码print函数输出的,

Python_模块

模块可以被看作工具包, 模块可以向外界提供工具,那模块能够向外界提供哪些工具?可以提供全局变量, 可以提供函数, 可以提供类. 但是这种直接执行的代码并不是向外界提供的工具, 写一个注意, 直接执行的代码,不是向外界提供的工具,

Python_模块

既然不是向外界提供的工具,那么外界再导入这个模块时,这些代码不需要被执行,现在碰到一个问题,当这个文件被导入时, 直接执行的代码不需要被执行.

Python_模块

 

这个是要通过代码演练共同确认的一个目标,在一个模块中向外界提供的工具应该有全局变量, 函数或者类,那现在做一个假设,假设小明在开发时开发了一个函数,使用def关键字来定义一个名字叫做say hello的函数,一个简单的函数开发完成,

Python_模块

 

小明开发完这个函数之后需要测试一下函数,因为只有测试执行的函数才能保证这个函数真的能够正常执行,就在第10行通过say hello来调一下函数,小明编写完代码要通过执行来测试say hello的执行,现在点击运行,控制台输出了小明开发的模块, 你好你好,我是say hello, say hello这个函数能够正常执行.

Python_模块

 

但是作为导入模块一方,

Python_模块

 

如果现在执行程序会看到控制台虽然输出了分割线,但是会把小明测试的代码同样也输出,小明测试的代码,在这一边导入的时候不需要被执行, 

Python_模块

 

因为这些代码只是小明在开发这个模块时,针对模块测试的代码.当这个文件被当做模块被导入时,这些代码并不需要被执行. 应该这样解决这个问题, 介绍了一个开发原则,一句话讲要保证每一个开发出来的python文件都应该是可以被导入的,因为这个原则可以大大的提高开发效率,介绍了一个导入文件的细节,就是文件中所有没有任何缩进的代码,再被导入时都会被执行一遍.

当一个文件被当做模块导入时,这些能够直接执行的代码不需要立即执行. 这个是碰到的一个问题.

8. __name__属性兼顾测试和导入两种模式

介绍一个内置属性叫做__name__,在开发中啊,刚刚__name__这个内置属性的应用场景非常的单一,通过这个属性就能够做到,在开发一个模块时,测试模块的代码能够正常的执行,但是当在其他文件中导入这个模块时,原本编写的测试模块的代码就不会执行了,这种方式刚好可以解决上一小节遇到的问题.那__name__这个属性中本质上保存的只是一个字符串,当在其他文件中导入这个模块时,__name__这个属性中保存的就是这个模块的模块名,但是如果直接执行当前正在开发的模块,__name__这个属性啊,保存的是一个非常固定的字符串,永远都是__main__.

Python_模块

 

看这个文件小明开发的模块, 那现在把光标放在第8行,使用print函数先来输出一下__name__这个内置属性,如果直接执行模块, 控制台输出__name__, 应该输出一个固定的__main__,

Python_模块

点击右键选择执行,永远都输出一个固定的__main__,

Python_模块 

那现在就把这个字符串选中,

Python_模块 

然后呢,在这里增加一个注释,如果直接执行模块, 那么得到的值永远都是__main__.

那现在再来看一下导入模块的文件,

Python_模块

 

如果现在选中这个文件来运行,注意观察一下控制台输出的__name__会发生什么变化,

Python_模块

 

现在点击运行,这次在运行的时候控制台输出的就是模块的名称,

Python_模块

 

而不再是__main__, 那再返回到小明开发的模块,

Python_模块

 

如果直接执行这个模块得到的结果永远__main__,那现在怎么样能够做到对模块测试的代码,只有在执行模块时才会被运行,只需要判断一下__name__这个属性,如果是__main__就说明当前在执行这个模块.

那既然如此, 就在下方增加一个判断,来判断一下__name__这个属性,如果这个属性中保存的字符串就是__main__,那么就来执行一下下方的测试代码,现在把原本的测试代码全部选中,

Python_模块

 

增加一个缩进,代码调整完成,

Python_模块

 

现在再以小明的身份来运行一下这个模块,点击右键选择执行,控制台仍然能够输出__main__,

Python_模块

 

并且调用say_hello这个函数,那现在再把文件切换到导入模块这个文件,Python_模块

选中这个文件,

Python_模块

 

然后点击右键,然后运行,现在运行控制台只会输出一个分隔线,并不会把小明针对模块测试的代码执行一遍,这个就是__name__这个内置属性专有的应用场景,一句话讲,如果需要测试模块,就增加一个条件判断,

Python_模块

 

在条件判断下方针对模块进行测试,这样呢,在开发模块时能够顺利的对模块进行测试,同时增加了这个判断之后,其他人再导入我们模块时,测试的代码就不会被执行了,这个if判断, 会在很多其他人开发的Python程序中能够见到.

如果今后在网络上查询一些其他人开发的代码, 通常呢会看到这种格式,

Python_模块

无论上方的代码怎样编写,但是在代码的末尾, 都会看到另一个名字叫做__main__的函数,主函数,

Python_模块

 

在主函数中编写有一系列的测试代码,然后呢,在模块文件的末尾有一个if判断,

Python_模块

 

判断__name__这个属性,是否等于__main__, 如果等于__main__就来调用函数,这种格式的代码是以后在网络上普遍看到的一种格式.

在开发Python文件时,应该同样按照这种格式来编写代码,因为按照这种格式编写的代码就能够做到在开发文件时, 可以在main 函数中针对文件进行测试,同时开发完成的程序还可以顺利的被作为模块导入到其他文件中,被其他文件重复的使用.
 

上一篇:高并发 Nginx+Lua OpenResty系列(2)——Nginx Lua API


下一篇:[JS]闭包和词法环境