Как сообщить об ошибке с помощью функции Python 'help ()'? - PullRequest
1 голос
/ 23 января 2010

В качестве хобби / учебного проекта я пишу генератор парсеров на Python. Один из моих файлов кода называется «token.py», который содержит пару классов для преобразования простых строк в объекты Token. Я только что обнаружил, что использование функции «help ()» из консоли в Python вызывает ошибку для любого модуля, определенного в каталоге, который содержит «token.py».

Вот способ воспроизвести ошибку. Создайте новый каталог со следующими файлами:

/New Folder
  main.py
  token.py

Оставьте «token.py» пустым. В main.py напишите простую функцию - например:

def test():
    pass

Затем в консоли Python импортируйте main и вызывайте help (main.test) - вот что вы получите:

C:\New Folder>python
Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import main
>>> help(main.test)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python31\lib\site.py", line 428, in __call__
    import pydoc
  File "C:\Python31\lib\pydoc.py", line 55, in <module>
    import sys, imp, os, re, inspect, builtins, pkgutil
  File "C:\Python31\lib\inspect.py", line 40, in <module>
    import tokenize
  File "C:\Python31\lib\tokenize.py", line 37, in <module>
    COMMENT = N_TOKENS
NameError: name 'N_TOKENS' is not defined
>>>

Если вы удалите файл «token.py», help () будет работать нормально. Как Python 3.1, так и Python 2.5 демонстрируют такое поведение.

Это известная проблема? Если нет, то как мне сообщить об этом?

EDIT:

В нескольких комментариях утверждается, что это поведение не является ошибкой. Модуль, который определяет «help», импортирует модуль под названием «token» из стандартной библиотеки Python. Тем не менее, Python ищет в папке приложения, прежде чем он ищет в своей библиотеке, чтобы найти модули. В приведенном выше примере «help» пытается использовать мой «token.py» вместо Python, что вызывает ошибку.

Поскольку Python определен, чтобы демонстрировать это поведение, я полагаю, что это не ошибка. Но почему люди думают, что это поведение приемлемо? Это означает, что добавление новых модулей в библиотеку Python - даже без изменения существующих модулей - может привести к поломке существующих приложений. Это также означает, что программисты, как ожидается, запомнят имена всех модулей в библиотеке Python - как это может быть менее смешно, чем ожидать, что программисты запомнят каждое пространство имен в .NET или Java? Почему приложения Python не получают свои собственные пространства имен? Почему модули стандартной библиотеки Python не находятся в своем собственном пространстве имен?

Ответы [ 4 ]

5 голосов
/ 23 января 2010

Проблема в том, что ваш локальный token.py импортируется help() вместо фактического token.py в Python. Это произойдет для любого количества .py файлов, имена которых конфликтуют со встроенными модулями. Например, попробуйте создать файл pydoc.py в CWD, а затем попробуйте help() в Python. help() - это просто встроенная функция Python, поэтому она следует тому же пути импорта, что и любой другой код Python.

3 голосов
/ 23 января 2010

Всякий раз, когда вы выбираете имена своих модулей таким образом, чтобы имитировать имена модулей, определенные в стандартной библиотеке Python, вы несете полную ответственность за все, что происходит в результате - другие модули стандартной библиотеки Python, вероятно, будут полагаться на те, которые вы используете. скрытие / переопределение, и если ваши собственные модули не имитируют тщательно скрытые функции модулей, это не ошибка с Python: это ошибка с вашим кодом. Конечно, это относится к модулю token так же, как и к любому другому.

Если это происходит с вами случайно, и вы ищете способ проверить свой код на наличие возможных ошибок или ненадежных конструкций (а не, как вы говорите, способ сообщить о несуществующей ошибке с помощью стандартной библиотеки Python ), Я думаю, что такие инструменты, как pylint , могут помочь.

1 голос
/ 23 января 2010

Вы можете искать проблемы и сообщать о новых здесь: http://bugs.python.org/.

0 голосов
/ 23 января 2010

Это не ошибка в методе help (). В стандартной библиотеке есть модуль с именем token.py , который импортируется с помощью tokenize.py (откуда появляется ошибка, которую вы видите).

от tokenize.py:

from token import *

Таким образом, tokenize.py ожидает наличие набора переменных из стандартной библиотеки token.py, но поскольку token.py в вашем рабочем каталоге фактически импортирован, их нет, что вызывает ошибку NameEr (одна из многих причин import * не должен использоваться).

...