Я бы хотел мотивировать, что предварительная компиляция выгодна как концептуально, так и «буквально» (как в «грамотном программировании»). взгляните на этот фрагмент кода:
from re import compile as _Re
class TYPO:
def text_has_foobar( self, text ):
return self._text_has_foobar_re_search( text ) is not None
_text_has_foobar_re_search = _Re( r"""(?i)foobar""" ).search
TYPO = TYPO()
в вашем приложении вы бы написали:
from TYPO import TYPO
print( TYPO.text_has_foobar( 'FOObar ) )
это примерно настолько просто с точки зрения функциональности, насколько это возможно. Поскольку этот пример очень короткий, я нашел способ получить _text_has_foobar_re_search
в одной строке. недостаток этого кода в том, что он занимает мало памяти для любого времени жизни библиотечного объекта TYPO
; Преимущество состоит в том, что при выполнении поиска в foobar вы получите два вызова функций и два поиска в словаре классов. сколько регулярных выражений кэшируется re
, и издержки этого кэша здесь не имеют значения.
сравните это с более обычным стилем, приведенным ниже:
import re
class Typo:
def text_has_foobar( self, text ):
return re.compile( r"""(?i)foobar""" ).search( text ) is not None
В приложении:
typo = Typo()
print( typo.text_has_foobar( 'FOObar ) )
Я с готовностью признаю, что мой стиль весьма необычен для python, возможно, даже спорен. однако в примере, который более точно соответствует тому, как Python в основном используется, чтобы выполнить одно совпадение, мы должны создать экземпляр объекта, выполнить три поиска в словаре экземпляра и выполнить три вызова функций; Кроме того, мы можем столкнуться с проблемами re
кэширования при использовании более 100 регулярных выражений. Кроме того, регулярное выражение скрывается внутри тела метода, что в большинстве случаев не очень хорошая идея.
следует сказать, что каждое подмножество мер --- целевые, псевдонимы по импорту; методы с псевдонимами, где это применимо; сокращение вызовов функций и поиска в словаре объектов --- может помочь уменьшить вычислительную и концептуальную сложность.