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

Мне немного любопытно узнать, почему Django 1.9 заменил tuples () на списки [] в настройках, 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),
]

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


person Kjjassy    schedule 18.03.2016    source источник


Ответы (2)


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

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

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

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

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

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

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

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

2) Списки не подвержены проблеме «пропущенная запятая в одноэлементном кортеже», которая укусит как новичков, так и опытных питонистов. В Django даже есть код для защиты от этой ошибки для нескольких настроек. Найдите «tuple_settings» в источнике.

И переключение на списки на самом деле произошло в проблеме № 24149, в которой также упоминалось вышеупомянутое обсуждение.

person Selcuk    schedule 18.03.2016

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

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

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

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

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

person RemcoGerlich    schedule 18.03.2016