Python 함수 기반 역할 영역 규칙 및 패키지 닫 기(상세 설명)

역할 영역 규칙
네 임 스페이스 는 이름 에서 대상 까지 의 맵 입 니 다.Python 에 서 는 주로 사전 을 통 해 이 루어 집 니 다.주로 다음 과 같은 네 임 스페이스 가 있 습 니 다.
내 장 된 네 임 스페이스 는 내 장 된 함수 와 내 장 된 이상 한 이름 을 포함 하여 Python 해석 기 가 시 작 될 때 만 들 고 해석 기 가 종 료 될 때 까지 저장 합 니 다.내 장 된 이름 은 실제로 라 는 이름 에 존재 합 니 다.builtins__의 모듈 에서 globals()['builtins__'].__dict__내 장 된 함수 와 내 장 된 이상 을 봅 니 다.
전역 네 임 스페이스 는 함수 가 있 는 모듈 을 읽 을 때 만 듭 니 다.보통 모듈 네 임 스페이스 는 해석 기 가 종 료 될 때 까지 저 장 됩 니 다.내 장 된 함수 globals()를 통 해 볼 수 있 습 니 다.
부분 네 임 스페이스 는 함수 호출 시 생 성 되 며 함수 매개 변수의 이름과 함수 체 내 할당 변 수 를 포함 합 니 다.함수 가 되 돌아 오 거나 함수 내부 에 처리 되 지 않 은 이상 을 일 으 켰 을 때 삭제 합 니 다.모든 재 귀적 호출 은 자신의 부분 네 임 스페이스 가 있 습 니 다.내 장 된 함수 locals()를 통 해 볼 수 있 습 니 다.
python 에서 변수 이름 을 분석 할 때 먼저 부분 네 임 스페이스 를 검색 합 니 다.일치 하 는 이름 을 찾 지 못 하면 전역 네 임 스페이스 를 검색 합 니 다.해석 기 가 전체 네 임 스페이스 에서 도 일치 하 는 값 을 찾 지 못 하면 내 장 된 네 임 스페이스 를 검사 합 니 다.여전히 찾 지 못 하면 네 임 에 러 이상 을 유발 할 수 있다.
서로 다른 네 임 스페이스 안의 이름 은 절대 관계 가 없습니다.예 를 들 어:

a = 42
def foo():
  a = 13
  print "globals: %s" % globals()
  print "locals: %s" % locals()
  return a
foo()
print "a: %d" % a
결과:

globals: {'a': 42, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Users\\h\\Desktop\\test4.py', '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x0000000002C17AC8>, '__doc__': None}
locals: {'a': 13}
a: 42
이 를 통 해 알 수 있 듯 이 함수 에서 변수 a 에 대한 할당 은 부분 적 인 역할 영역 에서 새로운 부분 변수 a 를 만 들 고 외부 에서 같은 이름 을 가 진 전체 변수 a 는 변 하지 않 습 니 다.
Python 에서 할당 작업 은 항상 가장 안쪽 에 있 는 역할 영역 입 니 다.할당 은 데 이 터 를 복사 하지 않 고 이름 만 대상 에 연결 합 니 다.삭제 도 마찬가지 입 니 다.예 를 들 어 함수 에서 del a 를 실행 하 는 것 도 부분 네 임 스페이스 에서 부분 변수 a 를 삭제 할 뿐 전체 변수 a 는 변 하지 않 습 니 다.
부분 변 수 를 사용 할 때 값 을 부여 하지 않 으 면 Unbound LocalError 이상 이 발생 합 니 다.

a = 42
def foo():
  a += 1
  return a
foo()
상기 함수 에서 부분 변수 a 를 정의 합 니 다.할당 문 a+=1 은 a 할당 전에 값 을 읽 으 려 고 시도 하지만 전체 변수 a 는 부분 변수 a 에 값 을 부여 하지 않 습 니 다.
부분 네 임 스페이스 에서 전역 변 수 를 조작 하려 면 global 문 구 를 사용 할 수 있 습 니 다.global 문 구 는 변 수 를 전역 네 임 스페이스 에 속 하 는 것 으로 명확 하 게 설명 할 수 있 습 니 다.

a = 42
def foo():
  global a
  a = 13
  print "globals: %s" % globals()
  print "locals: %s" % locals()
  return a
foo()
print "a: %d" % a
출력:

globals: {'a': 13, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Users\\h\\Desktop\\test4.py', '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x0000000002B87AC8>, '__doc__': None}
locals: {}
a: 13
전역 변수 a 가 바 뀌 었 음 을 알 수 있 습 니 다.
Python 은 내장 함수(패 킷 닫 기)를 지원 하지만 python 2 는 가장 안쪽 에 있 는 역할 영역 과 전체 네 임 스페이스 에서 만 변 수 를 다시 할당 할 수 있 습 니 다.내부 함 수 는 외부 함수 의 부분 변 수 를 다시 할당 할 수 없습니다.예 를 들 어:

def countdown(start):
  n = start
  def display():
    print n
  def decrement():
    n -= 1
  while n > 0:
    display()
    decrement()
countdown(10)
이 문 제 를 해결 하 는 방법 은 목록 이나 사전 에 변 수 를 넣 는 것 입 니 다.

def countdown(start):
  alist = []
  alist.append(start)
  def display():
    print alist[0]
  def decrement():
    alist[0] -= 1
  while alist[0] > 0:
    display()
    decrement()
countdown(10)
python 3 에서 nonlocal 문 구 를 사용 하여 이 문 제 를 해결 할 수 있 습 니 다.nonlocal 문 구 는 현재 호출 스 택 의 다음 함수 정 의 를 검색 합 니 다.:

