0

Below is my code:

 def before_Upd(self):
     count = 0
     def Update(self):
         if count = 0:
             a = something
             b = something
         count = count+1

         x= min(a,newa)
         self.after(2000,self.Update)             

I am trying to call a function within another function. I Only want the initial values to be set to something. And from the next iteration onwards to compare the previous minimum value (i.e x) with a new value to get a new minimum(x again).. This has to be done every 2 seconds. The problem here is, Update() is never called. I know this would be something silly but I am not able to figure it out.. TIA for all the suggestions!

4
  • 2
    self.after() is indented to be part of the Update() function. Commented Oct 14, 2015 at 6:49
  • If the self.after() call is meant to be part of the Update() function, then there is indeed nothing here to call the Update() function in the first place. You either need to call it explicitly at least once. Commented Oct 14, 2015 at 6:53
  • @MartijnPieters : I tried doing what you said, calling explicitly Update() but it throws an error saying :"Classname_Task" has no attribute Update(). How do I go about it? Commented Oct 14, 2015 at 6:58
  • Ah, remove self.; Update is not a method. Commented Oct 14, 2015 at 7:12

2 Answers 2

1

I can see three problems:

  • self.after() might well call the nested function, but it itself part of Update(), so it'll never get called. Either unindent it (so it is now part of the parent function and called just once), or call Update() explicitly in before_Upd() at least once.

  • Update() is not a method; it doesn't exist on self. Remove the self. part from the call:

    self.after(2000, Update)
    
  • count is not a closure variable; it is a local variable, because you assign to it.

    Mark it as nonlocal:

     def before_Upd(self):
         count = 0
         def Update(self):
             nonlocal count
             if count = 0:
                 a = something
                 b = something
             count = count+1
    
             x= min(a,newa)
    
         self.after(2000, Update)             
    
Sign up to request clarification or add additional context in comments.

1 Comment

One more problem: self.Update won’t exist on the object since Update is just local to the current execution of before_Upd.
0

Indentation in Python is important. Consider the sample below and how the internal function test_in is being invoked by the external function test_out:

#!/usr/bin/python3 -B

def test_out(arg1):
    cnt = 0
    def test_in(arg2):
        nonlocal cnt
        print('arg2 is {}'.format(arg2))
        if cnt == 0:
            print('cnt is 0')
        cnt += 1

    # indentation here is part of test_out body calling test_in
    test_in(arg1)

if __name__ == '__main__':
    for i in range(3):
        test_out(i)

In your case, you need to fix the indentation of the self.after call.

Also note that you might run into an UnboundLocalError with your count variable. You may need to mark it with the nonlocal keyword or move it to have a greater scope and reference it as a global.

Another issue is the self.after(2000,self.Update) line. It should be self.after(2000, Update) because Update is not bound to self.

2 Comments

No reason to make a non-global variable suddenly global. Python 3 has nonlocal for that.
@poke: Yes, I think you caught me with your comment while I was editing it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.