TIL #27 : [Python] 함수(기본)

셀레스틴 허·2020년 12월 31일
0
post-thumbnail

매개변수와 인수


매개변수(parameter)와 인수(arguments)를 혼동하지 말자. 매개변수는 함수에 입력으로 전달된 값을 받는 변수를 의미하며, 인수는 함수를 호출할 때 전달하는 입력값이다.

def add(a, b):
	a + b
   
print(add(3, 4)) # 

add(a, b) 속 a,b는 매개변수이며, add(3, 4)는 인수다.

함수


총 4가지 유형의 함수가 있다.

1. 일반 함수

입력값과 결괏값이 둘 다 있는 함수를 일반 함수라고 부른다.

# 일반 함수
def add(a, b):
	result = a + b
    return result
    
# 사용하는 법
z = add(3, 4)
print(z) #7

add함수는 2개의 입력값을 받고 result라는 결괏값을 돌려준다.

결괏값 있는 함수의 사용법 :결괏값을 받을 변수 = 함수이름(입력인수1, 입력인수2, ...)

2. 입력값 없는 함수

# 입력값이 없는  함수
def world():
	return 'Hello World!'
    
# 사용하는 법
a = world()
print(a)

입력값을 비워놓아도 결괏값을 반환한다.

입력값 없는 함수의 사용법 : 결괏값을 받을 변수 = 함수이름()

3. 결괏값 없는 함수

# 결과값 없는 함수
def add(a, b):
	print('The sum of %d, %d is %d.' % (a, b, a+b))
    
# 사용하는 법
add(3, 4) # The sum of 3, 4 is 7.

결괏값 없는 함수의 사용법 : 함수이름(입력인수1, 입력인수2, ...)

** 결괏값은 오로지 return 명령어로만 받을 수 있으며 해당 결괏값은 None이다.

4. 입력값도 결괏값도 없는 함수

# 입력값도 결괏값도 없는  함수
def world():
	print('Hello World!')
    
# 사용하는 법
world() # Hello World!

결괏값이 없는 함수의 사용법 : 함수이름()

매개변수 지정 호출도 가능하다는 점!

def add(a, b):
	return a + b
result = add(a=3, b=4)
print(result) # 7

매개변수는 순서 상관없이 입력 가능하다 : a=3, b=4, b=4, a=3 둘 다 된다.

입력값이 몇개인지 모를 때?

(*매개변수)를 활용한다!

def add_all(*args):
	result = 0
    for i in args:
    	result += i
    return result

result_one = add_all(1, 2, 3, 4)
print(result_one) # 10

result_two = add_all(1, 2)
print(result_two) # 3

매개변수 앞에 *를 붙이면 입력값을 모두 모아 튜플로 만들어준다.

def add_mul(choice, *args): 
     if choice == "add": 
         result = 0 
         for i in args: 
             result = result + i 
     elif choice == "mul": 
         result = 1 
         for i in args: 
             result = result * i 
     return result 
result = add_mul('add', 1,2,3,4,5) # 15
result_two = add_mul('mul', 1,2,3,4,5) # 120

choiceadd, mul에따라 *args가 더해지거나 곱해진다.

키워드 파라미터

매개변수**kwargs는 딕셔너리가 되고 key=value 형태의 결괏값으로 딕셔너리에 저장된다.

# 키워드 파라미터 
def print_kwargs(**kwargs):
    print(kwargs)

# 활용
print_kwargs(a=1)
{'a': 1}
print_kwargs(name='foo', age=3)
{'age': 3, 'name': 'foo'}

키워드 인수 사용

인수의 순서와 용도를 기억하기 불편하면 키워드 인수를 사용해서 key=value 형식을 사용하면 된다.

>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

키워드 인수의 순서가 바뀌어도 (ex. age=30, address='서울시 용산구 이촌동', name='홍길동') 해당하는 값에 키워드가 들어간다.

🔹 print함수에 사용되는 sepend도 키워드 인수다.

키워드 인수와 딕셔너리 언패킹 사용

딕셔너리를 선언한 다음 **kwargs 값에 넣어도 정상적으로 함수가 출력된다.

>>> def personal_info(name, age, address):
    print('이름: ', name)
    print('나이: ', age)
    print('주소: ', address)

>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**x)
이름:  홍길동
나이:  30
주소:  서울시 용산구 이촌동

**x와 같이 딕셔너리를 언패킹하면 딕셔너리의 값들이 함수의 인수로 들어간다.

