Automatically Type Cast Parameters In Python

后端 未结 6 2039
死守一世寂寞
死守一世寂寞 2020-12-30 04:37

Background:
I mostly run python scripts from the command line in pipelines and so my arguments are always strings that need to be type casted to the app

6条回答
  •  孤城傲影
    2020-12-30 05:26

    You could just use plain eval to input string if you trust the source:

    >>> eval("3.2", {}, {})
    3.2
    >>> eval("True", {}, {})
    True
    

    But if you don't trust the source, you could use literal_eval from ast module.

    >>> ast.literal_eval("'hi'")
    'hi'
    >>> ast.literal_eval("(5, 3, ['a', 'b'])")
    (5, 3, ['a', 'b'])
    

    Edit: As Ned Batchelder's comment, it won't accept non-quoted strings, so I added a workaround, also an example about autocaste decorator with keyword arguments.

    import ast
    
    def my_eval(s):
        try:
            return ast.literal_eval(s)
        except ValueError: #maybe it's a string, eval failed, return anyway
            return s       #thanks gnibbler
    
    def autocaste(func):
        def wrapped(*c, **d):
            cp = [my_eval(x) for x in c]
            dp = {i: my_eval(j) for i,j in d.items()} #for Python 2.6+
            #you can use dict((i, my_eval(j)) for i,j in d.items()) for older versions
            return func(*cp, **dp)
    
        return wrapped
    
    @autocaste
    def f(a, b):
        return a + b
    
    print(f("3.4", "1")) # 4.4
    print(f("s", "sd"))  # ssd
    print(my_eval("True")) # True
    print(my_eval("None")) # None
    print(my_eval("[1, 2, (3, 4)]")) # [1, 2, (3, 4)]
    

提交回复
热议问题