Skip to content

Latest commit

 

History

History
85 lines (58 loc) · 5.41 KB

第八章-对象的引用、可变性和回收.md

File metadata and controls

85 lines (58 loc) · 5.41 KB

CHAPTER 8 Object References, Mutability, and Recycling

‘You are sad,’ the Knight said in an anxious tone: ‘let me sing you a song to comfort you. [...] The name of the song is called “HADDOCKS’ EYES”.’ ‘Oh, that’s the name of the song, is it?’ Alice said, trying to feel interested. ‘No, you don’t understand,’ the Knight said, looking a little vexed. ‘That’s what the name is CALLED. The name really IS “THE AGED AGED MAN."’ (adapted from Chapter VIII. ‘It’s my own Invention’). — Lewis Carroll Through the Looking-Glass, and What Alice Found There

Alice and the Knight set the tone of what we will see in this chapter. The theme is the distinction between objects and their names. A name is not the object; a name is a separate thing.

We start the chapter by presenting a metaphor for variables in Python: variables are labels, not boxes. If reference variables are old news to you, the analogy may still be handy if you need to explain aliasing issues to others.

We then discuss the concepts of object identity, value, and aliasing. A surprising trait of tuples is revealed: they are immutable but their values may change. This leads to a discussion of shallow and deep copies. References and function parameters are our next theme: the problem with mutable parameter defaults and the safe handling of mutable arguments passed by clients of our functions.

The last sections of the chapter cover garbage collection, the del command, and how to use weak references to “remember” objects without keeping them alive.

This is a rather dry chapter, but its topics lie at the heart of many subtle bugs in real Python programs.

Let’s start by unlearning that a variable is like a box where you store data.

Variables Are Not Boxes 变量不是个盒子

In 1997, I took a summer course on Java at MIT. The professor, Lynn Andrea Stein— an award-winning computer science educator who currently teaches at Olin College of Engineering—made the point that the usual “variables as boxes” metaphor actually hinders the understanding of reference variables in OO languages. Python variables are like reference variables in Java, so it’s better to think of them as labels attached to objects.

Example 8-1 is a simple interaction that the “variables as boxes” idea cannot explain. Figure 8-1 illustrates why the box metaphor is wrong for Python, while sticky notes provide a helpful picture of how variables actually work.

例子8-1是一个简单的“变量即盒子”思想不能解释的交互命令。图表8-1

Example 8-1. Variables a and b hold references to the same list, not copies of the list

>>>a=[1,2,3] 
>>>b=a
>>> a.append(4) 
>>> b
[1, 2, 3, 4]

img

Figure 8-1. If you imagine variables are like boxes, you can’t make sense of assignment in Python; instead, think of variables as sticky notes—Example 8-1 then becomes easy to explain

图表8-1. 如果你想象变量跟盒子一样,你就无法理解Python中的赋值;相反,

Prof. Stein also spoke about assignment in a very deliberate way. For example, when talking about a seesaw object in a simulation, she would say: “Variable s is assigned to the seesaw,” but never “The seesaw is assigned to variable s.” With reference variables, it makes much more sense to say that the variable is assigned to an object, and not the other way around. After all, the object is created before the assignment. Example 8-2 proves that the righthand side of an assignment happens first.

Example 8-2. Variables are assigned to objects only after the objects are created

>>> class Gizmo:
...     def __init__(self):
...         print('Gizmo id: %d' % id(self))
... 
>>> x = Gizmo()
Gizmo id: 4303555472
>>> y = Gizmo() * 10
Gizmo id: 4303555544
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'instance' and 'int'
>>> dir()
['Gizmo', '__builtins__', '__doc__', '__name__', '__package__', 'x']
  1. The output Gizmo id: ... is a side effect of creating a Gizmo instance.
  2. Multiplying a Gizmo instance will raise an exception.
  3. Here is proof that a second Gizmo was actually instantiated before the multiplication was attempted.
  4. But variable y was never created, because the exception happened while the right- hand side of the assignment was being evaluated.

Tips 提示

To understand an assignment in Python, always read the right- hand side first: that’s where the object is created or retrieved. Af‐ ter that, the variable on the left is bound to the object, like a label stuck to it. Just forget about the boxes.

要理解Python中赋值,你要一直从右边读起来:此处为对象被创建或者重新取回。之后,左边的变量被绑定到对象,就像粘上去的标签一样。所以,把盒子给忘掉吧。

Because variables are mere labels, nothing prevents an object from having several labels assigned to it. When that happens, you have aliasing, our next topic.

因为变量仅仅是标签而已,没有什么能阻止一个对象给自己使用多个标签。

Identity, Equality, and Aliases

Lewis Carroll is the pen name of Prof. Charles Lutwidge Dodgson. Mr. Carroll is not only equal to Prof. Dodgson: they are one and the same. Example 8-3 expresses this idea in Python.

Example 8-3. charles and lewis refer to the same object