sswu

파이썬 기말 정리

hi._.0seon 2021. 11. 15. 18:31
반응형

1. 딕셔너리

  • 값을 저장하는 자료구조
  • 값과 관련된 키도 저장된다.
  • 순서가 없다.

Key : Value

Key

  • 반드시 불변 객체여야 한다.
    -> 문자열, 숫자, 튜플 ,, (리스트는 X)
  • 한 딕셔너리 내에서 유일한 키를 가져야 한다.
  • key가 중복되면 기존 값을 덮어쓰기 한다.

Value

  • 어떤 타입도 올 수 있다.
  • 딕셔너리도 올 수 있다.

1.1 딕셔너리 연산

항목 탐색

capitals = {"Korea": "Seoul", "USA": "Washington"}

1)
print(capitals["France"])
--> Key Error

2)
print(capitals.get("France", "해당 키가 없습니다."))
// 프로그램 오류로 중단되지 않게 하려면 이렇게 해야 함

or

if "France" in capitals:
  • dict에 없는 키 값을 가져오려 하면 Error
  • dict.get()이나 in 연산자로 사용
  • 2) get()은 key가 없으면 None 반환 / 두번째 인자가 있으면 인자를 반환
  • in 연산자는 key를 대상으로 찾음

항목 추가

capitals = {"Korea": "Seoul", "USA": "Washington"}

capitals["UK"] = "London"

print(capitals)
# {"Korea": "Seoul", "USA": "Washington", "UK": "London"}
  • 새로운 키를 가지고 대입하면 새 항목이 추가된다.

딕셔너리 전체 추가/변경 - update({})

capitals = {"Korea": "Seoul", "USA": "Washington"}

capitals.update({"Korea": "Busan", "France": "Paris", "Germany": "Berlin"})

# {"Korea": "Busan",
# "USA": "Washington",
# "France": "Paris", 
# "Germany": "Berlin"}
  • update 메소드 사용하여 새로운 딕셔너리를 기존 딕셔너리에 추가하거나 수정
  • 이미 있는 키는 value만 update된다.

항목 삭제하기 - dict.pop("UK") / dict.clear()

city = capitals.pop("UK")

# 에러 발생 안하게 하려면..
if "UK" in capitals:
	capitals.pop("UK")

# 전체 삭제
capitals.clear()
  • 주어진 키를 가진 항목이 없으면 KeyError 가 발생한다.
  • 전체 삭제 = clear()

항목 방문

for key in capitals:
	print(key, ":", capitals[key])
    
for key, value in capitals.items(): # tuple 리스트를 리턴(List(tuple))
	print(key, ":", value)
  • dict.items()는 튜플들의 리스트를 리턴

키 or 값만 가져오기

capitals.keys()
# ['Korea', 'USA', 'UK']

capitals.values()
# ['Seoul', 'Washington', 'London']

if user == 3:
	pass # 나중에 구현

딕셔너리 메소드

d = dict() 공백 딕셔너리 생성
d = {k1: v1, k2:v2, ..} 초기값으로 딕셔너리 생성
len(d) 딕셔너리에 저장된 항목 갯수 반환
k in d k 가 딕셔너리 d 안에 있는 키인지 반환
k not in d k가 딕셔너리 d 안에 없으면 True
d[key] = value 딕셔너리에 키와 값을 저장
d.get(key, default = None) 주어진 키를 가지고 값을 찾는다. 없으면 default 값이 반환된다.
d.pop(key) 항목 삭제
d.values() 딕셔너리 안의 모든 값의 (시퀀스)리스트 반환
d.keys() 딕셔너리 안의 모든 키의 시퀀스(리스트)를 반환한다.
d.items() 딕셔너리 안의 모든 (key, value)를 리스트 형태로 반환

딕셔너리 복사하기

  • dict2 = dict1.copy()
  • dict2 = dict1
  • dict2 = dict(dict1)
  • dict2 = dict(dict1.items())

1.2 딕셔너리 함축

딕셔너리 함축

dic = { i: str(i) for i in [1,2,3,4,5]}
#{1: "1", 2: "2", 3:"3", 4:"4", 5: "5"}

dic1 = {"One": 1, "Two": 2, "Three": 3}
dic2 = {n:w for w,n in dic1.items()}
# dic2 {1: "One", 2: "Two", 3: "Three"}

출력 수식에는 { key : 값 } 수식 형태로 되어야 한다.

 

ex) 학생 성적 처리

3가지 과목에서의 각 학생의 성적 평균 구하기

score_dic = {'Kim': [99, 83, 95],
              'Lee': [68, 45, 78],
              'Choi': [25, 56, 69]}

result = {k: (sum(l) / len(l)) for k, l in score_dic.items()}
# {'Kim': 92.33333333333333, 'Lee': 63.666666666666664, 'Choi': 50.0}

 

1.3 단어 카운터 만들기

from collections import Counter

text_data = "Create the highest, ,,,,you become what you believe"

Counter(text_data.split())
# Counter({'you': 2, 'Create': 1, ,,,})

2. 문자열

아나콘다 모듈: BeautifulSoup, csv, json, nltk

Java, Python : Unicode

C++ : ASCII

문자열 내장 함수

chr(97) = 'a' 정수 -> 문자로 변환
ord('a') = 97 문자 -> 정수로 변환
ascii 문자열에서 아스키면 아스키 값, 이외의 값은 유니코드로 바꿔주는 함수
len( ) 문자열의 길이를 반환
str( ) 객체의 문자열 표현을 반환

2.1 문자열 슬라이싱

s = "Monty Python"
s[6:10]
# "Pyth"

