•클래스(Class)
클래스는 새로운 타입(Type)을 만드는 설계도라고 할 수 있다.
클래스의 작동 구성요소(멤버)로는 멤버 변수(속성), 메서드(행위)로 볼 수 있다.
클래스를 통해서 만들어진 것을 객체(object)라고 한다. 이 객체들은 객체들 각각의 고유의 특징을 갖고 있고, 다른 객체에게 영향을 주지 않는다는 특징이 있다.
이전 게시글에서 작성한 모듈 같은 경우 파일 단위로 이름 공간을 갖지만, 클래스의 경우 생성하는 인스턴스로 이름 공간을 갖는다. 여기서 인스턴스는 클래스로 인해 만들어진 것이다. 그렇다면 여기서 '인스턴스 = 객체'인가 라는 생각이 들게 되는데 엄밀히 구분을 하면 다음과 같이 설명할 수 있다.
x는 변수, Test_Class라는 클래스가 존재한다고 가정 x = Test_Class() 여기서 x는 객체이자 Test_Class의 인스턴스다. 즉, 어떤 클래스의 객체인지를 관계 중심의 설명으로 하고자할 때 표현하는 방법이다. |
그 외에도 클래스에서는 오버로딩과 오버라이딩이라는 것이 존재한다.
* 오버로딩(Overloading) : 같은 클래스 내에서 똑같은 이름으로 메소드를 사용 하는 것(하나의 생성자 또는 메소드 이름으로 여러가지 기능을 담는 것)을 말한다. 여기서 또 두가지로 종류가 나뉘는데 다양한 방법으로 객체를 생성 가능하도록 한 메소드에서 파생되어 이름은 같지만 매개변수의 개수나 유형을 다르게 사용하는 '사용자 오버로딩'과 클래스 내 같은 이름의 메소드를 여러 개 선언하는 '메소드 오버로딩'이라고 한다. 단, 메소드 오버로딩의 성립 조건은 매개 변수의 타입, 개수, 순서 중 하나가 달라야 한다. 만약에 앞의 조건은 동일하지만 반환값이 다른 경우 성립되지 않는다. 이러한 메소드 오버로딩을 사용하는 이유는 다양한 값들을 받아서 처리하기 위함이다. 하지만 파이썬에서는 가장 최근에 입력된 값을 사용하기 때문에 오버로딩을 지원하지 않는다. (알고 있으면 좋을 것 같아 적어놨다.)
* 오버라이딩(Overriding) : 부모 클래스로부터 상속 받아서 메소드를 자식 클래스가 재정의하여 사용하는 것을 말한다.
쉽게 말하면 부모로부터 물려 받은 것을 새롭게 덮어쓰기하는 것이라고 보면 된다.
(예시1)
class test_class:
var = 0 # 멤버 변수는 전역변수다.(단, 클래스의 이름을 사용한다)
def __init__(self): # 객체 생성 시 자동 호출하여 실행
print('생성자 메소드 : 객체 생성 시 초기화 출력')
var = 1
def __del__(self): # 객체 종료 시 자동 호출
print('소멸자 메소드 : 프로그래밍 종료 시 마무리 출력')
var = 2
def member(self):
print('메소드 : 객체의 활동을 정의하고자 할때 사용')
name = '멤버 변수'
print('member의 지역 변수 :', name)
print("test_class.member : ", test_class.member) # 클래스 이름으로 멤버 변수(지역)의 주소 호출
# test.member() # 에러 발생 : 클래스의 이름으로 멤버 메소드를 호출할 수 없다.
test = test_class() # Class(설계도)에 의한 객체 생성 선언, ()는 생성자 메소드를 호출하는 역할, 괄호가 없으면 설계도를 던지는 역할
print(test) # 객체의 주소 확인
print(type(test)) # <class '__main__.TestClass'>
test.member() # 중요! 객체 변수.메소드명() 하면 자동으로 객체 변수가 인수로 담겨서 호출이 진행됨.
print()
# test.member(any) # 에러 발생2 : class명.메소드(객체변수)
print('-'*15)
test2 = test_class()
print(test2)
print(type(test2))
print('-'*15)
test3 = test_class()
print(test3)
print(type(test3))
test_class.member : <function test_class.member at 0x0000020A78C01F70> 생성자 메소드 : 객체 생성 시 초기화 출력 <__main__.test_class object at 0x0000020A78BD8700> <class '__main__.test_class'> 메소드 : 객체의 활동을 정의하고자 할때 사용 member의 지역 변수 : 멤버 변수 --------------- 생성자 메소드 : 객체 생성 시 초기화 출력 <__main__.test_class object at 0x0000020A78BD8AC0> <class '__main__.test_class'> --------------- 생성자 메소드 : 객체 생성 시 초기화 출력 <__main__.test_class object at 0x0000020A78BD8760> <class '__main__.test_class'> 소멸자 메소드 : 프로그래밍 종료 시 마무리 출력 소멸자 메소드 : 프로그래밍 종료 시 마무리 출력 소멸자 메소드 : 프로그래밍 종료 시 마무리 출력 |
단, 위 예시에서 에러가 첫 번째로 발생하는 주석 처리한 부분의 오류의 원인은 아래에 작성한 test 객체는 method()로써 작동되어 self값이 들어가지만 위에서 바로 사용한 test클래스명은 그렇지 않기 때문이다. 실제로 오류가 발생하는 부분을 실행하면 'member() missing 1 required positional argument: 'self' ' 이란 내용이 출력된다.
__del__ 경우 프로그램이 종료되면 출력되는 것이기 때문에 test, test2, test3의 모든 작동이 완료되었을 때 한 번에 출력된다.
또 '중요!' 라고 주석처리한 부분은 Bound method, 두 번째 에러 발생 주석 처리 부분을 Unbound method라고 한다.
* Bound method : 클래스는 여러 개의 멤버 함수들을 가질 수 있다. 이 멤버 함수들의 공통점이 'self'를 첫 번째 인자로 갖는다. 이 특징은 해당 함수가 어떤 클래스에 포함된 method라는 것을 구분하기 위함이다. 이것을 Bound method라고 한다.
때문에 위의 예시에서는 test라는 test_class의 인스턴스(객체)를 만들어서 member 메소드에 접근한 것이다.
*Unbound method : 위 예시에서 test.meber(any)로 에러가 발생하는 두 번째의 경우 첫 번째의 인자 값으로 self를 갖고 있는데 any라는 인자를 더 주었기 때문에 'member() takes 1 positional argument but 2 were given' 라는 오류가 발생한다.
사실 예시가 부적절하다 생각해서 다시 설명하자면 어떤 함수 any()가 어떤 클래스 test() 내부에 존재한지만 input 값을 갖지 않기 때문에 method로 호출(callable)할 수 없다. 이를 호출하면 에러가 발생할 것이다.
그렇기 때문에 이런 경우 Static method를 사용하면 test.any = staticmethod(test.any)로 바로 실행할 수 있고, 이전에 작성한 데코레이터 기능을 이용하여 해당 함수 위에 @staticmethod를 작성해준 후 일반 함수처럼 test.any()로 호출하여 사용하면 된다.
2023.01.14 - [파이썬] - 파이썬 - 함수 추가 내용(4)_Decorator & 재귀 함수
파이썬 - 함수 추가 내용(4)_Decorator & 재귀 함수
•Decorator(데코레이터) Decorator(데코레이터, 함수 장식자, Function Decorator)란 하위 클래스를 직접 사용하지 않고도 함수나 메소드 또는 클래스의 기능을 사용할 수 있다. 즉 Meta(데이터의 데이터) 기
bluenoa.tistory.com
(예시2)
class car_accident:
# 멤버 변수
global Vehicle_type
Vehicle_type = {1:'경형', 2:'소형', 3:'중형', 4:'대형'}
Acc_speed = 0
def __init__(self, name, type, Acc_speed): # name과 type, Acc_speed는 parameter
self.name = name # 기존에 없던 값을 할당
self.type = Vehicle_type[type]
self.speed = Acc_speed
def show_report(self):
km = ' 킬로미터' # 지역 변수
rep = '속도 : ' + str(self.speed) + km
return rep
car_acc1 = car_accident('임광석', 1, 70)
print(car_acc1.name, car_acc1.type, car_acc1.speed)
print(car_acc1.show_report())
car_acc1.color = 'blue' # car_acc1에 객체 멤버 추가할 수 있다.
print('car_acc1.color : ', car_acc1.color)
print() # 한줄띄기
car_acc2 = car_accident('정상수', 4, 120)
print(car_acc2.name, car_acc2.type, car_acc2.speed)
print(car_acc2.show_report())
print()
print(car_accident, car_acc1, car_acc2) # 주소 확인
print(id(car_accident), id(car_acc1), id(car_acc2)) # id확인
# 각 주소와 id가 다르기 때문에 각자의 객체에서 발생하는 일은 자신 이외에는 알 수 가 없다.
print('\n 멤버를 확인할 때 사용하는 문법 dict, 각 객체에만 저장된 값들')
print('car_acc1 : ', car_acc1.__dict__) # car_acc1에만 차량 색상과 관련된 객체를 만들어줬기에 car_acc1만 존재
print('car_acc2 : ', car_acc2.__dict__)
# print(car_acc2.color) # 오류 발생 car_acc2에는 색상이 없기 때문이다.
임광석 경형 70 속도 : 70 킬로미터 car_acc1.color : blue 정상수 대형 120 속도 : 120 킬로미터 <class '__main__.car_accident'> <__main__.car_accident object at 0x00000195C9907F70> <__main__.car_accident object at 0x00000195C9F88760> 1742841517648 1742843445104 1742850262880 멤버를 확인할 때 사용하는 문법 dict, 각 객체에만 저장된 값들 car_acc1 : {'name': '임광석', 'type': '경형', 'speed': 70, 'color': 'blue'} car_acc2 : {'name': '정상수', 'type': '대형', 'speed': 120} |
(예시3) 예시1을 상속받아 재정의(오버라이딩)
class test_class:
var = 0 # 멤버 변수는 전역변수다.(단, 클래스의 이름을 사용한다)
def __init__(self): # 객체 생성 시 자동 호출하여 실행
print('생성자 메소드 : 객체 생성 시 초기화 출력')
var = 1
def __del__(self): # 객체 종료 시 자동 호출
print('소멸자 메소드 : 프로그래밍 종료 시 마무리 출력')
var = 2
def member(self):
print('메소드 : 객체의 활동을 정의하고자 할때 사용')
name = '멤버 변수'
print('member의 지역 변수 :', name)
class inheritance_class(test_class): # class 클래스명(상속할 클래스명)
def member(self): # 오버라이딩
print('재정의 되었다!')
name = '재정의된 멤버 변수'
print('member의 재정의된 지역 변수 : ', name)
def abb(self):
print('\n부모 클래스의 멤버 함수 호출')
super().member()
a = inheritance_class()
a.member()
print('부모 클래스 확인 : ', inheritance_class.__bases__) # 현재 클래스의 부모 클래스 확인하는 명령어(.__bases__)
a.abb()
생성자 메소드 : 객체 생성 시 초기화 출력 재정의 되었다! member의 재정의된 지역 변수 : 재정의된 멤버 변수 부모 클래스 확인 : (<class '__main__.test_class'>,) 부모 클래스의 멤버 함수 호출 메소드 : 객체의 활동을 정의하고자 할때 사용 member의 지역 변수 : 멤버 변수 소멸자 메소드 : 프로그래밍 종료 시 마무리 출력 |
'파이썬(Python)' 카테고리의 다른 글
파이썬 - 클래스(3) (0) | 2023.02.18 |
---|---|
파이썬 - 클래스(2) (0) | 2023.02.08 |
파이썬 - 읽고 쓰기와 모듈(Module) (2) | 2023.01.19 |
파이썬 - 함수 추가 내용(4)_Decorator & 재귀 함수 (0) | 2023.01.14 |
파이썬 - 함수 추가 내용(3)_일급 함수와 축약 함수(lambda) (0) | 2023.01.11 |