관리 메뉴

IT journey

Python - 클래스 2편 본문

개인공부공간/Python

Python - 클래스 2편

step 2021. 5. 28. 16:31
728x90
반응형

직접 내용 정리하고 만든 예이니 퍼가실 때는 출처를 남겨주세요:)

 

Python - 클래스 1편 을 못 보고 오신 분들은 봐주시고 와주세요.

(7) 속성, 메서드 이름을 찾는 순서

인스턴스와 클래스에서 __dict__ 속성을 출력해 보면 현재 인스턴스와 클래스의 속성을 딕셔너리로 확인이 가능합니다.

class Zoo:
  def __init__(self,animal,age,food):
    self.hello = "안녕하세요"
    self.animal = animal 
    self.age = age
    self.food = food
  
  def ZooKeeper(self):
    print('{0} 저는 {1} 사육사입니다.'.format(self.hello,self.animal))

monkey = Zoo('원숭이',20,'바나나')
monkey.ZooKeeper()

monkey.__dict__ #인스턴스.__dict__
Zoo.__dict__ #클래스.__dict__

(8) 클래스와 메서드의 독스트링 사용하기

클래스의 독스트링은 클래스.__형식을 쓰고

메서드의 독스트링은 클래스.메서드.__doc__ 또는 인스턴스.메서드.__doc__형식으로 사용합니다.

class Zoo:
  '''동물원 클래스입니다.'''
  def __init__(self,animal,age,food):
    self.hello = "안녕하세요"
    self.animal = animal 
    self.age = age
    self.food = food
  
  def ZooKeeper(self):
    '''사육사 메서드입니다.'''
    print('{0} 저는 {1} 사육사입니다.'.format(self.hello,self.animal))

print(Zoo.__doc__)
print(Zoo.ZooKeeper.__doc__)
monkey = Zoo('원숭이',20,'바나나')
print(monkey.ZooKeeper().__doc__)

(8) 생성자와 소멸자

생성자

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드를 '생성자'라 말합니다.

객체를 생성할 때 자동적으로 인스턴스 변수를 초기화합니다. 또한 가장 먼저 실행되고 기본적으로 1개씩 가지고 있습니다.

#생성자 기본 구조
class 클래스명:
	def __init__(self):
    	문장
        ...

소멸자

인스턴스가 소멸될 때 호출되는 메서드를 말합니다.

#생성자 기본 구조
class 클래스명: 
	def __del__(self): 
    	문장 
        ...

아래는 생성자와 소멸자를 쓰기 전과 후에 대한 코드입니다.

class Zoo:
  def Animal(self,animal,age,food):
    self.animal = animal 
    self.age = age
    self.food = food
  
  def ZooKeeper(self):
    print("제가 담당하는 동물은",self.animal,"입니다.")
    print("그 동물의 나이는",self.age,"입니다.")
    print("그 동물이 좋아하는 먹이는",self.food,"입니다.")

monkey = Zoo()
monkey.Animal('원숭이',20,'바나나')
monkey.ZooKeeper()

print("\n\n")

giraffe = Zoo()
giraffe.Animal('기린',28,'잎사귀')
giraffe.ZooKeeper()

#위랑 같은 의미입니다.(생성자와 소멸자가 들어간 버전입니다.)
class Zoo:
  def __init__(self,animal,age,food):
    self.animal = animal
    self.age = age
    self.food = food

  def ZooKeeper(self):
    print("제가 담당하는 동물은",self.animal,"입니다.")
    print("그 동물의 나이는",self.age,"입니다.")
    print("그 동물이 좋아하는 먹이는",self.age,"입니다.")
  
  def __del__(self):
    print("객체가 소멸될 때 소멸되는 소멸자입니다.")

monkey=Zoo('원숭이',20,'바나나')
monkey.ZooKeeper()

print("\n\n")

giraffe = Zoo('기린',28,'잎사귀') 
giraffe.ZooKeeper()

(9) 정적 메서드 사용하기

메서드 위에 @staticmethod 붙여주고, 정적메서드는 매개변수에 self를 지정하지 않습니다.

@staticmethod처럼 앞에 @이 붙은 것을 데코레이터라고 하며 메서드(함수)에 추가기능을 구현할 때 사용합니다. 정적 메서드는 인스턴스 속성과 인스턴스 메서드가 필요 없습니다.

