Python面向对象编程(2)
一、理解面向对象
面向对象是一种抽象化的编程思想
面向对象就是将编程当成是一个事物,对于外界来说,事物是直接可以使用的,不用去管他的内部的情况。而编程就是设置事物能够做什么事。
二、类和对象
类和对象的关系:用类去创建一个对象/用类实例化一个对象
类
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物
- 特征即是属性
- 行为即是方法
类比如是制造洗衣机时要用的图纸,也就是说类是用来创建对象
对象
对象是类创建出来的真实存在的事物
注意:开发中,先有类,再有对象
面向对象实现方法
定义类
-
语法:
class 类名(): 代码 ......
注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯
创建对象
-
语法:
-
对象名 = 类名()
体验
# 需求: 洗衣机,功能:能洗衣服
# 1. 定义洗衣机类
class Washer():
def wash(self):
print('能洗衣服')
# 2. 创建对象
haier = Washer()
# 3. 验证成果
# 打印haier对象
print(haier)
# 使用wash功能 实例方法/对象方法 对象名.Wash()
haier.wash()
self
self指的是调用该函数的对象
# 1. 定义洗衣机类
class Washer():
def wash(self):
print('我会洗衣服')
# <__main__.Washer object at 0x0000021F4AED8948>
print(self)
# 2. 创建对象
haier = Washer()
# <__main__.Washer object at 0x0000021F4AED8948>
print(haier)
haier.wash()
一个类创建多个对象
# 1. 定义洗衣机类
class Washer():
def wash(self):
print('我会洗衣服')
# <__main__.Washer object at 0x0000021F4AED8948>
print(self)
# 2. 创建对象
haier1 = Washer()
haier2 = Washer()
haier1.wash()
haier2.wash()
# 我会洗衣服
# <__main__.Washer object at 0x0000012AFB2BA788>
# 我会洗衣服
# <__main__.Washer object at 0x0000012AFE70CBC8>
三、添加和获取对象属性
对象属性既可以在外面添加和获取,也能在类里面添加和获取
类外面添加对象属性
-
语法:
对象名.属性名 = 值
-
体验
haier1.width = 500 haier1.height = 800
类外面获取对象属性
-
语法:
对象名.属性名
-
体验
print(f'haier1的宽度是{harer1.width}') print(f'haier1的宽度是{harer1.height}')
类里面获取对象属性
-
语法:
-
self.属性名
-
体验
class Washer(): def wash(self): print('洗衣服') def print_info(self): print(f'宽度{self.width}') print(f'高度{self.height}') # 2. 创建对象 haier1 = Washer() haier1.width = 500 haier1.height = 800 # 对象调用实例方法 haier1.print_info() # 宽度500 # 高度800
四、魔法方法
在Python中,____xx()的函数叫做魔法方法,指的是具有特殊功能的函数
____init() 方法的作用:初始化对象
class Washer():
# 定义__init__,添加实例属性
def __init__(self):
self.width = 500
self.height = 800
def print_info(self):
print(f'{self.height},{self.width}')
haier1 = Washer()
haier1.print_info()
# 800,500
注意:
- ____init()方法,在创建一个对象时默认被调用,不需要手动调用
- ____init(self)中的self,不需要开发中传递,Python解释器会自动吧当前的对象引用传递过去
带参数的______init__()
一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性:传参数
class Washer():
# 定义__init__,添加实例属性
def __init__(self, width, height):
self.width = width
self.height = height
def print_info(self):
print(f'{self.width},{self.height}')
haier1 = Washer(10, 20)
haier1.print_info()
# 10,20
haier2 = Washer(30, 40)
haier2.print_info()
# 30,40
____str()
当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了______str__()方法,那么就会打印从在这个方法中return的数据。
class Washer():
# 定义__init__,添加实例属性
def __init__(self, width, height):
self.width = width
self.height = height
def __str__(self):
return '这是说明书'
def print_info(self):
print(f'{self.width},{self.height}')
haier1 = Washer(10, 20)
haier1.print_info()
print(haier1)
# 10,20
# 这是说明书
____del()
当删除对象时,python解释器也会默认调用______del__()方法。
class Washer():
def __init__(self, width, height):
self.width = width
self.height = height
def __del__(self):
print(f'{self}对象已经被删除')
haier1 = Washer(10, 20)
# <__main__.Washer object at 0x0000026118223278>对象已经被删除
del haier1
五、应用-烤地瓜
# 定义类:
# 地瓜的属性: 备考的时间,地瓜的状态,添加的调料
# 地瓜的方法: 备考 用户根据意愿设定每次烤地瓜的时间 判断地瓜被烤的总时间是在哪个区间,修改地瓜状态
# 添加调料 用户根据意愿设定添加的调料 将用户添加的调料存储
# 显示对象信息
# 1.定义类: 初始化属性、被烤和添加调料的方法、显示对象信息的str
class SweetPotato():
def __init__(self):
self.cook_time = 0
self.cook_static = '生的'
self.condiments = []
def cook(self, time):
self.cook_time += time
if 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, x):
self.condiments.append(x)
def __str__(self):
return f"这个地瓜烤了{self.cook_time}分钟,状态是{self.cook_static},添加的调料有:{' '.join(self.condiments)}"
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
digua1.add_condiments('辣椒')
digua1.cook(5)
print(digua1)
# 这个地瓜烤了0分钟,状态是生的,添加的调料有:
# 这个地瓜烤了7分钟,状态是熟了,添加的调料有:辣椒
六、应用-搬家具
# 将小于房子剩余面积的家具摆放到房子中
# 需求涉及两个事物: 房子和家具,故被案例涉及两个类: 房子类和家具类
# 房子类: 实例属性:房子地理位置,房子占地面积,房子剩余面积,房子内家具列表 实例方法:容纳家具 显示房屋信息
# 家具类: 家具名称,家具占地面积
class Furniture():
def __init__(self, name, area):
self.name = name
self.area = area
class Home():
def __init__(self, address, area):
self.address = address
self.area = area
self.free_area = area
self.furniture = []
def __str__(self):
return f'房子地理位置在{self.address},房屋面积是{self.area}, 剩余面积{self.free_area}, 家具有{self.furniture}'
def add_furniture(self, item):
if self.free_area >= item.area:
self.free_area -= item.area
self.furniture.append(item.name)
else:
print('家具太大,剩余面积不足,无法容纳')
bed = Furniture('板凳', 20)
sofa = Furniture('沙发', 100)
jia = Home('天水', 1000)
print(jia)
jia.add_furniture(bed)
print(jia)
jia.add_furniture(sofa)
print(jia)
# 房子地理位置在天水,房屋面积是1000, 剩余面积1000, 家具有[]
# 房子地理位置在天水,房屋面积是1000, 剩余面积980, 家具有['板凳']
# 房子地理位置在天水,房屋面积是1000, 剩余面积880, 家具有['板凳', '沙发']
七、继承
-
拓展1:经典类或旧式类
不由任意内置类型派生出的类,称之为经典类
class 类名: 代码 ......
-
拓展2:新式类
class 类名(object): 代码
继承的概念
Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和方法
# 父类
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
# 子类B
class B(A):
pass
result = B()
result.info_print()
# 1
单继承
class Master(object):
def __init__(self):
self.kongfu = '古法煎饼果子配方'
def make_cake(self):
print(f'运用{self.kongfu}制作煎饼果子')
class Prentice(Master):
pass
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
多继承
多继承就是一个类同时继承了多个父类
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):
pass
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
# 私有煎饼果子配方
# 运用私有煎饼果子配方制作煎饼果子
子类重写父类的同名属性和方法
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}制作煎饼果子')
daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()
# 独创煎饼果子配方
# 运用独创煎饼果子配方制作煎饼果子
- 拓展 ____mro 查看继承关系
类名.__mro__
# (<class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>,
#<class 'object'>)
子类调用父类的同名属性和方法
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):
# 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
self.__init__()
print(f'运用{self.kongfu}制作煎饼果子')
#调用父类方法,但是为保证调用到的也是父类的属性,必须在调用父类的初始化
def make_master_cake(self):
Master.__init__(self)
Master.__init__(self)
def make_school_cake(self):
School.__init__(self)
School.__init__(self)
daqiu = Prentice()
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()
daqiu.make_cake()
# 运用独创煎饼果子配方制作煎饼果子
# 运用古法煎饼果子配方制作煎饼果子
# 运用私有煎饼果子配方制作煎饼果子
# 运用独创煎饼果子配方制作煎饼果子
多层继承
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):
self.__init__()
print(f'运用{self.kongfu}制作煎饼果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
xiaoqiu.make_cake()
xiaoqiu.make_master_cake()
xiaoqiu.make_school_cake()
# 运用独创煎饼果子配方制作煎饼果子
# 运用古法煎饼果子配方制作煎饼果子
# 运用私有煎饼果子配方制作煎饼果子
super()
-
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}制作煎饼果子')
# 有参数
# super(School, self).__init__()
# super(School, self).make_cake()
# 无参数
super().__init__()
super().make_cake()
class Prentice(School):
def __init__(self):
self.kongfu = '独创煎饼果子配方'
def make_cake(self):
self.__init__()
print(f'运用{self.kongfu}制作煎饼果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
def make_old_cake(self):
# 方法一:如果定义的类名修改,这里也要修改, 代码量庞大,冗余
# School.__init__(self)
# School.make_cake(self)
# Master.__init__(self)
# Master.make_cake(self)
# 方法二:super()
# 方法2.1 super(当前类名, self).函数()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2: super().函数()
super().__init__()
super().make_cake()
daqiu = Prentice()
daqiu.make_old_cake()
# 运用私有煎饼果子配方制作煎饼果子
# 运用古法煎饼果子配方制作煎饼果子
私有属性和私有方法
在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}制作煎饼果子')
# 有参数
# super(School, self).__init__()
# super(School, self).make_cake()
# 无参数
super().__init__()
super().make_cake()
class Prentice(School):
def __init__(self):
self.kongfu = '独创煎饼果子配方'
# 定义私有属性
self.__money = 200000
def make_cake(self):
self.__init__()
print(f'运用{self.kongfu}制作煎饼果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
def make_old_cake(self):
# 方法一:如果定义的类名修改,这里也要修改, 代码量庞大,冗余
# School.__init__(self)
# School.make_cake(self)
# Master.__init__(self)
# Master.make_cake(self)
# 方法二:super()
# 方法2.1 super(当前类名, self).函数()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2: super().函数()
super().__init__()
super().make_cake()
# 定义私有方法
def __info_print(self):
print('这是私有方法')
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
xiaoqiu.make_old_cake()
获取和修改私有属性值
在Python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值
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}制作煎饼果子')
# 有参数
# super(School, self).__init__()
# super(School, self).make_cake()
# 无参数
super().__init__()
super().make_cake()
class Prentice(School):
def __init__(self):
self.kongfu = '独创煎饼果子配方'
# 定义私有属性
self.__money = 200000
def make_cake(self):
self.__init__()
print(f'运用{self.kongfu}制作煎饼果子')
def make_master_cake(self):
Master.__init__(self)
Master.make_cake(self)
def make_school_cake(self):
School.__init__(self)
School.make_cake(self)
def make_old_cake(self):
# 方法一:如果定义的类名修改,这里也要修改, 代码量庞大,冗余
# School.__init__(self)
# School.make_cake(self)
# Master.__init__(self)
# Master.make_cake(self)
# 方法二:super()
# 方法2.1 super(当前类名, self).函数()
# super(Prentice, self).__init__()
# super(Prentice, self).make_cake()
# 方法2.2: super().函数()
super().__init__()
super().make_cake()
# 定义私有方法
def __info_print(self):
print('这是私有方法')
# 定义函数:获取私有属性值 get_xx
def get_money(self):
return self.__money
# 定义函数: 修改私有属性值 set_xx
def set_money(self):
self.__money = 5000
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
print(xiaoqiu.get_money())
xiaoqiu.set_money()
print(xiaoqiu.get_money())
# 2000000
# 5000
八、多态 类方法 类属性
面向对象的三大特性
封装
- 将属性和方法书写到类里面的操作即为封装
- 封装可以为属性和方法添加私有权限
继承
- 子类默认继承父类的所有属性和方法
- 子类可以重写父类属性和方法
多态
- 传入不同的对象,产生不同的结果
多态
了解多态
多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)
- 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
- 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
- 实现步骤:
- 定义父类,并提供公共方法
- 定义子类,并重写父类的方法
- 传递子类对象给调用者,可以看到不同子类执行效果不同
体验多态
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(ad)
daqiu.work_with_dog(dd)
# 追击敌人
# 追查毒品
类属性和实例属性
设置和访问类属性
- 类属性就是 类对象 所拥有的属性,他被 该类的所有实例对象 所共有
- 类属性可以使用 类对象 或 实例对象 访问
class Dog(object):
tooth = 10
wangcai = Dog()
xiaohei = Dog()
print(Dog.tooth) # 10
print(wangcai.tooth) # 10
print(xiaohei.tooth) # 10
类属性的优点:
- 记录的某项数据始终保持一致,则定义类属性
- 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有,仅占一份内存,更加节省内存空间
修改类属性
类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性
class Dog(object):
tooth = 10
wangcai = Dog()
xiaohei = Dog()
# 通过类修改类属性 类.类属性 = 值
Dog.tooth = 20
print(Dog.tooth) # 20
print(wangcai.tooth) # 20
print(xiaohei.tooth) # 20
# 通过对象修改属性, 创建了一个实例属性
wangcai.tooth = 200
print(Dog.tooth) # 10
print(wangcai.tooth) # 200
print(xiaohei.tooth) # 10
类方法和静态方法
类方法
-
类方法的特点:
需要用装饰器 @classmenthod 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以 cls 作为第一个参数
-
使用场景
当类方法中 需要使用类对象(如访问私有类属性等)时,定义类方法
类方法一般和类属性配合使用
class Dog(object):
__tooth = 10
@classmethod
def get_tooth(cls):
return cls.__tooth
wangcai = Dog()
result = wangcai.get_tooth()
print(result) # 10
静态方法
-
静态方法特点
需要通过装饰器@staticmethod 来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls).
静态方法 也能够通过 实例对象和类对象去访问
-
使用场景
当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象(如类方法、类属性、创建实例等)时,定义静态方法
取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗
class Dog(object):
@staticmethod
def info_print():
print('这是一个狗类,用于创建实例')
wangcai = Dog()
wangcai.info_print()
# 这是一个狗类,用于创建实例
九、异常
了解异常
当检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”
异常的写法
try:
可能发生错误的代码
except:
如果出现异常执行的代码
捕获异常
体验
try:
print(num)
except:
print("有错误")
捕获指定异常
try:
可能发生错误的代码
except 异常类型:
如果出现异常执行的代码
try:
print(num)
except NameError:
print("有错误")
如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
一般try下放只放一行尝试执行的代码
捕获多个指定异常
当捕获多个异常时,可以把要捕获的异常类型的名字,放在except后,并使用元组的方式进行书写
try:
print(1/0)
except (NameError, ZeroDivisionError):
print("有错误")
捕获异常描述信息
try:
print(1/0)
except (NameError, ZeroDivisionError) as result:
print(result)
捕获所有异常
try:
print(num)
except Exception as result:
print(result)
异常的else
else 表示的是如果没有异常要执行的代码
try:
print(1)
except Exception as result:
print(result)
else:
print('我是else,是没有异常的时候执行的代码')
异常finally
finally表示的是无论是否异常都要执行的代码,例如关闭文件
try:
f = open('test.txt', 'r')
except Exception as result:
f = open('text.txt', 'w')
else:
print('没有异常,真开心')
finally:
f.close()
异常的传递
体验异常传递
需求:
- 尝试只读方式打开test.txt文件,如果文件存在则读取文件的内容,文件不存在则提示用户即可
- 读取内容要求:尝试循环读取内容,读取过程中如果检测到用户意外终止程序,则except捕获异常并提示用户
try:
f = open('test.txt', 'r')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(3)
print(content)
except:
# 如果在读取文件过程中,产生了异常,那么就会捕获到
# 比如 按下了 ctrl+c
print('意外终止了读取数据')
finally:
f.close()
print('关闭文件')
except:
print('该文件不存在')
自定义异常
在Python中,抛出自定义异常的语法为raise异常类对象
需求:密码长度不足,则报异常(用户输入密码,如果输入的长度不足3位,则报错,即抛出自定义异常,并捕获该异常)
# 自定义异常类,继承Exception
class ShortInputError(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 main():
try:
con = input('请输入密码:')
if len(con) < 3:
raise ShortInputError(len(con), 3)
except Except as result:
print(result)
else:
print('密码已经输入完成')
main()
十、模块和包
了解模块
Python模块(Module),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句。
模块能定义函数,类和变量,模块里也能包含可执行的代码
导入模块
- import 模块名
- from 模块名 import 功能名
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
导入模块
import
# 导入模块
import 模块名
import 模块名1,模块名2...
# 调用功能
模块名.功能名()
from … import…
from 模块名 import 功能1, 功能2, 功能3...
from … import *
from 模块名 import *
as定义别名
# 模块定义别名
import 模块名 as 别名
# 功能定义别名
from 模块名 import 功能 as 别名
制作模块
在Python中,每个Python文件都可以作为一个模快,模块的名字就是文件的名字。也就是自定义模块名必须要符合标识符命名规则
定义模块
新建一个Python文件,命名为my_model.py,并定义testA函数
def testA(a, b):
print(a + b)
测试模块
在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如,在my_model.py文件中添加测试代码
def testA(a, b):
print(a + b)
# 只有当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行testA函数调用
if __name__ == '__main__':
testA(1,1)
调用模块
import my_model
模块的定位顺序
当导入一个模块,Python解释器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录
- 如果都找不到,Python会查看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录
注意:
- 自己的文件名不要和已有模块名重复,否则导致模块功能无法使用
- 使用from 模块名 import 功能 的时候,如果功能名字重复,调用到的是最后定义或导入的功能
名字重复
import time 模块名 ,功能名字重复问题,在Python中数据是通过引用传递的
____all
如果一个模块文件中有______all__变量,当使用 form xxx import * 导入时,只能导入这个列表中的元素
my_model模块代码
__all__ = ['testA']
def testA():
print('testA')
def testB():
print('testB')
导入模块的文件代码
from my_model import *
testA()
testB() # 会报错,因为__all__列表中没有testB
包的使用方法
包将有联系的模块组织在一起,即放在用一个文件夹下,并且文件夹创建一个名字为______init__.py文件,那么这个文件夹就成为包
制作包
【New】 – 【Python Package】 – 输入包名 – 【OK】 – 新建功能模块(有联系的模块)
注意:新建包后,包内部会自动创建______init__.py 文件,这个文件控制着包的导入行为
导入包
import 包名.模块名
from 包名 import * 模块名.目标 (必须要在______init__.py 中加入功能名)
拓展:____dict
class A(object):
a = 0
def __init__(self):
self.b = 1
aa = A()
# 返回类内部所有属性和方法对应的字典
print(A.__dict__)
# 返回实例属性和值组成的字典
print(aa.__dict__)
十一、案例面向对象版学员管理系统
student.py
class Student(object):
def __init__(self, name, gender, tel):
self.name = name
self.gender = gender
self.tel = tel
def __str__(self):
return f'{self.name}, {self.gender}, {self.tel}'
managerSystem.py
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
# 二、系统功能函数
# 2.1 显示功能菜单 -- 打印序号的功能对应关系 --静态方法
@staticmethod
def show_menu():
print("请选择如下功能:")
print("1.添加学员")
print("2.删除学员")
print("3.修改学员信息")
print("4.查询学员信息")
print("5.显示所有学员信息")
print("6.保存学员信息")
print("7.退出系统")
# 2.2 添加学员
def add_student(self):
# 1. 让用户输入姓名、性别、手机号
name = input("请输入您的姓名:")
gender = input("请输入您的性别:")
tel = input("请输入您的电话号码:")
# 2. 创建学员对象
student = Student(name, gender, tel)
# 3. 将该对象添加到学员列表
self.student_list.append(student)
print(self.student_list)
print(student)
# 2.3 删除学员
def del_student(self):
def_name = input("请输入要删除的学员姓名:")
for i in self.student_list:
if i.name == def_name:
self.student_list.remove(i)
break
else:
print("查无此人")
print(self.student_list)
# 2.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}")
break
else:
print("查无此人!")
# 2.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}")
break
else:
print("查无此人!")
# 2.6 显示所有学员信息
def show_student(self):
print("所有学员信息\n姓名\t\t性别\t\t电话号码")
for i in self.student_list:
print(f"{i.name}\t{i.gender}\t{i.tel}")
# 2.7 保存学员信息
def save_student(self):
f = open('student.data', 'w')
new_list = [i.__dict__ for i in self.student_list]
print(new_list)
f.write(str(new_list))
f.close()
# 2.8 加载学员信息
def load_student(self):
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()
main.py
from managerSystem import *
if __name__ == '__main__':
student_manager = StudentManager()
student_manager.run()