PYTHON

[Python] self, __init__, 추상 클래스, 상속, 클래스 변수, 객체 변수

미소서식지 2023. 6. 11. 10:04

self

파이썬 메서드의 첫 번째 인자로 항상 인스턴스가 전달된다.

 

class Foo:
    def func1():
            print("function 1")
    def func2(self):
            print("function 2")
>>> f = Foo()
>>> f.func2()
function 2
>>>

 

이때 func2()를 호출하면 잘 작동한다. 호출할 때는 아무것도 전달하지 않는 이유는 첫 번째 인자인 self에 대한 값은 파이썬이 자동으로 넘겨주기 때문이다. 

 

>>> f.func1()
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    f.func1()
TypeError: func1() takes 0 positional arguments but 1 was given
>>>

 

하지만, 인스턴스를 통해 func1()을 호출해보면 오류가 발생한다.

오류 메시지를 살펴보면 “func1()은 인자가 없지만 하나를 받았다”라는 것을 볼 수 있다.

이는 파이썬 메서드의 첫 번째 인자로 항상 인스턴스가 전달되기 때문에 발생하는 문제이다.

 

그렇다면 self의 정체는 무엇일까?

 

self는 클래스 내에 정의된 self는 클래스 인스턴스이다.

 

>>> class Foo:
        def func1():
                print("function 1")

        def func2(self):
                print(id(self))
                print("function 2")

>>>

 

# 인스턴스 f가 메모리에 할당된 주솟값 출력
>>> f = Foo()
>>> id(f)
43219856
>>>

# 인스턴스 f가 func2 메소드 호출
# self가 메모리에 할당된 주솟값 출력 - print(id(self))
>>> f.func2()
43219856
function 2
>>>

 

위와 같은 코드를 실행했을 때 인스턴스 f가 메모리에 할당된 주솟값과 self가 메모리에 할당된 주솟값은 같다.

즉, 클래스 내에 정의된 self는 클래스 인스턴스임을 알 수 있다.

 

__init__

  • 컨스트럭터라고 불리는 초기화를 위한 함수(메소드) - 자바의 생성자 같은 것
  • 인스턴스화를 실시할 때 반드시 처음에 호출되는 특수한 함수
  • 오브젝트 생성(인스턴스를 생성)과 관련하여 데이터의 초기를 실시하는 함수

 

class MyStatus:
    def __init__(self,age,name,height,weight):
        self.age = age
        self.name = name
        self.height = height
        self.weight = weight

    def print_name(self):
        print(self.name)

    def print_age(self):
        print(self.age)

    def print_height(self):
        print(self.height)

    def print_weight(self):
        print(self.weight)

a = MyStatus(34,"yamada",170,78)

 

상속

 

class 부모클래스:
    ...내용...

class 자식클래스(부모클래스):
    ...내용...

 

  • 자식클래스를 선언할때 소괄호로 부모클래스를 포함시킨다.
  • 자바와 달리 다중상속이 가능하다.

 

class Country:
    """Super Class"""

    name = '국가명'
    population = '인구'
    capital = '수도'

    def show(self):
        print('국가 클래스의 메소드입니다.')


class Korea(Country):
    """Sub Class"""

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

    def show_name(self):
        print('국가 이름은 : ', self.name)

 

추상 클래스

파이썬에서는 추상클래스를 통해 이를 상속하는 클래스들에게 특정 메소드의 구현을 강제할 수 있다.

자바의 경우에는 interface가 같은 역할을 한다.

추상 클래스를 만들려면 import로 abc 모듈을 가져와야 한다.

abc는 abstract base class의 약자이다.

 

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

 

일단 추상 클래스를 만든 모습이다.

추상클래스 옆에 (metaclass=ABCMeta)를 써준다.

 

그럼 추상클래스 StudentBase를 만들고, 이를 상속받아서 구현한 Student 클래스를 만들어보자.

 

from abc import *
 
class StudentBase(metaclass=ABCMeta): # 추상클래스
    @abstractmethod # 추상메소드
    def study(self):
        pass
 
    @abstractmethod
    def go_to_school(self):
        pass
 
class Student(StudentBase): # StudentBase를 상속받아서 구현한 구현클래스
    def study(self): # 추상메소드를 구현
        print('공부하기')
    def go_to_school(self):
    	print('학교가기')
 
james = Student()  # Student 클래스 인스턴스 생성
james.study()
james.go_to_school()

 

Student 클래스의 인스턴스를 생성하고 study, go_to_school과 같은 메소드를 호출하면 재정의(overriding)해서 구현한 Student 클래스의 함수가 호출된다.

 

클래스 변수와 객체 변수

https://junstar92.tistory.com/65

 

class Shop:
    def __init__(self): # 자식 클래스(HairShop, Restaurant)에도 초기화되는 객체 필드
        self.reserve_list = []

    def reserve(self, customer): # self가 인자로 들어가기 때문에 객체별로 생성되어야 하는 메소드 (객체별로 reserve_list 다름)
        self.reserve_list.append(customer)
        return True

class Restaurant(Shop):
    def __init__(self): # Restaurant 클래스의 인스턴스 생성 시 자동으로 상속되지만 명시함
        super().__init__()

    def reserve(self, customer):
        if customer.num_of_people >= 2 and customer.num_of_people <= 8:
            count = 0
            for i in self.reserve_list:
                if i.time == customer.time:
                    count += 1
            if count <= 1:
                super().reserve(customer)
                return True
        return False

 

 

Ref.

https://wikidocs.net/1742