객체지향 프로그래밍 ①¶
다음 어휘를 익혀보자.¶
클래스(class)
python이 새로운 자료형을 만들도록 한다.
객체(object)
가장 기초적인 자료형 또는 어떤 자료형의 인스턴스를 의미한다.
def
함수를 정의하는 방법
self
클래스의 함수 안에서 사용.
접근한 인스턴스 / 객체를 가리키는 변수
상속(inheritance)
한 클래스가 다른 클래스의 특성(trait)을 자식이 부모에게 물려받듯 상속한다는 개념이다.
합성(composition)
한 클래스를 다른 클래스의 일부로 합성할 수 있다는 개념이다.
속성(attribute)
클래스가 가진 속성(property)으로, 보통 합성으로 생기고 변수 형태이다.
is-a
'연어'is-a'물고기'처럼 한 항목이 다른 항목을 상속했다는 뜻의 문구이다.
has-a
'연어'has-a'입'처럼 한 항모이 다른 항목을 합성했거나 어떤 특성(trait)을 가졌다는 뜻의 문구이다.
class X(Y):
"X 클래스라는 Y의 일종(X is-a Y)을 만든다"
class X(object):
def __init__(self, J)
"X 클래스는 self와 J 매개변수를 받는
__init__
을 가졌다."(X 클래스 has-a
__init__
)
class X(object):
def M(self, J)
"X 클래스는 self와 J 매개변수를 받는 이름이 M인 함수를 가졌다."
(class X has-a 이름이 M인 함수)
foo = X()
"foo 변수를 X 클래스의 인스턴스 하나로 정한다."
foo.M(J)
"foo 변수에서 M 함수를 받아 self, J 매개변수를 넣어 호출한다."
foo.K = Q
"foo 변수에서 K 속성을 받아 Q 값으로 정한다."
위의 X, Y, M, J, K, Q, foo가 있는 곳마다 빈 공간이 있는 것처럼 생각하고 치환하여 general하게 적용하자!¶
다음 코드를 리뷰해보자.¶
아래 코드는 클래스의 개념을 묻고 답하는 테스트를 해주는 스크립트이다.
전반적인 코드의 큰 틀은 다음과 같다.
- 클래스를 만드는 다양한 형태를 문자로 일반화 시킨 코드와 그 코드 해석을 딕트로 만든다.
- 코드가 문제가 될지, 코드 해석이 문제가 될지 선택할 수 있는 로직을 if문을 사용하여 추가.
- 일반화된 특수 문자를 단어로 교체하기 위해 단어 불러오기
- 특수문자를 단어로 바꿔주는 convert 함수 작성
- 실행 시 돌아가는 부분을 작성
- 무한 loop(while True)를 활용
# -*- coding: utf-8 -*-
import random
from urllib import request
from urllib.request import *
import sys
# key = class를 작성하는 코드 / value = 코드를 해석
## 이를 사전으로 만든다.
PHRASES = {
"class %%%(%%%):":
"%%% 클래스라는 %%%의 일종을 만든다.", # is-a
"class %%%(object):\n\tdef __init__(self, ***)":
"%%% 클래스는 self와 *** 매개변수를 받는 __init__을 가졌다.", # has-a
"class %%%(object):\n\tdef ***(self, @@@)":
"%%% 클래스는 self와 @@@ 매개변수를 받는 이름이 ***인 함수를 가졌다.", # has-a
"*** = %%%()":
"*** 변수를 %%% 클래스의 인스턴스 하나로 정한다.",
"***.***(@@@)":
"*** 변수에서 *** 함수를 받아 self, @@@ 매개변수를 넣어 호출한다.",
"***.*** = '***'":
"*** 변수에서 *** 속성을 받아 *** 값으로 정한다."
}
# 스크립트를 실행할때, argv가 두개 이고, 두 번째 argv가 "한국어"이면 코드 해석이 문제로 나온다.
## argv 없이 스크립트를 그냥 실행하거나, 3개 이상이면 코드가 문제가 코드해석을 답으로 써야 한다.
if len(sys.argv) == 2 and sys.argv[1] == "한국어":
PHRASES_FIRST = True
else:
PHRASES_FIRST = False
WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []
# 웹사이트에서 단어를 불러온다.
for word in urlopen(WORD_URL).readlines():
# 따옴표 안의 \n와 같은 탈출문자열 코드를 없애준다. 그래서 단어만으로 리스트를 만들 수 있다.
WORDS.append(word.strip())
def convert(snippet, phrase):
"""class dict 안 기호('@@@' 등)를 단어로 변경"""
# snippet에 "%%%"가 들어 있는 개수 만큼 WORDS list에서 단어를 랜덤하게 뽑고, 단어의 첫 글자를 대문자로 바꿔라.
## 그리고 그것을 list로 만들어라.
class_names = [w.capitalize() for w in random.sample(WORDS, snippet.count("%%%"))]
# snippet에 "***"가 들어 있는 개수 만큼 WORDS list에서 단어를 랜덤하게 뽑아라.
other_names = random.sample(WORDS, snippet.count("***"))
results = []
param_names = []
for i in range(0, snippet.count("@@@")):
# param_count는 1, 2, 3 중 랜덤으로 뽑아라.
param_count = random.randint(1,3)
# 위에서 랜덤으로 정해진 param_count 개수 만큼 단어를 무작위로 뽑아라.
## param_names 리스트에 추가해라.
param_names.append(', '.join(random.sample(WORDS, param_count)))
for sentence in snippet, phrase:
# sesntence 리스트를 첫 원소부터 마지막 원소까지 자르면서 복사해라.(슬라이싱하면서 리스트를 복사)
result = sentence[:]
# 가짜 클래스 이름
for word in class_names:
# "%%%"를 word로
## result.replace(old, new[, count]) -> str
result = result.replace("%%%", "{}".format(word), 1)
# 가짜 나머지 이름
for word in other_names:
result = result.replace("***", "{}".format(word), 1)
# 가짜 매개변수 목록
for word in param_names:
result = result.replace("@@@", "{}".format(word), 1)
results.append(result)
return(results)
# Ctrl-D를 누를 떄까지 계속한다.
## input 생성
try:
input = raw_input
except NameError:
pass
try:
while True:
snippets = list(PHRASES.keys())
# random.shuffle(리스트) 리스트가 들어가야 하므로 키값을 리스트로 변경시켜 주었다.
random.shuffle(snippets)
for snippet in snippets:
phrase = PHRASES[snippet]
question, answer = convert(snippet, phrase)
# 만약 PHRASES_FIRST = True라면, 답과 질문을 바꿔주면 된다.
if PHRASES_FIRST:
question, answer = answer, question
print(question)
input(">")
print("답: {}\n\n".format(answer))
except EOFError:
print("\nBye")
urllib
모듈 안의 urlopen
을 python-3에서 실행시키려면 아래의 request
모듈을 모두 실행시켜야 한다.¶
urlopen
은 python-3 부터 request에 포함되므로 아래와 같이 request를 모두 import 해줘야 한다!
from urllib import request
from urllib.request import *
word 정리¶
WORDS = []
for word in urlopen(WORD_URL).readlines():
print(word)
print(word.strip())
WORDS.append(word.strip())
print(WORDS)
위 코드의 output은 위와 같다.
.strip()
의 역할은 위에서 보듯이\n
와 같은 탈출문자열을 벗겨주는 기능을 한다.
터미널에서 실행은 다음과 같다.¶
python oop_test.py
코드를 보고 코드 해석
python oop_test.py 한국어
코드 해석을 보고 코드 작성