파이썬+클래스+구조+이해하기 20160310

161
PYTHON CLASS 구구 Moon Yong Joon

Upload: yong-joon-moon

Post on 12-Jan-2017

2.451 views

Category:

Software


0 download

TRANSCRIPT

Page 1: 파이썬+클래스+구조+이해하기 20160310

PYTHONCLASS구조

Moon Yong Joon

Page 2: 파이썬+클래스+구조+이해하기 20160310

기술적접근

Page 3: 파이썬+클래스+구조+이해하기 20160310

객체

Page 4: 파이썬+클래스+구조+이해하기 20160310

왜 모든 것을 객체로 관리하나 ?

모든 것은 객체

값 문자열컨테이너

함수클래스

튜플리스트

딕션너리

집합

파이썬은 모든 것을 객체로 인식한다 . 데이터 구조가 다 객체이므로 클래스를 가지고 생성시 참조를 가지고 있음

파일모듈 패키지

모듈

Page 5: 파이썬+클래스+구조+이해하기 20160310

객체로 구성했나 ?실제 오퍼페이터를 내부적으로 메소드로 정의되어 있어서 메소드 처리로 인식되고 테이터 타입을 명확히 맞춰서 계산처리 됨

1.+(1) 1

__add__( 객체 )

>>> 1+12>>> >>> 1.+12.0>>> int(1.+1)2>>> >>> p=1>>> p.__add__(1)2>>>

Page 6: 파이썬+클래스+구조+이해하기 20160310

클래스 정의

Page 7: 파이썬+클래스+구조+이해하기 20160310

Class Notation파이썬 언어에서 객체를 만드는 타입을 Class 를 정의하여 사용

클래스 명변수

메소드

class 클래스이름 [( 상속 클래스명 )]:

< 클래스 변수 1> < 클래스 변수 2> ... def 인스턴스 메소드 (self[, 인수 1, 인수 2,,,]): < 수행할 문장 1> < 수행할 문장 2> ... def 클래스메소드 (cls[, 인수 1, 인수 2,,,]): < 수행할 문장 1> < 수행할 문장 2> ... def 정적메소드 ([, 인수 1, 인수 2,,,]): < 수행할 문장 1> < 수행할 문장 2> ...

Page 8: 파이썬+클래스+구조+이해하기 20160310

Instance Notation인스턴스 객체는 실제 클래스 객체가 생성시 할당인스턴스 변수와 메소드는 런타임 즉 실행시 등록하여 사용할 수 있음

인스턴스명 : 클래스명인스턴스 변수

인스턴스 메소드( 인스턴스 바인딩 경우 )

class 클래스이름 [( 상속 클래스명 )]: def __init__(self[, 인수 1, 인수 2,,,]): self. 변수명 = 인수 1 …… < 수행할 문장 2> ... def 인스턴스메소드 (self[, 인수 1, 인수 2,,,]): < 수행할 문장 1> < 수행할 문장 2> ... ...

Instance 명 = 클래스명 ( 초기인자들 )

Page 9: 파이썬+클래스+구조+이해하기 20160310

Class 로 Instance 처리파이썬 언어에서 객체를 만드는 타입을 Class 로 생성해서 처리Class 는 객체를 만드는 하나의 틀로 이용자바 언어와의 차이점은 Class 도 Object 로 인식

Class Object

Instance Object 1

Instance Object 2

Instance Object 3

instanciate

클래스에서 객체 생성하기

Page 10: 파이썬+클래스+구조+이해하기 20160310

New style classObject 를 상속하여 명확히 클래스들이 표시됨 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'>)FalseFalse(' class type ', <type 'type'>)(' class type ', (<type 'object'>,))TrueFalse

Page 11: 파이썬+클래스+구조+이해하기 20160310

Old style classObject 를 상속할 경우 old style class 로 표시되어 classobj 로 처리되 인스턴스는 intance 타입을 가짐

Import typesclass 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'>)TrueTrue

Page 12: 파이썬+클래스+구조+이해하기 20160310

Instance 생성자

Page 13: 파이썬+클래스+구조+이해하기 20160310

생성자 사용법__new__

__init__

새 인스턴스의 생성을 제어 할 필요시 사용 __new__ 인스턴스 생성의 첫 단계 __new__ 는 첫 번째 인수로 클래스를 받고 , 해당 유형의 새 인스턴스를 반환 mutable 및 immutable 유형 모두 사용

새 인스턴스의 초기화를 제어해야하는 경우 사용 __init__ 아무것도 반환하지 없음 __init__ 는 첫 번째 인수로 인스턴스를 받아 해당 인스턴스의 속성을 수정 . OBJ .__ 초기화 __ (* 인수 ) 를 호출하여 작성 후 수정 될 수 있음 mutable 의 유형에 사용

