질문자 :MacPython
*args
및 **kwargs
의 개념에 어려움이 있습니다.
지금까지 나는 다음과 같은 사실을 배웠습니다.
-
*args
= 인수 목록 - 위치 인수로 -
**kwargs
= 사전 - 키가 별도의 키워드 인수가 되고 값이 이러한 인수의 값이 됩니다.
이것이 어떤 프로그래밍 작업에 도움이 될지 이해가 되지 않습니다.
아마도:
나는 목록과 사전을 함수의 인수로 입력하고 동시에 와일드 카드로 입력한다고 생각하므로 모든 인수를 전달할 수 있습니까?
*args
와 **kwargs
가 어떻게 사용되는지 설명하는 간단한 예가 있습니까?
또한 내가 찾은 튜토리얼에서는 "*"와 변수 이름만 사용했습니다.
*args
및 **kwargs
단지 자리 표시자입니까, 아니면 코드에서 *args
및 **kwargs
구문은 *
및 **
입니다. *args
및 **kwargs
라는 이름은 관례에 따른 것일 뿐 사용에 대한 엄격한 요구 사항은 없습니다.
*args
사용합니다. 즉, 함수에 임의의 수의 인수를 전달할 수 있습니다. 예를 들어:
>>> def print_everything(*args): for count, thing in enumerate(args): ... print( '{0}. {1}'.format(count, thing)) ... >>> print_everything('apple', 'banana', 'cabbage') 0. apple 1. banana 2. cabbage
마찬가지로 **kwargs
사용하면 미리 정의하지 않은 명명된 인수를 처리할 수 있습니다.
>>> def table_things(**kwargs): ... for name, value in kwargs.items(): ... print( '{0} = {1}'.format(name, value)) ... >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable apple = fruit
명명된 인수와 함께 사용할 수도 있습니다. 명시적 인수는 먼저 값을 얻은 다음 다른 모든 것은 *args
및 **kwargs
전달됩니다. 명명된 인수가 목록에서 맨 처음에 옵니다. 예를 들어:
def table_things(titlestring, **kwargs)
동일한 함수 정의에서 둘 다 사용할 수도 있지만 *args
**kwargs
보다 먼저 발생해야 합니다.
함수를 호출할 때 *
및 **
구문을 사용할 수도 있습니다. 예를 들어:
>>> def print_three_things(a, b, c): ... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c)) ... >>> mylist = ['aardvark', 'baboon', 'cat'] >>> print_three_things(*mylist) a = aardvark, b = baboon, c = cat
이 경우에서 볼 수 있듯이 항목 목록(또는 튜플)을 가져와서 압축을 풉니다. 이를 통해 함수의 인수와 일치시킵니다. 물론 함수 정의와 함수 호출 모두에 *
가 있을 수 있습니다.
Dave Webb*args
및 **kwargs
것이 매우 유용한 한 곳은 서브클래싱입니다.
class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs)
이렇게 하면 Foo에 대해 너무 많이 알 필요 없이 Foo 클래스의 동작을 확장할 수 있습니다. 변경될 수 있는 API로 프로그래밍하는 경우 매우 편리할 수 있습니다. MyFoo는 모든 인수를 Foo 클래스에 전달합니다.
Mark van Lent다음은 3가지 유형의 매개변수를 사용하는 예입니다.
def func(required_arg, *args, **kwargs): # required_arg is a positional-only parameter. print required_arg # args is a tuple of positional arguments, # because the parameter name has * prepended. if args: # If args is not empty. print args # kwargs is a dictionary of keyword arguments, # because the parameter name has ** prepended. if kwargs: # If kwargs is not empty. print kwargs >>> func() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: func() takes at least 1 argument (0 given) >>> func("required argument") required argument >>> func("required argument", 1, 2, '3') required argument (1, 2, '3') >>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo") required argument (1, 2, '3') {'keyword2': 'foo', 'keyword1': 4}
Kit다음은 Dave Webb의 마지막 예에서와 같이 **
구문을 사용하는 데 가장 좋아하는 장소 중 하나입니다.
mynum = 1000 mystr = 'Hello World!' print("{mystr} New-style formatting is {mynum}x more fun!".format(**locals()))
이름 자체를 사용하는 것과 비교할 때 끔찍하게 빠른지 확실하지 않지만 입력하는 것이 훨씬 쉽습니다!
Wayne Werner*args 및 **kwargs가 유용한 한 가지 경우는 래핑되는 함수에 전달하기 위해 임의의 인수를 받아들일 수 있어야 하는 래퍼 함수(예: 데코레이터)를 작성할 때입니다. 예를 들어, 래핑되는 함수의 인수와 반환 값을 인쇄하는 간단한 데코레이터는 다음과 같습니다.
def mydecorator( f ): @functools.wraps( f ) def wrapper( *args, **kwargs ): print "Calling f", args, kwargs v = f( *args, **kwargs ) print "f returned", v return v return wrapper
jchl*args 및 **kwargs는 Python의 특별한 마법 기능입니다. 알 수 없는 수의 인수를 가질 수 있는 함수를 생각해 보십시오. 예를 들어, 이유가 무엇이든 알 수 없는 숫자의 합계를 구하는 함수를 원합니다(내장 합계 함수를 사용하고 싶지 않음). 그래서 당신은 이 함수를 작성합니다:
def sumFunction(*args): result = 0 for x in args: result += x return result
sumFunction(3,4,6,3,6,8,9)과 같이 사용하십시오.
**kwargs에는 다른 기능이 있습니다. **kwargs를 사용하면 함수에 임의의 키워드 인수를 제공하고 사전으로 액세스할 수 있습니다.
def someFunction(**kwargs): if 'text' in kwargs: print kwargs['text']
someFunction(text="foo")을 호출하면 foo가 인쇄됩니다.
Steven Mohr함수가 있지만 필요한 매개변수의 수를 제한하고 싶지 않다고 상상해 보십시오. 예시:
>>> import operator >>> def multiply(*args): ... return reduce(operator.mul, args)
그런 다음 이 기능을 다음과 같이 사용합니다.
>>> multiply(1,2,3) 6 or >>> numbers = [1,2,3] >>> multiply(*numbers) 6
Felix Kling*args
및 **kwargs
또는 **kw
라는 이름은 순전히 관례에 따릅니다. 서로의 코드를 더 쉽게 읽을 수 있습니다.
편리한 한 곳은 struct 모듈을 사용할 때입니다.
struct.unpack()
은 튜플을 반환하는 반면 struct.pack()
은 다양한 수의 인수를 사용합니다. 데이터를 조작할 때 튜플을 struck.pack()
에 전달할 수 있는 것이 편리합니다.
tuple_of_data = struct.unpack(format_str, data) # ... manipulate the data new_data = struct.pack(format_str, *tuple_of_data)
이 기능이 없으면 작성해야 합니다.
new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)
이것은 또한 format_str이 변경되고 튜플의 크기가 변경되면 돌아가서 정말 긴 줄을 편집해야 함을 의미합니다.
John La Rooy*args/**kwargs는 함수 호출 구문의 일부이며 실제로는 연산자가 아닙니다. 이것은 내가 만난 특별한 부작용이 있습니다. 즉, print는 함수가 아니기 때문에 print 문과 함께 *args 확장을 사용할 수 없다는 것입니다.
이것은 합리적으로 보입니다.
def myprint(*args): print *args
불행히도 컴파일되지 않습니다(구문 오류).
컴파일:
def myprint(*args): print args
그러나 우리가 원하는 것이 아닌 튜플로 인수를 인쇄합니다.
이것이 내가 결정한 솔루션입니다.
def myprint(*args): for arg in args: print arg, print
yoyo이러한 매개변수는 일반적으로 프록시 기능에 사용되므로 프록시는 모든 입력 매개변수를 대상 기능에 전달할 수 있습니다.
def foo(bar=2, baz=5): print bar, baz def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments print x foo(*args, **kwargs) # applies the "non-x" parameter to foo proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo proxy(6)# calls foo with its default arguments proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument
그러나 이러한 매개변수는 실제 매개변수 이름을 숨기므로 피하는 것이 좋습니다.
Rudipython 문서(FAQ의 docs.python.org)를 볼 수 있지만 더 구체적으로 좋은 설명을 보려면 신비한 미스터리 args 및 미스터 kwargs(archive.org 제공) (원본, 데드 링크가 여기 있음 ).
간단히 말해서, 둘 다 함수나 메소드에 대한 선택적 매개변수가 사용될 때 사용됩니다. Dave가 말했듯이 *args는 전달할 인수의 수를 모를 때 사용하고 **kwargs는 다음과 같이 이름과 값으로 지정된 매개변수를 처리하려는 경우 사용됩니다.
myfunction(myarg=1)
Yoni H출처 : http:www.stackoverflow.com/questions/3394835/use-of-args-and-kwargs