본문 바로가기
🔅Computer Science🔅/❗자료구조

[자료구조] 001. 파이썬 클래스 단계별 복습

by 윤무무 2023. 1. 7.

* 본 포스팅은 신찬수 교수님의 자료구조 강의 중 '파이썬 클래스 단계별 복습' 내용을 정리한 것

* [00.class의 정의]는 '점프 투 파이썬' 책을 참고함

 

https://youtu.be/PIidtIBCjE

00. 클래스 정의
  • Class : 설계 도면
  • Object(객체) : 클래스로 만든 피조물 (객체마다 고유한 성격을 갖고 있으며, 서로에게 영향을 주지 않음)
  • Instance : 특정 객체가 어떤 클래스의 객체인지 관계 위주로 설명 ex) a는 Cookie의 인스턴스
  • Method : 클래스 안에 구현된 함수

1. Class 매개 변수 (self)

 

self : 객체 자신을 호출하는 매개 변수 

 

class FourCal() :
    def __init__ (self, first, second):
        self.first = first
        self.second = second​
class FourCal:
    def setdata(self, first, second): #setdata 메서드의 매개변수
        self.first = first #메서드의 수행문
        self.second = second 
        
a = FourCal() #객체 생성
a.setdata(4, 2) #메서드 호출

 

Q. self, first, second와 같이 3개의 매개변수가 필요한데 a.setdata(4,2)에서는 두 개의 값만 전달한 이유?

 

A. setdata 메서드를 호출한 객체 a가 self의 값에 자동으로 전달되기 때문 즉, self를 통해 객체 자신을 호출하는 것

 

2. 생성자(Constructor)

 

객체가 생성될 때 자동으로 호출되는 메서드 (__init__ 사용)

class FourCal() :
    def setdata(self, first, second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first + self.second
        return result

a = FourCal()
a.setdata(4,2)
print(a.add())

=> 현재는 생성자가 없는 상태

class FourCal() :
    def __init__ (self, first, second):
        self.first = first
        self.second = second

=> 일반적으로 class에 제일 위에 생성자를 생성하는 것이 맞음

 

3. 상속, 오버라이딩

 

  • 상속 : 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것
  • 메서드 오버라이딩 : 부모 클래스에 있는 메서드를 동일한 이름으로 다시 만드는 것, 오버라이딩 하면 부모클래스의 메서드 대신 오버라이딩한 메서드가 호출됨
class FourCal() :
    def __init__ (self, first, second):
        self.first = first
        self.second = second
    def setdata(self, first, second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first + self.second
        return result

class MoreFourCal(FourCal): #class 상속
    def pow(self):
        result = self.first ** self.second
        return result

a = MoreFourCal(4,2)
print(a.pow())

 

01. Point 클래스 선언
class Point:
    def __init__ (self, x=0, y=0):
        self.x = x
        self.y = y
    
p = Point(1, 2)
print(p)

이렇게 코드를 쓰고 작동을 시키면  <__main__.Point object at 0x0000020FCE71BE50> 라는 오류가 난다.

 

=> print(p)를 하면 객체 p에 대한 정보를 출력해야 하는데, 구체적으로 어떤 내용인지 알지 못 하기 때문이다. (print 함수는 단순히 리턴된 문자열을 출력하는 것)

 

1. __str__ 함수, __repr__함수

 

  • __str__ 함수는 Point 객체의 출력하고 싶은 내용을 문자열로 만들어 리턴 해줌
  • (위 오류는 str 함수가 정의되어 있지 않아 객체의 기본 정보만 출력된 것)
  •  __repr__은 인간이 이해할 수 있는 표현으로 나타내게 하는 것
  • __str__ 은 문자열화를 하여 서로 다른 객체 간의 정보를 전달하는 데 사용하는 것
class Point:
    def __init__ (self, x=0, y=0):
        self.x = x
        self.y = y
    
    def __str__ (self):
        return f"({self.x}, {self.y})"

p = Point(1, 2)
print(p)

=> 올바른 코딩의 예

 

* 참고링크 : https://recordnb.tistory.com/47

 

 

02. Point 클래스 메쏘드 - 연산자 오버로딩

1. magic method

 

두 개의 underscore(__)로 감싼 특별한 메쏘드를 의미한다.  ex) __init__

 

class Point:
    def __init__ (self, x=0, y=0):
        self.x = x
        self.y = y
    
    def __str__ (self):
        return f"({self.x}, {self.y})"

    def __add__ (self, other):
        return Point(self.x + other.x, self.y + other.y)

p = Point(1,2)
q = Point(3,4)
r = p + q #직관적이라서 이해하기 쉼게 됨
s = p.__add__(q) 
print(r,s)

위의 코드와 같이, r = p+q의 형식으로 p.__add__(q) 의 메소드를 호출하는 것이다. 

 

r = p+q 의 형식으로 + 연산자를 사용한다면 직관적인 장점이 존재하고, 이를 위한 magic method를 제공하며, 

__add__ : r = p+q를 하면 실제로 r = p.__add__(q)가 호출되어, 두 벡터의 합 벡터가 리턴되어 r에 저장

 

* 연산자 오버로딩의 종류 : https://blog.hexabrain.net/287

 

class Point:
	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y
	
	def __str__(self):
		return f"({self.x}, {self.y})"
	
	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)
	
	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)
	
	def __rmul__(self, other):
		return Point(self.x * other, self.y * other)
	
