Python对象和类

内容简介

  • 类和对象之间的关系
  • 面向对象设计基本步骤
  • 定义类和创建对象
  • 使用构造方法实例化对象
  • 掌握封装的概念及其使用

定义类

  • 定义类

    # 演员类
    class Actor:
        def __init__(self, name, sex, job):
            self.name = name    # 使用变量存储数据域,表示状态或属性
            self.sex = sex
            self.job = job
    
        # 共有行为:吃饭、表演
        def eat(self):          # 使用方法(类中定义的函数)/函数来定义一个对象的行为
            pass
    
        def performs(self):
            pass
    
  • 创建对象

    类会提供一种特殊的方法:_ init _,被称为初始化程序,它在创建和初始化这个新对象时被调用

    # 一旦定义了一个类,就可以使用构造方法由类来创建对象
    actor = Actor("佟湘玉", "女", "掌柜的")
    

    在这里插入图片描述

类和对象之间的关系

  • 类是抽象的概念,仅仅是模板

  • 对象是一个你能够看得到、摸得着的具体实体

构造方法

  • 对象的初始化方式很"low"且容易遗漏

    role = Role()
    role.name = “佟湘玉"
    role.sex = "女"
    role.job = "掌柜的"
    role.age = 28;
    
  • 解决方案:使用构造方法传参

    def __init__(self, name, intro, power, type):
        self.name = name
        self.intro = intro
        self.power = power
        self.type = type
    

隐藏数据域

  • 数据域私有

    def set_age(self, age):
        if 0 <= age <= 100:
            self.__age = age
        else:
            self.__age = 18
    
    
    def get_age(self):
        return self.__age
    
  • 让数据域私有来保护数据

    • 为避免直接修改数据域,就不要让类用户直接访问数据域,这被称为数据隐藏

    • 在Python中,私有数据域以两个下划线开头

    • 私有数据域和方法只能在类的内部被访问

    # @function:隐藏数据域
    # @Description:一只萤火虫
    
    class Role:
        def __init__(self, name, sex, job, age):
            self.__name = name          # 两个前导下划线开头的变量仅供对象的内部使用 -- 私有数据域
            self.__sex = True
            self.__age = age
            self.set_age(age)
            self._job = "一个下划线"     # 一个下划线开头的属性,称为受保护的属性
    
        def set_sex(self, sex):
            self.__sex = sex
    
        def set_age(self, age):
            if age > 100 or age < 0:
                self.__age = 18
            else:
                self.__age = age
    
        def is_sex(self):
            """ bool类型成员,一般使用is开头的方法实现读取器 """
            return self.__sex
    
        def get_age(self):
            return self.__age
    
        def get_name(self):
            return self.__name          # 因为没有定义set_name方法,所以name一旦确定,后面就不能修改了
    
    
    
    if __name__ == '__main__':
        role = Role("李大嘴", "男", "大厨", 25)
        print(role.get_name() + "年龄是:", role.get_age())
        print("受保护的属性仍然可以被类的用户访问到", role._job)
    
  • 注意:

    • 1、类只是在程序内部使用,没有必要隐藏数据域;类需要给其它程序使用时,为了防止数据域被修改,需要隐藏数据域

    • 2、不要以一个以上的下划线结尾:Python中,以两个下划线开头并结尾的名字具有特殊意义

    • 3、类的抽象是将类的实现和使用相分离;类的实现细节对用户而言是不可见的,这就是类的封装

