python学习
目录
Python基础语法
Python基础语法
1,数据类型
python3中有六个标准的 数据类型:
Number(数字)
String(字符串)
List(列表)
Tuple(元组)
Set(集合)
Dictionary(字典)
语法:
1. int(): 将其他数据类型转换为整型
str1 = "12"
print(int(str1)) # 12
print(int(str1,base=16)) # 18 表示将字符串12以16进制的形式转换为整型.
2.str(): 将其他数据类型转换为字符串
num = 12
num1 = 87
# print(num1 + num) # 99
# print(type(num)) # <class 'int'>
# print(type(num1)) # <class 'int'>
str1 = str(num)
str2 = str(num1)
3.float(): 将其他数据类型转换为浮点型
float1 = "12.34"
# print(type(float1)) #
# print(type(float(float1))) # <class 'float'>
float2 = "hello123" # 不能转换为浮点型
print(float(float2)) # 报错
4.bool() : 用于将给定参数转换为布尔类型.如果没有参数,返回False
# 布尔类型: True 和 False
# bool(): 将其他数据类型转换为布尔类型
print(bool(100)) # True
print(bool(3.12)) # True
print(bool(0)) # False
print(bool("hello")) # True
print(bool('')) # False
print(bool("")) # False
print(bool(' ')) # True
print(bool([12,34,7])) # True
5.list() : 用于将其他数据类型转换为列表.
tup = (12,34,678,9)
# print(tup)
# print(type(tup)) # <class 'tuple'>
# print(type(list(tup))) # <class 'list'>
list1 = list(tup)
# print(list1) # [12, 34, 678, 9]
str = "hello"
list2 = list(str)
# print(list2) # ['h', 'e', 'l', 'l', 'o']
num = 12
# print(list(num)) 报错
注意:
一般情况下,是字符串和元组类型的数据转换为列表类型居多
6.tuple() : 用于将其他类型的数据转换为元组
print(bool([])) # False
print(bool((32,45,67))) # True
print(bool({"name":"三哥","age":18})) # True
print(bool(())) #False
print(bool({})) # False
print(bool(None)) # False
# 数字0,空字符串""或者'',空列表[],空元组(),空字典{},空集合set(),None这些数据转换为bool类型
时是False.
# 隐式类型转换 一般用于条件表达式 if if..else.
print(3 > 2) # True
print(98 < 87) # False
num = 12
if num: # num在这里隐式转换为True
print("num是一个数字")
7.list() : 用于将其他数据类型转换为列表
tup = (12,34,678,9)
# print(tup)
# print(type(tup)) # <class 'tuple'>
# print(type(list(tup))) # <class 'list'>
list1 = list(tup)
# print(list1) # [12, 34, 678, 9]
str = "hello"
list2 = list(str)
# print(list2) # ['h', 'e', 'l', 'l', 'o']
num = 12
# print(list(num)) 报错
注意:
一般情况下,是字符串和元组类型的数据转换为列表类型居多.
8.1str(字符串)
# 创建字符串
str = "apple"
str1 = 'orange'
print(type(str),type(str1))
# \ 转义字符 作用:让一些符号失去原有的意义
str2 = "\"吴亦凡\""
str3 = '\'都美竹\''
print(str2,str3)
# 定义字符串的时候,单双引号可以互相嵌套
str4 = "凡哥,'这次车翻的有点厉害'"
print(str4)
8.2字符串特殊处理:
字符串前加 r
r"" 的作用是去除转义字符.
即如果是“\n”那么表示一个反斜杠字符,一个字母n,而不是表示换行了。
以r开头的字符,常用于正则表达式,对应着re模块。
字符串前加f
# 以 f开头表示在字符串内支持大括号内的python 表达式
print(f'{name} done in {time.time() - t0:.2f} s')
字符串前加b
b" "前缀表示:后面字符串是bytes 类型。网络编程中,服务器和浏览器只认bytes 类型数据。
字符串前加u
例:u"我是含有中文字符组成的字符串。"
后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次
使用时出现乱码。
8.3字符串的下标和切片
下标:也叫索引,表示第几个数据
在程序中,下标一般从0开始,可以通过下标获取指定位置的数据
str1 = "welcome"
print(str1[0]) # w
print(str1[3]) # c
切片:从字符串中复制一段指定的内容,生成一个新的字符串
str2 = "welcome to beijing"
'''
切片的语法:
字符串[start:end:step]
start 表示开始下标 截取的字符串包含开始下标对应的字符串
end表示结束下标
step表示步长
'''
print(str2[0:3]) # wel 包含start 不包含end
print(str2[1:] # 若只设置了start 表示从开始下标一直截取到最后
print(str2[:4]) # 若只设置了end 表示从第一个字符开始一直截取到指定结束的位置
print(str2[1:4:2]) # ec
print(str2[1:4:0]) # 在切片的时候,步长不能设置为0
print(str2[::]) # 若未设置开始和结束,表示复制字符串
print(str2[::-1]) # 表示翻转字符串
print(str2[-9:-3]) #start和end若都为负数,表示从右边开始数
11获取长度和次数
str3 = "凡哥,'这次车翻的有点厉害'"
# 获取字符串的长度 len()
print(len(str3))
# count() 在整个字符串中查找子字符串出现的次数
str = "电脑卡了,ss电脑呢?"
print(str.count("电脑")) # 3
#在指定区间内查找出现的次数
print(str.count("电脑",5,30)) # 2
8.4字符串查找:
# find() 查找子串在字符串中第一次出现的位置, 返回的是下标,若未找到返回-1
ss3 = "123asdfASDCXaZ8765sahbzcd6a79"
print(ss3.find("a")) # 3
print(ss3.find("y")) # -1 未找到子串,返回-1
# 在指定区间内查找
print(ss3.find("a",5,20)) # 12
# rfind 查找子串在字符串中最后一次出现的位置,返回的是下标,若未找到返回-1
print(ss3.rfind("a")) # 25
print(ss3.rfind("y")) # -1
# index() 功能和find类似 在字符串中未找到的时候,直接报错
print(ss3.index("d")) # 5
# print(ss3.index("y")) # ValueError: substring not found
#
# max() min() 依据ASCII 码进行的获取
print(max(ss3)) # z
print(min(ss3)) # 1
8.5大小写转换
# 2.字符串大小写转换 upper() lower()
# upper()将字符串中的小写字母转换为大写
str1 = "i Miss you Very Much!"
print(str1.upper()) # I MISS YOU VERY MUCH!
# lower() 将字符串中的大写字母转化为小写
print(str1.lower()) # i miss you very much!
# swapcase 将字符串中的大写转换为小写,将小写转换为大写
print(str1.swapcase()) # I mISS YOU vERY mUCH!
# title() 将英文中每个单词的首字母转换为大写
str2 = "i love you forever!"
print(str2.title()) # I Love You Forever!
8.6提取
# strip() 去除字符串两边的指定字符(默认去除的是空格)
ss4 = " today is a nice day "
ss5 = "***today is a nice day****"
print(ss4)
print(ss4.strip())
print(ss5)
print(ss5.strip("*"))
x
# lstrip 只去除左边的指定字符(默认去除的是空格)
# print(ss5.lstrip("*"))
# rstrip 只去除右边的指定字符(默认去除的是空格)
print(ss5.rstrip("*"))
8.7分割和合并
# split() 以指定字符对字符串进行分割(默认是空格)
ss6 = "this is a string example.....wow!"
print(ss6.split()) # 以空格进行分割 ['this', 'is', 'a', 'string',
'example.....wow!']
print(ss6.split("i"))
# splitlines() 按照行切割
ss7 = '''将进酒
君不见黄河之水天上来,
奔流到海不复回.
君不见高堂明镜悲白发,
************.
'''
print(ss7)
print(ss7.splitlines())
# join 以指定字符进行合并字符串
ss8 = "-"
tuple1 = ("hello","every","body")
print(tuple1)
print(ss8.join(tuple1)) # hello-every-body
8.8替换
# 替换
replace() 对字符串中的数据进行替换
ss9 = "AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBB"
print(ss9)
print(ss9.replace("AAAAA","***"))
# 控制替换的字符的次数
print(ss9.replace("AAAAA","***",2))
8.9判断
# 字符串判断
# isupper() 检测字符串中的字母是否全部大写
print("ASDqwe123".isupper()) # False
print("ASD123".isupper()) # True
# islower() 检测字符串中的字母是否全部小写
print("ASDqwe123".islower()) # False
print("qwe123".islower()) # True
# isdigit() 检测字符串是否只由数字组成
print("1234".isdigit()) #True
print("1234asd".isdigit()) # False
#istitle() 检测字符串中的首字母是否大写
print("Hello World".istitle()) # True
print("hello everybody".istitle()) # False
# isalpha() 检测字符串是否只由字母和文字组成
print("你好everyone".isalpha()) # True
print("你好everyone123".isalpha()) # False
# isalnum()
8.10前缀和后缀(重点)
# 前缀和后缀 判断字符串是否以指定字符开头或者以指定字符结束
# startswith() 判断字符串是否以指定字符开头
# endwith() 判断字符串是否以指定字符结束
s1 = "HelloPython"
print(s1.startswith("Hello")) # True
print(s1.endswith("thon")) # True
8.11编解码
# encode() 编码
# decode() 解码
s2 = "hello 千锋教育"
print(s2.encode()) # b'hello
\xe5\x8d\x83\xe9\x94\x8b\xe6\x95\x99\xe8\x82\xb2'
print(s2.encode("utf-8")) # b'hello
\xe5\x8d\x83\xe9\x94\x8b\xe6\x95\x99\xe8\x82\xb2'
print(s2.encode("gbk")) # b'hello \xc7\xa7\xb7\xe6\xbd\xcc\xd3\xfd'
# 解码
s3 = b'hello \xe5\x8d\x83\xe9\x94\x8b\xe6\x95\x99\xe8\x82\xb2'
print(s3.decode()) #
8.12ASCII码转换
chr() 将对应的ASCII码的值转换为对应的字符
ord() 获取对应字符的ASCII的值
print(chr(68)) # D
print(ord("a")) # 97
8.13格式化输出
# 字符串格式化输出
'''
% 占位符
%d 表示整数
%f 表示小数
%s 表示字符串
%.3f (表示保留3位小数,保留的小数数位自己可以控制)
'''
name = "畅总"
sex = "型男"
money = 198987932.787532
print("我的姓名是:%s"%name)
print("我的大号是%s,性别是%s,我的财富是%.2f"%(name,sex,money))
# 还可以通过 f"{}{}"这种方式实现格式化输出
print(f"我的大号是:{name},性别是:{sex},我的财富是{money}")
9.1.list(列表)
list1 = ["幻影","兰博基尼","迈巴赫","玛莎拉蒂","布加迪威龙","红
旗","唐","宋","元","汉","秦",123,True]
print(list1)
9.2创建列表
1.创建列表
list1 = [] 空列表
2.带元素的列表
list2 = ["五菱宏光","哈弗H6","大狗","欧拉",True]
3.列表中的元素可以是不同的数据类型
list3 = [12,3.13,True,False,"hello","米西米西"]
注意: 将数据保存到列表的时候,不用考虑列表的大小,如果数据很大的话,底层会进行自动扩容.
9.3获取元素
访问方式:通过索引访问列list2 = ["五菱宏光","哈弗H6","大狗","欧拉",True]
list2[0] 表示第一个元素
list2[-1] 表示最后一个元素
len(list2) 表示获取列表元素的个数
list2[11]
表中的元素【有序,索引:决定了元素在内存中的位置】
9.4替换元素(修改元素的值)
list2 = ["五菱宏光","哈弗H6","大狗","欧拉",True]
# 修改列表元素 语法:列表名[索引] = 值
print(list2)
list2[2] = "天狗"
print(list2)
9.5遍历列表
list3 = ["肠粉","佛跳墙","白切鸡","云吞"]
'''
# 第一种方式:
for i in list3:
print(i)
# 第二种方式: 通过索引的方式访问元素
for i in range(len(list3)):
print(list3[i])
'''
# 第三种方式:enumrate() 同时遍历索引和元素
for index,value in enumerate(list3):
print(index,value)
9.6列表元素组合
合并列表: 通过 + 实现
list = [12,34,6,8,3.13]
list1 = ["荔枝","龙眼","桂圆","榴莲","芒果"]
print(list,list1)
# 通过 + 实现列表的合并 list + list1
list2 = list + list1
print(list2)
9.7列表元素重复
重复输出列表中的元素: 通过 * 实现
list = [1,2,3]
list1 = list * 4
print(list1)
9.10判断元素是否在列表中
判断指定元素是否在列表中,使用成员运算符检查 in 和 not in 返回值是一个布尔类型
True和False
list1 = [12,34,4.12,"haha","lele","hehe"]
print(12 in list1) # True
if "haha" in list1:
print("字符串在列表中")
else:
print("不在列表中")
9.11列表截取【切片】
list2 = [13,45,2,35,7,9]
# 语法: 列表名[开始下标:结束下标] 特点: 前闭后开 包含开始下标的元素不包含结束下标的元
素
print(list2[1:6])
print(list2[:4]) # [13, 45, 2, 35]
print(list2[1:]) # [45, 2, 35, 7, 9]
print(list2[:]) # [13, 45, 2, 35, 7, 9]
print(list2[-2:]) # [7, 9]
9.12列表的功能【掌握】
# 1.添加元素
'''
# a. append() 向列表的尾部追加元素
list1 = ["香妃","妲己","赵飞燕","杨贵妃","东施"]
print(list1)
# 追加单个元素
list1.append("西施")
# 追加多个元素的时候,不能直接追加,必须使用列表的方式追加,原列表变成了二维列表
list1.append(["王昭君","貂蝉","大小乔"])
print(list1)
# b.extend 用于在列表末尾一次追加另一个列表中的多个元素
list1 = ["香妃","妲己","赵飞燕","杨贵妃","东施"]
list1.extend(["乾隆","商纣王","汉昭帝","唐玄宗","解博超"])
list1.extend("秦始皇") # "秦" "始" "皇"
print(list1)
# c.insert() 在列表中指定的索引处插入元素,后面的其他的元素依次后延
list2 = ["秦始皇","汉武帝","曹操","刘备","孙权"]
list2.insert(1,"刘邦")
# 若想一次性插入多个元素使用列表的形式插入 原列表会变为二维列表
list2.insert(3,["诸葛亮","马超"])
print(list2)
'''
#2. 删除元素
list2 = ["秦始皇","汉武帝","曹操","刘备","孙权"]
'''
# pop() 传输的参数是下标 不传参数的时候,默认移除最后一个元素,返回的是原列表
print(list2)
# list2.pop() ["秦始皇","汉武帝","曹操","刘备"]
list2.pop(2) # ['秦始皇', '汉武帝', '刘备', '孙权']
print(list2)
'''
'''
# remove() 传输的参数是指定移除的元素
list2.remove("刘备")
print(list2)
'''
# clear() 清空列表
print(list2)
list2.clear()
print(list2) # []
3.获取元素
list = [12,34,2,5.23,True,False,"hello"]
# print(len(list)) # len 获取列表的长度
# 获取列表中的最大值 max()
list1 = [12,3,4,32,98,14,3,78,3,34,3]
# print(max(list1))
# 获取列表中的最大值 min()
# print(min(list1))
# 获取指定元素的索引 index(元素名称)
# print(list1.index(98))
4.其他用法
# 列表的其他用法
list = [12,42,34,16,87]
# print(list)
# reverse 翻转列表元素 注意:在原列表的内部进行翻转,不会生成新列表
# list.reverse()
# print(list)
# sort() 对原列表元素进行排序 默认是升序 不会生成一个新的列表
# 升序
# list.sort()
# 降序 在sort函数中传入reverse=True 实现降序
# list.sort(reverse=True)
# print(list)
# sorted() 对列表元素进行排序,默认是升序, 排序的结果会生成一个新列表
# 升序
# list1 = sorted(list)
# 降序 传入reverse=True
list1 = sorted(list,reverse=True)
#print(list1)
list2 = ["a","hello","abe","bc","everyone"]
# 按照元素的长度进行排序
list3 = sorted(list2,key=len)
print(list3)
9.13二维列表
list = [12,34,6,7,"boy",True] # 一维列表
list1 = [32,14,"girl",False,[16,31,9.12,"haha"]] #二维列表
print(list1[1]) # 14
print(list1[4][2]) # 9.12
9.14列表生成式
list comprehension
系统内置的用于创建list的方式
range(start,end,step)缺点:生成的列表一般情况下都是等差数列
# 最基本的列表
# 1.生成1-10之间所有的数字
list1 = list(range(1,11))
print(list1)
# 需求:通过程序的方式生成列表 [1,4,9,16,25]
#第一种方法:使用原始的方式生成
list2 = []
for i in range(1,6):
list2.append(i ** 2)
print(list2)
# 第二种方法:使用列表生成式
list3 = [i**2 for i in range(1,6)]
print(list3) # [1, 4, 9, 16, 25]
# 使用列表生成式 生成1-10之间所有的奇数
list4 = [i for i in range(1,11) if i % 2 == 1]
print(list4)
# 使用列表生成式 生成1-10之间所有的奇数并且能被3整除的数字
list5 = [i for i in range(1,11) if i % 2 == 1 and i % 3 == 0]
print(list5)
# 列表生成式中使用双重循环
list6 = [i + j for i in "xyz" for j in "987"]
print(list6)
# 字典生成式:(了解)
dict1 = {i:i*i for i in range(1,6)}
print(dict1)
# 集合生成式:(了解)
set1 = {i*i for i in range(1,6)}
print(set1)
10.1.dict(字典)
列表和元组的使用缺点:当存储的数据要动态添加、删除的时候,我们一般使用列表,但是列表
有时会遇到一些麻烦
解决方案:既能存储多个数据,还能在访问元素的很方便的定位到需要的元素,采用字典
语法: {键1: 值1, 键2: 值2, 键3: 值3, ..., 键n: 值n}
说明:键值对: key-value
字典和列表类似,都可以用来存储多个数据
在列表中查找某个元素时,是根据下标进行的;字典中找某个元素时,是根据'名字'(就是
冒号:前面的那个值,例如上面代码中的'name'、'id'、'sex')
字典中的每个元素都由2部分组成,键:值。例如 'name':'班长' ,'name'为键,'班长'为值
键可以使用数字、布尔值、元组,字符串等不可变数据类型,但是一般习惯使用字符串,切
记不能使用列表等可变数据类型
每个字典里的key都是唯一的,如果出现了多个相同的key,后面的value会覆盖之前的value
习惯使用场景:
列表更适合保存相似数据,比如多个商品、多个姓名、多个时间
字典更适合保存不同数据,比如一个商品的不同信息、一个人的不同信息
10.2定义字典
# 1.定义空字典 {}
dict1 = {}
print(type(dict1)) # <class 'dict'>
#2.定义非空字典
# 第一种定义字典的方式
dict2 = {"name":"小解","age":25,"love":"女","sex":"**"} # 最常用
print(dict2)
print(type(dict2))
print(dict2["name"],dict2["love"]) # 访问字典
# 第二种定义字典的方式 dict(key=value,key1=value1,...) key表示键 value表示值
dict3 = dict(num1 = "123",num2 = "987")
print(dict3)
# 第三种定义字典的方式
# dict(zip([key1,key2,key3....],[value1,value2,value3......]))
# 注意:key和value的数量不一致时,以数量少的为基准
dict4 = dict(zip(['n1','n2','n3'],[12,34,56]))
dict5 = dict(zip(['n1','n2','n3'],[12,34,56,45,67,89]))
print(dict4)
print(dict5)
# 第四种方式:
dict6 = dict([("a",10),("b","98"),("c",67),("d",34)])
print(dict6) # {'a': 10, 'b': '98', 'c': 67, 'd': 34}
10.3字典的操作
# 1.访问字典中的元素
# 第一种方式: 直接通过下标访问
dict1 = {"name":"中国医生","author":"刘伟强","person":"张涵予"}
print(dict1['author'])
# print(dict1['money']) # 访问字典中不存在的key时,直接报错
# 第二种方式:通过get()方法获取
print(dict1.get('name'))
print(dict1.get('money')) # None 访问字典中不存在的key时,返回None
print(dict1.get('money',10000000)) # 访问字典中不存在的key时,若传递了第二个参数,第二个
参数会设置为默认值,
#2. 获取字典的长度 len()
print(len(dict1))
# 3.获取字典中所有的key
print(dict1.keys()) # dict_keys(['name', 'author', 'person'])
# 4.获取字典中所有的value
print(dict1.values()) # dict_values(['中国医生', '刘伟强', '张涵予'])
# 5.获取字典中的所有的key和value items()
print(dict1.items()) # dict_items([('name', '中国医生'), ('author', '刘伟强'),
('person', '张涵予')])
# 6.遍历字典
'''
# 第一种方式: for in
for i in dict1: # 遍历字典中所有的key
print(i)
# 第二种方式:enumrate() 遍历字典中所有的key
for k,v in enumerate(dict1):
print(k,'----',v)
# 第三种方式: items 遍历字典中所有的key和value
for k,v in dict1.items():
print(k,'----',v)
# 第四种方式:遍历 字典中所有的值
for v in dict1.values():
print(v)
# 合并字典 update()
dict2 = {"name":"袁建鑫","money":"1999999","age":23}
dict3 = {"sex":"猛男"}
dict2.update(dict3)
print(dict2)
'''
dict4 = {"name":"iPhone13","money":20000,"color":"土豪金"}
# 增
dict4["size"] = 6.5
print(dict4)
# 改
dict4['color'] = "骚粉"
print(dict4)
# 删
# 第一种:pop() 删除指定的元素
#dict4.pop("color")
print(dict4)
# 第二种:popitem() 随机返回并删除字典中的最后一对key和value
dict4.popitem()
print(dict4)
# clear() 清空字典
dict4.clear()
print(dict4)
11.1set集合
和数学上的集合基本是一样的,
特点:不允许有重复元素,可以进行交集,并集,差集的运算
本质:无序,无重复元素的集合
11.22创建
# 创建空集合
set1 = set()
print(set1)
print(type(set1)) #<class 'set'>
# 创建包含元素的集合
set2 = {12,345,633,21}
set3 = {"hello","world","everyone"}
print(set2,set3)
print(type(set2)) # <class 'set'>
11.3操作
# 获取集合的长度 len()
print(len(set2)) # 4
# 集合不能通过下标访问元素
# print(set2[3])
11.4添加
set2 = {12,345,633,21}
# 向集合中添加一个元素 add()
set2.add(98)
print(set2)
# 通过update() 向集合中添加多个元素 追加的元素以列表的形式出现
set2.update([1,2,3])
print(set2)
11.5删除
set2 = {12,345,633,21}
# pop() 随机删除一个
set2.pop()
print(set2)
# remove() 删除指定的元素,传入的参数是要删除的元素,如果删除的元素不存在,会报错
# set2.remove(22)
set2.remove(2)
print(set2)
# discard()删除指定的元素,传入的参数是要删除的元素,如果删除的元素不存在,不会报错
set2.discard(21)
# set2.discard(22)
print(set2)
# clear() 清空集合
set2.clear()
#print(set2)
11.6遍历
set2 = {12,345,633,21}
for i in set2:
print(i)
11.7交集和并集
# 集合之间的关系
set5 = {12,34,56,23,86s}
set4 = {23,45,25,12,41}
print(set5 & set4) # 交集
print(set5 - set4) # 差集
print(set5 | set4) # 并集
print(set4 > set5) # set4是否包含set5
print(set4 < set5) # set5是否包含set4
12.1元组(tuple)
a.列表:[ ] 元组:( )
b.列表中的元素可以进行增加和删除操作,但是,元组中的元素不能修改【元素:一旦被初始化,将不
能发生改变】
12.2创建元组
创建空列表:list1 = [ ]
创建有元素的列表:list1 = [元素1,元素2,。。。。。]
创建空元组:tuple1 = ( )
创建有元素的元组:tuple1 = (元素1,元素2,。。。。)
# 1.创建空元组
tuple1 = ()
print(type(tuple1)) # <class 'tuple'>
# 2.创建带有元素的元组
tuple2 = (12,34,6,87)
print(tuple2)
print(type(tuple2)) # <class 'tuple'>
# 3.元组中的元素可以是各种类型
tuple3 = (12,34,4.12,"lala",True,m)
print(tuple3)
# 注意:创建的元组只有一个元素时, 会在元素的后面加上一个逗号 ,
tuple4 = (2)
print(tuple4)
print(type(tuple4)) # <class 'int'>
tuple5 = (3,)
print(tuple5)
print(type(tuple5)) #<class 'tuple'>
12.3元组元素的访问
tuple1 = (14,32,35,7,87)
# 1.访问元组的元素,使用下标访问,下标默认从0开始
print(tuple1[1])
# print(tuple1[5]) # tuple index out of range 索引越界
print(tuple1[-1]) # 87 访问元组的最后一个元素 下标是-1
print(tuple1[-3]) # 35
# 2. 元组的元素的值不能进行修改
# tuple1[2] = 99
# print(tuple1) # 'tuple' object does not support item assignment
# 3.删除元组 del
# del tuple1
print(tuple1) # name 'tuple1' is not defined
12.4元组操作
# 1.合并元组 +
tuple1 = (12,34,56)
tuple2 = (3.12,56,"hello")
print(tuple1 + tuple2)
# 2.重复元组中的元素 *
tuple3 = (23,45,67)
print(tuple3 * 4)
# 3.判断指定元素是否在元组中 使用成员运算符 in 和 not in
print(56 in tuple2)
if "hello" in tuple2:
print("终于找到你")
else:
print("你在哪里呢!")
# 4.元组的截取(切片)
tuple4 = (12,3,5,7,98)
print(tuple4[1:4]) # (3, 5, 7)
print(tuple4[-1:]) # (98,)
print(tuple4[:2]) # (12, 3)
12.5元组功能
# 元组常见的功能
#1.len 获取元组的长度
print(len(tuple4)) # 5
# 2.获取元组中的最大值max()和最小值min()
print(max(tuple4)) # 98
print(min(tuple4)) # 3
# 3.其他数据类型转换为元组 tuple()
list1 = [12,34,57,89]
print(type(list1)) # <class 'list'>
print(type(tuple(list1))) # <class 'tuple'>
# 4.遍历元组
# 第一种方式: for in
for i in tuple4:
print(i)
# 第二种方式: 通过下标访问
for i in range(len(tuple4)):
print(tuple4[i])
# 第三种方式: enumrate() 返回索引和元素
for key,value in enumerate(tuple4):
print(key,value)
12.6二维元组
# 二维元组
tuple2 = (12,34,5,6,(763,341,23),980,89)
print(tuple2)
print(tuple2[3]) # 6
print(tuple2[4][1]) # 二维元组的访问
12.7赋值 深拷贝 浅拷贝
#深浅拷贝的可视化视图
http://pythontutor.com/live.html#mode=edit
# 赋值: 其实就是对象的引用(别名)
list = [12,34,57,9]
list1 = list
list[1] = 78
# print(list,list1)
# 浅拷贝: 拷贝父对象,不会拷贝对象内部的子对象.浅拷贝一维列表的时候,前后两个列表是独立的.
import copy
a = [12,35,98,23] # 一维列表
b = a.copy()
a[1] = 67
# print(a,b)
# 浅拷贝在拷贝二维列表的时候,只能拷贝最外层列表,不能拷贝父对象中的子对象,当修改子对象中的值的时
候,新拷贝的对象也会发生变化
c = [14,53,25,[31,89,26],42] # 二维列表
d = c.copy()
c[3][1] = 11
print(c,d)
# 若要解决浅拷贝处理二维列表时的问题,需要使用深拷贝解决
e = [14,53,25,[31,89,26],42] # 二维列表
f = copy.deepcopy(e)
e[3][1] = 11
print(e,f)
13.1匿名函数
# 匿名函数: lambda
def fn(n):
return n**2
print(fn(3))
# 匿名函数
f1 = lambda n: n**2
print(f1(3))
#匿名函数
f2 = lambda x,y:x*y
print(f2(12,3))
#有名字的函数的写法
def ji(x,y):
return x*y
13.2回调函数
def fn(a,b):
print(a + b)
fn(12,34) # 46
test = fn # 将函数fn赋值给一个变量test, 那这个变量test能够实现和函数fn一样的功能
print(type(test),type(fn)) # <class 'function'> <class 'function'>
test(12,34) # 46
# 函数名: fn既是函数的名称,同时也指向了该函数的对象(变量)
# 函数调用的格式: 函数名()====>变量名()
# 回调函数: 把一个函数(a)作为一个参数传递到另外一个函数(b)中去,那么函数a就叫做回调函数.
def add(x,y):
print(x+y)
def cha(x,y):
print(x-y)
def ji(x,y):
print(x*y)
def shang(x,y):
print(x/y)
add(56,23)
cha(78,21)
# 封装一个函数,实现加减乘除运算.
def demo(x,y,func):
func(x,y)
demo(56,23,add) # 此时add函数就是一个回调函数
demo(78,12,cha)
13.3闭包和装饰器【掌握】
如果在一个函数的内部定义另外一个函数,外部的函数叫做外函数,内部的函数叫做内函数
如果在一个外部函数中定义一个内部函数,并且外部函数的返回值是内部函数,就构成了一个闭
包,则这个内部函数就被称为闭包【closure】
实现函数闭包的条件:
1.必须是函数嵌套函数
2.内部函数必须引用一个定义在闭合范围内的外部函数的变量,----内部函数引用外部变量
3.外部函数必须返回内部的函数
# 闭包: 如果在一个外部函数中定义一个内部函数,并且外部函数的返回值是内部函数,就构成了一个
闭包,则这个内部函数就被称为闭包【closure】
# 最简单的闭包
# 外部函数
def outer():
# 内部函数
def inner():
print("lala")
return inner # 将内部函数返回
fn = outer() # fn =====> inner函数
fn() # 相当于调用了inner函数 输出 lala
# 内部函数使用外部函数的变量
def outer1(b):
a = 10
def inner1():
# 内部函数可以使用外部函数的变量
print(a + b)
return inner1
fun1 = outer1(12)
fun1()
'''
注意:
1.当闭包执行完毕后,仍然能够保存住当前的运行环境
2.闭包可以根据外部作用域的局部变量得到不同的效果,类似于配置功能,类似于我们可以通过修改外部
变量,闭包根据变量的改变实现不同的功能.
应用场景: 装饰器
'''
13.4装饰器
def test():
print("你好啊!")
# test()
# 需求: 给上面的函数test增加一个功能, 输出 我很好
# 第一种方式: 修改了原来的函数
'''
def test():
print("你好啊!")
print("我很好")
test()
# 第二种方式: 定义一个新函数,在新函数中调用原函数,然后追加功能
def test1():
test()
print("我很好")
test1()
'''
13.5简单装饰器
# 原函数
def test():
print("你好啊!")
# 需求: 给上面的函数test增加一个功能, 输出 我很好
# 第三种方式: 通过装饰器的方式给函数追加功能 装饰器使用闭包实现
'''
闭包函数:
1.函数嵌套函数
2.内部函数使用外部函数的变量
3.外部函数中返回内部函数
'''
#a.书写闭包函数 此处的outer函数就是装饰器函数
def outer(fn): #b. fn表示形参, 实际调用的时候传递的是原函数的名字
def inner():
fn() #c.调用原函数
#d. 给原函数添加功能, 注意:添加的功能可以写在原函数的上面也可以写在原函数的下面
print("我很好")
return inner
print("添加装饰器之前:",test,__name__) #<function test at
0x00000223ED1DC268>
test = outer(test)
print("添加装饰器之后:",test,__name__) # <function outer.<locals>.inner at
0x00000223ED793510>
test()
总结:
1.在装饰器中,给原函数添加的功能,可以写在原函数的上面,也可以写在原函数的下面
2.outer 函数就是我们的装饰器函数
13.6系统的简写
#a.书写闭包函数 此处的outer函数就是装饰器函数
def outer(fn): #b. fn表示形参, 实际调用的时候传递的是原函数的名字
def inner():
fn() #c.调用原函数
#d. 给原函数添加功能, 注意:添加的功能可以写在原函数的上面也可以写在原函数的下面
print("我很好")
return inner
# test = outer(test)
# 装饰器的简写方式 @ + 装饰器名称
@outer # 等价于 =====>test = outer(test)
def test():
print("你好啊!")
test()
'''
注意:
1.在使用装饰器的简写方式的时候,原函数必须在装饰器函数的下面
2.outer就是装饰器函数. @outer等价于 test = outer(test)
'''
13.7不定长参数的装饰器(通用装饰器)
# 同一个装饰器装饰多个函数
def jisuan(fn):
def inner(*args):
print("数学运算的结果是:",end=" ")
fn(*args)
return inner
@jisuan
def add(a,b):
print(a+b)
add(12,34)
@jisuan
def cha(a,b,c):
print(a-b-c)
cha(100,23,26)
13.8带返回值的装饰器
def outer(fn):
def inner():
print("我的爱好是:",end = " ")
return fn() # fn() ===> swim() ===> "i like swimming(这句话返回到了第4
行)
return inner
@outer
def swim():
return "i like swimming!"
love = swim()
print(love)
13.9多个装饰器作用同一个函数
# 多个装饰器作用域一个函数
def outer1(fn):
def inner():
print("~~~~~~~1111")
fn()
return inner
def outer2(fn):s
def inner():
print("~~~~~~~2222")
fn()
return inner
# 原函数
@outer2
@outer1
def show():
print("今晚我的好基友从广州过来了,好开心!....")
show()
'''
当多个装饰器修饰一个函数的时候,装饰器从上往下依次执行. 并且原函数只执行一次.
'''
14.1global和nonlocal关键字的使用
global
num = 11
def test():
num = 78
print(num)
test() # 78
print(num) # 11
# 若想在函数的内部,对全局变量进行修改,需要使用global关键字
num1 = 11
def test1():
# 通过global关键字将函数内部声明变量变为了全局变量
global num1
num1 = 75
print(num1)
test1() # 75
print(num1) # 75
.nonlocal
# nolocal 关键字主要用于闭包函数中
# nolocal关键字用于闭包函数中
x = 15 # 全局变量
def outer():
x = 19
def inner():
# x = 23
# global x # 使用的是 x = 15
nonlocal x # 这时候使用的变量是 x = 19
x += 1
print("inner:",x)
return inner
# 闭包会保存住当前的运行环境
test = outer()
test() # 20
test() # 21
test() # 22
num = 11
def demo():
print(num)
demo() # 11
demo() # 11
demo() # 11
15.fifilter和map函数
filter是一个内置类 主要做数据的筛选.第一个参数是一个函数,第二个参数是一个可迭代对象
ages = [12,34,5,21,44,98]
# 将ages列表中数值大于30的数字筛选出来
# 返回值是一个filter类型的对象
list1 = filter(lambda ele:ele > 30,ages)
print(list1)
map() 主要是用于数据的处理 第一个参数是一个函数 第二个参数是一个可迭代对象
# 返回值:是一个map类型的对象
list2 = map(lambda ele:ele + 3,list1)
print(lsit2)
16.time时间模块
import time
# 获取时间戳 从1970年1月1日0时0分0秒到现在经过的秒数
time.time()
# 延迟程序多长时间执行一次
time.sleep()
17.datetime日期模块【掌握】
import datetime
# 获取当前的日期对象
date = datetime.datetime.now()
print(date)
# 设置日期对象
date1 = datetime.datetime(year=2022,month=11,day=10,hour=10,minute=23,second=11)
print(date1)
print(type(date1)) # <class 'datetime.datetime'>
print(date1.year,date1.month,date1.day) # 年 月 日
print(date1.hour,date1.minute,date1.second) # 时 分 秒
print(date1.date()) # 2022-11-10
print(date1.time()) # 10:23:11
# 将datetime.datetime类型转换为字符串
# strftime() 将日期对象转换为字符串
print(type(date1.strftime("%Y-%m-%d %H:%M:%S"))) # <class 'str'>
print(date1.strftime("%Y{}%m{}%d{}").format("年","月","日")) #2022年11月10日
# strptime() 将字符串转换为日期对象
str1 = "2021-07-27 10:40:21"
print(type(datetime.datetime.strptime(str1,'%Y-%m-%d %H:%M:%S'))) # <class
'datetime.datetime'>
# timestamp() 日期对象转换为时间戳da daimestamp()) # 1668046991.0
# fromtimestamp() 时间戳转换为日期对象
print(datetime.datetime.fromtimestamp(1668046991.0)) # 2022-11-10 10:23:11
# 时间差
d1 = datetime.datetime(2022,1,13)
d2 = datetime.datetime(2021,10,1)
print(d1 - d2)
print(d2 - d1)
# timedelta 代表两个日期之间的时间差
dt = datetime.timedelta(days=5,hours=8)
print(d1 + dt) # 2022-01-18 08:00:00
print(d1 - dt) # 2022-01-07 16:00:00
'''
# %y 两位数的年份表示(00-99)
# %Y 四位数的年份表示(000-9999)
# %m 月份(01-12)
# %d 月内中的一天(0-31)
# %H 24小时制小时数(0-23)
# %I 12小时制小时数(01-12)
# %M 分钟数(00-59)
# %S 秒(00-59)
# %a 本地简化星期名称
# %A 本地完整星期名称
# %b 本地简化的月份名称
# %B 本地完整的月份名称
# %c 本地相应的日期表示和时间表示
# %j 年内的一天(001-366)
# %p 本地A.M.或P.M.的等价符
# %U 一年中的星期数(00-53)星期天为星期的开始
# %w 星期(0-6),星期天为星期的开始
# %W 一年中的星期数(00-53)星期一为星期的开始
# %x 本地相应的日期表示
# %X 本地相应的时间表示
# %% %号本身
'''
18.1os模块
用于获取系统的功能,主要用于操作文件或者文件夹
import os
# listdir 查看指定目录下面所有的文件夹和文件
# r"" 将字符串中的特殊字符进行转义
print(os.listdir(r"C:\Users\chenbingjie\Desktop\python2105\day11")) #
['test.py', '代码', '作业', '昨日作业', '笔记', '视频']
# 当前目录 .
# 上级目录 ..
# curdir 表示当前目录
print(os.curdir) # .
# getcwd() 获取当前路径
print(os.getcwd()) # C:\Users\chenbingjie\Desktop\python2105\day11\代码
# mkdir() 创建文件夹 (不能创建已经存在的文件夹)
# os.mkdir("测试")
# makedirs() 创建多层文件夹
# os.makedirs("a/b/c")
# rmdir() 删除文件夹 (只能删除空文件夹)
# os.rmdir("demo")
# rename() 重命名文件夹或者重命名文件
# os.rename("a","a11")
# ./表示当前目录 ../表示上级目录
# os.rename("../test.py","../demo.py")
# remove() 删除文件
# os.remove("demo.py")
# os.path.join() 拼接路径
print(os.path.join(r"C:\Users\chenbingjie\Desktop\python2105\day11\代
码","func.py"))
# os.path.split() 拆分路径
path = r"C:\Users\chenbingjie\Desktop\python2105\day11\代码\1栈和队列.py"
print(os.path.split(path))
# os.path.splitext() 拆分文件和扩展名
print(os.path.splitext(path))
# os.path.abspath 获取绝对路径
print(os.path.abspath("func.py"))
# os.path.getsize() 获取文件大小
print(os.path.getsize("func.py"))
# os.path.isfile() 判断是否是文件,若是文件返回True 若不是文件 返回False
print(os.path.isfile("func.py")) # True
# os.path.isdir() 判断是否是文件夹, 若是文件夹 返回True 若不是文件夹 返回False
print(os.path.isdir("a11")) # True
# os.path.exists() 判断文件或者文件夹是否存在 若存在返回True 若不存在 返回False
print(os.path.exists("demo.py")) #False
# os.path.dirname 获取路径的文件夹部分
print(os.path.dirname(path))
# os.path.basename 获取路径的文件名部分
print(os.path.basename(path))
重点掌握:
1.os.listdir() 获取指定路径下的文件夹和文件 (是一个列表)
2.os.mkdir() 创建目录(目录存在,不能创建)
3.os.makedirs() 创建多层目录
4.os.rmdir() 删除目录
5.os.remove() 删除文件
6.os.rename() 重命名文件或者重命名文件夹
7.os.path.join() 拼接路径
8.os.path.split() 拆分路径
9.os.path.splitext() 拆分文件名和扩展名
10.os.path.isfile() 判断是否是文件
11.os.path.isdir() 判断是否是目录
12.os.path.exists() 判断文件或者文件夹是否存在
13.os.path.getsize() 获取文件大小
18.2递归遍历目录
# 需求: 查找当前目录下面的所有的 .py文件和 .txt文件
# 提示: listdir() endwith()
path = r"C:\Users\chenbingjie\Desktop\python2105\day11\代码"
import os
def get_file(path):
# 判断路径是否存在
if not os.path.exists(path):
print("路径不存在")
return
file_list = os.listdir(path)
# print(file_list)
for file in file_list:
if file.endswith(".py") or file.endswith(".txt"):
print(file)
get_file(path)
import os
# 需求: 使用递归的方式遍历newdir文件夹下面的所有文件和文件夹
path = r"C:\Users\chenbingjie\Desktop\python2105\day11\代码\newdir"
def search_dir(path):
# 判断路径是否合法
if not os.path.exists(path):
print("路径不存在")
return
file_list = os.listdir(path) # ['dir1', 'dir2', 'os.py']
for file in file_list:
# dir1 = "C:\Users\chenbingjie\Desktop\python2105\day11\代码\newdir\dir1"
# 获取文件或者文件夹的绝对路径
file_path = os.path.join(path,file)
# print(file_path)
# 判断file_path是否是文件,若是文件直接输出,若是文件夹通过递归方式继续遍历
if os.path.isfile(file_path):
print("---",file,"是文件")
# 否则是文件夹
else:
print(file,"是文件夹")
# 递归
search_dir(file_path)
search_dir(path)
19.面向对象
python中的面向对象的学习主要是类和对象。
类:多个具有特殊功能的个体的集合 例如: 人类 狗 猫
对象:在一个类中,一个具有特殊功能的个体,能够帮忙解决某件特定的事情,也被称为实例
【instance】
比如: 左韬 左韬家的黑毛猪 陈冰杰家的狼青
两者之间的关系:类用于描述某一类对象的共同特征,而对象是类的具体的存在
思考问题:先有类还是先有对象?
类的定义
语法:
class 类名( ):
说明:
代码演示:
# dir1 = "C:\Users\chenbingjie\Desktop\python2105\day11\代码\newdir\dir1"
# 获取文件或者文件夹的绝对路径
file_path = os.path.join(path,file)
# print(file_path)
# 判断file_path是否是文件,若是文件直接输出,若是文件夹通过递归方式继续遍历
if os.path.isfile(file_path):
print("---",file,"是文件")
# 否则是文件夹
else:
print(file,"是文件夹")
# 递归
search_dir(file_path)
search_dir(path)
类体
a.Python中使用class关键字定义类
b.类名只要是一个合法的标识符即可,但是要求:遵循大驼峰命名法则【首单词的首字母大写,不同单词之间首字母大写】
c.通过缩进区分类体
d.类体一般包含两部分内容:属性和方法(属性就是描述一些静态信息的,比如人的姓名\年龄\性别等 等, 方法:一般用函数表示,用来实现具体的功能)
代码演示:
class Dog():
# 类属性
name = "局长"
sex = "公"
# 类方法
def eat(self):
print(self.name,"吃肉!")
def say(self):
print("我是吼的方法")
类中的方法和变量的定义
类中的方法和变量是为了描述事物的行为和特征
类中定义的方法被称为成员方法
类中定义的变量被称为成员变量,也被称为属性 [os.name]
成员变量:类具有的特征
成员方法:类具有的行为
类存在的意义:拥有相同特征和行为的对象可以抽取出来一个类,类的存在是为了创建一个具体 的对象
代码演示:
class Dog():
# 类属性
name = "局长"
sex = "公"
# 类方法
def eat(self):
print(self.name,"吃肉!")
def say(self):
print("我是吼的方法")
类中方法和属性的使用
1.创建对象【实例化对象】
已知类,通过类创建对象
对象的创建过程被对象的实例化过程
语法:变量名 = 值
对象名 = 类名()
代码演示:
# 定义Dog类
class Dog():
# 类属性
name = "局长"
sex = "公"
# 类方法
def eat(self):
print(self.name, "吃肉!")
def say(self):
print("我是吼的方法")
# 通过Dog类创建对象
labuladuo = Dog()
#通过对象访问方法
labuladuo.eat()
labuladuo.say()
# 通过对象访问属性
print(labuladuo.name)
print(labuladuo.sex)
总结:
访问变量采用:对象名.属性名
访问方法采用:对象名.方法名(参数列表)
构造函数和析构函数
1.构造函数
采用上面的方式创建对象【直接给成员变量赋值】,很多的类一般倾向于创建成有初始状态的
__init__:构造函数【作用:创建对象,给对象的成员变量赋初始值】
构造函数:构造器
调用的时机:当一个对象被创建的时候,第一个被自动调用的函数
per = Person()
语法:
def __init__(self,args1,args2....)
函数体
说明:
a.之前的写法中并没有显式的定义__init__函数,说明系统默认提供了一个无参的构造函数
b.args1,args2...一般设置的形参列表和成员变量有关
代码演示:
class GirlFriend():
'''
类属性:(不推荐这么写)
name = "王凡老表"
age = 22
'''
# 构造函数 参数是对象相关的属性
def __init__(self,name,age):
# 对象属性
self.name = name
self.age = age
print("构造函数的触发时机是:当创建对象的时候自动触发")
# 对象方法
def say(self):
print(self.name,"喊大源,来啊来啊!")
def sing(self):
print("唱歌给大源听,喝了吧!")
# 当创建对象的时候,会自动调用__init__()
wangfanlaobiao = GirlFriend("王小妹",22)
wangfanlaobiao.say()
析构函数
与构造函数正好相反,当对象被销毁的时候自动调用的函数,被称为析构函数
__del__:
删除变量: del 变量名,此时可以触发析构函数的调用
使用情景:清理工作,比如关闭数据库,关闭文件等
代码演示:
class GirlFriend():
'''
类属性:(不推荐这么写)
name = "王凡老表"
age = 22
'''
# 对象方法
def sing(self):
print("唱歌给大源听,喝了吧!")
# 析构函数:触发时机是当对象被删除时,会被自动调用,释放内存
def __del__(self):
print("脚本运行结束,释放内存")
# 当创建对象的时候,会自动调用__init__()
wangfanlaobiao = GirlFriend()
wangfanlaobiao.sing()
print("我是最后执行的一句代码了!")
'''
析构函数的应用场景:
关闭数据库 保存文件
内存回收的方式:
1.当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数会被调用一次,这样可以用来释放内存空
间.
2.当使用del删除对象的时候,也会调用该对象的析构函数,相当于手动释放内存
'''
封装
1.概念
广义的封装:函数和类的定义本身,就是封装的体现
狭义的封装:一个类的某些属性,在使用的过程 中,不希望被外界直接访问,而是把这个属性给
作为私有的【只有当前类持有】,然后暴露给外界一个访问的方法即可【间接访问属性】
封装的本质:就是属性私有化的过程
封装的好处:提高了数据的安全性,提高了数据的复用性
属性私有化和方法私有化
如果想让成员变量不被外界直接访问,则可以在属性名称的前面添加两个下划线__,成员变量则被
称为私有成员变量
私有属性的特点:只能在类的内部直接被访问,在外界不能直接访问
代码演示:
class Girl():
def __init__(self,name,sex,height):
self.name = name
self.sex = sex
self.height = height
# 比如女孩的年龄是秘密,在外面不能轻易的访问,需要把年龄设置为私有属性
self.__age = 18
def say(self):
print("帅哥,帮个忙呗!")
# 在类的内部可以访问私有属性
def sayAge(self,boyFriend):
if boyFriend == "大源":
print(f"{self.name}偷偷的告诉{boyFriend}说:老娘今年88了!")
else:
print("女孩的年龄是秘密,不知道吗?上来就问,活该你单身,傻狗!")
# 私有方法
# 接吻
def __kiss(self):
print("一吻定终身!")
# 类中可以访问私有方法
def love(self,relationship):
if relationship == "情侣关系":
self.__kiss()
else:
print("不能随便kiss,小心中毒!")
xiaohong = Girl("小红","美女",165)
print(xiaohong.name)
print(xiaohong.sex)
print(xiaohong.height)
# print(xiaohong.age) # 将age设置为私有属性后,外部不能直接访问
xiaohong.say()
xiaohong.sayAge("大源")
xiaohong.love("情侣关系")
'''
私有属性:
1.写法:在属性的前面加两个下划线 __age
2.用法:只能在类的内部访问,不能在类的外部访问 可以在类的内部设置一个外部访问的接口(这个接
口一般会做各种条件判断,满足后才能访问),让外部获取私有属性的值
私有方法:
1.写法:在方法的前面加两个下划线 __kiss()
2.用法:只能在类的内部访问,不能在类的外部访问. 私有方法一般是用来在类的内部实现某些功能
的,对于外部来说没有实质的意义.这种方法一般定义为私有方法.
'''
get函数和set函数
get函数和set函数并不是系统的函数,而是自定义的,为了和封装的概念相吻合,起名为getXxx
和setXxx
get函数:获取值
set函数:赋值【传值】
代码演示:
上面的访问和设置私有属性的命名规则不推荐.
# 第一种访问和设置 私有属性的方式 get和set函数
class Girl():
def __init__(self,name,age):
self.name = name
self.__age = age
# 访问私有属性 命名规则: get + 私有属性名(属性名单词首字母大写)
def getAge(self):
return self.__age
# 设置私有属性 命名规则:set + 私有属性名(属性名单词首字母大写)
def setAge(self,age):
self.__age = age
lan = Girl("小兰",21)
print(lan.name)
# print(lan.__age)
# 访问私有属性
age = lan.getAge()
print(age)
# 设置私有属性
lan.setAge(18)
print(lan.getAge())
.@property装饰器
装饰器的作用:可以给函数动态添加功能,对于类的成员方法,装饰器一样起作用
Python内置的@property装饰器的作用:将一个函数变成属性使用
@property装饰器:简化get函数和set函数
使用:
@property装饰器作用相当于get函数,同时,会生成一个新的装饰器
@属性名.settter,相当于set函数的作用
作用:使用在类中的成员函数中,可以简化代码,同时可以保证对参数做校验
代码演示:
# 第一种访问和设置 私有属性的方式 get和set函数
class Girl():
def __init__(self,name,age):
self.name = name
self.__age = age
'''
# 访问私有属性 命名规则: get + 私有属性名(属性名单词首字母大写)
def getAge(self):
return self.__age
# 设置私有属性 命名规则:set + 私有属性名(属性名单词首字母大写)
def setAge(self,age):
self.__age = age
'''
# 通过装饰器@property 获取私有属性age 相当于getAge()
@property
def age(self):
return self.__age
# 通过装饰器设置私有属性 @ + 私有属性名 + setter 相当于 setAge()
@age.setter
def age(self,age):
self.__age = age
lan = Girl("小兰",21)
print(lan.name)
print(lan.age) # 通过装饰器修访问私有属性,访问格式: 对象名.私有属性名
lan.age = 19 # 通过装饰器设置私有属性,格式: 对象名.私有属性名 = 值
print(lan.age)
类方法和静态方法
类方法:使用@classmethod装饰器修饰的方法,被称为类方法,可以通过类名调用,也可以通
过对象调用,但是一般情况下使用类名调用
静态方法:使用@staticmethod装饰器修饰的方法,被称为静态方法,可以通过类名调用,也可
以通过对象调用,但是一般情况下使用类名调用
代码演示:
class Animal():
# 类属性
name = "牧羊犬"
# 对象属性
def __init__(self,name,sex):
self.name = name
self.sex = sex
'''
类方法:
1.通过@classmethod装饰器修饰的方法就是类方法
2.类方法可以使用类名或者对象调用. 但是一般情况下使用类名调用类方法(节省内存)
3.没有self,在类方法中不可以使用其他对象的属性和方法(包括私有属性和私有方法)
4.可以调用类属性和其他的类方法, 通过cls来调用
5.形参的名字cls是class的简写,可以更换,只不过是约定俗成的写法而已
6.cls表示的是当前类
'''
@classmethod
def run(cls):
print("我是类方法")
print(cls.name)
print(cls == Animal) # cls表示的是当前类
'''
静态方法:
1.通过@staticmethod装饰器修饰的方法就是静态方法
2.通过类名或者对象名都可以调用静态方法 (推荐使用类名调用)
3.静态方法形式参数中没有cls, 在静态方法中不建议调用(类属性\类方法\静态方法)
4.静态方法一般是一个单独的方法,只是写在类中
'''
# 静态方法
@staticmethod
def eat():
print("我是静态方法")
Animal.run() # 类名调用类方法
Animal.eat() # 类调用静态方法
# 创建对象
dog = Animal('中华土狗','公')
# dog.run() # 对象调用类方法
总结:实例方法【成员方法】、类方法以及静态方法之间的区别
a.语法上
实例方法:第一个参数一般为self,在调用的时候不需要传参,代表的是当前对象【实例】
静态方法:没有特殊要求
类方法:第一个参数必须为cls,代表的是当前类
在调用上
实例方法:只能对象
静态方法:对象 或者 类
类方法:对象 或者 类
在继承上【相同点】
实例方法、静态方法、类方法:当子类中出现和父类中重名的函数的时候,子类对象调用的是子类中的方法
【重写】
注意:注意区分三种函数的书写形式,在使用,没有绝对的区分
类中的常用属性
__name__
通过类名访问,获取类名字符串
不能通过对象访问,否则报错
__dict__
通过类名访问,获取指定类的信息【类方法,静态方法,成员方法】,返回的是一个字典
通过对象访问,获取的该对象的信息【所有的属性和值】,,返回的是一个字典
__bases__
通过类名访问,查看指定类的所有的父类【基类】
代码演示:
class Animal(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
def eat(self):
print("吃")
animal = Animal("二哈","公狗")
# __name__ 通过类名访问获取当前类的类名,不能通过对象访问
print(Animal.__name__) # Animal
# __dict__以字典的形式返回类的属性和方法 以及 对象的属性
print(Animal.__dict__) # 以字典的形式显示类的属性和方法
print(animal.__dict__) # 以字典的形式显示对象的属性
# __bases__ 获取指定类的父类 返回的是一个元组
print(Animal.__bases__) # (<class 'object'>,)
魔术方法: __str__() 和 __repr__()
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def swim(self):
print("游泳的方法")
# __str__() 触发时机: 当打印对象的时候,自动触发. 一般用它来以字符串的形式返回对象的相关
信息,必须使用return返回数据
'''
def __str__(self):
return f"姓名是:{self.name},年龄是:{self.age}"
# print("姓名是:{self.name},年龄是:{self.age}")
'''
# __repr__()作用和 __str__()类似,若两者都存在,执行 __str__()
def __repr__(self):
return f"姓名是:{self.name},年龄是:{self.age}"
# print("姓名是:{self.name},年龄是:{self.age}")
xiaohong = Person("小红",18)
print(xiaohong)
继承
概念
如果两个或者两个以上的类具有相同的属性或者成员方法,我们可以抽取一个类出来,在抽取的
类中声明公共的部分
被抽取出来的类:父类,基类,超类,根类
两个或者两个以上的类:子类,派生类
他们之间的关系:子类 继承自 父类
父类的属性和方法子类可以直接使用。
注意:a. object是所有类的父类,如果一个类没有显式指明它的父类,则默认为object
b.简化代码,提高代码的复用性
.单继承
2.1使用
简单来说,一个子类只能有一个父类,被称为单继承
语法:
父类:
class 父类类名(object):
类体【所有子类公共的部分】
子类:
class 子类类名(父类类名):
类体【子类特有的属性和成员方法】
说明:一般情况下,如果一个类没有显式的指明父类,则统统书写为object
代码演示:
最简单的继承
# 父类
class Person(object):
def say(self):
print("说话的方法")
# 子类
class Boy(Person): # 定义一个子类 将父类的类名传进去 子类就继承了父类
def eat(self):
print("子类自己的吃饭的方法")
boy = Boy()
boy.eat() # 子类调用自己的方法
boy.say() # 子类调用父类的方法
有构造函数的单继承
# 父类
class Animal(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
def eat(self):
print("所有的动物都有捕食的技能")
# 子类
class Cat(Animal):
def __init__(self,name,sex,tail): # 先继承父类的属性,再重构
# 1.经典的写法
# Animal.__init__(self,name,sex) # 继承父类的构造方法
# 2.隐式的继承父类的构造函数
super(Cat,self).__init__(name,sex)
self.tail = tail # 定义子类自己的属性
def catchMouse(self):
print("猫抓老鼠")
cat = Cat("波斯猫","母","揪尾巴")
print(cat.name)
print(cat.sex)
print(cat.tail)
cat.eat()
cat.catchMouse()
总结:
继承的特点:
a.子类对象可以直接访问父类中非私有化的属性
b.子类对象可以调用父类中非私有化的成员方法
c.父类对象不能访问或者调用子类 中任意的内容
继承的优缺点:
优点:
a.简化代码,减少代码的冗余
b.提高代码的复用性
c.提高了代码的可维护性
d.继承是多态的前提
缺点:
通常使用耦合性来描述类与类之间的关系,耦合性越低,则说明代码的质量越高
但是,在继承关系中,耦合性相对较高【如果修改父类,则子类也会随着发生改变】
多继承
一个子类可以有多个父类
语法:
class 子类类名(父类1,父类2,父类3.。。。):
类体
代码演示:
# 父亲类
class Father(object):
def __init__(self,surname):
self.surname = surname
def make_money(self):
print("钱难挣,屎难吃!")
# 母亲类
class Mother(object):
def __init__(self,height):
self.height = height
def eat(self):
print("一言不合,就干饭!")
# 子类
class Son(Father,Mother): # 子类继承多个父类时,在括号内写多个父类名称即可
def __init__(self,surname,height,weight):
# 继承父类的构造函数
Father.__init__(self,surname)
Mother.__init__(self,height)
self.weight = weight
def play(self):
print("就这这么飞倍爽!")
son = Son("卢","178",160)
print(son.surname)
print(son.height)
print(son.weight)
son.make_money()
son.eat()
son.play()
多态【了解】
一种事物的多种体现形式,函数的重写其实就是多态的一种体现
在Python中,多态指的是父类的引用指向子类的对象
代码演示:
# 多态: 在继承的基础上,(多个子类继承一个父类,并且重写父类的一个方法),去调用子类的方法可以
实现不同的功能.
# 父类
class Animal():
def eat(self):
print("吃的发方法")
# 子类
class Fish(Animal):
def eat(self):
print("大鱼吃小鱼,小鱼吃虾米")
class Dog(Animal):
def eat(self):
print("狼行千里吃肉,狗走万里吃粑粑!")
class Cat(Animal):
def eat(self):
print("猫爱吃鱼!")
# 严格意义的多态:使用对象调用eat方法
class Person():
def feed(self,animal):
animal.eat()
'''
在父类和子类中出现了函数重名的情况,会调用子类的函数, 子类和父类函数重名的现象叫做重载
(重写)
不同的子类之间调用和父类相同的方法,调用的都是自己的方法, 这就是多态的一种体现.
'''
fish = Fish()
dog = Dog()
cat = Cat()
# 最简单的多态的体现
fish.eat()
dog.eat()
cat.eat()
# 严格意义的多态的体现
Person().feed(dog)
Person().feed(cat)
总结:
简化代码,提高代码的可读性,可维护性
单例设计模式
1.概念
什么是设计模式
经过已经总结好的解决问题的方案
23种设计模式,比较常用的是单例设计模式,工厂设计模式,代理模式,装饰模式
什么是单例设计模式
单个实例【对象】
在程序运行的过程中,确保某一个类只能有一个实例【对象】,不管在哪个模块中获取对象,获取到的
都是同一个对象
单例设计模式的核心:一个类有且仅有一个实例,并且这个实例需要应用在整个工程中
应用场景
实际应用:数据库连接池操作-----》应用程序中多处需要连接到数据库------》只需要创建一个连接
池即可,避免资源的浪费
.实现
模块
Python的模块就是天然的单例设计模式
模块的工作原理:
import xxx,模块被第一次导入的时候,会生成一个.pyc文件,当第二次导入的时候,会直接加
载.pyc文件,将不会再去执行模块源代码
使用new
__new__():实例从无到有的过程【对象的创建过程】
代码演示:
class Person(object):
# __init__ 对象初始化属性时,自动触发
def __init__(self,name):
print("__init__")
self.name = name
# 定义一个类属性,接收创建好的对象
instance = None
@classmethod
def __new__(cls,*args,**kwargs):
print("__new__")
# 如果类属性的instance == None表示 该类未创建过对象
if cls.instance == None:
cls.instance = super().__new__(cls)
return cls.instance
p = Person("陈梦")
p1 = Person("陈梦")
p2 = Person("陈梦")
print(p == p1 == p2)
__new__():在创建对象的时候自动触发
__init__():在给创建的对象赋值属性的时候触发.
20正则表达式
引入案例
代码演示:
#需求:判断一个手机号码是否合法.
""
import re #regular Expession
#使用正则表达式实现上面的需求
# 需求:封装一个函数,判断手机号是否合法?
def checkPhone(phone):
if len(phone) != 11:
return "手机号码长度不符合要求!"
if phone[0] != "1":
return "手机号码不是1开头!"
if not phone.isdigit():
return "手机号码不是全部是数字"
return "手机号码格式正确"
# print(checkPhone("28617767023"))
# 正则验证手机号码是否正确
import re
result= re.search("^1\d{10}$","28617767024"))
if(result):
return "手机号码合法"
else:
return "手机号码不合法"
概述
正则表达式【Regular Expression】,简写为regex,RE,使用单个字符串来描述一系列具有特殊
格式的字符串
功能:
a.搜索
b.替换
c.匹配
使用情景:
爬虫
验证手机号,验证邮箱,密码【用户名】
常用的函数
# 1.re.match() 匹配字符串是否以指定的正则内容开头,匹配成功返回对象, 匹配失败返回None
'''
第一个参数: 正则表达式
第二个参数: 要验证的字符串
第三个参数: 可选参数,正则表达式修饰符
'''
# \d: 0-9
# +:表示出现1次或者多次
print(re.match("\d+","12345esd")) # <re.Match object; span=(0, 5),
match='12345'>
print(re.match("\d+","as12345esd")) # None
# #2.re.search() 匹配字符串中是否包含指定的正则内容,匹配成功返回对象,匹配失败返回
None
'''
第一个参数: 正则表达式
第二个参数: 要验证的字符串
第三个参数: 可选参数,正则表达式修饰符
'''
# 3.re.findall() 获取所有匹配的内容,会得到一个列表
'''
第一个参数: 正则表达式
第二个参数: 要验证的字符串
使用规则
匹配单个数字或者字符
代码演示:
import re
"""
----------匹配单个字符与数字---------
. 匹配除换行符以外的任意字符
[0123456789] []是字符集合,表示匹配方括号中所包含的任意一个字符
[good] 匹配good中任意一个字符
[a-z] 匹配任意小写字母
[A-Z] 匹配任意大写字母
[0-9] 匹配任意数字,类似[0123456789]
[0-9a-zA-Z] 匹配任意的数字和字母
[0-9a-zA-Z_] 匹配任意的数字、字母和下划线
[^good] 匹配除了good这几个字母以外的所有字符,中括号里的^称为脱字符,表示不匹
配集合中的字符
[^0-9] 匹配所有的非数字字符
\d 匹配数字,效果同[0-9]
\D 匹配非数字字符,效果同[^0-9]
\w 匹配数字,字母和下划线,效果同[0-9a-zA-Z_]
\W 匹配非数字,字母和下划线,效果同[^0-9a-zA-Z_]
\s 匹配任意的空白符(空格,回车,换行,制表,换页),效果同[ \r\n\t\f]
\S 匹配任意的非空白符,效果同[^ \f\n\r\t]
"""
#[] :只匹配其中的一位
# - :表示一个区间
print(re.search("he[0-9]llo","he9llo")) # <re.Match object; span=(0, 6),
match='he9llo'>
print(re.search("go[zxc]od","goxod")) # <re.Match object; span=(0, 5),
match='goxod'>
print(re.search("he[a-z]llo","hepllo")) # <re.Match object; span=(0, 6),
match='hepllo'>
print(re.search("hello[0-9a-zA-Z_]","hello9"))
print(re.search("hello\d","hello2")) # <re.Match object; span=(0, 6),
match='hello2'>
print(re.search("hello\D","helbwklo_")) # <re.Match object; span=(0, 6),
match='hello_'>
print(re.search("hello\w","hello1")) # <re.Match object; span=(0, 6),
match='hello1'>
print(re.search("hello\W","hello!")) # <re.Match object; span=(0, 6),