p = Point(1, 2)
q = Point(3, 4)
r = p - q
print(r)
r = 3 * p
print(r)
r = p * 3		# rmul 은 오른쪽에 등장하는 객체가 self이 되는 것이라서 이렇게 되면 오류
print(r)

__rmul__ : scalar와 vector 와 같이 두 객체의 타입이 같지 않을 때 사용하는 연산자 오버로딩이며, 이는 오른쪽 객체를 기준으로 오버로딩 되는 것이다.

 

03.  Point 클래스 메쏘드 - 일반
import math

class Point:
    def __init__ (self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__ (self):
        return f"({self.x},{self.y})"
    
    def __sub__ (self, other):
        return Point(self.x - other.x, self.y - other.y)

    def length(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

    def dot(self, q):
        return self.x*q.x + self.y*q.y
    
    def dist(self, q):
        return (self-q).length()

    def move(self, dx=0, dy=0):
        self.x += dx
        self.y += dy

p = Point(1,2)
q = Point(2,3)
import math

class Point:
	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y
	
	def __str__(self):
		return f"({self.x}, {self.y})"
	
	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)
	
	def length(self):
		return math.sqrt(self.x**2 + self.y**2)
	
	def dot(self, q):
		return self.x*q.x + self.y*q.y
	
	def dist(self, q):
		return (self-q).length()

	def move(self, dx=0, dy=0):
		self.x += dx
		self.y += dy

p = Point(1, 2)
q = Point(2, 3)

print(f"p = {p}, q = {q}")
print("length of p =", p.length())
print("dot of p and q =", p.dot(q))
print("dist of p and q =", p.dist(q))
p.move(3, 5)
print("move p by (3, 5) =", p)

연산자 오버로딩을 통한 산술 연산 구현 제외 벡터의 길이 / 내적 / 거리 / 이동 등을 구현한 것

 

04. Point 클래스를 Vector 클래스로 확장

Point 클래스는 2차원의 점이나 벡터만을 위한 클래스이기 때문에 여러 차원의 벡터를 표현하지 못함

 

1. def function (*args)

 

임의의 개수의 매개 변수들을 tuple args를 통해 전달하는 함수

 

2. nonpublic 변수

 

_coords 와 같이 _ 하나로 시작하는 멤버 변수는 만약 이 클래스가 다른 곳에서 import 사용하는 경우 import 되지 않고 감춰짐

 

 

 

 

댓글