python学习笔记(3)

news/2024/11/16 18:28:28/

接python学习笔记(2)

python学习笔记3

  • 一、面向对象基础
    • 1、理解面向对象
    • 2、类和对象
    • 3、添加和获取对象属性
    • 4、魔法方法
    • 5、综合应用
  • 二、面向对象-继承
    • 1、继承的概念
    • 2、单继承
    • 3、多继承
    • 4、子类重写父类的同名属性和方法
    • 5、子类调用父类的同名属性和方法
    • 6、多层继承
    • 7、super()
    • 8、私有属性和私有方法
  • 三、面向对象-其他
    • 1、面向对象三大特性
    • 2、类属性和实例属性
    • 3、类方法和静态方法
  • 四、异常
    • 1、了解异常
    • 2、捕获异常
      • 捕获指定异常
      • 捕获多个指定异常
      • 捕获异常描述信息
      • 捕获所有异常
    • 3、异常的else
    • 4、异常finally
    • 5、异常的传递
    • 6、自定义异常
  • 五、模块和包
    • 1、了解模块
    • 2、导入模块
    • 3、制作模块
    • 4、模块定位顺序
    • 5、_ _all__
    • 5、包的使用
      • 5.1 了解包
      • 5.2 制作包
      • 5.3 导入包
  • 六、面向对象版学员管理系统
    • 1、系统需求
    • 2、准备程序文件
    • 3、书写程序

一、面向对象基础

1、理解面向对象

面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事情。面向对象就是化简代码用的

2、类和对象

1、什么是类和对象,它们是什么关系?

洗衣机是怎么生产出来的呢?
图纸–>洗衣机–>洗衣服
在面向对象编程过程中,有两个重要组成部分:类和对象
类相当于是图纸,对象相当于是洗衣机
类和对象的关系:用类去创建(实例化)一个对象

2、类

类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真是存在的事物。类里面有变量和函数。

对象

对象是类创建出来的真是存在的事物,例如:洗衣机
注意:在开发中,先有类,再有对象

3、面向对象实现方法
3.1、定义类
语法:

class 类名():代码......
注意:类名要满足标识命名规则,同时遵循大驼峰命名习惯

3.2、创建对象
语法:

对象名=类名()

3.3、体验类和对象
需求:洗衣服,功能:能洗衣服

#1、定义洗衣机类
class Washer():def wash(self):print("能洗衣服")
#2、创建对象
#对象名=类名()
haier=Washer()
#3、验证结果
#3.1、打印haier对象
print(haier)
#3.2、使用wash功能---实例方法/对象方法--》用法:对象名.wash()
haier.wash()
结果为:
<__main__.Washer object at 0x0000019A17E52358>
能洗衣服

3.4、类里面的self
上述例子,我们定义函数时,输入小括号直接弹出了self,这个self是什么呢?

self指的是调用该函数的对象

代码如下:

class Waher():def wash(self):print("洗衣服")print(self)     #打印的结果就是haier对象的内存地址
haier=Waher()
print(haier)
haier.wash()
结果为:
<__main__.Waher object at 0x0000022543D42358>
洗衣服
<__main__.Waher object at 0x0000022543D42358>

3.5、一个类创建多个对象
一个类创建多个对象,多个对象都调用函数时,self地址是否相同?
验证代码如下:

class Washer():def wash(self):print("洗衣服")print(self)
haier1=Washer()
haier1.wash()haier2=Washer()
haier2.wash()
结果为:一个类可以创建多个对象,多个对象都调用函数时,self的值不一样
洗衣服
<__main__.Washer object at 0x00000277DD9652E8>
洗衣服
<__main__.Washer object at 0x00000277DD965358>

3、添加和获取对象属性

属性即是特征,比如:洗衣机的宽度,高度,重量…
对象属性既可以在类外面添加和获取,也能在类里面添加和获取

1、在类外面添加对象属性

语法:对象名.属性名=值

举例:

haier.width=500
haier.height=800

2、在类外面获取对象属性

语法:对象名.属性名
用户想要看见结果,就必须使用print输出结果

代码如下:

haier.width=500
haier.height=800
print("haier洗衣机的宽度是{},高度是{}".format(haier.width,haier.height))
结果为:
haier洗衣机的宽度是500,高度是800

3、在类里面获取对象属性

语法:self.属性名

class Washer():def wash(self):#类里面获取实例属性print(f"haier洗衣机的宽度是{self.width}")print(f"haier洗衣机的高度是{self.height}")
#创建对象
haier=Washer()
#添加实例属性
haier.width=500
haier.height=800
haier.wash()
结果为:
haier洗衣机的宽度是500
haier洗衣机的高度是800