s[:2] # "Mo"

s[4:] # "y Python"

s[:] # "Monty Python"

문자열은 불변 객체이다.

-> 수정할 수 없다. (word[0] ='a' 불가능)

word = "abcd"

word = "A" + word[1:] # Abcd

새로운 메모리를 가리키게 된다.

  • 문자열도 시퀀스 자료형

text[ start_index : end_index + 1 ]

2.2 문자열 연산, 메소드

==, != , <, > 연산자를 사용할 수 있다.

문자열 메소드

s.capitalize() 맨 앞글자만 대문자로 변환해준다.
s.lower() 전체를 소문자로 변환한 값 리턴
s.upper() 전체를 대문자로 변환한 값 리턴
s.endswith(".py") 문자열이 .py 로 끝나는지
s.startswith("ab") 문자열이 ab로 시작하는지
s.find(".kr") ".kr"이 들어있는지 찾아서 .kr이 있는 위치를 리턴한다.
s.rfind("let") 오른쪽부터 찾아서 처음에 나오는 문자열 위치를 리턴한다
s.count(".")
s.count(".", 0, 5)
문자열에 포함된 . 의 갯수를 세서 반환
index 0~4 범위에서 찾음
s.isdigit() 문자열이 숫자인지
s.isalpha() 문자열이 알파벳인지
"abc".islower() 문자열이 소문자인지
s.strip()
s.lstrip()
s.rstrip()
앞, 뒤에 있는 공백을 제거한다.
왼쪽에 있는 공백 제거
오른쪽 끝에 있는 공백 제거
- 문자열이 주어지는 경우 그 문자를 제거한다.
s.split()
s.split(",")
공백문자를 기준으로 문자열을 분리하여 리스트에 넣는다.
주어진 문자를 구분자로 하여 문자열을 분리해 리스트 형태로 반환
(list(문자열) -> 한글자씩 쪼개진 리스트가 된다)
",".join(["apple", "grape"])
-> "apple,grape"
주어진 문자열을 맨 앞 문자열을 가지고 붙인다.
s.isspace() 공백문자인지 체크 (' ', \n, \t..)

3. 객체와 클래스

파이썬은 객체지향을 지원하긴 하지만 완전히 구현한 언어는 아니다. OOP로 완벽한 언어는 아님

  • 객체 지향 프로그래밍에서는 서로 관련 있는 데이터와 함수를 묶어서 객체로 만들고 이들 객체들이 모여서 하나의 프로그램이 된다.
  • 객체지향: data(object)부터 생각하는 Bottom-Up(상향식)
  • 함수형: 기능부터 생각하는 Top-down(하향식)
  • 절차지향과 객체 지향
    • 절차지향
      프로시저 기반 프로그래밍 방법
      - 작은 SW, 실시간 시스템에 적합
    • 객체지향
      데이터와 함수를 하나의 덩어리로 묶어서 생각하는 방법
      - 큰 시스템에 적합, 재사용성이 높다.

3.1 객체지향 3대 특성 PIE

Polymorphism

  • 다형성
  • 오버라이딩 된 메서드가 다형성을 띈다고 한다.
  • 클래스 상속 관계를 갖는 클래스의 객체 중 오버라이딩 된 메서드를 호출하면 그 객체에 타입에 맞는 메서드가 호출된다.

Encapsulation

  • 캡슐화
  • class = data + behavior(func)
    data를 가려서 보이지 않게 하고, func(사용법)만 밖에 보이게 한다.
  • 공용 인터페이스만 제공하고 구현 세부 사항을 감추는 것이다.
  • struct 는 data만 가진다.

Inheritance

  • 상속
  • is-a 관계를 상속 관계라고 한다.
  • 기존 코드를 재사용한다. 기존 클래스를 바탕으로 새로운 클래스를 정의한다.
  • 클래스 계층 구조가 나타난다.

파이썬에서는 모든 것이 객체이다.

파이썬에서는 모든 것이 객체로 구현된다. 정수도 객체, 문자열도 객체, 리스트도 객체이다.

 

3.2 클래스 작성하기

class 클래스이름:
    def __init__(self, ..):
        self.count = 0
    def func1(self, ..):
        pass
  • python 클래스의 모든 메소드는 제일 앞에 self가 온다.
  • C++, Java는 this가 넘어가긴 하는데, 숨어서 넘어간다.
    this: C++(포인터), Java(this = 레퍼런스 객체)
  • python은 변수 선언 시 자료형을 명시적으로 선언하지 않음(변수 선언 명시적으로 안함)
  • __init__ 안에서 하는 self.count 형식으로 멤버변수를 선언한다.

3.3 객체 생성

객체 생성

  • C++
    • 일반 객체는 스택 영역에 메모리 잡힘
    • new 로 생성한 객체는 heap 영역에 들어감
  • Java
    • class 객체는 무조건 heap 영역에 잡힘
    • 모든 클래스 객체는 new 로 생성
  • Python
    • Java같은 형태
  • __init__은 객체 생성시 자동으로 호출되는 생성자이다.
  • 멤버변수 선언 시 self.을 붙이지 않으면 지역변수가 된다.
  • 멤버 변수/메소드명 앞에 __를 붙이면 private 변수가 된다
    (외부에서 클래스 멤버 변수에 직접 접근하는 것은 정보은닉에 위배된다.)
  • privte 인스턴스 변수는 클래스 내부에서만 접근할 수 있다.

3.4 객체 참조

  • 파이썬에서 변수는 실제로 객체를 저장하지 않는다. 변수는 단지 객체의 메모리 주소를 저장한다.
  • 객체 자체는 메모리의 다른 곳에 생성된다.