Page 14: 파이썬+클래스+구조+이해하기 20160310

생성자 형식__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

Page 15: 파이썬+클래스+구조+이해하기 20160310

생성자 사용법 예시__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 cprint 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'>Truedahl

Page 16: 파이썬+클래스+구조+이해하기 20160310

__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'>0data type <type 'list'>[1, 2, 3]

Page 17: 파이썬+클래스+구조+이해하기 20160310

__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

Page 18: 파이썬+클래스+구조+이해하기 20160310

__init__ 메소드 예시불변 인스턴스는 생성되면 초기화가 되지 않음가변은 초기화가 변경됨

# 튜플은 불변이므로 초기화 무시x=(1,2)x.__init__([3,4])print(x)

# 리스트는 가변이므로 초기화 됨y=[1,2]y.__init__([3,4])print(y)

# 결과값(1, 2)[3, 4]

Page 19: 파이썬+클래스+구조+이해하기 20160310

인스턴스 즉시 호출

Page 20: 파이썬+클래스+구조+이해하기 20160310

인스턴스 속성 미정의 후 생성클래스 생성자에 인스턴스 즉시호출 속성을 미정의하고 인스턴스를 호출시 실제 인스턴스가 없으므로 오류처리

>>> 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>>>

Page 21: 파이썬+클래스+구조+이해하기 20160310

인스턴스 속성 미정의 후 호출인스턴스 속성 미정의할 경우 반드시 인스턴스 처리하는 __call__ 메소드를 정의하여 처리해야 함

>>> class B:... def __init__(self):... print "From init ... "... def __call__(self):... print "From call ... "... >>> b = B()From init ... >>> b()From call ... >>>

Page 22: 파이썬+클래스+구조+이해하기 20160310

__init__ 과 __call__ 메소드 차이클래스 생성자에 따른 인스턴스를 초기화하고 즉시 인스턴스가 실행될 필요가 있을 경우 __call__ 처리

class D: def __init__(self): print "init" def __call__(self): print "call" D() # init D()() # init call

d = D() #initd() # call

생성자와 인스턴스 호출 메소드 정의

생성자와 인스턴스 호출 메소드 정의

Page 23: 파이썬+클래스+구조+이해하기 20160310

object class 이해하기

Page 24: 파이썬+클래스+구조+이해하기 20160310

object classObject class 내의 속성 확인하기

>>> dir(object)['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

Page 25: 파이썬+클래스+구조+이해하기 20160310

object class -1Object class 내의 기본 속성 확인하기

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'112

Page 26: 파이썬+클래스+구조+이해하기 20160310

object class -2Object class 내의 생성 및 호출 속성 확인하기

print object.__new__p = list.__new__(list)p.__init__([1,2])

print object.__init__, pprint 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

Page 27: 파이썬+클래스+구조+이해하기 20160310

object class -3Object class 내의 속성 핸들링 속성 확인하기

class A(object) : def __init__(self) : self.name = None self.age = Nonea = A() print a.__dict__ print object.__delattr__(a,"age")print object.__setattr__(a,"name",'dahl')print object.__getattribute__(a,"name")print a.__dict__

{'age': None, 'name': None}NoneNonedahl{'name': 'dahl'}

Page 28: 파이썬+클래스+구조+이해하기 20160310

object class -4Object class 내의 속성에 메모리 사이즈 및 주소 속성 확인하기

p = list.__new__(list)p.__init__([1,2])print object.__hash__(id(p))print object.__sizeof__(p)

-214166312220

Page 29: 파이썬+클래스+구조+이해하기 20160310

Class Member

Page 30: 파이썬+클래스+구조+이해하기 20160310

Class MemberClass 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}

인스턴스 메소드

Page 31: 파이썬+클래스+구조+이해하기 20160310

Predefined Class At-tributes

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.

Page 32: 파이썬+클래스+구조+이해하기 20160310

Instance MemberInstance 생성시 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} # 인스턴스 객체 관리 영역

Page 33: 파이썬+클래스+구조+이해하기 20160310

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

Page 34: 파이썬+클래스+구조+이해하기 20160310

클래스와 인스턴스 구조

Page 35: 파이썬+클래스+구조+이해하기 20160310

Object Namespace 흐름Base class

class

in-stance

in-stance

in-stance

상속

인스턴스 생성

Dict{}

Dict{}

Dict{} Dict{} Dict{}

Namespace 검색

객체는 자신들이 관리하는 Namespace 공간을 생성하며 객체 내의 속성이나 메소드 호출시 이를 검색해서 처리

Page 36: 파이썬+클래스+구조+이해하기 20160310

