29. TIL (python-class)

dream.log·2021년 7월 30일
0

TIL

목록 보기
28/42
post-thumbnail

데코레이터에 대해 공부하다보니, 클래스에 대해 알고 있다고 생각했지만 헷갈려하는 개념들이 꽤 있었다.
다시 한 번 처음부터 공부하며 개념을 확립하고 넘어가자!!

흔히 비유할 때, class를 제품을 담는 틀, method를 틀에서 나온 제품으로 비유하곤 한다.

1.class의 간단한 예시

☑️ 기본 구문

class Cookie:

a = Cookie()
b = Cookie()
  • 빈 클래스 Cookie를 생성한다.
    객체 a,b는 Cookie class의 결과값을 돌려받는다.


☑️__init__ 구문 예시

class name:
	def __init__(self, first, second): #first - 매개변수1, second - 매개변수2
    	self.first = first #self.속성1 = 매개변수
        self.second = second #self.속성2= 매개변수2
  • self : 객체를 호출할 때 호출한 객체 자신이 전달되기 때문에 self를 사용한다. 각종 구문 쓸 때 빠뜨리지 않도록 유의하자. self가 아닌 다른 이름을 써도 상관은 없다.
class Person:
	def __init__(self, name, age, address):
  	  self.hello 	= '안녕하세요'
  	  self.name 	= name
  	  self.age 	= age
    	  self.address 	= address
    
    	def greeting(self):
        	print('{0} 저는 {1} 입니다.'.format(self.hello,self,name))
            
dodam = Person('도담' , 20 , '서울특별시')
dodam.greeting() #안녕하세요 저는 도담 입니다.

print('이름:', dodam.name) # 이름 : 도담
print('나이:', dodam.age)  # 나이 : 20
print('주소:', dodam.address) # 주소 : 서울특별시

🌱 init 메서드를 살펴보면, self 뒤에는 name,age,address 를 지정해주었다.
그리고 메서드 안에서 self.name = name 처럼 매개변수를 그대로 self에 넣어서 속성으로 만들었다.

🌱 greeting에서는 인사하고 이름을 출력하며, 출력할 순서를 딕셔너리 형태로 지정해준 후 .format 을 활용해 출력할 매개변수를 순서대로 호출해준다. self를 포함해서!

🌱 클래스 바깥에서 인스턴스를 통해 접근하는 인스턴스 속성을 활용해 하단 프린트를 진행한다.

⚠️ class의 위치 인수, 키워드 인수

# 위치 인수
class Person:
    def __init__(self, *args):
        self.name    = args[0]
        self.age     = args[1]
        self.address = args[2]
 
dodam = Person(*['도담', 20, '서울특별시'])


# 키워드 인수
class Person:
    def __init__(self, **kwargs):   
        self.name    = kwargs['name']
        self.age     = kwargs['age']
        self.address = kwargs['address']
 
dodam1 = Person(name='도담', age=20, address='서울특별시')
dodam2 = Person(**{'name': '도담', 'age': 20, 'address': '서울특별시'})

🌱 위치 인수와 리스트 언패킹을 사용하려면 *args 를 사용해야한다. 매개변수에서 값을 가져오려면 arg[0] 의 형태로 사용한다.

🌱 키워드 인수와 딕셔너리 언패킹을 쓰려면 **kwargs 사용하면 된다.

class Person
	pass
dodam = person()   # 인스턴스 생성
dodam.name = '도담' # 생성한 인스턴스 속성 추가
dodam.name

인스턴스를 생성한 후 .을 이용해 속성을 추가하고 값을 넣어 인스턴스.속성 = 값 의 형태로 속성을 추가할 수 있다. 이 속성은 해당 인스턴스에만 해당된다!

2. 정적 메서드 및 클래스 상속 사용하기

☑️ 정적 메서드 사용하기

class Calc:
    @staticmethod
    def add(a, b):
        print(a + b)
 
    @staticmethod
    def mul(a, b):
        print(a * b)
 
Calc.add(10, 20)    # 클래스에서 바로 메서드 호출
Calc.mul(10, 20)    # 클래스에서 바로 메서드 호출

@ 데코레이터를 활용해 함수에 추가기능을 구현하고,
클래스에서 바로 메서드를 호출하는 방식으로 정적 메서드를 사용한다.
정적 메서드는 self가 없어 인스턴스 속성에는 접근할 수 없으며, 인스턴스 속성과 메서드가 필요 없을 때 사용하면 된다.

메서드의 실행이 외부 상태에 영향을 끼치지 않는 순수 함수를 만들 때 사용한다!
인스턴스의 상태를 변화시키지 않는 메서드를 만들 때 적합!!!

☑️ 클래스 상속 사용하기
기존 기능을 재사용할 때 용이한 기능이다. 상속 받을 클래스 안에 ()괄호를 넣고 기반 클래스의 이름을 넣어준다!

class Person:
    def greeting(self):
        print('안녕하세요.')
 
class Student(Person):
    def study(self):
        print('공부하기')
 
james = Student()
james.greeting()    # 안녕하세요.: 기반 클래스 Person의 메서드 호출
james.study()       # 공부하기: 파생 클래스 Student에 추가한 study 메서드

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

  • 상속관계를 확인하고 싶을 때는?
    issubclass(Student, Person) => True
    issubclass 함수를 활용해 ( ) 괄호 안에 각각의 함수 이름을 넣어 비교해주면 된다.

