티스토리 뷰

728x90

프로그램을 보다 효율적으로 작성하기 위한 방법은 좋은 함수 작성에서 시작한다고 해도 과언이 아닐 정도로 함수를 잘 활용하면 프로그램의 가독성 향상과 효율화를 가져올 수 있습니다. 파이썬의 함수는 입력 파라미터 타입의 제한이 없고 리턴되는 값 또한 자유로워서 뛰어난 확장성을 갖습니다. 함수의 정의는 아래와 같은 형식을 취합니다.


def 함수명(파라미터 리스트):

코드블럭


함수명은 변수 작성에 따라 제한없이 작성할 수 있지만 추후 클래스명 등과 혼동되지 않도록 되도록 소문자로 시작 합니다. 

파라미터 리스트에 기술하는 변수들은 적용 범위가 해당 함수 내부로 한정되는 로컬 변수로 취급 합니다. 변수명=값의 형식으로 기술한 파라미터는 기본값을 가지는 파라미터로 함수를 호출하는 곳에서 해당 파라미터를 지정하지 않으면 에러가 아니라 기본값이 설정 됩니다. 파라미터가 없는 함수도 가능 합니다.

코드블럭은 들여쓰기가 적용되어야 하고 return 문장으로 값을 리턴할 수 있습니다. 값 없이 return하거나 return 문장을 기술하지 않을 수도 있습니다(Procedure function). 여러개의 값을 리턴할 때는 tuple 타입 형태로 return 하면 됩니다. 아래의 예제는 숫자를 입력받아 홀수면 True, 짝수면 False를 리턴하는 함수 입니다.

def myodd( num = 10 ):
    if num % 2 == 1:
        return True
    return False

함수의 사용은 함수 정의에 나열한 파라미터의 순서에 맞게 값을 전달하면 됩니다. 파라미터중에 기본값이 정의되어 있는 경우에는 인수를 생략할 수도 있습니다. 또한  파라미터 이름을 지정하는 방식으로 순서와 무관하게 인수를 전달할 수도 있다. 아래의 예제는 위에서 정의한 함수를 인수가 없는 경우, 자리에 맞게 전달한 경우, 이름을 지정한 경우를 각각 사용한 예제 입니다.

>>> test1 = myodd( num=10 )
>>> test2 = myodd( 11 )
>>> test3 = myodd()
>>> print test1, test2, test3
False True False

앞서 정의된 함수는 프로그램의 모든 영역에서 사용할 수 있는 글로벌(global)한 범위를 가지고 있으나 특정 클래스에 속한 함수는 해당 클래스에 대해서만 동작하고 사용 할 때도 클래스 오브젝트.함수명()의 형태로 사용 합니다. 이런 함수를 메소드 또는 메소드 함수라 하는데 스트링 오브젝트의 대문자/소문자화 메소드같은 내장 메소드를 예로 들수 있습니다.

>>> "abcde".upper()
ABCDE


