0

The idea behind this is, simply said, I want to have:

def test (a,b):
    a += b
    return a

>>>test(0,1)
>>>1

So it records that a = 1, and saves it as its new parameter for a. So if I return to this function again and run it again, the result should be 2. Also I was wondering, is there any way to check the contents of a parameter? Apologies about noob questions, I'm literally just starting to learn python.

Thank you!

crescent1033
  • 5
  • 1
  • 6
  • I am not sure what your questions are. If you run that program twice, the result will be the same both times. Variables passed in python arguments do not change their values outside the function. – Sam Craig Feb 23 '18 at 04:02
  • 1
    wait. you mean you want to run the program once, and it is 1, and then run it again, and you think it should be 2? If so, that isn't how a program is going to work. The interpreter only has access to the variables/values available to it at runtime. You have never "saved" a new variable for `a` – matisetorm Feb 23 '18 at 04:02
  • Please clarify, do you want to run the function multiple times in the same script and have the value persist, or do you want to run the script multiple times and have it persist. If the second option is true, search for python shelve -- you can store values offline that way. However, this is likely not really what you want, why don't you tell us what you are trying to accomplish with this. – SteveJ Feb 23 '18 at 04:06

3 Answers3

3

First off: this isn't quite how Python 'works' with regard to locally-scoped variables (nor indeed how a lot of languages do) and if you're considering it for a serious application then you may have to reevaluate.

That said... you can leverage (read: abuse) mutable defaults to this end, without placing variables in the global namespace. Something like:

def fn(a=0, b=0, *, storage={}):
    if not storage:
        storage.update(locals())
    storage['a'] += b
    return storage['a']

>>> fn(0, 1)
1
>>> fn(20, 1) # value of a no longer matters
2
>>> fn(b=3)
5
  • that's a cool hack. Although I don't think there's a point in continuing to have a parameter `a` when `a` is never used. Technically that is the requested behavior, just not a useful behavior. – Matthew Ciaramitaro Feb 23 '18 at 04:33
2

In most languages, the parameters of a function are local variables, and as such they do not exist outside of the function definition.

it's impossible to access a or b outside of test

What you wanted to do was the following

def test(b):
    return a + b
#create a global variable `a`
a = 0
#update global a
a = test(1)

or alternatively:

def test(lst, b):
    #we can update a list by changing the values at indices
    lst[0] += b
#initialize accumulator as list index 0
lst = [0]
test(lst, b)

The second method works because lists contain pointers to their values, so when a local variable lst is made in test it has the same pointer to the first element. When we change the value it points to, the value will change in the original list.

Matthew Ciaramitaro
  • 1,184
  • 1
  • 13
  • 27
1

Using decorator to do this, for this is just a demo, if you like you can also store a in db or file:

def store_a(func):
    record_a = None

    def wrap(**kwargs):
        nonlocal record_a
        a = kwargs.get('a', None)
        b = kwargs.get('b', 0)
        if a is not None:
            record_a = a
        record_a = func(record_a, b)
        return record_a

    return wrap


@store_a
def test(a=None, b=None):
    if a is None:
        a = 0
    a += b
    return a


print(test(a=0, b=1))
print(test(b=2))
print(test(b=3))

and you can get 1, 3, 6 as result

Menglong Li
  • 2,177
  • 14
  • 19