Python基础(持续更新)

Python复习

文章目录

  • Python复习
    • 1.Python基础
      • 1.1.非法标识符
      • 1.2.常量和数据类型
        • 1.2.1变量
        • 1.2.2数据类型
        • 1.2.3变量的输入与输出
        • 1.2.4算术运算符
    • 2.流程控制
      • 2.1条件语句
        • 2.1.1if语句
        • 2.1.2if-else语句
        • 2.1.3if-elif-else语句
        • 2.1.4if嵌套
      • 2.2循环语句
        • 2.2.1while循环
        • 2.2.2for循环
        • 2.2.3循环嵌套
      • 2.3跳转语句
        • 2.3.1break语句
        • 2.3.2continue语句
    • 3.字符串
      • 3.1字符串介绍
      • 3.2格式化字符串
        • 3.2.1使用%格式化字符串
        • 3.2.2使用f-string格式化字符串
        • 3.2.3使用format()方法格式化字符串
          • 其他格式处理
      • 3.3字符串常见操作
        • 3.3.1索引和切片
        • 3.3.2字符串的查找与替换
        • 3.3.3字符串的分割与拼接
        • 3.3.4删除字符串的指定字符串
          • 字母转化
          • 字符对齐
    • 4.组合数据类型
      • 4.1认识组合数据类型
      • 4.2列表
        • 4.2.1创建列表
        • 4.2.2列表的基本操作
        • 4.2.3添加列表元素
        • 4.2.4.元素排序
        • 4.2.5删除列表元素
        • 4.2.6列表的循环
        • 4.2.7列表的复制
        • 4.2.8列表推导式
      • 4.3元组
      • 4.4集合
      • 4.5字典
        • 4.5.1字典的创建
        • 4.5.2字典的访问
        • 4.5.3字典的常用操作
    • 5.函数
      • 5.1函数的定义和调用
      • 5.2函数参数的传递
      • 5.3函数的返回值
      • 5.4变量作用域
        • 5.4.1global和nonlocal关键字
    • 6.文件与数据格式化
      • 6.1文件基本操作
        • 6.1.1打开文件
        • 6.1.2文件的读写
        • 6.1.3文件的定位读写
      • 6.2一二维数据的存储与读写
    • 7.面向对象
      • 7.1类的定义与使用
      • 7.2类的成员
        • 7.2.1类方法
        • 7.2.2实例方法
        • 7.2.3静态方法
        • 7.2.4私有成员
      • 7.3特殊方法
        • 7.3.1构造方法
        • 7.3.2析构方法
      • 7.4封装
      • 7.5继承
        • 7.5.1单继承
        • 7.5.2多继承
        • 7.5.3重写
      • 7.6多态

1.Python基础

1.1.非法标识符

  • 以数字开头:4gen
  • 属于python的关键字
  • 包含了特殊字符:$book

1.2.常量和数据类型

  • 和常量相对应的是变量
  • Python中并没有提供定义常量的关键字
  • 在PEP8规范中定义常量的命名规范,常量由大写字母和下划线组成
  • 常量首次被赋值后,其值还可以被其他代码修改
1.2.1变量
  • 当我们修改其中一个变量的值,内存地址会发生变化。与C语言恰好相反
  • Python允许为多个变量同时赋值
  • Python变量的类型可以随时发生变化,与C区分开
1.2.2数据类型

数据类型:

  • 数字类型(numbers)

    • 整型(int)

      • 十进制数:0、-3、8、10
      • 八进制数(使用8个数字来表示整数以0o开头):0o43、-0o123
      • 十六进制数(由09、AF组成,以0x、0X开头):0x36、0X21f
    • 浮点型(float)

    • 复数类型(complex)

  • 字符串类型(str):字符串是一个由单引号、双引号或者三引号包裹的、有序的字符集合。使用单双引号该字符在一行,使用三引号字符可以分布多行。

  • 列表类型(list):列表是多个元素的集合,它可以保存任意数量、任意类型的元素,**且可以被修改。Python中使用“[]”**创建列表,列表中的元素以逗号分隔,示例如下:[1, 2, ‘hello’],类似于C的数组。

  • 元组类型(tuple):元组与列表的作用相似,它可以保存任意数量与类型的元素,**但不可以被修改。**Python中使用“()”创建元组,元组中的元素以逗号分隔,示例如下:(1, 2, ‘hello’)。

  • 字典类型(dict):字典中的元素是“键(Key):值(Value)”形式的键值对,键不能重复。Python中使用“{}”创建字典,字典中的各元素以逗号分隔,示例如下:{“name”: “zhangsan”, “age”: 18},类似于C++的STL中的Map

  • 集合类型(set):集合与列表和元组类似,也可以保存任意数量、任意类型的元素,不同的是,集合使用“{}”创建,集合中的元素无序且唯一。示例如下:{‘apple’, ‘orange’, 1} ,类似于C++中STL的SET。

decimal_number = 10
octal_representation = oct(decimal_number)
#使用oct将十进制转化为八进制
print(f"{decimal_number} 的八进制表示是 {octal_representation}")

octal_number = "0o12"
decimal_representation = int(octal_number, 8)
#将八进制转化十进制直接用int进行类型转化,十六进制转化为十进制也是一样
print(f"{octal_number} 的十进制表示是 {decimal_representation}")

decimal_number = 26
hexadecimal_representation = hex(decimal_number)
#将10进制转化为16进制用hex
print(f"{decimal_number} 的十六进制表示是 {hexadecimal_representation}")

1.2.3变量的输入与输出
name = input("请输入:")
print(name) #print函数默认换行
print(name, end='') #不换行输出
  • %o输出八进制整数,%d输出十进制整数,%x输出十六进制整数

  • %f保留小数点后6位有效数字,如果%.3f保留三位

  • %s:字符串输出,%10s右对齐,占位符10位,%-10s左对齐,占位符10位、

  • f-字符串格式化输出

name = '小明'
age = 13
print(f'姓名:{name}, 年龄:{age}')
1.2.4算术运算符

**:幂运算(返回x的y次幂)

print(10**2) #100

//:取整除(返回商的整数部分)

