파이썬 객체지향
객체
객체란 속성과 행동으로 이루어진 것을 말한다.
객체 지향 프로그래밍
프로그램을 여러 개의 독립된 객체들과 그 객체들 간의 상호작용으로 파악하는 프로그래밍 접근법이다.
객체 지향적으로 설계하는 것을 모델링이라 한다.
객체 지향 프로그래밍으로 프로그램을 만들려면
- 프로그램에 어떤 객체들이 필요할지 정한다.
- 객체들의 속성과 행동을 정한다.
- 객체들이 서로 어떻게 소통할지 정한다.
객체 만들기
클래스, 인스턴스
객체의 설계도를 클래스라고 한다.
클래스를 통해 구현할 것을 객체라고 한다.
객체를 실체화 시킨것을 인스턴스라고 한다.
class User:
pass
user1 = User()
user2 = User()
클래스 이름의 첫 글자는 항상 대문자로 작성한다.
User클래스를 통해서 인스턴스를 생성할 수 있다.
user1과 user2는 별개의 인스턴스다.
인스턴스 변수
- 인스턴스 변수 정의하기
인스턴스 이름.속성이름(인스턴스 변수) = “속성에 넣을 값”user1.name = "철수" user1.email = "ccc@naver.com"
인스턴스가 독립적으로 가지고 있는 값을 인스턴스 변수라고 한다.
객체에서의 속성을 인스턴스 변수로 나타낸다. - 인스턴스 변수 사용하기
인스턴스 이름.인스턴스 변수 이름print(user1.name)
인스턴스 메소드
객체의 행동은 메소드로 나타낸다.
메소드의 종류에는 인스턴스 메소드, 클래스 메소드, 정적 메소드가 있다.
인스턴스 메소드는 인스턴스 변수를 사용하거나, 인스턴스 변수에 값을 설정하는 메소드다.
class User:
def hello(user):
print("안녕하세요 {}입니다.".format(user.name))
인스턴스 메소드 사용하기
아래의 두가지 방법은 동일한 결과를 낸다.
User.hello(user1)
클래스에서 메소드를 호출한다.
user1.hello()
인스턴스에서 메소드를 호출한다.
이 때는 인스턴스가 메소드의 첫 번째 파라미터로 자동으로 전달된다.
그래서 인스턴스 메소드를 정의할 때는 첫 번째 파라미터는 인스턴스 자신을 받는 의미에서 이름을 self라고 짓는다.
만약 파라미터를 한개만 받는 메소드인데 파라미터를 입력하게 되면 파라미터를 두개를 받는 셈이 되어 에러가 나게된다.
파라미터를 여러개 받는 경우라면 인스턴스가 메소드의 첫 번째 파라미터로 전달되니 그것을 뺀 나머지 파라미터만 넣어주면 된다.
self
class User:
def hello(self):
print("안녕하세요 {}입니다.".format(self.name))
인스턴스 메소드의 첫 번째 파라미터의 이름은 self로 쓴다.
강제되는 것은 아니지만 하나의 규칙이다.
인스턴스 변수와 같은 이름을 갖는 파라미터를 사용할 수 도 있다.
class User:
def check(self, name):
return self.name == name
이름이 같지만 둘은 전혀 다른것이기 때문에 상관없다.
init
인스턴스 생성시 자동 호출된다.
class User:
def info(self, name, age):
self.name = name
self.age = age
user1 = User()
user1.info("철수", 27)
print(user1.name)
print(user1.age)
기존의 방식에서는 user1인스턴스를 생성하고 호출을 했지만
__init__을 사용하면 인스턴스 생성 후 호출할 필요없이 자동 호출된다.
class User:
def __init__(self, name, age):
self.name = name
self.age = age
user1 = User("철수", 27)
print(user1.name)
print(user1.age)
인스턴스 생성과 인스턴스 변수 초기값 설정을 한 줄에 할 수 있다.
str
__str__은 print함수를 호출할 때 자동으로 호출된다.
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "사용자: {}, 나이: {}".format(self.name, self.age)
user1 = User("철수", 27)
print(user1)
클래스 변수
인스턴스 자신만의 속성은 인스턴스 변수고 같의 클래스의 인스턴스들이 공유하는 속성은 클래스 변수다.
class User:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
User.count += 1
User.count = 1
print(User.count)
user1 = User("철수", 27)
print(user1.count)
위 코드에서는 속성이 공유되어서 인스턴스가 생성될 때 마다 count가 올라간다.
- 읽는 법
인스턴스 이름.클래스 변수 이름 user1.count
클래스 이름.클래스 변수 이름 User.count - 값 설정하는 법
클래스 이름.클래스 변수 이름 = “값” User.count = 1
인스턴스 이름.클래스 변수 이름 = “값” user1.count = 1 은 불가능하다.
이 방식은 인스턴스 변수를 설정할 때 사용하는 문법이기 때문이다.
클래스 변수에 값을 설정할 때는 클래스 이름으로만 해야한다.
데코레이터
어떤 함수를 꾸며서 새로운 함수를 만들어 낼 수 있다.
def hello():
print("hello")
def add_print_to(original):
def wrapper():
print("시작")
original()
print("끝")
return wrapper
print_hello = add_print_to(hello)
print_hello()
기존의 hello함수에 wrapper함수를 사용해 내용을 추가했다.
데코레이터를 사용해 더 간단하게 작성할 수 있다.
def add_print_to(original):
def wrapper():
print("시작")
original()
print("끝")
return wrapper
@ add_print_to
def hello():
print("hello")
hello()
클래스 메소드
class User:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
User.count += 1
@classmethod
def number_of_users(cls):
print(cls.count)
user1 = User("철수", 27)
user2 = User("영희", 25)
User.number_of_users()
user1.number_of_users()
클래스 메소드는 @classmethod 데코레이터를 사용하고 첫 번째 파라미터의 이름은 cls를 사용한다.
클래스로 클래스 메소드를 호출할 수 도 있고
인스턴스로 클래스 메소드를 호출할 수 도 있다.
인스턴스 메소드를 사용할 때는
User.hello(user1)
user1.hello()
두번 째 경우에만 인스턴스가 파라미터로 자동 전달이 되었지만
클래스 메소드를 사용할 때는 두가지 방법 다 클래스가 파라미터로 자동 전달된다.
위의 클래스 메소드를 인스턴스 메소드로 작성해 보면
def number_of_users(self):
print(User.count)
이렇게 되는데 잘 보면 self를 사용하지 않고 User클래스는 사용을 하고 있기 때문에 애초에 클래스 메소드로 쓰는게 효율적이다.
인스턴스 변수를 사용하지 않고 클래스 변수만 사용하고 있다면 클래스 메소드를 쓴다.
만약 클래스 변수와 인스턴스 변수 둘 다 쓴다면 인스턴스 메소드를 사용한다. 클래스 메소드에서는 인스턴스 변수가 사용 불가능하기 때문이다.
그리고 인스턴스가 하나도 생성되지 않았을 때도 사용할 가능성이 있으면 클래스 메소드를 쓴다.
정적 메소드
인스턴스 변수, 클래스 변수를 다루지 않는 메소드다.
def __str__(self):
return "사용자: {}, 나이: {}, 이메일: {}".format(self.name, self.age, self.email)
@classmethod
def number_of_users(cls):
print("총 유저 수는: {}입니다".format(cls.count))
@staticmethod
def is_valid_email(email_address):
return "@" in email_address
인스턴스 메소드는 인스턴스 변수를 사용하고 있고,
클래스 메소드는 클래스 변수를 사용하고 있고,
정적 메소드는 아무 변수도 사용하고 있지 않다.
Leave a comment