简体   繁体   中英

change argument of python function globally

Let's say I have the following python code

y = 2

def f(x, y):
    y = y**2
    return x*y

for i in range(5):
    print(f(2,y))

Is it somehow possible to make the change to y within f global while still passing it to f as an argument? I know that

y = 2

def f(x, y):
    global y
    y = y**2
    return x*y

for i in range(5):
    print(f(2,y))

will not work because y cannot be both global and a function parameter. The 'ugly solution that I have is simply not to pass y as an argument:

y = 2
def f(x):
    global y
    y = y**2
    return x*y

for i in range(5):
    print(f(2,y))

but I am not satisfied with this, as I would like to explicitly pass y to the function and basically call it by reference.

The background of this question is that I would like to use scipy's odeint, and I have to use sparse matrices in the computation of the derivative that also change with time.

If I want to avoid converting these to numpy and back to sparse at every timestep, I have to store them globally and modify them from within the function. Because the output of the function is dictated by odeint (it has to be said derivative) it is not an option to include these matrices in the output (and I don't know how that would work anyway, because I'd have to mix scalars and matrices in the output array).

It would be nice if I could somehow pass them as a parameter but make the changes to them from within the function globally permanent.

Just use a different name for the formal argument to f :

y = 2

def f(x, y2):
    global y
    y = y2**2
    return x*y

for i in range(5):
    print(f(2,y))

If I understand your intent, then I believe this should work for you.

You cannot do this exactly, for the reason you have described: a variable cannot be at the same time global and a local argument.

However, one solution would be to do this:

y_default = 2

def f(x, y=None):
    if y is None:
      y = y_default
    y = y**2
    return x*y

This will do what you want, as you can now call f(2) or f(2,3)

Essentially the problem is that y is global and local as the error message will suggest. Therefore you avoid the local variable issue by introducing a variable z locally. You can still pass y into z, which then yields the desired result.

y = 2

def f(x, z):
  y = z**2
  global y
  return x*y

for i in range(5):
  print f(2,y)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM