Les patchs Monkey étendent ou modifient le code de langage dynamique (par exemple Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.) au moment de l'exécution sans modifier le code source d'origine. Comment faire.
[Voir wiki](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%82%AD%E3%83%BC%E3%83%91%E3% 83% 83% E3% 83% 81)
Le rond n'est plus arrondi en Python 3
print round(2.5) # => 3.0
print(round(2.5)) # => 2
Il semble que la fonction round soit traitée comme une virgule flottante depuis python3. Pour que vous puissiez l'utiliser en arrondissant !!
def custom_round(x, d=0):
import math
p = 10 ** d
return float(math.floor((x * p) + math.copysign(0.5, x)))/p
print(custom_round(2.5)) #=> 3.0
sample.py
import setting
print(round(2.5)) #=> 3.0
setting.py
import builtins #Les fonctions intégrées sont intégrées
def custom_round(x, d=0):
import math
p = 10 ** d
return float(math.floor((x * p) + math.copysign(0.5, x)))/p
builtins.round = custom_round # monkey patch
sample.py
import setting
print(round(2.5)) #=> 3.0
sample.py
import setting
print(round(2.5)) #=> 3.0
import sample2
sample2.py
print(round(2.5)) #=> 3.0
python
import inspect, imp
import builtins
def custom_round(x, d=0):
import math
p = 10 ** d
return float(math.floor((x * p) + math.copysign(0.5, x)))/p
frame = [frame for (frame, filename, _, _, _,_) in
inspect.getouterframes(inspect.currentframe())[1:]
if not 'importlib' in filename and not __file__ in filename][0]
#Parce qu'il y a des cas où importlib est utilisé pour obtenir l'appelant et importer.
frame.f_locals['round'] = custom_round
sample.py
import setting
print(round(2.5)) #=> 3.0
import sample2
sample2.py
print(round(2.5)) #=> 2
Remplacement de la dernière ligne.py
# ${module} :Module cible, ${function} :Fonction cible
replacing = imp.load_module('temp', *imp.find_module(${module}))
setattr(replacing, '${function}', ${fonction personnalisée})
frame.f_locals[${module}] = replacing
sample.py
import setting
print(round(2.5)) #=> 3.0
import sample2
sample2.py
import setting
print(round(2.5)) #=> 2
=> Le module importé une fois est conservé dans sys.modules, et dans la seconde importation, il est référencé à partir de sys.module et le code n'est pas appelé.
setting.py
import inspect, imp
import builtins
def custom_round(x, d=0):
import math
p = 10 ** d
return float(math.floor((x * p) + math.copysign(0.5, x)))/p
def hooking():
frame = [frame for (frame, filename, _, _, _,_) in
inspect.getouterframes(inspect.currentframe())[1:]
if not 'importlib' in filename and not __file__ in filename][0]
#Parce qu'il y a des cas où importlib est utilisé pour obtenir l'appelant et importer.
frame.f_locals['round'] = custom_round
class Importer(object):
old_import = __import__
def new_import(self, *args, **kwargs):
if args[0] == __name__: hooking()
return self.old_import(*args, **kwargs)
hooking()
import builtins
builtins.__import__ = Importer().new_import
sample.py
import setting
print(round(2.5)) #=> 3.0
import sample2
sample2.py
import setting
print(round(2.5)) #=> 3.0
Enfin, j'ai pu implémenter un patch monkey uniquement avec le module où le paramètre d'importation est écrit.
Recommended Posts