Python Forum
function with 'self' input parameter errors out with and without 'self' called
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
function with 'self' input parameter errors out with and without 'self' called
#1
Hi,

I've got something that just cropped up. This is not a tkinter question, though I'm using tkinter in the app. I've got some functions that are called from some tkinter objects, so I had to define them with 'self' as an input parameter, as the code was requiring that.

Except, when I'm trying to call the function from within another function, it gives me an error if I include 'self', and gives me an error if I exclude 'self'.

Here is the function definition. I should also stipulate that this is not defined within a class:

def updateMainTasks(self):
    global mydict
   

    cnxn= sqlite3.connect(sqlFileLoc)
    mydict, data = getCboMainTaskList()

    #try is to catch that mydict-key.get value exception when it is null
    try:
        #compensating for when Headline is not filled in yet.
        if HeadlineMainTask.get()== '':
            thisTask =cboMainTask.get()
        elif HeadlineMainTask.get() != cboMainTask.get():
            thisTask=HeadlineMainTask.get()
        else: thisTask = cboMainTask.get()

        if cboMainTask.get().__len__() !=0:
            sql='Select TaskID, Headline, Requester, Headline, Explanation,RequestDate, \
                Complete, Acknowledged,DueDate from MainTasks \
                where TaskID = ' + str(mydict[thisTask]) 

            df=pd.read_sql_query(sql, cnxn)
    
            
    
            #clear then fill cboTask
            cboMainTask['values']=list(mydict)
            
            #thiscur.close()
    
            #Requester
            RequesterMainTask.delete(0,'end')
            try:
                RequesterMainTask.insert(0,df.iat[0,2])
            except:
                pass
    
            #Headline
            HeadlineMainTask.delete(0,'end')
            HeadlineMainTask.insert(0,df.iat[0,3])
        
            #Explanation
            ExplanationMainTask.delete('1.0','end')
            ExplanationMainTask.insert('1.0',df.iat[0,4])
        
            #Request Date
            RequestDateMainTask.delete(0,'end')
            try:
                RequestDateMainTask.insert(0,df.iat[0,5])
            except:
                pass
    
            #Due Date
            DueDateMainTask.delete(0,'end')
            try:
                DueDateMainTask.insert(0,df.iat[0,8])
            except:
                pass
    
            #Complete
        
            if df.iat[0,6]=='1':
                ChkButtonCompleteMainTask.select()
            else:
                ChkButtonCompleteMainTask.deselect()
    
            #Acknowledged
            if df.iat[0,7]== '1':
                ChkButtonAcknowledgedMainTask.select()
            else:
                ChkButtonAcknowledgedMainTask.deselect()
        
    
            #filter down cboTaskSteps
            cboTaskStep.set('')

            sql2="Select StepDescription, TaskStepID \
                from TaskSteps where TaskID = " + str(mydict[thisTask]) 
            thiscur=cnxn.cursor()
            thiscur.execute(sql2)
            cnxn.commit()
            mydict=dict(thiscur.fetchall())
            data = list(mydict.keys())
            cboTaskStep['values']=list(mydict)
            if mydict.__len__() > 0:
                cboTaskStep.current(0)
                
            #update taskStepList
            taskStepList.delete(0,'end')
            for c in list(mydict):
                taskStepList.insert('end',c)
            
            #filter down cboSubTasks
            #print(str(mydict[cboTaskStep.get()]))
            cboSubTasks.set('')
            #If no record, don't do it.
            if mydict.__len__()> 0:
                sql2="Select StepDescription, SubTaskStepID \
                from SubTasks where TaskStepID = " + str(mydict[cboTaskStep.get()]) 
                thiscur=cnxn.cursor()
                thiscur.execute(sql2)
                cnxn.commit()
                mydict=dict(thiscur.fetchall())
                data = list(mydict.keys())
                cboSubTasks['values']=list(mydict)
            if mydict.__len__() > 0:
                cboSubTasks.current(0) 
                
        #clears the screen when you hit the clear button
        else:
            
            sql='Select TaskID, Headline, Requester, Headline, Explanation,RequestDate, \
                Complete, Acknowledged,DueDate from MainTasks \
                where TaskID is null' 
            RequesterMainTask.delete(0,'end')
            HeadlineMainTask.delete(0,'end')
            ExplanationMainTask.delete('1.0','end')
            RequestDateMainTask.delete(0,'end')
            DueDateMainTask.delete(0,'end')
            ChkButtonCompleteMainTask.deselect()
            ChkButtonAcknowledgedMainTask.deselect()
    
        cnxn.close()
    
        #unset dirty flag on Save button
        btnsaveMainTasks.config(bg="silver")
    
        #update history of selections at top of screen
        displayHistory()
    except:
        pass
    
    return
