주식 알고리즘 만들기 - 5.2) 클래스 (__init__, self)
2022.10.10 - [Python] - 주식 알고리즘 만들기 - 5.1) 클래스
주식 알고리즘 만들기 - 5.1) 클래스
2022.10.09 - [Python] - 주식 알고리즘 만들기 - 4. 함수와 모듈 (모듈) 주식 알고리즘 만들기 - 4. 함수와 모듈 (모듈) 2022.10.09 - [Python] - 주식 알고리즘 만들기 - 4. 함수와 모듈 (함수) 주식 알고리즘..
jiain.tistory.com
출처 : https://wikidocs.net/1740
2) 클래스 생성자
6.1절에서 파이썬의 클래스에 대해 배웠습니다. 지금까지 배운 내용을 정리해보면 다음과 같습니다. - 파이썬의 클래스를 이용하면 프로그래머가 원하는 새로운 타입을 만들 수 ...
wikidocs.net
우리는 이전 포스트에서 파이썬의 클래스에 대해 배웠습니다. 배운 내용을 정리해보면 다음과 같습니다.
- 파이썬의 클래스를 이용하면 나만의 원하는 새로운 타입을 만들 수 있다.
- 생성된 타입은 데이터와 데이터를 처리하는 메서드(함수)로 구성돼 있다.
이번에도 이전 포스트에 만든 클래스를 활용해서 클래스를 심층적으로 배워 보도록 하겠습니다.
1) __init__ (self)
__init__ () 함수를 쉽게 설명하자면, 그림처럼 폴더가 생성되는 동시에 파일이 생성하는 개념과 같습니다.
이번 파트에서는 __init__ 개념을 코드로 배워 보도록 하겠습니다.
class Stock_total_info:
def stock_info(self, name, pre_price, cur_price, date):
self.name = name
self.pre_price = pre_price
self.cur_price = cur_price
self.date = date
def print_info(self):
print("--------------------")
print("종목명: ", self.name)
print("전일가: ", self.pre_price)
print("현재가: ", self.cur_price)
print("날짜: ", self.date)
print("--------------------")
관심종목1 = Stock_total_info()
관심종목1.stock_info("엔씨소프트",350500,349000,"2022-10-07")
관심종목1.print_info()
지금까지 우리는 인스턴스를 생성하고 난 후에 데이터를 입력했습니다. 내부에 부품이 없이 소나타의 외관만 만들어서 그 안에 부품을 넣은 셈이죠. 이 순서가 맞을까요? 부품을 넣으면서 소나타를 만드는 방법은 없는 걸까요?
아니요, 있습니다. 바로 파이썬 클래스에는 인스턴스 생성과 동시에 자동으로 호출되는 메서드인 생성자가 존재합니다.
파이썬에서는 __init__ (self)와 같은 이름의 메서드를 생성자라고 하며, 파이썬 클래스에서__로 시작하는 함수는 모두 특별한 메서드를 의미합니다. 무슨말인지 이해가 안가시죠? 직접 프로그램을 짜보면서 이해하도록 합시다.
class MyClass:
def __init__(self):
print("객체가 생성됐습니다.")
위코드는 __init__(self) 메서드를 가진 MyClass 클래스를 정의한 것입니다. 앞서 설명한 것처럼 생성자의 첫 번째 인자도 항상 self여야 합니다. 생성자 내부에는 print 문을 통해 간단한 메시지를 출력했습니다. MyClass라는 클래스를 정의했으니 이제 이 클래스의 인스턴스를 생성해보겠습니다.
inst1 = MyClass()
객체가 생성됐습니다.
위 코드를 보면 인스턴스를 생성하자마자 화면에 메시지가 출력되는 것을 확인할 수 있습니다. 이는 인스턴스가 생성되는 시점에 자동으로 생성자인 __init__(self) 메서드가 호출됐기 때문입니다. 참고로 init이라는 영어 단어는 ‘초기화하다’라는 뜻이 있는 initialize의 약어입니다. 자 이제 우리는 인스턴스 생성 동시에 데이터를 넣을 수 있다는 걸 알게된 셈이죠.
class Stock_total_info:
def __init__(self, name, pre_price, cur_price, date):
self.name = name
self.pre_price = pre_price
self.cur_price = cur_price
self.date = date
def print_info(self):
print("--------------------")
print("종목명: ", self.name)
print("전일가: ", self.pre_price)
print("현재가: ", self.cur_price)
print("날짜: ", self.date)
print("--------------------")
앞서 배운 __init__ 메서드 함수를 활용해서 코드를 다시 작성을 했습니다. 이제 관심종목1 인스턴스를 생성하면 되는데
관심종목1.Stock_total_info() 라고 쓰면 인스턴스가 생성이 될까요?
TypeError: __init__() missing 4 required positional arguments: 'name', 'pre_price', 'cur_price', and 'date'
이제 우리는 이전에 번거롭게 stock_info 메서드 함수를 불러와서 입력해야했던 데이터 변수를 인스턴스 생성과 동시에 입력할 수 있게 됐습니다.
관심종목1 = Stock_total_info("엔씨소프트",350500,349000,"2022-10-07")
관심종목1.print_info()
--------------------
종목명: 엔씨소프트
전일가: 350500
현재가: 349000
날짜: 2022-10-07
--------------------
어떤가요? 클래스를 이용하니 인스턴스생성과 데이터 입력을 동시에 할 수 있으니 엄청 편리한거 같지 않나요?
알면 알수록 재밌는 클래스 입니다.
2) self 이해하기
앞에서 클래스 내에 정의된 함수를 메서드라고 부른다고 했습니다. 그리고 메서드의 첫 번째 인자는 항상 self여야 한다고 외웠습니다. 하지만 메서드의 첫 번째 인자가 항상 self여야 한다는 것은 사실 틀린 말입니다. 이게 무슨 뚱딴지같은 소리죠? 하시는 분이 있을지 모르니 self의 정체를 확실히 이해하기 위해서 간단한 클래스를 만들어 보겠습니다.
먼저 다음과 같이 두 개의 메서드가 정의된 Stock 클래스를 만들어 봅시다.
class Stock:
def naver():
print("naver")
def daum(self):
print("daum")
여기서 눈여겨봐야 할 점은 naver() 메서드의 첫 번째 인자가 self가 아님에도 클래스를 정의할 때 에러가 발생하지 않는다는 점입니다. 일단 클래스를 정의했으니 해당 클래스에 대한 인스턴스를 생성해보겠습니다.
webtoon = Stock()
webtoon.daum()
daum
위 코드에서 메서드를 호출한 결과를 보면 화면에 정상적으로 'daum'가 출력된 것을 볼 수 있습니다. 그렇다면 naver 메서드처럼 메서드를 정의할 때부터 아무 인자도 없는 경우에는 어떻게 될까요?
그렇습니다. 여러분이 예상 했던 것처럼 self 인자가 없기 때문에 오류가 발생했다고 볼 수 있죠.
오류 메시지를 살펴보면 "naver()는 인자가 없지만 하나를 받았다"라고 설명하고 있습니다.
무슨의미 일까요? 이는 앞서 설명한 것처럼 파이썬 메서드의 첫 번째 인자로 항상 인스턴스가 전달되기 때문에 발생하는 문제입니다. 아직 우리는 self를 이해하기에는 부족하다고 생각이 듭니다 그래서 이번엔 id를 이용해서 self의 정체를 조금더 파헤치도록 하겠습니다.
class Stock:
def naver():
print("naver")
def daum(self):
print(id(self))
print("daum")
webtoon = Stock()
webtoon.daum()
140141392198992
daum
위코드를 보면 이상한 점이 있습니다. 우리는 self의 주소를 출력했는데 이게 webtoon 인스턴스의 주소와 일치하는 놀라운 현상을 발견했죠. 즉, 클래스 내에 정의된 self는 클래스 인스턴스임을 알 수 있습니다. 이해되시나요?
그러면 이제는 우리는 인스턴스를 변수로 넣을 수있다는 놀라운 사실을 알게 된거죠
자 우리는 헷갈립니다.
클래스.메서드()
인스턴스.메서드()
둘다 본적이 있을거에요
이 차이가 멀까요?
저는 webtoon, news라는 인스턴스를 생성했습니다. 다음 코드로 비교를 해보시기 바랍니다.
결론부터 말씀드리면 둘 사이에는 아무런 차이가 없습니다. 한가지 표현 방식의 차이죠.
self라는 변수를 사용한 메서드는 클래스.메서드()가 불가능하고 클래스.메서드(인스턴스)를 꼭 넣어줘야합니다.
self라는 변수를 사용하지 않은 메서드는 클래스.메서드() 가능하고 인스턴스.메서드가 불가능합니다.
이해가 가시나요?
출처 :