SlideShare uma empresa Scribd logo
1 de 160
PYTHON
객체지향
이해하기
Moon Yong Joon
기술적접근
객체
왜 모든 것을 객체로 관리하나?
모든 것은 객체
값
문자열
컨테이너
함수
클래스
튜플
리스트
딕션너리
집합
파이썬은 모든 것을 객체로 인식한다.
데이터 구조가 다 객체이므로 클래스를 가지고 생성시 참조를 가지고 있음
파일
모듈
패키지
모듈
객체로 구성했나?
실제 오퍼페이터를 내부적으로 메소드로 정의되어 있어서
메소드 처리로 인식되고 테이터 타입을 명확히 맞춰서 계
산처리 됨
1.+(1) 1
__add__(객체)
>>> 1+1
2
>>>
>>> 1.+1
2.0
>>> int(1.+1)
2
>>>
>>> p=1
>>> p.__add__(1)
2
>>>
클래스 정의
Class Notation
파이썬 언어에서 객체를 만드는 타입을 Class를 정의하여 사용
클래스 명
변수
메소드
class 클래스이름[(상속 클래스명)]:
<클래스 변수 1>
<클래스 변수 2>
...
def 인스턴스 메소드(self[, 인수1, 인수2,,,]):
<수행할 문장 1>
<수행할 문장 2>
...
def 클래스메소드(cls[, 인수1, 인수2,,,]):
<수행할 문장1>
<수행할 문장2>
...
def 정적메소드([, 인수1, 인수2,,,]):
<수행할 문장1>
<수행할 문장2>
...
Instance Notation
인스턴스 객체는 실제 클래스 객체가 생성시 할당
인스턴스 변수와 메소드는 런타임 즉 실행시 등록하여 사용할 수 있음
인스턴스명 : 클래스명
인스턴스 변수
인스턴스 메소드
(인스턴스 바인딩 경우)
class 클래스이름[(상속 클래스명)]:
def __init__(self[, 인수1, 인수2,,,]):
self.변수명 = 인수1
……
<수행할 문장 2>
...
def 인스턴스메소드(self[, 인수1, 인수2,,,]):
<수행할 문장1>
<수행할 문장2>
...
...
Instance명 = 클래스명( 초기인자들)
Class로 Instance 처리
파이썬 언어에서 객체를 만드는 타입을 Class로 생성해서 처리
Class는 객체를 만드는 하나의 틀로 이용
자바 언어와의 차이점은 Class도 Object로 인식
Class Object
Instance Object 1
Instance Object 2
Instance Object 3
instanciate
클래스에서 객체 생성하기
Class Member
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}
인스턴스 메소드
Predefined Class Attributes
Attribute Type Read/Write Description
__dict__ dictionary R/W The class name space.
__name__ string R/O The name of the class.
__bases__ tuple of classes R/O The classes from which this class inherits.
__doc__ string OR None R/W The class documentation string
__module__ string R/W
The name of the module in which this class
was defined.
Instance Member
Instance 생성시 self로 정의된 변수만 인스턴스 영역에서 관리하고 인
스턴스 메소드는 클래스에서 관리함
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 ins method ', 1)
{'ins_var': 1} # 인스턴스 객체 관리 영역
Predefined Instance Attributes
Attribute Type Read/Write Description
__dict__ dictionary R/W The instance name space.
__class__ Base class R The base class
__doc__ string OR None R/W The instance documentation string
클래스와 인스턴스 구조
Object Namespace 흐름
Base
class
class
instance instance instance
상속
인스턴스 생성
Dict{}
Dict{}
Dict{} Dict{} Dict{}
Namespace
검색
객체는 자신들이 관리
하는 Namespace 공간
을 생성하며
객체 내의 속성이나 메
소드 호출시 이를 검색
해서 처리
Class & instance scope
Class Object는 인스턴스를 만드는 기준을 정리한다.
클래스를 정의한다고 하나의 저장공간(Namespace) 기준이 되는 것은 아니다.
- 클래스 저장공간과 인스턴스 저장공간이 분리된다
User
defined
Class
Instance
Instance
Instance
Built-in
Class
상속 인스턴스화
Object Scope
Object Namespace
Class/Instance 관계 매핑
Class 키워드로 클래스 정의
상속은 class 키워드 다음() 내에 상속할 클래스 정의
인스턴스 생성은 클래스명에 ()연산자 사용
Super ClassClassinstance
상속인스턴스화
class A(object):
def whoami(self):
return self.__class__.__name__
a = A()
Class/Instance 관계 보기
내장 변수를 이용해서 Class와 Instance 관계를
확인
class A(object):
def whoami(self):
return self.__class__.__name__
a = A()
print a.whoami()
print a.__class__.__base__.__name__
인스턴스의 클래스 이름
: A
인스턴스의 클래스의 상속
클래스 이름
: object
생성자와 소멸자
생성자 처리 구조
파이썬은 생성자는 클래스이 __init__()메소드를
binding 하여 처리
Instance = ClassA(인자) ClassA.__init__(instance,인자)
ClassA( 상위클래스) :
def __init__(self,인자) :
# 생성자로직
Source code Execute code
생성자-Creating Instance
파이썬 생성자 __init__() 함수를 오버라이딩한 후
클래스이름(파라미터)를 이용하여 객체 생성
생성자 함수는 자동으로 연계됨
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
생성자 정의
인스턴스 객체 생성
생성자와 자동으로 연계
소멸자- Destroying Objects
클래스의 생성된 인스턴스를 삭제하는 메소드
#!/usr/bin/python
class Point:
def __init( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "destroyed"
pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts
del pt1
del pt2
del pt3
소멸자 정의
소멸자 활용
인스턴스 생성과 인스턴스 호출
__init__과 __call__ 메소드 차이
클래스 생성자에 따른 인스턴스 생성 및 인스턴
스 호출에 대한 내장메소드 처리
class A:
def __init__(self):
print "init“
def __call__(self):
print "call"
A() # init
A()() # init call
a = A() #init
a() # call
생성자와 인스턴스
호출 메소드 정의
생성자와 인스턴스
호출 메소드 정의
인스턴스 속성 미정의 후 생성
클래스 생성자에 인스턴스 속성을 미정의하고 인
스턴스를 호출시 실제 인스턴스가 없으므로 오류
처리
>>> class A:
... def __init__(self):
... print "From init ... "
...
>>> a = A()
From init
...
>>> a()
Traceback (most recent call last): File "<stdin>", line 1, in
<module> AttributeError: A instance has no __call__ method
>>>
인스턴스 속성 미정의 후 호출
인스턴스 속성 미정의할 경우 반드시 인스턴스
처리하는 __call__ 메소드를 정의하여 처리해야
함
>>> class B:
... def __init__(self):
... print "From init ... "
... def __call__(self):
... print "From call ... "
...
>>> b = B()
From init ...
>>> b()
From call ...
>>>
Class decorator : 기본
 생성자에서 함수 전달, 인스턴스 호출에서 함수의
파라미터 전달
 전달함수 실행시 생성자 실행 및 인스턴스 실행
#테코레이터 클래스 정의하고 생성자에 전달
class decoratorWithoutArguments(object):
def __init__(self, f):
print ("Inside __init__()")
self.f = f
#호출하는 곳에 내부함수 처리 로직 처리
def __call__(self, *args):
print( "Inside __call__()")
self.f(*args)
print( "After self.f(*args)")
#데코레이터 정의 및 전달함수 정의
@decoratorWithoutArguments
def sayHello(a1, a2, a3, a4):
print( 'sayHello arguments:', a1, a2, a3, a4)
데코레이터 클래스 정의 전달 함수 정의 함수 실행
#데코레이터 호출
print ("Preparing to call sayHello()")
sayHello("say", "hello", "argument", "list")
print ("After first sayHello() call")
sayHello("a", "different", "set of",
"arguments")
print ("After second sayHello() call"))
메소드 접근자
Class 멤버 접근자 - cls
클래스 객체의 변수나 메소드 접근을 위해 cls 키워
드 사용
Instance 멤버 접근자-self
인스턴스객체 메소드의 첫 인자는 Self를 사용하여
각 인스턴스별로 메소드를 호출하여 사용할 수 있
도록 정의
Method- Instance
클래스 객체에서 생성되는 모든 인스턴스 객체에서 활용되므로
클래스 이름공간에서 관리
메소드 첫 파라미터에 self라는 명칭을 정의
Method- 클래스 decorator
클래스 객체에서 처리되는 메소드를 정의한다. 클래스 메소
드는 첫번째 파라미터에 cls를 전달한다.
장식자 @classmethod : 클래스 함수 위에 표시-Python 2.x
함수 classmethod() : 별도 문장으로 표시 – Python 3.x
인스턴스 객체도 호출이 가능
Method- 정적 decorator
클래스 객체로 생성된 모든 인스턴스 객체가 공유하여 사용
할 수 있다.
장식자 @staticmethod : 정적함수 위에 표시 – Python 2.x
함수 staticmethod()는 별도의 문장으로 표시 –Python 3.x
정적메소드는 파라미터에 별도의 self, cls, 등 객체에 대한
참조값을 전달하지 않아도 됨
인스턴스 객체에서도 호출이 가능
Accessing Members
클래스를 정의한 후에 인스턴스를 생성하고 메소
드 호출 및 클래스 변수를 직접 호출하여 출력
class Employee:
'Common base class for all employees‘
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
Class 정의
#인스턴스 객체 생성 : 생성자 호출
emp1 = Employee("Zara", 2000)
# 인스턴스 메소드 호출
emp1.displayEmployee()
#인스턴스 객체 생성 : 생성자 호출
emp2 = Employee("Manni", 5000)
# 인스턴스 메소드 호출
emp2.displayEmployee()
#클래스 변수 호출 및 출력
print "Total Employee %d" % Employee.empCount
Instance 생성 및 호출
Method Bound/unbound(1)
클래스이름과 인스턴스이름으로 메소드를 호출
하면 bounding 처리 됨
메소드 선언시 인자로 self, cls를 정의되어 있음
>>> class Preson() :
... def printP(self) :
... print(' instance method ')
... def printC(cls) :
... print(' class method')
…
>>> p = Preson() # 인스턴스 생성
>>> p.printP() #인스턴스 메소드 bounding
instance method
>>> Preson.printP(p) # 인스턴스 메소드 unbounding
instance method
>>>
 인스턴스를 생성하고
 인스턴스 메소드 호출시는 bounding 처리
 클래스로 인스턴스 메소드 호출시는 인자로
