[python] 파이썬 비 로컬 문장

Python nonlocal문은 무엇입니까 (Python 3.0 이상에서)?

공식 파이썬 웹 사이트에는 문서 help("nonlocal")가 없으며 작동하지 않습니다.



답변

이것을 사용하지 않고 이것을 비교하십시오 nonlocal:

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

이를 위해, 사용하는 nonlocal경우, inner()‘s에하는 것은 x이제도 outer()의’ x:

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

만약 우리가를 사용한다면 , 적절하게 “전역”값에 global바인딩 될 것입니다 x:

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

답변

즉, 외부 (전역이 아닌) 범위의 변수에 값을 할당 할 수 있습니다. 모든 세부 사항 은 PEP 3104 를 참조 하십시오.


답변

“python nonlocal”에 대한 Google 검색에서 제안, PEP 3104 가 나타 났으며, 이 문장의 구문과 추론을 완전히 설명합니다. 간단히 말해서, global함수에 대해 전역 적이거나 로컬이 아닌 변수를 참조하는 데 사용된다는 점을 제외 하면 명령문 과 정확히 동일한 방식으로 작동합니다.

여기 당신이 할 수있는 일의 간단한 예가 있습니다. 카운터 생성기는 이것을 사용하여 다시 닫을 수 있으므로 클로저가있는 언어의 관용구처럼 보입니다.

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

분명히 이것을 다음과 같은 생성기로 작성할 수 있습니다.

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count

그러나 이것은 완벽하게 관용적 인 파이썬이지만 첫 번째 버전은 초보자에게는 더 분명한 것 같습니다. 리턴 된 함수를 호출하여 제너레이터를 올바르게 사용하는 것은 일반적인 혼동 지점입니다. 첫 번째 버전은 명시 적으로 함수를 반환합니다.


답변

@ooboo :

소스 코드의 참조 지점에 “가장 가까운”것을 사용합니다. 이것을 “Lexical Scoping”이라고하며 현재> 40 년 동안 표준입니다.

파이썬의 클래스 멤버는 실제로 사전에 있으며 사전 __dict__어휘 범위에 도달하지 않습니다.

지정하지 않고 nonlocal수행 x = 7하면 새 로컬 변수 “x”가 작성됩니다. 을 지정 nonlocal하면 “가장 가까운” “x”를 찾아 할당합니다. 지정 nonlocal하고 “x”가 없으면 오류 메시지가 나타납니다.

키워드 global는 가장 바깥 쪽을 제외한 다른 모든 “x”를 행복하게 무시하기 때문에 항상 이상하게 보였습니다. 기묘한.


답변

help ( ‘nonlocal’) nonlocal진술


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

그만큼 nonlocal 명령문은 나열된 식별자가 가장 가까운 엔 클로징 범위에서 이전에 바인드 된 변수를 참조하게합니다. 바인딩의 기본 동작은 로컬 네임 스페이스를 먼저 검색하는 것이므로 중요합니다. 이 명령문은 캡슐화 된 코드가 전역 (모듈) 범위 외에 로컬 범위 외부에서 변수를 리 바인드 할 수 있도록합니다.

nonlocal성명서에 기재된 이름 과 달리 성명서에
기재된 이름global 은 둘러싸는 범위의 기존 바인딩을 참조해야합니다 (새 바인딩을 작성해야하는 범위를 명확하게 판별 할 수 없음).

nonlocal명령문에 나열된 이름 은 로컬 범위의 기존 바인딩과 충돌하지 않아야합니다.

또한보십시오:

PEP 3104- 외부 범위
의 이름에 대한 액세스 설명에 대한 사양 nonlocal.

관련 도움말 주제 : 전역, NAMESPACES

출처 : 파이썬 언어 레퍼런스


답변

로부터 견적 파이썬 3 참조 :

로컬이 아닌 명령문은 나열된 식별자가 전역을 제외한 가장 가까운 둘러싸는 범위에서 이전에 바인딩 된 변수를 참조하게합니다.

참조에서 언급했듯이 여러 중첩 함수의 경우 가장 가까운 둘러싸는 함수의 변수 만 수정됩니다.

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        x = 2
        innermost()
        if x == 3: print('Inner x has been modified')

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Inner x has been modified

“가장 가까운”변수는 몇 단계 떨어져있을 수 있습니다.

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Outer x has been modified

그러나 전역 변수는 될 수 없습니다.

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    inner()

x = 0
outer()
if x == 3: print('Global x has been modified')

# SyntaxError: no binding for nonlocal 'x' found


답변

a = 0    #1. global variable with respect to every function in program

def f():
    a = 0          #2. nonlocal with respect to function g
    def g():
        nonlocal a
        a=a+1
        print("The value of 'a' using nonlocal is ", a)
    def h():
        global a               #3. using global variable
        a=a+5
        print("The value of a using global is ", a)
    def i():
        a = 0              #4. variable separated from all others
        print("The value of 'a' inside a function is ", a)

    g()
    h()
    i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)