使用内标操作多个对象

  • 使用列表可以简化对多个同类型对象的操作
    在这里插入图片描述
    模块代码

    # @Projection: 定义类
    # @Function: 一只萤火虫
    
    # 演员类
    class Actor:
        def __init__(self, name, sex, job="演员"):
            self.name = name    # 使用变量存储数据域,表示状态或属性
            self.sex = sex
            self.job = job
    
        def __eq__(self, other):
            """ 当调用 == 符号比较两个对象时,自动调用本方法 """
            if self.name == other.name:
                return True
            else:
                return False
    
        # 共有行为:吃饭、表演
        def eat(self):          # 使用方法(类中定义的函数)/函数来定义一个对象的行为
            pass
    
        def performs(self):
            # self. 可以访问当前对象定义的属性以及方法
            print(self.sex + "子, " + self.name + "正在表演拿手好戏!")
    

    主程序

    from actor import Actor    # 引入模块
    
    if __name__ == '__main__':
        actor_list = [
            Actor("佟湘玉", "女"),
            Actor("吕轻侯", "男"),
            Actor("白展堂", "男"),
            Actor("郭芙蓉", "女")
        ]
    
        # 判断对象是否存在于列表中
        new_actor = Actor("佟湘玉", "女")
        is_exists = False
        for actor in actor_list:
            if new_actor == actor:
                is_exists = True
        if not is_exists:
            actor_list.append(new_actor)
    
        # 可以使用循环操作多个在列表中的对象
        for actor in actor_list:
            actor.performs()
    
        print(Actor("佟湘玉", "女") == Actor("佟湘玉", "女"))
    

    输出结果
    在这里插入图片描述

可变对象和不可变对象

  • 可变对象传参时内容有可能改变

    # @function:自定义的类实例就是一个可变类型
    # @Description:一直萤火虫
    
    class User:
        def __init__(self, user_name, login_pwd):
            """
            :param user_name: 登录用户名
            :param login_pwd: 登录密码
            """
            self.__user_name = user_name
            self.__login_pwd = login_pwd
            self.__login_count = 0              # 用来记录当前用户登录成功的次数
    
        def get_user_name(self):
            return self.__user_name
    
        def get_login_pwd(self):
            return self.__login_pwd
    
        def get_login_count(self):
            return self.__login_count
    
        def set_login_count(self, login_count):
            if login_count < 0:
                self.__login_count = 0
            else:
                self.__login_count = login_count
    
        def __eq__(self, other):
            return self.__user_name == other.get_user_name() and self.__login_pwd == other.get_login_pwd()
    
    
    # 已经注册的用户列表
    register_user_list = [
        User("墨家巨子", "兼爱非攻"),
        User("鬼谷子", "天下大势,唯我纵横"),
        User("道家", "道法自然"),
        User("123", "123456")
    ]
    
    
    class UserManagement:
        """
        用户业务类:当程序逻辑非常复杂时,可以讲关于用户的业务逻辑方法单独封装在这个类中
        """
        def validate(self, user):
            user.set_login_count(1000)
            for curr in register_user_list:
                if curr == user:
                    curr.set_login_count(curr.get_login_count() + 1)
                    return curr
            return None
    
    
    if __name__ == '__main__':
        user_name = input("请输入用户名:")
        password = input("请输入密码:")
        login_user = User(user_name, password)
        # 实例化业务对象,调用验证方法
        user_manager = UserManagement()
        result = user_manager.validate(login_user)
        if not result:
            print("用户名和密码不匹配!")
        else:
            print("登录成功,欢迎您:", result.get_user_name())
            print("登录系统的次数:", result.get_login_count())
            print("可变类型在函数中修改属性后:", login_user.get_login_count())
    
    输出结果:
    请输入用户名:123
    请输入密码:123456
    登录成功,欢迎您: 123
    登录系统的次数: 1
    1000
    

小结:面向对象的思考

  • 使用面向对象的软件设计重点在对象以及对象的操作上

  • 在面向过程程序中,数据和数据上的操作是分离的,而且这种做法要求传递数据给方法

  • 面向对象程序设计将数据和对它们的操作都放在一个对象中

  • 面向对象程序设计方法以一种反映真实世界的方式组织程序

    • 在真实世界中,所有的对象和属性及动作都是相关联的
    • 使用对象提高了软件的可重用性,并且使程序更易于开发和维护
  • Python程序设计涉及对对象的思考,一个Python程序可以看做是一个相互操作对象的集合

  • 封装的概念:

    • 封装对象初始化

    • 封装对象的操作

    • 封装对象的内部数据

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值