4、魔法方法

在python中,__ xx__()的函数叫做魔法方法,指的是具有特殊功能的函数

1、_ init_()

作用:用来初始化对象
注意:
1、在创建一个对象时默认被调用,不需要手动调用
2、_ init _(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去

代码如下:

#目标:定义init魔法方法设置初始化属性并且访问调用
#1、定义类:init魔法方法:width和height;添加实例方法:访问实例属性
class Washer():def __init__(self):self.width=400self.height=500def print_info(self):print(f"haier洗衣机的宽度为{self.width},洗衣机的高度为{self.height}")
#2、创建对象
haier=Washer()
#3、验证成果
haier.print_info()
结果为:
haier洗衣机的宽度为400,洗衣机的高度为500

2、带参数的_ init _()

一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性呢?
答案为:传参数

代码如下:

class Washer():def __init__(self,width,height):self.width=widthself.height=heightdef print_info(self):print(f"洗衣机的宽度为{self.width}")print(f"洗衣机的高度为{self.height}")haier1=Washer(30,40)  #创建多个对象且属性值不同
haier1.print_info()   #调用实例方法
print("-"*20)
haier2=Washer(50,60)
haier2.print_info()
结果为:
洗衣机的宽度为30
洗衣机的高度为40
-------------------
洗衣机的宽度为50
洗衣机的高度为60

3、_ str_()

当使用print输出对象的时候,默认打印对象的内存地址。如果定义了_str_方法,那么就会打印:在这个方法中return的数据

代码如下:

class Washer():def __init__(self,width,height):self.width=widthself.height=heightdef print_info(self):print(f"洗衣机的宽度为{self.width}")print(f"洗衣机的高度为{self.height}")def __str__(self):return "这是海尔洗衣机的说明书"
haier=Washer(100,200)
print(haier)
haier.print_info()
结果为:
这是海尔洗衣机的说明书
洗衣机的宽度为100
洗衣机的高度为200

4、_ del_()

当删除对象时,python解释器也会默认调用_del_()方法

代码如下:

class Washer():def __init__(self):self.width=300def __del__(self):print("对象已经删除")
haier=Washer()
结果为:
对象已经删除

5、综合应用

需求一:烤地瓜

1、被烤的时间和对应的地瓜状态:
0-3分钟:生的
3-5分钟:半生不熟
5-8分钟:熟的
超过8分钟:烤糊了
2、添加的调料
用户根据自己的意愿添加调料

步骤分析如下:
在这里插入图片描述
实现代码如下:

class SweetPotato():def __init__(self):#被烤的时间self.cook_time=0#烤的状态self.cook_static="生的"#调料列表self.condiments=[]def cook(self,time):"""烤地瓜的方法"""#之前烤的时间+这次烤的时间self.cook_time+=timeif 0<=self.cook_time<3:self.cook_static="生的"elif 3<=self.cook_time<5:self.cook_static="半生不熟"elif 5<=self.cook_time<8:self.cook_static="熟了"elif self.cook_time>=8:self.cook_static="烤糊了"def add_condiments(self,condiment):"""添加调料"""self.condiments.append(condiment)def __str__(self):return f"这个地瓜烤了{self.cook_time}分钟,状态是{self.cook_static},添加的调料有{self.condiments}"digua=SweetPotato()
digua.cook(4)
digua.add_condiments("蜂蜜")
print(digua)
digua.add_condiments("芥末")
print(digua)

结果为:
在这里插入图片描述
需求二:搬家具

将小于房子剩余面积的家具摆放到房子中

步骤分析:

需求涉及两个事物:房子和家具,涉及两个类:房子类和家具类

在这里插入图片描述
实现代码如下:

class Furniture():def __init__(self,name,area):#家具名字self.name=name#家具占地面积self.area=area
class Home():def __init__(self,adress,area):self.adress=adressself.area=areaself.free_area=areaself.furniture=[]def __str__(self):return f"房子坐落于{self.adress},占地面积为{self.area},剩余面积为{self.free_area},家具有{self.furniture}"def add_furniture(self,item):"""容纳家具"""#如果家具占地面积小于房子的剩余面积,就可以搬入(家具列表添加数据,房屋剩余面积要更新)if self.free_area>=item.area:self.furniture.append(item.name)self.free_area-=item.areaelse:print("家具太大,房屋剩余面积不足,无法容纳")jia1=Home("北京",100)
print(jia1)
#可以搬入家具的情况
bed=Furniture("双人床",10)
jia1=Home("北京",100)
jia1.add_furniture(bed)
print(jia1)
#无法搬入家具的情况
sofa=Furniture("沙发",105)
jia1.add_furniture(sofa)
print(jia1)

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

二、面向对象-继承

1、继承的概念

子类不需要写什么代码,继承父类。作用就是为了化简代码
python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法

体验继承

#父类A
class A(object):def __init__(self):self.num=1def info_print(self):print(self.num)
#子类B,继承父类
class B(A):pass
result=B()
result.info_print()   #结果为:1

在python中,所有类默认继承object类,object类是顶级类或者基类;其他子类叫做派生类(如上述例子的A,B都是派生类)

2、单继承

子类继承父类,默认继承父类里的所有属性及方法

徒弟想要继承师傅的煎饼果子大法

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class Prentice(Master):passxiaoming=Prentice()
print(xiaoming.kongfu)
xiaoming.make_cake()
结果为:
[古法煎饼果子配方]
运用[古法煎饼果子配方]制作煎饼果子

3、多继承

所谓多继承就是一个子类同时继承了多个父类

小明除了在师傅那里学习了煎饼大法,还在黑马培训班里,包名学习了煎饼大法

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(object):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class Prentice(School,Master):passxiaoming=Prentice()
print(xiaoming.kongfu)
xiaoming.make_cake()
结果为:
[黑马煎饼果子配方]
运用[黑马煎饼果子配方]制作煎饼果子

结论:当一个类拥有多个父类的时候,默认使用第一个父类的同名属性和方法

4、子类重写父类的同名属性和方法

小明掌握了师傅和黑马培训的煎饼果子技术之后,自己研究出了自己的一套独创煎饼果子配方技术

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(object):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class Prentice(School,Master):def __init__(self):self.kongfu='[独创煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")xiaoming=Prentice()
print(xiaoming.kongfu)
xiaoming.make_cake()
结果为:
[独创煎饼果子配方]
运用[独创煎饼果子配方]制作煎饼果子

结论:如果子类和父类拥有同名属性和方法,子类创建对象调用属性和方法的时候,调用的是子类里面的同名属性和方法
拓展:_mro _顺序

可以查看类之间的继承顺序

print(Prentice.__mro__)
结果为:
(<class '__main__.Prentice'>, <class '__main__.Master'>, <class 'object'>)

5、子类调用父类的同名属性和方法

很多顾客都希望能吃到古法和黑马技术的煎饼果子

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(object):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class Prentice(Master,School):def __init__(self):self.kongfu='[独创煎饼果子配方]'def make_cake(self):#加自己的初始化的原因:如果不加,会导致kongfu属性值是上一层次调用的init内的kongfu属性值self.__init__()print(f"运用{self.kongfu}制作煎饼果子")#子类调用父类的同名属性和方法,把父类的同名属性和方法再次封装def make_master_cake(self):#再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置,所以需要再次调用initMaster.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)xiaoming=Prentice()
xiaoming.make_cake()
xiaoming.make_master_cake()
xiaoming.make_school_cake()
xiaoming.make_cake()

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

6、多层继承

n年后,小明老了,想要把所有技术传承给自己的徒弟

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(object):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class Prentice(Master,School):def __init__(self):self.kongfu='[独创煎饼果子配方]'def make_cake(self):#加自己的初始化的原因:如果不加,会导致kongfu属性值是上一层次调用的init内的kongfu属性值self.__init__()print(f"运用{self.kongfu}制作煎饼果子")#子类调用父类的同名属性和方法,把父类的同名属性和方法再次封装def make_master_cake(self):#再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置,所以需要再次调用initMaster.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)
#创建徒孙类
class Tunsun(Prentice):pass
xiaozhang=Tunsun()
xiaozhang.make_school_cake()
结果为:

7、super()

1、作用

可以快速调用父类方法,可以减少代码的冗余
语法:super(当前类名,self).函数()/super().函数

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(Master):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")#2.1:有参数的super(),想要显示Master里面的内容,就得添加这个代码,调用父类:Master#super(School,self).__init__()#super(School,self).make_cake()#2.2:无参数的supersuper().__init__()super().make_cake()
class Prentice(School):def __init__(self):self.kongfu='[独创煎饼果子配方]'def make_cake(self):#加自己的初始化的原因:如果不加,会导致kongfu属性值是上一层次调用的init内的kongfu属性值self.__init__()print(f"运用{self.kongfu}制作煎饼果子")#子类调用父类的同名属性和方法,把父类的同名属性和方法再次封装def make_master_cake(self):#再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在init初始化位置,所以需要再次调用initMaster.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)#一次性调用两个父类def make_old_cake(self):#方法1(2.1):类名修改比较频繁;代码量庞大,代码冗余#School.__init__(self)#School.make_cake(self)#Master.__init__(self)#Master.make_cake(self)#方法2(2.2):super(),带参数的super()#super(Prentice,self).__init__()#super(Prentice,self).make_cake()super().__init__()super().make_cake()
daqiu=Prentice()
daqiu.make_old_cake()
结果为:
运用[黑马煎饼果子配方]制作煎饼果子
运用[古法煎饼果子配方]制作煎饼果子

注意:使用super()可以自动查找父类。

8、私有属性和私有方法

1、定义私有属性和私有方法
在python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或方法不继承给子类

如果某些属性或方法不想继承给子类,就将这些属性及方法设置为私有属性,方法

小明把技术传承给徒弟的同时,不想把自己的钱传承给徒弟,这个时候就要为钱这个实例属性设置私有权限

设置私有权限的方法:在属性名和方法名前面加上两个下划线_ _

class Master(object):def __init__(self):self.kongfu='[古法煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")
class School(Master):def __init__(self):self.kongfu='[黑马煎饼果子配方]'def make_cake(self):print(f"运用{self.kongfu}制作煎饼果子")class Prentice(School,Master):def __init__(self):self.kongfu='[独创煎饼果子配方]'#私有属性self.__money=2000def __info_print(self):print("这是私有方法")class Tunsun(Prentice):pass
xiaoqiu=Tunsun()
#print(xiaoqiu.__money) #私有属性也无法访问
xiaoqiu.__info_print()

结果为:
在这里插入图片描述
2、获取和修改私有属性值

注意:私有属性和私有方法只能在类里面访问和修改
在python中,一般定义函数名get_xx用来获取私有属性值,定义set_xx用来修改私有属性值

部分代码如下:

class Prentice(School,Master):def __init__(self):self.kongfu='[独创煎饼果子配方]'#私有属性self.__money=2000#定义函数,获取私有属性值def get_money(self):return self.__money#定义函数,修改私有属性值def set_money(self):self.__money=500def __info_print(self):print("这是私有方法")
class Tunsun(Prentice):pass
xiaoqiu=Tunsun()
print(xiaoqiu.get_money())
xiaoqiu.set_money()
print(xiaoqiu.get_money())
结果为:
2000
500

三、面向对象-其他

1、面向对象三大特性

1、封装

将属性和方法书写到类的里面的操作即为封装
封装可以为属性和方法添加私有权限

2、继承

子类默认继承父类的所有属性和方法
子类可以重写父类属性和方法,拥有自己的属性和方法

3、多态

传入不同的对象,产生不同的结果

了解多态

多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)
好处:不同的子类对象调用相同的父类方法,调用灵活,有了多态,更容易编写出通用的编程,以适应需求的不断变化

