Python отказывается от text.replace () в одной среде - PullRequest
3 голосов
/ 04 марта 2011

Я издевался над следующим грязным кодом поддержки для приложения pylons, которое работает отлично в оболочке python, отдельном файле python или при работе в paster. Теперь мы поместили приложение в режиме онлайн через mod_wsgi и apache, и этот конкретный фрагмент кода перестал работать полностью. Во-первых, сам код:

def fixStyle(self, text):
    t = text.replace('<p>', '<p style="%s">' % (STYLEDEF,))
    t = t.replace('class="wide"', 'style="width: 125px; %s"' % (STYLEDEF,))
    t = t.replace('<td>', '<td style="%s">' % (STYLEDEF,))
    t = t.replace('<a ', '<a style="%s" ' % (LINKSTYLE,))
    return t

Это кажется довольно простым, и, честно говоря, это так. Так что же происходит, когда я помещаю в него фрагмент текста, например:

<table><tr><td>Test!</td></tr></table>

Вывод должен быть:

<table><tr><td style="stuff-from-styledef">Test!</td></tr></table>

и это так, на большинстве систем. Когда мы помещаем это через приложение на Apache / mod_wsgi, происходит следующее:

<table><tr><td>Test!</td></tr></table>

Вы догадались.

Я поставил logging в начале вывода текста, а в конце вывода исходного текста и переменной t. Он отображает то, что я здесь представляю: в большинстве систем t изменяется, в среде apache это не так.

Конечно, я удостоверился, что перезапускаю apache (чтобы он перезагружал файлы .py) после каждого изменения, и это отражено в выходных данных журнала.

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

Если чего-то не хватает, я отредактирую это.

Ответы [ 3 ]

0 голосов
/ 04 марта 2011

Понятия не имею, в чём ваша проблема, но я считаю, что повторение replace() не очень хорошая вещь: если в строке четыре шаблона, будет создание новой строки в 4 раза.

ИМО, это должно быть лучше:

def fixStyle(self, text):
    t = text.replace('<p>', '<p style="%s">' % (STYLEDEF,))
    t = t.replace('class="wide"', 'style="width: 125px; %s"' % (STYLEDEF,))
    t = t.replace('<td>', '<td style="%s">' % STYLEDEF)
    t = t.replace('<a ', '<a style="%s" ' % (LINKSTYLE,))
    return t

import re

STYLEDEF = 'stuff-from-styledef'
LINKSTYLE = 'VVVV'

def aux(m, dic = {'<p':('<p style="',STYLEDEF),
                  '<td':('<td style="',STYLEDEF),
                  'class="wide"':('style="width: 125px; ',STYLEDEF),
                  '<a':('<a style="',LINKSTYLE)} ):

    return '%s%s"' % dic[m.group()]

pat = re.compile('<p(?=>)>|class="wide"|<td(?=>)|<a(?= )')

ch = '<table><tr><td>Test!</td></tr></table><a type="brown" >'
print ch
print fixStyle(None, ch)
print pat.sub(aux,ch)

результат

<table><tr><td>Test!</td></tr></table><a type="brown" >
<table><tr><td style="stuff-from-styledef">Test!</td></tr></table><a style="VVVV" type="brown" >
<table><tr><td style="stuff-from-styledef">Test!</td></tr></table><a style="VVVV" type="brown" >

Я думаю, re.sub() выполняет замены только за один проход по строке.

Определение параметра dic с аргументом по умолчанию => значение присваивается dic при определении aux () и больше не изменяется , При каждом вызове не передается аргумент dic с внешнего уровня: значение сохраняется внутри функции.

Кроме того, функция aux () не должна выходить и искать значения STYLEDEF и LINKSTYLE, кроме функции.

Все это должно увеличить скорость выполнения.

.

EDIT: Поскольку ' style="' и STYLEDEF являются общими для нескольких возвращаемых результатов, я попытался сократить их список и обнаружил

def aux(m, dic = {'<p'          :'<p style="%s"',
                  '<td'         :'<td style="%s"',
                  'class="wide"':'style="width: 125px; %s"'} ):
    if m.group(1):
        return '<a style="%s"' % LINKSTYLE
    else:
        return dic[m.group()] % STYLEDEF

pat = re.compile('<p(?=>)|class="wide"|<td(?=>)|(<a)(?= )')

Чтобы снять условные строки, я написал предыдущее решение и, я не знаю почему, я остановился на этом. Интерес решения заключался в написании строки регулярного выражения с утверждениями, позволяющими написать решение Джона Мачина, но я осквернил его этими тупыми кортежами.

Существует также это решение:

def aux(m, STY = STYLEDEF,LIN = LINKSTYLE ):
    return ( 'style="width: 125px; ' if m.group(3) else m.group(1)+' style="' ) + \
           ( LIN if m.group(2) else STY) + '"'   

pat = re.compile('(<p(?=>)|<td(?=>)|(<a(?= )))|(class="wide")')

Но более ясное и простое решение, как заметил Джон Мачин:

def aux(m, dic = {'<p' :'<p style="%s"' % STYLEDEF,
                  '<td':'<td style="%s"' % STYLEDEF,
                  '<a' :'<a style="%s"' % LINKSTYLE,
                  'class="wide"':'style="%s"' % ('width: 125px; '+STYLEDEF) } ):
    return dic[m.group()] 

pat = re.compile('<p(?=>)|class="wide"|<td(?=>)|<a(?= )')

Значения в dic рассчитываются только при выполнении определения функции aux () .

На самом деле, это очень близко к аргументам функций replace().

0 голосов
/ 07 марта 2011

Извините, но: описания отладки, в которых не упоминается repr(), не заслуживают доверия. Убедитесь, что вы регистрируете repr(text) и repr(t), НЕ text и t.

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

0 голосов
/ 04 марта 2011

Добавьте несколько печатных отчетов и изучите журналы Apache:

def fixStyle(self, text):
    print "text:", text
    print "STYLEDEF", STYLEDEF
    t = text.replace('<p>', '<p style="%s">' % (STYLEDEF,))
    print "t:", t
...