Here is the code from where it is being called, down towards the bottom. I can't include the whole program as it is too extensive.

def saveMainTasks():
    #saves dirty fields to database
    
    global ChkComplete1
    global ChkAcknowledged1
    global mydict
    mydict, data = getCboTaskList()
    #Try to save an existing record with a TaskID
    if cboTask.get() != '':
        sql="Update MainTasks set \
            Requester = '" + RequesterMainTask.get() + "', \
            Headline = '" + HeadlineMainTask.get() + "', \
            Explanation= '" + ExplanationMainTask.get('1.0','end') + "', \
            RequestDate= '" + RequestDateMainTask.get() + "', \
            DueDate= '" + DueDateMainTask.get() + "', \
            Complete = '" + str(ChkComplete1.get()) + "', \
            Acknowledged= '" + str(ChkAcknowledged1.get()) +"' \
        Where TaskID = " + str(mydict[cboTask.get()])
    #If that fails, try to add a new record
    else:
        sql="Insert into MainTasks (Requester, Headline, Explanation, RequestDate, DueDate, Complete, Acknowledged) \
        Values('" +RequesterMainTask.get()+ "', '" + HeadlineMainTask.get()+ "', '" + ExplanationMainTask.get('1.0','end') + "', '"+ RequestDateMainTask.get() + "', ' \
         " + DueDateMainTask.get()+ "', '" + str(ChkComplete1.get()) + "','" + str(ChkAcknowledged1.get()) + "')"


    cnxn= sqlite3.connect(sqlFileLoc)
    c=cnxn.cursor()
   
    c.execute(sql)
    cnxn.commit()
      
    #refresh combo box after delete
    c.execute('Select Headline, TaskID  from MainTasks')
    cnxn.commit()
    mydict=dict(c.fetchall())
    data = list(mydict.keys())
    
    updateMainTasks()
    
    #don't add key reference again.  only one works.
    cboTask.config(values=data)
    
    c.close()
    cnxn.close()
    btnsaveMainTasks.config(bg="silver")
This is also where that updateMainTasks function is being called, from a widget. This is where I think it is requiring me to use 'self', even though it does not call it with a parameter at this point.
btnRefreshMainTask = tk.Button(maintaskframe, command=updateMainTasks, text = "Refresh", bg="silver")
btnRefreshMainTask.place(x=col2+240, y=y7, width=60)
The error I get if I don't call it with the 'self' parameter is:

Output:
updateMainTasks() missing 1 required positional argument: 'self'
The error I get when I do call with 'self' is:

Output:
name 'self' is not defined
Thing is, the was working previously, and I don't know what change caused it to break. Any ideas appreciated. I'm finding the constraints imposed by tkinter a little exasperating.
Reply
#2
More information is needed, where and how is this being used.
You need to show more code.
Reply
#3
Thanks Yoriz. I've updated my original post to show the function from where it is being called.
Reply
#4
Sorry but the code you have shown is pretty irrelevant to the problem at hand, maybe I asked for the wrong thing.
can you show the definition of updateMainTasks()
You are using self which is normally used with a class but it doesn't look like you are using classes.
by your error it seems like you have a function that is defined as follows
def updateMainTasks(self):
    ....
