简体   繁体   中英

Python confusing function reference

Can anyone explain to me why the two functions below a and b are behaving differently. Function a changes names locally and b changes the actual object.

Where can I find the correct documentation for this behavior?

def a(names):
    names = ['Fred', 'George', 'Bill']

def b(names):
    names.append('Bill')

first_names = ['Fred', 'George']

print "before calling any function",first_names
a(first_names)
print "after calling a",first_names
b(first_names)
print "after calling b",first_names

Output:

before calling any function ['Fred', 'George']
after calling a ['Fred', 'George']
after calling b ['Fred', 'George', 'Bill']

Assigning to parameter inside the function does not affect the argument passed. It only makes the local variable to reference new object.

While, list.append modify the list in-place.

If you want to change the list inside function, you can use slice assignment:

def a(names):
    names[:] = ['Fred', 'George', 'Bill']

Function a creates a new, local variable names and assigns list ['Fred', 'George', 'Bill'] to it. So this is now a different variable from the global first_names , as you already found out.

You can read about modifying a list inside a function here .

One way to make function a behave the same as function b is to make the function a modifier :

def a(names):
    names += ['Bill']

Or you could make a pure function:

def c(names):
    new_list = names + ['Bill']
    return new_list

And call it:

first_names = c(first_names)
print first_names
# ['Fred', 'George', 'Bill']

A pure function means it doesn't change the state of the program, ie it doesn't have any side effects, like changing global variables.

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