파이썬에서 파이썬 코드를 포함하는 문자열을 어떻게 실행합니까?
파이썬에서 파이썬 코드를 포함하는 문자열을 어떻게 실행합니까?
답변:
문장의 경우 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
와eval
exec
하여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를 실행합니다