복붙노트

[PYTHON] 빈 목록 인 기본 매개 변수를 피하는 비법은 무엇입니까?

PYTHON

빈 목록 인 기본 매개 변수를 피하는 비법은 무엇입니까?

때로는 빈 목록 인 기본 매개 변수를 갖는 것이 자연스러운 것 같습니다. 그러나 파이썬은 이러한 상황에서 예기치 않은 동작을합니다.

예를 들어, 나는 함수가있다 :

def myFunc(working_list = []):
    working_list.append("a")
    print working_list

처음에는 기본값으로 호출 할 때 작동하지만 이후에 호출하면 끊임없이 업데이트되는 목록이 사용됩니다.

그럼, 내가 원하는 행동 (각 호출에 대한 신선한 목록)을 얻으려면 파이썬 방법은 무엇입니까?

해결법

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

    1.

    def myFunc(working_list=None):
        if working_list is None: 
            working_list = []
        working_list.append("a")
        print working_list
    

    내가 어떻게하는지.

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

    2.이 경우 중요한 것은 아니지만 개체 ID를 사용하여 없음을 테스트 할 수 있습니다.

    이 경우 중요한 것은 아니지만 개체 ID를 사용하여 없음을 테스트 할 수 있습니다.

    if working_list is None: working_list = []
    

    부울 연산자 또는 파이썬에서 정의 된 방법을 활용할 수도 있습니다.

    working_list = working_list or []
    

    호출자가 working_list와 같은 빈 목록 (false로 계산)을 제공하고 함수가 자신이 지정한 목록을 수정하기를 기대한다면 예기치 않게 작동합니다.

  3. ==============================

    3.기존 답변은 이미 요청 된 직접 솔루션을 제공했습니다. 그러나 이것이 새로운 Python 프로그래머에게는 매우 흔한 함정이기 때문에, Python이 "Hitchhikers Guide to Python"에서 "Mutable Default Arguments"로 잘 요약 된 이유를 설명하는 이유를 추가 할 가치가 있습니다. http://docs.python-guide.org/ko/latest/writing/gotchas/

    기존 답변은 이미 요청 된 직접 솔루션을 제공했습니다. 그러나 이것이 새로운 Python 프로그래머에게는 매우 흔한 함정이기 때문에, Python이 "Hitchhikers Guide to Python"에서 "Mutable Default Arguments"로 잘 요약 된 이유를 설명하는 이유를 추가 할 가치가 있습니다. http://docs.python-guide.org/ko/latest/writing/gotchas/

    Quote : "Python의 기본 인수는 함수가 정의 될 때 한 번 평가되며 함수가 호출 될 때마다 (예 : Ruby와 같이) 평가되지는 않습니다. 즉, 기본 인수를 변경하여 변경할 수있는 경우, 함수에 대한 이후의 모든 호출을 위해 해당 객체를 변경했습니다. "

    구현할 샘플 코드 :

    def foo(element, to=None):
        if to is None:
            to = []
        to.append(element)
        return to
    
  4. ==============================

    4.이 함수의 목적이 working_list로 전달 된 매개 변수를 수정하는 것이라면 HenryR의 대답 (= 없음, 내부에서 없음 확인)을 참조하십시오.

    이 함수의 목적이 working_list로 전달 된 매개 변수를 수정하는 것이라면 HenryR의 대답 (= 없음, 내부에서 없음 확인)을 참조하십시오.

    그러나 인수를 돌연변이 화하려는 의도가 아니라면 인수를 목록의 시작점으로 사용하십시오. 간단히 복사 할 수 있습니다.

    def myFunc(starting_list = []):
        starting_list = list(starting_list)
        starting_list.append("a")
        print starting_list
    

    (또는이 간단한 경우에 단지 starting_list + [ "a"]를 인쇄하십시오. 그러나 저는 그것이 장난감의 예라고 생각합니다)

    일반적으로 인수를 변경하는 것은 파이썬에서 나쁜 스타일입니다. 완전히 돌연변이 된 것으로 예상되는 유일한 기능은 객체의 메소드입니다. 선택적 인수를 변경하는 것이 더 드문 경우입니다. 일부 호출에서만 실제로 발생하는 부작용이 실제로 가장 좋은 인터페이스입니까?

    선택적인 arg가 자주 변경되는 하나의 패턴은 재귀 함수에서 숨겨진 "메모"arg입니다 :

    def depth_first_walk_graph(graph, node, _visited=None):
        if _visited is None:
            _visited = set()  # create memo once in top-level call
    
        if node in _visited:
            return
        _visited.add(node)
        for neighbour in graph[node]:
            depth_first_walk_graph(graph, neighbour, _visited)
    
  5. ==============================

    5.나는 논쟁의 여지가 없을 수도 있지만, 변수의 수를 전달하기를 원한다면, 파이썬적인 방법은 튜플 * args 또는 사전 ** kargs를 전달하는 것임을 기억하십시오. 이들은 선택적이며 구문 myFunc ([1, 2, 3])보다 좋습니다.

    나는 논쟁의 여지가 없을 수도 있지만, 변수의 수를 전달하기를 원한다면, 파이썬적인 방법은 튜플 * args 또는 사전 ** kargs를 전달하는 것임을 기억하십시오. 이들은 선택적이며 구문 myFunc ([1, 2, 3])보다 좋습니다.

    튜플을 전달하려면 다음을 수행하십시오.

    def myFunc(arg1, *args):
      print args
      w = []
      w += args
      print w
    >>>myFunc(1, 2, 3, 4, 5, 6, 7)
    (2, 3, 4, 5, 6, 7)
    [2, 3, 4, 5, 6, 7]
    

    사전을 전달하려면 다음을 수행하십시오.

    def myFunc(arg1, **kargs):
       print kargs
    >>>myFunc(1, option1=2, option2=3)
    {'option2' : 2, 'option1' : 3}
    
  6. ==============================

    6.이미 좋은 답변이 제공되었습니다. 난 단지 당신이 예를 들어 기본 빈 목록을 사용하여 클래스를 만들고 싶을 때 내가 더 아름답게 보이고 싶은 것을 작성하는 또 다른 구문을주고 싶었습니다.

    이미 좋은 답변이 제공되었습니다. 난 단지 당신이 예를 들어 기본 빈 목록을 사용하여 클래스를 만들고 싶을 때 내가 더 아름답게 보이고 싶은 것을 작성하는 또 다른 구문을주고 싶었습니다.

    class Node(object):
        def __init__(self, _id, val, parents=None, children=None):
            self.id = _id
            self.val = val
            self.parents = parents if parents is not None else []
            self.children = children if children is not None else []
    

    이 스 니펫은 if else 연산자 구문을 사용합니다. 나는 콜론이없는 깔끔한 작은 하나의 라이너가 포함되어 있기 때문에 특히 마음에 들었고 보통의 영어 문장처럼 거의 읽습니다. :)

    당신의 경우에는

    def myFunc(working_list=None):
        working_list = [] if working_list is None else working_list
        working_list.append("a")
        print working_list
    
  7. from https://stackoverflow.com/questions/366422/what-is-the-pythonic-way-to-avoid-default-parameters-that-are-empty-lists by cc-by-sa and MIT license