- 主题:求指点一个hotpatch类的问题
最简代码大致如下。
============= aabbcc.py ===========
class A(object):
def __init__(self):
print("A")
class B(A):
def __init__(self):
A.__init__()
print("B")
=============== ddeeff.py =============
import aabbcc
from aabbcc import A as OrigA
class MyA(OrigA):
def __init__(self):
super(MyA, self).__init__()
print("MyA")
aabbcc.A = MyA
b = B() # 此时报错如下
====
TypeError: unbound method __init__() must be called with MyA instance as fir
st argument (got nothing instead)
====
假设aabbcc.py文件不能改,请教如何写ddeeff.py可以让b=B()顺利通过呢?(功能上保
证hotpatch的MyA和原始的A是完全一致的)
--
修改:CKevin FROM 220.243.191.*
FROM 220.243.191.*
一开始的想法是能不能reload B,让B继承的实际上从OrigA变成MyA。然后发现不能rel
oad指定的类只能reload模块整体。
后来想是不是把B也hotpatch一下,改一下其init方法。但是如果将来aabbcc.py库升级
了,原始代码发生了变化,hotpatch可能就挂了。。。
后来又想能不能只hotpatch一句话“A.__init__()”,变成super之类的,但是好像反射
啊动态修改啊之类的不能改函数里面的指定一句。。。?
最后还想能不能动态让B改为继承MyA也就是动态修改一个类的基类。找了找好像没这个
机制。。。
【 在 CKevin 的大作中提到: 】
: 最简代码大致如下。
: ============= aabbcc.py ===========
: class A(object):
: ...................
--
FROM 220.243.191.*
我试了一下效果和你不一样啊:
一样的代码,在 super(MyA, self).__init__() 这一行报错:
File "d:\Dev\python_projects\try_codegeex\ddeeff.py", line 11, in __init__
super(MyA, OrigA).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of type
改了一下,似乎正常:
aabbcc.py================
class A(object):
def __init__(self):
print("in A.__init__")
class B(A):
def __init__(self):
print("in B.__init__")
A.__init__(self)
ddeeff.py================
import aabbcc
from aabbcc import A as OrigA
from aabbcc import B
class MyA(OrigA):
def __init__(self):
print("in MyA.__init__")
OrigA.__init__(self)
aabbcc.A = MyA
b = B()
输出==========
in B.__init__
in MyA.__init__
in A.__init__
【 在 CKevin 的大作中提到: 】
: 一开始的想法是能不能reload B,让B继承的实际上从OrigA变成MyA。然后发现不能rel
: oad指定的类只能reload模块整体。
: 后来想是不是把B也hotpatch一下,改一下其init方法。但是如果将来aabbcc.py库升级
: ...................
--
FROM 58.135.83.*
aabbcc原始代码里B的初始化不是super.__init,而是A.__init,二者的含义不同导致外
部patch有问题。
查到了一个动态调整bytecode的方法,jit的思想,不过python2不适用。
现在干脆暴力解决了,针对python2.7到python3.10的各个版本都把aabbcc也改一遍,服
务运行前根据所在环境patch对应的基础库。。但是方法太丑了,先凑合用吧,等推动业
务方淘汰了他们的py2再说。。。
【 在 ToSimplicity 的大作中提到: 】
: patch本来就无效
: 试试:
: [code=py]
: ...................
--
FROM 220.243.191.*
呃是的,开头那个错误的详细文本是从一个py2环境摘下来的,py3的错误和py2不一样。
。。
一开始py3其实用来了另一种写法
class MyA(A):
def __init__(self):
if isinstance(self, MyA):
super(..)
else:
A.__init__
然后有的业务反馈说不行,发现他们是py2,于是开始研究怎么搞一下自动兼容环境的,
结果没搞定丢人了哈哈哈。。。
【 在 dyingsun 的大作中提到: 】
: 我试了一下效果和你不一样啊:
: 一样的代码,在 super(MyA, self).__init__() 这一行报错:
: File "d:\Dev\python_projects\try_codegeex\ddeeff.py", line 11, in __init__
: ...................
--
FROM 220.243.191.*