오늘은 챕터8 Functions에 대해서 배워보자. 우리는 이때까지 어떤 기능이 있으면 따로따로 구현을 하거나 파이썬에 내장된 Functions을 가지고 프로그램을 만들었다. 하지만 이번 장부터는 우리에게 필요한 기능을 가진 function을 생성함으로써 더욱 더 견고하고 좋은 코드를 짤 수 있게 된다. 그러면 본격적으로 function에 대해 알아보도록 하자.

 

  • Defining a Function

 function이란 무엇일까?? function은 어떠한 특수한 기능을 가진 블록을 말하는데 예를 들어서 두 변수의 합을 구하고 싶다고 하자. 그러려면 a+b = c 이런 식의 코드가 필요할 것이다. 이것을 미리 function으로 구현해서 여러 번 쓸 수도 있고 function의 명칭을 plus()로 만들어서 어떤 기능을 사용하는지 눈에 쉽게 알 수도 있으며 해당 부분에서 error가 나면 해당되는 function만 수정하면 되기 때문에 유지보수도 용이하다.

 이처럼 function을 사용하게 되면 내 코드가 조금 더 발전할 수 있고 가독성, 편의성, 유지 보수 등등 여러한 곳에서 이점이 생긴다. 자! 그러면 아래의 간단한 예제 코드를 살펴보고 function의 사용법을 알아보자.

 

def greet_user():		# 함수 정의 -> def 이름():
    print("Hello!")		# 함수 내용
    
greet_user()			# 함수 호출

결과
Hello!

 

 function의 시작은 def로 시작한다. keyword def는 파이썬에서 function을 정의한다는 의미로 시작되고 그 뒤에는 function의 이름, 매개변수(), 따음표(:)로 첫 줄이 마무리된다. 다른 if(), for() 등의 함수들과 마찬가지로 내용은 들여쓰기로 지정되있으며 내용으로는 자신이 원하는 기능을 추가하면 된다. function을 호출하는 방법은 해당 function의 이름을 호출하고 지정한 매개변수에 맞게 variable 혹은 value를 대입하여 호출해야 한다. 

 위의 예제는 몇 번을 실행하든 항상 같은 결과가 나올 것이다. 아래 예제를 실행해보고 실행할 때마다 들어가는 값에 따라 변하는 function의 사용법을 알아보자.

 

def greet_user(name):
    print("Hello! {0}".format(name))

greet_user('Jain')

결과
Hello! Jain

 

  • Passing Argument

 다음은 본격적으로 여러 개의 매개 변수를 활용하여 사용하는 function들에 대해서 알아보도록 하자. 매개 변수는 없을수도 있고 한개 혹은 한개 이상을 가질 수 있다. type에 따라서 여러 가지 유형으로 바뀔 수도 있으며 무궁무진한 활용 또한 가능하다. 아래 예제를 살펴보고 매개 변수를 활용한 function의 사용법에 대해 알아보자.

 

def describe_pet(animal_type, pet_name):			# 매개 변수를 2개 가지는 function
    print("I have a {0}\n"
          "My {0}'s name is {1}".format(animal_type, pet_name))
describe_pet('hamster', 'harry')				# 함수 호출(매개 변수 2개)

결과
I have a hamster
My hamster's name is harry

 

  • Keyword Agument

  하지만 여러 개의 매개 변수를 사용하다가 보면 순서가 뒤바뀌는 일들이 존재할 수 있다. 그러한 일들을 방지하기 위해 파이썬에서는 keyword argument가 존재한다. 순서에 상관없이 keyword에 맞게 value가 대입되는 것이다. 아래 예제를 살펴보고 keyword argument를 사용하는 function에 대해서 알아보자.

 

def describe_pet(animal_type, pet_name):
    print("I have a {0}\n"
          "My {0}'s name is {1}".format(animal_type, pet_name))
describe_pet(animal_type='hamster', pet_name='harry')		# 각 keyword에 맞게 value 대입

결과
I have a hamster
My hamster's name is harry

 

  • Default Values

 다음으로는 우리가 argument에 value 혹은 variable을 지정해야 function을 호출할 수 있다고 했지만 argument에 default value를 설정하면 굳이 지정하지 않아도 function을 호출하여 사용할 수 있다. 한마디로 value를 대입하지 않아도 default value를 대입하여 function을 사용한다는 것이다. 아래 예제를 살펴보고 default value를 사용하는 function에 대해서 사용법을 알아보자.
(주의사항 : default value는 두 개 중 한 개만 지정해도 되지만 지정한다면 항상 지정된 agument는 지정되지 않는 agument보다 뒤에 위치하여야 한다. / 그렇지 않으면 error)

 

def describe_pet(pet_name, animal_type='dog'):		# animal_type의 default value : 'dog'
    print("I have a {0}\n"
          "My {0}'s name is {1}".format(animal_type, pet_name))
describe_pet(pet_name='harry')

결과
I have a dog
My dog's name is harry

 

  • Return Values 

 앞서 agument에 관한 여러 가지 경우에 대해 알아봤으니 인제 우리가 알고 있는 return value에 대해 알아보자. 흔히 알고 있는 return에는 여러 가지 의미가 있지만 여기서는 function에서 어떤 기능을 수행하고 그에 맞게 value를 반환하는 기능의 return을 배워볼 것이다.
 우리가 function을 어떠한 기능을 수행하기 위해서 사용하기 때문에 기능을 수행하고 나서 그 value는 function 안에서만 지속되기 때문에 밖으로 꺼내올 방법이 필요하다. 그 때 필요한 기능이 return이다. return을 통해 기능을 수행하고 해결된 value를 밖의 variable에게 전달하여 function의 기능을 더욱 극대화시키는 것이다. 아래 예제를 살펴보고 return value를 사용하는 function의 사용법에 대해 알아보자.

 

def get_formatted_name(first_name, last_name):
    full_name = '{0} {1}'.format(first_name, last_name)
    return full_name.title()				# return value : full_name 값 반환
musician = get_formatted_name('jimi', 'hendrix')
print(musician)

결과
Jimi Hendrix

 

  • Using a Function with a while Loop

 그 다음은 우리가 앞서 배웠던 while문과 function을 조합한 코드를 알아보자. while문은 반복적인 기능을 수행할 때 사용할 수 있기 때문에 기능을 구현해 놓은 function과 함께 쓰면 꽤 좋은 코드가 완성된다. 사용 방법은 우리가 예상하는 것과 크게 다르지 않기 때문에 금방 익힐 수 있을 것이다. 아래 예제를 살펴보고 while문과 function을 같이 쓰는 방법에 대해 알아보자.

 

def formatted_name(first_name, last_name):		# 이름 합치기 함수 정의
    full_name = "{0} {1}".format(first_name, last_name)
    return full_name

while True:						# 무한 루프
    print("Please tell me your name"
          "\nex) Pack jisun\n")
    f_name, l_name = input("Your full name : ").split()
    full_name = formatted_name(f_name, l_name)
    print("Hello, {0}!!!".format(full_name))
    ch = input("\nGO and STOP?(Enter is stop) ")	# 아무거나 입력은 계속, 엔터는 종료
    if ch:						# ch == True
        print("---------------------------")
    else:						# ch == False
        break
        
결과
Please tell me your name
ex) Pack jisun

Your full name : edfs dfsdf
Hello, edfs dfsdf!!!

GO and STOP?(Enter is stop) ef
---------------------------
Please tell me your name
ex) Pack jisun

Your full name : df sfesf
Hello, df sfesf!!!

GO and STOP?(Enter is stop) 				# 엔터 입력하여 종료

 

  • Passing a List

 그 다음으로 list와 function을 같이 쓰는 경우에 대해 알아보자. 앞에서는 multiple agument를 사용할 때 여러 공간을 할당해서 받았지만 그것마저도 한 개로 정의하여 list로 받으면 더 많은 values를 한 번에 받을 수 있지 않겠는가?? 이처럼 agument를 list type으로 대입하여 여러 values를 한번에 받을 수 있다. 아래 예제를 살펴보고 그 방법에 대해 알아보자.

 

def greet_users(names):
    for name in names:				# for문을 통한 list 출력
        msg = "Hello, {0}".format(name.title())
        print(msg)
usernames = ['hannah', 'ty', 'margot']		# list type : usernames 생성
greet_users(usernames)				# list type 대입

결과
Hello, Hannah
Hello, Ty
Hello, Margot

 

 책에서는 원본 list를 수정하지 않고 싶은 방법에 대해서도 나오는데 우리가 앞서 배웠던 slicing을 사용하면 원본 list는 수정하지 않으면서 원본 list를 복사하여 사용할 수 있는 방법이 있다. 잠깐 slicing을 복습하자면 list에서 사용하는 방법으로 자신이 원하는 부분을 잘라 복사해서 사용하는 방법이었다. 그러면 전체 복사를 어떻게 하는가??(모르겠다면 돌아가서 찾아보고 오자!!) 바로 list[ : ] 이렇게 표현하면 전체 범위가 지정되므로 원본 list를 그대로 복사할 수 있다. 이 방법도 있으니 한 번 기억하고 넘어가기로 하자.

 

  • Passing an Arbitraty Number of Arguments

그 다음으로는 Argumets 개수가 정해지지 않는 경우에 대해서 알아보자. 앞서 배웠던 경우에는 한 개인 경우, 한 개 이상인 경우, list type(다른 type도 가능)인 경우에 대해 공부했다. 하지만 경우에 따라서 1개 혹은 1개 이상으로 그때그때마다 다르면 어떻게 할까?? 그 문제에 대해서 이번 장에서 배울 수 있다.
 바로 argument 앞에 *을 붙여 사용하는 방법이다. 이렇게 되면 values 개수가 변해도 변한만큼 argument로 사용할 수 있으며 type은 tuple type으로 들어가기 때문에 수정이 불가능하다는 단점도 있다. 아래 예제를 살펴보고 개수가 변하는 argument 경우에 대한 사용법을 알아보자.

 

def make_pizza(*toppings):
    print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

결과
('pepperoni',)					# tuple type인 소괄호가 보임
('mushrooms', 'green peppers', 'extra cheese')

 

