파이썬에서 읽고있는 책에서 코드를 계속 사용합니다. eval(input('blah'))
설명서를 읽고 이해했지만 여전히 input()
기능이 어떻게 바뀌는 지 알 수 없습니다 .
무엇을합니까? 누군가 설명 할 수 있습니까?
파이썬에서 읽고있는 책에서 코드를 계속 사용합니다. eval(input('blah'))
설명서를 읽고 이해했지만 여전히 input()
기능이 어떻게 바뀌는 지 알 수 없습니다 .
무엇을합니까? 누군가 설명 할 수 있습니까?
답변:
eval 함수를 사용하면 Python 프로그램이 자체적으로 Python 코드를 실행할 수 있습니다.
평가 예 (대화식 쉘) :
>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1
eval()
동적 코드를 실행하는 데 사용될 수도 있지만 사용하기 전에 보안 및 성능 위험을 완전히 인식해야합니다.
eval
그것으로하는 일도 할 수 없습니다 eval
.
eval
안전하지 않은 것 외에는 단일 표현식 만 평가할 수 있기 때문에 코드 패드와 같은 전체 프로그램을 실행할 수 없습니다.
eval()
문자열을 코드로 해석합니다. 많은 사람들이 이것을 사용하는 것에 대해 경고 한 이유는 사용자가 이것을 컴퓨터에서 코드를 실행하는 옵션으로 사용할 수 있기 때문입니다. 당신이있는 경우 eval(input())
및 os
수입, 한 사람에 입력 할 수 있습니다 input()
os.system('rm -R *')
홈 디렉토리에있는 모든 파일을 삭제할 것이다. (유닉스 시스템이 있다고 가정). 사용 eval()
은 보안상의 허점입니다. 문자열을 다른 형식으로 변환해야하는 경우와 같이 그렇게하는 것을 사용하십시오 int()
.
eval
with를 사용 하는 input()
것은 보안상의 허점임을 의미 합니다. input()
평가 명세서에 넣지 마십시오 . 괜찮을 것입니다.
eval
많은 경우에 보안 문제입니다.
input
일반적으로 콘솔에서 데이터를 취 사용자는 프로그램을 종료하고 입력 할 수 있습니다 rm -R *
... 어쨌든
좋은 여기에 대한 답변,하지만 아무도 많이 사용 설명 eval()
의 맥락에서 globals
와 locals
즉 kwargs로, eval(expression, globals=None, locals=None)
(대한 문서를 참조 eval
여기를 ).
이들은 기능을 통해 사용 가능한 기능을 제한하는 데 사용될 수 있습니다 eval
. 예를 들어 새로운 파이썬 인터프리터를로드하면 locals()
and globals()
가 동일하고 다음과 같이 보입니다.
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
builtins
모듈 내부에는 시스템에 심각한 손상을 줄 수있는 기능이 있습니다. 그러나 우리가 원하지 않는 모든 것을 차단할 수 있습니다. 예를 들어 봅시다. 시스템에서 사용 가능한 코어의 도메인을 나타내는 목록을 구성한다고 가정 해보십시오. 나에게 8 코어가 있으므로 목록을 원할 것 [1, 8]
입니다.
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
마찬가지로 모두 __builtins__
사용할 수 있습니다.
>>>eval('abs(-1)')
1
확인. 그래서 우리는 우리가 노출시키고 자하는 하나의 함수와 우리가 노출하고 싶지 않은 하나의 (훨씬 더 복잡한) 방법의 예를 볼 수 있습니다. 모든 것을 차단합시다.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
우리는 모든 __builtins__
기능 을 효과적으로 차단하여 시스템을 어느 정도 보호했습니다. 이 시점에서 노출하고자하는 함수를 다시 추가 할 수 있습니다.
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
이제 우리는 cpu_count
원하지 않는 모든 것을 여전히 차단하면서 기능을 사용할 수 있습니다. 제 생각에 이것은 일반적인 구현이 아닌 다른 답변의 범위에서 강력하고 명확합니다. 이와 같은 용도로 여러 가지 용도가 있으며 올바르게 처리되는 한 개인적 eval
으로 큰 가치로 안전하게 사용할 수 있다고 생각 합니다.
NB
이것들에 대한 다른 멋진 점은 kwargs
코드에 속기를 사용할 수 있다는 것입니다. 가져온 텍스트를 실행하기 위해 eval을 파이프 라인의 일부로 사용한다고 가정 해 봅시다. 텍스트는 정확한 코드를 가질 필요가 없으며 일부 템플릿 파일 형식을 따를 수 있으며 여전히 원하는 것을 실행할 수 있습니다. 예를 들면 다음과 같습니다.
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
파이썬 2.X에서 input(...)
와 같습니다 eval(raw_input(...))
, 파이썬 3.x의에서 raw_input
이름이 바뀌 었 input
하는 I 의심 리드 당신의 혼란, (당신은 아마에 대한 문서보고 있었다 input
파이썬 2.X에서). 또한 eval(input(...))
Python 3.x에서는 잘 작동하지만 TypeError
Python 2에서는 증가합니다 .
이 경우 표현식 eval
에서 리턴 input
되고 해석 되는 문자열을 강제하는 데 사용됩니다 . 일반적으로 이것은 나쁜 습관으로 간주됩니다.
input
일을 의미 하는 Python 3.x 책 raw_input
입니다.
행을 읽고 해석하는 잘못된 예일 수 있습니다.
시도 eval(input())
하고 입력하십시오 "1+1"
-인쇄해야합니다 2
. 평가 식을 평가합니다.
eval()
전달 된 문자열을 Python 표현식으로 평가하고 결과를 리턴합니다. 예를 들어, eval("1 + 1")
표현식을 해석하고 실행 "1 + 1"
하고 결과를 리턴합니다 (2).
혼동 될 수있는 한 가지 이유는 인용 한 코드에 간접적 인 수준이 관련되어 있기 때문입니다. 내부 함수 호출 (입력)이 먼저 실행되므로 "blah"프롬프트가 표시됩니다. "1 + 1"(명확성을 위해 추가 된 인용 부호, 프로그램을 실행할 때 입력하지 않음)로 응답한다고 가정하고 입력 함수는 해당 문자열을 반환 한 다음 문자열을 해석하는 외부 함수 (eval)로 전달합니다. 결과를 반환합니다 (2).
eval()
이름에서 알 수 있듯이 전달 된 인수를 평가합니다.
raw_input()
이제 input()
파이썬 3.x의 버전에서. 따라서 가장 일반적으로 사용되는 예 는 2.x 버전의 Python에서 eval()
제공하는 기능을 제공하는 것입니다 input()
. raw_input은 사용자가 입력 한 데이터를 문자열로 반환했지만 입력은 입력 한 데이터의 값을 평가하여 반환했습니다.
eval(input("bla bla"))
따라서 input()
2.x 의 기능 , 즉 사용자가 입력 한 데이터를 평가 하는 기능을 복제합니다 .
간단히 말해서 : eval()
전달 된 인수를 평가하여 eval('1 + 1')
2를 반환 했습니다 .
유용한 응용 프로그램 중 하나는 eval()
문자열에서 파이썬 표현식을 평가하는 것입니다. 예를 들어 사전의 파일 문자열 표현에서로드 :
running_params = {"Greeting":"Hello "}
fout = open("params.dat",'w')
fout.write(repr(running_params))
fout.close()
변수로 읽어서 편집하십시오.
fin = open("params.dat",'r')
diction=eval(fin.read())
diction["Greeting"]+="world"
fin.close()
print diction
산출:
{'Greeting': 'Hello world'}
eval
합니까?
나는이 질문에 대답하기 늦었지만 아무도 그 질문에 대한 명확한 대답을하지 않는 것 같습니다.
사용자가 숫자 값을 입력 input()
하면 문자열이 반환됩니다.
>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'
따라서 eval()
문자열 인 반환 값 (또는 표현식)을 평가하고 정수 / 부동 소수점을 반환합니다.
>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>>
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14
꾸짖음으로 이것은 나쁜 습관입니다. int()
또는 이 경우 float()
대신 사용해야합니다 eval()
.
>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14
평가 문자열을 간단한 리터럴로 제한하려는 경우 다른 옵션을 사용하는 것 ast.literal_eval()
입니다. 몇 가지 예 :
import ast
# print(ast.literal_eval('')) # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a')) # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1')) # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1')) # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}")) # {'a':1}
로부터 문서 :
파이썬 리터럴 또는 컨테이너 디스플레이를 포함하는 표현식 노드 또는 문자열을 안전하게 평가하십시오. 제공된 문자열 또는 노드는 문자열, 바이트, 숫자, 튜플, 목록, dicts, set, booleans 및 None과 같은 Python 리터럴 구조 로만 구성 될 수 있습니다.
값을 직접 구문 분석 할 필요없이 신뢰할 수없는 소스의 Python 값을 포함하는 문자열을 안전하게 평가하는 데 사용할 수 있습니다. 그것은 것입니다 하지 운영자 또는 색인을 포함하는, 예를 들어, 임의의 복잡한 식을 평가할 수.
메일 링리스트 에서 왜 그렇게 제한되어 있는지에 관해서 :
리터럴로 연산자 표현식을 허용하는 것이 가능하지만 현재 구현보다 훨씬 복잡합니다. 간단한 구현은 안전하지 않습니다. 노력없이 기본적으로 무제한 CPU 및 메모리 사용을 유도 할 수 있습니다 ( "9 ** 9 ** 9"또는 "[없음] * 9 ** 9"시도).
유용성에 관해서는,이 함수는 리터럴 값과 컨테이너를 repr ()에 의해 문자열로 "판독"하는데 유용합니다. 예를 들어 JSON과 비슷하지만 더 강력한 형식으로 직렬화에 사용할 수 있습니다.
ast.literal_eval
귀하의 '1+1'
예 와 달리 연산자를 지원하지 않습니다 . 그럼에도 불구하고 목록, 숫자, 문자열 등을 지원하므로 일반적인 eval
사용 사례에 대한 좋은 대안입니다 .