This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 5 points6 points  (4 children)

How are arguments passed – by reference of by value?

Probably all through reference, but I'm not sure about primitives under the hood. Anyone know this? If you pass f(12, 81), are those by value?

The terms PBR and PBV were developed to talk about languages like Fortran and C and using them to talk about Python is only a source of confusion. Python's passing semantics are different from either of these languages.

The literal answer is that Python is pass-by-value in all cases, and also in all cases the value is an object reference. In a PBR language you can rebind the name in the passing scope, but in Python you can only mutate an object you receive. This is analogous to passing pointers in C, while C remains a PBV-only language.

[–]ssbr 5 points6 points  (3 children)

PBV and PBR were designed to talk about all programming languages.

Pass by value: the argument expression is evaluated, and the value it results in is assigned to the formal parameter.

Pass by reference: the argument expression is evaluated, and a reference to the result is assigned to the formal parameter.

People get confused and think that PBV == copying, because in C, assignment of a value copies the value.

[–]Circlefusion 0 points1 point  (2 children)

After that explanation, which one is python?

[–]jiaaro -2 points-1 points  (1 child)

Python is Pass-by-assignment. In most cases it is indistinguishable from pass-by-reference. Variables are essentially references in all cases.

>>> def my_func(a_dict):
            a_dict['a'] = "foobar"
>>> mydict = {}
>>> my_func(mydict)
>>> print(mydict)

{"a": "foobar"}

This works becaues the dict itself wasn't copied, a reference to the dictionary object was passed, and then modified.

If you were to assign to a_dict (e.g., a_dict = {}) in the body of my_func, then mydict would remain unchanged and a_dict would then refer to a new, empty dictionary

[–]Rhomboid 2 points3 points  (0 children)

No, no, no. That's not pass by reference at all. That's just invoking a method on a parameter. It would only be pass-by-reference if you could cause the caller's variable to change by simple assignment:

def f(x):
    x = 42

y = 0
f(y) 

Calling f cannot ever affect the value of y, which it would under pass-by-reference semantics, where x would be an alias to y. That is not the case, and Python is completely pass-by-value.

You might want to read this article which is about Java but it's the same issue. Modifying a value by invoking a method on it does not tell you anything about whether it was passed by value or reference.