3sm1r
3sm1r

Reputation: 530

using a function to update one of its argument permanently

How can I create a function that updates the value of one of its arguments? Consider the following example:

def f(x,b):
    b+=1
    return x*b

b=4
a=f(1,b)
print a
print b

The update of b is valid only inside the function, but b keeps its original value after the function has been used. Of course, in this case I could just solve the problem by returning also b and then using a,b=f(1,b) but I do not want to do it.

What should I do if I actually want b to be updated and change its value without returning it explicitly ?

Upvotes: 0

Views: 823

Answers (4)

LevB
LevB

Reputation: 953

Functions can have attributes which can be assigned internally. Those attributes can retain the values you want the function to hold throughout multiple calls.

def f(x,b=None):
    try:
    f.b+=1
except AttributeError:
    f.b=b # first pass (initialize the attribute) 
return x*f.b

b=4
a=f(1,b) # initialize 
print (f(2))
print (f(2))
print (f(2))

Output:

10
12
14

Upvotes: 1

Sazzy
Sazzy

Reputation: 1994

To manage global states of your variables, consider using classes instead. Your function only modifies the value of b locally to your function. If you don't want to have all of your code inside a class, but only a part of it, and keep the b value, make @classmethods instead. Here is an example you may try:

class Store:
    b = [4]

    @classmethod
    def f(cls, x):
        cls.b[0] += 1
        return x * cls.b[0]

Store.f(1) # -> 5
Store.f(1) # -> 6
Store.f(1) # -> 7

Please note, this changes how you can call into the function, as b, or in this case, the cls.b, is in the namespace of the class. You can get/set/reset the b value by setting on the class directly, just like this: Store.b = [42].

Upvotes: 1

tdelaney
tdelaney

Reputation: 77347

You want to hold state which is a strong indication that a class is needed. I assume that second and following calls to f should use the saved b variable. Here is a class that keeps that state and uses a magic method to make it callable:

class F:

    def __init__(self, b):
        self.b = b

    def __call__(self, x):
        self.b += 1
        return x * self.b

b = 4
f = F(b)
a = f(1)
print(a, f.b)

Upvotes: 3

Michael Butscher
Michael Butscher

Reputation: 10959

Python doesn't support call by reference. There are only ugly workarounds like e.g.

def f(x,b):
    b[0]+=1
    return x*b[0]

b=[4]
a=f(1,b)
print a
print b[0]

Upvotes: 1

Related Questions