Class & instance scopeClass Object 는 인스턴스를 만드는 기준을 정리한다 . 클래스를 정의한다고 하나의 저장공간 (Namespace) 기준이 되는 것은 아니다 . - 클래스 저장공간과 인스턴스 저장공간이 분리된다

User de-finedClass

Instance

Instance

Instance

Built-inClass

상속 인스턴스화

Object Scope

Object Namespace

Page 37: 파이썬+클래스+구조+이해하기 20160310

Class/Instance 관계 매핑 Class 키워드로 클래스 정의 상속은 class 키워드 다음 () 내에 상속할 클래스 정의 인스턴스 생성은 클래스명에 () 연산자 사용

Super ClassClassinstance

상속인스턴스화

class A(object): def whoami(self): return self.__class__.__name__

a = A()

Page 38: 파이썬+클래스+구조+이해하기 20160310

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

Page 39: 파이썬+클래스+구조+이해하기 20160310

생성자와 소멸자

Page 40: 파이썬+클래스+구조+이해하기 20160310

생성자 처리 구조파이썬은 생성자는 클래스이 __init__() 메소드를 binding 하여 처리

Instance = ClassA( 인자 ) ClassA.__init__(instance, 인자 )

ClassA( 상위클래스 ) : def __init__(self, 인자 ) : # 생성자로직

Source code Execute code

Page 41: 파이썬+클래스+구조+이해하기 20160310

생성자 -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)

생성자 정의

인스턴스 객체 생성생성자와 자동으로 연계

Page 42: 파이썬+클래스+구조+이해하기 20160310

소멸자 - 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 = pt1pt3 = pt1print id(pt1), id(pt2), id(pt3) # prints the ids of the obejctsdel pt1del pt2del pt3

소멸자 정의

소멸자 활용

Page 43: 파이썬+클래스+구조+이해하기 20160310

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)")

# 데코레이터 정의 및 전달함수 정의@decoratorWithoutArgumentsdef 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", "argu-ments")

print ("After second sayHello() call"))

Page 44: 파이썬+클래스+구조+이해하기 20160310

메소드 접근자

Page 45: 파이썬+클래스+구조+이해하기 20160310

Class 멤버 접근자 - cls클래스 객체의 변수나 메소드 접근을 위해 cls 키워드 사용

Page 46: 파이썬+클래스+구조+이해하기 20160310

Instance 멤버 접근자 -self인스턴스객체 메소드의 첫 인자는 Self 를 사용하여 각 인스턴스별로 메소드를 호출하여 사용할 수 있도록 정의

Page 47: 파이썬+클래스+구조+이해하기 20160310

Method- Instance클래스 객체에서 생성되는 모든 인스턴스 객체에서 활용되므로 클래스 이름공간에서 관리메소드 첫 파라미터에 self 라는 명칭을 정의

Page 48: 파이썬+클래스+구조+이해하기 20160310

Method- 클래스 decorator클래스 객체에서 처리되는 메소드를 정의한다 . 클래스 메소드는 첫번째 파라미터에 cls 를 전달한다 .

장식자 @classmethod : 클래스 함수 위에 표시 -Python 2.x함수 classmethod() : 별도 문장으로 표시 – Python 3.x

인스턴스 객체도 호출이 가능

Page 49: 파이썬+클래스+구조+이해하기 20160310

Method- 정적 decorator클래스 객체로 생성된 모든 인스턴스 객체가 공유하여 사용할 수 있다 .

장식자 @staticmethod : 정적함수 위에 표시 – Python 2.x함수 staticmethod() 는 별도의 문장으로 표시 – Python 3.x

정적메소드는 파라미터에 별도의 self, cls, 등 객체에 대한 참조값을 전달하지 않아도 됨 인스턴스 객체에서도 호출이 가능

Page 50: 파이썬+클래스+구조+이해하기 20160310

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.emp-Count 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 생성 및 호출

Page 51: 파이썬+클래스+구조+이해하기 20160310

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

Page 52: 파이썬+클래스+구조+이해하기 20160310

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)

Page 53: 파이썬+클래스+구조+이해하기 20160310

Class Inheritance

Page 54: 파이썬+클래스+구조+이해하기 20160310

Inheritance상속은 상위 클래스를 하나 또는 여러 개를 사용하는 방법 class 상위 클래스명 : pass class 클래스명 ( 상위 클래스명 ) : pass

상속 정의시 파라미터로 상위 클래스명을 여러 개 작성시 멀티 상속이 가능함 class 클래스명 ( 상위 클래스명 , 상위 클래스명 ) : pass

Page 55: 파이썬+클래스+구조+이해하기 20160310

Class 구조 클래스는 슈퍼클래스를 상속

Super ClassClass

상속

class A(object): def __init__(self) : self.instanceS = " static instance member" def whoami(self): return self.__class__.__name__

