[python Cookbook]阅读笔记

@toc]

前记:为了补充一下python语法知识,感谢网友的推荐阅读了pythonCookbook,这本书确实不错,以问题为导向,引导解决思路。
这个博文是从阅读笔记typora中直接复制过来的没有排版,仅作为记录!方便自己查询使用!书还没看完!持续更新!代码部分是直接使用IDLE运行的;

更新迭代记录

操作时间备注
阅读前八章2021/11/27 23:04:12Jucw
添加第九章/十一章2021/11/28 12:25:22Jucw
添加8.3/8.42021/11/29 23:50:26Jucw
添加9.1装饰器的内容2021/12/01 08:47:47Jucw

第二章 惰性匹配

2.1(. * ?)

  1. . 匹配任意除换行符外
  2. *匹配前一个字符出现0次或者无限次
  3. ?匹配前边字符的0次或者1次重复
  4. +或者*后面跟着?表示匹配0次或者1次出现,为非贪婪匹配,匹配最短

2.2字符串拼接

  1. 对于可迭代容器中的每个元素是字符串时候,使用join 进行字符串拼接

    parts = ['my', 'is', 'a', 'handsome', 'boy']
    t = ' '.join(parts)
    print(t)
    # 'my is a handsome boy'
    
    

    针对列表,元组,字典,文件,集合,生成器

    针对简单的直接拼接的时候,使用 + 进行拼接 ;

    +可以连接多个字符,之后拼接成完整的字符串


  1. 打印的时候使用字符进行分割

    a = 0
    b = 2
    c = 5
    print(a,b,c,sep=':') # 使用这种方法更好
    print(':'.join(a,b,c))
    
  2. 格式化文本

    # 
    import textwrap
    text = ""
    print(textwrap.fill(text,40,initial_indent='')) # 每40个为一行,最后使用空字符结尾
    
    

  1. 在字节串执行

    能在文本字符串上执行的操作都能在字节字符串上进行

    Byte String

    打印的时候将字节字符串转化为ascii码进行打印,这个时候就跟文本字符串一样

    print(bString.decode(‘ascii’))


第三章,数字,日期时间

3.1数据

3.11 浮点数取整(固定位数)

round(num, n) 进行四舍五入到指定小数点后面几位

执行之后的id 是不一样的,也就是在内存的位置是不一样的

1852106442928

id ©
1852106442928
id (d)
1852106441840
c==d
True
id ©==id(d)
False

当处于中间数的时候,取值是最接近的偶数

1.5=2 2.5=2

round(1.5)
2
round(2.5)
2


3.2 浮点数计算存在误差

这是CPU计算浮点数的特性

from decimal import Decimal

将浮点数转为字符串进行计算


3.3 二进制,十进制,八进行,十六进制

将一个整数转为二进制,八进制,十六进制

bin()

oct()

hex()

这一种转化会出现前缀,可以使用切片进行处理
如果使用不想出现前缀使用

format(a, ‘b’) # 二进制

format(a, ‘o’) # 八进制

format(a, ‘x’) # 十六进制

将字符串的形式不同进制转换为整数,需要使用 int 同时指定 当前字符串所代表的进制类型就可以转为整数

int(‘4b2’,16)

int(‘010101’,2)


3.4 复数

a.real

a.imag

a.conjugate()

对复数进行运算

import cmath

cmath.sin()

cmath.cos()

cmath.exp()

Python 的标准库默认是不会产生复数值,所以计算复数的时候使用cmath 或者 numpy 是可以对复数进型运算的

import cmath
a = 1-2j
a.real
1.0

a.imag
-2.0
a.conjugate()
(1+2j)
cmath.sin(a)


3.5 随机数

random 使用马特赛特旋转算法(梅森旋转算法)来计算随机数,这是一个确定性的算法。通过random.seed() 来修改 初始的种子值;

  1. 随机数选择

    import random

    random.choice() # 随机选择一个数

  2. 随机数生成

    随机采样n个数

    random.sample(a, N)

  3. 对元素进行原地打乱


