from PIL import Image
import requests
클래스 공부 2단계
init()
-
STOOOP를 다시 복습
= 'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true'
url1 = 'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop2.png?raw=true' url2
class STOOOP:
= '학교폭력!'
title = url1
url = '멈춰~~~~'
end def stop(self):
print(self.title)
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print(self.end)
=STOOOP() # STOOOP라는 클래스에서 s1이라는 인스턴스를 만드는 과정 s1
s1.title, s1.url, s1.end
('학교폭력!',
'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true',
'멈춰~~~~')
s1.stop()
학교폭력!
멈춰~~~~
-
왜 s1의 default title이 항상 “학교폭력”이어야 하는가? => __init__
의 개발
-
성능4: __init__()
함수를 이용하여 “클래스->인스턴스”의 시점에서 수행하는 일련의 동작들을 묶어서 수행할 수 있음
class STOOOP:
#title = '학교폭력!'
= url1
url = '멈춰~~~~'
end def __init__(self,title):
self.title = title
def stop(self):
print(self.title)
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print(self.end)
-
잘못된사용
=STOOOP() # 이 시점에서 _init_ 이 수행된다! s1
TypeError: __init__() missing 1 required positional argument: 'title'
-
올바른사용
=STOOOP("수강신청") # 이 시점에서 _init_ 이 수행된다! s1
s1.title, s1.url, s1.end
('수강신청',
'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true',
'멈춰~~~~')
s1.stop()
수강신청
멈춰~~~~
-
잘못된 사용에서 에러가 발생한 이유?
TypeError: __init__() missing 1 required positional argument: 'title'
- s1 = STOOOP() 가 실행되는 순간
__init__()
이 내부적으로 실행된다. - 그런데
__init__()
의 첫번째 입력은self
는 입력안해도 무방했음. (현재는 메소드와 함수를 구분하는 문법으로 self를 이해하면 된다.) 그런데 두번째 입력은 title은 입력을 해야했음. - 그런데 title을 입력하지 않아서 발생하는 에러
-
__init__(self, arg1, arg2, ...)
함수에 대하여 - 엄청나게 특별해 보이지만 사실 몇가지 특별한 점을 제외하고는 어떠한 마법도 없는 함수이다. - 특별한점1: 첫번째 입력으로 반드시 self를 넣어야함. (이거 ㄴ사실 클래스 내의 메소드 거의 다 그러하다.) - 특별한점2: 클래스에서 인스턴스를 만드는 시점에 자동으로 생성됨 - 특별한점3: __init__(self, arg1, arg2, ...)
의 입력중 self 이외의 입력들은 “클래스->인스턴스”의 시점에서 “인스턴스이름 = 클래스이름(arg1,arg2,…)”와 같이 사용한다. (이 예제의 경우 STOOOP(title)와 같이 사용해야함)
-
title 이 디폴트로 들어가는 상황도 불편했지만, title을 명시적으로 넣지 않으면 에러가 발생하는 것도 불편하다?
class STOOOP:
#title = '학교폭력!'
= url1
url = '멈춰~~~~'
end def __init__(self,title=None):
self.title = title
def stop(self):
print(self.title)
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print(self.end)
=STOOOP()
s2=STOOOP('KOSPI하락') s3
s2.stop()
None
멈춰~~~~
- 제목이 없으면 없는데로
s3.stop()
KOSPI하락
멈춰~~~~
self의 의미
-
이전 예제를 다시 복습
class Klass4:
= 1
n = 'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true'
url def show(self):
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print("당신은 이 이미지를 {}번 보았습니다".format(self.n))
self.n = self.n+1
=Klass4() k4
k4.show()
당신은 이 이미지를 5번 보았습니다
-
위의 예제는 아래와 같이 구현할 수도 있다.
class Klass4:
= 1
n = 'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true'
url def show(self):
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print("당신은 이 이미지를 {}번 보았습니다".format(self.n))
# self.n = self.n+1
=Klass4() k4
k4.n
1
k4.show()
당신은 이 이미지를 1번 보았습니다
= k4.n +1 k4.n
k4.show()
당신은 이 이미지를 2번 보았습니다
= k4.n + 1 k4.n
k4.show()
당신은 이 이미지를 3번 보았습니다
-
결국에는 k4.n = k4.n +1
의 기능을 구현하여 넣은 것이 self.n = slef.n + 1
이다.
-
따라서 self는 k4에 대응한다. 즉 self는 인스턴스의 이름에 대응한다. 우리가 하고 싶은 것은 클래스를 선언하는 시점에 인스턴스가 생성된 이후의 시점에 대한 어떠한 동작들을 정의하고 싶음. 그런데 클래스를 설계하는 시점에서는 인스턴스의 이름이 정해지지 않았으므로 (아직 인스턴스가 태어나지도 않음) 이러한 동작들을 정의하기 불편하다. 그래서 클래스를 설계하는 시점에서 그 클래스로부터 만들어지는 인스턴스는 그냥 self라는 가칭으로 부른다. (굳이 비유하면 self는 인스턴스의 태명같은것..)
# 여기서 말하는 인스턴스는 정확하게 무엇인가? 그냥.. self, k4 와 같이 이름을 말하는건가?
-
self의 의미는 (이후에 만들어질) 인스턴스의 이름이다. (즉 self는 인스턴스의 태명같은 것임)
파이썬의 비밀1
탐구 : 인스턴스의 자료형이 뭔지 탐구하자!
-
아래의 두 클래스를 비교해보자
class STOOOP:
#title = '학교폭력!'
= url1
url = '멈춰~~~~'
end def __init__(self,title=None):
self.title = title
def stop(self):
print(self.title)
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print(self.end)
class Klass4:
= 1
n = 'https://github.com/guebin/IP2022/blob/master/_notebooks/2022-05-07-stop1.jpeg?raw=true'
url def show(self):
open(Image.io.BytesIO(requests.get(self.url).content)))
display(Image.print("당신은 이 이미지를 {}번 보았습니다".format(self.n))
#self.n = self.n+1
-
인스턴스를 생성해보자.
=Klass4()
k4=STOOOP() s1
-
타입을 알아보자.
k4?
Type: Klass4 String form: <__main__.Klass4 object at 0x7fc527259890> Docstring: <no docstring>
s1?
Type: STOOOP String form: <__main__.STOOOP object at 0x7fc527259bd0> Docstring: <no docstring>
-
??? 타입은 자료형, 즉 int, float, list 이런 것 아니었나?
=[1,2,3]
a a?
Type: list String form: [1, 2, 3] Length: 3 Docstring: Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
=3.14
a a?
Type: float String form: 3.14 Docstring: Convert a string or number to a floating point number, if possible.
-
그런데 지금 k4, s1의 타입은 Klass4, STOOOP이다.
- 가설1: 사실 파이썬 내부에 Klass4, STOOOP 이라는 자료형이 있었다. 그런데 내가 만든 k4, s1이 우연히 그 자료형을 따르는 것 (억지스러움)
class SoWhatTV:
='어쩔티비' title
=SoWhatTV()
a a?
Type: SoWhatTV String form: <__main__.SoWhatTV object at 0x7fc5259e6810> Docstring: <no docstring>
# 잉.. 우연히 자료형이 sowhattv가 잇을거 같진 않은데. .가설1이 맞진 않는거 같다
- 가설2: type이 list인것은 사실 list라는 클래스에서 생긴 인스턴스이다. -> 리스트자료형을 찍어낼 수 있는 어떠한 클래스가 내부적으로 존재할 것이다.
깨달음1
-
가설2가 맞다면 아래는 모두 어딘가에서 찍혀진 인스턴스이다.
=[1,2,3]
a a?
Type: list String form: [1, 2, 3] Length: 3 Docstring: Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
='1'
a a?
Type: str String form: 1 Length: 1 Docstring: str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
-
그리고 위의 a=[1,2,3]
과 같은 것들은 모두 “클래스->인스턴스”에 해당하는 과정이었음
깨달음2
-
생각해보니까 아래와 같이 list를 선언하는 방식도 있었음
=list()
a a
[]
- list라는 이름의 클래스에서 a라는 인스턴스를 찍어내는 문법이다.
-
아래도 가능
=list((1,2,3))
a a?
Type: list String form: [1, 2, 3] Length: 3 Docstring: Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
-
list라는 이름의 클래스에서 a라는 인스턴스를 찍어내는 문법. 여기에서 (1,2,3)은 __init__()
의 입력이다.
깨달음3
-
각 자료형마다 특수한 기능들이 있다.
=[1,2,3]
a a
[1, 2, 3]
-
a.
+ tab 을 하면 append, clear 등등이 나온다.
-
이러한 기능은 지금까지 우리가 “list자료형 특수기능들” 이라고 부르면서 사용했다. 그런데 a가 list클래스에서 생성된 인스턴스라는 관점에서 보면 이러한 기능들은 list클래스에서 정의된 메소드라고 볼 수 있다.
깨달음4
-
a.f()
는 f(a)
로 해석가능하다고 했다. 이 해석에 따르면 메소드의 첫번째 입력은 메소드가 소속된 인스턴스라고 해석할 수 있다.
-
동일한 논리로 아래의 코드는 stop()의 입력에서 s1을 넣는다는 의미이다.
#s1자체가 입력이 되는것 s1.stop()
None
멈춰~~~~
숙제
아래의 조건에 맞는 클래스를 생성하라.
[‘가위’,‘바위’]와 같은 리스트를 입력으로 받아 인스턴스를 생성한다.
위의 리스트에서 하나의 값을 뽑는 메소드 f를 가지고 있다.
# # 너무 헷 갈ㄹ ㅕ ..
# # 사용예시
# a = Klass(['가위','바위'])
# a.f() # 가위가 1/2 바위가 1/2의 확률로 출력
# b = Klass(['가위','바위','보'])
# b.f() # 가위, 바위, 보가 1/3의 확률로 출력