华科我爱科比
发表于 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:}