str, int, tuple, list type들을 알아봤는데 아직 배우지 않은 type이 있다. 무엇일까?? 바로 dic type 쓰는 법을 아직 배우지 않았다. 그래서~ 여러 type을 같이 쓰는 법과 dic type을 argument로 가지는 방법에 대해 설명하고자 한다. dic type은 vaule가 한 개가 아닌 한 쌍을 가지는 type으로 key:value 이렇게 사용하는 type이다. 그렇기 때문에 우리가 이때까지 쓰던 형태로 쓰지 않고 dic type argument는 **을 붙여서 사용한다. 그러면 아래 예제를 살펴보고 여러 type, dic type을 argument로 쓰는 방법에 대해 알아보자.

 

def build_profile(first, last, **user_info):				# dic type : **user_info
"""항상 dic type(**) or 개수가 다른 type(*)은 항상 맨 뒤에 써야 한다"""
    user_info['first_name'] = first
    user_info['last_name'] = last
    return user_info
user_profile = build_profile('albert', 'einstein',
                             location='princeton',
                             field='physics')
print(user_profile)

결과
{'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}

 

  • Storing Your Function in Modules

  다음은 Modules를 만드는 방법에 대해서 알아보자. Module이란 각종 변수, 함수, 클래스를 담고 있는 .py 파일이다. 주로 특정 기능을 담고 있으며 우리가 input(), print() 등을 사용할 수 있는 이유도 파이썬에서 기본적으로 제공하고 있는 라이브러리에 입력 함수 모듈, 출력 함수 모듈 등이 포함되어 있기 때문이다. 여기서 용어에 대해서 한 번 정리하고 다시 설명하겠다.

  • 모듈(Modules) : 특정 기능을 .py 단위로 작성한 것

  • 패키지(Package) : 특정 기능을 가진 여러 모듈을 하나도 묶은 것

  • 라이브러리(Library) : 파이썬에서 기본적으로 설치된 모듈, 패키지, 내장 함수들을 묶은 것

 솔직히 우리가 모듈이나 패키지를 만들기에는 아직 공부하 많이 부족하다. 그리고 파이썬에는 생각보다(우리가 생각한 것 보다 훨씬 많이.....) 많은 모듈과 패키지들을 존재하기 때문에 그 중에서 우리가 필요한 것을 찾아쓰는 것이 더 효율적이라고 생각한다.
 하지만 그렇기 위해서도 간단하게 모듈과 패키지를 사용하는 방법에 대해서는 알아야 찾아서 쓸 수 있기 때문에 여기서는 모듈을 사용하는 방법에 대해서 알아보자. 아래 예제를 살펴보고 모듈을 포함하고 변수나 함수를 사용하는 방법에 대해 알아보자.(책과 다르게 math 모듈을 사용했다.)

 

import math				# module : math 포함
print(math.pi)				# math 모듈의 pi 변수 사용
print(math.factorial(5))		# math 모듈의 factorial 함수 사용

결과
3.141592653589793
120

 

 사용법은 간단하다. | import 모듈이름 | 과 같은 형식으로 포함시키고 | 모듈이름.변수?함수? | 과 같은 형식으로 포함된 기능들을 사용할 수 있다. 모듈이름은 재정의해서 사용할 수 있으며 모듈 전체 혹은 모듈의 일부 변수나 함수만 가져와서 사용하는 것도 가능하다. 아래 예제를 살펴보고 다른 사용법에 대해서도 알아보자.

 

import math as m		# math module을 m으로 재정의
print(m.pi)
print(m.factorial(5))

결과
3.141592653589793
120

from math import factorial as f	# math module에서 factorial function만 가저와서 f로 재정의
print(f(5))

결과
120

 

 이번 장은 꽤 많은 내용들을 배우게 되었다. 그만큼 function이 코딩에서는 빼먹을 수 없는 중요한 내용이며 꼭 사용법을 기억해둬야 한다는 것이다. 다만 모든 내용을 숙지하되 다 알고 있을 필요는 없고(전부 기억도 나지 않는다...) 챕터 마지막에 있는 Styling Function처럼 자신이 쓰기 편하고 괜찮다 싶은 스타일의 function을 완성하면 되기 때문에 크게 걱정할 필요는 없다. 사람마다 코딩하는 스타일이 모두 다르기 때문에 자신에게 맞는 코딩을 찾는 것이 첫번째이다.

 다음 장에서는 코딩의 꽃이라고 할 수 있는 Class에 대해서 공부한다. Class까지 배운다면 코딩을 하는 사람으로써 쫌 배운 사람이고 있어 보이는 코딩을 할 수 있게 된다. 그러면 다음 장에서 봐요~

'Python > No Starch Press_Python' 카테고리의 다른 글

Chapter8-2. Function++  (0) 2020.05.13
Chapter9. Classes  (0) 2020.05.08
Chapter7. USER INPUT AND WHILE LOOPS  (0) 2020.04.20
Chapter6. DICTIONARIES  (0) 2020.04.17
Chapter5. IF STATEMENTS  (0) 2020.04.10
블로그 이미지

Mr.HB

프로그래밍 이야기

,