YDJCJ 发表于 2021-8-16 17:51:54

小有所获

xn1 发表于 2021-9-18 15:51:59

看来还是得多学习

ReinhardV 发表于 2021-9-21 20:06:07

第三个没看懂

lzb1001 发表于 2022-2-25 08:33:10

本帖最后由 lzb1001 于 2022-2-25 10:52 编辑

# 以下代码必须在python3下运行!!!

class PlugIn(object): # 定义一个能给对象扩展方法类PlugIn(最顶层基类)
    def __init__(self): # 初始化定义
      self.methods = [] # 对象方法列表

    def add(self, owner): # 定义add函数(具体添加方法),owner是类对象(也就是下面的c)
      # 关键代码:修改对象的行为(而不是修改类的),利用__dict__来扩展对象的方法!!!
      for f in self.methods: # 当f在对象方法列表中则循环
            owner.__dict__ = f # 将f赋值给对象属性(对象的方法中原本没有方法f,通过赋值扩展方法f)
            # _ _name_ _是一个Python预定义全局变量,在模块内部是用来标识模块名称的
            # 如果模块是被其他模块导入的,_ _name_ _的值是模块的名称,主动执行时它的值就是字符串“_ _main_ _”

    # 没有下面这段代码,最后返回结果也一样!!!
    def minors(self, owner): # 定义minors函数,owner是类对象(也就是下面的c)
      # 关键代码:修改对象的行为(而不是修改类的),利用__dict__来扩展对象的方法!!!
      for f in self.methods: # 当f在对象方法列表中则循环
            del owner.__dict__ # 删除对象属性赋值(对象的方法中原本有方法f,通过del删除方法f)?


class AFeature(PlugIn): # 定义PlugIn子类AFeature(子类AFeature继承了基类Plugin上面所有的方法)
    def __init__(self): # 初始化定义
      super(AFeature, self).__init__() # 自动找到基类的方法,并传入self参数,此处super().__init__()也可
      self.methods.append(self.get_a_value) # 方法列表添加get_a_value的值
      # 上面这句代码是将AFeature的方法添加(贮存)到一个列表中,以备add或者minors函数的使用

    def get_a_value(self): # 定义get_a_value函数
      print('a feature.') # 打印输出字符串a feature.


class BFeature(PlugIn): # 定义PlugIn子类BFeature(子类BFeature继承了基类Plugin上面所有的方法)
    def __init__(self): # 初始化定义
      super(BFeature, self).__init__() # # 自动找到基类的方法,并传入self参数,此处super().__init__()也可
      self.methods.append(self.get_b_value) # 方法列表添加get_b_value的值
      # 上面这句代码是将AFeature的方法添加(贮存)到一个列表中,以备add或者minors函数的使用

    def get_b_value(self): # 定义get_b_value函数
      print('b feature.') # 打印输出字符串b feature.


# class Combine: # 也可以执行
class Combine(AFeature, BFeature): # 定义Combine子类,同时继承AFeature、BFeature两个基类
    pass # ……


c = Combine() # 将Combine子类实例化(c是Combine子类的实例对象)


AFeature().add(c) # 将c这个实例对象作为参数传入add函数(super帮助找到add函数在子类AFeature的基类PlugIn的方法中)
BFeature().add(c) # 将c这个实例对象作为参数传入add函数(super帮助找到add函数在子类AFeature的基类PlugIn的方法中)


c.get_a_value() # 给实例对象c添加AFeature的方法,具体为:找到get_a_value函数并执行
c.get_b_value() # 给实例对象c添加BFeature的方法,具体为:找到get_b_value函数并执行

# 以上就是Mixin编程机制的插件方式,即通过使用__dict__这个特殊属性来扩展对象c的方法的同时确保类Combine不会受到影响

print(AFeature.__bases__) # 打印输出类AFeature的基类,输出格式(<class '__main__.基类名'>,)
print(BFeature.__bases__) # 打印输出类BFeature的基类,输出格式(<class '__main__.基类名'>,)
print(Combine.__bases__) # 打印输出类Combine的基类,输出格式(<class '__main__.基类名'>, ……)
print(PlugIn.__bases__) # 打印输出最顶层类PlugIn的基类,输出格式(<class 'object'>,)
print(AFeature.__bases__, BFeature.__bases__, Combine.__bases__, PlugIn.__bases__) # 打印输出所有类的基类,输出格式为以上的汇总,中间以空格间隔

运行后返回结果:

a feature.
b feature.
(<class '__main__.PlugIn'>,)
(<class '__main__.PlugIn'>,)
(<class '__main__.AFeature'>, <class '__main__.BFeature'>)
(<class 'object'>,)
(<class '__main__.PlugIn'>,) (<class '__main__.PlugIn'>,) (<class '__main__.AFeature'>, <class '__main__.BFeature'>) (<class 'object'>,)

辅助说明:

1、首先定义了一个能给对象扩展方法的类(PlugIn),具体添加的方法是plugin函数, 即这一句:
owner.__dict__ = f
owner就是类对象,也就是下面的c。

2、接着定义了两个用作例子的类AFeature、BFeature, 它们都是Plugin 的子类,所以它们都继承了plugin的方法。其中AFeature中的:
self._exported_methods.append(self.get_a_value)
就是将AFeature 的方法 添加(贮存)到一个列表中,以备plugin或者plugout函数的使用。

3、最后就是:
AFeature().plugin(c)
将c这个实例对象作为参数传入 plugin函数,然后给c添加AFeature的方法。 通过插件方式使用__dict__类Combine不会受到影响。

PS. 代码中的 super函数的写法只写 super().__init__() 也是可以的。

ASM023 发表于 2022-3-2 19:46:05

还可以坚持下去

墨羽鱼 发表于 2022-4-8 17:21:31

van314159 发表于 2016-8-15 21:29
首先定义了一个能给对象添加方法的类(PlugIn),具体添加的方法是plugin函数, 即这一句 owner就是类对象, ...

self._exported_methods不是空列表吗?这里是什么意思呢
for f in self._exported_methods:
            owner.__dict__ = f

LDQ17 发表于 2022-8-5 15:48:23

{:10_249:}

Tkhmily 发表于 2024-7-18 19:07:21

{:10_250:}
页: 1 2 3 4 5 6 [7]
查看完整版本: Python Mixin 编程机制(转)