exec定义了什么,如何处理?

时间:2019-07-09 21:00:21

标签: python

我正在编写代码以使考试随机化,我需要能够将一个变量随机化,以便从列表中选择一个变量,但不等于另一个变量。

我正在使用eval()评估字符串,并使用exec()在python中定义变量,以便可以从另一个值创建一个值。我遇到的问题是在某些情况下无法识别变量。

就地将变量名和随机化参数作为文本字符串从单独的文件中提取。捕获我的问题的简化的提取代码块是:

import random

def question_randomizer():

    randomdef={'w':'random.choice([1,2,3])', 'x':'w+1', 'y':'random.choice([i for i in [w,x] if i not in [2]])', 'z':'random.choice([i for i in [1,2,3] if i not in [w]])'}

    for var in randomdef:
        variablevalue=eval(randomdef[var])

        exec("%s = %s" % (var,variablevalue))

        print(var, ' = ', variablevalue)

    return

question_randomizer()

exec调用应在代码中定义变量,并且在创建w,x和y时可以正常工作;

w  =  2
x  =  3
y  =  3

但是z总是返回错误

name 'w' is not defined

有人知道如何解决此问题,或者在成功使用w之前为什么会发生此错误?我唯一需要注意的是,我正在尝试避免使用全局变量。

谢谢。

1 个答案:

答案 0 :(得分:1)

首先,exec()eval()有点危险,很难正确使用。如果您必须以这种方式解决问题,请改用locals()函数,然后手动将其添加到局部变量列表中:

locals()[variablename] = variablevalue

但是解决此问题的更好方法可能是使用random.sample()函数,该函数使您可以从样本中选择任意数量的唯一值:

x1, x2, x4 = random.sample(range(1, 6), 3)  # 3 unique values between 1 and 5 inclusive

random.choice(vals)函数大致等效于random.sample(vals, 1)

如果要避免重复值,可以使用set减法来减少可接受的随机样本的范围:

x3 = random.choice(set(range(1, 6)) - {x1, x2, x4, 2})  # a value between 1 and 5 that is not equal to x1, x2, or x4, or the integer 2