인스턴스 객체를 전달해서 unbounding
Method Bound/unbound(2)
메소드 선언시 인자로 self, cls를 정의되어 있는
것에 따라 매칭시켜야 됨
Transformation Called from an Object Called from a Class
Instance method f(*args) f(obj,*args)
Static method f(*args) f(*args)
Class method f(cls, *args) f(*args)
Class Inheritance
Inheritance
상속은 상위 클래스를 하나 또는 여러 개를 사용하는
방법
class 상위 클래스명 :
pass
class 클래스명(상위 클래스명) :
pass
상속 정의시 파라미터로 상위 클래스명을 여러 개 작
성시 멀티 상속이 가능함
class 클래스명(상위 클래스명, 상위 클래스명) :
pass
Class 구조
클래스는 슈퍼클래스를 상속
Super ClassClass
상속
class A(object):
def __init__(self) :
self.instanceS = " static instance member"
def whoami(self):
return self.__class__.__name__
클래스 구조 예시(1)
>>> one = 1
>>> type(one)
<type 'int'>
>>> type(type(one))
<type 'type'>
>>> type(one).__bases__
(<type 'object'>,)
>>>
>>> object
<type 'object'>
>>> type
<type 'type'>
>>> type(object)
<type 'type'>
>>> object.__class__
<type 'type'>
>>> object.__bases__
()
>>> type.__class__
<type 'type'>
>>> type.__bases__
(<type 'object'>,)
>>> isinstance(object, object)
True
>>> isinstance(type, object)
True
>>> isinstance(object, type)
True
objecttype
int float str
클래스 구조
클래스 구조 예시(2)
>>> list
<type 'list'>
>>> list.__class__
<type 'type'>
>>> list.__bases__
(<type 'object'>,)
>>> tuple.__class__, tuple.__bases__
(<type 'type'>, (<type 'object'>,))
>>> dict.__class__, dict.__bases__
(<type 'type'>, (<type 'object'>,))
>>>
>>> mylist = [1,2,3]
>>> mylist.__class__
<type 'list'>
데이터 타입은 상속을 받을 때 타입 객체를 바로
받지만 base는 object 클래스를 처리
객체 생성 예시
메타클래스 클래스 인스턴스
type object
list mylist
Inheritance- scope
상속된 클래스도 검색하는 순서가 파라미터를 정리
한 순서대로 변수나 메소드를 검색하여 처리됨
상속된 클래스에 동일한 이름이 변수나 메소드가 존
재시 첫번째 검색된 것으로 처리함
class 클래스명(상위 클래스명, 상위 클래스명) :
pass
Inheritance - 예시
class Parent: # define parent class
parentAttr = 100
def __init__(self):
print "Calling parent constructor“
def parentMethod(self):
print 'Calling parent method'
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print "Parent attribute :", Parent.parentAttr
class Child(Parent): # define child class
def __init__(self):
print "Calling child constructor"
def childMethod(self):
print 'Calling child method'
c = Child() # instance of child
c.childMethod() # child calls its method
c.parentMethod() # calls parent's method
c.setAttr(200) # again call parent's method
c.getAttr() # again call parent's method
# 결과값
Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200
Class 정의 인스턴스 생성 및 호출
Mixin
기존 상속구조에 대한 변경을 최소화하기 위해 메소
드기반의 클래스 생성하여 상속받아 처리하는 방법
class Mixin :
def add(self,x,y) :
return self.x + self.y
def sub(self,x,y) :
if isinstance(self, String) :
return " String no support"
else :
return self.x - self.y
class Number(Mixin) :
def __init__(self, x,y) :
self.x = x
self.y = y
class String(Mixin) :
def __init__(self, x,y) :
self.x = x
self.y = y
n1 = Number(5,6)
n1.add(n1.x,n1.y)
n1.sub(n1.x,n1.y)
s1 = String("hello ", "world")
print s1.add(s1.x, s1.y)
print s1.sub(s1.x, s1.y)
인스턴스 생성 및 호출
상속구조 확인하기
MRO 처리
Method resolution order는 상속에 대한 처리
순서를 명확히 표시
class test1 :
print " test1 “
print test1.mro()
# 실행 결과
AttributeError: class test1 has no attribute
'mro'
class test1(object) :
print " test1 "
print test1.mro()
# 실행 결과
test1
[<class '__main__.test1'>, <type 'object'>]
'
상속 : __mro__, mro()
상속인 경우 클래스 객체들이 우선순서를 확인하
는 속성과 메소드
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class test(Base2,Base3) :
A = 'aaaa‘
instance = test()
instance.amethod()
print test.__mro__
print test.mro()
# 실행 결과
Base1
(<class '__main__.test'>, <class
'__main__.Base2'>, <class '__main__.Base1'>,
<class '__main__.Base3'>, <type 'object'>)
[<class '__main__.test'>, <class
'__main__.Base2'>, <class '__main__.Base1'>,
<class '__main__.Base3'>, <type 'object'>]
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의 값
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'
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’) 처럼 인식
Super() 함수(3.x)
파이썬 3.x 버전부터 super()함수이 파라미터가 없
어도 자동으로 스택프레임에서 검색하여 처리함
Overriding
Overriding
메소드를 이름으로 검색하므로 하위 클래스에 동
일한 메소드가 존재하면 인스턴스 호출시 하위
클래스 메소드 부터 호출하므로 Overriding 처리
class 상위 클래스명 :
def method(self) :
pass
class 클래스명(상위 클래스명) :
def method(self) :
pass
Overriding 구조
동일한 메소드를 instance/Class/Super Class에
다 정의할 경우 실행시 instance부터 호출이 되는 구
조
Super ClassClassinstance
상속인스턴스화
클래스 정의
시 메소드
클래스 정의
시 슈퍼 클래스메소
드 재정의
Runtime 시
클래스 및 슈퍼클래
스 메소드 정의
Overriding 발생 Overriding 발생
연산자 Overriding 예시
Super ClassClassinstance
상속인스턴스화
Overriding 발생
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a,
self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b +
other.b)
# __init__ 생성자 메소드 overriding
v1 = Vector(2,10)
v2 = Vector(5,-2)
# __add__ 메소드 overriding
print v1 + v2
# __str__ 메소드 overriding
print v1
__getattr__/__setattr__ 메소드
인스턴스에서 상속된 부모 클래스의 속성을 조회
및 갱신이 가능
>>> dir(dict)
['__class__', '__cmp__', '__contains__', '__delattr__',
'__delitem__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__getitem__', '__gt__',
'__hash__', '__init__', '__iter__', '__le__', '__len__',
'__lt__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', ….']
>>>
dict 클래스에서 보관하는
속성을 조회
>>> # dict 인스턴스 생성하고 dict 내
>>> # 매소드 호출
>>> d = {'a': 1}
>>> d.__getattribute__('__class__')
<type 'dict'>
>>>
dict 클래스의 인스턴스로
클래스 내부의 속성을 조
회
./[] 연사자 overriding
다른 클래스를 만들어서 연산자를 다양하게 사용
하기 위해 오버라이딩 처리
class Test1(dict) :
def __getattr__(self,name) :
return self[name]
def __setattr__(self,name, value) :
self[name] = value
t1 = Test1()
t1.a= 10
t1['btest'] = 100
print t1.a
print t1['btest']
print t1.__dict__
print t1
#결과값
10
100
{}
{'a': 10, 'btest': 100}
Super
Class
Classinstance
상속인스턴
스화
Overriding 발생
./[] 연사자 overriding - 설명
부모 클래스의 메소드를 재정의해서 현재 클래스
의 메소드가 호출되도록 처리
class Test1(dict) :
def __getattr__(self,name) :
return self[name]
def __setattr__(self,name, value) :
self[name] = value
1. dict 클래스의 __getattr__,
__setattr__ 메소드에 대한 오
버라이딩 처리
2. dict 타입이라서 실제 self 내부
데이터 타입에 저장됨
인스턴스 생성 기초
Instance 구조
클래스는 슈퍼클래스를 상속하고 인스턴스를 만
들어서 실제 기능들을 동작시킨다.
Super ClassClassinstance
상속인스턴스화
Instance 생성 방식
클래스명에 파라미터에 인스턴스 변수값을 정의해
서 인스턴스를 생성함
인스턴스 생성시 생성자가 호출되어 처리됨
변수명 = 클래스명(인스턴스 변
수값,인스턴스 변수값)
def __init__(self, 인스턴스 변수
값,인스턴스 변수값) :
self.인스턴스 변수 = 인스턴
스변수값 매칭호출시
매칭됨
Instance 생성 예시
Class 키워드로 클래스 정의
상속은 class 키워드 다음() 내에 상속할 클래스 정의
인스턴스 생성은 클래스명에 ()연산자 사용
Super ClassClassinstance
상속인스턴스화
class A(object):
def whoami(self):
return self.__class__.__name__
a = A()
Instance Scope
객체들간의 관계(상속 및 instance 생성 등)에 따라 객체 멤버들에 대
한 접근을 처리
검색 순서 : 인스턴스> 클래스> 상속클래스>builtin Class
상속이 많아지면 다양한 상위 멤버들을 접근하여 처리할 수 있다.
Predefined Instance Attributes
Attribute Type Read/Write Description
__dict__ dictionary R/W The instance name space
__class__ class R/W The class of this instance
클래스와 인스턴스 접근
Members(변수) Access
Class/Instance 객체에 생성된 변수에 대한 구조
및 접근 방법
>>> # class 정의
>>> class C(object):
... classattr = "attr on class“
...
>>> #객체 생성 후 멤버 접근
>>> cobj = C()
>>> cobj.instattr = "attr on instance"
>>>
>>> cobj.instattr
'attr on instance'
>>> cobj.classattr
'attr on class‘
멤버접근연사자(.)를 이용하여
접근
C
classattr
cobj:C
instattr
cobj = C()
Members(변수) Access -세부
Class/Instance 객체는 내장 __dict__ 멤버(변수)에
내부 정의 멤버들을 관리함
>>> # 내장 __dict__를 이용한 멤버 접근
>>> # Class 멤버
>>> C.__dict__['classattr']
'attr on class'
>>> # Instance 멤버
>>> cobj.__dict__['instattr']
'attr on instance'
>>>
>>> C.__dict__
{'classattr': 'attr on class', '__module__': '__main__',
'__doc__': None}
>>>
>>>
>>> cobj.__dict__
{'instattr': 'attr on instance'}
>>>
C
cobj:C
cobj = C()
__dict__:dict
classattr
__dict__:dict
classattr
내장 객체
내장 객체
Members(메소드) Access
Class 정의시 인스턴스 메소드 정의를 하면 Class
영역에 설정
>>> #Class 생성
>>> class C(object):
... classattr = "attr on class“
... def f(self):
... return "function f"
...
>>> # 객체 생성
>>> cobj = C()
>>> # 변수 비교
>>> cobj.classattr is C.__dict__['classattr']
True
변수 비교
C
classattr
f
cobj:C
instattr
cobj = C()
Members(메소드) Access-세부
인스턴스에서 인스턴스메소드 호출하면 실제 인스
턴스 메소드 실행환경은 인스턴스에 생성되어 처리
>>> #인스턴스에서 실행될 때 바운드 영역이 다름
>>> # is 연산자는 동일 객체 체계
>>> cobj.f is C.__dict__['f']
False
>>>
>>> C.__dict__ {'classattr': 'attr on class',
'__module__': '__main__', '__doc__': None,
'f': <function f at 0x008F6B70>}
>>> 인스턴스에 수행되는 메소드 주소가 다름
>>> cobj.f
<bound method C.f of <__main__.C instance at
0x008F9850>>
>>> # 인스턴스 메소드는 별도의 영역에 만들어짐
>>> # 인스턴스 내에 생성된 메소드를 검색
>>> C.__dict__['f'].__get__(cobj, C)
<bound method C.f of <__main__.C instance at
0x008F9850>>
C
cobj:C
cobj = C()
__dict__:dict
classattr
f
__dict__:dict
classattr
f
내장 객체
내장 객체
Controlling Attribute Access
Instance의 Attribute에 대한 접근을 할 수 있는 내
부 함수
__getattr__(self, name)
__setattr__(self, name, value)
__delattr__(self, name)
__getattribute__(self, name)
Controlling Attribute Access
인스턴스의 속성에 대한 접근을 내부 함수로 구현하
여 접근
class A() :
__slots__ =['person_id', 'name']
def __init__(self, person_id, name) :
self.person_id = person_id
self.name = name
def __getattr__(self, name) :
return self.__dict__[name]
def __setattr__(self, name, value):
if name in A.__slots__ :
self.__dict__[name] = value
else:
raise Exception(" no match attribute")
def __delattr__(self, name) :
del self.__dict__[name]
def __getattribute__(self, name):
return self.__dict__[name]
a = A(1,'dahl')
print a.__getattr__('name')
print a.__getattr__('person_id')
print a.__dict__
print a.__setattr__('name','moon')
print a.__setattr__('person_id',2)
print a.__getattr__('name')
print a.__getattr__('person_id')
print a.__delattr__('name')
print a.__dict__
a.name = 'gahl'
#a.s = 1
print a.__dict__
Association
Association
객체간에 관계를 구성하여 처리
객체내부에 관계 객체를 생성하여 해당 객체의 기능을 처리
A
B
Association:Object Chain
#class 정의하고 인스턴스에서 타 객체를 호출
class A:
def __init__(self ):
print 'a'
self.b = B()
#object chain을 하는 class 생성
class B:
def __init__(self ):
print 'b'
def bbb(self):
print "B instance method "
a = A()
print a.b.bbb()
객체들간의 연결고리(Association, Composite 관계)가 있을 경
우 메소드 결과값을 객체로 받아 연속적으로 실행하도록 처리
객체.내부객체.메소
드 처리
#결과값
a
b
B instance
method
None
Dependency
객체간에 관계를 구성하여 처리
객체내부에 관계 객체로써 메소드 등에서 일회성으로 해당 객체를 생성하여 기능
을 처리
A
B
Dependency: Method Chain
class C:
def __init__(self ):
print 'a'
self.b = B()
def ccc(self, b) :
return b.bbb()
#object chain을 하는 class 생성
class B:
def __init__(self ):
print 'b'
def bbb(self):
print "B instance method "
a = C()
print a.b.bbb()
print a.ccc(B())
객체의 관계가 일회성 적으로 처리가 되는 관계
객체.메소드(인스턴스
객체) 처리
#결과값
a
b
B instance method
None
b
B instance method
None
Self Method Chain
class Person:
def name(self, value):
self.name = value
return self
def age(self, value):
self.age = value
return self
def introduce(self):
print "Hello, my name is", self.name, "and I am", self.age, "years old."
person = Person()
#객체의 메소드를 연속적으로 호출하여 처리
person.name("Peter").age(21).introduce()
객체 내의 메소드의 결과를 자기자신으로 리턴하여 메소드를
연속해 호출하여 처리
타 객체 Method Chain
class A:
def __init__(self ):
print 'a'
self.b = B()
class B:
def __init__(self ):
self.c = C()
print 'b'
def bbb(self):
print "B instance method "
return self.c
class C:
def __init__(self ):
print 'c'
def ccc(self):
print "C instance method "
클래스 정의시 내부에서 인스턴스를 가진 경우
chain 처리를 위해 return으로 해당 객체를 전달
#결과값
a
c
b
B instance method
C instance method
None
a = A()
print a.b.bbb().ccc()
Class 확인 방법
issubclass/isinstance 함수
>>> issubclass(list,object)
True
>>> list.__bases__
(<type 'object'>,)
>>> issubclass(list, type)
False
>>>
issubclass() : __bases__ 기준으로 상속관계
isinstance() : __ class__ 기준으로 인스턴스 객
체 관계
>>> isinstance(list, type)
True
>>> list.__class__
<type 'type'>
>>>
>>> isinstance(list, object)
True
>>>
issubclass 처리 isinstance 처리
Class & instance namespace
Class Object는 클래스 메소드, 정적메소드, 클래스 내부 변수 등을 관리한다.
파이썬은 변수나 메소드 검색 기준이 인스턴스> 클래스 > Built-in Class 순으로 매
칭시키므로 .연산자를 이용하여 인스턴스도 메소드 호출이 가능하다.
>>> class Simple :
... pass
...
>>> Simple
<class __main__.Simple at 0x0212B228>
>>> Simple.__name__
'Simple‘
>>> Simple.__dict__
{'__module__': '__main__', '__doc__': None}
>>> s = Simple()
>>> s.__dict__
{}
>>> s.name = "Simple instance"
>>> s.__dict__
{'name': 'Simple instance'}
Instance 생성 및 인스턴스 멤버 추가Class 정의
Descriptor Protocol
Descriptor
설명은 그 속성 접근 기술자 프로토콜의 방법에
의해 무시되었다 "바인딩 행동"을 가진 객체 속성
중 하나입니다
__get__(self, instance, owner),
__set__(self,instance, value),
__delete__(self, instance).
Descriptor 종류
Method descriptor와 Data descripter 로 구분
 Method descriptor는 __get__(self, instance,
owner) 구현
 Data descriptor는 __get__(self, instance,
owner) __set__(self,instance, value),
__delete__(self, instance) 구현
Descriptor : int.__add__
Method descriptor로 구현되어 __get__(self,
instance, owner) 가지고 있다
P =1
# 직접 호출
p.__add__(3) # 결과값 4
#인스턴스에서 호출
type(p).__add__.__get__(p,int)(3) #결과값 4
#class에서 호출
int.__add__.__get__(1,int)(3)
Descriptor : binding behavior
binding 하는 방법
Direct Call
Instance Binding
Class Binding
Super Binding
class D(object) :
def __init__(self, x) :
self.x = x
def __get__(self,instance=None,cls=None) :
return self.x
class D1(D) :
def __init__(self, x) :
D.__init__(self,x)
d = D(1)
print " d"
print d.__dict__
print d.x
print " direct call",d.__get__()
print " Class binding call ",D.__get__(d,d)
print "instance binding",type(d).__get__(d,d)
d1 = D1(2)
print " d1"
print d1.__dict__
print d1.x
print " direct call",d1.__get__()
print " Class binding call ", D1.__get__(d1,d1)
print "instance binding",type(d1).__get__(d1,d1)
print D1.mro()
print "super binding",super(D1,d1).__get__(d1,d1)
Creating data descriptor
Data Descriptor 클래스를 생성해서 처리하는
방법
class Descriptor(object):
def __init__(self):
self._name = ''
def __get__(self, instance, owner):
print "Getting: %s" % self._name
return self._name
def __set__(self, instance, name):
print "Setting: %s" % name
self._name = name.title()
def __delete__(self, instance):
print "Deleting: %s" %self._name
del self._name
class Person(object):
name = Descriptor()
>>> user = Person()
>>> user.name = 'john smith'
Setting: john smith
>>> user.name
Getting: John Smith
'John Smith‘
>>> del user.name
Deleting: John Smith
Creating 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 생김)
Creating Property–객체 직접 정의(2)
실제 인스턴스 객체의 변수에 접근하면 Property
객체의 메소드를 호출하여 처리되고 인스턴스 객
체의 변수값이 변경됨
p1 = P(1001)
print id(p1.x)
print P.__dict__['x']
print id(p1.__dict__['x'])
print p1.x
p1.x = -12
print p1.x
print p1.__dict__
#처리결과값
44625868
<property object at
0x02C1D4E0>
44625868
1001
-12
{'x': -12}
Creating Property decorator(1)
인스턴스 객체의 변수 접근을 메소드로 제약하기 위해서는
Property 객체로 인스턴스 객체의 변수를 Wrapping 해야 함
property(fget=None, fset=None, fdel=None, doc=None)
class P:
def __init__(self,x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
self.__x = x
@x.deleter
def x(self):
del self.x
Getter, setter, deleter 메
소드를 정의
인스턴스 객체의 변수명과
동일하게 Property 객체 생
성(내부에 _x 생김)
Creating Property decorator(2)
Property 객체 생성하여 처리하는 방식과 동일
p1 = P(1001)
print id(p1.x)
print P.__dict__['x']
print id(p1.__dict__['x'])
print p1.x
p1.x = -12
print p1.x
print p1.__dict__
#처리결과값
44625916
<property object at
0x02C1D3C0>
44625916
1001
-12
{'x': -12}
내장함수를 통한 객체접근
Built-in 내장함수
내장함수를 이용하여 객체의 속성에 대한 접근
getattr(object, name[, default])
setattr(object, name, value)
delattr(object, name)
hasattr(object, name)
callable(object)
Built-in 내장함수: 예시 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
Built-in 내장함수: 예시 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
Information Hiding
Information hiding -변수
__명칭 : Private
(객체 내부에서만 사용)
외부에서 호출시 mangling 되는 구조로
요청시 접근 가능
인스턴스._클래스명__명칭
_명칭 : protected
(클래스 및 하위 클래스에서만 사용)
Information hiding -변수예시
명칭 : public
(파이썬은 공개되는 게 기본)
__명칭 : Private
(객체 내부에서만 사용)
mangling 되는 구조로 명칭이 변경됨
호출시는
인스턴스._클래스명__명칭
_명칭 : protected
(클래스 및 하위 클래스에서만 사용권고)
“don’t touch this, unless you’re a subclass”
>>>class foo:
… def __secret(self): pass
…
foo.__secret => AttributeError: __secret
>>>foo.__dict__
{'_foo__secret': <function __secret at fc328>,
'__module__': '__main__', '__doc__': None}
Private 메소드 정의 및 호출 Class Namespace 명칭
Information hiding –변수-특별
__명칭__ : 내장된 변수나 함수 등을 정의
Information hiding –
Descriptor(Property)
파이썬은 Property 객체를 이용하여 객체내의 변수들의 접근을 메소드
로 제어한다.
Descriptor 객체, Property 객체나 @property decorator를 이용
인스턴스 객체의 변수 명과 동일한 property 객체가 생성되어야 함
Class P
Instance p1
{‘x’: }
Descriptor
/Property
x
생성
인스턴스생성
p1.x 접근
Property 내 메소드 호출하여 처리
Abstract Base Class
Abstract Class
추상화 클래스란 직접 인스턴스를 만들지 못하고
상속을 받아 메소드 오버라이딩해서 사용하는 방
식
Concrete Class instance
Obj = ConcreteClass()
인스턴스 객체 생성
Abstract Class instance
Obj = ConcreteClass()
인스턴스 객체 생성
X
Abstract
Class
Concrete
Class
instance
ConcreteClass
(Abstract Class)
상속
Obj = ConcreteClass()
인스턴스 객체 생성
Abstract Class 정의 방법
추상화 클래스는 exception 및 abc 모듈 2가지
처리 방법으로 만들 수 있다.
exception 방식
abc 모듈 방식
모든 메소드를 subclass에서 정의할
필요가 없다
오류처리 : NotImplementedError
모든 메소드를 subclass에서 정의해야
한다.
오류처리 : TypeError
Abstract Class : exception 방식
클래스 정의 후에 메소드 실행 부분을 exception
처리하고 상속받은 클래스에서 메소드 오버라이
딩 처리
class Base:
def foo(self):
raise NotImplementedError("foo")
def bar(self):
raise NotImplementedError("bar")
class Concrete(Base):
def foo(self):
return "foo() called"
상속 및 메소드 오버라이딩
추상클래스의 모든 메소
드를 구현할 필요없음
Abstract Class : ABC 모듈
ABC 모듈을 이용하여 정의해서 추상클래스 정의
후 상속을 받아 메소드 오버라이딩 처리
from abc import ABCMeta, abstractmethod
class Base():
__metaclass__=ABCMeta
@abstractmethod
def foo(self):
pass
@abstractmethod
def bar(self):
pass
class Concrete(Base):
def foo(self):
pass
def bar(self):
pass
상속 및 메소드 오버라이딩
추상클래스의
모든 메소드를
구현되어야 함
Abstract Class :property 정의
Abstract Class에서 decorator(@property)를
사용하여 처리하기
class 구현클래스명() :
변수명
@property
def get메소드명 :
@변수명.setter
def set메소드명 :
@변수명.deleter
def del메소드명 :
import abc
class 추상클래스명() :
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def get메소드명 :
@변수명.setter
def set메소드명 :
@변수명.deleter
def del메소드명 :
매칭
Abstract Class :property 구현
Abstract Class에서 decorator(@property)를
사용하여 처리하기
import abc
class Base(object):
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def value(self):
return 'Should never see this'
@value.setter
def value(self, newvalue):
return
class Implementation(Base):
# private 처리
_value = 'Default value'
@property
def value(self):
return self._value
@value.setter
def value(self, newvalue):
self._value = newvalue
abc 모듈을 이용해서 추상클래스 정의 추상클래스 상속받은 하위클래스 정의
Duck typing
Duck typeing 정의 방법
다양한 클래스가 동일한 메소드를 처리할 수 있
도록 인터페이스를 갖도록 만드는 법
함수
클래스
Duck typing에 필요한 함수 정의 후
인스턴스들의 메소드 호출 처리
Duck typing에 필요한 클래스 정의 후
인스턴스들의 메소드 호출 처리
Duck typeing : 함수 구현(1)
Duck typeing 함수 정의 후 클래스에 동일한 메
소드 정의
def in_the_forest(duck):
duck.quack()
duck.feathers()
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray
feathers.")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather
from the ground and shows it.")
def name(self):
print("John Smith")
함수 정의 클래스 정의
Duck typeing : 함수 구현(2)
Duck typeing 처리
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
print "function duck typeing "
game()
# 실행 결과
function duck typeing
Quaaaaaack!
The duck has white and gray feathers.
The person imitates a duck.
The person takes a feather from the ground
and shows it.
Duck typeing : 클래스 구현(1)
Duck typeing 클래스 정의 후 클래스에 동일한
메소드 정의
class InTheForest() :
@staticmethod
def quack(self) :
self.quack()
@staticmethod
def feathers(self) :
self.feathers()
@classmethod
def all(cls,self) :
cls.quack(self)
cls.feathers(self)
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray
feathers.")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather
from the ground and shows it.")
def name(self):
print("John Smith")
함수 정의 클래스 정의
Duck typeing : 클래스 구현(2)
Duck typeing 처리
def gameC():
donald = Duck()
john = Person()
InTheForest.all(donald)
InTheForest.all(john)
print " class duck typeing "
gameC()
# 실행 결과
class duck typeing
Quaaaaaack!
The duck has white and gray feathers.
The person imitates a duck.
The person takes a feather from the ground
and shows it.
INSPECT
MODULE
Insepect Module
Inspect module
module에 대한 다양한 점검을 위한 함수를 제공
Function Description
inspect.getmoduleinfo(path)
모듈에 대한 정보를 가져오기
ModuleInfo(name='in_test', suffix='.py', mode='U',
module_type=1)
inspect.getmodulename(path)
모듈 네임만 문자열로 가져옴
in_test
inspect.ismodule(object) import한 모듈을 확인 여부
Inspect 객체
객체에 대한 다양한 점검을 위한 함수를 제공
Function Description
inspect.getmembers(object[, predicat
e]
객체의 멤버를 튜플(키와 값)로 표시
inspect.isclass(object) Object에 클래스가 들어가면 True이고 나머지는 False
inspect.ismethod(object) Object가 메소드 여부
inspect.isabstract(object) Object가 추상클래스 여부
inspect.ismethoddescriptor(object)
int.__add__ 처럼 내장 메소드일 경우 descriptor protocol 존재해서
true 처리
inspect.isdatadescriptor(object) __get__, __set__, __delete__ 메소드를 가진 인스턴스일 경우 True
Inspect 함수
함수에 대한 다양한 점검을 위한 함수를 제공
Function Description
inspect.isfunction(object) Object가 함수 여부
inspect.isgeneratorfunction(object)
Object가 제너레이터 함수 여부
inspect.isgenerator(object)
Object가 제너레이터 여부
개념적 접근
객체지향이란?
왜 객체지향을 하는가?
 소프트웨어이 관리 기준은 모듈이지만 실행환경에서 모듈은
객체처럼 움직이면서 관리
 실행환경과 구현환경이 동일하게 관리하는 것이 객체지향을
도입한 중요한 이유
 인간의 사고는 추상화적인 분류를 기준
 추상화를 위한 단위를 객체로 보고 소프트웨어를 만드는 것이
인간의 사고
 개발자들이 추상적인 생각을 키우면서 소프트웨어를 개발하기
딱 맞는 환경이 객체지향이고 이를 위해 소프트웨어도 그 개념
을 받아들여 발전
 객체 즉 사물을 보고 잘 분류하는 사고가 필요
객체지향 사물의 분류
 사물(Things)은 곧 객체이다.
 사물에는 형태를 가진 것과 개념만 존재하는 것으로 분류할 수 있다.
 소프트웨어 분석 설계 구현을 한다는 것은 실세계의 사물을 가상세계의 사물로 전환
하는 것이다.
 객체 모델링, 데이터 모델링도 다 사물들을 관리하는 기준에 맞춰 분류하는 것이다.
 타입, 클래스는 객체 즉 사물을 분류했을 때 정의하는 것에 지나지 않는다.
 사물을 어떻게 분류할 것인가?
 책을 예시로 보면 책은 객체이다. 책에 대한 정보만 관리하는 것은 개념 객체이고 책의 실물을
관리하는 사물을 관리하는 객체가 구별되어 관리되어야 한다.
 책이라는 객체가 책 정보에 대한 분류 기준으로 도서문헌상의 분류 규칙을 따르므로 다양한
분류체계를 관리하는 객체도 발생할 수 있다.
 사물은 단순이 존재한다고 하나의 객체만은 아니다.
 보는 관점, 각 비즈니스 도메인별로 차이가 발생하므로 사물의 분류 기준을 비즈니스
에 맞춰 모델링이 되어야 한다.
계약중심의 설계
 실세계 객체들이 대화 즉 의사소통을 통행 움직인다.
 소프트웨어도 실제 객체들이 혼재되어 실행되지만 객체간의 영향을
항상 조화를 이룰 수 있다면 깨지지 않고 많은 것을 처리할 수 있다.
 이를 위해 객체간의 메시지 즉 소통을 위해 각 객체들은 자신들의 할
수 있는 일과 상대방에게 요구하는 일들을 약속해서 명확하게 처리
되어야 한다.
 design by contract 계약중심의 설계는 실제 객체들이 실행시 자신
들의 권리와 의무를 명확히 하고 이를 어길 경우에도 정확한 에러처
리를 통해 소프트웨어가 잘 작동할 수 있는 설계를 하자는 것이다.
 소프트웨어는 가상의 물질 즉 객체들에 의해 작동되지만 실세계의
객체들이 움직임처럼 명확히 살아있는 것처럼 생각해서 설계가 되어
야 스파게티 소스를 만들지 않을 수 있는 지름길이다.
객체의 생명주기 관리
 계약이란 쌍방이 매매를 했을 때 권리와 의무를 명확히 표시한 거래이다.
 계약이 발생하면 그 계약이 시작점과 종료점이 있다.
 계약도 생명주기를 갖는다.
 생명주기를 갖는 것은 하나의 객체로서 관리를 해야 한다는 것이다.
 온라인 쇼핑몰에서 책을 구매한다.
 책을 매매한 계약은 배송으로 끝나는 것이 아니라 반품 등이 발생할 수 있으므로 최소 14일 정
도까지는 기다려야 한다.
 회사 정책으로 더 많은 기간을 반품기간으로 정할 경우는 매매계약이 생명주기는 더 길어진다.
 이처럼 생명주기가 발생하는 것은 개념 객체이므로 객체로 관리해야 하는 대상이다.
 매매계약이 발생했을 때 이 계약에 필요한 문서 등을 고객에게 출력해줘야 하는 경우
는 생명주기가 더 길어진다.
 계약 문서 등도 별도의 객체이므로 계약과의 연관관계를 유지하도록 한다.
 객체는 항상 생명주기가 있고 보는 시각을 달리하면 생명주기 관리기준도 다양하게
발생한다.
 객체를 보는 관점을 다양하게 갖는 게 아주 중요하다.
상속대신 연관관계로 표현
 객체지향 설계 시 상속을 사용하지 않는 이유는 상
속관계가 끊어지면 모델을 다시 만들어야하기 때
문이다.
 상속은 인간들이 보기가 좋지만 상속 레벨이 3단계
가 넘어가거나 다중상속일 경우 인간이 이해하는
범위가 넘어가서 실질적인 상속을 이해할 수가 없
다.
 실제 생물들도 부모로부터 상속을 받지만 상속관
계로 표현할 수 있는 게 너무 없어서 실제 상속을
사용할 수 있는 것을 없다.
상속을 끊을 경우 어떤 대안은
 별도의 클래스를 생성할 수 있는 팩토리 체계를
만들어서 상속대신 관계성을 가질 수 있는 설계
로 반영해야 한다.
 실세계에 존재하는 객체들은 그렇게 상속을 가
지지 못하거나 너무 복잡해서 우리가 인식할 수
없다.
 상속을 사용할 경우 시스템 재개발 등이 발생
시 더 많은 비용이 들 수 있어 연관관계를 사용
해서 다양한 클래스로 분리
상속만으로 추상화는 불가
 객체지향 프로그램 언어는 상속을 가지고 재사용성을 높일 수
있다고 한다.
 실제 상속은 비즈니스 환경에서는 맞지 않는다.
 상속으로 재사용성을 높인다고는 하지만 재사용은 변경이 아
니라 추가인데 상속에서 추가를 한다는 것은 자식을 추가하는
것인데 자식들만 추가한다고 그 자식들이 거의 유사한 것들이
되는 것인가?
 상속을 하려면 자식들이 가진 아주 대표적인 것만 부모가 되어
야 하는데, 비즈니스 환경에서는 부모와 자식이 구분이 안되는
경우가 더 많다.
 객체들이 많다면 그 객체들이 통합이 가능한지를 먼저 확인하
고 객체들을 별도로 추상화하여 각 객체들이 집단간의 연관관
계를 고려하는 게 더 추상화가 높을 수 있다.
왜 스파게티가 될까?
 기술적 재사용성만 강조하면 다중 상속이 필요
하고 이를 반영하려면 클래스가 세분화 된다.
 하나의 서비스를 처리하기 위해 사용되는 클래
스들이 많아지면 상속 및 연관관계가 일관되게
유지되기 어렵다.
 스파게티를 해결하려면 특정 도메인으로 분리
해서 실제 연관관계를 분리해야 한다
SOLID?
SOLID
 단일 책임 원칙 (Single responsibility
principle)
 개방-폐쇄 원칙 (Open/closed principle)
 리스코프 치환 원칙 (Liskov substitution
principle)
 인터페이스 분리 원칙 (Interface segregation
principle)
 의존관계 역전 원칙 (Dependency inversion
principle)
단일 책임 원칙
 Single responsibility principle
 한 클래스는 하나의 책임만 가져야 한다.
단일 책임 원칙: 예시
 거래당사자 정보를 정보관리와 거래 당사자의
역할로 분할하여 책임 정의
Involved Party
Person Organization
Role
Customer Employee Owner …
개방-폐쇄 원칙
 Open/closed principle
 “소프트웨어 요소는 …… 확장에는 열려 있으나 변
경에는 닫혀 있어야 한다.”
 요구사항의 변경이나 추가사항이 발생하더라도,
기존 구성요소는 수정이 일어나지 말아야 하며, 기
존 구성요소를 쉽게 확장해서 재사용할 수 있어야
한다는 뜻입니다.
 필수적인 요구사항만, 구성요소(클래스)안에 구현
하고, 나머지는, 구현자체를 생략하라는 겁니다.
개방-폐쇄 원칙: 예시
 거래당사자의 역할은 기존 클래스를 변경하는 게
아니라 새로운 책임성을 가지는 클래스를 추가
Role
Customer Employee Owner …Applicant
리스코프 치환 원칙
 Liskov substitution principle
 서브타입은 언제나 자신이 기반타입 (base type)으로
교체할 수 있어야 한다.
 서브타입 클래스의 메소드를 변경하지 않아야 기반 클래스의
사용자는 그 기반 클래스에서 유도된 클래스(서브타입)에 대해
아무것도 알 필요가 없어야 한다.
 상속은 코드 재사용을 위해서가 아니라 명확한 가족 관계
가 있을때 사용해야 하며, 그 행위(Behavior) 와 연관
이 있습니다. 부모와 파생된 객체들이 존재 할때 가능한
모두 동일한 메소드 이름과 갯수를 가지게 함으로써 언
제든지 서브 타입이 기반타입으로 교체될 수 있어야 함을
말합니다.
리스코프 치환 오용
 상속관계가 아닌 객체를 비슷한 일을 하는 것
을 보고 코드 재사용 욕심에 가족 관계로 묶는
것.
 다중 상속이나 다단계 상속으로 계층 구조가 깊
고 복잡하게 하는 것.
 파생 타입에 부모, 형제들과는 전혀 동떨어진
능력을 부여 함으로써 돌연변이를 만들어 버리
는 것.
리스코프 치환 원칙 : 예시
 서브타입에 특정 기능을 오버라이딩한 것이 없도록 처
리하여 기반타입으로 교체해도 이상이 없도록 함
class rectangle() :
def __init__(self,height, width) :
if height == width :
self.height = height
self.width = width
else :
if self.__class__.__name__ == 'square' :
print " error "
else :
self.height = height
self.width = width
def area(self) :
return self.height * self.width
class square(rectangle) :
pass
r = rectangle(5,8)
print r.__dict__
print r.area()
try :
s = square(5,6)
print s.__dict__
print s.area()
except :
pass
{'width': 8, 'height': 5}
40
error
{}
인터페이스 분리 원칙
 Interface segregation principle
 “특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이
스 하나보다 낫다.”
 클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺
으면 안된다.
 비대한 클래스(Fat class) 거대하고 보기 흉하다는 사실 말고
도, 한 사용자가 이 비대한 클래스의 메소드를 다 사용하는 일
이 매우 적다는 것도 문제입니다. 즉. 메소드를 몇십개 선언한
클래스에서 사용자는 단지 두세 개만 호출 할 지도 모르죠. 불
행하게도 이 사용자들은 호출하지도 않는 메소드에 생긴 변화
에도 영향을 받습니다.
인터페이스 분리 원칙 : 예시
 인터페이스에 대한 통합은 필요하지 않은 기능도 호출이 되므
로 실질적으로 필요한 기능만 호출할 수 있어야 함
Involved Party
Person Organization
인터페이스
Involved
Party
Person Organization
인터페이스
인터페이스에 대한 분리
의존관계 역전 원칙
 Dependency inversion principle
 “프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안
된다.” 의존성 주입은 이 원칙을 따르는 방법 중 하나다.
 고차원의 모듈은 저차원의 모듈에 의존하면 안된다. 이 두 모
듈 모두 다른 추상화된 것에 의존한다.
 추상화 된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것
이 추상화된 것에 의존해야 한다.
 자주 변경되는 구상 클래스(Concreate class)에 의존하지 마
라. 만약 어떤 클래스에서 상속받아야 한다면, 기반 클래스를
추상 클래스로 만들어라. 만약 어떤 클래스의 참조(Reference)
를 가져야 한다면, 참조 대상이 되는 클래스를 추상 클래스로
만들어라. 만약 어떤 함수를 호출해야 한다면, 호출 되는 함수
를 추상 함수로 만들어야 합니다.
의존관계 역전 원칙: 예시
 각 레이어별로 역할이 정해져 있으면 역참조를 할 수 없도록 구성해야 함
 역참조가 발생할 수 있는 것은 BCS(Business common service) Layer 를 구성해서
역전이 발생하지 않도록 처리
 레이어도 무한정 정리할 수 없으므로 타 시스템 연계 등을 EIS(Enterprise Interface
Service)Layer로 구분하여 의존관계 역전 원칙 준수
Application Service layer
Process Service layer
Domain Service layer
ORM Service layer
B
C
S
L
A
Y
E
R
E
I
S
L
A
Y
E
R
외부
시스템
Class란?
클래스 명명규칙 및 정의
 클래스 명명규칙과 정의는 그 클래스가 무엇인지를 설명해야 하고 명확한 책임성을 반영되어
야 함
 클래스가 식별되면 책임성에 대해 정의하고 유사 개념 또는 중복성 여부를 판단할 명확한 근거를
정리해야 함
 클래스의 중요성을 간결하게 정의되어야 함
Class name
Attribute
Operation
 클래스 이름은 명확히 구별되어야 하며, 클래스 정의를 위한 명확한
구별이 가능해야 함
 왜 그 클래스가 업무에 중요한가를 나타낼 수 있는 명명을 지정하고
정의에서 세부적인 책임성을 설명해야 함
 클래스 정의는 “왜 이것이 업무에 중요한가?”라는 질문에 답을 해야
함
 필요한 경우, 클래스가 여러 기능, 공정, 조직 또는 시스템관점(view)
을 가로질러 사용 된다면, 그것이 적용되는 관점(view)을 명료하게 표
시한 각 뷰(관점)별로 정의사항을 추가하라
클래스 명명 및 정의시 작성되어야 할 사항
클래스 구성
 클래스에 대한 기술은 이 클래스의 인스턴스들을 생성하는 template역할을
한다.
 클래스는 데이터타입과 비슷하나, 클래스는 데이터와 함께 기능도가지고
있다.
Class name
Attribute
Operation
object object object …..
생성
생성
생성
클래스의 성질
 기업이 실제 처리하는 비즈니스 도메인의 범위 안에 있어야 함
 기업이 그에 대한 정보를 보관코자 하는 어떤 것을 나타냄
 클래스의 속성들의 응집성에 의해 결정된 단일개념을 나타냄
 하나의 실제사물(객체)이 아니라 동종 또는 유사 사물의 집합을 나타냄
 집합의 본질을 희석시키지 않고, 해당 클래스내의 객체를 구별할 수 있는 능력을 제공 함
B 단위 업무 영역
A 단위 업무 영
역
C 단위 업무 영역
실세계 업무 범위
클래스가 갖춰야 할 요건
 클래스들은 실세계를 가능한 완벽하게 추상화 시켜야 한다.
 실세계를 제대로 추상화해 내지 못하면 좋은 시스템을 기대할 수 없다.
 정보는 기능이나 데이터가 아닌 클래스들을 중심으로 국지화되어야 한다.
 클래스들의 구현방법은 철저하게 외부로 부터 숨겨져야 하며, 밖으로는 잘 정의된 인터페이스만이 나타나야 한
다.(구현적 의미에서 보면)
객체 영역
A Class name
Attribute
Operation
B Class name
Attribute
Operation
추상화
Class/Object 식별 기준
카테고리화에 의한 분류:상품
 새로운 클래스를 설정하고 기존 클래스와 연관 예정이나 비즈니스 규칙과 같은 보다
추상적인 개념을 다루거나 실물과 지식의 구별을 강조
 유사한 개념은 하나의 개념으로 묶어 그룹화하여 하나의 범주로 통합하여야 함
 개념의 공통성을 찾아 하나의 범주로 묶어야 함
일반대출 계좌
주택대출 계좌
지급보증 계좌
…..
여신 계좌
Category 화
 상품 소분류나 중분류별
관리되는 계좌정보에 대해
통합된 개념으 Category
화 필요
 개념 사물에 대한 세부
원칙을 통합관리 기준으로
분리
보통예금 계좌
저축예금 계좌
정기적금 계좌
…..
예금 계좌
Category 화 Category 화
계약
카테고리화에 의한 분류: 서비스
 금융상품을 제외한 다양한 서비스에 대한 처리에 대
한 계약 처리
 송금, 지급결제, 환전 등이 별도 거래
기타 판매
기타 수납
대여금고
…..
기타 서비스
Category 화
 금융상품을 제외한 다양
한 서비스에 대한 계약에
따른 세부 분리
송금
지급결제
환전
…..
금전서비스
Category 화 Category 화
계약
집합으로 규정할 수 있어야 함
 동일한 부류나 범주의 집합으로 규정하여 클래스간의 책임성 중복이 발생
하지 않아야 함
 집합으로 정의할 수 있도록 명확한 분류 기준을 수립해야 함
 집합에 속한 객체들이 중복되지 않도록 명확해야 함
계약
고객과의 수신, 여신 상
품을 신규할 경우 계약
조건 등 계약에 필요한
정보를 관리
=
집합 정의
공통성과 변이성을 구분
 비즈니스 소프트웨어의 복잡성의 가장 중요한 원인은 ‘변형(variation)’의 규모에서
온다.
 이러한 변형 경우를 분석함으로써 ‘공통점(Commonality)’을 추출할 수 있다.
 클래스 복잡성을 해결하기 위한 핵심은 공통점과 변형을 구분하는 데 있다.
James
.part-time
.weekly-paid
John
.full-time
.weekly-paid
Jane
.part-time
.monthly-paid
공통점 분석 후,…
[Payment Type]
.weekly-paid
.monthly-paid
[Working Style]
.part-time
.full-time
[Worker]
.name
. …

공통점 변형
독립적인 집합 이어야 함
 어떤 다른 집합과는 본질적으로 다른 자기 혼자만의 고유한 집합이어야 한
다는 것
 다른 집합의 부분집합이되거나 다른 집합과의 교집합을 가지지 않아야 한
다는 것
계약 거래상품
하나의 독립적인 집합으로 유지되며 독립적인 사물로써 상호작용을 수행
사물(Things) 정의
 대상 문제에 있어 명확한 경계와 의미를 가진 것이 객체이며, 공동 의미, 행
동을 가진 객체 그룹
 실존하는 집합으로써 다른 집합들과 구별(Identify)할 수 있는 것
 어떤 사물의 집합. 이 집합 안의 사물들은 같은 특징을 공유하고, 같은 방식
으로 행동하고, 같은 규칙과 정책을 준수함
통장 증서 수표 어음
실제 비즈니스에서 존재하는 사물들을 하나의 집합으로 묶어 클래스화
비사물(Non-Things) 정의
 비즈니스 내의 관행 등으로 관리되는 논리적인 관리대상을 객체들의 집합
을 식별하는 것
 논리적인 이유로 같은 부류에 속하는 객체들의 집합을 식별하는 것
 공통성을 찾아 의미적으로 통합하여 하나의 집합으로 묶을 수 있어야 함
계약
자기앞수표
발행
제사고신고 거래
비즈니스에서 관리되는 개념 객체들을 그룹화하여 클래스 화
행위관리 대상체의 분리
 사물에 대한 복잡성 완화를 위해 객체들에 대한 고유정보와 행위관리를 위
한 책임성을 분리하여야 함
 행위가 반복적으로 발생하는 주체와 그 행위가 대상이 되는 사물정보에 대
해 분리하여 관리함
계약상품
계약조건상품조건
기업의 판매되는 사물 대상체 판매된 행위관리 대상체
사물과 행위관리
기준으로 분리
서브 클래스화에 의한 분류
 기존 클래스를 특수화해 서브클래스를 설정
 서브 클래스마다 데이터나 메소드가 달라지는 경우 또는 별개의 클
래스와 연관을 가지는 등 모델구조의 차이를 강조하기 위해 사용
계약
수신 계약 대출 계약
지급보증
계약
수신관련
Class
대출관련
Class
지급보증
관련
Class
특정 비
즈니스
를 수용
을 위한
Level
세부 업무별
특화된 처리
자기참조를 위한 계층 구조화
 자기 참조가 되는 구조를 구성하여 계층구조를 만들
어속성과 메소드의 중복 해결해야 함
 새로운 계층의 추가에 대응을 통한 구조변경 용이
고객
개인 조직
재귀적인 호출을 위해 계
층구조
클래스간의 상호작용 확장
 실제 객체들을 클래스화하면서 응집도를 높이기 위해서는 식별된 클래스
간의 관계 및 상호인터페이스 기준을 명확히 설정해야 함
 클래스간의 상호관계가 명확히 될 수록 클래스간의 커플링이 약하게 구성
되어 다른 클래스와의 상호작용이 용이함
계좌 거래내역
타점권
내역
 계좌의 책임성을 계좌생
명주기로 축소
 계좌내의 입출금이 발생
하는 모든 이벤트에 대한 책
임성을 거래내역에 부여
 계좌내의 입금 발생시 거
래내역에 속한 타점권 정보
관리에 대한 책임성을 부여
입금발생시 사물
정보인 타점권
관리책임 분리
계좌개설 및 해
지까지의 관리책
임 분리
관리하고자 하는 대상 확장
 '관리하고자 하는' 이란 의미는 관리하고자 하는 정보만을 클래스로 취할 것임을 의미한다.
 업무의 목적과 범위, 전략, 방향에 따라 클래스로 취할 수도 있고 버릴 수도 있다는 것을 의미한
다. 그렇다면 먼저 이러한 부분이 분명하게 정의하는 것은 매우 중요한 일일 것이다.
 현재 우리가 관리하고자 하는 것과 앞으로 관리하고자 하는 것까지도 포함하는 말이다.
계약
거래
계약이후 계약이 종료시까지
세부적인 행위내역을 관리
계약에 대한 행위를 관리
고객과의 계약이후 해제까지의 비즈니스적 관리 대상
계약
생명주기
거래
생명주기
계약
조건변경
거래
입출금
거래

Mais conteúdo relacionado

Mais procurados

python data model 이해하기
python data model 이해하기python data model 이해하기
python data model 이해하기Yong Joon Moon
 
파이썬+데이터+구조+이해하기 20160311
파이썬+데이터+구조+이해하기 20160311파이썬+데이터+구조+이해하기 20160311
파이썬+데이터+구조+이해하기 20160311Yong Joon Moon
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기Yong Joon Moon
 
파이썬+함수 데코레이터+이해하기 20160229
파이썬+함수 데코레이터+이해하기 20160229파이썬+함수 데코레이터+이해하기 20160229
파이썬+함수 데코레이터+이해하기 20160229Yong Joon Moon
 
파이썬정리 20160130
파이썬정리 20160130파이썬정리 20160130
파이썬정리 20160130Yong Joon Moon
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기 Yong Joon Moon
 
파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기Yong Joon Moon
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409Yong Joon Moon
 
파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기Yong Joon Moon
 
Reflect package 사용하기
Reflect package 사용하기Reflect package 사용하기
Reflect package 사용하기Yong Joon Moon
 
파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기Yong Joon Moon
 
파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301Yong Joon Moon
 
파이썬 class 및 인스턴스 생성 이해하기
파이썬 class 및 인스턴스 생성 이해하기파이썬 class 및 인스턴스 생성 이해하기
파이썬 class 및 인스턴스 생성 이해하기Yong Joon Moon
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
Python+numpy pandas 4편
Python+numpy pandas 4편Python+numpy pandas 4편
Python+numpy pandas 4편Yong Joon Moon
 
파이썬 Collections 모듈 이해하기
파이썬 Collections 모듈 이해하기파이썬 Collections 모듈 이해하기
파이썬 Collections 모듈 이해하기Yong Joon Moon
 
엘라스틱서치 이해하기 20160612
엘라스틱서치 이해하기 20160612엘라스틱서치 이해하기 20160612
엘라스틱서치 이해하기 20160612Yong Joon Moon
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기Yong Joon Moon
 
Processing 기초 이해하기_20160713
Processing 기초 이해하기_20160713Processing 기초 이해하기_20160713
Processing 기초 이해하기_20160713Yong Joon Moon
 

Mais procurados (20)

python data model 이해하기
python data model 이해하기python data model 이해하기
python data model 이해하기
 
파이썬+데이터+구조+이해하기 20160311
파이썬+데이터+구조+이해하기 20160311파이썬+데이터+구조+이해하기 20160311
파이썬+데이터+구조+이해하기 20160311
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기
 
파이썬+함수 데코레이터+이해하기 20160229
파이썬+함수 데코레이터+이해하기 20160229파이썬+함수 데코레이터+이해하기 20160229
파이썬+함수 데코레이터+이해하기 20160229
 
파이썬정리 20160130
파이썬정리 20160130파이썬정리 20160130
파이썬정리 20160130
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기
 
파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409
 
파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기
 
Reflect package 사용하기
Reflect package 사용하기Reflect package 사용하기
Reflect package 사용하기
 
파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기
 
파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301파이썬+Json+이해하기 20160301
파이썬+Json+이해하기 20160301
 
파이썬 class 및 인스턴스 생성 이해하기
파이썬 class 및 인스턴스 생성 이해하기파이썬 class 및 인스턴스 생성 이해하기
파이썬 class 및 인스턴스 생성 이해하기
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
파이썬 심화
파이썬 심화파이썬 심화
파이썬 심화
 
Python+numpy pandas 4편
Python+numpy pandas 4편Python+numpy pandas 4편
Python+numpy pandas 4편
 
파이썬 Collections 모듈 이해하기
파이썬 Collections 모듈 이해하기파이썬 Collections 모듈 이해하기
파이썬 Collections 모듈 이해하기
 
엘라스틱서치 이해하기 20160612
엘라스틱서치 이해하기 20160612엘라스틱서치 이해하기 20160612
엘라스틱서치 이해하기 20160612
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기
 
Processing 기초 이해하기_20160713
Processing 기초 이해하기_20160713Processing 기초 이해하기_20160713
Processing 기초 이해하기_20160713
 

Semelhante a 파이썬+객체지향+이해하기 20160131

Python Programming: Class and Object Oriented Programming
Python Programming: Class and Object Oriented ProgrammingPython Programming: Class and Object Oriented Programming
Python Programming: Class and Object Oriented ProgrammingChan Shik Lim
 
Smalltalk at Altlang 2008
Smalltalk at Altlang 2008Smalltalk at Altlang 2008
Smalltalk at Altlang 2008daliot
 
Java, android 스터티2
Java, android 스터티2Java, android 스터티2
Java, android 스터티2Heejun Kim
 
Android Programming
Android ProgrammingAndroid Programming
Android ProgrammingJake Yoon
 
Android Programming - Input
Android Programming - InputAndroid Programming - Input
Android Programming - InputJake Yoon
 
Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)승욱 정
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)문익 장
 
