4.7 함수

** 함수는 입력 매개변수(parameter)로 모든 타입을 여러 개 취할 수 있다. 그리거 반환 값으로 모든 타입을 여러 개 반환할 수 있다. **

def make_a_sound():
print('quack')
make_a_sound()

quack ** 함수로 전달한 값은 인자(argument)라고 부른다. **

def commentary(color):
if color == 'red':
return "It's a tomato"
elif color == 'green':
return "It's a green pepper"
elif color == 'bee purple':
return " I don't know what it is, but only bees can see it"
else:
return "I've never heard of the color" + color + "."
comment = commentary('blue')
print(comment)

I’ve never heard of the colorblue.

thing = None
if thing:
print("It's soem thing")
else:
print("It's no thing")

It’s no thing

None은 아무것도 없다는 것을 뜻하는 파이썬의 값이다. None이 부울로 평가 될 때는 False처럼 보이지만 부울값의 False와는 다르다.

if thing is None:
print("It's nothing")
else:
print("It's something")

It’s nothing 빠뜨린 빈 값을 구분 하기 위해 None을 사용했다. 정수(0), 부동소수점(0.0), 빈 문자열(‘’), 빈리스트([]), 빈튜플((,)), 빈 딕셔너리({}), 빈셋(set())은 모두 False이지만 None과 같지 않다

4.7.1 위치 인자

def menu(wine, entree, dessert):
return {'wine': wine, 'entree': entree, 'dessert': dessert}
menu('chardonnay', 'chicken', 'cake')

{‘dessert’: ‘cake’, ‘entree’: ‘chicken’, ‘wine’: ‘chardonnay’}

4.7.2 키워드 인자

** 위치 인자의 혼동을 피하기 위해 매개변수에 상응하는 이름을 인자에 지정 간으. 인자를 함수의 정의와 다른 순서로 지정 가능 **

menu(entree='beef', dessert='bagel', wine='bordeaux')

{‘dessert’: ‘bagel’, ‘entree’: ‘beef’, ‘wine’: ‘bordeaux’}

menu('frontenac', dessert='flan', entree='fish')

{‘dessert’: ‘flan’, ‘entree’: ‘fish’, ‘wine’: ‘frontenac’} * 위치 인자와 키워드 인자를 혼용하여 사용할때 함수를 호출 한다면 위치 인자가 먼저 와야 한다.*

4.7.3 기본 매개변수 값 지정하기

def menu(wine, entree, dessert='pudding'):
return {'wine': wine, 'entree': entree, 'dessert': dessert}
menu('chardonnay', 'chicken')

{‘dessert’: ‘pudding’, ‘entree’: ‘chicken’, ‘wine’: ‘chardonnay’}

menu('dunkelfelder', 'duck', 'doughnut')

{‘dessert’: ‘doughnut’, ‘entree’: ‘duck’, ‘wine’: ‘dunkelfelder’} 기본 인자값은 함수가 실행될 때 계산되지 않고 함수를 정의 할때 계산된다.

def buggy(arg, result=[]):
result.append(arg)
print(result)
buggy('a')

[‘a’]

buggy('b')

[‘a’, ‘b’]

def works(arg):
result = []
result.append(arg)
return result
works('a')

[‘a’]

works('b')

[‘b’]

def nonbuggy(arg, result=None):
if result is None:
result = []
result.append(arg)
print(result)
nonbuggy('a')

[‘a’]

nonbuggy('b')

[‘b’]

4.7.4 위치 인자 모으기: *

** 함수의 매개변수에 애스터리스크를 사용할 때, 애스터리스크는 매개변수에서 위치 인자 변수 들을 튜플로 묶는다 **

def print_args(*args):
print('Positional argument tuple:', args)
print_args()

Positional argument tuple: ()

print_args(3,2,1,'wait!','uh...')

Positional argument tuple: (3, 2, 1, ‘wait!’, ‘uh…’)

def print_more(required1, required2, *args):
print('Need this one:', required1)
print('Need this one too:', required2)
print('All the rest:', args)
print_more('cap', 'gloves', 'scarf', 'monocle', 'mustache wax')

Need this one: cap Need this one too: gloves All the rest: (‘scarf’, ‘monocle’, ‘mustache wax’) 위치 인자를 지정 할 때 맨 끝에 *args를 써서 나머지 인자를 모두 취하게 할 수있다.