Page 56: 파이썬+클래스+구조+이해하기 20160310

클래스 구조 예시 (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

클래스 구조

Page 57: 파이썬+클래스+구조+이해하기 20160310

클래스 구조 예시 (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

Page 58: 파이썬+클래스+구조+이해하기 20160310

Inheritance- scope

상속된 클래스도 검색하는 순서가 파라미터를 정리한 순서대로 변수나 메소드를 검색하여 처리됨상속된 클래스에 동일한 이름이 변수나 메소드가 존재시 첫번째 검색된 것으로 처리함class 클래스명 ( 상위 클래스명 , 상위 클래스명 ) : pass

Page 59: 파이썬+클래스+구조+이해하기 20160310

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 childc.childMethod() # child calls its method c.-parentMethod() # calls parent's method c.se-tAttr(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 정의 인스턴스 생성 및 호출

Page 60: 파이썬+클래스+구조+이해하기 20160310

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)

인스턴스 생성 및 호출

Page 61: 파이썬+클래스+구조+이해하기 20160310

상속구조 확인하기

Page 62: 파이썬+클래스+구조+이해하기 20160310

Method resolution orderMro 메소드는 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'>])

Page 63: 파이썬+클래스+구조+이해하기 20160310

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'>]'

Page 64: 파이썬+클래스+구조+이해하기 20160310

상속 : __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'>]

Page 65: 파이썬+클래스+구조+이해하기 20160310

자기 메소드 호출하기

Page 66: 파이썬+클래스+구조+이해하기 20160310

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

# 실행 결과TrueTrueTrueB SA

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__")

Page 67: 파이썬+클래스+구조+이해하기 20160310

Super() 사용하기

Page 68: 파이썬+클래스+구조+이해하기 20160310

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()).barprint 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 의 값

Page 69: 파이썬+클래스+구조+이해하기 20160310

Super() 함수의 binding(2.x)Super( 클래스 , 인스턴스 ). 메소드 () 은 클래스 .메소드 ( 인스턴스 ) 로 연결되는 구조이므로 파라미터가 빠지면 binding 이 되지 않는다 .

print super(C) # 실행 결과<super: <class 'C'>, NULL>

print super(C).fooFoo 는 인스턴스 함수이라서 binding 에러# 실행 결과AttributeError: 'super' object has no attribute 'foo'

Page 70: 파이썬+클래스+구조+이해하기 20160310

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().supprint D().sup.fooprint super(C,D()).fooprint 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’) 처럼 인식

Page 71: 파이썬+클래스+구조+이해하기 20160310

Super() 함수 (3.x)파이썬 3.x 버전부터 super() 함수이 파라미터가 없어도 자동으로 스택프레임에서 검색하여 처리함

Page 72: 파이썬+클래스+구조+이해하기 20160310

Overriding

Page 73: 파이썬+클래스+구조+이해하기 20160310

Overriding메소드를 이름으로 검색하므로 하위 클래스에 동일한 메소드가 존재하면 인스턴스 호출시 하위 클래스 메소드 부터 호출하므로 Overriding 처리 class 상위 클래스명 : def method(self) : pass class 클래스명 ( 상위 클래스명 ) : def method(self) : pass

Page 74: 파이썬+클래스+구조+이해하기 20160310

Overriding 구조 동일한 메소드를 instance/Class/Super Class 에 다 정의할 경우 실행시 instance 부터 호출이 되는 구조

Super ClassClassinstance

상속인스턴스화

클래스 정의 시 메소드클래스 정의 시 슈퍼 클래스메소드 재정의Runtime 시 클래스 및 슈퍼클래스 메소드 정의

Overriding 발생 Overriding 발생

Page 75: 파이썬+클래스+구조+이해하기 20160310

연산자 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__ 생성자 메소드 overridingv1 = Vector(2,10) v2 = Vector(5,-2)

# __add__ 메소드 overriding print v1 + v2

# __str__ 메소드 overriding print v1

Page 76: 파이썬+클래스+구조+이해하기 20160310

__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 클래스의 인스턴스로 클래스 내부의 속성을 조회

Page 77: 파이썬+클래스+구조+이해하기 20160310

./[] 연사자 overriding다른 클래스를 만들어서 연산자를 다양하게 사용하기 위해 오버라이딩 처리

class Test1(dict) : def __getattr__(self,name) : return self[name] def __setattr__(self,name, value) : self[name] = value

t1 = Test1()t1.a= 10t1['btest'] = 100

print t1.aprint t1['btest']print t1.__dict__print t1

# 결과값10100{}{'a': 10, 'btest': 100}

Super Class

Classinstance

상속인스턴스화

Overriding 발생

Page 78: 파이썬+클래스+구조+이해하기 20160310

