2016-05-13 1 views
2

Скажем, у меня есть пользовательский класс, производный от str, который реализует/переопределяет некоторые методы:Возможно ли использовать персонализированные префиксы строк в Python?

class mystr(str): 
    # just an example for a custom method: 
    def something(self): 
     return "anything" 

Теперь в настоящее время я должен вручную создавать экземпляры mystr, передавая ему строку в конструкторе:

ms1 = mystr("my string") 

s = "another string" 
ms2 = mystr(s) 

Это не так уж плохо, но это приводит к мысли, что было бы здорово использовать пользовательский строковый префикс, похожий на b'bytes string' или r'raw string' или u'unicode string'.

ли это как-то возможно в Python, чтобы создать/зарегистрировать такой обычай строкового литерала префикс как m так, что буквальных m'my string' результатов в новом экземпляре mystr?
Или эти префиксы жестко закодированы в интерпретаторе Python?

+0

К сожалению, нет, не изменяя интерпретатор и не компилируя свои собственные.Интересно, что это то, что [ECMAScript может сделать в будущем] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals). –

ответ

7

Эти префиксы жестко закодированы в интерпретаторе, вы не можете зарегистрировать больше префиксов.


Что вы могли сделать однако, предобработки файлов Python, с помощью пользовательского источника кодека. Это довольно аккуратный взлом, который требует регистрации пользовательского кодека, а также для понимания и применения преобразований исходного кода.

Python позволяет указать кодировку исходного кода специальным комментарием: в верхней части

# coding: utf-8 

бы сказать Python, что исходный код кодированного с UTF-8, и будет декодировать файл соответственно перед разбором , Python ищет кодек для этого в реестре модулей codecs. И вы можете зарегистрировать свои собственные кодеки.

pyxl project использует этот трюк, чтобы проанализировать синтаксис HTML из файлов Python, чтобы заменить их на реальный синтаксис Python для создания этого HTML-кода на этапе «декодирования». См. codec package в этом проекте, где register module регистрирует custom codec search function, который преобразует исходный код, прежде чем Python фактически анализирует и компилирует его. A custom .pth file установлен в ваш каталог site-packages, чтобы загрузить этот шаг регистрации во время запуска Python. Другой проект, который делает то же самое, чтобы проанализировать форматирование строки в стиле Ruby, - interpy.

Все, что вам нужно сделать тогда, построить такой кодек также, что будет анализировать исходный файл Python (размечает это, возможно, с tokenize module) и заменяет строки литералов пользовательского префикса с mystr(<string literal>) вызовов. Любой файл, который вы хотите проанализировать, вы отмечаете с помощью # coding: yourcustomcodec.

Я оставлю эту часть в качестве упражнения для читателя. Удачи!

Обратите внимание, что результат этого преобразования затем скомпилируется в байт-код, который кэшируется; ваша трансформация должна только запустить один раз на версию исходного кода, все остальные импорт модуля с использованием вашего кодека загрузит кешированный байт-код.

+0

Вау, я не уверен, что это хорошая смерть, но фактор взлома отличный –

+0

Эй, это классный подход. Определенно, ничто не хотело бы в производственном коде, но было бы точно. Я просто боюсь, что просто написать 'mystr (« моя строка »)' намного проще ...;) будет придерживаться этого. Благодаря! –

+0

@ByteCommander: Ну, я уверен, что Dropbox использует кодек 'pyxl' в производстве. Регистрация кодека довольно легкая, и шаг преобразования декодирования-токенизации должен иметь место * во время компиляции *. Результат компилируется в байт-код и кэшируется. Этот шаг не повторяется до тех пор, пока исходный код не изменится, что приведет к недействительности кеша байт-кода. –

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