2010-02-17 13 views
9

J'ai essayé de mettre en œuvre la composition de fonctions avec une belle syntaxe et voici ce que j'ai:composition de la fonction Python

from functools import partial 

class _compfunc(partial): 
    def __lshift__(self, y): 
     f = lambda *args, **kwargs: self.func(y(*args, **kwargs)) 
     return _compfunc(f) 

    def __rshift__(self, y): 
     f = lambda *args, **kwargs: y(self.func(*args, **kwargs)) 
     return _compfunc(f) 

def composable(f): 
    return _compfunc(f) 

@composable  
def f1(x): 
    return x * 2 

@composable 
def f2(x): 
    return x + 3 

@composable 
def f3(x): 
    return (-1) * x 

print f1(2) #4 
print f2(2) #5 
print (f1 << f2 << f1)(2) #14 
print (f3 >> f2)(2) #1 
print (f2 >> f3)(2) #-5 

Il fonctionne très bien avec des nombres entiers, mais échoue sur les listes/tuples:

@composable 
def f4(a): 
    a.append(0) 

print f4([1, 2]) #None 

Où est une erreur?

+0

Je suppose que par « béguin » vous voulez dire "accidents"? Et par "accidents" je suppose que vous voulez dire "jette une exception"? En outre, si je cours le code exact que vous avez posté, cela fonctionne très bien. – porgarmingduod

+1

Je ne vois pas comment 'f4()' ne fonctionne pas comme prévu. Peut-être avez-vous des attentes erronées. –

+0

Merci, Ignacio. J'ai fait une erreur vraiment stupide. – si14

Répondre

9

append-t en place plus, comme Ignacio Vazquez-Abrams dit (bien, implicite) - donc, alors que vous pouvez corriger cela en ajoutant simplement un return à votre fonction, il aurait l'effet secondaire de modifier la argument, il a été adopté aussi:

@composable 
def f4(a): 
    a.append(0) 
    return a 

il serait préférable d'utiliser le code suivant encore plus concise qui crée et retourne un nouvel objet:

@composable 
def f4(a): 
    return a + [0] 
+0

Merci. Mon erreur est horrible. – si14

+1

Nous sommes seulement humains :) – badp

Questions connexes