대부분 클래스를 정의할 수 있는 기능을 갖고 있다. 파이썬은 클래스에 매직 메서드
라는 기능을 추가했다.
9.1 클래스와 객체 기본 문법
class Car :
accel = 3.0
mpg = 25
car1 = Car()
car2 = Car()
print('car1.accel : ' , car1.accel) # 3.0 출력
print('car1.mpg : ' , car1.mpg) # 25 출력
print('car2.accel : ' , car2.accel) # 3.0 출력
print('car2.mpg : ' , car2.mpg) # 25 출력
car1이 갖고 있는 인스턴스의 변수를 내 맘대로 수정할 수도 있다.
car1.accel = 5.0
car1.mpg = 300
>>> car1.accel
5.0
>>> car1.mpg
3000
>>> car2.accel
3.0
>>> car2.mpg
25
9.2 인스턴스 변수
파이썬의 인스턴스 변수는 클래스 안에서 직접 생성되지 않는다.
필요할 때 마다 바로 생성되거나 __init__
메서드 안에서 생성된다.
자바와 같은 다른 언어는 인스턴스 변수도 사용하기 전에 멤버 변수로 미리 정의
해야 하지만,
파이썬 인스턴스 변수는 미리 정의하지 않고 필요할 때 바로 값을 대입
한다는 것을 의미함
ex) Dog 클래스로 생성한 인스턴스에 여러 속성 추가
class Dog :
pass # 처리할 것이 없을 때 pass 키워드 사용하면 됨
my_dog = Dog() # Dog 클래스의 인스턴스를 생성
# 원래 Dog 클래스에서 정의하지 않은 name, breed, age 라는 멤버변수를
# 바로 만들어내서 대입하는 코드
my_dog.name = 'Chanm"
my_dog.breed = 'Great Dane'
my_dog.age = 5
이렇게 3개의 변수를 my_dog 객체에 할당했다. 각 변수에 접근하고 싶다면 my_dog.name,my_dog.breed, my_dog.age으로 접근하면 된다.
당연히 name, breed, age는 my_dog 인스턴스에만 할당된 변수이지
Dog 클래스를 가지고 만든 다른 인스턴스에는 해당 변수들이 저장되지 않는다.
그렇다면.. 어떻게 동일한 클래스의 모든 객체가 같은 속성(인스턴스 변수들)을 가질 수 있을까?
이를 위해 __init__
메서드를 사용한다.
9.3 __init__
메서드, __new__
메서드
클래스에서 __init__
메서드를 정의했다면 해당 클래스의 인스턴스가 생성될 때 마다 자동으로 __init__
메서드가 호출된다.
클래스의 모든 인스턴스가 동일한 변수들의 집합을 가지면서 각 인스턴스 별로 독립적인 값을 갖도록 할 때 사용할 수 있다.
class 클래스이름 :
def __init__ (self, args) :
코드
ex) Dog 클래스
class Dog :
def __init__ (self, name, breed, age) :
self.name = name
self.breed = breed
self.age = age
위와 같이 정의하면 Dog의 객체를 생성할 때 마다 반드시 3개의 인수를 입력해야 한다.
그 인수들은 __init__
메서드로 전달되면서 해당 인스턴스의 변수에 값을 넣어준다.
top_dog = Dog('Hand', 'Bulldog', 10)
__new__
메서드는 2가지 상황에서만 사용된다.
1) 메모리 할당을 위한 특별한 기법을 사용하는 경우
2) 하위 클래스가 불변(immutable)이거나 내장(built-in) 클래스인 경우
9.4 클래스와 선행 참조 문제
class Marriage :
def __init__ (self) :
self.wife = Person('f')
self.husband = Person('m')
a_marriage = Marriage() # 코드 순서를 보면 아직 Person 클래스를 정의하지 않았다.
# 하지만, Marriage 클래스의 인스턴스를 생성하는 과정에서
# 아직 생성하지 않은 클래스를 사용하려고 하기 때문에 오류가 발생한다.
class Person :
def __init__ (self, gender) :
self.gender = gender
위에서는 Marriage 클래스
에서 Person 클래스의 인스턴스
를 생성하려고 하니까Person 클래스
의 선언이 완료된 이후에 Marriage 클래스이 인스턴스를 생성해야 한다.
9.6 전역변수/ 메서드와 지역변수/ 메서드
객체 지향 언어를 사용하는 목적 중 하나가 캡슐화
다. 캡슐화를 통해 클래스 내부의 내용을 바깥으로 노출하지 않도록 한다.
파이썬의 철학은 이 사상과 대치된다. 스크립팅 언어인 파이썬은 모든 것을 노출하는 경향이 있으며 모든 것을 볼 수 있다.
때문에, 다른 언어에 비해 보안과 타입 확인 능력(3.6에서는 다소 개선됨) 이 다소 부족하다.
대신, 파이썬은 유용한 규약을 따르고 있다.
_
1개로 변수와 메서드 이름이 시작 : 내부용_
2개로 변수와 메서드 이름이 시작 : 맹글링(mangling, 의도치 않은 접근을 통제)
ex)
class Odd :
def __init__(self) :
self.x = 10
self.y = 20
self.__z = 30 # 맹글링 적용
def pr(self) :
print('__z = ' , self.__z) # 클래스 내부에서는 맹글링 없이 접근 가능
>>> o.x
10
>>> o.y
20
>>> o.__z # 에러 발생
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Odd' object has no attribute '__z'
에러가 발생하는 이유는 파이썬이 변수 __z
를 클래스 이름과 변수 이름의 조합으로 훼손된(mangled) 이름으로 교체하기 때문이다.
하지만, 클래스 내부에서는 맹글링 없이 접근할 수 있다.
9.7 상속
파이썬은 하위 클래스 만들기(subclassing)
, 상속(inheritance)
을 지원한다.
- 상위 클래스를 단일 상속
class 클래스이름(상위_클래스) :
코드
위와 같이 만든 클래스는 상위 클래스의 모든 클래스 변수와 메소드를 상속받게 된다.
새로운 변수, 메서드 정의를 추가할 수 있고 기존에 정의된 메서드를 재정의할 수도 있다.
ex)
class Mammal :
def __init__ (self, name, size) :
self.name = name
self.size = size
def speak(self) :
print("My name is" , self.name)
def call_out(self) :
self.speak()
self.speak()
class Dog(Mammal) : # Mammal 클래스를 상속받은 Dog 클래스
def speak(self) : # Mammal 클래스에서 정의되어 있던 speak 메서드를 재정의
print("월월!!")
class Cat(Mammal) : # Mammal 클래스를 상속받은 Cat 클래스
def speak(self) : # Mammal 클래스에서 정의되어 있던 speak 메서드를 재정의
print("야옹!")
>>> my_cat = Cat('Pre', 11)
>>> my_cat.call_out() # speak 메서드가 Cat 클래스에서 재정의한 걸 볼 수 있다
야옹!
야옹!
위 코드에서 Dog, Cat 클래스가 추가적인 초기화 작업을 진행하고 싶다면 어떻게 해야 할까? super().__init__
을 이용하면 된다.
class Dog(Mammal) :
def speak(self) :
print("월월!!")
def __init__ (self, name, size, breed) :
super().__init__(name, size) # 상위 클래스에서 상속받은 인스턴스 변수들을 초기화하고
self.breed = breed # 추가로 정의한 변수를 초기화한다.
9.8 다중 상속
하나의 클래스가 2개 이상의 상위 클래스를 상속받을 수 있다.
class 클래스이름(상위_클래스1, 상위_클래스2, 상위_클래스3, ...) :
코드
ex) Dog 클래스가 Mammal, Pet, Carnivore 라는 3개의 클래스를 상속받고 있다고 하자.
class Dog(Mammal, Pet, Carnivore) :
def speak(self) :
print("월월!!")
def __init__ (self, name, size, nickname, breed) :
Mammal.__init__(self, name, size)
Pet.__init__(self, nickname)
self.breed = breed
'Python' 카테고리의 다른 글
[파이썬 코드 업] 9-2장. 클래스와 매직 메서드 (0) | 2023.05.07 |
---|---|
[파이썬 코드 업] 4-3장. 데코레이터 (0) | 2023.05.06 |
[파이썬 코드 업] 4-2장. (0) | 2023.05.06 |
[파이썬 코드 업] 4-1장. 프로그래밍 지름길 (0) | 2023.05.05 |
[파이썬 스킬 업] 3장. 리스트 기능 (0) | 2023.04.27 |