1

foo = "foo" def bar(foo): foo = "bar"

bar(foo)
print foo

# foo is still "foo"...

foo = {'foo':"foo"}
def bar(foo): 
    foo['foo'] = "bar"

bar(foo)
print foo['foo']

# foo['foo'] is now "bar"?

I have a function that has been inadvertently over-writing my function parameters when I pass a dictionary. Is there a clean way to declare my parameters as constant or am I stuck making a copy of the dictionary within the function?

Thanks!

3 Answers 3

3

In a case like this, you'd have to copy the dictionary if you want to change it and keep the changes local to the function.

The reason is that, when you pass a dictionary into your second bar function, Python only passes a reference to the dictionary. So when you modify it inside the function, you're modifying the same object that exists outside the function. In the first bar function, on the other hand, you assign a different object to the name foo inside the function when you write foo = "bar". When you do that, the name foo inside the function starts to refer to the string "bar" and not to the string "foo". You've changed which object the name refers to. But foo inside the function and foo outside the function are different names, so if you change the object labeled by foo inside the function, you don't affect the name foo outside the function. So they refer to different objects.

Sign up to request clarification or add additional context in comments.

5 Comments

Fair enough. I was hoping that there would be something like a const keyword to make this a little nicer. Thanks a lot!
This is a point where I'd make a shameless plug for learning C++. Half of these sort of misunderstandings in high-level languages come from a lack of understanding of how the languages work. If you take the time to learn a bit of C++ you'll start to find that allot of these sort of things in Python are the way they are because they are either a) the fastest or b) the easiest implementation. You don't have to know C++ to understand how Python works, but it makes it easier.
@Shaun: nothing is really constant in Python (except keyword names like None, True, False, 1, 2, etc.) and anyway, a const keyword wouldn't help you here because your second bar() is performing an operation on the object named foo, not changing what the name refers to. const prevents the latter but not the former. Timothy has a good point that learning C++ (or C) would probably help make this clearer.
presumably a const foo function parameter would cause an interpreter error on the line where you attempt to modify the content of foo.
@jmucchiello: the thing is, since Python is so flexible in allowing you to change built-in behavior, it's nearly impossible to tell for certain whether any particular piece of code actually modifies the object or not. For instance, I could create an object foo such that the line foo['foo'] = "bar" just prints bar to the console and doesn't modify foo. It would be really weird, but it could be done.
1

Arguments are passed by value, but in this case the value is a reference to an object. This is also called call by sharing. So yes, if you need a new dictionary, you will have to create one in the function.

Comments

0

I would like to add that

temp_dict = CONSTdict 

did not help, as this simply copies the pointer.

Instead, I needed:

temp_dict = dict(CONSTdict)

Cheers,

Shaun

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.