Python TIL (20180806)

2019-02-14

.

study program : https://www.fastcampus.co.kr/dev_school_css

# CPU와 GPU의 차이점

  • CPU는 순차적인 연산을 진행한다.

  • GPU는 실수밖에 연산을하지 못하는 단점이 있다. GPU에는 연산을 하는 모듈이 수많이 들어있다. 수많은 연산을 한번에 시행할 수 있다.

# 프로그래밍의 패러다임은 함수를 만든다거나 OOP은 추상화를 하는 개념인데 프로그래밍을 하는데 있어서 가장 중요한 부분이다.

# 하드웨어, 자료구조&알고리즘을 배우는 이유는 프로그램의 성능최적화를 이해하기 위한 내용이다.

# 절차지향, 객체지향이 왜 나왔냐

  • 절차지향은 이 프로그램은 어떤일을 하는가에 대한 의문

  • 객체지향은 현실세계에 존재하는 객체를 어떻게 모델링 할 것인가에 대한 의문

# 절차지향은 함수를 이용한 프로그래밍이다. 그렇다면 OOP(객체지향) 개념은 어디서 나온것인가?

  • 현실세계에 존재하는 객체 (사람, 동물, 식물 등등…)를 어떻게 컴퓨터 내에서 표현할 것인가에 대한 내용이다.

  • OOP는 객체를 이용해서 프로그래밍을 한다.

  • OOP의 3대 개념

1) encapsulation(캡슐화)

2) information hiding(정보은닉) : 캡슐화에 포함되는 개념이다. 파이썬은 정보은닉 개념을 제공하지 않는다.

3) polymorphism(다형성) : 3대 개념중 가장 중요한 개념이다. 상속을 활용한 구현

# 객체

  • 객체는 속성들로 이루어져있다.

  • 속성에는 두가지가 있다. 변수와 함수이다.

  • 객체는 결론적으로 관련있는 변수(=멤버)와 함수(=메소드)의 모음이다.

  • 프로그래밍의 최대 고민거리는 클래스 간의 관계를 어떻게 설정하냐이다.

  • 클래스는 붕어빵을 찍어내는 틀, 객체는 붕어빵

# 캡슐화

  • 관련있는 변수(데이터라고도 부를 수 있다)랑 함수를 하나의 단위로 묶는 것을 말한다.

  • 묶을때는 대부분 클래스로 묶는다.

# information hiding

  • 멤버에는 직접적으로 접근하지 못하도록 막는 것을 말한다.

  • 엑세스 function(함수)를 통해서만 멤버에 접근하여 연산을 수행할 수 있게 한다.

  • 이를 통해 사용자가 실수를 할 것(예를들어 입금을 -3000만원을 한다던지, 잔고보다 많이 인출을 시도할 경우)을 그 함수 안에서의 조건들을 걸어 이 실수를 방지할 수 있다.

  • 추상화는 내부구현과 인터페이스를 분리하는 것이다.

  • 예시1) Account 프록램 만들기

class Person:
    def __init__(self, name, money): 
        self.name=name
        self.money=money

## 위에 name과 money를 instance member 또는 객체 맴버라고 한다.
## 객체들이 가지는 고유한 값을 인스턴스 맴버라고 한다.
## self는 메모리 자체를 의미한다.
## 언더바 앞뒤로 있는것은 파이썬이 예약해놓은것이다. 
## 객체를 만들때 반드시 한번은 호출하기 때문에 데이터를 초기화 한다.
## __init__을 생성자(constructor)라고 하며 객체 만들 때 member(변수, data) 형식으로 초기화한다.

## 아래처럼 self같이 자기자신을 가리키는 것을 instance method 라고 한다.
## 객체가 가진 메서드이다.
    def get_money(self, money):
        self.money+=money

    def give_money(self, other, money):
        other.get_money(money)
        self.money-=money

## give_money 함수를 구현하는데 아래와 같이 하면 절대안된다 !!!!
## other.money+=money
## self.money-=money

    def __str__(self): 
        return '{} : {}'.format(self.name, self.money)

## 위에 __str__함수 이것도 예약함수이다
## 객체가 스트링으로 변환해서 반환해준다.
## 이 객체가 가지고 있는 스트링 함수로 변환해서 아래와 같은 문자열을 반환해준다.

