Ich möchte eine Klasse zur Laufzeit überschreiben (patchen). In meinem Fall benutze ich gui2py und möchte einige seiner Funktionen außer Kraft setzen, um Image in MenuItems zu unterstützen, ohne den Code des endgültigen Programms zu ändern.Python: Überschreiben (Affepatching) Klasse
das heißt ich habe
overrides.py
import gui,wx
# this is the tricky line
gui.MenuItem.image = gui.component.InitSpec()
def menu__init__(self, parent, *args, **kwargs):
gui.menu.wx_DummyWindow.__init__(self, parent, *args, **kwargs)
wx.MenuItem.__init__(self, parentMenu=parent,id=kwargs['id'],text=kwargs['label'],kind=kwargs['style'])
if self.GetKind() == wx.ITEM_SEPARATOR:
self.parent.AppendSeparator()
else:
self.SetHelp(kwargs['help'])
# The next is added code
img = kwargs.get("image")
if img:
self.SetBitmap(wx.Bitmap(img))
self.parent.AppendItem(self)
gui.menu.wx_MenuItem.__init__ = menu__init__
program.py
from overrides import *
with gui.Window(name='win', ):
with gui.MenuBar(name='menu',):
with gui.Menu(label=u'File', name='file',):
gui.MenuItem(label=u'Quit', name='quit', image='quit.png')
gui.main_loop()
Das wird nicht funktionieren.
Allerdings, wenn ich ändern direkt gui/menu.py
class MenuItem(Component):
#add this line
image = InitSpec()
Dann funktioniert es
Download This für eine Arbeits Demo
Ich schätze das Problem ist, Sie patching '__init__' nur durch die Funktion als ein Klassenattribut festlegen. Sie sollten es zuvor in eine [Instanzmethode] (https://docs.python.org/2/library/types.html#types.MethodType) umwandeln. –
Irgendwie funktioniert das "__init__" wie erwartet, es ist die Klasseneigenschaft _image_, die die Änderung vornimmt. Wenn es in der Quelle direkt geändert oder überschrieben wird – Magen
Was ist Ihre Fehlermeldung dann? –