常用模块

os模块

对文件进行重命名、删除等一些操作,在python中可以利用os模块。

os模块提供一些系统级别的操作命令

OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作。

方法作用
os.system(“cd e:”)运行shell命令,直接显示
print(os.environ[‘path’])获取系统环境变量
os.name字符串指示当前使用平台。win->‘nt’; Linux->‘posix’
os.getcwd()获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(“dirname”)改变当前脚本工作目录;相当于shell下cd os.chdir(“d://”)
os.curdir返回当前目录: (’.’)
os.pardir获取当前目录的父目录字符串名:(’…’)
os.sep操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep用于分割文件路径的字符串
os.makedirs(‘dir1/dir2’)可生成多层递归目录 os.makedirs(“notes/note”)
os.removedirs(‘dirname1’)若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.removedirs(“notes/note”)
os.mkdir(‘dirname’)生成单级目录;相当于shell中mkdir dirname os.mkdir(“notes”)
os.rmdir(‘dirname’)删除单级空目录,若目录不为空则无法删除,报错 os.rmdir(“notes”)
os.listdir(‘dirname’)列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.listdir() os.listdir(".") os.listdir(os.curdir)
os.remove()删除一个文件
os.rename(“oldname”,“new”)重命名文件/目录
os.stat(‘path/filename’)获取文件/目录信息
方法作用
os.path.abspath(path)返回path规范化的绝对路径
os.path.isabs(path)如果path是绝对路径,返回True
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.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.path.getsize(path)返回path所指向的文件的大小,单位是字节

Os常用操作

1. 文件重命名

rename(需要修改的文件名, 新的文件名)
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")

2. 删除文件

remove(待删除的文件名)
import os
os.remove("毕业论文.txt")

3.创建文件夹

import os
os.mkdir("张三")  #只能生成单级目录
os.makedirs('dir1/dir2')  #可生成多层递归目录

4.删除文件夹

os.rmdir('dirname')  #删除单级空目录,若目录不为空则无法删除,报错
os.removedirs('dirname1')  #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 

5. 获取目录列表

import os
os.listdir("./")  #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 

Os.path常用操作

1.获取路径的绝对路径

os.path.abspath(path)  #返回path规范化的绝对路径

2.判断路径是否是绝对路径

os.path.isabs(path)  #如果path是绝对路径,返回True

3.目录分割

os.path.split(path)   #将path分割成目录和文件名二元组返回

os.path.dirname(path)    #返回path的目录。其实就是os.path.split(path)的第一个元素

os.path.basename(path)    #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素

4. 判断路径文件存在

os.path.exists(path)    #如果path存在,返回True;如果path不存在,返回False

os.path.isfile(path)    #如果path是一个存在的文件,返回True。否则返回False

os.path.isdir(path)    #如果path是一个存在的目录,则返回True。否则返回False

5.路径拼接

os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回
path = os.path.join(os.getcwd(),'gl')

os.walk的用法

os.walk是一个简单易用的文件、目录遍历器,可以帮助我们高效的处理文件、目录方面的事情。

os.walk的函数声明为:

walk(top, topdown=True, οnerrοr=None, followlinks=False)

参数

  • top – 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名】。
  • topdown --可选,为True或者没有指定, 一个目录的的3-元组将比它的任何子文件夹的3-元组先产生 (目录自上而下)。如果topdown为 False, 一个目录的3-元组将比它的任何子文件夹的3-元组后产生 (目录自下而上)。
  • onerror – 可选,是一个函数; 它调用时有一个参数, 一个OSError实例。报告这错误后,继续walk,或者抛出exception终止walk。
  • followlinks – 设置为 true,则通过软链接访问目录。
import os
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        print(os.path.join(root, name))
    for name in dirs:
        print(os.path.join(root, name))

文件操作

文件操作一般步骤

打开文件
读/写文件
保存文件
关闭文件

文件打开与关闭

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,

​ **注意:**使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

完整的语法格式为:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明:

  • file: 必需,文件路径(相对或者绝对路径)。
  • mode: 可选,文件打开模式
  • buffering: 设置缓冲 可取值有0,1,-1三个,0代表buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),-1表示初始化的buffer大小;
  • encoding: 一般使用utf8
  • errors: 报错级别
  • newline: 区分换行符
  • closefd: 传入的file参数类型