The c++ programming language 10장 클래스 발표
The c++ programming language 10장 클래스 발표The c++ programming language 10장 클래스 발표
The c++ programming language 10장 클래스 발표재정 이
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지SeongHyun Ahn
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리ssuser7c5a40
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7Yeonah Ki
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스SeoYeong
 
2014-15 Intermediate C++ Study #6
2014-15 Intermediate C++ Study #62014-15 Intermediate C++ Study #6
2014-15 Intermediate C++ Study #6Chris Ohk
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++KWANGIL KIM
 
Python Programming: Function
Python Programming: FunctionPython Programming: Function
Python Programming: FunctionChan Shik Lim
 
Python class
Python classPython class
Python classHerren
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initializationEunjoo Im
 

Semelhante a 파이썬+객체지향+이해하기 20160131 (20)

Python Programming: Class and Object Oriented Programming
Python Programming: Class and Object Oriented ProgrammingPython Programming: Class and Object Oriented Programming
Python Programming: Class and Object Oriented Programming
 
Smalltalk at Altlang 2008
Smalltalk at Altlang 2008Smalltalk at Altlang 2008
Smalltalk at Altlang 2008
 
Java, android 스터티2
Java, android 스터티2Java, android 스터티2
Java, android 스터티2
 
Android Programming
Android ProgrammingAndroid Programming
Android Programming
 
