exec가 하위 기능이있는 함수에서 작동하지 않는 이유는 무엇입니까?
하위 기능이있는 함수에서 exec를 사용할 수없는 것 같습니다.
이 Python 코드가 작동하지 않는 이유를 아는 사람이 있습니까? test2의 exec에서 오류가 발생합니다. 또한 exec가 좋은 스타일이 아니라는 것을 알고 있지만 저를 믿으십시오. 적절한 이유로 exec를 사용하고 있습니다. 그렇지 않으면 사용하지 않을 것입니다.
#!/usr/bin/env python
#
def test1():
exec('print "hi from test1"')
test1()
def test2():
"""Test with a subfunction."""
exec('print "hi from test2"')
def subfunction():
return True
test2()
편집 : 하위 기능에 기능이 있도록 버그를 좁혔습니다. raise 키워드와는 관련이 없습니다.
옳은. 컨텍스트를 지정하지 않으면 하위 기능이있는 함수에서 exec를 사용할 수 없습니다. 문서에서 :
exec가 함수에서 사용되고 함수에 자유 변수가있는 중첩 블록이 포함되어있는 경우 exec가 exec에 대한 로컬 네임 스페이스를 명시 적으로 지정하지 않는 한 컴파일러는 SyntaxError를 발생시킵니다. (즉, "exec obj"는 불법이지만 "exec obj in ns"는 합법적입니다.)
일요일 밤이 아니었다면 아마 이해할만한 이유가 있습니다. 자, 다음 질문 : 왜 exec를 사용하고 있습니까? 거의 필요하지 않습니다. 당신은 정당한 이유가 있다고 말합니다. 나는 그것에 대해 회의적이다. ;) 타당한 이유가 있으면 해결 방법을 알려 드리겠습니다. :-피
오, 어쨌든 여기 있습니다.
def test2():
"""Test with a subfunction."""
exec 'print "hi from test2"' in globals(), locals()
def subfunction():
return True
Python에서는 지역 변수가 사전에 저장되는 것처럼 보이지만 locals()
일반적으로 그렇지 않습니다. 대신 대부분 스택에 저장되고 인덱스에 의해 액세스됩니다. 이렇게하면 매번 사전 조회를 수행해야하는 경우보다 로컬 변수 조회가 더 빨라집니다. 이 locals()
함수를 사용하면 모든 지역 변수에서 생성 된 새로운 사전이 생성되므로에 할당이 locals()
일반적으로 작동하지 않습니다.
이 시나리오에는 몇 가지 예외가 있습니다.
exec
함수 내에서 정규화되지 않은 것을 사용할 때 Python은 최적화를 끄고 로컬 변수에 실제 사전을 사용합니다. 즉 exec
, 내부에서 변수를 만들거나 업데이트 할 수 있지만 해당 함수의 모든 로컬 변수 액세스가 더 느리게 실행된다는 의미이기도합니다.
다른 예외는 함수를 중첩 할 때 내부 함수가 외부 함수 범위의 지역 변수에 액세스 할 수 있다는 것입니다. 이렇게하면 변수가 스택에 저장되는 대신 '셀'개체에 저장됩니다. 추가 수준의 간접 지정으로 인해 내부 또는 외부 함수에서 액세스하든 범위 변수를 모두 더 느리게 사용할 수 있습니다.
당신이 만난 캐치는 지역 변수가 일반적으로 저장되는 방법에 대한 이러한 두 가지 예외가 호환되지 않는다는 것입니다. 변수를 사전에 저장하고 동시에 셀 참조를 통해 액세스 할 수 없습니다. Python 2.x는 범위 변수를 사용하지 않는 경우에도 exec를 허용하지 않음으로써이 문제를 해결합니다.
이것은 다소 흥미로운 경우입니다.
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return True
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'func' because
it contains a nested function with free variables
이것이 실제로 작동하지 않는 이유 subfunction
는 자유 변수 가 포함되어 있기 때문이며 Python 2에서는 exec
이론적으로 포함 범위의 지역을 수정할 수 있기 때문에 변수가 전역 또는 부모에서 바인딩되어야하는지 여부를 결정할 수 없습니다. 기능 범위. Zen of Python의 구절 중 하나는 "모호함에 직면하여 추측하려는 유혹을 거부하십시오."입니다. 이것이 파이썬 2가하는 일입니다.
이제 질문은이 자유 (바인딩되지 않은) 변수가 무엇입니까? 글쎄요 True
!
실제로 다음과 None
같이 재현 가능합니다 .
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return None
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'test2' because it contains a nested
function with free variables
비록 None
에 할당 할 수 없으며, 그것은으로 간주 일정 바이트 코드에서 버그 파서가 여기에 언 바운드 변수입니다 생각합니다.
그러나 그것을 대체하고 1
문제없이 작동 한다면 :
>>> def test2():
... exec('print "hi from func"')
... def subfunction():
... return 1
...
>>>
이 오류를 방지하려면에서 사용할 전역 및 가능한 지역을 명시 적으로 지정하십시오 exec
.
>>> def test2():
... exec 'print "hi from test2"' in {}
... def subfunction():
... return None
...
>>>
Python 3에서는 exec
단순한 함수일 뿐이며 파서 나 바이트 코드 컴파일러에 의해 특별히 처리되지 않습니다. Python 3에서는 exec
함수 로컬 이름을 리 바인드 할 수 없으므로이 SyntaxError 및 모호성이 존재하지 않습니다.
Python 2 대 3 호환성의 특이한 경우는 Python 2.7 문서에 다음과 같이 명시되어 있다는 것입니다.
양식
exec(expr, globals)
은과 동일exec expr in globals
하고 양식exec(expr, globals, locals)
은과 동일합니다exec expr in globals, locals
. 튜플 형식은exec
Python 3과의 호환성 을 제공합니다. 여기서는exec
문이 아니라 함수입니다.
중첩 된 함수 가 exec
있는 함수를 처리하는 데 버그 가 있었기 때문에 튜플 형식이 항상 100 % 호환되는 것은 아닙니다 (문제 21591) . Python 2.7.8까지 다음 코드에서 예외가 발생할 수 있습니다.
def func():
exec('print "hi from test2"', {})
def subfunction():
return None
이것은 Python 2.7.9에서 수정되었으며 더 이상 던지지 않습니다.
print 함수를 사용하도록 print 문을 수정 한 후 Python 3.1.3에서 잘 작동합니다.
Python 2.6에서는을 생성 SyntaxError: unqualified exec is not allowed in function 'test2' it contains a nested function with free variables
하지만 버그라고 생각하지 않습니다.
오류는 나에게 상당히 명백한 것 같습니다.
SyntaxError: unqualified exec is not allowed in function 'test2' it contains a nested function with free variables
자세한 정보는 pep 227을 참조하십시오 : http://www.python.org/dev/peps/pep-0227/
dict
및 list
지능형 또한 파이썬 2.7.5에 하위 기능으로 간주 할 수있다
예를 들어 Python 2.7.5에서는 실패하지만 Python 2.7.12에서는 작동합니다.
def func():
exec('print("a")')
(str(e) for e in range(10))
와:
File "./a.py", line 4
exec('print("a")')
SyntaxError: unqualified exec is not allowed in function 'func' it contains a nested function with free variables
아마도 그것은 바이트 코드의 함수로 내부적으로 컴파일되었을 것입니다.
TODO find the fixing commit. It was beyond my git log --grep
foo.
Analogous for dict
comprehensions:
def func():
exec('print("a")', {e:str(e) for e in range(10)})
which is specially bad since it is a common parameter for the global
argument.
Also raised at: https://github.com/sphinx-doc/sphinx/issues/5417#issuecomment-421731085
ReferenceURL : https://stackoverflow.com/questions/4484872/why-doesnt-exec-work-in-a-function-with-a-subfunction
'programing' 카테고리의 다른 글
마우스 오버시 툴팁이나 아이템 정보를 어떻게 표시합니까? (0) | 2021.01.19 |
---|---|
리플렉션을 통해 activerecord 연결을 얻는 방법 (0) | 2021.01.19 |
URL에서 더하기 (+) 기호를 인코딩하는 방법 (0) | 2021.01.19 |
테스트를위한 공용 SAML v2 서비스 제공 업체? (0) | 2021.01.19 |
java replaceLast () (0) | 2021.01.18 |