连接条件读取表单YAML文件以字符串形式出现

时间:2019-12-02 13:33:02

标签: python yaml

在我的项目中,我想在YAML文件中维护连接条件(pyspark数据框连接条件)。

示例连接条件如下。

table1.col1 == table2.col1

在YAML中,条件是这样的。

cond: table1.col1 == table2.col1

当我从YAML中读取加入条件时。我得到如下(字符串类型)。

table1.col1 ==  table2.col1

条件将转换为String(用单引号引起来)。

为了解决这个问题(获取确切的文字而不是字符串),我尝试了以下方法。但是,它们无法正常工作。

1)

import ast
final_cond = ast.literal_eval(cond)

2)

import json
final_cond = json.loads(cond)

我在读取而不是String时需要确切的文字,或者将这种等式连接条件从String转换为文字。

注意:要应用连接条件,一种方法是编写这样的代码。

joined = table1.join(table2, [table1.col1 == table2.col1], "inner")

但是,如果我接受YAML的条件,则joined如下所示。

joined = table1.join(table2, ['table1.col1 == table2.col1'], "inner")  # notice the enclosed single quotes 

引号(单引号或双引号)是失败的原因。

当前,YAML文件只有以下一对。如果这种方法可行,我将添加更多类似的条件。

cond: table1.col1 ==  table2.col1

1 个答案:

答案 0 :(得分:1)

在YAML中,table1.col1 == table2.col1是标量。标量是默认情况下加载到字符串中的字符序列。

在Python中,table1.col1 == table2.col2是一个被解析为AST一部分的表达式。在标准实现中,AST被处理为字节码并放入.pyc文件中。所有这些都在执行任何代码之前发生,这意味着在代码读取您的YAML文件之前发生。这就是为什么您不能直接从YAML注入AST的一部分的原因。

但是,您可以在运行时访问Python的解析和解释工具(简而言之,这就是将当今所谓的“解释”语言与已编译语言区分开的地方)。这意味着您可以写

joined = table1.join(table2, [eval('table1.col1 == table2.col1')], "inner")

eval()解析给定的字符串作为Python源,然后在当前上下文中对其进行评估(即,将所有名称解析为在呼叫站点可见的本地名称)。这样,您可以评估从YAML文件获得的字符串,就好像它是Python源代码的一部分一样。

请注意,eval()基本上与整个Python语言一样强大,因此在使用它之前,请确保它永远不会在您无法完全控制的任何字符串上执行。如果您曾经根据用户输入执行eval(),则该用户基本上可以执行应用程序中的任何代码,这是一个严重的安全漏洞。