3.6 时间换算

天数转为秒,小时转为分钟

datatime 可以实现不同的时间单位的换算

datadelta表示时间间隔

now = datatime.datatime

datatime.timedelta(days = 2, minutes = 20, seconds = 10) # 都要加上s 来表示时间单位,然后可以往前推导出时间

计算上周五的日期

上周五是几月几号

from datetime import datetime, timedelta
weeksday = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']



第四章 迭代器和生成器

4.1 访问元素

next() 进行迭代

items._iter_()

生成器只会在响应迭代操作时候才会运行

一旦生成器函数返回,迭代也就停止,如果执行for 语句的时候这些是不需要进行考虑的;


定义一个反向迭代

def __reversed__(self):
   n = 1
   while n < self.start:
        yield n
        n = n + 1

​ 迭代器和生成器是没法执行普通的切片操作

使用itertools.islice() 返回一个生成器,这是通过访问生成器然后丢弃掉开始索引之前的元素来实现切片操作

这里会消耗掉前面丢弃的数据,因为生成器是没法倒回去的,如果需要倒回去需要将生成器转为列表之后再进行操作

import itertools

跳过文件的注释行

from itertools import dropwhile

with open(“”) as f:
	for line in dropwhile(lambda line: line.startswith('#'), f)
    print(line, end=' ')
    

排列组合

iterations.permutations # 排列 考虑顺序

iterations.combinations # 组合 {a, b} 和 {b, a} 是一样的只会出现一次,不考虑顺序

iterations.combinations_with_replacement # 选择过之后的数字仍然可以在一次选择, {a, a, a} 相当于有放回的选择小球

迭代一个序列保存序列的下标

a = [1, 2, 3, 4, 5]
for idx, val in enumerate(a):
print(idx, val)

0 1
1 2
2 3
3 4
4 5

索引下标是从0开始的

同时迭代多个序列使用 zip

a = []

b = []

for x,y in zip(a,b):

​ 同时迭代a and b 这两个序列

​ print (x, y)

zip 的工作原理是创建出一个迭代器,该迭代器可以产生元组,(x ,y) 当其中某个序列没有元素可以进行迭代的时候,迭代过程结束;

如果要匹配最长迭代对象

import iterations.zip_longest

这个时候产生的是最长迭代队列,短的序列使用None来替代

zip 返回的是一个迭代器,必要时候需要将其转换为列表;


4.2 多个迭代对象

处理多个迭代对象,返回一个迭代器

  1. from iterations import chain

    from iterations import chain 
    a = [1, 1, 2]
    b = ['i', 'love', 'you']
    for i in chainm(a,b):
        print(i, end=' ')
        
    1 1 2 i love you
    

set = iteration()

inactive_items = set()


4.3 合并多个有序序列

  1. import heapq

import  heapq
a = [1,5,2]
d = [4,5,6]
b = [1,2,3]
for c in heapq.merge(a,b):
    print(c, end=' ')

print(end='\n')
for e in heapq.merge(d,b):
    print(e, end=' ')
    
1 1 2 3 5 2 
1 2 3 4 5 6 

如果序列不是有序的,合并之后还是不会对序列进行排序,这个使用对进行合并不会一次性进行读取,而是在合并过程中边读取边比较

主要是用在将两个有序的序列进行合并之后保证序列还是有序的

只是简单的检查每个序列的第一个元素,比较之后将第一个元素较小的发送出去,之后再从新的序列读取下一个元素,重复操作直到元素读取结束


第五章 文件和IO

5.1 读写文本数据

换行符: \r\n 和 \n 这是 UNIX 和 Window 之间的区别

输出进行重定向 也就是将读取的内容重新写入到新的文件中,

with open(“…txt”, ‘’wt’) as f:

使用 print(“text”, file = f) # 只要是确保文件是使用文本格式打开的就行,如果是使用二进制打开可能会打印失败!

以不同的分割符打印数据

print(, seq = ‘;’, end=‘!!\n’) # 读取的内容使用; 进行分割,最后结尾部分使用!!还有换行进行输出