def countdown(start):
  n = start
  def display():
    print n
  def decrement():
    nonlocal n
    n -= 1
  while n > 0:
    display()
    decrement()
countdown(10)
폐쇄 하 다
패 킷 닫 기(closure)는 함수 식 프로 그래 밍 의 중요 한 문법 구조 입 니 다.Python 도 이 기능 을 지원 합 니 다.예 를 들 어 내장 함수:

def foo():
  x = 12
  def bar():
    print x
  return bar
foo()()
출력:12
내 장 된 함수 가 외부 함수 가 정의 하 는 역할 영역 에 접근 할 수 있 는 변 수 를 볼 수 있 습 니 다.실제로 내 장 된 함수 가 이름 을 해석 할 때 먼저 부분 적 인 역할 영역 을 검사 한 다음 에 가장 내부 호출 함수 의 역할 영역 부터 모든 호출 함수 의 역할 영역 을 검색 할 수 있 습 니 다.이 는 국 지적 이지 만 전체 적 인 이름 이 아 닙 니 다.
함 수 를 구성 하 는 문장 과 문장의 실행 환경 을 한데 묶 으 면 얻 은 대상 을 폐쇄 라 고 한다.내장 함수 에서 패 키 지 는 내부 함수 수행 에 필요 한 전체 환경 을 포착 합 니 다.
python 함수 의 code 대상 또는 바이트 코드 중 두 개의 패키지 와 관련 된 대상 이 있 습 니 다.
co_cellvars:포 함 된 함수 가 참조 하 는 부분 변 수 를 포함 하 는 원 그룹 입 니 다.
co_freevars:원 그룹 입 니 다.사용 한 외부 역할 영역 에 있 는 변수 이름 을 저장 합 니 다.
위의 내장 함 수 를 다시 보 세 요:

>>> def foo():
    x = 12
    def bar():
      return x
    return bar
 
>>> foo.func_code.co_cellvars
('x',)
>>> bar = foo()
>>> bar.func_code.co_freevars
('x',)
외층 함 수 를 볼 수 있 는 code 대상 의 cocellvars 는 내부 내장 함수 가 인용 해 야 할 변수의 이름 을 저장 하고 내부 내장 함수 의 code 대상 의 cofreevars 는 외부 함수 역할 영역 을 참조 해 야 할 변수 이름 을 저장 합 니 다.
함수 컴 파일 과정 에서 내부 함수 에 폐쇄 된 특수 속성 이 있 습 니 다closure__(func_closure)。__closure__속성 은 cell 대상 으로 구 성 된 원 그룹 으로 여러 역할 영역 에서 참조 하 는 변 수 를 포함 합 니 다.

>>> bar.func_closure
(<cell at 0x0000000003512C78: int object at 0x0000000000645D80>,)
패 킷 에 있 는 변수의 내용 을 보 려 면:

>>> bar.func_closure[0].cell_contents
12
내부 함수 에 외부 함수 변수 에 대한 인용 이 포함 되 지 않 으 면closure__속성 은 존재 하지 않 습 니 다:

>>> def foo():
    x = 12
    def bar():
      pass
    return bar
 
>>> bar = foo()
>>> print bar.func_closure
None
함 수 를 대상 으로 다른 함수 에 매개 변 수 를 전달 할 때 폐쇄 와 내장 함 수 를 결합 한 다음 에 하나의 함 수 를 되 돌려 주 는 것 이 python 장식 기의 응용 입 니 다.
지연 바 인 딩
주의해 야 할 것 은 python 함수 의 역할 영역 은 코드 에 의 해 결정 되 고 정적 이지 만 사용 은 동적 이 며 실행 할 때 확 정 됩 니 다.

>>> def foo(n):
    return n * i
 
>>> fs = [foo for i in range(4)]
>>> print fs[0](1)
결과 가 0 이 되 기 를 기대 할 때 결 과 는 3 이다.
이것 은 함수 foo 가 실 행 될 때 만 변수 i 의 값 을 검색 하기 때 문 입 니 다.순환 이 끝 났 기 때문에 i 는 최종 값 3 을 가리 키 기 때문에 같은 결 과 를 얻 을 수 있 습 니 다.
패 킷 닫 기 에 도 같은 문제 가 존재 합 니 다.

def foo():
  fs = []
  for i in range(4):
    fs.append(lambda x: x*i)
  return fs
for f in foo():
  print f(1)
돌아 가기:
해결 방법,하 나 는 함수 매개 변 수 를 위 한 기본 값 을 설정 하 는 것 입 니 다.

>>> fs = [lambda x, i=i: x * i for i in range(4)]
>>> for f in fs:
    print f(1)
그리고 폐쇄 를 사 용 했 습 니 다.

>>> def foo(i):
    return lambda x: x * i
 
>>> fs = [foo(i) for i in range(4)]
>>> for f in fs:
    print f(1)
또는:

>>> for f in map(lambda i: lambda x: i*x, range(4)):
    print f(1)
패 키 지 를 사용 하면 편 함수 와 유사 하 며 편 함수 도 사용 할 수 있 습 니 다.

>>> fs = [functools.partial(lambda x, i: x * i, i) for i in range(4)]
>>> for f in fs:
    print f(1)
이렇게 하면 자유 변수 i 는 패 킷 함수 에 우선 연 결 됩 니 다.
파 이 썬 함 수 를 기반 으로 한 역할 영역 규칙 과 패키지 닫 기(상세 설명)는 바로 소 편 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 가 되 고 많은 응원 부탁드립니다.

좋은 웹페이지 즐겨찾기