Mixins mechanism. md_super_polymorphic_binding_built-in method

One: the correct way to open Python multiple inheritance: mixins mechanism

Mixins core: Under the background of multiple inheritance, improve the readability of multiple inheritance as much as possible

ps: Let multiple inheritance satisfy people's thinking habits ==> what is what

# PI = 3.1415926

 

Two: examples

class Vehicle:   # transport 
    DEF Fly (Self):
         Print ( " the I AM Flying " ) 


class CivilAircraft (Vehicle):   # civil aircraft 
    Pass 


class Helicopter (Vehicle):   # helicopter 
    Pass 


class Car (Vehicle):   # car and can not fly, but according to the above inheritance, the car can fly 
    Pass 
class vehicle:   # vehicle 
    Pass 


class Flyable:     # Create a new class Flyable, can fly only as vehicles parent 
    DEF fly (Self):
         Print ( " I am flying" ) 


Class CivilAircraft (Vehicle, Flyable):   # civil aircraft 
    Pass 


class Helicopter (Vehicle, Flyable):   # helicopter 
    Pass 


class Car (Vehicle):
     Pass 
  Python language can not interface functions, but it may be that multiple inheritance Python yes. Should n’t it be implemented with multiple inheritance? Yes, no. Say yes, because from the grammatical point of view, it is indeed achieved through multiple inheritance. Say no, because its inheritance still adheres to the " is - a" relationship, meaning point of view still follow the principle of single inheritance. 

class vehicle:   # vehicle 
    Pass 


class FlyableMixin:         # plus a Mixin end, can be used as a false parent mixed zone 
    DEF Fly (Self):
         Print ( " the I AM Flying " ) 


classCivilAircraft (Vehicle, FlyableMixin):   # civil aircraft 
    pass 


class Helicopter (Vehicle, FlyableMixin):   # helicopter 
    pass 


class Car (Vehicle):   # car does not fly, but according to the above inheritance, the car can fly 
    pass 
here As you can see, both CivilAircraft and Helicopter inherit Vehicle and FlyableMixin, but FlyableMixin, which means mix - in , tells others that this class is added as a function to a subclass, not as a parent class. The function is the same as the interface in Java. 
Use the Mixin class to implement multiple inheritance with great care
     1. First it must represent a certain function, not an item, like Runnable, Callable, etc. in Java
     2. Secondly it must have a single responsibility, if there are multiple functions, then Write multiple Mixin classes
     3. Then, it does not depend on the implementation of the subclass
     4. Finally, even if the subclass does not inherit the Mixin class, it still works, but it lacks a certain function.

 

 

New method derived from subclass super ()

One: Method 1

Named surname calls a function under a certain class ==> does not depend on inheritance

class OldboyPeople:
    school = 'OldBoy'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def f1(self):
        print(f'{self.name} say hello')


class Student(OldboyPeople):
    def choose_course(self):
        print('学生%s 正在选课' % self.name)


class Teacher(OldboyPeople):
    #           老师的空对象,'egon',18,'male',3000,10
    def __init__(self, name, age, sex, salary, level):
        # 方式1:# 指名道姓地跟父类OldboyPeople去要__init__
        # OldboyPeople.__init__(self, name, age, sex)
        self.salary = salary
        self.level = level

    def score(self):
        print('老师 %s 正在给学生打分' % self.name)


print(Teacher.mro())  # [<class '__main__.Teacher'>, <class '__main__.OldboyPeople'>, <class 'object'>]

 

二:方式2

super()调用父类提供给自己的方法 ==> 严格依赖继承关系

class OldboyPeople:
    school = 'OldBoy'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def f1(self):
        print(f'{self.name} say hello')


class Student(OldboyPeople):
    def choose_course(self):
        print('学生%s 正在选课' % self.name)


class Teacher(OldboyPeople):
    #           老师的空对象,'egon',18,'male',3000,10
    def __init__(self, name, age, sex, salary, level):
        # 方式2:# 调用super()会得到一个特殊的对象,该对象会参照当前类的mro,去当前类的父类里找属性
        super().__init__(name, age, sex)  # 调用的是方法,自动传入对象
        self.salary = salary
        self.level = level

    def score(self):
        print('老师 %s 正在给学生打分' % self.name)


print(Teacher.mro())  # [<class '__main__.Teacher'>, <class '__main__.OldboyPeople'>, <class 'object'>]
class A:
    def test(self):
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass


print(A.mro())  # [<class '__main__.A'>, <class 'object'>]
print(B.mro())  # [<class '__main__.B'>, <class 'object'>]
print(C.mro())  # 在代码层面A并不是B的子类,但从MRO列表来看,属性查找时,就是按照顺序C->A->B->object,B就相当于A的“父类”
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,<class ‘object'>]

obj = C()
obj.test()  # 属性查找的发起者是类C的对象obj,所以中途发生的属性查找都是参照C.mro()
# from B
class A:
    def test(self):
        print('from A')
        super().test1()


class B:
    def test1(self):
        print('from B')


class C(A, B):
    def test1(self):
        print('from C')


print(C.mro())  # 在代码层面A并不是B的子类,但从MRO列表来看,属性查找时,就是按照顺序C->A->B->object,B就相当于A的“父类”
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,<class ‘object'>]

obj = C()
obj.test()  # 属性查找的发起者是类C的对象obj,所以中途发生的属性查找都是参照C.mro()

 

三:使用须知

super()和之前的方法不能混用,只能用其中一种

 

 

多态

 

一:什么是多态

 

同一事物有多种形态

 

二:为何要有多态 ==> 多态会带来什么样的特性,多态性

 

多态性指的是:可以在不考虑对象的具体类型情况下 直接使用对象

 

class Animal:
    def say(self):
        print('动物基本的发声...', end='')


class People(Animal):
    def say(self):
        super().say()
        print('卧槽')


class Dog(Animal):
    def say(self):
        super().say()
        print('汪汪汪')


class Pig(Animal):
    def say(self):
        super().say()
        print('吼吼吼')


obj1 = People()
obj2 = Dog()
obj3 = Pig()


# obj1.say()  # 动物基本的发声...卧槽
# obj2.say()  # 动物基本的发声...汪汪汪
# obj3.say()  # 动物基本的发声...吼吼吼


# 定义统一的接口,接收传入的动物对象
def animal_say(animal):
    animal.say()


animal_say(obj1)
animal_say(obj2)
animal_say(obj3)

 

 

Python中len的精妙之处

 

# len('hello')
# len([1, 2, 3])
# len({'name': 'xxq', 'age': 18})

# print('hello'.__len__())
# print([1, 2, 3].__len__())
# print({'name': 'xxq', 'age': 18}.__len__())


def my_len(val):
    return val.__len__()


print(my_len('hello'))
print(my_len([1, 2, 3]))
print(my_len({'name': 'xxq', 'age': 18}))

 

 

三:鸭子类型

 

# Python推崇的是鸭子类型

class Cpu:
    def read(self):
        print('cpu read')

    def write(self):
        print('cpu write')


class Mem:
    def read(self):
        print('Mem read')

    def write(self):
        print('Mem write')


class Txt:
    def read(self):
        print('Txt read')

    def write(self):
        print('Txt write')


obj1 = Cpu()
obj2 = Mem()
obj3 = Txt()

obj1.read()
obj2.read()
obj3.read()

 

 

四:了解知识点

 

import abc

# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):  # 统一所有子类的方法
    @abc.abstractmethod     # 该装饰器限制子类必须定义有一个名为talk的方法
    def say(self):
        print('动物基本的发声...', end='')


class People(Animal):   # 但凡继承Animal的子类都必须遵循Animal规定的标准
    pass


class Dog(Animal):
    pass


class Pig(Animal):
    pass


obj1 = People()
obj2 = Dog()
obj3 = Pig()

obj1.say()  # 动物基本的发声...卧槽
obj2.say()  # 动物基本的发声...汪汪汪
obj3.say()  # 动物基本的发声...吼吼吼

# 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化
# TypeError: Can't instantiate abstract class People with abstract methods say

class Animal(metaclass=abc.ABCMeta):  # 统一所有子类的方法
    @abc.abstractmethod
    def say(self):
        print('动物基本的发声...', end='')


class People(Animal):
    def say(self):
        super().say()
        print('卧槽')


class Dog(Animal):
    def say(self):
        super().say()
        print('汪汪汪')


class Pig(Animal):
    def say(self):
        super().say()
        print('吼吼吼')


obj1 = People()
obj2 = Dog()
obj3 = Pig()

obj1.say()  # 动物基本的发声...卧槽
obj2.say()  # 动物基本的发声...汪汪汪
obj3.say()  # 动物基本的发声...吼吼吼

 




绑定

一:绑定方法:特殊之处在于 将调用者本身当做第一个参数 自动传入

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