☑️ 포함 관계
영어로 has-a 관계. 같은 종류의 동등한 관계일 때는 상속을 이용하고, 그 이외에는 속성에 인스턴스를 넣는 포함 방식을 사용한다.

class Person:
    def greeting(self):
        print('안녕하세요.')
 
class PersonList:
    def __init__(self):
        self.person_list = []    # 리스트 속성에 Person 인스턴스를 넣어서 관리
 
    def append_person(self, person):    # 리스트 속성에 Person 인스턴스를 추가하는 함수
        self.person_list.append(person)

Person 내부에 PersonList가 포함되는 포함관계!

3. 기반 클래스의 속성 사용하기

☑️ super()로 기반 클래스 초기화하기

class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '안녕하세요.'
 
class Student(Person):
    def __init__(self):
        print('Student __init__')
        super().__init__()                # super()로 기반 클래스의 __init__ 메서드 호출
        self.school = '파이썬 공부중'
 
james = Student()
print(james.school)
print(james.hello)

super().__init__() 을 통해 기반 클래스가 초기화 되어 속성이 만들어진다.
현재, super() 를 사용하지 않으면 오류가 발생하는 상황이다.
기반 클래스인 Person의 __init__ method가 호출되지 않았기 때문이다.
Person의 __init__ method가 호출되지 않아 print(james.hello) 를 출력하려고 하면 에러가 발생한다.

파생클래스에서 __init__ method를 생략하면 기반 클래스의 __init__이 자동으로 호출되므로 super()을 사용하지 않아도 됨.

4. 메서드 오버라이딩

: 파생클래스에서 기반클래스 메서드를 새로 정의하는 것! 기반클래스의 메서드를 무시하고 새로운 메소드를 만든다는 의미이다. 어떠한 기능이 같은 메서드의 이름으로 계속 사용되어야 할 때 오버라이딩을 활용한다!
[overriding - 무시하다, 우선하다 ]

☑️ 오버라이딩 활용 예시

class Person:
    def greeting(self):
        print('안녕하세요.')
 
class Student(Person):
    def greeting(self):
        super().greeting()    # 기반 클래스의 메서드 호출하여 중복을 줄임
        print('저는 도담 입니다.')
 
james = Student()
james.greeting()

출력 결과 : 안녕하세요. 저는 도담 입니다.
Student의 greeting에서 super().greeting() 으로 person의 greeting을 호출했다! 즉, 중복되는 기능을 사용한다면 파생 클래스에서 다시 만들지 않고, 기반 클래스의 기능을 사용하면 된다는 의미이다.

5. 다중 상속 사용하기

여러 기반 클래스로부터 상속을 받아 파생 클래스를 만드는 방법이다.

☑️ 기본 형식

class 기반클래스이름1:
    코드
 
class 기반클래스이름2:
    코드
 
class 파생클래스이름(기반클래스이름1, 기반클래스이름2):
    코드

파생클래스의 괄호에 기반 클래스의 이름을 적어준다. 왼쪽에 적은 기반클래스1이 우선으로 여겨지는 값이므로 더 먼저 따라야 하는 클래스가 있다면 왼쪽에 적어주면 된다!

6. 추상 클래스

추상 클래스는 메서드의 목록만 가진 클래스이며 상속 받는 클래스에서 메서드 구현을 강제하기 위해 사용한다!
import abc 를 통해 모듈을 가져온다!. 그 후 데코레이터를 활용해 사용할 수 있다.
(abstract base class)의 약자

☑️ 추상 클래스의 기본 틀

from abc import *
 
class 추상클래스이름(metaclass=ABCMeta):
    @abstractmethod
    def 메서드이름(self):
        코드

☑️ 실제로 사용하기

from abc import *
 
class TodolistBase(metaclass=ABCMeta):
    @abstractmethod
    def Study_python(self):
        pass
 
    @abstractmethod
    def walking(self):
        pass
 
class Student(TodolistBase):
    def study_python(self):
        print('파이썬 공부하기')
 
    def walking(self):
        print('산책하기')
 
bella = Student()
bella.study_python()
bella.walking()

TodolistBase 에 내가 해야 할 일을 추상 메서드로 만들고, Student에는 추상클래스의 내용들을 모두 구현하여 클래스를 작성했다!
추상 클래스는 파생 클래스가 반드시 구현해야하는 메서드를 정해줄 수 있다!
추상 클래스의 추상 메서드를 모두 구현했는지 확인하는 시점은 파생 클래스가 인스턴스를 만들 때 이다!
bella = Student() 에서 확인! 구현되지 않았다면 TypeError 발생!

추상 클래스는 인스턴스로 만들 수 없으니 유의해야한다!
상속에만 사용하며, 파생 클래스에서 반드시 구현해야 할 메서드를 정해줄 때 사용한다.


클래스의 개념이 어렵기도 하고, 헷갈리는 개념들이 있었는데
프로젝트 가기 전에 한 번 정리하고 가는 것이 좋을 것 같아
처음부터 싹 - 훑어보았다.
확실히 더 많이 이해가 된 것 같아 뿌듯하다!

나중에 헷갈릴 때 다시 참고하자!


🟡 출처 : 코딩도장
(https://dojang.io/mod/page/view.php?id=2389)

profile
한 걸음, 한 걸음 포기하지 않고 발전하는 Backend-developer 👩🏻‍💻 노션 페이지를 통한 취업 준비 기록과 회고를 진행하고 있습니다. 계획과 기록의 힘을 믿고, 실천하고자 합니다.

0개의 댓글