Welcome! Everything is fine.

[3주차] Python 100 문제풀이 Part.3 - OOP 본문

자격증 및 기타 활동/여름방학 스터디(Python)

[3주차] Python 100 문제풀이 Part.3 - OOP

개발곰발 2021. 7. 22.
728x90

💡 OOP(Object Oriented Programming)

클래스 

클래스를 사용하면 변수와 함수를 하나로 묶어서 데이터를 더 효율적이고 체계적으로 사용할 수 있다. 각각의 객체를 생성 할 수 있는 '틀' 이라고 생각하면 된다. class로 만들어낸 것을 객체라고 하며, 클래스의 '인스턴스 객체를 생성한다'고 한다. 클래스 하나로 여러 개의 인스턴스를 만들 수 있다.

class 클래스명:
	 # 관련 코드 구현하기

클래스를 사용하려면 class 키워드를 선언하고 클래스명을 지정한다. 파이썬은 보통 snake_case를 사용하지만, 클래스의 이름은 관례적으로 CamelCase를 사용한다. 함수가 아니기 때문에 클래스명 뒤에 괄호()를 하지않고 바로 콜론(:)을 붙여 종료한다. 그러나 상속을 받는 클래스는 뒤에 괄호()를 붙인다. 클래스 내부에서 여러가지의 변수와 함수가 정의되고 사용되는데, 이를 클래스 멤버라고 한다. 클래스에서는 클래스의 행위나 동작을 구현하는 함수를 메서드라고 부른다.

클래스 사용법

❔ 아래 코드의 결과로 출력되는 것을 말해보시오.

class Pet:
    def bark_dog():
        print("멍멍!")
    def bark_cat():
        print("먀옹!")
    def bark_hamster():
        print("찍찍!")
 
p1 = Pet()
p1.bark_dog()

p2 = Pet()
p2.bark_cat()

p3 = Pet()
p3.bark_hamster()

✔ 위 코드는 에러가 난다. 왜냐하면 각 클래스 메서드마다 인자로 self 를 넣어주지 않았기 때문이다. self 를 사용하는 이유는 메서드 안에서 필드에 접근하기 위해서이다. 따라서 self 를 매개변수라기보단 메서드 안에 무조건 써야하는 것이라고 볼 수 있다. 그러나 메서드 안에서 필드에 접근 할 일이 없다면 self 는 생략이 가능하다.

# 에러가 나지 않도록 고친 코드
class Pet:
    def bark_dog(self):
        print("멍멍!")
    def bark_cat(self):
        print("먀옹!")
    def bark_hamster(self):
        print("찍찍!")

p1 = Pet()
p1.bark_dog()

p2 = Pet()
p2.bark_cat()

p3 = Pet()
p3.bark_hamster()

이름과 나이를 전달받아 객체를 생성하는 Person 클래스를 만들고 객체 정보를 출력하시오.

아래는 처음에 짠 코드로, 이름과 나이를 입력받아 출력하는 형식으로 만들었다.

# 처음에 짠 코드
class Person:
    def create_info(self):
    global pName, pAge
    pName = input("> ")
    pAge = input("> ")

    def print_info(self):
        print("Name :", pName)
        print("Age :", pAge)
        
p1 = Person()
p1.create_info() 
p1.print_info()

그러나 name과 age라는 매개변수를 만들어서 출력할 수도 있다. self 를 잘 활용해야한다.

class Person:
    def create_info(self, name, age):
        self.name = name
        self.age = age    # 이 메소드를 호출한 객체의 이름과 나이로 저장됨

    def print_info(self):
        print("Name :", self.name)
        print("Age :", self.age)
        
p1 = Person()
p1.create_info("홍길동", 20)   # 인자가 3개라고 해서 맨 앞에 p1을 적어줄 필요X
p1.print_info()

생성자 메서드와 소멸자 메서드

생성자 메서드란 객체가 클래스로부터 만들어지는 순간 제일 먼저 자동으로 호출되는 메소드다. 아래와 같이 __init__ 속성을 사용하여 정의한다. 생성자 메서드를 통해서 객체가 생성될 때 해당 객체의 여러 초기 값을 셋팅할 수 있다.

# 생성자 메서드
def __init__(self):
	# 관련 코드 구현하기

생성자나 소멸자와 같이 앞뒤에 '__' 2개가 붙은 경우에는 특별한 용도로 사용되는 메서드라는 뜻이며, '스페셜 메서드'라고도 부른다. 소멸자 메서드란 생성자 메서드와 반대로 객체가 소멸될 때 실행되는 메서드다. 소멸자 메서드는 __del__ 속성을 사용하여 정의한다. 주의할 점은 객체가 소멸된 후에는 해당 객체는 메소드를 사용할 수 없다는 점이다. 만약 객체가 소멸된 후에 사용한다면 에러가 난다.

# 소멸자 메서드
def __del__(self):
	# 관련 코드 구현하기

생성자 메서드를 사용하여 "객체가 하나 생성되었습니다."를 화면에 출력해보시오.

