How can I set a class variable from inside a function inside another function?
var.py
class A:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def seta(self):
def afunction():
self.a = 4
afunction()
def geta(self):
return self.a
run.py
cA = A()
print cA.a
cA.seta()
print cA.a
print cA.geta()
python run.py
1
1
1
why does a not equal 4 and how can I make it equal 4?
Edit:
Thanks everyone - sorry, I just saw now. I accidentally was off by a _ in one of my names.... so my scope is actually all ok.
A function defined inside another function is called a nested function. Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them.
The scope of a nested function is inside the enclosing function, i.e. inside one of the constituent blocks of that function, which means that it is invisible outside that block and also outside the enclosing function. A nested function can access other local functions, variables, constants, types, classes, etc.
Inner functions, also known as nested functions, are functions that you define inside other functions. In Python, this kind of function has direct access to variables and names defined in the enclosing function.
A function which is defined inside another function is known as inner function or nested functio n. Nested functions are able to access variables of the enclosing scope. Inner functions are used so that they can be protected from everything happening outside the function.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With