我刚刚重新打包了程序。以前,所有模块都位于“ Whyteboard”程序包下,而“ fakewidgets”程序包则包含一堆虚拟GUI测试对象。

现在,我所有的模块都在软件包中,例如whyteboard.gui,whyteboard.misc,whyteboard.test-这就是现成的假部件所在的地方。

现在,在运行测试时,我遇到一个异常,

  File "/home/steve/Documents/whyteboard/whyteboard/gui/canvas.py", line 77, in __init__
    wx.ScrolledWindow.__init__(self, tab, style=wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN)
TypeError: unbound method __init__() must be called with ScrolledWindow instance as first argument (got Canvas instance instead)


这是
 有关课程

class Canvas(wx.ScrolledWindow):
    def __init__(self, tab, gui, area):
        wx.ScrolledWindow.__init__(self, tab, style=wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN)


但是,除单元测试外,我的程序可以正确加载和运行。代码是相同的,只是我的测试导入的代码与从新软件包中提取的代码不同。

之前:

import os
import wx

import fakewidgets
import gui
import lib.mock as mock

from canvas import Canvas, RIGHT, DIAGONAL, BOTTOM
from fakewidgets.core import Bitmap, Event, Colour

from lib.configobj import ConfigObj
from lib.pubsub import pub
from lib.validate import Validator


现在:

import os
import wx

import whyteboard.test
import whyteboard.gui.frame as gui

from whyteboard.lib import ConfigObj, mock, pub, Validator
from whyteboard.gui.canvas import Canvas, RIGHT, DIAGONAL, BOTTOM
from whyteboard.test.fakewidgets.core import Bitmap, Event, Colour, PySimpleApp


值得一提的是,fakewidgets软件包在使我的程序认为它正在使用wxPython类的过程中做了一些欺骗,即使它们是模拟的。
这是由whyteboard.test.fakewidgets的__init__导入的模块中

class Window(object):
    def __init__(self, parent, *args, **kwds):
        self.parent = parent
        self.Enabled = True
        self.calls = []
        self.size = (0, 0)
        self.captured = False

    def GetClientSizeTuple(self):
        return (0, 0)
        self.captured = True

    def GetId(self):
        pass

    def Fit(self):
        pass

    def SetFocus(self):
        pass

    def PrepareDC(self, dc):
        pass

    def Destroy(self):
        pass

...


class ScrolledWindow(Window):
    def SetVirtualSize(self, *size):
        pass

    def SetVirtualSizeHints(self, *size):
        pass

import wx
wx.__dict__.update(locals())

最佳答案

当您import whyteboard.test时,会自动运行whyteboard.test.fakewidgets.core吗?我认为问题是在模拟代码运行之前就创建了Canvas。这说明了切换。

>>> import wx
>>> class Test1(wx.Window):
...    pass
...
>>> wx.Window = object
>>> class Test2(wx.Window):
...    pass
...
>>> dir(Test1)[:10]
['AcceleratorTable', 'AcceptsFocus', 'AcceptsFocusFromKeyboard',
 'AddChild', 'AddPendingEvent', 'AdjustForLayoutDirection',
 'AssociateHandle', 'AutoLayout', 'BackgroundColour', 'BackgroundStyle']
>>> dir(Test2)[:10]
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
 '__getattribute__', '__hash__', '__init__', '__module__', '__new__']


在您发布的旧文件中,fakewidgets是在canvas之前导入的。

如果那不起作用,请将此代码直接放在import wx之后的任何其他导入之前:

import inspect

class DummyMeta(type):
    def __new__(meta, clsname, bases, clsdict):
        if clsname == 'Canvas':
            lineno = inspect.stack()[1][2]
            print "creating Canvas with mro: {0}".format(inspect.getmro(bases[0]))
            print "file:{0}:{1}".format(__file__, lineno)
        return super(DummyMeta, meta).__new__(meta, clsname, bases, clsdict)

class ScrolledWindowDummy(wx.Window):
    __metaclass__ = DummyMeta

wx.ScrolledWindow = ScrolledWindowDummy


这将表明在进行模拟之前将创建一个Canvas类,并将为您提供发生这种情况的文件和行号。本质上,对于MRO,您应该看不到wx的任何内容。如果我错了,那么您将根本看不到任何东西,因为在创建名为“ Canvas”的任何类之前,您将用一个没有ScrolledWindowDummy类型的类替换了DummyMeta

09-27 20:42