zoukankan      html  css  js  c++  java
  • 19、property、绑定方法(classmethod、staticmethod)、继承

    一、property

    装饰器是在不修改被装饰对象的源代码以及调用方式的前提下,为被装饰对象添加新功能的可调用对象。

    property是一个装饰器,是用来绑定给对象的方法伪造成一个数据属性

    #案例1
    class People:
        def __init__(self, name, height, weight):
            self.name = name
            self.height = height
            self.weight = weight
    
        # 定义函数的原因1:
        # 1、从bmi公式上看,应该是触发功能计算得到的
        # 2、bmi是随着身高、体重的变化而动态变化的,不是一个固定的值
        # 但是bmi听起来更像一个数据属性,而非功能
        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    
    obj1 = People('egon', 1.80, 70)
    print(obj1.bmi)  # 直接调,不用加括号
    

    人的正常思维逻辑

    使用者.name去用

    案例2
    方式1:
    class People:
        def __init__(self, name):
            self.__name = name
    
        def get_name(self):
            return self.__name
    
        def set_name(self, val):
            if type(val) is not str:
                print('必须传入字符串')
                return
            self.__name = val
    
        def del_name(self):
            print('不让删除')
    
        name = property(get_name, set_name, del_name)
    
    
    obj1 = People('egon')
    print(obj1.name)  # 查找操作
    obj1.name = '18'  # 更改操作
    print(obj1.name)
    del obj1.name  # 删除操作
    -----------------输出结果---------------------
    egon
    不让删除
    
    方式二:
    第一步:先将函数名字都改成name
    第二步:在函数的上方添加@
    class People:
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, val):
            if type(val) is not str:
                print('必须传入字符串')
                return
            self.__name = val
    
        @name.deleter
        def name(self):
            print('不让删除')
    
    
    obj1 = People('egon')
    print(obj1.name)  # 查看名字
    obj1.name = 'EGON'  # 更改名字
    print(obj1.name)
    del obj1.name  # 删除名字
    -----------输出结果----------
    egon
    EGON
    不让删除
    

    二、绑定方法

    特殊之处在于将调用者本身当作第一个参数自动传入

    ​ 1、绑定给对象的方法:调用者是对象,自动传入的是对象

    ​ 2、绑定给类的方法:调用者类,自动传入的是类

    classmethod绑定方法

    import settings
    
    
    class Mysql:
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        def func(self):
            print("%s:%s" % self.ip, self.port)
    
        @classmethod  # 将下面的函数装饰成绑定给类的方法
        def from_conf(cls):
            print(cls)
            return cls(settings.IP, settings.PORT)
    
    
    # 应用场景很窄,给你提供一种新的造对象的方式
    # 来自于配置文件和其他地方
    obj1 = Mysql('1.1.1.1', 3306)
    
    obj2 = Mysql.from_conf()
    print(obj2.__dict__)
    

    staticmethod非绑定方法

    静态方法:没有绑定给任何人:调用者可以是类、对象、没有自动传参的效果

    class Mysql:
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        @staticmethod  # 将下述函数装饰成一个静态方法
        def create_id():  # 如果有参数,必须传参,需要手动传
            import uuid
            return uuid.uuid4()
    
    
    obj1 = Mysql('1.1.1.1', 3306)
    print(Mysql.create_id())
    print(obj1.create_id())
    

    三、继承

    继承是创建新类的一种方式
    新建的类称之为子类
    被继承的类称之为父类、基类、超类
    继承的特点是:子类可以遗传父类的属性
    
    类是用解决对象之间冗余问题的
    而继承则是来解决类与类之间冗余问题的
    
    在python中支持多继承
    class Parent1(object):  # 考虑代码兼容问题,可以在()加object
        pass  # 在python3中所有的类都是新式类
    
    
    class Parent2(object):
        pass
    
    
    class Sub1(Parent1):
        pass
    
    
    class Sub2(Parent1, Parent2):
        pass
    
    
    print(Sub1.__bases__)
    print(Sub2.__bases__)
    但凡是继承了object类的子类以及该子类的子子孙孙类都是新式类
    反之就是经典类
    
    在python2中有新式类与经典类之分,在python3中全都是新式类
    print(Parent1.__bases__)
    print(Parent2.__bases__)
    
    
    多继承的优缺点
    优点:子类可以同时遗传多个父类的属性,最大限度地重用代码
    缺点:
    	1、违背人的思维习惯:继承表达的是一种什么'是'什么的关系
    	2、代码的可读性变差	
    

    ​ 继承背景下的属性查找

    # 示例1
    class Bar:
        def f1(self):
            print('Bar.f1')
    
        def f2(self):
            print('Bar.f2')
            self.f1()  # obj.f1()
    
    class Foo(Bar):
        def f1(self):
            print("Foo.f1")
    
    obj = Foo()
    obj.f2()
    --------输出结果---------
    Bar.f2
    Foo.f1
    
    # 示例2
    class Bar:
        def __f1(self):  # _Bar__f1
            print('Bar.f1')
    
        def f2(self):
            print('Bar.f2')
            self.__f1()  # self._Bar_f1
    
    class Foo(Bar):
        def __f1(self):  # _Foo__f1
            print("Foo.f1")
    
    obj = Foo()
    obj.f2()
    ----------输出结果---------
    Bar.f2
    Bar.f1
    

  • 相关阅读:
    占位 CP
    占位 LR
    占位 DL
    占位 SC
    Your name ?
    占位 RK
    Gson 关于SpringMVC和json格式问题
    JDBC
    Outlook2016 2019修改默认存储路径文件夹
    Windows Server 2016 任务管理器没有了远程控制 远程桌面,能够控制其它远程用户的会话
  • 原文地址:https://www.cnblogs.com/zhaokunhao/p/14263103.html
Copyright © 2011-2022 走看看