본문 바로가기
  • 紹睿: 자유롭고 더불어 사는 가치있는 삶
Data/python·알고리즘

[python 기초] python의 함수에 대하여

by 징여 2018. 6. 28.
반응형

Python 함수: Functional Language 특징을 가지고 있음


추상화의 한 단계

1. 함수의 작성 def method1()

def square(x):
    return x*x

print(square(5)) # 25

 


Parameter: abc(x, y)

정의 시: Formal parameter

호출 시: Actual parameter

1. Loop 변수의 문제

local scope(자신이 지정된 function 또는 block)만 을 이용하는 변수

함수 내에서는 기본적으로 별도의 copy본을 만들어 사용 (두 x는 다른 아이들임)

def inc(x):
    return x+1

x = 20
print(inc(x)) # 21
print(x) # 20

2. return 값을 굳이 주지 않아도 됨

def change(n):
    n[0] = 'Me'
    
names = ['you', 'her', 'him', 'our']
change(names)

print(names) #['Me', 'her', 'him', 'our']
 

3. positional parameter, Keyword parameter, default parameter

1) positional parameter

받는 parameter의 위치가 중요하다.

def hello1(greeting, name):
    print("%s, %s" % (greeting, name))
        
hello1("Hi", "jiyoung")
# Hi, jiyoung

def hello2(greeting, name):
    print("%s, %s" % (name, greeting))

hello2("Hi", "jiyoung")
# jiyoung, Hi

2) Keyword parameter 

하지만, keyword를 정확하게 안다면, 순서와 상관없이 올바른 parameter값을 받을 수 있다.

hello1(name='jiyoung', greeting='goodbye')
#goodbye, jiyoung
 

3) default parameter

defualt 값을 미리 지정하여, 아무것도 입력하지 않아도 정의된 default값으로 나오게 할수도 있다.

def hello3(greeting='Hello', name='jiyoung'):
    print("%s, %s" % (greeting, name))

hello3() # Hello, jiyoung
hello3("nice to meet you", "jiyoung") # nice to meet you, jiyoung

4. parameter의 갯수 변동

*params 여러개의 keyword parameter를 수집할 수 있다.

def print_params(*params):
    print(params)
    
print_params(10) # (10,)
print_params(1,2,3,4,1,7) # (1, 2, 3, 4, 1, 7)

keyword parameter, default... 섞어서 쓸 수 있다.

def print_params(title, *params):
    print(title)
    print(params)
    
print_params(10) # 10
                 # ()
print_params(1,2,3,4,1,7) # 1
                          # (2, 3, 4, 1, 7)

**는 dictionary의 key, value 형식으로 받는다.

def print_params(x, y, z=3, *position_par, **keyword_par):
    print('x: %d, y: %d, z: %d' %(x, y, z))
    print(position_par)
    print(keyword_par)

print_params(1, 10, 45, 'MONDAY', 'TODAY', name='jiyoung', email='jiyoung@mail.com')

# x: 1, y: 10, z: 45
# ('MONDAY', 'TODAY')
# {'name': 'jiyoung', 'email': 'jiyoung@mail.com'}
 

dictionary를 쓸때, dictionary를 통째로 넘겨줄 경우!

 **를 쓰던 안쓰던 같은 결과 값을 출력하는 것을 볼수 있음!

def with_stars(**keywords):
    print(keywords['name'], 'is', keywords['age'], 'years old.')
    
def without_stars(keywords):
    print(keywords['name'], 'is', keywords['age'], 'years old.')
    
a = {'name': 'jiyoung', 'age': 20}

with_stars(**a) # jiyoung is 20 years old.
without_stars(a) # jiyoung is 20 years old.

 

예제

def story(**kwds):
    return print('Once upon a time, there was a '\
        '%(job)s called %(name)s' % kwds)
    
story(job='king', name='Arthur')
# Once upon a time, there was a king called Arthur

params = {'job': 'king', 'name': 'Arthur'}
story(**params)
# Once upon a time, there was a king called Arthur

