2010-11-29 48 views
4

Définition d'une fonction,Quelle est la façon pythonique de gérer les arguments * vides lors de la création d'un ensemble?

myfunction (argument * args): [faire quelque chose à l'argument [arg] pour arg args *]

si * args est vide, la fonction ne fait rien , mais je veux faire le comportement par défaut « utiliser la totalité de l'ensemble si la longueur de * args == 0 »

def Export(source, target, *args, sep=','): 
    for item in source: 
     SubsetOutput(WriteFlatFile(target), args).send(item[0]) 

Je ne veux pas vérifier la longueur de args à chaque itération, et je ne peux pas Accédez aux clés de dans la source jusqu'à ce que l'itération commence ...

pour que je puisse

if len(args) != 0: 
    for item in source: 

else 
    for item in source: 

qui fonctionnera probablement mais ne semble pas assez « pythonique »?

est-ce une façon standard d'approcher * args ou ** kwargs et comportement par défaut quand l'un est vide?

Plus code:

def __coroutine(func): 
    """ 
    a decorator for coroutines to automatically prime the routine 
    code and method from 'curous course on coroutines and concurrency' 
    by david beazley www.dabeaz.com 
    """ 

    def __start(*args, **kwargs): 
     cr = func(*args, **kwargs) 
     next(cr) 
     return cr 
    return __start 


def Export(source, target, *args, sep=','): 
    if args: 
     for item in source: 
      SubsetOutput(WriteFlatFile(target, sep), args).send(item) 
    else: 
     for item in source: 
      WriteFlatFile(target, sep).send(item) 

@__coroutine 
def SubsetOutput(target, *args): 
    """ 
    take *args from the results and pass to target 

    TODO 
    ---- 
    raise exception when arg is not in result[0] 
    """ 
    while True: 
     result = (yield) 
     print([result.arg for arg in result.dict() if arg in args]) 
     target.send([result.arg for arg in result.dict if arg in args]) 


@__coroutine 
def WriteFlatFile(target, sep): 
    """ 
    take set of results to a flat file 

    TODO 
    ---- 
    """ 
    filehandler = open(target, 'a') 
    while True: 
     result = (yield) 
     line = (sep.join([str(result[var]) for 
         var in result.keys()])).format(result)+'\n' 
     filehandler.write(line) 
+0

écrivez-vous 'l'exportation()' 'ou SubsetOutput()'? –

+0

bien, les deux. L'exportation est la «source» pour le début d'un tuyau de coroutine. Si la fonction d'exportation est appelée avec * args, les * args doivent être retirés de 'source' avant d'être envoyés dans le tube. –

+0

Est-ce que "argument" est une liste ou un dict? Do * args indice comme index de liste ou clés de dictionnaire? – kevpie

Répondre

3

est-il un moyen de passer un argument « ensemble complet » à SubsetOutput, de sorte que vous pouvez enterrer le conditionnel à l'intérieur de son appel plutôt que d'avoir un if explicite? Cela pourrait être None ou [], par exemple. Si ce n'est pas le cas, j'irais avec la solution à deux boucles, en supposant que la boucle est vraiment une seule ligne. Il lit bien et est un cas d'utilisation raisonnable pour un peu de duplication de code.

def Export(source, target, *args, sep=','): 
    if args: 
     for item in source: 
      SubsetOutput(WriteFlatFile(target), args).send(item[0]) 
    else: 
     for item in source: 
      FullOutput(WriteFlatFile(target)).send(item[0]) 
+0

la solution à deux boucles semble être la plus facile à mettre en œuvre (dans ce cas), même si je suppose que j'étais plus préoccupé par le cas général où la boucle peut ne pas être une seule ligne. Essayer d'éviter la répétition du code. –

0

Il suffit de vérifier sa non pas, vous ne devez pas créer un argument séparé

def test(*args): 
    if not args: 
     return #break out 
    return True #or whatever you want 
1

Que diriez-vous ceci:

def MyFunc(argument, *args): 
    (DoSomething for i in (filter(args.__contains__ ,argument) if args else argument))