Programming & Machine Learning/Python X 머신러닝
파이썬 기초 문법 - 3 (클래스와 오브젝트)
Yamarae
2017. 7. 27. 02:36
클래스와 오브젝트
#################################################################
#################################################################
### 클래스에서 self, cls, static의 역할
# class는 붕어빵 빵틀, object는 붕어빵이라고 비유가 가능.
# self는 붕어빵 각각이 가지는 속성이고, cls는 붕어빵 빵틀이 가지는 속성임.
# 클래스의 멤버변수를 선언할때 아래처럼 선언하면 빵틀 변수가 되는 것이고,
# init 에서 self로 선언하면 붕어빵의 변수가 되는 것이다.
class InstanceCounter:
count = 0
count2 = 0
def __init__(self):
self.count3 = 0
InstanceCounter.count += 1
self.count2 += 1
@classmethod
def print_instance_count(cls):
print(cls.count)
print(cls.count2)
@staticmethod
def print_static_count():
print(InstanceCounter.count)
print(InstanceCounter.count2)
a = InstanceCounter()
InstanceCounter.print_instance_count()
InstanceCounter.print_static_count()
b = InstanceCounter()
InstanceCounter.print_instance_count()
InstanceCounter.print_static_count()
c = InstanceCounter()
c.print_instance_count()
InstanceCounter.print_static_count()
#################################################################
#################################################################
### 예제2
class Car:
count = 0
def __init__(self):
Car.count += 1
def print(self):
print(self.count)
a = Car()
a.print()
b = Car()
b.print()
c = Car()
c.print()
# --> init 할때마다 붕어빵 빵틀의 속성 자체가 변하고 있음,
# 새로 Car 오브젝트를 생성하면 붕어빵의 기본 count가 빵틀에서 나온 속성으로 설정됨.
#################################################################
#################################################################
### 클래스의 퍼블릭, 프라이빗
class HasPrivate:
def __init__(self):
self.public = "Public"
self.__private = "Private"
def print_from_internal(self):
print(self.public)
print(self.__private)
obj = HasPrivate()
obj.print_from_internal()
print(obj.public)
print(obj.__private) # error -> __membervariable은 외부접근 불가.
### 상속
class Base:
def base_method(self):
print("base_method")
class Derived(Base):
pass
base = Base()
base.base_method()
derived = Derived()
derived.base_method()
#################################################################
#################################################################
### super를 이용한 상속
class A:
no_init = "hello no init"
def __init__(self):
self.hello = "hello"
print("A.__init__()")
class B(A):
def __init__(self):
#super().__init__()
print("B.__init__()")
b = B()
b.hello
b.no_init
# super로 부모클래스를 init해주지 않으면 부모의 init에서부터 생성된 속성 사용 불가
# super로 init 안해줘도 no_init 같은 속성은 사용 가능.
### 다중상속
class A:
pass
class B:
pass
class C(A,B):
pass
# super와 오버라이딩을 이용하면, 다중상속에서 다이아몬드 상속 문제를 해결 가능함.
#################################################################
#################################################################
### 데코레이터
# __call__() 메소드는 객체를 함수 호출 방식으로 사용하게 만듬.
# 첫번째 방법
class Callable:
def __call__(self):
print("I am called.")
obj = Callable()
obj()
class MyDecorator:
def __init__(self, f):
print("initialize decorator")
self.func = f
def __call__(self):
print("begin :{0}".format(self.func.__name__))
self.func()
print("end :{0}".format(self.func.__name__))
def print_hello():
print("hello world!")
obj = MyDecorator(print_hello)
obj()
# 두번째 방법
class MyDecorator:
def __init__(self, f):
print("Initializing MyDecorator...")
self.func = f
def __call__(self):
print ("Begin :{0}".format( self.func.__name__))
self.func()
print ("End :{0}".format(self.func.__name__))
@MyDecorator
def print_hello():
print("Hello.")
print_hello()
#################################################################
#################################################################
### 추상클래스와 메서드 implementation
from abc import ABCMeta
from abc import abstractmethod
class AbstractDuck(metaclass=ABCMeta):
@abstractmethod
def Quack(self):
pass
class Duck(AbstractDuck):
def Quack(self):
print("implementation")
duck = Duck()
duck.Quack()