2016-01-09 1 views
2

J'écris un algo en Python (en l'apprenant juste pour écrire cet algo) et je le casse en petits morceaux ou en modules donc c'est compréhensible.Flux de contrôle Python 3 dans le script avec beaucoup d'étapes

En Python, existe-t-il un moyen propre de parcourir un ensemble de fonctions avec le dernier passage dans la valeur de la précédente?

Je maintenant, mais il y aura probablement une douzaine d'autres étapes ce qui en fait ressembler à une pyramide massive et fo:

calculate_excess_returns(
    calculate_returns(
     get_monthly_historical_returns('./assets/monthly_historical_returns.csv') 
    ) 
) 

Je pourrais aussi le faire, mais je trouve beaucoup moins lisible:

monthly_historical_returns = get_monthly_historical_returns('./assets/monthly_historical_returns.csv') 
calculated_returns = calculate_returns(monthly_historical_returns) 
calculated_excess_returns = calculate_excess_returns(calculated_returns) 

en JavaScript, nous avons un flux de contrôle commun appelé "promesses" qui ressemblent à ceci:

getJSON('story.json') 
    .then(function(story) { 
    return getJSON(story.chapterUrls[0]); 
    }).then(function(chapter1) { 
    console.log("Got chapter 1!", chapter1); 
    }); 

Vous pouvez voir que ça passe les résultats comme ils viennent et il est facile de suivre le flux: getJSON de l'histoire puis getJSON du premier chapitre puis utilisateur tell qu'ils ont obtenu au chapitre 1.

Ce serait bien dans mon script algo pour être en mesure de faire quelque chose de similaire, comme:

SomeModuleOrPackage 
    .startWith(get_monthly_historical_returns('./assets/monthly_historical_returns.csv')) 
    .then(calculate_returns) 
    .then(calculate_excess_returns) 

Juste quelque chose qui est très clair ce que chaque étape est. Peut-être une sorte de tableau des fonctions qui boucle et en quelque sorte passe la valeur à la suivante?

Répondre

2

Fondamentalement, vous voulez une manière plus agréable à la recherche de composer des fonctions. Je vous recommande d'utiliser un package de programmation fonctionnelle, tel que funcy ou fn. Voici un exemple utilisant le premier paquet.

import funcy 


pipeline = funcy.rcompose(
    get_monthly_historical_returns, 
    calculate_returns, 
    calculate_excess_returns 
) 

result = pipeline('./assets/monthly_historical_returns.csv') 

Ou si vous ne prévoyez pas d'utiliser le pipeline à plusieurs reprises, vous pouvez calculer le résultat tout de suite:

result = funcy.rcompose(
    get_monthly_historical_returns, 
    calculate_returns, 
    calculate_excess_returns 
)('./assets/monthly_historical_returns.csv') 

Les fonctions sont exécutées de gauche à droite. La sortie d'une fonction est transmise en tant que premier argument au suivant. Vous pouvez utiliser functools.partial de la bibliothèque standard pour fournir des agréments supplémentaires à vos fonctions, si elles nécessitent plus d'un argument, par ex.

import funcy 
from functools import partial 


composition = funcy.rcompose(
    partial(func1, additional_arg_name=something), 
    ... 
) 

Je pense que vous avez l'idée. En ce qui concerne votre exemple getJSON, vous pouvez passer des fonctions anonymes (lambda) à rcompose pour que le code soit presque identique à votre exemple JavaScript.

Vous pouvez installer le package via pip: pip install funcy

+0

Impressionnant! Le 2ème exemple a parfaitement fonctionné –

1

Vous pouvez les mettre dans un list ou tuple et boucle à travers eux:

var = './assets/monthly_historical_returns.csv' 
for func in (get_monthly_historical_returns, 
      calculate_returns, 
      calculate_excess_returns): 
    var = func(var)