#!/usr/bin/env python # coding: utf-8 # *** # *** # # 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)) # ### 1-2 함수 객체와 함수 호출 # - 함수의 이름 자체는 함수 객체의 레퍼런스(Reference)를 지니고 있다. # In[2]: def add(a, b): return a + b print(add) # In[3]: c = add(10, 30) print(c) # - 함수 이름에 저장된 레퍼런스를 다른 변수에 할당하여 그 변수를 이용한 함수 호출 가능 # In[4]: f = add print(f(4, 5)) # In[9]: print(f) print(f is add) # - 함수의 몸체에는 최소한 한개 이상의 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) # ### 1-3 함수 인수값 전달방법 # - 파이썬에서의 인수값 전달 방법 # - 기본적으로 값에 의한 호출(Call-by-Value) # - 하지만 변수에 저장된 값이 참조값(Reference)이므로 실제로는 참조에 의한 호출(Call-by-Reference)로 실행됨 # - 함수 인자에 변경불가능(Immutable) 객체인 숫자값을 전달 # - 함수 내에서 다른 숫자값으로 치환 --> 의미 없는 인자 전달 # In[7]: def f1(b): b = 100 a = 200 f1(a) print(a) # ![image](../images/function_arg_int.png) # - 함수 인자에 변경불가능(Immutable) 객체인 문자열을 전달 # - 함수 내에서 다른 문자열로 치환 --> 의미 없는 인자 전달 # In[8]: def f2(b): b = "abc" a = "def" f2(a) print(a) # ![image](../images/function_arg_str.png) # - 함수 인자에 변경불가능(Immutable) 객체인 튜플을 전달 # - 함수 내에서 다른 튜플로 치환 --> 의미 없는 인자 전달 # In[9]: def f3(b): b = (1,2,3) a = (4,5,6) f3(a) print(a) # ![image](../images/function_arg_tuple.png) # - 함수 인자에 변경가능한(Mutable)한 객체인 리스트 전달 및 내용 수정 # - 전형적인 함수 인자 전달법 및 활용법 # In[10]: def f4(b): b[1] = 10 a = [4,5,6] f4(a) print(a) # ![image](../images/function_arg_list.png) # - 함수 인자에 변경가능한(Mutable)한 객체인 사전 전달 및 내용 수정 # - 전형적인 함수 인자 전달법 및 활용법 # In[11]: def f5(b): b['a'] = 10 a = {"a":1, "b":2} f5(a) print(a) # ![image](../images/function_arg_dict.png) # ### 1-4 반환(return)문 # - 인수 없이 return 문을 사용하면 실제로는 None 객체가 전달된다. # - None 객체: 파이썬 내장 객체로서 아무 값도 없음을 나타내기 위한 객체 # In[12]: def nothing(): return print(nothing()) # - return문 없이 리턴하기 # In[13]: def print_menu(): print('1. Snack') print('2. Snake') print('3. Snick') print_menu() # - return문이 없는 함수라 해도, 실제로는 None 객체가 리턴됨 # In[14]: a = print_menu() print(a) # - 한 개의 값을 리턴할 때 # In[15]: def abs_function(x): if x < 0 : return -x return x print(abs_function(-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]) # 하나의 이름으로 튜플을 받아서 처리할 수 도있다. # - 새로운 리스트를 리턴하는 함수의 예 # - 문자열 리스트를 받아서 각 문자열의 길이 정보를 지닌 리스트를 리턴 # 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)) # In[18]: l = ['python', 'pyson', 'pythong', 'pydon'] print([len(s) for s in l]) # ### 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) # *** # ## 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) # - [주의] 함수 정의를 할 때 기본 값을 지닌 인수 뒤에 일반적인 인수가 올 수 없음 # In[82]: def incr(step=1, a): return a + step # - 함수 정의 시에 여러 개의 기본 인수 값 정의 가능 # In[22]: def incr(a, step=1, step2=10): return a + step + step2 print(incr(10)) # ### 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) # - 함수를 호출 할 때에 키워드 인수는 마지막에 놓여져야 한다. # In[24]: print(area(20, width=5)) # - [주의] 함수 호출시에 키워드 인수 뒤에 일반 인수 값이 올 수 없다. # In[26]: area(width=5, 20) # 기존: SyntaxError: non-keyword arg after keyword arg # - 기본 인수값 및 키워드 인수의 혼용 # In[27]: def incr(a, step=1, step2=10, step3=100): return a + step + step2 + step3 print(incr(10, 2, step2=100)) # - 함수 호출 시에 키워드 인수 뒤에 일반 인수 값이 오면 에러 # 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 # In[29]: def incr(a, step=1, step2=10, step3=100): return a + step + step2 + step3 print(incr(10, 2, step2=100, step3=200)) # ### 2-3 가변 인수 리스트 # - 함수 정의시에 일반적인 인수 선언 뒤에 *args 형식의 인수로 가변 인수를 선언할 수 있음 # - The special syntax *args in function definitions in python is used to pass a variable number of arguments to a function. # In[11]: def myFun(*args): print(type(args), args) print() for arg in args: print(arg) myFun('Hello', 'Welcome', 'to', 'GeeksforGeeks') # - 함수 호출시 넣어주는 인수 값들 중 일반 인수에 할당되는 값을 제외한 나머지 값들만을 지닌 튜플 객체가 할당된다. # In[12]: def varg(a, *args): print(a, args) varg(1) varg(2, 3) varg(2, 3, 4, 5, 6) # - C언어의 printf문과 유사한 형태의 printf 정의 방법 # In[13]: def printf(format, *args): print(format % args) printf("I've spent %d days and %d night to do this", 6, 5) # - The special syntax ****kwargs** in function definitions in python is used to pass a keyworded, variable-length argument list. # In[29]: def myFun(**kwargs): print(type(kwargs), kwargs) print() for key, value in kwargs.items(): print("{0}: {1}".format(key, value)) myFun(first ='Geeks', mid ='for', last='Geeks') # In[30]: def myFun(arg1, **kwargs): for key, value in kwargs.items(): print ("{0} - {1}: {2}".format(arg1, key, value)) myFun("Hi", first ='Geeks', mid ='for', last='Geeks') # ### 2-5 튜플 인수와 사전 인수로 함수 호출하기 # - 함수 호출에 사용될 인수값들이 튜플에 있다면 "*튜플변수"를 이용하여 함수 호출이 가능 # In[16]: def h(a, b, c): print(a, b, c) args = (1, 2, 3) h(*args) # - 함수 호출에 사용될 인수값들이 사전에 있다면 "**사전변수"를 이용하여 함수 호출이 가능 # In[23]: def h(a, b, c): print(a, b, c) dargs = {'aa':1, 'bb':2, 'cc':3} h(*dargs) dargs = {'a':1, 'b':2, 'c':3} h(**dargs) # In[32]: def myFun(arg1, arg2, arg3): print("arg1:", arg1) print("arg2:", arg2) print("arg3:", arg3) args = ("Geeks", "for", "Geeks") myFun(*args) kwargs = {"arg1" : "Geeks", "arg2" : "for", "arg3" : "Geeks"} myFun(**kwargs) # In[33]: def function(**arg): for i in arg: print (i, arg[i]) function(a=1, b=2, c=3, d=4) # - Asterisks in Python: what they are and how to use them # - https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/ # In[37]: a, *b = [1, 2, 3, 4] print(a) print(b) # In[40]: def func(a, *b): print(a, b) func(1, 2, 3, 4) # In[44]: numbers = [2, 1, 3, 4, 7] more_numbers = [*numbers, 11, 18] print(more_numbers) # In[47]: print(*more_numbers) # In[48]: fruits = ['lemon', 'pear', 'watermelon', 'tomato'] print(fruits[0], fruits[1], fruits[2], fruits[3]) print(*fruits) # In[49]: def transpose_list(list_of_lists): return [list(row) for row in zip(*list_of_lists)] t_l = transpose_list([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) print(t_l) # In[51]: date_info = {'year': "2020", 'month': "01", 'day': "01"} filename = "{year}-{month}-{day}.txt".format(**date_info) print(filename) # In[52]: fruits = ['lemon', 'pear', 'watermelon', 'tomato'] numbers = [2, 1, 3, 4, 7] print(*numbers, *fruits) # In[54]: date_info = {'year': "2020", 'month': "01", 'day': "01"} track_info = {'artist': "Beethoven", 'title': 'Symphony No 5'} filename = "{year}-{month}-{day}-{artist}-{title}.txt".format( **date_info, **track_info, ) print(filename) # In[57]: from random import randint def roll(*dice): print(type(dice), dice) return sum([randint(1, die) for die in dice]) print(roll(20)) print(roll(6, 6)) print(roll(6, 6, 6)) # In[67]: def tag(tag_name, **attributes): attribute_list = ["{0}='{1}'".format(name, value) for name, value in attributes.items()] return "<{0} ".format(tag_name) + ' '.join(attribute_list) + ">" print(tag('a', href="http://treyhunner.com")) print(tag('img', height=20, width=40, src="face.jpg")) #

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