print(10//4) #2

海豹运算符:该运算符用于在表达式内部为变量赋值

num_one = 1
#使用海象运算符为num_two赋值
result = num_one + (num_two:=2)
print(result)

eval:函数将函数里的内容自动转化为内容应该的类型

tmp = eval(input())
print(type(tmp))

2.流程控制

一定注意python的缩进如同c/c++中的{},所以一定要注意

2.1条件语句

2.1.1if语句

if语句格式:

#if 条件表达式:
#	代码块

a, b, c = 4, 5, 0
if a>b :
 c = b
if a < b:
 c = a
print(c)
2.1.2if-else语句

if-else语句格式:

#if 判断条件:
#	代码块1
#else:
#	代码块2

a = 5
if a % 2 == 0:
 print("这是一个偶数")
else:
 print("这是一个奇数")
2.1.3if-elif-else语句

if-elif-else语句格式:

#if 判断条件1:
#	代码块1
#elif 判断条件2:
#	代码块2
#...
#else:
#	代码块n

day = int(input("请输入第几天课程:"))
if day == 1:
print("one")
elif day == 2:
print("two")
else:
print("another")
2.1.4if嵌套
#判断某一年是否是闰年
year = int(input("请输入年份: "))
flag = 0
if year % 4 == 0:
    if year % 100 == 0:
        if year % 400 == 0:
            flag = 1
        else:
            flag = 0
     else:
        flag = 1
else:
    flag = 0
    
 if flag == 1:
    print("闰年")
 else:
    print("平年")
            

2.2循环语句

2.2.1while循环

while循环格式:

while 条件表达式:
 代码块
n = 1
sum = 0
while n <= 99 :
 sum += n
 n += 1
print("1~99的整数和为: ", sum)
2.2.2for循环

for循环格式:

#for 临时变量in目标对象:
#	代码块

sum = 0
for i in range(1, 100):
 sum += i
print("1~99的整数和为: ", sum)
  • **range(stop)*生成从0开始到stop结束(不包含stop)的一系列数值,比如range(3)生成的数值为:0,1,2
  • **range(start, stop)*生成从start开始到stop结束(不含stop),如range(2, 5)生成的数值为:2,3,4
  • **rang(start, stop, step)*再上一个基础上是按照step的大小跳动
#输出所有的水仙花数
for i in range(100, 1000):
    a = i % 10
    b = i // 10 % 10
    c = i // 100
    if(i == a ** 3 + b ** 3 + c ** 3):
        print(i)
#判断一个数是否是素数

import math
m = int(input("请输入一个整数m: "))
n = int(math.sqrt(m))

prime = 1
for i in range(2, n+1):
    if( m % i == 0):
        prime = 0

if(prime == 1) :
    print(f'{m}是素数')
else:
    print(f'{m}不是素数')
2.2.3循环嵌套
#打印九九乘法表
for i in range(1, 10):
    for j in range(1, i+1):
        print('{}x{}={}\t'.format(j, i, i*j), end = '')
    print()

2.3跳转语句

2.3.1break语句

用于结束循环,若嵌套使用了break,程序结束本层循环

break语句语句格式:

for i in range(10):
 if i == 5:
     break
 print(i, end = '')
2.3.2continue语句

continue语句用于满足条件的情况下跳出本次循环,该语句通常也与if语句配合使用

continue语句格式:

for word in "Python":
	if word == 'o':
		continue;
	print(word, end= '')

3.字符串

3.1字符串介绍

python使用反斜杠‘\’转义。例如,在字符串中的引号前添加“\”,此时Python解释器会将“\”之后的引号解释为一个普通字符,而非特殊符号。

print('let\'s learn python)

\ \代表 反斜杠(\)
‘代表 单引号(’)

  • isinstance函数:判断一个变量是否是字符串
testString = "ts"
isinstance(testString, str)

3.2格式化字符串

3.2.1使用%格式化字符串
  • 格式化字符串是指将指定的字符串转换为想要的格式。Python字符串可以通过**%格式符**格式化输出。

格式:
format % values

str = 'hello python'
print('%s')
#....
3.2.2使用f-string格式化字符串
  • f字符串用花括号“{}”表示被替换的字段。
name = "张三"
studenId = "202201"
print(f'我叫{anme},学号为{studenId}')
3.2.3使用format()方法格式化字符串
  • 为了更直接、便捷地格式化字符串,Python为字符串提供了一种格式化字符串format()。

格式:
str.format(values)

print("{}年{}学期我们学习了{}门课程".format("2022", "上"20))
其他格式处理
  • format()方法地模板字符串地空位不进可以填写参数序号,还有其他地格式处理形式。

对齐:“<”为左对齐,“>”为右对齐,“^”为居中对齐。
符号:
宽度:指定空位所占宽度。
分隔符:用逗号“,”分隔数字地千位,用于整数和浮点数。
精度:用“.precision”指定浮点数地精度或字符串输出地最大长度,例如:“.5”。
类型:用于指定类型。

  • 书写规则时,除非对应部分不出现,否则就必须严格按照上述顺序,绝对不能修改
  • 如“{0:<5}”不能写成“{0:5<}”
aString = "{0:+>20}".format("价格", 10)
print(aString)

默认情况下,填充字符是空格符,可以不填写

3.3字符串常见操作

3.3.1索引和切片
  • 索引
    • 数学上0,-0,+0都是指向同一个数字0
    • 正向第一个索引是0,反向第一个索引是-1
aString = "你好! 世界"
print(aString[3])
#通过下标索引直接访问
  • 切片

    • 返回[m, n)的字符串
      可以使用aString[m:n]写法(m

      m,n也可以是负数,但是要注意的负数的大小,例如:aString[-3:-1]

    • 如果m,n分别指的是字符串的开头或者结尾

      aString[1:] #查询第二个字符开始到结尾的子串
      aString[:-2] #反向查询从开头到倒数第二个字符
      
    • aString[m::n]

      从字符串的索引值m开始,每n个字符取出一次的情况

3.3.2字符串的查找与替换
  • Python中提供了实现字符串查找操作的find()方法,该方法可查找字符串中是否包含子串,若包含则返回子串首次出现的位置,否则返回-1

格式:
str.find(sub[, start[, end]])
sub:指定要查找的子串
start:开始索引默认为0
end:结束索引,默认为字符串的长度

word = 't'
string = 'Python'
result = string.find(word)
print(result)
  • Python中提供了实现字符串替换操作replace()方法,该方法可将当前字符串中的指定子串替换成新的子串,并返回替换后的新字符串。

格式:
str.replace(old, new[, count])
old:被替换的旧子串
new:替换旧子串的新子串
count:表示替换旧子串的次数,默认全部替换

string = "He Said, 'Then have to go forward Then'"
new_String = string.replace("Then", "then", 2)
print(new_String)
3.3.3字符串的分割与拼接
  • split()方法可以按照指定分割符对字符串进行分割,该方法会返回由分割后的子串组成的列表。

格式:
str.split(sep=None, maxsplit=-1)
sep:分割符,默认为空字符
maxsplit:分割次数,默认值为-1,表示不限制分割次数

string = "Hello, my name is Hzumglo"
#以空格作为分隔符,并分割两次
print(stringsplit(' ', 2)
  • join()方法使用指定的字符连接字符串并生成一个新的字符串。join()方法的语法格式如下。

格式:
str.join(iterable)
iterable:表示连接字符串的字符

symbol = '*'
world = "Python"
print(symbol.join(world))
  • Python还可以使用运算发“+”拼接字符串

    • “Py” + “thon” ——> “Python”
3.3.4删除字符串的指定字符串
  • 字符串中可能会包含一些无用的字符(如空格),在处理字符串之前往往需要先删除这些无用的字符。Python中的**strip()、lstrip()和rstrip()**方法可以删除字符串中的指定字符。
方法 语法格式 功能说明
strip() str.strip([chars]) 移除字符串头尾指定的字符
lstrip() str.lstrip([chars]) 移除字符串头部指定的字符串
rstrip() str.rstrip([chars]) 移除字符串尾部指定的字符
str = "00000dfsdfsdfs00"
print(str.strip('0')) #去除首尾字符0
字母转化
  • 在特定情况下会要求英文单词的大小写形式进行要求。Python中支持字母大小写转换的方法由uppe()、lower()、capitalize()和title()。
方法 功能说明
upper() 将字符串中的小写字母全部转化为大写字母
lower() 将字符串中的大写字母全部转化为小写字母
capitalize() 将字符串中第一个字母转化为大写形式
title() 将字符串中每个单词的首字母转化为大写形式
字符对齐
  • Python提供了center()、ljust()、rjust()这三个方法来设置字符串的对齐方式。
方法 语法格式 功能说明
center() str.center(width[,fillchar]) 返回长度为width的字符串,原字符串居中显示
ljust() str.ljust(width[,fillchar]) 返回长度为width的字符串,原字符串左对齐显示
rjust() str.rjust(width[,fillchar]) 返回长度为width的字符串,原字符串右对齐显示

4.组合数据类型

4.1认识组合数据类型

  • python集合具备确定性互异性无序性三个特性。python要求放入集合中的元素必须是不可变类型,python中的整形、浮点型、字符串和元组属于不可变类型,列表、字典及集合都属于可变的数据类型。
  • 映射类型以键值对的形式存储元素,键值对中的键与值之间存在映射关系。**字典(dict)**是python唯一的内置映射类型,字典的键必须遵守以下两个原则:
    • 每个键只能对应一个值,不允许同一个键在字典中重复出现。
    • 字典中的键是不可变类型。

4.2列表

4.2.1创建列表
list_one = [] #使用[]创建空列表
list_two = list() #使用list()创建空列表

list01 = [1, 2, 3, 4, 5]
list02 = ['zml', 'wjn', 'yjh', 'zrj']
  • 通过“[]”创建列表,;列表中的元素可以是不同类型的,但是通常是相同类型的。

  • 在python中,支持通过for…in…语句迭代获取数据的对象是可迭代对象。我们还可以使用isinstance()函数可以判断目标是否为可迭代对象,返回True表示为可迭代对象

from collection.adc import Iterable
ls = [3, 4, 5]
print(isinstance(ls, Iterable))
4.2.2列表的基本操作
list01 = [1, 2, 'Python', 'hzumglo']
print("list01[3]:", list01[3]) #取列表的第四个元素
print("list01[-1]", list01[-1]) #列表第四个元素也是最后一个元素
  • 切片是指从序列中截取部分元素组成新的序列,且不会使原序列发生变化。
# seq[start:end:strp] 获取的区间左闭右开,seq为序列名称
list01 = [1, 2, 'Python', 'hzumglo']
print("list01[1:3]",list01[1:3])
print("list01[:3]",list01[:3])

  • 相加与重复-序列相加,pyhton支持用“+”运算将序列连接起来。

    list01 = ['hugo', 1]
    list02 = ['abc', 'io']
    print(list01 + list02)
    

    如果不同类型的序列相加,程序将会出现异常。

print("python"*5) #字符串python重复五次
print(["python"]*5) #列表重复五次
  • 成员归属,在Python中用in运算符检查一个值是否存在序列,返回的是bool值。

    list01 = [1, 2, 3, 4, 5]
    if 3 in list03:
    	print("3在序列中")
    else:
    	print("3不在序列中")
    
    • 长度及最值

      python中的内置函数len()可以计算序列长度,即序列元素的数量。

      sname = "python"
      print("字符串的长度:", len(sname))
      list01 = ['123', 'C++', 'Java']
      print(len(list01))
      
4.2.3添加列表元素
  • 向列表中添加元素是非常常见的一种操作,python提供了append()、extend()和insert()这几个方法。
list_one = ["Java", "C#", "Python"]
list_one.appned("C++") #在列表末尾添加元素
list_one.extend(["Android", "IOS"]) #在列表末尾添加一个序列所有元素
list_one.insert(2, "Html") #按照索引将元素插入列表的指定位置
4.2.4.元素排序
  • 列表的排序是将元素按照某种规则规定进行排序。列表中常用的排序方法有sort()、reverse()、sorted()。

    li_one = [6, 2, 5, 3]
    li_one.sort() #有序的元素会覆盖原来的列表元素, 不产生新列表
    li_two = sorted(li_one) #产生排序后的新列表,排序操作不会对源列表产生影响
    li_one.reverse() #逆置列表
    
4.2.5删除列表元素
  • 删除列表元素的常用方式有del语句、remove()方法、pop()方法和clear()方法。
li_one = [6, 2, 5, 3, 3]
del li_one[0] #删除列表中指定位置的元素
li_one_remove(3) #移除列表中匹配的第一个元素
li_one.pop() #移除列表中i你的某个元素,若未指定具体元素,则移除列表中的最后一个元素,如有参数,则为要弹出的元素的下标
li_one.clear() #清空列表
4.2.6列表的循环
  • 列表的遍历即获取列表中每一个元素的值,常用的遍历方式有三种:

    • for训话直接遍历

      food_list = ["苹果", "香蕉", "橘子"]
      for item in food_list:
          print(item)
      
    • range()函数索引遍历

      food_list = ["苹果", "香蕉", "橘子"]
      for i in range(len(food_list)):
      	print(f"索引为{i}的元素是{food_list[i]}")
      
    • enumerate()函数遍历

      food_list = ["苹果", "香蕉", "橘子"]
      for index, item in enumerate(food_list):
      	print(f"索引为{index}的元素是{item}")
      
4.2.7列表的复制
  • 列表的复制可以通过两种方式实现,一种是创建一个包含整个列表的切片,即同时省略起始索引和终止索引([:]);另一种方式是用copy()方法
copy_list = list.copt()
4.2.8列表推导式
  • 列表推导式提供了一种创建列表的简洁方法。通常操作某个序列的每个元素,并将其结果作为新列表的元素,或者根据判定条件创建子序列。列表推导式一般由表达式以及for语句构成,其后还可以有零到多个for或if子句,返回结果是表达式在for和if语句的操作下生成出来的列表。
#方法1
square_list = []
for item in range(1, 11):
    square_list.append(item ** 2)
print(square_list)

#方法2
square_list = [item ** 2 for item in range(1, 11)]

4.3元组

元组与列表类似,也是由一系列按照特定顺序排列的元素组成的,但是它是不可变序列,不能增加、修改和删除。创建元组可以通过两种方式,直接通过圆括号**“()”创建以及通过tuple()函数创建。**

tuple_name = "python", 1, 2  #通过逗号将元素隔开即可以创建一个元组
tuple_name = ("python", 1, 2) #通常需要用圆括号括起来
tuple_name = (1, ) #当元组中只有一个元素时,也必须在这个元素后面加上一个逗号
tuple_name = () #元组内容也可以为空,即创建一个空元组
  • tuple()函数可以将列表,字符串,range()对象等转化为元组,直接用tuple()函数创建一个空元组。

    tuple01 = tuple()
    tuple02 = tuple("Hzumglo") #将字符串转化为元组
    tuple03 = tuple([1, 2, 3, 4, 5]) #将列表转化为元组
    tuple04 = tuple(range(1, 5, 2)) #将range()对象转化为元组
    
  • 元组的遍历同列表相同。

列表与元组的区别:

​ 列表是可变序列,可以使用append()方法增加元素,通过remove()方法删除元素以及使用索引或切片修改元素等,而元组是不可变序列,不能增加、修改和删除元素。

元组不可替代的原因:

  • 元组可以在字典中作为键使用,而列表不行
  • 元组比列表的访问和处理速度快,如果只需要访问元素,而不需要修改的话,建议使用元组。
  • 元组可以作为很多内置函数和方法的返回值

4.4集合

集合类型由一组无序排列不重复的元素组成。集合中的元素类型只能是不可变数据类型。集合分为可变集合(set)和不可变集合(frozenset),下面只介绍常用的可以进行添加、删除元素操作的可变集合。

可变集合由两种创建方式:
直接用花括号“{}”创建,元素之间以逗号隔开
set()函数创建,其它数据类型也可以通过set()函数转换为集合

PS:创建空集合不能使用{}只能使用set()函数创建。

  • set()函数可以将字符串、元组、列表、字典等序列类型和映射类型转化为集合。
set01 = set("Hzumglo")
set02 = set(("小千", "小峰"))
set03 = set(["小千", "小峰"])
set04 = set({"小千":19, "小峰":18})
  • 向集合中添加元素使用add()方法
language_set = {"hzumglo", "wjn", "zhu"}
language_set.add("zml")
  • 从集合中删除元素可以使用remove()方法和discard()方法。其中remove()方法删除一个元素,如果元素不存在则会产生KeyError;discard()方法删除一个元素,如果元素不存在,则不会报错。
language_set = {"hzumglo", "wjn", "zhu", "zml"}
language_set.discard("zhu")
language_set.remove("zml")
  • 集合的四种基本操作,交集(&),并集(|),差集(-),对称差集(^)

    set01 = {1, 2, 3, 4}
    set02 = {3, 4, 5, 6}
    print(set01&set02)
    print(set01|set02)
    print(set01-set02)
    print(set01^set02)
    

4.5字典

4.5.1字典的创建

字典是一种映射类型,每个元素都是一个键值对,元素之间是无序的。键值对(key,value)是一种二元关系,源于属性和值的映射关系。键(key)表示一个属性,值(value)表示属性的内容,键值对整体而言表示一个属性和它对应的值。

字典以花括号“{}”为标志,元素均为键值对形式,键值对形如“key:value”,以英文冒号“:”为标志,元素之间以逗号“,”分隔。字典中的键需要是不可变的数据类型,例如数字、字符串和元组,且不能重复;值可以是任意数据类型,可以重复。

字典有两种常用的创建方式:
直接通过花括号“{}”创建,所以上面说过创建一个空集合不能用{}
通过dict()函数创建

  • 通过“{}”创建字典
empty_dice = {} #创建一个空字典
person_dict = {"name":"hzumglo", "id":"21030", "grade":"Three"}
student_dict = {(202103, "wjn"):"大三", (202130, "zml"):"大三"} #使用元组作为字典的键
  • 通过dict()创建字典

    empty_dict = dict() #通过dict()创建一个空字典
    
    #dict函数将二元组列表转化为字典
    student_list = [("name", "zml"), ("stu_id", "202130"), ("grade", "大三")]
    student_dict = dict(student_list)
    
    #通过在dict()函数中设置关键字参数的方式创建字典
    student_dict01 = dict(name="wjn", stu_id="202103", grade = "大三")
    print(student_dict01)
    
4.5.2字典的访问
  • 通过键访问字典元素的值

    studen_dict = {"name":"zml", "id":"202130"}
    print("学号为:", student_dict["id"]) #如果访问的键不在时,程序就会异常
    
  • 通过get()方法访问字典元素的值

    student_dict = {"name":"wjn", "id":"202103"}
    score_value = student_dict.get("score", "此键不存在")
    print(score_value) 
    #使用get方法时,第一个参数必不可少;第二个参数用于指定键不存在时候要返回的值,时可选的。
    
  • 字典涉及的数据分为键、值和元素(键值对),除了直接利用键访问值外,Python还提供了内置的方法keys(), values()和items()。

    info = {"name":"wjn", "age":"21"}
    print(info.keys()) #获取所有的键
    print(info.values()) #获取所有的值
    print(info.items()) #获取所有的元素
    
4.5.3字典的常用操作
  • 字典的成员归属,可以使用成员运算符(in,not in)来判断某键是否在字典中

    student_dict = {"name":"hzumglo", "id":"202130", "grade":"大三"}
    if "name" in student_dict:
        print("字典中含有这个键")
    else:
        print("字典中没有这个键")
    
  • 修改,添加和删除字典元素-修改字典元素

    #字典元素的修改是通过键来完成的
    person_dict = {"name":"wjn"}
    person_dict["name"] = "huahua"
    print(person_dict)
    
    #修改时如果键不存在,则会在字典中添加此键值对
    
  • 可以通过setdefault()方法添加字典元素,该方法有两个参数,第1个参数表示键,第2个参数表示值。如果键在字典中不存在,那么setdefault()方法会向字典中添加该键,并以第2个参数作为该键的值,没有指定第2个参数的情况下,键的值默认是None。setdefault()方法会返回设置的键对应的值。

    person_dict = {"name":"zml", "id":"202130"}
    value = person_dict.setdefault("grade":"大三")
    print(f"返回值:{value}, 字典:{person_dict}")
    
    #如果字典中已经存在这个键,setdefault()方法不会修改键对应的值,并会返回原来的键对应的值。
    
  • 使用del语句,需要指定字典和要删除的键

    person_dict = {"name":"hzumglo", "age":21}
    del person_dict["age"]
    
  • 字典的复制,字典的复制使用copy()方法

    goods_dict = {"牛奶":20, "杯子":10}
    latest_goods = goods_dict.copy()
    
  • 字典的合并,update()方法,{* *d1, * *d2}方法,“|”、"|="运算符

#update()方法
dict01 = {"a":1, "b":2}
dict02 = {"a":3, "b":4}

dict01.update(dict02)
#{**d1, **d2}方法
dict01 = {"a":1, "b":2}
dict02 = {"a":3, "d":4}
dict03 = {**dict01, **dict02}
print(dict03)
#"|"、"|="运算符
dict01 = {"a":1, "b":2}
dict02 = {"a":3, "d":4}
dict03 = dict01|dict02

5.函数

函数式编程具有一下优点:

  • 将程序模块化,既减少了冗余代码,又让程序结构更为清晰
  • 提高开发人员的编程效率
  • 方便后期的维护与扩展

5.1函数的定义和调用

#语法格式
def 函数名 ([参数列表]):
    ["""文档字符串"""] #可选
    函数体
    [return 语句]
  • 定义计算矩形面积的函数

    • 在定义函数时的参数列表里面的参数是形式参数,简称为“形参”,指length和width;当调用函数时,要传给函数内部的参数是实际参数,简称为“实参”,指cal_square(4,3)中的4和3。
    del cal_square(length, width):
    	return length*width
    result = cal_square(4, 3)
    print(result)
    
  • 函数的返回值

    ​ 进行函数调用时,传递参数实现了从函数外部向函数内部进行数据传输,而return语句则实现了从函数内部向函数外部输出数据。函数的返回值可以是空值、一个值或者多个值。
    ​ 如果定义函数时没有return语句或者只有return语句而没有返回数据时,则Python会认为此函数返回的是None,None表示空值。

    #求一个三位数的百、十、个位的值
    def cal_digit(number):
    	hight = number // 100
    	mid = number // 10 % 10
    	low = number % 10
    	return hight, mid, low
    
    result = cal_dight(543) #当函数的返回值为多个时,返回的多个值是由逗号隔开的,此时有了构成元组的标志,函数的返回值构成了一个元组
    print(result)
    a, b, c = cal_dight(543)
    print(a, b, c)
    
  • 函数的嵌套定义,函数在定义时可以在其内部嵌套定义另外一个函数,此时嵌套的函数称为外层函数,被嵌套的函数称为内层函数。

    def add_modify(a, b):
    	result = a + b
    	print(result)
    	def test():
    		print("我是内层函数")
    add_modify(10, 20)
    
    • 函数外部无法直接调用内层函数

    • 只能通过外层函数间接调用内层函数

5.2函数参数的传递

  • 函数调用时,实参的传递顺序与定义函数形参的顺序需要保持一致,如果顺序不正确,结果会不符合预期。

  • 实参和形参的类型和个数必须匹配,否则程序就会异常。

  • 参数的关键字传递中,会直接将形参的名称和实参的值关联起来,故允许传递实参的顺序与定义函数的形参顺序不一致。

    def favorite_place(name,place):
        print(f"我的名字是{name}")
        print(f"我最喜欢的名胜古迹是{place}")
    favorite_place(place="桂林山水",name="小锋")
    
  • Python在3.8版本中新增了仅限位置形参的语法,使用符号“/”来限定部分形参只接收采用位置传递方式的实参。下面例子中“/”指明:前面的a, b参数是仅限位置形参。

    def func(a, b, /, c)
    	print(a, b, c)
    func(10, 20, c = 30)
    
  • 函数在定义时可以指定形参的默认值,如此在被调用时可以选择是否给带有默认值的形参传值,若没有给带有默认值的形参传值,则直接使用该形参的默认值。

    def connect(ip, port = 8080)
    	print(f"设备{ip}:{port}连接! ")
    connect(ip = "1.1.1.2")
    connect(ip = "1.1.1.1", port = 3306)
    
  • 参数的打包与解包,如果函数在定义时无法确定需要接收多少个参数,那么可以**在定义函数时为形参,添加“* ”或 * * **

    • “*”——接收以元组形式打包的多个值
    • “* *”——接收以字典形式打包的多个值
    def test(*args):
    	print(args)
    test(11, 22m 33, 44, 55)
    
    def test1(**kwargs):
        print(kwargs)
    test1(a = 11, b = 22, c = 33, d = 44)
    
  • 混合传递

    def test(a, b, c = 33, *args, **kwargs):
    	print(a, b, c, args, kwards)
    print(test(1,2))
    print(test(1, 2, 3))
    print(test(1, 2, 3, 4))
    print(test(1, 2, 3, 4, e=5))
    

5.3函数的返回值

  • 函数中的return语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行。

  • 如果函数使用return语句返回了多个值,那么这些值将被保存到元组中。

5.4变量作用域

  • 变量并非在程序的任意位置都可以被访问,其访问权限取决于变量定义的位置,其所处的有效范围称为变量的作用域。根据作用域的不同,变量可以划分为局部变量全局变量
5.4.1global和nonlocal关键字
  • 函数内部无法直接修改全局变量或在嵌套函数的外层函数声明的变量,但可以使用global或nonlocal关键字修饰变量以间接修改以上变量。

  • gloabal关键字,使用global关键字可以将局部变量声明为全局变量,其使用方法如下:

    number = 10 #定义全局变量
    def test_one():
    	global number #使用global声明变量number为全局变量
    	number += 1 
    	print(number)
    test_one()
    print(number)
    
  • nonlocal关键字,使用nonlocal关键字可以在局部作用域中修改嵌套作用域中定义的变量,其使用方法如下:

    def test():
    	number = 10
    	def test_in():
    		nonlocal number
    		number = 20
    	test_in()
    	print(number)
    test()
    
  • 列表、字典等数据类型作为全局变量时,在函数内部可以对全局变量进行修改,不需要global关键字进行声明。

    stu_dict = {
    	"name":"wjn",
    	"stu_id":202103,
    	"grade":"大三",
    }					#定义全局变量stu_dict
    def change_grade():
    	stu_dict["grade"] = "大三下"
    change_grade()
    print(stu_dict)
    

6.文件与数据格式化

6.1文件基本操作

6.1.1打开文件
  • 打开文件,内置函数open()用于打开文件,该方法的声明如下:

    open(file, mode="r", buffering = -1)
    #file:文件的路径。
    #mode:设置文件的打开模式,取值有r、w、a。
    #buffering:设置访问文件的缓冲方式。取值为0或1。
    
  • 关闭文件

    file.close()
    

    python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭

    with open("text.txt", "r") as f:
    	#对文件对象f进行操作
    #with关键字还可以打开多个文件
    with open("text01.txt", "r") as f1, open("text02.txt", "a") as f2:
     	 #通过文件对象f1、f2分别操作text01、text02文件
    
6.1.2文件的读写
  • read()方法可以从指定文件中读取字节的数据,其语法格式如下:

    with open('file.txt', mode='r') as f
    	print(f.read(2)) #读取两个字节的数据
    	print(f.read()) #读取剩余的全部数据
    
  • readline()方法可以从指定文件中读取一行数据,其语法格式如下:

    with open('file.txt', mode = 'r') as f:
    	print(f.readline())
    	print(f.readline())
    
  • 使用rstrip()函数去除多余空白行

    with open('file.txt', 'r') as f:
    	while True:
    		text = f.readline()
    		if not text:
    			break
    		print(text.rstrip())
    
  • 文件对象时可迭代对象,故可以通过for循环遍历文件

    with open('file.txt', 'r') as f:
    	for line in f:
    		print(line.rstrip())
    
  • readlines()方法可以一次读取文件中的所有数据,若读取不成功,该方法会返回一个列表,文件中的每一行每一类对应列表中的一个元素。语法格式如下:

    with open('file.txt', 'r') as f:
    	print(f.readlines()) #一般为了保证读取安全,通常调用read()方法。
    
  • 写文件——write()方法

    string = "Here we are all, by day; by night."
    with open ("write_file.txt", mode = 'w', encoding = 'utf-8') as f:
    	size = f.write(string) #写入字符串
    	print(size) #打印字节数
    
  • write|lines()方法用于将行列表写入文件,其语法格式如下:

    string = "Here we are all, by day;\nby night we're hurl'd By dreams, 
    each one into a several world."
    with open('write_file.txt', mode='w', encoding='utf-8') as f:
        f.writelines(string)
    
6.1.3文件的定位读写
  • tell()方法用于获取文件当前的读写位置,以操作文件file.txt为例,tell()的用法如下:

    with open('file.txt') as f:
    	print(f.tell()) #获取文件读写的位置
    	print(f.read(5)) #利用read()方法移动文件读写的位置
    	print(f.tell()) #再次获取文件读写位置
    
  • seek()方法,python提供了seek方法,使用该方法可控制文件的读写位置,实现文件的随机读写。seek()方法的语法格式如下:

    with open('file.txt') as f:
    	f.seek(5,0)	# 相对文件开头移动5字节
    	f.seek(3,1)
    

6.2一二维数据的存储与读写

二维数据可视为多条一维数据的集合,当二维数据只有一个元素时,这个二维数据就是一维数据。
CSV(Commae-Separeted Values,逗号分隔值)是国际上通用的一二维数据存储格式。

CSV格式规范:

  • 以纯文本形式存储表格数据
  • 文件的每一行对应表格中的一条数据记录
  • 每条记录由一个或多个字段组成
  • 字段之间使用逗号(英文、半角)分隔
  • Windows平台中CSV文件的后缀名为.csv,可通过Office Excel或记事本打开Python在程序中读取.csv文件后会以二维列表形式存储其中内容。

    csv_file = open('score.csv')
    lines = []
    for line in csv_file:
    	line = line.replace('\n', '')
    	lines.append(line.split(','))
    print(lines)
    csv_file.close()
    
  • reader对象读取csv文件

    #创建reader对象需要用到reader()方法
    import csv
    with open("score.csv", "r") as f:
    	reader = csv.read(f)
    	for item in reader:
    		print(item)
    
  • 创建DictReader类对象,csv.DictReader(f, fieldnames),f是指文件对象,fieldnames是指一个序列,如果省略fieldnames,则文件f第一行中的值将用作fieldnames、DictReader类对象也是可迭代对象,可以用for循环遍历。

    import csv
    with open("score.csv", "r") as f :
    	reader = csv.DictReader(f)
    	for item in reader:
    		print(item)
    
  • 数据写入,以序列形式写入CSV文件,需要先用到csv模块中的writer()方法将文件对象转为writer对象。

方法 说明
csvwriter.writerow(row) 单行写入,将序列的所有元素写入到CSV文件的一行中
csvwriter.writerows(rows) 多行写入,将序列中的每个元素逐行写到CSV文件中
  • writerow
import csv
list01 = [["名称", "数量"], ["苹果", "18"], ["西瓜", "10"]]
with open("fruit.csv", 'w', encoding="utf-8-sig") as f:
	writer = csv.write(f)
	writer.writerow(list01)
  • writerows

    import csv
    list01 = [["名称","数量"],["苹果","18"],["西瓜","10"]]
    with open("fruit.csv","w",encoding="utf-8-sig") as f:
        writer = csv.writer(f)
        writer.writerows(list01)
    
  • 以字典形式写入CSV文件

    import csv
    student_dict = [
        {“name”:“小乐","age":"19"},
        {“name”:“小师","age":"20"},
    ]
    fileheader = ["name","age"]
    with open("student.csv","w",encoding="utf-8-sig",newline="") as f:
        writer = csv.DictWriter(f,fileheader)
        writer.writeheader()
        writer.writerows(student_dict)
    

7.面向对象

7.1类的定义与使用

对象是类的一个实例

  • 定义一个类需要使用class关键字,类名的首字母常用大写

  • 构造方法__init__(),构造方法一般用于类的初始化操作,在创建实例对象时被自动调用和执行。

  • self的作用,self的作用是代表将来要创建的实例对象本身,让实例能够访问类中的属性和对象。

  • 最少含有一个self参数,用于绑定实例对象的方法称为实例方法,可以被实例对象直接调用。

class Dog:
	def __init__(self, name, breed, age):
            """初始化属性name、breed和age"""
            self.name = name
            self.breed = breed
            self.age = age
        def eat(self):
        	"""小狗正在吃狗粮"""
        	print(f"{self.name}正在吃狗粮")
        def run(self)
        	"""小狗正在奔跑"""
        	print(f"{self.name}在奔跑玩耍")
            
d1 = Dog("小巴", "哈巴狗", 4) #创建实例对象

#访问属性,需要使用“实例名.属性”的方式
print(f"狗狗的姓名是{d1.name}")       #访问name属性
print(f"狗狗的品种是{d1.breed}")      #访问breed属性
print(f"狗狗的品种是{d1.age}")         #访问age属性

#创建实例对象后,可以调用类中的实例方法,形式是“实例名.实例方法”
d1.eat()                                       #调用eat()方法
d1.run()                                       #调用run()方法

7.2类的成员

属性按声明的方式可以分为两类:类属性和实例属性。

  • 类属性

    • 声明在类内部,方法外部的属性。

    • 可以通过类对象进行访问,但只能通过类进行修改。

      class Car:
      	wheels = 4 #属性
      	def drive(self): #方法
      		print("形式")
      car = Car()           	   # 创建对象car
      print(Car.wheels)       # 通过类Car访问类属性
      print(car.wheels)        # 通过对象car访问类属性
      Car.wheels = 3    	  # 通过类Car修改类属性wheels
      print(Car.wheels)    #3
      print(car.wheels)     #3
      car.wheels = 4          # 通过对象car修改类属性wheels
      print(Car.wheels)   #3
      print(car.wheels)    #4
      
  • 实例属性

    • 实例属性是在方法内部声明的属性
    • Python支持动态添加实例属性
    class Car:
        def drive(self):  
            self.wheels = 4                      # 添加实例属性
    car = Car()                                    # 创建对象car
    car.drive()          
    print(car.wheels)                           # 通过对象car访问实例属性
    print(Car.wheels)                          # 通过类Car访问实例属性
    self.wheels = 3 #修改实例属性
    print(car.wheels)                          
    print(Car.wheels)  
    
    #动态添加实例属性——类外部使用对象动态添加实例属性
    class Car:
        def drive(self):  
            self.wheels = 4                   # 添加实例属性
    car = Car()                                  # 创建对象car
    car.drive()
    self.wheels = 3                            # 修改实例属性      
    print(car.wheels)                         # 通过对象car访问实例属性
    car.color = "红色"                        # 动态地添加实例属性
    print(car.color)
    

Python中的方法按定义方式和用途可以分为三类:实例方法、类方法和静态方法。

  • 实例方法

    • 形似函数,但是定义在类内部
    • 以self为第一个形参,self参数代表对象本身
    • 只通过对象调用
    class Car:
        def drive(self):                           # 实例方法
            print("我是实例方法")
    car = Car()                
    car.drive()                                      # 通过对象调用实例方法
    #Car.drive()                                     # 通过类调用实例方法,错误的
    
7.2.1类方法
  • 类方法是定义在类内部
  • 使用装饰器@classmethod修饰的方法
  • 第一个参数为cls,代表类本身
  • 可以通过类和对象调用
class Car:
    @classmethod
    def stop(cls):  			 # 类方法
        print("我是类方法")
car = Car()    
car.stop()   			# 通过对象调用类方法
Car.stop()   		               # 通过类调用类方法
  • 类方法中可以使用cls访问和修改类属性的值

    class Car:
        wheels = 3                  # 类属性
        @classmethod
        def stop(cls):               # 类方法
            print(cls.wheels)      # 使用cls访问类属性 3
            cls.wheels = 4         # 使用cls修改类属性 
            print(cls.wheels)	#4
    car = Car()                
    car.stop() 
    
7.2.2实例方法
class Employee:
	number = 0
	def __init__(self,name):
		self.name = name
		Employee.number += 1
	@classmethod
	def count_num(cls):
		print("员工个数", cls.number)
e1 = Employee("张三")
e2 = Employee("李四")
e3 = Employee("王五")
e1.count_num()
Employee.count_num()
7.2.3静态方法
  • 静态方法是定义在类内部

  • 使用装饰器@staticmethod修饰的方法

  • 没有任何默认参数

  • 静态方法内部不能直接访问属性或方法,但可以使用类名访问类属性或调用类方法

    class Car:
     	@staticmethod
     	def test():
     		print("我是静态方法")
    
7.2.4私有成员

类的成员默认公有成员,可以在类的外部通过类或对象随意地访问,这样显然不够安全。
为了保证类中数据的安全,Python支持将公有成员改为私有成员,在一定程度上限制在类的外部对类成员的访问。

  • Python通过在类成员的名称前面添加双下画线(__)的方式来表示私有成员,语法格式如下:
class Car:
    __wheels = 4         						# 私有属性
    def __drive(self):  						# 私有方法
        print("开车")
  • 私有成员在类的内部可以直接访问,在类的外部不能直接访问,但可以通过调用类的公有成员方法的方式进行访问。

    class Car:
        __wheels = 4        						# 私有属性
        def __drive(self): 						# 私有方法
            print("行驶")
        def test(self):     
            print(f"轿车有{self.__wheels}个车轮") 	                                        # 公有方法中访问私有属性
            self.__drive()                                                                        	# 公有方法中调用私有方法
    
    
  • Python并没有从语法上严格的保证成员是私有的,只是给私有成员换了一个名称,来妨碍对私有成员的访问。
    如果知道私有属性的命名规则,仍然可以访问到它们,命名规则为“对象名._类名__属性”。
    与私有属性类似,在类外也能访问私有方法,访问方式是“对象名._类名__方法”。

class Room:
    def __init__(self,name):
        self.__name = name        #定义私有属性__name
r1 = Room("房间1")                #创建一个实例对象
name = r1._Room__name      #访问Room中的私有属性,并赋值给name
print(name)

7.3特殊方法

7.3.1构造方法
  • 构造方法指的是__init__()方法。
  • 创建对象时系统自动调用,从而实现对象的初始化
  • 每个类默认都有一个__init__()方法,可以在类中显式定义__init__()方法。
  • __ init __()方法可以分为无参构造方法有参构造方法
  • 当使用无参构造方法创建对象时,所有对象的属性都有相同的初始值。
  • 当使用有参构造方法创建对象时,对象的属性可以有不同的初始值。
  • 无参构造方法
class Car:
    def __init__(self):      							# 无参构造方法
        self.color = "红色"        
    def drive(self):    
        print(f"车的颜色为:{self.color}")
car_one = Car()   							# 创建对象并初始化
car_one.drive()
car_two = Car()   							# 创建对象并初始化
car_two.drive()
  • 有参构造方法
class Car:
    def __init__(self, color):  			# 有参构造方法
        self.color = color        			# 将形参赋值给属性 
    def drive(self): 
        print(f"车的颜色为:{self.color}")
car_one = Car("红色")   				# 创建对象,并根据实参初始化属性
car_one.drive()
car_two = Car("蓝色")   				# 创建对象,并根据实参初始化属性
car_two.drive()
7.3.2析构方法
  • 析构方法(即__ del__()方法)是销毁对象时系统自动调用的方法
  • 每个类默认都有一个__ del__()方法,可以显式定义析构方法
class Car:
    def __init__(self):
        self.color = "蓝色"
        print("对象被创建")
    def __del__(self):   			
        print("对象被销毁")
car = Car()
print(car.color)
del car  				
print(car.color)

7.4封装

封装是面向对象的重要特性之一,它的基本思想是对外隐藏类的细节提供用于访问类成员的公开接口。
如此,类的外部无需知道类的实现细节,只需要使用公开接口便可访问类的内容,这在一定程度上保证了类内数据的安全。

私有属性和私有方法都属于Python封装的形式,通过在属性和方法前加上两个下划线的方式,阻碍类外对类内属性和方法的访问和修改。但是Python中的私有属性和私有方法不是完全私有化的,是一种通过改变名称而阻碍类外访问的方式,实际上,还是可以通过“_类名__属性名”或者“_类名__方法名”的形式对其进行访问。

​ 为了契合封装思想,我们在定义类时需要满足以下两点要求。

  • 将类属性声明为私有属性。
  • 添加两类供外界调用的公有方法,分别用于设置或获取私有属性的值。
class Student:
    def __init__(self,score):
        self.__score = score
    def __get_score(self):
        return self.__score
s1 = Student(100)
print(s1._Student__score)                   #访问私有属性__score
print(s1._Student__get_score())          #访问私有方法__get_score()

#私有属性和私有方法不能直接访问,否则就会报错。通过加上类名的形式进行访问,能够成功访问,但是并不建议这种访问方式。=
  • @property的使用,@property是Python内置的装饰器,能够把方法变为属性

    class Score:
        def __init__(self,data):
            self.__data = data            #定义私有属性__data
        @property                           #使用@property将属性变为只读的
        def data(self):
            return f"私有属性的值为{self.__data}"
    s1 = Score(60)
    print(s1.data)                          #访问属性
    
    class Score:
        def __init__(self,data):
            self.__data = data              #定义私有属性__data
        @property                           #使用@property将属性变为只读的
        def data(self):
            return f"私有属性的值为{self.__data}"
        @data.setter                        #使用data.setter将属性变为可修改的
        def data(self,value):
            if value < 0 or value > 100:
                raise ValueError("您的输入有误,输入的范围应该在0~100之间")
            else:
                self.__data = value
    s1 = Score(60)
    print(s1.data)
    s1.data = 100
    print(s1.data)
    

7.5继承

继承是面向对象的重要特性之一,它主要用于描述类与类之间的关系,在不改变原有类的基础上扩展原有类的功能。
若类与类之间具有继承关系,被继承的类称为父类或基类,继承其他类的类称为子类或派生类子类会自动拥有父类的公有成员。

7.5.1单继承
  • 单继承即子类只继承一个父类。现实生活中,波斯猫、折耳猫、短毛猫都属于猫类,它们之间存在的继承关系即为单继承。
  • Python中单继承的语法格式如下所示:
    class 子类名(父类名):
class Cat(object):  
    def __init__(self, color):
        self.color = color   
    def walk(self):
        print("走猫步~")
# 定义继承Cat的ScottishFold类
class ScottishFold(Cat): 
    pass
fold = ScottishFold("灰色")          # 创建子类的对象
print(f"{fold.color}的折耳猫")       # 子类访问从父类继承的属性
fold.walk()                                   # 子类调用从父类继承的方法

PS:子类不会拥有父类的私有成员,也不能访问父类的私有成员。

class Cat(object):  
    def __init__(self, color):
        self.color = color    # 增加私有属性
        self.__age = 1
    def walk(self):
        print("走猫步~")
    def __test(self):         # 增加私有方法
        print("测试")
7.5.2多继承
  • 程序中的一个类也可以继承多个类,如此子类具有多个父类,也自动拥有所有父类的公有成员。
  • Python中多继承的语法格式如下所示:
    class 子类名(父类名1, 父类名2, …):
# 定义一个表示房屋的类
class House(object):  
    def live(self):   						# 居住
        print("供人居住")
# 定义一个表示汽车的类
class Car(object):  
    def drive(self):  						# 行驶
        print("行驶")
# 定义一个表示房车的类
class TouringCar(House, Car): 
    pass
tour_car = TouringCar()
tour_car.live()   						# 子类对象调用父类House的方法
tour_car.drive()  						# 子类对象调用父类Car的方法

PS:如果子类继承的多个父类是平行关系的类,那么子类先继承哪个类,便会先调用哪个类的方法。

7.5.3重写
  • 子类会原封不动地继承父类的方法,但子类有时需要按照自己的需求对继承来的方法进行调整,也就是在子类中重写从父类继承来的方法。

  • 在子类中定义与父类方法同名的方法,在方法中按照子类需求重新编写功能代码即可。

    # 定义一个表示人的类
    class Person(object):
        def say_hello(self):
            print("打招呼!")
    # 定义一个表示中国人的类
    class Chinese(Person):
        def say_hello(self):  					# 重写的方法
            print("吃了吗?")
    chinese = Chinese()
    chinese.say_hello()       					# 子类调用重写的方法
    
  • 子类重写了父类的方法之后,无法直接访问父类的同名方法,但可以使用super()函数间接调用父类中被重写的方法。

# 定义一个表示中国人的子类
class Chinese(Person):
    def say_hello(self):
        super().say_hello()                # 调用父类被重写的方法
        print("吃了吗?")

7.6多态

多态是面向对象的重要特性之一,它的直接表现即让不同类的同一功能可以通过同一个接口调用,表现出不同的行为。

class Cat:
    def shout(self):
        print("喵喵喵~")
class Dog:
    def shout(self):
        print("汪汪汪!")

def shout(obj):
    obj.shout()
cat = Cat()
dog = Dog()
shout(cat)
shout(dog)

你可能感兴趣的:(python,java,windows)