./[] 연사자 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 내부 데이터 타입에 저장됨

Page 79: 파이썬+클래스+구조+이해하기 20160310

인스턴스 생성 기초

Page 80: 파이썬+클래스+구조+이해하기 20160310

Instance 구조 클래스는 슈퍼클래스를 상속하고 인스턴스를 만들어서 실제 기능들을 동작시킨다 .

Super ClassClassinstance

상속인스턴스화

Page 81: 파이썬+클래스+구조+이해하기 20160310

Instance 생성 방식 클래스명에 파라미터에 인스턴스 변수값을 정의해서 인스턴스를 생성함 인스턴스 생성시 생성자가 호출되어 처리됨

변수명 = 클래스명 ( 인스턴스 변수값 , 인스턴스 변수값 )def __init__(self, 인스턴스 변수값 , 인스턴스 변수값 ) : self. 인스턴스 변수 = 인스턴스변수값 매칭호출시 매칭됨

Page 82: 파이썬+클래스+구조+이해하기 20160310

Instance 생성 예시 Class 키워드로 클래스 정의 상속은 class 키워드 다음 () 내에 상속할 클래스 정의 인스턴스 생성은 클래스명에 () 연산자 사용

Super ClassClassinstance

상속인스턴스화

class A(object): def whoami(self): return self.__class__.__name__

a = A()

Page 83: 파이썬+클래스+구조+이해하기 20160310

Instance Scope 객체들간의 관계 ( 상속 및 instance 생성 등 ) 에 따라 객체 멤버들에 대한 접근을 처리검색 순서 : 인스턴스 > 클래스 > 상속클래스 >builtin Class

상속이 많아지면 다양한 상위 멤버들을 접근하여 처리할 수 있다 .

Page 84: 파이썬+클래스+구조+이해하기 20160310

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

Page 85: 파이썬+클래스+구조+이해하기 20160310

클래스와 인스턴스 접근

Page 86: 파이썬+클래스+구조+이해하기 20160310

Members( 변수 ) AccessClass/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()

Page 87: 파이썬+클래스+구조+이해하기 20160310

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

내장 객체

내장 객체

Page 88: 파이썬+클래스+구조+이해하기 20160310

Members( 메소드 ) AccessClass 정의시 인스턴스 메소드 정의를 하면 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()

Page 89: 파이썬+클래스+구조+이해하기 20160310

Members( 메소드 ) Access- 세부인스턴스에서 인스턴스메소드 호출하면 실제 인스턴스 메소드 실행환경은 인스턴스에 생성되어 처리

>>> # 인스턴스에서 실행될 때 바운드 영역이 다름>>> # is 연산자는 동일 객체 체계>>> cobj.f is C.__dict__['f'] False >>>>>> C.__dict__ {'classattr': 'attr on class', '__mod-ule__': '__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

내장 객체

내장 객체

Page 90: 파이썬+클래스+구조+이해하기 20160310

Controlling Attribute AccessInstance 의 Attribute 에 대한 접근을 할 수 있는 내부 함수__getattr__(self, name)__setattr__(self, name, value)__delattr__(self, name)__getattribute__(self, name)

Page 91: 파이썬+클래스+구조+이해하기 20160310

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__

Page 92: 파이썬+클래스+구조+이해하기 20160310

Association

Page 93: 파이썬+클래스+구조+이해하기 20160310

Association객체간에 관계를 구성하여 처리객체내부에 관계 객체를 생성하여 해당 객체의 기능을 처리

AB

Page 94: 파이썬+클래스+구조+이해하기 20160310

Association객체간에 관계를 구성하여 처리객체내부에 관계 객체를 생성하여 해당 객체의 기능을 처리

Page 95: 파이썬+클래스+구조+이해하기 20160310

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 associa-tion)

Aggregation is a weak Association (If the life of contained object doesn't depends on the container object, it is called weak associa-tion)

Page 96: 파이썬+클래스+구조+이해하기 20160310

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 관계 ) 가 있을 경우 메소드 결과값을 객체로 받아 연속적으로 실행하도록 처리

객체 . 내부객체 .메소드 처리# 결과값abB instance method None

Page 97: 파이썬+클래스+구조+이해하기 20160310

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 al-tered()" self.other.altered() print "CHILD, AFTER OTHER altered()"

Page 98: 파이썬+클래스+구조+이해하기 20160310

Dependency객체간에 관계를 구성하여 처리객체내부에 관계 객체로써 메소드 등에서 일회성으로 해당 객체를 생성하여 기능을 처리

AB

Page 99: 파이썬+클래스+구조+이해하기 20160310

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())

객체의 관계가 일회성 적으로 처리가 되는 관계

객체 . 메소드 (인스턴스객체 ) 처리# 결과값abB instance method NonebB instance method None

