python 的小白之路---
name: icelandergu
2020年11月2日 开始第一天记录---
变量,常量
名字全部大写表示常量,例如:AGE
name = ‘lee’
name1 = name
变量name和name1同时的指向lee
name = "rain"
name1 的值还是"lee"
lee如果没有被变量指定,将会被回收
身份运算
type()
判断:is,is not
None 表示空值
变量初始化时用
name is None 或者 name = None
三元运算
a=10
b=5
if a>15:
c=a
else
c=b
d=a if a>15 else b
#if 条件成立把a赋给d 否则就把b赋给d
注释:
#表示单行注释
注释快捷键ctrl+?
表示多行注释
2020年11月3日
数据类型
str 字符串类型
int 整数 python3里表示所有整数
float 小数
python属于弱类型语言,不需要提前强制定义
字符串
有引号的所有字符串'aon' ,"ben。
'" 多行字符 "' 字符串的拼接用+
字符串的复写用*
布尔类型
Ture False 判断语句,选择执行路径
列表
就是用一个变量存储多个字符串,通过索引序号取值,顺序定义元素
name=[]定义
增 appdend 对列表的末尾进行添加数据
插入 insert()对指定位置插入数据; insert(2,"Alex")
列表嵌套
name.insert(2,[1,2,3])
name[2][1]
extend() #合并
删 del name[6] 也可以[-2]从尾部删
pop() #默认删除最后一个元素并返回
pop(1)#指定删除
remove() #删除从左到右的第一个值
clear() #清空列表
查 "Alex" in names
name.index("Alex") 查字符串的索引位置,并返回
name.count("Alex") 返回Alex的个数
改
name[0] = "lee" #直接赋值
切片
a[1:4] #a内取索引1,2,3的值 顾头不顾尾
a[1:-1] #1到最后第2个
a[1:] #1到最后1个,1后面全取
a[:5] #第一个到4的值
a[-5:-1] #-5到最后第二个
步长:
a[0:-1:1]
a[0:-1:2] #第一到最后第二个偶数位置取值
a[-1:-5:-1] #从左二往右到-5取值
a[:] #全取
a[::2] #偶数位置取值,步长为2
排序与反转
a[::-1] #反转
a.reverse #反转
a.sort() #排序,数字和字符串不能放在一起排序,类型必须一致
2020年11月4日
输入
input('enter:') 接收的数据都以字符串的格式处理
输出
格式化输出
''' I am a student! My name is %s Age is %s .... '''%(Alex,23)
算数运算 比较运算 赋值运算 逻辑运算 and,or,not
流程控制 if else
单分支 双分支 多分支
缩进
1.顶级代码必须顶行写,如果一行代码不依赖任何条件的,那它不能有任何缩进。
2.同一级代码必须同一缩进。
3.官方规定缩进用4个空格。
流程控制 while
continue#中止本次循环,进行下次循环
break#退出循环
else#当循环正常结束时执行
dead loop
2020年11月6日(5日感冒)
dict 字典 (字典是无序的)
person=dict{name="lee",age=20}
person=dict({"name":"girl",'age':20})
批量生成
keys = [1,2,3,4,5]
pp2 = {}.fromkeys(keys,999)
print(pp2)
[增]
d['name']='leo'#重新赋值并且覆盖
d.setdefault('salary',[1,2,3])#赋值,如果存在的话,则不覆盖不操作
删
del d['name']#删除key 为name的值
del d #删除字典d
d.pop("name") #删除key 为name的值并返回
d.popitem() #随机删除
d.clear() #清空字典
d.update(d2) #将字典d2加入字典d,有的覆盖,没有的加入
a= d.get("name") #取KEY为name的值,没有返回NONE
a= d.get("name1","-1") #没有返回指定的值“-1”
改
a["name"]= "lee"
查
d.keys() #返回 所以的key
d.values() #返回所以的value
d.items() #返回所以的key,value
for i in d: #效率高的循环
print(i,d[i])
for k,v in d.items():
print(k,v)
len() 返回字典的长度
set 集合(字符串,数字,元组)
1.元素不可以变
2.不重复
3.无序
作用:去除重复和关系运算
增
aa.add(1) #集合中增加1个元素
删
aa.discard(5) #删除一个存在的值,不存在,不操纵不报错
aa.pop() #随机删除并返回
aa.remove() #删除集合内有的值,没有回报错,其他同discard
查
name in aa
改
不能改
11月7日
关系运算
交集"&"
并集"|"
对称差集"^"
对称差集"^"
两个集合三种关系:相交,包含,不相交
a.isdisjoint(b) #判断a与b是不是相交
a.issubset(b) #判断a是不是b的子集
a.issuperset(b) #判断a是不是b的父集
a.difference(b) #表示差集"-"
a.union(b) #表示并集"|"
a.intersection(b)) #表示交集"&"
a.symmetric_difference(b) #表示对称差集"^"
a.difference_update(b) #求差集并重新赋值a
元组(tuple)
不可变,只读列表
元祖内的数据不能修改,其他操作和列表相同,
但是元祖内的数据是可变元素(数组,列表),只可以对数祖内的可变元素进行修改
字符串
1.从左到右顺序定义字符的集合
2.索引
3.切片
4.不可变,所有字符串的操作都是生成新的字符串
补充:字符串中的单双引号是无法取消特殊字符的含义,如果想让引号内字符取消特殊的含义,可以在引号前面加r name= r"r/nb//r"
11月12日
字符串的赋值或变更,其实是在内存中新建一个字符串,然后重新指向它!
a1 =a.capitalize() #首字母大写
a2= a.casefold() #大写全部改成小写
p=a.center(50,'*') #两边用‘*’代替填补50长度
a3 = a.count('a',2,20) #在字符串中,从索引位2开始到8中有几个字符a
a4 = a.endswith('e?') #判断是否已该字符串结尾
a5=a.find('a',3) #从字符串中找a,并返回从左到右找到的第一个值得索引值,
3表示从索引3开始找,如果返回-1表示找不到
#format 格式化,可以在任意位置替换想要的值
a = 'what is %s Name?My name is %s.'%("your","lee")
a1 = "what is {0} Name?My name is {1}."
a1 = a1.format("yo","le")
a2 = "what is {name} Name?My name is {use}."
a2 = a1.format(name="yo",use="le")
b=a.replace("is","are",1) #is 替换为 are 1代表替换1个
b2=a.split(" ",2) #按照","来分割字符串,2表示分割2个,从左到右 sep为分割符
b3=a.rsplit(" ",2) #按照","来分割字符串,2表示分割2个,从右到左 sep为分割符
a.startswith("A") #大写转为小写,小写转为大写
a.upper() #全部变成大写
a.lower() #全部变成小写
b6= a.zfill(50) #长度50,用零来补满
HASH
散列,复杂的运算
特点:就是你不能从结果推算出输入,又称不可逆的算法
作用:
1.密码,网络密码,md5加密算法,基于hash,保证同一的输入的出的结果一直一致
2.文件完整性的校验,MD5值
3.数字签名,区块链
基于hash的类型:dict,set
dict:key唯一,key不可变,查询速度快,且不受dict大小的影响,
dict的key都是要经过hash运算
set:天生去重,值存到set里时,先经过hash得出值,存时先检查值得位置上有没有,
有是否相等,相等就不存,与后面位置继续对比,如空就存
文件操作
f.open(filename) #打开文件
f.read(100) #读取100字节
f.write(name) #写名字到文件
f.close() #关闭文件
文件打开模式:只能以一种模式操作文件
r #read 表示读(默认)
w #write 表示写 创建模式,先清空文件在写
a #append 表示追加
file的其他功能
f.seek(2) #光标移动2个字节的位置
f.flush() #缓存中的数据强制存到硬盘上
f.tell #返回光标的位置
f.truncate() #按指定长度截断文件
w+ #写读 创建一个新文件,写内容,可以再读出来,需要用seek定位光标到开头
r+ 实用 #读写 能读能写,写到文件最后,同追加。读取时从头开始
a+ #追加读 打开时,光标在文件尾部,写的数据都是追加的形式
不占内存的修改文件
f = open('fox','r')
f_new = open('fox_new','w')
old = "old old"
new = "new new"
for line in f:
if old in line:
line = line.replace(old,new)
f_new.write(line)
f.close()
f_new.close()
#将fox内的old old修改成new new存到fox_new中
import sys
print(sys.argv) #文件外的读入
11月15日 补充
数据存到硬盘,硬盘只能存储2进制
2进制--》十进制--asscii/gbk/utf-8/ unicode
数据往硬盘上存,就要以相应的编码转成2进制后存储
文字--》utf-8/gbk-->2进制
图片--》jpg/png-->2进制
音乐--》MP3/wam-->2进制
视频--》mp4/mov-->2进制
bytes类型,以16进制形式表示,2个16进制数构成1个byte,以b''来标识,字节串
py3文件默认编码是utf-8
pycharm默认加载文件都是用utf-8编码
mode= 'wb' #wb就是以2进制模式打开文件并创建
mode= 'rb' #wb就是以2进制模式读文件
mode= 'ab' #wb就是以2进制模式追加
f = open("bytes.txt","w",encoding="gbk")指定编码
python r按你指定的编码来编成2进制
b binary
1.字符存硬盘,要变成bytes
2.网络传输,字符,要变成bytes
t mode = 'rt'
1.只针对文本文件
2.读写都是以字符串为单位
3.必须指定字符编码,即指定encoding参数
b mode = 'rb'
硬盘的数据以二进制读入内存,在b模式下,不做任何的转换,读入内存
1.读写都是以bytes为单位
2.可以针对所有文件
3.一定不能指定字符编码,即一定不能指定encoding参数
总结:存文本文件用t模式方便,其他的用b模式
浅copy
只对列表中不可变类型的数据进行copy,是把原列表第一层的内存地址不加区分的完全copy一份给新列表。对于可变类型的数据地址没有复制,所以没有做到完全独立与旧列表,原列表中可变数据变更时,还是会相应的变更。
import copy list2 = list1.copy()
深copy
对列表中的全部内存地址进行copy给新列表,与旧列表完全独立,原列表更改,新列表不会变。
is 与 ==
is 是比较左右2个值身份ID是否相等
== 是比较左右2个值的值是否相等
值相等,id可能不同,即两块不同的内存里存放相同的值。 id相等,值一定相等
小整数池[-5,256]
解析器启动时,就会在内存中事先申请,好一系列在内存空间存放好常用的整数
seek的应用
文件的检测,并显示追加的内容
import time
with open('aa.log',mode='rb')as f:
f.seek(0,2)
while True:
li = f.readline()
if len(li) == 0:
time.sleep(0.3)
else:
print(li.decode('utf-8'))
文件修改的两种方法:
1.适用于文本编辑,费内存,省硬盘空间
with open('a.txt','rt',encoding="utf-8")as f:
res = f.read()
data = res.replace("lee","fox")
print(data)
with open('a.txt','wt',encoding='utf-8')as f1:
f1.write(data)
2.省内存,费硬盘空间
import os
with open('a.txt','rt',encoding='utf-8')as f,\
open('.a.txt.swap','wt',encoding='utf-8')as f1:
for line in f:
f1.write(line.replace("fox",'bee'))
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')
11月17日
闭包现象
闭包的意义:返回的函数对象,不仅仅是个函数对象,在改函数外还包裹了一次作用域,这使得该函数无论何处调用,都优先使用自己外出包裹的作用域
def out():
name = 'lee'
def inne():
print("inne",name)
return inne
f = out()
f()
装饰器
def login(func):
def inner():
if account["is_authenticated"] is False:
usename = input("user:")
password = input("pasaword:")
if usename == account["usename"] and password == account["password"]:
print("welcome login ...")
account["is_authenticated"] = True
func()
else:
print("wrong usename or password!")
else:
print("用户已经登录,验证成功!")
func()
return inner
函数
位置参数(最左)-》关键参数\默认参数
非固定参数(定义函数是,不确定后面调用时,会传递多少个参数进来) (*args,**kwargs)
函数遇到return就停止程序,并返回结果,所以return语句代表函数结束。
如果未指定return,返回值为None
return 1,2,3,4,5 返回值为元组(1,2,3,4,5)
局部变量(locals())
全局变量(globals())
1.函数中的变量为局部变量,程序一开始定义的变量为全局。
2.全局变量的作用域为整个程序,局部变量的作用域为定义该变量的函数。
3.变量的查找顺序为局部变量,然后在全局变量。
4.当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用,其他地方全局变量起作用。
5.在函数里是不能直接修改全局变量的
glboal name 表示在函数内部声明(创建)一个全局变量。(不建议使用)
6.列表,集合,字典,函数调用时,可以对里面的值进行修改
嵌套函数
匿名函数(不需要显示指定函数名) calc = lambda x,y:x*y
高阶函数 (变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数。)
递归函数(在函数内部,可以调用其他函数。一个函数在内部调用自身本身) 特性: 1.必须有一个明确的结束条件 2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少 3.递归效率不高,递归层次过多会导致栈溢出。
内置函数
序列化与反序列化
序列化是将内存中的数据转换成一种特定的格式
可以用于存储或者在各种平台之间传输
反序列化就是反向转换
json 模块的数据存储与读取用法,与其他语言交互的特定格式
json 格式兼容所有语言通用的数据类型,不能识别某一语言的独有数据类型 pickle 模块的方法同json,它是python之间交互用的格式
import json
复杂的写操作
list_test = [1,2,"fdsfsf",True,"#$%‘",False]
str_list = json.dumps(list_test)
with open("test.json","wt",encoding="utf-8")as f:
f.write(str_list)
简单的写操作
list_test = [1,2,"fdsfsf",True,"#$%‘",False]
with open("test.json","wt",encoding="utf-8")as f:
json.dump(list_test,f)
复杂的读操作
with open("test.json","rt",encoding="utf-8")as f:
str_list = f.read()
json_list = json.loads(str_list)
print(json_list)
简单的从文件读取操作
with open("test.json","rt",encoding="utf-8")as f:
json_list = json.load(f)
生成器
yield 可以多次返回值 return 只能一次返回
def func():
print("第1次")
yield 1
print("第2次")
yield 2
print("第3次")
yield 3
print("第4次")
g = func()
print(next(g))
print(next(g))
print(next(g))
装饰器
def login(func):
@wraps(func)#将原函数的属性赋值给func
def inner(*args,**kwargs):
input("enter:")
print("验证!")#加各种功能
res= func(*args,**kwargs)
return res
return inner
@login
def home():
print("test1")
def abb():
print("test2")
def hunan():
print("test3")
home()
abb()
hunan()
闭包现象
def outer():
name = "i am lee!"
def inner():
print(name)
print(inner)
return inner
f= outer()
f()
print(f)
print(outer)
日志文件的生成
import logging
from logging import handlers
class Ignor_Filter(logging.Filter):
def filter(self,record):
return "db backup" not in record.getMessage()
#1.生产logger对象
logger = logging.getLogger("web")
logger.setLevel(logging.INFO)
# 2.生产handler对象
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# fh = logging.FileHandler("web.log")
# fh.setLevel(logging.WARNING)
# fh = handlers.RotatingFileHandler("web.log",maxBytes=10,backupCount=3)#按照文件长度进行分
fh = handlers.TimedRotatingFileHandler("web.log",when="s",interval=5,backupCount=3)#按照时间长短来分
# 3.吧handler对象绑定到logger
logger.addHandler(ch)
logger.addHandler(fh)
#4.生成formatter对象
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
logger.warning("test")
logger.error("test2")
logger.debug("test3")
猴子补丁
就是用自己的代码替换原有模块的源代码。
import json
import ujson
def monkey_json():
json.__name__="ujson"
json.dumps = ujson.dumps
json.loads = ujson.loads
monkey_json()#在程序的入口处调用,将ujson的代码实现的功能,替换json的2个功能
max,map,filter,reduce的应用
li = {"alex":3000,
"lee":5000,
"fox":2000,
"rain":10000}
================max===================
def func(name):
return li[name]
res = max(li,key=func)
res = max(li,key=lambda k:li[k])#匿名函数的简单使用,取工资最大的名字
sot = sorted(li,key=lambda k:li[k])#对工资大小进行排序
print(res)
=================map=====================
li2 = ["alex","lee","fox","rain"]
res = [name+"dsb" for name in li2]
res = map(lambda name:name+"dsb",li2)
for p in res.__iter__():print(p)
===================filter()==================
li3 = ["alexsb","lee","foxsb","rain"]
# res = (name for name in li3 if name.endswith("sb"))
res = filter(lambda name:name.endswith("sb"),li3)
print(res.__next__())
print(res.__next__())
========================reduce================字符或者数字的累加
from functools import reduce
res = reduce(lambda x,y:x+y,[1,3,4,5],5)
res1 = reduce(lambda x,y:x+y,["h","e","l","l","o"])
print(res,res1)
import sys 值为一个列表,存放了一系列的文件夹 查找优先级 1.先从内存找,(内置模块) 2.从硬盘找,按照sys.path存放的文件路径顺序查找
正则表达式
res = "aAbc23a14_=$%^ @$a\nb#!naAba2bAAA"
print(re.findall("\w",res))#\w匹配数字字母下划线
print(re.findall("\W",res))#\W匹配非数字字母下划线
print(re.findall("\s",res))#\s匹配空白字符 \t,\n,\r
print(re.findall("\S",res))#\S匹配非空白字符
print(re.findall("\d",res))#\d匹配数字0-9
print(re.findall("\D",res))#\D匹配非数字
print(re.findall("\AaAb",res))#\d匹配数字0-9
print(re.findall("A\Z",res))#\d匹配数字0-9,只能匹配单行的
print(re.findall("^aAb",res))#\d匹配aAb开头
print(re.findall("A$",res))#\d匹配A结尾的
print(re.findall("c.3",res))#. 匹配一个字符,除\n以为所有字符
print(re.findall(".",res,re.DOTALL))#. 匹配一个字符所有字符
print(re.findall("aA*",res))#. 匹配左侧字符aA,a必须有,A可以0个或者无数个
print(re.findall("aA+",res))#. 匹配左侧字符aA,a必须有,A可以1个或者无数个
print(re.findall("aA?",res))#. 匹配左侧字符aA,a必须有,A可以0个或者1个
print(re.findall("aA{1,3}",res))#. 匹配左侧字符aA,a必须有,A可以1个或者3个,{n}表示出现n次
print(re.findall("\d+\.?\d*","abafaf23fdsf1.333fdf3.ffio9."))#. 匹配左侧字符aA,a必须有,A可以1个或者3个
print(re.findall("a[0-5a-zA-Z]b",res))#. 匹配字符a[中间可以0到5a到zA到Z]b,
print(re.findall("a[^0-5a-zA-Z]b",res))#. 匹配字符a[除了这些0到5a到zA到Z以外的]b,
作业
import re
import json
from tabulate import tabulate
DB_KET = ["id","name","age","phone","dept","enroll_date"]
def db_up(db_file):
f = open(db_file,"r")
db_list = []
first = f.readline()
while len(first)!= 0:
db_list.append(first.strip().split(","))
first = f.readline()
print(db_list)
return db_list
def db_date(db_file):#将数据库的数据加载到内存中,并且重新组合
db_staff = {}
for i in DB_KET:
db_staff[i]= []
f = open(db_file,"r")
for line in f:
staff_id,name,age,phone,dept,enroll_date= line.strip().split(",")
db_staff["id"].append(staff_id)
db_staff["name"].append(name)
db_staff["age"].append(age)
db_staff["phone"].append(phone)
db_staff["dept"].append(dept)
db_staff["enroll_date"].append(enroll_date)
return db_staff
db_file ="staff_table.txt"
STAFF_DATE = db_date(db_file)
print(STAFF_DATE["name"])
def print_info(msg,info):# error信息格式化
if info == "error":
print("\33[31;1m%s\33[0m"%msg)
else:
print(msg)
def op_gt(clause_key,val):
index_num = []
for j,i in enumerate(STAFF_DATE[clause_key]):
if int(i) > int(val):
index_val = []
for value in DB_KET:
index_val.append(STAFF_DATE[value][j])
index_num.append(index_val)
# print(index_num)
return index_num
# else:
# print("mei")
def op_lt(clause_key,val):
index_num = []
for j,i in enumerate(STAFF_DATE[clause_key]):
if int(i) < int(val):
index_val = []
for value in DB_KET:
index_val.append(STAFF_DATE[value][j])
index_num.append(index_val)
return index_num
def op_equal(clause_key,val):
index_num = []
for j,i in enumerate(STAFF_DATE[clause_key]):
if i == val:
index_val = []
for value in DB_KET:
index_val.append(STAFF_DATE[value][j])
index_num.append(index_val)
return index_num
def op_like(clause_key,val):
index_num = []
for j,i in enumerate(STAFF_DATE[clause_key]):
if val in i:
index_val = []
for value in DB_KET:
index_val.append(STAFF_DATE[value][j])
index_num.append(index_val)
# print(index_num)
return index_num
def parse_where(parse):
# print(parse)
clause = {
">":op_gt,
"<":op_lt,
"=":op_equal,
"like":op_like
}
for op_key,op_val in clause.items():
if op_key in parse:
clause_key,val = parse.strip().split(op_key)
# print(val)
val_temp= format(eval(val))
# print(val_temp)
# print(val_temp,clause_key)
list_result = op_val(clause_key.strip(),val_temp)#查询数据
# print(list_result)
return list_result
# break
else:
print_info("语法错误!where条件只包含><=like!","error")
def S_find(date_set,query_clause):
query_str = query_clause.strip().split("from")
query_str_new = query_str[0].strip().split(" ")
val_list = []
# print(query_str)
val_li = query_str_new[1].strip().split(",")
print(val_li)
if val_li[0] == "*":
val_li = DB_KET
# print(val_li)
for j in date_set:
val_add= []
for i in val_li:
index = DB_KET.index(i)
val_add.append(j[index])
val_list.append(val_add)
print(tabulate(val_list,headers=val_li,tablefmt="grid"))
# else:
# print_info("语法错误!字段名错误", "error")
# val_list.append(val.split(","))
def S_add(date_set,query_clause):
pass
def S_del(date_set,query_clause):
# ss = set(date_set)
db_list = db_up(db_file)
for i in db_list:
if date_set[0]==i:
del db_list[i]
print(db_list)
print("ok")
return date_set
def S_update(date_set,query_clause):
if "set" in query_clause:
print(date_set)
print(query_clause)
date = query_clause.strip().split("set")
val_name,val_up = date[1].split("=")
val_name=val_name.strip()
print(val_name)
val_up = eval(val_up)
if val_name in DB_KET:
index = DB_KET.index(val_name)
print(index)
for i in date_set:
i[index]=val_up
return date_set
# print(date_set)
else:
print_info("语法错误!没有找到关键字update","error")
def parse_date(query_clause, where_clause):#被主程序调用执行语句判断增删改查,然后调用parse_where 解析where条件
query_list = {
"find":S_find,
"add":S_add,
"del":S_del,
"update":S_update
}
print(query_clause)
if query_clause.split()[0] in ("find","del","add","update"):
date_set = parse_where(where_clause) # 返回查找结果['2', 'Jack Wang', '28', '13451024608', 'HR', '2015-01-07']
print(date_set)
if query_clause.split()[0] in query_list:
query_list[query_clause.split()[0]](date_set,query_clause)
else:
print_info("语法错误!字段名错误!", "error")
def main():
while True:
db_up(db_file)
input_date = input(">>>>>:").strip()
query_clause, where_clause = input_date.split("where")
parse_date(query_clause, where_clause)
# print(db_date())
# keyword = input_date.split()
# query_clause,where_clause = input_date.split("where")
# date_set = parse_where(where_clause)#返回查找结果['2', 'Jack Wang', '28', '13451024608', 'HR', '2015-01-07']
# query_str = query_clause.strip().split("from")
# query_str_new =query_str[0].strip().split(" ")
# print(date_set)
# S_find(date_set,query_str_new[1])
# print_info("语法错误!","error")
main()