동현 유
척척석사
동현 유
전체 방문자
오늘
어제
  • 분류 전체보기 (178)
    • BlockChain (48)
      • [paper] Consensus (13)
      • [paper] Execution (19)
      • [paper] Storage (5)
      • [paper] ZKP (1)
      • [paper] Oracle (1)
      • Blockchains (9)
    • Java (19)
      • Java의 정석 (13)
      • Java 파헤치기 (5)
    • Python (20)
      • Python 뜯어보기 (6)
      • 데이터 분석 기초 (5)
      • Python 기초 강의 (6)
      • Python 기초 강의 부록 (3)
    • Golang (0)
    • MySQL (3)
      • programmers (2)
      • 기본 문법 (0)
    • 웹 프로젝트 (IBAS) (36)
      • Django 레거시 (14)
      • SpringBoot api 개편 (14)
      • Infra (3)
      • 서버 장애 기록 (4)
      • 신입팀원 교육 자료 (1)
    • CS (30)
      • Operating System (22)
      • Computer Security (3)
      • Network (4)
      • DBMS (1)
    • 책 (10)
      • 도메인 주도 설계 철저 입문 (9)
      • Real MySQL 8.0 (1)
    • BOJ 문제 풀이 (3)
    • 이러쿵저러쿵 (7)
    • 회고 (1)

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.
동현 유

척척석사

[Python 뜯어보기] 2.극한의 '객체'충 파이썬
Python/Python 뜯어보기

[Python 뜯어보기] 2.극한의 '객체'충 파이썬

2021. 3. 17. 20:09

이번 공부를 하면서 얻은 교훈!

 

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 스타일 코딩이다.

 

연습해보실 분은 밑의 파일을 받고 클래스를 구현해보시라!

 

학생관리프로그램 개요.docx
0.04MB

 

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
    동현 유
    동현 유
    Fault Tolerant System Researcher for more Trustful World and Better Lives. (LinkedIn: https://www.linkedin.com/in/donghyeon-ryu-526b8a276/)

    티스토리툴바