python模块:
一个模块编写完毕之后,其他模块直接调用,不用再从零开始写代码了,节约了工作时间;避免函数名称和变量名称重复,在不同的模块中可以存在相同名字的函数名和变量名,但是,切记,不要和系统内置的模块名称重复。
模块的三种来源:
1.内置的(python解释器自带)
2.第三方的(别人写的)
3.自定义的(我们自己写的)
模块的四种表现形式:
1.使用python编写的py文件(也就意味着py文件也可以称之为模块:一个py文件也可以称之为一个模块)
2.已被编译为共享库或DLL的C或C++扩展(了解)
3.把一系列模块组织到一起的文件夹(文件夹下有一个__init__.py文件,该文件夹称之为包)包:一系列py文件的结合体
4.使用C编写并连接到python解释器的内置模块
为什么要用模块:
1.用别人写好的模块(内置的,第三方的):典型的拿来主义,极大的提高开发效率
2.使用自己写的模块(自定义的):当程序比较庞大的时候,你的项目不可能只在一个py中那么当多个文件中都需要使用相同的方法的时候 可以将该公共的方法写到一个py文件中其他的文件以模块的形式导过去直接调用即可
在我们使用模块的时候一定要区分哪个是执行文件,哪个是被导入文件。
#我们先自定义一个模块 名为mod.py;
print("hello world")
name = "fan"
def func1():
print("fan1")
def func2():
print("fan2")
func()
#然后我们使用里一个py文件进行导入这个模块;
import mod
import mod
import mod
#打印输出:
hello world
#可以发现只打印了一次,是因为每次导入模块时,解释器都回去检查一下这个模块有没有之前被导过,多次导入不会再执行模块文件。
"""
模块导入的过程:
1.找到这个需导入的模块;
2.判断这个模块是否被导入过;
如果没有被导入过:
创建一个属于这个模块的命名空间;如果用户没有定义变量来引用这个模块的内存地址的话,
那么就使用模块的名称来引用这个模块的内存地址;如果用户使用as来指定变量接受这个内存地址的话,
那么就将内存地址赋值给这个变量;且下文在调用时只能使用这个变量进行调用不能再使用模块名进行调用了,然后执行这个模块中的代码。
如果该模块已经被导入过:
那么解释器不会重新执行模块内的语句,后续的import语句仅仅是对已经加载到内存中的模块的对象
关于导入的模块与当前空间的关系:
带入的模块会重新开辟一块独立的名称空间,定义在这个模块中的函数把这个模块的命名空间当做全局命名空间,
这样的话当前的空间就和模块运行的空间分隔了,谁也不影响谁;
为模块起别名:
模块在导入的时候开辟了新空间内存,默认是使用模块的名称来引用这个内存地址的,有时候模块的名称很长再加上执行调用里面的功能的时候,
就显的很不方便,为了更好的使用模块,我们可以给模块起别名;也就是在导入模块的时候我们不让它使用默认的名字来引用内存地址,
而是由我们自己定义的变量来引用这个模块的内存地址;
方法:import mdddddddddd as md
这样的话就表示使用变量md来引用这个内存地址,然后我们在文中再使用这个模块的时候,只要使用md来调用这个模块里的功能即可。
"""
from...import和import:
from...import跟import不同的是import会读取整个模块,所以impot必须进行定义后才能读取它的变量名,而from...import访问模块中的名字不需要加模块名前缀,它直接拿到指向模名称空间中某个值的名字进行访问的,但是from...import在访问模块中的名字可能会与当前执行文件中的名字冲突。例如:
# import datetime是引入整个datetime模块,如果使用datetime模块中的datetime类,
需要加上模块名的限定。
import datetime
print datetime.datetime.now()
# 如果不加模块名限定会出现错误:TypeError: 'module' object is not callable \
AttributeError: 'module' object has no attribute 'now'
# from datetime import datetime是只引入datetime模块里的datetime类,
在使用时无需添加模块名的限定。
from datetime import datetime
print datetime.now()
模块的查找顺序是:先从内存中找,内存中没的话会去内置中找,内置中找不到的话会去sys.path中找(环境变量)
if __name__ == '__main__':
只要我们创建了一个模块(一个.py文件),这个模块就有一个内置属性name生成,该模块的 name 的值取决于如何应用这个模块。简单的说就是,如果我们直接运行该模块,那么__name__ == "__main__";如果你 import 一个模块,那么模块name 的值通常为模块文件名。
如,创建一个test1.py:模块中,首先定义了函数func(),用来打印出hello, world!
然后判断__name__ 是否等于 __main__,如果等于,就打印。
def func():
print('hello, world!')
if __name__ == "__main__":
func()
# 输出结果为:
hello, world!
# 说明__name__ 等于 __main__
# 当文件被当做执行文件执行的时候__name__打印的结果是__main__
# 当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀)
模块的绝对导入和相对导入:
绝对导入的格式为 import A.B 或 from A import B,相对导入格式为 from . import B 或 from ..A import B,.代表当前模块,..代表上层模块,...代表上上层模块,依次类推。
相对导入可以避免硬编码带来的维护问题,例如我们改了某一顶层包的名,那么其子包所有的导入就都不能用了。但是存在相对导入语句的模块,不能直接运行,否则会有异常:
如果是绝对导入,一个模块只能导入自身的子模块或和它的顶层模块同级别的模块及其子模,
如果是相对导入,一个模块必须有包结构且只能导入它的顶层模块内部的模块所以,如果一个模块被直接运行,则它自己为顶层模块,不存在层次结构,所以找不到其他的相对路径,所以如果直接运行python xx.py ,而xx.py有相对导入就会报错
# 绝对导入
import sys, os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
# 相对导入:
import sys, os
from . import models
from ..proj import settings
"""
绝对导入必须依据执行文件所在的文件夹路径为准
绝对导入无论在执行文件中还是被导入文件都适用
相对导入
.代表的当前路径
..代表的上一级路径
...代表的是上上一级路径
相对导入不能再执行文件中使用
相对导入只能在被导入的模块中使用,使用相对导入 就不需要考虑
执行文件到底是谁 只需要知道模块与模块之间路径关系
"""
软件开发目录规范:
1.首先是项目名:
2.bin 文件夹:
start.py 启动文件
3.conf 文件夹:
settings.py 项目配置文件
4.core 文件夹:
src.py 项目核心逻辑
5.db 文件夹:
数据库相关文件
6.lib 文件夹:
common.py 项目所用到的公共功能
7.log 文件夹:
log.log 项目的日志文件
8.Readme:
文本文件:项目简介