python入门_模块2
0.collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
# namedtuple 具名元组
# tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:
# 例如:
from collections import namedtuple
a = (1,2)
p = namedtuple('坐标',['x','y'])
location1 = p(1,2) # 元素的个数一定要跟上面第二个参数的个数相同
print(location1) # 坐标(x=1, y=2)
print(location1.x) # 1
print(location1.y) # 2 card = namedtuple('扑克牌',['color','number'])
A = card('','A')
print(A) # 扑克牌(color='', number='A')
print(A.color) #
print(A.number) # A
# 用具名元组来记录一个城市的信息
from collections import namedtuple
City = namedtuple('City', 'name country population coordinates')
bj = City('BeiJing', 'BJ', 39.9, (116.2317, 39.5427))
print(bj)
# City(name='BeiJing', country='BJ', population=39.9, coordinates=(116.2317, 39.5427))
print(bj.population)
# 39.9
deque双端队列
# 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。 # deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
from collections import deque q = deque(['s','n','v'])
# append 和appendleft 分别向2端添加元素
q.append('1')
q.appendleft('2')
print(q) # deque(['2', 's', 'n', 'v', '1'])
# pop与popleft分别是2端删除元素
q.pop()
q.popleft()
print(q) # deque(['s', 'n', 'v'])
Counter计数器
# Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value from collections import Counter c = Counter('asdfadghfd_asdf 31242431!')
print(c)
# Counter({'d': 4, 'a': 3, 'f': 3, 's': 2, '3': 2, '1': 2, '2': 2, '4': 2, 'g': 1, 'h': 1, '_': 1, ' ': 1, '!': 1})
OrderedDict: 有序字典
from collections import OrderedDict
d = dict([('a',1),('c',2),('b',3),('e',0)])
print(d)
# {'a': 1, 'c': 2, 'b': 3, 'e': 0}
d['z'] = 5
d['y'] = 6
print(d)
# {'a': 1, 'c': 2, 'b': 3, 'e': 0, 'z': 5, 'y': 6}
print(d.keys())
# dict_keys(['a', 'c', 'b', 'e', 'z', 'y'])
defaultdict: 带有默认值的字典
from collections import defaultdict # 有下列集合,将所有大于66的值保存至字典的第一个key中,将小于66的值保存在第二个key值中
# 即: {'k1': 大于66 , 'k2': 小于66}
ls = [11,22,33,44,55,66,77,88,99]
my_dict= defaultdict(list)
for i in ls:
if i>66:
my_dict['k1'].append(i)
else:
my_dict['k2'].append(i) print(my_dict())
# defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99]}) #
from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
dd['key1'] # key1存在
'abc'
dd['key2'] # key2不存在,返回默认值
'N/A'
一、random模块
(0, 1):random.random()
[1, 10]:random.randint(1, 10)
[1, 10):random.randrange(1, 10)
(1, 10):random.uniform(1, 10)
单例集合随机选择1个:random.choice(item)
单例集合随机选择n个:random.sample(item, n)
洗牌单列集合:random.shuffle(item)
import random
#模块地址
print(random) # <module 'random' from 'F:\\安装包\\Python36\\lib\\random.py'> #random.random()取值范围0-1之间的小数,不包含0和1
for i in range(2):
print(random.random()) #(0,1)
#取值0-2之间,但是random.random()输出的值都是0-1之间
#0.6179348878875671
#0.7546476092920288 #random.randint() 取值范围[1,5]:包含1和5
for i in range(5):
print(random.randint(1,5)) #[1,5] # random.randrange() #[1,5)取值范围1-4,不包含5
for i in range(5):
print(random.randrange(1,5)) #[1,4] # random.uniform() 取值范围(1,5)之间的小数
for i in range(5):
print(random.uniform(1,5)) #小数:(1,5)
# print('%.3f' % random.uniform(1,5)) #%f 可以定义取值的长度 %.3f取3位小数 #洗牌单列集合:random.shuffle(item)
ls = [1,2,3,4,5]
print(random.shuffle(ls)) #None
print(ls) #对ls随机排序[4, 5, 2, 3, 1] #单例集合随机选择1个:random.choice(item)
print(random.choice(ls)) # 随机输出ls中一个值 #单例集合随机选择n个:random.sample(item, n)
print(random.sample(ls,3)) # [2, 4, 3] 不会同时出现2个一样的数字
练习:验证码功能
# 方法一
# count验证码位数,根据需求出几位
import random
def get_code(count):
code = ""
# 能产生大小写字母和数字
# 进行字符串拼接
for i in range(count):
c1 = chr(random.randint(65,90)) #(65,90) ascii表对应大写字母,chr对应数字转换为字母
c2 = chr(random.randint(97,122)) #(97,122) ascii表对应小写字母
c3 = str(random.randint(0,9)) # 数字 code += random.choice([c1,c2,c3])
return code print(get_code(4)) # 方法二:效率高,只需要循环2个,但逻辑多
def get_code(count):
code = ""
for i in range(count):
r = random.choice([1,2 ,3])
if r == 1:
c = chr(random.randint(65,90))
elif r == 2:
c = chr(random.randint(97,122))
else:
c = str(random.randint(0,9))
code += c
return code print(get_code(6)) # d7H7C3 # 第3中方法:将所有字母数字的选项都写在一起,每次选中都不会重复
def get_code(count):
target = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMwqertiuopadsfklzvcxbnm"
code_list = random.sample(target,count)
return ''.join(code_list) #3PqXiR82
return code_list #['p', '1', 'S', '9', 'c', 's', 'k', 'A']
print(get_code(18)) #Kv47ZiznkPD0eO3I5d
需求:
1.允许用户最多选3次
2.每次放出20个车牌供用户选择
3.京【A-Z】-【xxxxx】,可以是字母和数字的组合 import random, string count = 0
while count < 3:
car_nums = [] #存储供用户选择的号
for i in range(20):
n1 = random.choice(string.ascii_uppercase) # 生成第一个车牌字母
n2 = "".join(random.sample(string.ascii_uppercase+string.digits, 5))
c_num = f"鄂{n1}-{n2}"
car_nums.append(c_num)
print(i+1, c_num)
# print(car_nums)
choice = input("输入选择号:").strip()
if choice in car_nums:
print(f"恭喜你选择了新车牌号:{choice}")
exit("Good luck...")
else:
print(f"不合法选择....") count += 1
# 300名员工,年会抽奖,奖项如下
# 一等奖3名
# 二等奖6名
# 3等奖30名
# 要求:共轴3次,第一次抽3等奖,第二次抽2等奖,第三次抽1等奖,抽中的人不能再抽取
import random
staff_list = []
for i in range(1,301):
staff_list.append(f"员工{i}")
level = [30, 6, 3]
count = 0
# 1. for j in range(3): 里面j 不是一定要用到它的
# 2-2.1 j count 的取值范围相同
# 2-2.2 j count 的数值运动轨迹相同
for j in range(3):
winnerList = random.sample(staff_list, level[j])
for winner in winnerList:
staff_list.remove(winner)
print(f"恭喜获得{3-j}等奖的是:{winnerList}")
print(f"还剩{len(staff_list)}个人未中奖")
二、序列化模块
# 什么是序列化:将对象转化为字符串
# 什么是反序列化:将字符串转化为对象
# 为什么要序列化:数据的存储和传输都采用的是字符串类型
# 序列化的模块:json pickle shelve # json:支持跨语言,用于数据的传输
# pickle:支持py的所有数据类型,所有可以将所有py的对象序列化后存储
# shelve:支持py的所有数据类型,可以即时存与取 # 序列化
dump
dumps # 反序列化
load
loads
三.Json模块:用于传输(多语言支持)
什么是json:就是完成文本序列化得到的文本字符串,json字符串具有一定的语法规范 1.支持的数据类型:int float str bool dict list null # json中布尔类型转换为小写,不支持set 和tuple
2.复杂的json都是由{}与[]嵌套形成的数据
3.json字符串只能有一个根: json_str = '{}{}' | '{}[]' | '[][]' | '1null' # 报错,都是两个根
4.json中的str类型必须用""包裹(json字符串中的字符串类型不支持'' """""")
import json # python对象 序列化 json字符串
data = None
res = json.dumps(data)
print(res) # json字符串 反序列化 python对象
json_str = '3.14'
json_str = 'true'
json_str = 'null'
json_str = '{}'
json_str = '[]'
json_str = '1, null' # 有误,两个根 json_str = "\"abc\"" #反序列化去引号
json_str = '"abc"'
obj = json.loads(json_str)
print(obj, type(obj))
操作文件:读()存与写(取)
# 序列化
obj = {'name': 'Simon', 'age': 17, 'gender': '男'} with open('a.txt', 'w', encoding='utf-8') as wf:
json.dump(obj, wf, ensure_ascii=False) # ensure_ascii 默认为True ansci码;#False跟随文件编码utf-8
# json.dump(obj, wf)
#{"name": "Simon", "age": 17, "gender": "男"}{"name": "Simon", "age": 17, "gender": "\u7537"} # 文件内容123456:因为wf文件只打开一次,打开的时候操作一次,之后都是写
# wf.write('123')
# wf.write('456') # 反序列化
with open('a.txt', 'r', encoding='utf-8') as rf:
obj = json.load(rf)
print(obj) # {'name': 'Simon', 'age': 17, 'gender': '男'} # 注:json模块的序列化与反序列化是一一对应关系
print(json.load(open('a.txt', 'r', encoding='utf-8')))
# {'name': 'Simon', 'age': 17, 'gender': '男'}
四、 pickle模块:支持所有数据类型(不支持其他语言,只用于python)
import pickle
obj = {'name': 'simon', 'age': 17, 'gender': '男'}
res = pickle.dumps(obj)
print(res)
# b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x05\x00\x00\x00simonq\x02X\x03\x00\x00\x00ageq\x03K\x11X\x06\x00\x00\x00genderq\x04X\x03\x00\x00\x00\xe7\x94\xb7q\x05u.' pickle.dump(obj,open('b.txt','wb'))
#内容: �}q (X nameqX simonqX ageqKX genderqX 男qu. # 反序列化
print(pickle.loads(res)) # {'name': 'simon', 'age': 17, 'gender': '男'}
print(pickle.load(open('b.txt', 'rb'))) # {'name': 'simon', 'age': 17, 'gender': '男'}
五、shelve模块:支持所有数据类型(优化存与取的方式)
# shelve将dump与load封装为一步
import shelve
# 将文件的方法封装到模块中,文件后缀自己随便取的
#新建了3个文件:c.shv.bak c.shv.dat c.shv.dir
shv_tool = shelve.open('c.shv') # 序列化
# shv_tool['name'] = 'Simon' # 反序列化
res = shv_tool['name']
print(res) # Simon shv_tool.close()
# 文件通过shelve对象来关闭,关闭后就不能再取,否则就报错 # 二次操作:重新打开与关闭
shv_tool = shelve.open('c.shv')
print(shv_tool['name']) # Simon
shv_tool.close() # 操作方式
with shelve.open('c.shv') as shv_tool:
print(shv_tool['name']) # Simon # writeback将反序列化到内存的数据,操作后即时同步到文件中
with shelve.open('c.shv', writeback=True) as shv_tool:
shv_tool['stus'] = ['Bob', 'Tom'] # 重置
# print(shv_tool['stus']) # ['Bob', 'Tom'] shv_tool['stus'].append('Jobs') # 将数据取到内存,在内存中添加
print(shv_tool['stus']) # ['Bob', 'Tom', 'Jobs']
六、shutil:可以操作权限的处理文件模块
import shutil # 基于路径的文件复制:
shutil.copyfile('source_file', 'target_file')
# 绝对路径:复制后的文件名是需要的
shutil.copyfile(r'C:\shelev.py',r'D:\target.py') # 基于流的文件复制:
with open('source_file', 'rb') as r, open('target_file', 'wb') as w:
shutil.copyfileobj(r, w) # 递归删除目标目录:目录里有文件也直接删除
shutil.rmtree('target_folder') # 文件移动
shutil.remove('old_file', 'new_file') # 文件夹压缩
# file_name: 压缩后得到的文件名 format:压缩格式 archive_path:要压缩的文件夹路径
shutil.make_archive('file_name', 'format', 'archive_path')
# 举例
shutil.make_archive('target/abc', 'zip', 'source') #在target 目录中将source目录压缩到target目录中名为abc.zip # 文件夹解压
# unpack_file: 解压的文件 unpack_name:解压得到的文件夹名 format:解压格式
shutil.unpack_archive('unpack_file', 'unpack_name', 'format')
# 举例
shutil.unpack_archive('target/abc.zip', 'target/xyz', 'zip') #将abc.zip解压为xyz文件夹
七、加密模块
# 一般加密解密方法:
# md5加密:不可逆加密
# 碰撞解密:用数据再进行一次加密,与原加密结果做匹配
hashlib模块加密
import hashlib data = '数据' # 生成对象
lock_obj = hashlib.md5(data.encode('utf-8')) # 生产加密锁对象,传入加密数据
result = lock_obj.hexdigest() # 获取加密后的加密串
print(result) # update可以往锁对象中添加加密数据
lock_obj = hashlib.md5()
lock_obj.update(b'123')
lock_obj.update(b'abc')
lock_obj.update('嘿嘿'.encode('utf-8'))
print(lock_obj.hexdigest()) lock_obj.update(b'000')
print(lock_obj.hexdigest()) # 000 | '123abc嘿嘿000'.encode('utf-8') print(hashlib.md5('123abc嘿嘿000'.encode('utf-8')).hexdigest())
# 注:要为新数据提供加密,一定要为该数据创建一个加密对象
# 加盐:前提是支持update
# 什么是加盐:在原数据前或后添加一些预定的数据,与原数据一起进行加密
# 为什么要加盐:
# 1.当原数据过于简单,可以对其加盐,提高数据的复杂度
# 2.盐与数据有一定相似度,混淆对真实数据的提取 data = 'ab_12'
lock_obj = hashlib.md5()
lock_obj.update(b'a12_d')
lock_obj.update(data.encode('utf-8'))
lock_obj.update(b'dd_121')
print(lock_obj.hexdigest())
# a12_dab_12dd_121在数据前后加盐混淆 # 其他位数加密
lock_obj = hashlib.sha3_256(b'123')
print(lock_obj.hexdigest())
lock_obj = hashlib.sha3_512(b'123')
lock_obj.update(b'salt')
print(lock_obj.hexdigest())
hmac模块加密
import hmac
# 与hashlib的不同点:生产锁对象时必须提高数据参数
lock_obj = hmac.new(b'')
print(lock_obj.hexdigest())
# 支持加盐
lock_obj = hmac.new(b'')
lock_obj.update(b'salt')
print(lock_obj.hexdigest())
八、logging:日志模块
# logging记录项目日志的模块
# 记录日志:将项目中产生的一些数据,或是信息,或是错误不再输出到控制台,而是输出到文件中,保存这样信息的文件就称之为日志文件
# 日志级别
在开始记录日志前还需要明确,日志的级别 随着时间的推移,日志记录会非常多,成千上万行,如何快速找到需要的日志记录这就成了问题 解决的方案就是 给日志划分级别
logging模块将日志分为了五个级别,从高到低分别是:
1.info 常规信息
2.debug 调试信息
3.warning 警告信息(默认级别)
4.error 错误信息
5.cretical 严重错误 本质上他们使用数字来表示级别的,从高到低分别是10,20,30,40,50
#1.导入模块
import logging #2.输出日志
logging.info("info")
logging.debug("debug调试")
logging.warning("warning警告")
logging.error("error错误")
logging.critical("critical严重错误") # 输出 WARNING:root:warning
# 输出 ERROR:root:error
# 输出 CRITICAL:root:critical
1.logging模块的基本配置使用:
import logging
import sys # 2.日志的基本配置
logging.basicConfig(
# 输出级别
level=logging.INFO,
# level=10, # 输出位置
# stream=sys.stderr, # sys.stdout 往控制台输出
filename='log/my.log', # 往文件输出 => 如果需要同时往多个位置输出,需要handles # 输出格式
format='%(asctime)s[%(name)s]: %(msg)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# my.log日志:2019-05-16 14:39:32[root]: error msg
# 标准输入
# print(sys.stdin.readline())
# filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
# filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
# format:指定handler使用的日志显示格式。
# datefmt:指定日期时间格式。
# level:设置rootlogger(后边会讲解具体概念)的日志级别 #案例:
logging.basicConfig(
filename="aaa.log",
filemode="at",
datefmt="%Y-%m-%d %H:%M:%S %p",
format="%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s",
level=10
)
格式化全部可用名称:
%(name)s:Logger的名字,并非用户名,详细查看
%(levelno)s:数字形式的日志级别
%(levelname)s:文本形式的日志级别
%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
%(filename)s:调用日志输出函数的模块的文件名
%(module)s:调用日志输出函数的模块名
%(funcName)s:调用日志输出函数的函数名
%(lineno)d:调用日志输出函数的语句所在的代码行
%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d:线程ID。可能没有
%(threadName)s:线程名。可能没有
%(process)d:进程ID。可能没有
%(message)s:用户输出的消息
2.logging的成员组成
logging模块的四个核心角色:
1.Logger 日志生成器 产生日志
2.Filter 日志过滤器 过滤日志
3.Handler 日志处理器 对日志进行格式化,并输出到指定位置(控制台或文件)
4.Formater 处理日志的格式
import logging # 1.打印者:自定义的打印者如何配置
log1 = logging.getLogger('logger name') # 2.输出位置:两个文件输出位置与一个控制台输出位置
hd_a = logging.FileHandler('log/a.log', encoding='utf-8')
hd_cmd = logging.StreamHandler() # 3.输出格式
fmt1 = logging.Formatter('%(asctime)s 【%(name)s】- %(msg)s')
fmt2 = logging.Formatter('%(asctime)s - %(msg)s') # 4.打印者添加句柄 - 设置打印者的输出位置
log1.addHandler(hd_a)
log1.addHandler(hd_cmd) # 5.将格式绑定给输出位置(句柄)
hd_a.setFormatter(fmt1)
hd_cmd.setFormatter(fmt2) # 6.权限控制
log1.setLevel(logging.DEBUG) # 打印者规定打印级别
hd_a.setLevel(logging.WARNING) # 不同输出位置(句柄)再可以二次限定输出级别
hd_cmd.setLevel(logging.DEBUG) # 不同输出位置(句柄)再可以二次限定输出级别 # 7.不同级别输出信息
log1.debug('debug msg')
log1.info('info msg')
log1.warning('warning msg')
log1.error('error msg')
log1.critical('critical msg')
import logging
# root打印者,用logging.basicConfig来配置
# logging.critical('12345') # 1.打印者:自定义的打印者如何配置
log1 = logging.getLogger('Owen')
# log1.critical('67890') log2 = logging.getLogger('Simon')
# log2.critical('00000') # 2.输出位置:两个文件输出位置与一个控制台输出位置
hd_a = logging.FileHandler('log/a.log', encoding='utf-8')
hd_b = logging.FileHandler('log/b.log', encoding='utf-8')
hd_cmd = logging.StreamHandler() #控制台输出 # )) 为输出者绑定输出位置
log1.addHandler(hd_a)
log1.addHandler(hd_b) log2.addHandler(hd_b)
log2.addHandler(hd_cmd) # 3.输出格式
fmt1 = logging.Formatter('%(asctime)s 【%(name)s】- %(msg)s')
fmt2 = logging.Formatter('%(asctime)s - %(msg)s') # ))将格式绑定给输出位置(句柄)
hd_a.setFormatter(fmt1)
hd_b.setFormatter(fmt1)
hd_cmd.setFormatter(fmt2) # 级别控制: 打印者规定打印级别,输出位置(句柄)再可以二次限定,级别>=打印者级别
log2.setLevel(logging.DEBUG)
hd_b.setLevel(logging.WARNING)
hd_cmd.setLevel(logging.DEBUG) log2.debug('debug msg')
log2.info('info msg')
log2.warning('warning msg')
log2.error('error msg')
log2.critical('critical msg') # 4.输出
log1.critical('log1 输出的 critical msg')
log2.critical('log2 输出的 critical msg') # 过滤:少用
# logging.Filter
多日志多级别输出
3.logging配置文件项目开发运用
# 1.将打印者,句柄,与格式封装成配置信息
# 2.加载配置信息
# 3.使用自定义logger,采用的就是配置信息设置的logger # 优势:1,2两步是一劳永逸的,后期开发只需要在要记录日志的文件中使用自定义logger
# 一、基础配置:目录conf/setting.py
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False, #让系统的默认配置失效
'formatters': {
# 名称格式定义
'o_fmt1': {
'format': '%(asctime)s 【%(name)s】- %(msg)s'
},
'o_fmt2': {
'format': '%(asctime)s - %(msg)s'
}
},
'filters': {},
'handlers': {
'o_hd_file': {
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler', # 打印到控制台
'formatter': 'o_fmt1',
'filename': 'log/sys.log',
'encoding': 'utf-8',
'maxBytes': 1024*1024*5, # 日志大小5M
'backupCount': 5, # 文件切分:写满一个就改名为sys1.log,写满5个清空重新记录
},
'o_hd_cmd': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到控制台
'formatter': 'o_fmt2'
}
},
'loggers': {
'o_owen': {
'level': 'DEBUG',
'handlers': ['o_hd_file', 'o_hd_cmd']
},
'o_simon': {
'level': 'DEBUG',
'handlers': ['o_hd_cmd'],
# 'propagate': True # 向更高的level logging传递
}
}
} # 二、加载配置
import logging.config
logging.config.dictConfig(LOGGING_DIC) # 三、使用
log = logging.getLogger('o_simon')
log.critical('信息') log1 = logging.getLogger('o_owen')
log1.critical('信息')
# 目录:lib/common.py
from conf.settings import LOGGING_DIC
import logging.config
logging.config.dictConfig(LOGGING_DIC) def getLogger(name):
return logging.getLogger(name)
测试:
from lib.common import getLogger
log = getLogger('o_owen') log.debug('12345')
log.critical('67890')
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
logfile_path = "配置文件路径" LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5, #日志文件最大个数
'encoding': 'utf-8', # 日志文件的编码
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'aa': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
# 把key设置为空
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
}
标准代码
#lib/common.py
#日志功能
import logging.config
from conf import settings # 在lib 文件夹的common文件中生成日志对象
#生成日志对象
def get_logger(name):
# 先把日志配置传给logging
logging.config.dictConfig(settings.LOGGING_DIC)
# 生产日志对象--》接收的是name,根据name打印相应的日志
my_logger = logging.getLogger(name)
return my_logger # conf/settings.py
import os # test目录
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
# test/db目录
DB_PATH = os.path.join(BASE_PATH, 'db') # 日志配置文件
'''
logging 配置
'''
import os
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 日志目录
LOG_PATH = os.path.join(BASE_PATH,'log')
log_filename = 'Atm_Shop.log' if not os.path.isdir(LOG_PATH):
os.mkdir(LOG_PATH) # log文件全路径
logfile_path = os.path.join(LOG_PATH,log_filename) LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5, #日志文件最大个数
'encoding': 'utf-8', # 日志文件的编码
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'aa': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
# 把key设置为空
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
} # 引用
from lib import common
# 获取银行日志功能
bank_log = common.get_logger('bank') bank_log.info('%s提现%s元成功,手续费为%s' % (user, money2,money3))
标准代码2
九、re模块
# re:正则,全称正则字符串 - re就是有特殊语法的字符串
# re可以将有正则语法的字符串解析为对应的正则对象,用来匹配目标字符串 # 学习re的目的:1.判断目标字符串是否合法 2.在目标字符串中提取想要的信息(信息匹配规则采用正则)
import re # 从123abc123中查找1
r1 = re.findall(r'1', '123abc123')
print(r1) # ['1', '1'] r2 = re.findall(r'a', '123abc123ABC', flags=re.I) # re.I 不区分大小写匹配
print(r2) # ['a', 'A'] # 1.将 r'\d' 丢给_compile得到可以匹配数字的 正则对象
# 2.正则对象.findall('目标字符串')
r3 = re.findall(r'\d', '123abc123')
print(r3) # ['1', '2', '3', '1', '2', '3'] re_obj = re.compile(r'\d') # 将 r'\d' 丢给_compile得到可以匹配数字的 正则对象
r4 = re_obj.findall('123abc123') # 正则对象.findall('目标字符串')
print(r4) # ['1', '2', '3', '1', '2', '3']
正则语法
单个字符语法:
import re # 一、单个字符语法
# 匹配a
print(re.findall(r'a', '123abc嘿嘿')) # ['a'] # a或b
print(re.findall(r'a|b', '123abc嘿嘿')) # ['a', 'b'] 不建议使用
print(re.findall(r'[ab]', '123abc嘿嘿')) # ['a', 'b'] 建议使用 # 非a非b
print(re.findall(r'[^ab]', '123abc嘿嘿')) # ['1', '2', '3', 'c', '嘿', '嘿'] # 数字
print(re.findall(r'[0-9]', '12abc嘿嘿12')) # ['1', '2', '1', '2'] 建议使用
print(re.findall(r'\d', '12abc嘿嘿12')) # ['1', '2', '1', '2'] 不建议使用 # 字母
print(re.findall(r'[a-zA-Z]', '12abc[嘿嘿ABC')) # ['a', 'b', 'c', 'A', 'B', 'C'] # 字母数字_常用汉字:\w => 建议使用 [a-zA-Z0-9_]
print(re.findall(r'\w', '12abc[_嘿嘿ABC')) # ['1', '2', 'a', 'b', 'c', '_', '嘿', '嘿', 'A', 'B', 'C'] # 汉字 [\u4e00-\u9fa5]代表汉字
print(re.findall(r'[\u4e00-\u9fa5]', '12abc[_嘿嘿ABC')) # ['嘿', '嘿'] # 空白字符:\s => 建议使用[ \f\n\r\t\v]
print(re.findall(r'\s', ' \f\n\r\t\v')) # [' ', '\x0c', '\n', '\r', '\t', '\x0b'] # 非\n的任意字符: .
print(re.findall(r'.', ' \f\n\r\t\v*&_.')) # [' ', '\x0c', '\r', '\t', '\x0b', '*', '&', '_', '.'] # 只想匹配.字符:\.
print(re.findall(r'\.', ' \f\n\r\t\v*&_.')) # ['.'] # re.S: 让.也能匹配\n,就可以理解为 . 可以匹配所有字符
print(re.findall(r'.', ' \f\n\r\t\v*&_.', flags=re.S)) # 取对立面 \d数字 \D非数字 \w=>\W \s=>\S
print(re.findall(r'\D', '12abc\f嘿嘿12')) # ['a', 'b', 'c', '\x0c', '嘿', '嘿']
重复字符语法:
print(re.findall(r'ab', 'abacbabc')) # ['ab', 'ab'] # 指定个数: 匹配abb
print(re.findall(r'ab{2}', 'aababbabbb')) # ['abb', 'abb'] # 贪婪匹配: 尽可能多的匹配
# a0~2个b: a | ab | abb
print(re.findall(r'ab{,2}', 'aababbabbb')) # ['a', 'ab', 'abb', 'abb'] # a0~n个b:
print(re.findall(r'ab{0,}', 'aababbabbb')) # ['a', 'ab', 'abb', 'abbb'] # a1~3个b:
print(re.findall(r'ab{1,3}', 'aababbabbb')) # ['ab', 'abb', 'abbb'] # *: {0,}
print(re.findall(r'ab*', 'aababbabbb')) # ['a', 'ab', 'abb', 'abbb']
# +: {1,}
print(re.findall(r'ab+', 'aababbabbb')) # ['ab', 'abb', 'abbb']
# ?: {,1}
print(re.findall(r'ab?', 'aababbabbb')) # ['a', 'ab', 'ab', 'ab'] # 非贪婪匹配
print(re.findall(r'ab{1,3}?', 'aababbabbb')) # ['ab', 'ab', 'ab'] # 重点:非贪婪匹配应用场景,一般都是结合有开头与结尾的标识
print(re.findall(r'<.{1,}>', '<a><b>msg</b></a>')) # ['<a><b>msg</b></a>']
# 匹配标签
print(re.findall(r'<.{1,}?>', '<a><b>msg</b></a>')) # ['<a>', '<b>', '</b>', '</a>'] # *?: {0,}?
# +?: {1,}?
# ??: {,1}?
print(re.findall(r'<.+?>', '<a><b>msg</b></a>')) # ['<a>', '<b>', '</b>', '</a>']
分组语法:
# 引子
print(re.findall(r'(?:ab){2}', 'abbabab')) # ['abab'] # findall(): 没有分组情况下,显示匹配的结果;如果有分组,显示分组结果 # 分组:()
# 取消分组:(?:)
# 有名分组:(?P<名字>) # 案例:
# 匹配链接
print(re.findall(r'www\..+?\.com', 'www.baidu.comabcwww.sina.com')) # ['www.baidu.com', 'www.sina.com']
# 获取链接的域名:['baidu', 'sina']
print(re.findall(r'www\.(.+?)\.com', 'www.baidu.comabcwww.sina.com')) # ['baidu', 'sina'] # 分组编号: 从左往右数左(进行分组编号
# [('www.baidu.com', 'baidu', 'com'), ('www.sina.edu', 'sina', 'edu')]
res = re.findall(r'(www\.(.+?)\.(com|edu))', 'www.baidu.comabcwww.sina.edu')
print(res)
print(res[0][1]) # 取消分组:(?:) 应用于,要将一些数据作为整体看待,但由不能产生分组
# [('www.baidu.com', 'baidu'), ('www.sina.edu', 'sina')]
res = re.findall(r'(www\.(.+?)\.(?:com|edu))', 'www.baidu.comabcwww.sina.edu')
print(res)
其他正则方法的使用:
# match:不是全文匹配,必须从头开始匹配,且只匹配一次
res = re.match(r'(www\.(?P<site_name>.+?)\.(?:com|edu))', 'www.baidu.comwww.sina.edu')
# 可以通过分组号直接取出分组内容
print(res.group(1))
print(res.group(2))
# print(res.group(0), res) # 匹配的整体 # 有名分组
print(res.group('site_name')) # split(): 拆分
print('abc def xyz'.split(' '))
print(re.split(r' ', 'abc def xyz'))
print(re.split(r'[,@ ]', 'abc,def@xyz opq')) # sub(): 替换
res = re.sub(r'good', 'bed', 'good good day a')
print(res) # bed bed day a res = re.sub(r'good', 'bed', 'good good day a', count=1)
print(res) # bed good day a res = re.sub(r'good day a', '123', 'good day a!!!')
print(res) # 123!!! # 结合分组可以完成数据的重组
res = re.sub(r'(good) (day) (a)', r'today is \3 \1 \2', 'good day a!!!')
print(res) # today is a good day!!!
元字符 | 描述 |
---|---|
\ | 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配\n。“\n”匹配换行符。序列“\”匹配“\”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。 |
^ | 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
$ | 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
* | 匹配前面的子表达式任意次。例如,zo能匹配“z”,也能匹配“zo”以及“zoo”。等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。 |
? | 当该字符紧跟在任何一个其他限制符(,+,?,{n},{n,},{n,m*})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o'] |
.点 | 匹配除“\n”和"\r"之外的任何单个字符。要匹配包括“\n”和"\r"在内的任何字符,请使用像“[\s\S]”的模式。 |
x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[zf]ood”则匹配“zood”或“food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“abc”可以匹配“plain”中的“plin”任一字符。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身. |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“a-z”可以匹配任何不在“a”到“z”范围内的任意字符。 |
\b | 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1”可以匹配“1_23”中的“1”,但不能匹配“21_3”中的“1_”。 |
\B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er” |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何可见字符。等价于 \f\n\r\t\v。 |
\w | 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。 |
\W | 匹配任何非单词字符。等价于“A-Za-z0-9_”。 |
\d | 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持 |
\D | 匹配一个非数字字符。等价于0-9。grep要加上-P,perl正则支持 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
( ) | 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。 |
(?:pattern) | 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 |
| | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。 |
十、shell脚本之subprocess模块
#Popen
order = subprocess.Popen('dir',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
res = order.stdout.read().decode('gbk')
print(res)
print('==============================')
res = order.stderr.read().decode('gbk')
print(res)
# 举例
# windows下测试列出目录文件
# run
import subprocess
order = subprocess.run('dir',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
res = order.stdout.decode('gbk')
print(res)
print('==============================')
# stderr 输出错误
res = order.stderr.decode('gbk')
print(res)
#Centos系统
>>> a = subprocess.call(['df','-lh'],shell=False)
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 9.0G 29G 25% /
/dev/vdb 99G 16G 78G 18% /db
tmpfs 783M 0 783M 0% /run/user/1000 >>> r1=subprocess.getstatusoutput("dir")
>>> r1
(0, 'lova test.sh') >>> r2 = subprocess.Popen('ping -c2 www.baidu.com',shell=True)
>>> PING www.a.shifen.com (115.239.210.27) 56(84) bytes of data.
64 bytes from 115.239.210.27 (115.239.210.27): icmp_seq=1 ttl=54 time=8.59 ms
64 bytes from 115.239.210.27 (115.239.210.27): icmp_seq=2 ttl=54 time=8.64 ms --- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 8.595/8.621/8.648/0.094 ms >>> subprocess.Popen('./test.sh',shell=True)
<subprocess.Popen object at 0x7f2c51f10160>
>>> Hello World! >>> res = subprocess.Popen('./test.sh',stdout = subprocess.PIPE,shell=True,stderr=subprocess.PIPE)
>>> res1 = res.stdout.read()
>>> res1
b'Hello World!\n'
>>> print(res1)
b'Hello World!\n'
def subrun(cmd):
comply = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
res_stdout = comply.stdout.read()
res_stderr = comply.stderr.read()
if res_stdout:
return res_stdout.decode('utf-8')
return res_stderr.decode('utf-8')
函数传参
十二、configparser 模块
# my.ini 配置文件读写
"""
[server]
ip = 192.168.66.88
port = 3306 [client]
user = root
password = root
""" import configparser # 1.初始化
parser = configparser.ConfigParser() # 2.读
parser.read('my.ini', encoding='utf-8')
# section | option | value
# 读取列表
sts = parser.sections()
print(sts, type(sts)) # ['server', 'client'] <class 'list'> ops = parser.options(sts[0])
print(ops) # ['ip', 'port']
value = parser.get(sts[0], ops[0])
print(value, type(value)) # 192.168.66.88 <class 'str'>
# # get=>str getboolean=>bool getfloat=>float getint=>int
print(parser.get('server', 'port')) # 3306 # 3.写
parser.read('my.ini', encoding='utf-8')
parser.set('server', 'port', '6666')
parser.write(open('my.ini', 'w'))
十三、xml模块
# xml文件:1.作为传输文件用于数据的传输 2.作为配置文件配置信息 # 1.只能由一个根标签
# 2.所有的标签都是自定义的
# 3.标签名就是key,标签的内容就是value
# 4.与json不同的是,标签不仅可以有key和value,还有标签的属性
# 注:xml的属性通常用来表示标签间的区分度,用于解析xml来使用
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>88888</gdppc>
<neighbor direction="N" name="Malaysia" />
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
</country>
</data>
my.xml
"""
{"countrys": [
{
"rank": 2,
"year": 2008,
"gdppc": 141100
},
{},
{}
]} {
"data": {
"countrys": [
{},
{},
{}
]
}
}
"""
# xml的文件解析 => 将xml转化为json类型的数据
# dict list => json import xml.etree.ElementTree as ET # 读文件
tree = ET.parse("my.xml")
print(tree) # xml.etree.ElementTree.ElementTree # <xml.etree.ElementTree.ElementTree object at 0x0000000001EACA58>
# 根节点
root_ele = tree.getroot()
print(root_ele) # Element 'data':<Element 'data' at 0x0000000001DBD4A8> # 遍历往下
# print(root_ele[1])
for ele in root_ele:
print(ele, ele.attrib)
if ele.attrib['name'] == 'Singapore':
for e in ele:
print(e, e.tag)
if e.tag == 'gdppc':
print(e.text)
e.text = '6666' # 只修改了内容 # 全文搜索指定名的子标签
# ele.iter("标签名")
# 非全文查找满足条件的第一个子标签
# ele.find("标签名")
# 非全文查找满足条件的所有子标签
# ele.findall("标签名")
# print('==============')
# cs = root_ele.iter('country')
# for c in cs:
# print(c)
# print('==============')
# print(root_ele.find('country').attrib) # {'name': 'Liechtenstein'}
# print(root_ele.find('rank').attrib) # 不能跨标签取,只能取子标签
# print('==============')
# print(root_ele.findall('country')) # 将内存的数据重新写入文件
tree.write("my.xml")
# 读
data = {'countrys': []}
tree = ET.parse("my.xml")
root = tree.getroot()
for ele in root:
country = {}
for e in ele:
if e.text and e.text.strip():
country[e.tag] = e.text
data['countrys'].append(country)
print(data)
十四、Excel操作
# Excel
年终报表
教学部 市场部 咨询部 总计
Jan-19 10 15 5 30
Feb-19 11 20 5 36
Mar-19 12 25 5 42
Apr-19 13 30 5 48
May-19 14 35 5 54
Jun-19 15 40 5 60
Jul-19 16 45 5 66
Aug-19 17 50 5 72
Sep-19 18 55 5 78
Oct-19 19 60 5 84
Nov-19 20 65 5 90
Dec-19 21 70 5 96
基本操作
imimport xlrd # 读取文件
work_book = xlrd.open_workbook("my.xlsx")
# 获取所有所有表格名称
print(work_book.sheet_names())
# 选取一个表
sheet = work_book.sheet_by_index(0)
# 表格名称
print(sheet.name)
# 行数
print(sheet.nrows)
# 列数
print(sheet.ncols)
# 某行全部
print(sheet.row(6))
print(sheet.row(13))
# 某列全部
print(sheet.col(4))
# 某行列区间
print(sheet.row_slice(6, start_colx=0, end_colx=4))
# 某列行区间
print(sheet.col_slice(3, start_rowx=0, end_rowx=3))
# 某行类型0:空 1:str 2:num 3:date | 值
print(sheet.row_types(1), sheet.row_values(6)) # 单元格
print(sheet.cell(6,0).value) # 取值
print(sheet.cell(6,0).ctype) # 取类型
print(sheet.cell_value(6,0)) # 直接取值
print(sheet.cell_type(6,0)) # 直接取类型 # 0:以1900年为基准 1:以1904年为基准
print(xlrd.xldate_as_datetime(sheet.cell(6, 0).value, 0))
import xlwt
# 创建工作簿
work = xlwt.Workbook()
# 创建一个表
sheet = work.add_sheet("员工信息数据")
# 创建一个字体对象
# font = xlwt.Font()
# font.name = "Times New Roman" # 字体名称
# font.bold = True # 加粗
# font.italic = True # 斜体
# font.underline = True # 下划线
# 创建一个样式对象
# style = xlwt.XFStyle()
# style.font = font
keys = ['Owen', 'Zero', 'Egon', 'Liuxx', 'Yhh']
# 写入标题
c = 0
for k in keys:
# sheet.write(0, keys.index(k), k, style)
# sheet.write(0, keys.index(k), k) sheet.write(keys.index(k) + 5, 2, k if k != 'Egon' else 'cool')
# sheet.write(c, c, k)
# c += 1 # 写入数据
# sheet.write(1, 0, 'cool', style)
# sheet.write(0, 0, 'cool')
# 保存至文件
work.save("new_my.xls")
python入门_模块2的更多相关文章
- Python 入门之 模块
Python 入门之 模块 1.模块 (1)模块是什么? 将一些常用的功能封装到一个文件中,那么这个存储着很多常用的功能的py文件,就是模块. 模块就是文件,存放一堆常用的函数.模块,就是一些常用 ...
- Python 进阶_模块 & 包
目录 目录 模块的搜索路径和路径搜索 搜索路径 命名空间和变量作用域的比较 变量名的查找覆盖 导入模块 import 语句 from-import 语句 扩展的 import 语句 as 自动载入模块 ...
- python 入门学习---模块导入三种方式及中文凝视
Python 有三种模块导入函数 1. 使用import 导入模块 import modname : 模块是指一个能够交互使用,或者从还有一Python 程序訪问的代码段.仅仅要导入了一个模块,就能够 ...
- python语法_模块
方便调用的分组函数文件,一个py模块就是一个模块,模块分三类 python标准库 第三方模块 应程序自定义模块 模块的掉用: 可以把多个功能(函数)包含在一个模块文件里,调用时直接使用import 就 ...
- python语法_模块_os_sys
os模块:提供对此操作系统进行操作的接口 os.getcwd() 获取python运行的工作目录. os.chdir(r'C:\USERs') 修改当前工作目录. os.curdir 返回当前目录 ( ...
- python入门之模块
序什么是包包的作用一.什么是模块二.模块的三种来源三.模块的四种表现形式四.为什么要使用模块五. 如何创建,编写模块,并使用模块5.1 给模块起别名5.2 模块的导入方式5.3 循环导入问题 TOC ...
- Python入门-pip模块管理工具
安装 # 在线安装 pip install <包名> 安装后,该模块文件会在安装python环境目录:lib/packages目录下 # 安装本地安装包 pip install <目 ...
- Python入门-常用模块
1.sys,os import sys import os #获取当前的路径 print(sys.path[0]) print(os.getcwd()) print(os.path.abspath(& ...
- python语法_模块_loggin_hashlib_conifgparser
loggin模块 日志模块,级别从上往下依次增强,debug 和 info 默认不输出信息,只有后三种级别有输出信息 loggin.debug('') loggin.info('') loggin.w ...
- python语法_模块_time_datetime_random
模块:可以被公共调用的. time import time print(time.time()) 时间戳方式显示时间. time.sleep(3) 休眠3秒 time.clock() 计算cpu执行时 ...
随机推荐
- SPSS安装及破解教程
SPSS是一种统计分析软件,其全称为"Statistical Product and Service Solutions".以下是SPSS的作用和好处: 作用: 数据管理:SPSS ...
- KingbaseES 物理备库影响主库的性能与垃圾回收
前言 KingbaseES 物理备库有些配置可能影响到主库性能,或者反过来说主库某些配置也会影响到备库.终极原因还是heap tuple 和dead tuple放在一起导致的. 首先,原理上讲,物理备 ...
- Scala 递归和尾递归
1 package com.atguigu.function 2 3 object Recursion { 4 def main(args: Array[String]): Unit = { 5 // ...
- Java也可以像python般range出连续集合
Java lamada:IntStream --range(int startInclusive, int endExclusive):前包后不包 IntStream.range(0, 10).for ...
- Java break、continue 详解与数组深入解析:单维数组和多维数组详细教程
Java Break 和 Continue Java Break: break 语句用于跳出循环或 switch 语句. 在循环中使用 break 语句可以立即终止循环,并继续执行循环后面的代码. 在 ...
- Qt操作ini文件
操作文件,无非就是读与写,以下为Qt读写ini文件的代码. demo: #include "widget.h" #include <QApplication> #inc ...
- RestTemplate进行https请求时适配信任证书
转载请注明出处: 1.http协议请求 使用RestTemplate进行http协议的请求时,不需要考虑证书验证相关问题,以下为使用RestTemplate直接使用的代码示例: import org. ...
- CentOS文件备份|还原
CentOS文件备份|还原 时间:2014-03-18 00:27 来源:51cto博客 作者:sailyangfan的空间 举报 点击:205次 dump备份 restore还原 dd数据备份 mk ...
- node require的循环引用是怎么一回事
require 运行过程 require 引用是同步的,没有异步这么一说,它会先运行一遍. setouttime(function(){ export=a; }) 如果我们require的时候,那么这 ...
- 重走py 之路 ——列表(一)
前言 因为最近公司有python项目维护,所以把python的基础入门的书整理一遍,因为有些忘记了,同时在看<<python编程>>这本书的时候觉得对有基础的有很多的赘余,打算 ...