从exec捕获返回值

时间:2017-04-10 10:22:02

标签: python

yaml档案

$ cat ec2_attr.yml

treeroot:
    branch1:
        name: Node 1
        snap: |
          def foo():

              from boto3.session import Session
              import pprint

              session = Session(region_name='us-east-1')
              client = session.client('rds')

              resp = client.describe_db_cluster_snapshots(
                  SnapshotType='manual',
              )

              filtered = [x for x in resp['DBClusterSnapshots'] if x[
                  'DBClusterSnapshotIdentifier'].startswith('xxxxx')]
              latest = max(filtered, key=lambda x: x['SnapshotCreateTime'])
              print(latest['DBClusterSnapshotIdentifier'])

          foo()        
    branch2:
        name: Node 2

代码:

import yaml
import pprint

with open('./ec2_attr.yml') as fh:
    try:
        yaml_dict = yaml.load(fh)
    except Exception as e:
        print(e)
    else:
        exec("a = yaml_dict['treeroot']['branch1']['snap']")
        print('The Value is: %s' % (a))

实际输出:

The Value is: def foo():

    from boto3.session import Session
    import pprint

    session = Session(region_name='us-east-1')
    client = session.client('rds')

    resp = client.describe_db_cluster_snapshots(
        SnapshotType='manual',
    )

    filtered = [x for x in resp['DBClusterSnapshots'] if x[
        'DBClusterSnapshotIdentifier'].startswith('xxxxx')]
    latest = max(filtered, key=lambda x: x['SnapshotCreateTime'])
    print(latest['DBClusterSnapshotIdentifier'])

foo()  

预期输出:

xxxxx-xxxx-14501111111-xxxxxcluster-2gwe6jrnev8a-2017-04-09

如果我使用exec作为exec(yaml_dict['treeroot']['branch1']['snap']),那么它会打印我想要的值,但我无法将该值捕获到变量中。我了解exec返回值为None。但是,我正在尝试执行与https://stackoverflow.com/a/23917810/1251660完全相似的操作,并且在我的情况下它不起作用。

1 个答案:

答案 0 :(得分:2)

您可以像这样使用exec

import yaml
import pprint

with open('./a.yaml') as fh:
    try:
        yaml_dict = yaml.load(fh)
    except Exception as e:
        print(e)
    else:
      a = {}
      exec(yaml_dict['treeroot']['branch1']['snap'], {}, a)
      print('The Value is: %s' % (a['foo']()))

将你的YAML改为:

treeroot:
  branch1:
      name: Node 1
      snap: |
        def foo():
            return("test")

  branch2:
      name: Node 2

实际上,您可以使用exec(str, globals, locals

内置函数globals()locals()分别返回当前的全局和本地字典,这可能有助于传递用作exec()的第二个和第三个参数

另外,您可以阅读The exec Statement and A Python Mysterylocals and globals