Parameter (*args, **kwargs) & Nested Function

jinatra·2021년 8월 10일
0

Python

목록 보기
10/15
post-thumbnail

Parameter (*args, **kwargs) & Nested Function


Parameter (*args, **kwargs)

*args

  • 가변인자를 위한 변수 (튜플 형식으로 저장)

함수의 인자가 몇개인지 모를 때 사용

#example

def add(a, b, c):
	add(a+b+c)

add(2, 3, 4)


# Output
9

일반적인 함수는 위와 같이 parameter 갯수가 지정이 된다.
그러나 일단 parameter 갯수가 몇개인지 모를 수 있을 때도 있다.

이럴 때를 위해서 존재하는 것이 arguments(*args) 이다.

일반적으로 *args 라고 쓰지만, * 뒤에 어떤게 와도 상관없다.
*hiphop , *love, *munequita 등 무엇이든 가능하다.

방법은 그냥 간단하게 함수의 parameter를 넣을 자리에 *args를 넣으면 된다.

# example 

def add(*args):
    result = 0
    for i in args:
        result += i
    print(result)
 
add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)


# Output
55

*args에 집어넣은 value는 튜플 형태가 된다.

예를 들어 위에서 1~10까지 넣었다면, add함수 안에 *args라는 튜플이 생기고, 그 안에 (1, 2, 3, .., 10)까지 튜플 형식으로 추가가 되는 것이다.


**kwargs

  • 가변인자를 위한 변수 (딕셔너리 형식으로 저장)

함수의 인자가 몇개인지 모를 때 사용

*args와 동일한 로직이며, 튜플이 아닌 딕셔너리 형태로 저장된다는 점이 다르다.

*args와 똑같이 **kwargs 말고도 다양한 이름으로 생성 가능하다.
(**rock, **peace, **jazz 등..)

# example

def movie_info(**kwargs):
	print(kwargs)

movie_info(name='Cold War', genre='Romance')


#Output
{'name': 'Cold War', 'genre': 'Romance'}

위에서처럼, movie_info 함수에 **kwargs를 준 후, 함수를 호출 할때 namegenre parameter를 각각 지정한 후 value를 나열해주면,
namegenrekey, 할당된 value들이 value와 같은 딕셔너리 형식으로 출력이 된다.


*args**kwargs 의 동시 사용

*args**kwargs 는 동시에 사용할 수 있다.

*args는 튜플의 형태로,
**kwargs는 딕셔너리의 형태로로 출력이 된다.

# example

def info(*args, **kwargs):
	return(f"*args is {args}, and **kwargs is {kwargs}")

print(info("Love", 6, True, name='Cold War', genre='Romance'))


# Output
*args is ('Love', 6, True), and **kwargs is {'name': 'Cold War', 'genre': 'Romance'}

*args로 지정해준 Love(string), 6(number), True(boolean)은 튜플 형태
('Love', 6, True)

**kwargs로 지정해준 name='Cold War', genre='Romance'는 딕셔너리 형태
{'name': 'Cold War', 'genre': 'Romance'}


Nested Function (중첩함수)

Nested Function 의 정의

중첩함수 -ㅎ 함수 안에서 정의된 함수

함수 안에서 함수를 선언하는 것이 가능

중첩 함수는 상위의 부모 함수 안에서만 호출이 가능하므로 부모 함수를 벗어나서 호출 될 수 없다.

# example_1

def parent_function():
	def child_function():
		return 'Yo'


print(parent_function())


# Output
None

부모함수parent_function() 이 아닌 중첩함수 child_function()return 값을 준 것이므로, 부모 함수를 호출한다고 해도 정의된 return 값이 없기에 None이 호출

# example_2

def parent_function():
	def child_function():
		return 'Yo'
	return child_function()

print(parent_function())


# Output
Yo

이번엔 부모함수parent_function()return값으로 자식함수child_function()를 주었으니, 자식함수의 return값을 부모함수 외부에서 호출할 수 있다.


Decorator

Decorator(데코레이터) - 다른 함수에 적용해서 적용된 함수가 실행되기 전에 무조건 실행되도록 하는 함수

데코레이터라는 말 그대로 어떤 함수가 실행되기 전 무조건 실행되도록 하기 위해 '꾸며준다' 라고 생각하면 된다.
특정 함수를 실행하기 전에 강제적으로 다른 함수가 먼저 실행된후 실행되도록 하는 강제성을 제공하는 기능이다.

예를 들어,
모든 가사 문장 뒤에 'yo yo!'를 붙이는 함수를 문장별로 만들어 본다고 하자.
문장을 만들때마다 뒤에 'yo yo!'를 붙일 수도 있지만, 이 경우엔 굉장히 귀찮은 작업이 될 것이다.

이때 데코레이터를 이용하면 굉장히 쉽게 할 수 있다.

# example

def yo_maker(func):
	def wrapper(*args, **kwargs):
		return f'{func(*args, **kwargs)}, yo yo!'
	return wrapper()

@yo_maker
def lyrics():
	return "This is hiphop"

print(lyrics)


# Output
This is hiphop, yo yo!

쉽게 생각해서, yo_maker(func)func 자리에 lyrics() 함수가 들어가서 yo_maker(lyrics)의 형태가 되도록 해주는 것이다.

  1. 데코레이터 부모함수 yo_maker(func) 선언
  2. 데코레이터 자식함수 wrapper() 선언
  3. wrapper 함수가 return 되면 func 함수 뒤에 'yo yo!'가 나오도록 설정
  4. lyrics 함수를 만들 때 yo_maker 함수를 데코레이터로 설정
  5. 그럼 lyrics 함수가 리턴되기 전에 yo_maker 함수부터 리턴
  6. 즉, yo_maker(lyrics) 의 형태




Take Away

*args**kwargs 차이에 대한 이해

이제 조금 명확하게 두 가변인자에 대한 차이를 알 수 있을 것 같다.

*args 는 튜플 형태
**kwargs 는 딕셔너리 형태

항상 기억하자!


Decorator

대강 Decorator가 어떤 기능인지 이해하고 위와 같이 정리하였으니, 내가 원하는 형태로 데코레이터를 설정하기 위해서는 아직도 애매모호한 것이 많은 듯 하다..

현업에서 어떠한 형태로 많이 쓰이는 지를 알아보고 싶다.





참고
https://legitcode267.tistory.com/13
https://dojang.io/mod/page/view.php?id=2427

profile
으악

0개의 댓글