3.5 is, is not

  • 2개의 변수가 동일한 객체를 참조하고 있는지를 검사하는 연산자 = is, is not
    주소를 비교한다.
  • s is t 와 s == t 는 같음
  • 내용이 같아도, 주소가 다르면 다른 객체
  • 기본 데이터타입들은 == 연산자에 대해 정의되어있으므로 값을 비교한다.
  • a = Television(10, 11)
    b = Television(10, 11)
    
    a == b
    # False
    
    a is b
    # False
    
    a is not b
    # True

3.6 None

  • 변수가 현재 아무것도 가리키고 있지 않다면 None 으로 설정하는 것이 좋다.
  • 아무것도 참조하고 있지 않다는 것을 나타내는 특별한 값.

3.7 가변 객체를 함수로 전달

  • 불변 객체는 함수로 전달되면 함수 안에서 변경이 일어나도 밖에서는 변경되지 않는다.
  • 가변 객체는 함수 내에서 변경되면 객체의 내용이 변경된다.

3.8 클래스 변수

class Television:
	serial = 0 # class 변수
    
    def __init__(self):
    	Television.serial += 1
  • 클래스 변수는 생성자가 아니라 클래스 안에 선언한다.
  • 클래스 변수에 접근할 때는 클래스명.변수 로 접근한다.
  • 객체명.클래스변수로 접근하는 것도 가능하지만 좋은 것은 아니다.
  • 상수는 흔히 클래스 변수로 정의된다.
  • Monster.WEAK -> 따로 상수 문법 없음
  • C++ => const
  • Java -> static(클래스 변수) final (상수)

3.9 특수 메소드

  • 연산자에 관련된 특수 메소드 = 연산자 오버로딩(C++, 같은 이름에 여러 의미 부여) (오버로딩: 같은 이름 함수가 여러개)
  • 객체에 대하여 연산 적용시 호출됨
연산자 메소드 설명
x + y __add__(self, y) 덧셈
x - y __sub__(self, y) 뺄셈
x * y __mul__(self, y) 곱셈
x / y __truediv__(self, y) 실수 나눗셈
x // y __floordiv__(self, y) 정수 나눗셈
x % y __mod__(self, y) 나머지
divmod(x, y) __divmod__(self, y) 실수 나눗셈과 나머지
x ** y __pow__(self, y) 지수
x << y __lshift__(self, y) 왼쪽 비트 이동
x >> y __rshift__(self, y) 오른쪽 비트 이동
x <= y __le__(self, y) less than or equal(작거나 같다)
x < y __lt__(self, y) less than (작다)
x >= y __ge__(self, y) greater than or equal (크거나 같다)
x > y __gt__(self, y) greater than (크다)
x == y __eq__(self, y) 같다
x != y __neq__(self, y) 같지 않다.

__str__() 메소드

  • print() 실행 시 자동으로 호출됨
  • Java의 toString() (클래스 정보를 문자열로 반환)
  • 일반적으로 객체를 문자열로 만들어 반환
    '(%g, %g)' % (self.x, self.y)
    %g: 실수

4. GUI 프로그래밍

tkinter는 파이썬에서 그래픽 사용자 인터페이스를 개발할 때 필요한 모듈이다.

유닉스 계열에서 사용되던 Tcl/Tk 위에 객체지향 계층을 입힌 것이다. Tk는 Tcl 스크립팅 언어를 위한 GUI 확장으로 개발

 

4.1 단순 위젯과 컨테이너 위젯

  • 단순 위젯
    • Button, Canvas, Checkbutton, Entry, Label, Message
  • 컨테이너 컴포넌트
    • 다른 컴포넌트를 안에 포함할 수 있는 컴포넌트
    • Frame, Toplevel, LabelFrame, PanedWindow

윈도우 생성하기

from tkinter import * # tkinter 모듈 포함

window = Tk() # 윈도우 생성
label = Label(window, text="Hello tkinter") # 레이블 위젯 생성
label.pack() # 레이블 위젯을 윈도우에 배치

window.mainloop() # 윈도우가 사용자 동작을 대기
  • python 에서는 GUI 프로그램은 맨 밑에 항상 window.mainloop() 가 있어야 함
  • Tk() 를 호출하면 Tk 클래스의 객체가 생성되면서 화면에 하나의 윈도우가 생성된다.
  • label = Label(window, text="Hello tkinter")
    레이블 위젯을 생성
  • label.pack()
    • pack() 은 압축 배치 관리자를 이용하여 레이블을 컨테이너에 위치시킨다.
  • window.mainloop()는 이벤트 처리 루프로서 사용자로부터오는 마우스나 키보드 이벤트를 처리한다.
Button 간단한 버튼으로 명령을 수행할 때 사용된다
Canvas 화면에 무언가를 그릴 때 사용한다
Checkbutton 2가지의 구별되는 값을 가지는 변수를 표현한다.
Entry TextField) 한 줄의 텍스트를 입력받는 필드
Frame 컨테이너 클래스이다. 프레임은 경계선과 배경을 가지고 있다. 다른 위젯들을 그루핑하는데 사용된다.
(Panel)
Label 텍스트나 이미지를 표시한다.
Listbox 선택 사항을 표시한다.
Menu 메뉴를 표시한다. 풀다운 메뉴나 팝업 메뉴가 가능하다.
Menubutton 메뉴 버튼. 풀 다운 메뉴가 가능하다.
Message 텍스트를 표시한다. 레이블 위젯과 비슷하다. 하지만 자동적으로 주어진 크기로 텍스트를 축소할 수 있다.
Radiobutton 여러 값을 가질 수 있는 변수를 표시한다.
Scale 슬라이더를 끌어서 수치를 입력하는데 사용된다.
Scrollbar 캔버스, 엔트리, 리스트 박스, 텍스트 위젯을 위한 스크롤 바를 제공한다.
Text 형식을 가지는 텍스트를 표시한다. 여러가지 스타일과 속성으로 테스트를 표시할 수 있다.
Toplevel 최상위 윈도우로 표시되는 독립적인 컨테이너 위젯
LabelFrame 경계선과 제목을 가지는 프레임 위젯의 변형
PanedWindow 자식 위젯들을 크기조절이 가능한 패널로 관리하는 컨테이너 위젯
Spinbox 특정한 범위에서 값을 선택하는 엔트리 위젯의 변형

