4.6.1. 함수의 종류

파이썬에는 내장함수, 외장함수, 사용자 정의함수 3가지 종류의 함수가 존재합니다.

1) 내장함수

파이썬 인터프리터에서 기본적으로 포함하고 있는 함수가 내장 함수(built-in function)입니다.

파이썬 내장 함수들은 외부 모듈과는 달리 import를 필요로 하지 않습니다. 내장 함수에는 다음과 같은 것들이 있습니다. 각각의 내장함수들은 docs.python.org 와 링크되어 상세 설명이 있습니다.

다음의 예제를 실습해 봅니다.

print("abs(-3)=",abs(-3))
 print("all([1, 2, 3])=",all([1, 2, 3]))
 print("all([1, 2, 3, 0])=",all([1, 2, 3, 0]))
 print("any([1, 2, 3, 0])=",any([1, 2, 3, 0]))
 print("any([0, ""])=",any([0, ""]))
 print("chr(97)=",chr(97))
 print("chr(48)=",chr(48))
 print("dir([1, 2, 3])=",dir([1, 2, 3]))
 print("divmod(7, 3)=",divmod(7, 3))
 print("hex(234)=",hex(234))
 print("id(3)=",id(3))
 print("int(3.4)=", int(3.4))
 print("len('python')=",len("python"))

2) 외장함수

외장 함수는 import 문을 사용하여 외부의 라이브러리에서 제공하는 함수입니다. 모든 라이브러리를 다 알 필요는 없지만 어떤 일을 할 때 어떤 라이브러리를 사용해야 한다는 정도는 알아야 합니다. 그러기 위해 어떤 라이브러리들이 존재하고 어떻게 사용되는지 알아야 할 필요가 있습니다. 자주 사용되고 꼭 알아 두면 좋은 라이브러리들 몇가지만 살펴보겠습니다. 파이썬 기본 라이브러리들은 파이썬 설치 시 자동으로 설치가 됩니다. 기본 라이브러리들은 다음과 같은 것들이 있습니다.

  • Sys: sys 모듈은 파이썬 인터프리터가 제공하는 변수들과 함수들을 직접 제어할 수 있게 해주는 모듈입니다.

  • Pickle: pickle은 객체의 형태를 그대로 유지하면서 파일에 저장하고 불러올 수 있게 하는 모듈입니다.

  • Os: OS 모듈은 환경 변수나 디렉터리, 파일 등의 OS 자원을 제어할 수 있게 해주는 모듈입니다.

  • Shutil: shutil은 파일을 복사해 주는 파이썬 모듈입니다.

  • Glob: 특정 디렉터리에 있는 파일 이름 모두를 알아야 할 때 사용하는 모듈이 바로 glob입니다. glob 모듈은 디렉터리 내의 파일들을 읽어서 리스트로 리턴합니다.

  • Tempfile: 파일을 임시로 만들어서 사용할 때 유용한 모듈이 바로 tempfile입니다.

  • Time: 시간과 관련된 time 모듈에는 유용한 함수가 굉장히 많습니다.

  • Calendar: calendar는 파이썬에서 달력을 볼 수 있게 해주는 모듈입니다.

  • Random: 난수(규칙이 없는 임의의 수)를 발생시키는 모듈입니다.

  • Webbrowser: webbrowser는 자신의 시스템에서 사용하는 기본 웹 브라우저가 자동으로 실행되게 하는 모듈입니다.

다음의 예제를 실습해 보겠습니다.

 import sys
 import pickle
 import os
 import shutil
 import glob
 import time
 import calendar
 import webbrowser

 print(sys.path)

 f = open("test.txt", 'wb')
 data = {1: 'python', 2: 'you need'}
 pickle.dump(data, f)
 f.close()

 f = open("test.txt", 'rb')
 data = pickle.load(f)
 print(data)

 print("os.environ",os.environ)

 shutil.copy("test.txt", "test_copy.txt")

 print(glob.glob("./*"))

 print("time=", time.time())
 print("ctime=",time.ctime())

 print("calendar 2019=",calendar.calendar(2019))
 webbrowser.open_new("http://google.com") 

3) 사용자 정의 함수

사용자 정의 함수(User defined function)는 def 문을 사용해서 우리가 별도로 정의해야 하는 함수입니다. def는 ‘정의하다’ 라는 뜻의 영어 단어 define에서 앞 글자를 딴 것입니다. 파이썬에서 함수는 def 키워드를 사용하여 정의되며, 다음과 같은 문법을 갖습니다. 여기서 입력 파라미터나 리턴 값은 구현하는 내용에 따라 있을 수도 있고, 없을 수도 있습니다.

def 함수이름(입력파라미터):     #파라메터가 여러 개인 경우 쉼표(,)로 구분합니다.
    문장1
    문장2
    [return 리턴값]

return문은 “return”과 같이 단독으로 쓰이면 아무 값을 호출자에게 전달하지 않으며, "return value"처럼 우측에 값이 있으면, 그 값을 호출한 부분으로 전달합니다. 함수에서 리턴되는 값이 하나 이상일 경우, 필요한 수만큼 return 키워드 다음에 콤마로 구분하여 적으면 됩니다. 예를 들어, return a,b,c 는 3개의 값을 리턴 합니다. 하지만, 기술적으로 좀 더 깊이 설명하면, 이는 (a,b,c) 세개의 값을 포함하는 Tuple 하나를 리턴하는 것으로 함수는 항상 하나의 리턴값을 전달하려고 볼 수 있습니다.

