单行文本:
"单行文本" '单行文本'多行文本:
"""多行文本""" '''多行文本'''转换:
str(19) //数字转化为字符串 int('12')//字符串转化为数字布尔类型:
整型:0转化为布尔值为false,其他均为true。
bool(0) //false ; bool(-1) //true
字符串:空字符串转为布尔值为false,其他均为true。
bool("") //false ; bool(" ") //true
变量名:只能包含数字、字母、下划线;不能以数字开头;不能使用内置的关键字。
v1 b = "日本" in/not in "日本人不是人" # true or false运算符的高级用法:
v1 = 值 and/or 值 v1 = ' ' and 2 # 2 等价于bool(' ') and bool(2) v2 = '' and 2 # ''- and具体用法:如果前面的值为true,则取决于后面的值。反之,如果前面的值为false则直接输出前面的值,无需判断后面的值。
- or具体用法:如果前面的值为true,则取决于前面的值。反之,如果前面的值为false则取决于后面的值。
1.进制转换
以下进制之间转换只能借助十进制互相转换
data = 234; v2 = bin(data) #二进制 0b11101010 v2 = oct(data) # 八进制 0o352 v2 = hex(data) #十六进制 0xea d1 = int("0b11101010",base = 2) d2 = int("0o352",base = 8) d3 = int("0xea",base = 16)计算机经常使用十六进制显式内容:相比较二进制、八进制,十六进制更加简短。
2.编解码
二进制 vs 字符 之间的映射关系。
Ascii编码:
- 规定:一个字符【英文字母】只能通过一个字节【8个比特位】表示。
- 计算机最初的编码格式,意味着该编解码器无法处理中文。
- 8个比特位0 or 1 表示,总共有2^8方式。意味着Ascii码只能处理256个字符。
GBK编码:基于Ascii码的缺陷,中国提供属于自己的规范即GBK【GBK-2312[纯中文]的升级版 -- 包含亚洲其他语言】。
万国码unicode:
- 适用全球的编解码器。
- ucs2,利用固定的2个字节表示二进制和文字的对应关系。2^16 = 65535种可能。
- ucs4,用4个字节表示二进制和文字的对应关系,2^32种可能 。
ucs2缺点:无法覆盖全部文字。
ucs4缺点:覆盖全部文字,但是4个字节比较浪费空间/流量。
UTF8编解码:对unicode进行压缩,利用尽可能少的字节表示数据。【中文占用3个字节】
# 三个中文共占用9个字节,每个3个字节,十六进制如下显式 print("吕梁市".encode("utf-8")) #b'\xe5\x90\x95\xe6\xa2\x81\xe5\xb8\x82'3.数据类型
可变类型:列表、字典、集合。内部元素可以修改。
不可变类型:字符串、整型、元组、布尔类型。
#定义空列表 v1 = [] ; v2 = list() #定义空元组 v1 = () ; v2 = tuple() #定义空字典 v1 = {} ; v2 = dict() #定义空集合 v2 = set()3.1.字符串
startswith、endswith、strip/lstrip/rstrip【去除空白:包含空格、换行、制表符】、索引、切片。
name = "吕梁市柳林县" print(len(name)) # 字符换索引 print(name[0]) print(name[1]) print(name[2]) #切片 左闭右开 print(name[0:2]) #吕梁 print(name[2:4]) #市柳 print(name[2:-1]) #市柳林 print(name[2:]) #市柳林县 print(name[:]) #吕梁市柳林县3.2.list
有序可变的容器。元素可以是多种不同的数据类型。
功能:追加、插入、删除【remove、pop】、切片。
data_list = [1, 2, 3, "北京", 5] #追加 data_list.append(34) for item in data_list: print(item) print("=============") #插入 data_list.insert(2, "上海") #删除【值】:元素不存在则报错; data_list.remove(2) #删除[索引位置] data_list.pop(1) #清空列表 # data_list.clear() #切片 for item in data_list[1:3]: print(item) data_list = [1, 2, 3, "北京", 5, ["山西", 45], 34] v1,v2 = [1,2]3.3.元组
有序且不可变的容器,元素可以是多种不同的数据类型。元组的元素也不能被替换成其他的值。
元组元素不可以被替换,元素个数也不允许修改
易错点:
v1 = (11,22) #正确 元组 v2 = (111,222,) #正确 元组 v3 = (666) #v3 = 666,并非元组 v4 = (666,) #正确 只有一个元素 # v11 等价于 v12 v11 = ((1),(2),(3)) #元组 元素为数字 v12 = (1,2,3) #元组 元素为数字 v13 = ((1,),(2,),(3,)) #元组元素为元组 v3,v4 = (11,22)如果元组中只有一个元素,如果尾部没有逗号则其非元组,而是去除括号后的那个值
公共功能:长度、索引、切片。由于其不可变集合特性导致无法添加、删除等操作。
3.4.字典
无序、键不能重复且元素只能是键值对的可变容器。
kv ={"name":"张三","age":34} print(kv.get("name")) #kv.keys() 高仿的列表 for item in kv.keys(): print(item) for item in kv.values(): print(item) for item in kv.items(): print(item) # kv 形式的类型,等价于Java理解 print("============") for k,v in kv.items(): print(k,v) # 键不存在则删除报错 del kv["age"]字典中键必须可hash,其中list、dict、set三种数据类型不可hash。
3.5.集合set
无序、可变、元素必须是可hash且元素不可重复的容器【不常用】。
#无序,所以没有索引、切片等操作 s1 = {1,31,4,5} #可变 s1.add(454) #直接覆盖原元素 s1.add(4) #删除 元素不存在,删除不会报错 v2.discard(1) #定义空集合 v1 = {1,2,3,4,5} v2 = {11,2,31,14,5} #交集1 v3 = v1.intersection(v2) print(v3) #交集2 print(v1 & v2) #并集 print(v1.union(v2)) print(v1 | v2) #差集 print(v1.difference(v2))使用场景:不希望重复的一个数据集合。
3.6.容器之间的转换
数组、元组、集合set之间可以互相转换,原则:想转化为谁就让谁的英文名字包裹一下。
v1 = [11,22,3,44,3] #数组转化为元组 print(tuple(v1)) #自动去重 print(set(v1))4.作用域
#注意与Java作用域的区别 if 1 == 1: data = "作用域" print(data) # 条件成立,内存存在变量data,可以在任何地方获取到该变量 if 1 == 2: data1 = "作用域" print(data1) # 报错。 条件不成立,内存不存在变量data15.range函数
协助生成一个数字列表。
v1 = range(5) for item in v1: print(item) v2 = range(5,10) # v2 = range(5,10,2) # 步长 v2 = range(5,0,-1) # 步长 -1 [5,4,3,2,1]6.文件操作
基于普通文本文件操作:打开文件、操作文件、关闭文件。
#wb模式: 只能写数据,如果文件不存在则创建文件,文件存在则清空文件并写入数据 #ab模式:只能写数据,如果文件不存在则创建文件,文件存在则追加数据 #r模式:open("file.txt",mode='r',encoding = 'utf-8') 指定编码格式则读取的数据自动编码为utf-8 #w模式:open("file.txt",mode='w',encoding = 'utf-8') 指定编码格式则写入时自动编码为utf-8 #b模式:open("file.txt",mode='a',encoding = 'utf-8') 指定编码格式则写入时自动追加内容编码为utf-8 file = open("file.txt",mode='wb') #加上换行符则追加内容,否则直接覆盖 file.write("this is 中文\n".encode("utf-8")) file.write("this is 英文\n".encode("utf-8")) file.close() file = open("file.txt",mode='rb') text = file.read() print(text.decode("utf-8")) #with上下文 编写文件操作的代码时,可以使用with上下文管理器,自动关闭文件 with open("file.txt",mode='rb') as file: text = file.read() print(text.decode("utf-8"))7.pip安装
安装目录:
安装Python会自带工具pip.exe。
pip install itsdangerous==2.2.0 #第三方包名 pip uninstall 第三方包名 pip list # 罗列第三方的包 # 将第三方包名 vs 版本号 写到文件requirements.txt中 pip freeze > requirements.txt【根目录下】requirements.txt的作用:pip install -r requirements.txt。批量将当前项目依赖的所有第三方包下载到本地。
第三方包网站
基于豆瓣源下载三方包:
一次性网站:
// 豆瓣源网址已经不能访问
pip install django -i https://pypi.douban.com/simple/ # 意味着每次都需要指定豆瓣源
永久选择豆瓣:
# /Users/zhfeng/.config/pip/pip.conf
pip config set global.index-url https://pypi.douban.com/simple/
pip install flask
7.1.源码安装
如果pip管理工具中没有对应的包就需要选择源码安装。
- 下载对应包的源码,并解压缩。
- 执行安装命令:进入解压后的解压包,存在setup.py文件。
- 编译:python3.9 setup.py build 。
- 安装:python3.9 setup.py install 。
7.2.wheel包安装
有些源码开发者,提前将代码打包成wheel包,使用者下载后无需编译直接安装即可。
首先pip支持wheel:pip install wheel。
以mysqlclient为例:官网下载其wheel包 Installing Packages - Python Packaging User Guide。
然后进入wheel目录,直接安装:
pip install mysqlclient.xxxx.whl
8.Async
本质:单线程运行程序。并不能提升运算速度,比较适合处理需要等待的任务。Async定义的函数返回的是一个协程对象(coroutine Object)。
async def _getname(): print("this is coroutine function") #返回的是coroutine对象,并不会运行函数体内的任何代码 corn = _getname() #RuntimeWarning: coroutine '_getname' was never awaited运行Async代码分为两步:进入Async模式即Event Loop;将coroutine变为task任务。
import asyncio async def _getname(): print("this is coroutine function") corn = _getname() # 有且仅有一种方式进入Async模式,即调用asyncio.run函数,参数类型为coroutine # 进入该模式执行的工作:创建一个Event Loop,将当前coroutine变为Event Loop中第一个task,并执行这个task asyncio.run(corn)多任务:以下代码执行耗时3秒
import asyncio import time async def say_after(delay,what): await asyncio.sleep(delay) print(what) async def main(): print(f"start at {time.strftime("%X")}") #await 当前任务释放线程的控制权 await say_after(1,"hello") await say_after(2,"world") print(f"end at {time.strftime("%X")}") # 第一步:main函数创建一个EventLoop(单线程循环),并执行main任务task # 第二步:遇到say_after函数后 释放当前task(main)执行权,将say_after作为task并执行该task # 第三步:遇到sleep函数后 释放当前task(say_after)执行权,将sleep作为task并执行该task # 第四步:sleep执行完毕释放线程执行权,say_after函数拿到执行权后 继续执行,依次类推... asyncio.run(main())线程控制权释放的方式:
- await
- 函数执行完主动释放。
import asyncio import time async def say_after(delay,what): await asyncio.sleep(delay) print(what) async def main(): print(f"start at {time.strftime("%X")}") #函数create_task的参数类型:coroutine #函数create_task将say_after注册到EventLoop上,但是不会执行task之say_after,此时执行的控制权尚在main任务中 task1 = asyncio.create_task(say_after(1,"hello")) task2 = asyncio.create_task(say_after(2, "world")) # 当await对象为coroutine时:将该函数包装为一个task任务,然后注册到EventLoop,并且通知EventLoop将线程使用权交出去运行 # 当执行asyncio.sleep等待时,因为此时EventLoop存在其他需要sleep的task,就会继续执行剩下的task await task1 await task2 print(f"end at {time.strftime("%X")} 一共cost 2秒") asyncio.run(main())等价于:
import asyncio import time async def say_after(delay,what): await asyncio.sleep(delay) return f"{what} - {delay}" async def main(): print(f"start at {time.strftime("%X")}") rnt = await asyncio.gather(say_after(1,"hello"),say_after(2,"world")) print(rnt) print(f"end at {time.strftime("%X")} 一共cost 2秒") asyncio.run(main())