버튼 위젯

from tkinter import *
window = Tk()

button = Button(window, text="클릭", bg="yellow",
					fg="blue", width=80, height=2)
# 크기 설정, 픽셀이 아닌 글자 단위
# 컨테이너 크기 설정 시 px 단위로 설정됨

button.pack() # 컴포넌트들을 팩으로 붙임
window.mainloop()

엔트리 위젯 = TextField

from tkinter import *
window = Tk()

entry = Entry(window, fg="black", bg="yellow", width=80)

entry.pack()
window.mainloop()
  • Entry().insert(추가할 위치, 넣을 문자열)
  • Entry().delete(삭제할 처음 위치, 마지막 위치)
  • END = 끝
    entry.delete(0, END) -> 처음부터 끝까지 지운다.

4.2 배치 관리자: Layout Manager

  1. 압축 배치 관리자
  2. 격자 배치 관리자
  3. 절대 배치 관리자

Java Swing:

FlowLayout, GridLayout, BorderLayout, GridBagLayout, ...

1) 압축 배치 관리자 Pack Geometry Manager

  • 압축 배치 관리자는 위젯들을 최대한 압축하여 컨테이너 안에 세로로 배치 (상하)
  • 위젯들을 사각형 블록으로 간주
  • pack() 메소드 사용
    from tkinter import *
    
    window = Tk()
    
    Label(window, text="박스 #1", bg="red", fg="white").pack()
    Label(window, text="박스 #2", bg="green", fg="black").pack()
    Label(window, text="박스 #3", bg="blue", fg="white").pack()
    
    window.mainloop()​
  • pack(side=LEFT)
    왼쪽에 붙임
  • LEFT, RIGHT, TOP(default), BOTTOM
  • "left", "right",,,
  • label, button color 변경
    bg="red" background color
    fg="black" foreground color

2) 격자 배치 관리자 Grid Geometry Manager

  • 위젯(버튼, 레이블 등)을 테이블 형태로 배치한다
  • grid(row= , column=) 메소드 사용
  • 모든 행과 열이 같을 필요는 없다.
  • 직사각형 형태일 필요 없음

3) 절대 위치 배치 관리자 Place

  • 절대 위치 배치 관리자는 절대 위치를 사용하여 위젯을 배치
  • 위젯의 왼쪽 상단 지점 위치 지정
  • place(x= , y= ) 메소드 사용
  • Frame
    • Java swing, awt = Pannel
    • 컴포넌트들을 그룹핑 하는 역할을 한다.
    • 위젯들을 프레임에 붙인 뒤 프레임을 윈도우에 붙인다.
  • 윈도우 크기 설정
    • window.geometry("600x100")
    • px 단위
  • 위젯 크기 설정
    • ex) Button(window, text="box1", width=10, height=1).pack()
    • 글자 단위로 설정됨

Java는 그리드 레이아웃의 모든 크기가 동일

  • Python은 그리드 레이아웃의 비율이 각각 다를 수 있음
  • sticky=W+E+N+S
    주어진 방향으로 딱 붙임
  • PhotoImage(file="d://fig3.png")
    • 이미지 넣기
    • file 경로 : 코드 파일과 같은 위치에 이미지가 있으면 상대경로 지정 가능
  • Grid
    • row, column 은 위치 지정
    • rowspan, columnspan 은 차지할 행의 수, 차지할 열의 수이다.

4.3 버튼 이벤트 처리

이벤트 드리븐 방식

이벤트가 발생하면 지정된 함수를 호출한다. (callback 함수 / 이벤트 핸들러)

Button(window, command=함수이름)

 

Label

  • Label 의 text 속성은 딕셔너리 같이 접근 가능
  • label['text']
  • label.config(text="world", bg="yellow")

4.4 람다식

  • 람다식은 이름은 없고 몸체만 있는 함수이다.
  • 람다식은 lambda 키워드로 만들어진다.
  • 람다식은 딱 한번 사용하는 함수를 만드는데 사용된다.
  • lambda x, y : x + y
  • lambda 매개변수: 수식
  • eval("2 + 3") -> 5
    문자열을 계산한다.
  • command=lambda t=button_text:click(t)
    def process(t = button_text)
        click(t)
    def click(key):
        pass

4.5 그림 그리는 화면 : Canvas

from tkinter import *

window = Tk()
w = Canvas(window, width=300, height=200)
w.pack()

i = w.create_rectangle(50, 25, 200, 100, fill="blue")

w.coords(i, 0, 0, 100, 100) # 좌표 변경
w.itemconfig(i, fill="blue") # 색상 변경

w.delete(i) # i 항목을 삭제한다
w.delete(ALL) # 모든 항목을 삭제한다

