python执行程序,可以访问特定的功能

时间:2015-02-21 11:41:56

标签: python

我想从用户那里执行一个程序。它应该能够从我允许的主程序中调用函数,并且可以在主程序中更改变量,但是如果没有这些允许的函数,它就不能在主程序中更改变量。

主程序:

import traceback

def forward():
  if pos < 100:
    pos += 1
    return True
  else:
    return False

def private():
  print "I'm private!"

pos = 0


print(pos)

path = input("Enter the path to your program: ")
try:
  program = open(path)
  code = compile(program.read(), path, "exec")
  # exec code in a way that allows the code to use the forward function
except:
  traceback.print_exc()
finally:
  program.close()

print(pos)

输入包含内容

的文件的路径
if forward():
  print("walked forward")
else:
  print("couldn't walk forward")

应该给出输出

0
walked forward
1

输入包含内容

的文件的路径
pos = 10 # should be a local variable for the users program

应该给出输出

0
0

输入包含内容

的文件的路径
private()

应该给出例外

NameError: name 'private' is not defined

输入包含内容

的文件的路径
pos += 5

应该给出例外

NameError: name 'pos' is not defined

1 个答案:

答案 0 :(得分:1)

作为exec函数的一部分,您可以传递一个字典,该字典将用作命名空间来执行代码。这可以防止意外滥用私有函数和变量。但是,这绝不是安全的。确定的人仍然可以访问privatepos

exec(code, {"forward": forward})

要证明函数引用的全局变量始终是它所定义的模块的全局变量。

value = 0
def getter():
    return value
def setter(new_value):
    global value
    value = new_value
source = """
assert getter() == 0, "expected 0, but got {}".format(getter())
setter(1)
value = -1
assert getter() == 1, "expected 1, but got {}".format(getter())
"""
try:
    exec(source) # using this modules globals
except AssertionError as e:
    print("executed source, but it raised an AssertionError")
    print(e)
else:
    assert value == -1
    print("executed source, but it modified our value")
value = 0 # reset value
exec(source, {"getter": getter, "setter": setter}) # no assertion error
assert value == 0
print("executed source, and it did not modify our value")