TIL 34. python 매개변수의 위치

rahula·2021년 6월 9일
0

python

목록 보기
7/10
post-thumbnail

위코드에서 파이썬 매개변수에 대한 3가지 질문을 받고 생각한 점들을 기록합니다.

문제 1. default value parameter의 위치

함수를 정의 할때 default value parameternon-default value parameter 앞에 정의 하면 안 되는 이유는?

문제가 뭐야?

def func(first = 1, second):
    print(first)
    print(second)

func(2)

위 코드에선 다음과 같은 에러가 난다.

# SyntaxError: non-default argument follows default argument

그러나 파이썬에서는 문법적인 오류라고 할 뿐, 자세한 이유는 설명해주지 않는다. non-default argument가 default argument 뒤에 오지 않게만 해주라고만 한다.

보통 같으면 대충 그렇구나 하고 넘어갈 에러지만 질문을 받은 김에 깊이 생각을 해보려고 한다.

그 이유가 뭘까?

처음에 떠올랐던 생각은, 그냥 "나름의 원칙이 필요하기 때문이 아닐까?" 였다.
그러나 생각을 한 번 더 해보니까, 생각보다 깊은 뜻이 있었다!

default value parameter의 의의

default value parameter을 쓰는 의의를 생각해보자.

default value parameter을 쓰는 이유는 뭘까?

가장 큰 이유는 '자주 쓰일 값에 대해 반복을 줄이기 위해서'라고 생각한다.

def greeting(param):
    print(param)

greeting("안녕하세요")
greeting("안녕하세요")
greeting("안녕하세요")
greeting("잘 부탁드려요")
greeting("좋은 아침이예요")

우리가 매일 하는 인사를 함수라고 생각하면, 대부분의 argument는 "안녕하세요"이다. 다른 인삿말이 굳이 필요한가 싶을 정도로 자주 쓰는 말이다.

그런데 그렇다고 해서 인자값을 받지 않고 평생 모든 인삿말을 "안녕하세요"라고 한다면, 상황에 따라 대화에 변화를 줄 수 없을 것이다.

그래서 쓰는 게 default value parameter이다. 별 생각이 없다면 "안녕하세요"를 default value로 하되, 평소와 달리 변화를 주고 싶다면 argument을 넣어주면 된다.

def greeting(param = "안녕하세요"):
    print(param)

greeting() # 안녕하세요
greeting() # 안녕하세요
greeting("잘 부탁드려요") # 잘 부탁드려요
greeting("좋은 아침이예요") # 좋은 아침이예요

그래서?

default value parameter을 일반 parameter 앞에 놓는 순간, default value parameter을 쓰는 의의가 없어진다고 볼 수 있다.

처음 봤던 코드로 돌아가보자.

def func(first = 1, second):
    print(first)
    print(second)

func(1, 3)
func(1, 20)

이 코드는 설령 에러를 내뱉지 않더라도, 좋지 않은 코드이다.

애초에 반복을 줄이려고 default value parameter을 쓰는데, default value parameter을 앞순서에 놓게 되면 매번 인자값을 넣어줘야 하기 때문이다.

문제 2. 위치 인수와 가변 인수

문제가 뭐야?

def func_param_with_var_args(name, *args, age):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)

func_param_with_var_args("정우성", "01012341234", "seoul", 20)

위 코드에선 다음과 같은 에러가 난다.

# TypeError: func_param_with_var_args() missing 1 required keyword-only argument: 'age'

*args의 의의

*args는 정해진 인수 외의 모든 argument를 하나의 튜플로 만드는 역할을 하는 키워드이다.

그래서 여러 parameter의 사이에 *args를 놓게 되면 *args는 그 뒤에 오는 모든 argument들을 포함하려고 한다.

그 결과로 *args뒤에 오는 parameter은 몇 개가 되든 의미가 없어진다.

def func(*args, 뒤는, 의미없음, ...):

그래서?

해결법은 간단하다. *args의 뒤에 다른 parameter가 오지 않게 해주면 된다.

def func_param_with_var_args(name, age, *args):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)

func_param_with_var_args("정우성", 20, "01012341234", "seoul")

문제 3. 위치 인수와 키워드 인수

문제가 뭐야?

def mixed_params(name="아이유", *args, age, **kwargs, address):
    print("name=",end=""), print(name)
    print("args=",end=""), print(args)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

mixed_params(20, "정우성", "01012341234", "male" ,mobile="01012341234", address="seoul")

위 코드에는 일단 문법의 문제가 있다.

위에서 말한 인수의 위치문제가 있으므로(지정 parameter과 일반 paratmeter의 순서, *args와 다른 parameter간의 순서), 다음과 같이 바꾼다.

def mixed_params(age,  address, name="아이유", *args, **kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

mixed_params(20,  "01012341234", "정우성", "male" , mobile="01012341234", address="seoul")

그래도 위의 코드는 에러가 생긴다.

TypeError: mixed_params() got multiple values for argument 'address'

한 인자값 'address'에 여러개의 값을 전달받았다고 한다.
맞는 말이다!

keyword parameter도 parameter이다

keyword parameter에 쓰이는 이름도 결국 parameter간에 구분이 되어야 한다.

그래서?

따라서 위의 코드에서는 둘 중 하나를 포기하거나, 이름을 바꿔야 한다.
나라면 이름을 바꾸겠다.

def mixed_params(age, address, name="아이유", *args, **kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

mixed_params(20,  "01012341234", "정우성", "male" , mobile="01012341234", location ="seoul")

내 생각

배운대로만 코드를 쓰다보면, 그것이 왜 생겨났고 왜 필요한지를 잊게 된다. 그리고 더 좋은 방법을 찾을 기회가 없어지는 것 같다.

앞으로 파이썬을 공부하면서 다른 문법과 표현에 대해서도 한 번씩 생각해봐야겠다.

profile
백엔드 지망 대학생

0개의 댓글