TIL# Python <Function parameter>

0
post-thumbnail

프로그래밍 언어에서 함수를 만드는 과정에 있어서 우리는 parameter라는 개념에 대해 알고 있다.

함수는 input parameter를 받아서 return 값을 output를 호출해준다는 것을 알고 있다.

우리는 이 부분에 대해서 parameter로 받는 argument에 대해 자세히 알아보도록 하자 .

What we are going to discuss today is the argument in python.

First of all, what is the meaning of Default value parameter and non-default value parameter and then, we discuss about Why can't non-default parameters follow default parameters.

Second, the meaning of the Positinoal arguments and variable length arugments.

Third, Let;s we discuss what we should be careful about when we use variable length keyword arguments and positional arguments. To see the example, when we use this incorrectly by looking at the errors.

Function Parameters


파라미터를 설명하기 앞서서 함수(function)란 사전적 의미로 "(사람 사물의)기능"이나 "기능하다"라고 표현되다. 사전적 의미에서 알 수 있듯이 프로그래머는 반복을 여러번 하는 것을 싫어하는 lazy한 사람이기 때문에 function이 이용된다고 할 수 있다.

함수(fucntion)는 일정한 작업을 수행하는 코드 블럭으로 함수를 사용하는 이유는 반복성을 줄이고 , 가독성을 위해서라고 말할 수 있다.

함수의 원리는 아래를 참조하자.

parameter의 개념은 여러 형태가 있는데 , 그 중에서 Keyword Arguments와 positional Argument에 대해 알아보자.

Keyword Arguments(Kwargs)

일반적으로 parameter는 순서가 중요하고 이 순서에 따라서 값을 전달해준다. 이 순서 대신에 parameter 이름으로 맞추어서 값을 전달해 줄 수 있는데 이 방식을 keyword argument 라고 한다. Kwargs는 keyword argument 줄임말로 키워드를 제공하며 keyword argument는 (keyword = 특정 값) 형태로 함수를 호출 할 수 있다. Keyword argument의 방식으로 parameter에 값을 전달 시 실제 parameter의 인자 순서를 고려하지 않아도 된다.

장점으로는 순서가 바뀌어도 괜찮은 것 외에도 가독성이 높아진다고 할 수 있다. keyword argument의 경우 실수로 값이 확률이 적으며 코드를 읽는 사람도 명확하게 어떤 인자를 넘기는지 알 수 있어서 가독성이 높다고 할 수 있다.

Mixing positional arguments and keword arguments

위치인자(positional arguments)와 keyword argument를 혼용하여 사용이 가능한데, 주의할 점은 kwargs의 경우 키워드를 받기 때문에 순서가 바뀌어도 괜찮지만 positinal arugment 같은 경우는 에러가 나기때문에 조심해야 한다.

![image-20201124080650702](/Users/byul/Library/Application Support/typora-user-images/image-20201124080650702.png)

위와 같이 에러가 나는 이유는 Positinal argument의 경우 이름에서 알 수 있듯이 순서가 매우 중요하기 때문이다.

함수 호출 시 순서에 의한 매개변수를 매칭 이후 그 다음으로 키워드 인수 매칭을 하기 때문에 위와 같은 에러가 나는 것이다.

저기와 반대로 greeting(my_name="정우성","아이유");의 경우도 동일한 에러가 발생한다.

**args(variable length arguments) 가변인수

가변인자는 줄임말 키워드로 astherisk 2개를 붙여 args라고 사용하며 복수의 일반 인자를 사용자에게 입력받아서 사용하고 싶을 때 사용한다.

임의의 여러 갯수의 postional Arguments 방식으로, 함수 내부에서는 튜플(Tuple)구조로 인식한다.

def name(*args):
    print(f"당신 그룹의 명단을 적어주세요. {args}")
    print(type(args))

name("홍길동")
name("파이썬", "이디비", "김코드","김자바")

결과는 ![image-20201124094401923](/Users/byul/Library/Application Support/typora-user-images/image-20201124094401923.png)

Default value parameter 과 non-default value parameter

default value parameter / non-default value parameter 개념부터 정리하고 조심해야 될 점에 대해서 알아보자.

Default value parameter / non-default value parameter

Default value parameter는 기본 매개 변수 값이라는 뜻으로 초기화가 값이 있는 매개변수를 뜻한다. 그와 반대로, Non-default value parameter는 초기화 값이 정의되지 않은 매개변수로 이해 할 수 있다. Default 값이 정해진 parameter는 값을 넘기지 않으면 기본적으로 설정한 default 값은 자동으로 반환되며 원리는 아래를 통해 이해해볼 수 있다.

다만 조심해야 할 점은 default 값이 정의된 parameter가 default 값이 정의 되지 않은 parameter 보다 먼저 위치해 있으면 안된다는 점입니다. 만일 default value parameter를 non-default value parameter 앞에 선언하면 syntax error가 납니다. 그렇다면, 우리는 함수를 정의 할때 default value parameter를 non-default value parameter 앞에 정의 하면 안된다고 알고 있지만 그 정확한 이유는 무엇일까?