window.mainloop()
create_line(15, 25, 200, 25) 직선을 그리는 메소드 (x1, y1, x2, y2)
create_rectangle(50, 25, 150, 75, fill="blue") 사각형을 그리는 메소드 (x1, y1, x2, y2)
create_text(200, 100, fill="darkblue", font="Times 30 italic bold", text="This is a text example") 텍스트 그리기
x, y 가 중심 좌표가 된다.
create_arc(10, 10, 100, 150, extent=90)
사각형에 내접한 원 중에서 90도만큼만 그려진다.(extent)
create_oval(15, 25, 100, 125) 타원은 지정된 사각형 안에 그려진다.
create_polygon(10, 10, 150, 110, 250, 20, fill="yellow") 10, 10 에서 출발, (150, 110) -> (250, 20) 에서 종료
    옵션
  • anchor=NWES
    NW => 북쪽 + 서쪽 방향에 붙인다.
  • width: 선 굵기

좌표 변경: canvas.coords(캔버스에 그린 객체 id, x1, y1, x2, y2)

좌표 가져오기: canvas.coords(캔버스에 그린 객체 id)

4.6 키보드와 마우스 이벤트 처리

def callback(event):
	pass
  • event.x, event.y 를 통해 클릭된 위치 파악 가능

이벤트 지정자

  • <Button-1> : 왼쪽 버튼
    마우스가 버튼 위젯 위에서 눌렸을 때 발생하는 이벤트
    <Button-2> 중간 버튼
    <Button-3> 오른쪽 버튼
    <Button-1>, <ButtonPress-1>, <1> 은 모두 버튼 이벤트를 가리킴
  • <B1-Motion>
    마우스 버튼 1이 눌려진 채로 움직일 때 발생
    중간버튼 B2, 오른쪽 버튼 B3
  • <ButtonRelease-1>
    사용자가 Button1 에서 손을 뗄 때 발생
  • <Double-Button-1>
    마우스 버튼 1이 더블 클릭될 때 발생
    Triple도 가능
    단일 클릭과 더블 클릭에 동시에 연결하면 양쪽 콜백 메서드가 모두 호출됨
  • <Enter>
    마우스 포인터가 위젯으로 진입하였을 때 발생
    *엔터키 아님
  • <Leave>
    마우스 포인터가 위젯을 떠났을 때 발생
  • <FocusIn>
    키보드 포커스가 현재의 위젯으로 이동
  • <FocusOut>
    키보드 포커스가 현재의 위젯에서 다른 위젯으로 이동
  • <return>
    엔터키 입력
    Backspace, Cancel(Break), Tab, return, Shift_L, Control_L, Alt_L 
  • <Key>
    사용자가 어떤 키라도 누르면 발생한다.
    눌려진 키는 이벤트 객체의 char 멤버(event.char)에 저장되어있다.
    F5같은 키는 저장 안됨
  • a
    사용자가 "a"를 입력하였을 때 발생. 대부분의 인쇄 가능한 문자는 이런 식으로 연결
    예외) <space>, "<": <less>
    1 - 키보드 바인딩
    <1> - 버튼 바인딩
  • <Shift-Up>
    시프트 키 + 위쪽 화살표
    <Shift-Down>
    시프트 + 아래쪽 화살표
    Alt, Shift, Control 과 같은 수식어 사용 가능
  • <Configure>
    위젯이 크기 변경했을 때 발생. 위젯의 위치나 플랫폼을 변경해도 발생
    새로운 크기는 콜백 메소드로 전달되는 이벤트 객체의 width나 height 속성에 저장된다.

1) 마우스이벤트 처리

from tkinter import *

window = Tk()

def key(event):
	print(repr(event.char), '가 눌렸습니다.')

def callback(event):
    frame.focus_set()
    print(event.x, event.y, '에서 마우스 이벤트 발생')

frame = Frame(window, width=100, height=100)
frame.bind('<Key>', key)
frame.bind('<Button-1>', callback)
frame.pack()

window.mainloop()
  • frame.focus_set() 메소드를 이용하여 원하는 위젯으로 포커스를 이동시킬 수 있다.
  • repr('a') ->  'a'  그대로 출력
  • event.char
    어느 키가 눌렸는지 알려줌
  • event.x, event.y
    마우스가 눌린 좌표

Java: JTextField, JPasswordField < - > Python: Entry

5. 상속

상속

기존에 존재하는 클래스로부터 멤버 함수와 멤버변수를 이어받고, 자신이 필요한 기능을 추가하는 기법

  • 객체지향 프로그래밍에서는 상속이 클래스 간의 is-a 관계를 생성하는데 사용
  • 자식 클래스 is a 부모 클래스
  • 푸들은 강아지이다.

상속 구현하기

class 자식클래스(부모클래스):
    def __init__(self, ..):
    	super.__init__(...)
        ...
  • 부모 클래스를 호출하는 방법
    super.으로 호출하거나
    부모클래스.  으로 호출 가능 (자식 클래스 내에서)
  • 파이썬은 반드시 자식 생성자에서 부모 생성자를 호출해야 한다.
    부모 클래스의 변수를 초기화 하기 위해서는 부모 클래스의 생성자를 호출해서 초기화 한다.
  • 부모 클래스의 생성자를 명시적으로 호출해야 함
  • 부모 클래스의 생성자를 호출하지 않으면 부모 클래스에 정의된 멤버변수가 생성되지 않는다. (사용 불가, 사용하려고 하면 Error)
  • C++, Java는 부모생성자를 호출하지 않으면 암묵적으로 호출됨) 컴파일러가 자동으로 호출해준다.

