仅为一个对象而不是类替换方法
你好,
我有多个属于同一类的对象
(我没有实施,我不想修改其代码)
现在,我想仅更改一个方法的一种方法(之后
被创建)不添加任何开销
呼叫另一个对象的方法。
这可能吗?
例子
#####这不是我想做的
#####当它覆盖此类所有对象的方法
O1 = Aclass()
O2 = Aclass()
#调用原始方法
O1.Method()
o2.Method()
#覆盖整个班级的方法
Aclass.Method = myMethod
o1.method()#现在新方法
o2.Method()#现在新方法
########什么不起作用,但是我想做什么
O1 = Aclass()
O2 = Aclass()
#调用原始方法
O1.Method()
o2.Method()
#覆盖整个班级的方法
O1.Method = myMethod
o1.method()#现在新方法
o2.Method()#仍然旧的方法
感谢您的任何指示。
P.S.我想,我尝试的是一个计算机科学术语
达到。
如果有人知道它,我也有兴趣学习它。
从函数引入部分导入
班级点:
def __init __(self,x,y):
self.x,self.y = x,y
def show(self,n):
对于(n)范围内的我:
打印"点:(%s,%s)"%(self.x,self.y)
def new_method(obj,func):
def方法(*args,** kw):
返回func(obj, *args,** kw)
返回方法
p1 =点(1,2)
p2 =点(3,4)
def show(self,n):
打印"不是点:%s-%s"%(self.x,self.y)
p2.show =部分(显示,p2)
p1.show(3)
P2.Show(3)
hth,
- -
miki
在10月14日,下午1:50,Hofer
预期的:
... def foo(self):返回"原始"
...
'原来的'
'原来的'
'原来的'
'修改的'
hth,
乔治
10月14日,11:20*上午,乔治·萨基斯(George Sakkis)<乔治·萨克(George.Sak)...
请发布实际不起作用的代码。以下作用为
预期的:
* * >> A类(对象):
* * ... * * def foo(self):返回'原始'
* * ...
* * >> a = a()
* * >> b = a()
* * >> a.foo()
* * '原来的'
* * >> b.foo()
* * '原来的'
* * >> b.foo = lambda:'修改'
* * >> a.foo()
* * '原来的'
* * >> b.foo()
* * '修改的'
hth,
乔治
您正在做的称为MonkeyPatching。我认为这很危险
但每一个他自己。 Python的元编程设施可以处理
它。
Lambda方法可能会泄漏,当
在绑定的方法周围改组(我的对象没有被收集
基本上是预期的。部分方法也很酷,但是
无法可靠地与__getAttr __和__setattr __这样的事情一起工作
我也学到了艰难的方法。可能前进的最佳方法
关于它是定义一个实现您一种方法的新类,并且
使用一些即时的魔法创建一个从继承的新类
您的MonkeyPatch类和当前实例的类:
在[2]中:class main_implementation(对象) :
...:def a(self):
...:打印'a'
...:def b(self,argb ='b'):
...:打印'b说%r'%argb
...:
...:
在[6]中:new_implementation_of_a(对象):
...:def a(self):
...:打印"这是一个新的实现"
...:
...:
在[7]中:mymain = main_implementation()
在[8]中:mymain.a()
一个
在[9]:mymain .__ class__ = type(mymain .__ class __.__ name __+'修改',
(new_implementation_of_a,mymain .__ class__),{})
在[10]:迈曼
out [10]:<__ main __。main_implementationmodified对象,请访问0x0137EA50>
在[11]中:mymain.a()
这是一个新的实现
在[12]中:mymain.b()
B说" B"
当您使用The Fly创建新类时,就会发生魔术
type()内置功能并将其分配给实例的__class __
属性。
祝你好运。
Bruno Desthuilliers写道:
关于新样式类的另一个注释:
您无法在实例上覆盖大多数魔术方法(__*__)。最多
魔术方法仅在类对象上查找。
克里斯蒂安
在10月14日,下午12:28,布鲁诺·德索利尔
...
'原来的'
'原来的'
'原来的'
'修改的'
除了B.FOO是一个普通的函数,而不是一种方法:
... def foo(self):返回"原始名为on%s"%self
...
'原始称为<__ main __。在0xB7C0C56C>>'的对象
'原始称为<__ main __。在0xb7c0c4ec>上的对象'
<功能
Trackback(最近的最新电话):
文件"
文件"
名称:未定义的全局名称"自我"
Trackback(最近的最新电话):
文件"
typeError:
你当然是对的;这就是您最少的测试所获得的;)
它仍然适用于少量修改,将自我绑定到b,默认
争论:
b.foo = lambda self = b:"修改为on%s"%self
functools.partial()解决方案是
这是一个以上的论点。所以我想知道,除了
Callable的精确类型(BOND方法VS功能与Function。
对象)还有其他区别,有理由偏爱一个
另一个 ?如果不是,functools.partial()似乎比
明确调用描述符。
乔治
乔治·萨基斯(George Sakkis A):
(剪)
好的,现在使用真实用例:使用命名函数代替lambda,
并在访问B! - )之前定义功能
一致性 ?可能表演(NB:不基准的 - 可能是
值得一些功课来检查一下)吗?
也许是我开始变得老龄并抵抗新的
想法,但是虽然确实有效,但我将partial()解决方案视为一个
WTF。调用函数。__get__ *是 *明显的[1]获得绑定的方法
函数的方法。
[1]对于任何知道PY的人 THON将功能变成方法,即...
但实际上,方法是专门的部分应用程序,您的
解决方案是完全有效的。
Bruno Desthuilliers Aécrit:
是的。
如果课程是新风格的[1],则只需要调用
独自描述协议以获取界限,即:
(剪)
我要么开始变老,要么我需要一些假期...手动
调用功能。
当然,课程。
(剪)
10月14日,7:50*pm,hofer
虽然我必须识别,但即使阅读了文档,我也不是真的
了解原因。
你好
感谢您的所有答案:
这里有三个建议解决方案的示例:
(我没有成功地用我的解决方案
例子)
############################# ######
导入线程
#一些对象
a = threading.event()
b =螺纹。event()
c =螺纹。event()
d = threading.event()
def run_dly(o):#测试功能
打印o," start",
O.等(1)
打印"停止"
#未修改的测试
run_dly(a)
run_dly(b)
run_dly(c)
run_dly(d)
#新方法
def verbose_wait(self,dly):
打印"冗长",
螺纹。_EVENT.WAIT(self,dly)
###部分实施
从函数引入部分导入
B.Wait =部分(verbose_wait,b)
### with __get__ for New Class
c.wait = verbose_wait .__获取__(c,type(c))
##与旧课程新的
导入新
d.wait = new.instancemethod(verbose_wait,d,type(d))
run_dly(a)
run_dly(b)
run_dly(c)
run_dly(d)
############# 结尾
再次感谢
Hofer
hofer aécrit:
感谢您的所有答案:
这里有三个建议解决方案的示例:
(我没有成功地用我的解决方案
例子)
############################# ######
导入线程
#一些对象
a = threading.event()
b =螺纹。event()
c =螺纹。event()
d = threading.event()
def run_dly(o):#测试功能
打印o," start",
O.等(1)
打印"停止"
#未修改的测试
run_dly(a)
run_dly(b)
run_dly(c)
run_dly(d)
#新方法
def verbose_wait(self,dly):
打印"冗长",
螺纹。_EVENT.WAIT(self,dly)
请注意,鉴于您的用例,您可以在这里使用装饰器
反而...
def verbose(方法):
def _verbose(*args,** kw):
打印"%s ons on%s"%(方法.__ name__,method.im_self)
打印" args:",args," - 夸尔格斯:",kw
返回方法(*args,** kw)
_verbose .__ name __ =" for%s"%方法.__ name______________________________________
返回_verbose
B.等=冗长(B.等)
或者,如果您想要一个更可扩展的 - 和"可逆"解决方案:
类动词(object)类:
def __init __(self,method,ther = none = none,after = none):
#我们只想在这里绑定的方法
obj = getAttr(方法," im_self",无)
如果OBJ没有:
err ="%s预期有界方法,获得%s"%(
类型(self),方法
)
提高价值ERRER(ERR)
self._method =方法
self._before =之前
self._af ter =之后
def _verbose_before(self, *args,** kw):
"""
您为您自己的需求进行动词术和泰勒(Taylor)
或或者将"在"回调之前通过A到动词
可以用方法来调用 *args,** kw
"""
如果可笑(self._before):
self._before(self._method, *args,** kw)
返回
# 默认
m = self._method
打印"即将被称为%s"%(m .__名称__,m.im_self)
打印" args:",args," - 夸尔格斯:",kw
def _verbose_after(self,result, *args,** kw):
"""
您为您自己的需求进行动词术和泰勒(Taylor)
或或者将"后"回调传递给动词
可以用方法来调用,结果, *args,** kw
"""
如果可召唤(self._fter):
self._after(self._method,结果, *args,** kw)
返回
# 默认
m = self._method
打印"%s on%s"%(m .__名称__,m.im_self)
打印" args:",args," - 夸尔格斯:",kw
打印"结果:",结果
def __call __(self, *args,** kw):
self._verbose_before(*args,** kw)
结果= self._method(*args,** kw)
self._verbose_after(结果, *args,** kw)
返回结果
def drop(self):
"""还原原始方法..."""
obj = self._method.im_self
delattr(obj,self._method .__名称__)
B类(对象):
def __init __(自我,名称):
self.name =名称
def等待(self,dly = 42):
返回"%s.wait(%s)"%(self.name,dly)
B1 = B('B1')
B2 = B('B2')
打印B1.Wait()
打印B2.Wait()
B1.Wait = verbosemethod(B1.Wait)
打印B1.Wait()
打印B2.Wait()
b1.wait.drop()
打印B1.Wait()
打印B2.Wait()
def之前(m, *args,** kw):
打印"测试之前"
印刷M,args,kw
def之后(m,r, *args,** kw):
打印"测试后"
打印M,R,Args,KW
b1.wait = verbosemethod(b1.wait,之前=之前,ather = after)
打印B1.Wait()
打印B2.Wait()
b1.wait.drop()
打印B1.Wait()
打印B2.Wait()
hth
标签: python