华科我爱科比 发表于 2016-5-26 15:21:28

谢谢分享。。。。

zhengge 发表于 2016-5-30 10:03:33

没看懂。。。最后一个写的是啥啊。。。{:10_266:}

诸天花雨 发表于 2016-6-8 13:22:20

似懂非懂ing

ndibao 发表于 2016-6-29 11:31:51

小甲鱼老师,能不能详细讲一下 插件方式 的用法啊?代码看不懂尼

ultramodel 发表于 2016-7-6 10:25:48

学习了

过河的小卒 发表于 2016-7-8 11:54:04

Mixin机制貌似就是通过修改对象的__dict__属性来添加或删除属性和方法

第三段的super()没看懂,是为了解决菱形继承?

泳爸 发表于 2016-8-13 20:46:10

受益匪浅,谢谢楼主,说最后看不懂的同学可以慢慢理解下,拿AFeature来说,原理就是把AFeature的get_a_value方法的   对象(为了方便叫做a对象 吧)   给了 c对象,具体怎么给就是:c对象的__dict__=a

意思就是说,c对象一提到a对象的名字:get_a_value,就给c对象一个a对象。

如果有什么不对欢迎指正

van314159 发表于 2016-8-15 21:29:14

本帖最后由 van314159 于 2016-8-15 21:41 编辑

首先定义了一个能给对象添加方法的类(PlugIn),具体添加的方法是plugin函数, 即这一句owner.__dict__ = f owner就是类对象,也就是下面的c
接着定义了两个用作例子的类 AFeature BFeature, 它们都是Plugin 的子类,所以它们都有plugin方法.
其中AFeature中的 self._exported_methods.append(self.get_a_value) 就是将AFeature 的方法 贮存到一个列表中,以备plugin或者plugout函数的使用。
最后就是 AFeature().plugin(c) 将c这个实例对象作为参数传入 plugin函数,然后给c添加AFeature的方法。 同时 类Combine 还没有受到影响。

PS. 代码中的 super函数的写法是不是 python2.7的写法? 只写 super().__init__() ,我试了也是可以的。

疾风。意破天晴 发表于 2016-10-14 17:13:38

原来如此。
class PlugIn(object):
    def __init__(self):
      self._exported_methods = []
      
    def plugin(self, owner):
      i = 0
      for f in self._exported_methods:
            owner.__dict__ = f
            i += 1
            print(f,i)
            

    def plugout(self, owner):
      for f in self._exported_methods:
            del owner.__dict__

class AFeature(PlugIn):
    def __init__(self):
      super(AFeature, self).__init__()
      self._exported_methods.append(self.get_a_value)

    def get_a_value(self):
      print ('a feature.')

class BFeature(PlugIn):
    def __init__(self):
      super(BFeature, self).__init__()
      self._exported_methods.append(self.get_b_value)

    def get_b_value(self):
      print ('b feature.')

class Combine:pass

c = Combine()
AFeature().plugin(c)
BFeature().plugin(c)

c.get_a_value()
c.get_b_value()


结果:
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python35-32/7.py
<bound method AFeature.get_a_value of <__main__.AFeature object at 0x0219A070>> 1
<bound method BFeature.get_b_value of <__main__.BFeature object at 0x01B976B0>> 1
a feature.
b feature.
>>>

蛋炒饭妖妖 发表于 2016-11-18 15:56:12

看不懂。。

wonbin2011 发表于 2016-12-25 23:49:39

疾风。意破天晴 发表于 2016-10-14 17:13
原来如此。





    AFeature().plugin(c)
File "mixin.py", line 18, in __init__
    self._exported_methods.append(self.get_a_value)
AttributeError: 'AFeature' object has no attribute '_exported_methods'


为什么我报这个错误, 代码一样的

Coldfengzi 发表于 2017-1-5 19:22:49

完全没看懂,说是说Mixn机制,可例子中完全没看到Mixin字样。网上有这样的例子:

class Dog(Mammal, RunnableMixin, CarnivorousMixin):
    pass


