Reputation: 161
I'm writing a library for some bird population parameters in different ecosystems. In order to not repeat code I want to take some variables defined in a previous method and use these in other method without passing this variable as return. For example
class asd:
def __init__(self):
self.a = a
self.b = b
def fun1(self):
self.a2 = self.a * 2
def fun2(self):
self.a4 = self.a2*2 #this is what i want to do.
Upvotes: 0
Views: 102
Reputation: 819
As @ffm_nosoup has stated, this is not possible as requested because of function scopes.
The general way to accomplish this sort of thing is to store any values you want in the class itself, and reference those values. Assuming the result of fun1
is expensive to compute and you don't want to recompute it when possible, your specific example might be rewritten as:
class Asd:
def __init__(self):
self.a = a
self.b = b
self.a2 = None
def fun1(self):
self.a2 = self.a * 2
def fun2(self):
if self.a2 is None:
raise ValueError("Attempted to use result from fun1() without first calling fun1()")
self.a4 = self.a2 * 2
Alternatively, you might auto-call fun1
, but this can be a riskier design choice in some instances.
def fun2(self):
if self.a2 is None:
self.fun1()
self.a4 = self.a2 * 2
A third option is to just use a cache, which will only compute the function once and reuse that result in the future. (As Mark Ransom points out in the comments, this will lead to issues if you ever need to recompute the result of fun1.)
from functools import lru_cache
class Asd:
def __init__(self):
self.a = a
self.b = b
@lru_cache
def fun1(self):
return self.a * 2
def fun2(self):
self.a4 = self.fun1() * 2
Upvotes: 1
Reputation: 1331
A good option to achieve this without messing with variable scopes, is to initialise self.a2
with a sentinel value, typically None
.
Then you can check self.a2
inside your fun2()
and react accordingly, i.e. call fun1()
before the expression:
class asd:
def __init__(self):
self.a = a
self.b = b
self.a2 = None
def fun1(self):
self.a2 = self.a * 2
def fun2(self):
if self.a2 is None:
self.fun1()
self.a4 = self.a2*2
Actually you can also get rid of the sentinel var, and use hasattr()
as a check:
class asd:
def __init__(self):
self.a = a
self.b = b
def fun1(self):
self.a2 = self.a * 2
def fun2(self):
if not hasattr(self, "a2")
self.fun1()
self.a4 = self.a2*2
This may be useful if your self.a2
could be assigned any value, None
included, thus defeating the sentinel purpose. It's not the case though, since you're using it in a mathematical expression.
Upvotes: 1
Reputation: 107
No this isn't possible variables always only exist in their scope. you need to work with global variables to achieve what you want or you have to overwrite your instance variables. It depends on the problem you'd like to solve and the design of your code.
Upvotes: -1