Page 100: 파이썬+클래스+구조+이해하기 20160310

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()

객체 내의 메소드의 결과를 자기자신으로 리턴하여 메소드를 연속해 호출하여 처리

Page 101: 파이썬+클래스+구조+이해하기 20160310

타 객체 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 으로 해당 객체를 전달

# 결과값acbB instance method C instance method None

a = A()

print a.b.bbb().ccc()

Page 102: 파이썬+클래스+구조+이해하기 20160310

Class 확인 방법

Page 103: 파이썬+클래스+구조+이해하기 20160310

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 처리

Page 104: 파이썬+클래스+구조+이해하기 20160310

Class & instance namespaceClass 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 정의

Page 105: 파이썬+클래스+구조+이해하기 20160310

Descriptor Protocol

Page 106: 파이썬+클래스+구조+이해하기 20160310

DescriptorDescriptor 는 특성 객체의 속성 접근시 먼저 그 속성의 특징을 체크하여 처리할 수 있는 방법으로기술자 프로토콜로 제지하면서 처리는 " 바인딩 행동 " 을 가진 메소드들로 구성 __get__(self, instance, owner),__set__(self, instance, value),__delete__(self, instance).

Page 107: 파이썬+클래스+구조+이해하기 20160310

Descriptor 메소드 파라미터별도의 descriptor 와 실체 class 인스턴스 간의 실행환경을 연계하여 처리Self: decriptor 인스턴스Instance: 실체 class의 인스턴스Owner: 실체 class 의 타입Value : 실체 class의 인스턴스의 변수에 할당되는 값

__get__(self, instance, owner),__set__(self, instance, value),__delete__(self, instance)

Page 108: 파이썬+클래스+구조+이해하기 20160310

Descriptor 종류Method descriptor 와 Data descripter 로 구분

Method descriptor 는 __get__(self, instance, owner) 구현

Data descriptor 는 __get__(self, instance, owner) __set__(self,instance, value),

__delete__(self, instance) 구현

Page 109: 파이썬+클래스+구조+이해하기 20160310

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)

Page 110: 파이썬+클래스+구조+이해하기 20160310

Descriptor : binding behavior

binding 하는 방법Direct Call

Instance Bind-ing

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.xprint " 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.xprint " 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)

Page 111: 파이썬+클래스+구조+이해하기 20160310

Basic data descriptorData 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

Page 112: 파이썬+클래스+구조+이해하기 20160310

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 생김 )

Page 113: 파이썬+클래스+구조+이해하기 20160310

Creating Property– 객체 직접 정의 (2)

실제 인스턴스 객체의 변수에 접근하면 Property 객체의 메소드를 호출하여 처리되고 인스턴스 객체의 변수값이 변경됨

p1 = P(1001)print id(p1.x)print P.__dict__['x']print id(p1.__dict__['x'])print p1.xp1.x = -12print p1.xprint p1.__dict__

# 처리결과값44625868<property object at 0x02C1D4E0>446258681001-12{'x': -12}

Page 114: 파이썬+클래스+구조+이해하기 20160310

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 생김 )

Page 115: 파이썬+클래스+구조+이해하기 20160310

Creating Property decorator(2)

Property 객체 생성하여 처리하는 방식과 동일

p1 = P(1001)print id(p1.x)print P.__dict__['x']print id(p1.__dict__['x'])print p1.xp1.x = -12print p1.xprint p1.__dict__

# 처리결과값44625916<property object at 0x02C1D3C0>446259161001-12{'x': -12}

Page 116: 파이썬+클래스+구조+이해하기 20160310

내장함수를 통한 객체접근

Page 117: 파이썬+클래스+구조+이해하기 20160310

Built-in 내장함수내장함수를 이용하여 객체의 속성에 대한 접근getattr(object, name[, default])setattr(object, name, value)delattr(object, name)hasattr(object, name)callable(object)

Page 118: 파이썬+클래스+구조+이해하기 20160310

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

# 처리결과값dahlMoon50

Page 119: 파이썬+클래스+구조+이해하기 20160310

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

# 처리결과값dahlMoon5020

Page 120: 파이썬+클래스+구조+이해하기 20160310

Information Hiding

Page 121: 파이썬+클래스+구조+이해하기 20160310

Information hiding - 변수__ 명칭 : Private ( 객체 내부에서만 사용 ) 외부에서 호출시 mangling 되는 구조로 요청시 접근 가능 인스턴스 ._ 클래스명 __ 명칭_ 명칭 : protected ( 클래스 및 하위 클래스에서만 사용 )

Page 122: 파이썬+클래스+구조+이해하기 20160310

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 명칭

Page 123: 파이썬+클래스+구조+이해하기 20160310

