Python scope inside a nested function inside a class?

Inside seta, you define a function

    def afunction(self):
        self.a = 4

...that would set self.a to 4 if it would ever be called. But it's not called anywhere, so a is unchanged.


The problem is that there are multiple self variables. The argument passed into your inner function overwrites the scope of the outer.

You can overcome this by removing the self parameter from the inner function, and making sure you call that function in some way.

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
    def seta(self):
        def afunction():  # no self here
            self.a = 4
        afunction()       # have to call the function
    def geta(self):
        return self.a

As others have mentioned, afunction is never called. You could do something like this:

class A:
    def __init__(self):
        self.a = 1

    def seta(self):
        def afunction(self):
            self.a = 4
        afunction(self)

    def geta(self):
        return self.a

a = A()
print a.a
a.seta()
print a.a

Here we actually call afunction and explicitly pass it self, but this is a rather silly way to set the attribute a -- especially when we can do it explicitly without the need for getters or setters: a.a = 4

Or you could return the function:

def seta(self):
    def afunction(): #Don't need to pass `self`.  It gets picked up from the closure
        self.a = 4
    return afunction

and then in the code:

a = A()
a.seta()()  #the first call returns the `afunction`, the second actually calls it.

Tags:

Python