-
Python 문법 기초 23 - class(import 사용)Python 2022. 10. 22. 16:57
print('뭔가를 하다가 모듈의 멤버인 클래스를 선언하기') class TestClass: # prototype, 원형클래스 객체 생성. 고유의 이름 공간을 확보 aa = 1 # 멤버변수(멤버필드), public def __init__(self): # 생성자 print('생성자') def __del__(self): # 소멸자 print('소멸자') def printMessage(self): # method name = '한국인' # 지역변수 print(name) print(self.aa) print(TestClass, id(TestClass)) print(TestClass.aa) print() test = TestClass() # 생성자 호출한 후 TestClass type의 객체 생성 됨(자바의 인스탄스 된 거랑 비슷함) print(test.aa) # 멤버필드 호출 <console> 뭔가를 하다가 모듈의 멤버인 클래스를 선언하기 <class '__main__.TestClass'> 2786687816240 1 생성자 1 한국인 1
test 라는 변수에 TestClass의 생성자를 넣어둔 뒤, 그 안에 있는 메소드를 호출하면 위와 같이 나온다.
소멸자는 파이썬에서 잘 사용하지 않는데 그 이유는 자바와 마찮가지로 쓰레기 수집기(GC)가 있기 때문에다. 그럼에도 불구하고 소멸자가 있는 이유는 c언어에 존재하기 때문인데 파이썬은 c언어로 만들었기 때문에 소멸자가 존재하는 것이다.
# 메소드 호출 # TestClass.printMessage() err missing 1 required positional argument test.printMessage() # Bound method call print() TestClass.printMessage(test) # UnBound method call <console> 한국인 1
메소드 안에 들어있는 매개변수는 반드시 self 를 가져야된다.
5번째 줄을 호출하면 인자 자리에 클래스 명이 들어가야 된다.
위의 경우에는 class를 test에 넣어주었기 때문에 저절로 들어가지만
5번째 줄은 인자를 직접 넣어주어야 된다.
그것이 Bound method call, UnBound method call 이다.
print() print(type(1)) print(type(1.1)) print(type(test)) print(id(test), id(TestClass)) <console> <class 'int'> <class 'float'> <class '__main__.TestClass'> 3120285018240 3120285559696
test 타입의 type을 호출해보면 새롭게 만든 클래스의 type이 나온다. 위의 사진을 보면 객체는 2개 생성되었다.
보면 test와 TestClass 둘의 주소는 다르다. 얕은 치환에도 불구하고 주소가 다른 이유는 객체는 생성될 때마다 새로운 주소를 갖기 때문이다.
# 클래스 class Car: handle = 0 # Car type의 객체에서 참조 가능 멤버 필드 speed = 0 def __init__(self, name, speed): self.name = name self.speed = speed def showData(self): # Car type의 객체에서 참조 가능 멤버 메소드 km = '킬로미터' msg = '속도:' + str(self.speed) + km + ', 핸들은 ' + str(self.handle) return msg print(id(Car)) print(Car.handle) print(Car.speed) car1 = Car('tom', 10) # 생성자 호출 후 객체 생성' print(car1.handle, car1.name, car1.speed) car1.color = '보라' print('car1 color : %s'%car1.color) car2 = Car('james', 20) <console> 1971391249408 0 0 0 tom 10 car1 color : 보라 0 james 20
객체를 생성할 때, self에는 car1이 저절로 들어가고 name 과 speed의 값을 부여하면 ca1의 객체가 생성된다.
위의 경우 car1를 참조하지만 handle은 car1에 존재하지 않는다. 이런 경우에는 자신의 부모인 Car에 가서 handle 값을 가져오게 된다.
car1에게 새로운 멤버필드를 지정해줄 수도 있다. 이런 경우에는 Car에는 color 필드가 들어가지 않고, car1의 고유의 멤버필드가 된다.
print('car2 color : %s'%car2.color) 'Car' object has no attribute 'color'
err car2에는 color가 없다. 없을경우 부모한테 찾는데 부모에게도 없어서 에러를 발생시킨다.print('주소 : ', id(Car), id(car1), id(car2)) <console> 주소 : 1971391249408 1971402010576 1971402010384
객체를 생성할 경우 얕은 복사여도 주소는 달라진다. 객체를 생성할 때마다 새로운 주소로 적용되기 때문이다.
print(car1.showData()) print(car2.showData()) print(Car.showData(car2)) print('~~~~') car2.speed = 100 Car.handle = 1 car1.handle = 2 print('car2 : ', car2.showData()) # 100 print('car1 : ', car1.showData()) # 10 <console> 속도:10킬로미터, 핸들은 0 속도:20킬로미터, 핸들은 0 속도:20킬로미터, 핸들은 0 ~~~~ car2 : 속도:100킬로미터, 핸들은 1 car1 : 속도:10킬로미터, 핸들은 2
ca1 에서 호출이 불가능한 경우 부모 객체인 Car 객체에서 참조한다. 그러나 Car 객체에도 없다면 err 가 발생된다.
위의 경우에는 ca1, car2 에게 handle 값을 부여하지 않았음므로 부모인 Car 에서 값을 가져온 것이다.
각각 고유의 객체에 handle 값을 부여해주면 값이 들어가기에 호출되는 것은 각각의 고유의 객체의 값이 호출된다.
메소드 호출
2, 3번째 줄은 똑같은 의미이다. Bound method call, UnBound method call
print(Car.showData(car2))
Car의 객체를 호출하고 있지만 car2의 주소를 가져갔기 때문에 똑같이 20킬로미터가 호출된 것이다.
정리
1. class 를 생하면 객체가 만들어진다.(java로 치면 Car car1 = new Car(’tom’, 10) 과 같은 말이다.)
2. car1의 객체를 새로운 주소로 생성 가능하다.
3. 부모 class인 Car를 가지고 car2의 객체를 만들 수도 있다.(새로운 주소)
print(car1.showData()) print(car2.showData()) print(Car.showData(car2)) print('~~~~') car2.speed = 100 Car.handle = 1 car1.handle = 2 print('car2 : ', car2.showData()) # 100 print('car1 : ', car1.showData()) # 10
car2의 speed를 변경해주면 그것은 car2만 적용이된다.
car1, Car는 값이 변경되지 않는다. 그 이유는 각각 고유의 주소를 가진 객체들이기 때문이다.
'Python' 카테고리의 다른 글
Python 문법 기초 25 - class 포함관계(2) (0) 2022.10.22 Python 문법 기초 24 - class 포함관계(1) (0) 2022.10.22 Python 문법 기초 22 - 모듈(module) (0) 2022.10.22 Python 문법 기초 21 - 재귀 함수(Recursive function) (0) 2022.10.22 Python 문법 기초 20 - 함수 장식자(decorator) (0) 2022.10.22