상속을 사용하는 이유

  1. 코드 중복을 제거할 수 있다.
  2. 중복되는 코드를 모아서 부모 클래스로 두게 되면 코드 재사용성이 높아진다.
  • type()
    함수를 사용하면 변수의 타입을 알 수 있다.
  • isinstance()
    부모 클래스까지 체크가 가능
    x = Animal()
    y = Dog()
    isinstance(x, Animal)
    >> True
    
    isinstance(y, Animal)
    >> True
    
    isinstance(y, Dog)
    >> True
    
    isinstance(x, Dog)
    >> False​
  • 부모 클래스의 private 멤버는 자식 클래스에서 사용할 수 없다.
    self.__data   # private

5.1 다중 상속

class A:
	def __init__(self, ...):

class B:
	def __init__(self, ...):
    pass

class C(A, B):
    def __init__(self, ...):
        # 다중 상속은 super()를 사용할 수 없음
        A.__init__(self, ...)
        B.__init__(self, ...)
  • 다중 상속에서 부모 클래스를 호출하는 경우 super()를 쓰면 알아볼 수 없으므로 클래스 이름으로 호출한다.
  • 다중 상속에서 부모 생성자를 호출할 때 self를 넘겨줘야 한다.

5.2 메소드 오버라이딩

  • 자식 클래스의 메소드가 부모 클래스의 메소드를 오버라이드한다고 말한다.
  • 자식 클래스가 부모 클래스에서 상속받은 메소드를 필요에 따라 변경하는 것
  • 다형성의 대상 == 자식 클래스
  • 상위 클래스와 하위 클래스에 동일한 함수 헤더가 정의되고 구현만 다른 경우
    C++: virtual이 붙어야 오버라이딩 됨
    Java, python: 자동 오버라이딩 효과

객체 출력

  • __str__(self):
    메소드가 문자열을 리턴한 내용이 객체 출력
    객체를 가독성있는 텍스트로 출력 (사용자 입장)
  • __repr__(self):
    str이 없을 때 메소드에서 반환하는 내용을 객체 출력시 출력
    객체를 확실히 구별하기 위한 출력 (시스템)

5.3 다형성

다형성은 많은(poly) + 모양(morph) 이라는 의미로
주로 프로그래밍 언어에서 하나의 식별자로 다양한 타입을 처리하는 것을 의미한다.
  • 동일한 코드로 다양한 타입의 객체를 처리할 수 있는 기법
  • Animal a = Dog() / Cat()
    a 안에 들어가 있는 객체의 타입에 맞는 speak를 호출한다.
    실행할 때 a 안에 들어있는 객체의  타입을 알 수 있다.
  • 다형성이 구현되려면 Runtime 바인딩이 되어야 한다.
  • 컴파일 시에는 실제 들어있는 객체의 타입이 무엇인지 알 수 없다.
  • 일반적인 경우에는 컴파일 시에 알수있다. 오버라이딩된 객체지향 언어인 경우 data type에 따라 호출하는 것이 아니라 안에 들어있는 객체의 타입을 보고 호출한다.
  • 부모 클래스에 구현되어 있지 않으면 오버라이딩이 아님
  • 다형성의 대상: 오버라이딩된 멤버함수

5.4 object class

  • 모든 클래스의 맨 위에는 object 클래스가 있다.
  • object class 메소드
    __init__(self, ..) 생성자
    __del__( self ) 소멸자
    __repr__( self ) 객체 표현 문자열 반환
    __str__( self ) 문자열 표현 반환
    __cmp__( self ) 객체 비교
    대부분 오버라이딩하여 사용, 불려야 할 때 자동으로 불림

5.5 클래스 관계

is-a 관계 = 상속 

  • Car is a Vehicle
  • Dog is a Animal
  • Circle is a Shape

has-a 관계 = 구성

  • Library has a book
  • Living room has a sofa

6. 내장함수, 람다식, 제너레이터, 모듈

6.1 내장함수

  1. abs(-20)
    숫자의 절댓값을 반환하는데 사용됨
    실수, 정수 동일
  2. all()
    시퀀스(리스트, 딕셔너리)를 받아서 시퀀스의 모든 항목이 참이면 True를 반환한다. (0이 없으면 True)
    (AND)
  3. any()
    시퀀스 객체에 있는 한 개의 항목이라도 참인 경우 True
    (OR)
  4. bin()
    정수의 이진 표현 반환
    bin(64) == 0b1000000
  5. eval('x + 1')
    전달된 수식을 구문 분석하고 프로그램 내에서 수식을 실행한다.
    - string으로 값을 넘겨줘야 함
  6. sum([1,2,3])
    리스트에 존재하는 항목들을 전부 더하여 합계를 반환한다.
  7. len()
    객체의 길이를 계산하여 반환하는 함수
  8. list()함수
    리스트를 생성하는 함수
    문자열을 넣으면 한글자씩 쪼갬
  9. map(function, 이터레이터 객체) 함수
    반복 가능한 객체의 각 항목에 주어진 결과를 적용한 후 결과를 반환
  10. dir()
    객체가 가지고 있는 변수나 함수를 보여준다
    객체에 사용가능한 함수들을 알고싶을 때 유용
  11. complex(실수 , 허수)
    복소수 객체 생성
  12. max(), min()
    리스트나 튜플, 문자열에서 가장 큰 항목을 반환
  13. enumerate()
    시퀀스 객체를 입력받아 열거형 객체를 반환
    열거형객체는 첫번째 요소가 번호, 두번째 요소가 해당 값을 갖는 객체
    ex) enumerate(mylist, start=1)
    [(1, 'a'), (2, 'b')] # 시작 번호가 1부터 시작함 (default = 0)
  14. filter(func, 반복 가능한 객체)
    함수의 결과가 true 인 요소만 뽑아냄
  15. zip()
    두개의 자료형을 하나로 묶어주는 함수
    numbers[1, 2, 3, 4], slist['a', 'b', 'c']
    zip(numbers, slist) => [(1, 'a'), (2, 'b'), (3, 'c')]