#구조
class 클래스이름 :
	@staticmethod
    def 메서드(매개변수1, 매개변수2):
    	코드

#예제
class Zoo:
  @staticmethod
  def Animal(animal,age):
    print("{0}입니다. 나이는 {1}살입니다.".format(animal,int(age)))

  @staticmethod
  def ZooKeeper(animal,food):
    print("{0}사육사입니다. 그가 좋아하는 먹이는 {1}입니다.".format(animal,food))

Zoo.Animal('원숭이','20') #클래스에서 바로 메서드 호출
Zoo.ZooKeeper('원숭이','바나나')

(10) 클래스 메서드(@classmethod )사용하기

#구조
class 클래스 이름:
	@classmethod
    def 메서드(cls,매개변수1,매개변수2):
    	코드
        
#사용한 예
#동물원 클래스 Zoo를 만들고 인스턴스가 몇 개 만들어졌는지 알아봅시다.
class Zoo:
  count = 0 #z클래스 속성

  def __init__(self):
    Zoo.count +=1 #인스턴스가 만들어질 때 클래스 속성 count에 1을 더함
  
  @classmethod
  def Animal_count(cls):
    print("{0}마리입니다.".format(cls.count)) #cls로 클래스 속성에 접근


monkey = Zoo()
turtle = Zoo()
giraffe = Zoo()
Zoo.Animal_count()

(11) 상속(is-a)관계

객체(Object Oriented) 지향 프로그래밍 나시나요?

기억 안나시는 분들은 Python - 클래스 1편에서 다루었으니 참고부탁드리겠습니다. 

 

이제 본론으로 들어가겠습니다. 상속은 객체 지향 프로그램의 이점 중 하나라고 할 수 있습니다.

 

상속은 물려받은 기능을 유지한 채 다른 기능을 추가할 때 사용하는 기능입니다.

기능을 물려주는 클래스를 기반 클래스(base class) 또는 슈퍼클래스(부모클래스)라고 합니다.

상속을 받아 새롭게 만드는 클래스를 파생 클래스(derived class) 또는 서브클래스(하위클래스 또는 자식클래스)라고 합니다. 이 클래스는 부모 클래스의 변수,메서드, 생성자를 물려받습니다.

단, 부모 클래스의 멤버의 개수보다 자식클래스의 멤버 개수가 작아서는 안됩니다.

 

클래스 상속은 연관되면서 동등한 기능일 때 사용합니다.

#기본 구조
class 기반클래스 이름:
	코드
class 파생클래스 이름(기반클래스 이름):
	코드

#사용한 예
class Animal:
  def __init__(self,animal,age,food):
    self.animal = animal
    self.age = age
    self.food = food

  def Animal_info(self):
    print("저는",self.animal,"입니다.")
    print("제 나이는",self.age,"입니다.")
    print("제가 좋아하는 먹이는",self.food,"입니다.")
  
  def eat(self):
    print(self.food,"먹기")

class Monkey(Animal):
  def eat(self):
    print("바나나 먹기")
  def color(self):
    print("노란색")

class Giraffe(Animal):
  def eat(self):
    print("잎사귀 먹기")
  def color(self):
    print("초록색")

monkey = Animal("원숭이",20,"바나나")
monkey.Animal_info()
monkey.eat()

print("\n\n")

giraffe = Animal('기린',28,'잎사귀') 
giraffe.Animal_info()
giraffe.eat()

 

쉽게 말해 아래와 같은 구조가 됩니다.

상속관계 확인해보는 함수

issubclass(파생클래스,기반클래스)로 확인할 수 있습니다.

확인했으면 맞을 경우는 True를 반환 아니면 False로 반환합니다.

issubclass(Monkey,Zoo)

오버라이딩

부모로부터 받은 메서드 내용을 자식 클래스에 맞게 내용을 변경하는 것을 말합니다.

(즉, 재정의한다고 합니다.) 

이 때 조건은 메서드명은 동일해야 합니다. 부모한테 받은 메서드보다 우선적으로 호출됩니다.

