이번 글은 코드잇 강의를 수강하면서 배운 내용을 주로 하여 정리되어 있습니다. (코드잇 스프린트 데이터 애널리스트 트랙 1기 훈련생)
객체(Object)
일반적으로 말하는 객체 : 컴퓨터,사람, 자동차처럼 우리가 주변에서 떠올릴 수 있는 모든 것
프로그래밍에서의 객체 : 데이터와 그 데이터를 활용한 함수들을 묶어서 저장해 놓을 수 있는 것들
파이썬에서 사용하는 수많은 기능들은 객체로 만들어져 있습니다. 새로운 기능을 만들때도 객체를 활용해야 합니다.
데이터 사이언스, 웹 개발, 업무 자동화 등 분야에 상관없이 초급자에서 벗어나 사용하는 코드를 모두 이해하고 본인만의 새로운 기능을 만들어내면서 자유자재로 프로그래밍하기 위해서는 객체가 어떻게 작동하는지 이해해야 합니다.
- 데이터 → 속성
- 함수가 작동하는 것 → 행동
객체와 클래스를 다루기 전에 구성하는 환경
- 파이썬 인터프리터
- VS code
- VS code Extension
위 파일들을 모두 다운받아 환경을 구성합니다.
클래스와 인스턴스 (파이썬에서 객체를 만드는 법)
인스타그램과 같은 sns에서 유저를 나타내는 객체를 만드는 목적의 예시를 통해 객체를 소개하겠습니다.
객체를 만들기 위해서는 속성과 행동을 저장하는 모델링이 필요한 데, 유저는 속성으로 이름, 이메일 주소, 비밀번호, 본인이 팔로우하는 유저 목록, 본인을 팔로우하는 유저 목록을 갖는다고 하고, 행동에는 소개 메시지를 출력하고, 로그인을 할 수 있다고 하겠습니다.
모델링이 끝났다면, 코드를 통해 객체를 생성할 수 있습니다.
하지만 유저는 1명이 아니라 다수입니다.
이러한 다수의 유저 객체를 생성하기 위해 틀이 필요한데 이러한 상황에서 객체를 만들기 위한 틀로 클래스를, 클래스로 만든 객체를 인스턴스를 생성하고 활용하게 됩니다.
클래스
- 클래스는 객체를 만들기 위한 틀이자 설계도 또는 템플릿입니다.
- 클래스는 객체가 가져야 할 속성과 메소드를 정의합니다.
- 즉, 클래스는 객체를 생성해주는 생성자, 객체가 공통적으로 가지는 속성, 공통적인 기능(함수)들을 정의합니다.
- 클래스를 정의할 때는 class 키워드를 사용합니다.
인스턴스
- 인스턴스는 클래스에서 정의된 내용을 바탕으로 생성된 실제 객체입니다.
- 클래스의 속성과 메소드를 사용할 수 있습니다.
- 엄밀히 말하면, 객체와 인스턴스는 다른 것이지만, 크게 중요하지 않기 때문에 혼용해서 사용해도 상관없습니다.
클래스와 인스턴스 예시
class User: # User라는 이름의 비어있는 클래스 생성
pass
user1 = User() # 클래스로부터 User 인스턴스 생성하고 user1이라는 변수에 저장
user2 = User() # 클래스로부터 User 인스턴스 생성하고 user2라는 변수에 저장
print(type(user1)) # <class '__main__.User'> 출력 / User라는 클래스의 타입이 출력된다.
print(type(user2)) # <class '__main__.User'> 출력
인스턴스
인스턴스 변수
인스턴스에 속성을 추가하는 것은 변수를 만드는 것과 비슷한 점이 많습니다.
유저 인스턴스에 속성을 추가하거나 이미 있는 속성을 다른 것으로 바꾸고 싶을 경우 인스턴스 변수 이름에 .을 찍고 속성 이름을 적습니다.
아래 예시에서 인스턴스에 속성 변수를 추가해주었으며, 이처럼 인스턴스 안에 독립적으로 저장된 변수를 인스턴스 변수라고 합니다.(인스턴스 변수는 클래스의 각 인스턴스마다 별도로 유지되는 개별 객체)
예) 자동차 클래스가 있을 때 각 인스턴스(각 차량)마다 고유한 속도, 색상 등을 나타내는 변수들이 인스턴스 변수이다.
정의하지 않은 인스턴스 변수를 사용할 경우에는 정의되지 않았기 때문에 오류가 발생합니다.
class User: # User라는 이름의 비어있는 클래스 생성
pass
user1 = User() # 클래스로부터 User 인스턴스 생성하고 user1이라는 변수에 저장
user2 = User() # 클래스로부터 User 인스턴스 생성하고 user2라는 변수에 저장
user1.name = "강영훈" # user 인스턴스에 이름 속성을 추가하기 위해 user1에 .을 찍고 name을 적은 후에 이름을 할당해주었음 -> user1.name 인스턴스 변수 정의
user1.email = "jeonghoon@tstory.com" # user1의 email 속성 생성 -> user1.email 인스턴스 변수 정의
user1.password = "abcdefg" # user1의 password 속성 생성 -> user1.password 인스턴스 변수 정의
user2.name = "이지은" # user2의 이름 속성 생성 -> user2.name 인스턴스 변수 정의
user2.email = "jieun@tstory.com" # user2의 email 속성 생성 -> user2.email 인스턴스 변수 정의
user2.password = "1234567" # user2의 password 속성 생성 -> user2.password 인스턴스 변수 정의
print(user1.email) # younghoon@tstory.com 출력
print(user2.password) # 1234567 출력
인스턴스 메소드
함수를 사용해서 객체의 행동을 정의할 수 있으며, 이러한 함수들을 인스턴스 메소드이자 짧게 메소드라고 합니다.(인스턴스 메소드는 인스턴스 변수에 사용하는 메소드)
# 예시
class User: # User 클래스 생성
def say_hello(some_user): # say_hello 이름의 메소드를 만들어 객체의 행동을 정의함
print(f"안녕하세요! 저는 {some_user.name}입니다!")
user1 = User() # 클래스로부터 User 인스턴스 생성
user2 = User() # 클래스로부터 User 인스턴스 생성
user1.name = "강정훈" # 인스턴스 변수
user1.email = "jeonghoon@tstory.com" #ㅠ인스턴스 변수
user1.password = "abcdefg" # 인스턴스 변수
user2.name = "이지은" # 인스턴스 변수
user2.email = "jimin@tstory.com" # 인스턴스 변수
user2.password = "1234567" # 인스턴스 변수
User.say_hello(user1) # 안녕하세요! 저는 강정훈입니다! 출력
User.say_hello(user2) # 안녕하세요! 저는 이지은입니다! 출력
user1.say_hello() # 함수에 파라미터를 넘겨주지 않았는데도 안녕하세요! 저는 강정훈입니다! 출력 / 위의 출력과 내부적으로 기능이 똑같다.
user2.say_hello()
위의 예시로 인스턴스 메소드가 모든 인스턴스가 공유하는 행동이긴 하지만 각 인스턴스의 고유 속성을 활용하여 결과가 다 다르게 나오게 함을 알 수 있습니다.
하지만 위의 출력 예시처럼 클래스를 통해 메소드를 호출할 수도 있지만, 이 방법은 많이 사용되지 않는 방법으로 대신 인스턴스를 통해 메소드를 호출하는 방법을 사용할 수 있으며, 그 예시가 아래 출력 예시입니다.
그리고 인스턴스 메소드를 호출할 때 파라미터를 적용하지 않아도 되는데 그 이유는 클래스가 아닌 인스턴스로 메소드를 호출하게 되면 인스턴스가 메소드의 첫번째 아규먼트로 알아서 인식되기 때문에, 이런 상황에서는 파라미터를 작성하지 않습니다.(오히려 파라미터를 줄 경우 아규먼트가 중복 인식되어 오류가 발생함)
인스턴스 메소드 활용
# 예시
class User: # User 클래스 생성
def say_hello(self): # say_hello 이름의 메소드를 만들어 객체의 행동을 정의함
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 이름의 메소드 생성 / 유저, 이메일, 비밀번호를 파라미터로 받음
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
user1 = User() # 클래스로부터 User 인스턴스 생성
user1.name = "강정훈" # 인스턴스 변수
user1.email = "jeonghoon@tstory.com" # 인스턴스 변수
user1.password = "abcdefg" # 인스턴스 변수
user1.login("jeonghoon@tstory.com", "abcdefg") # 첫번째 아규먼트는 생략하고, 나머지 아규먼트만 넘겨주었다.
# 위 줄을 출력할 경우 로그인 성공, 환영합니다. 가 나오면서 결과가 잘 출력된다.
파라미터가 여러 개인 메소드를 호출할 때는 첫번째 아규먼트는 알아서 인식되기 때문에 첫번째 아규먼트를 제외한 아규먼트들만 넘겨주어 메소드를 호출할 수 있습니다.
메소드를 정의할 때는 항상 첫번째 파라미터로 인스턴스를 받기 위한 파라미터를 사용해야 합니다.
파이썬에서는 첫번째 인스턴스 메소드를 정의할 때 첫번째 파라미터를 항상 self로 짓는 것을 권장합니다.
메소드를 호출할 경우 인스턴스 자신이 첫번째 파라미터로 항상 들어가기 때문에 자기자신을 의미하는 self로 작성하는 것입니다.
그리고 파라미터로 넘겨주는 아규먼트의 이름과 인스턴수 변수의 이름이 같아도 코드에 아무런 문제가 없는데, 이는 이름이 같아도 엄연히 다른 변수로 인식되어 정상적으로 코드가 작동되기 때문입니다.
인스턴스 변수 초기화
인스턴스 변수는 항상 사용하기 전에 초기화가 필요합니다.
이러한 변수 초기화를 메소드를 통해 진행한다면, 코드가 길어지고 어떤 변수들을 초기화해야 할지 판단하기 어려운 문제들을 방지할 수 있습니다.
인스턴스 변수 초기화는 각 객체가 고유한 상태를 가질 수 있도록 인스턴스 변수를 설정하는 과정입니다.
초기화가 진행되는 과정은 인스턴스를 생성하고, __init__() 메소드가 호출되어 변수가 초기화되는 과정으로 이루어집니다.
# 예시
class User: # User 클래스 생성
def __init__(self, name, email, password): # 객체가 생성될 때 자동으로 호출된다. 이 메서드는 인스턴스 변수를 초기화하는 역할을 한다.
self.name = name # name 인스턴스 변수 초기화
self.email = email # email 인스턴스 변수 초기화
self.password = password # password 인스턴스 변수 초기화
def say_hello(self): # say_hello 메소드
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 메소드
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
user1 = User("강정훈", "jeonghoon@tstory.com", "abcdefg") # 인스턴스가 생성되고, 인스턴스에 이름, 이메일주소, 비밀번호 부여
user2 = User("이지은", "jieun@tstory.com", "1234567") # user2에게 이름, 이메일주소, 비밀번호 부여
print(user1.name, user1.email, user1.password) # 객체의 인스턴스 변수 접근
print(user2.name, user2.email, user2.password)
각 객체는 고유한 인스턴스 변수를 가지며, 이를 통해 객체별로 다른 상태를 유지할 수 있습니다.
위와 같이 인스턴스 변수를 초기화함으로써 객체가 생성될 때 필요한 초기 상태를 설정할 수 있습니다.
__str__() 메소드
언더 하이픈이 양 옆에 들어가는 메소드를 특수 메소드라고 부르며, 특정 상황에 자동으로 호출되는 메소드입니다.
그 중 str() 메소드는 객체를 문자열로 표현하는 방법을 정의하는 특수 메소드입니다.
이 메소드는 print 함수나 str 함수가 호출될 때 자동으로 호출되어, 객체를 사람이 읽기 쉬운 형태의 문자열로 변환합니다.
# 예시
class User: # User 클래스 생성
def __init__(self, name, email, password): #인스턴스 변수 초기화 메소드
self.name = name # name 인스턴스 변수 초기화
self.email = email # email 인스턴스 변수 초기화
self.password = password # password 인스턴스 변수 초기화
def say_hello(self): # say_hello 메소드
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 메소드
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
def __str__(self):
return f"사용자: {self.name}, 이메일: {self.email}"
user1 = User("강정훈", "jeonghoon@tstory.com", "abcdefg") # 인스턴스 user1에 이름, 이메일주소, 비밀번호 부여
user2 = User("이지은", "jieun@tstory.com", "1234567") # user2에게 이름, 이메일주소, 비밀번호 부여
print(user1)
print(user2)
# print()을 호출하면 user 객체의 __str__() 메소드가 자동으로 호출되어 사용자: 강정훈, 이메일: jeonghoon@tstory.com 문자열을 반환합니다.
결과적으로 __str__() 메소드를 활용하여 객체를 더 직관적으로 표현할 수 있습니다.
클래스
클래스 변수
클래스 변수(class variable)는 클래스 내에 정의된 변수로, 클래스의 모든 인스턴스가 공유하는 변수(값)입니다.
예) 자동차 클래스에서 모든 차량이 공유하는 기본 속도 등
인스턴스 변수는 각 인스턴스마다 개별적으로 존재하고 인스턴스마다 다른 값을 가질 수 있는 반면에 클래스 변수는 클래스의 모든 인스턴스가 동일한 값을 공유합니다.
클래스 변수의 특징
- 공유 특성: 클래스 변수는 클래스의 모든 인스턴스가 공유합니다. 하나의 인스턴스에서 클래스 변수를 변경하면, 다른 모든 인스턴스에서도 해당 변경 사항이 반영됩니다.
- 정적 특성: 클래스 변수는 클래스가 메모리에 로드될 때 한 번 초기화되며, 프로그램이 종료될 때까지 존재합니다.
- 클래스 레벨 접근: 클래스 변수는 클래스명으로 접근할 수 있으며, 인스턴스에서도 접근할 수 있지만 이는 혼동을 일으킬 수 있습니다.
# 예시
class User: # User 클래스 생성
# 클래스 변수는 클래스 이름 밑에 정의
count = 0 # 클래스 변수
def __init__(self, name, email, password): #인스턴스 변수 초기화 메소드
self.name = name # name 인스턴스 변수 초기화
self.email = email # email 인스턴스 변수 초기화
self.password = password # password 인스턴스 변수 초기화
# __init__()메소드는 자동으로 호출되기 때문에 유저의 수를 알고 싶다면 이 메소드 안에 클래스 변수를 1개씩 카운트하는 수식을 작성하면 쉽게 유저 수를 구할 수 있습니다.
User.count += 1
def say_hello(self): # say_hello 메소드
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 메소드
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
def __str__(self):
return f"사용자: {self.name}, 이메일: {self.email}"
user1 = User("강정훈", "jeonghoon@tstory.com", "abcdefg") # 인스턴스 user1에 이름, 이메일주소, 비밀번호 부여
user2 = User("이지은", "jieun@tstory.com", "1234567") # user2에 이름, 이메일주소, 비밀번호 부여
user2 = User("이정민", "jeongmin@tstory.com", "abcd567") # user3에 이름, 이메일주소, 비밀번호 부여
print(User.count) # init 메소드가 3번 호출되어 유저의 수인 3이 출력. (클래스 변수의 값 확인)
클래스 변수 접근
위에서 클래스 변수는 모든 인스턴스들이 공유하는 값이라고 했는데, 그래서 클래스뿐만 아니라 인스턴스를 통해서도 클래스 변수의 값을 읽어올 수 있습니다.
print(User.count) # 출력: 3
print(user1.count) # 출력: 3
print(user2.count) # 출력: 3
하지만 인스턴스를 통해 클래스 변수를 수정할 수는 없습니다.
user3.count = 5
print(User.count) # 출력: 3
print(user1.count) # 출력: 3
print(user3.count) # 출력: 5
지금 위 예시는 클래스 변수의 값을 설정하는 게 아니라, 결과적으로 단순히 같은 이름의 인스턴스 변수를 추가하는 것의 결과밖에 없다는 것을 확인할 수 있습니다.
그 이유는 같은 이름의 클래스 변수와 인스턴스 변수가 둘 다 있으면, 인스턴스 변수를 읽기 때문입니다. (user3.count는 user의 인스턴스 변수 count를 나타내는 것 뿐이다.)
그래서 이러한 혼란을 막기 위해 클래스 변수의 값은 클래스를 통해서만 설정하는 것이 좋습니다.
클래스 메소드
클래스 메소드는 클래스 자체를 대상으로 동작하는 메소드로, 인스턴스가 아닌 클래스를 첫 번째 인자로 받습니다.
클래스 메서드를 정의할 때는 @classmethod 데코레이터를 사용하며, 첫 번째 인자로 보통 이름에 대한 약속으로 cls를 사용합니다.
클래스 메소드는 인스턴스 대신에 클래스가 자동적으로 전달됩니다.
# 예시
class User: # User 클래스
count = 0 # 클래스 변수
def __init__(self, name, email, password): #인스턴스 변수 초기화 메소드
self.name = name # name 인스턴스 변수 초기화
self.email = email # email 인스턴스 변수 초기화
self.password = password # password 인스턴스 변수 초기화
User.count += 1 # 유저의 수를 알 수 있게 자동으로 호출되는 init 메소드 안에 클래스 변수를 1개씩 카운트하는 수식을 작성
def say_hello(self): # say_hello 메소드
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 메소드
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
def __str__(self):
return f"사용자: {self.name}, 이메일: {self.email}"
@classmethod # 데코레이터를 사용하여 클래스메소드 지정
def print_number_of_users(self): # 클래스 메소드로 클래스 속성에 접근하여 유저 수를 세는 메소드 구현
print(f"총 유저 수는: {cls.count}입니다.") # cls.count는 User.count와 같다고 보면 된다.
user1 = User("강정훈", "jeonghoon@tstory.com", "abcdefg") # 인스턴스에 속성 부여
user2 = User("이지은", "jieun@tstory.com", "1234567") # 인스턴스에 속성 부여
user2 = User("이정민", "jeongmin@tstory.com", "abcd567") # 인스턴스에 속성 부여
User.print_number_of_users() # 총 유저 수는: 3입니다. 가 출력. (클래스 변수의 값 확인)
이와 같은 과정들로 클래스 메서드는 클래스 속성에 접근하거나 클래스 레벨에서 필요한 작업을 수행할 수 있습니다.
인스턴스 메소드와 클래스 메소드
클래스 변수를 사용하는 경우에 클래스 메소드를 사용하는 이유는 인스턴스 변수의 값을 읽거나 설정하지 않기 때문입니다.
그래서 인스턴스 변수 말고 클래스 변수만 사용하는 메소드라면 클래스 메소드로 작성해야 합니다.
그리고 인스턴수 변수와 클래스 변수를 둘 다 사용하는 경우에는 인스턴스 메소드를 사용하여 인스턴스 변수, 클래스 변수 둘 다 가져올 수 있습니다.
인스턴스 메소드에서 인스턴스 변수는 self를 통해, 클래스 변수는 그냥 클래스 이름에 점을 붙여 가져오면 두 변수를 모두 사용할 수 있습니다.
하지만 클래스 메소드에서는 인스턴스 변수를 가져올 수 없기에 인스턴스 변수, 클래스 변수와 인스턴스 변수 둘 다 필요할 때는 인스턴스 메소드를 사용해야 합니다.
마지막으로 인스턴스 변수가 없을 때도 사용해야 하는 메소드가 있다면, 이 경우에 필요한 메소드라면 꼭 클래스 메소드를 사용해야 합니다.
인스턴스가 없어도 클래스 메소드는 정상적으로 값을 출력할 수 있으며, 언제라도 사용할 가능성이 있다면 클래스 메소드로 만들어 주시길 바랍니다.
정적 메소드 (Static Method)
인스턴스와 클래스에 관련된 내용이 전혀 필요하지 않은 메소드입니다.
인스턴스나 클래스가 필요하지는 않지만 직접적인 연관이 있어 묶어서 클래스 안에서 제공하는 것이 좋을 것 같을 때 사용합니다.
클래스 메소드와 비슷하게 데코레이터를 사용하며, @staticmethod로 호출합니다.
클래스에 속하지만 인스턴스에 종속되지 않는 메소드, 클래스의 속성이나 다른 메소드에 접근할 필요가 없을 때 유용합니다.
주요 특징
- 클래스와 관련 있지만 인스턴스와는 관련이 없음
- 정적 메소드는 클래스의 상태나 속성에 접근할 필요가 없는 기능을 구현할 때 사용
- 첫번째 인수로 self를 받지 않는다(자동으로 전달되는 파라미터가 필요가 없다)
- 정적 메소드는 인스턴스의 속성에 접근할 필요가 없으므로 self를 받지 않음
- 클래스의 이름을 통해 직접 호출 정적 메소드는 클래스의 이름을 직접 호출하여 인스턴스를 생성할 필요가 없음
# 예시
class User: # User 클래스
count = 0 # 클래스 변수
def __init__(self, name, email, password): #인스턴스 변수 초기화 메소드
self.name = name # name 인스턴스 변수 초기화
self.email = email # email 인스턴스 변수 초기화
self.password = password # password 인스턴스 변수 초기화
User.count += 1 # 유저의 수를 알 수 있게 자동으로 호출되는 init 메소드 안에 클래스 변수를 1개씩 카운트하는 수식을 작성
def say_hello(self): # say_hello 메소드
print(f"안녕하세요! 저는 {self.name}입니다!")
def login(self, email, password): # login 메소드
if self.email == email and self.password == password:
print("로그인 성공, 환영합니다.")
else:
print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
def __str__(self):
return f"사용자: {self.name}, 이메일: {self.email}"
@classmethod # 데코레이터를 사용하여 클래스메소드 지정
def print_number_of_users(self): # 클래스 메소드로 클래스 속성에 접근하여 유저 수를 세는 메소드
print(f"총 유저 수는: {cls.count}입니다.")
@staticmethod # 인스턴스와 클래스에 관련된 내용이 전혀 필요하지 않은 메소드
def valid_email(email):
return "@" in email
User.valid_email("jieun@tstory.com") # True 출력
순수 객체 지향 언어 파이썬
파이썬에서는 다양한 기능들을 객체를 통해서 만들고 사용하고 있으며, 파이썬은 모든 기능이 객체로 만들어져 있는 순수 객체 지향 언어입니다.
그래서 파이썬에서 추가로 특징 기능을 만들고 싶다면 객체로 작성해야만 합니다.
파이썬 객체 확인
import random
def print_say_hello():
print("안녕하세요! ourkofe입니다.")
print(type(2))
# 출력: <class 'int'>
print(type("test"))
# 출력: <class 'str'>
print(type([]))
# 출력: <class 'list'>
print(type({}))
# 출력: <class 'dict'>
print(type(print_hello))
# 출력: <class 'function'>
print(type(random))
# 출력: <class 'module'>
위 예시를 보면, 파이썬에서 사용하는 다양한 것들이 어떤 클래스의 인스턴스, 즉 객체인 것을 알 수 있습니다.
지금까지 사용해온 개념들이 파이썬을 만든 개발자들이 각 기능들을 미리 클래스로 정의했던 것들이고, 지금까지 저희는 클래스의 인스턴스를 활용해왔던 것입니다.
스페셜 메소드
우리가 지금까지 파이썬에서 계속 사용해 왔던 함수나 연산자들은 인스턴스 변수나 메소드를 사용하는 게 아니라 조금 다른 방식으로 사용해 왔는데 그 방식은 특수한 상황에서 자동으로 호출되는 스페셜 메소드를 통해 사용하는 방식입니다.
스페셜 메소드는 특수한 상황에서 자동으로 호출되며, 간단한 스페셜 메소드의 예시를 보면서 파이썬 내부적으로는 어떻게 해석돼서 실행되고 있던것인지 확인해보겠습니다.
print(int1 + int2)
# 위의 간단한 수식의 + 연산자가 사용될 때 앞에 있는 정수나 문자열 클래스 안에 정의된 __add__() 메소드가 호출되고,
# 아규먼트로 연산자 오른편에 있는 인스턴스가 아규먼트로 전달됩니다.
print(int1.__add__(int2))
이와 같은 스페셜 메소드는 파이썬을 만든 개발자들이 각 클래스에 구현해놓은 메소드이므로, 위와 같이 두 정수의 산술 합과 같은 메소드를 호출해 줄 수 있습니다.
파이썬에는 정말 다양한 스페셜 메소드들이 있으며, 저희는 계속 이러한 메소드를 통해 파이썬을 편리하게 이용하고 있습니다.
다양한 스페셜 메소드 중에 몇가지 예시
사칙연산 메소드
기능 이름 | 기능을 위해 구현해야 하는 메소드 | 호출되는 경우 실행되는 메소드 |
더하기 | __add__(self, other) | x + y → x.__add__(y) |
빼기 | __sub__(self, other) | x - y → x.__sub__(y) |
곱하기 | __mul__(self, other) | x * y → x.__mul__(y) |
나누기 | __truediv__(self, other) | x / y → x.__truediv__(y) |
불린 메소드
기능 이름 | 기능을 위해 구현해야 하는 메소드 | 호출되는 경우 실행되는 메소드 |
불린 | __bool__(self) | bool(x) → x.__bool__() |
컨테이너 메소드 (컨테이너 : 정해지지 않은 개수의 데이터를 담을 수 있는 객체)
기능 이름 | 기능을 위해 구현해야 하는 메소드 | 호출되는 경우 실행되는 메소드 |
길이 | __len__(self) | len(x) → x.__len__() |
요소 갖고 오기 | __getitem__(self, key) | x[key] → x.__getitem__(key) |
요소 설정하기 | __setitem__(self, key, item) | x[key] = item → x.__setitem__(key, item) |
클래스와 모듈
일반적으로 클래스를 정의할 때는 클래스를 정의하는 코드와, 그 클래스 및 인스턴스를 사용하는 코드를 다른 파일들에 분리해 놓습니다.
하나가 아니라 여러 클래스를 가지고 와서 사용하는 경우들도 많기 때문에 일반적으로 각 클래스마다 하나의 파일, 또는 연관 있는 클래스들을 한 파일에 묶어서 저장하고, 실행하기 위한 파일을 따로 만듭니다.
이 파일을 모듈이라고도 하며, 모듈은 관련된 코드들을 하나의 파일로 묶어서 재사용 가능하게 만든 것입니다.
모듈은 변수, 함수, 클래스 등을 포함할 수 있으며, 이를 다른 파일에서 불러와 사용할 수 있습니다.
모듈을 사용하면 코드의 재사용성이 높아지고, 코드의 구조를 더 잘 조직할 수 있습니다.
예를 들어, Car 클래스를 car.py 라는 파일에 저장했다고 가정했을 때, Car 클래스를 사용하고 싶다면 아래 코드를 적용해볼 수 있습니다.
from car import Car
추가적으로 car.py 파일 안에 클래스 정의가 아닌 실행하는 코드가 있으면 현재 파일에서 임포트 해올 때 실행코드도 실행이 됩니다. 이걸 방지하기 위해서는 if __name__ == “__main__”: 를 조건문 안에 넣어야 합니다.
이번 글에서는 객체 / 클래스와 인스턴스 / 인스턴스 변수 / 인스턴스 메소드 / 클래스 변수 / 클래스 메소드 / 정적 메소드 / 스페셜 메소드가 포함된 내용을 정리했으며, 파이썬에서 데이터 분석을 하거나 프로그래밍을 하는 사람들에게 알아두면 유용한 개념들로 이번 기회를 통해 다른 분들도 정리하면 좋을 것 같습니다.
글 읽어주셔서 감사합니다.
출처 및 참고자료 : 코드잇 사이트 강의 '객체와 클래스' https://www.codeit.kr/topics/objects-and-classes
'프로그래밍 언어 > Python' 카테고리의 다른 글
[파이썬 개념 정리 12] Pandas의 DataFrame 마스터하기 2️⃣ (데이터 전처리) (0) | 2024.07.28 |
---|---|
[파이썬 개념 정리 11] Pandas의 DataFrame 마스터하기 1️⃣ (DataFrame의 기본) (0) | 2024.07.28 |
[파이썬 개념 정리 9] 맥 운영체제에서 파이썬 환경 구축 내용 정리 (0) | 2024.07.15 |
[파이썬 개념 정리 8]Seaborn 라이브러리를 이용한 시각화 개념 (2) | 2024.07.05 |
[파이썬 개념 정리 7]통계의 기본과 파이썬을 이용한 데이터 시각화 개념 (2) | 2024.07.05 |
데이터 분석을 공부하고 카페를 열심히 돌아다니는 이야기
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!