2016-05-04 2 views
0

J'ai cherché un peu pour cela, alors s'il vous plaît pardonner si j'ai raté quelque chose.peut ** kwargs développer dans args nommé explicite dans un appel de méthode

Je désire généralement que les méthodes dans mon système n'ont que des arguments explicites nommés (autres que moi bien sûr), comme suit:

# want an explicit parameter signature 
def method_1(self, *, x = None, y = None): 
    . . . 
    # and here i want to pass x and/or y if they are not None 
    possible_args = { } 
    if x is not None: 
     possible_args['x'] = x 
    if y is not None: 
     possible_args['y'] = y 

    self.method_2(**possible_args) 

# want an explicit parameter signature 
def method_2(self, *, x = 1, y = None): 
    . . . 

malheureusement, les valeurs de x et/ou y ne sont pas mis en correspondance en les args nommés dans method_2, mais si je le fais à la place à la fin de method_1:

self.method_2(x = x, y = y) 

puis les valeurs par défaut de x et y de method_1 remplacer les valeurs par défaut telle qu'elle est exprimée dans la signature de method_2. Ce que je veux est un moyen, sans vaguifier les signatures de méthodes en acceptant un kwargs complètement ouvert et non spécifié, de mapper tout ce qui pourrait être spécifié dans l'appel dict en paramètres nommés explicites et ne pas remplacer les valeurs par défaut pour les autres arguments qui sont pas dans le dict passé.

est-ce possible?

ceci est pour un système de centaines de classes, et leurs interfaces doivent être très bien spécifiées, sinon c'est folie. c'est pourquoi je ne veux pas passer ** kwargs sauf d'une manière très contrôlée, et je veux aussi tirer parti des arguments nommés ayant des valeurs par défaut spécifiées dans la signature de la méthode. sinon, je pourrais traiter des défauts de paiement au sein du corps de la méthode, bien sûr:

if x is None: 
    x = 5 

qui est tout simplement pas aussi belle ...

+0

Pouvez-vous fournir un [MCVE] qui démontre un comportement incorrect? Je comprends l'essentiel de ce que vous demandez, mais je ne suis pas entièrement certain que je comprends exactement ce que vous voulez. –

+0

@steve: hmmm, dites-vous qu'une telle correspondance devrait avoir lieu? Je vais essayer de faire un meilleur exemple et exécutable. Jusque-là, supposons que j'ai bâclé cela en quelque sorte. va revenir ... merci. – Bruce

+0

soupir. il semble que je me trompe complètement ici. le comportement que j'ai vu était mon propre faire. Dans ma propre défense très maigre, j'ai demandé à notre python très compétent en interne cette même question, et il a dit que ça ne marcherait pas où un kwargs ** passé mapperait ses arguments dans un ensemble d'arguments nommés dans la signature de la méthode appelée , mais il semble, comme j'essaie de tester cela plus loin, qu'il fasse exactement cela. Je suis si heureux à propos de ça, je vais me faire avoir. mes excuses abjects pour avoir perdu votre temps. Si la vengeance est ce que vous voulez maintenant, sachez que j'ai perdu beaucoup plus de mon temps !! : - – Bruce

Répondre

0

Je lui ai donné un tourbillon, parce que je perdais à ce que le problème était. Je suis toujours perdu, mais au moins maintenant je peux vous montrer un MCVE pour elle:

#! /usr/bin/env python3 

''' 
A quick **kwargs demo 
''' 


def method_1(*, x_val=None, y_val=None): 
    ''' 
    A demonstration with kwargs, that calls another with **kwargs. 
    ''' 

    possible_args = {} 
    if x_val is not None: 
     possible_args['x_val'] = x_val 
    if y_val is not None: 
     possible_args['y_val'] = y_val 
    method_2(**possible_args) 


def method_2(*, x_val=1, y_val='y_from_2'): 
    ''' 
    Print things for the demo. 
    ''' 
    print('x_val = ', x_val, ', y_val = ', y_val) 

method_1(x_val=17, y_val=7) 
method_1(x_val=13) 
method_1(y_val=5) 
method_1() 

produit la sortie:

x_val = 17 , y_val = 7 
x_val = 13 , y_val = y_from_2 
x_val = 1 , y_val = 5 
x_val = 1 , y_val = y_from_2 

Ce qui est exactement ce que l'on doit attendre.

+0

cela montre exactement le comportement que je voulais mais je ne pensais pas que je voyais. Merci beaucoup. – Bruce