自7月3日到今天差不多正好一个月,终于结束了Python的基础语法学习,进度属实是有点慢。暑期在家中时不时就会有一些乱七八糟的事情,但还好跟着课程坚持下来了,起码还在路上嘛。
本部文章中对基础的语法大部分都进行了阐述,并有代码赋上,也可以算是一期保姆文章了。之后如果有补充小编也会给抓紧更新。家人们有建议欢迎评论 ❤️
家人们的每一次支持都是我前进的动力,冲鸭!
为了编程规范,在代码后面至少两个空格后写注释符号
print("hello") #输出hello
选中代码后Ctrl+==/==批量注释,也可以批量解除注释
# print("A")
# print("B")
# print("C")
# print("D")
用三个单引号或者双引号将代码套起来
"""
print("E")
print("F")
print("G")
print("H")
"""
input(“prompt=None”) prompt提示信息,会在控制台中显示,默认值为Nnoe
注意:iuput()会把接收到的用户输入的数据都当做字符串处理,也就是说,input()默认输入的是字符串类型的数据
name=input("请输入姓名:")
print("name:" , name) //请输入姓名:susu
name: susu
基本语法
print(*values,sep="",end="",file=sys.stdout,flush=False)
参数说明:
1.*values
可以依次输出多个值,值与值之间用==,==分离
print("susu", "linlin") #运算结果: susu linlin
print("su", "mao", "lin") #运算结果: su mao lin
2.sep
用来间隔多个值,默认值是空格
print("su", "mao", "lin", sep="!") #运算结果: su!mao!lin
print("su", "mao", "lin", sep="$") #运算结果: su$mao$lin
sep必须在所有的values=之后才可以使用。意味着值与值之间的符号不可以设置不同的。
3.end
用来设置以什么结尾,默认是"\n"
print("susu")
print("maomao")
#运算结果:susu
# maomao
print("susu", end=" and ")
print("maomao") #运算结果:susu and maomao
print("su", "mao", "lin", end="!") #运算结果:su mao lin!
占位符:插在输出位用来占位置的符号(占据位置的,并不是输出的)
<1> %s字符串
name="susu"
word="study python"
print("我的名字: %s" % name) #运算结果: 我的名字: susu
print("%s say %s" % (name, word)) #运算结果: susu say study python
<2> %d(整数)
name="susu"
age=21
print("my name is %s age is %d" % (name, age)) #运算结果: my name is susu age is 21
print("age: %03d" % age) #去结果为三位数 运算结果: age: 021
想要其为x位数可以用%xd
例如:%03d:表示这个整数为三位数,不足三位前面的数字用0补齐。如果实际数字超过三位数,原样输出
<3>%f(浮点数)
num=1.234
print("float:%f" % num) #默认为六位小数 运算结果: float:1.234000
print("float:%.2f" % num) #取两位小数 运算结果: float:1.23
想要其为x位小数可以用%.xf
例如:%.3f:表示这个整数为三位小数,四舍五入
这种方法并不常用,但是我们在学习过程中应该懂得这种方法和思想
print(f"想要输出的东西{变量}")
name="susu"
age=21
print(f"name is {name}, age is {age}") # 运算结果: name is susu, age is 21
可以数学运算:
m=1
n=2
print(f"{m} + {n} ={m+n}") # 运算结果: 1 + 2 =3
可以控制小数精度:
n=1.2345
print(f"n={n:.2f}") # 运算结果: n=1.23 如果为.6f 则结果为1.234500
可以理解为一个容器,计算机中的存储空间。可以用来保存数据(在开始时最好养成编程规范,变量名避免a,b,c此类的,如果代码很多的话重新回来看时自己都不知道定义的是什么)
定义规则:只能以数字、字母、下划线组成(不能以数字开头,不能是内置关键字【是关键字字体颜色会发生变化】),严格区别大小写
例如需求:定义一个变量保存数学成绩,98分
math_score = 98 //=是赋值运算符,专门用来给变量赋值
print(math_score) #print(math_score)被识别为变量名
print("math_score") #print("math_score")被识别为具体的数据,数据类型为字符串
数据类型=数值类型+字符串
1.int整形:任意大小的整数
num=1000
print(num,type(num)) #输出num,num的数值类型 在之后我们想要查看数据类型时都可以使用这种方法
2.float浮点型:带有小数点的数
3.bool布尔型;两个固定值True(真) False(假),通常用于判断
运算时,True相当于1 False相当于0
print(False+1) 运算结果会是0
被引号(单引号,双引号)括起来的就是字符串类型的数据
name="susu"
print(name,type(name)) #输出name,name的数值类型
基本的加减乘除正常使用便可不再赘述±*/
需要注意的就是除法结果一定是浮点数,除数不能为0
2.取整除//取
整数部分向下取整点击此处进入我的另外一篇博客中可以了解向下向上取整
print(10//3) //3
print(10//-3) //-4
3.取余数%(只取余数部分)
m=10
n=3
print(m% n) #1
4.幂运算
m**n #m的n次方
m=2
n=5
print(m**n) # 2的5次方
优先级:()>幂运算>乘、除、取余、取整>加减
同级运算从左到右运算
给变量赋值,在使用的时候,将右侧的值赋给左边的变量
1.基本的=便不再赘述
2.+=加法赋值运算(+=之间不能有空格)
n=1
n+=1 #等效于n=n+1=1+1=2
3.-=减法赋值运算符(-=之间不能有空格)
n=3
n-=2 #等效于n=n-2=3-2=1
== 比较左右两边的值是否相等,相等就返回True,不相等就返回False
!= 比较左右两边的值是否相等,不相等就返回True,相等就返回False
< >就不再赘述
and 左右两边都要满足才为True (有一个值为零,则结果为零)
or 左右两边只要一边满足就为True,即只要其中的一个条件满足就返回真 (所有值为零才为零)
只能在字符串里使用
\t 制表符:四个空格
\n换行符:换行
\\反斜杠符号:\
#字符串内的引号使用会影响系统对于字符串长度的判断,需要注意
print("susu say:\"hello!\"") # 使用 \'来表示' \"来表示"
print('suus say:"hello!"') #或者外面使用单引号,外面使用双引号(外双内单也可以)
print("I'm a student")
print('I\'m a student')
r:取消转义 使字符串默认不转义
print(r"\\\\") //如果不用r的话,输出的应该是\\
基本用法:(如果条件为单纯的一个字符或字符串,数字,则直接为真)
age=19
if age >=18:
printf("可以去网吧")
else:
printf("go out")
if 条件1:
满足条件1做的事情
elif 条件2:
满足条件2做的事情
elif 条件3:
满足条件3做的事情
else:
所有条件都不满足做的事情
#注意:条件都是相关的,如果前面的条件符合,下面的条件就不会再去判断
printf("可以去网吧") if age >=18 else printf("go out")
注意嵌套使用要注意每一级判断的缩进
例题:火车安检需要满足两个需求,有票,体温<37.2
ticket=True
temp=38
if ticket:
print("进站")
if temp<37.2:
print("通过安检")
else:
print("体温异常")
else:
print("无票不能通过")
基本格式:while 循环条件
循环体
改变变量
i=0 #输出五遍susu
while i<5:
print("susu")
i+=1
如果判断条件一直为真,程序就会一直执行下去,点击下图按钮可以终止程序
循环嵌套:
while 条件1: # 外层循环
循环体1
while 条件2: # 内层循环
循环体2
# 注意缩进:缩进决定层级
常用于依次取出字符串(列表、元组、字典、集合)中的元素;执行已知次数的循环
基本格式: for 临时变量 in 可迭代对象: ( 字符串、列表、元组都是可迭代对象 )
循环体
家人们记得加引号,一开始我真的每次都忘记
for i in "susu":
print(i) #注意在print前要有缩进
range(start,end,step) 包前不包后,默认从0开始
start:起始值,可以省略,默认值为0
end:终止值(不包括自身)不能省略
step:步长,即两个数之间的间隔,可以省略,默认值为1
所以当只有一个值时,便是start;两个值时,是start end;
for i in range(3): #从0开始,到3结束,不包括3.
print(i)
for i in range(1,4): #从1开始,到4结束,不包括4.
print(i)
for i in range(1,8,2): #从1开始,到8结束,不包括8,步长为2
print(i)
break:直接退出本级循环
for i in range(0,5,1):
print(f"在吃第{i}个苹果")
if i==2:
print("吃饱了,不吃了")
break
continue:直接退出本次循环,下次循环继续
i=1
while i<5:
print(f"在吃第{i}个苹果")
if i==2:
print(f"第{i}个太软了,不吃了")
i+=1 #此处如果不改变变量,就会一直在第2个循环
continue
i+=1
**break和continue只针对当前所在的循环有效,也就是说在嵌套循环中,只对最近的一层循环起作用 **
for i in range(0,4):
print(f"外循环{i}")
if i==2:
print("停止")
continue
for j in range(0,4):
print(f"内循环{j}") #外循环2会直接结束,开始外循环3
for num_right in range(1,10): #右边的乘数与行数相同,右边的乘数范围到9,打出九行数据,
for line in range(1,10): #一共有9行
if num_right==line: #判断:当行数和右边的乘数相等时才会输出数据
#使用循环输出行的数据
for num_left in range(1, num_right + 1): #range包前不包后,需要i+1
print(f'{num_left}*{num_right}={num_left * num_right}', end="\t") #使用end来分隔行内的数据
while num_left == num_right: #数据输出完毕后进行换行
print("\n")
break #break退出循环,否则会一直进行下去
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}*{i}={j * i}",end="\t")
print("")
li = [1, 2, 3, 4, 5, 6, 7, 8, 9]
sum = 0
for i in li:
sum+=li[i-1]
print(sum)
print(f'"sum="{sum}')
str:字符串数据,我们人可以直接理解
bytes:二进制数据,由计算机理解
endcode():为str类型提供的方法,将str转变为bytes类型
st="我是苏苏"
print(st,type(st))
st2=st.encode()
print(st2,type(st2))
运行结果:
我是苏苏
b’\xe6\x88\x91\xe6\x98\xaf\xe8\x8b\x8f\xe8\x8b\x8f’
decode():为bytes提供的方法,将bytes转变为str类型
st=b'\xe6\x88\x91\xe6\x98\xaf\xe8\x8b\x8f\xe8\x8b\x8f'
st2=st.decode()
print(st2,type(st2)) #我是苏苏
+字符串拼接
print(1+1) #2 整数相加
print("1"+"1") #11 字符串相加
c1="你好"
c2="世界"
print(c1+c2) #你好世界
*重复
print("帅哥\n"*3)
运行结果: 帅哥
帅哥
帅哥
in not in检查字符串中是否包括某个字符
in: 如果包含,就返回True,不包含就返回False
not in: 如果不包含,就返回True,包含就返回False
name="susu"
print("s" in name) # True
print("a" in name) # False
print("a" not in name) #True
Python中下标从0开始(从左到右) 从-1开始(从右到左)
❗ ❗ ❗ 注意注意家人们,字符串是可以直接索引的,不需要使用循环什么的。我是练习小题目时才返回来看知识点意识到的
通过下标快速找到对应的数据 索引不能超过范围
ins="woshisu" 索引不能超过6
print(ins[0]) #w
print(ins[1]) #o
print(ins[-1]) #u
对操作的对象截取其中一部分进行操作
语法[开始下标:结束下标:步长]
切片的下标包前不包后,可以超过范围,步长的符号代表索引方向(正数从左到右,负数从右到左)
ins="woshisu"
print(ins[0:6]) #woshis
print("w" in ins[1:4]) #False
print(ins[-1:-8:-1]) #usihsow
print(ins[:8:2]+ins[1:8:2]) #wsiuohs
检测某个子字符串是否包含在字符串中,如果在返回这个字串开始的位置下标,否则就返回-1
基本语法find(字串,开始下标,结束下标) 包前不包后原则
ins="woshisu"
print(ins.find("s")) #2
print(ins.find("c")) #-1
print(ins.find("h",1,4)) #3
index(): 检测某个子字符串是否包含在字符串中,如果在返回这个字串开始的位置下标,否则就报错
基本语法index(字串,开始下标,结束下标) 包前不包后原则
ins="woshisu"
print(ins.index("s")) #2
print(ins.index("c")) #报错未找到,没有该字符串
print(ins.index("h",0,3)) #报错未找到,包前不包后
count(): 返回某个子串在字符串中出现的次数,没有就返回0
基本语法: count(子字符串, 开始下标, 结束下标) 包前不包后原则
ins="woshisusu"
print(ins.count("s")) #3
print(ins.count("s",0,5)) #1
replace(): 替换
replace(旧内容, 新内容, 替换次数)
purpose="好好学习,天天向上天"
print(purpose.replace("天","时",1)) #修改一次,从左到右进行修改 好好学习,时天向上天
print(purpose.replace("天","时",2)) #修改两次,从左到右进行修改 好好学习,时时向上天
print(purpose.replace("天","时",)) #默认修改为全部修改 好好学习,时时向上时
split():指定分隔符来切字符串
split(分隔符, 分割次数)
purpose="好好学习,天天向上天"
print(purpose.split("学")) # ['好好', '习,天天向上天']
print(purpose.split(",")) # ['好好学习', '天天向上天']
startswith(子串, 开始下标, 结束下标): 判断是否以…开头
endswith(子串, 开始下标, 结束下标): 判断是否以…结尾
ins="woshisusu"
print(ins.startswith("w")) #True
print(ins.endswith("u")) #True
isupper(): 判断字符串中所有字母是否都为大写,是的话就返回True,否则返回False
islower(): 判断字符串中所有字母是否都为小写,是的话就返回True,否则返回False
letter1="ABCD"
print(letter1.isupper()) #True
letter2="abcd"
print(letter2.islower()) #True
letter3="ABcd"
print(letter3.islower()) #False
需求: 检测字符串中有多少个大写字母,有多少个小写字母 `````
letter=input()
print(f"输入字符串为:{letter}")
l=len(letter) #获得字符串长度,即range,例如aaabb,l=3,则需要遍历letter[0][1][2],索引为i,i就需要在range(3)中
let_upper=0
let_lower=0
for i in range(l): #遍历字符串进行大小写判断
if letter[i].isupper()==True:
let_upper+=1
else:
let_lower+=1
print(f"大写字母个数为:{let_upper}")
print(f"小写字母个数为:{let_lower}")
用来处理一组有序项目的数据结构
列表名=[元素,元素,元素,元素,元素](元素与元素之间用逗号隔开,一个列表之间的数据类型可以不同)
a=[1,2,3] #[1, 2, 3]
列表也可以索引,切片,循环遍历
<1>增加元素
append():在末尾追加元素
extend():分散添加,将一个类型中的元素逐个添加
insert():在指定位置添加元素(通过索引)
li=[1,2,3]
li.append("susu")
print(li) #[1, 2, 3, 'susu']
li.append([4,5])
print(li) #[1, 2, 3,'susu', [4, 5]]
li.extend("susu")
print(li) #[1, 2, 3, 'susu', 's', 'u', 's', 'u']
li.insert(2,6)
print(li) #[1, 2, 6, 3, 'susu', 's', 'u', 's', 'u']
<2>删除元素
del():根据下标删除,如果超出范围就报错(可以直接删除整个列表)
remove():根据元素的值进行删除,如果元素不存在就报错
li=[1,2,3,4]
del li[1]
print(li) #[1, 3, 4]
li.remove(3)
print(li) #[1, 4]
del li #删除列表li
print(li) #报错,列表li不存在
<3>改变元素
基本语法:列表名[下标]=值
li=[1,2,3,4]
li[0]="susu"
li[1]=65
print(li) #['susu', 65, 3, 4]
<4>查找元素
还是in not in indexcount 与字符串中的运算符同理,但是这里是在列表中进行查找,也不用把查找元素加引号
li=[1,2,3]
print(1 in li) #True
print(li.index(2)) #1
print(li.count(3)) #1
例题:用户输入名字注册昵称,如果重复不能使用
name=["susu","maomao","linlin"]
while True: #当昵称重复时便会一直循环直到注册成功
scanf = input()
if scanf in name:
print("昵称重复,请重新输入")
else:
print("昵称注册成功")
name.append(scanf) #注册成功后更新name
break #注册成功后退出循环
sort()默认按照从小到大的顺序排列
reverse()将列表倒置,反过来
li = [1,4,6,8,5,2]
li.sort()
print(li) #[1, 2, 4, 5, 6, 8]
li.reverse()
print(li) #[8, 6, 5, 4, 2, 1]
li=[1,2,3,[4,5,6]]
print(li[1]) #2
print(li[3][0]) #4
将下面列表中的元素去重。
a_list=[1, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 3, 5, 2]
a_list=[1, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 3, 5, 2]
s=set(a_list)
a_list=list(s)
print(a_list)
元组名=(元素,元素,元素)
其元素数据可以为不同的类型:数值类型、字符串、列表、元组、字典、集合
如果元组内的元素只有一个时,元素后面必须加==,==
tu=(1,2,"susu")
print(tu[1]) #2
print(tu[-1]) #susu
元组不支持增删改,只可以进行查找操作。也支持循环遍历等等
查找依然通过in not in index count 进行查找,用法与字符串、列表相同
ins1=("bingbing",19)
ins2=("susu",20)
print("我是%s,年龄是%d" % ins1) #我是bingbing,年龄是19
print("我是%s,年龄是%d" % ins2) #我是susu,年龄是20
字典名=(键:值,键:值)
字典的元素以键值对的形式存在,键与值用 : 分隔,
键值对与键值对**,**用分割
dic={"name":"susu","age":21}
print(dic) #{'name': 'susu', 'age': 21}
字典中的键名不能为集合、字典、列表。键名不能重复,如果重复后面的键值对会覆盖之前的
字典名[键名]=值
dic={"name":"susu","age":21}
dic["sex"]="man"
print(dic) #{'name': 'susu', 'age': 21, 'sex': 'man'}
(1)del
dic={"name":"susu","age":21}
del dic["name"]
print(dic) #{'age': 21}
#也可以del dic 直接删除这个元组,但是再打印时就会报错,显示查找不到元组,也不能向元组内添加元素
(2)clear:删除元组内的元素,但是不会删除元组,依然可以向内添加元素
dic={"name":"susu","age":21}
dic.clear()
print(dic) #{}
dic["school"]="hgd"
print(dic) #{'school': 'hgd'}
dic={"name":"susu","age":21}
dic["age"]=20
print(dic) #{'name': 'susu', 'age': 20}
字典名[键名] 字典名.get(键名)
dic={"name":"susu","age":21}
print(dic["name"]) #susu
print(dic.get("name")) #susu
dic = {"name": '小明', "age": 25, "sex": "男", "height": 1.78, "remark": "在线征婚"}
for i in dic:
print(i)
#运行结果 name
age
sex
height 可以看出只输出了键名
remark
dic = {"name": '小明', "age": 25, "sex": "男", "height": 1.78, "remark": "在线征婚"}
print(dic.keys()) #dict_keys(['name', 'age', 'sex', 'height', 'remark'])
for i in dic.keys():
print(i)
#运行结果 name
age
sex
height
remark
dic = {"name": '小明', "age": 25, "sex": "男", "height": 1.78, "remark": "在线征婚"}
print(dic.values()) #dict_values(['小明', 25, '男', 1.78, '在线征婚'])
for i in dic.values():
print(i)
#运行结果 小明
25
男
1.78
在线征婚
dic = {"name": '小明', "age": 25, "sex": "男", "height": 1.78, "remark": "在线征婚"}
print(dic.items()) #dict_items([('name', '小明'), ('age', 25), ('sex', '男'), ('height', 1.78), ('remark', '在线征婚')])
for i in dic.items():
print(i)
#运行结果('name', '小明')
('age', 25)
('sex', '男')
('height', 1.78)
('remark', '在线征婚')
有如下值集合[11, 22, 33, 44, 55, 66, 77, 88, 99, 90],将所有大于或等于66的值保存至字典的第一个key中,将小于66的值保存至第二个key的值中。
li=[11,22,33,44,55,66,77,88,99,90]
dic={}
list1=[]
list2=[]
for i in li:
if i>=66:
list1.append(i)
dic["key1"] = list1
else:
list2.append(i)
dic["key2"] = list2
print(dic)
集合名={元素,元素,元素} 集合中的元素不能是集合,字典,元组
a={1,2,3}
print(a,type(a)) #{1, 2, 3}
b=set()
print(b,type(b)) #set()
m={"a","b","c","a","b"}
n={1,2,3,4,5}
print(m) #{'c', 'b', 'a'}
print(n) #{1, 2, 3, 4, 5}
集合有自动去重功能,所以,当集合内添加的数据是当前集合已有数据的话,就不进行任何操作
add
m={"a","b","c"}
m.add(55)
print(m) #{'b', 'c', 'a', 55} #集合具有无序性,也意味着不能使用索引
update
将数据拆分逐个加入到集合中
m={"a","b","c"}
m.update([5,7,6])
print(m) #{5, 6, 7, 'c', 'a', 'b'}
m.update("sml")
print(m) #{5, 6, 7, 'c', 'm', 'l', 's', 'a', 'b'} #无序性
remove
m={"a","b","c"}
m.remove("a")
print(m) #{'c', 'b'}
m.remove("d")
print(m) #报错,无元素d
discard
m={"a","b","c"}
m.discard("a") #discard删除指定元素,如果没有该元素不进行任何操作
print(m) #{'c', 'b'}
m.discard("d")
print(m) #{'c', 'b'}
m={"a","b","c",2,1}
n={1,2,3,4,5}
print(m&n) #{1, 2}
print(m|n) #{'c', 1, 2, 3, 4, 5, 'b', 'a'}
int(x)
将x转换为一个整型数据,只能转换由纯数字组成的字符串。
输入的数字为123,那为什么会报错呢。这里大家回忆一下input的输出元素是字符串类型,很明显字符串类型与整型数据是不能比较的,所以会爆红。(此外强转int中如果有数字或者正负号以外的字符也会报错。)
num=int(input("请输入数据:"))
if num==123:
print("输入正确")
str():强转字符串,任何类型都可以强转字符串
eval():可以理解为将str数据去掉引号,它可以实现字符串类型与其他数据类型之间的转换
num=10.5
num1=int(num)
print(num1) #10
num2=float(num)
print(num2) #10.5
bun='[1,2,3]'
print(bun,type(bun)) #[1,2,3]
bun1=eval(bun)
print(bun1,type(bun1)) #[1, 2, 3]
tuple() list() chr()
其中只有float,char,int,str还比较常用
例如:li=li1
如果li1改变,那么li的值我们即使没有操作过也会改变
li=[1,2,3]
li1=li
li.append(5)
print(li) #[1, 2, 3, 5]
print(li1) #[1, 2, 3, 5]
赋值等于完全共享资源,一个值的改变完全被另一个值共享
数据半共享简单从结果来说,只有最外层的数据不会共享,嵌套内的都会共享
import copy
li=[1,2,3,[4,5]]
li1=copy.copy(li) #浅拷贝,引用的copy模块中的copy方法
print (li) #[1, 2, 3, [4, 5]]
print (li1) #[1, 2, 3, [4, 5]]
li.append(6) #添加元素6
print (li) #[1, 2, 3, [4, 5], 6]
print (li1) #[1, 2, 3, [4, 5]]
print(id(li)) #2771963033480
print(id(li1)) #2771963033928 内存地址不一样,是不同对象
li[3].append(7) #在嵌套列表中添加元素7
print (li) #[1, 2, 3, [4, 5, 7], 6]
print (li1) #[1, 2, 3, [4, 5, 7]]
print(id(li[3])) #2771963033416
print(id(li1[3])) #2771963033416 嵌套内的数据内存地址一样,是相同对象
我们看一下查看的4个id地址,第一次查看的li和li1的id地址不同,说明她们俩不是一个对象,里面的内容不相同也就可以理解。第二次查看的li[3]也就是嵌套列表内的地址是相同的,所以这就是为什么浅拷贝中嵌套列表的元素是共享的。
==完全不共享:==把数据嵌套外层的对象和内部的元素全都拷贝了一遍
import copy
li=[1,2,3,[4,5]]
li1=copy.deepcopy(li) #深拷贝,引用的copy模块中的deepcopy方法
print(id(li)) #1613543651080
print(id(li1)) #1613543651528 内存地址不一样,是不同对象
li[3].append(7) #在嵌套列表中添加元素7
print(id(li[3])) #2341695301448
print(id(li1[3])) #2341695316296 内存地址不一样,是不同对象
无论是否嵌套,其内存地址都不相同,所以深拷贝完全不共享
存储空间保存的数据可以被修改 dic,list,set
可变类型就是变量对应的值可以改变,但是内存地址保持不变
s={1,2,3}
print(id(s)) #3017877126280
s.add(4)
print(id(s)) #3017877126280
存储空间保存的数据不可以被修改
数值类型:int float bool complex 字符串类型:char 元组类型:tumple都是不可变类型
n=1
print(id(n))
n=2 #重新赋值,修改n的值会生成一个新的值,重新赋值给变量n
print(id(n))
st="hello world"
print(id(st))
st="hello" #注意字符串类型也是不能够修改的,只能是进行重新赋值
print(id(st))
不可变类型从本质上来说就是变量对应的不能改变,如果修改就只能生成一个新的值从而分配新的内存空间。
简单来说,函数就是一堆可以完成某项功能的代码,在需要的时候再去调用,可以反复使用。
例题:定义一个欢迎新同学的函数,并调用
def welcome_new(): #定义函数
print("你好")
print("我是susu")
print("欢迎你的到来")
welcome_new() #调用函数
函数执行结束之后,给调用者返回一个结果
函数如果有返回值,就需要通过print()打印返回结果
def sum():
a=1
b=2
return a+b #返回值
print(sum()) #3
并不是所有函数都需要返回值,当函数中没有返回值时,返回值为None
实质上打印函数时def sum():,会先打印出函数的结果,再打印返回值
def sum():
print(123)
print(sum())
def sum():
a=1
b=2
return a+b
print(456) #没有被执行,在return处就结束了
print(sum()) #3
def sum():
return 123,456 #当有多个返回值时,输出结果为元组类型
print(sum(),type(sum())) #(123, 456)
形参:函数定义时,小括号里面的变量
实参:调用函数时,小括号里面具体传的值
def sum(a,b): #a,b为形参
return a+b
print(sum(1,2)) #3 1,2为实参
print(sum(3,2)) #5 3,2为实参
函数的传参就是将实参的值传给形参的过程(形参和实参的个数必须相等,顺序对应)
def ins(name,age,sex):
return f"我是{name},今年{age}岁,性别{sex}"
print(ins("susu","20","nan")) #我是susu,今年20岁,性别nan
print(ins("linlin",21,"nv")) # 我是linlin,今年21岁,性别nv
#susu传到了name,20传到了age,nan传到了sex
为形参赋值,调用函数时就可以不传该形参的值。(注意需要传参的形参必须要在不需要传参的形参前面)如果有形参已经被赋值,但实参也有赋值,则使用实参
def ins(name,age,sex="nan"):
return f"我是{name},今年{age}岁,性别{sex}"
print(ins("susu","20",)) #我是susu,今年20岁,性别nan
print(ins("linlin",21,"nv")) # 我是linlin,今年21岁,性别nv
也叫万能参数
传入的值的数量是可以改变的,可以为一个,也可以为很多个
格式:
def ins(*args): #args为普通形参名,约定使用args,可以改为其他,*才表示任意
print (args)
ins(1,2,3) #(1, 2, 3)
ins(1,2,) #(1, 2)
def func(*args):
print(*args)
func(1,2,3,4) #1 2 3 4
属于可变参数,通过**kwargs接受关键字参数然后将其转换成一个字典赋值给kwargs这个普通形参
def ins(**kwargs):
print (kwargs)
ins(name="susu") #{'name': 'susu'}
ins(name="susu",age=18) #{'name': 'susu', 'age': 18}
也可以不通过kwargs
def func(name,age):
print(f"{name},{age}")
func(age="17",name='suus') #suus,17
可以通过关键字传参,即使顺序不对,结果也是正常的
顾名思义,就是变量可以生效的范围
在函数体内部临时保存数据,当函数调用完成后,则在内存中释放局部变量
def ins():
a=100 #a在函数内部定义,是一个局部变量
print(a)
ins() #100
print(a) #报错
在函数体外部定义的变量,在函数体内外都能生效,整个py文件窦娥能使用
a=100 #全局变量
def ins():
print(a)
ins() #100
print(a) #100
如果函数体内有赋值,则使用函数体内的。如果没有则往上寻找最近的全局变量
a=90
a=100 #全局变量
def ins():
a=120 #局部变量
print(a)
ins() #120
print(a) #100
在函数体内部使用global修改全局变量的值
a=100
def ins():
global a #修改全局变量a的值
a=120
print(a)
ins() #120
print(a) #120
注意如果没有运行函数之前全局变量a是不会改变的。如果没有ins()直接print(a),打印出的a还是100。
def ins():
global a #将局部变量a声明为全局变量
a=120
print(a)
ins() #120
print(a) #120 原本打印a是会报错的,但在将a变为全局变量后就允许了
小例题:
def funa():
a=120
print(a)
def funb():
global a
a=150
print(a)
a=100
funa() #120
print(a) #100
funb() #150
print(a) #150
将变量声明为外层变量(意味着nonlocal必须在嵌套函数中使用)
如果函数内部需要使用变量,会先从函数内部找,有的话直接使用,没有就往上一层找
加深理解
1
def outer():
a=10
def inner():
nonlocal a #此处的nonlocal意思为将a=10变为a=5
a=5
print("内部函数",a) #直接调用inner函数内的a=5
inner()
print("外部函数", a) #直接调用outer函数内的a=10,但是因为nonlocal变为了5
outer()
2
def outer():
a=5
def inner():
nonlocal a
a=20
def inner1():
a=30
print("内层函数1a=",a) #直接调用inner1函数内的a=30
inner1()
print("内层函数a=",a) #直接调用inner函数内的a=20
inner()
print("外层函数a=",a) 直接调用函数内的a=5,但是因为nonlocal变为了20
outer()
def outer():
a=5
def inner():
nonlocal a #在执行这里时a已经等于30,而不是20。再将其赋值给a=5中的a
a=20
def inner1():
nonlocal a
a=30
print("内层函数1a=",a)
inner1()
print("内层函数a=",a)
inner()
print("外层函数a=",a)
outer()
有理解不了的家人可以自己多debug一下,理解一下执行的顺序。
1.定义一个函数,判断传入的参数对象(字符串、列表、元组)长度是否大于5,并调用该函数。
def judge(ele):
l=len(ele)
print(l)
e=[1,2,3,4,5]
judge(e)
2.定义一个根据身高、体重计算BMI指数的函数fun_bmi(),该函数包括3个参数,分别用于指定姓名、身高和体重,再根据公式:BMI=体重/(身高*身高),计算BMI指数,并输出结果。
注意:
BMI指数小于18.5,体重过轻;
BMI指数在18.5-24.9之间,体重正常;
BMI指数在24.9-29.9之间,体重较重;
BMI指数大于29.9,需要减肥啦。
def fun_bmi(name,height,weight):
BMI=weight/(height*height)
print(f"{name}的bmi为{BMI}")
if BMI<18.5:
print("体重过轻")
elif BMI<24.9:
print("体重正常")
elif BMI<29.9:
print("体重偏重")
else:
print("需要减肥了")
n=input("请输入姓名:")
h=float(input("请输入身高为__米:"))
w=float(input("请输入体重为__公斤:"))
fun_bmi(n,h,w)
是程序执行过程中检测到错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常。”
NameError:使用了一个未被赋值的变量
SyntaxError:代码不符合python的语法规定
IndexError:下标/索引超出范围
ZeroDivisionError:除数为0
KeyError:字典中不存在这个键盘
IOError:输入/输出操作失败,基本上是因为无法打开文件(比如你要读的文件不存在)
AttributeError:对象没有这个属性
ValueError:传入的值有错误
TypeError:类型错误,传入的类型不匹配
ImportError:无法引入模块或包,基本上是因为路径问题或名称错误
IndentationError:缩进错误,代码没有正确对齐
==Traceback:==异常的追踪信息,可以追溯到程序异常的具体位置
刚开始时我是认为这个东西是超级没用的,因为错误信息都给到了Traceback,为什么还要多此一举专门搞一个这个呢。最后耐着性子学完后还是感觉有点香的啊家人们哈哈哈。因为最后让我似乎明白了这些编译器他们是如何将错误信息来显示出来的,话不多说开始展示。
try:
输入可能异常的代码(一般只有一行)
except 异常类型: #(异常类型可以省略)
如果异常需要执行的代码
1
a=int(input("输入被除数"))
b=int(input("输入除数"))
print(a/b) #这是一个简单的除法,我们都直到除数是不可以为0的,所以用0来测试捕获异常
a=int(input("输入被除数")) #4
b=int(input("输入除数")) #0
try:
print(a/b)
except ZeroDivisionError: #只捕获除0错误
print("此行有问题")
如果正常执行,是会直接报错的,但是使用异常捕获后如果异常则会执行except代码
异常类型则是我们想要捕获的异常类型,比如上例中是除0错误,如果我们想要捕获类型错误的话会报错。
a=int(input("输入被除数")) #4
b=int(input("输入除数")) #0
try:
print(a/b)
except TypeError: #只捕获类型错误
print("此行有问题")
如果想要捕获多种错误,可以将异常类型放入一个元组中或使用Exception万能异常(但不是任何异常都可以捕获,例如语法错误<比如没有缩进>,标识符错误<比如小括号使用的是中文的>是不能捕获的)
try:
print(a/b)
except (TypeError,NameError):
print("此行有问题")
#或
try:
print(a/b)
except Exception:
print("此行有问题")
而Exception的最大意义就是可以捕获到错误类型,并将其赋给变量
a=int(input("输入被除数")) #4
b=int(input("输入除数")) #0
try:
print(a/b)
except Exception as e :
print("此行有问题")
print("错误提示:",e)
这样的话我们是不是就可以稍微理解编译器可以理解代码执行错误的提示是如何实现的了呢
此外还会有另外一种格式
try:
可能报错的代码
except:
代码异常的情况下要执行的代码
else:
代码无异常的情况下要执行的代码
finally:
无论是否异常都会执行的代码
从字面理解来看try和else都是在无异常的情况下执行的代码,我们可以跑一跑验证一下
a=int(input("输入被除数")) #4
b=int(input("输入除数")) #0
try:
print(a/b)
except:
print("代码错误")
else:
print("代码无异常")
finally:
print("执行完毕")
finally则是无论是否异常都会执行。现在我的理解便是可以在finally的代码写为将文件关闭。因为有时候无论是否执行成功,都是需要先将文件关闭的,因为会一直占用电脑的资源。
1.提示用户输入性别,如果非"男"非"女",抛出异常并处理。
s = input("请输入性别:")
def judge(sex):
if s=="男":
print("性别为男")
elif s=="女":
print("性别为女")
elif s!="男"and s!="女":
raise Exception("非男非女")
try:
judge(s)
except Exception as e:
print(e)
2.编写一个计算减法的函数,当第一个数小于第二个数时,抛出“被减数不能小于减数"的异常,并进行捕获处理。
def substruction(num1,num2):
if num1<num2:
raise Exception("被减数不能小于减数")
print(f"{num1}-{num2}={num1-num2}")
try:
substruction(1,3)
except Exception as e:
print(e)
一个py文件就是一个模块
内置模块:如拷贝中提到的copy。
第三方模块:如request。使用前需要下载安装,可以通过指令实现:pip install 模块名
自定义模块:自定义模块命名尽量不要与第三方模块或者内置模块起冲突,否则会导致模块功能无法使用
可以在程序的任意位置使用,一般在文件的开头写,同一个模块只需要导入一次
语法: import 模块名 as 别名 (as 别名 可加可不加) #导入模块的所有内容
也可以一次性导入多个模块,模块之间用逗号隔开。但是这种方法并不推荐,最好是一个模块一个模块依次导入
但是很明显我们经常只需要导入模块的一部分就可以,所以还有另外一种格式
语法:
from 模块名 import 功能名
功能
from abcdefg import fun,a #导入abcdefg模块中的fun()函数,a变量
fun() #调用函数 不需要加前缀
print("a=",a)
也可以使用from的方法调用模块的所有内容(不能说鸡肋,因为这样调用功能可以不用加前缀嘛,可以偷懒)
from abcdefg import *
fun()
print("a=",a)
但是使用第二种方法是需要注意,如果有两个模块中需要调用的功能重名,那么后调用的会直接覆盖先调用的。
from cheng import fun
from cheng1 import fun
fun()
#正常来说会显示两个模块中的fun()函数,但是只会显示出cheng1中的fun()函数
#解决方法也很简单,就是导入一个模块后就使用功能,然后再导入第二个来使用。或者直接使用第一种方法
该说不说,还是有点鸡肋哈哈哈。但是我们总要知道是怎么回事嘛,多了解了解。
程序员呢,尤其是对于我们这种新手来说,每写一段代码都需要来测试一下自己的代码是否正确。但是有时候代码段中会有其他模块中导入的功能。功能中的一些测试代码我们明显并不想运行。那么如何进行控制呢
这时候就可以在其他模块功能的测试代码中加入一个判断语句。下面是两个模块中的代码
BIAN.py
import cheng1
cheng1.fun() #运行结果:cheng1 而不是两行cheng1。这说明测试代码并没有运行
cheng1.py
def fun():
print("cheng1")
print(__name__)
if __name__ == "__main__":
#测试代码
fun() #要验证定义函数是否正确就需要测试一下,但在BIAN.py模块中我们并不想执行这行代码,就加上了上面的判断语句
这个判断语句的原理:
__name__本质上是一个变量,如果是在本模块中时__name__的值是 ,但是如果在其它模块中被导入时__name__的值就变为了被导入模块的模块名
还是举一个简单的例子
BIAN.py
import cheng1
注意注意 ❗️ ❗️ ❗️ ❗️ ,运行结果中的cheng1并不是被调用了函数,我们没有调用函数。这是输出的被调用的cheng1模块的模块名
家人们,终于要结束python的基础语法篇了,这段期间算是对之前大一大二的贪玩买单吧,即使之前没有学习过python,但是基础语法上还是有很多的相似之处。查缺补漏了一番,感觉自己收获还是挺多的,不管是知识上,还是对编程的理解上。还是能感觉到自己有进步的字数也达到了10000字以上,写完之后把自己也吓了一跳,有一种写暑假作业的感觉哈哈哈。
接下来会进行面向对象的学习,意味着又要断更一段时间啦。大家加油