Ich möchte Affenpatches nur teilweise sicher mit Python machen

Was ist Affenpflaster?

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)

Gegenstand

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 !!

Rundungscode

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

Referenz-URL

↓ ↓ Ich möchte so schreiben ↓ ↓

sample.py


import setting
print(round(2.5)) #=> 3.0

Generieren Sie settings.py

1. Affenpflaster vorerst

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
Ich dachte, es war ein Erfolg, weil es angezeigt wurde

sample.py


import setting
print(round(2.5)) #=> 3.0
import sample2

sample2.py


print(round(2.5)) #=> 3.0
=> Nicht sicher !!!!?

2. Hängen Sie den Namensraum des Anrufers in die Stapelverfolgung ein

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
Ich frage mich, ob die Datei getrennt wurde ... Der Einstellungsprozess wird in sample2 nicht durchgeführt ...

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.

3. Ersetzen Sie builtins.import direkt und rufen Sie zum Zeitpunkt des Imports die Affen-Patch-Funktion auf.

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

Zusammenfassung

Schließlich konnte ich einen Affen-Patch nur mit dem Modul implementieren, in dem die Importeinstellung geschrieben ist.

Recommended Posts

Ich möchte Affenpatches nur teilweise sicher mit Python machen
Ich möchte Dunnetts Test in Python machen
Ich möchte mit Python ein Fenster erstellen
Ich möchte eine Variable in einen Python-String einbetten
Ich möchte in Python schreiben! (2) Schreiben wir einen Test
Ich möchte eine Datei mit Python zufällig testen
Ich möchte am Ende etwas mit Python machen
Ich möchte so etwas wie Uniq in Python sortieren
Ich möchte eine schöne Ergänzung zu input () in Python hinzufügen
Ich möchte in der Einschlussnotation drucken
Ich möchte eine Python-Umgebung erstellen
Ich möchte APG4b mit Python lösen (nur 4.01 und 4.04 in Kapitel 4)
Ich möchte den vollständigen Text mit elasticsearch + python durchsuchen
[Python / AWS Lambda-Ebenen] Ich möchte nur Module in AWS Lambda-Ebenen wiederverwenden
Ich möchte ein Spiel mit Python machen
Ich möchte eine in Python in PDF konvertierte Tabelle wieder in CSV konvertieren
Ich möchte verschachtelte Dicts in Python zusammenführen
Ich möchte einen Teil der Excel-Zeichenfolge mit Python einfärben
Ich möchte mit Python in eine Datei schreiben
Ich möchte den Fortschritt in Python anzeigen!
Ich möchte eine Prioritätswarteschlange erstellen, die mit Python (2.7) aktualisiert werden kann.
Python-Programm ist langsam! Ich möchte beschleunigen! In einem solchen Fall ...
Ich möchte einen Python-Generator viele Male iterieren
Ich möchte schnell UUID generieren (Gedenknotiz) ~ Python Edition ~
Ich möchte mit einem Knopf am Kolben übergehen
Auch mit JavaScript möchte ich Python `range ()` sehen!
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
[Python] Ich möchte aus einer verschachtelten Liste einen Taple machen
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Ich möchte R-Datensatz mit Python verwenden
Ich möchte einen Quantencomputer mit Python betreiben
Ich möchte Strings in Kotlin wie Python manipulieren!
[Python] Ich möchte nur den Index verwenden, wenn ich eine Liste mit einer for-Anweisung schleife
Ich möchte eine Python-Datenquelle in Re: Dash verwenden, um Abfrageergebnisse zu erhalten
[Python] Ich möchte einen gemeinsamen Satz zwischen numpy erhalten
Ich möchte viele Prozesse von Python aus starten
Ich habe versucht "Wie man eine Methode in Python dekoriert"
Ich möchte eine Nachricht von Python an LINE Bot senden
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
Ich möchte Python mit VS-Code ausführen können
[Python] Wie man PCA mit Python macht
Ich möchte mit Python debuggen
Möchten Sie mit Python Selenium auf allgemeine Zwecke warten?
Was tun, wenn in Python minus Null angezeigt wird?
MacBookPro-Setup Schließlich möchte ich eine Neuinstallation durchführen
Ich habe eine Funktion zum Laden des Git-Erweiterungsskripts in Python geschrieben
Ich habe versucht, ein missverstandenes Gefangenendilemma in Python zu implementieren
Wenn Sie einer Variablen in Python einen CSV-Export zuweisen möchten
Ich wollte so etwas wie Elixirs Pipe in Python machen
[Einführung] Ich möchte mit Python einen Mastodon-Bot erstellen! 【Anfänger】
Ich habe ein Skript geschrieben, um Webseiten-Links in Python zu extrahieren
Ich möchte eine Pipfile erstellen und im Docker wiedergeben
Ich habe versucht, PLSA in Python zu implementieren
Ich habe versucht, Permutation in Python zu implementieren
Führen Sie eine nicht rekursive Euler-Tour in Python durch
Ich habe ein Pay-Management-Programm in Python erstellt!
So machen Sie R chartr () in Python
Ich habe versucht, PLSA in Python 2 zu implementieren
Ich möchte ein Glas aus Python verwenden