python

[python] 강제성 부여 추상클래스 | 매직 메서드

전감자(◔◡◔) 2022. 9. 26. 21:22

'''
    추상 클래스 ( abstract class )
    1. abstract(추상적) 의미: 구체화되지 않음을 의미
    2. 특징:
           - 메모리에 못 올라간다. 즉, 객체생성이 불가능하다.
           - 추상 메서드(abstract method)를 갖는다.
              ==> 자식클래스에서 반드시 사용해야 되는 메서드를 추상메서드로 만든다. (강제성 부여)
              @abstractmethod
              def eat(self):
                  pass
              ==> 상속받은 자식클래스에서 부모의 추상메서드를 반드시 재정의해야
                  자식을 객체생성할 수있다.
    3. 문법
        from abc import ABC, abstractmethod
        class Pet:
          ==> 일반클래스
          ==> p = Pet() #객체생성 가능
        class Pet(ABC):
          ==> 추상클래스
          ==> p = Pet() #객체생성 불가
'''
from abc import ABC, abstractmethod

class Pet(ABC):
    @abstractmethod
    def eat(self):
        pass

class Cat(Pet):
    def eat(self):
        print("Cat eat")

class Dog(Pet):
    def eat(self):
        print("Dog eat")

# p = Pet()  # Pet은 추상메서드를 포함한 추상클래스이기 때문에 객체생성불가
c = Cat()
c.eat()
d = Dog()
d.eat()







'''
    매직 메서드 ( magic method , 스페셜 메서드)
   1. __메서드명__  형식으로 구성됨
   2. 우리가 직접 호출하는 것이 아니고 특정 작업을 하면
      자동으로 호출된다.
   3. 확인 방법
      print(dir(str))
   4. 결론은 필요할 때 매직 메서드를  재정의해서 사용하자. (*****)
'''

# 1. 클래스 생성할때 호출
class Cat:

    def __init__(self): # 인스턴스 값 초기화할 목적으로 재정의 했음.
        print("__init__")

c1 = Cat()

# 2. 클래스 생성후에  클래스를 참조하는 변수 출력(print)할 때
class Cat:

    def __init__(self,username, age):
        self.username = username
        self.age = age

    def __str__(self): # 자바의 toString() 메서드와 동일 기능
        return self.username + str(self.age)

    # 가정: 함수 호출해서 username과 age 얻기
    # def info(self):
    #     return self.username + str(self.age)

c = Cat("야옹이", 2)
# print(c.info()) # c.info() 라는 함수호출해서 "야옹이2" 결과값 받음 ==> info() 메서드를 반드시 호출해야됨.
print(c)         # c.info() 라는 함수호출없이 그냥 c만 출력해서 "야옹이2" 결과값 받음 ( 훨씬 편하게 원하는 데이터 얻을 수 있음 )


# 3. __call__ 재정의,
# 함수처럼 호출 가능도록 재정의 ==> 여지껏 사용했던 코드들중에서 호출할 수 있었던 것들은 모두 XXX 재정의했음.
# 호출 여부 확인 ?  callable(값)
class Cat:
    pass

class Dog:
    def __call__(self):
        return "__call__"

class Bird:
    def __call__(self, *n):
        return "__call__" + str(n)

c = Cat()
d = Dog()
b = Bird()
print("Cat 호출 가능 여부", callable(c)) # False, c() 불가능
print("Dot 호출 가능 여부", callable(d),  d()) # True
print("Bird 호출 가능 여부", callable(b),  b("까마귀")) # True __call__까마귀
print("Bird 호출 가능 여부", callable(b),  b("까마귀","꿩")) # __call__('까마귀', '꿩')

print("str 호출 가능 여부", callable(str)) # True, str()
print("int 호출 가능 여부", callable(int)) # True, int()
print("list 호출 가능 여부", callable(list)) # True, list()
print("tuple 호출 가능 여부", callable(tuple)) # True, tuple()
print("dict 호출 가능 여부", callable(dict)) # True, dict()