상대객체와 상호작용을 할때 다시말해 변수를 변경했을때 내상태정보와 상대방의

상태정보가 바뀔때 이런식으로 상대방에 변수에 직접적으로 접근하면 안된다.

상대방의 데이터를 바꾸려면 상대방이 가지고 있는 메소드를 호출해서 변경해야 한다.

결론적으로 상대방의 객체와 상호작용할때 아래와 같이 해야 한다.

상대방이 가지고 있는 함수를 호출함으로써 바꿔줘야 한다.

다시말해 위에 other.get_money(money)처럼 함수를 호출해줘야 한다.

이러한 기법을 메세지 패싱(message passing)이라고 한다.

mark=Person('Mark',5000)
## 객체를 만들때는 인스턴스명 = 클래스()라고 하면된다.
greg=Person('greg',3000)

greg.give_money(mark,3000)
##어떤 객체의 매서드를 사용할때는 객체.메서드 형식으로 해주면된다.

print(mark)
print(greg)
Mark : 8000
greg : 0

[ 실행과정 ]

step1) 글로벌 프레임이 생성되고 그 안에는 Person 클래스 정보를 가리키는 공간이 생긴다.

step2) mark=Person(‘Mark’,5000) 가 실행되어 init 함수를 실행하는 프레임이 글로벌 프레임 위에 쌓이고 __init__함수를 통해 mark=Person(‘Mark’,5000)가 실행된다.

step3) init 함수를 실행하는 프레임이 사라지고 글로벌 프레임안에 mark 정보를 가리키는 공간이 생긴다. 동시에 Person instance라는 별도의 공간에 마크 인스턴스 공간이 생긴다.

step4) greg=Person(‘greg’,3000)가 실행되고 위와같은 과정이 겨쳐 그렉의 정보가 담긴 그렉 인스턴스 공간이 생긴다. 참고로 마크 인스턴스 공간과 아예 다른 공간에 저장된다.

step5) greg.give_money(mark,3000)가 실행되면 greg.give_money 함수를 실행하는 프레임이 글로벌 프레임 위에 쌓이고 mark,greg 인스턴스 공간을 참조하며 연산이 실행된다.

step6) 마크와 그렉의 퍼슨 인스턴스를 보여준다.

다시정리하면

메소드와 function은 메모리 공간상에는 어떻게 표현되는지 알아보면

위에 클래스를 선언하는 순간 메모리 공간에 클래스 정보와 그 안에 있는 함수 정보들이 담기게 된다. 여기서 함수는 뻥션이다.

greg=Person(‘greg’,3000)이라고 입력하는 순간 그렉이라는 객체의 메모리 공간이 생성된다.

그리고 거기 거기 안에는 네임과 에이지 공간 및 메소드 정보들이 있는(특정 정보를 가리키고 있는 공간을 / 메소드의 경우 클래스 정보와 그 안에 있는 함수 정보들이 담긴 공간에 해당되는 함수를 가리키게 된다.) 공간들이 만들어진다.

만약에 그렉.get money이나 give_money 등을 입력해서 실행하면 그 기능의 스텍프레임공간이 새로 생기고 그 안에서 연산이 실행된다.

논리적으로는 greg=Person(‘greg’,3000)을 선언하는 순간 그레그 객체의 정보 및 Person 클래스 내의 메소드 정보도 모두 갖고 있는 것이다.

# self와 init

  • 예시코드)
class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print(self.x + ' ' + foo)

a = A()

1) self : self는 객체의 인스턴스 그 자체를 의미한다. 대부분 객체지향 언어는 이걸 메소드에 안 보이게 전달하지만 파이썬에서 클래스의 메소드를 정의할 때는 self를 꼭 명시해하고 그 메소드를 불러올 때 self는 자동으로 전달된다.

2) init : __init__은 파이썬에서 쓰이는 생성자. 위의 코드에서 A()는 생성자 __init__에 어떤 파라미터도 넘기지 않고, 그 결과로 A타입의 객체를 생성해 이를 반환받는다. A(24, ‘Hello’)와 같이 쓰면 파라미터 2개를 받는 생성자가 필요한데 현재 __init__은 그 어떤 파라미터도 받지 않으니 exception이 발생합니다.