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

原文地址:https://www.cnblogs.com/zhaokunhao/p/14263103.html