15. 파이썬 함수




1 함수의 정의와 호출


  • 함수: 여러 개의 Statement들을 하나로 묶은 단위
  • 함수 사용의 장점
    • 반복적인 수행이 가능하다
    • 코드를 논리적으로 이해하는 데 도움을 준다
    • 코드의 일정 부분을 별도의 논리적 개념으로 독립화할 수 있음
      • 수학에서 복잡한 개념을 하나의 단순한 기호로 대치하는 것과 비슷

1-1 간단한 함수의 정의

  • 함수 정의시 사용하는 키워드: def
In [1]:
def add(a, b):
    return a+b

print(add(1, 2))
print()

def myabs(x):
    if x < 0 : 
        x = -x
    return x

print(abs(-4))
print(myabs(-4))
3

4
4

1-2 함수 객체와 함수 호출

  • 함수의 이름 자체는 함수 객체의 레퍼런스(Reference)를 지니고 있다.
In [2]:
def add(a, b):
    return a + b

print(add)
<function add at 0x10d9ad6e0>
In [3]:
c = add(10, 30)
print(c)
40
  • 함수 이름에 저장된 레퍼런스를 다른 변수에 할당하여 그 변수를 이용한 함수 호출 가능
In [4]:
f = add
print(f(4, 5))
9
In [9]:
print(f)

print(f is add)
<function add at 0x10b5ad758>
True
  • 함수의 몸체에는 최소한 한개 이상의 statement가 존재해야 함
    • 아무런 내용이 없는 몸체를 지닌 함수를 만들 때에는 pass 라는 키워드를 몸체에 적어주어야 함
In [8]:
def simpleFunction():
    pass

simpleFunction()
  • 함수 사용 예
In [6]:
def addmember(members, newmember):
    if newmember not in members:   # 기존 멤버가 아니면
        members.append(newmember)  # 추가

members = ['hwang', 'lee', 'park', 'youn']  # 리스트에 초기 멤버 설정

addmember(members, 'jo')  # 새로운 멤버 추가

addmember(members, 'hwang') # (이미 존재하는) 새로운 멤버 추가

print(members)
['hwang', 'lee', 'park', 'youn', 'jo']

1-3 함수 인수값 전달방법

  • 파이썬에서의 인수값 전달 방법
    • 기본적으로 값에 의한 호출(Call-by-Value)
    • 하지만 변수에 저장된 값이 참조값(Reference)이므로 실제로는 참조에 의한 호출(Call-by-Reference)로 실행됨
  • 함수 인자에 변경불가능(Immutable) 객체인 숫자값을 전달
    • 함수 내에서 다른 숫자값으로 치환 --> 의미 없는 인자 전달
In [7]:
def f1(b):
    b = 100

a = 200
f1(a)
print(a)
200

image

  • 함수 인자에 변경불가능(Immutable) 객체인 문자열을 전달
    • 함수 내에서 다른 문자열로 치환 --> 의미 없는 인자 전달
In [8]:
def f2(b):
    b = "abc"

a = "def"
f2(a)
print(a)
def

image

  • 함수 인자에 변경불가능(Immutable) 객체인 튜플을 전달
    • 함수 내에서 다른 튜플로 치환 --> 의미 없는 인자 전달
In [9]:
def f3(b):
    b = (1,2,3)

a = (4,5,6)
f3(a)
print(a)
(4, 5, 6)

image

  • 함수 인자에 변경가능한(Mutable)한 객체인 리스트 전달 및 내용 수정
    • 전형적인 함수 인자 전달법 및 활용법
In [10]:
def f4(b):
    b[1] = 10

a = [4,5,6]
f4(a)
print(a)
[4, 10, 6]

image

  • 함수 인자에 변경가능한(Mutable)한 객체인 사전 전달 및 내용 수정
    • 전형적인 함수 인자 전달법 및 활용법
In [11]:
def f5(b):
    b['a'] = 10

a = {"a":1, "b":2}
f5(a)
print(a)
{'a': 10, 'b': 2}

image

1-4 반환(return)문

  • 인수 없이 return 문을 사용하면 실제로는 None 객체가 전달된다.
    • None 객체: 파이썬 내장 객체로서 아무 값도 없음을 나타내기 위한 객체
In [12]:
def nothing():
    return

print(nothing())
None
  • return문 없이 리턴하기
In [13]:
def print_menu():
    print('1. Snack')
    print('2. Snake')
    print('3. Snick')
    
print_menu()
1. Snack
2. Snake
3. Snick
  • return문이 없는 함수라 해도, 실제로는 None 객체가 리턴됨
In [14]:
a = print_menu()

print(a)
1. Snack
2. Snake
3. Snick
None
  • 한 개의 값을 리턴할 때
In [15]:
def abs_function(x):
    if x < 0 : return -x
    return x

print(abs_function(-10))
10
  • 두 개 이상의 값을 리턴할 때
In [16]:
def swap(x, y):
    return y, x   # 튜플로 리턴된다.

a = 10
b = 20
print(a, b)
print()

a, b = swap(a, b) # 결과적으로 a, b = b, a와 동일
print(a, b)
print()

a = 10
b = 20
x = swap(a, b)
print(x[0], x[1])  # 하나의 이름으로 튜플을 받아서 처리할 수 도있다.
10 20