■ 함수 사용팁
    • Docstring
      함수에 대한 설명을 코드 블럭에 작성해 두어 help(함수명) 등으로 함수 사용법을 손쉽게 확인할 수 있도록 제공하는 기능 입니다. 코드 블럭의 첫줄에 """  .....  """ 사이에 설명을 작성하면 됩니다다(여러줄도 가능). 함수 내에 Docstring이 없는 상태에서 help()를 수행하면 함수 정의의 헤더부만 표시 합니다.
      Docstring은 함수 뿐만아니라 모듈과 클래스에도 적용되어 모듈의 시작 부분에 문자열을 기술하면 모듈에 대한 문서화 자료로 클래스문 다음에 문자열을 기술하면 클래스 문서화 자료로 활용 됩니다. 아래는 Docstring을 작성한 예제입니다.
      >>> def myodd( num = 10 ):
          """ myodd - 짝수, 홀수 구분 함수

      홀수면 True 리턴, 짝수면 False 리턴
      인수로 숫자를 입력하세요"""
          if num % 2 == 1:
              return True
          return False

      >>> help(myodd)
      Help on function myodd in module __main__:

      myodd(num=10)
          myodd - 짝수, 홀수 구분 함수
         
          홀수면 True 리턴, 짝수면 False 리턴
          인수로 숫자를 입력하세요
      Docstring은 함수 속성인 __doc__를 사용하여 함수이름.__doc__로 참조 할 수 있습니다.
    • Stub와 점진적 개발
      함수를 사용할 때 얻는 중요한 장점 가운데 하나는 프로그램을 점진적으로 개발할 수 있게 된다는 점 입니다.(Incremental development) 프로그램의 특정 기능을 함수로 떼어 놓고 해당 함수는 빈 코드 블럭인 Stub  함수 형태로 전체적인 구조를 만든 다음에 점진적으로 함수의 내용을 채워가는 방식 입니다. 이런 방식을 통해서 테스트를 병행하는 개발이 가능해져서 위험도를 현저하게 줄일 수 있습니다.
    • 재귀적 호출
      함수의 코드 블럭 내부에서 스스로를 호출하는 방식으로 트리 운행이나 팩토리얼을 구하는 함수등에 아주 유용 합니다. 아래는 팩토리얼을 구하는 함수 예제 입니다.
      def factorial(n):
      if n == 0:
      return 1
      else:
      recurse = factorial(n-1)
      result = n * recurse
      return result
    • 함수 단위의 완성도가 프로그램의 완성도를 높입니다.
      파이썬에서는 C언어에서 처럼 파라미터 타입의 사전 검증이 없고 동적으로 타입을 적용하기 때문에 위의 팩토리얼 함수의 경우만 보더라도 숫자가 아닌 타입을 인수로 넘기면 프로그램은 예외를 발생시키고 중단되고 맙니다. 그래서, 완성도 높은 함수를 만들기 위해서는 함수 내부에서 전달된 인수의 타입 검증 및 변환이 꼭 필요하고, Unit test 적용등의 방법으로 오류 가능성을 사전에 최대한 차단하는 것이 필요 합니다.
    • 전역변수 사용하기
      함수 내부에서 사용하는 변수들은 그 적용 범위가 함수 내부인 로컬 변수로 함수 외부의 전역 변수를 사용하려면 대상 변수 이름을 "global 변수명"의 방식으로 함수 내부에 기술해 주어야 합니다.
      def func():
      global gbl_para
      a = gbl_para
    • 가변 인수
      인수의 개수가 가변적일 때 사용하는 것으로 함수 정의에서는 필수 인수들을 먼저 정의하고, 나머지를 "*변수명"의 형식으로 가변 인수를 정의 합니다. 단, 가변인수는 인수 목록 끝에 한개만 사용할 수 있습니다.
      가변 인수는 tuple 타입으로 내용이 전달 됩니다. 이름으로 인수를 전달할 때 정의 되어 있지 않은 인수 이름으로 전달되는 인수도 전달 받으려면 "**변수명"의 형식으로 지정하면 전달 내용을 사전 타입으로 넘겨 받을 수 있습니다. 단, "**변수"는 인수 목록의 맨 마지막에 와야 합니다.
      >>> def funcvar(a, *b, **c) :
      print a,b,c
      >>> funcvar(1,2,3,4,5,x=5,k=10,r=9)
      1 (2, 3, 4, 5) {'x': 5, 'k': 10, 'r': 9}
    • 함수를 인수로 사용하기
      파이썬에서는 이미 정의된 함수를 인수로 전달해서 C언어의 복잡한 함수 포인터를 손쉽게 사용할 수 있도록 기능을 제공하고 있습니다. 아래는 그 사용 예제 입니다.
      >>> def func1(n):
      return n+1
      >>> def func2(n):
      return n*2
      >>> def funcfunc(fn, n):
      return fn(n)
      >>> funcfunc(func1, 10)
      11
      >>> funcfunc(func2, 10)
      20
    • filter(함수, 배열)
      배열의 각 원소에 대하여 첫 인수로 전달된 함수의 결과가 True 인 것들만 묶은 새로운 배열을 리턴 합니다. 아래의 예는 첫 인수로 10보다 크면 True를 리턴하는 람다 함수를 전달하고 두번째는 정수 배열을 전달해서 조건에 맞는 항목들만 필터링한 결과입니다.
      >>> filter(lambda n: n > 10, (1,3,10,5,9,20,30))
      (20, 30)
    • reduce(함수, 배열, 초기값)
      배열의 각 원소에 대하여 첫 인수로 전달된 함수에 차례대로 적용한 결과를 리턴 합니다. 첫인수로 전달되는 함수는 인수를 두개 받는 함수입니다. 초기값은 생략 할 수 있습니다. 함수 적용 순서는 초기값이 있으면 초기값과 배열 첫원소가 함수로 전달되고 그 결과와 두번째 원소가 차례대로 전달되는 방식 입니다. 초기값이 없다면 첫번째와 두번째 원소가 맨처음에 함수로 전달 됩니다. 아래의 예는 두 인수를 더해서 리턴하는 람다 함수를 통해서 배열의 모든 원소를 더하는 과정입니다.
      >>> reduce(lambda a,b: a+b, (1,2,3,4,5,6,7))
      28
    • 람다 함수(Lambda)
      일반적인 함수 정의를 따르지 않고 별도의 이름도 없으며  return 문도 사용할 수 없지만 간단하게 함수 객체를 생성하여 사용하거나 인수로 주고 받을 수 있습니다. 정의 방법은 "lambda 인수리스트:표현식"의 형태로 인수 리스트는 생략할 수 있으며 표현식의 결과 값을 리턴하는 형태 입니다. 아래의 예는 두개의 인수를 받는 간단한 lambda함수와 위의 예제에 있는 funcfunc함수에 func1과 func2를 lambda 함수 형태 로 변환한 것입니다.
      >>> f1 = lambda para1,para2:para1**2 + para2 + 10
      >>> f1(3, 4)
      23

      >>> funcfunc(lambda n:n+1, 10)
      11
      >>> funcfunc(lambda n:n*2, 10)
      20






728x90
댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함