我遇到了这段代码并且它有效,但我不完全确定何时使用ast 和是否存在性能问题使用此代码而不是获取来自input()
的字符串值并将其转换为int。
import ast
cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
# this get the user input as an int to the variable cyper_key
我阅读了我理解它的作用的文档。
这可以用于安全地评估包含Python的字符串 来自不受信任来源的值,无需解析值 自己。它无法评估任意复杂性 表达式,例如涉及运算符或索引。
我正在寻找上述大胆点的解释。
答案 0 :(得分:7)
何时使用。
如果您期望用户列出(或类似的)列表,那么 ast.literal_eval(input())
会很有用。例如,'[1,2]'
将转换为[1,2]
。
如果用户应提供号码ast.literal_eval(input())
可以替换为float(input())
,或int(input())
如果需要整数。
效果
请注意premature [micro-]optimization is the root of all evil.但是,因为你问:
要测试ast.literal_eval(input())
和float(input()
的速度,您可以使用timeit
。
根据用户提供的输入,时间会发生变化。
Ints和float是有效的输入,而其他任何东西都是无效的。给予50%的整数,40%的浮动和10%的随机输入,float(input())
x12 更快。
10%,10%,80%和float(input())
x6 更快。
import timeit as tt
lst_size = 10**5
# Set the percentages of input tried by user.
percentages = {'ints': .10,
'floats': .10,
'strings': .80}
assert 1 - sum(percentages.values()) < 0.00000001
ints_floats_strings = {k: int(v*lst_size) for k, v in percentages.items()}
setup = """
import ast
def f(x):
try:
float(x)
except:
pass
def g(x):
try:
ast.literal_eval(x)
except:
pass
l = [str(i) for i in range({ints})]
l += [str(float(i)) for i in range({floats})]
l += [']9' for _ in range({strings}//2)] + ['a' for _ in range({strings}//2)]
""".format(**ints_floats_strings)
stmt1 = """
for i in l:
f(i)
"""
stmt2 = """
for i in l:
g(i)
"""
reps = 10**1
t1 = tt.timeit(stmt1, setup, number=reps)
t2 = tt.timeit(stmt2, setup, number=reps)
print(t1)
print(t2)
print(t2/t1)
答案 1 :(得分:1)
如果它将用作int
,那么只需使用:
cypher_key = int(input("Enter the key (a value between 0 and 25) : "))
如果您希望用户输入10e7
或其他内容,请仅使用该功能。如果你想处理不同的基础,你可以使用int(input(...), 0)
自动神圣基础。如果它确实是0到25之间的整数值,则没有理由使用ast
。
答案 2 :(得分:0)
在python-3.x shell中运行它,当我给出正确的输入时,我没有区别:
>>> cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
Enter the key (a value between 0 and 25) : 5
>>> cyper_key
5
但是,当您提供字符串或无法转换的内容时,错误可能会造成混淆和/或误导:
>>> cyper_key = ast.literal_eval(input("Enter the key (a value between 0 and 25) : "))
Enter the key (a value between 0 and 25) : foo
Traceback (most recent call last):
File "python", line 3, in <module>
ValueError: malformed node or string: <_ast.Name object at 0x136c968>
但是,如果您不想将float
或int
投射到您的输入中,这可能很有用,这可能导致ValueErrors
或int
或float
您ast
的浮点数。
因此,我发现在使用{{1}}解析您的输入时没有使用必要,但它可以作为替代。
答案 3 :(得分:0)
ast -> Abstract Syntax Trees
如果输入不是有效的Python数据类型,则 ast.literal_eval
会引发异常,因此如果代码不是,则不会执行代码。
这个链接AST对您有用了解。