vcy*_*rfc 6 python oop reference object
入门Python教科书定义了“对象引用”,如下所示,但我不明白:
对象引用不过是对象身份(存储对象的内存地址)的具体表示。
教科书试图通过使用箭头将对象引用显示为赋值语句中从变量a到对象的某种关系来说明这一点。1234a = 1234
从我收集的关闭维基百科,的(对象)的引用a = 1234将是一个协会之间a并1234分别a被“指点”来1234(随意澄清“基准与指针”),但它已经有点难以核实的( 1)我正在自学Python,(2)许多搜索结果都谈论Java引用,(3)搜索结果中很少涉及对象引用。
那么,Python中的对象引用是什么?谢谢您的帮助!
与变量名相关的任何内容都必须存储在程序内存中的某个位置。想到这一点的一个简单方法是,内存的每个字节都有一个索引号。为了简单起见,让我们想象一台简单的计算机,这些索引号从 0(第一个字节)向上到有多少个字节。
假设我们有一个 37 个字节的序列,人类可能会将其解释为一些单词:
"The Owl and the Pussy-cat went to sea"
Run Code Online (Sandbox Code Playgroud)
计算机将它们存储在一个连续的块中,从内存中的某个索引位置开始。该索引位置通常称为“地址”。显然这个地址绝对只是一个数字,这些字母所在的内存的字节数。
@12000 The Owl and the Pussy-cat went to sea
Run Code Online (Sandbox Code Playgroud)
因此,在地址 12000 处是 a T,在 12001 处是 a h,12002 处是e... 直到最后a一个 12037 处。
我在这里强调这一点是因为它是每种编程语言的基础。12000 就是这个字符串的“地址”。它也是对其位置的“参考”。对于大多数意图和目的来说, anaddress是 apointer是 a reference。不同的语言对这些有不同的语法处理,但本质上它们是相同的——处理给定数量的数据块。
Python 和 Java 尝试尽可能地隐藏这种寻址C,而类似的语言非常乐意公开指针的确切内容。
由此得出的结论是,anobject reference是数据在内存中存储位置的编号。(正如 a 一样pointer。)
现在,大多数编程语言都区分简单类型(字符和数字)和复杂类型(字符串、列表和其他复合类型)。这就是对对象的引用产生影响的地方。
所以在对简单类型进行操作时,它们是独立的,它们各自有自己的内存进行存储。想象一下 python 中的以下序列:
>>> a = 3
>>> b = a
>>> b
3
>>> b = 4
>>> b
4
>>> a
3 # <-- original has not changed
Run Code Online (Sandbox Code Playgroud)
变量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
Run Code Online (Sandbox Code Playgroud)
我们指定t为s,但显然在本例中t 是 s- 它们共享相同的内存。等等,什么!在这里我们发现 和s都是t对同一个对象的引用- 它们只是共享(指向)内存中的相同地址。
Python 与其他语言的不同之处在于,它将字符串视为一种简单类型,并且它们是独立的,因此它们的行为类似于数字:
>>> j = 'Pussycat'
>>> k = j
>>> k
'Pussycat'
>>> k = 'Owl'
>>> j
'Pussycat' # <-- Original has not changed
Run Code Online (Sandbox Code Playgroud)
而 inC字符串肯定会作为复杂类型处理,并且表现得像 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
Run Code Online (Sandbox Code Playgroud)
但:
def fnB( number ):
number += 1
x = 3
fnB( x )
print( x )
3 # <-- x was NOT changed inside the function
Run Code Online (Sandbox Code Playgroud)
因此请记住,通过引用使用的“对象”的内存由所有副本共享,而简单类型的内存则不然,很明显这两种类型的操作不同。
对象就是事物。一般来说,它们就是您在等式右侧看到的内容。
变量名称(通常简称为“名称”)是对实际对象的引用。当名称位于等式1的右侧时,会自动查找它引用的对象并在等式中使用。右侧表达式的结果是一个对象。等式左侧的名称成为对此(可能是新的)对象的引用。
请注意,如果您正在使用容器对象(如列表或字典),则可以使用非显式名称的对象引用:
a = [] # the name a is a reference to a list.
a.append(12345) # the container list holds a reference to an integer object
Run Code Online (Sandbox Code Playgroud)
以类似的方式,多个名称可以引用同一个对象:
a = []
b = a
Run Code Online (Sandbox Code Playgroud)
id我们可以通过查看a和b并注意到它们是相同的来证明它们是同一个对象。a或者,我们可以看看改变or引用的对象的“副作用” b(如果我们改变一个,我们就会改变两个,因为它们引用同一个对象)。
a.append(1)
print a, b # look mom, both are [1]!
Run Code Online (Sandbox Code Playgroud)
1更准确地说,当名称用于表达式中时