python基础之模块(一)
概述
模块,用一砣代码实现了某个功能的代码集合。一个功能可能由 N 个函数来组成,这些函数写到一个py文件中,那么这个Py文件就是传说中的模块.
模块可将代码归类,让你的代码看着条理清晰,当然还需要你在提前设计程序时的设计思路清晰,更多的调用,慢慢练吧,骚年!
模块使用时的特点:
- 先导入,后使用
- 模块可为目录,也可为py文件
模块分为三类:
- 内置模块
- 第三方模块
- 自定义模块
自定义模块
自定义模块顾名思义就是自己编写的对某功能实现的一些函数集合.
模块的导入
模块导入的方式比较多:
import index #执行py与index在同一目录
from index import func1 #执行py与index在同一目录,func1为index.py中的某个函数
又比如,有某个目录:
|____1.py
|____2.py
|______pycache__
| |____geno.cpython-35.pyc
|____db
|____digui.py
|____geno.py
|____iter_test.py
|____lib
| |______pycache__
| | |____commands.cpython-35.pyc
| |____commands.py
1.py想导入lib/commands.py文件中的东西,commands是一个模块,我们可以这么做:
from lib import commands #导入
commands.func1 #调用func1函数
#也可以这么用
from lib.commands import *
func1 #直接调用
那么问题来了,不同目录之间怎么调用呢?
.
|______init__.py
| |____a
| | |____22.py
| | |______init__.py
| | |______pycache__
| | | |______init__.cpython-35.pyc
| | | |____test.cpython-35.pyc
| | |____test.py
| |____b
| | |____1.py
b/1.py 想调用a/22.py 模块,这就需要添加环境变量来调用了
import sys
sys.path.append('..')
但这么搞是不是有点太low了,来个比较高档点吧:
import sys,os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
为毛这么搞可以?来解释下:
- file 获取当前文件以及所在的位置,但有可能得到的是相对路径
- os.path.abspath() 获取文件的绝对路径
- os.path.dirname() 获取文件的上级目录
这里需要插播一下python自动创建的全局变量:
- file 获取当前文件以及所在的位置,但有可能得到的是相对路径
- name 如果模块被导入,那么__name__的名字就为模块的名字,如果模块是被直接执行,__name__的值为’main’
- main 仅仅是用来检测该文件代码是否是主程序文件,也即非模块。通常可以用来测试模块比如你可以通过检测来执行一些测试用例,但当文件作为模块导入其他程序中时,检测__main__会为False,即里面的代码不会执行
- doc 获取文件的注释
- cached 字节码的路径
- package 一般使用方式:print(xxx.package),显示xxx模块的文件路径
内置模块
sys模块
来看一个比较好玩的进度条吧,装逼器:
import sys,time
def view_bar(num,totle):
rate=num/totle
rate_num=int(rate*100)
r='\r%s>%d%%'%('='*num,rate_num)
sys.stdout.write(r)
sys.stdout.flush()
if __name__ == '__main__':
for i in range(101):
time.sleep(0.1)
view_bar(i,100)
sys比较简单,主要用来提供对python解释器的操作.
sys.argv #命令行参数List,第一个元素是程序本身路径
sys.exit(n) #退出程序,正常退出时exit(0)
sys.version #获取Python解释程序的版本信息
sys.maxint #最大的Int值
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform #返回操作系统平台名称
sys.stdin #输入相关
sys.stdout #输出相关
sys.stderror #错误相关
os模块
提供对操作系统进行调用的接口:
os.getcwd() #获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") #改变当前脚本工作目录;相当于shell下cd
os.curdir #返回当前目录: ('.')
os.pardir #获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2') #可生成多层递归目录
os.removedirs('dirname1') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') #生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() #删除一个文件
os.rename("oldname","new") #重命名文件/目录
os.stat('path/filename') #获取文件/目录信息
os.sep #操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep #当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep #用于分割文件路径的字符串
os.name #字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ #获取系统环境变量
os.path.abspath(path) #返回path规范化的绝对路径
os.path.split(path) #将path分割成目录和文件名二元组返回
os.path.dirname(path) #返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) #如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) #如果path是绝对路径,返回True
os.path.isfile(path) #如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) #如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) #返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) #返回path所指向的文件或者目录的最后修改时间
os.getlogin() #获取当前登录用户
重点说下os.path.join()的用法:
一般是在拼接路径的时候用的。举个例子
os.path.join(“home”, "me", "mywork")
在Linux系统上会返回
“home/me/mywork"
在Windows系统上会返回
"home\me\mywork"
好处是可以根据系统自动选择正确的路径分隔符"/"或"\"
之前博客中有写一篇判断文件是否存在的模块,链接在这:
点我点我点我
hashlib
用于加密相关的操作,替代了MD5和SHA,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
看下例子:
import hashlib
obj=hashlib.md5(bytes('asdfasdf',encoding='utf8')) #1
obj.update(bytes('123',encoding='utf8'))
res=obj.hexdigest()
print(res)
1位置有一个'hashlib.md5(bytes('asdfasdf',encoding='utf8'))',干啥用的呢?因为如果碰到撞库攻击的时候,对方会用的密码字典去匹配你的密码,所以我们在前面加上自己的字段,这样生成的md5值肯定和对方的不一样了!
之前博客中有一篇说了下一个密码加密的东西,链接:
点我点我点我
random模块
随机模块,比较简单,不多做说明了.
之前博客中有一篇随机生成验证码的模块,链接在这:
点我点我点我
序列化模块
Python中序列化数据的模块有两个:
- json 用于【字符串】和 【python基本数据类型】 间进行转换
- pickle 用于【字符串】和 【python基本数据类型】 间进行转换
其实无非是load/dump/loads/dumps的应用
json 和 pickle 区别
json 更适合夸语言操作,字符串,基本数据类型操作
pickle 适合所有类型的序列化 python 操作,pickle 仅适用于 python,2和3可能不兼容
json
通过 json.loads 反序列化时,一定要注意双引号,要与其他语言格式相匹配了
之前博客写过一片json的使用,链接:
点我点我
pickle
大体类似,上个例子吧,需要注意的一点就是二进制文件的读写模式:
import pickle
li=[1,2,3,4,5,'cc']
####pickle.dump(li,open('db','wb'))
r=pickle.dumps(li)
print(r)
res=pickle.loads(r)
print(res)
out:
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04K\x05X\x02\x00\x00\x00ccq\x01e.'
[1, 2, 3, 4, 5, 'cc']
requests模块
Requests 是一个第三方的库,是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。要比urllib模块强大.
安装很简单: pip3 install requests
配合json可以玩个有意思的天气查询:
import json,requests
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
response.encoding='utf-8'
dic=json.loads(response.text) #text 指 requests生成的内容
print(dic)
out:
{'desc': 'OK', 'data': {'wendu': '20', 'forecast': [{'fengxiang': '无持续风向', 'date': '14日星期二', 'low': '低温 18℃', 'high': '高温 24℃', 'fengli': '微风级', 'type': '雷阵雨'}, {'fengxiang': '无持续风向', 'date': '15日星期三', 'low': '低温 17℃', 'high': '高温 30℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '16日星期四', 'low': '低温 20℃', 'high': '高温 33℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '17日星期五', 'low': '低温 22℃', 'high': '高温 33℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '18日星期六', 'low': '低温 21℃', 'high': '高温 31℃', 'fengli': '微风级', 'type': '多云'}], 'yesterday': {'fx': '无持续风向', 'date': '13日星期一', 'low': '低温 18℃', 'high': '高温 22℃', 'fl': '微风', 'type': '雷阵雨'}, 'city': '北京', 'ganmao': '各项气象条件适宜,无明显降温过程,发生感冒机率较低。', 'aqi': '45'}, 'status': 1000}
time模块
时间相关的操作,有time,datetime两个模块.
python中的时间表示,有三种方式:
- 1970年1月1日之后的秒,即:time.time()
- 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
- 结构化时间 是一个元组数据,元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
import time
import datetime
print(time.time()) #返回当前系统时间戳
print(time.ctime()) #输出Tue Jan 26 18:23:48 2016 ,当前系统时间
print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式
print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式
print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,但返回本地时间
print(time.mktime(time.localtime())) #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
time.sleep(4) #常用,用来暂停
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式
print(time.strptime("2016-01-28","%Y-%m-%d") ) #将字符串格式转换struct_time格式
################################
print(datetime.date.today()) #输出格式 2016-01-26
print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 将时间戳转成日期格式
current_time = datetime.datetime.now() #
print(current_time) #输出2016-01-26 19:04:30.335935
print(current_time.timetuple()) #返回struct_time格式
###############################################
"""datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])"""
print(current_time.replace(2014,9,12)) #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换
############################################
str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式
new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天
new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天
new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时
new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s
具体时间的表示方式:
%Y Year with century as a decimal number.
%m Month as a decimal number [01,12].
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%M Minute as a decimal number [00,59].
%S Second as a decimal number [00,61].
%z Time zone offset from UTC.
%a Locale's abbreviated weekday name.
%A Locale's full weekday name.
%b Locale's abbreviated month name.
%B Locale's full month name.
%c Locale's appropriate date and time representation.
%I Hour (12-hour clock) as a decimal number [01,12].
%p Locale's equivalent of either AM or PM.
看起来复杂吧,来张图吧,应该就清楚了:
logging模块
logging用于记录日志且线程安全的模块.
日志level的分类:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
但文件日志记录
import logging
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10)
logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')
需要注意一点:只有【当前写等级】大于【日志等级】时,日志文件才被记录
format格式中的一些说明:
属性 | 格式化 | 描述 |
---|---|---|
args | 将参数的元组合并进消息产生消息,或者将字典中对应的值合并为消息 | |
asctime | %(asctime)s | 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
created | %(created)f | 当前时间,用UNIX标准的表示时间的浮 点数表示 |
exec_info | 异常信息 | |
filename | %(filename)s | 调用日志输出函数的模块的文件名 |
funcName | %(funcName)s | 调用日志输出函数的函数名 |
levelname | %(levelname)s | 文本形式的日志级别 |
levelno | %(levelno)s | 数字形式的日志级别 |
module | %(module)s | 调用日志输出函数的模块名 |
msecs | %(msecs)d | 创建日志时的毫秒时间 |
message | %(message)s | 用户输出的消息 |
msg | 传入的格式化字符串 | |
name | %(name)s | logger的名字 |
pathname | %(pathname)s | 调用文件的路径 |
process | %(process)d | 调用日志系统的进程ID |
processNmae | %(processNmae) | 进程名字 |
thread | %(thread)d | 线程 |
threadName | %(threadName)s | 线程名称 |
那么多文件的写入日志需要怎么搞呢?
日志如果要模块化时,需要有4个知识点:
- logger 创建一个在应用程序中用到的接口
- handler 处理器,将logger产生的日志,发送给对应的文件
- filter 过滤器,用来将符合条件的日志过滤出来
- formatter 输出前格式化日志,形成你想要的格式的日志
import logging
######## create logger
logger = logging.getLogger('TEST-LOG')
logger.setLevel(logging.DEBUG)
######## create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
######## create file handler and set level to warning
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)
######## create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
######## add formatter to ch and fh
ch.setFormatter(formatter)
fh.setFormatter(formatter)
######## add ch and fh to logger
logger.addHandler(ch)
logger.addHandler(fh)
调用方式:
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
解释下上面的代码:
- 创建一个logger接口
- 创建显示终端或文件,并设置日志级别
- 创建日志格式标准
- 格式标准添加至显示终端
- 将终端的handler添加至logger
之前博客写过一篇日志处理的模块,链接:
点我点我点我
python基础之模块(一)的更多相关文章
- python基础——第三方模块
python基础——第三方模块 在Python中,安装第三方模块,是通过包管理工具pip完成的. 如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了. 如果你正在使用Window ...
- python基础——使用模块
python基础——使用模块 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用. 我们以内建的sys模块为例,编写一个hello的模块: #!/usr/bin/env ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- python 基础之 模块
Python 基础之模块 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文 ...
- 【Python之路】第六篇--Python基础之模块
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- 周末班:Python基础之模块
什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写 ...
- python基础-各模块文章导航
python基础学习日志day5-各模块文章导航 python基础学习日志day5---模块使用 http://www.cnblogs.com/lixiang1013/p/6832475.html p ...
- python基础--导入模块
一,import的使用1, 模块就是一组功能的集合体,我们的程序可以导入模块来复用模块中的功能一个模块就是包含了一组功能的python文件,例如demo.py 可以通过import来使用这个文件定义d ...
- python基础-7模块,第三方模块安装方法,使用方法。sys.path os sys time datetime hashlib pickle json requests xml
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- 学习PYTHON之路, DAY 6 - PYTHON 基础 6 (模块)
一 安装,导入模块 安装: pip3 install 模块名称 导入: import module from module.xx.xx import xx from module.xx.xx impo ...
随机推荐
- React 之 高阶组件的理解
1.基本概念 高阶组件是参数为组件,返回值为新组件的函数. 2.举例说明 ① 装饰工厂模式 组件是 react 中的基本单元,组件中通常有一些逻辑(非渲染)需要复用处理.这里我们可以用高阶组件对组件内 ...
- 什么是EDID,EDID能做什么,EDID基本介绍
转至 http://blog.csdn.net/Jkf40622/article/details/48311455 Q1: 为什么要写这篇文章? A1:在最近的工作中遇到了不少问题,其中很多都是和ED ...
- Restful架构API编码规范
Restful API 目前比较成熟的一套互联网应用程序的API设计理论 一.协议 API与用户的通信协议,总是使用HTTPs协议. 二.域名 应该尽量将API部署在专用域名之下. https://a ...
- CSS 布局和 BFC
什么是 BFC 在一个Web页面的CSS渲染中,块级格式化上下文 (Block Fromatting Context)是按照块级盒子布局的.W3C对BFC的定义如下:浮动元素和绝对定位元素,非块级盒子 ...
- 006——转载-MATLAB数字与字符之间的转换
(一)参考文献:https://jingyan.baidu.com/article/5bbb5a1bd8dcb113eba1799d.html (二)数字转换成字符串 第一步在我们的电脑上打开matl ...
- MD5加密的引用
使用MD5 加密时 需要在后台代码中添加using System.Security.Cryptography; 引用 //MD5加密密码 byte[] a = MD5.Create().Compute ...
- RabbitMQ的5种模式
队列截图,去rabbitMq.com去找学习文档 =========================================================================== ...
- P2891 [USACO07OPEN]吃饭Dining
漂亮小姐姐点击就送:https://www.luogu.org/problemnew/show/P2891 题目描述 Cows are such finicky eaters. Each cow ha ...
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- python 最小二乘 leastsq 函数实现 法线式 解决与x轴垂直问题
当使用y=kx+b时,与x轴垂直的直线无法计算.因此使用法线式ysin(theta)+xcos(theta) = dist.貌似这么用有点复杂了,直接使用ax+by=1不知道能不能计算,未测试. # ...