class User: # 클래스 이름 첫글자는 항상 대문자
pass
user1 = User() # 유저 인스턴트 생성
user2 = User()
user3 = User() # 이 3개의 인스턴스들은 같은 클래스로 만들었어도 서로 다른 존재
# 인스턴스 변수 정의하기
# 인스턴스 이름. 속성 이름(인스턴스 변수) = "속성에 넣을 값"
user1.name = "홍길동" # 이름을 나타내는 속성 추가
user1.email = "gildong@naver.com"
user1.password = "12345"
user2.name = "강영훈"
user2.email = "younghoon@naver.com"
user2.password = "23456"
user3.name = "최지웅"
user3.email = "jiwoong@naver.com"
user3.password = "34567"
# 인스턴스 변수 사용하기
# 인스턴스 이름. 인스턴스 변수 이름
# 예시 print(user1.email)
<예시 1>
# 클래스 변수 사용법
class User:
count = 0
def __init__(self, name, email, pw):
# 유저 인스턴스의 모든 변수를 지정해주는 메소드
self.name = name
self.email = email
self.pw = pw
def say_hello(self):
print("안녕하세요! 저는 {}입니다!".format(self.name))
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
User.count = 1 # 클래스 변수 설정
print(User.count) # 클래스 변수 출력 -> 출력값 1
<예시 2>
# 클래스 변수 사용법
class User:
count = 0
def __init__(self, name, email, pw):
# 유저 인스턴스의 모든 변수를 지정해주는 메소드
self.name = name
self.email = email
self.pw = pw
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다!".format(self.name))
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
print(User.count)
<예시 3>
# 클래스 변수 : 한 클래스의 모든 인스턴스가 공유하는 속성
class User:
count = 0
def __init__(self, name, email, pw):
# 유저 인스턴스의 모든 변수를 지정해주는 메소드
self.name = name
self.email = email
self.pw = pw
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다!".format(self.name))
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
user1.count = 5 # 클래스 변수와 같은 이름의 인스턴스 변수 생성해주는 것
# 따라서 클래스 변수 출력 값에는 변화 없음
# -> 이렇게 헷갈릴 수 있기 때문에 클래스 변수 값을 설정할 때는 클래스 이름으로 다뤄주기!!
print(User.count)
print(user1.count)
print(user2.count)
2
5
2
*클래스 변수의 값 읽는 법 | *클래스 변수의 값 설정하는 법 |
---|---|
클래스 이름. 클래스 변수 이름 | 클래스 이름. 클래스 변수 이름 (얘로 쓰기!!) |
인스턴스 이름.클래스 변수 이름 |
: 인스턴스 변수를 사용하거나 인스턴스 변수의 값을 설정하는 메소드
*인스턴스 메소드의 특별한 규칙- 첫번때 파라미터의 이름은 꼭 self로 쓰기 !
class User:
def say_hello(self):
# 인사 메세지 출력 메소드
print("안녕하세요! 저는 {}입니다!".format(self.name))
def login(self, my_email, my_password):
# 로그인 메소드
if (self.email == my_email and self.password == my_password):
print("로그인 성공, 환영합니다!")
else:
print("로그인 실패, 없는 아이디거나 잘못된 비밀번호입니다.")
# 파이썬에선 인스턴스 메소드의 첫번째 파라미터 이름을 self로 쓰라고 권장!!
# 인스턴스 메소드를 호출하는 인스턴스 자신이 첫번째 파라미터로 들어가기 때문에 self로 써주는 게 의미상으로도 좋은듯!
<예시 1>
class User:
def say_hello(some_user):
print("안녕하세요! 저는 {}입니다!".format(some_user.name))
# name이라는 인스턴스 변수를 사용하므로 say_hello는 인스턴스 메소드
user1 = User()
user2 = User()
user3 = User()
user1.name = "홍길동"
user1.email = "gildong@naver.com"
user1.password = "12345"
user2.name = "강영훈"
user2.email = "younghoon@naver.com"
user2.password = "23456"
user3.name = "최지웅"
user3.email = "jiwoong@naver.com"
user3.password = "34567"
# 인스턴스 메소드 사용하기
# 클래스 이름.메소드 이름(인스턴스)
# 예시 1. User.say_hello(user1)
# 인스턴스 이름.메소드 이름()
# 예시 2. user1.say_hello()
# 예시 2 -> 파라미터를 넘겨주지 않았는데 왜 오류가 안날까?
# 예시 2처럼 인스턴스 메소드를 호출하면 인스턴스가 자동으로 파라미터로 들어간다.
# 오히려 안에 파라미터 써주면 에러 발생!
<예시 2>
class User:
def say_hello(some_user):
# 인사 메세지 출력 메소드
print("안녕하세요! 저는 {}입니다!".format(some_user.name))
def login(some_user, my_email, my_password):
# 로그인 메소드
if (some_user.email == my_email and some_user.password == my_password):
print("로그인 성공, 환영합니다!")
else:
print("로그인 실패, 없는 아이디거나 잘못된 비밀번호입니다.")
user1 = User()
user1.name = "홍길동"
user1.email = "gildong@naver.com"
user1.password = "12345"
user1.login("gildong@naver.com", "12345")
# 위와 동일하게 첫번째 파라미터 자동으로 들어가서 생략해줘야함
로그인 성공, 환영합니다!
<예시 3>
class User:
def say_hello(self):
# 인사 메세지 출력 메소드
print("안녕하세요! 저는 {}입니다!".format(self.name))
def check_name(self, name):
# 파라미터로 받는 name이 유저의 이름과 같은지 불린으로 리턴
return self.name == name
user1 = User()
user2 = User()
user1.name = "홍길동"
user1.email = "gildong@naver.com"
user1.password = "12345"
user2.name = "강영훈"
user2.email = "younghoon@naver.com"
user2.password = "23456"
print(user1.check_name("홍길동"))
True
: 클래스 변수의 값을 읽거나 설정하는 메소드
*인스턴스 메소드의 특별한 규칙- 첫번때 파라미터의 이름은 꼭 cls로 쓰기 !
<예시 1>
class User:
count = 0
def __init__(self, name, email, pw):
self.name = name
self.email = email
self.pw = pw
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다.".format(self.name, self.email))
def __str__(self):
return "사용자: {}, 이메일: {}, 비밀번호: *****".format(self.name, self.email)
#클래스 메소드 만들어 주기
@classmethod
def number_of_users(cls):
# 자동전달되는 cls 파라미터는 User 클래스를 나타냄. 따라서 cls.count = User.count
print("총 유저 수는: {}입니다.".format(cls.count))
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
user3 = User("dong","dong@naver.com","12345")
User.number_of_users()
user1.number_of_users()
총 유저 수는: 3입니다.
총 유저 수는: 3입니다.
❓ 왜 클래스 메소드를 사용할까?
-인스턴스 변수를 사용하지 않기 때문에(보면 self를 써도 인스턴스 변수를 불러오지 않음. 클래스변수만 사용하기 때문에)
-인스턴스 변수가 하나도 없을 때 사용될 수 있는 경우에 !
❓그렇다면 클래스변수와 인스턴스 변수 둘다 쓴다면?
→ 인스턴스 변수 사용하기!! (인스턴스 변수, 클래스 변수 모두 사용 가능하기 때문에)
-클래스 메소드는 인스턴스 변수 사용불가!!
<예시 2>
class User:
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
@classmethod
def from_string(cls, string_params):
params_list = string_params.split(",")
name = params_list[0]
email = params_list[1]
password = params_list[2]
# cls.name 이런 식으로 쓰게 되면 인스턴스 변수가 아닌 클래스 변수에 값을 넣게 된다
# 클래스 변수는 모든 클래스가 공통으로 가지는 변수
return cls(name, email, password) # 생성자를 통해 인스턴스 변수 생성
@classmethod
def from_list(cls, list_params):
name = list_params[0]
email = list_params[1]
password = list_params[2]
return cls(name, email, password)
# 유저 생성 및 초기값 설정
younghoon = User.from_string("강영훈,younghoon@codeit.kr,123456")
yoonsoo = User.from_list(["이윤수", "yoonsoo@codeit.kr", "abcdef"])
print(younghoon.name, younghoon.email, younghoon.password)
print(yoonsoo.name, yoonsoo.email, yoonsoo.password)
강영훈 younghoon@codeit.kr 123456
이윤수 yoonsoo@codeit.kr abcdef
-인스턴스 변수, 클래스 변수를 전혀 다루지 않는 메소드
class User:
count = 0
def __init__(self, name, email, pw):
self.name = name
self.email = email
self.pw = pw
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다!".format(self.name))
def __str__(self):
return "사용자: {}, 이메일: {}, 비밀번호: ******".format(self.name, self.email)
@classmethod
def number_of_users(cls):
print("총 유저 수는: {}입니다".format(cls.count))
# 정적 메소드
@staticmethod
def is_valid_email(email_address):
return "@" in email_address
print(User.is_valid_email("taehosung"))
print(User.is_valid_email("taehosung@codeit.kr"))
print(user1.is_valid_email("taehosung"))
print(user1.is_valid_email("taehosung@codeit.kr"))
# 인스턴스, 클래스 두가지 모두를 통해 사용 가능
False
True
False
True
class User:
# 인스턴스 변수 설정
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
self.following_list = [] # 이 유저가 팔로우하는 유저 리스트
self.followers_list = [] # 이 유저를 팔로우하는 유저 리스트
# 팔로우
def follow(self, another_user):
# 나의 팔로잉 리스트
self.following_list.append(another_user)
another_user.followers_list.append(self)
# 내가 몇 명을 팔로우하는지 리턴
def num_following(self):
return len(self.following_list)
# 나를 몇 명이 팔로우하는지 리턴
def num_followers(self):
return len(self.followers_list)
# 유저들 생성
user1 = User("Young", "young@codeit.kr", "123456")
user2 = User("Yoonsoo", "yoonsoo@codeit.kr", "abcdef")
user3 = User("Taeho", "taeho@codeit.kr", "123abc")
user4 = User("Lisa", "lisa@codeit.kr", "abc123")
# 유저마다 서로 관심 있는 유저를 팔로우
user1.follow(user2)
user1.follow(user3)
user2.follow(user1)
user2.follow(user3)
user2.follow(user4)
user4.follow(user1)
# 유저 이름, 자신의 팔로워 수, 자신이 팔로우하는 사람 수를 출력합니다
print(user1.name, user1.num_followers(), user1.num_following())
print(user2.name, user2.num_followers(), user2.num_following())
print(user3.name, user3.num_followers(), user3.num_following())
print(user4.name, user4.num_followers(), user4.num_following())
Young 2 2
Yoonsoo 1 3
Taeho 2 0
Lisa 1 1
= 특정 상황에서 자동으로 호출되는 메소드
= 더블 언더스코어(double underscore)를 줄여서 던더 메소드라고 부르기도함
: 한줄에 인스턴스 생성과 초기값을 바로 한 줄에 생성해줄 수 있게 한다
class User:
# __init__은 인스턴스가 생성될 때 자동으로 호출
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
# user 생성, 초깃값을 설정
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
user3 = User("dong","dong@naver.com","12345")
print(user1.email)
print(user2.name)
print(user3.password)
hong@naver.com
gil
12345
: print 사용할 때 자동으로 호출(어떤 인스턴스를 호출하면 이 메소드의 리턴값이 출력
class User:
def __init__(self, name, email, pw):
# 유저 인스턴스의 모든 변수를 지정해주는 메소드
self.name = name
self.email = email
self.pw = pw
def say_hello(self):
print("안녕하세요! 저는 {}입니다!".format(self.name))
def __str__(self):
# __str__는 print 사용할 때 자동으로 호출(어떤 인스턴스를 호출하면 이 메소드의 리턴값이 출력
return "사용자: {}, 이메일: {}, 비밀번호 : *****".format(self.name, self.email)
user1 = User("hong","hong@naver.com","12345")
user2 = User("gil","gil@naver.com","12345")
# __str__ 정의하지 않을 경우
print(user1) # 인스턴스가 어떤 클래스인지 나오고 주솟값이 나온다 <__main__.User object at 0x10cac7c40>
# __str__ 정의 한 뒤
print(user2) # 사용자: gil, 이메일: gil@naver.com, 비밀번호 : *****
-파라미터로 어떤 함수를 받아 그 함수를 꾸며서 새로운 함수를 리턴해준다
def print_hello():
print("안녕하세요!")
# 데코레이터 함수 생성
def add_print_to(original): # 파라미터로 함수를 받는다
def wrapper():
print('함수 시작') # 부가기능 1
original()
print('함수 끝') # 부가기능 2 -> original(print_hello)를 꾸며줌(데코레이팅)
return wrapper
add_print_to(print_hello)()
# 좀 더 깔끔하게 출력
print_hello = add_print_to(print_hello)
print_hello()
함수 시작
안녕하세요!
함수 끝
함수 시작
안녕하세요!
함수 끝
⭐ 더 간단하게 데코레이터 사용하기!!! @데코레이터
def add_print_to(original): # 파라미터로 함수를 받는다
def wrapper():
print('함수 시작') # 부가기능 1
original()
print('함수 끝') # 부가기능 2 -> original(print_hello)를 꾸며줌(데코레이팅)
return wrapper
@add_print_to
# print_hello함수를 add_print_to로 꾸며주라는 뜻
def print_hello():
print("안녕하세요!")
print_hello()
함수 시작
안녕하세요!
함수 끝