您好!此笔记的文本和代码以网盘形式分享于文末!
因个人能力有限,错误处欢迎大家交流和指正!基础部分内容简单,但多且零散!
python之路——模块和包 | ||
模块定义:模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py | ||
import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到python解释器的内置模块 | ||
模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行 | ||
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突 | ||
为源文件(my_module模块)创建新的名称空间,在my_module中定义的函数和方法若是使用到了global时访问的就是这个名称空间。 | ||
.在新创建的命名空间中执行模块中包含的代码,见初始导入import my_module | ||
用法 | 栗子 | 结果 |
mymodule代码 | print('from the my_module.py') money = 1000 def read1(): print('my_module->read1->money',money) def read2(): print('my_module->read2 calling read1') read1() def change(): global money money = 0 | |
模块的独立名称空间 | # 模块测试 import mymodule # 变量、函数的独立名称空间 money = 10 print(money) print(mymodule.money) print(money) mymodule.change() print(money) print(mymodule.money) # 函数名相同测试 def read1(): print('======') mymodule.read1() read1() | from the my_module.py 10 1000 10 10 0 my_module->read1->money 0 ====== |
模块的别名 | # 模块别名 import mymodule as mym print(mym.money) | from the my_module.py 1000 |
据用户输入选择模块 | # 根据输入选择不同的模块 db_type = input('mysql or oracle: ') if db_type == 'mysql': import mysqltest as db elif db_type == 'oracle': import oracletest as db db.sqlparse() | mysql or oracle: mysql from mysql sqlparse |
选择读取不同的模块 | # if file_format == 'xml': # import xmlreader as reader # elif file_format == 'csv': # import csvreader as reader # data = reader.read_date(filename) | |
一行中导入多个模块 | # 一行中导入多个模块 # import sys,os,re | |
from导入 仍然是使用模块的 命名空间 | # from 导入 from mymodule import read1 money = 15 read1() | from the my_module.py my_module->read1->money 1000 |
from导入 函数调用 仍然是使用模块中的函数 | from mymodule import read2 def read1(): print('********') read2() | from the my_module.py my_module->read2 calling read1 my_module->read1->money 1000 |
覆盖关系 | from mymodule import read1 def read1(): print('********') read1() | from the my_module.py ******** |
变量赋值的绑定关系 | from mymodule import money, read1 money = 100 # 将当前位置的名字money绑定到了100 print(money) # 打印当前的名字 read1() # 读取my_module.py中的名字money,仍然为1000 | from the my_module.py 100 my_module->read1->money 1000 |
from导入的重命名 和导入多个 | # 支持as from mymodule import read1 as read # 支持导入多行 from mymodule import (read1, read2, money) | |
from my_module import * | 把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置 | 缺点:造成误覆盖和可读性差 |
from my_module import * 优化 | __all__=['money','read1'] #这样在另外一个文件中用from my_module import *就这能导入列表中规定的两个名字 | |
模块的循环引用 | ||
模块的加载与修改 | def func1(): print('func1') import time,importlib import aa time.sleep(20) # 等待期间修改aa.py中的内容 # importlib.reload(aa) aa.func1() | |
将模块作为脚本执行 | 当做脚本运行: __name__ 等于'__main__' 当做模块导入: __name__= 模块名 def fib(n): a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() if __name__ == "__main__": print(__name__) num = input('num :') fib(int(num)) | |
模块搜索路径 | ||
查找模块中定义的名字 | import my_module dir(my_module) | 3.4 模块的搜索路径 |
编译python文件:为了提高加载模块的速度,解释器会在__pycache__目录中下缓存每个模块编译后的版本.pyc文件 | ||
你可以使用-O或者-OO转换python命令来减少编译模块的大小 | ||
- O 转换会帮你去掉assert语句 | ||
-OO转换会帮你去掉assert语句和__doc__文档字符串 | ||
在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的 | ||
dir()不会列举出内建函数或者变量的名字 | import builtins dir(builtins) | |
包 | ||
包是一种通过使用‘.模块名’来组织python模块名称空间的方式。 | ||
凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法 | ||
包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录) | ||
产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件 | ||
在python3中,即使包下没有__init__.py文件,import 包仍然不会报错 | ||
创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块 | ||
模块 最重要是 自定义模块 | ||
包的绝对路径和相对路径 | ||
包的引用和 特点 | ||
用法 | 栗子 | 结果 |
创建一个包 | # 创建包 import os os.makedirs('glance/api') os.makedirs('glance/cmd') os.makedirs('glance/db') l = [] l.append(open('glance/__init__.py', 'w')) l.append(open('glance/api/__init__.py', 'w')) l.append(open('glance/api/policy.py', 'w')) l.append(open('glance/api/versions.py', 'w')) l.append(open('glance/cmd/__init__.py', 'w')) l.append(open('glance/cmd/manage.py', 'w')) l.append(open('glance/db/__init__.py', 'w')) l.append(open('glance/db/models.py', 'w')) map(lambda f: f.close(), l) | |
import 用法 | # 当前文件与glance同级别的中测试 import glance.db.models glance.db.models.register_models('mysql') | from models.py: mysql |
form import 用法 | # import导入的模块明确且不能带点 from glance.db import models models.register_models('mysql') from glance.db.models import register_models register_models('mysql') | from models.py: mysql from models.py: mysql |
__init__.py文件 | # __init__.py文件 第一次导入包或者是包的任何其他部分, # 都会依次执行包下的__init__.py文件 # 修改glance下 init文件 查看执行 from glance.db import models models.register_models('mysql') | form glance __init__.py File from models.py: mysql |
from glance.api import * 的用法 | # 该语句只会导入包api下__init__.py文件中定义的名字, # 可以在这个文件中定义__all___ """ #在api文件夹下__init__.py中定义 x=10 def func(): print('from api.__init.py') __all__=['x','func','policy'] """ # 使用import * 的用法 但是versions 依然是不能使用的 from glance.api import * policy.get() | form glance __init__.py File from policy.py |
绝对导入和相对导入 | # 绝对导入和相对导入 """ 包内文件互掉, 注意事项和优缺点 绝对导入:以glance作为起始 相对导入:用.或者..的方式最为起始 (只能在一个包中使用,不能用于不同目录内) """ # 在glance/api/version.py 文件中 # # 绝对导入 # from glance.cmd import manage # manage.main() # # # 相对导入 # from ..db import models # models.register_models('db') # 测试结果 与glance同级文件 from glance.api import versions # # 导入自定义的子模块时,应该使用form……import # # 绝对或者相对导入,且包的相对导入只能用from的形式。 | form glance __init__.py File from manage.py from models.py: db |
绝对路径问题 | 看视频 欠 | |
相对路径问题 | 看视频 欠 | |
单独导入包 | # 单独导入包 # 单独导入包名称时不会导入包中所有包含的所有子模块 import glance glance.cmd.manage.main() | form glance __init__.py File Traceback (most recent call last): |
# 解决办法 """ #在glance/__init__.py中添加 from . import cmd #在glance/cmd/__init__.py中添加 from . import manage """ import glance glance.cmd.manage.main() | form glance __init__.py File from manage.py | |
python软件开发 目录结构规范 | # python软件开发目录结构规范 import os # bin/ 存放项目的一些可执行文件 os.makedirs('soft/bin') # conf/ 配置文件 os.makedirs('soft/conf') # core/ 存放项目的所有源代码(核心代码) # 1>源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。 os.makedirs('soft/core') # core/tests/ 子目录 存放单元测试代码; os.makedirs('soft/core/tests') # db/ 数据库文件 os.makedirs('soft/db') # lib/ 库文件,放自定义模块和包 os.makedirs('soft/lib') # log/ 日志文件 os.makedirs('soft/log') # docs/ 存放一些文档 os.makedirs('soft/doc') l = [] # README 是项目说明文件 l.append(open('soft/README', 'w')) l.append(open('soft/__init__.py', 'w')) | |
# start 写启动程序 l.append(open('soft/bin/start.py', 'w')) l.append(open('soft/bin/__init__.py', 'w')) # setting 写相关配置 l.append(open('soft/conf/setting.py', 'w')) l.append(open('soft/conf/__init__.py', 'w')) # my_log_setting 存放logging配置文件 l.append(open('soft/conf/my_log_setting.py', 'w')) # config.ini 存放配置文件 l.append(open('soft/conf/config.ini', 'w')) # main 程序的入口,存放核心逻辑代码 l.append(open('soft/core/main.py', 'w')) l.append(open('soft/core/__init__.py', 'w')) # 存放单元测试代码 l.append(open('soft/core/tests/test.main.py', 'w')) l.append(open('soft/core/tests/__init__.py', 'w')) # 写数据库文件 l.append(open('soft/db/db.json', 'w')) # 存放常用功能 l.append(open('soft/lib/common.py', 'w')) l.append(open('soft/lib/__init__.py', 'w')) # 存放日志 l.append(open('soft/log/all.log', 'w')) map(lambda f: f.close(), l) |
愿有更多的朋友,在网页笔记结构上分享更逻辑和易读的形式:
链接:暂无
提取码:暂无