1、模块的介绍
-
在python中
以扩展名py为结尾的文件就是一个模块 -
模块名同样也是一个标识符,需要符合
标识符的命名规则 -
在模块中定义的
全局变量、函数、类都是提供给外界直接使用的工具 -
模块就好比工具包,要想使用这个工具包中工具,就需要
先导入这个模块
2、模块的导入方式
导入模块是指:
◆ 在一个.py文件中,使用另外一个.py文件时,需要将这个文件导入
◆ 在一个模块中,使用另外一个模块时,需要将这个模块导入
① import 模块名
- 在使用
import 模块名导入模块时,会将整个文件导入成一个模块对象 - 在使用模块中的成员(全局变量、函数、类)时,需要使用
模块名.成员名
语法格式
在导入模块时,每个导入的模块应该独占一行(推荐使用)
import 模块名1
import 模块名2
以下这种(不推荐使用)
import 模块名1,模块名2
示例1
第一步:新建一个自定义模块(user_defined.py)
# 可以定义全局变量
a = 1
# 可以定义函数
def func():
print("hello python!")
# 可以定义类
class show(object):
def func(self):
print("hello world")
print(a)
func()
b = show()
b.func()
第二步:新建一个测试模块(test.py)用来使用自定义模块
# 先导入user_defined模块,不写其他代码,先运行测试结果
import user_defined
######结果######
1
hello python!
hello world
通过结果说明:模块是一个对象,在导入模块时,创建了该模块的对象,也就会去执行该模块中的所有文件。
示例2
第一步:新建一个自定义模块(user_defined.py)
# 定义全局变量
a = 1
# 定义函数
def func():
print("hello python!")
# 定义类
class show(object):
def func(self):
print("hello world")
第二步:新建一个测试模块(test.py)用来使用自定义模块
import user_defined
# 使用模块名.变量调用user_defined模块中的变量
print(user_defined.a)
# 使用模块名.函数调用user_defined模块中的函数
user_defined.func()
# 使用模块名.类名()来实例化user_defined模块中的类
b = user_defined.show()
b.func()
######结果######
1
hello python!
hello world
通过结果说明:import-模块名的方式要想使用模块中的成员,通过模块名.成员调用。
② import别名形式
问: 为什么要用别名形式???
答: 别名就是为复杂的模块名起一个代号,可以通过这个代号来调用模块名中的相应的成员。比如有个模块名:abcddfgsdflsdfsdfasdf,调用模块中成员非常麻烦,这时候就可以用as取一个别名来调用成员。
示例
第一步:新建一个自定义模块(user_defined.py)
# 定义全局变量
a = 1
# 定义函数
def func():
print("hello python!")
# 定义类
class show(object):
def func(self):
print("hello world")
第二步:新建一个测试模块(test.py)用来使用自定义模块
导入user_defined模块并起一个别名为b
import user_defined as b
# 使用别名.变量调用user_defined模块中的变量
print(b.a)
# 使用别名.函数调用user_defined模块中的函数
b.func()
# 使用别名.类名()来实例化user_defined模块中的类
c = b.show()
# 如果类只调用一次方法可以使用匿名函数:b.show().func(),不用变量接收。
# 如果写两次内存地址不一样
c.func()
③ from 模块名 import 成员名
问: 已经有了import导入模块,为什么还需要from 模块名 import 成员名 这个导入方式
答: import 代表导入某个或多个模块中的所有功能,但是有些情况下,我们只希望使用这个模块下的某些方法。而不需要全部导入,这个时候就建议采用from 模块名 import 成员。
◆ from-import方式导入的是指定模块中的指定成员
◆ 当使用from-import方式导入时,不需要再使用 模块名.成员 调用成员。可以在当前文件中直接使用成员名,相当于将导入的模块复制到本地一份。
示例
第一步:新建一个自定义模块(user_defined.py)
# 定义全局变量
a = 1
# 定义函数
def func():
print("hello python!")
# 定义类
class show(object):
def func(self):
print("hello world")
第二步:新建一个测试模块(test.py)使用from-import方式调用成员
# 使用from-import方式导入模块中的a方法
from user_defined import a
# 直接打印变量a,不需要再用 模块名.成员 的方式调用成员
print(a)
######结果######
1
这个时候调用 fun() 函数
# 使用from-import方式导入模块中的a变量
from user_defined import a
# 直接打印变量a,不需要再用 模块名.成员 的方式调用成员
print(a)
# 调用func函数
func()
######结果######
1
报错
为什么报错呢? 没有导入模块中 func函数 成员
# 使用from-import方式导入模块中的a变量和func函数
from user_defined import a
from user_defined import func
# 直接打印变量a,不需要再用 模块名.成员 的方式调用成员
print(a)
func()
######结果######
1
hello python!
④ from-import 别名形式
语法格式:
from 模块名 import 成员名 as 别名
from 模块名 import 成员名 as 别名, 成员名 as 别名……
示例:
第一步:新建一个自定义模块(user_defined.py)
# 定义函数
def func():
print("hello python!")
第二步:新建一个测试模块(test.py)
# 使用from-import方式导入模块中func函数并取别名f
from user_defined import func as f
# 调用函数
f()
######结果######
hello python!
⑤ from 模块名 import*
◆ 使用import时,可以将
整个模块中的成员都导入进来
◆ 如果使用from-import时,可以使用哪个成员导入哪个成员,这样更加节省资源。
◆ 如果想使用from - import方式导入所有成员,可以使用from 模块名 import ∗
◆ 如果使用通配符*的方式导入所有成员,那么就不能使用 as 为成员取别名
示例:
第一步:新建一个自定义模块(user_defined.py)
# 定义全局变量
a = 1
# 定义函数
def func():
print("hello python!")
# 定义类
class show(object):
def func(self):
print("Hi world")
第二步:新建一个测试模块(test.py)使用from-import *方式调用成员
# 使用from-import *方式导入模块所有成员
from user_defined import *
# 调用成员
print(a)
func()
show().func()
######结果######
1
hello python!
Hi python!
3、两种导入方式区别
1.import方式,是拿到了模块对象的引用地址,通过这个引用地址来使用模块中的成员;
2.from-import方式,相当于将被导入模块中的成员,复制一份到本地模块中,所有可以直接使用成员来访问被导入的成员;
3.对于impot方式来说没有任何限制;
4.对于from-import方式来说,有些成员是不能被导入的(有权限限制)
示例: 验证3和4
第一步:新建一个自定义模块(user_defined.py)
# 全局变量:模块间的公有变量
a = 1
# _私有变量:文件内私有变量
_b = 2
# __私有变量:一般出现在类中
__c = 3
第二步:新建一个测试模块(test.py)
# 使用import方式导入模块
import user_defined
# 调用成员
print(user_defined.a)
print(user_defined._b)
print(user_defined.__c)
######结果######
1
2
3
# 使用from-import *方式导入模块所有成员
from user_defined import *
# 调用成员
print(a)
print(_b)
print(__c)
######结果######
1
报错
报错
通过结果说明:在使用from-import方式导入模块时,不会将私有属性导入。
但是可以通过__all__这个魔法属性,可以改变from-import的导入规则(一般不会在这里去使用__all__属性)
示例:
第一步:新建一个自定义模块(user_defined.py)
# 全局变量:模块间的公有变量
a = 1
# _私有变量:文件内私有变量
_b = 2
# __私有变量:一般出现在类中
__c = 3
# 使用__all__方法改变from-import方式的导入规则
__all__ = ["_b","__c"]
第二步:新建一个测试模块(test.py)
# 使用from-import *方式导入模块所有成员
from user_defined import *
# 调用成员
print(a)
print(_b)
print(__c)
######结果######
报错
2
3
4、from import方式的命名冲突
当我们编写多个模块时,可能在导入到其他页面时,会产生一个问题:全局变量、函数、类出出现重名情况,我们把这个情况就称之为“命名冲突”。
示例
第一步:新建两个模块
module1.py
def func():
print("module1中的方法")
module2.py
def func():
print("module2中的方法")
第二步:新建一个测试模块(test.py)导入module1和module2模块
from module1 import func
from module2 import func
# 导入func方法
func()
######结果######
module2中的方法
通过结果说明:导入的module1和module2里面都封装了一个func()方法,其中在导入后,module2中的func()就会覆盖module1中的func()。命名冲突是后面的会覆盖前面的。
解决方法:
- 使用import方式导入
- 修改成员名
- 给重名的方法用as重命名
5、模块导入顺序
查找顺序
1.当前程序所在目录
2.在当前程序所在工程的根目录
3.PYTHONPATH
4.系统目录
5.site_packages 第三方模块的安装目录
6、设置程序入口
当使用__name__属性在获取当前模块名时,会有两种效果
- 如果当前模块文件是主动执行时,
__name__得到的结果是字符串__main__表示这是程序的入口; - 如果当前模块文件是被动执行时(被别人导入时),
__name__得到的结果就是当前模块文件的文件名。
示例:
第一步:新建一个自定义模块(user_defined.py)并运行结果
print("name:",__name__)
######结果######
name: __main__
通过结果说明:直接运行python程序时,__name__的值为__main__
第二步:新建一个测试模块(test.py)导入模块并运行结果
import user_defined
######结果######
name: user_defined
通过结果说明:其他程序导入.py文件运行时,__name的值为文件名,即模块名。
作用: 依据该特性,最直接的作用就是,区分py文件直接被执行,还是被引入其他程序中。
应用
项目需求生成求和的模块,程序编写过程,通常会在程序中写上一些测试脚本,来验证程序是否正确。
第一步:新建一个自定义模块(user_defined.py)并运行测试结果
# 定义一个求和函数
def sums(a, b):
result = a + b
return result
# 以下针对模块的测试信息
c = sums(3, 4)
print(c)
######结果######
7
产生问题 那么这样就产生了一个问题,其他人在调用这个模块的时候,测试内容也会打印出来。当然可以在提交代码前,删除这些用于测试的代码。不过通常提交以后,可能会因为一些BUG,或者需求本身进行了调整,代码需要重新修改,那么测试代码也可能被再次添加。如此反复自然就徒增一些代码量。
解决方案 只要在测试代码前面加上:if __name__ == '__main__':那么,编写调试过程直接运行该模块时__name__ 的值为__main__ ",即测试内容被执行。而在导入该模块,__name__ 的值为py文件名,测试内容则不会被执行。
# 定义一个求和函数
def sums(a, b):
result = a + b
return result
# 程序被导入,以下代码不会被执行
if __name__ == '__main__':
c = sums(3, 4)
print(c)