2008-12-03 7 views
33

Est-ce que python peut créer des mots-clés dynamiques?Arguments de mots clés dynamiques en Python?

Par exemple:

qset.filter(min_price__usd__range=(min_price, max_price)) 

Je veux être en mesure de changer les USD partie basée sur une devise choisie.

+1

Voir http://stackoverflow.com/questions/310732/in-django-how-does-one-filter-a-queryset-with-dynamic-field-lookups –

Répondre

40

Oui, c'est le cas. Utilisez **kwargs dans une définition de fonction.

Exemple:

def f(**kwargs): 
    print kwargs.keys() 


f(a=2, b="b")  # -> ['a', 'b'] 
f(**{'d'+'e': 1}) # -> ['de'] 

Mais pourquoi avez-vous?

+2

Merci, ça l'a fait. J'en avais besoin car je n'ai pas accès à la fonction elle-même (c'est une fonction Django). Donc, la méthode elle-même est déjà à la recherche de ** kwargs, mais je dois créer dynamiquement le mot-clé de la méthode à analyser. – user42876

0

Oui, en quelque sorte. Dans votre méthode de filtrage, vous pouvez déclarer une variable générique qui recueille toutes les inconnues keyword arguments. Votre méthode pourrait ressembler à ceci:

def filter(self, **kwargs): 
    for key,value in kwargs: 
     if key.startswith('min_price__') and key.endswith('__range'): 
      currency = key.replace('min_price__', '').replace('__range','') 
      rate = self.current_conversion_rates[currency] 
      self.setCurrencyRange(value[0]*rate, value[1]*rate) 
+0

Merci, mais malheureusement je n'ai pas accès à la fonction elle-même (c'est une fonction Django). Donc, la méthode elle-même est déjà à la recherche de ** kwargs, mais je dois créer dynamiquement le mot-clé de la méthode à analyser. – user42876

10

Vous pouvez facilement le faire en déclarant votre fonction comme ceci:

def filter(**kwargs): 

votre fonction sera maintenant passé un dictionnaire appelé kwargs qui contient les mots-clés et des valeurs passées à votre fonction. Notez que, syntaxiquement, le mot kwargs n'a pas de sens; le ** est ce qui provoque le comportement du mot-clé dynamique.

Vous pouvez également faire l'inverse. Si vous appelez une fonction, et vous avez un dictionnaire qui correspond aux arguments, vous pouvez faire

someFunction(**theDictionary) 

Il y a aussi le moins utilisé * variante foo, ce qui vous fait de recevoir un tableau d'arguments. Ceci est similaire aux tableaux vararg normaux.

21

Si je comprends ce que vous demandez correctement,

qset.filter(**{ 
    'min_price_' + selected_currency + '_range' : 
    (min_price, max_price)}) 

fait ce que vous avez besoin.

+1

exactement ce dont j'avais besoin! Merci. –