2016-03-18 2 views
34

Je suis peu curieux de savoir pourquoi Django 1.9 remplacé tuples() avec des listes [] dans les paramètres, les URL et autres fichiers de configurationPourquoi Django 1.9 a-t-il remplacé les tuples() par lists [] dans les paramètres et les URL?

Je viens de mettre à Django 1.9 et remarqué ces changements. Quelle est la logique derrière eux?

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), 
] 

Est-ce quelque chose de différent à cause de ces changements?

Répondre

53

Il est expliqué dans le numéro #8846 (moi qui souligne):

Dans la documentation pour créer vos propres paramètres, il y a une recommandation qui se lit « Pour les paramètres qui sont des séquences, utilisez tuples au lieu de listes. C'est purement pour la performance. "

Ceci est une couchette. Le profilage montre que les tuples ne s'exécutent pas plus vite que les listes pour la plupart des opérations (certainement en boucle, ce que nous sommes susceptibles de faire le plus souvent avec ). D'autre part, syntaxe liste littérale a l'avantage que il ne se réduit pas à une seule valeur lorsque vous avez un seul élément et omettre la virgule, comme la syntaxe tuple. Utilisation de la syntaxe de liste n'est pas plus lent, plus lisible et moins sujet aux erreurs. Une vue souvent exprimée dans la communauté Python plus large semble que les tuples ne doivent pas être considérés comme des listes immuables. Ils sont conçus comme des enregistrements de longueur fixe - en effet, le concept mathématique d'un tuple est tout à fait distinct de celui d'une séquence .

Voir également this answer pour une discussion plus à jour.

Une autre answer (pas directement lié à cette question) démontre que les éléments accès est plus rapide avec un list. Il est correct que le problème ci-dessus a été fermé il ya des années, mais je l'ai inclus parce qu'il a expliqué la logique derrière la décision et de nombreuses discussions similaires se réfèrent à la même fiche. La décision de mise en œuvre effective a été déclenchée après la following discussion on django-developers a commencé par noyau développeur Django Aymeric Augustin:

je les préfère [liste] pour deux raisons:

1) Tous ces paramètres sont des séquences de choses semblables. De telles valeurs sont mieux représentées avec des listes, sauf si elles doivent être immuables, en auquel cas un tuple peut être utilisé. (Les tuples sont tous les deux "namedtuples sans les noms " et "listes immuables" en Python.)

2) Les listes ne sont pas sujettes aux "virgules manquantes en un seul item" problème qui mord les débutants et les pythonistes expérimentés. Django a même du code pour se défendre contre cette erreur pour une poignée de paramètres . Recherchez "tuple_settings" dans la source.

Et le passage aux listes s'est réellement passé dans issue #24149 qui a également fait référence à la discussion ci-dessus.

10

En the release notes of 1.9, il y a:

Les paramètres par défaut qui étaient tuples sont des listes maintenant

Les paramètres par défaut dans django.conf.global_settings étaient une combinaison de listes et tuples. Tous les paramètres qui étaient auparavant des tuples sont maintenant des listes.

Il semble donc que ce soit juste fait pour la cohérence. Les tuples et les listes devraient fonctionner correctement. Si vous utilisez un tuple avec 1 élément, rappelez-vous la virgule (1,) car sinon ce n'est pas un tuple mais simplement une expression en parens. Quant aux urlpatterns, ceux-ci étaient définis à l'aide d'une fonction patterns(), mais cela était obsolète dans Django 1.8, car une liste d'instances d'URL fonctionne correctement. Comme la fonction sera supprimée à l'avenir, elle ne doit pas être utilisée dans de nouvelles applications et de nouveaux projets.