Android Programming - Input
Android Programming - InputAndroid Programming - Input
Android Programming - Input
 
Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)
 
The c++ programming language 10장 클래스 발표
The c++ programming language 10장 클래스 발표The c++ programming language 10장 클래스 발표
The c++ programming language 10장 클래스 발표
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7
 
Java_05 class
Java_05 classJava_05 class
Java_05 class
 
Java class
Java classJava class
Java class
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스
 
2014-15 Intermediate C++ Study #6
2014-15 Intermediate C++ Study #62014-15 Intermediate C++ Study #6
2014-15 Intermediate C++ Study #6
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
 
Python Programming: Function
Python Programming: FunctionPython Programming: Function
Python Programming: Function
 
Python class
Python classPython class
Python class
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initialization
 
Python class
Python classPython class
Python class
 

Mais de Yong Joon Moon

Scala companion object
Scala companion objectScala companion object
Scala companion objectYong Joon Moon
 
Scala block expression
Scala block expressionScala block expression
Scala block expressionYong Joon Moon
 
Scala self type inheritance
Scala self type inheritanceScala self type inheritance
Scala self type inheritanceYong Joon Moon
 
Scala type class pattern
Scala type class patternScala type class pattern
Scala type class patternYong Joon Moon
 
Scala nested function generic function
Scala nested function generic functionScala nested function generic function
Scala nested function generic functionYong Joon Moon
 
