模块的介绍
什么是模块
模块就是一系列功能的集合体
模块大致分为四个类别:
一个py文件就是一个模块,文件名叫test.py,模块名叫test
一个包含了_init_.py文件的文件夹称之为包,包也是模块
使用c编写并链接到python解释器的内置模块
已被编译为共享库或DLL的C或C++扩展
模块的三种来源:
自带的模块
第三方模块
自定义模块
为何要用模块
(自带的模块,第三方模块)->拿来注意,提升开发效率
自定义模块是为了解决代码冗余问题
如何用模块
模块都是用来被导入使用的,不是直接使用的
首次导入模块发生的事情
1.运行spam.py,创建一个模块的名称空间,将spam.py运行过程中产生的名字都丢到模块的名称空间中
2.在当前名称空间中得到一个名字,改名字指向模块的名称空间
后续的导入直接引用首次导入成功的,不会重复执行spam.py,不会重复创建名称空间
导入规范
通常情况下,所有的导入语句都应该写入文件的开头,然后分为三步:
第一部分,先导入内置的模块
第二部分,导入第三方
第三部分,导入自定义的
import的其他用法
import os,sys,re
import spam as sm #模块名换别名
print(sm.m)
import spam as a
print(a.h)
print(a.m)
m = 85
print(m)
首次导入模块发生的事情
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)
其他用法
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()
模块的搜索路径和优先级
内置
import time, os
print(time) #
print(os) #
import sys
print(sys.path) #导入一个出一个当前执行的文件夹的文件路径
环境变量以当前执行文件为准,当前文件夹默认加入sys.path里面
sys.path里面加文件,属于临时加文件,程序运行结束就直接还原了
设置sys.path文件路径案例
import a1 a1在同一个文件夹下直接调用就可以
a1.f1()
import aaa.a1 as m a1在同一个文件夹下的子文件夹aaa,aaa.a1代表路径分隔符的意思
m.f1()
import sys
sys.path.append(r"D:\pycharm文件\test") a2在不同的文件夹下面,且a2的文件上面还有另一个名称为a2的一个子文件夹,需要把路径添加到sys.path里面
print(sys.path)
import a2.a2 as m
m.f2()
目录规范
导入文件目录处理逻辑
1.把所有的文件环境变量都添加到启动的文件start文件中,快捷方式:直接把启动文件拖入根文件夹ATM中,
2.把文件的启动项从核心文件中拆开,把核心文件导入到启动项中
3.把日志文件从核心代码文件中拆开,将日志文件导入到核心代码文件中
4.把日志路径文件从日志文件中拆开,将日志文件路径导入到日志文件中
**核心代码模块**
# 装饰器模板
# def outter(func):
# def wrapper(*args, **kwargs):
# res = func(*args, **kwargs)
# return res
#
# return wrapper
# func_dic = {
# "1": ["提现", withdraw],
# "2": ["转账", transfer],
# "3": ["查询余额", check_balance]
# }
from lib import common
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