20 10

20 10
  • 새로운 리스트를 리턴하는 함수의 예
    • 문자열 리스트를 받아서 각 문자열의 길이 정보를 지닌 리스트를 리턴
In [17]:
def length_list(l):
    res = []
    for el in l:
        res.append(len(el))
    return res

l = ['python', 'pyson', 'pythong', 'pydon']
print(length_list(l))
[6, 5, 7, 5]
In [18]:
l = ['python', 'pyson', 'pythong', 'pydon']
print([len(s) for s in l])
[6, 5, 7, 5]

1-5 함수 인자에 대한 동적인 자료형 결정

  • 파이썬에서는 모든 객체는 동적으로 (실행 시간에) 그 타입이 결정된다.
  • 그러므로, 함수 인자는 함수가 호출되는 순간 해당 인자에 전달되는 객체에 따라 그 타입이 결정된다.
    • 함수 몸체 내에서 사용되는 여러가지 연산자들은 함수 호출시에 결정된 객체 타입에 맞게 실행된다.
In [19]:
def add(a, b):
    return a + b

c = add(1, 3.4)
d = add('dynamic', 'typing')
e = add(['list'], ['and', 'list'])
print(c)
print(d)
print(e)
4.4
dynamictyping
['list', 'and', 'list']

2 함수 인수 처리


2-1 기본 인수 값

  • 기본 인수 값
    • 함수를 호출할 때 인수를 넘겨주지 않아도 인수가 기본적으로 가지는 값
In [20]:
def incr(a, step=1):
    return a + step

b = 1
b = incr(b)     # 1 증가
print(b)

b = incr(b, 10) # 10 증가
print(b)
2
12
  • [주의] 함수 정의를 할 때 기본 값을 지닌 인수 뒤에 일반적인 인수가 올 수 없음
In [82]:
def incr(step=1, a):
    return a + step
  File "<ipython-input-82-67693752f310>", line 1
    def incr(step=1, a):
SyntaxError: non-default argument follows default argument
  • 함수 정의 시에 여러 개의 기본 인수 값 정의 가능
In [22]:
def incr(a, step=1, step2=10):
    return a + step + step2

print(incr(10))
21

2-2 키워드 인수

  • 키워드 인수
    • 인수 값 전달 시에 인수 이름과 함께 값을 전달하는 방식을 일컫는다.
In [23]:
def area(height, width):
    return height * width

#순서가 아닌 이름으로 값이 전달
a = area(height='height string ', width=3)
print(a)

b = area(width=20, height=10)
print(b)
height string height string height string 
200
  • 함수를 호출 할 때에 키워드 인수는 마지막에 놓여져야 한다.
In [24]:
print(area(20, width=5))
100
  • [주의] 함수 호출시에 키워드 인수 뒤에 일반 인수 값이 올 수 없다.
In [26]:
area(width=5, 20)
# 기존: SyntaxError: non-keyword arg after keyword arg
  File "<ipython-input-26-020abdaed872>", line 1
    area(width=5, 20)
                 ^
SyntaxError: positional argument follows keyword argument
  • 기본 인수값 및 키워드 인수의 혼용
In [27]:
def incr(a, step=1, step2=10, step3=100):
    return a + step + step2 + step3

print(incr(10, 2, step2=100))
212
  • 함수 호출 시에 키워드 인수 뒤에 일반 인수 값이 오면 에러
In [28]:
def incr(a, step=1, step2=10, step3=100):
    return a + step + step2 + step3

print(incr(10, 2, step2=100, 200))
# 기존: SyntaxError: non-keyword arg after keyword arg
  File "<ipython-input-28-c7368e92bb98>", line 4
    print(incr(10, 2, step2=100, 200))
                                ^
SyntaxError: positional argument follows keyword argument
In [29]:
def incr(a, step=1, step2=10, step3=100):
    return a + step + step2 + step3

print(incr(10, 2, step2=100, step3=200))
312

2-3 가변 인수 리스트

  • 함수 정의시에 일반적인 인수 선언 뒤에 *var 형식의 인수로 가변 인수를 선언할 수 있음
    • var에는 함수 호출시 넣어주는 인수 값들 중 일반 인수에 할당되는 값을 제외한 나머지 값들을 지닌 튜플 객체가 할당된다.
In [30]:
def varg(a, *arg):
    print(a, arg)

varg(1)
varg(2,3)
varg(2,3,4,5,6)
1 ()
2 (3,)
2 (3, 4, 5, 6)
  • C언어의 printf문과 유사한 형태의 printf 정의 방법
In [31]:
def printf(format, *args):
    print(format % args)

printf("I've spent %d days and %d night to do this", 6, 5)
I've spent 6 days and 5 night to do this

2-5 튜플 인수와 사전 인수로 함수 호출하기

  • 함수 호출에 사용될 인수값들이 튜플에 있다면 "*튜플변수"를 이용하여 함수 호출이 가능
In [32]:
def h(a, b, c):
    print(a,b,c)
    
args = (1, 2, 3)
h(*args)
1 2 3
  • 함수 호출에 사용될 인수값들이 사전에 있다면 "**사전변수"를 이용하여 함수 호출이 가능
In [33]:
dargs = {'a':1, 'b':2, 'c':3}
h(**dargs)
1 2 3

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일