Tapez automatiquement les paramètres de diffusion en Python
De fond:
J'ai principalement d'exécuter des scripts python à partir de la ligne de commande dans les pipelines et si mes arguments sont toujours les chaînes qui doivent être de type coulé du type approprié. Je fais beaucoup de petits scripts chaque jour et de conversion de type de chaque paramètre pour chaque script prend plus de temps qu'il ne le devrait.
Question:
Est-il une manière canonique pour automatiquement le type de fonte paramètres d'une fonction?
Ma Façon:
J'ai développé un décorateur pour faire ce que je veux si il n'y a pas une meilleure façon. Le décorateur est l'autocast fxn ci-dessous. La décorées fxn est fxn2 dans l'exemple. Notez qu'à la fin du bloc de code j'ai passé 1 et 2 comme des chaînes de caractères et si vous exécutez le script, il va ajouter automatiquement. Est-ce une bonne façon de le faire?
def estimateType(var):
#first test bools
if var == 'True':
return True
elif var == 'False':
return False
else:
#int
try:
return int(var)
except ValueError:
pass
#float
try:
return float(var)
except ValueError:
pass
#string
try:
return str(var)
except ValueError:
raise NameError('Something Messed Up Autocasting var %s (%s)'
% (var, type(var)))
def autocast(dFxn):
'''Still need to figure out if you pass a variable with kw args!!!
I guess I can just pass the dictionary to the fxn **args?'''
def wrapped(*c, **d):
print c, d
t = [estimateType(x) for x in c]
return dFxn(*t)
return wrapped
@autocast
def fxn2(one, two):
print one + two
fxn2('1', '2')
EDIT: Pour la personne qui vient ici et veut que la mise à jour et concis version de travail rendez-vous ici:
https://github.com/sequenceGeek/cgAutoCast
Et ici est aussi rapide version de travail basé sur la ci-dessus:
def boolify(s):
if s == 'True' or s == 'true':
return True
if s == 'False' or s == 'false':
return False
raise ValueError('Not Boolean Value!')
def estimateType(var):
'''guesses the str representation of the variables type'''
var = str(var) #important if the parameters aren't strings...
for caster in (boolify, int, float):
try:
return caster(var)
except ValueError:
pass
return var
def autocast(dFxn):
def wrapped(*c, **d):
cp = [estimateType(x) for x in c]
dp = dict( (i, estimateType(j)) for (i,j) in d.items())
return dFxn(*cp, **dp)
return wrapped
######usage######
@autocast
def randomFunction(firstVar, secondVar):
print firstVar + secondVar
randomFunction('1', '2')
source d'informationauteur sequenceGeek
Vous devez vous connecter pour publier un commentaire.
Si vous voulez auto-convertir des valeurs:
Vous pouvez ajuster
boolify
à accepter d'autres valeurs booléennes si vous le souhaitez.Vous pouvez simplement utiliser de la plaine eval de la chaîne d'entrée si vous faites confiance à la source:
Mais si vous ne faites pas confiance à la source, vous pouvez utiliser literal_eval d'ast module.
Edit:
Comme Ned Batchelder commentaire, il n'accepte pas non chaînes entre guillemets, j'ai donc ajouté une solution de contournement, un exemple à propos de autocaste décorateur avec le mot-clé arguments.
J'imagine que vous pouvez faire une signature de type système avec une fonction décorateur, comme vous l'avez, un seul qui prend des arguments. Par exemple:
Tel un décorateur peut être construit assez facilement. Quelque chose comme ceci (EDIT -- marche!):
Et juste comme ça, vous pouvez maintenant imprégner des fonctions de type signatures!
En gros, c'est un type explicite version de @utdemir de la méthode.
Si vous êtes à l'analyse des arguments de la ligne de commande, vous devez utiliser le
argparse
module (si vous utilisez Python 2.7).Chaque argument peut avoir un type prévu afin de savoir à quoi il devrait être relativement simple. Vous pouvez même définir vos propres types.
Il y a quelques problèmes dans votre code.
Ce serait toujours vérifier pour
True
parce que vous êtes des tests contre les cordes'True'
et'False'
.Il n'est pas automatique, la contrainte de types de python. Vos arguments lorsque vous recevez via
*args
et**kwargs
peut être n'importe quoi. La première va chercher la liste de valeurs (qui peut être n'importe quel type de données primitif et complexe) et de la seconde recherchez un mapping (avec toute la cartographie possible). Donc, si vous écrivez un décorateur, vous allez vous retrouver avec une bonne liste de vérifications d'erreur.Normalement, si vous souhaitez envoyer dans str, juste au moment où la fonction est appelée, catalogué à la chaîne via (
str
) et de l'envoyer.Je sais je suis arrivé en retard à ce jeu, mais que diriez-eval?
ou bien (et avec plus de sécurité):