복붙노트

[PYTHON] UnboundLocalError가 발생하는 이유를 이해하지 못함 [중복]

PYTHON

UnboundLocalError가 발생하는 이유를 이해하지 못함 [중복]

여기서 내가 뭘 잘못하고 있니?

counter = 0

def increment():
  counter += 1

increment()

위의 코드는 UnboundLocalError를 발생시킵니다.

해결법

  1. ==============================

    1.파이썬에는 변수 선언이 없으므로 변수 자체의 범위를 알아 내야합니다. 그것은 간단한 규칙에 의해 그렇게합니다 : 함수 내에 변수에 대한 할당이 있다면, 그 변수는 지역 변수로 간주됩니다. [1] 따라서, 라인

    파이썬에는 변수 선언이 없으므로 변수 자체의 범위를 알아 내야합니다. 그것은 간단한 규칙에 의해 그렇게합니다 : 함수 내에 변수에 대한 할당이 있다면, 그 변수는 지역 변수로 간주됩니다. [1] 따라서, 라인

    counter += 1
    

    암시 적으로 카운터를 increment ()에 로컬로 만듭니다. 그러나이 행을 실행하려고하면 할당되기 전에 로컬 변수 counter의 값을 읽으려고 시도하므로 UnboundLocalError가 발생합니다. [2]

    counter가 전역 변수 인 경우 global 키워드가 도움이됩니다. increment ()가 지역 함수이고 지역 변수를 카운터하는 경우 Python 3.x에서 로컬이 아닌 것을 사용할 수 있습니다.

  2. ==============================

    2.지역 변수 대신 전역 변수 카운터를 수정하려면 전역 명령문을 사용해야합니다.

    지역 변수 대신 전역 변수 카운터를 수정하려면 전역 명령문을 사용해야합니다.

    counter = 0
    
    def increment():
      global counter
      counter += 1
    
    increment()
    

    counter가 정의 된 범위가 전역 범위가 아니라면 Python 3.x에서 nonlocal 문을 사용할 수 있습니다. 파이썬 2.x와 동일한 상황에서 비 로컬 이름 카운터에 재 할당 할 방법이 없기 때문에 카운터를 변경 가능하게 만들고 수정해야합니다.

    counter = [0]
    
    def increment():
      counter[0] += 1
    
    increment()
    print counter[0]  # prints '1'
    
  3. ==============================

    3.당신의 제목 라인에있는 질문에 답하기 위해서 * 예, 함수 안에 만 적용된다는 점과 (파이썬 2.x에서는) 읽기 전용이라는 점을 제외하고는 파이썬에서 클로저가 있습니다; 이름을 다른 오브젝트에 다시 바인드 할 수는 없습니다 (오브젝트가 변경 가능한 경우에도 내용을 수정할 수 있음). Python 3.x에서는 nonlocal 키워드를 사용하여 클로저 변수를 수정할 수 있습니다.

    당신의 제목 라인에있는 질문에 답하기 위해서 * 예, 함수 안에 만 적용된다는 점과 (파이썬 2.x에서는) 읽기 전용이라는 점을 제외하고는 파이썬에서 클로저가 있습니다; 이름을 다른 오브젝트에 다시 바인드 할 수는 없습니다 (오브젝트가 변경 가능한 경우에도 내용을 수정할 수 있음). Python 3.x에서는 nonlocal 키워드를 사용하여 클로저 변수를 수정할 수 있습니다.

    def incrementer():
        counter = 0
        def increment():
            nonlocal counter
            counter += 1
            return counter
        return increment
    
    increment = incrementer()
    
    increment()   # 1
    increment()   # 2
    

    원래 질문의 제목은 Python에서 클로저에 대해 물었습니다.

  4. ==============================

    4.코드가 UnboundLocalError를 던지는 이유는 이미 다른 답변에서도 잘 설명되어 있습니다.

    코드가 UnboundLocalError를 던지는 이유는 이미 다른 답변에서도 잘 설명되어 있습니다.

    하지만 itertools.count ()처럼 작동하는 무언가를 만들려고하는 것 같습니다.

    그래서 당신이 그것을 밖으로 시도하고 그것을 귀하의 사건에 적합한 지 확인하십시오 :

    >>> from itertools import count
    >>> counter = count(0)
    >>> counter
    count(0)
    >>> next(counter)
    0
    >>> counter
    count(1)
    >>> next(counter)
    1
    >>> counter
    count(2)
    
  5. ==============================

    5.함수 내에서 전역 변수를 수정하려면 global 키워드를 사용해야합니다.

    함수 내에서 전역 변수를 수정하려면 global 키워드를 사용해야합니다.

    선없이이 작업을하려고 할 때

    global counter
    

    증분 정의의 내부에서 counter라는 이름의 로컬 변수가 생성되어 전체 프로그램이 의존 할 수있는 카운터 변수를 망칠 수 없도록합니다.

    변수를 수정할 때 전역 변수 만 사용해야합니다. 당신은 글로벌 문장이 필요없이 증가 안에서 카운터를 읽을 수 있습니다.

  6. ==============================

    6.파이썬은 기본적으로 렉시 컬 스코핑을 가지고 있습니다. 즉, 인 클로즈 스코프가 그것의 둘러싼 스코프에서 값에 접근 할 수는 있지만 전역 키워드로 전역 변수로 선언하지 않는 한 수정할 수는 없습니다.

    파이썬은 기본적으로 렉시 컬 스코핑을 가지고 있습니다. 즉, 인 클로즈 스코프가 그것의 둘러싼 스코프에서 값에 접근 할 수는 있지만 전역 키워드로 전역 변수로 선언하지 않는 한 수정할 수는 없습니다.

    클로저는 둘러싼 환경의 값을 로컬 환경의 이름에 바인딩합니다. 그런 다음 로컬 환경은 바인드 된 값을 사용할 수 있으며 해당 이름을 다른 것으로 재 할당 할 수 있지만 엔 클로징 환경에서 바인딩을 수정할 수는 없습니다.

    귀하의 경우에는 바운드 값 대신 카운터를 로컬 변수로 처리하려고합니다. 둘러싼 환경에서 할당 된 x 값을 바인딩하는이 코드는 잘 작동합니다.

    >>> x = 1
    
    >>> def f():
    >>>  return x
    
    >>> f()
    1
    
  7. ==============================

    7.이 시도

    이 시도

    counter = 0
    
    def increment():
      global counter
      counter += 1
    
    increment()
    
  8. ==============================

    8.파이썬은 순수하게 어휘 적으로 범위가 지정되지 않습니다.

    파이썬은 순수하게 어휘 적으로 범위가 지정되지 않습니다.

    참고 : 전역 변수를 작성한 함수가 아닌 다른 함수에서 전역 변수 사용

    및 이것 : http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/

  9. from https://stackoverflow.com/questions/9264763/dont-understand-why-unboundlocalerror-occurs by cc-by-sa and MIT license