class Mysql:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    def func(self):
        print(f'{self.ip} {self.port}')


obj = Mysql('127.0.0.1', 3306)
obj.func()      # 127.0.0.1 3306

 

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

新的方法:

setting.py

IP = '127.0.0.1'
PORT = 3306
import settings


class Mysql:
    def __init__(self, ip, port):
        self.nid = self.create_id()
        self.ip = ip
        self.port = port

    def func(self):
        print(f'{self.ip} {self.port}')

    @classmethod    # 绑定给类的方法
    def form_conf(cls):
        print(cls)
        return cls(settings.IP, settings.PORT)

    @staticmethod  # 将下述函数 装饰成一个静态方法
    def create_id():
        import uuid
        return uuid.uuid4()

    @classmethod
    def f1(cls):
        pass

    def f2(self):
        pass

obj2 = Mysql.form_conf()    # <class '__main__.Mysql'>
print(obj2.__dict__)        # {'nid': UUID('fb7015fb-8e6c-4c1e-9a24-241a7c3aff10'), 'ip': '127.0.0.1', 'port': 3306}

 

二:非绑定方法

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

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', 2208)

# print(Mysql.create_id)  # <function Mysql.create_id at 0x037083D0>
# print(obj1.create_id)   # <function Mysql.create_id at 0x037083D0>

Mysql.create_id()
obj1.create_id()

 

 
内置方法
# print(abs(-1))                 # 返回绝对值  # 1
#
# print(all([1, 2, 3, '']))      # 返回可迭代对象,有一个为0,None,空就是假的 # False
# print(all([1, 2, 3, ]))        # 返回可迭代对象    # True
#
# print(any([]))                 # False
#
# print(bin(111))                # 0b1101111
# print(oct(111))                # 0o157
# print(hex(111))                # 0x6f
#
# print(bool(''))                # False

# def func():
#     pass


# class Foo:
#     pass


# print(callable(Foo))            # True


# print(chr(65))                    # A
# print(ord('A'))                   # 65


# # ======= 掌握 =======
# class Foo:
#     pass
# obj = Foo()
# obj.xxx = 111

# print(dir(Foo))     # 可以查看可以.出来哪些属性     #['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

# print(dir(obj))     # 可以查看可以.出来哪些属性     #['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'xxx']

# print(divmod(1000,4))         #总数据量,每一页的数据量
# 返回值:总页数,剩余数据       # (250, 0)

# # ======= 掌握 =======
# for i, v in enumerate(['a', 'b', 'c']):
#     print(i, v)
#
# #  0 a
# #  1 b
# #  2 c

# # ======= 掌握 =======
# res = eval('1+2')       # eval就是执行字符串中的表达式
# print(res)

# # ======= 掌握 =======
# 不可变集合
# s = frozenset({1, 2, 3})
# print(s)    # frozenset({1, 2, 3})

# hash(不可变类型)

# # ======= 掌握 =======
# isinstance判断一个对象是不是一个类的实例
# class Foo:
#     pass
#
# obj = Foo()
# print(isinstance(obj, Foo))     # True
# print(isinstance([], list))     # True  # 推荐
# print(type([]) is list)         # True  # 不推荐

# # 10 ** 2 % 3
# print(pow(10, 2, 3))        # 1

# # 了解
# print('aaa'.__repr__())  # 'aaa'

# # round 四舍五入
# print(round(1.545))    #  2
# print(round(1.445))    #  1

# # 切片
# s = slice(1, 4, 2)  # 不常用
# l1 = [1, 2, 3, 4]
# l2 = [3, 2, 5, 9, 6, 7]
#
# print(l1[1:4:2])  # [2, 4]
# print(l2[1:4:2])  # [2, 9]
# print(l1[s])    # [2, 4]
# print(l2[s])    #[2, 4]


# # ======= 掌握 =======
# # zip拉链函数 一个对一个,没有对应的就报错
# v1 = 'hello'
# v2 = [111, 222, 333, 444, 555]
# res = zip(v1, v2)
# print(list(res))    # [('h', 111), ('e', 222), ('l', 333), ('l', 444), ('o', 555)]


# # ======= 掌握 =======
# __import__()
import time
# import 'time'   # 报错
# 变量名 = __import__('time')
# x = __import__('time')
# x.sleep(3)



# # ======= 掌握 =======
# 下周:反射

 

 

 

Guess you like

Origin www.cnblogs.com/2722127842qq-123/p/12677747.html