实现步骤:

1、定义父类,提供公共方法
2、定义子类,重写父类方法
3、传递子类对象给调用者,可以看到不同子类执行效果不同

体验多态
需求:警务人员和警犬一起工作,警犬分两种:追击敌人和追击毒品,携带不同的警犬,执行不同的工作

class Dog(object):#父类提供唯一的方法,哪怕是空方法def work(self):print("指哪打哪")
class ArmyDog(Dog):def work(self):print("追击敌人")
class DrugDog(Dog):def work(self):print("追击毒品")
class Person(object):def work_with_dog(self,dog):dog.work()ad=ArmyDog()
dd=DrugDog()
daqiu=Person()
daqiu.work_with_dog(dd)

2、类属性和实例属性

类属性

类属性就是类对象所拥有的属性,它被该类的所有实例对象所共有
类属性可以使用类对象实例对象访问

#定义类,定义类属性
class Dog(object):tooth=10
#创建对象
wangcai=Dog()
xiaohei=Dog()
#访问类属性:类和对象分别访问
print(Dog.tooth)
print(xiaohei.tooth)

类属性的优点:

记录的某项数据始终保持一致时,则定义类属性
实例属性要求每个对象为其单独开辟一份内存空间来记录数据,而属性为全类所共有,仅占用一份内存,更加节省内存空间

