首页 > 其他分享 >面向对象之封装、多态、反射

面向对象之封装、多态、反射

时间:2022-11-07 19:34:01浏览次数:46  
标签:.__ obj name self 多态 面向对象 print 封装 def

面向对象之封装、多态、反射

面向对象之封装

封装:将数据和功能‘封装’起来
隐藏:将数据和功能隐藏起来不让用户直接调用,并开发一些接口间接调用,而且可以在接口内添加一些额外的操作
伪装:将类里面的方法伪装成类里面的数据

隐藏

    class A:
        a = 1
        _b = 2 
        __c = 3  # 类在定义阶段时,类里面的数据变量名前面有两个下划线,那么该名字会被隐藏起来,无法直接访问
    # 在Python中没有真正意义上的隐藏,所谓的隐藏只是披了一层皮而已,_类名__名字
    
    print(A.a)  # 1
    obj = A()
    print(obj.a)  # 1
    print(obj._b)  # 2
    print(obj.__c)  # 报错
    print(A._b)  # 2
    print(A.__c)  # 报错
    print(obj._A__c)  # 3
如果想让对象也拥有隐藏属性的话同样的也是需要在类定义阶段就弄好
    obj.__name = 'zyg'
    print(obj.__name)  # zyg
    # 如果直接添加和正常的数据一样
    
    class Person:
        def __init__(self, name, age, hobby):
            self.__name = name  # 对象也可以拥有隐藏的属性
            self.__age = age
            self.__hobby = hobby

        # 类体代码中可以直接使用隐藏的属性
        def get_info(self):
            print(f"""    
            姓名:{self.__name}
            年龄:{self.__age}
            爱好:{self.__hobby}
            """)
        
        
        # 对隐藏的属性开放修改的接口
        def set_name(self, new_name):
            if len(new_name) == 0:
                raise ValueError('你好歹写点东西')
            if new_name.isdigit():
                raise ValueError('名字不能是数字')
            self.__name = new_name
            
        obj = Person('zyg', 18, 'None')
        obj.get_info()
        #   姓名:zyg
        #   年龄:18
        #   爱好:None
        obj.set_name('json')
        obj.get_info()
        # 姓名:json
        # 年龄:18
        # 爱好:None

伪装

我们在定义一个类以后,如果想要调用类里面的方法是需要加括号的
   class Person:
        def __init__(self, name, age, hobby):
            self.__name = name 
            self.__age = age
            self.__hobby = hobby
        def get_info(self):
            print(f"""    
            姓名:{self.__name}
            年龄:{self.__age}
            爱好:{self.__hobby}
            """)
    obj = Person('zyg', 18, 'read')
    obj.get_info()
    # 伪装就是把括号去掉直接变成 obj.get_info  就像调用数据
    class Foo:
        def __init__(self, val):
            self.__NAME = val  # 将属性隐藏起来

        @property
        def name(self):
            return self.__NAME

        @name.setter  # 修改
        def name(self, value):
            # 在修改数据之前可以做一系列数据验证
            self.__NAME = value  # 通过类型检查后,将值value存放到真实的位置self.__NAME

        @name.deleter  # 删除
        def name(self):
            raise PermissionError('Can not delete')
    obj = Foo('zyg')
    print(obj.name)  # zyg
    obj.name = 'lxj' 
    print(obj.name)  # lxj

面向对象之多态

面向对象中多态的意思是一种事物可以有多种形态,但是针对相同的功能应该定义相同的方法,这样无论我们拿到哪种状态的事物都可以通过相同的方法调用功能
eg: 
    在Linux系统中文件、内存、硬盘都是可以读取数据和保存数据的,那么在对他们定义时可以定义相同的读取和写入方法
    class File:
        def read(self): pass
        def write(self): pass
    class Memory:
        def read(self): pass
        def write(self): pass
    class Disk:
        def read(self): pass
        def write(self): pass

# python永远提倡自由简介大方 不约束程序员行为 但是多态提供了约束的方法
import abc


# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod  # 该装饰器限制子类必须定义有一个名为talk的方法
    def talk(self):  # 抽象方法中无需实现具体的功能
        pass