检查文件是否已经存在

import os
if not os.path.exists(''):
    with open ('', '') as f: ##使用xb 模式进行打开就不用判读, 将会直接进行覆盖
        f.read()
    else:
        print("File is exitst!!")

5.2 处理路径名

os.path.basename() # 获取最后的文件名称

os.path.dirname() #获取路径名

os.path.join(‘’,‘’,os.path.basename(path)) # 将多个字符串组装成新的路径

5.3 将对象转为字节流

import pickle

data = …

with open(‘’, ‘’) as f:

pickle.dump(data, f)

在字节流中重新创建出对象

pickle.load() 这是在文件传输过程中需要进行序列化的一种方式。这样比较高效的进行文件传输;


第六章数据编码与处理

6.1 读写CSV数据

写入数据到csv文件中

head = []

rows = [(),()]

with open(‘’, ‘’) as f:

f_csv = csv.writer(f):

f_csv.writerow(head)

f_csv.write
rows(rows)

数据是字典,也就是使用列表存储字典,之后将字典的对应的值映射到表格中

headers = []

rows = [{}{}]

with open() as f:

f_csv = csv.DictWriter(f, headers) # 将表头和文件进行建立联系

f_csv.writeheader() # 先将表头写入到表格中

f_csv.writerows(rows) # 将每行对应数据写入到表格中

6.2 读取JSON数据

json.dumps()

json.loads()

数据是字典的格式

使用json.dumps(data)

将数据dumps 到 json 文件中去

读取json文件

读取的网页信息使用功pprint 进行打印,可以更好的展示结果

这个过程使用的是json 会将信息以字典或者列表的形式进行存储


6.3 B64编码和解码

import base64.b64encode()

import base64.B64decode()

面向字节的编码

字节串和字节数组

编码之后输出字节串 之后可以转换为decode(‘ascii’)


第七章 函数

7.1 接受任意类型的函数

def avg(fist, *rest):
    return (first + sum(rest))/(1+len(rest))
# rest 可以是多个数据
>>> def avg(first, *rest):
	return (first + sum(rest))/(1+len(rest))

>>> c = avg(1,2,3,4,5,6)
>>> c
3.5 = 21/6

rest 作为一个元组传来,代码将其作为一个序列进行处理

*rest 和 ** kwargs
前者传递位置参数(元组)
后者是传递关键字参数(字典)
size = 'large', quantity = 6 # 这里是传递一个字典
(1, 2, 3) # 这里是传递一个位置参数,这是一个元组

注意: * 打头的只能作为最后一个位置参数出现,以 ** 打头的只能作为最后一个参数出现

也就是说以 * 打头之后的参数只能是关键字参数


7.2 函数返回多个值

只要简单的返回一个元组,就可以实现函数返回多个值


7.3 定义匿名函数或内联函数

add = lambda x, y: x+y # 将x, y 直接连接起来

>>> x = 10
>>> b = lambda y:x+y
>>> x = 20
>>> c = lambda y:x+y
>>> b()10
SyntaxError: invalid syntax
>>> b(10) # 这里执行的时候x是20
30
>>> c(10) # 这里执行的时候x也是20
30

lambda 中的变量是在执行的是后进行绑定,也就是说执行是变量时多少就是多少,而不是定义的时候的值


第八章类与对象

8.1 修改实例字符串表示

通过定义_repr_()

_str_()方法实现

_repr_()返回的是实例的代码表示,通常可以用他返回的字符串文本来重新创建这个实例,内建的repr()函数可以用来返回这个字符串,_str_()将实例转为字符串,这就是使用print() 和 str() 这两个方法产生的效果,

p = Pair(3,4) # _repr_() output 输出的时候使用!r 表示使用特殊的格式化代码输出

print§ # _str_()

8.2 对象支持上下文管理

with 要实现_enter_() and _exit_()函数

如果_enter_()有返回值的话,被放置在使用as作为限定下


8.3 装饰器

@property
类外直接调用属性变量

>>> class good():
	@property
	def size(self):
		return 100
