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
클래스에서 객체 생성하기
10.
New style class
Object를상속하여 명확히 클래스들이 표시됨
import types
class A(object) :
def __init__(self,name) :
self.name = name
a = A('dahl')
print a.name
print(" instance type ", type(a))
print(types.ClassType == type(A))
print(type(a) is types.InstanceType)
print(" class type ", type(A))
print(" class type ", a.__class__.__bases__)
print(isinstance(a,object))
print(isinstance(a,type))
dahl
(' instance type ', <class '__main__.A'>)
False
False
(' class type ', <type 'type'>)
(' class type ', (<type 'object'>,))
True
False
11.
Old style class
Object를상속할 경우 old style class로 표시되
어 classobj로 처리되 인스턴스는 intance 타입
을 가짐
Import types
class B():
def __init__(self,name) :
self.name = name
b = B('moon')
print type(b)
print(" class type ", type(B))
print(type(b) is types.InstanceType)
print(types.ClassType == type(B))
<type 'instance'>
(' class type ', <type 'classobj'>)
True
True
생성자 사용법
__new__
__init__
새인스턴스의 생성을 제어 할 필요시 사용
__new__ 인스턴스 생성의 첫 단계
__new__는 첫 번째 인수로 클래스를 받고, 해당
유형의 새 인스턴스를 반환
mutable 및 immutable 유형 모두 사용
새 인스턴스의 초기화를 제어해야하는 경우 사
용
__init__ 아무것도 반환하지 없음
__init__는 첫 번째 인수로 인스턴스를 받아 해
당 인스턴스의 속성을 수정. OBJ .__ 초기화 __
(* 인수)를 호출하여 작성 후 수정 될 수 있음
mutable 의 유형에 사용
14.
생성자 형식
__new__(...)
T.__new__(S, ...)-> a new object with
type S, a subtype of T
__new__
__init__
__init__(...)
x.__init__(...) initializes x;
see help(type(x)) for signature
15.
생성자 사용법 예시
__new__실행 후에 인스턴스를 만들고 __init__
으로 초기화
class C(object) :
def __new__(cls) :
return super(C, cls).__new__(cls)
def __init__(self,name) :
self.name = name
c = C.__new__(C)
print c
print type(c)
print c.__class__
print isinstance(c,C)
c.__init__('dahl')
print c.name
#결과값
<__main__.C object at
0x10495670>
<class '__main__.C'>
<class '__main__.C'>
True
dahl
16.
__new__ 메소드 예시
클래스로가변과 불변 타입에 상관없이 새로운
인스턴스만 생성함
#불변 인스턴스 생성
pp = int.__new__(int,0)
print("data type", type(pp))
print(pp)
#가변 인스턴스 생성
ss = list.__new__(list,[])
print("data type", type(ss))
#가변인스턴스 초기화
ss.__init__([1,2,3])
print(ss)
#결과값
data type <type 'int'>
0
data type <type 'list'>
[1, 2, 3]
17.
__new__ 메소드: 예시2
사용자정의 클래스를 만들고 생성한 후에 초기
값 세팅하는 처리
#클래스 생성
class S(object) :
pass
print("S type ",S)
clss = object.__new__(S)
clss.__init__()
#클래스의 인스턴스 여부 확인
print(type(clss), isinstance(clss,S))
#결과값
S type <class '__main__.S'>
<class '__main__.S'> True
인스턴스 속성 미정의후 생성
클래스 생성자에 인스턴스 즉시호출 속성을 미정
의하고 인스턴스를 호출시 실제 인스턴스가 없으
므로 오류처리
>>> 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
>>>
21.
인스턴스 속성 미정의후 호출
인스턴스 속성 미정의할 경우 반드시 인스턴스
처리하는 __call__ 메소드를 정의하여 처리해야
함
>>> class B:
... def __init__(self):
... print "From init ... "
... def __call__(self):
... print "From call ... "
...
>>> b = B()
From init ...
>>> b()
From call ...
>>>
22.
__init__과 __call__ 메소드차이
클래스 생성자에 따른 인스턴스를 초기화하고 즉
시 인스턴스가 실행될 필요가 있을 경우 __call__
처리
class D:
def __init__(self):
print "init"
def __call__(self):
print "call"
D() # init
D()() # init call
d = D() #init
d() # call
생성자와 인스턴스
호출 메소드 정의
생성자와 인스턴스
호출 메소드 정의
object class -1
Objectclass 내의 기본 속성 확인하기
print object.__class__
print object.__doc__
print object.__str__("objct")
print int.__repr__(1)
print object.__format__("1234","4.2s")
<type 'type'>
The most base type
'objct'
1
12
26.
object class -2
Objectclass 내의 생성 및 호출 속성 확인하기
print object.__new__
p = list.__new__(list)
p.__init__([1,2])
print object.__init__, p
print object.__call__
i = int.__call__(5)
print i
<built-in method __new__ of type object at
0x1E2296E0>
<slot wrapper '__init__' of 'object' objects> [1, 2]
<method-wrapper '__call__' of type object at
0x1E2296E0>
5
object class -4
Objectclass 내의 속성에 메모리 사이즈 및 주소
속성 확인하기
p = list.__new__(list)
p.__init__([1,2])
print object.__hash__(id(p))
print object.__sizeof__(p)
-2141663122
20
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}
인스턴스 메소드
31.
Predefined Class Attributes
AttributeType 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.
32.
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} # 인스턴스 객체 관리 영역
33.
Predefined Instance Attributes
AttributeType 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
instanceinstance instance
상속
인스턴스 생성
Dict{}
Dict{}
Dict{} Dict{} Dict{}
Namespace
검색
객체는 자신들이 관리
하는 Namespace 공간
을 생성하며
객체 내의 속성이나 메
소드 호출시 이를 검색
해서 처리
36.
Class & instancescope
Class Object는 인스턴스를 만드는 기준을 정리한다.
클래스를 정의한다고 하나의 저장공간(Namespace) 기준이 되는 것은 아니다.
- 클래스 저장공간과 인스턴스 저장공간이 분리된다
User
defined
Class
Instance
Instance
Instance
Built-in
Class
상속 인스턴스화
Object Scope
Object Namespace
37.
Class/Instance 관계 매핑
Class키워드로 클래스 정의
상속은 class 키워드 다음() 내에 상속할 클래스 정의
인스턴스 생성은 클래스명에 ()연산자 사용
Super ClassClassinstance
상속인스턴스화
class A(object):
def whoami(self):
return self.__class__.__name__
a = A()
38.
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
41.
생성자-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)
생성자 정의
인스턴스 객체 생성
생성자와 자동으로 연계
42.
소멸자- 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
소멸자 정의
소멸자 활용
43.
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"))
Method- 클래스 decorator
클래스객체에서 처리되는 메소드를 정의한다. 클래스 메소
드는 첫번째 파라미터에 cls를 전달한다.
장식자 @classmethod : 클래스 함수 위에 표시-Python 2.x
함수 classmethod() : 별도 문장으로 표시 – Python 3.x
인스턴스 객체도 호출이 가능
49.
Method- 정적 decorator
클래스객체로 생성된 모든 인스턴스 객체가 공유하여 사용
할 수 있다.
장식자 @staticmethod : 정적함수 위에 표시 – Python 2.x
함수 staticmethod()는 별도의 문장으로 표시 –Python 3.x
정적메소드는 파라미터에 별도의 self, cls, 등 객체에 대한
참조값을 전달하지 않아도 됨
인스턴스 객체에서도 호출이 가능
50.
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(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)
Inheritance
상속은 상위 클래스를하나 또는 여러 개를 사용하는
방법
class 상위 클래스명 :
pass
class 클래스명(상위 클래스명) :
pass
상속 정의시 파라미터로 상위 클래스명을 여러 개 작
성시 멀티 상속이 가능함
class 클래스명(상위 클래스명, 상위 클래스명) :
pass
55.
Class 구조
클래스는 슈퍼클래스를상속
Super ClassClass
상속
class A(object):
def __init__(self) :
self.instanceS = " static instance member"
def whoami(self):
return self.__class__.__name__
클래스 구조 예시(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
58.
Inheritance- scope
상속된 클래스도검색하는 순서가 파라미터를 정리
한 순서대로 변수나 메소드를 검색하여 처리됨
상속된 클래스에 동일한 이름이 변수나 메소드가 존
재시 첫번째 검색된 것으로 처리함
class 클래스명(상위 클래스명, 상위 클래스명) :
pass
59.
Inheritance - 예시
classParent: # 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 정의 인스턴스 생성 및 호출
60.
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)
인스턴스 생성 및 호출
Method resolution order
Mro메소드는 type 클래스에 있으므로 직접
type.mro(class) 로 호출 가능
class A(object) :
def __init__(self,name) :
self.name = name
a = A('dahl')
print a.name
print(type.mro(A))
print(type(a),type(a).mro())
# 실행 결과
dahl
[<class '__main__.A'>, <type 'object'>]
(<class '__main__.A'>, [<class '__main__.A'>,
<type 'object'>])
63.
MRO 처리 시오류
Old style로 정의시 type class를 알 수 없으므로
mro를 사용하려면 명확히 상속을 표시해야 함
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'>]
'
64.
상속 : __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'>]
Hasattr 메소드 재작성후 확인
상속인 경우 클래스 객체들이 우선순서를 확인하
고 속성을 접근하는 예시
class A(object) :
def __init__(self,name) :
self.name = name
def hasattr(self, attrname):
if hasattr(self,attrname) :
val = "B“ # 최상위
if attrname in A.__dict__ :
val = "A“ # 클래스
if attrname in self.__dict__ :
val = "S“ #인스턴스
else :
val = "N"
return val
# 실행 결과
True
True
True
B
S
A
a = A("dahl")
print hasattr(a,"name")
print hasattr(a,"__str__")
print hasattr(object,"__str__")
print a.hasattr("__str__")
print a.hasattr("name")
print a.hasattr("__init__")
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의 값
69.
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'
70.
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’) 처럼 인식
Overriding
메소드를 이름으로 검색하므로하위 클래스에 동
일한 메소드가 존재하면 인스턴스 호출시 하위
클래스 메소드 부터 호출하므로 Overriding 처리
class 상위 클래스명 :
def method(self) :
pass
class 클래스명(상위 클래스명) :
def method(self) :
pass
74.
Overriding 구조
동일한 메소드를instance/Class/Super Class에
다 정의할 경우 실행시 instance부터 호출이 되는 구
조
Super ClassClassinstance
상속인스턴스화
클래스 정의
시 메소드
클래스 정의
시 슈퍼 클래스메소
드 재정의
Runtime 시
클래스 및 슈퍼클래
스 메소드 정의
Overriding 발생 Overriding 발생
./[] 연사자 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 발생
78.
./[] 연사자 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 생성 방식
클래스명에파라미터에 인스턴스 변수값을 정의해
서 인스턴스를 생성함
인스턴스 생성시 생성자가 호출되어 처리됨
변수명 = 클래스명(인스턴스 변
수값,인스턴스 변수값)
def __init__(self, 인스턴스 변수
값,인스턴스 변수값) :
self.인스턴스 변수 = 인스턴
스변수값 매칭호출시
매칭됨
82.
Instance 생성 예시
Class키워드로 클래스 정의
상속은 class 키워드 다음() 내에 상속할 클래스 정의
인스턴스 생성은 클래스명에 ()연산자 사용
Super ClassClassinstance
상속인스턴스화
class A(object):
def whoami(self):
return self.__class__.__name__
a = A()
83.
Instance Scope
객체들간의 관계(상속및 instance 생성 등)에 따라 객체 멤버들에 대
한 접근을 처리
검색 순서 : 인스턴스> 클래스> 상속클래스>builtin Class
상속이 많아지면 다양한 상위 멤버들을 접근하여 처리할 수 있다.
84.
Predefined Instance Attributes
AttributeType 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()
87.
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
내장 객체
내장 객체
88.
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()
89.
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
내장 객체
내장 객체
90.
Controlling Attribute Access
Instance의Attribute에 대한 접근을 할 수 있는 내
부 함수
__getattr__(self, name)
__setattr__(self, name, value)
__delattr__(self, name)
__getattribute__(self, name)
91.
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
객체간에 관계를 구성하여처리
객체내부에 관계 객체를 생성하여 해당 객체의 기능을 처리
Composition is an Association
Aggregation is an Association
Composition is a strong Association (If the life of contained object
totally depends on the container object, it is called strong association)
Aggregation is a weak Association (If the life of contained object
doesn't depends on the container object, it is called weak association)
96.
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
97.
Association: 작성 예시
#association 클래스 정의
class Other(object):
def override(self):
print "OTHER override()"
def implicit(self):
print "OTHER implicit()"
def altered(self):
print "OTHER altered()"
객체관의 관계가 상속이 아닌 사용관계(use)로
전환
# 사용 클래 스 정의
class Child(object):
def __init__(self):
# 인스턴스 생성시 속성으로 정이
self.other = Other()
def implicit(self):
self.other.implicit()
def override(self):
print "CHILD override()"
def altered(self):
print "CHILD, BEFORE OTHER altered()"
self.other.altered()
print "CHILD, AFTER OTHER altered()"
Dependency: Method Chain
classC:
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
100.
Self Method Chain
classPerson:
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()
객체 내의 메소드의 결과를 자기자신으로 리턴하여 메소드를
연속해 호출하여 처리
101.
타 객체 MethodChain
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()
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 처리
104.
Class & instancenamespace
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
Descriptor는 특성 객체의속성 접근시 먼저 그 속
성의 특징을 체크하여 처리할 수 있는 방법으로
기술자 프로토콜로 제지하면서 처리는 "바인딩 행동"
을 가진 메소드들로 구성
__get__(self, instance, owner),
__set__(self, instance, value),
__delete__(self, instance).
107.
Descriptor 메소드 파라미터
별도의descriptor 와 실체 class 인스턴스 간의 실행환경을 연계하여 처리
Self: decriptor 인스턴스
Instance: 실체 class의 인스턴스
Owner: 실체 class의 타입
Value : 실체 class의 인스턴스의 변수에 할당되는 값
__get__(self, instance, owner),
__set__(self, instance, value),
__delete__(self, instance)
108.
Descriptor 종류
Method descriptor와Data descripter 로 구분
Method descriptor는 __get__(self, instance,
owner) 구현
Data descriptor는 __get__(self, instance,
owner) __set__(self,instance, value),
__delete__(self, instance) 구현
109.
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)
110.
Descriptor : bindingbehavior
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)
111.
Basic data descriptor
DataDescriptor 클래스를 생성해서 처리하는
방법
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
112.
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 생김)
Information hiding -변수
__명칭: Private
(객체 내부에서만 사용)
외부에서 호출시 mangling 되는 구조로
요청시 접근 가능
인스턴스._클래스명__명칭
_명칭 : protected
(클래스 및 하위 클래스에서만 사용)
122.
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 –
Descriptor(Property)
파이썬은Property 객체를 이용하여 객체내의 변수들의 접근을 메소드
로 제어한다.
Descriptor 객체, Property 객체나 @property decorator를 이용
인스턴스 객체의 변수 명과 동일한 property 객체가 생성되어야 함
Class P
Instance p1
{‘_x’: }
Descriptor
인스턴스 생성
x
생성
인스턴스생성
class 내 descripter 인스턴스의 메소드 호출하여 처리
Instance p1
p1.x 접근
Descriptor
Abstract Class
추상화 클래스란직접 인스턴스를 만들지 못하고
상속을 받아 메소드 오버라이딩해서 사용하는 방
식
Concrete Class instance
Obj = ConcreteClass()
인스턴스 객체 생성
Abstract Class instance
Obj = ConcreteClass()
인스턴스 객체 생성
X
Abstract
Class
Concrete
Class
instance
ConcreteClass
(Abstract Class)
상속
Obj = ConcreteClass()
인스턴스 객체 생성
127.
Abstract Class 정의방법
추상화 클래스는 exception 및 abc 모듈 2가지
처리 방법으로 만들 수 있다.
exception 방식
abc 모듈 방식
모든 메소드를 subclass에서 정의할
필요가 없다
오류처리 : NotImplementedError
모든 메소드를 subclass에서 정의해야
한다.
오류처리 : TypeError
128.
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"
상속 및 메소드 오버라이딩
추상클래스의 모든 메소
드를 구현할 필요없음
129.
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
상속 및 메소드 오버라이딩
추상클래스의
모든 메소드를
구현되어야 함
Duck typeing 정의방법
다양한 클래스가 동일한 메소드를 처리할 수 있
도록 인터페이스를 갖도록 만드는 법
함수
클래스
Duck typing에 필요한 함수 정의 후
인스턴스들의 메소드 호출 처리
Duck typing에 필요한 클래스 정의 후
인스턴스들의 메소드 호출 처리
134.
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")
함수 정의 클래스 정의
135.
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.
136.
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")
함수 정의 클래스 정의
137.
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.
런타임 클래스 생성정의
다른 클래스를 __new__,__init__, type()를 이용
해서 새로운 클래스 생성
class ChattyType(type):
def __new__(cls, name, bases, dct):
print( "Allocating memory for class", name)
return type.__new__(cls, name, bases, dct)
def __init__(self, name, bases, dct):
print ("Init'ing (configuring) class", name)
super(ChattyType, self).__init__(name, bases, dct)
클래스를 메모리에 생성
__new__ : 클래스 생성
클래스 configure 처리
__init__ : 초기화 생성
141.
런타임 클래스 실행
클래스와메소드 함수를 정의
X = ChattyType('X',(),{'foo':lambda self:'foo'})
#Allocating memory for class X
#Init'ing (configuring) class X
print(“XXXX”,X.__dict__)
print( X().foo())
#(<class '__main__.X'>, 'foo')
#처리결과
<class '__main__.X'>
foo
#처리결과
('XXXX', dict_proxy({'__dict__': <attribute '__dict__'
of 'X' objects>, '__module__': '__main__', 'foo':
<function <lambda> at 0x10577930>,
'__weakref__': <attribute '__weakref__' of 'X'
objects>, '__doc__': None}))
클래스 생성 함수정의
클래스와 메소드 함수를 정의
#클래스에 등록할 메소드 정의
def say_foo(self):
print('foo')
#클래스 생성 메소드 정의
def class_with_method(func):
class klass:
pass
# setattr(obj, name, value, /)
# setattr(x, 'y', v) is equivalent to ``x.y = v''
setattr(klass, func.__name__, func)
return klass
클래스내의 속성을 등록 :
Setattr(클래스명, 속성명, 속성값)
145.
클래스 생성 함수실행
클래스 생성함수 파라미터에 메소드를 전달 한
후 실행
#클래스 생성
Foo = class_with_method(say_foo)
print('Foo dict ', Foo.__dict__)
#인스턴스 생성 및 메소드 호출
foo = Foo()
foo.say_foo()
#클래스 __dict__ 출력 결과
('Foo dict ', {'__module__': '__main__', 'say_foo':
<function say_foo at 0x107071B0>, '__doc__':
None})
foo
#Foo.say_foo() 호출 처리 결과
foo
클래스 생성 함수정의
클래스와 메소드 함수를 정의
# 생성자 및 세팅 메소드 추가
def __init__(self, x=None):
self._x = x
def set_x(self, value):
self.x = value
#type 함수를 이용하여 클래스 정의
SubClass = type('SubClass', (object,),
{ '__init__':__init__,'set_x': set_x})
Type(클래스명,상속(튜플),dict에
속성 추가)
150.
클래스 생성 함수실행
인스턴스를 생성해서 속성 세팅 실행
print(SubClass.__dict__)
# 인스턴스 생성
obj = SubClass()
#속성세팅
obj.set_x(42)
print( obj.x ) # Prints 42
print (isinstance(obj, object) )
#클래스 __dict__ 출력 결과
{'set_x': <function set_x at 0x10577830>,
'__module__': '__main__', '__dict__': <attribute
'__dict__' of 'SubClass' objects>, '__weakref__':
<attribute '__weakref__' of 'SubClass'
objects>, '__doc__': None, '__init__': <function
__init__ at 0x10707030>}
#obj.x 호출 처리 결과
42
#isinstance() 함수 처리결과
True
상속 클래스 정의
상속할클래스 정의
# 상속될 클래스 정의
class BaseClass(object) :
def __init__(self,x) :
self.x = x
# 속성(메소드) 정의
def set_x(self, value):
self.x = value
153.
클래스 생성 실행
클래스생성 및 인스턴스 생성 후 실행
SubClass1 = type('SubClass', (BaseClass,), { 'set_x':
set_x})
obj1 = SubClass1(5)
print(obj1.x)
obj1.set_x(50)
print(obj1.x)
#처리결과
#obj.x before
5
#obj.x after
50
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한 모듈을 확인 여부
157.
Inspect class/object
객체에 대한다양한 점검을 위한 함수를 제공
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
158.
Inspect 함수
함수에 대한다양한 점검을 위한 함수를 제공
Function Description
inspect.isfunction(object) Object가 함수 여부
inspect.isgeneratorfunction(object)
Object가 제너레이터 함수 여부
inspect.isgenerator(object)
Object가 제너레이터 여부