zoukankan      html  css  js  c++  java
  • python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)

    介绍装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式

    有时候需要給类添加额外的东西,有些东西很频繁,每个类都需要,如果不想反复的复制粘贴到每个类,可以动态添加。

     1 # coding=utf-8
     2 
     3 def create_class_attribution(cls):
     4     def _inner(*args, **kwargs):
     5         if not hasattr(cls, 'xx'):
     6             cls.xx = 1
     7 
     8         def funa(self, a, b):
     9             return a + b
    10 
    11         if not hasattr(cls, 'funa'):
    12             cls.funa = funa
    13         return cls(*args, **kwargs)
    14 
    15     return _inner
    16 
    17 
    18 class Base():
    19     # __metaclass__ = Meta
    20     def __new__(cls, *args, **kwargs):
    21         if not hasattr(cls, 'yy'):
    22             cls.yy = 2
    23         return super().__new__(cls)
    24 
    25     def funb(self, a, b):
    26         return a + b
    27 
    28 
    29 class MyType(type):
    30     def __new__(cls, name, bases, attrs):
    31         attrs['zz'] = 3
    32         attrs['func'] = lambda self, a, b: a + b
    33         return super(MyType, cls).__new__(cls, name, bases, attrs)
    34 
    35 
    36 class MyMixin():
    37     def __init__(self, *args, **kwargs):
    38         if not hasattr(self, 'ww'):
    39             self.__class__.ww = 4
    40 
    41     def fund(self, a, b):
    42         return a + b
    43 
    44 
    45 @create_class_attribution
    46 class A(MyMixin, Base, metaclass=MyType):
    47     pass
    48 
    49 
    50 a = A()
    51 print (a.xx)
    52 print (a.yy)
    53 print (a.zz)
    54 print (a.ww)
    55 print (a.funa(1, 2))
    56 print (a.funb(3, 4))
    57 print (a.func(5, 6))
    58 print (a.fund(7, 8))

    这样就完成了给类添加属性和方法了。

    A类什么都不写,a的实例就有4个自定义的方法和4个属性了。

    1、其中,元类,是在代码不进行任何对类的调用,就已经运行了。可以打印下就知道了。这和其他几个惰性的添加属性和方法不同 。相关的可以看下菜鸟教程的java单例模式中的饿汉和饱汉,我喜欢用饱汉模式,程序启动速度快,特别是有人喜欢把io操作的结果赋值给类属性还仍然使用饿汉模式,会大幅降低程序启动速度。

    关于元类的理解,就是创建类的类,默认是有type类来创建所有类。用的时候把普通类想象成实例,元类想象成类,这样就能脑袋转过弯使用他了。

    所以元类可以影响类的__dict__,但影响不了实例的__dict__。

    2、装饰器版本,没啥好说的了,给类添加属性

    3、继承版本,很普通的,和mixin版本代码都一模一样。继承是is的关系,mixin是can的关系,mixin充当的功能应该类似于java的接口,但带了方法实现。

    比如动物类,有猪、燕子、麻雀,这三个都可以继承动物类,燕子和麻雀除了可以继承动物类,还可以继承一个有飞行方法的mixin类。猪就不要继承这个mixin了。燕子是动物,燕子能够飞行,但燕子不是飞行。is can或者has的概念。

    除这四种方式外,还有组合的方式加属性,见(二)

  • 相关阅读:
    09-23
    21-9-18日记1
    paho mqtt库使用记录
    UIS8811 的 NB-IOT 初认识(21-9-10工作记录 )
    go语言之异常捕获
    【原创】数据库基础之PostgreSQL
    【原创】Linux基础之fail2ban
    【原创】大叔经验分享(132)mac os 12启动idea失败
    【原创】大数据基础之Hadoop(3)hdfs diskbalancer
    【转】常用 Git 命令清单
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9211521.html
Copyright © 2011-2022 走看看