class Animal:
  def __init__(self,animal,age):
    self.animal = animal
    self.age = age
  
  def food(self):
    pass

  def Animal_info(self):
    print("저는",self.animal,"입니다.")
    print("제 나이는",self.age,"입니다.")
  
  def eat(self):
    print(self.food,"먹기")

class Monkey(Animal):
  def __init__(self,animal,age):
    self.animal = animal
    self.age = age

  def food(self):
    print("바나나 먹기")
  
  def color(self):
    print("노란색")

class Giraffe(Animal):
  def __init__(self,animal,age):
    self.animal = animal
    self.age = age
  
  def food(self,feed):
    print(self.animal,feed)
  
  def color(self):
    print("초록색")

monkey = Monkey("원숭이",20)
monkey.food()

giraffe = Giraffe('기린',28) 
giraffe.food("잎사귀 먹기")

super()

㉮ 자식 클래스가 부모 클래스를 호출합니다.(super().부모클래스)

class Animal:
  def __init__(self,animal,age,food):
    self.animal = animal
    self.age = age
    self.food = food

  def Animal_info(self):
    print("저는",self.animal,"입니다.")
    print("제 나이는",self.age,"입니다.")
    print("제가 좋아하는 먹이는",self.food,"입니다.")
  
  def eat(self):
    print(self.food,"먹기")

class Monkey(Animal):
  def eat(self):
    print("바나나 먹기")
  def color(self):
    print("노란색")
  #메서드 오버라이딩
  def Animal_info(self):
    super().Animal_info()


monkey = Monkey("원숭이",20,"바나나")
monkey.Animal_info()

㉯ super()로 기반 클래스 초기화 합니다. (super().__init__())

class Animal:
    def __init__(self):
        print('Animal __init__')
        self.hello = '안녕하세요'

class Monkey(Animal):
  def __init__(self):
    print("Monkey__init__")
    super().__init__() #super()로 기반 클래스의 __init__ 메서드 호출
    self.animal = "원숭이"

monkey = Monkey()
print(monkey.animal)
print(monkey.hello)

다중 상속 사용하기

#구조
class 기반클래스 이름1:
	코드
class 기반클래스 이름2:
	코드
    
class 파생클래스 이름(기반클래스 이름1,기반클래스 이름2):
	코드
    
#사용한 예
class Person:
  def hello(self):
    print("안녕하세요")

class Friend:
  def friendship(self):
    print("이것은 우정입니다.")

class Relation(Person,Friend):
  def Loyalty(self):
    print("의리입니다.")

둘리 = Relation()
둘리.hello
둘리.friendship()
둘리.Loyalty()

다이아몬드 상속

상속문제가 복잡하다고 생각할 수 있지만 우선순위가 앞이므로 앞에 있는 것을 상속받습니다.

class Person:
  def hello(self):
    print("안녕하세요 Person")

class Friend:
  def hello(self):
    print("안녕하세요 Friend")

class Family(Person):
  def hello(self):
    print("안녕하세요 Family")

class Relation(Friend,Family):
  pass

둘리 = Relation()
둘리.hello()

(12) 포함(has-a)관계

동등하지 않은 관계이며 속성에 인스턴스를 넣는 포함 방식을 사용합니다. 

쉽게 생각해 객체 속에 객체를 넣는다고 생각하면 됩니다.

예를 들면 저금통은 동전을 가지고 있다.를 생각해 볼 수 있습니다. 

 

다시 정리해보면 같은 종류에 동등한 관계일 때는 상속을 사용하나, 

그 외에는 속성에 인스턴스를 넣는(포함하는) 방식을 사용하면 됩니다.

 

class Piggy_bank:
  def __init__(self):
    self.isfulled = False #꽉 안차있습니다.
    self.coin_inside=[] #리스트로 빈공간 선언했으며 Piggy_bank 인스턴스를 넣어 관리합니다.

#넣을 공간이 남았습니다.
  def not_fulled(self):
    self.isfulled = True
    print("넣을 공간이 남았어요.")

  def put(self,sth):
    if self.isfulled:
      self.coin_inside.append(sth) #Piggy_bank 인스턴스를 추가하는 함수입니다.
      print("저금통안에 동전이 들어갔어요")
    else:
      print("넣을 공간이 없으니 비워주세요")

