python进阶
属性
在一个对象中,属性是用来表示对象的重要指标,方法是一系列的功能。如下表格(引自3wschool)
对象 | 属性 | 方法 |
---|---|---|
car.name=porsche car.model = 911 car.length=4499mm car.color = white |
car.start() car.drive() car.brake() car.stop() |
__dict__
该属性字典形式存放了类里所有self.*类型的东西
1 | class man(): |
-
第一个是只返回了已经创建的对象的属性,cls这个全局属性没有被返回
-
第二个是返回一个类的所有属性
方法
__getattribute__
这个方法是访问对象属性后进行拦截,每次访问后都会执行该方法里的内容
- 需要注意访问对象属性会让该方法陷入死循环,所以方法返回值要禁用self
- 例如以下一个错误用法
1 | class man(): |
- 使用super().__getattribute__(attr)返回访问到的属性
1 | class man(): |
__getattr__
方法的作用是当__getattribute__抛出异常时执行
1 | class man(): |
返回值的None是来自print的输出
只要__getattribute__抛出异常则该方法就有效
__setattr__
试图给属性赋值时自动调用该方法
1 | class man(): |
如果不加self.__dict__[attr]=velue则属性将无法被赋值
不能使用self.attr=velue,会造成无限循环
raise
当程序出错python会自动抛出异常,也可以通过raise人为地引发异常,raise后面的语句将不能执行
字符串
format格式化
1 | print("{0:.4f}{1:>10.2%}".format(10/3,20)) |
保留4位小数,>是右对齐10.2%表示输出宽度是10保留2位百分比小数
1 | print("{0:.}{0:#x}{0:#o}".format(1111)) |
在千分位插入.,格式化成十六进制,格式化成八进制
统计
1 | text.rindex(*) #最后一个出现位置 |
1 | text.replace(*,*) #替换 |
1 | table="".maketrans('123','一二三') #制作替换表 |
1 | text.ljust(10) #居左长度10 |
常见方法
获得列表最后一个
1 | a = [1,2,3] |
split
分隔字符串rsplit从右往左
1 | a = "123" |
以2作为分隔标注
strip
去掉首尾特定字符串
1 | a = "11231" |
restrip
去掉尾部特定字符串
1 | a = "112311" |
isdigit
判断字串是否为纯数字
1 | a = "112311" |
find
字符串查找,返回的是索引,没有返回-1
1 | a = "112311" |
join
将符号加在每一个字符串后面
1 | a = "123" |
lower
转换为小写
1 | a = "ABC" |
upper
capitalize
title
swapcase
lambda
lambda函数是匿名函数,在单行下编写(不能多行)
lambda agument:expression
传入参数,返回的是表达式计算的结果。
1 | sum=lambda y,x:x+y |
下面返回多个值
1 | sum=lambda y,x:(x+y,x*y) |
lambda函数通常和其他函数并用。
生成列表
1 | l = [i*2 for i in range(5)] |
生成列表的作用是取一个循环i作为参数,对参数进行表达式运算再生成一个列表
单行分支
1 | l = [i if i%2==0 else None for i in range(5)] |
处理1 if 条件 else 处理2:如果满足条件进行处理1,否则进行处理2
Json数据
json是一种通用数据,众多语言中都有,长得字典,但是他是字符串
loads&load方法
想要使用json数据就要先转换为字典
1 | import json |
打印出来的时字典格式了
load是针对文件进行格式转化的
dumps&dump
将字典转化为json
1 | import json |
同理dump是转化文件的,带s都和字符串有关
高阶函数
1 | def funa(n,fun): |
高阶函数使用非常绕,遇到复杂的问题需要分析很久,尽量避免。
map
对列表每一个数执行函数的运算,map返回的是iterators而不是list,需要转成list能直接输出
1 | l1=[1,2,3] |
下面转化为list
1 | l1=[1,2,3] |
zip
合并列表
1 | l1=[1,2,3] |
可以不用list转化,直接用for循环
filter
根据函数进行过滤
1 | l1=[1,2,3] |
对列表进行了过滤,只返回了偶数
reduce
需要from functools import reduce
对列表进行累加
1 | from functools import reduce |
enumerate
添加标注
1 | l1=[1,2,3] |
代表从0开始进行标注。
偏函数
偏函数就是函数的辅助,将一个函数生成一个新函数。
1 | a = int("0x67",base=16) #将16进制转成10进制 |
在生成新函数的同时,函数的最后一个参数被赋值,在新参数里只需要对前面的参数赋值即可
1 | from functools import partial |
上面的输出结果可以看出,偏函数可以给任意参数赋值生成新函数。但是偏函数的第一个参数一定是那个函数名
闭包
在一个函数中有一个子函数,retrun 子函数名 在外面接收的子函数名可以当一个函数使用
1 | def test(num): |
函数嵌套,返回处理值
1 | def fun_1(): |
也可以循环嵌套函数
1 | def fun_1(): |
装饰器
-
作用:在执行一个函数之前先进行装饰处理
-
原理:装饰函数将函数作为参数传入了,只是将他在外面套了一层
1
2
3
4
5
def 另一个函数名
原理同下:
另一个函数名 = 函数名(另一个函数名)1
2
3
4
5def dec(fun):
def dec_in():
print("this is dec")
fun()
return dec_in参数fun是要被装饰的函数,在装饰函数需要第二层进行返回,返回的函数不能带括号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def fun_a(a):
print("装饰器")
def fun_c():
a()
return fun_c
def fun_b():
print("1")
fun_b() #其实是fun_a(func_b)()
>>>
装饰器
1还有一种写法,可以简单理解
1
2
3
4
5
6
7
8
9
10
11
12
13def fun_a(a):
print("装饰器")
return a
def fun_b():
print("1")
fun_b() #其实是fun_a(func_b)()
>>>
装饰器
1里面的a就是fun_b
多装饰器
1 |
|
装饰器只能装饰函数,所以2先装饰函数3
被装饰函数带参装饰器
带参装饰器返回值装饰器==>通用装饰器
1 | def dec(func): |
这里的带参数是指的函数带参数,上面有个直接返回的例子,里面没有嵌套函数无法使用带参数的函数
1 | def fun_a(fun_a): |
看起来还是挺易懂的。
装饰器带参
在外面多定义一层专门用来用来处理装饰器的参数,比较麻烦
1 | def fun_a(*d): #*d是收到的装饰器的参数 |
字符串对比
set()
set函数可以将字符串转化成set形式,可以使用遍历的形式进行单个输出,并且它会对列表里重复的进行去重
1 | a = "123" |
&交集
求出两个都有的
1 | a = "123" |
|并集
求出两个的和
1 | a = "123" |
-差集
前面一个减去后面的,后面的一个都不留,只留下前面没重复的
1 | a = "123" |
^对称差集
前面一个减去后面的,留下前后没有重复的
1 | a = "123" |
排序
sort方法的另一种方式,key=abs设置绝对值,reverse=True倒排
1 | a = "123" |
collections
collections是python内建的一个模块,主要和数据类型有关
namedtuple
定义一个可以通过属性来访问的tuple数据结构
1 | from collections import namedtuple as nt #导入模块 |
tp = nt(“tp”,[“a”,“b”])第一个tp是一个句柄,用来后面赋值所用,第二个tp是结构标志,当使用print(t)时可以看到tp(a=‘1’, b=‘2’)
OrderedDict
有序字典,普通字典是无序的,ordereddict作用是记住key里面值的添加顺序。从下面代码我们可以看到遍历输出的是key
1 | dic = {"a":1,"b":2,"c":3} |
实例展示:
无,python3中已将没有这个症状了
Counter
统计次数生成一个字典形式
1 | from collections import Counter as ct |
可以看到吧字符作为key,次数是key值
depue
队列和栈,实现双向增删
1 | from collections import deque as dq |
序列化和反序列化
Pickle
python中一切皆对象,对象就是一小块内存的数据,而将这些数据写入硬盘或传输需要进行序列化或反序列化
广泛的应用在分布式、并行系统上。
序列化:将对象转化成“串行化”数据形式,存储到硬盘或通过网络传输到其他地方。pickle.dump(obj,f),obj是要被序列化的对象,f是要保存到的文件
1 | import pickle |
反序列化:是指相反的过程,将读取到的“串行化数据”转化成对象。Python中使用 pickle 模块中的函数,实现序列化和反序列操作。pickle.load(f),f是一个被序列化的一个文件
1 | import pickle |
shelve
相当于一个小型的数据库,它可以保存python所支持的数据类型(以字典形式)
1 | import shelve |
查看文件的方法
1 | import shelve |
深拷贝
模块重导入
需要使用imp模块,应用场景是:如果模块在执行中会被改变,那么需要重新导入这模块才能改变作用。
1 | import sys |
深拷贝
平时使用的拷贝都是浅拷贝:仅仅在地址上打一个新标签,当原地址的东西改变后拷贝的也跟着改变,深拷贝:单独使用一个空间拷贝进去,不随原地址改变而改变
对于不可变类型(数值,字符串,元组):
深拷贝,浅拷贝,等号赋值的所有的id结果都一样
1 | import copy |
对于可变类型(列表和字典):
1 | import copy |
我们可以看到c和d的id已经被改变,下面看一些原地址内容改变的情况。
简单的单层对象改变
1 | import copy |
多层对象改变
1 | import copy |
对比发现,浅拷贝只能拷贝一层,深拷贝多层
迭代器&生成器
迭代器:一个可以按顺序访问的对象,只能往前访问无法往后访问(list不是可迭代对象)
1 | a = (i for i in range(10)) #生成一个可迭代对象,他不是元组类型 |
可以看到可迭代对象是单独生成的,它是边生成边调用,不像list浪费内存。可以使用for
使用**iter()**可以创建迭代对象
生成器:从本质上讲生成器就是一个迭代器,每次遇到yield函数都会保存信息返回yield的值,下一次继续从这个位置开始
1 | def gen(): |
这必有一个报错,报错类型是StopIteration,迭代终止,所以使用错误处理。
1 | def gen(): |
创建完对象后,首先需要进行next处理(必须进行这一步),后面才能对值进行传输,最后一个2是print(g.send(i))打印的。
shell命令
check_output
可以在windows或者linux中执行系统命令,方式都是一样的命令不同
1 | import subprocess |
输出的是二进制,想要能看懂必须进行编码。
getoutput
1 | import subprocess |
getstatusoutput
返回元组,可以调用结果
1 | import subprocess |
多线程
threading
多线程需要导入threading模块,可以同时对一个函数进行多次执行。
1 | import threading |
上面的输出每次都不一样,因为线程结束不一样。
1 | import threading |
上面试带参数多线程调用
资源竞争及解决方案
1 | """再用到多线程时,往往会出现资源竞争的情况""" |
按照常理来说应该输出100000,和200000的但是到后面就乱了,这是由于俩个对全局变量的竞争导致的。
使用互斥锁解决
1 | import threading |
互斥锁的原理是,上锁后全局变量只提供这个函数使用,在多次循环中不至于两个函数互挣。
多进程
multiprocessing
使用方法和多线程同理,不过他是创建多个应用程序运行。
1 | import multiprocessing |
Queue队列
这个队列是用来共享数据的,同样是multiprocessing模块,队列就是先进先出
1 | import multiprocessing |
进程池
进程池可以对进程进行批量创建,并且统一管理。用到mutiprocessing的Pool
1 | from multiprocessing import Pool |
进程池有容量设定,如果设定2个,不管多少个任务同时开的进程只有两个,一个任务完成再让下一个任务进入池中。
-5~256定理
-5到256包括-5和256。这个区域被称为小整数池,他是原本就存在内存中的,使用id查看都是一样的。当使用交互式的时候这个区域的数字都是一个地址
1 | >>> b=-5 |
有时候会遇到这种,也不要感觉惊讶,因为这是一个定理。
进制转换
二进制
1 | print(bin(10)) #将十进制转成二进制 |
0b是二进制的标志
1 | print(int(0b1010)) #将二进制转成十进制 |
八进制
1 | print(oct(10)) #将十进制转成八进制 |
0o是八进制的标志
1 | print(int(0o12)) #将八进制转成十进制 |
十六进制
1 | print(hex(10)) #将十进制转成十六进制 |
0x是十六进制标志
1 | print(int(0xa)) #将十六进制转成十进制 |
字符串
使用chr可以将二到十六进制转成字符串
1 | print(chr(0b1)) |
但是每个都有上限
二进制表示上限:0b100010000000000000000
八进制表示上限:0o4200000
十六进制表示上限:0x110000
将字符串转为十进制ASCII码
1 | print(ord("")) |
一次只能够转化一个字符串,之后还可将十进制转成其他进制
其他转换
网页的十六进制编码\xc9\xc1\xd2\xd5\xbb\xa5\xb6\xaf 是这种形式的
1 | str = "\xc9\xc1\xd2\xd5\xbb\xa5\xb6\xaf" |
可以直接使用输出
正则表达式
这则表达式是一种匹配一类型语句的表达式,可以进行查找修改替换。原子是是表达式的基本组成单位
普通字符作为原子
1 | import re |
通用字符作为原子
1 | import re |
\w | 字母,数字,下划线 |
---|---|
\W | 非字母,数字,下划线 |
\d | 十进制数字 |
\D | 非十进制数字 |
\s | 空白字符 |
\S | 非空白字符 |
非打印字符作为原子
1 | import re |
\n | 换行符 |
---|---|
\t | 制表符 |
原子表
. | 除换行为任意一个字符 |
---|---|
^ | 开始位置 |
$ | 结束位置 |
* | 任意次 |
+ | 1次或多次 |
? | 0或1次 |
{n} | n次 |
{n,m} | n-m次 |
| | 或 |
() | 模式单元 |
1 | import re |
模式修正符
I | 匹配时忽略大小写 |
---|---|
M | 多行匹配 |
L | 本地化识别匹配 |
U | unicode |
S | 匹配包括换行符* |
1 | import re |
贪婪模式
尽可能多跨度的进行匹配特定内容
1 | import re |
懒惰模式
尽可能少跨度的进行匹配特定内容
1 | import re |
sys
argv
实现外部向程序传入参数,其中第一个参数为文件本身。
1 | import sys |
输出的形式是list,可以使用for循环进行遍历。
exit
退出程序0表示正常退出,可以定义退出提示
1 | import sys |
提示抛出到values,打印values。
platform
打印当前运行的平台(win32,Linux)
1 | import sys |
modules
返回程序导入的所有模块
1 | import sys |
tempfile
属于内置模块用于创建临时文件和目录,当程序运行结束会自动删除文件和目录。
临时文件
临时是创建在寄存器里的,在普通的目录文件中无法找到,使用是必须使用seek改变指针
1 | from tempfile import TemporaryFile |
这个文件和普通文件一样可以使用普通文件语法例如:readline
创建临时文件
创建的临时文件夹在该语句结束之前可以找到路径,一旦语句结束文件夹立刻消失、
1 | from tempfile import TemporaryDirectory |
当输入一个任意字符串后该目录立刻消失,就算里面放进去东西也一起消失.。
Os
os模块是对系统操作的模块,属于python内置库
getcwd()
得到当前路径
1 | import os |
listdir()
列出当前目录的所有东西
1 | import os |
chdir()
改变当前的工作路径
1 | import os |
path
使用join进行路径连接
1 | import os |
使用isdir判断是否是文件夹
1 | import os |
使用exists判断是否存在
1 | import os |
access
用来判断是否存在这个路径,并且可以根据传入的参数进行判断
1 | import os |
os.access(path,mode),mode还有几个参数:
- os.F_OK,是否存在
- os.R_OK,是否可读
- os.W_OK,是否可写
- os.X_OK,是否可执行
scandir
不带路径返回一个当前目录的迭代对象,需要使用到for循环输出。
1 | import os |
除了获得name属性还有其他一些
-
name 获得名字
-
path 获得绝对路径
-
is_dir 是否为文件夹
-
.stat() 文件信息
st_size 大小
st_atime 最近访问时间
st_mtime 最近修改时间
st_ctime windows系统文件创建时间
st_birthtime linux系统文件创建时间
walk
遍历路径,输出一个元组,有三个返回参数,分别是路径,目录名,文件名
1 | import os |
文件夹
mkdir可以在系统中创建文件夹,makedirs可以进行创建递归文件夹。
1 | import os |
removedirs删除指定目录的文件夹基本上被忽略,因为他只能删除空文件夹。
文件
remove(path)删除指定路径的文件。
rename(src,dst)重命名文件
操作文件不建议使用,os.open
1 | # 打开文件 |
shutil
copy
复制文件
1 | import shutil |
copytree
复制文件夹
1 | import shutil |
move
移动文件/文件夹
使用方法和上面的一样
shutil.move(“src”,“dst”)