Information hiding – 변수 - 특별 __ 명칭 __ : 내장된 변수나 함수 등을 정의

Page 124: 파이썬+클래스+구조+이해하기 20160310

Information hiding –Descriptor(Property)

파이썬은 Property 객체를 이용하여 객체내의 변수들의 접근을 메소드로 제어한다 .Descriptor 객체 , Property 객체나 @property decorator 를 이용인스턴스 객체의 변수 명과 동일한 property 객체가 생성되어야 함

Class P Instance p1{‘_x’: }

Descriptor 인스턴스 생성x

생성

인스턴스생성

class 내 descripter 인스턴스의 메소드 호출하여 처리

Instance p1p1.x 접근

Descriptor

Page 125: 파이썬+클래스+구조+이해하기 20160310

Abstract Base Class

Page 126: 파이썬+클래스+구조+이해하기 20160310

Abstract Class추상화 클래스란 직접 인스턴스를 만들지 못하고 상속을 받아 메소드 오버라이딩해서 사용하는 방식

Concrete Class instanceObj = ConcreteClass()

인스턴스 객체 생성

Abstract Class instanceObj = ConcreteClass()

인스턴스 객체 생성XAbstract

ClassConcrete

Class instance

ConcreteClass(Abstract Class)

상속

Obj = ConcreteClass()

인스턴스 객체 생성

Page 127: 파이썬+클래스+구조+이해하기 20160310

Abstract Class 정의 방법추상화 클래스는 exception 및 abc 모듈 2 가지 처리 방법으로 만들 수 있다 .

exception 방식

abc 모듈 방식

모든 메소드를 subclass 에서 정의할 필요가 없다오류처리 : NotImplementedError

모든 메소드를 subclass 에서 정의해야 한다 . 오류처리 : TypeError

Page 128: 파이썬+클래스+구조+이해하기 20160310

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"

상속 및 메소드 오버라이딩

추상클래스의 모든 메소드를 구현할 필요없음

Page 129: 파이썬+클래스+구조+이해하기 20160310

Abstract Class : ABC 모듈ABC 모듈을 이용하여 정의해서 추상클래스 정의 후 상속을 받아 메소드 오버라이딩 처리

from abc import ABCMeta, abstractmethodclass Base(): __metaclass__=ABCMeta @abstractmethod def foo(self): pass @abstractmethod def bar(self): pass

class Concrete(Base): def foo(self): pass def bar(self): pass

상속 및 메소드 오버라이딩

추상클래스의 모든 메소드를 구현되어야 함

Page 130: 파이썬+클래스+구조+이해하기 20160310

Abstract Class :property 정의Abstract Class 에서 decorator(@property) 를 사용하여 처리하기

class 구현클래스명 () : 변수명@propertydef get 메소드명 :@ 변수명 .setterdef set 메소드명 :@ 변수명 .deleterdef del 메소드명 :

import abcclass 추상클래스명 () : __metaclass__ = abc.ABCMeta

@abc.abstractpropertydef get 메소드명 :@ 변수명 .setterdef set 메소드명 :@ 변수명 .deleterdef del 메소드명 :

매칭

Page 131: 파이썬+클래스+구조+이해하기 20160310

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 모듈을 이용해서 추상클래스 정의 추상클래스 상속받은 하위클래스 정의

Page 132: 파이썬+클래스+구조+이해하기 20160310

Duck typing

Page 133: 파이썬+클래스+구조+이해하기 20160310

Duck typeing 정의 방법다양한 클래스가 동일한 메소드를 처리할 수 있도록 인터페이스를 갖도록 만드는 법

함수

클래스

Duck typing 에 필요한 함수 정의 후 인스턴스들의 메소드 호출 처리

Duck typing 에 필요한 클래스 정의 후 인스턴스들의 메소드 호출 처리

Page 134: 파이썬+클래스+구조+이해하기 20160310

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")

함수 정의 클래스 정의

Page 135: 파이썬+클래스+구조+이해하기 20160310

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.

Page 136: 파이썬+클래스+구조+이해하기 20160310

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")

함수 정의 클래스 정의

Page 137: 파이썬+클래스+구조+이해하기 20160310

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.

Page 138: 파이썬+클래스+구조+이해하기 20160310

CLASS 로 RUNTIME클래스 생성

Moon Yong Joon

Page 139: 파이썬+클래스+구조+이해하기 20160310

클래스 정의 하기

Page 140: 파이썬+클래스+구조+이해하기 20160310

런타임 클래스 생성 정의다른 클래스를 __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__ : 초기화 생성

Page 141: 파이썬+클래스+구조+이해하기 20160310

런타임 클래스 실행클래스와 메소드 함수를 정의

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}))

Page 142: 파이썬+클래스+구조+이해하기 20160310

