J'essaie de remplacer une fonction définie dans une classe afin de modifier sa fonction (comme dans les rouages internes) sans changer le code réel. Je n'ai jamais fait cela auparavant, donc j'ai eu des problèmes lors du remplacement. Changer le code me fera accéder au paquet dans ma bibliothèque python qui n'est pas vraiment une option.
Par exemple, si le module s'appelait testMOD
class testMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
Ensuite, j'importerais testMOD, définirais une classe (mytest = testMOD ()) et accèderais à la fonction définie dans la classe, testFunc, et la changerais en fonction déjà définie.
Par exemple,
from somemodule import testMOD
mytest = testMOD()
def alternativeFunc(self, variable):
var = variable
self.something = var + 1.2
#problem here
mytest.testFunc = alternativeFunc
Comme vous pouvez le voir, si je remplace manuellement (?) La fonction de la classe par ma fonction définie, elle ne fonctionnera pas correctement. Cela ne donne pas d'erreurs de syntaxe, cependant, le problème est que la fonction remplacée pense que le "soi" est une autre variable pour la fonction et dit qu'elle nécessite un autre argument pour la variable "variable" (je suppose que ce n'était pas un bon nom).
Ce que je veux faire, c'est que la fonction de remplacement soit exactement la même chose que la fonction remplacée, mais avec du code supplémentaire ou quelques modifications mineures. Cependant, le "soi" ne fonctionne pratiquement pas comme il devrait l'être dans une classe. Y aurait-il un moyen d'implémenter correctement une fonction définie pour remplacer une fonction d'une classe importée?
Je propose 4 solutions, du pire au meilleur (à mon humble avis), mais bien sûr cela dépend aussi de vos contraintes spécifiques:
Remplacez la méthode d'instance (1): j'utilise le fait que les fonctions sont des descripteurs en Python, pour pouvoir utiliser le __get__
méthode sur AlternativeFunc
pour l'obtenir comme méthode de l'instance mytest
et écraser la méthode testFunc
de l'instance mytest
(sans écraser la méthode de classe ):
class testMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
print('Original:', self.something)
def alternativeFunc1(self, variable):
var = variable
self.something = var + 1.2
print('Alternative1:', self.something)
mytest1 = testMOD()
mytest1.testFunc(10) # Original: 22
mytest1.testFunc = alternativeFunc1.__get__(mytest1, testMOD)
mytest1.testFunc(10) # Alternative1: 11.2
mytestX = testMOD()
mytestX.testFunc(10) # Original: 22
Remplacez la méthode d'instance (2): cette fois, j'utilise types.MethodType
qui est un peu plus lisible que la première solution:
import types
class testMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
print('Original:', self.something)
def alternativeFunc1(self, variable):
var = variable
self.something = var + 1.2
print('Alternative1:', self.something)
mytest1 = testMOD()
mytest1.testFunc(10) # Original: 22
funcType = types.MethodType
mytest1.testFunc = funcType(alternativeFunc1, mytest1)
mytest1.testFunc(10) # Alternative1: 11.2
mytestX = testMOD()
mytestX.testFunc(10) # Original: 22
Effectuez une correction de singe de la méthode de classe. À la différence de la première méthode, elle modifie le comportement de n'importe quelle instance de la classe:
class testMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
print('Original:', self.something)
def alternativeFunc2(self, variable):
var = variable
self.something = var + 1.2
print('Alternative2:', self.something)
mytest2 = testMOD()
mytest2.testFunc(10) # Original: 22
testMOD.testFunc = alternativeFunc2
mytest2.testFunc(10) # Alternative2: 11.2
mytestX = testMOD()
mytestX.testFunc(10) # Alternative2: 11.2
Créez une classe héritée de testMOD
pour remplacer la méthode:
class testMODNew(testMOD):
def testFunc(self, variable):
var = variable
self.something = var + 1.2
print('Alternative3:', self.something)
mytest3 = testMODNew()
mytest3.testFunc(10) # Alternative3: 11.2
Vous pouvez patch singe cette méthode comme suit:
class TestMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
print(f'original {self.something}')
def alternativeFunc(self, variable):
var = variable
self.something = var + 1.2
print(f'alternative {self.something}')
if __name__ == '__main__':
test_original = TestMOD()
test_original.testFunc(12)
TestMOD.testFunc = alternativeFunc
test_alternate = TestMOD()
test_alternate.testFunc(12)
original 24
alternative 13.2
vérifier l'héritage de classe en python, pour créer votre propre classe personnalisée:
from somemodule import TestMOD
class YourCustomClass(TestMOD):
# change the function
def test_func(self, variable):
#
#
your_class = YourCustomClass()
your_class.test_func(x)