可否能用这类例子来解释一下,为什么要用Mixin,是不是只是一种习惯或规范,其实完全可以:
class Dog(Mammal, Runnable, Carnivorous):
    pass
对不对,只要编写的时候自己注意。

还是后面带了Mixin关键字,冲突方法会被Python解释器自动忽略

Kindling_ 发表于 2017-3-9 23:19:09

class PlugIn(object):
    def __init__(self):
      self._exported_methods = []    #初始化 输出的方法
      
    def plugin(self, owner):
      for f in self._exported_methods:   #对每一个输出的方法 在字典里扩充
            owner.__dict__ = f

    def plugout(self, owner):
      for f in self._exported_methods:    #去掉输出的方法
            del owner.__dict__

class AFeature(PlugIn):
#继承 插件必须由PlugIn 否者报错
    def __init__(self):
      super(AFeature, self).__init__()
#格式就是如此 也可以删掉super()括号中的内容
'''super(AFeature, self).__init__() :super(AFeature, self)
首先找到AFeature的父类(就是类PlugIn)
,然后把类AFeature的对象self转换为类PlugIn的对象
然后“被转换”的类PlugIn对象调用自己的__init__函数。'''
      self._exported_methods.append(self.get_a_value)
#这里直接将PlugIn的sel._exported_methods 移过来!
#self.get_a_value 不能去掉self, 这个函数也需要self来指向。

#通过AFeature().plugin(c) 将 get_a_value存入字典中 形式为c.get_a_value(owner.__dict__)
#c.get_a_value = self.get_b_value   这时候的self B->A , 调用就可以A调用B的 self.get_b_value!

    def get_a_value(self):
      print ('a feature.')

class BFeature(PlugIn):
    def __init__(self):
      super(BFeature, self).__init__()
      self._exported_methods.append(self.get_b_value)

    def get_b_value(self):
      print ('b feature.')

class Combine:
    pass

c = Combine()
AFeature().plugin(c)
BFeature().plugin(c)
#将AB 中的方法 像“插件”的形式插入到c中。
c.get_a_value()
c.get_b_value()

'''  
    1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,
       产生了一个super对象;
    2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
    3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;
    4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数
       只调用一次(如果每个类都使用super);
    5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一
       个父类函数被调用多次。'''

jackche0214 发表于 2017-3-29 11:55:27

其实从AFeature类开始理解应好理解一点,当u类实例化时,那么就进入__init__,则会有super(AFeaTure,self).__init__()这句代码执行,那么AFeature类就会得到一个_exported_methods的属性(因为继承自PlugIn).然后下一句就是把get_a_value这个方法存到列表中去待用。然后当AFeature实例化完毕后也会有基类的plugin方法,然后将c赋值进去时,c就是那个owner,然后就会owner.__dict__ = f这一句来把get_a_value保存给c。

Heather_zero 发表于 2017-4-12 11:12:51

jiexinren 发表于 2015-8-3 16:04
这个在我电脑上无法运行啊(3.4.3,64位版本)
Traceback (most recent call last):
File "E:/桌面/j ...

我的一样,根本无法运行

太阳花田 发表于 2017-4-24 10:32:10

e,看得不是很懂

阿飞23 发表于 2017-6-16 11:21:32

jiexinren 发表于 2015-8-3 16:04
这个在我电脑上无法运行啊(3.4.3,64位版本)
Traceback (most recent call last):
File "E:/桌面/j ...

我的也运行不了

1114288530 发表于 2017-7-25 14:39:09

最后一个一知半解。。。还是多看几遍吧,,,

cashchen17909 发表于 2017-7-27 13:53:35

f.__name__是啥意思呀。。哪位帮忙解释下。。{:10_266:}

cashchen17909 发表于 2017-8-2 21:05:21

插件模式完全看不懂{:10_266:}{:10_266:}求解{:10_266:}{:10_266:}
页: 1 [2] 3 4 5 6 7
查看完整版本: Python Mixin 编程机制(转)