• 面向對象深入


    封裝
    封裝是將類中的屬性或方法對外部隱藏,對外部提供接口用來輸出想要展示的信息
    不封裝的情況下直接將類中的屬性展示出來,可以被隨意修改。但是封裝之後對外界只提供接口來輸出

    數據,提高了安全性。

    首先可以對屬性進行封裝

    class Student:
        def __init__(self,name,age,gender,id_card):
            self.name = name
            self.age = age
            self.gender = gender
            self.__id_card = id_card
    
        # 访问被封装的属性  称之为访问器
        def get_id_card(self,pwd):
            # 可以在这里添加额外的任何逻辑代码 来限制外部的访问
            # 在类的内部 可以访问
            if pwd =="123":
                return self.__id_card
            raise Exception("密码错误!")

    對方法也可以進行封裝

    class ATM:
    
        def withdraw(self):
            self.__user_auth()
            self.__input_money()
            self.__save_record()
            # 输入账号和密码
            # 显示余额
            # 输入取款金额
            # 保存记录
    
        def __user_auth(self):
            print("请输入账号密码....")
    
        def __input_money(self):
            print("余额为100000000,请输入取款金额!")
    
        def  __save_record(self):
            print("记录流水....")

    封裝的原理:
    python是通过 变形的方式来实现的封装
    如何变形 在名称带有双下划线开头的变量名字前添加_类名  如_Person__id_card
    当然通过变形后的名字可以直接访问被隐藏的属性  但通过不应该这么做
    变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形  就是普通属性

    property的另一種使用場景
    一個屬性他得值不是固定的,而是通過運算動態產生的

    class Person:
        def __init__(self,name,height,weight):
            self.name = name
            self.height = height
            self.weight = weight
            # self.BMI = weight / (height ** 2)
    
        @property
        def BMI(self):
            return self.weight / (self.height ** 2)
    
        @BMI.setter
        def BMI(self,new_BMI):
            print("BMI 不支持自定义.....")

    多態

    多態指的是不同類型對象可以相應同一種方法而產生不同效果

    鴨子類型就是典型的多態,多種不同的類型使用方法一樣

    class Cat():
        def bark(self):
            print("喵喵喵")
        def run(self):
            print("四条腿跑!")
        def sleep(self):
            print("趴着睡!")
            
    class Pig():
        def bark(self):
            print("哼哼哼!")
        def run(self):
            print("四条腿跑!")
        def sleep(self):
            print("侧躺着睡!")

    常用的内置函數
    __str__

    使用:如:
    class Car:
        def __init__(self, newWheelNum, newColor):
            self.wheelNum = newWheelNum
               self.color = newColor    
        def __str__(self):
            msg = "嘿。。。我的颜色是" + self.color + "我有" + int(self.wheelNum) + "个轮胎..."
            return msg
        def move(self):
            print('车在跑,目标:夏威夷')
    BMW = Car(4, "白色")
    #嘿。。。我的颜色是白色我有4个轮胎...

    在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法

    当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

    __del__

    当对象被删除前会自动调用 该方法
    声明时候会删除对象?
        1.程序运行结束 解释器退出 将自动删除所有数据
        2.手动调用del 时也会删除对象

    假设要求每一个person对象都要绑定一个文件
    class Person:
        def __init__(self,name,path,mode="rt",encoding="utf-8"):
            self.name = name
            self.file = open(path,mode,encoding=encoding)
    
    
    
        # 读取数据的方法
        def read_data(self):
            return self.file.read()
    
    
        def __del__(self):
            print("del run!")
            self.file.close()

    反射
    反射是通過字符串來操作對象屬性

    1.hasattr(object, name):可以查看前面的元素是否拥有后面的元素,后面的元素要用引号包裹,前面不需要。

    但是这里必须要实例化,如果是hasattr(Foo,‘name’)报False.

    2.getattr(object, name[, default]):   根据括号的元素拿到相应的值,getattr(l1,l2),也就是如果后面的元素属于前面,那么会取出l1.l2的值。如果不是那就报错。

    如果getattr(l1,'l2')尾部再加上'加上某些东西',例:gerattr(l1,'l2','l3'),如果是错误了那么会显示最后双引号里面的东西,也就是l3,如果是正确则不会显示,只会显示正确的答案。

    class Base():
        def __init__(self,name,id):
            self.id=id
            self.name=name
    
    
        def show(self):
            print('id:%s,name:%s'%(self.id,self.name))

    b1=Base('aaa',12)
    print(getattr(b1,'name'))

    ==》aaa



    3.setattr(object, name, value) :给object对象的name属性赋值value,如果对象原本存在给定的属性name,则setattr会更改属性的值为给定的value;如果对象原本不存在属性name,setattr会在对象中创建属性,并赋值为给定的value;



    4.delattr(object, name)  :  函数作用用来删除指定对象的指定名称的属性,和setattr函数作用相反。

    class MY_CMD:
    
        def dir(self):
            os.system("dir")
    
        def ipconfig(self):
            os.system("ipconfig")
    
    cmd = MY_CMD()
    
    while True:
        name = input("请输入要执行的功能:")
        if hasattr(cmd,name):
            method = getattr(cmd,name)
            print(method)
            method()
        else:
            print("sorry this method is not exists....!")

    動態導入

    直接写import 称之为静态导入  建立在一个基础上:提前已经知道有这个模块
    动态导入  指的是  在需要的任何时候 通过指定字符串类型的包名称来导入需要的模块
    import importlib
    mk = importlib.import_module(m_name)
    mk 即导入成功的模块

    补充

    __getattr__:当对象获取自己没有的属性的时候自动触发
    __setattr__:当对象想要给某个属性赋值时,如” user.id=11“

  • 相关阅读:
    轻松管理您的网络password
    尝到awk
    重载虚函数的相关问题
    阿赫亚web安全JSON
    SplitContainer如何实现左侧导航,正确显示和导航内容
    POJ 3450 Corporate Identity KMP解决问题的方法
    virtio-blk分析
    JavaScript权威指南科03章 种类、值和变量(1)
    iOS开展-Xcode技巧总结(持续更新)
    POI设置边框
  • 原文地址:https://www.cnblogs.com/duGD/p/10896910.html
Copyright © 2020-2023  润新知