betterway23키워드 인자

김승환·2021년 7월 11일

코딩의 기술

목록 보기
14/36
# 함수를 호출할 때 위치에 따라 인자를 넘길 수 있다.
def remainder(number, divisor):
    return number % divisor

assert remainder(20, 7) == 6
#키워드와 위치 인자를 필요에 따라 섞어 쓸 수도 있다.
remainder(20, 7)
remainder(20, divisor=7)
remainder(number=20, divisor=7)
remainder(divisor=7, number=20)
# 위치 기반 인자를 지정하려면 키워드 인자보다 앞에 지정해야한다.
remainder(number=20, 7)

File "", line 2
remainder(number=20, 7)
^
SyntaxError: positional argument follows keyword argument

# 각 인자는 한번만 지정
remainder(20, number=7)

TypeError Traceback (most recent call last)
in
1 # 각 인자는 한번만 지정
----> 2 remainder(20, number=7)

TypeError: remainder() got multiple values for argument 'number'

# 딕셔너리의 내용물을 사용해 remainder와같은 함수를 호출하고 싶다면 **연산자를 사용할 수 있다.
# 각 대응하여 들어간다.
my_kwargs = {
    'number': 20,
    'divisor': 7,
}

assert remainder(**my_kwargs) == 6
# 연산자를 위치 인자나 키워드 인자와 섞어서 함수를 호출 할 수 있다.
# 다만 중복 인자는 없어야 한다.
my_kwargs = {
    'divisor': 7,
}

assert remainder(number=20, **my_kwargs) == 6
#** 연산자는 여러번 사용할 수 있다.
#다만 딕셔너리에 겹치는 키가 없어야한다.

#
my_kwargs = {
    'number': 20,
}

other_kwargs = {
    'divisor': 7,
}

assert remainder(**my_kwargs, **other_kwargs) == 6

아무 키워드 인자나 받는 함수를 만들고 싶다면 모든 키워드 인자에 dict에 모아주는 **kwargs라는 파라미터를 사용한다.

  • 함수 본문에는 이 dict를 사용해 필요한 처리를 할 수 있다.
#
def print_parameters(**kwargs):
    for key, value in kwargs.items():
        print(f'{key} = {value}')

print_parameters(alpha=1.5, beta=9, 감마=4)

alpha = 1.5
beta = 9
감마 = 4

키워드 인자가 제공하는 3가지 장점

  • 첫 번째 키워드 인자를 사용하면 처음 보는 사람들에게 함수 호출의 의미를 명확히 알려줄 수 있다.
  • 두 번째 키워드 인자의 경우 함수 정의에서 디폴트 값을 지정할 수 있다.
    - 따라서 필요할 때는 원하는 함수 인자를 설정할 수 있는 기능제공하지만, 그렇지 않은 대부분의 경우에는 디폴트 동작을 그냥 받아들여도 된다. 이로인해 코드 중복과 잡음이 줄어든다.
  • 세 번째 어떤 함수를 사용하던 기존 호출자에게는 하위 호환성을 제공하면서 함수 파라미터를 확장할 수 있다.
    - 이로인해 기존 코드를 별도로 마이그레이션하지 않아도 기능을 추가할 수 있다.. 새로운 버그 생길 여지가 줄어든다.
# 예시
#  어떤 탱크에 흘러 들어가는 유테의 시간당 유입량을 계산하고 싶다고 하자.
# 탱크에 저울이 달려 있어서 어느 두 시점 사이의 무게 차이를 사용해 시간당 유입량을 계산할 수 있다.
def flow_rate(weight_diff, time_diff):
    return weight_diff / time_diff

weight_diff = 0.5
time_diff = 3
flow = flow_rate(weight_diff, time_diff)
print(f'{flow:.3} kg/s')

0.167 kg/s

#추가로 한 시간이나 하루 단위 유입량을 추정하고 싶다.
# 배율 추가하면 이렇다.

#
def flow_rate(weight_diff, time_diff, period):
    return (weight_diff / time_diff) * period

weight_diff = 0.5
time_diff = 3
flow = flow_rate(weight_diff, time_diff, 5)#5를 추가하여 5를 곱해줌
print(f'{flow:.3} kg/s')

0.833 kg/s

flow_per_second = flow_rate(weight_diff, time_diff, 1)
print(f'{flow_per_second:.3} kg/s')

0.167 kg/s

#잡음을 없애기 위해 디폴트 값으로 1을 설정하면 
#앞으로는 선택적인 과제가 된다.
def flow_rate(weight_diff, time_diff, period=1):
    return (weight_diff / time_diff) * period

#period를 설정안해도 작동, 해도 작동
flow_per_second = flow_rate(weight_diff, time_diff)
flow_per_hour = flow_rate(weight_diff, time_diff, period=3600)
print(f'{flow_per_second:.3} kg/s')
print(f'{flow_per_hour:.3} kg/s')

0.167 kg/s
6e+02 kg/s

위 방법은 간단한 디폴트일 경우 잘 작동한다. 하지만 복잡하면 코드가 복잡해진다.

#세번째 이점 예시
# 킬로그램이 아닌 무게 단위를 사용해 시간당 유입량을 계산
#새로운 파라미터 생성

#
def flow_rate(weight_diff, time_diff,
              period=1, units_per_kg=1):
    return ((weight_diff * units_per_kg) / time_diff) * period

pounds_per_hour = flow_rate(weight_diff, time_diff,
                            period=3600, units_per_kg=2.2)
print(pounds_per_hour)

1320.0

period나 units_per_kg 같은 선택적인 키워드 인자를 여전히 위치 인자로 지정할 수 있는 문제가 있다.

pounds_per_hour = flow_rate(weight_diff, time_diff, 3600, 2.2)
print(pounds_per_hour)

1320.0

  • 선택적인 인자를 지정하는 최선의 방법은 항상 키워드 인자를 사용하고 위치 인자를 절대 사용하지 않는 것이다.
  • 함수를 작성한 사람으로서 여러분은 누구든 함수를 호출할 때는 잠재적 오류를 최소화 하기 위해 더 명시적인 키워드 인자 스타일 코드를 사용하라고 요구할 수 있다.
profile
인공지능 파이팅!

0개의 댓글