Class에 대한 밍기적 in Python

Posted by : at

Category : Etc


클래스

  • 클래스는 관련된 속성과 동작을 하나의 범주로 묶어 실세계의 사물을 흉내 낸다.

 

왜 사용하는가?

  • 계좌를 떠올려 보자. 계좌에는 잔액이 있고 입출금 및 조회라는 행위가 존재한다.

  • 계좌를 이용하고 싶은데 입금을 하려면 A라는 곳으로 가야하는데 잔액 조회를 하려면

    B라는 곳으로 가야한다면 얼마나 불편할까

  • 이를 한 번에 묶어서 계좌를 만드는 순간 입출금, 잔액조회를 한 장소에서 할 수 있게 해주는 것이 클래스이다

 

생성자

  • num = 5와 같이 integer변수를 초기화 하는 것은 매우 간단하다.
  • 그런데 아까 같이 계좌를 떠올리면 어떤가? 계좌에는 정말 많은 정보(멤버)가 존재한다
    • 계좌번호, 잔액, 은행, 거래내역…
  • num을 초기화 할 때처럼 일일이 넣는다면 코드가 비효율적으로 늘어날 것이다.
  • 이를 효율적으로 해결해주는 게 생성자이다.

 

class Class이름:
    
    def __init__(self, 초기값):
        멤버 초기화
        
    메서드 정의
    
객체1 = Class이름(맴버1, 맴버2, 맴버3, ...)
객체2 = Class이름(맴버1, 맴버2, 맴버3, ...)

 

  • 생성자는 이처럼 새로운 객체를 만들 때 불린다.
  • 편하게 붕어빵을 찍어낸다 생각하면 될 것이다.

 

상속

  • 기존에 만든 클래스(부모)에 몇 가지 기능을 추가하여 새로운 클래스(자식)를 만들고 싶을 때 사용한다.

  • 내가 새로 만든 클래스의 모든 기능을 다시 다 작성하지 않고 부모클래스의 기능을 가져올 수 있다는 점은

    매우 매력적인 기능임을 사용하다 보면 느끼게 될 것이다.

  • 그렇다고 부모의 기능을 무조건 사용해야 하는 것은 아니다. 자식 클래스에 맞게 부모의 함수를 바꾸는 Override라는 기능도 있다.

  • 앞으로 많이 볼테니 예시 코드는 생략 >_O

 

액세서

  • 클래스에 있는 멤버를 일정한 규칙으로 접근하게 하는 메서드로 GetterSetter가 있다.
  • 아까 계좌를 떠올려보자. 계좌의 멤버에 아무렇게나 변경할 수 있게 한다면 실수로 잔액이 -50000원이 될 지도 모르는일 아닌가?
  • 말로만 설명하는 것보다 직접 살펴보는 편이 이해가 더 잘 될 것이다.

 

class Date:
    
    def __init__(self, month):
        self.__month = month;

    @property
    def month(self):
        return self.__month

    @month.setter
    def month(self, month):
        if 1 <= month <= 12:
            self.__month = month

today = Date(8)
today.month = 15
print(today.month)

 

  • @propertyGetter의 decorator이고 @이름.setterSetter의 decorator이다.
  • 위와 같이 GetterSetter를 사용하면 15월달이 새로 생기는 불상사는 일어나지 않을 것이다.

 

클래스 메서드

  • 여태까지 사용했던 함수들은 다 객체별로 따로 동작하였다.
  • 그런데 모든 객체가 공유할 수 있는 함수 혹은 변수가 있으면 유용하지 않을까?(그냥 그렇다고 하자)
  • 그런 당신의 의문을 위해 준비했다. 바로 클래스 메서드이다.

 

class Car:
    
    count = 0
    
    def __init__(self, name):
        self.name = name
        Car.count += 1
        
    @classmethod
    def outcount(cls):
        print(cls.count)

pride = Car("프라이드")
korando = Car("코란도")
Car.outcount()

 

  • @classmethod는 클래스 메서드의 decorator이다.

  • 새로운 Car객체가 생길 때마다 클래스 전체에 공유되는 변수 count가 1씩 증가하게 되고

    최종적으로 Car.outcount()함수를 부르면 여태까지 생긴 Car객체의 개수가 출력되게 된다.

 

