Is Python call-by-value or call-by-reference? Binding Names to Objects
来源:互联网 发布:js设计模式 编辑:程序博客网 时间:2024/05/22 07:51
Is Python call-by-value or call-by-reference? Neither.
Posted on Nov 13, 2012 by Jeff Knupp
One aspect of Python programming that trips up those coming from languages like C or Java is how arguments are passed to functions in Python. At a more fundamental level, the confusion arises from a misunderstanding about Python object-centric data model and its treatment of assignment. When asked whether Python function calling model is "call-by-value" or "call-by-reference", the correct answer is: neither. Indeed, to try to shoe-horn those terms into a conversation about Python's model is misguided. "call-by-object," or "call-by-object-reference" is a more accurate way of describing it. But what does "call-by-object" even mean?
In Python, (almost) everything is an object. What we commonly refer to as "variables" in Python are more properly called names. Likewise, "assignment" is really the binding of a name to an object. Each binding has a scope that defines its visibility, usually the block in which the name originates.
That's a lot of terminology all at once, but those basic terms form the cornerstone of Python's execution model. Compared to, say, C++, the differences are subtle yet important. A concrete example will highlight these differences. Think about what happens when the following C++ code is executed:
string some_guy = "Fred";// ...some_guy = "George";
In the above, the variable some_guy
refers to a location in memory, and the value 'Fred' is inserted in that location (indeed, we can take the address of some_guy
to determine the portion of memory to which it refers). Later, the contents of the memory location referred to bysome_guy
are changed to 'George'. The previous value no longer exists; it was overwritten. This likely matches your intuitive understanding (even if you don't program in C++).
Let's now look at a similar block of Python code:
some_guy = 'Fred'# ...some_guy = 'George'
Binding Names to Objects
On line 1, we create a binding between a name, some_guy
, and a string object containing 'Fred'. In the context of program execution, the environment is altered; a binding of the namesome_guy
' to a string object is created in the scope of the block where the statement occurred. When we later say some_guy = 'George'
, the string object containing 'Fred' is unaffected. We've just changed the binding of the name some_guy
. We haven't, however, changed either the 'Fred' or 'George' string objects. As far as we're concerned, they may live on indefinitely.
With only a single name binding, this may seem overly pedantic, but it becomes more important when bindings are shared and function calls are involved. Let's say we have the following bit of Python code:
some_guy = 'Fred'first_names = []first_names.append(some_guy)another_list_of_names = first_namesanother_list_of_names.append('George')some_guy = 'Bill'print (some_guy, first_names, another_list_of_names)
So what get's printed in the final line? Well, to start, the binding of some_guy
to the string object containing 'Fred' is added to the block's namespace. The name first_names
is bound to an empty list object. On line 4, a method is called on the list object first_names
is bound to, appending the object some_guy
is bound to. At this point, there are still only two objects that exist: the string object and the list object. some_guy
and first_names[0]
both refer to the same object (Indeed, print(some_guy is first_names[0])
shows this).
Let's continue to break things down. On line 6, a new name is bound:another_list_of_names
. Assignment between names does not create a new object. Rather, both names are simply bound to the same object. As a result, the string object and list object are still the only objects that have been created by the interpreter. On line 7, a member function is called on the object another_list_of_names
is bound to and it is mutated to contain a reference to a new object: 'George'. So to answer our original question, the output of the code is
Bill ['Fred', 'George'] ['Fred', 'George']
This brings us to an important point: there are actually two kinds of objects in Python. Amutable object exhibits time-varying behavior. Changes to a mutable object are visible through all names bound to it. Python's lists are an example of mutable objects. An immutable object does not exhibit time-varying behavior. The value of immutable objects can not be modified after they are created. They can be used to compute the values of new objects, which is how a function like string.join works. When you think about it, this dichotomy is necessary because, again, everything is an object in Python. If integers were not immutable I could change the meaning of the number '2' throughout my program.
It would be incorrect to say that "mutable objects can change and immutable ones can't", however. Consider the following:
first_names = ['Fred', 'George', 'Bill']last_names = ['Smith', 'Jones', 'Williams']name_tuple = (first_names, last_names)first_names.append('Igor')
Tuples in Python are immutable. We can't change the tuple object name_tuple
is bound to. But immutable containers may contain references to mutable objects like lists. Therefore, even though name_tuple
is immutable, it "changes" when 'Igor' is appended to first_names
on the last line. It's a subtlety that can sometimes (though very infrequently) prove useful.
- Is Python call-by-value or call-by-reference? Binding Names to Objects
- Is Python call-by-value or call-by-reference?
- call by value or reference ?
- call by value or reference
- call by value or reference
- call by value or reference
- call by value or reference
- Call-by-reference and Call-by-value
- Call by value VS. Call by reference.
- call by value 和 call by reference
- call by value 和call by reference
- call by value 和 call by reference
- call by value / call by reference
- Call by value Call by pointer Call by reference
- call by value ;call by address/reference ;call by name;call by pointer
- call by value 与call by reference的区别
- 实例浅析javascript call by value与call by reference
- call by value 和 call by reference的区别
- TCP能检测到"断网""断电"事件吗(面试可以问倒很多人)?
- HDU 2090 算菜价
- php学习笔记---PHP生成二维码名片,并把名片内容添加到联系人中
- or1200处理器中QMEM模块的作用
- 【深入Java虚拟机】之七:Javac编译与JIT编译
- Is Python call-by-value or call-by-reference? Binding Names to Objects
- Basic表示一个简单的属性
- 寻找单链表中倒数第k个元素
- OneToMany描述一个一对多的关联
- 分布式数据库【4、可用性、CAP原理、BASE原理】
- 【常规解题报告】C++格式化输出和关于字符串的一些常用法
- 苹果推送APNS自己总结
- AS3 Starling塔防教程——第二部分——游戏状态
- 第1章引论