파이썬에서 파이썬 코드를 포함하는 문자열을 어떻게 실행합니까?
파이썬에서 파이썬 코드를 포함하는 문자열을 어떻게 실행합니까?
답변:
문장의 경우 exec(string)(Python 2/3) 또는 exec string(Python 2)를 사용하십시오.
>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world
표현식의 값이 필요하면 다음을 사용하십시오 eval(string).
>>> x = eval("2+2")
>>> x
4
그러나 첫 번째 단계는 정말로 필요한지 스스로에게 물어보아야합니다. 실행 코드는 일반적으로 최후의 수단이되어야합니다. 사용자가 입력 한 코드를 포함 할 수 있으면 속도가 느리고 추악하며 위험합니다. 고차 함수와 같은 대안을 먼저 살펴보고 이것이 더 나은 요구를 충족시킬 수 있는지 확인해야합니다.
if s=='foo': x.foo = 42 elif s=='bar': x.bar = 42쓸 수 있습니다 exec ("x.%s = 42" % s). (당신은 단지 문자열에 저장된 객체의 속성에 접근 할 필요)이 일반적인 경우를 들어, 더 빠르게, 더 깨끗하고 안전 기능이 getattr바로 쓰기 : getattr(x, s) = 42같은 일을 의미.
setattr(x, s, 42)인가요? 시도 getattr(x, 2) = 42하고 실패했습니다can't assign to function call: <string>, line 1
setattr(x, s, 42). 올바른 구문입니다. 오류가 발생하는 데 시간이 오래 걸린다는 사실에 놀랐습니다. 어쨌든, 요점은 것입니다 getattr및 setattr대안이다 exec당신이 원하는 모든 임의 회원을 얻을 때, 문자열에 의해 보였다.
이 예에서 문자열은 exec 함수를 사용하여 코드로 실행됩니다.
import sys
import StringIO
# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()
code = """
def f(x):
x = x + 1
return x
print 'This is my output.'
"""
# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr
exec code
# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print f(4)
s = codeErr.getvalue()
print "error:\n%s\n" % s
s = codeOut.getvalue()
print "output:\n%s" % s
codeOut.close()
codeErr.close()
exec합니다 ( 코드 문자열이 신뢰할 수있는 출처에서 온 것을 알지 않는 한 ).
eval그리고 exec올바른 솔루션이며, 그들은이에서 사용할 수있는 안전한 방법.
에서 설명하고있는 바와 같이 파이썬의 참조 설명서를 명확하게 설명 이 튜토리얼의 eval과 exec기능은 사용자가 글로벌 및 지역 함수와 변수가 사용할 수있는 지정할 수있는 두 개의 추가 매개 변수를.
예를 들면 다음과 같습니다.
public_variable = 10
private_variable = 2
def public_function():
return "public information"
def private_function():
return "super sensitive information"
# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len
>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12
>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined
>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters
>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined
본질적으로 코드가 실행될 네임 스페이스를 정의하고 있습니다.
eval하거나 exec사용하려고 exec(input("Type what you want"))합니까? 프로그램이 계산의 결과로 프로시 저나 함수를 작성할 수있는 경우가 많습니다. 결과적으로 작성된 기능은 훌륭하고 잘 작성된 프로그램의 다른 부분과 마찬가지로 안전하고 빠릅니다 (한 번 평가). 안전하지 않은 프로그램이 포함 된 안전하지 않은 프로그램 exec은 프로그램에 exec새로운 권한을 부여하지 않으므로 자체적으로 손상을 수행하는 안전하지 않은 프로그램보다 위험 하지 않습니다.
exec와evalexec하여eval파이썬에서 를 것은 매우 찡그림입니다.최고 답변 (강조 광산)에서 :
진술을 위해
exec.식의 값이 필요한 경우을 사용하십시오
eval.그러나 첫 번째 단계는 정말로 필요한지 스스로에게 물어보아야합니다. 실행 코드는 일반적으로 최후의 수단이되어야 합니다. 사용자가 입력 한 코드를 포함 할 수 있으면 느리고, 추악하고, 위험합니다. 고차 함수와 같은 대안을 먼저 살펴 보고 이것이 더 나은 요구를 충족시킬 수 있는지 확인해야합니다.
문자열 이름으로 변수 값 설정 및 가져 오기
eval작동 하는 동안 일반적으로 프로그램 자체에 의미가있는 변수 이름을 사용하지 않는 것이 좋습니다.대신 dict을 사용하는 것이 좋습니다.
에서 http://lucumr.pocoo.org/2011/2/1/exec-in-python/ (강조 광산)
파이썬은 PHP가 아니다
다른 언어에서는 다르게 사용하기 때문에 파이썬 관용구를 우회하려고하지 마십시오. 네임 스페이스는 이유 가 있기 때문에 파이썬으로되어 있으며 도구를 제공한다고해서 해당 도구
exec를 사용해야한다는 의미는 아닙니다.
에서 http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html (강조 광산)
따라서 모든 지구본과 내장을 제거하더라도 eval은 안전하지 않습니다!
eval ()을 보호하려는 이러한 모든 시도 의 문제점 은 이들이 블랙리스트라는 것 입니다. 그들은 위험 할 수있는 것을 명시 적으로 제거합니다. 목록에 남은 항목이 하나만 있으면 시스템을 공격 할 수 있기 때문에 전투에서 패배 합니다. .
그렇다면 평가를 안전하게 할 수 있습니까? 말하기 어렵다. 이 시점에서 가장 좋은 추측은 이중 밑줄을 사용할 수 없으면 아무런 해를 입을 수 없으므로 이중 밑줄이있는 문자열을 제외하면 안전합니다. 아마도...
에서 http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (강조 광산) :
첫째,
exec인간이 코드를 읽기 어렵게 만듭니다 . 무슨 일이 일어나고 있는지 파악하기 위해 코드를 읽을 필요가 없으며 코드 를 읽고 생성 할 문자열을 파악한 다음 가상 코드를 읽어야합니다. 따라서 팀에서 작업하거나 오픈 소스 소프트웨어를 게시하거나 StackOverflow와 같은 곳에서 도움을 요청하는 경우 다른 사람들이 도움을주기가 더 어려워집니다. 6 개월 후이 코드를 디버깅하거나 확장 할 가능성이 있다면 직접 작성하기가 더 어려워집니다.
cfg.yaml) reldir : ../my/dir/ , 그리고 reldir = cfg[reldir]. 그러나이 파이썬 코드는 Windows와 Linux 모두에서 실행되므로 다른 운영 체제 경로 분배기에 맞게 조정해야합니다. 하나 \\ 또는 /. 그래서 나는 reldir : os.path.join('..','my','dir')구성 파일에서 사용 합니다. 그러나 이것은 reldir이 리터럴 문자열 일뿐 이며 평가되지 않으므로에서 파일을 열 수 없습니다 reldir. 당신은 제안이 있습니까?
그것의 가치 '가 언급 exec아니라 전화로의'형제의 존재를 execfile당신이 파이썬 파일을 호출 할 경우. 끔찍한 IDE가 포함 된 타사 패키지에서 작업하고 패키지 외부에서 코드를 작성하려는 경우 때로는 좋습니다.
예:
execfile('/path/to/source.py)'
또는:
exec(open("/path/to/source.py").read())
알았어 .. 이것이 정확히 답이 아니라는 것을 알고있는 사람들을위한 메모 일 것입니다. 다른 사용자 / 고객을 위해 특정 코드를 실행하고 싶었지만 exec / eval을 피하고 싶었습니다. 처음에는 각 사용자의 데이터베이스에 코드를 저장하고 위의 작업을 수행하려고했습니다.
나는 'customer_filters'폴더 내에서 파일 시스템에 파일을 만들고 'imp'모듈을 사용하여 그 고객에게 적용된 필터가 없다면 방금 진행했습니다.
import imp
def get_customer_module(customerName='default', name='filter'):
lm = None
try:
module_name = customerName+"_"+name;
m = imp.find_module(module_name, ['customer_filters'])
lm = imp.load_module(module_name, m[0], m[1], m[2])
except:
''
#ignore, if no module is found,
return lm
m = get_customer_module(customerName, "filter")
if m is not None:
m.apply_address_filter(myobj)
customerName = "jj"는 customer_filters \ jj_filter.py 파일에서 apply_address_filter를 실행합니다