Параметры автоматического ввода литья на питоне

Background:
В основном я выполняю питоновые сценарии из командной строки в трубопроводах, и поэтому мои аргументы всегда представляют собой строки, которые должны быть приведены к соответствующему типу. Я делаю много маленьких скриптов каждый день и приведение типа каждого параметра для каждого скрипта занимает больше времени, чем должно.

Вопрос:
Существует ли канонический способ автоматического приведения параметров к типу функции?

Мой способ:
Я разработал декоратора, чтобы делать то, что я хочу, если нет лучшего способа. Декоратором является автоматическое литье fxn ниже. Декорированный fxn является fxn2 в примере. Обратите внимание, что в конце блока кода я передал 1 и 2 в качестве строк, и если вы запустите скрипт, он будет автоматически добавлять их. Хороший ли это способ?

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: Для всех, кто приходит сюда и хочет обновлённую и лаконичную рабочую версию, перейдите сюда:

https://github.com/sequenceGeek/cgAutoCast

И вот также быстрая рабочая версия, основанная на вышеприведённой информации:

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')

13
задан sequenceGeek 2 April 2012 в 06:23
поделиться