Python——模块简介
模块分类:
1. 内置模块
2. 第三方模块
3. 自定义模块
py文件的两种功能:
1. 脚本:一个文件就是整个陈旭,用来被执行。
2. 模块:文件中存放着一堆的功能,用来被导入使用。
模块与包
模块:将一些具有相同功能且经常会被使用的代码放在一个py文件中。该py文件就可以叫一个模块。
包:只要文件夹下含有__init__.py文件就是一个包。
导入和加载:
导入:指将py文件导入进内存当中进行后期的使用。(如果需要使用模块方法,那么每次都会进行导入。而不会再重新加载模块内代码了。)
import test #当第一次导入时,会加载所有test内的代码进入到内存。(相当于运行了一遍)
加载:指运行所导入模块内的具体方法。(当第一次导入模块时,会自动加载所导入的模块。并且加载一次后,后面再次导入就不会进行加载。)
import test print(test.name) #相当于打印已经加载好的name变量。
导入模块:
需要注意点:
1. 导入模块时,只会把当前运行的py文件所属的路径加载到python路径中去,而不会将其他包内的路径一同加入。而使用pycharm时,会将创建的项目路径一同加入到python路径中。而如果使用非pycharm运行时,因为没有加载而出错,所以如果包含多个包的项目,首先将根路径加入。
import os BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
2. 导入模块时,要尽量小的来导入,如果能使用该模块的大部分功能,那么可以导入所有。如果只用一个,那么最好就使用form来进行导入。
——————————————Day04.py———————————— def a(): print(a) print(123) ——————————————test.py—————————————— 1. import Day04 #将Day04内所有函数进行导入。 Day04.a() 2. from Day04 import a #将包中某一个函数单独提取。 a() 3. from Day04 import * #功效和1一样。 4. from Day04 import a as f #给a函数重新命名,以免在本函数内有相同命名。 f()
第一次导入模块将执行的三件事:import与from同样效果。
1. 创建一个以模块名命名的名称空间。
2. 执行这个名称空间(即导入的模块)里的代码。
3. 通过此模块名 . 的方式引用该模块里的内容
import的使用
import语句是可以在程序中的任意位置使用的。且针对同一个模块import很多次,为了防止你重复导入,python的优化手段:
1. 第一次导入后就将模块名加载到内存了。
2. 后续的import语句仅对已经加载到内存中的模块对象增加了一次应用,不会重新执行模块内的语句。
起别名:
import test as B from test import func as x ''' 1. 将很长的模块名改短,方便使用 2. 有利于代码的扩展和优化 '''
导入多个模块:
''' 1. 逐一导入 2. 从小到多的名称导入 ''' import x import xx import xxx
from X import *
会把X中的不是以下划线(_)开头的名字都导入到当前位置。
使用all来配合使用。
#test.py __all__=['func'] print('this is test.py') def func(): print('this is test.py_func') def func2(): print('this is test.py_func2') —————————————————————————————————————————————————— #run.py from test import * func() func2() #由于没有写在all里,将会报错。
执行文件不等于导入文件:
在项目中应尽量避免出现循环/嵌套导入,如果出现多个模块都需要共享的数据,可以将共享的数据集中存放在某一个地方。具体事例可以看练习题2和3加深理解。
用字符串形式来导入模块:
1. getattr
import test a = getattr(test,'a') print(a)
2. __import__('模块名')
a = __import__('test') print(a.a)
3. 导入多次相同的模块,只会使用第一次导入时的加载内容。如果必须要加载两次可以使用:importlib模块。
import importlib import test1 importlib.reload(test1)
4. 可以通过导入模块来构造出来一个单例模式。相当于只加载一次刚导入的
+++++++++jd.py++++++++ class Foo(object): pass obj=Foo() +++++++++app1+++++++++ import jd print(jd.obj) +++++++++app2++++++++++ import jd print(jd.obj)
__name__的作用:
1. 当文件被当做脚本执行时:__name__=='__main__'
2. 当文件被当做模块导入时:__name__ == 模块名
这样可以用来控制.py文件在不同的应用场景下执行不同的逻辑。
Python引用模块规则及顺序:
1. 内存中已经加载的模块进行寻找
2. 内置模块中寻找
3. sys.path中路径包含的模块中寻找
4. 再没找到就报错。
小练习1
''' 看两个得出结果是否一样,如果不一样为什么。 ''' # test.py # print('this is test.py') # def func(): # print('this is test.py_func') # def func(): # print('24') # from test import func # func() #得出的结果 # from test import func # def func(): # print('24') # func() #得出的结果 ''' 说明当import的名称和现有的方法相冲突时,会覆盖掉前面的内存指向。 '''
小练习2
''' 创建的3个文件,当运行run时,会不会报错,为什么?他们的流程是什么。 如果出错,那么如何改正。 ''' #m1.py # print('正在导入m1') # from m2 import y # x = 'm1' #m2.py # print('正在导入m2') # from m1 import x # y='m2' #run.py # import m1 ''' 1. 会报错 2. 运行run,运行m1,运行m2,由于此时m1还在导入m2的过程中,并没有将x导入到内存,所以m2无法导入x,报错。 3. 将from m2 import y 更改到x下面即可 '''
小练习3
''' 运行m1,会不会报错,如果报错是哪里错了。流程是什么 ''' #m1.py # print('正在导入m1') # from m2 import y # x = 'm1' #m2.py # print('正在导入m2') # from m1 import x # y='m2' ''' 1.打印m1,导入m2 2.打印m2,导入m1 3.打印m1,导入m2,由于已经导入了m2,所以直接要y,没有报错了。 '''