9. 함수 구조
함수가 정의되면 바로 함수를 객체로 구조화
함수
코드
함수
인자
함수
명
참조
def add(x,y) :
return x+y
add def add(x,y) :
return x+y
{‘x’ : None, ‘y’:None}내부주소
전환
10. 함수 내부 구조 조회
함수는 객체이므로 함수의 내부 구조를 속성으로 구
성한 function type과 code type 이 존재
function type 내부 속성
code type func_code
.
func_code 일 경우 : code type
함수명
.함수명
내부 속성
.
11. function type
함수 내부의 정보 조회
Attribute Description
__doc__ doc에 대한 정보 조회
__name__ 정의된 함수의 이름
func_code byte code 형태 code로 세분화
func_defaults arguments 내의 defult 조회
func_doc __doc__ 동일
func_globals 정의된 함수의 글로벌 영역
func_name __name__ 과 동일
12. function type : 예시
Function type에 대한 내부 예시
>>> def add(x,y) :
… return x+y
>>>add.func_code
<code object add at 10552E30, file
"<ipython-input-105-308d5e309ac4>",
line 1>
>>> add.func_name
'add'
13. Code type
실제 code에 대한 조회
Attribute Description
co_argcount number of arguments (not including * or ** args)
co_code string of raw compiled bytecode
co_consts tuple of constants used in the bytecod
co_filename name of file in which this code object was created
co_firstlineno number of first line in Python source code
co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
co_lnotab encoded mapping of line numbers to bytecode indices
co_name name with which this code object was defined
co_names tuple of names of local variables
co_nlocals number of local variables
co_stacksize virtual machine stack space required
co_varnames tuple of names of arguments and local variables
14. Code type : 예시
func_code가 code type을 생성하므로 그 내부의
정보를 조회
>>> def add(x,y) :
... return x+y
...
>>> #함수정의에 대한 내부 구조
>>> add.func_code.co_varnames
('x', 'y')
>>>
>>> # 함수코드는 bytecode로 나타남
>>> add.func_code.co_code
'|x00x00|x01x00x17S'
>>>
15. inspect 모듈 : 함수 구조 조회
Inspect 모듈을 이용한 함수 구조 조회
function Description
inspect.getdoc(object) object 내부의 doc을 출력
inspect.getsourcefile(object) object에 대한 소스파일(모듈이름0을 출력
inspect.getmodule(object) object에 대한 모듈 이름을 출력
inspect.getsource(object) object 내부의 소스를 출력
inspect.getsourcelines(object) object 내부의 소스를 라인별로 분리해서 출력
inspect.getargspec(func) 함수의 argument에 대한 정보 출력
inspect.getcallargs(func[, *args][, **kwds]) 함수 실행을 정의할 경우 실제 argument 연결 정보를 출력
16. inspect 모듈 : 조회 예시
Inspect 모듈을 이용해서 함수에 대한 정보 조회
def sum(x,y) :
return x+y
print(" function sum variable ")
print("tuple of names of arguments and local variables")
print(sum.func_code.co_varnames)
print("dict of names of arguments ")
print(inspect.getcallargs(sum,5,5))
print(" function sum code ")
print(sum.func_code.co_code)
print(inspect.getsource(sum))
print(inspect.getsourcefile(sum))
#처리결과
function sum variable
tuple of names of arguments and local variables
('x', 'y')
dict of names of arguments
{'y': 5, 'x': 5}
function sum code
|
def sum(x,y) :
return x+y
C:/myPython/ispect/inspect_sor_test.py
18. 함수 와 메소드 구별
파이썬은 메소드는 일반 함수와 차이점은 첫번째 인자가 context를 받
아야 한다. 함수를 정의 후 클래스의 정의에 메소드로 할당해서 사용가
능함
self : 인스턴스 메소드
cls: 클래스 메소드
class Foo() :
def __init__(self,name=None) :
self.name = name
bar = external_bar
def external_bar(self,lastname):
self.lastname = lastname
return self.name+ " " + self.lastname
내부 인스턴스 메소드로 사용
할 함수를 외부에 정의
함수로 인식
클래스에서 외부함수를 메소
드로 정의
인스턴스 메소드로 인식
20. 함수 – 메모리 생성 규칙
함수 호출 시 마다 Stack에 함수 영역을 구성하
고 실행됨
함수를 재귀호출할 경우 각 호출된 함수 별로
stack영역을 구성하고 처리
함수정의
함수호출 1
함수호출 2
함수호출 3
함수호출 4
Stack
제일 마지막 호출된 것을 처리가 끝
나면 그 전 호출한 함수를 처리load
21. 함수 – 메모리 생성 예시
정의된 함수에서 실제 함수를 실행시 함수 인스턴스
를 만들어서 실행됨
funcs = []
for i in range(4):
def f():
print I
# 함수 인스턴스를 추가
funcs.append(f)
print funcs
i =0
for f in funcs:
i += 1
print id(f), f()
[<function f at 0x02C1CF30>, <function f at
0x02C29EF0>, <function f at 0x02C29FB0>,
<function f at 0x02C37370>]
46255920 1
None
46309104 2
None
46309296 3
None
46363504 4
None
함수 생성된
개수만큼
생성됨
레퍼런스를 정수로
변환처리
23. 함수 변수 Scoping
함수에 실행하면 함수 내의 변수에 대한 검색을 처리.
검색 순은 Local > global > Built-in 순으로 호출
Global/nonlocal 키워드를 변수에 정의해서 직접 상위 영역을 직접 참조할 수 있다
globalBuilt-in
함수 Scope
함수 Namespace
local
내부함수
local
24. 함수-scope 관리 기준
함수내의 인자를 함수 이름공간으로 관리하므로
하나의 dictionary로 관리
함수 인자는 이름공간에 하나의 키/값 체계로 관
리
함수의 인자나 함수내의 로컬변수는 동일한 이름
공간에서 관리
locals() 함수로 함수 내의 이름공간을 확인할
수 있음
#
25. 지역변수와 전역변수
동적 데이터 타입 : 변수에 값이 할당될 경우 데이터 타입이 확정됨
변수는 이름공간 내에서 관리되면 변수는 동적으로 할당이 가능하다.
변수 검색 기준은 Local > Global > Built-in 영역 순으로 찾는다
Locals()와 globals() 함수를 이용해서 검색
>>> p = 100
>>>
>>> def add(x,y) :
… p =0
… print(locals())
>>> globals()
>>>
함수내 파라미터와 그
내부에 정의된 변수
함수 외부 변수는 전
역변수
26. locals()/globals()
함수의 이름공간 locals() 함수를 이용하여 확인하기
함수명.__globals__ 나 globals() 함수를 호출하여 글로
벌context 내의 이름공간을 확인
>>> def add(x,y) :
... p="local variable"
... print locals()
... return x+ y
...
>>>
>>> add(1,2)
{'y': 2, 'p': 'local variable', 'x': 1}
3
>>> add.__globals__
>>> globals()
함수별로 자신의 이름공간
을 관리(dict())
함수 외부 환경에 대한 변
수들을 관리하는 이름공간
27. 함수 내에서 global 변수 갱신
함수의 내부에서 정의없이 변수를 처리할 경우 오류
가 발생하므로 이를 확인하여 global 키워드를 이용
해서 처리되어야 함
def f(x,y) :
z = x+y+z
return z
f(5,5)
#z 변수가 로컬에 정의되어 있지 않아 오래 처리
UnboundLocalError: local variable 'z'
referenced before assignment
z = 10
def f(x,y) :
global z
z = x + y + z
return z
f(5,5)
#z 변수를 global로 정의해서 처리
20
28. Global 변수를 인자로 처리
함수의 인자를 함수 외부와 내부에서 동시에 활용
하려면 mutable(변경가능)한 객체로 전달처리
함수를 정의
변수에는 참조만 가지고 있으므로
전체를 카피해야 리스트 원소들이
변경됨
Mutable 인 리스트로 값을 전달하여 swap() 처리
Return 이 없어도 실제 값이 변경됨
#함수정의
def swap(a,b) :
x = a[:]
a[:] = b[:]
b[:] = x[:]
#함수 실행
a = [1]
b = [2]
print(swap(a,b))
print(a,b) //[2] ,[1]
34. 함수-Namespace : 인자관리
파이썬은 함수 인자와 함수 내의 로컬 변수를 동일
하게 관리.
함수 인자와 함수 내의 로컬변수명이 같은 경우 동
일한 것으로 처리
#함수 정의
def add(x, y) :
return x+y
#함수 실행
add(1,2) # 3 을 return
Add 함수 내의 로컬 영역에 인자를 관리
하는 사전이 생기고
{‘x’: None, ‘y’:None}
Add 함수 내의 로컬 영역에 인자에 매핑
{‘x’: 1, ‘y’: 2}
35. 함수 인자 – mutable/immutable
함수가 실행시 함수 실행을 위한 프레임을 하나를 가지고 실행
반복적으로 함수를 호출 시 인자의 값이 참조 객체일 경우는 지속적으
로 연결
인자에 참조형을 기본 인자로 사용하면 원하지 않는 결과가 생기므로
None으로 처리한 후 함수 내부에 참조형을 추가 정의해야 함
def f(a, l=[]) :
l.append(a)
return l
f(1)
f(2)
f(3)
함수
정의
함수
실행
{ ‘a’:1, ‘l’ :[1]}
함수 내부이름공간
{ ‘a’:2, ‘l’ :[1,2]}
{ ‘a’:2,
‘l’ :[1,2,3]}
f(1)
실행
f(2)
실행
f(3)
실행
실제 List
객체
참조객체를 함수
인자에 초기값으로
받을 경우 함수 호
출시에 연결된게
남아있는다.
def f(a, l=None) :
l = []
l.append(a)
return l
함수정의
인자에 변경가능한 값을 할당하지 않
음
36. 함수 인자 -인자 정의
함수 정의시 인자에 대한 변수 정의
# 함수정의
add 함수 내의 로컬 영역에 인자를 관리
하는 사전이 생기고
{‘x’: None , ‘y’:None}
#함수 실행
add 함수 내의 로컬 영역에 인자에 매핑
{‘x’: 1, ‘y’: 20}
#함수 정의
def add(x, y) :
return x+y
#함수 실행
add(1,20)
37. 함수 인자 -초기값 할당
함수 내의 인자를 별도의 이름공간에 관리하므로 고
정인자일 경우에도 이름에 값을 할당 가능
add 함수 내의 로컬 영역에 인자를 관리
하는 사전이 생기고
{‘x’: 10, ‘y’:None}
# 초기값을 무시하고 입력값을 사용
add 함수 내의 로컬 영역에 인자에 매핑
{‘x’: 1, ‘y’: 20}
#함수 정의
def add(y, x=10) :
return x+y
#함수 실행
add(20,1)
#함수 실행
add(y=20)
# 초기값과 입력값을 사용
add 함수 내의 로컬 영역에 인자에 매핑
{‘x’: 10, ‘y’: 20}
38. 함수-가변인자-값(*args)
함수 인자의 개수가 미정일 경우 사용
add 함수 내의 로컬 영역에 인자를 관리
하는 사전이 생기고
{‘arg’: None}
add 함수 내의 로컬 영역에 인자에 튜플
값으로 매핑
{‘arg’: (1,2) }
#함수 정의
def add(*arg) :
x =0
for y in arg :
x=x+y
return x
#함수 실행
add(1,2) # 3 을 return
39. 함수-가변인자-키/값(**args)
함수 인자의 개수가 미정이고 인자 변수를 정의할
경우
add 함수 내의 로컬 영역에 인자를 관리
하는 사전이 생기고
{‘arg’: None}
add 함수 내의 로컬 영역에 인자에 사전
으로 매핑
{‘arg’: { ‘x’:1,’y’:2} }
#함수 정의
def add(**arg) :
return arg[‘x’] + arg[‘y’]
#함수 실행
add(x=1,y=2) # 3 을
return
40. 함수-가변인자 통합
*args, **kargs를 통합하여 파라미터를 지정시 항
상 *args가 먼저 정의되고 **kargs나 뒤에 정의되
면 가변인자가 처리가 가능
#함수 내부 로컬변수 관리기준
{'sum': 0, 'kagrs': {'y': 1, 'x': 1},
'args': (1,)}
3
#함수 처리결과
3
#함수정의
def add_ar(*args, **kagrs) :
sum = 0
print(locals())
for i in args :
sum += i
for k,v in kagrs.items():
sum += v
return sum
#함수실행
print(add_ar(1,x=1,y=1))
41. 가변인자 확인하기
*args: 튜플타입으로 값만 가진 가변인자
**kargs : 키/값인 dict 타입의 가변인자
Inspect.getcallargs(함수명,*args,**kagrs) 로 함수 로
컬변수를 가져옴
import inspect
def func(*args,**kargs) :
#함수의 파라미터를 가져오기
print "locals() ", locals()
func_args = inspect.getcallargs(func,*args,**kargs)
print " func_args ", func_args
print " inspect get call args ", inspect.getcallargs(func,*args,**kargs)
func(1,2,3,x=1)
#가변인자에 대한 처리
locals() {'args': (1, 2, 3), 'kargs': {'x': 1}}
func_args {'args': (1, 2, 3), 'kargs': {'x': 1}}
inspect get call args {'args': (1, 2, 3),
'kargs': {'x': 1}}
42. 가변인자 처리하기
튜플과 맵처리는 sequence이므로 여러 개를 처리
해야 하므로 for문을 이용해서 처리
import inspect
def func(*args,**kargs) :
print "locals() ", locals()
func_args = inspect.getcallargs(func,*args,**kargs)
print " func_args ", func_args
print " inspect get call args ", inspect.getcallargs(func,*args,**kargs)
value = 0
for i in func_args['args'] :
value += i
items = func_args['kargs']
for k,v in items.items() :
value += v
return value
print func(1,2,3,x=1)
#가변인자에 대한 처리
locals() {'args': (1, 2, 3), 'kargs': {'x': 1}}
func_args {'args': (1, 2, 3), 'kargs': {'x': 1}}
inspect get call args {'args': (1, 2, 3),
'kargs': {'x': 1}}
#함수 처리결과
7
44. First Class Object(1)
일반적으로 First Class 의 조건을 다음과 같이 정의한다.
변수(variable)에 담을 수 있다
인자(parameter)로 전달할 수 있다
반환값(return value)으로 전달할 수 있다
1급 객체(first class object)
#함수를 변수에 할당
func = add
print func
# 함수를 함수의 인자로 전달
def addplus(func,x,y) :
return func(x,y)
print addplus(add,5,5)
# 함수를 함수의 리턴 결과로 전달
def addpass(func) :
return func
print addpass(add)(5,5)
# 결과
<function add at 0x041F7FB0>
10
10
45. First Class Object(2)
1급 함수(first class object)
런타임(runtime) 생성이 가능
익명(anonymous)으로 생성이 가능
# 함수를 함수의 리턴 결과로 전달
def addpass(func) :
return func
print addpass(add)(5,5)
#lambda 함수를 이용하여 익명으로
#사용하지만 함수가 객체이므로 처리가됨
print addpass(lambda x,y: x+y)(5,5)
46. 함수를 변수에 할당
함수도 객체이므로 변수에 할당이 가능
함수 객체
함수
인자
객체
함수명
(참조주소)
함수 정의
변수
변수에 할당
def swap(a,b) :
x = a[:]
a[:] = b[:]
b[:] = x[:]
func_var = swap # 함수를 변수에 할당
a = [1]
b = [2]
#print(swap(a,b))
print(func_var(a,b))
print(a,b)
변수는 참조를 저장하므로
함수의 참조도 변수에 저장되고 실행연
산자( () )를 이용하여 처리 가능
47. 함수를 파라미터로 전달
함수도 하나의 객체이며 데이터 타입이므로 파라
미터인자로 전달이 가능
외부에 함수를 정의하고 실행함수에 파라미터로
전달 후 실행함수 내부에서 실행
#파라미터 전달 함수 정의
def greet(name):
return "Hello " + name
#실행 함수 정의
def call_func(func):
other_name = “Dahl“
#파라미터 전달된 함수 실행
return func(other_name)
#함수 실행
print call_func(greet)
48. 함수 결과값을 함수로 전달
함수 결과값을 함수정의된 참조를 전달해서 외부
에서 전달받은 함수를 실행하여 처리
#실행함수 정의
def compose_greet_func():
#내부함수 정의
def get_message():
return "Hello there!“
#내부함수를 함수처리결과값으로 전달
return get_message
#함수실행 : 결과값은 함수의 참조 전달
#함수를 변수에 할당
greet = compose_greet_func()
#함수 실행: 변수에 할당된 내부함수가 실행됨
print greet()
51. 함수 반복 호출
함수도 호출 방법에 따라 다양한 구현 및 처리가 가
능
연속(재귀)호출
특정 시점 호출
부분 호출
함수를 인자값을 바꿔가면 처리가 완료 될
때까지 연속해서 호출하여 처리
함수를 구동시켜 필요한 시점에 호출하여
결과 처리(iteration, generation)
함수를 인자별로 분리하여 호출하면서 연
결해서 결과를 처리
52. 함수 재귀호출
함수 정의시 함수가 여러 번 호출될 것을 기준으로
로직을 작성해서 동일한 함수를 지속적으로 처리할
도록 호출
def factorial(n):
print("factorial has been called with n = " + str(n))
if n == 1:
return 1
else:
result = n * factorial(n-1)
print("intermediate result for ", n, " * factorial(" ,n-1, "): ",result)
return result
print(factorial(5))
자신의 함수를 계속
호출하면 stack에
새로운 함수 영역이
생겨서 처리한다
53. 함수 시점 호출 iteration
sequence 객체 등을 반복해서 사용할 수 있도
록 지원하는 객체처리 방식
>>> l= [1,2,3,4]
>>> iter(l)
<listiterator object at 0x06585090>
>>> li = iter(l)
>>> li.next()
1
>>> li.next()
2
>>> li.next()
3
>>> li.next()
4
>>> li.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
54. 함수 시점 호출 :Generation
함수를 호출해도 계속 저장 함수를 호출
처리가 종료되면 exception 발생
>>> v = (i for i in l)
>>> v
<generator object <genexpr> at 0x06521E90>
>>> v.next()
0
>>> v.next()
1
>>> v.next()
2
>>> v.next()
3
>>> v.next()
4
>>> v.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
>>> def returnfunc(x) :
... for i in x :
... yield i
...
>>> p = returnfunc([1,2,3])
>>> p
<generator object returnfunc at 0x06480918>
>>> p.next()
1
>>> p.next()
2
>>> p.next()
3
>>> p.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
Generation Expression Generation Function
55. 함수 시점호출 : Generation
함수 Return 대신 Yield 대체
함수를 호출(next())해도 계속 저장 함수를 호출
처리가 종료되면 exception 발생
>>> def list_c(l) :
... for i in l :
... yield i
...
>>> list_c(l)
<generator object list_c at 0x06521A08>
>>> v = list_c(l)
>>> v.next()
0
>>> v.next()
1
>>> v.next()
2
>>> v.next()
3
>>> v.next()
4
>>> v.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
56. 함수부분호출 : Curry
함수의 인자를 점진적으로 증가하면서 처리하는 법
으로 외부함수에서 내부함수로 처리를 위임해서 점
진적으로 실행하도록 처리하는 함수
def f(a):
print "function class object ",id(f)
def g(b, c, d, e):
print(a, b, c, d, e)
return g
print " function instance ", id(f(1))
f1 = f(1)
f1(2,3,4,5)
def f1(a):
def g1(b):
def h1(c, d, e):
print(a, b, c, d, e)
return h1
return g1
f1(1)(2)(3,4,5)
f1(1) 함수 실행하면
g1(2) 함수가 실행되고
h1 (3,4,5)가 최종적으
로 실행되여 결과는
(1,2,3,4,5) 출력
57. 함수부분 호출 : partial
파이썬에서는 partial 함수를 제공해서 함수를 분할
하여 처리함
from functools import partial
def f2(a, b, c, d):
print(a, b, c, d)
#<functools.partial object at 0x029CE210>
print partial(f2, 1, 2, 3)
g2 = partial(f2, 1, 2, 3)
g2(4)
Partial 함수 객체를 생
성하고 추가 인자를 받
으면 처리
(1,2,3,4) 출력
63. Lambda 함수 실행
Lambda는 변수에 할당 및 즉시 실행으로 처리
변수명 = Lambda 파라미터 : 표현식
변수명(파라미터)
(Lambda 파라미터 : 표현식)(파라미터)
변수
할당실행
즉시
실행
64. Lambda 함수 실행 : 변수
Lambda는 변수에 할당한 후 변수에 실행연산
자를 연결하여 실행
add = lambda x,y : x+y
add(5,5)
#결과값
10
65. Lambda 함수 실행 : 즉시 실행
Lambda 함수와 () 실행연산자를 사용해서 즉시 실
행
(lambda x,y : x+y )(5,5)
#결과값
10
66. Lambda함수 주의할 점
Lambda는 표현식에서 2개의 리턴 값이 생기면 에러
표현식에서 2개 이상 결과를 나타내려면 tuple 처리해
야 함
>>> x = lambda x,y : y,x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>
>>> x = lambda x,y : (y,x)
>>> x(1,2)
(2, 1)
69. 함수를 내부함수 정의
함수는 사용하기 전에 정의해서 사용.
함수 내에 다시 함수를 정의하여 사용
# 외부 함수 정의
def outer() :
# 내부 함수정의
def inner() :
pass
# 내부함수 실행 후 결과 전달
# 결과값은 아무것도 없음
return inner()
70. 함수를 내부함수 처리
함수 내부에 함수를 정의하고 함수 내부에서 실
행하여 처리
def greet(name):
#내부 함수 정의
def get_message():
return "Hello “
#내부함수 실행
result = get_message()+name
return result
#외부함수 실행
print greet("Dahl")
함수 내부에 기능이 필요한 경우 내부 함
수를 정의하여 호출하여 처리
71. 내외부 함수에 대한 변수 scope
외부함수에 정의된 자유변수를 내부함수에서 활용하
여 처리 가능
단, 내부함수에서 갱신할 경우 mutable 타입이 사용
해야 함
#자유변수에 대한 스코핑
def compose_greet_func(name):
#내부 함수 정의
# 외부 함수 자유변수 name을 사용
def get_message():
return "Hello there "+name+"!“
#내부함수를 함수 결과값으로 전달
return get_message
#함수실행
greet = compose_greet_func(“Dahl")
print greet()
73. 함수 – Closure : context
외부함수 내의 자유변수를 내부함수에서 사용하면 기존 외부함
수도 내부함수가 종료시까지 같이 지속된다.
함수 단위의 variable scope 위반이지만 현재 함수형 언어에서는
함수 내의 변수를 공유하여 처리할 수 있도록 구성하여 처리할
수 있도록 구성이 가능하다.
외부함수
내부함수
외부함수
이름공간
내부함수
이름공간
Closure context 구성
내부함수 변수 검색 순
서는 내부함수 이름공
간 -> 외부함수 이름
공간
74. 함수 – Closure : __closure__
파이썬은 클로저 환경에 대해서도 별도의 객체로 제공하며 이
환경에 대해서도 접근이 가능함
def generate_power_func(n):
out_v = 10.0
def nth_power(x):
return x**n + out_v
return nth_power
print clo.__closure__
print clo.__closure__[0]
print type(clo.__closure__[0])
print clo.__closure__[0].cell_contents
print type(clo.__closure__[1])
print clo.__closure__[1].cell_contents
(<cell at 0x02940ED0: int object at 0x01DAABC4>, <cell at
0x02B6FEF0: float object at 0x02766600>)
<cell at 0x02940ED0: int object at 0x01DAABC4>
<type 'cell'>
4
<cell at 0x02B6FEF0: float object at 0x02766600>
10.0
__closure__는 튜플로 구성되어
자유변수에 대해 객체로 구성됨
75. 함수 – Closure : 자유변수(1)
외부함수 내의 자유변수를 내부함수에서 사용하면 기존 외부함
수도 내부함수가 종료시까지 같이 지속된다.
def generate_power_func(n):
print "id(n): %X" % id(n)
print ' outer ', locals()
def nth_power(x):
print ' inner ', locals()
#return x**n
v = x**n
# n = v + n #UnboundLocalError: local variable 'n' referenced
#before assignment
return v
print "id(nth_power): %X" % id(nth_power)
return nth_power
clo = generate_power_func(4)
print clo(5)
자유변수가
immutable 일 경
우 내부함수에 생
기지만 변경할 수
없으므로 에러처
리
Locals()함수를 이
용하여 함수에서
관리하는 변수를
출력
outer {'n': 4}
inner {'x': 5, 'n': 4}
76. 함수 – Closure : 자유변수(2)
변수는 Mutable 값과 Immutable 값이 binding되면서 정의되므로
내부함수에서 외부함수의 변수(immutable)에 재할당 시
unboundlocalerror 발생시 해결 방안
내부함수에 키워드 nonlocal를 변수에 사용
외부함수에 mutable 값을 할당한 변수를 사용(리스트, 사전으로 정의)
외부함수
Context
내부함수
Context
Local Local
Int
Float
string
Immutable 객체
외부함수의 변수를 변경하려면 외부함수
context 에서 처리 되어야 함
함수의 인자 전달시 동일한 원칙이 발생
79. 함수 연속 실행
함수 chian은 함수를 결과값으로 받고 실행연산자
(parameter)를 연속하면 함수들을 계속 실행함
def chain(obj) :
return obj
def cc(obj):
print obj
chain(cc)('str')
함수1 실행 하고 함수
2실행
#결과값
str
81. Decorator 문법
반드시 미리 정의된 함수명을 사용해야 하고 전
달함수 이외의 함수파라미터가 있을 경우 함수
파라미터를 추가해야 함
@함수명[(함수파라미터)]
82. Decorator 사용 기법
함수 Chain : 함수를 결과 값 처리
고차함수
클로저
functools 모듈의 wraps함수 사용
83. Decorator : functools 사용이유
functools 모듈의 wraps함수 사용을 할 경우
__doc__/__name__이 삭제되지 않고 함수의 것
을 유지
84. Decorator 처리 흐름
Decorator 함수 내부에 내부함수를 정의해서 파라미터로 받은
함수를 wrapping하여 리턴 처리하고 최종으로 전달함수를 실행
함수Chain 처리(버블링)
함수 1
함수 2
함수 3
(전달함
수)
함수2(함수3)
함수 3
실행
함수1(함수2(함수3))
@f1 @f2
Decorator 순서
함수1(함수2(함수3))(전달변수)
함수호출 순서
85. Decorator 단순 예시
Decorator는 함수의 실행을 전달함수만 정의해
도 외부함수까지 같이 실행된 결과를 보여준다.
def func_return(func) :
return func
def x_print() :
print(" x print ")
x = func_return(x_print)
x()
def func_return(func) :
return func
@func_return
def r_print() :
print (" r print ")
r_print()
외부함수
전달함수
함수 실행
86. Decorator :단순 wrapping 예시
Decorator 되는 함수에 파라미터에 실행될 함수를 전달되고 내부함
수인 wrapping함수를 리턴
Wrapping 함수 내부에 전달함수를 실행하도록 정의
데코레이터와 전달함수 정의
전달함수를 실행하면 데코레이터 함수와 연계해서 실행 후 결과값
출력
def common_func(func) :
def wrap_func() :
return func()
return wrap_func
@common_func
def r_func() :
print " r func "
데코레이터 함수 정의 전달 함수 및 데코레이션 정의 함수 할당 및 실행
r_func()
#처리결과
r func
87. Decorator:전달함수(파라미터)
Decorator 할 함수를 정의하여 기존 함수 처리말고 추가 처리
할 부분을 정의
실제 실행할 함수 즉 전달함수를 정의
실행할 함수를 실행하면 decorator 함수까지 연계되어 처리
됨
def outer_f(func) :
def inner_f(*arg, **kargs) :
result = func(*arg, **kargs)
print(' result ', result)
return result
return inner_f
@outer_f
def add_1(x,y):
return x+y
데코레이터 함수 정의 전달 함수 및 데코레이션 정의 함수 할당 및 실행
#데코레이터 호출
x = add_1(5,5)
print(' decorator ', x)
#함수 처리 순서
v = outer_f(add)
v(5,5)
88. Function decorator : 파라미터
데코레이터 함수에서 사용할 파라미터 전달
내부함수에 전달함수를 파라미터로 전달(클로저 구성)
wrapping 함수 정의 및 내부함수 파라미터 전달
def tags(tag_name):
def tags_decorator(func):
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
#함수 실행
print get_text("Dahl")
89. Functools Module
functools.wraps(wrapped[, assigned][,
updated]) 을 이용하여 데코레이션 처리
from functools import wraps
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
return wrapper
@my_decorator
def example():
"""Docstring"""
print 'Called example function'
example()
1. Functool를 import
처리
2. @wraps(전달함수)
3. Wrapper로 함수에 파
라미터 전달
4. 데코레이션 정의
5. 전달함수 작성
6. 전달함수 실행
90. Functools Module: 파라미터
데코레이터 파라미터를 처리하기 위해 파라미터
처리하는 함수를 하나 더 처리
from functools import wraps
def my_decorator0(x) :
print x
def my_decorator1(f):
@wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
return f(*args, **kwds)
return wrapper
return my_decorator1
@my_decorator0('xxx')
def example1():
"""Docstring"""
print 'Called example function'
example1()
1. 데코레이터 파라미터
처리함수 정의
2. Functool를 import
처리
3. @wraps(전달함수)
4. Wrapper로 함수에 파
라미터 전달
5. 데코레이션 정의
6. 전달함수 작성
7. 전달함수 실행
91. 복수 Function decorator 순서
실행 func을 호출시 실행 순서는
decorate1(decorate2(decorat3(func)))로 자동
으로 연결하여 처리됨
#decorate1
def decorate1 :
pass
#decorate2
def decorate2 :
pass
#decorate3
def decorate3 :
pass
@decorate1
@decorate2
@decorate3
def func :
pass
92. 복수 Function decorator 예시
함수 호출 순서는 f1(f2(add))(5,5)로 자동으로
연결하여 처리됨
#decorator 함수 1
def f1(func) :
def wrap_1(*args) :
return func(*args)
print " f1 call"
return wrap_1
#decorator 함수2
def f2(func) :
def wrap_2(*args) :
return func(*args)
print "f2 call"
return wrap_2
#decorator 처리
@f1
@f2
def add(x,y) :
print " add call "
return x +y
print add(5,5)
#함수연결 호출
print f1(f2(add))(5,5)
#decorator처리 결과
f2 call
f1 call
add call
10
#함수 연결 처리결과
f2 call
f1 call
add call
10
Decorator 함수 정의 함수 실행
95. 클래스 생성 함수 정의
클래스와 메소드 함수를 정의
#클래스에 등록할 메소드 정의
def say_foo(self):
print('foo')
#클래스 생성 메소드 정의
def class_with_method(func):
class klass:
pass
# setattr(obj, name, value, /)
# setattr(x, 'y', v) is equivalent to ``x.y = v''
setattr(klass, func.__name__, func)
return klass
클래스내의 속성을 등록 :
Setattr(클래스명, 속성명, 속성값)
96. 클래스 생성 함수 실행
클래스 생성함수 파라미터에 메소드를 전달 한
후 실행
#클래스 생성
Foo = class_with_method(say_foo)
print('Foo dict ', Foo.__dict__)
#인스턴스 생성 및 메소드 호출
foo = Foo()
foo.say_foo()
#클래스 __dict__ 출력 결과
('Foo dict ', {'__module__': '__main__', 'say_foo':
<function say_foo at 0x107071B0>, '__doc__':
None})
foo
#Foo.say_foo() 호출 처리 결과
foo
100. 클래스 생성 함수 정의
클래스와 메소드 함수를 정의
# 생성자 및 세팅 메소드 추가
def __init__(self, x=None):
self._x = x
def set_x(self, value):
self.x = value
#type 함수를 이용하여 클래스 정의
SubClass = type('SubClass', (object,),
{ '__init__':__init__,'set_x': set_x})
Type(클래스명,상속(튜플),dict에
속성 추가)
101. 클래스 생성 함수 실행
인스턴스를 생성해서 속성 세팅 실행
print(SubClass.__dict__)
# 인스턴스 생성
obj = SubClass()
#속성세팅
obj.set_x(42)
print( obj.x ) # Prints 42
print (isinstance(obj, object) )
#클래스 __dict__ 출력 결과
{'set_x': <function set_x at 0x10577830>,
'__module__': '__main__', '__dict__': <attribute
'__dict__' of 'SubClass' objects>, '__weakref__':
<attribute '__weakref__' of 'SubClass'
objects>, '__doc__': None, '__init__': <function
__init__ at 0x10707030>}
#obj.x 호출 처리 결과
42
#isinstance() 함수 처리결과
True
103. 상속 클래스 정의
상속할 클래스 정의
# 상속될 클래스 정의
class BaseClass(object) :
def __init__(self,x) :
self.x = x
# 속성(메소드) 정의
def set_x(self, value):
self.x = value
104. 클래스 생성 실행
클래스 생성 및 인스턴스 생성 후 실행
SubClass1 = type('SubClass', (BaseClass,), { 'set_x':
set_x})
obj1 = SubClass1(5)
print(obj1.x)
obj1.set_x(50)
print(obj1.x)
#처리결과
#obj.x before
5
#obj.x after
50
110. help함수
함수, 클래스, 메소드 등에 대한 내부 정보를 확인할 때 사용
>>>help(vars)
vars(...)
vars([object]) -> dictionary
Without arguments, equivalent to
locals().
With an argument, equivalent to
object.__dict__.
112. Type 처리 함수
파라미터를 하나 받아 객체를 실행하면 타입전환 처
리함
>>> int
<type 'int'>
>>> float
<type 'float'>
>>> str
<type 'str'>
>>> list
<type 'list'>
>>> dict
<type 'dict'>
>>> tuple
<type 'tuple'>
>>> set
<type 'set'>
>>> complex
<type ‘complex’)
int()
float()
str()
list()
dict()
tuple()
set()
complex()
113. 타입처리 함수
함수 설명
bytearray() 갱신가능한 문자열 처리 타입
bytes() Str가 같은 처리
frozenset() 갱신불가한 set 처리
object() Object 타입을 생성하기
114. Type 함수
파이썬은 실제 리터럴 즉 값이 객체이므로 기본
객체의 구성을 이해해야
>>> type(1.1)
<class ‘float'>
>>>
>>> type(17)
<class 'int'>
값을 type() 함수를 이용해 데이터 타
입을 확인
reference
type
value
float
주소
1.1
reference
type
value
int
주소
17
데이터 관리 방안(예시)
117. Class Member
Class Object는 클래스 메소드, 정적메소드, 클래스 내부 변수 등을 관
리한다.
class Class_Member :
cls_var = 0
@classmethod
def cls_method(cls) :
cls.cls_var = 1
print("call cls_method ", cls.cls_var)
@staticmethod
def sta_method() :
cls_var = 100
print("call sta_method ", cls_var)
def ins_method(self) :
self.ins_var = 1
print('call ins method ', self.ins_var)
c = Class_Member()
c.ins_method()
print(c.__dict__)
클래스 변수
클래스 객체 메소드
클래스 정적 메소드
# 처리결과
('call cls_method ', 1)
('call sta_method ', 100)
#Class_Member 내부 관리 영역
{'sta_method': <staticmethod object at 0x0215A650>, '__module__': '__main__', 'ins_method': <function ins_method
at 0x029D2270>, 'cls_method': <classmethod object at 0x01D92070>, 'cls_var': 1, '__doc__': None}
인스턴스 메소드
118. Super() 함수(2.x)
Super(클래스, 서브클래스 또는 인스턴스)
Class변수를 호출하였지만 mro() 순성 따라 A.bar가
호출되어 처리됨
class A(object) :
bar = 100
def foo(self) :
pass
class B(object) :
bar = 0
class C(A,B) :
xyz = 'abc'
print " super function ", super(C,C())
print C.mro()
print super(C,C()).__self__
print super(C,C()).bar
print super(B,B()).__self__
print super(B,B()).__self__.bar
# 실행 결과
super function <super: <class 'C'>, <C object>>
[<class '__main__.C'>, <class '__main__.A'>, <class
'__main__.B'>, <type 'object'>]
<__main__.C object at 0x0F01BA10>
100 A.bar의 값
<__main__.B object at 0x0F01B6B0>
0 B.bar의 값
119. Super() 함수의 binding(2.x)
Super(클래스, 인스턴스).메소드()은 클래스.메소
드(인스턴스)로 연결되는 구조이므로 파라미터가
빠지면 binding이 되지 않는다.
print super(C) # 실행 결과
<super: <class 'C'>, NULL>
print super(C).foo
Foo는 인스턴스 함수이라서 binding 에러
# 실행 결과
AttributeError: 'super' object has no attribute 'foo'
120. Super() 을 이용한 접근(2.x)
Super(클래스, 인스턴스) 객체에 __get__ 메소드
가 구현되어 있어 재상속 후에 처리시 에러없이
상위 클래스를 접근 가능
class A(object) :
bar = 100
def foo(self) :
pass
class B(object) :
bar = 0
class C(A,B) :
xyz = 'abc‘
class D(C) :
sup = super(C)
print D().sup
print D().sup.foo
print super(C,D()).foo
print D().sup.bar
# 실행 결과
<super: <class 'C'>, <D object>>
<bound method D.foo of <__main__.D object at
0x0F01BF90>>
<bound method D.foo of <__main__.D object at
0x0F01BF90>>
100
D().sup 일때 상위 클래스 C와 하위 인스턴스 D()가 있어
매핑되어 처리 가능
D().sup.foo == Super(C,D()).foo로 바인딩한 것과 같
다
Super(C).__get__(D(), ‘foo’) 처럼 인식
121. Property 함수- 객체 직접 정의(1)
인스턴스 객체의 변수 접근을 메소드로 제약하기 위해서는
Property 객체로 인스턴스 객체의 변수를 Wrapping 해야 함
property(fget=None, fset=None, fdel=None, doc=None)
class P:
def __init__(self,x):
self.x = x
def getx(self) :
return self.x
def setx(self, x) :
self.x = x
def delx(self) :
del self.x
x = property(getx,setx,delx," property test ")
Getter, setter, deleter 메
소드를 정의
인스턴스 객체의 변수명과
동일하게 Property 객체 생
성(내부에 _x 생김)
124. all()/ any()
all(iterable) 함수는 iterable 내부에 연속적인
원소들을 모두 가지고 있을 경우 :True
Any(iterable) 함수는 iterabe 내부에 연속적인
원소가 없어도 true 처리
i=[1,2,3]
all(i) # True
any(i) # True
j=[[],[],[]]
all(j) # False
any(i) # True
125. Iterable 처리 함수 – 시점 호출
sequence 객체 등을 반복해서 사용할 수 있도
록 지원하는 객체처리 방식
>>> l= [1,2,3,4]
>>> iter(l)
<listiterator object at 0x06585090>
>>> li = iter(l)
>>> li.next()
1
>>> li.next()
2
>>> li.next()
3
>>> li.next()
4
>>> li.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
126. Iterable 처리 함수 – range
range(첫번째, 마지막번째, 간격) 함수는 범위에
대해 리스트 객체로 리턴
range(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(1,10) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
range(1,10,2) #[1, 3, 5, 7, 9]
131. 객체접근 함수
내장함수를 이용하여 객체의 속성에 대한 접근
object.x getattr()
object.x = value setattr()
del(object.x) delattr()
함수 구조
getattr(object, name[, default])
setattr(object, name, value)
delattr(object, name)
hasattr(object, name) # 객체내의 속성(변수나 메소드)
callable(object) # 메소드 및 함수 여부 점검
132. 객체접근 함수: 예시 1
객체의 속성을 접근하고변경
class A():
def __init__(self, name,age) :
self.name = name
self.age = age
a = A('dahl',50)
if hasattr(a,"name") :
print getattr(a,"name")
setattr(a,"name","Moon")
print getattr(a,"name")
else :
pass
if hasattr(a,"age") :
print getattr(a,"age")
else :
pass
#처리결과값
dahl
Moon
50
133. 객체접근 함수: 예시 2
메소드 및 함수여부 확인 후 실행
class A():
def __init__(self, name,age) :
self.name = name
self.age = age
def in_set(self,name,default) :
self.__dict__[name] = default
print self.__dict__[name]
a = A('dahl',50)
def add(x,y) :
return x+y
if callable(add) :
add(5,6)
else :
pass
if callable(a.in_set) :
a.in_set('age',20)
else:
pass
#처리결과값
dahl
Moon
50
20
135. 지역변수와 전역변수
동적 데이터 타입 : 변수에 값이 할당될 경우 데이터 타입이 확정됨
변수는 이름공간 내에서 관리되면 변수는 동적으로 할당이 가능하다.
변수 검색 기준은 Local > Global > Built-in 영역 순으로 찾는다
Locals()와 globals() 함수를 이용해서 검색
>>> p = 100
>>>
>>> def add(x,y) :
… p =0
… print(locals())
>>> globals()
>>>
함수내 파라미터와 그
내부에 정의된 변수
함수 외부 변수는 전
역변수
137. __import__함수
Import한 원 파일에 대한 위치를 확인
>>>__import__('inspect')
<module 'inspect' from 'C:Python27libinspect.pyc'>
138. Vars() 함수
Var(object)를 넣으면 현재 관리되는 속성들을 표시
vars(...)
vars([object]) -> dictionary
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
def add(x,y) :
print(" vars : ",vars())
print(" locals : ", locals())
return x + y
add(5,5)
vars : {'y': 5, 'x': 5}
locals : {'y': 5, 'x': 5}
139. dir함수
클래스, 모듈 등의 관리하는 내부 정보를 확인할 때 사용
>>>dir(B)
['__doc__', '__init__', '__module__', 'name']
141. Sequence 타입 정렬
Sequence 객체에 대한 정렬 처리 (sorted,
reversed) 별도의 sequence 객체 생성
>>> for i in reversed(xrange(1,10,2)):
... print i
...
9 7 5 3 1
>>> basket = ['apple', 'orange', 'apple',
'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print f
...
apple banana orange pear
reversed() sorted()
144. eval : Expression 실행
Eval 함수는 컴파일 및 표현식을 평가하고 실행 처리
>>> eval("1+2")
3
>>>
145. exec : Statement 실행
Exec함수는 컴파일하여 문장을 평가하고 실행하기
>>> exec('print "hello world"')
hello world
>>>
146. Run-time function 처리
Exec함수는 컴파일한 문장을 평가하고 실행하기
# 함수를 문자열에 정의
code_str = '''
def add(x=1,y=1) :
""" add x, y """
print(" vars : ",vars())
print(" locals : ", locals())
return x + y
a = add(5,5)
print(a)
''‘
#컴파일 처리
code_obj = compile(code_str, '<string>', 'exec')
print(type(code_obj))
# 실행
exec(code_obj)
#처리 결과
<type 'code'>
vars : {'y': 5, 'x': 5}
locals : {'y': 5, 'x': 5}
10
147. reload/execfile
함수
함수 설명
reload()
reload(...)
reload(module) -> module
Reload the module. The module must have been successfully imported before.
reload(inspect_sor_test) : import inspect_sor_test 한 모듈을 reload
execfile()
execfile(...)
execfile(filename[, globals[, locals]])
execfile(“xxxx.py”) : filenam에 스트링으로 모듈명을 입력하여 실행
149. High Order Function
고차함수(high order function)는 2가지 중에 하나를 수행
하나 이상의 함수를 파라미터로 받거나,
함수를 리턴 결과로 보내는 함수
#고차 함수 정의
def addList8(list):
return reduce(add8, list)
#일반함수 정의
def add8(*arg):
v = []
for i in arg:
v = v +i
return v
#고차함수 실행
print addList8([[1, 2, 3],[4, 5],[6],[]])
print reduce(add8, [[1, 2, 3],[4, 5],[6],[]])
# 결과값
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
150. map 함수
map(f, iterable)은 함수(f)와 반복가능한 자료형(iterable)
을 입력으로 받아 입력 자료형의 각각의 요소가 함수 f에
의해 수행된 결과를 묶어서 리턴하는 함수
# 파이썬 2 및 파이썬 3
# 5개 원소를 가진 리스트의 제곱하여 변환
list(map(lambda x: x ** 2, range(5)))
# 결과값 : [0, 1, 4, 9, 16]
151. reduce 함수
reduce(f, iterable)은 함수(f)와 반복가능한 자료형
(iterable)을 입력으로 받아 입력 자료형의 각각의 요소가
함수 f에 의해 수행된 결과를 리턴하는 함수
def addList7(list):
return reduce(add, list)
def add(*arg):
x = 0
for i in arg :
x = x + i
return x
print "addlist", addList7([1, 2, 3])
print "reduce ", reduce(add, [1, 2, 3])
# 결과값
addlist 6
reduce 6
152. filter 함수
# 파이썬 2 및 파이썬 3
#10개 원소중에 5보다 작은 5개만 추출
list(filter(lambda x: x < 5, range(10)))
# 결과값 : [0, 1, 2, 3, 4]
filter(f, iterable)은 함수(f)와 반복가능한 자료형(iterable)
을 입력으로 받아 함수 f에 의해 수행된 결과 즉 filter된 결
과를 리턴하는 함수
153. enumerate 함수
Sequence 타입을 받아 index와 value를 처리하는
함수
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
enumerate()
154. zip 함수
Sequence 2개를 받아 쌍을 만들어주는 함수
>>> l1 = [1,2,3,4]
>>> la = ['a','b','c','d']
>>> for k,v in zip(l1,la) :
... print k, v
...
1 a
2 b
3 c
4 d
>>>
zip()
156. Input/format/print 함수
>>>format("12345678","8.4s") # '1234’
‘1234’
>>>print(“Hello World “)
Hello World
>>>len([1,2,3,4])
4
>>> #
>"Hello World"
Hello World
Format/print/input 처리
a = input(">")
print(a)
Input으로 값을 받고 출력
157. Repr 함수
개체의 표준적인 캐릭터 라인 표현을 처리
repr(...)
repr(object) -> string
For most object types, eval(repr(object)) == object.
>>> # str 처리시 다른 결과가 발생. 객체를 str로 처리하기
>>> repr('123')
"'123'"
>>> str(123)
'123‘
>>>repr(123)
'123'
>>> str(123)
'123'
163. 파일 관리 함수
Open()/file()은 파일을 오픈
함수 설명
file()
파일 생성
file('test.txt','w') <open file 'test.txt', mode 'w' at 0x107EDC80>
파일 존재시 첨가 모드로
file('test.txt','a') <open file 'test.txt', mode 'a' at 0x107EDE90>
open()
f = open("새파일.txt", 'w')
f.close()