Franco Barrionuevo
Franco Barrionuevo

Reputation: 161

Is it possible to call a variable from a method without passing as a return variable?

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

Answers (3)

Exalted Toast
Exalted Toast

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

Max Shouman
Max Shouman

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

ffm_nosoup
ffm_nosoup

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

Related Questions