修改类属性
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性

#定义类,定义类属性
class Dog(object):tooth=10
#创建对象
wangcai=Dog()
xiaohei=Dog()
#修改类属性,通过类
Dog.tooth=12
print(Dog.tooth)
print(xiaohei.tooth)
结果为:12   12#测试通过对象修改类属性
wangcai.tooth=13
print(Dog.tooth)
print(wangcai.tooth)
print(xiaohei.tooth)
结果为:
10
13
10

3、类方法和静态方法

类方法
类方法特点

需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数

类方法使用场景

当方法中,需要使用类对象(如访问私有类属性等)时,定义类方法
类方法一般和类属性配合使用

#定义类,私有类属性,类方法获取这个私有类属性
class Dog(object):__tooth=10#定义类方法@classmethoddef get_tooth(cls):return cls.__tooth
wangcai=Dog()
result=wangcai.get_tooth()
print(result)

静态方法
静态方法特点

需要通过装饰器@staticmethod来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)
静态方法也能够通过实例对象和类对象去访问

静态方法使用场景

当方法中既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象(如类属性,类方法,创建实例等)时,定义静态方法
取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗

#定义类,定义静态方法
class Dog(object):@staticmethoddef info_print():print("这是一个静态方法")
#创建对象
wangcai=Dog()
#调用静态方法:类和对象都可以调用
wangcai.info_print()
Dog.info_print()

