Поддержка обоих
Я хотел попытаться преобразовать библиотеку BeautifulSoup в 3x для проекта, над которым я работаю, но я понимаю, как трудно поддерживать две разные ветви кода.
Текущая модель для этого включает:
- внести изменения в ветку 2x
- пробег 2to3
- молитесь, чтобы в первый раз это было правильно,
- запустите код
- запустить модульные тесты, чтобы убедиться, что все работает
- скопировать вывод в 3х ветку
Эта модель работает, но ИМХО это отстой. Для каждого изменения / выпуска вы должны пройти через эти шаги :: sigh ::. Кроме того, он не рекомендует разработчикам расширять ветку 3x новыми функциями, которые могут поддерживаться только в py3k, потому что вы по-прежнему нацеливаете весь код на 2x.
Решение ... использовать препроцессор
Поскольку я не смог найти приличный препроцессор в стиле c с директивами #define и #ifdef для python, я написал одну.
Он называется pypreprocessor и может быть найден в PYPI
По сути, то, что вы делаете:
- импортный препроцессор
- определить, какую версию python запускает скрипт в
- установить 'define' в препроцессоре для версии (например, 'python2' или 'python3')
- посыпать директивами #ifdef python2 и #ifdef python3, где код зависит от версии
- запустить код
Вот и все. Теперь это будет работать как в 2 раза, так и в 3 раза. Если вы беспокоитесь о дополнительном падении производительности при запуске препроцессора, есть также режим, который удаляет все метаданные и выводит исходный текст после обработки в файл.
Лучше всего ... преобразование 2to3 нужно выполнить только один раз.
Вот рабочий пример:
#!/usr/bin/env python
# py2and3.py
import sys
from pypreprocessor import pypreprocessor
#exclude
if sys.version[:3].split('.')[0] == '2':
pypreprocessor.defines.append('python2')
if sys.version[:3].split('.')[0] == '3':
pypreprocessor.defines.append('python3')
pypreprocessor.parse()
#endexclude
#ifdef python2
print('You are using Python 2x')
#ifdef python3
print('You are using python 3x')
#else
print('Python version not supported')
#endif
Вот результаты в терминале:
python py2and3.py
>>>You are using Python 2x
python3 py2and3.py
>>>You are using python 3x
Если вы хотите вывести в файл и создать чистый исходный файл для конкретной версии без дополнительных метаданных, добавьте эти две строки где-нибудь перед оператором pypreprocessor.parse ():
pypreprocessor.output = outputFileName.py
pypreprocessor.removeMeta = True
Тогда:
python py2and3.py
Создает файл с именем outputFileName.py, специфичный для Python 2x, без дополнительных метаданных.
python3 py2and3.py
Создает файл с именем outputFileName.py, специфичный для Python 3x, без дополнительных метаданных.
Документацию и другие примеры смотрите в разделе pypreprocessor в GoogleCode .
Я искренне надеюсь, что это поможет. Я люблю писать код на python и надеюсь, что поддержка поддержки продвинется в область 3x как можно скорее. Я ненавижу видеть язык, а не прогресс. В частности, поскольку версия 3x разрешает многие функции WTF и делает синтаксис более удобным для пользователей, переходящих с других языков.
Документация на данный момент полная, но не обширная. Я постараюсь вскоре получить вики более подробную информацию.
Обновление:
Хотя я разработал pypreprocessor специально для решения этой проблемы, он не работает, потому что лексер выполняет синтаксическую проверку всего кода перед выполнением любого кода.
Если бы python имел реальную поддержку директивы препроцессора C, это позволило бы разработчикам писать вместе и код python2x, и python3k вместе в одном файле, но из-за плохой репутации препроцессора C (злоупотребление заменой макросов для изменения языка). ключевые слова) В ближайшее время я не вижу, чтобы в python добавлялась легитимная поддержка препроцессора C.