객체지향 프로그래밍(Object Oriented Programming) : 객체를 우선으로 생각해서 프로그래밍한다는 의미
3주차에 "스마트스토어 상품 자동 등록 자동화 프로그램"프로젝트 리팩토링을 계획했다. 리팩토링을 하기전에 기존 코드가 객체지향 언어인 파이썬으로 작성되었지만 내부 동작은 절차지향으로 되었기 때문에 OOP(Object Oriented Programming)도 같이 적용하기로 했다. 그래서 우선적으로 파이썬 클래스에 대해 공부하는 시간을 가지기로 했다. (참고로 OOP에 대해서도 공부하는 시간을 가지기로 함.)
클래스(Class) : 객체지향 프로그래밍의 기본 단위
객체(Object) : 여러 가지 속성을 가질 수 있는 대상
클래스 구조
class 클래스 이름: 클래스 내용
인스턴스 생성
인스턴스 이름(변수 이름) = 클래스 이름()
생성자(Constructor) : 클래스 이름과 같은 함수
class 클래스 이름:
def __init__(self, 추가적인 매개변수):
pass
메소드 : 클래스가 가지고 있는 함수
class 클래스 이름:
def 메소드 이름(self, 추가적인 매개 변수):
pass
# 클래스 선언
class Student:
def __init__(self):
pass
# 학생 선언
student = Student()
# 인스턴스 확인
print("isinstance(student, Student) : ", isinstance(student, Student))
결과값
isinstance(student, Student) : True
type(student) == Student
를 사용가능!__<이름>__() 형태의 메소드는 특수한 상황에 자동으로 호출되도록 만들어짐.
이름 | 영어 | 설명 |
---|---|---|
eq | equal | 같다 |
ne | not equal | 다르다 |
gt | greater than | 크다 |
ge | greater than or equal | 크거나 같다 |
lt | less than | 작다 |
le | less than or equal | 작거나 같다 |
class 클래스 이름:
클래스 변수 = 값
클래스 이름.변수이름
# 클래스 선언
class Student:
count = 0
def __init__(self, name, korean, english, math):
# 인스턴스 변수 초기화
self.name = name
self.korean = korean
self.english = english
self.math = math
# 클래스 변수 설정
Student.count += 1
print(f"{Student.count}번째 학생이 생성되었습니다.")
# 학생 리스트 선언
students = [
Student("윤인성", 87, 88, 98),
Student("연하진", 98, 96, 98),
Student("구지연", 87, 88, 79),
Student("나선주", 99, 87, 88)
]
# 출력
print()
print(f"현재 생성된 총 학생 수는 {Student.count}명입니다.")
결과값
1번째 학생이 생성되었습니다.
2번째 학생이 생성되었습니다.
3번째 학생이 생성되었습니다.
4번째 학생이 생성되었습니다.
현재 생성된 총 학생 수는 4명입니다.
class 클래스 이름:
@classmethod
def 클래스 함수(cls, 매개변수):
pass
클래스 이름.함수 이름(매개변수)
# 클래스 선언
class Student:
# 클래스 변수
count = 0
students = []
# 클래스 함수
@classmethod
def print(cls):
print("----- 학생 목록 -----")
print("이름\t총점\t평균")
for student in cls.students:
print(str(student))
print("----- ----- -----")
# 인스턴스 함수
def __init__(self, name, korean, english, math):
# 인스턴스 변수 초기화
self.name = name
self.korean = korean
self.english = english
self.math = math
# 클래스 변수
Student.count += 1
Student.students.append(self)
def get_sum(self):
return self.korean + self.english + self.math
def get_average(self):
return self.get_sum() / 3
def __str__(self):
return f"{self.name}\t{self.get_sum()}\t{self.get_average()}"
# 학생 리스트 선언
Student("윤인성", 87, 88, 98)
Student("연하진", 98, 96, 98)
Student("구지연", 87, 88, 79)
Student("나선주", 99, 87, 88)
# 현재 생성된 학생을 모두 출력
Student.print()
결과값
----- 학생 목록 -----
이름 총점 평균
윤인성 273 91.0
연하진 292 97.33333333333333
구지연 254 84.66666666666667
나선주 274 91.33333333333333
----- ----- -----
__<변수 이름>
형태로 선언# 모듈 가져오기
import math
# 클래스 선언
class Circle:
def __init__(self, radius):
self.__radius = radius
def get_circumference(self):
return 2 * math.pi * self.__radius
def get_area(self):
return math.pi * (self.__radius ** 2) # **연산자는 제곱을 뜻함.
# 원의 둘레와 넓이 구하기
circle = Circle(10)
print("#원의 둘레와 넓이를 구하기")
print("원의 둘레 :", circle.get_circumference())
print("원의 넓이 :", circle.get_area())
print()
# __radius에 접근
print("# __radius에 접근")
print(circle.__radius)
#원의 둘레와 넓이를 구하기
원의 둘레 : 62.83185307179586
원의 넓이 : 314.1592653589793
# __radius에 접근
Traceback (most recent call last):
File "C:/Users/21528463/PycharmProjects/pythonProject1/private_var.py", line 25, in <module>
print(circle.__radius)
AttributeError: 'Circle' object has no attribute '__radius'
# 클래스 선언
class Circle:
...생략
# 게터와 세터
def get_radius(self):
return self.__radius
def set_radius(self, value):
self.__radius = value
# 원의 둘레와 넓이 구하기
circle = Circle(10)
print("#원의 둘레와 넓이를 구하기")
print("원의 둘레 :", circle.get_circumference())
print("원의 넓이 :", circle.get_area())
print()
# 간접적으로 __radius에 접근
print("# __radius에 접근")
print(circle.get_radius())
print()
# __radius 값 변경 후 원의 둘레와 넓이 구하기
circle.set_radius(2)
print("#원의 둘레와 넓이를 구하기")
print("원의 둘레 :", circle.get_circumference())
print("원의 넓이 :", circle.get_area())
print()
#원의 둘레와 넓이를 구하기
원의 둘레 : 62.83185307179586
원의 넓이 : 314.1592653589793
# __radius에 접근
10
#원의 둘레와 넓이를 구하기
원의 둘레 : 12.566370614359172
원의 넓이 : 12.566370614359172
# 클래스 선언
class Circle:
...생략
# 게터와 세터
@property
def radius(self):
return self.__radius
@radius.setter
def radius(self, value):
self.__radius = value
# 원의 둘레와 넓이 구하기
circle = Circle(10)
print("#원의 둘레와 넓이를 구하기")
print("원의 둘레 :", circle.get_circumference())
print("원의 넓이 :", circle.get_area())
print()
# 간접적으로 __radius에 접근
print("# __radius에 접근")
print(circle.radius)
print()
# __radius 값 변경 후 원의 둘레와 넓이 구하기
circle.radius = 2
print("#원의 둘레와 넓이를 구하기")
print("원의 둘레 :", circle.get_circumference())
print("원의 넓이 :", circle.get_area())
print()
결과값
#원의 둘레와 넓이를 구하기
원의 둘레 : 62.83185307179586
원의 넓이 : 314.1592653589793
# __radius에 접근
10
#원의 둘레와 넓이를 구하기
원의 둘레 : 12.566370614359172
원의 넓이 : 12.566370614359172
상속(inheritance) : 기존 class를 그대로 물려받아 업그레이드시켜 사용하는 방법
# 부모 클래스 선언
# 부모 클래스 선언
class Parent:
def __init__(self):
self.value = "테스트"
print("Parent 클래스의 __init__() 메소드가 호출되었습니다.")
def test(self):
print("Parent 클래스의 test() 메소드입니다.")
# 자식 클래스 선언
class Child(Parent):
def __init__(self):
Parent.__init__(self)
print("Child 클래스의 __init__() 메소드가 호출되었습니다.")
# 자식 클래스의 인스턴스를 생성하고 부모의 메소드를 호출
child = Child()
child.test()
print(child.value)
결과값
Parent 클래스의 __init__() 메소드가 호출되었습니다.
Child 클래스의 __init__() 메소드가 호출되었습니다.
Parent 클래스의 test() 메소드입니다.
테스트
다중상속 : 다른 누군가가 만들어 놓은 형태들를 조립해서 내가 원하는 것을 만드는 것