Разрешить зарезервированные ключевые слова в качестве методов в CPython

#python #syntax-error #cpython #pyodide

#python #синтаксическая ошибка #cpython #pyodide

Вопрос:

Похоже, что в Python есть список зарезервированных ключевых слов, которые нельзя использовать в качестве имен методов. Например,

 class A:
   def finally(self):
       return 0
  

возвращает a SyntaxError: invalid syntax . Есть способ обойти это с помощью getattr/setattr ,

   class A:
      pass
  

  setattr(A, 'finally', lambda self: 0)
  
  a = A()
  print(getattr(a, "finally")())
  

работает нормально. Тем не менее, a.finally() все еще выдает SyntaxError: invalid syntax .

Есть ли способ избежать этого? В частности, существуют ли какие-либо настройки при компиляции CPython 3.8 из исходных текстов (или исправления кода), которые позволили бы избежать этой ошибки?

Обратите внимание, что та же ошибка возникает в PyPy 3.

Контекст заключается в том, что в Pyodide, который создает CPython для WebAssembly, можно передавать объекты Javascripts в Python. И из-за существующего ограничения в настоящее время код Python, подобный Promise.new(...).then(...).finally(...) ошибке, выдает синтаксическую ошибку (см. GH-pyodide #769)

Комментарии:

1. Javascript делает все возможное, чтобы разрешить ключевые слова в качестве идентификаторов в некоторых контекстах, но Python этого не делает, и большинство языков, о которых я знаю, этого не делают. Python также не имеет ничего похожего на синтаксис дословного идентификатора C #. То, что вы ищете, может быть возможно, если вы генерируете байт-код напрямую, но на уровне исходного кода — нет.

Ответ №1:

Это невозможно в Python. Стандартный способ обойти это — добавить символ подчеркивания, если имя будет зарезервировано (например finally_ ). В противном случае вы можете просто выбрать другое имя.

В вашем конкретном случае у вас есть код JavaScript, поэтому неясно, почему вы хотите, чтобы он также был действительным кодом Python. Если это не то, что вам нужно выполнять на языке Python, то, вероятно, оно должно быть в виде строки вместо необработанного кода; может быть, есть способ сообщить кросс-компилятору, чтобы он выдавал код JavaScript, представленный в виде строки. Если вам нужно выполнить его в Python-land, тогда getattr(promise, 'finally') он его получит; может быть удобно определить вспомогательную функцию для работы с обещаниями JavaScript в Python, чтобы вам не приходилось писать getattr везде.

Комментарии:

1. Возможно, ссылка / цитата PEP 8 , в которой говорится: «single_trailing_underscore: используется по соглашению, чтобы избежать конфликтов с ключевым словом Python».

2. Спасибо! Мой вариант использования заключается в том, что pyodide позволяет вам взять объект JS (скажем, обещание), создать прокси-объект в Python и использовать его там pyodide.readthedocs.io/en/latest/type_conversions.html . Следовательно, в случае обещания JS это будет объект Python с finally методом. Это правда, что getattr должно сработать, но я искал более элегантное решение. Изменение этого прокси-объекта для добавления a _ к именам ограниченных методов, вероятно, также может быть решением.

Ответ №2:

Я не знаю ни о каких таких флагах, но я полагаю, что это был бы подвиг, учитывая, как зарезервированные ключевые слова встроены в саму грамматику Python. Вам придется внести некоторые структурные изменения, чтобы разрешить использование ключевых слов в качестве имен методов. Это может быть легко, но нужно иметь знания о грамматике Python и о том, как она переводится на C. Вы можете начать с изучения раздела Tools, в частности проектов peg_generator и parser.

Надеюсь, кто-то более осведомленный, чем я, может дать более удовлетворительный ответ.

Комментарии:

1. Спасибо за расследование! Это была моя оценка ситуации, и это правда, что это, вероятно, не стоит усилий.