Monkey-Patches erweitern oder ändern den dynamischen Sprachcode (z. B. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy usw.) zur Laufzeit, ohne den ursprünglichen Quellcode zu ändern. Wie es geht.
[Siehe 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)
Round wird in Python 3 nicht mehr gerundet
print round(2.5) # => 3.0
print(round(2.5)) # => 2
Es scheint, dass die Rundungsfunktion von Python3 als Gleitkomma behandelt wird. Damit Sie dies durch Runden nutzen können !!
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 #Eingebaute Funktionen sind eingebaut
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]
#Weil es Fälle gibt, in denen importlib verwendet wird, um den Anrufer abzurufen und zu importieren.
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
Ersatz der letzten Zeile.py
# ${module} :Zielmodul, ${function} :Zielfunktion
replacing = imp.load_module('temp', *imp.find_module(${module}))
setattr(replacing, '${function}', ${benutzerdefinierte Funktion})
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
=> Das einmal importierte Modul bleibt in sys.modules erhalten, und beim zweiten Import wird auf sys.module verwiesen, und der Code wird nicht aufgerufen.
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]
#Weil es Fälle gibt, in denen importlib verwendet wird, um den Anrufer abzurufen und zu importieren.
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
Schließlich konnte ich einen Affen-Patch nur mit dem Modul implementieren, in dem die Importeinstellung geschrieben ist.
Recommended Posts