Python复习

文章目录

1.Python基础

1.1.非法标识符

1.2.常量和数据类型

1.2.1变量
  • 当我们修改其中一个变量的值,内存地址会发生变化。与C语言恰好相反
  • Python允许为多个变量同时赋值
  • Python变量的类型可以随时发生变化,与C区分开
1.2.2数据类型
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='') #不换行输出
1.2.4算术运算符

2.流程控制

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

2.1条件语句

2.1.1if语句
2.1.2if-else语句
2.1.3if-elif-else语句
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循环
2.2.2for循环
#输出所有的水仙花数
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,程序结束本层循环

2.3.2continue语句

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

3.字符串

3.1字符串介绍

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

3.2格式化字符串

3.2.1使用%格式化字符串
  • 格式化字符串是指将指定的字符串转换为想要的格式。Python字符串可以通过**%格式符**格式化输出。
3.2.2使用f-string格式化字符串
  • f字符串用花括号“{}”表示被替换的字段。
name = "张三"
studenId = "202201"
print(f'我叫{anme},学号为{studenId}')
3.2.3使用format()方法格式化字符串
  • 为了更直接、便捷地格式化字符串,Python为字符串提供了一种格式化字符串format()。
print("{}年{}学期我们学习了{}门课程".format("2022", "上"20))
其他格式处理
  • format()方法地模板字符串地空位不进可以填写参数序号,还有其他地格式处理形式。

3.3字符串常见操作

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

3.3.2字符串的查找与替换
  • Python中提供了实现字符串查找操作的find()方法,该方法可查找字符串中是否包含子串,若包含则返回子串首次出现的位置,否则返回-1
  • Python中提供了实现字符串替换操作replace()方法,该方法可将当前字符串中的指定子串替换成新的子串,并返回替换后的新字符串。
3.3.3字符串的分割与拼接
  • split()方法可以按照指定分割符对字符串进行分割,该方法会返回由分割后的子串组成的列表。
  • join()方法使用指定的字符连接字符串并生成一个新的字符串。join()方法的语法格式如下。
  • Python还可以使用运算发“+”拼接字符串

3.3.4删除字符串的指定字符串
  • 字符串中可能会包含一些无用的字符(如空格),在处理字符串之前往往需要先删除这些无用的字符。Python中的**strip()、lstrip()和rstrip()**方法可以删除字符串中的指定字符。
str = "00000dfsdfsdfs00"
print(str.strip('0')) #去除首尾字符0
字母转化
  • 在特定情况下会要求英文单词的大小写形式进行要求。Python中支持字母大小写转换的方法由uppe()、lower()、capitalize()和title()。
字符对齐
  • Python提供了center()、ljust()、rjust()这三个方法来设置字符串的对齐方式。

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_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()对象转化为元组
    
  • 元组的遍历同列表相同。

4.4集合

  • 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字典的创建
  • 通过“{}”创建字典
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一二维数据的存储与读写

  • 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对象。

  • 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)
    
  • 实例方法

    • 形似函数,但是定义在类内部
    • 以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通过在类成员的名称前面添加双下画线(__)的方式来表示私有成员,语法格式如下:
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构造方法
  • 无参构造方法
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封装

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)
12-25 07:48