'속성'과 '행동'으로 이루어진 것.
'속성'과 '행동'을 떠올릴 수 있는 것이라면, 그것이 현실에 존재하던 가상에 존재하던 모두 객가 될 수 있다.
파이썬에서 속성은 변수로, 행동은 함수로 나타낸다.
프로그램을 여러 개의 독립된 객체들과 그 객체들 간의 상호작용으로 파악하는 프로그래밍 접근법이다.
즉, 프로그램을 객체들 간의 소통으로 바라보는 것.
인스턴스 변수 정의하기
인스턴스 변수 : 클래스 정의에서 메서드 안에서 사용되면서 self.변수명 처럼 사용되는 변수
self.인스턴스 변수명을 사용하여 엑세스, 클래스 밖에서는 객체명.인스턴스변수명 으로 엑세스class User:
pass
user1 = User()
user1.name = "김"
user1.email = "kim@gmail.com"
user2 = User()
user2.name = "이"
user2.email = "lee@gmail.com"
인스턴스 메서드 정의하기
인스턴스 메서드 : 해당 객체 안에서 호출(self.메서드명)
class User:
def say_hello(some_user):
print(f"안녕, 나는 {some_user.name}이야!")
pass
user1 = User()
user1.name = "김"
user2 = User()
user2.name = "이"
User.say_hello(user1) # 클래스에서 메서드 호출
print(user1)
user2.say_hello() # 인스턴스에서 메서드 호출
print(user2)
>>>
안녕, 나는 김이야!
<class '__main__.User'>
안녕, 나는 이이야!
<__main__.User object at 0x0000023127E686A0>
user2.say_hello()에 user2을 인자로 넘기지 않아도 호출이 된다.
인스턴스가 메서드를 호출할 때는 자기 자신이 첫 번째 인자로 넘어간다!
self를 사용하자
이를 명시해주기 위해 파이썬에서는 인스턴스 메서드의 첫 파라미터로 "self"를 사용한다.
이렇게 안해도 에러가 나는건 아니지만, 이건 파이썬 쓰는 사람들끼리의 규칙이다.
class User:
def say_hello(self): # self 사용
print(f"안녕, 나는 {self.name}이야!")
pass
user1 = User()
user1.name = "김"
user2 = User()
user2.name = "이"
User.say_hello(user1) # 클래스에서 메서드 호출
user2.say_hello() # 인스턴스에서 메서드 호출
>>>
안녕, 나는 김이야!
안녕, 나는 이이야!
user2.say_hello() 에서 user2가 def say_hello(self):의 self로 자동으로 들어간다.
init
__init__메서드는 클래스 생성시 자동으로 호출된다.class User:
def initialize(self, name, email):
self.name = name
self.email = email
user1 = User()
user1.initialize("김코딩", "hi@gmail.com")
__init__메서드 없이는 객체 속성을 지정하기 위해 위처럼 해야한다.
__init__메서드는 객체를 생성할 때 인자를 넘겨주면 되므로 훨씬 간단해진다.
class User:
def __init__(self, name, email):
self.name = name
self.email = email
user1 = User("김코딩", "kim@gmail.com")
user1 = User("김코딩", "kim@gmail.com") 요 코드 한 줄이 실행되면 1) User의 인스턴스 하나가 생성됨, 2) init메서드가 호출됨 한 번에 객체를 생성하고 속성을 지정해줄 수 있다는 장점 때문에 보통 클래스를 만들땐 항상 init 메서드가 같이 호출된다.
str
위 코드에서 print(user1)을 해보면 <__main__.User object at 0x7fc9ab5c9670>이런 값이 나온다.
인스턴스를 출력 했을 때 원하는 값이 나오게 하려면 __str__을 사용하면 된다.
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return self.name
user1 = User("김코딩", "kim@gmail.com")
print(user1)
>>>
김코딩
클래스 변수
클래스 변수 : 클래스 정의에서 메서드 밖에 존재하는 변수
클래스명.변수명으로 엑세스 가능class User:
count = 0
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return self.name
User.count = 1
print(User.count)
>>>
1
__init__메서드가 호출되므로 거기에 더해주면 된다.class User:
count = 0
def __init__(self, name, email):
self.name = name
self.email = email
User.count += 1
def __str__(self):
return self.name
user1 = User("김", "kim@gmail.com")
user2 = User("이", "lee@gmail.com")
user3 = User("박", "park@gmail.com")
print(User.count)
>>>
3
클래스 변수를 출력하고 할당하는 방법에 대해 좀 더 살펴보자.
...생략....
user1 = User("김", "kim@gmail.com")
user2 = User("이", "lee@gmail.com")
user3 = User("박", "park@gmail.com")
user2.count = 10
print(User.count)
print(user1.count)
print(user2.count)
print(user3.count)
>>>
3
3
10
3
데코레이터
함수를 인자로 받아 꾸며진 함수를 리턴하는 함수
def print_hello():
print("안녕")
def add_print_to(original):
def wrapper():
print("함수 시작")
original()
print("함수 끝")
return wrapper
add_print_to(print_hello)()
>>>
함수 시작
안녕
함수 끝
def add_print_to(original):
def wrapper():
print("함수 시작")
original()
print("함수 끝")
return wrapper
@add_print_to
def print_hello():
print("안녕")
print_hello()
>>>
함수 시작
안녕
함수 끝
클래스 메소드
@classmethod 데코레이터를 달아주면 된다.self가 아닌 cls를 사용한다.cls.클래스변수명으로 엑세스 가능하다. 단, 객체 속성/메소드는 접근 불가class User:
count = 0
def __init__(self, name, email):
self.name = name
self.email = email
User.count += 1
def __str__(self):
return self.name
@classmethod
def number_of_users(cls):
print(f"총 유저수는 {cls.count}입니다.")
user1 = User("김", "kim@gmail.com")
user2 = User("이", "lee@gmail.com")
user3 = User("박", "park@gmail.com")
User.number_of_users() # 클래스를 통해 클래스 메서드 호출
user1.number_of_users() # 인스턴스를 통해 클래스 메서드 호출
>>>
총 유저수는 3입니다.
총 유저수는 3입니다.
인스턴스 메소드 vs 클래스 메소드
User.say_hello(user1) 또는 user1.say_hello()User.number_of_users() 또는 user1.number_of_users()언제 각 메소드를 사용해야 할까?
정적 메소드(static method)
...생략...
@staticmethod
def is_valid_email(email_address):
return "@" in email_address
user1 = User("김", "kim@gmail.com")
user2 = User("이", "lee@gmail.com")
user3 = User("박", "park@gmail.com")
print(User.is_valid_email("email")) # 클래스를 통해 클래스 메서드 호출
print(user1.is_valid_email("email@email.com"))
>>>
False
True
private, protected, public
__(double underscore)를 붙이면 접근이 허용되지 않음_(single underscore)를 붙여서 표기파이썬에서의 private, protected, public
Public
class Quadrangle:
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
def get_area(self):
return self.width * self.height
def set_area(self, width, height):
self.width = width
self.height = height
square = Quadrangle(5, 5, 'black')
print(square.get_area())
print(square.width)
square.width = 10
print(square.get_area())
>>>
25
5
50
Private
class Quadrangle:
def __init__(self, width, height, color):
self.__width = width
self.__height = height
self.__color = color
def get_area(self):
return self.__width * self.__height
def __set_area(self, width, height):
self.__width = width
self.__height = height
square = Quadrangle(5, 5, 'black')
print(square.__set_area(10, 10))
>>>
AttributeError : 'Quadrangle' object has no attribute '__set_area'
1) 파이썬은 순수 객체 지향 언어다 = 모든 것이 객체다
print(type(1))
print(type("a"))
print(type([]))
print(type({}))
print(type(()))
>>>
<class 'int'>
<class 'str'>
<class 'list'>
<class 'dict'>
<class 'tuple'>
2) 파이썬 가변 타입 vs 불변타입

3) 절차지향 vs 객체지향

4) 파이썬은 동적 타입 언어이다.
5) type hinting
변수명: type명이다.name: str = "kim"