스칼라 클래스 이해하기 _Scala class understanding
스칼라 클래스 이해하기 _Scala class understanding스칼라 클래스 이해하기 _Scala class understanding
스칼라 클래스 이해하기 _Scala class understandingYong Joon Moon
 
파이썬 문자열 이해하기
파이썬 문자열 이해하기파이썬 문자열 이해하기
파이썬 문자열 이해하기Yong Joon Moon
 
파이썬 내부 데이터 검색 방법
파이썬 내부 데이터 검색 방법파이썬 내부 데이터 검색 방법
파이썬 내부 데이터 검색 방법Yong Joon Moon
 
파이썬 Xml 이해하기
파이썬 Xml 이해하기파이썬 Xml 이해하기
파이썬 Xml 이해하기Yong Joon Moon
 
파이썬 엑셀_csv 처리하기
파이썬 엑셀_csv 처리하기파이썬 엑셀_csv 처리하기
파이썬 엑셀_csv 처리하기Yong Joon Moon
 
파이썬 파일처리 이해하기
파이썬 파일처리 이해하기파이썬 파일처리 이해하기
파이썬 파일처리 이해하기Yong Joon Moon
 

Mais de Yong Joon Moon (20)

rust ownership
rust ownership rust ownership
rust ownership
 
Scala namespace scope
Scala namespace scopeScala namespace scope
Scala namespace scope
 
Scala companion object
Scala companion objectScala companion object
Scala companion object
 
Scala block expression
Scala block expressionScala block expression
Scala block expression
 
Scala self type inheritance
Scala self type inheritanceScala self type inheritance
Scala self type inheritance
 
Scala variable
Scala variableScala variable
Scala variable
 
Scala type class pattern
Scala type class patternScala type class pattern
Scala type class pattern
 
Scala match pattern
Scala match patternScala match pattern
Scala match pattern
 
Scala implicit
Scala implicitScala implicit
Scala implicit
 
Scala type args
Scala type argsScala type args
Scala type args
 
Scala trait usage
Scala trait usageScala trait usage
Scala trait usage
 
Scala nested function generic function
Scala nested function generic functionScala nested function generic function
Scala nested function generic function
 
Scala dir processing
Scala dir processingScala dir processing
Scala dir processing
 
Scala syntax function
Scala syntax functionScala syntax function
Scala syntax function
 
스칼라 클래스 이해하기 _Scala class understanding
스칼라 클래스 이해하기 _Scala class understanding스칼라 클래스 이해하기 _Scala class understanding
스칼라 클래스 이해하기 _Scala class understanding
 
파이썬 문자열 이해하기
파이썬 문자열 이해하기파이썬 문자열 이해하기
파이썬 문자열 이해하기
 
파이썬 내부 데이터 검색 방법
파이썬 내부 데이터 검색 방법파이썬 내부 데이터 검색 방법
파이썬 내부 데이터 검색 방법
 
파이썬 Xml 이해하기
파이썬 Xml 이해하기파이썬 Xml 이해하기
파이썬 Xml 이해하기
 
파이썬 엑셀_csv 처리하기
파이썬 엑셀_csv 처리하기파이썬 엑셀_csv 처리하기
파이썬 엑셀_csv 처리하기
 
파이썬 파일처리 이해하기
파이썬 파일처리 이해하기파이썬 파일처리 이해하기
파이썬 파일처리 이해하기
 

