一,注释
#单行注释
"""
多行
注释
"""
'''
多行
注释
'''
二,变量
变量的定义 储存数据时当前数据所在的内存地址的名字
标识符 命名规则 1由数字 字母 下划线组成 2不能由数字开头 3不能使用内部关键字 4严格区分大小写(A a)
命名习惯 1见名知意 2大驼峰(MyName) 3小驼峰(myName) 4下划线(my_name)
使用变量
myName = 'tom'
print(myName)
schoolName = '老峰村男子职业技术学院'
print(schoolName)
变量的数据类型
#容器类型/数据序列
列表类型=> list,[1,2,3] =>数据可以发生变化
元组类型=> tuple,(1,2,3) =>数据一旦定义 其数值就无法改变
集合类型=> set,{1,1,2,3} =>{1,2,3} =>天生去重 类似select distinct列名称
字典类型=> dict,{key:value键值对} => {'name':'张三','age':23,'address':'老峰村男子职业技术学院'} =>用于查询
判断数据类型
type(c).print => print(type(c)) 返回c的数据类型
isinstance(d,str).print => print(isinstance(d,str)) 判断d是否为str类型 返回布尔值
三,bug
bug就是程序中的错误 (代码顶格 一般不能随意缩进)
debug工具 通过打断点判断错误原因和位置
四,常用快捷键
ctrl / 对选中内容快速注释
ctrl s 对代码进行强制保存
ctrl z 撤销 ctrl y 恢复
ctrl alt l 代码标准格式化
tab 对父子关系进行缩进
ctrl d 快速复制本行内容到下一行
五,输出
输出函数print
print(输出内容,end='')
end参数为输出内容结束后的追加的内容 一般默认为\n 换行符
百分号格式化输出
name = '猪八戒'
age = 300000
wife_age = 16.88
print('名叫%s,年龄%06d,老婆%.2f岁了'%(name,age,wife_age))
format格式化输出
另一种格式 format格式
print("姓名:{},联系方式:{}".format(name,mobile))
format简写格式
print(f'姓名:{name},年龄:{age}')
六,输入
输入函数input
code = input('请输入你的密码' )
#注意input输入的内容均被视为字符串
price = input ('请输入价格 ')
#输入 *
print ( price * 2)
#输出结果为 **
七,数据类型转换
str1 = '10'
str2 = '1.88'
num1 = int (str1)
num2 = float (str2)
#eval方法的作用是将字符串类型的值转换为原始数据类型
num3 = eval (str1)
num4 = eval (str2)
八,运算符
1算数运算符
print(f'整除运算:{num1 // num2}')
print(f'求余运算:{num1 % num2}')
print(f'幂指数运算:{num ** 2}')
print(f'优先级运算:{(num1 + num2) * num3}')
2赋值运算符
多个变量同时赋值(元组拆包)
num,str,bool=10,'hello',True
复合赋值运算符
3比较运算符
4逻辑运算符
python中 空字符串 0 None为False 其余都是True
注意:空字符串指的是单引号内没有内容 但是空格键是一个字符
扩展 短路运算
逻辑运算符两边可以是表达式 也可以是数值类型数据或者字符串类型的数据 如果是后者 则返回的不是False 或者True 而是决定结果的那个数据
print(3 and 4) #结果为4
print(0 and 1) #结果为0
python中的三目运算符
max = num1 if num1 > num2 else num2
#得出num1和num2之间的最大值
作用就是简化if else 语句
如果st = True if False else False 那么, print(st)打印的结果是False
九,if选择结构
基本语法
if 条件 :
执行语句(前面的空格是一个Tab)
一个Tab等于四个空格键
if else结构
age = int ( input('请输入您的年龄 ') )#数据转换很重要
if age >= 18:
print('您已成年 祝您游戏愉快')
else :
print('未成年 汇回家好好学习')
if elif else多重判断结构
if 条件1 :
执行语句
elif 条件2 :
执行语句
else : (都不满足)
执行语句
如果有一个elif满足条件 则不会继续往下运行
#python中允许这样写
if 60 >= age >=20:
#执行语句
十,random随机数模块
在python中通过导入random模块实现随机数功能
1 import (模块名称)
2 模块名称.函数名称()
import random
print(random.randint(0,2))#产生0-2之间随机整数
十一,python中的循环结构
while循环语法
while 条件:
重复执行的代码1
重复执行的代码2
两个关键词 break continue
break 终止循环 不在继续进行
continue 中断循环 此次循环不往下进行 进行下一次循环
num = 5
i = 1
while i <= 5:
print(f'正在吃第{i}个苹果')
if i == 3 :
print('有虫 不吃了')
i += 1
continue
i += 1
import random
randnum = random.randint(1,100)
while True:
i = int(input('请输入一个数字'))
if i == randnum:
print ('恭喜你 猜对了')
break
elif i > randnum:
print ('猜大了 再输入一次')
else:
print ('猜小了 再输入一次')
while嵌套循环输出三角形
i = 0
while i < 5:
j = 0
while j <= i:
print('*',end='\t')
j += 1
print('')
i += 1
while嵌套输出九九乘法表
i=1
while i<=9:
j=1
while j<=i:
print(f'{j}*{i}=',i*j,end='\t')
j+=1
print('')
i+=1
for循环基本语法
for 临时变量 in 数据序列:(字符串/列表/元组/集合)
循环体语句
循环体语句
作用:每次循环时 系统会自动把数据序列里的元素放入临时变量中,序列中有多少元素就自动循环多少次
str1='hello'
for i in str1:
print(i)
运行结果h e l l o
range函数基础用法
range()函数返回的是一个可迭代对象(类型是对象)并非列表类型,打印的时候不会打印列表
#基本语法
range(stop)
range(start,stop[,step])
start:计数从start开始默认是0开始 range(5)等价于range(0,5);
stop:计数到stop结束,但是不包括stop range(0,5)是[0,1,2,3,4]没有5
step:步长,默认为1 range(0,5)等价于range(0,5,1)
for循环输出九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print(f'{j}*{i}={j*i}',end=' ')
print('')
while循环else结构 else后是循环正常结束后执行的代码
基本语法
while 条件:
循环体代码
else:
循环正常结束后执行代码(一次)
break 和 continue对while...else语句的影响
break使得循环不正常结束 不会执行else之后的代码 continue可以让循环正常结束 执行else之后的代码
for循环else结构
与while基本语法相同
十二,turtle(海龟)模块绘图(time模块)
#引入turtle模块
import turtle
#引入time模块
import time
turtle.pencolor('red')
#绘制五角星
for i in range(5):
turtle.forward(200)#绘制直线
turtle.right(144)#每次偏移144度
#休眠20秒用来展示画面
time.sleep(20)
turtle绘图网站python123
十三,字符串
两种方式定义字符串(后者的好处是可以换行)
#一组单引号
str1='山西大学'
#三组单引号
str2='''山
西
大
学'''
#这里不是注释
转义字符
print('i'm tom')#系统报错 引号总是成对出现
#解决办法 转义字符
print('i\'m tom')# \'被认为是普通的字符
input的作用 1 打断正在执行的程序直到用户输入完成
2 返回值永远都是字符串类型
在计算机中 python字符串属于序列结构 索引下标
name='shanxi'
print(name[0]) #s
print(name[3]) #n
字符串切片(截取)
基本语法
变量名称[从哪里开始切:到哪里结束:每次前进多少步]
numstr='0123456789'
#1有起始位置有结束位置有步长
print(numstr[2:5:1]) #234
#2有起始位置有结束位置无步长(默认为正一)
print(numstr[2:5]) #234
#3只有结束位置(从第一个开始截取)
print(numstr[:5]) #01234
#4只有起始位置(若没有结尾则一直到末尾)
print(numstr[1:]) #123456789
#5只有冒号(相当于复制操作)
print(numstr[:])
#6只有步长
print(numstr[::2]) #02468
#7结尾是负数
print(numstr[:-1]) #012345678
#8起始位置与结束位置都是负数(如果步长为正,从起始到结束必须从右往左)
print(numstr[-4:-1]) #678
print(numstr[-1:-4]) #无法获取数据
#9无起始位置和结束位置且步长为负数(字符串翻转的一种手段)
print(numstr[::-1]) #9876543210
python中字符串的查找
find()方法 字符串变量.find(搜索的内容),若在字符串内搜索到 返回搜索内容起始位置的下标,找不到返回-1
index()方法 字符串变量.index(搜索的内容),若在字符串内搜索到则返回搜索内容起始位置的下标 找不到则报错
str1='hello world'
print(str1.find('world'))
str2='hello python'
print(str2.index('python'))
#上传一张照片获取文件名或者后缀名(.jpg .png .gif)
filename=input('输入文件名')
index=filename.rfind('.')#rfind=right find(从右边开始查询第一个出现的搜索字符)
print(filename[:index])#获取文件名
print(filename[index:])#获取文件后缀
字符串修改
#replace
str1 = 'hello linux and hello linux'
# 把字符串中所有linux字符替换为python
print(str1.replace('linux','python'))
# 把字符串中的第一个linux进行替换为python
print(str1.replace('linux', 'python',1))
# 把and字符串替换为&&
print(str1.replace('and','&&'))
#split join
str1='apple-banana-orange'
print(str1.split('-'))
list1=['apple','banana','orange']
print('-'.join(list1))
#upper lower title
str1='i am tom,nice to meet you'
print(str1.title())#首字母大写
print(str1.upper())#全大写
print(str1.lower())#全小写
字符串判断
随机生成四位数验证码
import random
mystr='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'
code=''
for i in range(4):
index=random.randint(0,len(mystr)-1)
code+=mystr[index]
print(code)
十四,列表list
列表的作用 一次性储存多个数据 程序员可以对这些数据进行的操作有增删查改
name_list=['tom','shelly','二狗']
print(name_list[0])
查找
#index查找元素在列表中的位置(下标)
name_list=['tom','shelly','二狗']
print(name_list.index('tom'))
#count统计关键词在列表中出现的次数
print(name_list.count('tom'))
#in not in 判断关键词是否出现在列表中 出现返回True 否则False
if 'tom' in name_list:
print('存在')
xiyou_list=['唐僧','猪八戒','孙悟空']
#append 追加方法 增加指定数据到列表
xiyou_list.append('沙僧')
print(xiyou_list)
#extend 列表合并
list1=['小白龙']
xiyou_list.extend(list1)
print(xiyou_list)
#insert 指定位置新增数据
xiyou_list.insert(2,'女儿国')
print(xiyou_list)
name_list=['tom','sam','lisa']
#del列表[索引] 删除列表中的某个元素
del name_list[0]
print(name_list)
#pop() 删除指定下标的数据 默认为最后一个 返回该数据
list1=name_list.pop()
print(list1)
#remove() 移除列表中某个数据的第一个匹配项
name_list.remove('sam')
print(name_list)
#clear() 清空列表,删除列表中的所有元素,返回空列表
name_list.clear()
print(name_list)
name_list=['大乔','小乔','貂蝉','八戒']
#列表[索引]=修改后的值
name_list[3]='赵云'
print(name_list)
#reverse() 将数据序列进行倒叙排列
name_list.reverse()
print(name_list)
#sort() 对列表序列进行排序
name_list.sort(reverse=True)#从大到小
print(name_list)
列表循环遍历
name_list=['tom','rose','lucy']
i=0
while i<len(name_list):
print(name_list[i])
i+=1
for i in name_list:
print(i)
列表嵌套(结合二维数组理解)
biglist=[['1tom','1lisa'],['2tom','2lisa'],['3tom','3lisa']]
print(biglist[1][1])
十五,元组tuple
可以存储多个数据 但一旦定义数据就不可改变 数据可以是不同的数据类型
定义
#单元素元组
tuple1=(10,)#单一元素后面必须要加逗号
print(type(tuple1))#tuple
#多元素元组
tuple2=(10,20,30)
print(type(tuple2))
#访问元组中的所有数据
for i in tuple2:
print(i)
相关操作
tuple=(12,23,34,34)
#index 返回元素在元组中出现的位置
print(tuple.index(23))
#count 统计元素在元组中出现的次数
print(tuple.count(34))
#len 公共方法 求元素个数
print(len(tuple))
十六,字典dict
字典里面的数据是以键值对的形式出现,字典数据和数据顺序没有关系,即字典不支持下标,后期无论数据如何变化,只需要按照对应的键的名字查找即可
#dict={key:value,key:value}
dict1={'name':'tom','age':20,'gender':'male'}
#空字典
dict2={}
dict2=dict()
#访问字典
print(dict1['name'])
字典中的增操作
#基本语法
#[key]=value 如果key存在就修改对应的值
person={}#空字典
person['name']='tom'
person['age']=40
person['address']='曦园'
print(person)
字典中的删操作
# del 字典名称[key]:删除指定的元素
person={'name':'tom','age':19,'address':'求真楼'}
del person['age']
print(person)
# clear() 清空字典中的所有key
person.clear()
print(person)
字典中的改操作与字典的增操作语法相同
字典中的查操作
person={'name':'tom','age':19,'address':'求真楼'}
#get(key)
address=person.get('address')
print(address)
#keys
print(person.keys())
#values()
print(person.values())
#items()
print(person.items())
十七,集合set
集合是一个无序不重复元素序列(天生去重),集合里的元素可以是列表,元组,字典
基本语法
#创建合集
set1={10,20,30}
set2=set('tom')#单一字符串
#创建空合集只能用ste() {}用来创建空字典
set3=set()
print(type(set2))
print(set2)
集合的增操作
#add() 向集合中增加一个元素(单一元素)
student=set()
student.add('王宁')
print(student)
#undate() 向集合中增加序列类型的数据(字符串 列表 元组 字典)
list1=['渊渊','谢谢']
student.update(list1)
student.update('洋')
print(student)
集合的删操作
student={'tom','rose','bob','xxx','yyy'}
#remove() 删除集合中指定数据 不存在就报错
student.remove('tom')
print(student)
#discard() 删除集合中指定数据 不存在也不报错
student.discard('rose')
print(student)
#pop() 随机删除某个数据并且返回
print(student.pop())
print(student)
集合中的查操作
# in not in
set1={'xxx','yyy','zzz'}
if 'xxx' in set1:
print('yes')
else:
print('no')
#集合的遍历
for i in set1:
print(i)
集合的交集并集差集特性
set1={'xxx','yyy','zzz'}
set2={'xxx','aaa','www'}
#交集
print(set1&set2)
#并集
print(set1|set2)
#差集
print(set1-set2)
十八,小结 常见公用方法
十九,函数def
作用:代码重用 模块化编程(一个系统分解为若干个模块)
#函数定义
def 函数名称([参数]):
函数体代码
return 返回值
函数同时返回多个值
#函数返回多个返回值(返回元组)
def calc(num1,num2):
jia=num1+num2
jian=num1-num2
cheng=num1*num2
chu=num1/num2
return(jia,jian,cheng,chu)
print(calc(10, 2))
函数的说明文档
def calc(num1,num2):
"""
返回两个数字的四则运算
"""
jia=num1+num2
jian=num1-num2
cheng=num1*num2
chu=num1/num2
return(jia,jian,cheng,chu)
print(calc(10, 2))
help(calc)
"""函数说明""" help()返回函数说明文档
def generate_code(num):
"""随机生成num位验证码"""
str1='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
code=''
lenth=len(str1)
import random
for i in range(num):
code += str1[random.randint(0,lenth-1)]
return code
print(generate_code(4))
函数的嵌套
def funcb():
print('funcb函数被调用')
def funca():
print('函数funca被调用')
funcb()
funca()
如果函数没有返回值 默认返回None
变量的作用域
局部变量:定义在函数内部 全局变量:定义在函数外部
global关键字
有个数据在两个函数种都需要使用,但是在函数体内部理论上是无法对全局变量进行修改的,所以需要使用global关键字
student=['tom','alise','shy']
def funcA():
global student
student.append('lisa')
def funcB():
for i in student:
print(i)
funcA()
funcB()
函数参数分为形参和实参 形参是在函数定义时所编写的参数,实参是函数调用时传递的参数
位置参数 函数定义时可以定义多个参数,调用函数时也应该传递多个参数,正常情况需要一一对应(位置)
关键词参数(python特有)函数调用时通过 键=值的形式加以指定这样就清楚了参数的顺序需求
缺省参数(默认参数)调用时如果不传入参数就使用默认值(注意 所有位置参数必须出现在默认参数前,包括函数的定义和调用
def user_inof(name,age,gender='女'):#缺省参数 默认gender为女
print(f'名字:{name},年龄:{age},性别:{gender}')
user_inof(age=18,name='aselly')#关键词参数
不定长参数 也叫可变参数 用于不确定调用时会传递多少个参数 此时可用 包裹(paking)位置参数,或者关键字参数
不定长元组(位置)参数
def user_of1(*args):
print(f'我的名字{args[0]},今年{args[1]}岁了,住在{args[2]}')
user_of1('tom','11','the us')
不定长字典(关键字)参数
def user_inof2(**kwargs):
print(f'我的名字{kwargs["name"]},今年{kwargs["age"]}岁了')
user_inof2(name='tom',age=27)
另外两种方式(两个都用)
#计算所有参数的和
def func(*args,**kwargs)
result=0
for i in args:
result+=i
for i in kwargs.values():
result+=i
return result
print(func(10,20,30,num1=40,num2=50))
def func(*args,**kwargs):
print(args)
print(kwargs)
#先定义变量再传递参数
list1=[10,20,30]
dict1={'num1':40,'num2':50}
func(*list1,**dict1)
包裹位置或者包裹关键字传递都是一个组包的过程
python组包:把多个数据组成元组或者字典的过程
二十,拆包(元组,字典)
def return_num():
return 100,200
#执行函数,把返回的两个结果一个放入变量num1,一个放入num2
num1,num2=return_num()
print(num1)
print(num2)
1如果使用return同时返回多个结果,则返回的数据类型为元组
2函数执行完毕后调用的位置会被替换为return返回值num1,num2=(100,200)
3所谓元组拆包就是把元组中的每个元素依次赋给变量
在不引入第三个变量的情况下交换两个变量的值
c1=10
c2=20
c1,c2=c2,c1#python特有拆包
#原理 把c1 c2 组成一个元组(c1,c2)然后拆包
二十一,python中变量的引用关系
显示变量地址的方法
print(id(a))
当我们把一个变量赋予给另一个变量时,其两者指向的内存地址相同 指向了同一块内存空间
不可变数据类型(数值)在赋值以后,其中一个值的改变不影响另一个变量,因为两者指向空间地址不同
如何分辨可变类型数据还是非可变类型
可变类型就是在内存中,其内存地址一旦固定,其变量的值是可以发生改变的
二十二,递推与递归
递推求斐波那契
def func(n):
if n==1 or n==2:
return 1
dict1={1:1,2:1}
for i in range(3,n+1):
dict1[i]= dict[i-1] + dict[i-2]
return dict1[n]
print(func(8))
程序调用自身的编程技巧称为递归
1简化问题:找到最优子问题(不能再小)2函数自己调用自己
两个重要的概念:
1递归点:找到解决当前问题的等价函数(先解决规模比当前问题小一些的函数,以此类推,最终实现对问题的解决 (递归有归)
2递归出口:当问题解决的时候,已经到达(必须存在)最优问题,不能再次调用函数了 如果一个递归函数没有递归出口就变成了死循环
递归函数求斐波那契
def func(n):
if n==1 or n==2:
return 1
return func(n-1)+func(n-2)
print(func(5))
二十三,lambda表达式
为了简化程序代码 我们会定义匿名函数 如果函数有一个返回值 并且只有一行代码,可以使用lambda简化
基本语法
变量=lambda 函数参数:表达式(函数代码 return返回值)
#调用
变量()
def func1(num1,num2):
return num1+num2
func2=lambda num1,num2:num1+num2
print(func2(10,20))
lambda不定长参数
func1=lambda *args:args
print(func1(10,23,34))
func2=lambda **kwards:kwards
print(func2(name='yom',age=29))
func2=lambda num1,num2: num1 if num1 >num2 else num2
#lambda三目运算
应用 列表数据和字典数据
students=[
{'name':'tom','age':12},
{'name':'rose','age':15},
{'name':'jenn','age':23}
]
#按照name升序排列
students.sort(key=lambda x:x['name'])
print(students)
#按照name降序排列
students.sort(key=lambda x:x['name'],reverse=True)
print(students)
#按照age升序排列
students.sort(key=lambda x:x['age'])
print(students)
二十四,文件操作
文件操作步骤通常为 打开 读写 关闭(可以不读写)
文件操作的作用:把一些内容(数据)储存起来,可以让程序下一次执行的时候直接使用,不用再重新制作一份
open()打开函数,打开一个已经存在的文件,或者创建一个新文件
open(name,mode)
文件读取操作
如果需要读取中文 则需要用unf-8的编码格式读取文件内容
f=open('pyhton.txt','r',encoding='utf-8')
content=f.read()
print(concent)
f.close()
name 可以是 文件路径
mode r w a
文件写入操作
f= open('测试.py','w',encoding='utf-8')
f.write('hello\npython\n')
f.close()
(w会先将文件内容清空)
文件指针 r和w都是指向第一行,a指向最后一行、
文件读取操作
f=open('测试','r',encoding='utf-8')
content=f.read()
print(content)
#print(f.readline()) 读取一行 然后把指针移动到下一行
#print(f.readline())
#print(f.readline())
f.close()
readlines()读取所有内容 返回的是个列表
seek函数移动光标
文件备份操作
oldname=input('请输入需要备份的文件名称:')#找到要备份的文件
index=oldname.rfind('.')
name=oldname[:index]#文件名
postfix=oldname[index:]#文件后缀
newname=name+'[备份]'+postfix
old_f= open(oldname,'r')#匿名函数
new_f= open(newname,'w')
#每次循环将最多1024个字节的原文件的内容复制到备份文件里直到复制完毕
#一般大文件不用readline一次性读取 太大会卡住
while True:
content = old_f.read(1024)
if len(content)==0:
break
new_f.write(content)
old_f.close()
new_f.close()
os模块
python中的文件和文件夹相关操作
重命名与删除文件操作
import os
import time
os.rename('测试[备份].py','测试备份.py')#重命名
time.sleep(20)
os.remove('测试[备份].py')#删除
import os
#1使用mkdir方法创建一个images文件夹
if not os.path.exists('images'):#检测是否已经存在此文件夹
os.mkdir('images')
if not os.path.exists('images/avatar'):
os.mkdir('images/avatar')
#2 getcwd = get current work directory
print(os.getcwd())
#3 os.chdir, ch=change dir=directory切换目录
os.chdir('images/avatar')
print(os.getcwd())
#4 切换到上一级目录->images
os.chdir('../../')
二十五,异常
异常就是程序无法继续运行 报错
异常的捕获
try:
可能会出错的代码
except:
如果出现异常的代码
捕获指定异常
try:
f=open('python.txt','r')
except FileNotFoundError:
print('访问的文件不存在')
捕获多个异常
try:
f=open('python.txt','r')
print(8/0)
except (FileNotFoundError,ZeroDivisionError):
print('访问的文件不存在或者除数为0')
捕获所有异常(Exception类)
try:
print(8/0)
except Exception as e:
print(e)#捕获所有异常 输入出错代码的位置与原因
异常捕获中的else finally语句
try:
可能出错的代码
except Exception as e:
捕获异常类型
else:
如果没有异常要执行的代码
finally:
无论是否出现异常都要执行的代码
异常的传递
import time
try:
f=open('python.txt','r')
try:
while True:
content=f.read(1)
if len(content)==0:
break
print(content)
time.sleep(2)
except:
print('文件未执行完成,人为终止了程序')
finally:
f.close()
except:
print('文件不存在')
finally:
f.close()
raise抛出自定义异常
需求 当用户输入的密码少于六位时报错
def intput_password():
password=input('输入密码')
if len(password)<6:
#print('输入的密码小于6位')
raise Exception('密码长度小于6位')
return
intput_password()
二十六,模块与包
模块 Module 是一个python文件以.py结尾 可以定义函数 类 变量
导入模块的方式
内置模块
pycharm中快捷键Ctrl +左键 点击 模块名称 函数名称
from 模块 import 功能名 导入指定的功能
from random import randint
print(randint(1,2))
#导入模块所有功能
from math import *
print(sqrt(9))
as关键字可以给模块定义别名
import time as t
from time import sleep as s
t.sleep(10)
s(40)
自定义模块
创建一个文件 编写模块中的 函数 类 变量 命名My_module
在使用模块前 引入该文件作为模块import My_module
除了测试以外 也可以用来编写python程序的入口
模块重名问题
魔术变量__all__限制调用
Package包
新建Package包
引入包中的模块
import mypackage.my_module1
二十七,面向对象编程
思维:1分析有哪些主体(对象)2分析这个对象有哪些属性和功能 3让对象调用相关属性和方法
面试题·:面向对象和面向过程的区别
OOA面向对象分析 OOD面向对象设计 OOP面向对象编程
类的定义
经典类与新式类
object是继承的
class Person(object):
def eat(self):
print('喜欢吃薯片')
print(self)#返回其对象所指的内存地址
def drink(self):
print('喜欢喝咖啡')
p1=Person()
print(p1)#如果直接打印Person实例化对象返回其对象所指的内存地址
p1.eat()
p1.drink()
类外添加和获取属性
添加 对象名.属性=属性值
获取 对象名.属性
class Monkey(object):
def show_inof(self):
print(f'名字:{self.name},技能:{self.skill}')
swk = Monkey()
swk.name='孙行者'
swk.skill='火眼金睛'
swk.show_inof()
二十八,魔术方法
python中__xxx__()函数叫做魔术方法 指有特殊功能的函数
__init__(初始化或者构造方法)
用于初始化
class Person():
def __init__(self,name,age):#第一个参数一定是self
self.name=name
self.age=age
p1=Person('榴莲',19)#init函数自动调用
print(p1.name)
print(p1.age)
__del__(删除或者析构方法)
用于关闭文件关闭数据库连接等
class Person():
def __init__(self,name,age):
self.name=name
self.age=age
def __del__(self):
print('当对象被删除时自动调用')
p1=Person('tttt',19)
print(p1.name)
del p1
__str__(当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__方法,那么就会打印从在这个方中 return 的数据。(另外要特别注意__str__方法返回字符串类型的数据))
class Person():
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return f'姓名:{self.name}'
p1=Person('tt',18)
print(p1)
二十九,封装继承多态
封装性 属性分为两种 共有和私有
私有属性的访问限制 在属性或方法名前面加 __就可
class Girl():
def __init__(self,name):
self.name=name
self.__age=18
xiaomei = Girl('小美')
print(xiaomei.name)
print(xiaomei.age)#报错
类中的私有属性和私有方法不能被子类继承
私有属性设置与访问接口
设置两个访问接口 get 与 set
class Girl():
def __init__(self,name):
self.name=name
self.__age=18
def get_age(self):
#内部访问允许直接访问
#外部访问根据需要添加限制条件
print(self.__age)
def set_age(self,code):
if code==112358:
self.__age +=1
else:
print('出错')
#在使用这个函数之前必须要进行权限验证
xiaomei = Girl('小美')
xiaomei.get_age()
print(xiaomei.name)
xiaomei.set_age(112358)
xiaomei.get_age()
继承
顶级类object (基类) 其他子类叫做派生类
单继承特性(多层继承):传递性
多继承
允许应该类同时继承多个类的特性
类的扩展重写 :当子类中的方法名与父类中的方法名相同时会重新定义此方法 当然父类的此方法还在
super()调用父类属性和方法
class Car(object):
def __init__(self,brand,color,model):
self.brand=brand
self.color=color
self.model=model
def run(self):
print('i can run')
class Gasolinecar(Car):
pass
class ElectricCar(Car):
def __init__(self,brand,color,model,battery):
super().__init__(brand,color,model)#强调重用父类的初始化方法
self.battery=battery
def run(self):#重写run方法
print('run in e')
tesla = ElectricCar('tesla','白','model y',70)
print(tesla.color)
print(tesla.brand)
print(tesla.model)
print(tesla.battery)
tesla.run()
MRO属性与方法:方法解析顺序
print(ElectricCar.__mro__)
print(ElectricCar.mro())
多态 定义:调用不同的子类对象的相同父类方法,可以产生不同的执行结果
多态依赖继承(不是必要) 子类方法必须要重写父类方法
好处:调用灵活 更容易做出通用的编程
class Fruit(object):
def makejuice(self):
print('i can make juice')
class Apple(Fruit):
def makejuice(self):
print('i can make apple juice')
class Banana(Fruit):
def makejuice(self):
print('i can make banana juice')
def service(obj):
obj.makejuice()
service(Apple())
service(Banana())
三十,面向对象的其它特性
class Tool(object):
count=0#记录此类被实例化了多少次
def __init__(self,name):
self.name=name
Tool.count+=1
@classmethod
def show_tool_count(cls):
print(f'当前{cls}类一共被实例化了{cls.count}次')
t1=Tool('斧头')
t2=Tool('榔头')
Tool.show_tool_count()
静态方法 既不需要调用对象属性方法,也不需要调用类属性和类方法
class Game(object):
@staticmethod
def menu():
print('开始')
print('暂停')
print('结束')
Game.menu()#两种调用方法
g=Game()
g.menu()