环境:VsCode中配置的Python环境
来源:【Python教程】《零基础入门学习Python》最新版(完结撒花🎉)_哔哩哔哩_bilibili
语法
1.数据类型:integer(整型)
floating point numbers(浮点数
字符串(string):不可变的序列
# -*- coding: gbk -*-
#都是创建一个新的字符串以供操作
x="I Love YOU"
a=x.capitalize()#一句中首字母大写
b=x.casefold()#所有字母小写 大部分语言可使用
c=x.swapcase()#所有字母大小写反转
d=x.title()#所有单词首字母大写
e=x.upper()#全部字母大写
f=x.lower()#全部字母小写 只能处理英文
print(a,b,c,d,e)
#对齐操作 center(填充宽度,填充字符)
aa=x.center(50)#宽度大于才会对齐操作 否则直接输出源字符
bb=x.ljust(50)
cc=x.rjust(50)
dd=x.zfill(50)
print(aa)
print(bb)
print(cc)
print(dd)
x="上海自来水来自上海 "
aaa=x.count("海")#记数
bbb=x.find("海")#寻找字符首个出现的位置 默认从左到右 从小到大
ccc=x.rfind("海")#从右找首个出现的字符
ddd=x.index("海")#找到第一个字符的索引
ab=x.exandtabs(4)#用空格代替tabs 里面的参数代表一个tabs用几个空格表示
ac=x.replace("上海","海神")#replace(new,old,count=-1)count指定的是替换的次数
#替换列表
table=str.maketrans("ABCDEFG","1234567") #创建替换的表
m="GFEDCBA"
m=m.translate(table)
#检验位置中的值是否一致
one=m.startwith("7")
two=m.endwith("1")#endwith("检索值","起始或结束位置")
"""istitle(),isupper()判断字符是否符合该格式 isalpha判断 是否全部是字母 isprintable()判断内容是否可以打印,注意含有转义字符时 issapce()是否含有空格 isdecimal()是否纯数字 isdigit()
isnumeric()判断是数字,罗马、其他都可以 isidentifier()判断是否是合法的标识符
x.upper.isupper(),从左到右依次执行"""
x=" 左侧不留白"
x=x.lstrip()#lstrip()右侧清除空格、rstrip()右侧清除空格、strip()左右都清除 括号为参数
y="www.ilovefish.com"
m=y.lstrip("wcom.")#他表示在目标字符串左侧依次寻找括号中的单个字符,匹配任何一个就将其删除掉
n=y.strip("wcom.")
aa=y.removeprefix("www.")#匹配整个参数进行删除
bb=y.removesuffix(".com")
cc=y.partition(".")#将其以"."分离成左 中 右 三部分的元组 rpartition()从右分
#split("字符",'几个')将字符以括号中的元素为间隔进行分隔成为列表元素
mm="米,莫,西"
nn=mm.split(",")
a="米 莫 西"
b=a.split()
#join()给各个字符间加入元素,使用方法 元组和列表都可以使用 join在大数据下效率高于加号
c=".".join(["www","baidu","com"])
#格式化使用字符串方法 使用format() format()中的元素当作为元组进行操作
year=2024
bc="今年是{}年".format(year)
cd="1+2={},2*2={}".format(1+2,2*2)
dc="{0}+{2}={1}".format(1,5,4)
cdc="{0}{0}{1}{1}".format("是","非")
bd="我是{name}".format(name="东方")
align对齐方式和其他用法:
#'<'强制字符在可用空间内左对齐 默认
#'>'强制字符在可用空间内右对齐
#'='强制将填充放置在符号(若有)之后但在数字之前的位置 如'+1200'的形式打印字符串
#'^'强制字符串在可用内居中
#'+-'表示数字前面的符号
#','表示千分位,用逗号分割
#'_'表示千分位,用下划线分割
#'.2f'表示浮点数,小数点后保留2位
#'.2g'表示浮点数是来讲,限定小数点前后一共显示多少个数位 此表示2位
#'.N'可以表示截取非数字类型格式的N位位宽 对于整数类型不适用
#{左侧:右侧} 左侧是位置或关键字索引 右侧是格式化选项
a="{:^10}"format(250)#10为位宽
b="{0:<10},{1:^10}".format("100","50")
#以进制输出时前面加#号可以显示格式
x="{:#b}".format(10)
y="{:b}".format(10)
语法糖:简化语法但不影响功能,上面就可以改变为
year=1904
a=F"今年是{year}"
b=f"明年是{year+1}"
c="{:{fill}{align}{width}.{prec}{ty}}".format(3.1415,fill="+",align='^',width=10,prec=
3,ty="g")
2.布尔类型:
a=bool(1)
b=bool("")
print(a,b)
3.条件语句
if-else
age=int(input("请输入你的年龄:"))
if age>=18:
print("欢迎光临")
else:
print("禁止进入")
if-elif-elif
age=int(input("请输入你的年龄:"))
if age>=18:
print("欢迎光临")
elif age>=16:
print("谨慎进入")
elif age>10:
print("禁止进入")
另一种写法:
age=int(input("请输入你的年龄:"))
a=("1" if 18<age<26 else
"2" if 16<age<=18 else
"3")
print(a)
4.循环语句
while语句
i=10
while i>0:
print("爱你10年")
i-=1
print("游戏结束")
for语句
for each in "I LOVE YOU":
print(each)
"""
range(stop)
range(start,stop)
range(start,stop,step)
"""
i=0
for i in range(10):
print(i)
print("结束")
若其中i未定义,则默认从0开始
a=[[1,2,3],[4,5,6],[7,8,9]]
for each in a:
for each in each:
print(each)
for each in a:
print(each)
#each表示当前迭代元素中的第一级组成元素
5.break:跳出一层 循环体
continue:结束本次循环,回到循环体开头,进行下一次循环
6.数字运算符及其优先级表示
7.列表:用方括号进行表示,逗号分隔开
a=[0,1,2,3,4,5,6,"结束啦"]
切片
b=a[0:3]
c=a[3:5]
d=a[2:6:2]
#[stat:stop:step]
#都是左闭右开的形式
增加元素
append:在列表末尾加上一个元素。 extend:在列表末尾 加上若干元素,必须是可迭代元素
a=[0,1,2]
a.append(3)
a.extend([4,5,6])
插入元素:insert
a=[0,2]
a.insert(1,1)
#insert(位置,元素)
删除元素:remove、pop、clear
a=[0,1,2,3,"无敌"]
a.remove("无敌")
#remove(元素)
a.pop(2)
#pop(索引),按照下标索引删除元素
a.clear()
#clear 为清除列表元素
替换元素:可使用切片方式
a=[0,1,2,3]
a[2:]=[3,4]
a[:2]=[1,2]
"""
step 1:将赋值号左边指定的内容删除
step 2:将包含在赋值号右边的可迭代对象的片段插入左边被删除的位置
""""
排序:sort、reverse、sorted、reversed
a=[0,1,6,4,7,8,9,30]
m=a.sort()
n=a.reverse()
b=a.sorted()
c=a.reversed()
#sort() 从小到大排序修改原列表 尽可以在列表使用
#reverse() 反转修改源列表
#序列都可以使用
#sorted() 从小到大排序产生新列表 排序的若是字符 一个一个字母比较 按照ascll码比较
#reversed() 反转产生 新列表
#注意这里不能赋值 输出为None
查:count、index
# -*- coding: gbk -*-
a=[0,1,6,4,7,8,9,8,30]
b=a.count(8)
c=a.index(8)
d=a.copy()#等比于d=a[:]
print(b,c,d)
#count(元素):计数相应元素的个数
#index(元素,start,stop):查找相应元素的首个索引,后面两个参数表示搜索的范围
#copy():复制元素到另一个名字去 类比于全切片赋值到新列表
8.列表(list)的运算
a=[1,2,3]
b=[4,5,6]
c=a+b #加法类似于拼接
d=a*3 #乘法相当于列表重复N次
嵌套列表
matrix01=[[1,2,3],[4,5,6],[7,8,9]]
matrix02=[[7,8,9],
[4,5,6],
[1,2,3]]
#访问嵌套列表
for i in matrix01:
for each in i:
print(each,end="\t")
print()
#end()表示关闭自动换行,在末尾添加字符串
a=matrix01[1,1]
b=matrix01[2,2]
#创建二维列表
for i in range(3)
A[i]=[0]*3
#错误写法
B=[[0]*3]*3 #不方便后期处理
浅拷贝和深拷贝
x=[1,2,3]
y=[1,2,3] #类比于y=x.copy()以及y=x[:] 上述我们称之为浅拷贝
z=x
a=x is y
b=x is z
x[1]=4
print(a,b,z)
#a is false x与y存储的空间是不同的
#b is true x与z共用同一个储存空间,其是引用类型
#copy是将对象复制
x=[[1,2,3],[4,5,6],[7,8,9]]
y=x.copy()#等价于y=copy.copy(x)需要引入copy模块
x[1][1]=0
print(x)
print(y)
#浅拷贝只拷贝了外层的对象,若包含嵌套的话,拷贝的只是其引用 与之相对的有深拷贝
#深拷贝 需要引入copy模块
import copy
x=[[1,2,3],[4,5,6],[7,8,9]]
y=copy.deepcopy(x)
x[1][1]=0
print(y)
列表推导式
# -*- coding: gbk -*-
a=[1,2,3,4,5,6,7,8,9]
a=[1,2,3,4,5,6,7,8,9]
#[expression for target in iterable]列表推导式
a=[i*2 for i in a]
print(a)
x=[i for i in range(10)]
print(x)
y=[]
for i in range(10):
y.append(i+1)
print(y)
#字符类的推导式
m=[c*2 for c in "shijiediyi"]
print(m)
n=[ord(c) for c in "abcd"] #ord()内置函数:将字符转为UniCode
print(n)
#获取矩阵主对角线元素
matrix=[[1,2,3],
[4,5,6],
[7,8,9]]
dia=[matrix[i][i] for i in range(len(matrix))]
xdia=[matrix[i][len(matrix)-1-i] for i in range(len(matrix))]#副对角线
print(dia)
print(xdia)
列表推导式的条件语句
# -*- coding: gbk -*-
"""[expression for target in iterable if condition]
执行的顺序:1.for target in iterable
2. if condition
3.expression
"""
#生成0~1000的偶数列表
even=[i for i in range(1001) if i%2==0]
print(len(even))
add=[i+1 for i in even if i+1<=1000]
print(add)
#筛选A开头的字符
m=["ABC","bac","AD"]
n=[i for i in m if i[0]=="b"]
print(n)
"""列表推导式的嵌套
[expression for target1 in iterable1
for target2 in iterable2
...
for targetN in iterableN]
类似于for循环嵌套"""
matrix=[[1,2,3],
[4,5,6],
[7,8,9]]
a=[j for i in matrix for j in i]
print(a)
9.元组(tuple)
语法格式:(元素1,元素是2,..,元素N)注意括号可以省略
定义完后,内部元素改变是不允许的,但若是元素指向的是一个可变的列表,其内容课可改变。
# -*- coding: gbk -*-
rhyme=(1,2,3,4,5,"上山打老虎")
a=1,2,3,4,5,"上山打老虎"
print(rhyme)
print(a)
"""仅支持查找
例如count、index
也可以拼接,
乘法就是重复几次创建新的对象
"""
#生成单个元素大的元组 逗号是关键
b=(520,)
print(type(b))
#打包与解包 适用于任何类型的序列,例如列表 序列数目必须一致
num=(1,2,3)#打包
A,B,C=num#解包
D,*C=num #解包是在左侧加*号表示将剩下的都给该元素
print(A,B,C)
NUM=([1,2,3],[4,5,6])
NUM[0][1]=0
print(NUM)
10.序列
#in运算符和not in运算符判断某个元素是否包含在序列中
"m" in ["m",12]
#del用于删除一个或多个指定的对象
x="fish"
y=[1,2,3,4]
del y[:]#删除内部元素等价于y.clear() y[::2]=[]该语法错误
del x,y#删除对象
序列之间的相互转换:列表、元组和字符串--list()、tuple()、str()
x=list("fish")#list(元素)将其转变为列表
m=tuple("fish")#tuple(元素)转变为元组
n=str("[1,2,3]")#str(元素)转变为字符串
搜索最大值max()和最小值min():比较的是ASCLL码 len()长度 sum()求和
s=[1,2,3]
m=[]
a=min(s)
b=max(m,default="什么都没有")
d=len(s)
c=sum(s,start=100)
all():判断可迭代对象中所有元素是否为真,any():判断可迭代对象中某个元素的值是否为真
x=[1,2,0]
y=[1,2,3]
print(all(x),all(y))
print(any(x),any(y))
enumerate():返回一个枚举对象,作用是将可迭代对象的每个元素及从零开始的序号共同构成一个二元组的列表
season=["春","夏","秋","冬"]
x=enumerate(season)#emumerate(元素,起始位置)
print(list(x))
zip():创建一个聚合多个可迭代对象的迭代器,它会将作为参数传入的每个可迭代对象的每个元素依次组合成元组,即第i个元组包含来自每个参数的第i个元素。若长度不一样,则以最短的为准。
x=[1,2,3]
y=[4,5,6]
zipped=zip(x,y)
m=list(zipped)
#长度不一致,保留最长的调用模块itertools
import itertools
z="stop you"
zm=itertools.zip_longest(x,y,z)
print(list(zm))
map():根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器。
#map(函数,可迭代对象)
mapped=map(ord,"fish")
print(list(mapped))
#函数许多个参数时,迭代对象相应位置对应计算 若对应个数不一样 则以最短的为准
x=map(pow,[1,2,3],[2,2,2])
filter():根据提供的函数对指定的可迭代对象的每个元素进行运算,并将运算结果为真的元素,以迭代器的形式返回。
x="FishC"
maped=filter(str.islower,x)#str.islow判断字符是否全部小写
11.迭代器(iter)和迭代对象
迭代器肯定是一个可迭代对象,
可迭代对象可以重复使用而迭代器则是一次性的(即后面操作元素为空),
mapped=map(ord,"fish")
for each in mapped:
print(each)
list(mapped)
#iter()使迭代对象变为迭代器
x=[1,2,3]
y=iter(x)
#next()从迭代器依次取出元素
a=next(x)
b=next(x)
c=next(x)
d=next(x,"没有啦")
12.字典(dict):python中唯一实现映射关系的内置类型
"""字典语法
{键1:值1,键2:值2,...,键N:值N} 键值对是唯一存在的 列表元素是可以重复的
"""
x={1:"a",2:"b",3:"c"}
"""
等价于x=dict(1="a",2="b",3="c")此时键不能加引号
x=dict([(1,"a"),(2,"b"),(3,"c")])
x=dict({1:"a",2:"b",3:"c"})
x=dict({1:"a",2:"b"},3="c")
x=dict(zip([1,2,3],["a","b","c"]))
"""
types=type(x)
#若字典中没有,则会自动创建键值对
x[4]="d"
#快速创建一个字典, 多键对一值
m=dict.fromkeys("Fish",250)
v=m.pop("F")#删除指定元素的索引或者键值
#删除元素
del d["i"]
n=m.clear()
#修改元素
m=dict.fromkeys("iml")
m.update({"i":5,"m",2})#不可以赋值
#查找元素 get(keys,[default])
m.get("m")
#查看一个元素是否位于字典中,若有返回其对应的值,无则指定一个新的值
m.setdefault("m","3")
m.setdefault("b",3)
视图对象:字典的动态视图,当字典的内容发生改变的时候,视图对象的内容也相应的跟着改变。
""" items():获取字典的键值对
keys():获取字典的键
values():获取字典的值 以列表格式输出
"""
# -*- coding: gbk -*-
n=dict.fromkeys("iml")
n.update({"i":5,"m":2,"l":4})
n.setdefault("m","3")
n.setdefault("b",3)
keys=n.keys()
values=n.values()
items=n.items()
#获取键值对的数量
len(n)
#嵌套字典
d={"吕布":{"语文":80,"数学":60},"关羽":{"语文":100,"数学":70}}
#输出吕布的语文成绩
d["吕布"]["语文"]
#嵌套列表
m={"吕布":[80,60],"关羽":[100,70]}
m["吕布"][0]
字典推导式
d={'f':70,'i':60,'s':50,'h':40}
b={v:k for k,v in d.items()}#上述实现了字典键和值的调换
c={x:y for x in [1,2,3] for y in [4,5,6]} #字典中键值对唯一性决定
13.集合(set:可变的):元素唯一性且无序,去除映射的字典就是集合,不能通过索引搜索元素
#-*-coding:gbk-*-
#集合产生方法
m={'a','b','c'}
n={i for i in "fish"}#输出体现了他的无序性 访问元素使用循环语句
a=set([1,1,2,2,3,3])#可以用集合检查序列的唯一性
#len(序列)==lens(set(序列))相等无重复
#判断关系 按照单个元素对比 但不更新集合
m.isdisjoint(set('JAVA'))#判断是否有相同的部分
m.issubset('abcsd')#判断是否为子集
m.issuperset('ab')#判断是否为超集 子集的对立面
m.union({1,2,3})#两者的并集
m.intersection({1,2,3})#两者交集
m.difference("FISH")#两者的差集
#上述都支持多参数
m.symmetric_difference()#两者对称差集:两者并集减去两者交集 不支持多参数
#也有运算<>|&- 子集、超集、并集、交集、差集 仅对集合有效
#使用更新的话举例子 intersection_update()
m.intersection_update("123")
集合(frozenset:不可变)
s={'fishc'}
s.update('mo')#单个字符并集更新
s.add("mo")#整个字符添加到集合
#remove() 集合不存在删除的元素报异常 discard() 静默处理
可哈希 :set不可哈希,frozenset可哈希
"""hash(object)可以获取一个对象的哈希值
对象值相等哈希值就相等
可变对象无法计算哈希值 比如列表
"""
x=hash(1)
14.函数
创建和调用函数
#定义函数
def myfunc():
pass # pass作为占位符 没什么实际作用 空语句
#调用函数
myfunc()
参数设计:实际参数、形式参数
"""
函数的返回值 return
"""
def myfunc(x,y):
z=x/y
return z
x,y=1,2
m=myfunc(x,y)
print(m)
#位置参数
def myfunc01(a,b,c): #默认参数放在最后
return "".join((b,a,c))#join里面是可迭代对象
print(myfunc01("1",'2','3'))#位置参数传递
print(myfunc01(a="1",b='2',c='3'))#关键字参数传递 位置参数必须在关键字参数前
#help()查看文档
#对于abs(x,/)斜杠代表其左侧参数必须传递位置参数而不能是关键字参数
xxx(a,*,c)*表示其右侧只能是关键字参数
def funci(a,/,b,c):
print(a,b,c)
funci(1,2,3)正确
funci(a=1,2,3)错误
#收集参数 形参任意多个 形参前面加* 其还有其他的形参时,可以用关键字传递 argument:参数
def func02(*args):
print("有{}个参数".format(len(args)))
print("第二个参数是:{}".format(args[1]))
func02(1,2,3,4)
func02(1,2,3,4,5,6)
#返回多个参数时打包成元组返回 之后在解包 只加一个*
#返回多个参数时打包成字典返回 之后在解包 只加两个* 传递时必须为键值对即必须关键字传递
def func03(**args):
print("有{}个参数".format(len(args)))
print("第二个参数是:{}".format(args[1]))
func03(a=1,b=2)
#解包操作
args=(1,2,3)
func02(*args)#*args就是对args元组解包
kargs={"a":1,"b":2}
func03(**kargs)#**kargs就是对kargs字典解包
作用域:局部作用域、全局作用域
LEGB:Local Enclosed Global Build-In
"""
函数内部的变量 作用域为函数内部 局部变量
函数外部的变量 作用域为全局 全局变量
全局变量可以在函数的内被访问 但无法修改局部变量的值
在其同名时,函数内部创建一个新的变量而不影响全局变量的值
#L:局部作用域
#E:嵌套函数的外层函数作用域
#G:全局作用域
#B:内置作用域
"""
x=520
print(x)
def funco():
x=666
print(x)
funco()
print(x)
#global语句 不提倡 使局部变量变为全局变量
y=520
print(y)
def funci():
global y
y=666
print(y)
funci()
print(y)
#嵌套 无法直接调用嵌套里面的函数 只能通过调用外部函数来间接调用内部函数 后面有间接处理可使用
def funA():
z=520
def funB():
z=888
print(z)
funB()
print(z)
funA()
#nonlocal语句 可以实现僭越 下列输出888 888
def funC():
z=520
def funD():
nonlocal z
z=888
print(z)
funD()
print(z)
funC()
闭包(closure)
#-*- coding:gbk-*-
def funA():
z=520
def funB():
print(z)
return funB # 这里是函数名 没有加括号
funA()()#直接调用funB funA()返回的是funB()的引用
m=funA()
m()
#闭包加工厂
def pow(exp):
def exp_of(base):
return exp**base
return exp_of
square=pow(2)#嵌套函数的外层作用域被保存下来 即此刻exp=2 此处为闭包操作
n=square(3)
print(n)
#装饰器-函数作为另一个函数的参数
#嵌套函数的外层作用域具有记忆功能可以让数据保存在外层函数的参数或者变量中
#将内层函数作为返回值返回
def myfunc():
print("我要开始表演啦")
def fun1(fun): #此处未加括号
print("表演开始")
fun() #此处加括号
print("表演结束")
fun1(myfunc) #此处未加括号 此处为闭包操作
#装饰器的实际应用 @+函数名表示其是一个装饰器 其类似于帽子叠加 就近原则执行 位于下一定义的函数前
def add(fun):
def inner():
x=fun()
return x+1
return inner
def pow(fun):
def inner():
x=fun()
return x*x
return inner
@add #装饰器0 只有具体返回值的情况才可以用装饰器
@pow #装饰器1 意义如下,将test函数的返回值作为参数传递给装饰器1进行处理,在传递给装饰器0处理
def test():
return 3
print(test()) #输出为10
#引入time包计算程序运行时间
import time
def timer01(fun):
def diff_time():
x1=time.time() #获取当前时刻
y=fun()
print(y)
x2=time.time() #获取当前时刻
print(x2-x1)
return diff_time
@timer01
def fun00():
time.sleep(0.2) #程序休眠0.2s
print("开始啦")
return 3
fun00()
#等价于下列
import time
def timer01(fun):
x1=time.time() #获取当前时刻
print(fun())
x2=time.time() #获取当前时刻
print(x2-x1)
def fun00():
time.sleep(0.2) #程序休眠2s
print("开始啦")
return 3
timer01(fun00)
lambda:匿名函数
#语法格式 lambda arg1,arg2,arg3,...,argN:expression
#关键字 参数 : 函数表达式以及返回值
#lambda是一个表达式,可用在常规函数不存在的地方
#传统方式
def spuareX(x):
return x*x
print(squareX(3))
#lambda函数
squareY=lambda y:y*y
squareY(3)
#上述两种都是squareX、squareY直接使用都是引用类型
#lambda是一个表达式,可用在常规函数不存在的地方
y=[lambda y:y*y,2,3]
y[0]=y[0](3)
生成器(generator)
#-*-coding:gbk-*-
#语法 yeild生成 其输出的也为i
def counter():
i=0
while i<=5:
yield i
i+=1
print(type(counter()))#此时调用返回的是一个生成器对象 而不是返回值 每调用依次提供一个数据并且记住当时的状态 无法使用下标索引访问元素
for i in counter():
print(i)
递归(recursion):函数调用自身的过程
#递归要向结束条件去推进
def sun(i):
if i>0:
print("hello world")
i-=1
sun(i)
sun(10)#输出10次 hello world
#比较迭代和递归 计算阶乘
def factiter(n):
result=n
for i in range(1,n):
result*=i
return result
print(factiter(10))#迭代
def recur(n):
if n==1:#结束条件
return 1
else:
return n*recur(n-1)#递归
print(recur(10))
#斐波拉契数列实现
def fibrecur():
a=1
b=1
c=1
while n>2:
c=a+b
a=b
b=c
n-=1
return c
print(fibrecur(12))#迭代
def fibo(n):
if n==1 or n==2:
return 1
else:
return fibo(n-1)+fibo(n-2)
print(fibo(12))#递归
#总结 递归的效率低于迭代 空间复杂度高
汉诺塔
def hanot(n,x,y,z):
if n==1:
print(x,"->",z)#若只有一层,直接将圆环从x移动到z
else:
hanot(n-1,x,z,y)#将x上的n-1个层移动到y
print(x,"->",z)#将最底下的层从x移动到z
hanot(n-1,y,x,z)#将y上的n-1个层移动到z
n=int(input('请输入层数:'))
hanot(n,'a','b','c')
函数文档
#引号中间的就是函数的文档
def exchange(dollar,rate=6.28):
'''
功能:汇率转换,美元->人民币
参数:
-dollar 美元数量
-rate 汇率 默认值:6.32(2022-01-12)
返回值:
-人民币的数量
'''
return dollar*rate
exchange(20)
help(exchange)
#类型注释
def times(s:str,n:int)->str: #希望调用着传入到s参数的类型是字符串类型 传入到n的类型是整型 且这个函数将会返回一个字符串类型的返回值
return s*n
#内省:程序运行时自我检测的一种机制
times._name_#看名字
times._annotations_
exchange._doc_#查看文档
高阶函数:higher-order function 一个函数将另一个函数作为参数
import functools
def add(x,y):
return x+y
functools.reduce(add,[1,2,3,4,5]) #reduce的作用是将可迭代对象种的元素依次传递到指定函数 最终返回累计的结果 类似于一下函数
add(add(add(add(1,2),3),4),5)
#偏函数 :对指定的函数进行二次包装 将现有的函数部分参数预先绑定从而得到一个新的函数
square = functools.partial(pow,exp=2)
print(square(2))
15.永久储存
#打开文件格式 绝对路径或相对路径
#open(file,mode='r',buffering=None,errors=None,newline=None,closefd=Ture,opener=None)
#文件操作
#f.close()关闭文件对象
#f.flush()将文件对象的缓存数据写入到文件中(不一定有效)
#f.read(size=-1,/)从文件中读取指定的字符,当未指定该参数时或为负数时,读取剩余的所有字符
#f.write(text,/)将字符串写入到文件对象中,并返回写入的字符数量(字符串的长度)
#f.writelines(lines./)将一系列字符串写入到文件对象中(不会自动添加换行符)
#文件关闭时,数据写入到文件中
#-*-coding:gbk-*-
ile=open("fish.txt",mode="w")
ile.write("123")
ile.writelines("456")
ile.close()
m=open("fish.txt",mode="r+")
n=m.readable()
a=m.writable()
for each in m :
print (each)
print(a,n)
print(m.read())#为空 前面for循环已经将文件指针指向末尾
print(m.tell())#告知目前文件指针位置
m.seek(0)#将文件指针指向位置0
路径处理:不同系统路径不一样
#导入模块
#-*-coding:gbk-*-
from pathlib import Path
x=Path.cwd() #获取当前工作目录
print(x)
#x=x/"shijie.text" #注意"/"是路径拼接符 不依赖于系统路径划分符号
print(x)
print(x.is_dir())#判断一个路径是否为一个文件夹
print(x.is_file())#判断一个路径是否为一个文件
print(x.exists())#判断一个文件是否存在
print(x.name)#获取文件路径的最后一个部分
print(x.stem)#获取文件名
print(x.suffix)#获取文件后缀名
print(x.parent)#获取父级目录
print(x.parents)#获取逻辑祖先路径构成的序列 每一级别的目录
print(x.parts)#将路径的各个组件拆分成元组
print(x.stat())#查询文件或者文件夹的信息 此时报错 因为不存在shijie.text
#Path("./doc").resolve()#相对路径转化为绝对路径
#print(x.iterdir())#获取当前路径下所有子文件和子文件夹这个对象
f=x/"shijie"
f.mkdir(exist_ok=True)#创建文件夹 若存在则无法创建 报错 括号中加入 exist_ok=true 则忽略报错
y=open("t.txt",mode="w")
y.write("世界第一")
y.close()
#rename()修改文件名 replace()修改文件夹名
#rmdir()删除文件夹 unlink()删除文件
with语句和上下文管理器
#传统
y=open("one.txt",mode="w")
y.write("世界第一")
y.close()
#with语句
with open ("two","w") as f:#上下文管理器 能够确保资源的释放
f.write("I love you")
"""
y=open("one.txt",mode="w")
y.write("世界第一")
m=1/0
y.close()#错误运行文本文件没有保存内容
with open ("two","w") as f:#上下文管理器 能够确保资源的释放
f.write("I love you")
1/0#错误运行文本文件 保存内容
"""
#pickle模块 允许将字符串、列表、字典保存为文件的格式
#对象序列化:将python对象转换为二进制字节流的过程
#写入
import pickle
x,y,z=1,2,3
s="世界第一"
l=["1",502,1314]
d={"one":1,"two":2}
with open("test.txt","wb") as f:
pickle.dump(x,f)
pickle.dump(y,f)
pickle.dump(z,f)
pickle.dump(l,f)
pickle.dump(s,f)
pickle.dump(d,f)
#读出
import pickle
with open("test.txt","rb") as f:
x=pickle.load(f)
y=pickle.load(f)
z=pickle.load(f)
s=pickle.load(f)
l=pickle.load(f)
d=pickle.load(f)
print(x,y,z,l,s,d)
16.对象=属性+方法
在对象生成以前,我们要创建一个类 一般都是大写字母开头
# -*- coding: gbk -*-
class Tutle:
#属性
head=1
hand=2
eyes=2
shell=True
#方法 其中类中的函数参数必须为self 其可以认为是每个实例化对象默认的ID 集示例对象本身
def crawl(self):
print("开始的时候")
def run(self):
print("虽然开始不会这样了")
def bite(self):
print("开始击打")
def sleep(self):
print("睡觉")
t1=Tutle()#实例化对象
print(t1.eyes)
t2=Tutle()#实例化对象
print(t2.eyes)
t2.eyes=1
print("t2还有{}个眼睛".format(t2.eyes))
t2.body=1#t2单独增加一个属性
print(t2.body)
#继承 通过继承创建的新类我们称之为子类 被继承的类称之为父类
class A:
x=520
def hello(self):
print("世界你好")
class B(A):#继承 在定义的类名后面加上一堆小括号其中为被继承的父类 B为子类 A为父类
pass #表示占位的空语句
b=B()
print(b.hello())
class B(A):#若继承的子类中的属性或方法与父类冲突 则子类中的覆盖父类
x=888
def hello(self):
print("做我自己")
c=B()
print(c.x)
print(c.hello())
#判断一个对象是否属于一个类 isinstance(对象,类) 子类也属于父类 issubclass(A类,B类) 判断A类是否为B类的子类
print(isinstance(c,B))
print(isinstance(c,A))
print(issubclass(B,A))
#多重继承 一个子类可以重复继承多个父类 子类(父类1,父类2,...父类N)优先级依次降低 最高级为父类1
class A:
x=520
def hello(self):
print("世界你好")
class B:
x=888
y=110
def hello(self):
print("做我自己")
class C(A,B):
pass
c=C()
print(c.x)
print(c.y)
print(c.hello())
#组合
class turtle:
def say(self):
print("不积硅步,无以至千里")
class cat:
x=1
def say(self):
print("喵喵喵")
class dog:
def say(self):
print("汪汪汪")
class garden:#开始组合
x=111
t=turtle()
c=cat()
d=dog()
def say(self):
self.t.say()#若不加self那么say调用的就是Garden外部的全局变量,
self.c.say()#加上self,执行Garden这个类名 就会传递给self,让say知道是要调用Garden里面的变量
self.d.say()
g=garden()
print(g.say())
#若我们需要知道当前对象具有那些专有属性 使用对象.__dict__查询 d但是其查询不到原来其固有的属性
g.y=520
print(g.__dict__)
#有函数参数的类的使用
class D:
z=110
def write(self,v):
self.x=v
m=D()
print(m.__dict__)
m.write(50)
print(m.__dict__)
#属性与函数重名
class O:
z=110
def set_z(self,v):
z=v #加上self 才能指定修改该对象的属性
o=O()
o.set_z(520)
print(o.z)
O.z=250#直接修改类的属性 后面固定了
print(O.z)
#最小的类 可以制作成一个字典
class MO:
pass
MO.x=1
MO.y="东方"
MO.z=[1,2,3]
"""
等价于
d={}
d['x']=1
d['y']="东方"
d['z']=[1,2,3]
"""
构造函数:_init_() 个性化定对象 钻石继承
#-*-coding:gbk-*- #构造函数 class C: def __init__(self,x,y): #双下划线 self.x=x self.y=y def add(self): return self.x+self.y def mult(self): return self.x*self.y c=C(2,3) print(c.add()) print(c.mult()) #重写 子类对父类的重写 class D(C): def __init__(self,x,y,z): C.__init__(self,x,y) self.z=z def add(self): return C.add(self)+self.z def mult(self): return C.mult(self)*self.z d=D(2,3,4) print(d.add()) print(d.mult()) #上述未调用未绑定的父类方法 砖石继承: class A: def __init__(self) -> None: print("123") class B1(A): def __init__(self) -> None: super().__init__(self) print("456") class B2(A): def __init__(self) -> None: super().__init__(self) print("789") class C(B1,B2): def __init__(self) -> None: super().__init__(self) super().__init__(self) print('结束啦') c=C() print(c) #-----------下列分开调用----------- #此事A调用了两次 为了避免 要使用super查找父类中指定的方法并自动绑定self参数 见下 #-*-coding:gbk-*- class A: # def __init__(self) -> None: print("123") class B1(A): def __init__(self) -> None: super().__init__() print("456") class B2(A): def __init__(self) -> None: super().__init__() print("789") class C(B1,B2): def __init__(self) -> None: super().__init__() print('结束啦') c=C() print(c) #MRO准则:Method Resolution Order 方法解析顺序 查看方法 类名.mro() 或者 类名.__mro__
Mixin:混入、乱入
#-*-coding:gbk-*-
#任何类都是Object的子类
class Dispaly:
def display(self,message):
print(message)
class LoggerMixin:
def log(self,message,filename="logfile.txt"):
with open(filename,"a") as a:
a.write(message)
def display(self,message):
super().display(message) #若其显式没有父类 则默认为Object类 但此时super()按照MRO顺序进行 及看同级类中
self.log(message)
class MySubClass(LoggerMixin,Dispaly): #从左到右依次继承 同名继承优先级高的类
def log(self, message):
super().log(message,filename="subclasslog.txt")
subclass=MySubClass()
subclass.display("this is test.")
多态:指的是同一函数 、运算符、或对象在不同的场景下具有不同的效果
#-*-coding:gbk-*-
#重写就是类继承的多态
class Shape:
def __init__(self,name) -> None:
self.name=name
def area(self):
pass
class Square(Shape):
def __init__(self,length) -> None:
super().__init__("正方形")
self.length=length
self.area= self.length**2
class Circle(Shape):
def __init__(self,radius) -> None:
super().__init__("圆形")
self.radius=radius
self.area= self.radius**2*3.14
s=Square(4)
c=Circle(2)
def Cir(x):
print(f"我是{x.name},我的面积是{x.area}")
Cir(s)
Cir(c)
#鸭子类型 编程中并不关心对象是什么类型 关心其行为是否符合要求
私有变量:指通过某种手段 ,使得对象中共的属性或方法无法被外部所访问到。
name mangling:名字改变、名称修饰,在名字前加两个连续的下横线
#-*- coding:gbk-*-
class C:
def __init__(self,x) -> None:
self.__x=x
def set_x(self,x):
self.__x=x
def get_x(self):
print(self.__x)
def __func(self):
print("hello world")
c=C(520)
#print(c.__x)#访问不成功 若想访问变量的值 必须通过指定的接口
c.__y=125#可以给实例化对象动态添加私有变量
print(c.__dict__)
print(c.get_x())
print(c.__dict__)
print(c._C__func())#访问私有方法 语法如下: _类名__私有方法()
#_单个下横线开头的变量:仅供内部使用的变量
#单个下划线结尾的变量_:解决变量名与固定的表示符其缓冲作用 例如带你故意变量class_
#为避免利用字典存放属性这种空间上的牺牲 python则设计了__slot__,
class C:
__slots__=["x","y"]#只能存放2个属性 牺牲了动态添加属性的功能
def __init__(self,x) -> None:
self.x=x
c=C(250)
c.y=520
#c.z=666#赋值失败
print(c)
#继承自父类的__solts__属性是不会在子类中生效的 即只对含有他的类中才起作用
class D(C):
pass
d=D(250)#传递到他的父类
print(d.x)
d.z=125
print(d.z)
魔法方法:
#-*- coding:gbk-*-
class CapStr(str):
def __new__(cls,string):#cls为类,string 为实例化传递进去的一个参数
string=string.upper()
return super().__new__(cls,string)
cs=CapStr("Fish")
print(cs)
print(cs.lower())
class C:
def __init__(self) -> None:
print("我来了")
def __del__(self):#当对象即将销毁的时候 也会调用一个魔法方法 __del__(self)
print("我走了")#del方法是在对象销毁之前的最后拦截 #可以实现对象的重生 自己没有实践
c=C()
print(c)
魔法方法 :省略了一部分视频,未看完
#-*- coding:gbk-*-
class S(str):
def __add__(self,other):#cls为类,string 为实例化传递进去的一个参数
return len(self)+len(other)
s1=S("Fish")
s2=S("Python")
s=s1+s2#相当于s1.__add__(s2)
print(s)
ss=s1+"Python"#输出字符串长度
sm="Fish"+s2#拼接字符串
#-*- coding:gbk-*-
from typing import Any
class C:
def __init__(self,name,age):
self.name=name
self.__age=age
c=C("Fsih",16)
print(c.name)
print(c._C__age)#访问私有变量
#魔法方法
hasattr(c,"name")
getattr(c,"name")
getattr(c,"_C__age")
delattr(c,"_C__age")
setattr(c,"_C__age",19)
#修改属性
#-*- coding:gbk-*-
class C:
def __init__(self,name,age):
self.name=name
self.__age=age
def __getattribute__(self, attrname):
print("哪里来的")
return super().__getattribute__(attrname)
c=C("小甲鱼",18)
print(getattr(c,"name"))
print(c._C__age)
property():
#class property(fget=None,fset=None,fdel=None,doc=None)语法格式
#_x:保护变量 __x:私有变量 在输出时属性前可不加下划线
class C:
def __init__(self) :
self._x=250
def getx(self):
return self._x
def setx(self,value):
self._x=value
def delx(self):
del self._x
x=property(getx,setx,delx)
c=C()
print(c._x)
print(c.__dict__)
del c._x
print(c.__dict__)
17.元类:metaclass 通俗来讲,他是创造类的模板 所有的元类都来自于Type
总结
1.解决输出无法使用中文的情况
报错:SyntaxError: Non-UTF-8 code starting with '\xd0' in file D:\pyhton\study1_23\demo.py on line 3, but no encoding declared; see https://peps.python.org/pep-0263/ for details
解决措施:代码文件前部加入以下代码
# -*- coding: gbk -*-
解决结果:
2.双引号和单引号本身无区别,仅在使用中注意格式必须成对出现,若要单独出现,使用转义字符
在含有转义字符的字符串语句前加r可以使其无效化:
print(r"D\think\bin\null")
3.注释:#表示单行注释
用一对连续的三个引号(单引号和双引号都可以)来表示多行注释
4.该语言具有严格的格式要求,其缩进决定了语言之间的缩进关系
5.流程图:用来表示算法或者代码结构层次的框图。
6.逻辑运算符的短路逻辑核心思想:从左往右,只有当第一个操作符的值无法确定逻辑运算的结果时,才对第二个操作数进行求值。
7.跨行表示除了用\表示,还可以用三个连续的引号表示
print("""123456789
123456
123
0""")
8.字符串不可变即同一个字符串只开辟一个存储空间,其变量都指向同一个储存空间。Python对于不同的对象存储机制是不一样的。 列表元素可变的,对元素一样的列表开辟不同的内存来存储,各个变量分别指向存储空间。
i作符:同一性运算符,用于检验两个变量是否指向同一个对象的运算符。
8.列表推导式与循环的区别
循环:通过迭代来逐个修改原列表中的元素
列表推导式:直接创建一个新的列表,然后在赋值给原来的这个变量名
9.保持KISS原则:Keep It Simple &Stupid
10.type()查看元素类型
单独一个下划线_表示匿名变量:主要用来忽略特定的值或者表示某个变量是临时的、不重要
a=5
print(type(a))
11.列表、元组、字符串将其统称为序列
(1)都可以通过索引获取每一个元素
(2)第一个索引值都为0
(3)都可以通过切片获取一个范围
(4)都有很多共同的运算符
其列表可变,元组和字符串不可变
12.异常(exception)
#try-except捕获并处理异常
#try:检测范围
#except[expression[as identifier]]:异常处理代码
try:
1/0
except:
print("出错了")#正确则输出
"""
等价于 expect ZeroDivisionError as e:
print(e)
"""
try:
1/0
except ZeroDivisionError:#还有ValueError,TypeError
print("出错了") #指定出错类才输出
try:
1/0
520+"123"
except ZeroDivisionError:
print("出错了")
except TypeError:
print("类型错误")
except ValueError:
print("值不正确")
#遇到错误直接执行后面的 跳过其他错误类型
#try-except-else 未报错则执行else的
#try-except-finally 无论是否会报错都会执行finally的内容
#异常的嵌套
try:
try:
520+"123"
except :
print("出错了")
1/0
except :
print('再次出错')
raise语句
# -*- coding: gbk -*-
raise ValueError("值不正确")
s="fish"
assert s=="fish" #条件成立不运行
assert s!="fish" #不成立的话运行
#利用异常来实现goto语句
13.OOP编程(object-Oriented Programming)面向对象编程
向造物者一般去思考问题。
面向对象是一种代码封装的方法。
字典处理空间占用大,其余都是优点
14.对象产生的方法:
#__new__(cls[,...])
#先调用__new__()方法,创建一个类的实例
#再将其传递给__init__()方法,再进行个性化定制
#重写__new__()方法的情况不外乎两种情况
#1.在元类中定制类 元类:魔法方法中的魔法方法
#2.在继承不可变数据类型的时候,对其修改
15.垃圾回收机制:Garbage collection
就是一个对象没有任何引用的时候才会将其销毁