6.2 정렬과 탐색

  • mylist.sort()
    • 이 메소드는 주어진 리스트를 정렬된 상태로 변경
    • 주어진 리스트가 정렬됨.
    • 리턴되지 않음
  • sorted(mylist)
    • 정렬된 리스트를 생성하여 리턴한다.
    • 기존 리스트는 변경되지 않음
    • sort()는 원 리스트를 변경하고, sorted()는 변경하지 않는다.
    • sort()는 리스트만을 위한 메소드
      sorted()는 반복가능한 어느 객체에도 사용 가능
    • key=str.lower 옵션
      sorted를 호출하기 전에 모두 소문자로 변경
      클래스 객체의 경우 특정 값을 리턴하는 함수를 넣을 수 있음
  • reverse = True 옵션
    • sort(), sorted() 모두 사용 가능
    • default = 오름차순 [1, 2, 3, 4, 5]
    • reverse = True => 내림차순 정렬[5, 4, 3, 2, 1]

6.3 람다식

  • 이름은 없고 몸체만 있는 함수
  • lambda 매개변수 : 수식
  • 딱 한번 사용하는 함수를 만드는데 사용된다.
  • 여러개의 매개변수, 리턴값은 하나 이하

reduce

import functools

result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4])
print(result) # 10
  • (((1 + 2) + 3) + 4) = 10

6.4 이터러블 객체 만들기

  1. __iter__()
    • 자기 자신을 반환
      return self
  2. __next__()
    • 다음 반복을 위한 값을 반환
    • 더 이상의 값이 없으면 raise StopIteration을 발생
class MyCounter(object):
    def __init__(self, low, high):
        self.current = low
        self.high = high
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 1
            return self.current - 1

6.5 제너레이터

  • 키워드 yield 를 사용해서 함수로부터 이터레이터를 생성
def myGenerator():
    yield 'first'
    yield 'second'
    yield 'third'

for word in myGenerator():
    print(word)
  • first
    second
    third가 순서대로 출력된다.
def myCounter(low, high):
    while low <= high:
        yield low
        low += 1

for i in myCounter(1, 10):
    print(i, end=" ")
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

피보나치 이터레이터

class FibIterator:
    def __init__(self, a=1, b=0, maxValue=50):
        self.a = a
        self.b = b
        self.maxValue = maxValue
    
    def __iter__(self):
        return self
    
    def __next__(self):
        n = self.a + self.b
        if n > self.maxValue:
            raise StopIteration()
        self.a = self.b
        self.b = n
        return n

for i in FibIterator():
	print(i, end =" ")
# 1 1 2 3 5 8 13 21 34

6.6 연산자 오버로딩

덧셈 x + y x.__add__(y)
뺄셈 x - y x.__sub__(y)
곱셈 x * y x.__mul__(y)
지수 x ** y x.__pow__(y)
나눗셈(실수) x / y x.__truediv__(y)
나눗셈(정수) x // y x.__floordiv__(y)
나머지 x % y x.__mod__(y)
작음 x < y x.__lt__(y)
작거나 같음 x <= y x.__le__(y)
같음 x == y x.__eq__(y)
같지 않음 x != y x.__ne__(y)
x > y x.__gt__(y)
크거나 같음 x >= y x.__ge__(y)

 

class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Point(x, y)
    
    def __str__(self):
        return f'Point({self.x}, {self.y})'

p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2)

6.7 모듈

  • 파이썬 프로그램이 길어지면 유지 보수를 쉽게 하기 위해 여러개의 파일로 분할할 수 있다.
  • 파일을 사용하면 한번 작성한 함수를 복사하지 않고 여러 프로그램에서 사용할 수 있다.
# fibo.py
def fib(n):
	pass

def fib2(n):
	pass

모듈 사용하기

import fibo

>>>> fibo.fib(1000)
>>>> fibo.fib2(100)

#모듈 이름
>>>> fibo.__name__
'fibo'
  • import 를 선언할 때 .py 를 붙이면 안됨
  • 모듈 안의 함수들을 현재 심볼테이블에 저장하지 않음
  • 모듈 이름 fibo만 심볼 테이블에 저장되므로 모듈 알의 함수들을 호출하려면 fibo. 으로 호출해야 한다
  • 모듈의 이름을 사용하지 않고 안에 함수들을 호출하려면
    from fibo import *
    from fibo import fib2
  • 모듈의 별칭
    import fibo as fib

모듈 탐색 경로 (sys.path는 다음과 같이 초기화 됨)

  1. 입력 스크립트가 있는 디렉토리 (현재 디렉토리)
  2. PYTHONPATH 환경 변수
    각자 만든 모듈의 경로를 넣어도 됨
  3. 설치에 의존하는 디폴트 값

Java: java.util

C++: STL

