Python学习日记(Alex老师)
跟着Alex老师学的Python,视频链接:96天从小白炼成PYTHON开发
Python学习日记
第一天
字符串
拼接:a+b
次数:a*3
赋值:单引号、双引号、多引号(多行)
列表(数组)
添加:插入name.insert(3,’alex’)、追加name.append(“tony”)
修改:name[2]=” “
删除:del name[2],name.remove(“ “)
查找:in
查找下标:name.index()返回坐标
字符串格式化输出
占位符:%s,%d,%f
深圳小事
不要烂在泥土里
贪欲吞噬人性
运算符
算数运算:幂** 取整除//
比较运算:
赋值运算:**=、//=
逻辑运算:and、or、not
while..else循环
如果while没有给break终止的话,执行else后的语句
第二天
课前鸡汤
复合型人才
变量的创建过程
a=“alex”
b=a
a、b都指向alex而不是b指向a
a=’alex’
a=’boy’
此时上下a指向的地址不一样
身份运算
is /is not
a=‘alex’
type(a) is string (true)
None 空值
a = None
if a is None :
三元运算
变量 = 值A if 条件A else 条件B
寻找帮助
help()
help(names.remove)
获取能进行的操作
names.
数据类型
列表
https://book.apeland.cn/details/30/
元组:只读列表
长度:len()
字符串:
不转义r(原生字符raw) a = r ‘ alex\n ‘ print(a) 得到alex\n
字典:
第三天
bytes类型
f = open ( “ python learning . txt “ , “w” , encoding = “utf - 8” ) 用utff-8的格式编码
f = open (“ “ , “wb” ) 不要加encoding 因为是用二进制的格式打开
python 和 pycharm 加载和编码都是默认utf8
str.encode() —->得到的是对应的bytes类型, 以 b ’ ‘ 标识
要转成二进制的情况 : 网络传输、写入硬盘
copy
在字符串、列表和集合中,修改一个字符串会创建一个新的地址,然后把原来的那个删除。
但是在字典中,s = s1 ,s和s1都指向同样的地址(容器)。
字典中每一个数据都有一个地址(容器里的物体)。
copy
浅copy s1 = s.copy() 只复制第一层, 当字典里面还有字典的话,改小字典的数据之后,两份都会影响。
深copy import copy s1 = s.deepcopy() 完全复制一份新的
编码和解码
编码 :str , encode(“utf-8”) 用utf-8编码
解码: str. decode(“utf-8”) 之前是用utf-8编码的,现在要把utf-8解码出来,解码后是unicode的格式
编码转换
在windows系统上,是gbk的方式编码
在mac/linux上,是以utf-8的方式编码
所以传输文件之后,要改变编码格式,不然会出现乱码。
gbk —> unicode —> utf-8
代码实现 utf-8 —> gbk
1 | #用utf-8格式 写入文件 |
函数的定义
默认返回值是None
返回多个,则会返回元组 return 1,2,3,4,5 —> (1,2,3,4,5)
函数的参数
参数的定义从右到左,参数的赋值从左到右
形参:相当于临时变量
实参
默认参数:靠右定义
位置参数
关键参数
def func( age , name , school )
func( 22 , name=”alex” , school = “scnu” ) 前一个是位置参数,后两个是关键参数
优先级:位置参数 > 默认参数/关键参数
非固定参数
def func( name , *args , **kwargs ) args会返回元组,kwargs会返回字典
func ( “alex” , 21 , 22 , age = 33 , sex = “female” ) 第一个是位置参数,后四个是非固定参数
第二三个会存到元组里,最后两个会存到字典里
局部变量和全局变量
局部变量和全局变量,即使名字一样,但是地址不一样。
使用时,查找顺序:局部变量>全局变量
locals() 返回全部局部变量,以字典的形式。
globals() 返会全部变量
在局部引用一个全局变量 声明(如果没有则创建):global name 然后再使用 //不建议这么使用
局部引用字典、列表
局部的函数里可以修改字典、列表里的数据,但是字典和列表本身时不可以修改的。
嵌套函数
函数里面再定义一个函数,这个小函数的作用域只在这个函数里面。临时函数。
匿名函数(lambda)
1 | def func(x): |
最复杂是一个三元表达式
1 | ex = lambda x : x**2 if x>10 else x**3 |
map( func , [ ] ) 把列表里的数据依次作为第一个函数的参数执行
1 | put = map ( lambda x:x**2 , [1,2,3,4,5] ) |
高阶函数
满足其一则为高阶函数:接受一个函数输入、返回一个函数
def func1 ( …. ) : …..
def func2 ( x , y , f ) : f (x)+ f(y) …..
func2 ( x , y , func2 )
函数递归
效率不高,会导致栈溢出
栈类似于队列
内置函数
abs 求绝对值
all 判断列表、字典、集合里面是否有 None 或者 0 。即如果每一个元素都 在 bool() 返回true,则为True。
any 判断是否有一个满足 bool(x) = True。
ascii 如果是在ascii表里的,返回原来的字符。如果不在,则返回unicode编码。” \ \ u “开头
bin 返回这个十进制数字的二进制形式
bool 判断是否为0和None,如果是,则返回False
bytearray 将bytes类型变成一个可以修改的bytes数组。例如 b [1] = …是不可以的,转成数组之后可以。
bytes 转化成bytes类型,以b 开头 。 a = bytes ( “中国 “ , “utf-8” ) —>a为 b’\xd6\xd0\xb9\xfa’
chr 返回数字对应的字符
complex 返回复数 complex ( 1,2 ) —> 1+2 j
dict 返回一个空字典
dir 返回能进行的操作(类似帮助)
divmod 除然后取模 —> divmod( 8,3 ) = ( 2, 2 )
enumerate 返回列表的索引和元素。 a = [“alex”,”kiki”] enumerate后得到 (0,”alex”) (1,”kiki”)
eval 把字符串变成对应的数据类型
exec 把字符串变成可以执行的语句 exec(“print (“12345) “) 会打印12345
exit 退出程序
filter 过滤不满足条件的数据 。 list(filter ( lambda x: x<10 , [1,2,3,4,5,11,22,33] ))
—> [1, 2, 3, 4, 5]
float 强制转换浮点数类型
frozenset 把集合变成不能改的
globals 返回所有变量、函数
hash 返回一串以hash编码的到的数据
help 帮助。help(hash) 返回关于hash的定义和使用方法。
hex 16进制
id 返回数据的地址
input 输入
int 转换整型
isinstance 判断是否是某个数据类型 isinstance( a , string )
len 长度
list 返回空列表
locals 返回局部变量
map map(function , list) 把列表中的数据一个一个带入到函数中
max 最大值
min 最小值
oct 返回10进制数的8进制表示
open 打开
ord 返回字符的ASCII码
print 输出
quit 离开程序
range 一个列表
round 四舍五入
set 返回空集合
sorted 排序
str 转化成字符串
sum 加法
tuple 返回空元组
type 返回数据类型
zip 可以合并两个列表 a = [1,2,3] b = [“alex” , “kiki” ]
zip(a,b) —> [ (1,”alex”) , ( 2,”kiki” ) ] 取小的那个
名称空间
LEGB
locals:局部的,函数内部的
enclosing function:嵌套函数最近的父函数
globals:全局变量
builtins:所有函数,包括内置函数
闭包
外层函数返回内层函数
函数运行完,函数的作用域不会消失
调用外层函数的时候,先不执行内部的函数,直接return 内部函数的地址
装饰器
问题产生:“开放-封闭”原则
封闭:已经实现的函数不能修改
开放:对现有函数进行扩展
不能改函数名
不能改调用方式
语法:
1 | def func1:..... |
可以加参数,非固定参数:*args **kwargs
列表生成式
给一个列表元素都加1的办法
1 | a = [1,3,4,5,6,7] |
生成器:惰性算法
用循环,range会首先生成一个列表,占空间
生成器优点:边执行边计算
语法:把列表生成式的[]改成()就好了 p = ( i for i in range(10) )
执行:next( p )
循环调用
1 | for i in p : |
函数生成器
把函数里面的return 改成yield
yield b : 程序或者循环 暂停,并且返回 b
一个有yield 的函数,可以在中间去执行别的代码,然后再返回来执行
执行方式
1 | next (func) |
但是此时函数会暂停,并且永不结束。
一般用for来调用,就不会这样了。
发送值给函数生成器
1 | def func(value): |
单线程下的多并发
线程:cpu执行任务的单元
多核:多个线程,并行运算
1 | import time |
迭代器iterator
迭代对象: 1.可以用于for循环的数据类型:set、tuple、list、dic、str
2.迭代器和迭代器函数
可迭代:Interable 可遍历、可循环 用isinstance()判断是不是可迭代对象
迭代器:可以用next()执行下一次的 例如generator
可以用iter()强制转换成迭代器
第四天
OS库:跟系统调用相关
os 模块提供了很多允许你的程序与操作系统直接交互的功能
1 | 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() |
sys库
1 | sys.argv 命令行参数List,第一个元素是程序本身路径 |
time模块
时间戳timestamp:从1970年1月1日到现在过去了多少秒
元组struct_time:年月日时分秒周 一年中第几天 是否是夏令时
UTC (Coordinated Universal Time ,世界协调时):中国时UTC+8
DST (Daylight Saving Time):夏令时
1 | time.localtime( [ timestamp ] ):将一个时间戳转换为当前时区的struct_time。若secs参数未提供,则以当前时间为准。 |
datatime模块
相比于time模块,datetime模块的接口则更直观、更容易调用
1 | datetime.date:表示日期的类。常用的属性有year, month, day; |
1 | 1. d=datetime.datetime.now() 返回当前的datetime日期类型 |
pickle && json
序列化:数据的 网络传输和储存在硬盘 的形式是 bytes类型。把各种数据类型转化成可以网络传输和储存的类型称为序列化。
反向过程叫做 反序列化
1 | #pickle |
1 | Json模块也提供了四个功能:dumps、dump、loads、load,用法跟pickle一致 |
pickle 和 json的区别
JSON:
优点:跨语言(不同语言间的数据传递可用json交接)、体积小
缺点:只能支持int\str\list\tuple\dict
Pickle:
优点:专为python设计,支持python所有的数据类型
缺点:只能在python中使用,存储数据占空间大
hashlib
HASH加密
一般译作散列或者哈希。是把任意输入(预映射)转化成固定长度(128位)的输出,这个输出称之为散列值。这是一种压缩算法。
密码学相关
碰撞:不同字符串通过hash算法得到相同的散列。
撞库:用穷举法反解散列值,以获得原来的明文密码。
加盐:通过给hash得到的散列通过加盐算法增加字符然后再次hash。
拖库:黑客获取了密码库。
MD5(Message-Digest Algorithm)
讯息摘要演算法。一种加密算法。
MD5的特点
- 压缩性:得到的散列一般比原数据 占内存小
- 易计算:通过MD5的算法,计算时间短
- 抗修改:修改原数据,将得到不同的HASH值
- 抗碰撞:一般不会有相同的HASH值
- 不可逆
MD5的效果
- 防篡改:发送和接受时的HASH值一样,则没有被篡改
- 防抵赖:申请数字签名
- 防看到明文:看不到密码
MD5的操作
1 | import hashlib |
SHA(Secure hash Algorithnm)
sha - 1 :得到160位的散列值。
sha - 256:得到256位。
一般用在密码学上,操作和MD5一样。
shutil模块
1 | #shutil.copyfileobj ( open(fsrc, "rb"), open(fdes, "wb") ) |
zipfile压缩&解压缩
1 | import zipfile |
tarfile压缩&解压缩
1 | import tarfile |
re正则匹配
匹配规则
- re.match() 从第一个字符开始匹配,如果不符合则返回None
- re.search() 匹配全局,返回第一个
- re.findall() 把所有匹配到的字符,放到一个列表返回
- re.split() 以匹配到的字符当做列表分隔符,与findall相反
- re.sub 匹配字符并替换 re.sub( 要替换,替换成,字符串,count=替换次数)
- re.fullmatch 精确匹配,这个字符串必须完全符合规则
表达式规则
1 | '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 |
re.compile(pattern, flags=0)
把这个规则先编译,这样就不用每次调用都重新编译
1 | prog = re.compile(pattern) |
Flags标志符
- re.I (re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
- re.M (MULTILINE): 多行模式,不会忽略 \n,改变’^’和’$’的行为
- re.S (DOTALL): 改变 ’ . ’ 的行为,能匹配特殊符号
- re.X (re.VERBOSE) 可以给你的表达式写注释,使其更可读,下面这2个意思一样
1 | a = re.compile ( r"""\d + # the integral part |