#이제 안넣기 위해 닫습니다.
  def close(self):
    self.isfulled = False
    print("이제 안넣을 거에요.")

class Money:
  pass

coin = Money()
coin_bag = Piggy_bank()
coin_bag.not_fulled()
#동전을 저금통에 넣어봅시다.
coin_bag.put(coin)
#저금통에 무엇이 있는지 확인해봅시다.
print("저금통에 있는 것은",coin_bag.coin_inside)
coin_bag.close()

(13) 기반 클래스의 속성 사용하기

출력하려고 하면 에러가 발생합니다.

class Animal:
  def __init__(self,animal,age,food):
    print("Animal__init__")
    self.animal = animal
    self.age = age
    self.food = food

  def Animal_info(self):
    print("저는",self.animal,"입니다.")
    print("제 나이는",self.age,"입니다.")
    print("제가 좋아하는 먹이는",self.food,"입니다.")
  
  def eat(self):
    print(self.food,"먹기")

class Monkey(Animal):
  def __init__(self):
    print("Monkey__init__")
    self.name = "Monkey"
  def eat(self):
    print("바나나 먹기")
  def color(self):
    print("노란색")

monkey = Monkey()
print(monkey.name)
print(monkey.animal) #기반 클래스의 속성을 출력하려고 하면 에러가 발생합니다.

연산자 오버로딩

연산자를 객체끼리 사용할 수 있게 기법을 말합니다.

어떤 연산자와 함수의 동작을 똑같이 수행하는 메서드를 정의합니다.

self는 객체 자신을 말하며, other은 더하고자 하는 값을 말합니다.

메서드(Method) 
__메서드명__(self,other)
연산자(Operator) 사용 예
__add__(self,other) +(이항) A+B,A-B
__pos__(self) +(단항) +A
__sub__(self,other) -(이항) A-B,A-=B
__neg__(self) -(단항) -A
__mul__(self,other) * A*B,*--B
__truediv__(self,other) / A/B,A/=B
__floordiv__(self,other) // A//B,A//=B
__mod__(self,other) % A%B,A%=B
__pow__(self,other) pow(),** pow(A,B),A**B
__lshift__(self,other) << A<<B,A<<=B
__rshift__(self,other) >> A>>B,A>>=B
__and__(self,other) & A&B,A&=B
__xor__(self,other) ^ A^B,A^=B
__or__(self,other) | A|B,A|=B
__invert__(self) ~ ~A
__abs__(self) abs() abs(A)
__lt__(self,other) < 작다(미만)
__le__(self,other) <= 작거나 같다
__eq__(self,other) == 같다
__ne__(self,other) != 같지 않다
__gt__(self,other) > 크다(초과)
__ge(self,other) >= 크거나 같다(이상)
__getitem__(self,index) [index] 인덱스 연산자
__contains__(self,other) in 멤버 확인
__len__(self) len 요소 길이
__str__(self) str 문자열 표현

연산자 오버로딩의 예입니다.

class calucate:
  def __init__(self,number):
    self.number = number
  
  def __add__(self,other):
    print("두 객체를 더할 때 실행")
    return self.number+other.number
  
  def __sub__(self,other):
    print("두 객체를 뺄 때 실행")
    return self.number-other.number

  def __truediv__(self,other):
    print("두 객체를 나눌 때 실행")
    return self.number/other.number

  def __floordiv__(self,other):
    print("두 객체를 나눗셈을 한 후 소수점 이하를 버림")
    return self.number//other.number

a = calucate(500)
b = calucate(80)

print(a+b)
print(a-b)
print(a/b)
print(a//b)

 

이전 발행글

Python - 클래스 1편

Python-함수

Python - 제어문

Python-자료형(사전형,집합)

Python-자료형(리스트,튜플)

Python - 자료형 (숫자형,문자열,불린형)

Python - 내장함수 1편

728x90
반응형

'개인공부공간 > Python' 카테고리의 다른 글

Python - 설치없이 이용하기,실행, 사용법  (12) 2021.05.30
Python - 모듈(외장함수) 1편  (10) 2021.05.29
Python - 클래스 1편  (18) 2021.05.27
Python-함수  (17) 2021.05.26
Python - 제어문  (10) 2021.05.25
Comments