언패킹할 때 주의해야할 점은:
1. 함수의 매개이름과 딕셔너리의 키 이름이 같아야하고
2. 매개변수 개수와 딕셔너리 키 갯수가 같아야 한다.

*을 한개 사용하면 키값을 언패킹하게 되며, 값을 언패킹하고 싶으면 ** 두개, 즉 2번 언패킹해야 한다.

매개변수에 초깃값 미리 설정

def say_myself(name, old, man=True): 
    print("나의 이름은 %s 입니다." % name) 
    print("나이는 %d살입니다." % old) 
    if man: 
        print("남자입니다.")
    else: 
        print("여자입니다.")
        
say_myself("박응용", 27) 
'''
나의 이름은 박응용입니다.
나이는 27살입니다.
남자입니다.
'''

say_myself("박응선", 27, False)
'''
나의 이름은 박응선입니다.
나이는 27살입니다.
여자입니다.
'''

마지막 값을 입력 안해도 자동적으로 man의 값은 참으로 설정돼서 남자입니다.가 출력됐다. 반대로 거짓으로 바꾸고 싶다면 False로 거짓값을 대입한다. 그러면 여자입니다.가 출력된다.

** 중요한 점: 초깃값을 설정하고 싶은 매개변수는 항상 맨 뒤에 놓아야 한다 아니면 SyntaxError가 뜬다.

※ [함수] 예제는 모두 점프투파이썬, dojang.io에서 복사했습니다.

이제 직접 써보자


def make_args(*args):
    for arg in args:
        print(arg * 2)

make_args(5, 10, 50)
'''
10
20
100
'''

출력 성공!

def make_args(*args, **kwargs):
    for arg in args:
        print(arg * 2)
    for kwarg in kwargs:
      print(kwarg)

make_args(5, 10, 50, name='Eri', role='PM')
'''
10
20
100
name
role
'''

출력 실패.. key값만 출력되는 이유는... 바로 kwargs는 딕셔너리 형식이기 때문에 keyvalue 둘 다 출력하고 싶다면 kwargs.items()으로 설정해야하 한다.

def make_args(*args, **kwargs):
    for arg in args:
        print(arg * 2)
    for kwarg in kwargs.items():
      print(kwarg)

make_args(5, 10, 50, name='Eri', role='PM')
'''
10
20
100
('name', 'Eri')
('role', 'PM')
'''

이렇게 kwargs.items()으로 바꾸면 튜플로 출력된다.

키워드 인수로 딕셔너리 언패킹

다른 방법으로 딕셔너리 언패킹하기

a = {'name' : 'Eri', 'role' : 'PM', 'hobby' : 'reading'}

def make_kwargs(name, role, hobby):
  print('name', name)
  print('role', role)
  print('hobby', hobby)

make_kwargs(**a)

make_kwargs(**{'name' : 'Eri', 'role' : 'PM', 'hobby' : 'reading'})
'''
name Eri
role PM
hobby reading
name Eri
role PM
hobby reading
'''

디폴트값을 추가한 딕셔너리 언패킹:

a = {'name' : 'Eri', 'role' : 'PM', 'hobby' : 'reading'}

def make_default(name, role, hobby, submit=False):
  print('name', name)
  print('role', role)
  print('hobby', hobby)
  if submit == False:
    print('No form submitted.')
  else:
    print('Form submitted. Check Mail.')

make_default(**a, True)
'''
name Eri
role PM
hobby reading
Form submitted. Check Mail.
'''

에러 고치기


  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)

1차 시도(성공):

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("정우성", "01012341234", "seoul", 20)

출력:

name=정우성
args=('seoul', 20)
age=01012341234
  1. 위치 인수, default args, 가변 키워드 인수는 마지막에!

문제:

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

1차 시도(성공):

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
  1. args('01012341234', 'male')으로 만들어서 집어넣었다.
    문제:
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")

1차 시도(성공):

def mixed_params(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)

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

출력:

name=정우성
args=('01012341234', 'male')
age=20
kwargs={'mobile': '01012341234'}
address=seoul

Reference
https://community.dataquest.io/t/python-function-order-of-parsing-arguments/2846/8
https://plan2018.tistory.com/202
https://wikidocs.net/24#_4
https://dojang.io/mod/page/view.php?id=2347

profile
Software Developer / 고통은 필연, 괴로움은 선택

0개의 댓글