搭建环境
**python官网:**https://www.python.org/
PyCharm:
设置模板:
file->settings->Editer->file and code template->python Script
print()函数
print()函数可以输出的内容:
- 可以是数字
- 字符串(双引号或单引号)
- 可以是含有运算符的表达式
print(123) print('asdbf') print("asdbf") print(1+2) #输出3 #以上都是换行输出 #不换行格式为; print('hello','world','python')
print()函数可以将内容输出到目的地
- 控制台
- 文件
#将数据输出到文件中
fp=open('D:/text.txt','a+')#如果文件存在则追加内容,文件不存在则创建
#fp是个变量(不用类型定义,直接用,符合标识符命名规则就行)
print('helloWord',file=fp) #file是关键字
fp.close()
转义字符:
#反斜杠+想要实现功能的首字母
# \\反斜杠
# \'单引
# \"双引
# \n换行
# \r回车(return) 即不打印\r之前的内容
# \t水平制表符(tab) 一个\t占4个字符的位置
# \b退格(back)即尾部删一个字符
#原字符 不希望转义字符起作用就使用原字符 即在字符串前加上r或R
print(r'hello\nworld') #注:最后一个字符不能是反斜杠(可以是两个反斜杠)
二进制与字符编码
8bit=1byte 1k=1024byte
print(chr(0b10001110)) #chr() 输出这个数字所对应的字符(0b代表二进制)
print(ord('乘')) #ord() 以十进制形式输出'乘'字所对应的unicode码值
标识符和保留字
#查看保留字
import keyword
print(keyword.kwlist)
标识符命名规则和c一样
变量的定义和使用
变量由三部分组成:
- 标识:表示对象所存储的内存地址,使用内置函数id(obj)来获取
- 类型:表示的是对象的数据类型,使用内置函数type(obj)来获取
- 值:表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出
数据类型:
-
int
- 默认十进制
- 二进制->0b
- 八进制->0o
- 十六进制->0x
-
float
- 浮点数计算有时候不精确
- 若不精确则要导入Decimal模块
from decimal import Decimal print(Decimal(1.1)+Decimal(2.2))
-
bool :(满足非0为真)
- true表示1 false表示0
- 是可以计算的
-
str :
- 用双引,单引,三引号括起来
- 三引可以多行写
str1='asdggsa' str2="asbjasf" str3_1=""" gysadf saff ksaud """ str3_2=''' asgd sdg dg '''
数据类型转换
name='张三' age=20 #加号在这里是连接符 print("我叫"+name+"今年"+age+"岁")#会报错str类型与int类型无法连接 #解决方案 :将int转为str类型 print("我叫"+name+"今年"+str(age)+"岁") #float() int() 同理
注释:
# 单行注释
''' '''多行注释
#coding:utf-8 中文编码声明
input函数:
name=input('请输入名字')#括号中的内容为提示语 input赋值得到的是str类型
age=int(input("请输入年龄"))#转换为int类型
常用运算符
- 算术运算符
-
标准算术运算符:加(+)减(-)乘(*)除(/)整除(//)
特殊:一正一负向下取整
-
取余运算符 %
特殊:一正一负要按公式来 余数=被除数-除数*商
-
幂运算符 **
-
- 赋值运算符
a=b=c=20 #+= -= *= /= %= //= a,b,c=10,20,30
- 比较运算符(比较结果为bool类型)
>,<,<=,>=,!= #对象value的比较 == #对象value的比较 is , is not #对象id的比较 a=b=10 print(a is b)
- 布尔运算符
#对于bool值之间的运算 #and 与 #or 或 #not 取反 #in/not in 判断你要的序列是否在指定序列中
- 位运算符
#按位与& 两个数的补码 对应位相同为1,不同为0
#按位或| 两个数的补码 对应位相同为0,不同为1
#左移<< 高位溢出则舍弃,低位补0
#右移>> 低位溢出则舍弃,高位补0
运算符优先级
有括号先算括号
算术运算符->位运算->比较运算->布尔运算->赋值运算
顺序结构
程序从上往下顺序地执行代码,中间没有任何的判断和跳转,知道程序结束
循环结构
- **range()函数:**用于生成一个整数序列
#创建range()对象的三种方式
range(stop) #创建一个(0,stop)之间的整数序列,步长为1
r=range(10) #[0,1,2,3,4,5,6,7,8,9,10],默认从0开始,默认步长为1
print(r) #输出range(0,10)
print(list(r)) #用于查看range对象中的整数序列
range(start,stop)#创建一个(start,stop)之间的整数序列,步长为1
r=range(1,10)#从1开始,到10结束,默认步长为1
range(start,stop,step)#创建一个(start,stop)之间的整数序列,步长为step
r=range(1,10,2)#从1开始,到10结束,步长为2
-
返回值是一个迭代器对象
-
**range类型的优点:**不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,
因为仅仅需要存储start,.stop和step,只有当用到range对象时,才会去计算序列中的相关元素 -
in与not in判断整数序列中是否存在(不存在)指定的整数
r=[1,2,3,4,5,6] print(10 in r)#false print(10 not in r)#true print(5 in r)#true
循环的分类
- while循环
a=10; while a<10: #满足非零为真 print(a) a+=1 #首行不缩进则认为语句不在循环体内
- for in循环
'''for in遍历的对象必须是可迭代对象(字符串,序列)''' for item in 'Python': #第一次取出P 赋值给item,然后输出;接着取出y... print(item) for item in range(10): print(item) #0,1,2,3,4,5,6,7,8,9 #如果在for in中不需要用到自定义变量,可将自定义变量写为"_" for _ in range(5) print('人生苦短,我用Python') #输出5次
**break:**跳出循环,跳出if else
**continue:**结束当前循环,进入下一次循环
分支结构
if age>=18 and age<=35: #冒号
print(age,'0x-',id(age),type(age))#注意要缩进
elif age>35:
print("转行")
else:
print("年龄太小")
条件表达式
x if a>b else y
#条件为真返回x,为假返回y
#x和y可以换成语句
pass语句
语句什么都不做,只是一个占位符在搭建语法结构,还没想好代码怎么写的时候用
a=input('你是应届生吗?y/n')
if a==y:
pass
else:
pass
else语句:
-
if条件表达式不成立时执行else
-
与while或for配合使用时,一整套循环执行完就执行else,如果过程中碰到break则else不再执行
列表:
列表是一个容器可以存储很多个数据槽,类似于数组但是它可存不同类型的数据
索引:相当于数组下标
Mylst=['hello','world',98]
print(id(Mylst))#输出列表的地址
print(type(Mylst))#输出<class 'list'>
print(Mylst)#输出列表的值
#创建方式
#方括号或调用内置函数list()
myList1=['aa','mm',98]
myList2=list(['aa','mm',98])
print(myList[0])#打印myList的第一个元素
列表的查询:
index()
- 如果要查询的列表中存在N个相同元素,只返回第一个元素的索引
- 如果查询的元素在列表中不存在,则会抛出ValueError
- 还可以在指定的start和stop间查询
mylst=["hello","world",98,"hello"]
print(mylst.index('hello'))# 0
print(mylst.index("hello",1,3))#从[1,3)中查找,不包括3
切片操作
#语法:lst[start:stop:step]
mylist=[10,20,30,40,50,60,70]
print(mylist[1:5:1])#切出20,30,40,50,60
注:
- 切出来的是一个新的列表对象
- 不写步长则默认步长为1
- step为正数[:start:stop]或[start::step]
- step为负数[stop::step]或[start::step]
判断指定元素是否在列表中
元素 in 列表名
元素 not in 列表名
mylst=[1,2,3,4]
print(1 not in mylst)#false
#列表元素的遍历
for item in mylist
print(item)
列表元素的增删改
增:
- append()在列表的末尾添加一个元素
- extend()在列表的末尾至少添加一个元素 extern(mylist2) 添加的要是可迭代的
- insert()在列表的任意位置添加一个元素 insert(位置,数据)
- 切片在列表的任意位置添加至少一个元素
删:
-
remove() 参数是值
- 一次只删除一个元素
- 重复元素只删除一个
- 元素不存在抛出ValueError
-
pop() 参数是索引
- 删除一个指定索引位置上的元素
- 指定索引不存在则抛出ValueError
- 不指定索引则删除最后一个元素
-
切片:一次至少删除一个元素
-
clear():清空列表
-
del: 删除列表
lst.clear()#清除列表中的所有元素 del lst#将列表对象删除
改:
#直接覆盖或者切片来改值
lst=[1,2,3,4]
lst[1:3]=[98,99,100]
print(lst)#[1,98,99,100,4]
列表元素的排序操作
常见的两种方式:
- 调用sort(),可使列表中所有元素默认按照从小到大的顺序进行排列,也可指定reverse=True,降序排列
- 调用内置函数sorted(),可以指定reverse=True,进行降序排序,原列表不发送改变。它会产生一个新的列表对象
lst=[1,2,9,4,5,3]
lst.sort()'''升序'''
print(lst)#[1,2,3,4,5,9]
lst.sort(reverse=True)#降序
lst=[5,4,3,2,1]
new_lst=storted(lst)#升序
print(lst)#[5,4,3,2,1]
print(new_lst)#[1,2,3,4,5]
desc_lst=storted(lst,reverse=True)#降序
列表生成式
可理解为“生成列表的公式”
#语法格式
#[带i的表达式 for i in range(1,10)] i是变量
lst1=[i for i in range(1,10)]#[1,10)
print(lst1)#[1,2,3,4,5,6,7,8,9]
lst2=[i*2 for i in range(1,10)]
print(lst2)#[2,4,6,8,10,12,14,16,18]
字典
什么是字典?(可理解为结构体数组)
- 字典是Python内置的数据结构之一,与列表一样是一个可变序列
- 以键值对的方式存储数据,字典是一个无序的序列
放在字典中的键必须是个不可变序列(即不可增删改)
存储位置是底层调用哈希函数算出来的,并不是按顺序存
字典的创建
#最常用的方法:用花括号
scores={'张三':100,'李四':98,'王五',45}
#使用内置函数dict()
dict(name='jack',age=20) #等号左边是键等号右边是值
字典的常用操作
-
字典中元素的获取
#①:[] scores[张三] #②:get() scores.get('张三')
-
[]取值与使用get()取值的区别
- []如果字典中不存在指定的key,抛出keyError异常
- get()方法取值,如果字典中不存在指定的key,并不会抛出keyError而是返回None可以通过参数设置默认的value,以便指定的key不存在时返回
scores={'张三':100,'李四':120,'赵五':125} print(['张三'])#100 print(scores.get('张三'))#100
key的判断
in/not in
scores={'张三':100,'李四':120,'赵五':125}
print('张三' in scores)
print('张三' not in scores)
key增删
scores={'张三':100,'李四':120,'赵五':125}
#删
del scores['张三']#删除指定的key-value对
scores.clear()#清空字典的元素
#增
scores['陈六']=99
#改
scores['陈六']=89
获取字典视图的三个方法
- keys()->获取字典中所有的key
- values()->获取字典中所有的value
- items()->获取字典中所有key-value对
scores={'张三':100,'李四':120,'麻五':125} mykeys=scores.keys() print(mykeys) print(type(mykeys)) print(list(mykeys))#将所有的key组成的视图转成列表 #values() items()同理 myitems=scores.items() print(list(myitems))#转换之后得到的列表元素是由元组()组成的 #[('张三',100),('李四',120),('麻五',125)]
字典元素的遍历
#输出字典中所有的键
for item in scores:
print(item)
#获取键和值
for item in scores:
print(item,scores[item])
字典的特点:
- 字典中所有元素都是一个键值对,key不允许重复,value可以重复(key重复的话会出现覆盖)
- 字典中的元素是无序的
- 字典中的key必须是不可变对象(整数,字符串)
- 字典也可以根据需要动态地伸缩
- 字典会浪费较大的内存(但是查找快),是一种用空间换时间的数据结构
字典生成式
内置函数zip()
- 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回这些元组组成的列表
!
items=['Fruits','Books','Others']
prices=[96,78,85]
d={item.upper():prince for item,price in zip(items,prices)}#加upper的作用是把键的所有字母都变为大写
print(d)#{'Fruits':96,'Books':78,'Others':85}
字典总结
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=c5bed1
元组
- python内置的数据结构之一,是一个不可变序列
不可变序列与可变序列:
- 不可变序列(没有增,删,改的操作):字符串,元组
- 可变序列(可对序列执行增,删,改操作并且对象地址不发生改变):列表,字典
元组的创建
#第一种:用小括号
t=('python','world',98)
print(t)#('python','world',98)
print(type(t))#<class 'tuple'>
###也可以不加小括号
t='python','world',98
#第二种,使用内置函数tuple()
t1=tuple(('python','world',98))
print(t1)
#只包含一个元组的元素需要使用逗号和小括号
t=('python',)#不加逗号就会被认为是本身的数据类型
#空列表的创建
lst1[]
lst2=list()
#空字典的创建
d1={}
d2=dict()
#空元组的创建
t1=()
t2=tuple()
为什么要将元组设计成不可变序列
- 在多任务环境下,同时操作对象时不需要加锁
- 因此,在程序设计中尽量使用不可变序列
注意:
- 元组中存储的是对象的引用
- 如果元组中对象本身是不可变对象,则不再引用其它对象
- 如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t=(10,[20,30],40)
print(t,type(t))
print(t[0],type(t[0]),id(type))#地址跟t[2]相同
print(t[1],type(t[1]),id(type))#地址跟t[0]和t[2]不同
print(t[2],type(t[2]),id(type))#地址跟t[0]相同
#元组的元素不可以改变,但是元组内的列表元素是可以改变的
t[1].append(100)#向列表中添加元素,且元组地址不改变
元组的遍历
t=('python','world',99)
for item in t:
print(item)
什么是集合
-
python提供的内置数据结构
-
与列表,字典一样都属于可变类型的序列
-
集合是没有value的字典(同样是底层调用哈希)
集合的创建
#第一种创建方式 {} s={2,3,5,5,7,7} print(s,type(s))#{2,3,5,7}会把重复的元素去掉 <class 'set'> #第二种创建方式 使用内置函数set() s1=set(range(6)) print(s1)#{1,2,3,4,5} #它可将字符,元组和列表转成集合 print("python")#{'h','n','y','o','p','t'} print(set((1,2,3,3,3,4)))#集合是无序的{2,3,4,1} print(set([1,2,3,4]))#{1,4,3,2} print(set{12,23,45,65}) #定义空集合 s=set()
集合的相关操作
-
集合元素的判断
- in或not in
-
print(5 in s)
-
增
- 调用add() 一次添加一个元素
- 调用update() 至少添加一个
s={10,20,30,40,50,60} s.add(80) s,update([1,2,3])#可添加元组,列表,集合
-
删
- 调用remove() 一次删一个指定元素,元素不存在报错
- 调用discard() 一次删一个指定元素,元素不存在不报错
- 调用pop() 一次只删除一个任意元素(该函数没有参数)
- 调用clear() 清空集合
集合间的关系
- 两个集合是否相等
#可用==或!=判断 s1={1,2,3,4} s2={2,1,4,3} print(s1==s2)#true print(s1!=s2)#false
- 一个集合是否是另一个集合的子集
#issubset s1={1,2,3,4} s2={1,2} print(s2.issubset(s1))#true s2是s1的子集
- 一个集合是否是另一个集合的超集
#issuperset #s2是s1的子集,s1是s2的超集 s1={1,2,3,4} s2={1,2} print(s1.issuperset(s2))#true s1是s2的超集
- 两个集合是否没有交集
#isdisjoint
#没有true 有false
s1={1,2,3,4}
s2={1,2,5}
s3={100,200}
print(s1.isdisjonit(s2))#false
print(s1.isdisjoint(s3))#true
集合的数学操作
- 交集
#intersection()与&等价 s1={10,20,30,40} s2={20,30,40,50} print(s1.intersection(s2))#{20,30,40} print(s1 & s2)
- 并集
#union和|等价 s1={10,20,30,40} s2={20,30,40,50} print(s1.union(s2))#{10,20,30,40,50} print(s1 | s2)
- 差集
#difference和-等价 s1={10,20,30,40} s2={20,30,40,50} print(s1.difference(s2))#{10} print(s2.difference(s1))#{50} print(s1-s2)#{10} print(s2-s1)#{50}
- 对称差集
#symmetric_difference与^等价 s1={10,20,30,40} s2={20,30,40,50} print(s1.symmetric_difference(s2))#{10,50} print(s1^s2)#{10,50}
集合生成式
#将列表生成式的中括号换为大括号即可
s={i*i for i in range(6)}
print(s)
字符串
在python中字符串是基本数据类型,是一个不可变的字符序列
字符串保留机制:
对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟相同的空间
a='python'
b="python"
c='''python'''
print(a,id(a))
print(b,id(b))
print(c,id(c))
#a b c 的id相同
-
驻留机制的几种情况(交互模式)
- 字符串的长度为0或1时
- 符合标识符的字符串
- 字符串只在编译是进行驻留,而非运行时
- [-5,256]之间的整数
-
sys中的inter方法强制2个字符串指向同一个对象
-
pyCharm对字符串进行了优化处理
字符串驻留的优缺点
- 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较影响性能的
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串的长度,然后再拷贝,只new一次对象,效率要比“+”高
字符串的常用操作
查找
s='hello,hello'
index()#查找字符串substr第一次出现的位置,如果查找的子串不存在时,抛异常
print(s,index('lo'))#3
rindex()#查找字符串substr最后一次出现的位置,如果查找的子串不存在时,抛异常
print(s,rindex('lo'))#9
find()#查找字符串substr第一次出现的位置,如果查找的子串不存在,则返回-1
print(s,find('lo'))#3
rfind()#查找字符串substr最后一次出现的位置,如果查找的子串不存在,则返回-1
print(s,rfind('lo'))#9
大小写转换
upper()#所有字符都转成大写
s='hello,python'
a=s.upper()#会产生一个新的字符串对象
lower#所有字符都转成小写
swapcase()#把所有大写转小写,小写转大写
print(s.swapcase())
capitalize()#把第一个字符转换为大写,其余字符转为小写
title()#把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
print(s.title())# Hello Python
字符串内容对齐
center()#居中对齐
s='hello,python'
print(s./center(20,'*'))# ****hello,python**** 20是字符串长度 填充符不写默认为空格
ljust#左对齐
print(s.ljust(20,'*'))# hello,python********
print(s.ljust(10,'*'))# hello,python
rjust()#右对齐(跟左对齐一样)
zfill()#右对齐,左边用0填充,该方法只结束一个参数,用于指定字符串的宽度,
#如果指定的宽度小于等于字符串的长度,则返回字符串本身
print(s.zfill(20))# 00000000hello,python
字符串劈分
split()
#从字符串的左边开始劈分,默认的劈分字符串是空格字符串,返回的值都是一个列表
s='hello world Python'
lst=s.split()
print(lst)#['hello','world','python']
#sep指定劈分符
print(s1.split(sep='|'))['hello','world','python']
#通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分后,
#剩余的子串会单独作为一部分
print(s1.split(sep='|',maxsplit=1))#['hello','world|python']
rsplit()
#从字符串的右侧开始劈分,其他和sqlit()一样
判断字符串
isidentfier()
#判断指定的字符串是不是合法的标识符
print('shf_ah,,,'.isidentfier())#false
print('subahks'.isidentfier)#true
isspace()
#判断指定的字符串是否全部由空白字符组成
isalpha()
#判断指定的字符串是否全部由字母组成
isdecimal()
#判断指定的字符串是否全部由十进制的数字组成
isnumeric()
#判断指定的字符串是否全部由数字组成
isalnum()
#判断指定字符串是否全部由字母和数字组成
替换与合并
replace()#替换
#第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的
#字符串,替换前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数
s='hello,python'
print(s.replace('python','go'))# hello,go
s1='hello,python,python,python'
print(s1.replace('python','go',2))# hello,go,go,python
join()#合并(元组,字符串,列表都行)
#将列表或元组中的字符串合并成一个字符串
lst=['hello','go','python']
print('|'.join(lst))#[hello|go|python]
print('',join(lst))#[hellogopython]
字符串大小的比较
用> < <= >= == !=来比较
print('apple'>'app')#true
#原理和c一样
print(ord'a')# 97
print(chr(97))# a
字符串的切片操作
- 字符串是不可变类型,不具备增,删,改等操作
- 切片操作将产生新的对象
s='hello,python'
s1=s[:5]# hello
#不写起始位置默认从零开始,切片操作会产生一个新的字符串
s2=s[6:]# world 没指定结束位置,所有会截取到末尾
s3='!'
newstr=s1+s2+s3
print(newstr)# hello!world
print(s[1:5:1])#从1开始截到5(不包含5),步长为1
格式化字符串
#(1)%占位符
name='张三'
age=20
print('我叫%s,今年%d岁'%(name,age))# %10d表示占了10个宽度
#(2){}
print('我叫{0},今年{1}岁',format(name,age))#{0}{1}代表format里的索引
#{0:.3}表示三位数
#{0:.3f}表示三位小数
#{0:10.3f}表示一共十位数,保留三位小数
#(3)f-string
print(f'我叫{name},今年{age}岁')
字符的编码转换
- 编码与解码的方式
- 编码:将字符串转换为二进制数据
- 解码:将bytes类型的数据转换成字符串类型
-
#编码 s="天涯觅知音" s.encode(encoding='GBK')#在GBK中,一个中文占两个字节 s.encode(encoding='UTF-8')#在UTF-8中,一个中文占3个字节 #解码 byte=s.encode(encoding='GBK') print(byte.decode(ending='GBK')) # GBK编的只能用GBK解,其他的同理
函数
-
函数就是执行特定任务来完成特定功能的一段代码
为什么需要函数
- 复用代码
- 隐藏实现细节
- 提高可维护性
- 提高代码可读性,便于调试
函数的创建
#创建
def fun(a,b):
c=a+b
return c
#调用
result=fun(10,20)
print(result)
#根据形参名称进行传参
res=fun(b=20,a=10)
#如果传的是可变序列,形参改变会影响实参;不可变对象则形参的改变不会影响实参
函数返回值
- 可以为空
- 一个返回值则直接返回原类型
- 多个返回值则返回元组
#函数返回多个值时,结果为元组
def fun(num):
odd=[] #存奇数
even=[] #存偶数
for i in num:
if i%2:
odd.append(i)
else:
even.append(i)
return odd,even
print(fun[10,29,23,34,44,53,55])#([29,23,53,55],[10,34,44])
函数参数的定义
- 函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参(类似于缺省)
def fun(a,b=10):
return a+b
fun(100)
fun(100,100)
-
个数可变的位置参数
- 定义函数时,可能无法事先确定传递参数的个数,位置时,使用可变的位置参数
- 使用*定义个数可变的位置形参
- 结果为一个元组
def fun(*args): print(args) fun(1)# (1,) fun(1,'tow',3)# (1,'tow',3)
-
个数可变的关键字参数
- 定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字参数
- 使用**定义个数可变的关键字形参
- 结果为一个字典
def fun(**args): print(args) fun(a=20)#{'a':20} fun(a=20,b=30,c=40)#{'a':20,'b':30,'c':40}
注:
- 在一个函数的定义过程中,既有*又有**的参数,要求,*放在**的前面
def fun(*args,**arg)
函数的参数总结
def fun1(a,b,*,c,d): #代表从*之后的参数在调用时只能采用关键字参数传递
pass
def fun2(a,b,*c,**d)
def fun3(*a,**b)
def fun4(a,b=10,*arg1,**arg2)#以上几种都是可以的
变量的作用域
- 程序代码能访问该变量的区域
- 根据变量的有效范围可分为
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成全局变量
- 全局变量:函数体外定义的变量
递归函数:
-
什么是递归函数
- 如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
-
递归的组成部分:递归调用与递归终止条件
-
递归的调用过程
- 每递归调用一次函数,都会在栈内分配一个栈帧
- 每执行完一次函数,都会释放相应地空间
-
递归的优缺点
- 缺点:占用内存多,效率低下
- 优点:思路和代码简单
#递归计算阶乘 def fun(a): if a==1: return 1 else: return a*fun(a-1) print(fun(6))
#斐波那契数列
#第一二项为1,第三项为前两项之和
def fib(a):
if a==1 or a==2:
return 1
else:
return fib(a-1)+fib(a-2)
print(fib(6))
常见bug类型
SyntaxError
age=input('请输入你的年龄:')#input赋值的变量为str型
python的异常处理机制
#多个except结构
try:
a=int(input('请输入第一个整数'))
b=int(input('请输入第二个整数'))
result=a/b
print('结果为:',result)
except ZeroDivisionError:
print('对不起,除数不允许为0')
except ValueError:
print('只能输入数值串')
print('程序结束')
try except else结构
如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
try:
n1=int(input('请输入一个整数'))
n2=int(input('请输入另一个整数'))
result=n1/n2
except BaseException as e:
print('出错了')
print(e)
else:
print('结果为:',result)
try except else finally结构
#finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
except BaseException as e:
print('出错了')
print(e)
else:
print('结果为:',result)
finally:
print("无论是否产生异常,总会被执行的代码")
print('程序结束')
异常类型:
异常类型 | 描述 |
---|---|
ZeroDivisionError | 除数(或求余)为0 |
IndexError | 序列中没有此索引 |
KeyError | 映射中没有这个键 |
NameError | 为声明/初始化对象 |
SyntaxError | python语法错误 |
ValueError | 传入无效的参数 |
编程思想
区别 | 事物比较简单,可以用线性思维去解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点 | 都是一种解决实际问题的一种思维方式 | |
二者相辅相成,并不是对立的 解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便我们分析 整个系统;具体到微观操作,仍然使用面向过程方式来处理 |
类与对象
-
数据类型
- 不同的数据类型属于不同的类
- 使用内置函数查看数据类型(type)
print(type(100)) <class 'int'> print(type(99)) <class 'int'> print(type(520)) <class 'int'>
-
对象
- 100,99,520都是int类之下包含的相似的不同个例,这个个例专业术语称为实例或对象
在Python中一切皆对象
class Student:#Student是类名,由一个或多个单词组成,首字母大写,其余小写
pass #也有id type value
类的创建
- 创建类的语法
class Student: native_place='吉林' #直接写在类里的变量称为类属性 def _init_(self,name,age):#namec,age为实例属性 self.name=name self.age=age #实例方法(在类外定义的称为函数,在类里定义的称为实例方法) def info(self): print('我的名字叫:',self.name,'年龄是:',self.age) #类方法 @classmethod def cm(cls): print('类方法') #静态方法 @staticmethod def sm(); print('静态方法')
类的组成
-
类属性
-
实例方法
-
静态方法
-
类方法
对象的创建
#创建Student类的对象 stu1=Student('张三',20) print(id(stu1)) print(type(stu1)) #<class '__main__Student'> print(stu1) print(id(Student)) #<class 'type'> print(type(Student)) print(Student) #对象调类中属性和方法用点 print(stu1.name) print(stu1.age) stu1.eat()#对象名.方法名 Student.eat(stu1) #stu1.eat()与Student.eat(stu1)作用相同 #类名.方法名(类的对象)-->实际上就是方法定义处的self
类属性,类方法,静态方法
- 类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
- 类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
- 静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
#静态方法的使用方式
Student.method() #对象名.静态方法名
动态绑定属性和方法
- python是动态语言,在创建对象之后,可以动态地绑定属性和方法
stu1=Student('张三',20)
stu2=Student('李四',30)
print(id(stu1))
print(id(stu2))
stu2.gender='女'
print(stu1.name,stu2.gender)#stu1没绑定性别无法使用gender
print(stu2.name,stu2.age,stu2.gender)