模块的介绍
什么是模块
模块就是一系列功能的集合体
模块大致分为四个类别:
一个py文件就是一个模块,文件名叫test.py,模块名叫test
一个包含了_init_.py文件的文件夹称之为包,包也是模块
使用c编写并链接到python解释器的内置模块
已被编译为共享库或DLL的C或C++扩展
模块的三种来源:
自带的模块
第三方模块
自定义模块
为何要用模块
(自带的模块,第三方模块)->拿来注意,提升开发效率
自定义模块是为了解决代码冗余问题
如何用模块
模块都是用来被导入使用的,不是直接使用的
首次导入模块发生的事情
1.运行spam.py,创建一个模块的名称空间,将spam.py运行过程中产生的名字都丢到模块的名称空间中
2.在当前名称空间中得到一个名字,改名字指向模块的名称空间
后续的导入直接引用首次导入成功的,不会重复执行spam.py,不会重复创建名称空间
导入规范
通常情况下,所有的导入语句都应该写入文件的开头,然后分为三步:
第一部分,先导入内置的模块
第二部分,导入第三方
第三部分,导入自定义的
import的其他用法
导入内置模块的用法:import os,sys,re
自定义模块用法
创建一个自定义模块spam。
h = "王辣辣"
m = 100
_all_ = [h, m]
def read():
print("wang lala")
导入自定义模块
import spam as sm # as模块名换别名
print(sm.m) # 100
import spam as a
print(a.h) # 王辣辣
print(a.m) # 100
m = 85
print(m) # 85
创建一个自定义模块spam。
h = "王辣辣"
m = 100
_all_ = [h, m]
def read():
print("wang lala")
from ... import ... 用法
1.运行spam.py,创建一个模块的名称空间,将spam.py运行过程中产生的名字都丢到模块的名称空间中
from spam import h
print(h)
2.在当前名称空间中得到一个名字,该名字指向模块的名称空间
后续的导入直接引用首次导入成功的,不会重复执行spam.py,不会重复创建名称空间
from spam import m
print(m)
from spam import read
read()
m = 2000
print(m) # 2000
其他用法
from spam import * # *号会把spam所有的变量名都导入到内存里面
read()
print(h)
print(m)
文件被导入另一个文件,会直接运行被导入模块的代码,创建一个模块的名称空间,将模块文件运行过程中产生的名字都丢到模块的名称空间中。在当前名称空间(执行文件)中得到一个模块的名字,该名称指向模块的名称空间中的对应的名称。
import与from import 导入模块两种语言的优点与缺点:
import 模块名
优点:与当前名称空间的名称不会冲突
缺点:每次调用都需要加模块名
from (模块名.子文件)import(数据/功能)
优点:调用简洁
缺点:如果当前名称空间也定义了相同的名称(功能/数据),则导入模块的(功能/数据)无法实现
循环导入问题
在一个模块里面调用另外一个模块,最好是不要这样调用。如果非要这样调用,可以利用函数定义时只监测语法,不执行代码的特性。
把需要调用的模块用函数用改成函数的形式
案例:
m1模块代码
print("========m1.py")
def f1():
from m2 import y
print(y)
x = 1111
m2模块代码
print("========m2.py")
def f2():
from m1 import x
print(x)
y = 2222
import m1
m1.f1()
import m2
m2.f2()
模块的搜索路径和优先级
1. 内存中已经导入好的
2. 内置 # python自带的模块
3. sys.path # sys.path是一个环境变量,环境级别的变量是只整个位置,内置的更外层空间。临时加文件路径,文件运行结束会释放
优先级:内存中已经导入好的--->内置--->sys.path
内置
import time, os
print(time) # <module 'time' (built-in)> time 就是一个内置文件
print(os) # <module 'os' from 'D:\\Python38\\lib\\os.py'> os是一个文件夹
import sys
print(sys.path) # 导入一个出一个当前执行的文件夹的文件路径
环境变量以当前执行文件为准,当前文件夹默认加入sys.path里面
sys.path里面加文件,属于临时加文件,程序运行结束就直接还原了
设置sys.path文件路径案例
调用函数f1()
import a1 a1在同一个文件夹下直接调用就可以
a1.f1()
import aaa.a1 as m a1在同一个文件夹下的子文件夹aaa,aaa.a1代表路径分隔符的意思
m.f1()
添加系统环境变量
import sys # 导入sys模块
print(__file__) # 打印当前文件所在的绝对路径
os.path.dirname(__file__) # 当前文件路径的上一级文件目录
os.path.dirname(os.path.dirname(__file__)) # 当前文件的上两级目录
BASE_PATH = os.path.dirname(os.path.dirname(__file__)) # 文件路径一般会设置成常量
sys.path.append(BASE_PATH) # 将文件的根目录添加到系统环境变量里面
目录规范
导入文件目录处理逻辑:
1.把所有的文件环境变量都添加到启动的文件start文件中
2.把文件的启动项从核心文件中拆开,把核心文件导入到启动项中
3.把日志文件从核心代码文件中拆开,将日志文件导入到核心代码文件中
4.把日志路径文件从日志文件中拆开,将日志文件路径导入到日志文件中
快捷方式:直接把启动文件拖入根文件夹ATM中,当前执行程文件所在的文件夹默认为系统环境变量文件夹
核心代码模块
"""
func_dic = {
"1": ["提现", withdraw],
"2": ["转账", transfer],
"3": ["查询余额", check_balance]
}
"""
from lib import common
func_dic = {}
# 将func_dic写成装饰器形式
def outter(n, msg):
def wrapper(func):
func_dic[str(n)] = [msg, func]
return wrapper
@outter(1, "提现")
def withdraw():
print("提现功能")
@outter(2, "转账")
def transfer():
print("转账功能")
common.logger("nana给吴彦祖转了一个亿")
@outter(3, "查询余额")
def check_balance():
print("查询余额")
def run():
while True:
for k, v in func_dic.items():
print(k, v[0])
choice = input("请输入命令编号,输入q退出").strip()
if choice == "q":
break
if choice in func_dic:
func_dic[choice][1]()
else:
print("输入错误,请重新输入")
文件运行模块
import sys
sys.path.append(r"D:\pycharm文件\ATM\core")
sys.path.append(r"D:\pycharm文件\ATM\lib")
sys.path.append(r"D:\pycharm文件\ATM")
from core import src
src.run()
如何把文件路径写活(处理环境变量)
# print(__file__) # 当前文件所在的绝对路径
# import os
# print(os.path.dirname(os.path.dirname(__file__))) # __file__显示当前文件的上一级文件路径
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# sys.path.append(BASE_DIR)
from core import src # 可以把执行文件直接拖到顶级文件夹下面,这样当前运行程序的文件夹会默认为环境变量文件夹
src.run()
日志模块
import time
from conf import settings
def logger(aaa):
with open(r"%s" % settings.LOG_PATH, mode="at", encoding="utf-8") as f:
f.write("%s %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), aaa))
日志文件路径配置文件
import os
# LOG_PATH = r"D:\pycharm文件\ATM\log\access.log"
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) #os.path.dirname 动态获取当前文件的绝对路径,__file__取当前文件所在的绝对路径
LOG_PATH = r"%s\log\access.log" % BASE_DIR