what is it that you actually need to pass into the function, if you don't need to pass in anything you can remove the self parameter from the definition.
BashBedlam likes this post
Reply
#5
Sorry. You asked for something about when and where it was being used, and that's how I interpreted it. I've updated the top post to include the function definition. Hope that helps.
Reply
#6
def updateMainTasks(self):
This is a function not a method of a class, self is not required and you do not use self anywhere inside the function it can be removed.
def updateMainTasks():
Reply
#7
Yes, logic would tell me that. However, that is not what I was running into. The interpreter was blowing up no matter what I did.

I did the following, in an attempt to use one function ( updateMainTasksWrapper) to be called from the widget, and the main function to be called from within other functions. It seems to be working at the moment. WHY, I have no idea. I've tried to find the website again where it says that the widget will tack on an unseen 'self' when it makes its call, but I can't find it. I think it was in a reply on a stack overflow question. I'd have to try to remember the exact phrase I was searching on when I found that.

def updateMainTasksWrapper():
    updateMainTasks()


#======================================================================

def updateMainTasks():
    cnxn= sqlite3.connect(sqlFileLoc)
    mydict, data = getCboMainTaskList()
    ......
Reply
#8
"self" is used to accept the instance argument in an instance method call just as "cls" is used to accept the class argument for a class method. The words "self" and "cls" are conventions and the arguments could be named anything, but it is best to follow conventions.

In Python you call an instance method like this "instance.method(args)" where "instance" is an instance of a class, "method" the name of the instance method, and args are whatever additional arguments are passed. Python converts this to "class.method(instance, args)" prepending the instance as the first argument to the method call. The instance argument becomes "self" inside the body of the method.

I think "update_main_tasks()" is a function, not a method and it should not have a "self" argument. When you bind this function to a tkinter widget, the function gets called with an argument, probably a tuple containing information about the event that caused the function to be called. You should find out what this information is. If you don't need the information you should modify the binding to not pass the argument. This is easily done using a lambda expression.
button = tk.Button(root, command=lambda event:update_main_tasks())
Reply
#9
If it's the case that you have an event handler that when called takes an event parameter but you want to be able to call it yourself and also have no need to use the event parameter just give it a default of None.
def updateMainTasks(event=None):
Reply
#10
(Jan-15-2022, 01:26 PM)deanhystad Wrote: command=lambda event:update_main_tasks()

This seems to be working, on an initial try. Thanks deanhystad. My first time trying a lambda. I was lamenting the corner I was painted into with the other way not allowing any function parameters. I'll experiment more with this. Again, thanks.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  difference between forms of input a list to function akbarza 6 1,102 Feb-21-2024, 08:02 PM
Last Post: bterwijn
  Multiple variable inputs when only one is called for ChrisDall 2 510 Oct-20-2023, 07:43 PM
Last Post: deanhystad
  determine parameter type in definition function akbarza 1 610 Aug-24-2023, 01:46 PM
Last Post: deanhystad
  Function parameter not writing to variable Karp 5 996 Aug-07-2023, 05:58 PM
Last Post: Karp
  Couldn't install a go-game called dlgo Nomamesse 14 3,208 Jan-05-2023, 06:38 PM
Last Post: Nomamesse
  [ERROR] ParamValidationError: Parameter validation failed: Invalid type for parameter gdbengo 3 11,201 Dec-26-2022, 08:48 AM
Last Post: ibreeden
Information How to take url in telegram bot user input and put it as an argument in a function? askfriends 0 1,133 Dec-25-2022, 03:00 PM
Last Post: askfriends
  how can a function find the name by which it is called? Skaperen 18 3,561 Aug-24-2022, 04:52 PM
Last Post: Skaperen
  Showing an empty chart, then input data via function kgall89 0 994 Jun-02-2022, 01:53 AM
Last Post: kgall89
  input function question barryjo 12 2,772 Jan-18-2022, 12:11 AM
Last Post: barryjo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020