• python之封装、多态、反射


    一、封装

    1.1封装的定义

    在程序设计中,封装是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。

    要了解封装,离不开“私有化”,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。

    1.2封装的用处

    封装数据的主要原因是:保护隐私(把不想别人知道的东西封装起来)

    封装方法的主要原因是:隔离复杂度

    注意:在编程语言里,对外提供的接口(接口可理解为了一个入口),就是函数,称为接口函数,这与接口的概念还不一样,接口代表一组接口函数的集合体。

    1.3封装的两个层面

    (1)类就是麻袋,这本身就是一种封装

    (2)类中定义私有的,只有类的内部使用,外部无法访问

    class People:
        _star='earth'     #单下划线表示被隐藏起来
        def __init__(self,name,id,age,salary):
            self.name=name
            self.id=id
            self.age=age
            self.salary=salary
    
        def get_id(self):
            print('[%s的身份证号是%s]'%(self.name,self.id))
    
    p1=People('czd','62012393208',18,100000)
    print(p1._star)
    
    
    
    
    class People:
        __star='earth'          #双下划綫
        def __init__(self,name,id,age,salary):
            self.name=name
            self.id=id
            self.age=age
            self.salary=salary
    
        def get_id(self):
            print('[%s的身份证号是%s]'%(self.name,self.id))
    
    p1=People('czd','62012393208',18,100000)
    # print(p1.__star)      #报错
    
    print(p1._People__star)

      这种自动变形的特点:

        1、类中定义的__star只能在内部使用,如品p1.__star,引用的就是变形的结果。

        2、这种变形其实正是针对外部的变形,在外部是无法通过__star这个名字访问到的。

        3、在子类定义的__star不会覆盖在父类定义的__star,因为子类中变形成了:_子类名__star,而父类中变形成了:_父

    类名__star,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

      注意:对于这一层面的封装(隐藏),我们需要在类中定义一个函数(接口函数)在它内部访问被隐藏的属性,然后

    外部就可以使用了

    二、多态

    2.1多态的概念

    多态的特性是调用不同的子类将会产生不同的行为,而无需明确知道这个子类实际上是什么。

    多态实际上是依附于继承的两种含义:"改变"和"扩展"本身就意味着必须有机制去选用你改变/扩展过的版本,多态实质上就是继承的实现细节

    子类实例化后调用基类的方法,w1.turn_ice()叫做多态;

    class H2O:
        def __init__(self,name,temperature):
            self.name=name
            self.temperature=temperature
        def turn_ice(self):
            if self.temperature<0:
                print('[%s]温度太低结冰了'%self.name)
            elif self.temperature>0 and self.temperature<100:
                print('[%s]液化成水'%self.name)
            elif self.temperature>100:
                print('[%s]温度太高变为水蒸气'%self.name)
    
    class Water(H2O):
        pass
    class Ice(H2O):
        pass
    class Steam(H2O):
        pass
    
    w1=Water('',25)
    
    i1=Ice('',-20)
    
    s1=Steam('蒸汽',200)
    
    # w1.turn_ice()     #执行过程中不同的对象调用相同的方法
    # i1.turn_ice()
    # s1.turn_ice()
    
    #或者定义一个接口来执行上面的调用
    def func(obj):
        obj.turn_ice()
    
    func(w1)   #---->w1.turn_ice()
    func(i1)
    func(s1)
    View Code

    三、反射

    3.1反射的介绍

    反射说简单点 --> 就是利用字符串的形式去对象(模块)中操作(寻找/检查/设置/删除)成员。

    • hasattr(object,"name")
    • getattr(object,"name",default=None)
    • setattr(x,y,v)
    • delattr(x,y)

    例如:

    class BlackMedium:
        feture = 'Ugly'
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def sell_house(self):
            print('[%s]正在卖房子,傻逼才买呢'%self.name)
    
        def rent_house(self):
            print('[%s]正在租房子,傻逼才租呢'%self.name)
    
    b1=BlackMedium('万成置地','天露园')
    
    print(hasattr(b1,'name'))
    print(hasattr(b1,'sell_house'))   #显示True
    print(hasattr(b1,"sell_houseaaa"))#显示False
    
    
    print(getattr(b1,'name'))
    print(getattr(b1,'rent_house'))
    func=getattr(b1,'rent_house')
    func()
    # print(getattr(b1,'rent_houseaaa'))  #没有则报错
    print(getattr(b1,'rent_houseaaa','没有这个属性'))
    
    #数据属性
    setattr(b1,'sb','True')    #相当于b1.sb=True
    setattr(b1,'123','czd')
    setattr(b1,'name','fuzhou')
    #函数属性
    setattr(b1,'func',lambda x:x+1)
    setattr(b1,'func1',lambda self:self.name+'sb')
    print(b1.__dict__)
    print(b1.func)
    print(b1.func(1))
    print(b1.func1(b1))
    
    delattr(b1,'sb')         #相当于del b1.sb
    print(b1.__dict__)
    代码示范

    3.2 反射的好处

    (1)好处一:实现可插拔机制

    有俩程序员,一个czd,一个是egon,lili在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,lili想到了反射,使用了反射机制czd可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现czd想要的功能。

    总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    class FtpClient:
        'ftp客户端,但是还么有实现具体的功能'
        def __init__(self,addr):
            print('正在连接服务器[%s]' %addr)
            self.addr=addr
    lei
    #from module import FtpClient
    f1=FtpClient('192.168.1.1')
    if hasattr(f1,'get'):
        func_get=getattr(f1,'get')
        func_get()
    else:
        print('---->不存在此方法')
        print('处理其他的逻辑')
    导入模块

    (2)好处二:动态导入模块(基于反射当前模块成员)

     

     

  • 相关阅读:
    你是怎么把字符串“2016-11-16” 变为 “16/11/2016” 的?
    js-------》(小效果)实现倒计时及时间对象
    Ruby方法
    JAVASCRIPT事件详解-------原生事件基础....
    html5的小知识点小集合
    原生js实现的效果
    IDEA 实用功能Auto Import:自动优化导包(自动删除、导入包)
    8.SpringBoot 模板引擎 Thymeleaf
    7.SpringBoot 之 Web
    6.日志的使用
  • 原文地址:https://www.cnblogs.com/changzhendong/p/11316998.html
Copyright © 2020-2023  润新知