Python笔记(二)

1.公共操作

1.1 公共运算符

运算符作用适用数据类型
+合并支持字符串、列表、元组
*复制支持字符串、列表、元组
in元素是否存在支持字符串、列表、元组、字典
not in元素是否不存在支持字符串、列表、元组、字典
str1 = 'my'
str2 = 'Name'
print(str1 + str2)  # myName
print(str1 * 5)  # mymymymymy
list1 = ['name', 'age']
list2 = ['nation']
print(list1 + list2)    # ['name', 'age', 'nation']
print(list1 * 4)    # ['name', 'age', 'name', 'age', 'name', 'age', 'name', 'age']
tuple1 = ('name', '123')
tuple2 = ('nation',)
print(tuple1 + tuple2)  # ('name', '123', 'nation')
print(tuple1 * 6)   # ('name', '123', 'name', '123', 'name', '123', 'name', '123', 'name', '123', 'name', '123')

1.2 公共方法

  1. len() 计算个数 字典、字符串、列表、元组、集合都支持
  2. del或del() 字典、字符串、列表、元组、集合都支持
  3. max() 返回元素的最大值 字典、字符串、列表、元组、集合都支持
  4. min() 返回元素的最小值 字典、字符串、列表、元组、集合都支持
  5. range(start, end, step) 生成从start到end的数字,步长为step,供for循环使用
  6. enumerate() 函数用于讲一个可遍历的数据对象(如列表、元组、字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中
    用法:enumerate(可遍历对象,start=0) start参数用来设置遍历数据的下标起始值,默认为0
list3 = [10, 20, 30, 40, 50, 60, 70, 80, 90]
for i in enumerate(list3):
    print(i)

for i, v in enumerate(list3, start=3):
    print(f'下标是{i},对应的字符是{v}')

1.3 数据类型转换

只针对序列(列表、元组、集合)。

  1. tuple() 将某个序列转换成元组
myList = [1, 2, 3, 4, 5, 6]
mySet = {10, 20, 30, 40, 50, 60}

print(tuple(myList))  # (1, 2, 3, 4, 5, 6)
print(tuple(mySet))  # (50, 20, 40, 10, 60, 30)
  1. list() 将某个序列转换成列表
mySet = {10, 20, 30, 40, 50, 60}
myTuple = ('a', 'b', 'c', 'd', 'e', 'f')

print(list(mySet))  # [50, 20, 40, 10, 60, 30]
print(list(myTuple))  # ['a', 'b', 'c', 'd', 'e', 'f']
  1. set() 将某个序列转换成集合
myList = [1, 2, 3, 4, 5, 6]
myTuple = ('a', 'b', 'c', 'd', 'e', 'f')

print(set(myList))  # {1, 2, 3, 4, 5, 6}
print(set(myTuple))  # {'d', 'c', 'a', 'e', 'b', 'f'}

1.4 推导式

需求1:创建0-10的偶数列表

evenNumList = [i for i in range(0, 10, 2)]
print(evenNumList)

需求2:创建字典 key是1-5的数字,v是这个数字的平方

newDict = {i: i ** 2 for i in range(1, 5)}
print(newDict)

需求3:将两个列表合并一个字典

keyList = ['name', 'age', 'nation']
valList = ['司马懿', '20', '魏']
infosList = {keyList[i]: valList[i] for i in range(len(keyList))}
print(infosList)

需求4:查找字典中,value值大于2500的数据

# 提取字典中目标数据
counts = {'XiaoMi': 2000, 'HuaWei': 6000, 'Oppo': 3000, 'Vivo': 3000}
# 查找字典中,value值大于2500的数据
count1 = {k: v for k, v in counts.items() if v > 2500}
print(count1)	# {'HuaWei': 6000, 'Oppo': 3000, 'Vivo': 3000}

需求5:创建一个集合,数据为下方列表的3次方

list4 = [1, 2, 3, 4, 5, 2]
set2 = {i ** 3 for i in list4}
print(set2)	# {64, 1, 8, 27, 125}

1.5 交换变量的值

A, B = 10, 20
A, B = B, A
print(A, B)  # 20 10

1.6 引用

在python中,值是靠引用来传递的。
不可变数据:整形、浮点型、元组、字符串
可变数据:列表、字典、集合

# 不可变数据 整形、浮点型、元组、字符串
a = 1
b = a
print(id(a))
print(id(b))
a = 2
print(a, b)  # 修改a的值不会影响b

# 可变数据:列表、字典、集合
c = [1, 2, 3, 4]
d = c
print(id(c))
print(id(d))
c = [2, 3, 4]
print(c, d)  # 修改c的值不会影响d

2. 猜拳小游戏

需求:玩家手动出拳,电脑随机出拳,然后判断输赢

import random

print("-----------游戏开始-----------")
print("1.石头\n2.剪刀\n3.布")
player = int(input("请输入数字"))
computer = random.randint(1, 3)
if player != computer:
    if computer == 1 and player == 2:
        print("电脑出的是石头,玩家失败")
    elif computer == 1 and player == 3:
        print("电脑出的是石头,玩家胜利")
    if computer == 2 and player == 1:
        print("电脑出的是剪刀,玩家胜利")
    elif computer == 2 and player == 3:
        print("电脑出的是剪刀,玩家失败")
    if computer == 3 and player == 1:
        print("电脑出的是布,玩家失败")
    elif computer == 3 and player == 2:
        print("电脑出的是布,玩家胜利")
else:
    print("平局")

3. 九九乘法表

j = 1
while j < 10:
    i = 1
    while i <= j:
        print(f"{i}*{j}={i * j}", end="\t")
        i += 1
    print()  # 打印换行
    j += 1
输出结果如下:
1*1=1	
1*2=2	2*2=4	
1*3=3	2*3=6	3*3=9	
1*4=4	2*4=8	3*4=12	4*4=16	
1*5=5	2*5=10	3*5=15	4*5=20	5*5=25	
1*6=6	2*6=12	3*6=18	4*6=24	5*6=30	6*6=36	
1*7=7	2*7=14	3*7=21	4*7=28	5*7=35	6*7=42	7*7=49	
1*8=8	2*8=16	3*8=24	4*8=32	5*8=40	6*8=48	7*8=56	8*8=64	
1*9=9	2*9=18	3*9=27	4*9=36	5*9=45	6*9=54	7*9=63	8*9=72	9*9=81

4.函数

4.1 help()

作用:查看函数的说明文档

def myFun():
    """
    这是一个自定义函数
    :return:
    """
    return 0


help(myFun)

4.2 全局变量的定义和使用

使用全局变量的时候要在前面加关键字global

a = 100
b = 200


def testA():
    global a  # 修改全局变量
    a = 200
    b = 300


testA()
print(a, b)  # 200 200

4.3 返回值

当return返回有多个值的时候,这时候的数据类型一般是元组

def testB():
    return 3, 4


print(testB())	# (3, 4)

4.4 不定长参数

不定长参数有两种,分别是

  1. 位置参数 *args
  2. 关键字参数 **kwargs

两个都可以将零散数据作为一个整体返回,这个过程就是组包

def testC(*args):
    print(args)  # 返回元组
    return args


def testD(**kwargs):
    print(kwargs)  # 返回字典
    return kwargs


testC('123', '111')	# ('123', '111')
testD(key1=123, key2='111')	# {'key1': 123, 'key2': '111'}

拆包:将函数返回的整体数据用多个变量来表示

a, b = testC('123', '111')
dict1 = testD(key1=123, key2='111')
c, d = dict1  # 取出来的是字典的key
print(a, b, c, d, dict1[c], dict1[d])   # 123 111 key1 key2 123 111

4.5 递归

就是指函数本身调用本身的一种行为。
需要注意的是:递归一定要有出口,不然程序会一直执行下去。
例如:使用递归实现一个数字累加,例如10以内的数字累加

def summation(num):
    if num == 1:  # 递归出口
        return 1
    return num + summation(num - 1)


print(summation(10))

4.6 匿名函数lambda

匿名函数的参数传递有下面5种,分别是:

  1. 无参数
  2. 一个参数
  3. 默认参数
  4. 可变参数*args
  5. 可变参数 **kwargs
# 无参数
fn1 = lambda: 100  # PEP8规范不建议这么使用
print(fn1())
# 一个参数
fn2 = lambda a: a  # PEP8规范不建议这么使用
print(fn2(100))
# 默认参数
fn3 = lambda a, b, c=100: a + b + c  # PEP8规范不建议这么使用
print(fn3(100, 200))
fn4 = lambda *args: args  # PEP8规范不建议这么使用
print(fn4(10, 20, 30, '22'))
fn5 = lambda **kwargs: kwargs  # PEP8规范不建议这么使用
print(fn5(age=10, name='22'))

匿名函数 lambda 的应用:
例如:对列表中的数据进行排序

students = [{'name': '诸葛亮', 'age': '19'}, {'name': '司马懿', 'age': '20'}, {'name': '周瑜', 'age': '21'},
            {'name': '荀彧', 'age': '26'}]
# 按name值升序排列
students.sort(key=lambda x: x['name'])
print(students)
# 按age值降序排列,sort函数中的key是用来比较的元素
students.sort(key=lambda x: x['age'], reverse=True)
print(students)

4.7 高阶函数

4.7.1 abs()

函数的作用是求绝对值。

print(abs(-1.2))    # 1.2

4.7.2 round()

函数的作用是四舍五入取近似值

print(round(-1.2)) # -1

4.7.3 函数可以当做参数

# 任意两个数字,要求求绝对值后,再进行求和计算
def sumNum(a, b, f):
    return f(a) + f(b)


print(sumNum(-10, 63.2, abs))

4.7.4 map(func,lst)

将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的迭代器返回(基于python3)
例如:计算列表中各个数字的3次方

# 计算列表中各个数字的3次方
list1 = [10, 20, 33, 66, 55]


def func(x):
    return x ** 3


print(list(map(func, list1)))
# 方法二
print(list(map(lambda x: x ** 3, list1)))

4.7.5 reduce(func,lst)

其中func必须有两个参数,每次func计算的结果继续和序列的下一个元素做累积计算
例如:求累加或者累积

# 计算列表中各个数字的累加和
print(reduce(lambda x, y: x + y, list1))
# 计算列表中各个数字的累乘积
print(reduce(lambda x, y: x * y, list1))

4.7.6 filter(func,lst)

用于过滤序列,过滤掉不符合条件的元素,返回一个filter对象。如果要转换为列表,可以使用list()来转换

# 过滤列表中不能被2整除的项
print(list(filter(lambda x: x % 2 == 0, list1)))

4.8 学生管理系统

需求:要求展示下列功能
1.添加学员信息
2.删除学员
3.修改学员信息
4.查询学员信息
5.显示所有学员信息
6.退出系统

代码实现:

stuDict = {}


def systemUI():
    """
    系统UI
    :return 对应的指令
    """
    print("--------------------欢迎来到学员管理系统--------------------")
    print("1.添加学员信息")
    print("2.删除学员")
    print("3.修改学员信息")
    print("4.查询学员信息")
    print("5.显示所有学员信息")
    print("6.退出系统")
    command = int(input("请输入对应功能前的数字:"))
    return command


def addStu():
    """
    添加学员
    :return:
    """
    stuId = int(input("请输入学员的编号:"))
    stuName = str(input("请输入学员的姓名:"))
    stuAge = int(input("请输入学员的年龄:"))
    stuSex = int(input("请输入学员的性别(0代表男,1代表女):"))
    # 判断编号是否已经存在
    if stuId in stuDict.keys():
        print(f"编号为{stuId}的学员已存在,请核对后添加。")
        runSystem()
    else:
        stuDict[stuId] = {'name': stuName, 'age': stuAge, 'sex': stuSex}
        print(f"编号为{stuId}的学员添加成功!")
        runSystem()


def delStu():
    """
    删除学员
    """
    stuId = int(input("请输入学员的编号:"))
    # 判断编号是否已经存在
    if stuId not in stuDict.keys():
        print(f"编号为{stuId}的学员不存在,请核对后再操作。")
        runSystem()
    else:
        del stuDict[stuId]
        print(f"编号为{stuId}的学员已成功删除!")
        runSystem()


def selectStu(*args):
    """
    查询学员
    """
    stuId = args
    if len(stuId) == 0:
        stuId = int(input("请输入学员的编号:"))
        print(stuDict[stuId])
        runSystem()
    elif stuId[0] == 'ALL':
        print(f"学员信息展示如下:{stuDict}")
        runSystem()
    else:
        # 判断编号是否存在
        if stuId[0] not in stuDict:
            print(f"编号为{stuId[0]}的学员不存在,请核对后再操作。")
            runSystem()
        else:
            print(f"编号为101的学员信息如下:{stuDict[stuId[0]]}")


def updateStu():
    """
    修改学员信息
    """
    stuId = int(input("请输入学员的编号:"))
    # 判断编号是否已经存在
    if stuId not in stuDict:
        print(f"编号为{stuId}的学员不存在,请核对后再操作。")
        runSystem()
    else:
        selectStu(stuId)
        newKey = input("请输入要修改的字段")
        # 判断输入的字段是否存在
        if newKey not in stuDict[stuId].keys():
            print(f"您输入的{newKey}字段不存在,请核对后再操作")
            runSystem()
        else:
            newVal = input("请输入修改后的内容")
            stuDict[stuId][newKey] = newVal
            print("修改成功")
            runSystem()


def runSystem():
    """
    系统主程序
    :return:
    """
    command = systemUI()
    if command == 1:
        addStu()
    elif command == 2:
        delStu()
    elif command == 3:
        updateStu()
    elif command == 4:
        selectStu()
    elif command == 5:
        selectStu('ALL')
    else:
        print("系统退出成功!")


runSystem()

5 文件/文件夹操作

5.1文件操作

5.1.1 打开文件

打开文件使用:open(name,mode),其中name是文件路径,mode是打开的模式
常用的模式有以下几种:

模式说明
r只读的方式打开文件,也是默认模式,文件不存在则报错 文件指针在开头
w写入文件,会替换原有内容,且如果文件不存在则会创建,文件指针在开头
a写入文件,不会替换原有内容,在原有基础上添加,且如果文件不存在则会创建,文件指针在结尾
rb+二进制打开文件,可以读写,写的话是追加
ab+二进制打开文件,可以读写, 文件指针在结尾

5.1.2 读写文件

写入数据使用:文件对象.write()
读取文件有3种常用的方法:

  1. read():可以传递读取的数据长度(字节),不传入默认读取全部
  2. readlines(): 按照行的方式返回,返回是一个列表,每一行代表一个元素
  3. readline(): 每次读取一行的数据,执行几次就读取第几行

5.1.3 seek()方法

用来移动文件指针。传递两个参数,一个是偏移量,一个是指针的起始位置:0开头 1当前 2 结尾

# 利用文件指针,获取数据
f = open(file='./data/test04.txt', mode='a+')  # a+模式打开文件后,指针指向文件最后
f.write(f"{datetime.datetime.now()}\n")
f.close()
# 查看写入的文件内容
f = open(file='./data/test04.txt', mode='a+')
f.seek(0, 0)  # 将指针指向起始位置,且无偏移量。 如果不改变指针位置,则读取不到数据
print(f.readlines())
f.close()

5.1.4 关闭

每次对文件操作完成后,都需要关闭。用法:文件对象.close()

5.2 OS模块

OS模块经常和文件/文件夹操作绑定在一起。在使用之前要先导入模块:import os
常用的方法有以下几种:
4. 文件重命名,os.rename(目标文件名,新文件名),也可以指定文件夹重命名。
5. 文件删除 os.remove(目标文件名)
6. 创建文件夹 os.mkdir(文件夹名字)
7. 删除文件夹 os.rmdir(文件夹名字)
8. 获取当前文件所在目录 os.getcwd()
9. 改变目录路径 os.chdir(文件夹名字)

# chdir() 应用:创建一个test文件夹,然后在test文件夹下面创建个name文件夹
os.mkdir("test")    # 创建test文件夹
os.chdir("test")    # 移入test文件夹
os.mkdir("name")    # 创建name文件夹
os.rmdir("name")    # 删除name文件夹
os.chdir(projectPath)   # 移入项目所在的文件夹,即test文件夹的上一级路径
os.rmdir("test")    # 删除test文件夹
  1. 获取当前文件所在的目录列表 os.listdir(),可传递参数:路径,即获取指定路径下的文件列表
print(os.listdir())
print(os.listdir("data"))

应用:用户输入当前目录下任意文件名,程序完成对该文件的备份功能(备份文件名为原始文件名_bak),例如:test_bak.txt
实现思路:

  1. 获取输入的文件名,并判断格式是否正确
  2. 构造新的文件名
  3. 获取旧文件里面的内容并写入新文件
    代码实现如下:
def fileBackup(filename):
    index = filename.rfind(".")  # 从右边查找,第一个"."就是文件类型
    if index <= 0:  # 例如:.xlsx
        print("您输入的文件名不正确!")
    else:
        # 获取原始文件的内容
        f = open("./data/" + filename, "rb")
        content = f.read()
        f.close()
        # 定义新文件名
        newFileName = filename[:index] + "_bak" + filename[index:]
        # 新建备份文件
        f = open("./data/" + newFileName, "wb+")
        f.write(content)
        f.close()
        print("文件备份成功")

6 面向对象

6.1 类和对象

     类和对象的关系:类是一个抽象的概念,相当于武器图纸。对象是个实际存在的东西,是一把实际的武器。即根据图纸去打造武器,根据类去创建对象。
     类的命名除了要满足基本的命名规则,也要养成大驼峰命名的习惯。例如: class Student()
     对象,即类的实例。语法是:对象名 = 类名() 即 student = Student()

class Student:
    def study(self):
        print("我是学生,我爱学习")
        print(self)
        print(f"self的内存地址是{id(self)}")

类里面的self 指的是调用该函数的对象。

class Student:
    def study(self):
        print("我是学生,我爱学习")
        print(self)
        print(f"self的内存地址是{id(self)}")


tom = Student()
tom.study()
print(tom)  # 输出的结果和study方法中的print(self)结果一样
print(f"tom的内存地址是{id(tom)}")

一个类可以创建多个对象,不同对象的内存地址不同,不同对象调用的方法中的self内存地址也不一样。

Lychee = Student()
Lychee.study()
print(Lychee)
print(f"Lychee的内存地址是{id(Lychee)}")

6.2 类添加属性

  1. 使用实例对象添加
Lychee.age = 19
print(Lychee.age)
  1. 直接在类里添加
class Weapon:
    def __init__(self, attack):
        # 初始化属性值
        self.attack = attack

    # 添加类说明,打印实例对象的时候,执行该函数
    def __str__(self):
        return "这是一个武器图纸"

    # 删除对象的时候触发
    def __del__(self):
        print(f"{self}已经被删除啦")

    def show_info(self):
        # 类里面获取属性
        print(f"攻击力是:{self.attack}")

6.3 __str__方法

用于 添加类说明,打印实例对象的时候,执行该函数

class Weapon:
    def __init__(self, attack):
        # 初始化属性值
        self.attack = attack

    # 添加类说明,打印实例对象的时候,执行该函数
    def __str__(self):
        return "这是一个武器图纸"

    def show_info(self):
        # 类里面获取属性
        print(f"攻击力是:{self.attack}")

6.4 __del__方法

删除对象的时候触发

class Weapon:
    def __init__(self, attack):
        # 初始化属性值
        self.attack = attack

    # 删除对象的时候触发
    def __del__(self):
        print(f"{self}已经被删除啦")

    def show_info(self):
        # 类里面获取属性
        print(f"攻击力是:{self.attack}")

6.5 继承

子类继承父类的属性和参数。继承分为单继承和多继承。
查看继承关系:子类名.__mro__

6.5.1 单继承:子类继承一个父类。

class Father(object):
    def __init__(self):
        self.skill = "风卷残云"

    def fight(self):
        print(f"释放技能{self.skill}")

class Disciple(Father):
	pass


zhang = Disciple()
print(zhang.skill)  # 风卷残云
zhang.fight()	# 释放技能风卷残云

子类继承父类后,可以调用父类的属性和方法。也可以重写父类方法
例如:Disciple类重写了Father类的fight方法

class Disciple(Father, School):
    def __init__(self):
        super().__init__()
        # 定义私有属性
        self.__weapon = "雾切之回光"

    def fight(self):  # 子类重写父类方法
        # 如果用到了子类自己的同名属性,则需要初始化
        self.__init__()
        print("释放技能麒麟残云")

6.5.2 多继承:子类继承多个父类,如果存在相同的属性和方法,优先继承第一类的。即Father类

class Father(object):
    def __init__(self):
        self.skill = "风卷残云"

    def fight(self):
        print(f"释放技能{self.skill}")


class School(object):
    def __init__(self):
        self.skill = "麒麟降世"

    def fight(self):
        print(f"释放技能{self.skill}")


# 继承School
class Disciple(Father, School):
	pass

zhang = Disciple()
print(zhang.skill)  # 风卷残云
zhang.fight()	# 释放技能风卷残云

6.5.3 多层继承

即孙子继承儿子,儿子继承父亲。

class GrandSon(Disciple):
    pass

多层继承想一次性调用所有父类方法:
需求:GrandSon想获得Father类和Disciple类的fight()方法
实现步骤:

  1. 在GrandSon类中定义一个方法fight_all()
  2. 在fight_all()里面使用super()去初始化父类和父类的fight()方法
  3. 在Disciple类中的fight()方法,做相同的操作。
class Father(object):
    def __init__(self):
        self.skill = "风卷残云"

    def fight(self):
        print(f"释放技能{self.skill}")


class School(object):
    def __init__(self):
        self.skill = "麒麟降世"

    def fight(self):
        print(f"释放技能{self.skill}")


# 继承School
class Disciple(Father, School):
    def __init__(self):
        super().__init__()
        # 定义私有属性
        self.__weapon = "雾切之回光"

    def fight(self):  # 子类重写父类方法
        # 如果用到了子类自己的同名属性,则需要初始化
        self.__init__()
        print("释放技能麒麟残云")
        super().__init__()
        super().fight()
        self.__unique_skill()

    # 定义私有方法
    def __unique_skill(self):
        print(f"使用{self.__weapon}释放出了技能:神里流-霜灭")

    # 子类调用父类的方法
    def fight_school(self):
        School.__init__(self)
        School.fight(self)

    # 获取私有属性
    def get_weapon(self):
        return self.__weapon

    # 修改私有属性的值
    def set_weapon(self, name):
        self.__weapon = name

class GrandSon(Disciple):
    # 一次性调用所有父类的方法,需要在Disciple类中也添加才能调用到Father类
    def fight_all(self):
        super().__init__()
        super().fight()

    pass


wang = GrandSon()
wang.fight_all()

运行结果:
在这里插入图片描述

6.5.4 在类中定义私有属性/方法

例如定义私有属性:self.__weapon = "雾切之回光"

# 定义私有方法
    def __unique_skill(self):
        print(f"使用{self.__weapon}释放出了技能:神里流-霜灭")

6.6 多态

多态是指:一类事物有多种形态。
即 子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
实现步骤:

  1. 定义父类,提供公共方法
  2. 定义子类,重写父类方法
  3. 传递子类的实例对象给调用者。

例如芙宁娜的荒芒两种形态:

# 定义四个类,分别是 旅行者、芙宁娜、荒属性芙宁娜、芒属性芙宁娜
class FuNN(object):
    def __init__(self):
        self.weapon = "静水之华"

    def skill(self):
        print(f"使用{self.weapon}战斗,释放技能")


class Waste(FuNN):
    def skill(self):
        super().__init__()
        super().skill()
        print("召唤「乌瑟勋爵」、「海薇玛夫人」、「谢贝蕾妲小姐」")


class Awn(FuNN):
    def skill(self):
        super().__init__()
        super().skill()
        print("召唤「众水的歌者」")


class Traveler(object):
    def __init__(self):
        self.weapon = "西风剑"

    def fight(self, teammate):
        teammate.skill()
        print(f"使用{self.weapon}战斗,释放技能")


# 实例化对象
ceyyen = Traveler()
wasteFnn = Waste()
awnFnn = Awn()
ceyyen.fight(wasteFnn)
ceyyen.fight(awnFnn)

运行结果:
在这里插入图片描述

6.7 类属性和实例属性

类属性就是类对象拥有的属性,被该类的所有实例对象共有。
类属性可以使用类对象或者是实例对象访问
类属性只能通过类对象来修改,如果使用实例对象去修改,则表示新增了一个实例属性

class Person:
    age = 30
    pass


# 类对象访问类属性
print(Person.age)  # 30
# 实例对象访问类属性
student = Person()
print(student.age)  # 30
# 类对象修改类属性
Person.age = 21
print(Person.age)  # 21
student.age = 18
print(Person.age)  # 21
print(student.age)  # 18

6.8 类方法和静态方法

     类方法:需要用装饰器@classmethod来标识的,就是类方法,对于类方法,第一个参数必须是类对象。一般用于操作私有类属性或者是类属性的时候使用
     静态方法:需要通过装饰器@staticmethod来进行修饰。该方法不需要传递任何参数,有利于减少内存占用和性能消耗

class Student(Person):
    __money = 10000

    @classmethod
    def get_money(cls):
        return cls.__money

    @staticmethod
    def info_display():
        print("这是一位学生")


sun = Student()
print(sun.get_money())  # 10000
sun.info_display()  # 这是一位学生

7 异常

语法:

try:
    发生异常的代码
except 异常类型:
    捕获到异常后执行的代码

7.1 捕获单个异常

try:
    print(num)
except NameError as result:  # 捕获多个异常
    print("执行报错")
    print(result)

7.2 捕获多个异常

捕获多个异常的时候,可以将异常类型组成元组,放到except 后面

try:
    print(1 / 0)
except (NameError, ZeroDivisionError) as result:  # 捕获多个异常
    print("执行报错")
    print(result)

7.3 捕获所有异常

else:如果没有报错,就执行该语句
finally:无论是否报错,都要执行的语句

try:
    print(1 / 0)
except Exception as result:  # 捕获所有异常
    print("执行报错")
    print(result)
else:
    print("如果没有报错,就执行我")
finally:
    print("无论是否异常,都必须执行我。")
    print("一般用于关闭文件或者是数据库连接")

7.4 自定义异常

自定义异常,继承Exception类,使用raise抛出异常
例如:当输入密码长度不符合要求,抛出异常。

class PwdInputError(Exception):
    def __init__(self, length, min_len):
        self.length = length
        self.min_len = min_len

    # 设置抛出的异常信息
    def __str__(self):
        return f"你输入的密码长度是{self.length},小于{self.min_len}个字符"


def test():
    try:
        pwd = input("请输入密码\n")
        if len(pwd) < 6:
            raise PwdInputError(len(pwd), 6)
    except PwdInputError as errInfo:
        print(errInfo)
    else:
        print("密码输入成功")


test()

8 模块和包

8.1 什么是模块

模块是一个Python文件,包含了python对象的定义和python语句

8.2 模块的作用

定义函数、类、变量、等其他可执行代码

8.3 导入模块的方式

  1. import 模块名
  2. from 模块名 import 功能名
  3. from 模块名 import *
  4. from 模块名 import 功能名 as 别名
  5. import 模块名 as 别名

8.4 制作模块的步骤

  1. 编写功能
def my_function(a, b):
    return a + b
  1. 测试功能
  2. 添加main执行函数
if __name__ == '__main__':
    print(my_function(1, 2))

8.5 模块的定位顺序

  1. 当前目录
  2. 不在当前目录,就去找shell变量PYTHONPATH下的每个目录,即python的安装目录
  3. 如果以上都找不到,则会查找默认路径。

8.6 __all__变量

定义多个功能,把某个功能添加到列表中,当不在列表中的功能,被模块调用时,不会执行。
一般在模块首行添加。例如:__all__ = ["my_function"]

8.7 什么是包

有联系的模块放在同一个文件夹下,并且在该文件下创建了一个__init__.py的文件,这个文件夹就是包。

8.8 如何导入包

  1. import.包名.模块名
  2. from 包名 import * 使用前需要在__init__.py 文件中添加__all__ = [模块名] ,控制允许导入的模块列表 ,不在列表里的模块,不能被调用。
  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值