문제

저는 pygame과 box2d를 사용하여 게임 엔진을 작성하고 있으며 캐릭터 빌더에서 keydown 이벤트에서 실행될 코드를 작성할 수 있기를 원합니다.

내 계획은 캐릭터 빌더에 다음과 유사한 코드를 작성할 수 있는 텍스트 편집기를 두는 것이었습니다.

if key == K_a:
    ## Move left
    pass
elif key == K_d:
    ## Move right
    pass

텍스트 편집기의 내용을 문자열로 검색하고 이 Character 메서드의 메서드에서 코드를 실행하려고 합니다.

def keydown(self, key):
    ## Run code from text editor

그렇게 하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책

당신은 사용할 수 있습니다 eval(string) 이를 수행하는 방법.

정의

eval(code, globals=None, locals=None)
코드는 단지 표준 Python 코드입니다. 즉, 여전히 적절하게 들여쓰기가 필요합니다.

전역 변수는 사용자 정의를 가질 수 있습니다 __builtins__ 보안 목적으로 유용할 수 있는 것으로 정의되었습니다.

eval("print('Hello')")

인쇄할 것 hello 콘솔에.코드에서 사용할 로컬 및 전역 변수를 지정할 수도 있습니다.

eval("print('Hello, %s'%name)", {}, {'name':'person-b'})

보안 문제

하지만 조심하세요.모든 사용자 입력이 실행됩니다.고려하다:

eval("import os;os.system('sudo rm -rf /')")

그 주위에는 여러 가지 방법이 있습니다.가장 쉬운 방법은 다음과 같이 하는 것입니다.

eval("import os;...", {'os':None})

하드 드라이브를 지우는 대신 예외가 발생합니다.귀하의 프로그램은 데스크톱이지만 사람들이 의도한 대로 스크립트를 재배포하는 경우 문제가 될 수 있습니다.

이상한 예

다음은 사용 예입니다. eval 오히려 이상하게도:

def hello() : print('Hello')
def world() : print('world')
CURRENT_MOOD = 'happy'

eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals()))

이것이 평가 라인에서 수행하는 작업은 다음과 같습니다.

  1. 현재 모듈에 다른 이름을 부여합니다. contrivedExample 스크립트에).소비자가 전화할 수 있음 contrivedExample.hello() 지금.)
  2. 그것은 정의한다 hi 가리키는 것으로 hello
  3. 해당 사전을 실행 모듈의 현재 전역 목록과 결합했습니다.

실패하다

실제로는 exec 성명.큰 죄송합니다.수정된 예시는 다음과 같습니다.


exec 정의

(이것은 친숙해 보인다!) exec는 진술입니다.
exec "code" [in scope]범위는 지역 변수와 전역 변수의 사전입니다.지정하지 않으면 현재 범위에서 실행됩니다.

코드는 단지 표준 Python 코드입니다. 즉, 여전히 적절하게 들여쓰기가 필요합니다.

exec

exec "print('hello')"

인쇄할 것 hello 콘솔에.코드에서 사용할 로컬 및 전역 변수를 지정할 수도 있습니다.

eval "print('hello, '+name)" in {'name':'person-b'}

exec 보안 문제

하지만 조심하세요.모든 사용자 입력이 실행됩니다.고려하다:

exec "import os;os.system('sudo rm -rf /')"

명세서 인쇄

댓글 작성자도 지적했듯이, print 3.0 이전의 모든 Python 버전에 있는 명령문입니다.2.6에서는 다음을 입력하여 동작을 변경할 수 있습니다. from __future__ import print_statement.그렇지 않으면 다음을 사용하십시오.

print "hello"

대신에 :

print("hello")

다른 팁

다른 사람들이 지적했듯이 텍스트를 문자열에로드하고 사용 할 수 있습니다. exec "codestring". 이미 파일에 포함 된 경우 사용합니다 execfile 로드하지 않아도됩니다.

한 가지 성능 참고 : Python 소스를 구문 분석하고 컴파일하는 것은 느린 프로세스이므로 코드를 여러 번 실행하지 않아야합니다. 즉. 가지고 있지 않음 :

def keydown(self, key):
    exec user_code

소스를 코드 객체로 컴파일하여 이것을 조금 향상시킬 수 있습니다 ( compile() 그리고 당신이 주위에 유지하는 함수를 구성하고 한 번만 빌드하여 그것을 실행하십시오. 사용자가 "def my_handler (args ...)"를 작성하거나 직접 선발하고 다음과 같은 일을하도록 요구합니다.

user_source = "def user_func(args):\n" + '\n'.join("    "+line for line in user_source.splitlines())

d={}
exec user_source in d
user_func = d['user_func']

그런 다음 나중에 :

if key == K_a:
   user_func(args)

당신이 사용할 수있는 eval()

평가 또는 실행. 프로그래밍 전에 Python 라이브러리 참조를 반드시 읽어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top