class Person:
    def __init__(self):
        print("객체가 하나 생성되었습니다.")

p1 = Person() # 인스턴스를 만들었을 뿐인데 바로 함수 호출

 생성자 메서드를 사용하여 이름과 나이를 전달받아 객체를 생성하는 Person 클래스를 만들고 객체 정보를 출력하시오.

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

    def print_info(self):
        print("Name :", self.name)
        print("Age :", self.age)

p1 = Person("홍길동", 20)
p1.print_info()

생성자를 이용하여 객체를 생성하는 코드이다. 결과로 출력되는 것을 말해보시오.

class SmartPhone:
    def __init__(self,name,price):
    	print(self.name + " 객체가 생성되었습니다.")
        self.name = name
        self.price = price
        print('-'*40)
        print(self.name + " 가격은 " + str(price) + "원 ")
        print('-' * 40)

s1 = SmartPhone('스마트폰', 500000)

✔ 에러가 난다. 단순히 순서를 뒤바꾼 문제인데, name과 price를 각각 self.name과 self.price에 할당 한 후에 출력해야한다.

# 올바른 코드
class SmartPhone:
    def __init__(self,name,price):
        self.name = name
        self.price = price
       	print(self.name + " 객체가 생성되었습니다.")
        print('-'*40)
        print(self.name + " 가격은 " + str(price) + "원 ")
        print('-' * 40)

s1 = SmartPhone('스마트폰', 500000)

클래스내에서 생성자와 소멸자를 모두 구현한 예제를 하나 만들어보시오.

class SmartPhone:
	# 생성자
    def __init__(self,name,price):
        self.name = name
        self.price = price
        print(self.name + " 객체가 생성되었습니다.")
        print('-'*40)
        print(self.name + " 가격은 " + str(price) + "원 ")
        print('-' * 40)
	# 소멸자
    def __del__(self):
        print(self.name + "객체가 소멸되었습니다.")

s1 = SmartPhone('엘지', 500000)
del s1

클래스 메서드 안에 다른 메서드 호출하기

self를 사용하여 클래스 내부에 있는 다른 함수를 호출 할 수 있다. 그러나 self 없이 호출 할 경우, 클래스 외부 함수를 호출하게 된다.

클래스 메서드 안에서 다른 메서드를 호출하는 코드를 만들어보시오.

class Self:
    def a_method(self):
        print("a_method가 호출되었습니다.")

    def b_method(self):
        self.a_method()     # self를 사용하여 클레스 내부에 있는 a_method 호출함.
        a_method()          # self 없이 메소드를 호출하면 클래스 외부 함수를 호출함.

def a_method():
    print("클레스 외부에 정의된 a_method입니다.")

s1 = Self()
s1.a_method()   # a_method를 바로 호출
s1.b_method()   # b_method 통하여 a_method 호출

클래스 변수

클래스 변수는 클래스 안에 공간이 할당된 변수를 의미한다. 클래스 변수는 인스턴스에 별도의 공간을 할당하지 않고, 여러 인스턴스가 클래스 변수의 공간을 함께 사용한다. 클래스 변수를 만드는 방법은 인스턴스 변수와 같지만, 접근 할 때는 클래스명.변수명 또는 인스턴스.변수명으로 접근해야한다.

변수를 클래스 외부에서 사용하는 예제를 만들어보시오.

class MyClass:
    # 클래스 변수
    a = 0
    # 클래스 메소드
    def a_method(self):
        MyClass.a = 6000

print("최초 클래스 변수 값 :", MyClass.a)

MyClass.a = 3000
print("클래스 변수 초기 값을 3000으로 변경 :", MyClass.a)

m1 = MyClass()
m1.a_method()
print("클래스내 메소드 호출을 통해 변수 값 수정 :", MyClass.a)

# print(MyClass.a_method()) --> Error, 반드시 객체를 통하여 접근하기

isinstance() 함수

특정 클래스의 인스턴스 객체인지 아닌지를 확인하기 위해서는 isinstance()함수를 사용한다. 특정 클래스의 인스턴스 객체가 맞으면 True, 아니면 False를 출력한다.

❔ 특정 클래스의 인스턴스 객체인지 아닌지를 확인하려면 어떻게 하는지를 설명해보시오.

class Person:
    pass
class Monster:
    pass

p1 = Person()
result_1 = isinstance(p1,Person)
print("[1] Person 클래스의 인스턴스가 맞나요? -->", result_1)

result_2 = isinstance(p1,Monster)
print("[2] Monster 클래스의 인스턴스가 맞나요? -->", result_2)

❔ 클래스의 인스턴스 객체가 생성될 때 마다 객체의 카운트를 1씩 증가시키는 클래스를 구현하시오.

class MyClass:
    count = 0
    def __init__(self, name, age, power):
        self.name = name
        self.age = age
        self.power = power
        self.increase_obj()
    def increase_obj(self):
        MyClass.count += 1
        print("현재까지 생성된 인스턴스 객체의 갯수 ->", MyClass.count)

m1 = MyClass("홍길동",20,7)