2017-05-08 14 views
0

내가 덮어 쓰려 (패치) 런타임에 클래스. 제 경우에는 gui2py를 사용하고 MenuItems의 이미지를 지원하지만 최종 프로그램의 코드를 변경하지 않고 일부 기능을 재정의하려고합니다.파이썬 : 재정 (원숭이 패치) 클래스

즉 나는

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() 

이 작동하지 않습니다했다. 이처럼 내가 수정하면

직접 GUI 그리고/menu.py

class MenuItem(Component): 
    #add this line 
    image = InitSpec() 

이 작동하는 데모

Download This 작동

+0

나는이 문제가 그냥 클래스 속성으로 기능을 설정하여 __init__''패치 것 같아요 잘 작동합니다. 당신은 그렇게하기 전에 [인스턴스 메소드 (https://docs.python.org/2/library/types.html#types.MethodType)으로 바꿀 것이다. –

+0

는 어떻게 든'예상대로 작동 __init__', 그것은 변화를 만드는 클래스 속성 _image_입니다. 소스에서 직접 수정되거나 덮어 쓰기되는 경우 – Magen

+0

오류 메시지가 무엇입니까? –

답변

0

이 좋아, 연구의 시간 후에 것 같습니다 올바른 방법은 클래스에 속성을 추가 할 수 있습니다 :

class _MenuItem(gui.MenuItem): 
    image = gui.component.InitSpec() 

# and then:   
gui.MenuItem = _MenuItem 

는 이제

+0

아무 문제가 함께 없다'gui.MenuItem.image = ...'(MenuItem's 메타 클래스는'__setattr__'를 정의하고 어떤 식 으로든 방해'는 제외). 나는 당신의 솔루션이 대부분의 경우에도 작동한다고 생각하지만 오류 메시지는 이전의 접근 방식이 작동하지 않는 이유를 파악하는 데 도움이됩니다. 'gui.MenuItem'이'image' 속성을 가지고 있다면 여전히 동일한 속성을 가지고 있습니다. '__mro__'에서'_MenuItem'의 인스턴스를 먼저 해결하는 새로운'이미지'입니다. 또한 객체가 패치 전에 그 참조를 저장했다면'type (_MenuItem()) == OriginalMenuItem'과 같은 타입 검사는 실패합니다. –