이번 공부를 하면서 얻은 교훈!
C 와 Python 의 가장 큰 차이점이 무엇인지 느껴졌다!!
C는 함수 호출 시 스택 메모리에 로드하고, 빠져나올 때 의미를 잃어버린다.
Python은 함수를 네임스페이스 라는 공간에 정의를 한다. 함수까지도 객체화 해버렸다.
여기서 많은 차이가 발생하는 것 같다. 마치 레고? 로봇? 같은 느낌이다.
우리가 쓰는 모든 변수는 잘 만들어진 로봇의 부품들을 하나하나 가리키는 용도일 뿐이다.
C는 주물작업으로 직접 레고 부품을 하나하나 만들고, 만들어진 부품을 내 손으로 직접 쌓는 느낌
Python은 절대 내 손으로는 그 부품을 만질 수 없다.
내가 타워 크레인이 된 것처럼 이미 잘 만들어진 것들을 이리저리 옮겨서 쌓는 느낌이다.
C는 장인의 손길이 느껴지는 반면, Python은 잘 만든 장난감 회사 제품 느낌이 난다.
그 동안 C를 통해 장인정신을 너무 기른 나머지
Python으로 코딩하다보면 불경스럽다는 생각도 든다.
1. 객체
- 모든 객체는 id / value / type 을 갖는다.
- 모든 것은 객체다. (함수까지도!)
- 변수는 객체를 가리키는 참조 역할만 할 뿐이다. (역시나 복사의 문제가 있다.)
- 모든 객체는 변경불가능하다. (dict, list 제외)
- 자주 쓰는 객체는 메모리에 올려져있다. (ex. 절대값이 2^8 보다 작은 정수 / None / True / ...),
객체 생성에 드는 시간을 줄이기 위함인듯하다.
같은 값을 다른 변수에 할당하면 같은 id !! 같은 변수에 다른 값을 할당하면 다른 id !!
- 모든 객체는 그들만의 고유한 namespace를 갖을 수 있다.
그래서 클래스에서 정의하지 않았던 data attribute를 생성하거나, 정의된 것들을 del 로 제거할 수 있다.
2. 클래스
- 클래스 자체도 객체다! Namespace 라는 개념 때문이다.
- 따라서 클래스 이름 자체로 호출할 수 있는 attribute 가 존재.
클래스의 변수(객체의 변수와는 다르다.)와 메소드. 던더 함수들. 이것들 모두 클래스 객체 안에 속한다.
3. 메서드
- 메서드도 객체다.
- 클래스의 메서드는 항상 불러낸 인스턴스를 parameter로 받는다.
이 부분이 굉장히 흥미롭다. 거꾸로 말하면 호출되는 메서드는 호출한 인스턴스를 스스로 알 수 없다.
왜냐하면 메서드는 클래스의 namespace에 있기 때문이다.
이런 특성 때문에 함수 자체를 다른 변수에 할당하고 불러낼 수 있다.
xf = x.f
while True:
print(xf()) # xf() 호출시에 해당 인스턴스 정보가 없다!!
# xf() 가 존재하는 클래스 namespace로 가서 호출!!?
# Class.f(x)와 같은 표현이다.
# 즉 인스턴스 x와 Class.f 를 묶어서 하나의 메서드 객체로 만든다.
4. private 객체
- 엄밀히 말해서 객체 내부에서만 접근 가능한 private라는 개념은 존재하지 않는다.
- 클라이언트로부터 완벽한 은닉을 구현할 수 없다. 메서드에 항상 self 객체를 인자로 넘겨주기 때문.
- c 언어는 필요한 정보와 구현을 은닉할 수 있다! cPython은 이를 보완한다고 한다. 메모리에도 직접 접근 가능하다.
- 밑줄 2개를 이름 앞에 붙여서( ex. __spam() ), 공개하지 않겠다는 의미로 사용되기는 한다.
통보 없이 변경되어도 되는 부분. 하지만 여전히 접근 가능하다는 점 유의!
5. 이터레이터 / 제너레이터
- __iter__() / __next__() 함수로 클래스에 해당하는 이터레이터를 쉽게 구현할 수 있다.
- 위의 이터레이터 구현을 yield 라는 명령어로 손쉽게 구현가능!
- 자바로 어플리케이션 구현할 때의 thread의 느낌이 난다.
- 이러한 특성때문에, for ~ in ~ 이라는 구조로 열거형 테이터 타입 엘리먼트에 쉽게 접근 가능.
- dojang.io/mod/page/view.php?id=2412 참고!
6. 기타
- 다중 상속 가능
- for문 < List Comprehension < Generator
심심해서 학생 관리 프로그램을 클래스로 구현해보았다.
최대한 파이썬스럽게 코딩해보려고 노력했는데
딱 봐도 C 스타일 코딩이다.
연습해보실 분은 밑의 파일을 받고 클래스를 구현해보시라!
class Student():
# name
# std_no
# grade_dict
def __init__(self, name, std_no, grade_dict):
self.name = name
self.std_no = std_no
self.grade_dict = grade_dict
def std_sum(self):
return sum(self.grade_dict.values())
def std_avg(self):
return self.std_sum()/len(self.grade_dict)
# end Student
class SMS():
# student_list = []
def __init__(self):
self.student_list = []
def all_sum(self):
return sum(stu.std_sum() for stu in self.student_list)
def all_avg(self):
return sum(stu.std_avg() for stu in self.student_list) / len(self.student_list)
def isExist(self,std_no):
flag = False
for i in self.student_list:
if(i.std_no == std_no):
flag = True
return flag
def insert(self, Student):
self.student_list.append(Student)
def del_std(self, std_no):
for i in self.student_list:
if(i.std_no == std_no):
self.student_list.remove(i)
break
def print_students(self):
for std in self.student_list :
print('학생 이름: ' + std.name,
'학생 학번: ' + std.std_no,
*['{}: {}'.format(k, v) for k, v in std.grade_dict.items()],
'총점:'+str(std.std_sum()),
'평균:'+str(std.std_avg()),
sep = ' | ',
end = '\n\n'
)
print('전체 평균: ' + str(self.all_avg()), end = '\n')
# end SMS
if __name__ == "__main__": # 이 모듈을 호출한 녀석의 네임스페이스가 __main__이어야 한다.
import os
import time
program = SMS()
while(True):
user_choice = int(input("1.조회 2.추가 3.삭제 4.프로그램 종료\n"))
delay_time = 1
if(user_choice == 1):
if(len(program.student_list) == 0):
print("리스트가 비었습니다!\n")
else:
program.print_students()
delay_time = 5
elif(user_choice == 2):
name = input('학생의 이름을 입력하세요:')
id = input('학생의 학번을 입력하세요:')
grade = {}
grade['국어'] = int(input('국어 성적을 입력하세요:'))
grade['수학'] = int(input('수학 성적을 입력하세요:'))
grade['사회'] = int(input('사회 성적을 입력하세요:'))
grade['과학'] = int(input('과학 성적을 입력하세요:'))
grade['영어'] = int(input('영어 성적을 입력하세요:'))
if(program.isExist(id)):
ans = input('이미 같은 학번의 학생이 존재합니다. \
새로 입력한 학생 정보로 기존 정보를 대체하시겠습니까?(Y/N)')
if(ans == 'n' or ans == 'N'):
continue
elif(ans == 'y' or ans == 'Y'):
program.insert(Student(name,id,grade))
else:
program.insert(Student(name,id,grade))
elif(user_choice == 3):
id = input('리스트에서 제거할 학생의 학번을 입력하세요:')
if(program.isExist(id)):
program.del_std(id)
else:
print('해당 학생이 리스트에 존재하지 않습니다.')
elif(user_choice == 4):
break
time.sleep(delay_time)
os.system('cls')
'Python > Python 뜯어보기' 카테고리의 다른 글
[Python 뜯어보기] 5. 파이썬 가상머신(PVM) 과 컴파일방식 (0) | 2022.04.13 |
---|---|
[Python 뜯어보기] 4. WSGI 와 Python (0) | 2022.03.22 |
[Python 뜯어보기] 3. 파이썬 Thread 와 GIL (1) | 2022.03.22 |
[Python 뜯어보기] 1. 파이썬은 어떻게 문장을 인식할까? (0) | 2021.03.10 |
[Python 뜯어보기] 0. 파이썬을 공부하기로 결심한 이유 (0) | 2021.03.10 |