目录
Python基础语法
-
注释
单行注释使用 # (在pycharm中的快捷键是Ctrl+/)
多行注释使用三个单引号或双引号 '''或“”“
-
数据类型和命名
1、变量
定义规则:变量名=数据 (不需要声明变量类型)
如想查看变量类型可使用type函数
#例如
a=100
b='老王'
print(type(a))
print(type(b))
2、基本数据类型
数字(num):int(整型) long(长整型,python3取消) float(浮点型) complex(复数) bool(布尔值 True False)
字符串(str)
字典(dict)
元组(tuple)
列表(list)
#高级类型
c={} #字典类型
d=() #元组类型
e=[] #列表类型
3、变量命名规则
变量必须以字母或下划线作为开头,不可以用数字开头
后面字符可以是字母、数字或下划线
变量区分大小写
Python关键字不能用作变量名
-
基本操作符
1、算术运算符
+ - * / % **(指数运算) //(地板除,只保留整数位)
2、比较运算符(结果是bool类型)
== != > < >= <=
3、逻辑运算符
and(与,两侧同真才为真) or(或,两侧同假才为假) not(取反,真假切换)
优先级:()优先于 not 优先于 and 优先于 or
4、赋值运算符
= += -= *= /= %= **= //= (例如c**=a等效于c=c**a)
-
输入和输出
输出的两种字符串格式化方法,其一是使用%做占位符,%后面跟的是变量类型;其二是使用{},后面用 .format()的格式
name='老王'
age=30
print('我是%s,我的年龄是%d'%(name,age))
print('我是{},我的年龄是{}'.format(name,age))
input方法来获取键盘输入
注意:input接受的键盘输入结果都是str类型,如果想要接受数字类型需要将str转成int
name=input('请输入您的姓名:')
age=input('请输入您的年龄:')
print('我的姓名是:%s 年龄是:%s'%(name,age)) #这里如果年龄是后面用%d就会报错
#接收时就转换为整型
name=input('请输入您的姓名:')
age=int(input('请输入您的年龄:'))
print('我的姓名是:%s 年龄是:%d'%(name,age))
流程控制结构
-
if-else语句
单分支 双分支 多分支
# 单分支
# if 条件表达式:
# 代码指令
# ......
score=60
if score<70: #满足条件才会输出以下打印的提示
print('成绩不理想继续加油')
pass #空语句或直接顶格写代码
print('语句运行结束')
# 双分支
# if 条件表达式:
# 代码指令
# else:
# 代码指令
score=70
if score>60: #True
print('成绩及格了')
pass #空语句或直接顶格写代码 可有可无
else: #False时执行
print('成绩不及格')
pass
# 多分支
# if 条件表达式:
# 代码指令
# elif 条件表达式:
# 代码指令
# .....
# else:
# 特征:只要满足其中一个分支的条件,就会退出本层if语句结构
# elif后面必须写上条件和语句
# else是选配,根据实际情况来填写,可能会没有
score=int(input('请输入你的成绩:')) #将str转为int
if score>=90:
print('您的成绩是A等级')
pass
elif score>=80:
print('您的成绩是B等级')
pass
elif score>=70:
print('您的成绩是C等级')
pass
elif score>=60:
print('您的成绩是D等级')
pass
else:#选配
print('不及格')
pass
# 多分支演练,猜拳机小游戏,用到了随机数的库
#0:石头 1:剪刀 2:布
import random #导入随机数
#计算机 人
person=int(input('请出拳:【0:石头 1:剪刀 2:布】'))
computer=random.randint(0,2)
if person==0 and computer==1: #多条件
print('你赢了')
pass
elif person==1 and computer==2:
print('你赢了')
pass
elif person==2 and computer==0:
print('你赢了')
pass
elif person==computer:
print('平手')
pass
else:
print('你输了')
if-else的嵌套使用
xuefen=int(input('请输入你的学分'))
if xuefen>10:
grade = int(input('请输入你的成绩'))
if grade>80:
print('你可以升班了')
pass
else:
print('成绩未达到要求')
pass
pass
else:
print('你的学分太低了')
-
while循环
# while 语法结构
# while 条件表达式:
# 代码指令
# 语法特点
# 1、有初始值
# 2、条件表达式
# 3、变量(循环体内计数变量)的自增自减,否则会造成死循环
#案例 输出1-100之间的数据
index=1 #定义一个变量
while index<=100:
print(index)
index+=1
pass
#循环的嵌套案例 打印九九乘法表
row=1
while row<=9:
col=1
while col<=row:
print('%d*%d=%d'%(row,col,row*col),end=' ') #print默认换行,需要加end=' '阻止换行
col+=1
pass
print()
row+=1
pass
-
for循环
# for语法结构
# for 临时变量 in 容器:
# 代码指令
# 语法特点:遍历操作,依次的取集合容器中的每个值
tag='我是中国人' #定义一个变量
for item in tag:
print(item)
pass
#range 次函数可以生成一个数据集合列表
#range(起始,结束,步长) 步长不能为0,步长不输入就默认为1 区间为左闭右开
for data in range(1,100): #左闭右开
print(data,end=' ')
# 九九乘法用for循环
for i in range(1,10):
for j in range(1,i+1):
print('%d*%d=%d'%(i,j,i*j),end=' ')
pass
print() #控制换行
pass
for---else
account='laowang'
pwd='123'
for i in range(3):
zh=input('请输入账号:')
pd=input('请输入密码:')
if account==zh and pwd==pd:
print('登陆成功')
break #退出本层循环
pass
pass
else: #for-else结构,只要break奏效,那么else的代码将不再执行,否则将会执行else后面的语句
print('您的账号已被系统锁定')
while---else
index=1
while index<=10:
print(index)
if index==6:
break
index+=1
pass
else:
print('执行else')
-
break、continue语句
一定是用在循环当中
break:代表中断结束,满足条件直接结束本层循环
continue:结束本次循环,继续进行下次循环
-
多条件与短路运算
Python数据类型
字符串及常用方法
序列:在Python中,序列就是一组按照顺序排列的值(数据集合)
在python中,存在三种内置的序列类型:
字符串、列表、元组
优点:可以支持索引和切片的操作
特征:第一个正索引为0,指向的是左端;第一个索引为负数的时候,指向的是右端
test='python'
print('获取第一个字符%s'%test[0]) #可以通过下标取数据
for item in test:
print(item,end=' ')
字符串常用函数:
#举例:字符串常用函数
name='zhangsan'
print('姓名首字母变大写%s'%name.capitalize())
a=' hello '
print(a.strip()) #去除字符串两边空格
print(a.lstrip()) #去除字符串左边的空格
print(a.rstrip()) #去除字符串右边的空格
b=a #在此只是把a对象的内存地址赋给了b
print('a的内存地址%d'%id(a)) #id函数 可以查看一个对象的内存地址
print('b的内存地址%d'%id(b)) #b的地址与a相同
dataStr='i love python'
print(dataStr.find('p')) #可以查找目标对象在序列对象中的位置 没找到返回-1,当查找重复字符时返回先找到的位置
print(dataStr.index('o')) #基本与find相同,检测字符串中是否包含子字符串,返回的是下标值
#index如果没有找到对象的数据就会报异常,而find函数不会,找不到的返回-1
print(dataStr.startswith('i')) #判断是否以某字母开始,返回true或false
print(dataStr.endswith('n')) #判断是否以某字母结尾,返回true或false
print(dataStr.upper()) #字符串全转为大写
print(dataStr.lower()) #字符串全转为小写
切片:【高级特性】可以根据下标获取序列对象的任意部分数据
语法结构:[start:end:step] step即步长默认是1,当步长为1时即将范围内左闭右开的字符都取出来,如步长为2即在范围内隔一个取一个字符
# 字符串切片举例
strMsg='hello word'
#slice[start:end:step] 左闭右开 start<=value<end
print(strMsg[2:7]) #打印结果是llo w
print(strMsg[2:]) #取l字符到最后 打印结果llo word
print(strMsg[:3]) #取从首字符到下标为3的字符 strMsg[:3]=strMsg[0:3] 打印结果hel
print(strMsg[::-1]) #倒序输出 符号表示方向 打印结果drow olleh
print(strMsg[2:7:2]) #打印结果low
列表及常用函数
list特点:
1、支持增删改查
2、列表中的数据是可以变化的(数据项可以变化,内存地址不会改变)
3、用[]来表示列表类型,数据项之间用逗号分割,注意:数据项可以是任何类型的数据
4、支持索引和切片来进行操作
列表常用函数:
# li=[] 空列表
# li=[1,2,3,'你好']
# print(len(li)) #打印结果4 #len函数可以获取到列表中的数据个数
# strA='我喜欢python'
# print(len(strA)) #打印结果9
# print(type(li)) #打印结果<class 'list'>
#----------查找------------
listA=['abcd',785,12.23,'qiuzhi',True]
print(listA) #输出完整列表
print(listA[0]) #输出第一个元素 类似于字符串
print(listA[1:3]) #输出从第二个开始到第三个元素 区间获取 同理也是左闭右开
print(listA[2:]) #输出从第三个元素到最后
print(listA[::-1]) #倒序输出
print(listA*3) #输出多次列表中的数据
print(listA.index(785)) #返回的是查找到元素的下标
print(listA.index(785,0,3)) #也可以指定区间查找
#----------增加-----------
listA.append(['fff','ddd']) #追加操作 这里追加了一个列表
listA.append(8888)
print('追加之后:',listA)
listA.insert(1,'这是我要插入的数据') #插入操作 在下标为1的位置即第二个元素的位置插入
print(listA)
rsData=list(range(10)) #强转成list对象
# print(type(rsData))
listA.extend(rsData) #拓展 等于批量增加 打印结果是['abcd', '这是我要插入的数据', 785, 12.23, 'qiuzhi', True, ['fff', 'ddd'], 8888, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
listA.extend([11,22,33,44]) #效果等同于上一行
# listA.append(rsData) #而append一次只能追加一个数据,可以是任何形式,append的添加效果是['abcd', '这是我要插入的数据', 785, 12.23, 'qiuzhi', True, ['fff', 'ddd'], 8888, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
print(listA)
#----------修改-----------
listA[0]=333.6 #可以修改为任何类型
print('修改之后',listA)
#---------删除------------
listB=list(range(10,50))
# del listB[0] #删除列表中第一个元素
del listB[1:3] #批量删除,删除下标为1到下表为2的元素 左闭右开
print(listB)
listB.remove(20) #移除指定数据值的元素,并不是按下标移除
print(listB)
listB.pop(1) #移除指定下标的项,与remove不同
print(listB)
元组
元组:是一种不可变得序列,在创建之后不能做任何改变
1、不可变
2、用()创建元组类型,数据项用逗号分割
3、可以是任何的类型
4、当元组中只有一个元素时要加上逗号,不然解释器会当做整型来处理
5、同样可支持切片操作
#元组的创建,不能增删改查
tupleA=() #空元组
print(id(tupleA))
tupleA=('abcd',89,9.12,'peter',[11,22,33])
print(id(tupleA)) #同样变量名的元组,内存地址不一样
# print(type(tupleA))
# print(tupleA)
# for item in tupleA:
# print(item,end=' ')
# print(tupleA[2:4]) #查找同list基本相同
# print(tupleA[::-1]) #从右往左输出时最右端下标不是0,而是-1,然后往左依次-2,-3,......
# print(tupleA[::-2]) #表示反转字符串,每隔一个取一次
# print(tupleA[-2:-1:]) #倒着取下标为-2到-1区间的元素,左闭右开,打印结果是('peter',)
# tupleA[0]='python' #错误的,不能修改
print(type(tupleA[4]))
tupleA[4][0]=785 #正确的,可以对元组中的列表类型的数据进行修改
print(tupleA)
tupleB=(1)
print(type(tupleB)) #打印结果是<class 'int'>
tupleB=('1')
print(type(tupleB)) #打印结果是<class 'str'>
tupleB=(1,) #当元组中只有一个数据项时,必须要在第一个数据项后面加上逗号
print(type(tupleB)) #打印结果是<class 'tuple'>
tupleC=(1,2,4,3,4,2,2,4,1)
print(tupleC.count(4)) #统计元素出现的次数
字典及常用函数
字典:也是Python中重要的数据类型,由键值对组成的集合,通常使用键来访问数据,效率非常高,和list一样,支持对数据的增删改查。
特点:
1、不是序列类型,没有下标的概念,是一个无序的键值集合,是内置的高级数据类型
2、用{}来表示字典对象,每个键值对用逗号分割
3、键必须是不可变得类型(元组、字符串),值可以是任意的类型
4、每个键必定是唯一的,如果存在重复的键,后者会覆盖前者
字典常用函数:
#如何创建字典
dictA={} #空字典
# print(type(dictA))
dictA={'pro':'艺术','school':'北电'}
# print(type(dictA))
# 添加字典数据
dictA['name']='老王' #key:value
dictA['age']=30
dictA['pos']='歌手'
print(dictA) #输出完整的字典
print(len(dictA)) #数据项长度
# print(dictA['name']) #通过建获取对应的值
#---------修改---------
# dictA['name']='张三' #修改键对应的值
dictA.update({'age':32}) #修改的另一种方式,该函数可添加或更新
dictA.update({'height':185}) #添加
# print(dictA)
#获取所有的键
# print(dictA.keys())
#获取所有的值
# print(dictA.values())
#获取所有的键和值
# print(dictA.items())
#
# for item in dictA.items():
# print(item)
#
# for key,value in dictA.items():
# print('%s==%s'%(key,value)) #等同于print('{}=={}'.format(key,value))
#删除操作
# del dictA['name'] #通过指定键进行删除
# dictA.pop('age') #通过指定键进行删除
# print(dictA)
# 如何排序
# 按照key排序
# print(sorted(dictA.items(),key=lambda d:d[0]))
# 按照value排序
# print(sorted(dictA.items(),key=lambda d:d[1])) #这里value类型不一致无法排序
共有操作
合并操作 + :两个对象相加操作,会合并两个对象,适用于字符串、列表、元组
复制 * :对象自身按指定次数进行+操作,适用于字符串、列表、元组
in判断元素是否存在:判断指定元素,是否存在于对象中。适用于字符串、列表、元组、字典
#共有操作
#-------合并--------
strA='人生苦短'
strB='我用python'
print(strA+strB)
listA=list(range(10))
listB=list(range(11,20))
print(listA+listB)
# -------复制--------
print(strA*3)
print(listA*3)
# -------in 对象是否存在 结果是一个bool值-------
print('生' in strA) #True
print(20 in listA) #Flase
dictA={'name':'peter'}
print('name' in dictA)
Python函数
函数基础
# 函数定义
# def 函数名(参数列表): #参数列表可以是0-n个
# '''
# 备注信息,在函数第一行,采用三个单引号
# :return:
# '''
# 代码块
# 函数的调用:函数名()
函数参数
# 参数的分类:必选参数、默认参数、可变参数、关键字参数
# 1、必选参数,在调用时必须赋值
def sum(a,b): #形式参数,在定义的时候不占内存地址的
sum=a+b
print(sum)
pass
# 函数调用
sum(20,15) #实际参数,实际占用内存地址的
# sum(15) #错误
# 2、默认参数
def sum1(a=20,b=30): #不可以sum1(a=20,b),规则是如果前面给了默认参数,后面也必须给。 像sum1(a,b=30)这种结构可以
print('默认参数使用=%d'%(a+b))
pass
# 默认参数调用
sum1() #两个都有默认参数可以不用提供实参 打印结果50
sum1(40) #当只有一个赋值时,默认给前面的变量 打印结果70
# 3、可变参数(当参数不确定时使用,比较灵活) 接受的数据是元组类型
def getComputer(*args): #可变长度的参数 创建一个空元祖
'''
计算累加和
:param args: 可变长的参数类型
:return:
'''
# print(args)
result=0
for item in args:
result+=item
pass
print('result=%d'%result)
pass
getComputer(1)
getComputer(1,2)
# 4、关键字可变参数
# **来定义
# 在函数体内 参数关键字是一个字典类型,key是一个字符串
def keyFunc(**kwargs): #创建一个空字典
print(kwargs)
pass
# 调用
# keyFunc(1,2,3) 不可以传递的 字典类型才可以
dictA={'name':'leo','age':35}
keyFunc(**dictA) #这一行与上一行合起来是第一种传参方式
keyFunc(name='peter',age=35) #第二种传参方式
def TestMup(*args,**kwargs):
'''
可变参数必须置于关键字可变参数之前
:param args:
:param kwargs:
:return:
'''
函数返回值
# 函数返回值
# 概念:函数执行完以后会返回一个对象,如果在函数的内部有return,就可以返回实际的值,否则返回空
# 类型:可以返回任意类型,返回值类型取决于return后面的类型
# 用途:给调用方返回数据
# 在一个函数体内可以出现多个return关键字,但是肯定只能返回一个return
# 如果一个函数体内执行了return,意味着函数就执行完成推出了,return后面的代码语句将不会执行
# def sum(a,b):
# sum=a+b
# return sum #将计算的结果返回
# rs=sum(10,30) #将返回值赋给其他的变量
# print(rs)
def returnTuple():
return 1,2,3 #返回元组类型的数据
# return {'name':'aaa'} #返回字典类型的数据
A=returnTuple()
print(type(A))
函数嵌套:在一个函数中调用另一个函数
函数例题:
# 例题1
# def add(*a):
# '''
# :param a: 可变长的参数,可以接受一个元组
# :return: 计算和
# '''
# # print(a)
# result=0
# for i in a:
# result+=i
# pass
# return result
# pass
# v=add(1,5,7)
# print(v)
# 例题2
# def newl(List):
# '''
#
# :param List: 接受一个列表或元组
# :return: 返回一个新的列表
# '''
# lis=[]
# le=len(List)
# print(type(List))
# # print(le)
# i=0
# while i<=le:
# lis.append(List[i])
# i+=2
# pass
# return lis
# pass
# a=newl((2,5,7,8,10))
# print(a)
# b=newl(['aaa',5.85,'laowang',(2,5),[2,3]])
# print(b)
# 例题2 法2
# def newl(List):
# lisnew=[]
# index=1
# for i in List:
# if index%2==1:
# lisnew.append(i)
# pass
# index+=1
# pass
# return lisnew
# a=newl([1,2,3,4,5])
# print(a)
# 例题3
# def check(**kwargs):
# # print(kwargs.values())
# for key,value in kwargs.items():
# if len(value)>2:
# kwargs[key]=value[:2]
# pass
# return kwargs
# pass
# a=check(name='laowang',age='adc')
# print(a)
#例题3 法2
# def dictFunc(dictParms): #**kwargs
# '''
# 处理字典类型的数据
# :param dictParms: 字典
# :return: 新的字典
# '''
# result={} #空字典
# for key,value in dictParms.items(): #key-value
# if len(value)>2:
# result[key]=value[:2] #向字典添加数据
# pass
# else:
# result[key]=value
# pass
# pass
# return result
# dictObj={'name':'欧阳夏雨','hobby':['唱歌','跳舞','编程']}
# print(dictFunc(dictObj))
函数的分类:根据函数的返回值和函数的参数
有参数无返回值、有参数有返回值、无参数有返回值、无参数无返回值
局部变量和全局变量
局部变量:在函数内部定义的变量,作用域仅仅在函数内部
(不同的函数可以定义相同的局部变量,但是各用各自的不会相互影响)
局部变量的作用:为了临时的保存数据,需要在函数中定义来进行存储
全局变量:
(当全局变量和局部变量名相同时,函数内部会优先使用函数内部定义的变量)
如果在函数内部想要对全局变量进行修改的话,必须使用global关键字进行声明。
引用
1、在python中,万物皆对象,在函数调用时,实参传递的就是对象的引用(地址)
2、了解了原理之后,就可以更好的去把控,在函数内部的处理是否会影响到函数外部的数据变化
匿名函数
语法:
lambda 参数1,参数2,参数3:表达式
# 特点:
# 1、使用lambda关键字去创建函数
# 2、没有名字的函数
# 3、匿名函数冒号后面的表达式有且只有一个,注意是表达式,不是语句
# 4、匿名函数自带return,而这个return的结果就是表达式计算后的结果。
# M=lambda x,y:x+y #例子 用匿名函数计算两个数的和
# print(M(23,19))
# lambda 与三元运算
# 如下语句
# if a:
# b
# else:
# c
# 能够由以下等效的表达式来模拟:
# b if a else c
# 这样的表达式(三元运算)可以放在lambda中
greater=lambda x,y:x if x>y else y
print(greater(5,3))
# 或者一下直接调用
rs=(lambda x,y:x if x>y else y)(12,16)
print(rs)
递归函数
自己调用自己,且必须有一个明确结束的条件
# def digui(n):
# '''
# 递归实现
# :return: 阶乘参数
# '''
# if n==1:
# return 1
# else:
# return n*digui(n-1)
# pass
# print('5的阶乘是{}'.format(digui(5)))
# 递归案例 模拟实现 树形结构遍历
import os #引入文件操作模块
def findFile(file_path):
listRs=os.listdir(file_path) #得到该路径下的所有文件夹和文件
for fileItem in listRs:
full_path=os.path.join(file_path,fileItem) #获取完整的文件路径
if os.path.isdir(full_path): #判断是否是文件夹
findFile(full_path) #如果是一个文件夹再次去递归
else:
print(fileItem)
pass
pass
else:
return
pass
#调用 搜索文件路径
findFile('D:\文档')
python内置函数
数学运算:
# abs 取绝对值
print(abs(-34))
#round 取近似值
print(round(2.5)) #python中0.5舍 大于0.5入 结果为2
print(round(2.55,1)) #保留1位小数近似 结果为2.5
#pow 求次方
print(2**3)
print(pow(2,3))
#divmod 求商和余数 返回值一个包含商和余数的元组(a//b,a%b) //为地板除只保留整数位
print(divmod(7,3)) #输出结果为(2, 1)
#max 求最大值 对象可以是序列(列表,元组,集合)
#min 求最小值
print(max(5,7))
print(max([2.2,15,58,6]))
print(max((2,3,8,9)))
#sum 求和
#语法 sum(iterable[,start]) iterable--可迭代对象(列表,元组,集合) start--指定相加的参数,没有设置就默认0
print(sum([2,3,5])) #结果10
print(sum([2,3,5],3)) #结果13
#eval 动态执行表达式
a,b,c=1,2,3
print(eval('a*b+c'))
print(eval('a+b+c',{'a':5,'b':3,'c':7}))
类型转换:int() float() str() ord() chr() bool() bin() hex() oct() list() tuple() dict() bytes()
#str() 转换为字符串
#chr() 数字转字符
print(chr(65)) #结果为A
#ord() 与chr()功能相反 字符转数字
#bin() 十进制转2进制
print(bin(10))
#hex() 十进制转换16进制
print(hex(23))
#oct() 十进制转为8进制
#list() 转换为列表
#tuple() 转换为元组
#dict() 创建字典
dic=dict()
dic['name']='laowang'
dic['age']=38
print(dic)
#bytes转换为字节
print(bytes('我喜欢python',encoding='utf-8'))
序列操作:all() any() sorted() reverse() range() zip() enumerate()
#序列操作 str 元组 列表
#all() 返回值:bool 对象中除了是0,空、False外都算True,所有元素都为True,结果才为TRUE
#注意:空元组可空列表都算True
# print(all([])) #True
# print(all(())) #True
# print(all([1,2,3,False])) #False
# print(all([1,2,3,''])) #False
#any() 1返回值:bool 只要有一个元素为True,结果就为TRUE
# print(any(['',0])) #False
#sort 和sorted
li=[2,45,1,67,10]
li.sort() #list的排序方法,sort仅仅适用于列表,直接修改原始对象,默认升序
print(li)
varList=sorted(li) #sorted可对列表或元组排序,排序后返回的是新的列表,与sort不同, 也是默认升序
print(varList)
varList=sorted(li,reverse=True) #降序
print(varList)
#reverse()函数用于反向列表中的元素
#range()函数可创建1个整数列表
#zip() 打包,会把序列中对应的索引位置的元素存储为一个元组,如果可迭代对象的元素个数不一样,那么按照最少的那个迭代对象进行压缩
s1=['a','b','c']
s2=['你','我','他']
# print(list(zip(s1))) #压缩一个数据 里面数据都是元组类型 打印结果[('a',), ('b',), ('c',)]
print(list(zip(s1,s2))) #打印结果[('a', '你'), ('b', '我'), ('c', '他')]
s3=['d','e','f','g']
print(list(zip(s2,s3))) #打印结果[('你', 'd'), ('我', 'e'), ('他', 'f')]
def printbook():
'''
zip应用
:return:
'''
books=[] #存储所有的图书信息
id=input('请输入编号:每个项以空格分隔') #str
bookname=input('请输入书名:每个项以空格分隔') #str
bookpos = input('请输入位置:每个项以空格分隔') # str
idlist=id.split(' ')
namelist = bookname.split(' ')
poslist = bookpos.split(' ')
bookinfo=zip(idlist,namelist,poslist) #打包处理
print(bookinfo)
for bookitem in bookinfo:
'''
zip函数的使用
遍历图书信息进行存储
'''
dictinfo={'编号':bookitem[0],'书名':bookitem[1],'位置':bookitem[2]}
books.append(dictinfo)
pass
for item in books:
print(item)
printbook()
# enumerate函数用于将一个可遍历的数据对象
# (如列表、元组、字符串,字典)组合成一个索引序列,同时列出数据和数据下标
# 一般用于for循环中
listObj=['a','b','c']
for item in enumerate(listObj):
print(item) #元组类型 打印结果(0, 'a') (1, 'b') (2, 'c') 默认下标从1开始
for index,item in enumerate(listObj,5):
print(index,item) #打印结果 5 a 6 b 7 c
集合:add() clear() difference() intersection() union() pop() discard() update()
#set 不支持索引和切片,是一个无序且不重复的容器
#类似于字典 但是只有key 没有value
#创建集合
set1={1,2,3}
print(type(set1))
#添加操作 add
# set1.add('python')
# print(set1)
#清空操作 clear (列表和字典也都可以使用)
# set1.clear()
# print(set1)
#差集
set2={2,3,4}
# rs=set1.difference(set2) #set1有 而set2没有的元素
# print(rs)
# print(set1-set2) #也是差集
#交集
# print(set1.intersection(set2))
# print(set1&set2)
#并集 union
# print(set1.union(set2))
# print(set1|set2)
#pop 就是从集合中拿数据并且同时删除
# quData=set1.pop()
# print(quData) #打印结果 1
# print(set1) #打印结果 {2, 3}
#discard 移除指定的元素
# set1.discard(3) #制定移除元素3
# print(set1)
#update 两个集合
set1.update(set2)
print(set1) #打印结果 {1, 2, 3, 4} 类似于并集
Python面向对象
面向对象(上)
面向对象编程:oop(object oriented programming)
类的三部分:类名,属性(特征),方法(行为)
#类结构 类名 属性 方法
#class 类名:
# 属性
# 方法
class Person:
name='xiaoming' #类属性(定义在类里面,方法外面的属性称之为类属性)
age=20
def eat(self): #实例方法
self.name='xiaowang' #在方法内部定义的(通过类似于self.变量名)变量,是实例属性
print('大口吃饭')
pass
#创建一个对象
xm=Person()
xm.eat()
#实例方法:在类的内部,使用def关键字来定义,第一个参数默认是self(也可以不是self,犯这个位置必须被占用)
#实例方法是归于类的实例所有
#类属性 实例属性
__init__(self):
#__init__(self)
#python自带的内置函数,也称为魔术方法
#是一个初始化的方法,用来定义实例属性和初始化数据的,在创建对象时自动调用
#利用传参的机制可以在创建对象时直接初始化,非常方便
class People:
def __init__(self):
'''
实例属性的声明
'''
self.name='小倩'
self.sex='女生'
self.age=20
pass
def eat(self):
print('吃榴莲')
pass
xq=People() #创建对象是自动执行init函数
print(xq.name,xq.sex,xq.age) #直接输出的是默认值
xq.name='小明'
print(xq.name) #输出修改后的姓名
#改进init
class People:
def __init__(self,name,sex,age): #相当于构造函数
'''
实例属性的声明
'''
self.name=name
self.sex=sex
self.age=age
pass
def eat(self,food):
print(self.name+'喜欢吃'+food)
pass
zp=People('帐篷','男',18)
print(zp.name,zp.sex,zp.age)
zp.eat('苹果')
self:
self只有在类中定义实例方法的时候才有意义,在调用时候不必传入相应的参数。
所谓的self可以理解为对象自己,某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可。self和对象指向同一内存地址。
self的名称是可以更改的,可以定义成其他的名字
self指的是类实例对象本身,相当于java中的this
class Person:
'''
定义类
'''
def eat(self):
'''
实例方法
:return:
'''
print('self=%s'%id(self))
pass
pass
#xw是一个实例化对象
xw=Person()
print('xw=%s'%id(xw))
xw.eat() #输出的两个地址相同
魔术方法
在python中,有一些内置的特定的方法,方法名是“__xxx__”,在进行特定的操作时会自动被调用,这些方法称之为魔术方法
常见的魔术方法:__init__;__str__;__new__;__class__;__del__;
class Person:
'''
定义类
'''
def __init__(self,pro,name,food):
self.pro=pro
self.name=name
self.food=food
print('----init----函数执行')
def eat(self):
'''
实例方法
:return:
'''
print('self=%s'%id(self))
pass
def __str__(self):
return '%s喜欢吃%s'%(self.name,self.food)
def __new__(cls, *args, **kwargs):
'''
创建对象实例的方法 每调用一次就会产生一个新的对象,cls就是class的缩写
场景:可以控制创建对象的一些属性设定,经常用来做单例模式的时候来使用
:param args:
:param kwargs:
:return:
'''
print('----new----函数的执行')
return object.__new__(cls) #cls代表当前这个类 #在这里是真正创建对象实例的
pass
#xw是一个实例化对象
xw=Person('计算机','小王','榴莲')
print(xw) #直接输出对象 当没有魔术方法str时输出的是实例化对象的地址,现在是执行魔术方法str
#__new__ 和 __init__函数的区别
# __new__ 类的实例化方法必须返回该实例,否则对象创建不成功
#__init__用来做数据属性的初始化工作,也可以认为是实例的构造方法,接受类的实例self并对其进行改造
#__new__ 至少有一个参数是cls代表要实例化的类,此参数在实例化时有python解释器自动提供
#__new__函数执行要先于__init__
面向对象(中)
面向对象三大特征:封装、继承、多态
析构方法:
当一个对象被删除(手动删除:del 对象)或者销毁时,python解释器也会默认调用一个方法,即__del__方法(魔术方法的一种)
程序执行结束自动调用__del__方法
封装
其实就是使用初始化构造方法将内容封装到对象中,然后通过对象直接或者self来获取被封装的内容
继承
子类继承父类的属性和行为
语法: class 子类名(父类名):
单继承和多继承
多继承语法:class 子类名(父类名1,父类名2)
当出现(子类对象.函数)语句时,优先在在子类中寻找该函数,如果子类中没有,才去父类中寻找该函数(多继承时先找父类1,再找父类2)。
重写
所谓重写就是子类中,有一个父类相同名字的方法,在子类中的方法会覆盖父类中同名的方法。
super.__init__(name,color) #在子类的构造函数中加上这个函数,相当于调用父类的构造函数,即具备父类中的初始化属性
#super是自动找父类,进而调用其方法,假设继承了多个父类,那么会按顺序逐个去找。然后再调用
类属性和实例属性
类属性:就是类对象所拥有的属性,它被所有类对象的实例对象所共有,类对象和实例对象都可以访问
实例属性:实例对象所拥有的属性,只能通过实例对象访问。若存在相同名称的实例属性和类属性,实例属性的优先级高
#类属性 实例属性
class Student:
name='黎明' #属于类属性 就是student类对象所拥有的
def __init__(self,age):
self.age=age #实例属性
pass
print('--------lm的数据------------')
lm=Student(18)
print(lm.name) #通过实例对象去访问类属性 打印结果黎明
lm.name='刘德华' #通过实例对象无法对类属性修改,实质上是添加了一个实例属性,因此下面打印时实例属性覆盖掉了类属性
print(lm.name) #打印结果刘德华
print(lm.age)
print('---------xh的数据-----------')
xh=Student(28)
print(xh.name) #打印结果黎明 类属性没有改变
print(xh.age)
#类属性可以通过类对象去修改
Student.name='张学友'
print('---------zw的数据-----------')
zw=Student(28)
print(zw.name) #打印结果张学友
print('-----通过类对象student去访问name------')
print(Student.name) #通过类对象访问类属性
# print(Student.age) #实例属性不能通过类对象访问
类方法
类对象所拥有的方法,对于类方法第一个参数必须是类对象,第一个参数通常默认使用cls(类似于实例方法中的self),需要用@classmethod来表示静态方法,类方法可以通过类对象和实例对象调用
静态方法
类对象所拥有的方法,需要用@staticmethod来表示静态方法,静态方法通常不需要任何参数,若是要引用属性的话,则可以通过类对象或实例对象去引用即可。
为什么使用静态方法?
由于静态方法主要来存放逻辑性的代码,本身和类以及实例对象没有交互
也就是说,在静态方法中,不会涉及到类方法和属性的操作。
class Pople:
country='china'
#类方法用classmethod来进行修饰
@classmethod
def get_country(cls): #cls相当于self
return cls.country #访问类属性
pass
@classmethod
def change_country(cls,data):
cls.country=data #在类方法中修改类属性的值
pass
@staticmethod
def getData():
return Pople.country
pass
pass
print(Pople.get_country()) #通过类对象去调用类方法
p=Pople()
print(p.get_country()) #通过实例对象调用类方法
Pople.change_country('美国')
print(Pople.get_country()) #通过类对象去调用类方法
print(Pople.getData()) #通过类对象调用静态方法
print(p.getData()) #注意一般情况下 我不会用实例对象去访问静态方法
多态
就是同一种行为对于不同的子类(对象)有不同的行为表现,
要实现多态的两个前提:
1、继承:多态必须发生在父类和子类之间
2、重写:子类重写父类方法
#案例演示
class Animal:
def say_who(self):
print('我是一个动物')
pass
pass
class Duck(Animal):
def say_who(self): #重写父类的方法
print('我是一只鸭子')
pass
pass
class Dog(Animal):
def say_who(self):
print('我是一只小狗')
pass
pass
def commonInvoke(obj):
'''
统一调用的方法
:return:
'''
obj.say_who()
# duck1=Duck()
# duck1.say_who()
# dog1=Dog()
# dog1.say_who()
listObj=[Duck(),Dog()]
for item in listObj:
commonInvoke(item)
面向对象(下)
私有化属性
前面加两个下划线,将属性私有化
特点:
1.私有化属性不能在类外部直接的访问,可以类的内部随意的使用
2、子类不能继承父类的私有化属性(只能继承父类公共的属性和行为)
使用场景:
1.把特定的属性隐藏起来,不想类的外部直接调用,不想让属性的值随意改变
2.保护这个属性,不让子类继承
class Person:
__hobby='跳舞' #类属性私有化,也同理,就不能在类外部直接访问了,在类内部可以访问
def __init__(self):
self.__name='李四' #加两个下划线,将属性私有化后,就不能在类外部直接访问了,在类内部可以访问
self.age=18
pass
def __str__(self):
'''
私有化属性在类内部可以使用
:return:
'''
return '{}的年龄是{},爱好是{}'.format(self.__name,self.age,self.__hobby)
def changeValue(self): #在类内部修改私有化类属性可以
Person.__hobby='唱歌'
class Student(Person):
def printinfo(self):
# print(self.__name) #无法访问父类中的私有化属性
print(self.age)
pass
x1=Person()
# print(x1.__name) #在外部不可以访问私有化属性
print(x1)
stu=Student()
stu.printinfo()
# print(stu.__name) #私有化属性无法继承
# print(stu.__hobby) #不可以访问
# print(Person.__hobby) #不可以访问
stu.changeValue()
print(stu)
私有化方法
前面加两个下划线,将方法私有化
同理也是子类不能继承,父类不能调用
class Animal():
def __eat(self):
print('吃东西')
pass
def run(self):
self.__eat() #在此调用私有化的方法
print('跑')
pass
pass
class Bird(Animal):
pass
b1=Bird()
# b1.__eat() #在外部不可以访问私有化方法
b1.run()
单下划线、双下划线、头尾双下划线说明
前面加单下划线,是protected类型的变量,即保护类型,只能允许在本身与子类进行访问。
前面加双下划线,是私有化的标志,只允许类内访问,子类也不可以访问。
前后加双下划线,是魔术方法的标志。
后面加单下划线,是为了避免属性名与python关键字冲突。无特殊意义。
property
访问私有变量,一般写两个方法一个访问一个修改,由方法控制访问
这样给调用者的感觉是调用了一个方法并不是访问属性。我们怎么做到让调用者直接以访问属性的方式,而且我们又能控制的方式提供给调用者
class Person():
def __init__(self):
self.__age=18 #定义了一个私有化属性
pass
# 实现方式1
# def get_age(self): #访问私有实例属性
# return self.__age
# def set_age(self,age): #修改私有实例属性
# if age<0:
# print('年龄不能小于0')
# else:
# self.__age=age
# pass
# pass
# #定义一个类属性 实现通过直接访问属性的形式去访问私有的属性
# age=property(get_age,set_age)
# 实现方式2 通过装饰器的方式来声明
@property #使用装饰器对age进行装饰,提供一个getter方法
def age(self):
return self.__age
@age.setter #使用装饰器进行装饰,提供一个setter方法
def age(self,parms):
if parms<0:
print('年龄不能小于0')
else:
self.__age=parms
pass
pass
pass
p1=Person()
print(p1.age) #通过设置property实现了直接访问私有属性
p1.age=25 #通过设置property实现了修改私有属性
print(p1.age)
# p1.get_age()
# p1.set_age(25)
项目实战
文件操作与垃圾回收机制
正则表达式
未完