[ 객체 지향 프로그래밍 ]
class User:
def settings(self, my_name, my_email, my_password) :
self.name = my_name
self.email = my_email
self.password = my_password
# User 인스턴스 생성
user1 = User()
# 인스턴스의 초기값을 설정
user1.settings("2CHAECHAE", "2CHAECHAE@gamil.com", "1234!")
user3 = User()
User.settings(user3, "2MONMON", "2MONMON@gamil.com", "0000!")
함수를 작성해서 인스턴스 변수에 각 인스턴스에 맞는 값을 할당할 수 있다.
user1의 경우는 인스턴스에서 메소드를 호출하고 있다. User 클래스의 settings 함수가 실행되면
첫번째 파라미터인 self로 자동으로 인스턴스 user1이 넘어간다.
그러니 settings 함수를 호출할 경우 user1 인스턴스 객체를 직접적으로 안넘겨줘도 된다.
하지만 user3의 경우는 클래스에서 메소드를 호출하고 있다. 클래스를 통해 메소드를 호출할 경우에는
첫번째 파라미터로 인스턴스가 자동으로 전달되지 않기 때문에 user3의 인스턴스를 첫번째 파라미터로 직접
넘겨줘야한다.
__init__
특수 메소드 : 특정 상황에서 자동으로 호출되는 메소드 ex) __init__
__init__메소드는 인스턴스가 생성될 때 자동으로 호출된다.
* init은 initialize인 초기화를 의미한다.
class User:
def __init__(self, my_name, my_email, my_password) :
self.name = my_name
self.email = my_email
self.password = my_password
user1 = User("2CHAECHAE", "2CHAECHAE@gamil.com", "1234!")
user3 = User("2MONMON", "2MONMON@gamil.com", "0000!")
User 인스턴스가 생성이 되는 해당 코드가 실행되면 __init__ 메소드가 자동으로 호출된다.
파라미터 self에는 코드가 실행되면서 생성된 User 인스턴스가 들어간다. 그리고 다음 파라미터에 해당하는
값들이 순서대로 들어간다. 그래서 __init__ 메소드가 인스턴스 변수들의 초기값을 설정해준다.
즉 __init__ 메소드를 사용한다면 인스턴스 생성과 인스턴스 변수 초기값 설정을 동시에 한줄로 처리할 수 있다
__str__
print 함수를 호출할 때 자동으로 호출된다.
즉 어떤 인스턴스( 원하는 정보 )를 출력하고 싶을 때 클래스에 __str__ 메소드를 정의하면 된다.
class User :
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
def __str__(self):
return "사용자 : {}, 이메일 : {}".format(self.name, self.email)
user1 = User("2CHAECHAE", "2CHAECHAE@gamil.com", "1234")
user2 = User("2MONMON", "2MONMON@gamil.com", "0000")
print(user1)
클래스 변수
인스턴스 변수 : 인스턴스 자신만의 속성
클래스 변수 : 같은 클래스의 인스턴스들이 서로 공유하는 값
* 인스턴스가 생성될 때 마다 인스턴스의 총합을 알고 싶은 경우 : 인스턴스가 생성될 때 마다 실행되는 메소드는
__init__ 메소드 이므로 __init__ 메소드 안에다가 클래스 변수를 생성해주면됨
< 클래스 변수 읽는 법 >
[ 클래스 변수 ].[ 클래스 변수 이름 ]
[ 인스턴스 이름 ].[ 클래스 변수 이름 ]
같은 이름의 클래스 변수와 인스턴스 변수가 있을 경우 인스턴스 변수가 읽어진다.
ex) 클래스 변수로 number가 존재한다 했을 때 user1.number는 클래스 변수 number가 아니라
user1의 인스턴스 변수인 number을 가리킨다.
데코레이터 ( decorator )
데코레이터 : 기존의 함수에 새로운 기능을 추가해주는 것
데코레이터 함수 : 어떠한 함수를 꾸며서 새로운 함수를 만들어준다.
데코레이터를 쓰는 이유 : 중복되는 부분을 모두 데코레이터 함수에 넣어서 함수를 사용하게 되면 훨씬 가독성이 높아짐
# 데코레이터를 사용하기 전
def print_hello() :
print("HELLO")
# 파라미터로 어떠한 함수를 인자로 받고 그 인자로 받은 함수를 wrapper 함수로 decorate 해준다.
# 즉 데코레이터 함수는 어떠한 함수를 인자로 받아 꾸며주고 새로운 함수를 리턴한다.
def add_print( original ) :
def wrapper() :
print("함수 시작")
original()
print("함수 끝")
return wrapper
# 정의했던 wrapper 함수를 실행시키는 것이 아니라 리턴만 한다.
# wrapper = add_print(print_hello)
# 리턴된 wrapper 함수는 호출한 부분에 그대로 들어가게 되므로
# 리턴된 함수를 호출하기 위해서는 뒤에 ()를 써줘야함
add_print(print_hello)()
print_hello = add_print(print_hello)
print_hello()
# 데코레이터를 사용하는 코드
def add_print( original ) :
def wrapper() :
print("함수 시작")
original()
print("함수 끝")
return wrapper
@add_print
def print_hello() :
print("HELLO")
# @add_print는 print_hello() 함수를 add_print로 꾸며주라는 의미
# 데코레이터를 쓰고 print_hello() 함수를 호출한다면 자동으로 꾸며진 print_hello() 함수가 호출됨
print_hello()
클래스 메소드
인스턴스 메소드 : 인스턴스 변수의 값을 읽거나 설정하는 메소드
클래스 메소드 : 클래스 변수의 값을 읽거나 설정하는 메소드
인스턴스 메소드는 첫번째 파라미터인 self로 인스턴스자신이 자동으로 전달되는 규칙이 존재하지만
클래스 메소드는 첫번째 파라미터로 클래스가 자동으로 전달이 되고, 클래스를 cls라는 파라미터로 전달받는다.
class User :
count = 0
def __init__(self, name, email, password ):
self.name = name
self.email = email
self.password = password
User.count += 1
def say_hello(self):
print(f"Hi! My name is {self.name}")
def __str__(self):
return f"사용자 : {self.name}, 이메일 : {self.email}"
# 자동 전달되는 클래스인 cls는 User 클래스를 의미함
# cls.count == User.count
@classmethod
def number_of_users(cls):
print("총 유저수 : {}".format(cls.count))
# 인스턴스 생성
user1 = User("2CHAECHAE", "2CHAECHAE@gamil.com",1234)
user2 = User("2MONMON", "2MONMON@gamil.com",0000)
User.number_of_users()
user1.number_of_users()
인스턴스 메소드 | 클래스 메소드 |
User.say_hi(user1) | User.number_of_users() user1.number_of_users() 클래스 메소드는 두가지 방법 모두 첫번째 파라미터로 클래스가 자동 전달된다. 클래스가 자동으로 전달되는 이유는@classmethod로 number_of_users()를 클래스 메소드로 만들었기 때문이다. |
user1.say_hi() 인스턴스 자신이 첫번째 파라미터로 자동 전달된다. |
인스턴스 메소드에서도 클래스 변수를 '클래스.클래스 변수' 형식으로 써서 가져올 수 있다.
class User :
count = 0
def number_of_users(self):
print(f"총 유저 수 : {User.count}")
# 인스턴스 생성
user1 = User("2CHAECHAE", "2CHAECHAE@gamil.com",1234)
user2 = User("2MONMON", "2MONMON@gamil.com",0000)
# 클래스에서 메소드를 호출하는 경우 파라미터로 인스턴스를 넘겨줘야함
User.number_of_users(user1)
# 인스턴스에서 메소드를 호출하는 경우 인스턴스가 자동으로 함수의 첫번째 파라미터로 전달됨
user1.number_of_users()
인스턴스 변수를 사용하지 않는다면 self에 접근할 필요도 없기 때문에 인스턴스 변수가 아닌 클래스 변수만 사용하는
메소드라면 클래스 메소드 ( @classmethod )로 작성해야한다.
인스턴스 변수를 사용한다면 인스턴스 메소드를 사용하고 클래스 변수를 사용한다면 클래스 메소드를 사용해야한다.
클래스 변수와 인스턴스 변수 둘다 사용할 경우는 인스턴스 메소드가 인스턴스 변수과 클래스 변수 모두를 사용 가능
하기 때문에 ( 인스턴스 변수는 self를 통해서, 클래스 변수는 "클래스이름.클래스변수"의 형태 ) 인스턴스 메소드로
작성하면 된다. 반면에 클래스 메소드는 인스턴스 변수를 사용하지 못하기 때문에 사용하지 못한다.
인스턴스가 없을 경우에는 클래스 메소드를 사용하면 된다.
정적 메소드
인스턴스 변수나 클래스 변수 중 아무것도 사용하지 않는 메소드라면 정적 메소드로 만들면 된다.
어떠한 속성도 다루지 않고 단지 기능적인 역할인 메소드를 정의할 때는 정적 메소드를 사용하면 된다.
@staticmethod
def check_valid(email) :
return "@" in email
class My_Calculator:
@staticmethod
def add(first_number, second_number):
return first_number + second_number
@staticmethod
def sub(first_number, second_number):
return first_number - second_number
@staticmethod
def mul(first_number, second_number):
return first_number * second_number
@staticmethod
def div(first_number, second_number):
return first_number / second_number
# 계산기 인스턴스 생성
calculator = My_Calculator()
print(calculator.add(2, 8))
print(calculator.sub(2, 8))
print(calculator.mul(2, 8))
print(calculator.div(2, 8))
'Python > 객체지향' 카테고리의 다른 글
[ 객체 지향 프로그래밍 ] 5일차 ( 상속 ) (0) | 2022.02.10 |
---|---|
[ 객체 지향 프로그래밍 ] 4일차 ( 추상화, 캡슐화 ) (0) | 2022.01.29 |
[ 객체 지향 프로그래밍 ] 3일차 ( 객체 지향 언어 ) (0) | 2022.01.21 |
[ 객체 지향 프로그래밍 ] 1일차 ( 객체지향 정의 ~ 인스턴스 ) (0) | 2022.01.12 |