4.7.5 키워드 인자 모으기

** 키워드 인자를 딕셔너리로 묶기 위해 두개의 애스터리스크를 사용할 수 있다. 인자의 이름은 키고, 값은 이 키에 대응하는 딕셔너리 값이다. **

def print_kwargs(**kwargs):
print('Keyword arguments:', kwargs)
print_kwargs(wine='merlot', entree='mutton', dessert='macaroon')

Keyword arguments: {‘wine’: ‘merlot’, ‘entree’: ‘mutton’, ‘dessert’: ‘macaroon’} ** 위치 매개변수와 *args, **kwargs를 섞어서 사용하려면 이들을 순서대로 배치해야 한다. **

4.7.6 docstring

def echo(anything):
'echo returns its input argument'
return anything
def print_if_true(thing, check):
"""
prints the first argument if a second argument is true.
The operation is:
1. Check whether the *second* argument is true.
2. If it is. print the *first* argument.
"""
if check:
print(thing)
help(echo)
help(print_if_true)

Help on function echo in module main:

echo(anything) echo returns its input argument

Help on function print_if_true in module main:

print_if_true(thing, check) prints the first argument if a second argument is true. The operation is:

  1. Check whether the second argument is true.
  2. If it is. print the first argument.
print(echo.__doc__)

echo returns its input argument

print(print_if_true.__doc__)

prints the first argument if a second argument is true. The operation is:

  1. Check whether the second argument is true.
  2. If it is. print the first argument.

4.7.7 일등 시민: 함수

** 함수를 변수에 ㅎ할당할 수 있고, 다른 함수에서 이를 인자로 쓸 수 있으며, 함수에서 이를 반환할 수 있다 **

def answer():
print(42)
answer()

42

def run_something(func):
func()
run_something(answer)

42

answer()를 전달하는 것이 아니라 answer를 전달했다. ()는 함수 호출의 의미이기 떄문이다. 괄호가 없으면 객체를 의미한다.

type(run_something)

function

def add_args(arg1, arg2):
print(arg1 + arg2)
type(add_args)

function

def run_something_with_args(func, *args):
func(args[0], args[1])
run_something_with_args(add_args, 5, 9)

14

def sum_args(*args):
return sum(args)
def run_with_positional_args(func, *args):
return func(*args)
run_with_positional_args(sum_args, 1,2,3,4)

10

4.7.8 내부 함수

** 함수안에 또 다른 함수를 정의 할 수 있다. **

def outer(a, b):
def inner(c, d):
return c + d
return inner(a, b)
outer(4, 7)

11

def knights(saying):
def inner(quote):
return "We are the knights who say: '%s'" % quote
return inner(saying)
knights('Ni!')

“We are the knights who say: ‘Ni!’”

4.7.9 클로져

** 내부 함수는 클로져 처럼 행동할 수 있다. 다른 함수에 의해 동적으로 생성. 바깥 함수로 부터 생성된 변수 값을 변경하고, 저장 할 수 있는 함수. **

def knights2(saying):
def inner2():
return "We are the knights who say: '%s'" % saying
return inner2
a = knights2('Duck')
b = knights2('Hasenpfeffer')
print(type(a))
print(type(b))

<class ‘function’> <class ‘function’>

print(a)
print(b)

<function knights2..inner2 at 0x7f98de3e9730> <function knights2..inner2 at 0x7f98de3e9ae8>

이들은 함수이지만 클로져 이기도 하다.

a()

“We are the knights who say: ‘Duck’”

b()

“We are the knights who say: ‘Hasenpfeffer’”

4.7.10 익명 함수: lambda()

def edit_story(words, func):
for word in words:
print(func(word))
stairs = ['thud', 'meow', 'thud', 'hiss']
def enliven(word):
return word.capitalize() + '!'
edit_story(stairs, enliven)

Thud! Meow! Thud! Hiss!

edit_story(stairs, lambda word: word.capitalize() + '!')

Thud! Meow! Thud! Hiss! 람다에서 하나의 word인자를 취했다. 람다의 콜론(:) 과 닫는 괄호 사이에 있는 것이 함수의 정의 부분이다.
틀히 콜백 함수를 정의 하는 그래픽 유저 인터페이스 (GUI) 에서 람다를 사용할 수 있다.

Comments