3

This is an attempt to make a number increase when a button is clicked.

def something():
  CP = 0
  counter = StringVar()
  counter.set("0")
  def click():
    global CP
    global counter
    CP = CP + 1
    counter.set(str(CP))
  label5=Label(window, textvariable=counter, font=("Georgia", 16), fg="blue")
  button5=Button(window, text='Make a Clip', command=click)
  label5.pack()
  button5.pack()

There is a name error on line 6 of this section.

Traceback (most recent call last):
File "D:\Program Files\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
  return self.func(*args)
File "D:\Program Files\Python\Python36\Paperclips.py", line 14, in click
  CP = CP + 1
NameError: name 'CP' is not defined

What is wrong with the code?

1 Answers1

0

CP is not a global but is a nonlocal. Just replace global by nonlocal so the variable is found in the embedding function.

There's a subtle difference with counter. You don't need to do that for the other variable counter since you're just using the reference (it's different with +=).

Simple standalone example:

def a():
    x = 0
    def b():
        nonlocal x  # tell python that x is in the function(s) above
        x += 1
    b()
    print(x)

a()

prints 1

fun difference when using += or append with lists:

def a():
    l = []
    def b():
        l.append(435)
    b()
    print(l)

a()

that works, now:

def a():
    l = []
    def b():
        # nonlocal l   # uncomment for it to work
        l += [435]
    b()
    print(l)

a()

this should be equivalent, but with += l needs to be "declared" as nonlocal (more here: Concatenating two lists - difference between '+=' and extend() and the relevant answer: https://stackoverflow.com/a/24261311/6451573)

For integers, though, += cannot be replaced by a function call BTW because of integers immutability. So nonlocal remains the sole viable option.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219