함수로 RUNTIME클래스 생성

Moon Yong Joon

Page 143: 파이썬+클래스+구조+이해하기 20160310

사용자 정의 함수 사용

Page 144: 파이썬+클래스+구조+이해하기 20160310

클래스 생성 함수 정의클래스와 메소드 함수를 정의

# 클래스에 등록할 메소드 정의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( 클래스명 , 속성명 , 속성값 )

Page 145: 파이썬+클래스+구조+이해하기 20160310

클래스 생성 함수 실행클래스 생성함수 파라미터에 메소드를 전달 한 후 실행

# 클래스 생성 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

Page 146: 파이썬+클래스+구조+이해하기 20160310

Type 함수 사용 ( 변수 )

Page 147: 파이썬+클래스+구조+이해하기 20160310

Type 함수 : 클래스 만들기 파이썬은 실제 리터럴 즉 값이 객체이므로 기본 객체의 구성을 이해해야

a =type('A',(object,),dict(a=1))

a.a # 1

Class A(object) : a = 1

과 동일한 표현

Page 148: 파이썬+클래스+구조+이해하기 20160310

Type 함수 사용

Page 149: 파이썬+클래스+구조+이해하기 20160310

클래스 생성 함수 정의클래스와 메소드 함수를 정의

# 생성자 및 세팅 메소드 추가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에 속성 추가 )

Page 150: 파이썬+클래스+구조+이해하기 20160310

클래스 생성 함수 실행인스턴스를 생성해서 속성 세팅 실행

print(SubClass.__dict__)# 인스턴스 생성obj = SubClass()

# 속성세팅obj.set_x(42)

print( obj.x ) # Prints 42print (isinstance(obj, object) )

# 클래스 __dict__ 출력 결과{'set_x': <function set_x at 0x10577830>, '__module__': '__main__', '__dict__': <at-tribute '__dict__' of 'SubClass' objects>, '__weakref__': <attribute '__weakref__' of 'SubClass' objects>, '__doc__': None, '__init__': <function __init__ at 0x10707030>}

#obj.x 호출 처리 결과42#isinstance() 함수 처리결과True

Page 151: 파이썬+클래스+구조+이해하기 20160310

Type 함수 사용 ( 상속 )

Page 152: 파이썬+클래스+구조+이해하기 20160310

상속 클래스 정의 상속할 클래스 정의

# 상속될 클래스 정의class BaseClass(object) :

def __init__(self,x) : self.x = x

# 속성 ( 메소드 ) 정의def set_x(self, value): self.x = value

Page 153: 파이썬+클래스+구조+이해하기 20160310

클래스 생성 실행클래스 생성 및 인스턴스 생성 후 실행

SubClass1 = type('SubClass', (BaseClass,), { 'set_x': set_x})

obj1 = SubClass1(5)

print(obj1.x)

obj1.set_x(50)

print(obj1.x)

# 처리결과#obj.x before5#obj.x after50

Page 154: 파이썬+클래스+구조+이해하기 20160310

INSPECTMODULE

Page 155: 파이썬+클래스+구조+이해하기 20160310

Insepect Module

Page 156: 파이썬+클래스+구조+이해하기 20160310

Inspect modulemodule 에 대한 다양한 점검을 위한 함수를 제공

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 한 모듈을 확인 여부

Page 157: 파이썬+클래스+구조+이해하기 20160310

Inspect class/object객체에 대한 다양한 점검을 위한 함수를 제공

Function Descriptioninspect.getmembers(object[, predi-

cate] 객체의 멤버를 튜플 ( 키와 값 ) 로 표시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

Page 158: 파이썬+클래스+구조+이해하기 20160310

Inspect 함수함수에 대한 다양한 점검을 위한 함수를 제공

Function Descriptioninspect.isfunction(object) Object 가 함수 여부

inspect.isgeneratorfunction(object) Object 가 제너레이터 함수 여부inspect.isgenerator(object) Object 가 제너레이터 여부

Page 159: 파이썬+클래스+구조+이해하기 20160310

함수클래스 확인Moon Yong Joon

Page 160: 파이썬+클래스+구조+이해하기 20160310

함수 구조함수를 정의하면 function class 이 인스턴스가 생성된다 .

object

function codedef add(x,y) : return x+y

in-stance

Page 161: 파이썬+클래스+구조+이해하기 20160310

함수 상속구조 확인하기add 함수를 기준으로 클래스 구조를 확인하면 최상위는 object 이고 function 과 code 클래스가 조회

object

function codedef add(x,y) : return x+y

instance

print add.__class__print type(add.func_code) print add.__class__.__bases__print add.func_code.__class__.__bases__

<type 'function'><type 'code'>(<type 'object'>,)(<type 'object'>,)