빈 목록이있는 기본 매개 변수를 피하는 Pythonic 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/366422

  •  21-08-2019
  •  | 
  •  

문제

때로는 빈 목록 인 기본 매개 변수가있는 것 같습니다. 아직 파이썬은 이러한 상황에서 예기치 않은 행동을 제공합니다.

예를 들어 기능이있는 경우 다음과 같습니다.

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

처음으로 기본값이라고 불리는 것은 작동하지만 그 후 전화는 기존 목록 (하나의 "각 호출"과 함께 업데이트 된 버전을 인쇄합니다.

그렇다면, 내가 원하는 행동을 얻는 Pythonic 방법은 무엇입니까 (각 통화의 새로운 목록)?

도움이 되었습니까?

해결책

def my_func(working_list=None):
    if working_list is None: 
        working_list = []

    working_list.append("a")
    print(working_list)

문서 사용해야한다고 말하십시오 None 기본적으로 명시 적으로 테스트하십시오 기능의 본문에서.

다른 팁

기존 답변은 이미 요청대로 직접 솔루션을 제공했습니다. 그러나 이것은 새로운 Python 프로그래머에게는 매우 일반적인 함정이므로 Python이 왜 이런 식으로 행동하는지 설명을 추가 할 가치가 있습니다.파이썬에 대한 히치하이커 가이드" 처럼 "변이 가능한 기본 인수": http://docs.python-guide.org/en/latest/writing/gotchas/

인용하다: "Python의 기본 인수는 함수가 정의 될 때 한 번 평가됩니다. 함수가 호출 될 때마다 (예 : Ruby). 이것은 돌연변이 가능한 기본 인수를 사용하고 돌연변이하면 기능에 대한 향후 모든 호출에 대해 그 객체를 돌려 놓았다는 것을 의미합니다."

구현하기위한 샘플 코드 :

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

이 경우에는 중요하지 않지만 객체 아이덴티티를 사용하여 없음을 테스트 할 수 있습니다.

if working_list is None: working_list = []

부울 운영자가 어떻게 파이썬에서 정의되는지를 활용할 수도 있습니다.

working_list = working_list or []

발신자가 빈 목록 (거짓으로 간주 됨)을 working_list로 제공하고 자신이 준 목록을 수정할 것을 기대하면 예기치 않게 행동 할 것입니다.

기능의 의도가 있다면 수정하다 매개 변수가 전달되었습니다 working_list, Henryr의 답변을 참조하십시오 (= 없음, 내부에 없음을 확인하십시오).

그러나 인수를 돌연변이하려고하지 않고 목록의 시작점으로 사용하면 간단히 복사 할 수 있습니다.

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

(또는이 간단한 경우에 print starting_list + ["a"] 하지만 나는 그것이 단지 장난감 예일 것 같아요)

일반적으로, 당신의 논증을 돌리는 것은 파이썬에서 나쁜 스타일입니다. 물체를 완전히 돌연변이 할 것으로 예상되는 유일한 기능은 객체의 방법입니다. 선택적인 인수를 돌연변이하는 것은 드문 일입니다. 일부 호출에서만 발생하는 부작용은 실제로 최고의 인터페이스입니까?

  • "출력 인수"의 C 습관에서 그것을하면 완전히 불필요합니다. 항상 여러 값을 튜플로 반환 할 수 있습니다.

  • 중간 목록을 구축하지 않고 긴 결과 목록을 효율적으로 구축하기 위해이 작업을 수행하면 발전기로 작성하고 사용하는 것을 고려하십시오. result_list.extend(myFunc()) 당신이 그것을 부를 때. 이렇게하면 전화 규칙은 매우 깨끗합니다.

옵션을 돌연변이하는 한 패턴 ~이다 재귀 함수의 숨겨진 "메모"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)

나는 주제를 벗어나지 않을 수도 있지만, 당신이 가변적 인 수의 인수를 통과시키고 싶다면, pythonic 방법은 튜플을 통과하는 것입니다. *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}

이미 좋은 답변이 제공되었습니다. 예를 들어 기본 빈 목록이있는 클래스를 만들고 싶을 때 더 아름답게 찾을 수있는 다른 구문을 작성하고 싶었습니다.

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 Operator 구문을 사용합니다. 나는 특히 콜론 등이없는 깔끔한 작은 1 라이너이기 때문에 특히 그것을 좋아하며 거의 평범한 영어 문장처럼 읽습니다. :)

당신의 경우 당신은 쓸 수 있습니다

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

UCSC Extension 클래스를 수강했습니다 Python for programmer

true of : def fn (data = []) :

a) 모든 통화마다 데이터 목록이 비어 있도록 좋은 아이디어입니다.

b) 호출에 인수를 제공하지 않는 함수에 대한 모든 호출이 빈 목록을 데이터로 얻을 수 있도록 좋은 생각입니다.

c) 데이터가 문자열 목록 인 한 합리적인 아이디어입니다.

d) 기본값이 데이터를 축적하고 기본값이 후속 호출에 따라 변경되기 때문에 나쁜 생각입니다.

대답:

d) 기본값이 데이터를 축적하고 기본값이 후속 호출에 따라 변경되기 때문에 나쁜 생각입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top