首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >假设unicode_literals,如何安全地计算文字的表示?

假设unicode_literals,如何安全地计算文字的表示?
EN

Stack Overflow用户
提问于 2019-01-16 20:22:34
回答 3查看 121关注 0票数 3

在Python 2中,我想计算包含文字表示的字符串。我想安全地这样做,所以我不想使用eval()-instead--我已经习惯于使用ast.literal_eval()来完成这类任务。

但是,我还想在这样的假设下进行评估,即纯文本引号中的字符串表示unicode对象,即您在from __future__ import unicode_literals中得到的与前向兼容的行为。在下面的示例中,eval()似乎尊重这个偏好,但ast.literal_eval()似乎不尊重这个偏好。

代码语言:javascript
复制
from __future__ import unicode_literals, print_function

import ast

raw = r"""   'hello'    """

value = eval(raw.strip())
print(repr(value))
# Prints:
# u'hello'

value = ast.literal_eval(raw.strip())
print(repr(value))
# Prints:
# 'hello'

注意,我正在寻找一个通用的literal_eval替代品--我事先不知道输出必然是一个字符串对象。我希望能够假设raw是任意Python文字的表示,它可能是字符串,也可能包含一个或多个字符串,或者不包含字符串。

有没有一种方法可以使这两个世界都发挥最大的作用:一个既安全地计算任意Python文本的表示,又尊重unicode_literals首选项的函数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-16 20:37:17

ast.literal_evalast.parse都没有提供设置编译器标志的选项。您可以将适当的标志传递给compile以解析unicode_literals激活的字符串,然后在结果节点上运行ast.literal_eval

代码语言:javascript
复制
import ast

# Not a future statement. This imports the __future__ module, and has no special
# effects beyond that.
import __future__

unparsed = '"blah"'
parsed = compile(unparsed,
                 '<string>',
                 'eval',
                 ast.PyCF_ONLY_AST | __future__.unicode_literals.compiler_flag)
value = ast.literal_eval(parsed)
票数 4
EN

Stack Overflow用户

发布于 2019-01-16 20:39:23

一个有趣的问题。我不确定ast.literal_eval是否有任何解决方案,但我提供了一个廉价/安全的解决方案:

代码语言:javascript
复制
def my_literal_eval(s):
    ast.literal_eval(s)
    return eval(s)
票数 4
EN

Stack Overflow用户

发布于 2019-01-16 20:49:58

使代码潜在不安全的是对名称和/或属性的引用。您可以对ast.NodeVisitor进行子类处理,以确保在给定代码段中没有这样的引用,然后再对其进行eval

代码语言:javascript
复制
import ast
from textwrap import dedent

class Validate(ast.NodeVisitor):
    def visit_Name(self, node):
        raise ValueError("Reference to name '%s' found in expression" % node.id)
    def visit_Attribute(self, node):
        raise ValueError("Reference to attribute '%s' found in expression" % node.attr)

Validate().visit(ast.parse(dedent(raw), '<inline>', 'eval'))
eval(raw)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54224792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档