常用方式

f = open(file,mode)	 	#打开文件
f.close()     			#关闭文件

文件找开模式

    r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
    w,只写模式【不可读;不存在则创建;存在则清空内容】
    x, 只写模式【不可读;不存在则创建,存在则报错】
    a, 追加模式【可读;   不存在则创建;存在则只追加内容】,文件指针自动移到文件尾。
"+" 表示可以同时读写某个文件
    r+, 读写【可读,可写】
    w+,写读【可读,可写】,消除文件内容,然后以读写方式打开文件。
    x+ ,写读【可读,可写】
    a+, 写读【可读,可写】,以读写方式打开文件,并把文件指针移到文件尾。
"b"表示以字节的方式操作,以二进制模式打开文件,而不是以文本模式。
    rb  或 r+b
    wb 或 w+b
    xb 或 w+b
    ab 或 a+b
 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

文件读取

文件内容的读取
    read() #一次读取全部的文件内容。
    
    read(num)#读取指定字符个数

    readline() #每次读取文件的一行。按行读取,但是一次只读取一行。

    readlines() #读取文件的所有行,返回一个字符串列表。按行读取,一次性读取所有内容,返回一个列表,每一行内容作为一个元素。

文件写入

文件写入
    write()				#参数就是需要写入的内容
    writelines() 		#可传一个可迭代

# 写模式打开一个test.txt 文件
f = open('test.txt', 'w')
f.writelines(['我','爱','我的','国家']) # writelines 方法将可迭代对象,迭代写入文件
f.close() # 关闭文件

文件指针操作

文件定位,指的是当前文件指针读取到的位置,光标位置。在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取

