newbie question: unbound method

Hi everybody:

I am beginning with Python and with wxPython, and I am having some problems.

I am developing a GUI for an academic image processing application. Until now, I am just trying to link the GUI with the function that I wrote (filterf, as you can see in the code below).

The function works fine alone (just read the image and makes some basic processing), but I have not been able to make it work through the GUI.

The error that appears is: �TypeError: unbound method filterf() must be called with MyEvent instance as first argument (got FiltroD instance instead)�. What am I missing?

Sorry for this really silly question. I appreciate any help.

Thanks,

Ali S.

###Here is the code (also in the attach):
import os
import wx
import Image
import ImageOps
import numpy as n

class MyEvent:
    def __init__(self):
        pass

    def filterf(self, input, output):
        """apply a directional filter on an image"""
        im = Image.open(input)
        out = ImageOps.expand(im, 1, 1)
        a = list(im.getdata())
        a1 = n.array(a).reshape(im.size[1],im.size[0])
        kernel = n.array([[-1,1,1],[-1,-2,1],[-1,1,1]]).astype(float)
        dotc = n.median(n.arange(1,kernel.shape[1]+1))
        dotr = n.median(n.arange(1,kernel.shape[0]+1))
        for i in n.arange(1,dotc):
            a1 = n.column_stack((a1[:,0],a1,a1[:,a1.shape[1]-1]))
        for i in n.arange(1,dotr):
            a1 = n.vstack((a1[0],a1,a1[a1.shape[0]-1]))
        a2 = a1.copy().astype(float)
        for i in n.arange(dotr-1,a1.shape[0]-(dotr-1)):
            for j in n.arange(dotc-1,a1.shape[1]-(dotc-1)):
                if kernel.sum()==0: skernel = 1
                elif kernel.sum()!=0: skernel = kernel.sum()
                a2[i,j] = (((kernel*a1[(i-1):(i+dotr),(j-1):(j+dotr)]).sum())/skernel).round()
        a3 = a2.copy()
        for i in n.arange(1,dotc):
            a3 = n.delete(a3, [0], axis=1)
            a3 = n.delete(a3, [a3.shape[1]-1], axis=1)
        for i in n.arange(1,dotr):
            a3 = n.delete(a3, [0], axis=0)
            a3 = n.delete(a3, [a3.shape[0]-1], axis=0)
        a4 = (((a3-a3.min())/n.diff([a3.min(),a3.max()]))*255).round().astype(int)
        im.putdata(list(n.ravel(a4)))
        im.save(output, "TIFF")

class FiltroD(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(300,150))

        vbox = wx.BoxSizer(wx.VERTICAL)
        stline = wx.StaticText(self, 11, '')
        vbox.Add(stline, 1, wx.ALIGN_CENTER|wx.TOP, 45)
        sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP)
        vbox.Add(sizer, 1, wx.ALIGN_CENTER)
        self.SetSizer(vbox)
        self.Bind(wx.EVT_BUTTON, self.OnOK, id=wx.ID_OK)

    def OnOK(self, event):
        MyEvent.filterf(self, "myimage.tif", "output.tif")

class MainWindow(wx.Frame):
  def __init__(self,parent,id,title):
    wx.Frame.__init__(self,parent,wx.ID_ANY, title, size = (200,100))
    #panel = wx.Panel(self, -1)
    self.CreateStatusBar() # A StatusBar in the bottom of the window

    # Setting up the Filter menu
    filt = wx.Menu()
    filt.Append(201,"&Filtro","Aplicar filtro")

    # Creating the menubar.
    menuBar = wx.MenuBar()
    menuBar.Append(filt,"&Filtro") # Adding the "filtmenu" to the MenuBar
    self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
    wx.EVT_MENU(self, 201, self.OnFiltro)

    self.Show(True)
    self.Centre()

  def OnFiltro(self,e):
    """ Launch the filtro12 dialog"""
    f12d = FiltroD(self, -1, 'Filtro')
    f12d.ShowModal()
    f12d.Destroy()