>>> obj = good()
>>> obj.size
100
>>> obj.size()
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    obj.size()
TypeError: 'int' object is not callable



>>> class good():
	@property
	def price(self):
		print("@price!")
	@price.setter
	def price(self, value):
		print("@price.setter!")
	@price.deleter
	def price(self):
		print("@price.deleter!")

		
>>> obf = good()
>>> obf.price
@price!
>>> obf.price = 123 # 可以进行修改属性值
@price.setter!
>>> del obf.price # 删除属性值
@price.deleter!
>>> 

8.4 深拷贝和浅拷贝

copy.copy() #
copy.deepcopy() # 深拷贝 直接复制一份地址不同

>>> a = [11, 22]
>>> import copy
>>> b = copy.copy(a)
>>> id(a)
2654535014080
>>> id(b)
2654503979648
>>> c = copy.deepcopy(a)
>>> id(c)
2654533146624
>>> e = a
>>> id(e)
2654535014080
>>> a.append(33)
>>> b
[11, 22]
>>> c
[11, 22]
>>> e
[11, 22, 33]


copy.copy() 和 copy.deepcopy() 都是直接复制一份

第九章 元编程

9.1 装饰器

定义一个装饰器:装饰器就是一个函数,接受一个函数作为输入并返回一个新的函数作为输出

from functools import wraps
def time():
	@wraps
    def wrapper():
        print(start-end)
        
        
@time # 使用什么定义的装饰器来作为自己的时间计算
def count():
# output: 输入@time 内中函数内容

装饰器的代码一般会涉及创建一个新的函数,利用*args 和 ** kwargs 来接受任意的参数;在这个函数内部需要调用原来的那个函数,也就是被包装的那个函数,它是装饰器的输入函数,这个新创建的wraps()函数会 作为装饰器的结果返回,取代原来的函数;

def set_fun(fun):
    def call_fun():
        print("quanxina1")
        fun()
    return call_fun


@set_fun
def test():
    print("----test----")

#ret = set_fun(test) 如果在test()前不添加@ 可以 使用这种方式,一样可以实现装饰器的作用,调用的原理是,先进入到闭包的外部函数,执行内部函数的定义,返回值调用内部函数,这个时候根据传进来的参数执行内部函数地址空间的信息;

test()

注解:这里是添加装饰器实现不修改原理函数从而添加新的需求功能
这里的装饰器是通过闭包调用的功能来实现,闭包的定义是外部函数返回内部函数,首先外部函数先进行定义内部函数并不执行内部函数,在返回值直接返回内部函数,这个时候才是调用内部函数,执行的流程是通过返回值调用内部函数,这个过程可以在内部函数先定义需要添加的功能, 之后在进行调用原来的旧的函数,这样就能实现增加新的功能而不修改原来的函数
使用是通过在原来函数前@闭包函数是实现,

对于装饰器这一章节还需要多学习

9.2 解析并分析python 源代码

编写一些程序来解析Python 源代码并对此进行一些分析工作

import ast 将python 编译为一个抽象语法树

ast.parse()

>>> import ast
>>> e = ast.parse('6+2')
>>> e
<_ast.Module object at 0x000001CBBD850CD0>
>>> ast.dump(e)
'Module(body=[Expr(value=BinOp(left=Constant(value=6, kind=None), op=Add(), right=Constant(value=2, kind=None)))], type_ignores=[])'

抽象语法树分析Python源码

知识博客地址:

第十一章 网络和Web编程

11.1 与网络进行交互

###  get func

from urllib import request, parse

url = ‘’

parms = {‘’:’’, ‘’:“”,}

u = request.urlopen(url)

response = u.read().decode(ascii)


## post func
将参数编码后作为可选参数传递gei URLopen(url, parms)
response = r.read()

需要重新看的章节部分

2.19这一章还没看

5.19/5.20这一章需要重新看

6.12 Struct 复习


time: 2021-11-27

posted @ 2022-05-02 19:40  jucw  阅读(48)  评论(0编辑  收藏  举报