gpt4 book ai didi

python - 带有元组字符串表示的格式错误的字符串 ValueError ast.literal_eval()

转载 作者:IT老高 更新时间:2023-10-28 21:49:23 64 4
gpt4 key购买 nike

我正在尝试从文件中读取元组的字符串表示形式,并将元组添加到列表中。这是相关代码。

raw_data = userfile.read().split('\n')
for a in raw_data :
print a
btc_history.append(ast.literal_eval(a))

这是输出:

(Decimal('11.66985'), Decimal('0E-8'))
Traceback (most recent call last):


File "./goxnotify.py", line 74, in <module>
main()
File "./goxnotify.py", line 68, in main
local.load_user_file(username,btc_history)
File "/home/unix-dude/Code/GoxNotify/local_functions.py", line 53, in load_user_file
btc_history.append(ast.literal_eval(a))
File "/usr/lib/python2.7/ast.py", line 80, in literal_eval
return _convert(node_or_string)

`File "/usr/lib/python2.7/ast.py", line 58, in _convert
return tuple(map(_convert, node.elts))
File "/usr/lib/python2.7/ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string

最佳答案

ast.literal_eval(位于 ast.py 中)首先用 ast.parse 解析树,然后用相当一个丑陋的递归函数,解释解析树元素并用它们的文字等价物替换它们。不幸的是,代码根本无法扩展,因此要将 Decimal 添加到代码中,您需要复制所有代码并重新开始。

为了更简单的方法,您可以使用 ast.parse 模块来解析表达式,然后使用 ast.NodeVisitorast.NodeTransformer 以确保没有不需要的语法或不需要的变量访问。然后用 compileeval 编译得到结果。

这段代码和literal_eval有点不同,这段代码实际上使用了eval,但在我看来更容易理解,不需要深挖进入 AST 树。它专门只允许某些语法,明确禁止例如 lambdas、属性访问(foo.__dict__ 非常邪恶)或访问任何被认为不安全的名称。它可以很好地解析你的表达式,另外我还添加了 Num( float 和整数)、列表和字典文字。

此外,在 2.7 和 3.3 上的工作方式相同

import ast
import decimal

source = "(Decimal('11.66985'), Decimal('1e-8'),"\
"(1,), (1,2,3), 1.2, [1,2,3], {1:2})"

tree = ast.parse(source, mode='eval')

# using the NodeTransformer, you can also modify the nodes in the tree,
# however in this example NodeVisitor could do as we are raising exceptions
# only.
class Transformer(ast.NodeTransformer):
ALLOWED_NAMES = set(['Decimal', 'None', 'False', 'True'])
ALLOWED_NODE_TYPES = set([
'Expression', # a top node for an expression
'Tuple', # makes a tuple
'Call', # a function call (hint, Decimal())
'Name', # an identifier...
'Load', # loads a value of a variable with given identifier
'Str', # a string literal

'Num', # allow numbers too
'List', # and list literals
'Dict', # and dicts...
])

def visit_Name(self, node):
if not node.id in self.ALLOWED_NAMES:
raise RuntimeError("Name access to %s is not allowed" % node.id)

# traverse to child nodes
return self.generic_visit(node)

def generic_visit(self, node):
nodetype = type(node).__name__
if nodetype not in self.ALLOWED_NODE_TYPES:
raise RuntimeError("Invalid expression: %s not allowed" % nodetype)

return ast.NodeTransformer.generic_visit(self, node)


transformer = Transformer()

# raises RuntimeError on invalid code
transformer.visit(tree)

# compile the ast into a code object
clause = compile(tree, '<AST>', 'eval')

# make the globals contain only the Decimal class,
# and eval the compiled object
result = eval(clause, dict(Decimal=decimal.Decimal))

print(result)

关于python - 带有元组字符串表示的格式错误的字符串 ValueError ast.literal_eval(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14611352/

64 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com