app = wx.PySimpleApp()
frame = MainWindow(None, -1, "Imagenes")
app.MainLoop()

image1.py (2.94 KB)

···

_________________________________________________________________
FREE pop-up blocking with the new MSN Toolbar - get it now! http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/

Hi Ali,

I think you need to create a MyEvent object and then call the filterf function.

eg.

    def OnOK(self, event):

        filter = MyEvent()

       filter.filterf("myimage.tif", "output.tif")

Bruce.

True.

Also, in your case, it seems that the filter method is actually just a function, defined as a method although it does not reference the class or the instance at all. Why not just use a function? Python isn’t Java, not everything needs to be defined in a class, and using a function would be clearer in your case.

If you do want filter to be a method and not a stand-alone function, you could define it as a ‘staticmethod’. With Python 2.4 and above, use the @staticmethod decorator: add @staticmethod on the line before ‘def filter(self, input, output)’, and remove the ‘self’ argument from the method definition. With this change, the code you posted would work as is.

  • Tal
···

On 5/21/07, Bruce at blazer bruce@blazertech.net wrote:

Hi Ali,

I think you need to create a MyEvent object and then call the filterf function.

eg.

    def OnOK(self, event):
        filter = MyEvent()
       filter.filterf("myimage.tif", "output.tif")

The error that appears is: "TypeError: unbound method filterf() must be
called with MyEvent instance as first argument (got FiltroD instance
instead)". What am I missing?

This is telling you that you are calling a method thats not attached
to an object yet. This usually means you haven't created an
instance. It then says the first argument (ie self) should be a
MyEvent instance but its getting a FiltroD instance instead.

If we look at where you call filterf:

class MyEvent:
   def filterf(self, input, output):
       """apply a directional filter on an image"""
      ....

class FiltroD(wx.Dialog):
   def OnOK(self, event):
       MyEvent.filterf(self, "myimage.tif", "output.tif")

we see exactly what the error said. You are calling the
method via athe class and passing the self of the FiltroD
method as the first argument.

You need to either make filterf a standalone function that
expects a filterD as its first argument (or create a
static/class methodof MyEvent if you prefer), or create
an instance of MyEvent and call the filterf method on that.

HTH,

···

"Ali Santacruz" <amsd2013@hotmail.com> wrote

--
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld

Thank you very much Bruce, Tal and Alan,

the code works now!

and thanks for your explanations, I am going to try the different ways,

Kind regards,

Ali S.

···

From: "Alan Gauld" <alan.gauld@btinternet.com>
Reply-To: wxPython-users@lists.wxwidgets.org
To: wxpython-users@lists.wxwidgets.org
Subject: [wxPython-users] Re: newbie question: unbound method
Date: Mon, 21 May 2007 08:35:21 +0100

"Ali Santacruz" <amsd2013@hotmail.com> wrote

The error that appears is: "TypeError: unbound method filterf() must be
called with MyEvent instance as first argument (got FiltroD instance
instead)". What am I missing?

This is telling you that you are calling a method thats not attached
to an object yet. This usually means you haven't created an
instance. It then says the first argument (ie self) should be a
MyEvent instance but its getting a FiltroD instance instead.

If we look at where you call filterf:

class MyEvent:
   def filterf(self, input, output):
       """apply a directional filter on an image"""
      ....

class FiltroD(wx.Dialog):
   def OnOK(self, event):
       MyEvent.filterf(self, "myimage.tif", "output.tif")

we see exactly what the error said. You are calling the
method via athe class and passing the self of the FiltroD
method as the first argument.

You need to either make filterf a standalone function that
expects a filterD as its first argument (or create a
static/class methodof MyEvent if you prefer), or create
an instance of MyEvent and call the filterf method on that.

HTH,

--
Alan Gauld
Author of the Learn to Program web site
Learning to program

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/