Python 함수 의 기본 매개 변수 설계 예제 상세 설명

Python 튜 토리 얼 에서 기본 매개 변 수 를 대상 으로'중요 경고'의 예 를 주 었 습 니 다.

def f(a, L=[]):
  L.append(a)
  return L

print(f(1))
print(f(2))
print(f(3))
기본 값 은 한 번 만 실 행 될 뿐 이 유 는 말 하지 않 았 다.결 과 를 출력 합 니 다:
[1]
[1, 2]
[1, 2, 3]
첫 번 째 언어 는 루비 라 서 좀 이상 하 다.하지만 분명 한 것 은 방법 f 에 변수 L 이 저장 되 어 있 을 것 이다.
준비 지식:포인터
p 는 숫자 와 같은 가 변 적 이지 않 은 대상 을 가리킨다.p 포인터 가 다른 메모리 주 소 를 가리 키 는 것 과 같다.
p 는 list 와 같은 가 변 대상 을 가리킨다.list 자체 의 변 화 는 list 대상 자체 가 있 는 메모리 주 소 를 바 꾸 지 않 습 니 다.그래서 p 가 가리 키 는 메모리 주 소 는 변 하지 않 습 니 다.

>>> p = 1
>>> id(p)
>>> p = p + 1
>>> id(p)
>>> p = 11
>>> id(p)

>>> p = []
>>> id(p)
>>> p.append(11)
>>> id(p)
근본 원인
Python 함수 의 인자 기본 값 은 컴 파일 단계 에서 연 결 됩 니 다.(코드 를 쓸 때 정 의 됩 니 다.)
다음은Python Common Gotchas에서 발췌 한 원인 설명 이다.
Python's default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.
이로부터 알 수 있다.
  • 코드 를 실행 할 때 함수 정의 로 실 행 될 때 기본 매개 변수의 표현 식 이 실 행 됩 니 다.
  • 함수 호출 시 기본 매개 변수의 표현 식 을 다시 실행 하지 않 습 니 다.⚠️ 이 점 은 루비 와 는 완전히 다르다.4567918)
  • 이 를 통 해 알 수 있 듯 이 기본 매개 변 수 는 L=1 과 같은 변 하지 않 는 대상 을 가리킨다.그러면 함수 가 호출 될 때 함수 내 에서 L 에 값 을 다시 부여 합 니 다.L 은 사실은 새로운 포인터 이 고 새로운 메모리 주 소 를 가리 키 는 것 입 니 다.원래 기본 매개 변수 L 자체 와 가리 키 는 메모리 주 소 는 컴 파일 을 시작 할 때의 함수 정의 에 저장 되 어 있 습 니 다.사용 가능default__살펴보다4567918)
  • 기본 매개 변수 가 list 와 같은 가 변 대상 을 가리 키 면 L.append(a)는 가 변 대상 자체 에 대한 수정 이 고 L 이 가리 키 는 메모리 주 소 는 변 하지 않 습 니 다.그래서 매번 함 수 를 호출 할 때마다 기본 매개 변 수 는 이 메모리 주소 의 대상 입 니 다.
  • 제3 조 위의 예 를 수정한다.
    
    def f(a, L = 1):
      L = a
      print(id(L))
      return L
    
    print("self",id(f.__defaults__[0]))
    print(f(1))
    print("self",id(f.__defaults__[0]))
    print(f(33))
    print("self",id(f.__defaults__[0]))
    
    #    :
    self 4353170064
    1
    self 4353170064
    33
    self 4353170064
    기본 매개 변수 L,컴 파일 단계 에서 연결 되 어 에 저 장 됩 니 다.default__안.함수 내의 L=a 표현 식 은 새로운 변 수 를 생 성 합 니 다.돌아 오 는 L 은 기본 매개 변수 와 무관 한 새로운 변수 입 니 다.
    제4 조 위의 예 입 니 다.기본 매개 변수의 유형 을 가 변 대상 list 로 바 꾸 십시오.
    
    def f(a, L = []):
      L.append(a)
      print(id(L))
      return L
    # L = f(1)
    print("self",id(f.__defaults__[0]))
    print(f(1))
    print("self",id(f.__defaults__[0]))
    print(f(33))
    print("self",id(f.__defaults__[0]))
    
    #    
    self 4337586048
    [1]
    self 4337586048
    [1, 33]
    self 4337586048
    id 번호 에서 알 수 있 듯 이 기본 매개 변수 자신 을 되 돌려 줍 니 다.
    어떻게 이 함정 이 불필요 한 번 거 로 움 을 가 져 오 는 것 을 피 할 수 있 습 니까?
    
    def f(a, L = None):
      if L is None:
        L = []
      L.append(a)
      return L
    파 이 썬 이 왜 이렇게 디자인 을 했 는 지.
      StackOverflow에 서 는 논쟁 이 많다.
    Ruby 에 문제 가 없 는 이 유 는 Ruby 의 def 키워드 가 폐쇄 적 인 역할 영역 을 정 의 했 기 때 문 이 라 고 생각 합 니 다.모든 데 이 터 는 매개 변 수 를 통 해 방법 에 들 어가 야 사용 할 수 있 습 니 다.
    Ruby 에 비해 Python 매개 변수의 역할 이 크게 약화 되 었 습 니 다.Python 의 등장 은 Ruby 보다 늦 었 고 그 창시자 가 Ruby 의 디자인 을 참고 한 것 이 분명 합 니 다.이 디자인 을 버 리 고 자바 script 과 유사 한 함수 방식 을 선택 하 였 습 니 다.def 가 정의 하 는 함수 입 니 다.실행 할 때 외부 역할 필드 의 변 수 를 받 을 수 있 습 니 다.
    어떤 관점 에 서 는:
    Python 컴 파일 러 의 실현 방식 을 고려 하여 함 수 는 내부 1 급 대상 입 니 다.매개 변수 기본 값 은 이 대상 의 속성 입 니 다.다른 모든 언어 에서 대상 속성 은 대상 이 생 성 될 때 바 인 딩 됩 니 다.따라서 함수 매개 변수 기본 값 이 컴 파일 할 때 바 인 딩 되 는 것 도 이상 하지 않다.
    본 고 는 참고 했다.http://cenalulu.github.io/python/default-mutable-arguments/#toc1그리고 자신의 이 해 를 넣 었 다.
    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기