Python中的对象引用是什么?

时间:2016-02-18 17:48:35

标签: python oop object reference

介绍Python教科书定义'对象参考'如下,但我不明白:

  

对象引用只不过是对象标识(存储对象的内存地址)的具体表示。

教科书尝试通过使用箭头将对象引用显示为赋值语句a中从变量1234到对象a = 1234的某种关系来说明这一点。 / p>

根据我从Wikipedia收集的内容,a = 1234的(对象)引用将是a1234之间的关联a是& #34;指示"到1234(随意澄清"引用与指针"),但有点难以验证为(1)我自学Python,(2)很多搜索结果谈论 Java 的引用,以及(3)关于 object 引用的搜索结果不多。

那么,Python中的对象引用是什么?谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

对象是的东西。一般来说,它们就是你在等式右边看到的东西。

变量名称(通常称为“名称”)是对实际对象的引用。当名称位于等式 1 的右侧时,它引用的对象将自动查找并在等式中使用。右侧表达的结果是一个对象。等式左边的名称成为对这个(可能是新的)对象的引用。

注意,如果使用容器对象(如列表或词典),可以具有非显式名称的对象引用:

a = []  # the name a is a reference to a list.
a.append(12345)  # the container list holds a reference to an integer object

以类似的方式,多个名称可以引用同一个对象:

a = []
b = a

我们可以通过查看ida的{​​{1}}并注意它们是相同的来证明它们是同一个对象。或者,我们可以看一下变异ba引用的对象的“副作用”(如果我们改变一个,我们会因为它们引用相同的对象而变异)。

b

1 更确切地说,当在表达式中使用名称时

答案 1 :(得分:0)

任何与变量名相关联的变量都必须存储在程序存储器中的某个位置。考虑这一点的一种简单方法是,内存的每个字节都有一个索引号。为了简单起见,让我们想象一下一台简单的计算机,这些索引号从0(第一个字节)开始,到有多少字节为止。

假设我们有一个37字节的序列,人类可以将其解释为某些单词:

"The Owl and the Pussy-cat went to sea"

计算机将它们存储在一个连续的块中,从内存中的某些索引位置开始。该索引位置通常被称为“地址”。显然,此地址绝对是一个数字,即这些字母所驻留的内存的字节数。

@12000 The Owl and the Pussy-cat went to sea

因此,地址12000是T,地址12001是h,地址12002是e ...直到12037的最后一个a

我在这里努力要点,因为它是每种编程语言的基础。 12000是此字符串的“地址”。它也是对其位置的“引用”。在大多数情况下,addresspointerreference。不同的语言对此有不同的句法处理,但本质上它们是同一回事-以给定数量处理一组数据。

Python和Java尝试尽可能地隐藏此寻址,在这种情况下,C之类的语言非常乐意公开其确切含义的指针。

由此得出的结论是,object reference是数据在内存中存储的数量。 (和pointer一样。)

现在,大多数编程语言区分简单类型:字符和数字,以及复杂类型:字符串,列表和其他复合类型。这是对对象的引用所起的作用。

因此,当对简单类型执行操作时,它们是独立的,它们每个都有自己的内存用于存储。想象一下python中的以下序列:

>>> a = 3
>>> b = a
>>> b
3
>>> b = 4
>>> b
4
>>> a
3      # <-- original has not changed

变量ab不共享存储其值的内存。但类型复杂:

>>> s = [ 1, 2, 3 ]
>>> t = s
>>> t
[1, 2, 3]
>>> t[1] = 8
>>> t
[1, 8, 3]
>>> s
[1, 8, 3]  # <-- original HAS changed

我们将t分配为s,但是显然在这种情况下t s-它们共享相同的内存。等等,什么!在这里,我们发现st都是对同一对象的引用-它们只是共享(指向)内存中的同一地址。

Python与其他语言的不同之处在于它将字符串视为简单类型,并且它们是独立的,因此它们的行为类似于数字:

>>> j = 'Pussycat'
>>> k = j
>>> k
'Pussycat'
>>> k = 'Owl'
>>> j
'Pussycat'  # <-- Original has not changed

C字符串中的字符串绝对被视为复杂类型,其行为类似于Python列表示例。

所有这些的结果是,当修改了通过引用处理的对象时,对此对象的所有引用都会“看到”更改。因此,如果将对象传递给对其进行修改的函数(即:保存数据的内存内容已更改),则更改也将反映在该函数之外。

但是,如果更改了简单类型或将其传递给函数,则会将其复制到该函数,因此更改不会在原始视图中看到。

例如:

def fnA( my_list ):
    my_list.append( 'A' )

a_list = [ 'B' ]
fnA( a_list )
print( str( a_list ) )
['B', 'A']        # <-- a_list was changed inside the function

但是:

def fnB( number ):
    number += 1

x = 3
fnB( x )
print( x )
3                # <-- x was NOT changed inside the function

因此请记住,引用所使用的“对象”的内存由所有副本共享,而简单类型的内存不共享,很显然,这两种类型的操作方式不同。

答案 2 :(得分:0)

严格来说,在python中,该语言仅命名对对象的引用,这些对象的行为与标签相同。赋值运算符仅绑定到名称。这些对象将保留在内存中,直到被垃圾回收