四、异常

1、了解异常

异常就是我们python编程中运行代码之后遇到的错误

异常的写法

try:可能发生错误的代码
except:如果出现异常执行的代码

体验案例
需求:尝试以r模式打开文件,如果文件不存在,则以w方式打开

try:f=open("test.txt","r")
except:f=open("test.txt","w")

了解异常类型
冒号前面的就是异常类型,冒号后面的就是异常描述信息
在这里插入图片描述

2、捕获异常

捕获指定异常

语法

try:可能发生错误的代码
except 异常类型:如果捕获到该异常类型执行的代码

代码体验
尝试打印num,捕获异常类型为NameError,如果捕获到这个异常类型,执行打印:有错误

try:print(num)
except NameError:print("有错误")

结果为:
在这里插入图片描述
如果异常类型不正确

try:print(1/0)
except NameError:print("有错误")

结果为:
在这里插入图片描述
注意:

1、如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
2、一般try下方只放一行尝试执行的代码

捕获多个指定异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except后,并使用元组的方式进行书写

使用场景

当尝试执行某个代码,并不确定代码的异常类型具体是哪一个,但大概知道是哪几个异常类型

体验:

try:print(1/0)
except (NameError,ZeroDivisionError):print("有错误")
结果为:
有错误

捕获异常描述信息

异常描述信息包含了具体错误信息,可以帮助我们去定位错误

try:print(num)
except (NameError,ZeroDivisionError) as result:print(result)

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

捕获所有异常

以上我们写的代码会发现,还要意识到是哪一个异常类型,如果我们记不清楚是哪一个异常类型怎么办呢,就出现了捕获所有异常
Exception是所有程序异常类的父类

try:print(num)
except Exception as result:print(result)
结果就是异常描述信息

3、异常的else

else表示的是如果没有异常要执行的代码

try:print(1)
except Exception as result:print(result)
else:print("我是else,当没有异常的时候,执行的代码")

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

4、异常finally

finally表示的是无论是否异常都要执行的代码,例如关闭文件

尝试以r打开一个文件,如果有异常,就用w打开文件,最后关闭文件

try:f=open("1.txt","r")
except Exception as result:f=open("1.txt","w")
else:print("没有异常,真开心")
finally:f.close()
结果就会创建一个新文件1.txt

5、异常的传递

需求:

1、尝试只读方式打开test.txt文件,如果文件存在则读取文件内容,文件不存在则提示用户即可
2、读取内容要求:尝试循环读取内容,读取过程中如果检测到用户意外终止程序,则except捕获异常并提示用户

import time
try:f=open("test.txt")#尝试循环读取内容try:while True:content=f.readline()if len(content)==0:breaktime.sleep(2)print(content)except:#命令提示符如果按下了ctrl+c,就表示终止结束print("程序被意外终止")finally:f.close()print("关闭文件")
except:print("该文件不存在")

6、自定义异常

自定义异常就是用来报错,报的是不符合程序逻辑要求的错误
在python中,抛出自定义异常的语法为raise异常类对象

基本语法:

1、自定义异常类
calss 异常类类名(Exception):代码#设置抛出异常的描述信息def __str__(self):return ...
2、抛出异常
raise 异常类名()
3、捕获异常
except Exception as result ...

需求:密码长度不足,则异常报错(用户输入密码,如果输入的长度不足3位,则报错,即抛出自定义异常,并捕获该异常)

#自定义异常类,继承Exception
class ShortInputError(Exception):def __init__(self,length,min_len):self.length=lengthself.min_len=min_len#设置抛出异常的描述信息def __str__(self):return f"你输入的长度是{self.length},密码长度不能少于{self.min_len}个字符"def main():#抛出异常,尝试执行,用户输入密码,如果长度小于3,就抛出异常try:passwd=input("请输入密码:")if len(passwd)<3:#raise为抛出异常类对象,抛出异常类创建的对象raise ShortInputError(len(passwd),3)   相当于print对象(),就打印出str的内容#捕获该异常except Exception as result:print(result)else:print("密码已经输入完成")
main()