파이썬+객체지향+이해하기 20160131

  • 4. 왜 모든 것을 객체로 관리하나? 모든 것은 객체 값 문자열 컨테이너 함수 클래스 튜플 리스트 딕션너리 집합 파이썬은 모든 것을 객체로 인식한다. 데이터 구조가 다 객체이므로 클래스를 가지고 생성시 참조를 가지고 있음 파일 모듈 패키지 모듈
  • 5. 객체로 구성했나? 실제 오퍼페이터를 내부적으로 메소드로 정의되어 있어서 메소드 처리로 인식되고 테이터 타입을 명확히 맞춰서 계 산처리 됨 1.+(1) 1 __add__(객체) >>> 1+1 2 >>> >>> 1.+1 2.0 >>> int(1.+1) 2 >>> >>> p=1 >>> p.__add__(1) 2 >>>
  • 7. Class Notation 파이썬 언어에서 객체를 만드는 타입을 Class를 정의하여 사용 클래스 명 변수 메소드 class 클래스이름[(상속 클래스명)]: <클래스 변수 1> <클래스 변수 2> ... def 인스턴스 메소드(self[, 인수1, 인수2,,,]): <수행할 문장 1> <수행할 문장 2> ... def 클래스메소드(cls[, 인수1, 인수2,,,]): <수행할 문장1> <수행할 문장2> ... def 정적메소드([, 인수1, 인수2,,,]): <수행할 문장1> <수행할 문장2> ...
  • 8. Instance Notation 인스턴스 객체는 실제 클래스 객체가 생성시 할당 인스턴스 변수와 메소드는 런타임 즉 실행시 등록하여 사용할 수 있음 인스턴스명 : 클래스명 인스턴스 변수 인스턴스 메소드 (인스턴스 바인딩 경우) class 클래스이름[(상속 클래스명)]: def __init__(self[, 인수1, 인수2,,,]): self.변수명 = 인수1 …… <수행할 문장 2> ... def 인스턴스메소드(self[, 인수1, 인수2,,,]): <수행할 문장1> <수행할 문장2> ... ... Instance명 = 클래스명( 초기인자들)
  • 9. Class로 Instance 처리 파이썬 언어에서 객체를 만드는 타입을 Class로 생성해서 처리 Class는 객체를 만드는 하나의 틀로 이용 자바 언어와의 차이점은 Class도 Object로 인식 Class Object Instance Object 1 Instance Object 2 Instance Object 3 instanciate 클래스에서 객체 생성하기
  • 11. 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} 인스턴스 메소드
  • 12. Predefined Class Attributes Attribute Type Read/Write Description __dict__ dictionary R/W The class name space. __name__ string R/O The name of the class. __bases__ tuple of classes R/O The classes from which this class inherits. __doc__ string OR None R/W The class documentation string __module__ string R/W The name of the module in which this class was defined.
  • 13. Instance Member Instance 생성시 self로 정의된 변수만 인스턴스 영역에서 관리하고 인 스턴스 메소드는 클래스에서 관리함 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 ins method ', 1) {'ins_var': 1} # 인스턴스 객체 관리 영역
  • 14. Predefined Instance Attributes Attribute Type Read/Write Description __dict__ dictionary R/W The instance name space. __class__ Base class R The base class __doc__ string OR None R/W The instance documentation string
  • 16. Object Namespace 흐름 Base class class instance instance instance 상속 인스턴스 생성 Dict{} Dict{} Dict{} Dict{} Dict{} Namespace 검색 객체는 자신들이 관리 하는 Namespace 공간 을 생성하며 객체 내의 속성이나 메 소드 호출시 이를 검색 해서 처리
  • 17. Class & instance scope Class Object는 인스턴스를 만드는 기준을 정리한다. 클래스를 정의한다고 하나의 저장공간(Namespace) 기준이 되는 것은 아니다. - 클래스 저장공간과 인스턴스 저장공간이 분리된다 User defined Class Instance Instance Instance Built-in Class 상속 인스턴스화 Object Scope Object Namespace
  • 18. Class/Instance 관계 매핑 Class 키워드로 클래스 정의 상속은 class 키워드 다음() 내에 상속할 클래스 정의 인스턴스 생성은 클래스명에 ()연산자 사용 Super ClassClassinstance 상속인스턴스화 class A(object): def whoami(self): return self.__class__.__name__ a = A()
  • 19. Class/Instance 관계 보기 내장 변수를 이용해서 Class와 Instance 관계를 확인 class A(object): def whoami(self): return self.__class__.__name__ a = A() print a.whoami() print a.__class__.__base__.__name__ 인스턴스의 클래스 이름 : A 인스턴스의 클래스의 상속 클래스 이름 : object
  • 21. 생성자 처리 구조 파이썬은 생성자는 클래스이 __init__()메소드를 binding 하여 처리 Instance = ClassA(인자) ClassA.__init__(instance,인자) ClassA( 상위클래스) : def __init__(self,인자) : # 생성자로직 Source code Execute code
  • 22. 생성자-Creating Instance 파이썬 생성자 __init__() 함수를 오버라이딩한 후 클래스이름(파라미터)를 이용하여 객체 생성 생성자 함수는 자동으로 연계됨 class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) 생성자 정의 인스턴스 객체 생성 생성자와 자동으로 연계
  • 23. 소멸자- Destroying Objects 클래스의 생성된 인스턴스를 삭제하는 메소드 #!/usr/bin/python class Point: def __init( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "destroyed" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts del pt1 del pt2 del pt3 소멸자 정의 소멸자 활용
  • 25. __init__과 __call__ 메소드 차이 클래스 생성자에 따른 인스턴스 생성 및 인스턴 스 호출에 대한 내장메소드 처리 class A: def __init__(self): print "init“ def __call__(self): print "call" A() # init A()() # init call a = A() #init a() # call 생성자와 인스턴스 호출 메소드 정의 생성자와 인스턴스 호출 메소드 정의
  • 26. 인스턴스 속성 미정의 후 생성 클래스 생성자에 인스턴스 속성을 미정의하고 인 스턴스를 호출시 실제 인스턴스가 없으므로 오류 처리 >>> class A: ... def __init__(self): ... print "From init ... " ... >>> a = A() From init ... >>> a() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: A instance has no __call__ method >>>
  • 27. 인스턴스 속성 미정의 후 호출 인스턴스 속성 미정의할 경우 반드시 인스턴스 처리하는 __call__ 메소드를 정의하여 처리해야 함 >>> class B: ... def __init__(self): ... print "From init ... " ... def __call__(self): ... print "From call ... " ... >>> b = B() From init ... >>> b() From call ... >>>
  • 28. Class decorator : 기본  생성자에서 함수 전달, 인스턴스 호출에서 함수의 파라미터 전달  전달함수 실행시 생성자 실행 및 인스턴스 실행 #테코레이터 클래스 정의하고 생성자에 전달 class decoratorWithoutArguments(object): def __init__(self, f): print ("Inside __init__()") self.f = f #호출하는 곳에 내부함수 처리 로직 처리 def __call__(self, *args): print( "Inside __call__()") self.f(*args) print( "After self.f(*args)") #데코레이터 정의 및 전달함수 정의 @decoratorWithoutArguments def sayHello(a1, a2, a3, a4): print( 'sayHello arguments:', a1, a2, a3, a4) 데코레이터 클래스 정의 전달 함수 정의 함수 실행 #데코레이터 호출 print ("Preparing to call sayHello()") sayHello("say", "hello", "argument", "list") print ("After first sayHello() call") sayHello("a", "different", "set of", "arguments") print ("After second sayHello() call"))
  • 30. Class 멤버 접근자 - cls 클래스 객체의 변수나 메소드 접근을 위해 cls 키워 드 사용
  • 31. Instance 멤버 접근자-self 인스턴스객체 메소드의 첫 인자는 Self를 사용하여 각 인스턴스별로 메소드를 호출하여 사용할 수 있 도록 정의
  • 32. Method- Instance 클래스 객체에서 생성되는 모든 인스턴스 객체에서 활용되므로 클래스 이름공간에서 관리 메소드 첫 파라미터에 self라는 명칭을 정의
  • 33. Method- 클래스 decorator 클래스 객체에서 처리되는 메소드를 정의한다. 클래스 메소 드는 첫번째 파라미터에 cls를 전달한다. 장식자 @classmethod : 클래스 함수 위에 표시-Python 2.x 함수 classmethod() : 별도 문장으로 표시 – Python 3.x 인스턴스 객체도 호출이 가능
  • 34. Method- 정적 decorator 클래스 객체로 생성된 모든 인스턴스 객체가 공유하여 사용 할 수 있다. 장식자 @staticmethod : 정적함수 위에 표시 – Python 2.x 함수 staticmethod()는 별도의 문장으로 표시 –Python 3.x 정적메소드는 파라미터에 별도의 self, cls, 등 객체에 대한 참조값을 전달하지 않아도 됨 인스턴스 객체에서도 호출이 가능
  • 35. Accessing Members 클래스를 정의한 후에 인스턴스를 생성하고 메소 드 호출 및 클래스 변수를 직접 호출하여 출력 class Employee: 'Common base class for all employees‘ empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary Class 정의 #인스턴스 객체 생성 : 생성자 호출 emp1 = Employee("Zara", 2000) # 인스턴스 메소드 호출 emp1.displayEmployee() #인스턴스 객체 생성 : 생성자 호출 emp2 = Employee("Manni", 5000) # 인스턴스 메소드 호출 emp2.displayEmployee() #클래스 변수 호출 및 출력 print "Total Employee %d" % Employee.empCount Instance 생성 및 호출
  • 36. Method Bound/unbound(1) 클래스이름과 인스턴스이름으로 메소드를 호출 하면 bounding 처리 됨 메소드 선언시 인자로 self, cls를 정의되어 있음 >>> class Preson() : ... def printP(self) : ... print(' instance method ') ... def printC(cls) : ... print(' class method') … >>> p = Preson() # 인스턴스 생성 >>> p.printP() #인스턴스 메소드 bounding instance method >>> Preson.printP(p) # 인스턴스 메소드 unbounding instance method >>>  인스턴스를 생성하고  인스턴스 메소드 호출시는 bounding 처리  클래스로 인스턴스 메소드 호출시는 인자로 인스턴스 객체를 전달해서 unbounding
  • 37. Method Bound/unbound(2) 메소드 선언시 인자로 self, cls를 정의되어 있는 것에 따라 매칭시켜야 됨 Transformation Called from an Object Called from a Class Instance method f(*args) f(obj,*args) Static method f(*args) f(*args) Class method f(cls, *args) f(*args)
  • 39. Inheritance 상속은 상위 클래스를 하나 또는 여러 개를 사용하는 방법 class 상위 클래스명 : pass class 클래스명(상위 클래스명) : pass 상속 정의시 파라미터로 상위 클래스명을 여러 개 작 성시 멀티 상속이 가능함 class 클래스명(상위 클래스명, 상위 클래스명) : pass
  • 40. Class 구조 클래스는 슈퍼클래스를 상속 Super ClassClass 상속 class A(object): def __init__(self) : self.instanceS = " static instance member" def whoami(self): return self.__class__.__name__
  • 41. 클래스 구조 예시(1) >>> one = 1 >>> type(one) <type 'int'> >>> type(type(one)) <type 'type'> >>> type(one).__bases__ (<type 'object'>,) >>> >>> object <type 'object'> >>> type <type 'type'> >>> type(object) <type 'type'> >>> object.__class__ <type 'type'> >>> object.__bases__ () >>> type.__class__ <type 'type'> >>> type.__bases__ (<type 'object'>,) >>> isinstance(object, object) True >>> isinstance(type, object) True >>> isinstance(object, type) True objecttype int float str 클래스 구조
  • 42. 클래스 구조 예시(2) >>> list <type 'list'> >>> list.__class__ <type 'type'> >>> list.__bases__ (<type 'object'>,) >>> tuple.__class__, tuple.__bases__ (<type 'type'>, (<type 'object'>,)) >>> dict.__class__, dict.__bases__ (<type 'type'>, (<type 'object'>,)) >>> >>> mylist = [1,2,3] >>> mylist.__class__ <type 'list'> 데이터 타입은 상속을 받을 때 타입 객체를 바로 받지만 base는 object 클래스를 처리 객체 생성 예시 메타클래스 클래스 인스턴스 type object list mylist
  • 43. Inheritance- scope 상속된 클래스도 검색하는 순서가 파라미터를 정리 한 순서대로 변수나 메소드를 검색하여 처리됨 상속된 클래스에 동일한 이름이 변수나 메소드가 존 재시 첫번째 검색된 것으로 처리함 class 클래스명(상위 클래스명, 상위 클래스명) : pass
  • 44. Inheritance - 예시 class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor“ def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method # 결과값 Calling child constructor Calling child method Calling parent method Parent attribute : 200 Class 정의 인스턴스 생성 및 호출
  • 45. Mixin 기존 상속구조에 대한 변경을 최소화하기 위해 메소 드기반의 클래스 생성하여 상속받아 처리하는 방법 class Mixin : def add(self,x,y) : return self.x + self.y def sub(self,x,y) : if isinstance(self, String) : return " String no support" else : return self.x - self.y class Number(Mixin) : def __init__(self, x,y) : self.x = x self.y = y class String(Mixin) : def __init__(self, x,y) : self.x = x self.y = y n1 = Number(5,6) n1.add(n1.x,n1.y) n1.sub(n1.x,n1.y) s1 = String("hello ", "world") print s1.add(s1.x, s1.y) print s1.sub(s1.x, s1.y) 인스턴스 생성 및 호출
  • 47. MRO 처리 Method resolution order는 상속에 대한 처리 순서를 명확히 표시 class test1 : print " test1 “ print test1.mro() # 실행 결과 AttributeError: class test1 has no attribute 'mro' class test1(object) : print " test1 " print test1.mro() # 실행 결과 test1 [<class '__main__.test1'>, <type 'object'>] '
  • 48. 상속 : __mro__, mro() 상속인 경우 클래스 객체들이 우선순서를 확인하 는 속성과 메소드 class Base1(object): def amethod(self): print "Base1" class Base2(Base1): pass class Base3(object): def amethod(self): print "Base3" class test(Base2,Base3) : A = 'aaaa‘ instance = test() instance.amethod() print test.__mro__ print test.mro() # 실행 결과 Base1 (<class '__main__.test'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>) [<class '__main__.test'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>]
  • 49. 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의 값
  • 50. 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'
  • 51. 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’) 처럼 인식
  • 52. Super() 함수(3.x) 파이썬 3.x 버전부터 super()함수이 파라미터가 없 어도 자동으로 스택프레임에서 검색하여 처리함
  • 54. Overriding 메소드를 이름으로 검색하므로 하위 클래스에 동 일한 메소드가 존재하면 인스턴스 호출시 하위 클래스 메소드 부터 호출하므로 Overriding 처리 class 상위 클래스명 : def method(self) : pass class 클래스명(상위 클래스명) : def method(self) : pass
  • 55. Overriding 구조 동일한 메소드를 instance/Class/Super Class에 다 정의할 경우 실행시 instance부터 호출이 되는 구 조 Super ClassClassinstance 상속인스턴스화 클래스 정의 시 메소드 클래스 정의 시 슈퍼 클래스메소 드 재정의 Runtime 시 클래스 및 슈퍼클래 스 메소드 정의 Overriding 발생 Overriding 발생
  • 56. 연산자 Overriding 예시 Super ClassClassinstance 상속인스턴스화 Overriding 발생 class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) # __init__ 생성자 메소드 overriding v1 = Vector(2,10) v2 = Vector(5,-2) # __add__ 메소드 overriding print v1 + v2 # __str__ 메소드 overriding print v1
  • 57. __getattr__/__setattr__ 메소드 인스턴스에서 상속된 부모 클래스의 속성을 조회 및 갱신이 가능 >>> dir(dict) ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', ….'] >>> dict 클래스에서 보관하는 속성을 조회 >>> # dict 인스턴스 생성하고 dict 내 >>> # 매소드 호출 >>> d = {'a': 1} >>> d.__getattribute__('__class__') <type 'dict'> >>> dict 클래스의 인스턴스로 클래스 내부의 속성을 조 회
  • 58. ./[] 연사자 overriding 다른 클래스를 만들어서 연산자를 다양하게 사용 하기 위해 오버라이딩 처리 class Test1(dict) : def __getattr__(self,name) : return self[name] def __setattr__(self,name, value) : self[name] = value t1 = Test1() t1.a= 10 t1['btest'] = 100 print t1.a print t1['btest'] print t1.__dict__ print t1 #결과값 10 100 {} {'a': 10, 'btest': 100} Super Class Classinstance 상속인스턴 스화 Overriding 발생
  • 59. ./[] 연사자 overriding - 설명 부모 클래스의 메소드를 재정의해서 현재 클래스 의 메소드가 호출되도록 처리 class Test1(dict) : def __getattr__(self,name) : return self[name] def __setattr__(self,name, value) : self[name] = value 1. dict 클래스의 __getattr__, __setattr__ 메소드에 대한 오 버라이딩 처리 2. dict 타입이라서 실제 self 내부 데이터 타입에 저장됨
  • 61. Instance 구조 클래스는 슈퍼클래스를 상속하고 인스턴스를 만 들어서 실제 기능들을 동작시킨다. Super ClassClassinstance 상속인스턴스화
  • 62. Instance 생성 방식 클래스명에 파라미터에 인스턴스 변수값을 정의해 서 인스턴스를 생성함 인스턴스 생성시 생성자가 호출되어 처리됨 변수명 = 클래스명(인스턴스 변 수값,인스턴스 변수값) def __init__(self, 인스턴스 변수 값,인스턴스 변수값) : self.인스턴스 변수 = 인스턴 스변수값 매칭호출시 매칭됨
  • 63. Instance 생성 예시 Class 키워드로 클래스 정의 상속은 class 키워드 다음() 내에 상속할 클래스 정의 인스턴스 생성은 클래스명에 ()연산자 사용 Super ClassClassinstance 상속인스턴스화 class A(object): def whoami(self): return self.__class__.__name__ a = A()
  • 64. Instance Scope 객체들간의 관계(상속 및 instance 생성 등)에 따라 객체 멤버들에 대 한 접근을 처리 검색 순서 : 인스턴스> 클래스> 상속클래스>builtin Class 상속이 많아지면 다양한 상위 멤버들을 접근하여 처리할 수 있다.
  • 65. Predefined Instance Attributes Attribute Type Read/Write Description __dict__ dictionary R/W The instance name space __class__ class R/W The class of this instance
  • 67. Members(변수) Access Class/Instance 객체에 생성된 변수에 대한 구조 및 접근 방법 >>> # class 정의 >>> class C(object): ... classattr = "attr on class“ ... >>> #객체 생성 후 멤버 접근 >>> cobj = C() >>> cobj.instattr = "attr on instance" >>> >>> cobj.instattr 'attr on instance' >>> cobj.classattr 'attr on class‘ 멤버접근연사자(.)를 이용하여 접근 C classattr cobj:C instattr cobj = C()
  • 68. Members(변수) Access -세부 Class/Instance 객체는 내장 __dict__ 멤버(변수)에 내부 정의 멤버들을 관리함 >>> # 내장 __dict__를 이용한 멤버 접근 >>> # Class 멤버 >>> C.__dict__['classattr'] 'attr on class' >>> # Instance 멤버 >>> cobj.__dict__['instattr'] 'attr on instance' >>> >>> C.__dict__ {'classattr': 'attr on class', '__module__': '__main__', '__doc__': None} >>> >>> >>> cobj.__dict__ {'instattr': 'attr on instance'} >>> C cobj:C cobj = C() __dict__:dict classattr __dict__:dict classattr 내장 객체 내장 객체
  • 69. Members(메소드) Access Class 정의시 인스턴스 메소드 정의를 하면 Class 영역에 설정 >>> #Class 생성 >>> class C(object): ... classattr = "attr on class“ ... def f(self): ... return "function f" ... >>> # 객체 생성 >>> cobj = C() >>> # 변수 비교 >>> cobj.classattr is C.__dict__['classattr'] True 변수 비교 C classattr f cobj:C instattr cobj = C()
  • 70. Members(메소드) Access-세부 인스턴스에서 인스턴스메소드 호출하면 실제 인스 턴스 메소드 실행환경은 인스턴스에 생성되어 처리 >>> #인스턴스에서 실행될 때 바운드 영역이 다름 >>> # is 연산자는 동일 객체 체계 >>> cobj.f is C.__dict__['f'] False >>> >>> C.__dict__ {'classattr': 'attr on class', '__module__': '__main__', '__doc__': None, 'f': <function f at 0x008F6B70>} >>> 인스턴스에 수행되는 메소드 주소가 다름 >>> cobj.f <bound method C.f of <__main__.C instance at 0x008F9850>> >>> # 인스턴스 메소드는 별도의 영역에 만들어짐 >>> # 인스턴스 내에 생성된 메소드를 검색 >>> C.__dict__['f'].__get__(cobj, C) <bound method C.f of <__main__.C instance at 0x008F9850>> C cobj:C cobj = C() __dict__:dict classattr f __dict__:dict classattr f 내장 객체 내장 객체
  • 71. Controlling Attribute Access Instance의 Attribute에 대한 접근을 할 수 있는 내 부 함수 __getattr__(self, name) __setattr__(self, name, value) __delattr__(self, name) __getattribute__(self, name)
  • 72. Controlling Attribute Access 인스턴스의 속성에 대한 접근을 내부 함수로 구현하 여 접근 class A() : __slots__ =['person_id', 'name'] def __init__(self, person_id, name) : self.person_id = person_id self.name = name def __getattr__(self, name) : return self.__dict__[name] def __setattr__(self, name, value): if name in A.__slots__ : self.__dict__[name] = value else: raise Exception(" no match attribute") def __delattr__(self, name) : del self.__dict__[name] def __getattribute__(self, name): return self.__dict__[name] a = A(1,'dahl') print a.__getattr__('name') print a.__getattr__('person_id') print a.__dict__ print a.__setattr__('name','moon') print a.__setattr__('person_id',2) print a.__getattr__('name') print a.__getattr__('person_id') print a.__delattr__('name') print a.__dict__ a.name = 'gahl' #a.s = 1 print a.__dict__
  • 74. Association 객체간에 관계를 구성하여 처리 객체내부에 관계 객체를 생성하여 해당 객체의 기능을 처리 A B
  • 75. Association:Object Chain #class 정의하고 인스턴스에서 타 객체를 호출 class A: def __init__(self ): print 'a' self.b = B() #object chain을 하는 class 생성 class B: def __init__(self ): print 'b' def bbb(self): print "B instance method " a = A() print a.b.bbb() 객체들간의 연결고리(Association, Composite 관계)가 있을 경 우 메소드 결과값을 객체로 받아 연속적으로 실행하도록 처리 객체.내부객체.메소 드 처리 #결과값 a b B instance method None
  • 76. Dependency 객체간에 관계를 구성하여 처리 객체내부에 관계 객체로써 메소드 등에서 일회성으로 해당 객체를 생성하여 기능 을 처리 A B
  • 77. Dependency: Method Chain class C: def __init__(self ): print 'a' self.b = B() def ccc(self, b) : return b.bbb() #object chain을 하는 class 생성 class B: def __init__(self ): print 'b' def bbb(self): print "B instance method " a = C() print a.b.bbb() print a.ccc(B()) 객체의 관계가 일회성 적으로 처리가 되는 관계 객체.메소드(인스턴스 객체) 처리 #결과값 a b B instance method None b B instance method None
  • 78. Self Method Chain class Person: def name(self, value): self.name = value return self def age(self, value): self.age = value return self def introduce(self): print "Hello, my name is", self.name, "and I am", self.age, "years old." person = Person() #객체의 메소드를 연속적으로 호출하여 처리 person.name("Peter").age(21).introduce() 객체 내의 메소드의 결과를 자기자신으로 리턴하여 메소드를 연속해 호출하여 처리
  • 79. 타 객체 Method Chain class A: def __init__(self ): print 'a' self.b = B() class B: def __init__(self ): self.c = C() print 'b' def bbb(self): print "B instance method " return self.c class C: def __init__(self ): print 'c' def ccc(self): print "C instance method " 클래스 정의시 내부에서 인스턴스를 가진 경우 chain 처리를 위해 return으로 해당 객체를 전달 #결과값 a c b B instance method C instance method None a = A() print a.b.bbb().ccc()
  • 81. issubclass/isinstance 함수 >>> issubclass(list,object) True >>> list.__bases__ (<type 'object'>,) >>> issubclass(list, type) False >>> issubclass() : __bases__ 기준으로 상속관계 isinstance() : __ class__ 기준으로 인스턴스 객 체 관계 >>> isinstance(list, type) True >>> list.__class__ <type 'type'> >>> >>> isinstance(list, object) True >>> issubclass 처리 isinstance 처리
  • 82. Class & instance namespace Class Object는 클래스 메소드, 정적메소드, 클래스 내부 변수 등을 관리한다. 파이썬은 변수나 메소드 검색 기준이 인스턴스> 클래스 > Built-in Class 순으로 매 칭시키므로 .연산자를 이용하여 인스턴스도 메소드 호출이 가능하다. >>> class Simple : ... pass ... >>> Simple <class __main__.Simple at 0x0212B228> >>> Simple.__name__ 'Simple‘ >>> Simple.__dict__ {'__module__': '__main__', '__doc__': None} >>> s = Simple() >>> s.__dict__ {} >>> s.name = "Simple instance" >>> s.__dict__ {'name': 'Simple instance'} Instance 생성 및 인스턴스 멤버 추가Class 정의
  • 84. Descriptor 설명은 그 속성 접근 기술자 프로토콜의 방법에 의해 무시되었다 "바인딩 행동"을 가진 객체 속성 중 하나입니다 __get__(self, instance, owner), __set__(self,instance, value), __delete__(self, instance).
  • 85. Descriptor 종류 Method descriptor와 Data descripter 로 구분  Method descriptor는 __get__(self, instance, owner) 구현  Data descriptor는 __get__(self, instance, owner) __set__(self,instance, value), __delete__(self, instance) 구현
  • 86. Descriptor : int.__add__ Method descriptor로 구현되어 __get__(self, instance, owner) 가지고 있다 P =1 # 직접 호출 p.__add__(3) # 결과값 4 #인스턴스에서 호출 type(p).__add__.__get__(p,int)(3) #결과값 4 #class에서 호출 int.__add__.__get__(1,int)(3)
  • 87. Descriptor : binding behavior binding 하는 방법 Direct Call Instance Binding Class Binding Super Binding class D(object) : def __init__(self, x) : self.x = x def __get__(self,instance=None,cls=None) : return self.x class D1(D) : def __init__(self, x) : D.__init__(self,x) d = D(1) print " d" print d.__dict__ print d.x print " direct call",d.__get__() print " Class binding call ",D.__get__(d,d) print "instance binding",type(d).__get__(d,d) d1 = D1(2) print " d1" print d1.__dict__ print d1.x print " direct call",d1.__get__() print " Class binding call ", D1.__get__(d1,d1) print "instance binding",type(d1).__get__(d1,d1) print D1.mro() print "super binding",super(D1,d1).__get__(d1,d1)
  • 88. Creating data descriptor Data Descriptor 클래스를 생성해서 처리하는 방법 class Descriptor(object): def __init__(self): self._name = '' def __get__(self, instance, owner): print "Getting: %s" % self._name return self._name def __set__(self, instance, name): print "Setting: %s" % name self._name = name.title() def __delete__(self, instance): print "Deleting: %s" %self._name del self._name class Person(object): name = Descriptor() >>> user = Person() >>> user.name = 'john smith' Setting: john smith >>> user.name Getting: John Smith 'John Smith‘ >>> del user.name Deleting: John Smith
  • 89. Creating 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 생김)
  • 90. Creating Property–객체 직접 정의(2) 실제 인스턴스 객체의 변수에 접근하면 Property 객체의 메소드를 호출하여 처리되고 인스턴스 객 체의 변수값이 변경됨 p1 = P(1001) print id(p1.x) print P.__dict__['x'] print id(p1.__dict__['x']) print p1.x p1.x = -12 print p1.x print p1.__dict__ #처리결과값 44625868 <property object at 0x02C1D4E0> 44625868 1001 -12 {'x': -12}
  • 91. Creating Property decorator(1) 인스턴스 객체의 변수 접근을 메소드로 제약하기 위해서는 Property 객체로 인스턴스 객체의 변수를 Wrapping 해야 함 property(fget=None, fset=None, fdel=None, doc=None) class P: def __init__(self,x): self.x = x @property def x(self): return self.__x @x.setter def x(self, x): self.__x = x @x.deleter def x(self): del self.x Getter, setter, deleter 메 소드를 정의 인스턴스 객체의 변수명과 동일하게 Property 객체 생 성(내부에 _x 생김)
  • 92. Creating Property decorator(2) Property 객체 생성하여 처리하는 방식과 동일 p1 = P(1001) print id(p1.x) print P.__dict__['x'] print id(p1.__dict__['x']) print p1.x p1.x = -12 print p1.x print p1.__dict__ #처리결과값 44625916 <property object at 0x02C1D3C0> 44625916 1001 -12 {'x': -12}
  • 94. Built-in 내장함수 내장함수를 이용하여 객체의 속성에 대한 접근 getattr(object, name[, default]) setattr(object, name, value) delattr(object, name) hasattr(object, name) callable(object)
  • 95. Built-in 내장함수: 예시 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
  • 96. Built-in 내장함수: 예시 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
  • 98. Information hiding -변수 __명칭 : Private (객체 내부에서만 사용) 외부에서 호출시 mangling 되는 구조로 요청시 접근 가능 인스턴스._클래스명__명칭 _명칭 : protected (클래스 및 하위 클래스에서만 사용)
  • 99. Information hiding -변수예시 명칭 : public (파이썬은 공개되는 게 기본) __명칭 : Private (객체 내부에서만 사용) mangling 되는 구조로 명칭이 변경됨 호출시는 인스턴스._클래스명__명칭 _명칭 : protected (클래스 및 하위 클래스에서만 사용권고) “don’t touch this, unless you’re a subclass” >>>class foo: … def __secret(self): pass … foo.__secret => AttributeError: __secret >>>foo.__dict__ {'_foo__secret': <function __secret at fc328>, '__module__': '__main__', '__doc__': None} Private 메소드 정의 및 호출 Class Namespace 명칭
  • 100. Information hiding –변수-특별 __명칭__ : 내장된 변수나 함수 등을 정의
  • 101. Information hiding – Descriptor(Property) 파이썬은 Property 객체를 이용하여 객체내의 변수들의 접근을 메소드 로 제어한다. Descriptor 객체, Property 객체나 @property decorator를 이용 인스턴스 객체의 변수 명과 동일한 property 객체가 생성되어야 함 Class P Instance p1 {‘x’: } Descriptor /Property x 생성 인스턴스생성 p1.x 접근 Property 내 메소드 호출하여 처리
  • 103. Abstract Class 추상화 클래스란 직접 인스턴스를 만들지 못하고 상속을 받아 메소드 오버라이딩해서 사용하는 방 식 Concrete Class instance Obj = ConcreteClass() 인스턴스 객체 생성 Abstract Class instance Obj = ConcreteClass() 인스턴스 객체 생성 X Abstract Class Concrete Class instance ConcreteClass (Abstract Class) 상속 Obj = ConcreteClass() 인스턴스 객체 생성
  • 104. Abstract Class 정의 방법 추상화 클래스는 exception 및 abc 모듈 2가지 처리 방법으로 만들 수 있다. exception 방식 abc 모듈 방식 모든 메소드를 subclass에서 정의할 필요가 없다 오류처리 : NotImplementedError 모든 메소드를 subclass에서 정의해야 한다. 오류처리 : TypeError
  • 105. Abstract Class : exception 방식 클래스 정의 후에 메소드 실행 부분을 exception 처리하고 상속받은 클래스에서 메소드 오버라이 딩 처리 class Base: def foo(self): raise NotImplementedError("foo") def bar(self): raise NotImplementedError("bar") class Concrete(Base): def foo(self): return "foo() called" 상속 및 메소드 오버라이딩 추상클래스의 모든 메소 드를 구현할 필요없음
  • 106. Abstract Class : ABC 모듈 ABC 모듈을 이용하여 정의해서 추상클래스 정의 후 상속을 받아 메소드 오버라이딩 처리 from abc import ABCMeta, abstractmethod class Base(): __metaclass__=ABCMeta @abstractmethod def foo(self): pass @abstractmethod def bar(self): pass class Concrete(Base): def foo(self): pass def bar(self): pass 상속 및 메소드 오버라이딩 추상클래스의 모든 메소드를 구현되어야 함
  • 107. Abstract Class :property 정의 Abstract Class에서 decorator(@property)를 사용하여 처리하기 class 구현클래스명() : 변수명 @property def get메소드명 : @변수명.setter def set메소드명 : @변수명.deleter def del메소드명 : import abc class 추상클래스명() : __metaclass__ = abc.ABCMeta @abc.abstractproperty def get메소드명 : @변수명.setter def set메소드명 : @변수명.deleter def del메소드명 : 매칭
  • 108. Abstract Class :property 구현 Abstract Class에서 decorator(@property)를 사용하여 처리하기 import abc class Base(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def value(self): return 'Should never see this' @value.setter def value(self, newvalue): return class Implementation(Base): # private 처리 _value = 'Default value' @property def value(self): return self._value @value.setter def value(self, newvalue): self._value = newvalue abc 모듈을 이용해서 추상클래스 정의 추상클래스 상속받은 하위클래스 정의
  • 110. Duck typeing 정의 방법 다양한 클래스가 동일한 메소드를 처리할 수 있 도록 인터페이스를 갖도록 만드는 법 함수 클래스 Duck typing에 필요한 함수 정의 후 인스턴스들의 메소드 호출 처리 Duck typing에 필요한 클래스 정의 후 인스턴스들의 메소드 호출 처리
  • 111. Duck typeing : 함수 구현(1) Duck typeing 함수 정의 후 클래스에 동일한 메 소드 정의 def in_the_forest(duck): duck.quack() duck.feathers() class Duck: def quack(self): print("Quaaaaaack!") def feathers(self): print("The duck has white and gray feathers.") class Person: def quack(self): print("The person imitates a duck.") def feathers(self): print("The person takes a feather from the ground and shows it.") def name(self): print("John Smith") 함수 정의 클래스 정의
  • 112. Duck typeing : 함수 구현(2) Duck typeing 처리 def game(): donald = Duck() john = Person() in_the_forest(donald) in_the_forest(john) print "function duck typeing " game() # 실행 결과 function duck typeing Quaaaaaack! The duck has white and gray feathers. The person imitates a duck. The person takes a feather from the ground and shows it.
  • 113. Duck typeing : 클래스 구현(1) Duck typeing 클래스 정의 후 클래스에 동일한 메소드 정의 class InTheForest() : @staticmethod def quack(self) : self.quack() @staticmethod def feathers(self) : self.feathers() @classmethod def all(cls,self) : cls.quack(self) cls.feathers(self) class Duck: def quack(self): print("Quaaaaaack!") def feathers(self): print("The duck has white and gray feathers.") class Person: def quack(self): print("The person imitates a duck.") def feathers(self): print("The person takes a feather from the ground and shows it.") def name(self): print("John Smith") 함수 정의 클래스 정의
  • 114. Duck typeing : 클래스 구현(2) Duck typeing 처리 def gameC(): donald = Duck() john = Person() InTheForest.all(donald) InTheForest.all(john) print " class duck typeing " gameC() # 실행 결과 class duck typeing Quaaaaaack! The duck has white and gray feathers. The person imitates a duck. The person takes a feather from the ground and shows it.
  • 117. Inspect module module에 대한 다양한 점검을 위한 함수를 제공 Function Description inspect.getmoduleinfo(path) 모듈에 대한 정보를 가져오기 ModuleInfo(name='in_test', suffix='.py', mode='U', module_type=1) inspect.getmodulename(path) 모듈 네임만 문자열로 가져옴 in_test inspect.ismodule(object) import한 모듈을 확인 여부
  • 118. Inspect 객체 객체에 대한 다양한 점검을 위한 함수를 제공 Function Description inspect.getmembers(object[, predicat e] 객체의 멤버를 튜플(키와 값)로 표시 inspect.isclass(object) Object에 클래스가 들어가면 True이고 나머지는 False inspect.ismethod(object) Object가 메소드 여부 inspect.isabstract(object) Object가 추상클래스 여부 inspect.ismethoddescriptor(object) int.__add__ 처럼 내장 메소드일 경우 descriptor protocol 존재해서 true 처리 inspect.isdatadescriptor(object) __get__, __set__, __delete__ 메소드를 가진 인스턴스일 경우 True
  • 119. Inspect 함수 함수에 대한 다양한 점검을 위한 함수를 제공 Function Description inspect.isfunction(object) Object가 함수 여부 inspect.isgeneratorfunction(object) Object가 제너레이터 함수 여부 inspect.isgenerator(object) Object가 제너레이터 여부
  • 122. 왜 객체지향을 하는가?  소프트웨어이 관리 기준은 모듈이지만 실행환경에서 모듈은 객체처럼 움직이면서 관리  실행환경과 구현환경이 동일하게 관리하는 것이 객체지향을 도입한 중요한 이유  인간의 사고는 추상화적인 분류를 기준  추상화를 위한 단위를 객체로 보고 소프트웨어를 만드는 것이 인간의 사고  개발자들이 추상적인 생각을 키우면서 소프트웨어를 개발하기 딱 맞는 환경이 객체지향이고 이를 위해 소프트웨어도 그 개념 을 받아들여 발전  객체 즉 사물을 보고 잘 분류하는 사고가 필요
  • 123. 객체지향 사물의 분류  사물(Things)은 곧 객체이다.  사물에는 형태를 가진 것과 개념만 존재하는 것으로 분류할 수 있다.  소프트웨어 분석 설계 구현을 한다는 것은 실세계의 사물을 가상세계의 사물로 전환 하는 것이다.  객체 모델링, 데이터 모델링도 다 사물들을 관리하는 기준에 맞춰 분류하는 것이다.  타입, 클래스는 객체 즉 사물을 분류했을 때 정의하는 것에 지나지 않는다.  사물을 어떻게 분류할 것인가?  책을 예시로 보면 책은 객체이다. 책에 대한 정보만 관리하는 것은 개념 객체이고 책의 실물을 관리하는 사물을 관리하는 객체가 구별되어 관리되어야 한다.  책이라는 객체가 책 정보에 대한 분류 기준으로 도서문헌상의 분류 규칙을 따르므로 다양한 분류체계를 관리하는 객체도 발생할 수 있다.  사물은 단순이 존재한다고 하나의 객체만은 아니다.  보는 관점, 각 비즈니스 도메인별로 차이가 발생하므로 사물의 분류 기준을 비즈니스 에 맞춰 모델링이 되어야 한다.
  • 124. 계약중심의 설계  실세계 객체들이 대화 즉 의사소통을 통행 움직인다.  소프트웨어도 실제 객체들이 혼재되어 실행되지만 객체간의 영향을 항상 조화를 이룰 수 있다면 깨지지 않고 많은 것을 처리할 수 있다.  이를 위해 객체간의 메시지 즉 소통을 위해 각 객체들은 자신들의 할 수 있는 일과 상대방에게 요구하는 일들을 약속해서 명확하게 처리 되어야 한다.  design by contract 계약중심의 설계는 실제 객체들이 실행시 자신 들의 권리와 의무를 명확히 하고 이를 어길 경우에도 정확한 에러처 리를 통해 소프트웨어가 잘 작동할 수 있는 설계를 하자는 것이다.  소프트웨어는 가상의 물질 즉 객체들에 의해 작동되지만 실세계의 객체들이 움직임처럼 명확히 살아있는 것처럼 생각해서 설계가 되어 야 스파게티 소스를 만들지 않을 수 있는 지름길이다.
  • 125. 객체의 생명주기 관리  계약이란 쌍방이 매매를 했을 때 권리와 의무를 명확히 표시한 거래이다.  계약이 발생하면 그 계약이 시작점과 종료점이 있다.  계약도 생명주기를 갖는다.  생명주기를 갖는 것은 하나의 객체로서 관리를 해야 한다는 것이다.  온라인 쇼핑몰에서 책을 구매한다.  책을 매매한 계약은 배송으로 끝나는 것이 아니라 반품 등이 발생할 수 있으므로 최소 14일 정 도까지는 기다려야 한다.  회사 정책으로 더 많은 기간을 반품기간으로 정할 경우는 매매계약이 생명주기는 더 길어진다.  이처럼 생명주기가 발생하는 것은 개념 객체이므로 객체로 관리해야 하는 대상이다.  매매계약이 발생했을 때 이 계약에 필요한 문서 등을 고객에게 출력해줘야 하는 경우 는 생명주기가 더 길어진다.  계약 문서 등도 별도의 객체이므로 계약과의 연관관계를 유지하도록 한다.  객체는 항상 생명주기가 있고 보는 시각을 달리하면 생명주기 관리기준도 다양하게 발생한다.  객체를 보는 관점을 다양하게 갖는 게 아주 중요하다.
  • 126. 상속대신 연관관계로 표현  객체지향 설계 시 상속을 사용하지 않는 이유는 상 속관계가 끊어지면 모델을 다시 만들어야하기 때 문이다.  상속은 인간들이 보기가 좋지만 상속 레벨이 3단계 가 넘어가거나 다중상속일 경우 인간이 이해하는 범위가 넘어가서 실질적인 상속을 이해할 수가 없 다.  실제 생물들도 부모로부터 상속을 받지만 상속관 계로 표현할 수 있는 게 너무 없어서 실제 상속을 사용할 수 있는 것을 없다.
  • 127. 상속을 끊을 경우 어떤 대안은  별도의 클래스를 생성할 수 있는 팩토리 체계를 만들어서 상속대신 관계성을 가질 수 있는 설계 로 반영해야 한다.  실세계에 존재하는 객체들은 그렇게 상속을 가 지지 못하거나 너무 복잡해서 우리가 인식할 수 없다.  상속을 사용할 경우 시스템 재개발 등이 발생 시 더 많은 비용이 들 수 있어 연관관계를 사용 해서 다양한 클래스로 분리
  • 128. 상속만으로 추상화는 불가  객체지향 프로그램 언어는 상속을 가지고 재사용성을 높일 수 있다고 한다.  실제 상속은 비즈니스 환경에서는 맞지 않는다.  상속으로 재사용성을 높인다고는 하지만 재사용은 변경이 아 니라 추가인데 상속에서 추가를 한다는 것은 자식을 추가하는 것인데 자식들만 추가한다고 그 자식들이 거의 유사한 것들이 되는 것인가?  상속을 하려면 자식들이 가진 아주 대표적인 것만 부모가 되어 야 하는데, 비즈니스 환경에서는 부모와 자식이 구분이 안되는 경우가 더 많다.  객체들이 많다면 그 객체들이 통합이 가능한지를 먼저 확인하 고 객체들을 별도로 추상화하여 각 객체들이 집단간의 연관관 계를 고려하는 게 더 추상화가 높을 수 있다.
  • 129. 왜 스파게티가 될까?  기술적 재사용성만 강조하면 다중 상속이 필요 하고 이를 반영하려면 클래스가 세분화 된다.  하나의 서비스를 처리하기 위해 사용되는 클래 스들이 많아지면 상속 및 연관관계가 일관되게 유지되기 어렵다.  스파게티를 해결하려면 특정 도메인으로 분리 해서 실제 연관관계를 분리해야 한다
  • 130. SOLID?
  • 131. SOLID  단일 책임 원칙 (Single responsibility principle)  개방-폐쇄 원칙 (Open/closed principle)  리스코프 치환 원칙 (Liskov substitution principle)  인터페이스 분리 원칙 (Interface segregation principle)  의존관계 역전 원칙 (Dependency inversion principle)
  • 132. 단일 책임 원칙  Single responsibility principle  한 클래스는 하나의 책임만 가져야 한다.
  • 133. 단일 책임 원칙: 예시  거래당사자 정보를 정보관리와 거래 당사자의 역할로 분할하여 책임 정의 Involved Party Person Organization Role Customer Employee Owner …
  • 134. 개방-폐쇄 원칙  Open/closed principle  “소프트웨어 요소는 …… 확장에는 열려 있으나 변 경에는 닫혀 있어야 한다.”  요구사항의 변경이나 추가사항이 발생하더라도, 기존 구성요소는 수정이 일어나지 말아야 하며, 기 존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한다는 뜻입니다.  필수적인 요구사항만, 구성요소(클래스)안에 구현 하고, 나머지는, 구현자체를 생략하라는 겁니다.
  • 135. 개방-폐쇄 원칙: 예시  거래당사자의 역할은 기존 클래스를 변경하는 게 아니라 새로운 책임성을 가지는 클래스를 추가 Role Customer Employee Owner …Applicant
  • 136. 리스코프 치환 원칙  Liskov substitution principle  서브타입은 언제나 자신이 기반타입 (base type)으로 교체할 수 있어야 한다.  서브타입 클래스의 메소드를 변경하지 않아야 기반 클래스의 사용자는 그 기반 클래스에서 유도된 클래스(서브타입)에 대해 아무것도 알 필요가 없어야 한다.  상속은 코드 재사용을 위해서가 아니라 명확한 가족 관계 가 있을때 사용해야 하며, 그 행위(Behavior) 와 연관 이 있습니다. 부모와 파생된 객체들이 존재 할때 가능한 모두 동일한 메소드 이름과 갯수를 가지게 함으로써 언 제든지 서브 타입이 기반타입으로 교체될 수 있어야 함을 말합니다.
  • 137. 리스코프 치환 오용  상속관계가 아닌 객체를 비슷한 일을 하는 것 을 보고 코드 재사용 욕심에 가족 관계로 묶는 것.  다중 상속이나 다단계 상속으로 계층 구조가 깊 고 복잡하게 하는 것.  파생 타입에 부모, 형제들과는 전혀 동떨어진 능력을 부여 함으로써 돌연변이를 만들어 버리 는 것.
  • 138. 리스코프 치환 원칙 : 예시  서브타입에 특정 기능을 오버라이딩한 것이 없도록 처 리하여 기반타입으로 교체해도 이상이 없도록 함 class rectangle() : def __init__(self,height, width) : if height == width : self.height = height self.width = width else : if self.__class__.__name__ == 'square' : print " error " else : self.height = height self.width = width def area(self) : return self.height * self.width class square(rectangle) : pass r = rectangle(5,8) print r.__dict__ print r.area() try : s = square(5,6) print s.__dict__ print s.area() except : pass {'width': 8, 'height': 5} 40 error {}
  • 139. 인터페이스 분리 원칙  Interface segregation principle  “특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이 스 하나보다 낫다.”  클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺 으면 안된다.  비대한 클래스(Fat class) 거대하고 보기 흉하다는 사실 말고 도, 한 사용자가 이 비대한 클래스의 메소드를 다 사용하는 일 이 매우 적다는 것도 문제입니다. 즉. 메소드를 몇십개 선언한 클래스에서 사용자는 단지 두세 개만 호출 할 지도 모르죠. 불 행하게도 이 사용자들은 호출하지도 않는 메소드에 생긴 변화 에도 영향을 받습니다.
  • 140. 인터페이스 분리 원칙 : 예시  인터페이스에 대한 통합은 필요하지 않은 기능도 호출이 되므 로 실질적으로 필요한 기능만 호출할 수 있어야 함 Involved Party Person Organization 인터페이스 Involved Party Person Organization 인터페이스 인터페이스에 대한 분리
  • 141. 의존관계 역전 원칙  Dependency inversion principle  “프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안 된다.” 의존성 주입은 이 원칙을 따르는 방법 중 하나다.  고차원의 모듈은 저차원의 모듈에 의존하면 안된다. 이 두 모 듈 모두 다른 추상화된 것에 의존한다.  추상화 된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것 이 추상화된 것에 의존해야 한다.  자주 변경되는 구상 클래스(Concreate class)에 의존하지 마 라. 만약 어떤 클래스에서 상속받아야 한다면, 기반 클래스를 추상 클래스로 만들어라. 만약 어떤 클래스의 참조(Reference) 를 가져야 한다면, 참조 대상이 되는 클래스를 추상 클래스로 만들어라. 만약 어떤 함수를 호출해야 한다면, 호출 되는 함수 를 추상 함수로 만들어야 합니다.
  • 142. 의존관계 역전 원칙: 예시  각 레이어별로 역할이 정해져 있으면 역참조를 할 수 없도록 구성해야 함  역참조가 발생할 수 있는 것은 BCS(Business common service) Layer 를 구성해서 역전이 발생하지 않도록 처리  레이어도 무한정 정리할 수 없으므로 타 시스템 연계 등을 EIS(Enterprise Interface Service)Layer로 구분하여 의존관계 역전 원칙 준수 Application Service layer Process Service layer Domain Service layer ORM Service layer B C S L A Y E R E I S L A Y E R 외부 시스템
  • 144. 클래스 명명규칙 및 정의  클래스 명명규칙과 정의는 그 클래스가 무엇인지를 설명해야 하고 명확한 책임성을 반영되어 야 함  클래스가 식별되면 책임성에 대해 정의하고 유사 개념 또는 중복성 여부를 판단할 명확한 근거를 정리해야 함  클래스의 중요성을 간결하게 정의되어야 함 Class name Attribute Operation  클래스 이름은 명확히 구별되어야 하며, 클래스 정의를 위한 명확한 구별이 가능해야 함  왜 그 클래스가 업무에 중요한가를 나타낼 수 있는 명명을 지정하고 정의에서 세부적인 책임성을 설명해야 함  클래스 정의는 “왜 이것이 업무에 중요한가?”라는 질문에 답을 해야 함  필요한 경우, 클래스가 여러 기능, 공정, 조직 또는 시스템관점(view) 을 가로질러 사용 된다면, 그것이 적용되는 관점(view)을 명료하게 표 시한 각 뷰(관점)별로 정의사항을 추가하라 클래스 명명 및 정의시 작성되어야 할 사항
  • 145. 클래스 구성  클래스에 대한 기술은 이 클래스의 인스턴스들을 생성하는 template역할을 한다.  클래스는 데이터타입과 비슷하나, 클래스는 데이터와 함께 기능도가지고 있다. Class name Attribute Operation object object object ….. 생성 생성 생성
  • 146. 클래스의 성질  기업이 실제 처리하는 비즈니스 도메인의 범위 안에 있어야 함  기업이 그에 대한 정보를 보관코자 하는 어떤 것을 나타냄  클래스의 속성들의 응집성에 의해 결정된 단일개념을 나타냄  하나의 실제사물(객체)이 아니라 동종 또는 유사 사물의 집합을 나타냄  집합의 본질을 희석시키지 않고, 해당 클래스내의 객체를 구별할 수 있는 능력을 제공 함 B 단위 업무 영역 A 단위 업무 영 역 C 단위 업무 영역 실세계 업무 범위
  • 147. 클래스가 갖춰야 할 요건  클래스들은 실세계를 가능한 완벽하게 추상화 시켜야 한다.  실세계를 제대로 추상화해 내지 못하면 좋은 시스템을 기대할 수 없다.  정보는 기능이나 데이터가 아닌 클래스들을 중심으로 국지화되어야 한다.  클래스들의 구현방법은 철저하게 외부로 부터 숨겨져야 하며, 밖으로는 잘 정의된 인터페이스만이 나타나야 한 다.(구현적 의미에서 보면) 객체 영역 A Class name Attribute Operation B Class name Attribute Operation 추상화
  • 149. 카테고리화에 의한 분류:상품  새로운 클래스를 설정하고 기존 클래스와 연관 예정이나 비즈니스 규칙과 같은 보다 추상적인 개념을 다루거나 실물과 지식의 구별을 강조  유사한 개념은 하나의 개념으로 묶어 그룹화하여 하나의 범주로 통합하여야 함  개념의 공통성을 찾아 하나의 범주로 묶어야 함 일반대출 계좌 주택대출 계좌 지급보증 계좌 ….. 여신 계좌 Category 화  상품 소분류나 중분류별 관리되는 계좌정보에 대해 통합된 개념으 Category 화 필요  개념 사물에 대한 세부 원칙을 통합관리 기준으로 분리 보통예금 계좌 저축예금 계좌 정기적금 계좌 ….. 예금 계좌 Category 화 Category 화 계약
  • 150. 카테고리화에 의한 분류: 서비스  금융상품을 제외한 다양한 서비스에 대한 처리에 대 한 계약 처리  송금, 지급결제, 환전 등이 별도 거래 기타 판매 기타 수납 대여금고 ….. 기타 서비스 Category 화  금융상품을 제외한 다양 한 서비스에 대한 계약에 따른 세부 분리 송금 지급결제 환전 ….. 금전서비스 Category 화 Category 화 계약
  • 151. 집합으로 규정할 수 있어야 함  동일한 부류나 범주의 집합으로 규정하여 클래스간의 책임성 중복이 발생 하지 않아야 함  집합으로 정의할 수 있도록 명확한 분류 기준을 수립해야 함  집합에 속한 객체들이 중복되지 않도록 명확해야 함 계약 고객과의 수신, 여신 상 품을 신규할 경우 계약 조건 등 계약에 필요한 정보를 관리 = 집합 정의
  • 152. 공통성과 변이성을 구분  비즈니스 소프트웨어의 복잡성의 가장 중요한 원인은 ‘변형(variation)’의 규모에서 온다.  이러한 변형 경우를 분석함으로써 ‘공통점(Commonality)’을 추출할 수 있다.  클래스 복잡성을 해결하기 위한 핵심은 공통점과 변형을 구분하는 데 있다. James .part-time .weekly-paid John .full-time .weekly-paid Jane .part-time .monthly-paid 공통점 분석 후,… [Payment Type] .weekly-paid .monthly-paid [Working Style] .part-time .full-time [Worker] .name . …  공통점 변형
  • 153. 독립적인 집합 이어야 함  어떤 다른 집합과는 본질적으로 다른 자기 혼자만의 고유한 집합이어야 한 다는 것  다른 집합의 부분집합이되거나 다른 집합과의 교집합을 가지지 않아야 한 다는 것 계약 거래상품 하나의 독립적인 집합으로 유지되며 독립적인 사물로써 상호작용을 수행
  • 154. 사물(Things) 정의  대상 문제에 있어 명확한 경계와 의미를 가진 것이 객체이며, 공동 의미, 행 동을 가진 객체 그룹  실존하는 집합으로써 다른 집합들과 구별(Identify)할 수 있는 것  어떤 사물의 집합. 이 집합 안의 사물들은 같은 특징을 공유하고, 같은 방식 으로 행동하고, 같은 규칙과 정책을 준수함 통장 증서 수표 어음 실제 비즈니스에서 존재하는 사물들을 하나의 집합으로 묶어 클래스화
  • 155. 비사물(Non-Things) 정의  비즈니스 내의 관행 등으로 관리되는 논리적인 관리대상을 객체들의 집합 을 식별하는 것  논리적인 이유로 같은 부류에 속하는 객체들의 집합을 식별하는 것  공통성을 찾아 의미적으로 통합하여 하나의 집합으로 묶을 수 있어야 함 계약 자기앞수표 발행 제사고신고 거래 비즈니스에서 관리되는 개념 객체들을 그룹화하여 클래스 화
  • 156. 행위관리 대상체의 분리  사물에 대한 복잡성 완화를 위해 객체들에 대한 고유정보와 행위관리를 위 한 책임성을 분리하여야 함  행위가 반복적으로 발생하는 주체와 그 행위가 대상이 되는 사물정보에 대 해 분리하여 관리함 계약상품 계약조건상품조건 기업의 판매되는 사물 대상체 판매된 행위관리 대상체 사물과 행위관리 기준으로 분리
  • 157. 서브 클래스화에 의한 분류  기존 클래스를 특수화해 서브클래스를 설정  서브 클래스마다 데이터나 메소드가 달라지는 경우 또는 별개의 클 래스와 연관을 가지는 등 모델구조의 차이를 강조하기 위해 사용 계약 수신 계약 대출 계약 지급보증 계약 수신관련 Class 대출관련 Class 지급보증 관련 Class 특정 비 즈니스 를 수용 을 위한 Level 세부 업무별 특화된 처리
  • 158. 자기참조를 위한 계층 구조화  자기 참조가 되는 구조를 구성하여 계층구조를 만들 어속성과 메소드의 중복 해결해야 함  새로운 계층의 추가에 대응을 통한 구조변경 용이 고객 개인 조직 재귀적인 호출을 위해 계 층구조
  • 159. 클래스간의 상호작용 확장  실제 객체들을 클래스화하면서 응집도를 높이기 위해서는 식별된 클래스 간의 관계 및 상호인터페이스 기준을 명확히 설정해야 함  클래스간의 상호관계가 명확히 될 수록 클래스간의 커플링이 약하게 구성 되어 다른 클래스와의 상호작용이 용이함 계좌 거래내역 타점권 내역  계좌의 책임성을 계좌생 명주기로 축소  계좌내의 입출금이 발생 하는 모든 이벤트에 대한 책 임성을 거래내역에 부여  계좌내의 입금 발생시 거 래내역에 속한 타점권 정보 관리에 대한 책임성을 부여 입금발생시 사물 정보인 타점권 관리책임 분리 계좌개설 및 해 지까지의 관리책 임 분리
  • 160. 관리하고자 하는 대상 확장  '관리하고자 하는' 이란 의미는 관리하고자 하는 정보만을 클래스로 취할 것임을 의미한다.  업무의 목적과 범위, 전략, 방향에 따라 클래스로 취할 수도 있고 버릴 수도 있다는 것을 의미한 다. 그렇다면 먼저 이러한 부분이 분명하게 정의하는 것은 매우 중요한 일일 것이다.  현재 우리가 관리하고자 하는 것과 앞으로 관리하고자 하는 것까지도 포함하는 말이다. 계약 거래 계약이후 계약이 종료시까지 세부적인 행위내역을 관리 계약에 대한 행위를 관리 고객과의 계약이후 해제까지의 비즈니스적 관리 대상 계약 생명주기 거래 생명주기 계약 조건변경 거래 입출금 거래