一、模块
什么是模块. 模块就是?个包含了python定义和声明的?件, ?件名就是模块的名字加上.py后缀. 换句话说我们?前写的所有的py?件都可以看成是?个模块,但是我们import加载的模块?共分成四个通?类别:
1. 使?pyhton编写的py?件 2. 已被变异为共享库或者DLL或C或者C++的扩展 3. 包好?组模块的包. 4. 使?c编写并连接到python解释器的内置模块
为什么要使?模块? 为了我们写的代码可以重?,不?于把所有的代码都写在?个?件内。当项?规模比较?的时候,完全可以使??个py搞定整个项?的开发。但是如果是?个?常庞?的项?,此时就必须要把相关的功能进?分离,?便我们的?常维护以及新项?的开发。
如何使?模块? 我们已经?过很多模块了, 导入模块有两种?式:
1. import 模块
2. from xxx import xxxx
?. import
?先, 我们先看import, 在使?import的时候, 我们先创建?个yitian.py,在该?件中创建?些武林前辈和?些打?场景,代码如下:
print("?头曲: music起~~~~~~~") main_person_man = "张?忌" main_person_woman = "赵敏" low_person_man_one = "成昆" low_person_man_two = "周芷若" def fight_on_light_top(): print("光明顶?战", main_person_man, "破坏了", low_person_man_one, "的?阴谋") def fight_in_shaolin(): print("少林寺?战", main_person_man, "破坏了", low_person_man_two, "的?阴谋")
接下来, ?庸上场。
import yitian print(yitian.main_person_man) # 使?模块中定义好的名字 print(yitian.low_person_man_one) yitian.fight_in_shaolin() # 调?模块中的函数 yitian.fight_on_light_top()
此时我们在?庸模块中引入了yitian模块,在Python中模块是不能够重复导入的,当重复导入模块时,系统会根据sys.modules来判断该模块是否已经导入了。如果已经导入, 则不会重复导入。
import sys print(sys.modules.keys()) # 查看导?的模块. import yitian # 导?模块. 此时会默认执?该模块中的代码 import yitian # 该模块已经导?过了. 不会重复执?代码 import yitian import yitian import yitian import yitian
导入模块的时候都做了些什么? ?先,在导入模块的?瞬间,python解释器会先通过sys.modules来判断该模块是否已经导入了该模块。如果已经导入了则不再导入,如果该模块
还未导入过, 则系统会做三件事:
1. 为导入的模块创?新的名称空间 2. 在新创建的名称空间中运?该模块中的代码 3. 创建模块的名字. 并使?该名称作为该模块在当前模块中引?的名字.
我们可以使?globals来查看模块的名称空间
print(globals())
注意,由于模块在导入的时候会创建其??的名称空间,所以,我们在使?模块中的变量的时候?般是不会产?冲突的。
import yitian main_person_man = "胡?菲" def fight_in_shaolin(): print(main_person_man, "?战曾?贤") print(yitian.main_person_man) # 张?忌 print(main_person_man) # 胡?菲 yitian.fight_in_shaolin() # 倚天屠?记中的 fight_in_shaolin() # ??的
注意,在模块中使?global,我们之前说global表?把全局的内容引入到局部。但是,这个全局指的是py?件,换句话说global指向的是模块内部,并不会改变外部模块的内容。
模块 yitian 中: print("?头曲. 啊! 啊~ 啊! 啊. 啊啊啊啊啊啊啊...") main_person_man = "张?忌" main_person_woman = "赵敏" low_person_man_one = "成昆" low_person_man_two = "周芷若" def fight_on_light_top(): print("光明顶?战", main_person_man, "破坏了", low_person_man_one, "的?阴 谋") def fight_in_shaolin(): global low_person_man_two # 注意看, 此时的global是当前模块. 并不会影响其他模块
low_person_man_two = "战五渣" print("少林寺?战", main_person_man, "破坏了", low_person_man_two, "的?阴谋")
调??: import yitian low_person_man_two = "刘海柱" yitian.fight_in_shaolin() print(yitian.low_person_man_two) # 战五渣 print(low_person_man_two) # 刘海柱. 并没有改变当前模块中的内容. 所以模块内部的global只是?于模块内部
特别要注意,如果我们在不同的模块中引入了同?个模块。并且在某?个模块中改变了被引入模块中的全局变量, 则其他模块看到的值也跟着变。 原因是python的模块只会引入
?次,?家共享同?个名称空间。
?庸: import yitian yitian.main_person_man = "灭绝师太" ?庸?号: import yitian import ?庸 print(yitian.main_person_man) # 灭绝师太.
上述问题出现的原因:
1. ?家共享同?个模块的名称空间. 2. 在?庸?改变了主?的名字
如何解决呢?
?先,我们不能去改python。因为python的规则不是我们定的,只能想办法不要改变主?的名字。但是,在?庸?我就有这样的需求,那此时就出现了,在?庸被执?的时候要执?的代码。在?庸被别?导入的时候我们不想执?这些代码。此时, 我们就要利??下__name__这个内置变量了。在Python中,每个模块都有??的__name__ ,但是这个__name__的值是不定的。当我们把?个模块作为程序运?的入?时, 此时该模块的__name__是"__main__" , ?如果我们把模块导入时,此时模块内部的__name__就是该模块??的名字。
?庸: print(__name__) # 此时如果运?该?件. 则__name__是__main__ ?庸?号: import ?庸 #此时打印的结果是"?庸" #我们可以利?这个特性来控制模块内哪些代码是在被加载的时候就运?的,哪些是在模块被别?导入的时候就要执?的,也可以屏蔽掉?些不希望别?导入就运?的代码,尤其是测试代码. if __name__ == ‘__main__‘: yitian.main_person_man = "灭绝师太" # 此时, 只有从该模块作为??运?的时候才会把main_person_man设置成灭绝师太 print("哇哈哈哈哈哈") # 只有运?该模块才会打印. import的时候是不会执?这?的代码的 #我们还可以对导入的模块进?重新命名: import yitian as yt # 导?yitian. 但是名字被重新命名成了yt,就好?变量赋值?样。 a = 1 b = a yt.fight_in_shaolin() # 此时可以正常运? # yitian.fight_in_shaolin() # 此时程序报错,因为引?的yitian被重命名成了yt print(globals())#打印出来看一下是不是被修改了。
?次可以引入多个模块
import time, random, json, yitian
正确的导入模块的顺序:
1. 所有的模块导入都要写在最上?. 这是最基本的
2. 先引入内置模块
3. 再引入扩展模块
4. 最后引入你??定义的模块
三. from xxx import xxx
第??块关于import就说这么多,接下来. 我们来看from xxx import xxx这种导入模块的效果。在使?from的时候, python也会给我们的模块创建名称空间,这?点和import是?样
的。但是from xxx import xxx的时候,我们是把这个空间中的?些变量引入过来了。说?了,就是部分导入,当?个模块中的内容过多的时候,我们可以选择性的导入要使?的内容。
from yitian import fight_in_shaolin fight_in_shaolin()
此时是可以正常运?的, 但是我们省略了之前的模块.函数(), 直接函数()就可以执?了, 并且from语句也?持??语句导入多个内容。
from yitian import fight_in_shaolin, fight_on_light_top, main_person_man fight_in_shaolin() fight_on_light_top() print(main_person_man) #同样?持as from yitian import fight_in_shaolin, fight_on_light_top, main_person_man as big_lao fight_in_shaolin() fight_on_light_top() print(big_lao)
最后,看?下from的坑。当我们从?个模块中引入?个变量的时候,如果当前?件中出现了重名的变量时,会覆盖掉模块引入的那个变量。
from yitian import main_person_man main_person_man = "超级?灭绝" print(main_person_man)
所以,不要重名,切记,不要重名! 不仅仅是变量名不要重复。我们??创建的py?件的名字不要和系统内置的模块重名。否则,引入的模块都是python内置的模块,切记, 切记!!!!!
我们现在知道可以使?import和from xxx import xxx来导入?个模块中的内容。那有?种特殊的写法: from xxx import * 。我们说此时是把模块中的所有内容都导入,注意, 如果模块中没有写出__all__ 则默认所有内容都导入。如果写了__all__ ,此时导入的内容就是在__all__列表中列出来的所有名字。
# haha.py __all__ = ["money", "chi"] money = 100 def chi(): print("我是吃") def he(): print("我是呵呵") # test.py from haha import * chi() print(money) # he() # 报错
原文地址:https://www.cnblogs.com/asia-yang/p/10197939.html