输入错误,结果为:
在这里插入图片描述
输入正确的情况是:
在这里插入图片描述

五、模块和包

1、了解模块

python模块(Module),是一个python文件,以.py结尾,包含了python对象定义和python语句
模块能定义函数,类和变量,模块里也能包含可执行的代码

下图就是我们平常使用的random模块
在这里插入图片描述

2、导入模块

2.1 导入模块的方式

  • import 模块名
  • from 模块名 import 功能名
  • from 模块名 import *
  • import 模块名 as 别名
  • from 模块名 import 功能名 as 别名

2.2 导入方式详解
2.2.1 、import
语法:

#1、导入模块
import 模块名
import 模块名1,模块名2...#2、调用功能
模块名.功能名()

需求:基于math模块下的aqrt(),用于开平方计算

import math  #导入模块
print(math.sqrt(9))  #调用sqrt功能
结果为:3.0

2.2.2 、from…import…

语法:from 模块名 import 功能1,功能2,功能3

from math import sqrt
print(sqrt(16))
结果为:4.0

2.2.3 、from…import *

from math import *
print(sqrt(81))
结果为:9.0

2.2.4、as 定义别名
语法与体验

#1、模块定义别名
import 模块名 as 别名
import time as tt
tt.sleep(2)
print("hello")#2、功能定义别名
from 模块名 import 功能 as 别名
from time import sleep as sl
sl(2)
print("hello")

3、制作模块

在python中,每个python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则

自己制作模块的作用:当python中的模块已经无法满足我们的要求,我们需要频繁使用包含类,函数,变量的代码,不需要频繁的粘贴,只需要做成模块,在需要的地方导入即可,解决了代码冗余。
3.1 定义模块
新建一个python文件,命名为my_module1.py,并定义testA函数
需求:一个函数完成任意两个数字的加法运算

def testA(a,b):print(a+b)

3.2 测试模块
在实际开发中,开发人员会自行在py文件中添加一些测试信息,为了让模块能够在项目中达到想要的效果
测试信息要保留,但是如果调用模块文件,测试信息就会被导入在正式结果里,解决方案如下:

def testA(a,b):print(a+b)
#当前文件print(__name__)的值为__main__,
#如果在其他导入模块的文件里,print(__name__)的值就是导入的模块名,所以我们用此来做区别
#只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行testA函数调用
if __name__=="__main__":testA(1,9)

注意:_ name_是系统变量,是模块的标识符,如果是自身模块,值是__main_,否则,是当前模块的名字

验证结果如下:
在这里插入图片描述
导入模块,就会导入模块文件里所有的代码
在这里插入图片描述
3.3 调用模块

import my_module1
my_module1.testA(1,3)
结果为:4

4、模块定位顺序

当导入一个模块,python解析器对模块位置的搜索顺序是:

  • 当前目录
  • 如果不在当前目录,python则搜索在shell变量PYTHONPATH下的每个目录
  • 如果都找不到,Python会查看默认路径,unix下,默认路径一般为/usr/local/lib/python

注意:

  • 自己的文件名不要和已有模块名重复,否则导致模块功能无法使用
  • 使用from模块名import功能的时候,如果功能名字重复,调用到的是最后定义或导入的功能

5、_ all_

如果一个模块文件中有_all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素
my_module1模块代码

#定义多个功能,将某个功能添加到_all_里
__all__=["testA"]
def testA():print("testA")
def testB():print("testB")

导入模块的文件代码

from my_module1 import *
testA()
testB()

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

5、包的使用

5.1 了解包

包将所有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为_init_.py文件,那么这个文件夹就称之为包

5.2 制作包

[New]-[Python Package]-输入包名-[OK]-新建功能模块(有联系的模块)

注意:新建包后,包内部会自动创建_init_.py文件,这个文件控制着包的导入行为,如下图
在这里插入图片描述

快速体验:

1.新建包mypackage
2.新建包内模块:my_module1和my_module2
3.模块内代码如下

