Почему Django 1.9 заменил tuples () на списки [] в настройках и URL?

Мне немного любопытно узнать, почему Django 1.9 заменил кортежи () списками [] в настройках, URL-адресах и других файлах конфигурации

Я только что обновился до Django 1.9 и заметил эти изменения. Какая логика стоит за ними?

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles'
    ]

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

urls.py

urlpatterns = [
    url(r'^', admin.site.urls),
]

Из-за этих изменений что-то изменилось?

2 ответа

Решение

Это объясняется в выпуске № 8846 (выделено мной):

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

Это койка Профилирование показывает, что для большинства операций кортежи выполняются не быстрее списков (конечно, зацикливание, что мы, скорее всего, будем делать чаще всего). С другой стороны, синтаксис литерала списка имеет то преимущество, что он не сводится к одному значению, когда у вас есть один элемент и пропускается запятая, как синтаксис кортежа. Использование синтаксиса списка не медленнее, более разборчиво и менее подвержено ошибкам. В более широком сообществе Python часто высказывается мнение, что кортежи не следует рассматривать как неизменяемые списки. Они предназначены для записей фиксированной длины - действительно, математическая концепция кортежа совершенно отличается от концепции последовательности.

Также смотрите этот ответ для более актуального обсуждения.

Другой ответ (не связанный непосредственно с этой проблемой) демонстрирует, что доступ к элементам на самом деле быстрее с list,

Обновление и дополнительная информация: верно, что вышеупомянутая проблема была закрыта несколько лет назад, но я включил ее, потому что она объяснила обоснование решения, и многие подобные обсуждения относятся к одному и тому же заявлению. Фактическое решение о реализации было принято после следующего обсуждения разработчиков django, начатого разработчиком ядра Django Аймериком Августином:

Я предпочитаю их [списки] по двум причинам:

1) Все эти настройки представляют собой последовательности похожих вещей. Такие значения лучше всего представлять в виде списков, если только они не должны быть неизменяемыми, и в этом случае можно использовать кортеж. (в Python кортежи - это как "именованные кортежи без имен", так и "неизменяемые списки".)

2) Списки не подвержены проблеме "пропущенной запятой в кортеже из одного элемента", которая кусает как начинающих, так и опытных питонистов. У Django даже есть код для защиты от этой ошибки для нескольких настроек. Ищите "tuple_settings" в источнике.

А переход к спискам фактически произошел в выпуске № 24149, в котором также упоминалось вышеизложенное.

В примечаниях к выпуску 1.9 есть:

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

Настройки по умолчанию в django.conf.global_settings были комбинацией списков и кортежей. Все настройки, которые раньше были кортежами, теперь являются списками.

Таким образом, кажется, что это было просто сделано для согласованности. И кортежи, и списки должны работать нормально. Если вы используете кортеж с 1 элементом, запомните (1,) потому что иначе это не кортеж, а просто выражение в скобках.

Что касается urlpatterns, те, которые были определены с использованием patterns() функция, но это устарело в Django 1.8, так как список экземпляров URL работает нормально. Поскольку функция будет удалена в будущем, ее не следует использовать в новых приложениях и проектах.

Другие вопросы по тегам