정적 메서드

  • 정적메서드는 클래스에 포함되는 단순한 유틸리티 메서드이다.
  • 특정 객체에 소속되지 않고 클래스와 관련된 동작을 하지도 않는다(?)

 

class Car:
    
    count = 0
    
    def __init__(self, name):
        self.name = name
        Car.count += 1
        
    @classmethod
    def outcount(cls):
        print(cls.count)
        
    @staticmethod
    def hello():
        print("오늘도 안전운전하세요")

Car.hello()

 

  • @staticmethod는 정적메소드의 decorator이다.
  • 말 그대로 그냥 클래스에 포함되어 있을뿐인 함수이다.

 

연산자 메서드

  • 우리는 if문에서 !=라든지 >=같은 비교연산자를 변수 사이에서 +//같은 연산자를 자주 사용했었다.

    그런데 객체 간에 이러한 연산자를 사용하고 싶으면 어떨까?

  • 눈치 빠른 사람이라면 바로 연산자 오버로드를 떠올릴 것이다. 그런데 C++에서는 자주 했었는데

    Python은 연산자를 함수의 이름으로 쓸 수 없다고 한다.ㅜ_ㅜ 그래서 준비했다~

 

연산자 메서드
== _ _ eq _ _
!= _ _ ne _ _
< _ _ lt _ _
> _ _ gt _ _
<= _ _ le _ _
>= _ _ ge _ _
+ _ _ add _ _
- _ _ sub _ _
* _ _ mul _ _
/ _ _ div _ _
// _ _ floordiv _ _
% _ _ mod _ _
** _ _ pow _ _

 

_ _ eq _ _

class Human:

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

    def __eq__(self, other):
        return self.age == other.age and self.name == other.name

 

kim = Human(29, "김상형")
sang = Human(29, "김상형")
moon = Human(44, "문종민")
print(kim == sang)
print(kim == moon)
print(kim is sang)

# ==> True False False

 

  • 우리가 원하는대로 나오는 것을 볼 수 있다.
  • 여기서 한 가지 재밌는 점은 is연산자를 사용했을 때 False가 나온다는 점이다. 정답은 생성자에 있다.

 

특수 메서드

  • 지금까지 기본적으로 사용되는 메서드를 배웠다고 하면 이제부터는 조금 심화버전의 메서드가 나온다.
  • 크게 str, repr, len 3가지를 볼 것이다. 설명과 예시를 보자.
메서드 설명
_ _ str _ _ str(객체) 형식으로 객체를 문자열화한다.
_ _ repr _ _ repr(객체) 형식으로 객체의 표현식을 만든다.
_ _ len _ _ len(객체) 형식으로 객체의 길이를 조사한다.

 

_ _ str _ _

class Human:

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

    def __str__(self):
        return "이름 %s, 나이 %d" %(self.name, self.age)

kim = Human(29, "김상형")
print(kim)

# __str__의 유무
# <__main__.Human object at 0x000002744AAD3588> => 이름 김상형, 나이 29

 

_ _ repr _ _

class Human:

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

    def __str__(self):
        return "이름 %s, 나이 %d" % (self.name, self.age)

    def __repr__(self):
        return "Human(" + str(self.age) + ",'" + self.name + "')"

kim = Human(29, "김상형")
print(kim)
kimexp = repr(kim)
kimcopy = eval(kimexp)
print(kimcopy)
  • 이 기능을 잘 사용하면 객체를 표현식으로 바꾸고 다시 표현식으로부터 객체를 만드는 등의 방식으로 활용할 수 있다.

 

_ _ len _ _

class Card:

    spade = []
    heart = []
    clover = []
    diamond = []

    def __init__(self, spade, heart, clover, diamond):
        self.spade.extend(spade)
        self.heart.extend(heart)
        self.clover.extend(clover)
        self.diamond.extend(diamond)

    def __len__(self):
        return len(self.spade) + len(self.heart) + len(self.clover) + len(self.diamond)

card = Card([0,1,2,3],[3,4,5,6],[1,2,7,'J'],['Q','K'])
print(len(card))

 



About GJ

안녕하세요 방문해주셔서 감사합니다. 혹시 보시면서 궁금하신것 있으시면 https://open.kakao.com/o/sivaz71c로 연락주세용~

Star
Useful Links