Python面向对象编程(2)

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

八、多态 类方法 类属性

面向对象的三大特性

封装
  • 将属性和方法书写到类里面的操作即为封装
  • 封装可以为属性和方法添加私有权限
继承
  • 子类默认继承父类的所有属性和方法
  • 子类可以重写父类属性和方法
多态
  • 传入不同的对象,产生不同的结果

多态

了解多态

多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)

  • 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
  • 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
  • 实现步骤:
    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(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()

异常的传递

体验异常传递

需求:

  1. 尝试只读方式打开test.txt文件,如果文件存在则读取文件的内容,文件不存在则提示用户即可
  2. 读取内容要求:尝试循环读取内容,读取过程中如果检测到用户意外终止程序,则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语句。

模块能定义函数,类和变量,模块里也能包含可执行的代码

导入模块
  1. import 模块名
  2. from 模块名 import 功能名
  3. from 模块名 import *
  4. import 模块名 as 别名
  5. 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解释器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录
  3. 如果都找不到,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()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值