我试图了解分配和对对象的新引用的创建会发生什么,或者为什么分配时会得到一个新创建的对象。
我无法理解 Python 和/或 Sublime 在这里的工作方式。 我有这个简单的 Sublime 插件:
import sublime
import sublime_plugin
class TestpythonCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
sel = view.sel()
sel_zero = sel[0];
sel_for = []
for r in sel:
sel_for.append(r)
sel_gen = [r for r in view.sel()]
print('SEL => ' + str(sel[0].a) +':' + str(sel[0].b) + ' ID: ' + str(id(sel[0])))
print(str(id(sel[0])) + ' .. ' + str(id(sel[0])) + ' .. access A value: ' + str(sel[0].a) + ' .. ' + str(id(sel[0])))
print('SEL[0] id is ' + str(id(sel[0])))
print('SEL_ZERO => ' + str(sel_zero.a) +':' + str(sel_zero.b) + ' ID: ' + str(id(sel_zero)))
print('SEL_FOR => ' + str(sel_for[0].a) +':' + str(sel_for[0].b) + ' ID: ' + str(id(sel_for[0])))
print('SEL_GEN => ' + str(sel_gen[0].a) +':' + str(sel_gen[0].b) + ' ID: ' + str(id(sel_gen[0])))
print('----- Test with self')
print(id(sel[0]) == id(sel[0]))
print(sel[0] is sel[0])
print(sel[0] == sel[0])
print('----- Test with list & generator function')
print(sel[0] is sel_zero)
print(sel[0] == sel_zero)
print(sel[0] is sel_for[0])
print(sel[0] == sel_for[0])
print(sel[0] is sel_gen[0])
print(sel[0] == sel_gen[0])
执行此操作将返回:
SEL => 657:657 ID: 4378999048
4378998328 .. 4378998328 .. access A value: 657 .. 4378998328
SEL[0] id is 4378998328
SEL_ZERO => 657:657 ID: 4379000488
SEL_FOR => 657:657 ID: 4378996816
SEL_GEN => 657:657 ID: 4378998760
----- Test with self
True
False
True
----- Test with list & generator function
False
True
False
True
False
True
现在,太多的事情对我来说毫无意义:
sel[0]
id 为 4378999048 ,但再次印刷将得到另一个 id ( 4378998328 < / strong>)is
(为什么要sel[0] is not sel[0]
?)来了解第二张纸。我试图了解这里的工作原理。具体来说,目的是要理解为什么将Generator-expression与for
一起使用时为什么会得到新的对象(而不是对同一对象有新的引用)。
我使用 SublimeText3 和 Python 2.7.10 。
编辑:我会对检查引用相等性的最佳实践感兴趣,而无需使用is
(即seems to be inconsistent, depending on implementation and caching)。 / p>
答案 0 :(得分:1)
在多个时间点打印表达式的id()
证明是绝对没有的。如果不再引用第一个对象,则第二个对象可能分配在相同的地址,因此具有相同的id
;在某些情况下,这实际上是相当可能的结果。两个对象必须同时存在 ,才能对其id
进行有意义的比较。例如,
a = sel[0]
b = sel[0]
print(id(a), id(b))
对于sel
的索引操作是每次返回同一对象还是从头开始创建一个对象,将是一个有效的测试。
答案 1 :(得分:0)
看这个例子:
from collections import UserList
class MyList(UserList):
def __init__(self):
self.gen = iter([10,20,30])
def __getitem__(self, index):
return next(self.gen)
# This is what you expect:
a = [10,20,30]
print(a[0] is a[0]) # True
# And this looks surprising at first:
b = MyList()
print(b[0] is b[0]) # False
# Without knowing MyList internals, I
# cannot predict what I am getting on
# each access (except maybe by trusting
# available documentation)
# I don't know about sublime.
# In my other comment I just wanted
# to emphasize that operator `is`
# works reliably.
# You don't know if a is b or not:
a = 1
b = 1
# a is b can be True or False.
# But as they hold the same immutable value
# it really doesn't matter. Things will work
# the same with either a or b.
# to find out about identity, just test with
# a is b