del params['job']
print(params) # {'name': 'Arthur'}
# story(**params) # KeyError: 'job'
def power(x, y, *others):
    if others:
        print('Received redundant parameters: ', others)
    return pow(x, y)

print(power(2, 4)) # 16

params = (5,)*2 
print(params) # (5, 5)
print(power(*params)) # 3125

print(power(3, 3, 'Hello'))
# Received redundant parameters:  ('Hello',)
# 27​
def interval(start, stop=None, step=1):
    'Imitates range() for step >0 '
    if stop is None:
        start, stop=0, start
    result = []
    i = start
    while i <stop:
        result.append(i)
        i+= step
    return result

print(interval(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(interval(1, 5)) # [1, 2, 3, 4]
print(interval(3, 7)) # [3, 4, 5, 6]

print(power(*interval(3, 7))) 
# Received redundant parameters:  (5, 6)
# 81
 
5. scoping의 문제

Namespace란?

변수 등의 이름이 존재 하는 곳

일종의 invisible dictionary = scope

 

- local -> global -> built-in

-local: 함수 내에서만

-nonlocal: closest enclosing scope의 변수

- global

- Rebinding global variable

making them refer to some new value

변수를 함수 내에서 정의하는 순간 자동으로 local 변수가 된다.

def foo(x, y):
    global a
    x, y = y, x
    b = 33
    c = 100
    print(a, b, x, y)
    
a, b, x, y = 1, 2, 3, 4
foo(17, 4) # 1 33 4 17

b는 함수 안에 있는 33이 찍혀 나오게 된다.

- Nested scope 

function 안의 function: outer 함수가 inner 함수를 반환 - not called

: returned function still has access to the scope where it was defined, it carries its environment(and the associated local variables) with it.

반환된 함수는 정의된 범위에 대해 접근 가능하다!

def foo(x, y):
    global a
    x, y = y, x
    b = 33
    c = 100
    print(a, b, x, y)
    
# inner function
def multiplier(factor):
    def multiplyByFactor(number): #closure
        return number*factor
    return multiplyByFactor

double = multiplier(2) # multiplyByFactor가 저장됨
print(double(5)) # number=5가 되어 결과값은 10

triple = multiplier(3)
print(triple(4)) # 12

print(multiplier(5)(6)) # 30
 

- 재귀함수

def factorial(n):
    if n==1:
        return 1
    else:
        return n*factorial(n-1)

print(factorial(10)) # 3628800
print(factorial(5)) # 120

- Lambda / in line /anonynous 함수

t2 = {'FtoK': lambda deg_f:273+(deg_f-32)*5/9, 
      'CtoK': lambda deg_c:273+(deg_c) }

print(t2)
# {'FtoK': <function <lambda> at 0x10350ef28>, 
# 'CtoK': <function <lambda> at 0x1035827b8>}

# 잠깐 필요할때, in line함수로 잠깐 이용할때.. 사용
print(t2['FtoK'](32)) # 273.0
print(t2['CtoK'](20)) # 293
 

- generator 함수: yield 

iteratior를 발생시킨다!

def four():
    x = 0
    while x<4:
        print('in generator, x = ', x)
        yield x
        x += 1
        
for i in four():
    print(i)
    
# in generator, x =  0
# 0
# in generator, x =  1
# 1
# in generator, x =  2
# 2
# in generator, x =  3
# 3

print(10 in four())
# in generator, x =  0
# in generator, x =  1
# in generator, x =  2
# in generator, x =  3
# False
 

- Decorators 함수 -> 

1) wrapping function(=decorator)

2) wapped function(후에 wrapping function의 argument로 이용/ @decorate)로 지정된다.

def decorate(func):
    print("in decorate function, decorating", func.__name__)
    def wrapped_func(*args):
        print("Executing", func.__name__)
        return func(*args)
    return wrapped_func

@decorate
def myfunction(param):
    print(param)
    
myfunction = decorate(myfunction)
myfunction("hello")
# in decorate function, decorating myfunction
# in decorate function, decorating wrapped_func
# Executing wrapped_func
# Executing myfunction
# hello​

 

반응형

댓글