# 以读模式打开test.txt 文件 
f = open('test.txt','r’) 
content = f.read(3) # 读取三个字符 
# 查看当前游标所在位置 
cur =f.tell() 
print(cur) 

content = f.read(3) # 读取三个字符 
# 查看当前游标所在位置 
cur =f.tell() 
print(cur) 

如果在操作文件的过程,需要定位到其他位置进行操作,用seek()。
seek(offset, from)有2个参数,offset,偏移量单位字节,负数是往回偏移,正数是往前偏移,from位置:0表示文件开头,1表示当前位置,2表示文件末尾
注意: Python3中取消了当前位置与文末偏移。只能将光标定位到开头,不可往回偏移。 seek 方法在Python3中只能做文件开头往前偏移,或者将光标定位到开头。

f = open("1.txt","r")
f.read(3)

print(f.tell())
f.seek(1,0)     #从文件开头往右偏移1位
f.seek(0)      #定位到文件开头
print(f.tell())

f.close()

文本文件指针操作
    file.seek(offset,whence=0)     #从文件中给移动指针,从whence(0起始,1当前,2末尾)偏移offset个字节,正往结束方向移动,负往开始方向移动
    file.tell()          #返回当前文件中的位置。获得文件指针位置

上下文管理with语句

当你做文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。

正常情况下,代码如下:

file = open("/tmp/foo.txt")
data = file.read()
file.close()

这里有两个问题。

一、是可能忘记关闭文件句柄;

二、是文件读取数据发生异常,没有进行任何处理。

然而with可以很好的处理上下文环境产生的异常。下面是with版本的代码:

with open("/tmp /foo.txt") as file:
    data = file.read()
with的基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

练习

#利用脚本完成自动备份,要求用户输入文件名称,完成自动备份
def copyfile(): 
    # 接收用户输入的文件名 
    old_file = input('请输入要备份的文件名:’) 
    file_list = old_file.split(".") 
                     
    # 构造新的文件名,加上备份后缀 
    new_file = file_list[0] + '_备份.' + file_list[1] 
    old_f = open(old_file, 'r’) # 打开需要备份的文件 
    new_f = open(new_file, 'w’) # 以写的模式打开新文件,不存在则创建 
    content = old_f.read() # 将文件内容读取出来 
    new_f.write(content) # 将读取的内容写入备份文件 
    # 将打开的文件关闭 
    old_f.close() 
    new_f.close() 

copyfile()
#如果处理超大文件,一次将全部内容读取出来显然是不合适的,在需求1的基础上改进下代码,让它备份大文件也不会导致内存被占满。

def copyfile(): 
    # 接收用户输入的文件名 
    old_file = input('请输入要备份的文件名:’) 
                     
    # 如果没有输入文件名则打印提示
    if not old_file:
        print('[ERROR]: 请输入正确的文件路径’) 
        return file_list = old_file.split(".") 
    # 构造新的文件名,加上备份后缀
    if len(file_list) < 2:
    	new_file = file_list[0] + '_备份’ 
    else: # 文集名没有后缀的情况 
   		new_file = file_list[0] + '_备份.' + file_list[1] 
          
    try: 
        # 同时打开需要备份的文件,新文件 
        with open(old_file, 'r') as old_f, open(new_file, 'a') as new_f:
        while True: 
            # 一次读取1024字符
            content = old_f.read(1024)
            new_f.write(content) 
            # 当读取的内容字符长度小于1024说明已经读取完毕 
            if len(content) < 1024: 
                break 
    except Exception as e: 
    	print(e) 

copyfile() 


time

python 中时间表示方法有:

时间戳,

​ 即从1975年1月1日00:00:00到现在的秒数;格式化后的时间字符串;

时间struct_time 元组。

​ struct_time元组中元素主要包括tm_year(年)、tm_mon(月)、tm_mday(日)、tm_hour(时)、tm_min(分)、tm_sec(秒)、tm_wday(weekday0 - 6(0表示周日))、tm_yday(一年中的第几天1 - 366)、tm_isdst(是否是夏令时)

方法作用
time.time():返回当前时间的时间戳。
time.localtime([secs])将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
time.gmtime([secs])和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
time.mktime(t)将一个struct_time转化为时间戳。
time.sleep(secs):线程推迟指定的时间运行。单位为秒。
time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。
time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:‘Sun Jun 20 23:21:05 1993’。如果没有参数,将会将time.localtime()作为参数传入。
time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
time.clock():这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间。(实际上是以WIN32上QueryPerformanceCounter()为基础,它比毫秒表示更为精确)

[外链图片转存失败(img-fTuiU3Yq-1563594859111)(./time.png)]

时间格式化符号

%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

import time
print(time.strftime("%Y/%m/%d %H:%M:%S",time.localtime()))
print(time.ctime())

2019/03/05 00:55:52
Tue Mar  5 00:55:52 2019

datetime

dateime是time的升级版,可以对date(日期)、time(时间)、datetime(日期时间)等三种单独管理。主要是由下面四个类组成

datetime模块中包含如下类:

类名功能说明
date日期对象,常用的属性有year, month, day
time时间对象
datetime日期时间对象,常用的属性有hour, minute, second, microsecond
datetime_CAPI日期时间对象C语言接口
timedelta时间间隔,即两个时间点之间的长度
tzinfo时区信息对象

date

date对象由year年份、month月份及day日期三部分构成:

>>> a = datetime.date.today()
>>> a
datetime.date(2017, 3, 22)
>>> a.year
2017
>>> a.month
3
>>> a.day
22

date对象中包含的方法与属性

1、用于日期比较大小的方法

方法名方法说明用法
__eq__(…)等于(x==y)x.__eq__(y)
__ge__(…)大于等于(x>=y)x.__ge__(y)
__gt__(…)大于(x>y)x.__gt__(y)
__le__(…)小于等于(x<=y)x.__le__(y)
__lt__(…)小于(xx.__lt__(y)
__ne__(…)不等于(x!=y)x.__ne__(y)

以上方法的返回值为True\False

日期的字符串输出
>>> a.strftime("%Y%m%d")
'20170322'

>>> a.__str__()   #如果只是相简单的获得日期的字符串,则使用__str__(...)
'2017-03-22'

>>> a.ctime()     #如果想要获得ctime样式的格式请使用ctime(...)
'Wed Mar 22 00:00:00 2017'

time

time类由hour小时、minute分钟、second秒、microsecond毫秒和tzinfo五部分组成

>>> a = datetime.time(12,20,59,899)
>>> a
datetime.time(12, 20, 59, 899)
>>> a.hour
12
>>> a.minute
20
>>> a.second
59
>>> a.microsecond
899
>>> a.tzinfo


>>> a.__getattribute__('hour')
12

比较时间大小

相关方法包括:__eq__(...), __ge__(...), __gt__(...), __le__(...), __lt__(...)__ne__(...)
这里的方法与date类中定义的方法大同小异,使用方法与一样,这里就不过多介绍了,示例如下:

时间的字符串输出
>>> a = datetime.time(12,20,59,899)
>>> a.strftime('%H:%M:%S')
'12:20:59'

>>> a = datetime.time(12,20,59,899)
>>> a.__str__()
'12:20:59.000899'

datetime

datetime类其实是可以看做是date类和time类的合体,其大部分的方法和属性都继承于这二个类,相关的操作方法请参阅,本文上面关于二个类的介绍。其数据构成也是由这二个类所有的属性所组成的。

>>> a = datetime.datetime.now()
>>> a
datetime.datetime(2017, 3, 22, 16, 9, 33, 494248)
>>> a.date()
datetime.date(2017, 3, 22)
>>> a.time()
datetime.time(16, 9, 33, 494248)
strptime(…):根据string, format 2个参数,返回一个对应的datetime对象:
>>> datetime.datetime.strptime('2017-3-22 15:25','%Y-%m-%d %H:%M')
datetime.datetime(2017, 3, 22, 15, 25)

timedelta

timedelta类是用来计算二个datetime对象的差值的。
此类中包含如下属性:
1、days:天数
2、microseconds:微秒数(>=0 并且 <1秒)
3、seconds:秒数(>=0 并且 <1天)

计算当前时间向后8个小时的时间

>>> d1 = datetime.datetime.now()
>>> d2 = d1 + datetime.timedelta(hours = 8)
>>> d2
datetime.datetime(2017, 3, 23, 1, 10, 37, 182240)

可以计算: 天(days), 小时(hours), 分钟(minutes), 秒(seconds), 微秒(microseconds).

计算上周一和周日的日期

today = datetime.date.today()
>>> today
datetime.date(2017, 3, 23)
>>> today_weekday = today.isoweekday()
>>> last_sunday = today - datetime.timedelta(days=today_weekday)
>>> last_monday = last_sunday - datetime.timedelta(days=6)
>>> last_sunday
datetime.date(2017, 3, 19)
>>> last_monday
datetime.date(2017, 3, 13)

计算三小时前的时间

print(datetime.datetime.now()-datetime.timedelta(hours=3))

random

方法作用
random.random ()随机产生[0, 1)之间的浮点数
random.uniform(1.3,5.8)随机产生[a, b)之间的浮点数, 区间端点可以不是整数
random.randint(1,6)随机产生[a, b]之间的整数(包含a和b)
random.randrange(0,10,2)随机产生指定范围[start, stop, step)的一个整数
random.choice(seq_list)序列选择(返回元素)—从序列中随机选取一个元素
random.choices(population, weights=None, *, cum_weights=None, k=1)# 3.6版本新增。从population集群中随机抽取K个元素(可重复)。weights是相对权重列表,cum_weights是累计权重,两个参数不能同时存在。
random.sample(seq_list, 4)序列节选(返回序列)—从序列中随机选取指定个数的元素
random.shuffle(seq_list)列表打乱(无返回值)—将指定列表打乱

练习

用random.random()写出10-100的随机数

hashlib

Python里面的hashlib模块提供了很多加密的算法,这里介绍一下hashlib的简单使用事例,用hashlib的md5算法加密数据

加密算法

md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(),
sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256.

hash对象方法

- update(arg): 更新加密的密文,得到的密文与原来的密文不相同。
- digest():    获取加密的密文,二进制,无参数。
- hexdigest(): 获取加密的密文,16进制,无参数。
- copy():      复制一份当前创建的hash对象,无参数。
    >>> import hashlib
    >>> m = hashlib.md5()
    >>> m.update(b"Nobody inspects")
    >>> m.update(b" the spammish repetition")
    >>> m.digest()
    b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
    
    #注意 update方法必须 要传二进制数据
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
    'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
hash = hashlib.md5()#md5对象,md5不能反解,但是加密是固定的,就是关系是一一对应,所以有缺陷,可以被对撞出来
hash.update(bytes('admin',encoding='utf-8'))#要对哪个字符串进行加密,就放这里
print(hash.hexdigest())#拿到加密字符串

print(hashlib.md5(b"Nobody inspects the spammish repetition").hexdigest())
m = hashlib.md5()
m.update(b"Nobody inspects the spammish repetition")
print(m.hexdigest())

转码方式

bytes('admin',encoding='utf-8'"admin".encode("utf-8")

json

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。

JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。

JSON 语法规则

JSON 语法是 JavaScript 对象表示法语法的子集。

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

JSON 数据类型

JSON 数据类型可以是:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在方括号中)
  • 对象(在花括号中)
  • null

在python中,有专门处理json格式的模块—— json 模块

Json 模块提供了四个方法: dumps、dump、loads、load

一. dumps 和 dump:

dumps和dump 序列化方法

​ dumps只完成了序列化为str,

​ dump必须传文件描述符,将序列化的str保存到文件中

python对象中有中文的,需要指定参数 ensure_ascii=True #中文需改为False,

###dumps()用法
dict = {"name":"Tom", "age":23"gender":"男"}  
json.dumps(dict,ensure_ascii=False)     # #中文需改为False,
#结果:
#'{"name": "Tom", "age": 23}'


#ensure_ascii=True  #中文需改为False,

###dump()用法
a = {"name":"Tom", "age":23}
with open("test.json", "w", encoding='utf-8') as f:
    # indent 超级好用,格式化保存字典,默认为None,小于0为零个空格
    f.write(json.dumps(a, indent=4))  #格式化写入文件利用  indent = 4 
    # json.dump(a,f,indent=4)   # 和上面的效果一样

二. loads 和 load

loads和load 反序列化方法

​ loads 只完成了反序列化,

​ load 只接收文件描述符,完成了读取文件和反序列化

json.loads()无法解析单引号字符串

#在使用json.loads()前使用eval()和json.dumps()进行处理
b = "{'name':'Tom', 'age':23}"
d = json.loads(json.dumps(eval(b)))
d = eval(b)
import json
###loads()用法
json.loads('{"name":"Tom", "age":23}')
#结果 
#{'age': 23, 'name': 'Tom'}


with open("test.json", "r", encoding='utf-8') as f:
    aa = json.loads(f.read())  #第一种写法loads()
    f.seek(0)  #将文件指针移动到文件开头
    bb = json.load(f)    # 与 json.loads(f.read())
print(aa)
print(bb)

# 输出:
{'name': 'Tom', 'age': 23}
{'name': 'Tom', 'age': 23}

python 原始类型向 json 类型的转化对照表:

PythonJSON
dictobject
list, tuplearray
str, unicodestring
int, long, floatnumber
Truetrue
Falsefalse
Nonenull

json 类型转换到 python 的类型对照表:

JSONPython
objectdict
arraylist
stringunicode
number (int)int, long
number (real)float
trueTrue
falseFalse
nullNone

csv文件

CSV(Comma-Separated Values)即逗号分隔值,可以用Excel打开查看。由于是纯文本,任何编辑器也都可打开。与Excel文件不同,CSV文件中:

  • 值没有类型,所有值都是字符串
  • 不能指定字体颜色等样式
  • 不能指定单元格的宽高,不能合并单元格
  • 没有多个工作表
  • 不能嵌入图像图表

在CSV文件中,以,作为分隔符,分隔两个单元格。像这样a,,c表示单元格a和单元格c之间有个空白的单元格。依此类推。

不是每个逗号都表示单元格之间的分界。所以即使CSV是纯文本文件,也坚持使用专门的模块进行处理。Python内置了csv模块。

从CSV文件中读取数据

import csv

filename = 'F:/Jupyter Notebook/matplotlib_pygal_csv_json/sitka_weather_2014.csv'
with open(filename,'r') as f:
    reader = csv.reader(f)
    print(list(reader))

前面的数字是行号,从1开始,可以用reader.line_num获取。

要注意的是,reader只能被遍历一次。由于reader是可迭代对象,可以使用next方法一次获取一行。

import csv

filename = 'F:/Jupyter Notebook/matplotlib_pygal_csv_json/sitka_weather_2014.csv'
with open(filename,'r') as f:
    reader = csv.reader(f)
    # 读取一行,下面的reader中已经没有该行了
    head_row = next(reader)
    for row in reader:
        # 行号从2开始
        print(reader.line_num, row)

写数据到csv文件中

有reader可以读取,当然也有writer可以写入。一次写入一行,一次写入多行都可以。

import csv

# 使用数字和字符串的数字都可以
datas = [['name', 'age'],
         ['Bob', 14],
         ['Tom', 23],
        ['Jerry', '18']]

with open('example.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    for row in datas:
        writer.writerow(row)
        
    # 还可以写入多行
    writer.writerows(datas)
    

如果不指定newline='',则每写入一行将有一空行被写入。上面的代码生成如下内容。

DictReader和DictWriter对象

使用DictReader可以像操作字典那样获取数据,把表的第一行(一般是标头)作为key。可访问每一行中那个某个key对应的数据。

import csv

filename = 'F:/Jupyter Notebook/matplotlib_pygal_csv_json/sitka_weather_2014.csv'
with open(filename,'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        # Max TemperatureF是表第一行的某个数据,作为key
        max_temp = row['Max TemperatureF']
        print(max_temp)

使用DictWriter类,可以写入字典形式的数据,同样键也是标头(表格第一行)

import csv

headers = ['name', 'age']

datas = [{'name':'Bob', 'age':23},
        {'name':'Jerry', 'age':44},
        {'name':'Tom', 'age':15}
        ]

with open('example.csv', 'w', newline='') as f:
    # 标头在这里传入,作为第一行数据
    writer = csv.DictWriter(f, fieldnames=headers)
    writer.writeheader()
    for row in datas:
        writer.writerow(row)
        
    # 还可以写入多行
    writer.writerows(datas)

logging模块

logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

  1. 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
  2. print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;

基本使用

配置logging基本的设置,然后在控制台输出日志,

import logging


logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')  # 设置的info 级别 只会显示大于等于INFO级别的日志

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

运行结果

2019-04-04 15:35:04,683 - root - INFO - info
2019-04-04 15:35:04,684 - root - WARNING - warning
2019-04-04 15:35:04,684 - root - ERROR - error
2019-04-04 15:35:04,684 - root - CRITICAL - critical

默认情况下,logging将日志打印到屏幕,日志级别为WARNING;
日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。

日志级别

为了实现在不同的环境记录不同详细程度的日志,这就需要用到日志等级了。

日志等级描述
DEBUG最详细的日志信息,通常出现在问题诊断
INFO通常只记录关键节点信息,用于确认一切按预期运行
WARNING一些意想不到的事情发生时记录的信息,但此应用程序还能正常运行。
ERROR一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL一个严重的错误导致应用程序无法继续运行时记录的信息

logging.basicConfig(配置参数)

参数描述
level指定日志级别。
format指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。
datefmt指定日期、时间格式,默认:datefmt="%Y-%m-%d %H:%M:%S"。
filename指定日志输出目标文件的文件名,指定该设置项后日志信息就不会被输出到控制台了。
filemode指定日志文件打开模式,默认为’a’。该选项在filename指定时才有效。
stream指定日志输出目标stream,如sys.stdout、sys.stderr。需要注意stream和filename不能同时出现,否则会引发ValueError异常。
style指定format格式字符串的风格,可取值为’%’、’{‘和’$’,默认为’%’

format格式化字符串的字段

字段名称使用格式描述
asctime%(asctime)s日志事件发生的时间,默认如:2018-05-04 21:48:05,956。
created%(created)f日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值。
msecs%(msecs)d日志事件发生事件的毫秒部分
levelname%(levelname)s该日志记录的文字形式的日志级(‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’)。
levelno%(levelno)s该日志记录的数字形式的日志级别。
name%(name)s所使用的日志器名称,默认是’root’,因为默认使用的是rootLogger。
message%(message)s日志记录的文本内容。
pathname%(pathname)s调用日志记录函数的源码文件的全路径。
filename%(filename)spathname的文件名部分,包含文件后缀。
module%(module)sfilename的名称部分,不包含后缀。
lineno%(lineno)d调用日志记录函数的源代码所在的行号。
funcName%(funcName)s调用日志记录函数的函数名。
process%(process)d进程ID。
processName%(processName)s进程名称
thread%(thread)d线程ID。
threadName%(thread)s线程名称。

将日志同时输出到文件和屏幕

import logging

logging.basicConfig(level=logging.DEBUG,filename="file.log",format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')  # 输出 到文件

logger = logging.getLogger()
console = logging.StreamHandler()     # 输出到控制台
console.setLevel(logging.INFO)        # 等级为 INFO
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logger.addHandler(console)

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

控制台输出

C:\Python36\python.exe D:/test.py
root        : INFO     info
root        : WARNING  warning
root        : ERROR    error
root        : CRITICAL critical

文件输出

2019-04-04 15:45:41,817 - root - DEBUG - debug
2019-04-04 15:45:41,817 - root - INFO - info
2019-04-04 15:45:41,817 - root - WARNING - warning
2019-04-04 15:45:41,817 - root - ERROR - error
2019-04-04 15:45:41,817 - root - CRITICAL - critical

logging模块组件

logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
logging.basicConfig():用默认Formatter为日志系统建立一个StreamHandler,设置基础配置并加到root logger中

每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:

gui=logging.getLogger(”chat.gui”)
而核心模块可以这样:
kernel=logging.getLogger(”chat.kernel”)

logging模块的四大组件

组件名称对应类名描述
日志器Logger提供了应用程序可一直使用的接口。
处理器Handler将logger创建的日志记录发送到合适的目的输出。
过滤器Filter提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录。
格式器Formatter决定日志记录的最终输出格式。

Logger对象常用方法

方法描述
Logger.setLevel()设置日志器将会处理的日志消息的最低严重级别。
Logger.addHandler()为该logger对象添加handler对象。
Logger.removeHandler()为该logger对象移除handler对象。
Logger.addFilter()为该logger对象添加filter对象。
Logger.removeFilter()为该logger对象移除个filter对象。

怎样得到一个Logger对象呢?

通常用: logger = logging.getLogger()

logging.getLogger()方法有一个可选参数name,该参数表示将要返回的日志器的名称标识,如果不提供该参数,则其值为’root’。

name相同:只要logging.getLogger(name)name相同,则返回的Logger实例就是同一个,最后logger的输出遵从后来设置的日志级别。

Handler对象常用方法

方法描述
Handler.setLevel()设置handler将会处理的日志消息的最低严重级别。
Handler.setFormatter()为handler设置一个格式器对象。
Handler.addFilter()为handler添加一个过滤器对象。
Handler.removeFilter()为handler删除一个过滤器对象。

一些常用的Handler子类

Handler描述
logging.StreamHandler将日志消息发送到Stream。
logging.FileHandler将日志消息发送到磁盘文件,默认情况下文件大小会无限增长。
logging.handlers.RotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按大小切割。
logging.hanlders.TimedRotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按时间切割。
logging.handlers.HTTPHandler将日志消息以GET或POST的方式发送给一个HTTP服务器。
logging.handlers.SMTPHandler将日志消息发送给一个指定的email地址。

Logging函数详解

                  |

| ---------------------- | --------------------------------------------- |
| Handler.setLevel() | 设置handler将会处理的日志消息的最低严重级别。 |
| Handler.setFormatter() | 为handler设置一个格式器对象。 |
| Handler.addFilter() | 为handler添加一个过滤器对象。 |
| Handler.removeFilter() | 为handler删除一个过滤器对象。 |

一些常用的Handler子类

Handler描述
logging.StreamHandler将日志消息发送到Stream。
logging.FileHandler将日志消息发送到磁盘文件,默认情况下文件大小会无限增长。
logging.handlers.RotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按大小切割。
logging.hanlders.TimedRotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按时间切割。
logging.handlers.HTTPHandler将日志消息以GET或POST的方式发送给一个HTTP服务器。
logging.handlers.SMTPHandler将日志消息发送给一个指定的email地址。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值