Python в emacs: __name__ == '__main__', но почему-то нет

Я кодирую Python в Emacs. Однако каким-то образом интерпретатор python, работающий в emacs, может удивить меня.

Если я напишу

print()
print(__name__)
print(__name__=='__main__')
if __name__ == '__main__':
    print("indeed")

в буфере emacs и скажите emacs запустить интерпретатор и запустить содержимое этого буфера, я получаю буфер, содержащий

Python 3.3.5 (default, Mar 18 2014, 02:00:02) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> 
__main__
True
>>> 

(И то и другое __main__ а также True являются выходными данными из оператора печати; буфер Python всегда отображает >>> и печатает сразу после него. Я знаю об этом, это не проблема.)

Из командной строки оба python а также python -i показать "действительно", как и ожидалось.

Как Emacs способен противоречиво оценивать __name__=='__main__' в True, не выполняя вещи внутри if __name__ == '__main__':? И как его перенастроить, чтобы он больше не делал?

3 ответа

Решение

Как отметил @Wooble в комментарии, это может быть python.el вопрос: C-c C-c работает
python-shell-send-buffer функция:

python-shell-send-buffer - это интерактивная скомпилированная функция Lisp в `python.el '.

(python-shell-send-buffer и необязательный ARG)

Отправить весь буфер подчиненному процессу Python. С префиксом ARG разрешено выполнение кода внутри блоков, разделенных "if __name__=='__main__':"

то есть, чтобы напечатать "действительно", добавьте префикс C-u C-c C-c,

Q: Я пытался копаться в python.el, и я до сих пор не уверен, как и где он это делает. Можете ли вы объяснить, чтобы я мог изменить поведение по умолчанию?

Чтобы узнать что C-c C-c в вашем случае открыть файл Python и введите M-x describe-key RET с последующим C-c C-c (на самом деле нажмите клавиши). По умолчанию работает python-shell-send-buffer функция в python.el, Вы можете переопределить ключи для вызова функции с аргументом, чтобы C-c C-c будет вести себя как C-u C-c C-c что позволяет работать "if __name__=='__main__':" часть:

;; Make C-c C-c behave like C-u C-c C-c in Python mode
(require 'python)
(define-key python-mode-map (kbd "C-c C-c")
  (lambda () (interactive) (python-shell-send-buffer t)))

Эта «Функция» никогда не устареет. Попробуйте использовать

      __name__=='__main__':

без пробела между оператором.

Тогда python.el его не обойдет. Так что посмотрите на свой форматировщик кода.

Как только вы запустили оболочку python, вы можете просто переопределить переменную:

__name__ = 'repl' 

Это предотвращает любой if __name__=='__main__': блокирует запуск на любом последующем C-c C-c вызовы.

Другие вопросы по тегам