[Python3] 클래스

Alexandria·2023년 8월 31일
0

Python3 Basic

목록 보기
14/19
post-thumbnail

1. Class

클래스(Class)는 객체를 생성하기 위한 설계도 혹은 틀이며, 객체 지향 프로그래밍의 기본적인 개념 중 하나입니다. 하나의 설계도를 통해서 동일한 결과를 계속 만들어 낼 수 있으므로, 코드의 재사용성확장성을 높일 수 있습니다.

클래스는 class 키워드를 사용하여 정의할 수 있으며, 다음과 같은 형식으로 정의할 수 있습니다.

class ClassName:
    # class variable
    class_var = 10
    
    # Constructor
    def __init__(self, args):
        # instance variable
        self.instance_var = args
        
    # instance method
    def instance_method(self, args):
        # TODO
    
    # class method
    @classmethod
    def class_method(cls, args):
        # TODO
    
    # static method
    @staticmethod
    def static_method(args):
        # TODO

객체를 생성하면 해당 클래스의 인스턴스(instance)가 생성됩니다. 객체가 생성되면 해당 클래스의 모든 속성을 상속하게 됩니다.

myclass = ClassName(10)

1.1. Private Variable

클래스 변수나 인스턴스 변수의 이름 앞에 __가 붙으면 클래스 내부에서만 사용할 수 있는 변수가 됩니다.

class MyClass:
    __private_class_var = 10

    def __init__(self):
        self.__private_instance_var = 3

    def sum(self) -> int:
        return MyClass.__private_class_var + self.__private_instance_var

myclass1 = MyClass()
print(myclass1.sum()) # 13

다음과 같이 클래스 외부에서 접근하면 AttributeError가 발생합니다.

print(myclass1.__private_class_var) 
print(myclass1.__private_instance_var)

2. Method

메서드(Method)는 클래스에 속한 함수입니다. 하지만 메서드의 종류에 따라 클래스 내의 데이터에 대한 접근 권한이 다르게 적용됩니다.

2.1. Constructor

초기 값을 설정해야 할 필요가 있을 때는 생성자(constructor)를 이용하여 설정할 수 있습니다. 메서드의 함수 이름이 __init__이면 생성자로 취급됩니다.

class MyClass:
    def __init__(self, a:int):
        self.a = a

myclass1 = MyClass(a=10)
myclass2 = MyClass(a=20)
print(myclass1.a) # 10
print(myclass2.a) # 20

객체들을 다른 초기 값으로 설정할 수 있다면 객체들을 생성할 때 공통으로 같은 값을 설정하고 싶다면 클래스 변수를 사용할 수 있습니다.

class MyClass:
    b = 5

    def __init__(self, a:int):
        self.a = a

myclass1 = MyClass(a=10)
myclass2 = MyClass(a=20)
print(myclass1.a, myclass1.b) # 10 5
print(myclass2.a, myclass2.b) # 20 5

💡 생성자에서 클래스 변수에 접근하려면 MyClass.b와 같이 클래스 명.클래스 변수 명으로 접근할 수 있습니다.

2.2. Instance Method

클래스의 인스턴스 변수에 접근이 가능하며, 인자의 첫 번째는 항상 self로 시작됩니다.

다음의 예시에서는 메서드의 인자의 개수는 2개인데, 클래스 객체가 인스턴스 메서드를 호출 시 1개의 인자를 전달하고 있습니다.

class MyClass:
    def __init__(self, b:int):
        self.b = b
    
    def instance_method(self, c:int) -> int:
        return self.b + c

myclass1 = MyClass(b=10)
print(myclass1.instance_method(5)) # 15

myclass1이 self로 인식되기 때문에 1개의 인자만 전달하여도 됩니다. 2개의 인자를 전달할 때는 다음과 같이 사용할 수 있습니다.

class MyClass:
    def __init__(self, b:int):
        self.b = b
    
    def instance_method(self, c:int) -> int:
        return self.b + c

myclass1 = MyClass(b=10)
print(MyClass.instance_method(myclass1, 5)) # 15

💡 인스턴스 메서드에서 클래스 변수에 접근하려면 MyClass.b와 같이 클래스 명.클래스 변수 명으로 접근할 수 있습니다.

