2013-10-15 2 views
-1

У меня есть класс UserDict с преобразованным __repr__ и __str__ и я отладки некоторый код, используя его Winpdb:winpdb: как работает Repr?

class UserDict(dict): 
    def __repr__(self): 
     return "this is repr" 
    def __str__(self): 
     return "this is str" 

variable = UserDict() 
variable["abc"] = 1 

Вот сеанс отладки этого сценария. Примечание 2 команды в консоли: eval(variable) и eval(variable.__repr__()), выданный, когда выполнение сценария достигло последнюю строку: enter image description here

Если я говорю eval(variable) в Winpdb консоли, которая должна потерпеть неудачу в обычной консоли питона, она возвращает то же самое как в столбце «Реп».

Интересно, как он заполняет содержимое этого столбца «Repr» и что он действительно делает, когда я говорю eval(variable)?

+0

Что означает 'eval' для оценки строки как кода Python. Это полная противоположность тому, что вы утверждаете, что ищете. Итак ... что заставляет вас думать, что «eval» - это то, что вы хотите в первую очередь? – abarnert

+0

@abarnert Я использовал неправильное слово. Я не обязательно хочу изменить, как это работает. Я хочу знать, что он делает. –

+0

Между тем, 'pdb' не вызывает' eval' на вашем объекте, чтобы получить его представление; он просто называет 'repr'. И я не уверен, почему вы ожидали определить «UserDict .__ repr__», чтобы повлиять на представление некоторых совершенно не связанных между собой классов, которые вы нам не показали, но ... это не так. – abarnert

ответ

2

eval делает это, чтобы оценить строку как выражение Python.

Вы не хотите называть eval об объектах, чтобы получить их представление. pdb/WinPDB не называет eval на своих объектах, чтобы получить их представление. Фактически, eval почти напротивrepr.

Если вы хотите увидеть результаты foo.__repr__(), позвоните по телефону repr(foo) или просто введите foo на пульте. Ввод любое выражение на консоли приводит его к показу repr(that expression).

Конечно, это означает, что если вы наберете eval(foo) на консоли, то вы увидите repr(eval(foo)). Но это не имеет никакого отношения к eval; это то же самое, что и любое другое выражение.


Между тем, в Winpdb console, вы не используете код Python, вы работаете Winpdb код. У Winpdb есть команда с именем eval, которая похожа на функцию Python eval, но это не одно и то же.

Как указано в документации, eval foo эффективно оценивает foo в вашем сеансе живой debuggee. Обратите внимание, что это фрагмент, который обрабатывается как выражение Python, не строка, содержащая такой фрагмент.

Итак, eval(variable) в консоли Winpdb аналогичен eval("(variable)") в интерактивном интерпретаторе. Который почти идентичен только (variable) в интерактивном интерпретаторе. Что эквивалентно variable.

Но если вы наберете variable (или (variable) или eval("(variable)")) в интерактивном интерпретаторе, он печатает repr(variable), который вызывает ваш метод __repr__. Почему это не происходит в Winpdb?

Поскольку распечатка repr любого выражения, которое вы вводите в интерактивном интерпретаторе, является функцией интерактивного интерпретатора, а не языка. Хотя консоль Winpdb может сделать то же самое, это не так.(Это позволяет отлаживать проблемы с помощью методов __repr__ и позволяет избежать запуска кода из debuggee в отладчике, не делая его явным.)

Итак, как насчет eval(variable.__repr__()). Как вы можете догадаться, это похоже на оценку строки "(variable.__repr__())" в debuggee. То, что .__repr__() заканчивается тем, что является частью выражения, которое вы оцениваете в среде debuggee, поэтому, конечно, оно вызывается в среде debuggee. Результатом является не объект UserDict, как в предыдущей версии, а строка.


Итак, наконец-то, что именно делает Winpdb показать в своей колонке магнезии и, как результат вызова eval? Ну, это явно не задокументировано, поэтому вы можете понять это через пробную версию и ошибку или прочитать источник.

0

eval() выполняет код python, переданный как строка. Если вы хотите, чтобы ваш dict возвращал «foo», используйте функцию repr (myUserDictVariable).