class Rectangle:
"""직사각형 클래스"""
def __init__(self, width=0, height=0):
self.width = width # self.width, self.height = parameter
self.height = height # width, height = argument
def info(self):
print(f'Rectangle(w={self.width}, h={self.height})')
if __name__ == '__main__':
rect1 = Rectangle(3, 2)
# argument를 아무 것도 전달하지 않으면
# 모든 parameter는 기본값 (default argument)를 사용하게 됨
print(type(rect1))
print(id(rect1))
rect1.info()
rect2 = Rectangle(1) # height만 default argument가 사용됨
rect2.info()
rect3 = Rectangle(height=1) # keyword argument를 사용한 호출
rect3.info()
rect4 = Rectangle(2, 3) # positional argument를 사용한 호출
rect4.info()
print(id(rect4))
rect5 = Rectangle(width=2, height=3)
rect5.info()
print(id(rect5))
print(rect4 == rect5) # 다른 객체로 메모리에 저장함.
# 두 개의 객체 rect4와 rect5의 주소를 비교하기 때문
출력 결과
<class '__main__.Rectangle'>
3244136092552
Rectangle(w=3, h=2)
Rectangle(w=1, h=0)
Rectangle(w=0, h=1)
Rectangle(w=2, h=3)
3244136092808
Rectangle(w=2, h=3)
3244136092616
False
def __eq__(self, other):
return self.width == other.width and self.height == other.height
print(rect4 == rect5)
출력 결과
True
print(rect4 == rect5) # 다른 객체로 메모리에 저장함.
# obj1 == obj2 비교하는 방법(== 연산자의 동작 방식):
# obj1.__eq__(obj2)
# == 연산자는 클래스의 __eq__함수를 호출한다.
# 개발자가 클래스를 정의할 때 __eq__ 메소드를 정의하지 않아도
# 모든 클래스는 __eq__메소드를 가지고 있음.
# 기본 __eq__메소드는 개체들의 주소값(id)를 비교한다.
# 개발자가 __eq__ 메소드를 다른 방식으로 작성하면
# == 연산자는 개발자의 의도대로 True/ False를 리턴하게 된다.
def area(self):
return self.width * self.height
print(f'rect4 넓이: {rect4.area()}')
출력 결과
6
# 객체의 내용을 print할 때 자동으로 호출되는 메소드
def __str__(self):
return f'<직사각형 가로:{self.width}, 세로:{self.height}>'
print(rect5)
출력 결과
<직사각형 가로:2, 세로:3>
<클래스 정의>
from math import pi
class Circle:
# field: 반지름(radius)
# method:
# __init__() : 초기화(객체 생성)함수,
# area() : 원에 넓이를 리턴
# perimeter(): 원의 둘레 길이를 리턴하는 함수
# __str__() : Circle(r = 12) 형식으로 출력되도록 하기
# __eq__(): 반지름이 같으면 equal(True)
def __init__(self, radius):
self.radius = radius
if self.radius < 0:
raise TypeError('radius는 반드시 숫자 타입')
def area(self):
return self.radius ** 2 * pi
def perimeter(self):
return 4 * pi * self.radius
def __eq__(self, other): # == 연산자 사용시 호출되는 메소드
return self.radius == other.radius
def __str__(self): # print(c1) 사용시 호출되는 메소드
return f'Circle(r = {self.radius})'
def __gt__(self, other):
# greater than: > 연산자를 사용하면 자동으로 호출되는 메소드
return self.radius > other.radius
def __ge__(self, other): # greater than or equal to, >= 연산자 사용시 자동 호출
return self.__gt__(other) or self.__eq__(other)
<객체 생성>
if __name__ == '__main__':
c1 = Circle(10)
c2 = Circle(10)
print(f'area : {c1.area()}')
print(f'area : {c1.area}')
print(f'perimeter : {c1.perimeter()}')
print(f'perimeter : {c1.perimeter}')
print(c1 == c2)
print(c1)
print(c1 > c2)
print(c1 >= c2)
print(c1 < c2) # __lt__ 메소드를 지정하지 않아도 gt 의 반대값으로 계산됨
출력 결과
area : 314.1592653589793
area : <bound method Circle.area of <__main__.Circle object at 0x000001A4EB2E1E48>>
perimeter : 125.66370614359172
perimeter : <bound method Circle.perimeter of <__main__.Circle object at 0x000001A4EB2E1E48>>
True
Circle(r = 10)
False
True
False
그 외 연산자
__lt__ : less than (<)
__le__ : less than or equal to (<= )
__ne__ : not equal to (!=)
def __repr__(self): # representation : 리스트 출력시 호출
return f'원({self.radius})'
circles = [
Circle(10),
Circle(7),
Circle(100),
Circle(50),
Circle(0)
]
print(circles)
print(sorted(circles))
print(sorted(circles, reverse=True))
출력 결과
[원(10), 원(7), 원(100), 원(50), 원(0)] # print(circles)
[원(0), 원(7), 원(10), 원(50), 원(100)] # print(sorted(circles)) , 오름차순 정렬
[원(100), 원(50), 원(10), 원(7), 원(0)] # print(sorted(circles, reverse=True)) , 내림차순 정렬