2.3. Class Method

클래스의 클래스 변수에 접근이 가능하며, 인자의 첫 번째는 항상 클래스 자신인 cls로 시작됩니다. 또한, 인스턴스를 만들지 않고도 호출할 수 있다는 특징이 있습니다.

클래스 메서드를 정의하려면 다음과 같이 @classmethod 데코레이터를 사용합니다.

class MyClass:
    a = 10
    
    @classmethod
    def class_method(cls, c:int) -> int:
        return cls.a + c

myclass1 = MyClass()
print(myclass1.class_method(5)) # 15
# 인스턴스 생성 없이 바로 호출
print(MyClass().class_method(5)) # 15

💡 클래스 메서드는 인스턴스 메서드에 접근할 수 없습니다.

2.4. Static Method

클래스나 인스턴스에 관련이 없는 함수를 정의할 때 유용합니다. 인스턴스 메서드나 클래스 메서드처럼 함수의 첫 번째 인자에 self나 cls를 사용하지 않습니다. 또한, 인스턴스를 만들지 않고도 호출할 수 있다는 특징이 있습니다.

스태틱 메서드를 정의하려면 다음과 같이 @staticmethod 데코레이터를 사용합니다.

class MyClass:
    @staticmethod
    def static_method(a:int, b:int) -> int:
        return a + b

myclass1 = MyClass()
print(myclass1.static_method(3, 5)) # 8
# 인스턴스 생성 없이 바로 호출
print(MyClass().static_method(3, 5)) # 8

💡 스태틱 메서드는 인스턴스 메서드에 접근할 수 없습니다.

2.5. Representation

객체의 문자열 표현을 반환할 때, __repr__을 이용하여 사용합니다. 이는 객체를 출력하거나 디버깅하는 데 사용됩니다.

다음과 같이 객체의 문자열을 표현할 수 있습니다.

class MyClass:
    def __init__(self):
        self.name = 'john'
        self.age = 20

    def __repr__(self) -> str:
        return f'MyClass(name={self.name}, age={self.age})'

myclass1 = MyClass()
print(myclass1) # MyClass(name=john, age=20)

3. Inheritance

상속(Inheritance)은 기존 클래스에서 공통된 속성과 메서드를 포함하는 새로운 클래스를 만드는 방법입니다. 새로운 클래스는 기존 클래스의 속성과 메서드를 그대로 사용할 수 있게 됩니다.

이렇게 상속을 받은 클래스는 자식 클래스라 하고, 기존 클래스를 부모 클래스라고 합니다.

다음과 같이 괄호 안에 부모 클래스 명을 입력하여 상속을 받을 수 있습니다. 10번째 줄의 super().__init__은 부모 클래스의 생성자를 통해 Student의 name과 age를 설정하게 됩니다.

class Person: # ParentClass
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def greeting(self):
        return f'my name is {self.name} and {self.age} years old'

class Student(Person): # ChildClass
    def __init__(self, name: str, age: int, id: int):
        super().__init__(name, age)
        self.id = id

    def get_student_id(self):
        return f'my student id is {self.id}'
    
john = Student(name="john", age=20, id=1)
print(john.greeting()) # my name is john and 20 years old
print(john.get_student_id()) # my student id is 1

3.1. Method Overriding

오버라이딩(Overriding)은 부모 클래스의 메서드를 자식 클래스에서 재정의하여 사용하는 것입니다. 오버라이딩을 통해 부모 클래스의 메서드보다 자식 클래스의 메서드가 실행됩니다.

class Person: # ParentClass
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def greeting(self):
        return f'my name is {self.name} and {self.age} years old'

class Student(Person): # ChildClass
    def __init__(self, name: str, age: int, id: int):
        super().__init__(name, age)
        self.id = id

    def greeting(self):
        return f'my name is {self.name} and id is {self.id}'
    
john = Student(name="john", age=20, id=1)
print(john.greeting()) # my name is john and id is 1

💡 Python에서는 오버로딩(Overloading)은 존재하지 않습니다.

profile
IT 도서관

0개의 댓글