2015-05-27 3 views
-1

Вот простой код Python, в чем разница между случаем 1 и случаем 2. Почему я получаю результат как False в первом случае и True в другом. Почему идентификаторы равны в случае 2. Также dir (object) вызывает object._dir __() внутренне? Если это так, возвращаемый объект/результат двух вызовов должен совпадать.Python dir (object) vs object .__ dir __()

class Hello: 
    def __init__(self): 
     self.a1 = "a1" 


hello = Hello() 
print(hello) 

# Case 1 
var1 = dir(hello) 
var2 = hello.__dir__() 
print(id(var1), id(var2), id(var1) == id(var2)) 

# Case 2 
print(id(dir(hello)), id(hello.__dir__()), id(dir(hello)) == id(hello.__dir__())) 
print(dir(hello) == hello.__dir__()) 

Выход

<__main__.Hello object at 0x7f320828c320> 
139852862206472 139852862013960 False 
139852862014024 139852862014024 True 
False 
+0

Если вы не думаете, что ваш вопрос является дубликатом, добавьте комментарий, объясняющий почему. И если ответы (либо на исходный вопрос, либо на этот) не охватывают все, что вы хотели знать, добавьте комментарий. Просто редактируя свой вопрос неоднократно и надеясь, что мы заметим, что изменения только срабатывают, если вам действительно повезло с выбором времени. – abarnert

+0

@abarnert, я очень новичок в stackoverflow. Я сделаю это со следующего раза, Спасибо, что сообщили мне. – ravi

+0

Нет проблем. Я бы ничего не сказал, кроме того, что я случайно заметил одно из ваших исправлений, когда я собирался закрыть страницу, и ответил на нее, отредактировав свой ответ, и я не хотел давать ложное впечатление, что вы можете рассчитывайте на этот вид времени каждый день. – abarnert

ответ

1

Это просто совпадение, что вы когда-либо получить True. (Ну, не совпадение, так как реализация CPython делает его весьма вероятно ... но это не то, что язык требует.)

В случае 1, у вас есть два различных dict с в var1 и var2. Они оба живы одновременно, поэтому они не могут иметь одинаковые id.

В случае 2 у вас снова есть два разных dict s-но на этот раз вы не храните их в любом месте; как только вы позвоните по телефону id, вы отпустите его, что означает, что он может получить собранный мусор *, прежде чем вы получите другой, **, что означает, что он может в конечном итоге повторно использовать то же самое id. ***

Обратите внимание, что документы для id сказать:

Это целое число, которое гарантированно будет уникальным и постоянным для этого объекта в течение его жизни. Два объекта с неперекрывающимся временем жизни могут иметь одинаковое значение id().

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


отредактированный вопрос также спрашивает:

делает также директории (объект) вызывает object._dir __() внутри?

По dir:

Если объект имеет метод, названный __dir__(), этот метод будет вызван и должен возвращать список атрибутов.

А раздел модель данных на __dir__ говорит:

Вызывается, когда dir() вызывается на объекте. Последовательность должна быть возвращена. dir() преобразует возвращенную последовательность в список и сортирует ее.

Тогда вы говорите:

Если да возвращение объект из двух вызовов должен быть одинаковым.

Ну, это зависит от того, что вы подразумеваете под «тем же». Он должен вернуть равное значение (поскольку ничего не изменилось), но это не будет то же значение, которое вы пытаетесь проверить. (Если не понятно, почему dir дает вам новый список каждый раз, все равно должно быть ясно, что он должен сделать это из-за того, что «dir() преобразует возвращенную последовательность в список и сортирует ее» ...)


* Поскольку CPython использует подсчет ссылок в качестве основного механизма сбора мусора, «можно собирать», как правило, означает, что «будет немедленно собрано». Это не относится к большинству других реализаций Python.

** Если порядок, в котором часть вашего выражения получить оценку не ясно, читая документы, вы можете попробовать dis.dis('id(dir(hello)) == id(hello.__dir__())') увидеть фактические байткоды в порядке.

*** В CPython, то id только адрес PyObject структуры, представляющей объект; если один PyObject освобождается, а другой тот же тип получает сразу после него, он обычно получает тот же адрес.

+0

Имея такой же идентификатор для dir (object) и object._dir __(), это меня смутило. Теперь все ясно. Благодарю. Также, если dir (object) вызывает объект .__ dir __(), почему вызов __dir __() не отображается в коде дизассемблера? dis.dis ('dir (hello)') – ravi

Смежные вопросы