모든 함수 내의 코드 블록은 콜론 (:)으로 시작되고 들여 쓰기가 되어야 합니다.

 def uadd(x, y):
   return x + y

 def square(x,y):
     return x*x, y*y

 def foo(val1, val2, val3, calcSum=True):
     if calcSum:                         # Calculate the sum
         return val1 + val2 + val3
     else:                               # Calculate the average instead
         return (val1 + val2 + val3) / 3


 print(uadd(3,8))

 xsq, ysq = square(2,3)
 print(xsq)  # Prints 4
 print(ysq)  # Prints 9

 print(foo(1, 2, 3))
 print(foo(1, 2, 3, calcSum=False))

4) Pass by reference vs value

파이썬 언어의 모든 매개변수(인수)는 참조(레퍼런스)로 전달됩니다. 즉, 함수 내에서 매개 변수가 참조하는 것을 변경하면 변경 내용은 호출 함수에서 다시 반영됩니다.

# Function definition is here
def changeme( mylist ):
   "This changes a passed list into this function"
   mylist.append([1,2,3,4]);
   print "Values inside the function: ", mylist
   return
# Now you can call changeme function
mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

위 코드에서는 전달된 객체의 레퍼런스를 유지하고 같은 객체에 [1,2,3,4] 값을 추가합니다. 따라서 다음과 같은 결과가 나옵니다.

Values inside the function:  [10, 20, 30, [1, 2, 3, 4]]
Values outside the function:  [10, 20, 30, [1, 2, 3, 4]]

5) Lambda(Anonymous Functions), map, filter, reduce

파이썬에서 익명 함수(lambda)는 함수가 이름이 없다는 것을 의미합니다. 우리가 이미 알고 있는 def 함수는 일반 사용자 정의 함수를 만드는데 사용되며 lambda 키워드는 익명 함수를 만드는 데 사용됩니다. 다음과 같은 형식으로 사용합니다.

lambda arguments: expression

일반적인 함수는 객체를 만들고, 재사용을 위해 함수를 메모리에 할당합니다. 그러나 익명함수는 한번 쓰이고 다음줄로 넘어가면 메모리 영역에서 사라집니다.

lambda 함수는 여러 개의 파라메터를 가질 수 있지만 하나의 리턴값만 반환됩니다. 함수가 필요한 곳 어디에서나 람다 함수를 자유롭게 사용할 수 있습니다. 다음 예제에서 일반 def 정의 함수와 람다 함수의 차이점을 이해해 봅니다. 주어진 값의 큐브를 반환하는 프로그램입니다.

from functools import reduce

 def cube(y):
     return y * y * y;

 g = lambda x: x * x * x
 print(g(7))

 print(cube(5))

 # Python code to illustrate filter() with lambda()
 li = [5, 7, 22, 97, 54, 62, 77, 23, 73, 61]
 final_list = list(filter(lambda x: (x%2 != 0), li))
 print(final_list)

 # map() with lambda()  to get double of a list.
 li = [5, 7, 22, 97, 54, 62, 77, 23, 73, 61]
 final_list = list(map(lambda x: x*2 , li))
 print(final_list)

 # reduce() with lambda() to get sum of a list

 li = [5, 8, 10, 20, 50, 100]
 sum = reduce((lambda x, y: x + y), li)
 print(sum)

 product = reduce((lambda x, y: x * y), [1, 2, 3, 4])
 print(product) 

람다 함수는 filter (), map () 및 reduce ()와 같은 내장 함수와 함께 사용할 수 있습니다.

filter() 함수는 filter(함수, literable)와 같이 인수로 함수와 리스트를 가지고 있습니다. 이 함수는 리스트의 모든 요소를 필터링하는 방법을 제공합니다. 두번째 인수인 반복 가능한 자료형 요소들을 첫번째 인자 함수에 하나씩 입력하여 리턴값이 참인 것만 묶어서 돌려줍니다.

map() 함수는 인수로 함수와 리스트를 가지고 있습니다. Map 함수는 람다 함수와 함께 리스트 목록을 파라메터로 호출되며, 리스트 목록 각 항목에 대해 해당 함수가 반환한 모든 람다 수정 항목을 포함하는 새로운 목록이 반환됩니다.

reduce() 함수도 함수와 리스트를 가지고 있습니다. reduce() 함수는 람다 함수와 리스트로 호출되고 새로운 감소된 결과가 반환됩니다. Reduce는 목록에서 계산을 수행하고 결과를 반환하는데 정말 유용한 함수입니다. 예를 들어, 정수 목록의 제품을 계산할 경우 다음과 같은 코드가 됩니다. Reduce 를 사용하는 경우와 사용하지 않는 경우를 비교해 보면 이해가 더 빠를것 입니다.

Reduce를 사용하지 않는 경우

product = 1
list = [1, 2, 3, 4]
for num in list:
    product = product * num
# product = 24

Reduce를 사용한 경우

product = reduce((lambda x, y: x * y), [1, 2, 3, 4])
# Output: 24

sum = reduce((lambda x, y: x + y), li) 와 같은 코드에서 ((((5 + 8) +10) +20) +50) +100)과 같이 목록의 끝까지 계속 결과를 두개씩 더해 나가는 코드입니다.

Last updated