介绍Python教科书定义'对象参考'如下,但我不明白:
对象引用只不过是对象标识(存储对象的内存地址)的具体表示。
教科书尝试通过使用箭头将对象引用显示为赋值语句a
中从变量1234
到对象a = 1234
的某种关系来说明这一点。 / p>
根据我从Wikipedia收集的内容,a = 1234
的(对象)引用将是a
和1234
之间的关联a
是& #34;指示"到1234
(随意澄清"引用与指针"),但有点难以验证为(1)我自学Python,(2)很多搜索结果谈论 Java 的引用,以及(3)关于 object 引用的搜索结果不多。
那么,Python中的对象引用是什么?谢谢你的帮助!
答案 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
我们可以通过查看id
和a
的{{1}}并注意它们是相同的来证明它们是同一个对象。或者,我们可以看一下变异b
或a
引用的对象的“副作用”(如果我们改变一个,我们会因为它们引用相同的对象而变异)。
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是此字符串的“地址”。它也是对其位置的“引用”。在大多数情况下,address
是pointer
是reference
。不同的语言对此有不同的句法处理,但本质上它们是同一回事-以给定数量处理一组数据。
Python和Java尝试尽可能地隐藏此寻址,在这种情况下,C
之类的语言非常乐意公开其确切含义的指针。
由此得出的结论是,object reference
是数据在内存中存储的数量。 (和pointer
一样。)
现在,大多数编程语言区分简单类型:字符和数字,以及复杂类型:字符串,列表和其他复合类型。这是对对象的引用所起的作用。
因此,当对简单类型执行操作时,它们是独立的,它们每个都有自己的内存用于存储。想象一下python中的以下序列:
>>> a = 3
>>> b = a
>>> b
3
>>> b = 4
>>> b
4
>>> a
3 # <-- original has not changed
变量a
和b
不共享存储其值的内存。但类型复杂:
>>> 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
-它们共享相同的内存。等等,什么!在这里,我们发现s
和t
都是对同一对象的引用-它们只是共享(指向)内存中的同一地址。
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中,该语言仅命名对对象的引用,这些对象的行为与标签相同。赋值运算符仅绑定到名称。这些对象将保留在内存中,直到被垃圾回收