Python02进阶应用
数据结构-基于列表list
可变与不可变:列表是可变的,这是他区别于字符串和元组最重要的特点
方法 | 描述 |
---|---|
list.append(x) | 把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。 |
list.extend(L) | 通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。 |
list.insert(i, x) | 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。 |
list.remove(x) | 删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。 |
list.pop([i]) | 从列表的指定位置移除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被移除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。) |
list.clear() | 移除列表中的所有项,等于del a[:]。 |
list.index(x) | 返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。 |
list.count(x) | 返回 x 在列表中出现的次数。 |
list.sort() | 对列表中的元素进行排序。 |
list.reverse() | 倒排列表中的元素。 |
list.copy() | 返回列表的浅复制,等于a[:]。 |
堆栈
列表可以当作一个堆栈使用,先进后出,使用append()将元素添加到栈顶,pop()将元素从栈顶释放出来
print()
stack =[1,2,3]
x=10
while x>=5:
stack.append(x)
x-=1
print(stack)
#[1, 2, 3, 10, 9, 8, 7, 6, 5]
stack =[1,2,3]
while len(stack)>0:
print(stack.pop(),end= ' ')
print(stack,45)
#3 2 1 [] 45
队列
列表可以充当队列,先进先出,但是效率不高,从后向前出快(元素不需要移动位置),从前向后出慢(需要每个元素进行移动位置)
#!usr/bin/python3
from collections import deque
stack =[1,2,3]
queue2=deque(stack)
print(queue2.pop(),queue2.popleft())
#pop在这里是队列出队函数,从头开始,则popleft就是从后往前出队
列表推导式
通过已有的序列操作的结果生成一个全新子序列元素,或者根据判定条件创建子序列
#!/usr/bin/python3
print()
stack1=[1,2,3,4]
stack2=[5,6,7,8]
stack3=[stack1[i]+stack2[i] for i in range(len(stack1))]
print(stack3)
#[6, 8, 10, 12]
stack3=[x*y for x in stack1 for y in stack2]
print(stack3)
#[5, 6, 7, 8, 10, 12, 14, 16, 15, 18, 21, 24, 20, 24, 28, 32]
#列表推导式支持复杂的函数以及表达式
嵌套列表
给我感觉像二维数组,在部分用法上
#多个列表嵌套在一起就成为一个,类似二维数组的东西
stack = [ [1,2,3,4]
,[5,6,7,8,9]]
print([[row[i] for row in stack] for i in range(4)])
#9是多出来的,所以这里range()一旦修改为5,9是没有对应的,程序会报错
del
#del是依照列表中索引来删除一个元素,与pop不同,del属于切割一个下来或者直接清空所有数据
del a[:]#删除所有a列表数据
del a#直接删除实体变量
数据结构-基于集合set
#创建空集合使用set()
#同样支持推导式
#不支持重复元素
set01=set('1122335544dbhjfdkljkhghnknnkfsad')
print(set01)
#{'5', 'g', 'l', 'b', '1', '3', 'd', 'h', 'n', 'f', 's', '4', 'j', 'k', 'a', '2'}
数据结构-基于字典dictionary
dict01=dict(a=4,4=55,6=io)#字典是通过关键字索引的索引键值对的键应该是字符串,这里就不行默认为数字了
dict01=dict(op=1,kl=5)
print(dict01)
数据结构-遍历列表、字典等序列
#字典遍历中键值对可以同时解读
dictionary01={'45':4,'kl':45,'kll':'jj'}
for x,y in dictionary01.items():
print(x,':',y,end=',')
#45 : 4,kl : 45,kll : jj,
#对于列表,位置和存储字段同样可以进行解读
stack2=[5,6,7,8]
for x,y in enumerate(stack2):
print(x,y)#使用enumerate函数传入序列,然后循环读取
#同样支持多序列遍历查询
print()
stack2=['prien','jjj','shhh']
stack3=['shan','jkj','4545']
for x,y in zip(stack2,stack3):
print('{0} is {1}'.format(x,y))
#prien is shan
#jjj is jkj
#shhh is 4545
for x in reversed(stack3):
print(x)#reversed反向遍历序列 指定序列传递参数
#4545
#jkj
#shan
深浅拷贝
#
python输入与输出
python有多种输出值的方式,表达式语句、print函数以及使用文件对象的write()方法(标砖输出文件可以使用sys.stdout)
输出格式美化
#字符串输出
str()#返回一个用户已读表现形式
repr()
#产生一个解释器易读的表达形式,带字符串前后带'或者",可以转义字符串中的特殊字符----直接输出,同步支持传入任何对象
str2="test str and repr \n"
print(str(str2)) #test str and repr
print(repr(str2))#'test str and repr \n'
#rjust(width,str)函数 返回一个字符串使之右对齐同时使用字符str填充至长度为width个单位的新字符串,如果windth单位小于源字符串长度则返回源字符串
#str须得是单个字符,否则报错
#--源字符串长度4,width长度为3,则返回源字符串,同时不填充也不追加后续内容
#str.rjust()
str1='20'
str2='test str and repr'
print(str2.rjust(5,'*'))#test str and repr,长度不够返回源字符串
print(str2.rjust(20,'*'))#***test str and repr,长度超过进行填充
print(str2)
#填充0的zfill(width) 长度不够width,就拿0来凑数补充
#print('{0:8} ==> {1:20}'.format('123','456'))
print('{0:8} ==> {1:20} {2}'.format('123','456','789'))
#123 ==> 456 789
颜色格式
#print()支持修改输出颜色且同时高亮显示
输入
#键盘输入
str = input("input here:")
文件
模式权限
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
with输出文件
str2="C:\\Users\\32793\\Desktop\\open.txt"
with open(str2,"a+") as file02:
print("\n test05",file=file02)#这也是输出文件的一种方式
file02.write('45454545')#这也是输出文件的一种方式
file1=open("C:\\Users\\32793\\Desktop\\open.txt", "a+")
file1.write("明天更好的你")#这也是输出文件的一种方式
print("\n test05",file=file02)#这也是输出文件的一种方式
file1.flush()
file1.close()
file文件标识符用法
#读写文件
#open(文件名,打开文件模式)
#open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
#路径、文件模式、缓冲、编码、报错等级、区分换行符、传入文件参数类型、自定义开启器
file1=open("C:\\Users\\32793\\Desktop\\open.txt", "r+")#是转义字符所以需要注意\\
file1.write("55qw")
file1.close()#每个文件打开处理完后都要进行关闭
#file.flush() 缓冲区刷新,将缓冲区数据立刻写入文件,同时清空缓冲区,不需要你被动等待输出缓冲区写入。
#一般情况下文件close后会自动刷新缓冲区,但有些时候需要在关闭前进行刷新操作,所以需要先执行file.flush()然后在file.close()
file1=open("C:\\Users\\32793\\Desktop\\open.txt", "r+")#是转义字符所以需要注意\\
file1.write("shdjk")
file1.write("55qw")
file1.flush()
file1.close()#每个文件打开处理完后都要进行关闭
#file.write() 写入文件函数,返回的是写入字符串的长度
#file.isatty() 如果当前文件连接到另外一个设备,会返回true,否则返回false
#file.readline(number) 读取整行number指定行数,包括\n字符
#file.readlines(number) 返回文件的列表包括所有行
file2 = open("C:\\Users\\32793\\Desktop\\open2.txt", "r")
print(file2.readlines())
file2.flush()
#file.tell()返回文件当前指针位置,目前测试时文件结尾位置
file1=open("C:\\Users\\32793\\Desktop\\open.txt", "r+")
file1.write("fuck456789\n45")
print(file1.tell())
file1.close()
#a更加方便
class insert:
@classmethod
def insert(self):
file02=open(self.file01,'a+')#文件指针直接指向文件末尾
file02.write(self.string)
file02.flush()
file02.close()
@classmethod
def __init__(self,file01,string):
self.file01 = file01
self.string = string
# return self.file01
insert1 = insert("C:\\Users\\32793\\Desktop\\open.txt","sssssss")
insert1.insert()
python3的OS模块
主要针对Python操作系统(OS)相关的部分
#os.access(检验文件路径,检测指标)
import os
result1=os.access("C:\\Users\\32793\\Desktop\\open2.txt",os.W_OK)
result2=os.access("C:\\Users\\32793\\Desktop\\open2.txt",os.F_OK)
result3=os.access("C:\\Users\\32793\\Desktop\\open2.txt",os.X_OK)
print(result1,result2,result3,os.access("C:\\Users\\32793\\Desktop\\open2.txt",os.R_OK))#返回值时boolean类型
#os.F_OK存在指标 os.R_OK可读指标 os.X_OK可写指标 os.W_OK可执行指标(正常打开?)
#改变当前工作目录到指定的路径os.chird("路径")
#改变的时当前执行py脚本的路径
#os,chmod("文件路径","权限") 更改文件或者目录权限 (lunix使用)
#stat.S_IXOTH: 其他用户有执行权0o001
#stat.S_IWOTH: 其他用户有写权限0o002
#stat.S_IROTH: 其他用户有读权限0o004
#stat.S_IRWXO: 其他用户有全部权限(权限掩码)0o007
#stat.S_IXGRP: 组用户有执行权限0o010
#stat.S_IWGRP: 组用户有写权限0o020
#stat.S_IRGRP: 组用户有读权限0o040
#stat.S_IRWXG: 组用户有全部权限(权限掩码)0o070
#stat.S_IXUSR: 拥有者具有执行权限0o100
#stat.S_IWUSR: 拥有者具有写权限0o200
#stat.S_IRUSR: 拥有者具有读权限0o400
#stat.S_IRWXU: 拥有者有全部权限(权限掩码)0o700
#stat.S_ISVTX: 目录里文件目录只有拥有者才可删除更改0o1000
#stat.S_ISGID: 执行此文件其进程有效组为文件所在组0o2000
#stat.S_ISUID: 执行此文件其进程有效用户为文件所有者0o4000
#stat.S_IREAD: windows下设为只读
#stat.S_IWRITE: windows下取消只读
#获取当前父目录os.pardir()
#直接返回父目录是 ..
print(os.path.abspath(os.path.join(os.getcwd(),os.pardir)))
#os.path.join(path1,path2,...)连接两个以上的路径,没有/会自动添加
#os.close(fd)关闭指定文件文件描述符,
#文件描述符 系统内核是利用文件描述符来访问文件的,描述符是非负整数 ,打开和新建一个文件时内核会自动返回一个文件描述符。读写文件需要文件描述符来指定等待读写的文件
file01 = open("C:\\Users\\32793\\Desktop\\open2.txt", "r")
file01.close()
file02 = os.open("C:\\Users\\32793\\Desktop\\open.txt",os.O_RDWR)
str2="PRINCE KLKL \n 555 "
#os.write()直接传递字符串会报错,需要bytes转换一次编码,个人理解是os不能获取脚本中使用的编码,需要重新编码一次才能读取内容
os.write(file02,bytes(str2,'UTF-8'))#是从头覆盖写入文件内容,
os.write(file02,bytes("55555",'UTF-8'))
#os.write(file02,str2)
os.close(file02)
#类型一致,用法相同
#open的文件状态支持通道标识符
#返回伪终端对的文件标识符 os.openpty()
m,s = os.openpty()#没试出来暂存
#创建指令路径管道Linux os.mkfifo('路径','目录设置权限数字模式')
path="/tmp/cs"
os.mkfifo(path,0644)
#创建管道,返回一对当前文件读写的文件描述符 os.pipe()
#返回文件标识符状态 os.fstat()
#返回的标识符状态有很多,查找特定的标识符需要自行查询,需要自行查找
#!/usr/bin/python3
file01=os.open("fstat01.txt",os.O_RDWR|os.O_CREAT)
inforamtion = os.fstat()
print(inforamtion)
print(inforamtion.st_dev)
#os.stat_result(st_mode=33206, st_ino=3659174697670032, st_dev=3839034241, st_nlink=1, st_uid=0, st_gid=0, st_size=20, st_atime=1641205665, st_mtime=1641205665, st_ctime=1641127288)
#3839034241
#os.getwd() 返回当前工作目录
#返回值就是目录
print(os.getwd())
#os.getcwdb()返回当前工作目录的unicode对象内容是工作目录的字节串(解码完在进行编码的字节串) 3.8后windows默认使用utf-8编码进行解码,原先使用ASC-ii
print(os.getcwdb())#b'C:\\ProgramEdit\\pythonProject\\202112245_03'
#剩下太多了,等需要再看吧
异常处理
try except else finally
#!\usr\bin\python3
while True:
try:
x= int(input("input int:"))
except ValueError:
print("input error")
#一个try可以对应多个except 语句抓取异常,但是最多只有一个except被同时执行,如果出现一个没有被匹配的异常那么这个异常会传到try里
#except可以没有异常类型,这样程序会先执行except下的内容,然后再去报异常
else:
#这里是没有异常是执行的代码,执行后在进行执行下一行程序
finally:
#这里是无论是否发生异常都需要执行的语句
import sys
try:
f = open('C:\\Users\\32793\\Desktop\\open.txt')#文件内容:5555 PRINCE
s= f.readlines()
i = int(s.strip('5'))
except OSError as err:
print("OS Error {0}".format(err))
except ValueError:
print("not int type")
except:
print("Unexcepted error:",sys.exc_info()[0])
raise
抛出异常raise
#当满足某个条件时自动抛出异常,是唯一一个指定了你要抛出的异常,必须有一个异常实例或者异常类
x =10
if x >5:
raise Exception('x si error{0}'.format(x))
#Traceback (most recent call last):
#File "C:\ProgramEdit\pythonProject\202112245_03\test04_OS.py", line 62, in <module>
#raise Exception('x si error {0}'.format(x))
#Exception: x si error 10
自定义异常
#python支持自定义一个异常类
class Error(Exception):
"""Error error"""
pass
class ValueTooSmallError(Error):
"""ValueTooSmallError error"""
pass
class VauleTooLargeError(Error):
"""VauleTooLargeError error"""
pass
#自定义异常类
number = 10
while True:
try:
num= int(input("input here:"))
if num < 10:
raise ValueTooSmallError
elif num>10:
raise VauleTooLargeError
except ValueTooSmallError:
print("small")
except VauleTooLargeError:
print("large")
else:
print("continue")
break
清理行为fianally与with
#finally具有清理作用
#如果一个异常在try子句内被抛出,又没有任何except进行拦截,那么这个异常会在finally中被抛出同时截住
#一些对象可以自行定义标准的清理行为,无论系统是否使用了这个清理行为,一旦不需要了这个清理行为也会自己执行
#使用with语句
for x in open("C:\\Users\\32793\\Desktop\\open.txt"):
print(x,end=' ')#这个循环执行完后不会关闭文件,是不正确的使用方式
with open("C:\\Users\\32793\\Desktop\\open.txt") as f:
for x in f:
print(x,end=" ")
python的对象
与java对象使用方式基本类似
#实例生成时先执行__new__(),然后执行__init__()方法
class classname:
def function():
print()
return
i=3
def __init__(self):
self.data=[]
#self代表当前对象生成的实例,即为当前对象的地址
#此方法,在类的实例化操作时会自动调用,可以传递参数
def prt(self):
print(self)
print(self.__class__)
#self代表当前对象生成的实例,即为当前对象的地址
#这个实例self参数不一定就是self,换成其他参数也没有问题
t= classname()
t.prt()# <__main__.classname object at 0x00000152604F3B80>
#<class '__main__.classname'>
#类方法使用@classmethod进行修饰,用它进行修饰就是类方法
#静态方法要用@staticmethod进行修饰,用它进行修饰就是静态方法
class Vector:
@classmethod
def __init__(self,a,b):
self.a=a
self.b=b
@classmethod
def __str__(self):
return '{0} {1}'.format(self.a,self.b)
@classmethod
def __add__(self, other):
return Vector(self.a+other.a,self.b+self.b)
@staticmethod
def staticfunction():pass
#类方法不是普通函数,类方法必须包含一个额外的实例参数,表示为对象的实例,默认时self
#class ij(object,name,age)与class ij(name,age)表现形式是一致的,每个类方法都额外需要一个实例参数,这个是类方法与普通函数的区别
#至于要不要在类方法里添加self,涉及到静态方法、类方法和类实例的区别
#继承
#单继承
class people:
name = ''
age = 0
__weight = 0
def __init__(self,n,a,w):
self.name=n
self.age=a
self.__weight= w
def speak(self):
print("{0} is {1} and {0} {2}".format(self.name,self.age,self.__weight))
class student(people):
grade = ' '
def __init__(self,n,a,w):
people.__init__(self,n,a,w)#子类必须在子类构造函数里执行一遍父类的构造函数才行
self.grade=g
def speak(self):
print("{0} is {1} and {0} {2} {3}".format(self.name,self.age,self.grade))
#self.__weight是私有属性,外部无法进行访问
#多继承
#比单继承多传入一个父类,同样,被继承的子类也要重新进行一变该父类的__init__方法
#子类可以通过同名类方法的形式重写父类方法
#类的属性与方法
#两个_开头的属性表示属性为私有属性,不能在类的外部使用和访问,所以实例不能访问私有变量
#两个_开头的方法也表示为私有方法,只能在类的内部调用
#访问私有属性有一种访问方式 ’_类名__私有属性名‘
class Vector:
__io = 2
@classmethod
def __init__(self,a,b):
self.a=a
self.b=b
@classmethod
def __str__(self):
return '{0} {1}'.format(self.a,self.b)
@classmethod
def __add__(self, other):
return Vector(self.a+other.a,self.b+self.b)
@staticmethod
def staticfunction():pass
v1= Vector(2,3)
v2= Vector(3,5)
print(v1+v2)
print(v1._Vector__io)
#类的专有方法 部分
__init__():#构造函数
__del__():#折构函数,释放对象使用
__repr__():#打印转换
__setitem__():#按照索引值赋值
__getitem__():#按照索引获取值
__len__():#或的长度
__cmp__():#比较运算
__call__():#函数调用
__add__():#加运算
__sub__():#减运算
__pow__():#乘方运算
#类的特殊属性 部分
#__dict__ 输出对象(实例对象)的属性字典
#__bases__ 输出全部父类类型的元素(对于子类,就是继承的全部父类)
#__base__只输出第一个继承的父类
#__class__ 输出对象所属于的类
动态绑定属性和方法
#python是一种动态语言,可以进行动态绑定方法和属性
def show():
print('show')
return
stu = student('jack',20)#假设有一个student类
stu2 = student('asd',90)
stu.grade = '20'#动态绑定一个属性
print(stu.name,stu.age,stu.grade)
stu.show =show#动态绑定一个方法
stu.show()
stu2.show()
print(stu2.grade)
class people:
name = ''
age = 0
__weight = 0
def __init__(self,n,a,w):
self.name=n
self.age=a
self.__weight= w
def speak(self):
print("{0} is {1} and {0} {2}".format(self.name,self.age,self.__weight))
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#super().__init__(self,n,a,w) super()进行继承需要注意子类跟父类的构造函数内形参个数一致,否则会报错
people.__init__(self,n,a,w)#这个子类多出父类people一个g参数所以需要使用people进行调用父类构造 目前理解是这样
self.grade = g
def speak(self):
print("{0} is {1} and {0} {2} ".format(self.name,self.age,self.grade))
命名空间和作用域
命名空间
内置命名空间(关键字、内置函数、异常)、全局命名空间(函数、类以及其他导入的模块)、局部命名空间(函数内自定义)
python默认查找顺序是局部命名空间-》全局命名空间-》内置命名空间,没有找到会报NameError异常
外部命名空间无法访问内部命名空间,因为对象一旦执行结束该对象对应的命名空间的生命周期就会结束
作用域
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b91e34lp-1641889113249)(C:\Users\32793\AppData\Roaming\Typora\typora-user-images\image-20220104141023085.png)]
#可以使用 global和nonlocal手动定义作用域范围
#global为全局变量#
#!/usr/bin/python3
nonlocal total = 0
def function():
global x =10
x+=10
print(x)
常用库
#os 操作系统接口
#glob 目录通配符生成文件列表
#sys 命令行参数
#math 数学模块
#re 字符串正则模块
#urlopen 互联网展示
#dattime 日期与时间
#zlib、gzip、bz2、zipfile、tarfile 压缩模块
#性能度量 timeit
#doctest 测试模块
#
#
多线程
每个独立线程都有一个程序入口,顺序执行序列和程序出口,但是线程不能够独立执行,必须一寸在应用程序内,有多个应用程序提供多个线程执行控制。
每个线程都有独立于自己的cpu寄存器,成为线程上下文,该上下文反映了线程上次运行该线程的cpu寄存器状态
线程分为用户线程和内核线程两部分
内核线程:由操作系统内核创建和撤销
用户线程:不需要内核支持的在用户程序中实现的线程
python3常用模块
#_thread
#threading 原thread已经被废弃
扩展
编码与解码
https://blog.csdn.net/lyb3b3b/article/details/74993327
从str到bytes为编码,比特流(01)变为str
从bytes到str为解码,str变为比特流(01)
str1="设置"
print(bytes(str1,'UTF-8'))#b'\xe8\xae\xbe\xe7\xbd\xae'
print(str(bytes(str1,'utf-8'),'utf-8'))#设置
#b‘是''',utf-8与asc-ii在英文方面兼容
管道
进程之间进行信息交互的手段
目前区分为两种:匿名管道和命名管道
匿名管道指不带名字标识的管道,用于父进程与其子进程之间的通信
命名管道则是带有名字标识符的管道,支持任意两个进程之间的通信。
命名管道 Linux命令?管道符号-grep\head\tail\wc\ls?
ls -l|wc、grep apple.txt| grep configure、管道命令符|
python导入非当前目录的py文件或者函数
如果是导入非当前目录的py文件需要以下步骤实现
#1、目录下新建__init__.py文件,将其目录变成一个包package,假设common包
#2、文件内输入__all__ = ['file1','file2']#最好包括目录内的所有文件,file1.py,file2.py
__all__ = ['yaml_util']
#import common.yaml_util
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TJwnKOEU-1641889113250)(C:\Users\32793\AppData\Roaming\Typora\typora-user-images\image-20220111142156918.png)]
le/details/74993327
从str到bytes为编码,比特流(01)变为str
从bytes到str为解码,str变为比特流(01)
str1="设置"
print(bytes(str1,'UTF-8'))#b'\xe8\xae\xbe\xe7\xbd\xae'
print(str(bytes(str1,'utf-8'),'utf-8'))#设置
#b‘是''',utf-8与asc-ii在英文方面兼容
管道
进程之间进行信息交互的手段
目前区分为两种:匿名管道和命名管道
匿名管道指不带名字标识的管道,用于父进程与其子进程之间的通信
命名管道则是带有名字标识符的管道,支持任意两个进程之间的通信。
命名管道 Linux命令?管道符号-grep\head\tail\wc\ls?
ls -l|wc、grep apple.txt| grep configure、管道命令符|
python导入非当前目录的py文件或者函数
如果是导入非当前目录的py文件需要以下步骤实现
#1、目录下新建__init__.py文件,将其目录变成一个包package,假设common包
#2、文件内输入__all__ = ['file1','file2']#最好包括目录内的所有文件,file1.py,file2.py
__all__ = ['yaml_util']
#import common.yaml_util
[外链图片转存中…(img-TJwnKOEU-1641889113250)]