class Cat(Animal):  # 但凡继承Animal的子类都必须遵循Animal规定的标准,都必须定义一个talk方法,不管父类有没有
    def talk(self):
        pass


cat = Cat()  # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

面向对象之反射

利用字符串操作对象的数据与方法,主要用于与用户交互
操作方法
    1.hasattr()  判断对象是否含有某个字符串对应的属性名或方法名
    2.getattr()  根据字符串获取对象对应的属性或方法
    3.setattr()  根据字符串设置对象或者修改数据
    4.delattr()  根据字符串删除对象中的名字

正常情况下我们修改数据是使用变量名来修改对应的数据,但是用户输入使用的是 input 输入的是字符串类型的数据,字符串'name'和变量名 name的差别还是很大的,这种情况下我们就可以利用反射来操作
    class C1:
        school_name = '小姐姐学院'

        def choice_course(self):
            print('大宝贝们正在选课')
    
obj = C1()
while True:
    target_name = input('请输入您想要操作的名字>>>:')  # 字符串类型的数据
    if hasattr(obj, target_name):  # 判断类中有没有输入的名字
        print('恭喜您 系统中有该名字')
        # 获取该名字对应的数据(值 函数)
        data_or_func = getattr(obj, target_name)  # 获取类中名字对应的值或方法
        if callable(data_or_func):  # 判断能不能加括号调用
            print('您本次使用的是系统中的某个方法')
            data_or_func()
        else:
            print('您本次使用的是系统中的某个数据')
            print(data_or_func)
    else:
        print('很抱歉 系统中没有该名字')

标签:.__,obj,name,self,多态,面向对象,print,封装,def
From: https://www.cnblogs.com/zyg111/p/16867155.html

相关文章

  • Python基础之面向对象:5、三大特征-多态
    面对对象之多态目录面对对象之多态一、多态1、多态的概念2、多态的实际应用1、自我约束2、abc模块一、多态1、多态的概念​ 多态在实际应用时较为抽象,指事物的多种形态......
  • Python基础之面向对象:6、三大特征-封装
    面向对象之封装目录面向对象之封装一、封装1、封装的概念2、为什么要封装3、封装的两个层面二、隐藏与调用的方法1、隐藏的方法2、调用与修改的方法三、伪装1、伪装的概念......
  • Python基础之面向对象:7、反射
    面向对象之反射目录面向对象之反射一、反射1、反射的定义2、使用的场景3、常用方法1.hasattr()2.getattr()3.setattr()4.delattr()4、反射的实际应用一、反射1、反射的......
  • 11月7日内容总结——派生方法实例、面向对象三大特性之封装、多态和反射
    目录一、派生方法实战二、面向对象三大特性之封装隐藏属性如何调用隐藏属性隐藏属性的作用和使用方式三、伪装伪装的操作两个小功能:删除和修改四、面向对象三大特性之多态......
  • 面向对象三
    目录派生方法实战演练面向对象三大特性之封装伪装三大特性之多态面向对象之反射反射实战案例派生方法实战演练importjsonimportdatetimed={'t1':datetime.dat......
  • Python基础之面向对象:4、super方法实战
    派生方法实战​ 以上我们学习了通过super()的方法可以重写父类、额外添加父类中的数据,下面将通过实战案例来讲述super()方法来重写、添加父类中的功能代码需求:1、使用js......
  • 面向对象封装/多态/反射
    内容概要派生方法实战面向对象三大特性之封装三大特性之多态面向对象之反射反射实战案例练习题派生方法实战派生方法实战案例:importjsonimportdatetime#......
  • Python——面向对象(封装、多态、反射)
    Python——面向对象派生方法实战#coding:utf-8importjsonimportdatetime#dict_demo={#'t1':datetime.date.today(),#'t2':datetime.datetime.to......
  • 面向对象3之封装多态映射
    目录派生方法实战演练面向对象三大特性之封装伪装三大特性之多态面向对象之反射反射实战案例派生方法实战演练importjsonimportdatetimed={'t1':datetime.da......
  • 面向对象之派生方法、封装、伪装、三大特性、反射
    面向对象之派生方法、封装、伪装、三大特性、反射派生方法实战演练什么是派生方法?子类中的定义方法和父类定义方法一模一样的方法,并且扩展了新功能(子类和父类一样,但是......