Im ersten Snippet bar.do_something_expensive
verweisen Sie auf das Funktionsobjekt, a_package.baz.do_something_expensive
auf das in diesem Moment verwiesen wird. Um wirklich "monkeypatch" zu machen, müssten Sie die Funktion selbst ändern (Sie ändern nur, worauf sich die Namen beziehen); Das ist möglich, aber das wollen Sie eigentlich nicht.
Bei Ihren Versuchen, das Verhalten von zu ändern a_function
, haben Sie zwei Dinge getan:
Im ersten Versuch machen Sie do_something_expensive zu einem globalen Namen in Ihrem Modul. Sie rufen jedoch auf a_function
, das in Ihrem Modul nicht nach Auflösungsnamen sucht, sodass es immer noch auf dieselbe Funktion verweist.
Im zweiten Beispiel ändern Sie das, worauf es sich a_package.baz.do_something_expensive
bezieht, sind aber bar.do_something_expensive
nicht magisch daran gebunden. Dieser Name bezieht sich immer noch auf das Funktionsobjekt, nach dem es beim Initialisieren gesucht hat.
Der einfachste, aber alles andere als ideale Ansatz wäre, sich zu ändern, um bar.py
zu sagen
import a_package.baz
def a_function():
print a_package.baz.do_something_expensive()
Die richtige Lösung ist wahrscheinlich eines von zwei Dingen:
- Definieren Sie neu
a_function
, um eine Funktion als Argument zu verwenden und dies zu nennen, anstatt zu versuchen, sich einzuschleichen und zu ändern, auf welche Funktion es schwer zu codieren ist, oder
- Speichern Sie die Funktion, die in einer Instanz einer Klasse verwendet werden soll. So machen wir den veränderlichen Zustand in Python.
Die Verwendung von Globals (das ist es, was das Ändern von Dingen auf Modulebene von anderen Modulen ist) ist eine schlechte Sache , die zu nicht wartbarem, verwirrendem, nicht testbarem, nicht skalierbarem Code führt, dessen Fluss schwer zu verfolgen ist.
from module import non_module_member
und Affen-Patches auf Modulebene sind aus diesem Grund nicht kompatibel und werden im Allgemeinen am besten vermieden.apackage
. H.from foo import bar
ist jedoch in Ordnung und wird gegebenenfalls empfohlen.