#my_module1
print(1)
def ingo_print1():print("my_module1")#my_module2
print(2)
def info_print2():print("my_module2"

5.3 导入包

方法一:

import 包名.模块名
包名.模块名.目标

代码如下:

#导入mypackage包下的模块1,使用这个模块内的info_print1函数
import mypackage.my_module1
mypackage.my_module1.info_print1()

方法二:

from 包名 import *
模块名.目标

注意:必须在_init_.py文件中添加_all_=[],控制允许导入的模块列表

代码如下:

from mypackage import *
my_module2.info_print2()_init_.py里的内容如下:
__all__=["my_module2"]
结果为:
2
my_module2

六、面向对象版学员管理系统

1、系统需求

使用面向对象编程思想,完成学员管理系统的开发,具体如下:

系统要求:学员数据存储在文件中
系统功能:添加,删除学员,修改,查询学员信息,显示所有学员信息,保存学员信息及退出系统等功能

2、准备程序文件

2、1 角色分析
1、学员
2、管理系统

工作中注意:
1、为了方便代码维护,一般一个角色一个程序文件
2、项目要有主程序入口,习惯为main.py

2、2 创建程序文件
创建项目目录,例如:StudentManagerSystem

程序文件如下
程序入口文件:main.py
学员文件:student.py
管理系统文件:managerSystem.py
在这里插入图片描述

3、书写程序

3.1 定义学员类-student.py
需求:

学员信息包含:姓名,性别,手机号
添加_str_魔法方法,方便查看学员对象信息

代码如下

class Student(object):def __init__(self,name,gender,tel):self.name=nameself.gender=genderself.tel=teldef __str__(self):return f"该学员的姓名为{self.name},性别为{self.gender},电话号码是{self.tel}"

3.2 定义管理系统类-managerSystem.py
需求:

存储数据的位置:文件(student.data)
加载文件数据
修改数据后保存到文件
存储数据的形式:列表存储学员信息
**系统功能:**添加学员,删除学员,修改学员,查询学员信息,显示所有学员信息,保存学员信息

需求:系统功能循环使用,用户输入不同的功能序号,执行不同的功能

保存学员信息:将修改后的学员数据保存到存储数据的文件里
步骤
打开文件;文件写入数据;关闭文件
文件内数据要求的数据类型是什么?应该为字符串

拓展:_ dict_

收集类对象或实例对象的属性和方法,以及对应的值,从而返回一个字典

代码如下:

from student import *
class StudentManager(object):def __init__(self):#存储学员数据-->列表self.student_list=[]#一、程序入口函数def run(self):#1、加载文件里面的学员数据self.load_student()while True:#2、显示功能菜单self.show_menu()#3、用户输入功能序号menu_num=int(input("请输入您需要的功能序号"))#4、根据用户输入的序号执行不同的功能if menu_num==1:#添加学员self.add_student()elif menu_num==2:#删除学员self.del_student()elif menu_num==3:#修改学员信息self.modify_student()elif menu_num==4:#查询学员信息self.search_student()elif menu_num==5:#显示所有学员信息self.show_student()elif menu_num==6:#保存学员信息self.save_student()elif menu_num==7:#退出系统break#二、系统功能函数#1、显示功能菜单-->打印序号和功能对应关系--->静态方法@staticmethoddef show_menu():print("请选择如下功能:")print("1:添加学员")print("2:删除学员")print("3:修改学员信息")print("4:查询学员信息")print("5:显示所有学员信息")print("6:保存学员信息")print("7:退出系统")#2、添加学员def add_student(self):#1、让用户输入姓名,性别,手机号name = input("请输入您的姓名")gender = input("请输入您的性别")tel = input("请输入您的手机号")#2、创建学员对象--->类,类在student.py里-->先导入student模块,再创建对象student=Student(name,gender,tel)#3、将该对象添加到学员列表里self.student_list.append(student)print(self.student_list)print(student)#3、删除学员def del_student(self):del_name=input("请输入要删除的学员姓名")for i in self.student_list:if del_name==i.name:self.student_list.remove(i)breakelse:print("查无此人")print(self.student_list)#4、修改学员信息def modify_student(self):modify_name=input("请输入要修改的学员姓名")for i in self.student_list:if i.name==modify_name:i.name=input("请修改学员姓名")i.gender=input("请修改学员性别")i.tel=input("请修改的手机号")print(f"修改学员信息成功,姓名:{i.name},性别{i.gender},手机号{i.tel}")breakelse:print("查无此人")#5、查询学员信息def search_student(self):search_name=input("请输入要查询的学员姓名")for i in self.student_list:if i.name==search_name:print(f"学员的姓名为{i.name},性别为{i.gender},手机号为{i.tel}")breakelse:print("查无此人")#6、显示所有学员信息def show_student(self):print("姓名\t性别\t电话")for i in self.student_list:print(f"{i.name}\t{i.gender}\t{i.tel}")#7、保存学员信息def save_student(self):#1、打开文件f=open("student.data","w")#2、文件写入学员数据#注意:文件写入的数据不能是学员对象的内存地址,需要把学员数据转换为列表字典数据再做存储#学员对象的列表转换为字典new_list=[i.__dict__ for i in self.student_list]print(new_list)#注意:文件内数据要求为字符串类型,故需要先转换数据类型f.write(str(new_list))#关闭文件f.close()#8、加载学员信息def load_student(self):#尝试以"r"模式打开数据文件,文件不存在就提示用户;文件存在(没有异常)则读取数据try:f=open("student.data","r")except:f=open("student.data","w")else:#读取数据data=f.read()#文件中读取的数据都是字符串且字符串为字典数据,故需要转换数据类型再转换字典为对象后存储到学员列表里new_list=eval(data)self.student_list=[Student(i["name"],i["gender"],i["tel"]) for i in new_list]finally:#关闭文件f.close()

3.3 程序入口文件-main.py

入口文件就是用户登录系统,需要run运行代码的文件

#导入managerSystem模块
from managerSystem import *#启动学员管理系统
#保证是当前文件运行才能启动管理系统,创建对象并调用run方法
if __name__=="__main__":student_manager=StudentManager()student_manager.run()

总结:
此次代码用到的python知识如下:

在这里插入图片描述


http://www.ppmy.cn/news/886311.html

相关文章

如何开发一个软件

一、软件开发流程 1. 需求分析 主要有两个文档&#xff0c;一个需求规格说明书和一个产品原型图 2. 设计 UI设计、数据库设计、接口设计 3. 编码 项目代码编写、单元测试 4. 测试 测试用例、测试报告 5. 上线运维 软件环境安装、配置 二、角色分工 项目经理 对整个…

个人Scratch程序合集 第二版 主页

个人Scratch程序合集 第二版 主页 本程序为本人的转换为HTML的Scratch程序制作的第二个主页。改用了响应式图片廊文字说明的形式&#xff0c;对不同尺寸的页面适配较好&#xff0c;但在一些分辨率上右侧空白区域过大。由于通常只有文字说明行数相同的图片才能并排&#xff0c;本…

计算机一级之WORD

1.设置阴影效果&#xff0c;发光效果&#xff0c;在开始界面 2.主题色和个性色表达一样 3.渐变也在开始界面 4.页面纸张大小在布局设置&#xff0c;页边距设置&#xff0c;在对话框具体设置页边距 5.设置页码格式&#xff0c;页码格式主要考核编号格式 6.页面填充颜色&…

wps带阴影的边框怎么设置_wps如何添加阴影边框-wps设置阴影边框的方法 - 河东软件园...

WPS是一款非常专业的办公软件&#xff0c;它包括PPT、word、Excel等组件。在使用Wps软件时&#xff0c;为了让文本看起来更加好看一些&#xff0c;我们经常要在其中插入图片并添加一些效果。比如为了表现图片的立体感时&#xff0c;可以添加阴影效果&#xff1b;如果为了保持图…

【宝藏系列】如何取消LaTeX插入图片时边框出现虚线阴影?

&#x1f496;作者简介&#xff1a;大家好&#xff0c;我是车神哥&#xff0c;府学路18号的车神&#x1f947; ⚡About—>车神&#xff1a;从寝室到实验室最快3分钟&#xff0c;最慢3分半&#xff08;半分钟献给红绿灯&#xff09; &#x1f4dd;个人主页&#xff1a;车手只…

文档图片阴影去除

文章目录 一、前言二、通过 Gamma 校正来去除阴影 (旧方法)2.1 原理2.2 C 代码2.3 运行结果对比图 三、通过自适应阈值化来去除阴影 (新方法)3.1 原理3.2 代码3.3 运行结果对比图 四、新旧方法对比图五、BEDSR-Net 去除阴影 (模型) 一、前言 在 OCR 的预处理中需要对文档图片中…

div 边框阴影

div边框加阴影效果,求高手帮忙~ 浏览次数&#xff1a;60次悬赏分&#xff1a;0 | 解决时间&#xff1a;2011-8-10 15:39 | 提问者&#xff1a;zmjailwy 在css样式里建了.mydiv{ width:500px;height:auto;border:#909090 1px solid;background:#fff;color:#333; filter:progi…

WEB前端代码:边框阴影、边框图片、背景样式、文本样式、字体样式

1、边框阴影 box-shadow:5px 10px 20px #000; 1)5px 相对于原div的左上角的x偏移 2)10px 相对于原div的左上角的y偏移 3)20px 在偏移的基础上进行模糊处理 4)#000 阴影div的颜色 .div1{margin:100px;width:256px;height:256px;background: #888;box-shadow:15px 15px 30px #00…