一.模块
1.模块是有些功能开发者自己无法完成这样的话需要借助已经实现的函数来完成这些功能.
2.模块的分类:
内置模块:安装python解释器的时候跟着装上的那些方法,一般在lib文件夹中
第三方模块(扩展模块):没在安装python解释器的时候安装的那些功能,一般放在site_package文件夹中
自定义模块:自己写的代码,如果是一个通用的功能那你就把它当做一个模块,必须是py文件
3.模块的好处:分类,管理方法;节省内存;提供更多的功能
4.导入模块的语法:import 模块名 (如果模块名是一个py文件不加.py) 调用语法:模块名.方法/变量
import 模块名相当于执行这个模块所在的py文件,一个模块不会重复导入
模块名必须满足变量的命名规范,模块的名字都是小写字母开头的
import 模块名 执行步骤:
(1)找到"模块名"模块
(2)创建一个属于模块的内存空间
(3)执行模块
(4)在当前所在命名空间和模块之间建立引用关系
导入多个模块格式:
import 模块名1
import 模块名2
import 模块名3
..........
所有的模块导入都应该尽量放到文件的开头
模块的导入顺序: 内置模块---->第三方模块---->自定义模块
5.重命名模块名 语法:import 模块名 as 新名字 (在当前内存中将模块名改成新名字但是模块本来的名字不会改变)
6.导入模块语法:form 模块名 import 方法
form 模块名 import 方法(属性) 相当于执行了整个文件
导入方法名就能使用方法,不导入的变量不能使用,不导入并不意味着不存在而是没有建立文件到模块中其它变量的引用.
form 模块名 import 方法的执行步骤:
(1)找到文件名中的模块
(2)开辟一块属于这个模块的命名空间
(3)执行这个模块
(4)知道了要import的方法名,这个名字就会在本文件中创建一个变量,方法名指向模块命名空间中的方法.
当模块中导入的方法(变量)和本文件(模块)中的方法(变量)重名的时候,那么这个名字只代表最后一次对它赋值的那个方法(变量)
在本文件中的全局变量修改是完全不会影响到模块中变量的引用
导入多个方法:from 模块名 import 方法名1,方法名2
重命名:from 模块名 import 方法名1 as 新名字1,方法名2 as 新名字2
form 模块名 import * ==>模块中所有的变量都能引用
在模块中的__all__可以控制*导入的内容
语法:模块中__all__["方法名1","方法名2"] 当前文件form 模块名 import * ==>可以导入方法1和方法2
7.运行一个py文件的两种方式
(1)以模块的形式运行
(2)直接右键运行,cmd运行(以脚本的形式运行)
例:
print(__name__,type(__name__))
以脚本运行:__main__ <class 'str'>
以模块运行:my_modules <class 'str'>
以脚本的形式运行,那么需要在本文件中直接打印的代码上方加上if __name__ == "__main__":判断
某段代码在被当做模块导入的时候不执行,就把它写在if __name__ == "__main__":下面
在编写py文件的时候,所有不在函数和类中封装的内容都应该写在if __name__ == "__main__":(快捷键:main+tab)判断下面
例:
在my_modules.py文件内容:
import sys
print(__name__)
print(sys.modules["__main__"])
print(sys.modules[__name__])
在new_modules.py文件中内容:
import my_modules
结果:
在my_modules.py文件以脚本运行:
__main__
<module '__main__' from 'F:/面向对象/18.08.03/my_modules.py'>
<module '__main__' from 'F:/面向对象/18.08.03/my_modules.py'>
在my_modules.py文件模块运行:
my_modules
<module '__main__' from 'F:/面向对象/18.08.03/new_modules.py'>
<module 'my_modules' from 'F:\\面向对象\\18.08.03\\my_modules.py'>
8.模块路径
sys.modules存储了所有导入的文件名字和这个文件的内存地址
使用反射自己模块中的内容的语法:import sys getattr(sys.modules[__name__],变量名)
sys.modules[__name__]这句话写在哪个文件中就代表那个文件的命名空间
9.模块的搜索路径
print(sys.path) 打印结果:第一是当前运行的脚本所在的目录,第二个(不可靠)是pycharm在你打开项目的时候给你添加进来的项目,剩余的都是python内置的目录包括(内置函数和第三方函数)
自定义的模块能否被导入要看sys.path中,是否存在要导入的文件所在的目录
模块的搜索路径全部储存在sys.path列表中如果要导入的模块和当前执行的文件同级直接导入即可,如果要导入的模块和当前执行的文件不同级需要把要导入模块的绝对路径添加到sys.path列表中.
模块导入的时候,python执行解释--编译.当一个文件作为一个脚本被导入的时候,就会在这个文件所在的目录的__pycache__下生成一个编译好的文件为了之后导入这个文件的时候,直接读这个编译好的pyc文件,就可以节省一些导入时候的时间
10.重新加载模块
在import之后,再修改这个导入的模块,在执行程序过程中也不会生效.
在模块导入中,不要产生循环引用问题,如果发生循环导入就会发生明明写在这个模块中的方法却显示找不到
二.包
定义:集合了一组py文件,提供了一组复杂功能的
当提供的功能比较复杂,一个py文件写不下的时候创建了包
语法1:import 包名1.包名1.2.py文件(模块) as 新名字 调用:包名1.包名1.2.py文件(模块).变量(方法)
语法2:from 包名1.包名1.2 import py文件(模块) 调用:模块.变量(方法)
只导入import 包名,相当于执行了这个包下面的__init__.py
从包中导入模块,要注意这个包所在目录是否在sys.path列表中;如果是直接导入一个包,那么相当于执行这个包中的__init__文件,并不会帮你把这个包下面的其他包以及py文件自动导入到内存;如果你希望直接导入包之后,所有的这个包下面的其他包以及py文件都能直接通过包来引用,那么你要自己处理__init__文件.
例:将路径添加到sys.path列表中
import sys
path = "F:\面向对象\18.08.03"
sys.path.append(path)
__file__拿到当前文件的绝对路径
例:
import sys
ret = __file__.split("/")
base_path = "/".join(ret[:-2])
sys.path.append(base_path)
三.文件开发规范