파이썬은 함수의 매개 변수를 받는데 있어서 순서가 중요하고 그것을 따라야하기 때문이다.

def sum(a,b,c):
  total = a + b + c
  return total

sum(2,3,5);>> 10
sum(2,3);  >>  sum() missing 1 required positional argument: 'c'
  
그렇다면 default가 설정된 함수의 경우는?

def sum(a,b, c = 2):
  total = a + b + c
  return total
sum(2,3,5); >> 10
sum(2,3);  >> 7

default value parameter를 쓸 때 조심해야 할 점은 non-Default value parameter 뒤에 위치해야 한다는 점이다.

def sum(a, b= 2 , c =3):
  total = a + b + c
  return total

sum(2,3) >> 8

아래의 함수의 결과는 아래와 같은 에러가 발생한다. SyntaxError: non-default argument follows default argument

def sum(a=1,b,c):
  total = a + b + c
  return total

def sum(a=1, b, c):
  total = a + b + c
  return total

def sum(a, b=2, c):
  total = a + b + c
  return total

Argument 의 부적절 사용 예제

Error 1: 위치인수와 가변인수의 위치 사용 에러

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'

에러의 경우 age의 키워드 인자가 없다고 발생한다. 이유는 ?

이 함수의 경우 파라미터 선언을 non default value parameter, *args(variable length postional parameter),non-default value parameter로 각각 선언하였다.

args의 경우 가변의 길이를 받을텐데 name 은 정우성이 받고, args로 번호부터 나이까지 전부 받아버리니 age의 argument가 받을 자리가 없기 때문인 것이다.

아마도 이 함수의 의도는 결과 로 유추해봍건데, name = "정우성" , age = "20" , args = 01012341234 , seoul ( 각각 전화번호와 사는 지역) 이렇게 주고 싶었던 걸로 판단한다. 그렇다면 해결 방법은?

Solution 1 : 함수 호출시 age의 인자 값을 키워드로 형태로 준다.

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", age = 20)

결과는: name=정우성 args=('01012341234', 'seoul')age=20

Solution 2: positional argument의 인자 순서를 맞춰주기 위해 age와 20을 2번째로 앞 당겨준다.

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")

결과는: name=정우성 args=('01012341234', 'seoul')age=20로 동일하게 해결된다.

Error 2: 위치인수와 가변인수의 위치 사용 에러

def func_param_with_kwargs(name, age, **kwargs, address=0):
    print("name=",end=""), print(name)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

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

에러결과: SyntaxError: invalid syntax 파라미터 정의 자체를 잘 못 해준 에러이다. 그렇기 때문에 아예선언 에러가 발생하여 함수자체가 작동을 안하게 되는 것이다.

Non-default value parameter 와 value-parameter 에러 에서 살펴봤듯이 함수 파라미터 선언 시 순서가 잘못되었기에 발생한것이다.

Solution 1: default value keyword인 address를 **kwargs 앞으로 옮겨준다.

def func_param_with_kwargs(name, age, address = "0", **kwargs ):
    print("name=",end=""), print(name)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

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

결과: name=정우성 age=20 kwargs={'mobile': '01012341234'} address=seoul 로 의도한 대로 잘 나온다.

Positional argument 를 각각 순서대로 받고 , 뒤에 2개는 kwargs로 받기 때문에 에러 없이 잘 구동된다.

Solution 2: seoul argument를 positional argument 쪽으로 줘서 3번째 인자로 들어가게 처리 해준다.

def func_param_with_kwargs(name, age, address=0, **kwargs):
    print("name=",end=""), print(name)
    print("age=",end=""), print(age)
    print("kwargs=",end=""), print(kwargs)
    print("address=",end=""), print(address)

func_param_with_kwargs("정우성", "20", "seoul", mobile="01012341234")

결과: name=정우성 age=20 kwargs={'mobile': '01012341234'} address=seoul 로 의도한 대로 잘 나온다.

Positional argument 를 각각 순서대로 받고 , 뒤에 2개는 kwargs로 받기 때문에 에러 없이 잘 구동된다.

Error 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")

에러결과: SyntaxError: invalid syntax 파라미터 정의 자체를 잘 못 해준 에러이다. 그렇기 때문에 아예선언 에러가 발생하여 함수자체가 작동을 안하게 되는 것이다.

Solution: 정의 부분에서 파라미터순서에 맞게 age를 positional arguments를 맞춰주었고 가변인수와 위치인수를 조절하여 선언부분을 조절함.

def exam3(age, name="아이유", *args,address, **kwargs):
    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)

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

결과: name=정우성 args=('01012341234', 'male') age=20 kwargs={'mobile': '01012341234'} address=seoul 로 잘 출력되었다.

결론:

Function(함수) 사용시 parameter의 순서를 잘 기억하고 사용하자!

profile
문과생 개발자되다

0개의 댓글