Проверка равенства ссылок на объекты в Python кажется бессвязной - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь понять, что происходит с назначением и созданием новых ссылок на объект, или почему я получаю новый созданный объект при назначении.

Я не могу понять, как 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

Теперь, слишком много вещей не имеют смысла для меня здесь:

  1. Первая печать показывает sel[0] идентификатор , чтобы быть 4378999048 , но печать его снова дает еще один идентификатор ( 4378998328 )
  2. Третий отпечаток делает то же самое;выглядит id , напечатанный в первой строке, потерян / изменен / не использован.
  3. First "Test with self" печать имеет смысл (сравнение строк id - True);но я не могу понять смысл второго отпечатка, используя is (почему sel[0] is not sel[0]?).

Я пытаюсь понять, как здесь все работает.В частности, цель состоит в том, чтобы понять, почему я получаю новые объекты (вместо новой ссылки на тот же объект) при использовании выражения-генератора с for.

Я использую SublimeText3 и Python 2.7.10 .

РЕДАКТИРОВАТЬ: Я был бы заинтересован в наилучшей практике для проверки ссылочного равенства , без использования is (что кажется несовместимым, в зависимости от реализации и кэширования ).

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Посмотрите на этот пример:

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
0 голосов
/ 24 сентября 2018

Распечатка id() выражения в нескольких точках времени доказывает, что АБСОЛЮТНО НИЧЕГО.Если на первый объект больше нет ссылки, второй объект может быть размещен по тому же адресу и, следовательно, иметь тот же id;при определенных обстоятельствах это на самом деле довольно вероятный результат.Оба объекта должны существовать одновременно , чтобы их id были достоверно сопоставлены.Например,

a = sel[0]
b = sel[0]
print(id(a), id(b))

будет допустимым тестом для того, чтобы операция индексирования sel каждый раз возвращала один и тот же объект или создавала его с нуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...