python: list, set, map

  1. copy 모듈
    • copy.deepcopy(['r', 'b', 'g'])
  2. random 모듈
    • random.randint(1, 6)
    • random.random()
      0 <= x < 1.0 범위의 실수형 난수
    • random.choice(mylist)
      mylist에서 랜덤으로 하나 선택
    • random.shuffle(mylist)
      리스트의 내용을 섞음
    • random.randrange(0, 101, 3)
      [0, 101 - 1] 범위의 3의 배수
    • random.sample("문자열", 선택할 문자 개수)
      문자열에서 선택할 문자 개수만큼 임의로 선택하여 리스트로 된 결과를 반환
  3. sys 모듈
    1. sys.prefix()
      파이썬 설치 경로
    2. sys.executable()
      파이썬 실행 파일
    3. sys.path
      라이브러리 경로
  4. time 모듈
    1. time.time()
      1970.1.1 0시부터 지금까지 초 시간
    2. time.asctime()
      현재 날짜와 시간을 문자열로 표현
    3. time.sleep(secs)
      초 단위
  5. calendar 모듈
    1. calendar.month(2016, 8)
      print(cal)
      해당 연도의 8월 달력 출력
  6. keyword 모듈
    1. keyword.iskeyword(name)
      name이 키워드 명인지 체크

7. 파일과 예외처리

파일의 맨 끝에는 EOF 마커가 들어있다.

7.1 파일 열고 닫기

infile = open('input.txt', 'r')

infile.close()
  • open( '파일 이름', '파일 모드' )
  • infile.close()
  • 파일 모드
    "r" 읽기 모드 파일의 처음부터 읽음
    "w" 쓰기 모드 파일의 처음부터 쓴다. 파일이 없으면 생성된다.
    파일이 존재하면 기존 내용은 지워진다.
    "a" 추가 모드 파일의 끝에 내용을 추가한다.
    파일이 없으면 생성됨
    "r+" 읽기 + 쓰기 파일에 읽고 쓸 수 있는 모드.
    seek()를 호출해서 현재 포인트 위치를 변경
  • seek(offset, 기준점)
    기준점 0: 맨 앞, 1: 현재 위치, 2: 맨 뒤

7.2 파일 읽고 쓰기

1) 파일 읽기

infile = open('input.txt', 'r')
# 홍길동\n
# 김철수\n

line = infile.readline() # 홍길동\n
while line != "":
    print(line) # 홍길동\n\n
    line = infile.readline()
  • readline()
    끝에 개행문자까지 읽어옴
  • infile.readline().rstrip()
    오른쪽에 있는 \n 문자 삭제 (공백문자 삭제)
  • for line in infile:
        print(line)
    파일에서 한줄씩 읽음 (개행문자까지 읽어들임)

읽기용 메소드

readline() 한 줄 씩 읽어옴 (개행문자 포함)
readlines() 파일 전체를 한줄씩 구분된 리스트로 읽어옴 (개행 포함)
read()
read(1)
파일 전체를 하나의 문자열로 읽음
원하는 갯수만큼 읽음

2) 파일 쓰기

outfile = open("output.txt", "w")

outfile.write("김영희\n");
print("hello world\n", file=outfile)
outfile.close()
  • outfile.write(text)
  • print(text, file=outfile)
    file에 쓸 객체 입력

3) 파일 닫기

  • f.close()
  • with open("test.txt", "w") as f:
        f.write("hello")
    블록을 빠져나오면 자동으로 파일이 닫힌다.

line.split()

-> 공백 문자를 기준으로 분리

ord('A')

-> 주어진 문자를 아스키 코드 숫자로 변환

7.3 이진 파일 읽고 쓰기

  • 이진 파일에서 데이터를 읽으려면
    infile = open(filename, "rb")
    "rb" = read binary
  • infile.read(8)
    입력 파일에서 8바이트 읽기
  • 이진 파일에 바이트들을 저장하려면
    outfile = open( filename, "wb" )
    outfile.write( bytes([255, 128, 0, 1]) ) # 4 byte

7.4 임의 접근의 원리

** seek()에서 offset 은 바이너리 파일만 지원. 텍스트 파일에서 오프셋은 사용할 수 없음(whence가 1, 2일 때)

  • seek( offset, 0 )
    파일 처음에서 offset 만큼 떨어진 위치에 접근
  • seek( offset, 1 )
    현재 위치에서 offset 만큼 떨어진 위치에 접근
  • seek( offset, 2 )
    파일 맨 끝에서 offset 만큼 떨어진 위치에 접근
    offset은 - 음수 값

7.5 예외 처리

Java: try, catch, finally

python: try, except, else, finally

1) 오류의 종류

  • IOError
    파일을 열 수 없을 때 발생
  • importError
    파이썬이 모듈을 찾을 수 없을 때
  • ValueError
    연산이나 내장 함수에서 인수가 적절치 않은 값을 가지고 있으면 발생
  • KeyboardInterrupt
    사용자가 인터럽트 키를 누르면 발생
  • EOFError
    내장 함수가 파일의 끝을 만나면 발생

2) try-catch 구조

  • try 에서 예외가 던져지면, except 목록 중에서 순서대로 내려가면서 첫번째로 일치되는 예외를 선택

(x, y) = (2, 0)

try:
    z = x/y
except ZeroDivisionError as e:
    print(e) # 에러 정보를 출력해줌

except 블록은 예외가 발생하지 않으면 실행되지 않는다.

3) else 블록

try:
    fh = open("testfile", "r")
    fh.write("test data file write\n")
except IOError as e:
    print(e)
else:
    print('else')
finally:
    print('finally')
  • else 블록
    • 아무런 예외가 발생하지 않았을 때 실행된다.
    • except 블록 바로 뒤에 옴
  • finally
    • 예외가 발생하는지 여부와 상관없이 무조건 실행하는 블록
    • try-catch 블록의 가장 마지막에 온다

4) 예외 발생하기

  • 파이썬에서는 오류가 감지되면 raise 문을 사용하여 예외를 생성한다
  • raise (error 객체)
    예외 객체를 생성해서 던짐
반응형