가변 개수의 인수를 함수에 전달할 수 있습니까?


345

C 또는 C ++에서 varargs를 사용하는 것과 비슷한 방식으로 :

fn(a, b)
fn(a, b, c, d, ...)

5
나는 훌륭한 로트 니스를 팟 캐스트 53을 참고합니다 : itc.conversationsnetwork.org/shows/…
David Sykes

2
로트 씨와 함께 가야 해요 파이썬 문서에서 이것에 대한 정식 답변을 빠르게 얻을 수 있으며, 문서에 무엇이 있는지 느낄 수 있습니다. 파이썬으로 작업 할 계획이라면 그러한 문서를 아는 것이 도움이됩니다.
Brian Neal

@DavidSykes 링크가 깨졌습니다
Dave Liu

답변:


447

예. 키워드*args아닌 인수 로 사용할 수 있습니다 . 그러면 여러 개의 인수를 전달할 수 있습니다.

def manyArgs(*arg):
  print "I was called with", len(arg), "arguments:", arg

>>> manyArgs(1)
I was called with 1 arguments: (1,)
>>> manyArgs(1, 2, 3)
I was called with 3 arguments: (1, 2, 3)

보시다시피, 파이썬은 모든 인수와 함께 단일 튜플로 인수를 압축 해제 합니다.

키워드 인수 의 경우 Skurmedel의 답변에 표시된대로 키워드 인수를 별도의 실제 인수로 수락해야합니다 .


8
또한 중요 ... 알 수없는 수의 인수를 함수에 전달해야 할 때가 있습니다. 이 경우 "args"라는 목록을 작성하고 "manyArgs (* args)"와 같은 manyArgs에 전달하여 "manyArgs"를 호출하십시오.
wilbbe01

4
이것은 가깝지만 불행히도 충분하지 않습니다.로 manyArgs(x = 3)실패합니다 TypeError. Skumedel의 답변은 이에 대한 해결책을 보여줍니다. 핵심은 함수의 일반 서명이 f(*list_args, **keyword_args)(not f(*list_args))이라는 것입니다.
Eric O Lebigot

2
의 유형은 args입니다 tuple. 키워드 args를kwargs 의미 합니다 . 의 유형은 kwargs입니다 dictionary.
RoboAlex

1
그냥 for arg in args:통과 인수를 통해 반복을위한
MasterControlProgram

228

소식을 추가하면 게시물이 해제됩니다.

여러 키-값 인수를 보낼 수도 있습니다.

def myfunc(**kwargs):
    # kwargs is a dictionary.
    for k,v in kwargs.iteritems():
         print "%s = %s" % (k, v)

myfunc(abc=123, efh=456)
# abc = 123
# efh = 456

그리고 당신은 두 가지를 혼합 할 수 있습니다 :

def myfunc2(*args, **kwargs):
   for a in args:
       print a
   for k,v in kwargs.iteritems():
       print "%s = %s" % (k, v)

myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123

그것들은 순서대로 선언되고 호출되어야합니다. 즉, 함수 서명은 * args, ** kwargs이어야하고 그 순서대로 호출되어야합니다.


2
myfunc (abc = 123, def = 456)가 어떻게 작동하는지 확실하지 않지만 내 (2.7)에서는 SyntaxError를 얻지 않고이 함수에서 'def'를 전달할 수 없습니다. 나는 이것이 def가 파이썬에서 의미를 갖기 때문이라고 가정합니다. 대신 myfunc (abc = 123, fgh = 567)를 시도하십시오. (그렇지 않으면 큰 답변과 감사합니다!)
Dannid

@ Dannid : haha ​​... 2.6 또는 3.2에서 작동하지 않습니다. 이름을 바꾸겠습니다.
Skurmedel

'순서대로'라고 말할 때 그 순서대로 통과 했습니까? 또는 다른 것?
Nikhil Prabhu

1
@NikhilPrabhu : 예. 키워드 인수는 호출 할 때 마지막에 와야합니다. 호출에 키워드가 아닌 인수가있는 경우 항상 마지막에옵니다.
Skurmedel

2
그냥 교환 : 파이썬 3 print aprint(a)하고 kwargs.iteritems():kwargs.items().
MasterControlProgram

22

내가 할 수 있다면 Skurmedel의 코드는 파이썬 2 용입니다. 파이썬 3에 적용하려면 iteritems로 변경 items하고 괄호를 추가하십시오 print. 그러면 나와 같은 초보자가 AttributeError: 'dict' object has no attribute 'iteritems'다른 곳 으로 들어가는 것을 막을 수 있습니다 (예 : NetworkX의 write_shp ()를 사용하려고 할 때 오류“ 'dict'객체에 'iteritems'속성이 없습니다 ' ). 이것이 왜 발생하는지.

def myfunc(**kwargs):
for k,v in kwargs.items():
   print("%s = %s" % (k, v))

myfunc(abc=123, efh=456)
# abc = 123
# efh = 456

과:

def myfunc2(*args, **kwargs):
   for a in args:
       print(a)
   for k,v in kwargs.items():
       print("%s = %s" % (k, v))

myfunc2(1, 2, 3, banan=123)
# 1
# 2
# 3
# banan = 123

12

다른 우수한 게시물에 추가합니다.

때때로 당신은 인수의 수를 지정하지 않으 그들을 위해 키를 (사전에 전달 된 하나 개의 인수는 방법에 사용하지 않는 경우 컴파일러가 불평) 사용하려고합니다.

def manyArgs1(args):
  print args.a, args.b #note args.c is not used here

def manyArgs2(args):
  print args.c #note args.b and .c are not used here

class Args: pass

args = Args()
args.a = 1
args.b = 2
args.c = 3

manyArgs1(args) #outputs 1 2
manyArgs2(args) #outputs 3

그럼 당신은 같은 일을 할 수 있습니다

myfuns = [manyArgs1, manyArgs2]
for fun in myfuns:
  fun(args)

2
def f(dic):
    if 'a' in dic:
        print dic['a'],
        pass
    else: print 'None',

    if 'b' in dic:
        print dic['b'],
        pass
    else: print 'None',

    if 'c' in dic:
        print dic['c'],
        pass
    else: print 'None',
    print
    pass
f({})
f({'a':20,
   'c':30})
f({'a':20,
   'c':30,
   'b':'red'})
____________

위의 코드가 출력됩니다

None None None
20 None 30
20 red 30

이것은 사전을 통해 변수 인수를 전달하는 것만 큼 좋습니다.


3
이것은 끔찍한 코드입니다. f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')
은총

0

이미 언급 한 좋은 답변 외에도 다른 방법으로 위치에 따라 선택적 명명 된 인수를 전달할 수 있다는 사실에 달려 있습니다. 예를 들어

def f(x,y=None):
    print(x)
    if y is not None:
        print(y)

수확량

In [11]: f(1,2)
1
2

In [12]: f(1)
1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.