Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

BASEMENT

Python 4주차 - 2 본문

Programming/Python

Python 4주차 - 2

2_34 2020. 7. 12. 18:43

파이썬 GUI 모듈

tkinter : 파이썬 표준 라이브러리

turtle : 파이썬에 내장되어 있는 라이브러리

kivy : 게임 및 안드로이드 어플리케이션 개발, pygame에서 발전

wxpython : 윈도우, 리눅스, 맥 os 등 다양한 운영체제에서 하나의 소스코드로 프로그램 구현 가능

pyqt : C++ 용의 QT 디자이너 GUI 툴을 파이썬에서도 사용할 수 있게 만든 모듈

pygame : 게임 만드는 라이브러리. 이미지 또는 사운드 처리 편리

tkinter (tk interface) 모듈

Tcl/Tk (Tool Command Language/Tool Kit)의 범용 GUI 라이브러리 기반 -> 유닉스, 매킨토시 등 운영체제 지원

위젯 : 윈도우창에 나올 수 있는 문자, 버튼, 체크박스, 라디오 버튼 등

 

1. 기본 윈도우 구성

from tkinter import *
window = Tk()    		# 기본 윈도우 반환, 루트윈도우 또는 베이스 윈도우
 # 화면 구성 처리 코드 작성
 # 코드작성
window.mainloop()
from tkinter import *

win01 = Tk()
win01.title("윈도우 연습")			# 윈도우창 제목
win01.geometry('400x100')			# 윈도우창 실행 시 사이즈 조절
win01.resizable(width=False, height=False)	# 사이즈 고정 : False

win01.mainloop()

cf) win01.resizable(width=True, height=True)  -> 디폴트값. 사이즈 고정하지 않고 사이즈 조절 가능

 

2. 레이블

  • Label(부모윈도우, 옵션...)
  • Label을 윈도우에 실행시키기 위해서는 pack() 함수 사용
  • Label은 수정 불가 -> 수정할 수 없는 문자열 (도움말, 타이틀) 등에 사용
from tkinter import *

window = Tk()

window.title("label 연습")
window.geometry('400x100')
window.resizable(width=True, height=True)

label1 = Label(window, text='Pytho을')
label2 = Label(window, text='이번 학기에')
label3 = Label(window, text='배웁니다')

label1.pack()		# pack() : label함수 실행
label2.pack()
label3.pack()

window.mainloop()

레이블 옵션 추가

  • fg : foreground 글자색 지정
  • bg : background 배경색 지정
  • anchor : label크기 안에서의 위치 선정. N, NE, E, SE, S, SW, W, NW, CENTER 등. 기본은 CENTER
from tkinter import *

window = Tk()

window.title("label 연습")
window.geometry('400x100')
window.resizable(width=True, height=True)

label1 = Label(window, text='Pytho을')
label2 = Label(window, text='이번 학기에', font=('굴림체',30), fg="blue")
label3 = Label(window, text='배웁니다', bg="magenta", width=20, height=5, anchor=SE)

label1.pack()
label2.pack()
label3.pack()

window.mainloop()

그림 이미지도 추가 가능

  • PhotoImage는 gif만 가능함
  • jpg의 경우 PIL (python image library)모듈 import하여 PIL의 Image 또는 ImageTk 사용함
from tkinter import *

window = Tk()

window.title("label 연습")
window.geometry('500x500')
window.resizable(width=True, height=True)

photo = PhotoImage(file='merry.gif')
label1 = Label(window, image=photo)
label1.pack()

window.mainloop()

움직이는 gif

  • pyglet 모듈 사용 (https://bitbucket.org/pyglet/pyglet/downloads)
  • cmd 에서 pip install pyglet 입력하여 설치
import pyglet

ag_file = "data/merry.gif"
animation = pyglet.resource.animation(ag_file)
sprite = pyglet.sprite.Sprite(animation)

win = pyglet.window.Window(width=sprite.width, height=sprite.height)

@win.event
def on_draw():
	win.clear()
    sprite.draw()
pyglet.app.run()

3. 버튼

 

마우스의 클릭이벤트를 이용한 특정 작업이 실행되도록 하는 위젯

Button(부모윈도우, 옵션...)

 

버튼 위젯 클릭 시, 윈도우가 닫히는 예제

from tkinter import *

window = Tk()

button1 = Button(window, text='Quit', fg='red', command=quit)
button1.pack()

window.mainloop()

messagebox를 통해 문자열 정보를 알려줌

from tkinter import *
from tkinter import messagebox      # messagebox 모듈 import

def messageFunc():
    messagebox.showinfo("Christmas button", "Merry Christmas!")

win01 = Tk()
photo = PhotoImage(file="merry.gif")
button1 = Button(win01, image=photo, command=messageFunc)  # 버튼 클릭시 실행될 함수 객체 작성
button1.pack()

window.mainloop()

4. 체크버튼

 

Checkbutton(부모윈도우, 옵션...)

from tkinter import *
from tkinter import messagebox

def checkFunc():
    if chk.get() == 0:		# 체크버튼에 체크가 안된 상태 / get()메소드로 값을 읽어옴
        messagebox.showinfo("check button", "Check Button Off")
    else:
        messagebox.showinfo("check button", "Check Button On")

window = Tk()

chk = IntVar()	# 정수형 타입의 변수를 생성시키는 클래스(위젯에 사용되는 값을 객체로 반환)
		# StringVar() : 문자열, DoubleVar() : 실수형
cb1 = Checkbutton(window, text="Please Click", variable=chk, command=checkFunc)
cb1.pack()

window.mainloop()

체크버튼 실습

from tkinter import *
from tkinter import messagebox

def checkFunc():
    if chk1.get() == 1:
        messagebox.showinfo("check button", "Python Check")
    elif chk2.get() == 1:
        messagebox.showinfo("check button", "visual C++ Check")
    elif chk3.get() == 1:
        messagebox.showinfo("check button", "Ruby Check")
    else:
        messagebox.showinfo("check button", "Check Button Off")        

window = Tk()
window.geometry('300x150')

chk1 = IntVar()
chk2 = IntVar()
chk3 = IntVar()

cb1 = Checkbutton(window, text="Python", variable=chk1, anchor=W, height=2, width=10, command=checkFunc)
cb2 = Checkbutton(window, text="visual C++", variable=chk2, anchor=W, height=2, width=10, command=checkFunc)
cb3 = Checkbutton(window, text="Ruby", variable=chk3, anchor=W, height=2, width=10, command=checkFunc)

cb1.pack(side=TOP)      
cb2.pack(side=TOP)
cb3.pack(side=TOP)

window.mainloop()

5. 라디오 버튼

 

여러개 중에서 하나를 선택하는 버튼

RadioButton(부모윈도우, 옵션...)

from tkinter import*

def radioFunc():
    if rbk.get() == 1:
        label1.configure(text='python')     # configure() : 기존의 출력된 label 변경
    elif rbk.get() == 2:
        label1.configure(text='C++')
    else:
        label1.configure(text='Java')

window = Tk()

rbk = IntVar()
rb1 = Radiobutton(window, text="python", variable=rbk, value=1, width=10, height=1, anchor=W, command=radioFunc)
rb2 = Radiobutton(window, text="C++", variable=rbk, value=2, width=10, height=1, anchor=W, command=radioFunc)
rb3 = Radiobutton(window, text="python", variable=rbk, value=3, width=10, height=1, anchor=W, command=radioFunc)

label1 = Label(window, text="선택한 언어: ", fg='red')
rb1.pack();rb2.pack();rb3.pack();label1.pack()

window.mainloop()

6. IntVar, StringVar, DoubleVar

 

Entry(부모윈도우, 옵션...)

from tkinter import*

def buttonClick():
    text1.delete(0,END)		# delete : 0부터 END 까지 지우고 싶은 위치값을 넣어줌
    text1.insert(0,'click')
def buttonVar():
    label1.configure(text=string.get())
    string.set('Merry Christmas!')

win = Tk()

string = StringVar()
text1 = Entry(win, textvariable=string, width=15)
btn1 = Button(win, text='Click', command=buttonClick)
btn2 = Button(win, text='var', command=buttonVar)
label1 = Label(win, text="value of text1")
text1.pack();btn1.pack();btn2.pack()

win.mainloop()

7. 위젯의 배치 및 크기 조절

 

위젯의 화면 출력 함수

  • pack() : 정렬옵션. pack(side=LEFT, RIGHT, ... )
  • place() : 고정 위치에 배치하는 함수. place(x=X좌표, y=Y좌표, width=폭, height=높이)
from tkinter import*

window = Tk()
button1 = Button(window, text='Button A')
button2 = Button(window, text='Button B')
button3 = Button(window, text='Button C')
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)

window.mainloop()
from tkinter import*

window = Tk()
button1 = Button(window, text='Button A')
button2 = Button(window, text='Button B')
button3 = Button(window, text='Button C')
button1.place(x=0, y=0)
button2.place(x=50, y=50)
button3.place(x=100, y=100)

window.mainloop()

리스트와 반복문 사용

from tkinter import*

window = Tk()
btnList = [None]*3

for i in range(len(btnList)):
	btnList[i] = Button(window, text='Button'+chr(65+i))
for btn in btnList:
	btn.pack(side=RIGHT)

window.mainloop()

 

위젯 사이의 여백 조절

  • padx, pady 사용
  • fill 은 윈도우에 폭을 맞추는 것. fill=X
from tkinter import*

window = Tk()
btnList = [None]*3

for i in range(len(btnList)):
    btnList[i] = Button(window, text='Button'+chr(65+i))
for btn in btnList:
    btn.pack(side=TOP, fill=X, padx=10, pady=10)

window.mainloop()

위젯 내부의 여백 조절

  • ipadx, ipady
from tkinter import*

window = Tk()
btnList = [None]*3

for i in range(len(btnList)):
    btnList[i] = Button(window, text='Button'+chr(65+i))
for btn in btnList:
    btn.pack(side=TOP, fill=X, ipadx=10, ipady=10)

window.mainloop()

cf) btn.pack(side=TOP, fill=x, padx=10, pady=10, ipadx=10, ipady=10)

 

실습 - 곱하기 계산 프로그램

from tkinter import*

def buttonClick():
    text1.delete(0,END)
    text2.delete(0,END)
    num1.set(0);num2.set(0)
    label1.configure(text='operator result')

def buttonCal():
    var1 = num1.get()
    var2 = num2.get()
    label1.configure(text=var1*var2)

win = Tk()
win.geometry('300x150')
win.title('multiple cal')

num1 = IntVar(value=0)
num2 = IntVar()
text1 = Entry(win, textvariable=num1, width=20)
text2 = Entry(win, textvariable=num2, width=20)

btn1 = Button(win, text="clear", width=8, height=1, command=buttonClick)
btn2 = Button(win, text="multi_cal", width=8, height=1, command=buttonCal)
label1 = Label(win, text="operator result")
text1.pack();text2.pack();btn1.pack();btn2.pack();label1.pack()

win.mainloop()

8. 마우스 이벤트 처리

 

def 이벤트처리함수(event):

## 코드

위젯.bind("마우스이벤트", 이벤트처리함수)

def clickLeft(event):
	messagebox.showinfo("mouse","leftclick")
window.bind("<Button-1>", clickLeft)

button 위젯의 콜백함수 호출 기능은 command

bind() : 콜백함수를 호출하는 옵션이 없는 위젯에 사용. 또는 키입력, 마우스 등의 이벤트의 콜백함수로도 사용

from tkinter import*
from tkinter import messagebox

def clickLeft(event):
    messagebox.showinfo("Mouse", "Click Left Button")

window = Tk()
window.bind("<Button-1>", clickLeft)
window.mainloop()

마우스 이벤트

 

1) 클릭할 때

  • <Button> : 모든 버튼 공통
  • <Button-1> : 왼쪽 버튼
  • <Button-2> : 가운데 버튼
  • <Button-3> : 오른쪽 버튼

2) 떼었을 때

  • <ButtonRelease> : 모든 버튼 공통
  • <ButtonRelease-1> : 왼쪽 버튼
  • <ButtonRelease-2> : 가운데 버튼
  • <ButtonRelease-3> : 오른쪽 버튼

3) 더블클릭할 때

  • <Double-Button> : 모든 버튼 공통
  • <Double-Button-1> : 왼쪽 버튼
  • <Double-Button-2> : 가운데 버튼
  • <Double-Button-3> : 오른쪽 버튼

4) 드래그할 때

  • <B1-Motion> : 왼쪽 버튼
  • <B2-Motion> : 가운데 버튼
  • <B3-Motion> : 오른쪽 버튼

5) 마우스 커서가 위젯 위로 올라 왔을 때 : <Enter>

6) 마우스 커서가 위젯에서 떠났을 때 : <Leave>

 

마우스 이벤트 처리  예제

from tkinter import*
from tkinter import messagebox

def clickLeft(event):
    messagebox.showinfo("Mouse", "Click Left Button")
def clickImage(event):
    messagebox.showinfo("Mouse","Mouse clicked on Merry Christmas")

window = Tk()
window.geometry('500x500')
photo = PhotoImage(file='./data/trees.gif')
label1 = Label(window, image=photo)
label1.bind("<Button>", clickImage)
window.bind("<Button-1>", clickLeft)
label1.pack(expand=1, anchor=CENTER)
window.mainloop()

9. 메뉴

 

기본메뉴생성 : config() 사용

메뉴자체 : 메뉴자체.add_cascade

메뉴자체 = Menu(부모윈도우)
부모윈도우.config(menu=메뉴자체)

상위메뉴 = Menu(메뉴자체)
메뉴자체.add_cascade(label="상위메뉴텍스트", menu=상위메뉴)
상위메뉴.add_command(label="하위메뉴1", command=함수1)
상위메뉴.add_command(label="하위메뉴2", command=함수2)
from tkinter import*

window = Tk()
mainMenu = Menu(window)
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Open")
fileMenu.add_separator()
fileMenu.add_command(label="Exit")

window.mainloop()

메뉴 선택 시 코드 실행 예제

from tkinter import*
from tkinter import messagebox

def func_open():
    messagebox.showinfo("Open", "Select Open")
def func_exit():
    window.quit()
    window.destroy()

window = Tk()
mainMenu = Menu(window)
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Open", command=func_open)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", command=func_exit)

window.mainloop()

메뉴 실습

from tkinter import*
from tkinter import messagebox
from tkinter import filedialog

def func_open():
    name = filedialog.askopenfilename(initialdir="/", tilte="Select file")

def func_exit():
    window.quit()
    window.destroy()

def func_edit():
    messagebox.showinfo("Editor", "This program was coded by Ann")

def func_version():
    yes = messagebox.askquestion("Ask Ok/Cancel", "Version 1.0 and Quit?")
    if yes == 'yes':
        window.quit()
        window.destroy()

window = Tk()
mainMenu = Menu(window)
window.config(menu=mainMenu)

fileMenu = Menu(mainMenu)
mainMenu.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Open", command=func_open)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", command=func_exit)

infoMenu = Menu(mainMenu)
mainMenu.add_cascade(label="Info", menu=infoMenu)
infoMenu.add_command(label="Editor", command=func_edit)
infoMenu.add_command(label="Version", command=func_version)

window.mainloop()

10. 대화상자

 

숫자 또는 문자를 윈도우에서 입력 받을 수 있도록 하는 모듈 사용

from tkinter import*
from tkinter.simpledialog import*

window = Tk()
window.geometry('500x500')

label1 = Label(window, text="Input value")
label1.pack()

value = askinteger("Number", "input from 1 to 6", minvalue=1, maxvalue=6)
label1.configure(text=str(value))

window.mainloop()

실습 - 이자를 합한 순수익 계산 프로그램

class Profit:
    name=""; rate=0.0; money=0; interest=0.0; total=0.0
    def cal(self):
        self.interest = float(text1.get())
        self.money = float(text2.get())
        self.total = self.money + (self.interest*self.money)
        self.name = text3.get()
        label4.configure(text="순수익: %.2f" % self.total)
    
    def clear(self):
        text1.delete(0,END)
        text2.delete(0,END)
        text3.delete(0,END)
        label4.configure(text="순수익: %.2f" % self.total)

me = Profit()

from tkinter import*

window = Tk()
window.title('이자율 계산')
window.geometry('350x200+800+400')
window.resizable(width=False, height=False)

label1 = Label(window, text="이자율(0.1~0.6) : ")
label2 = Label(window, text="입금 금액 : ")
label3 = Label(window, text="사용자 : ")
label4 = Label(window, text="순수익")

text1 = Entry(window, bd=3, width=20)
text2 = Entry(window, bd=3, width=20)
text3 = Entry(window, bd=3, width=20)

button1 = Button(window, text='계산', fg='blue', command=me.cal)
button2 = Button(window, text='닫기', fg='blue', command=quit)
button3 = Button(window, text='삭제', fg='blue', command=me.clear)

label1.grid(row=1, column=1, padx=3, pady=7)
text1.grid(row=1, column=2, padx=3, pady=7)
label2.grid(row=2, column=1, padx=3, pady=7)
text2.grid(row=2, column=2, padx=3, pady=7)
label3.grid(row=3, column=1, padx=3, pady=7)
text3.grid(row=3, column=2, padx=3, pady=7)
label4.grid(row=4, column=1, padx=3, pady=7)

button1.place(x=70, y=150, height=40, width=60)
button2.place(x=140, y=150, height=40, width=60)
button3.place(x=210, y=150, height=40, width=60)

window.mainloop()

Collections 모듈

파이썬 내장 자료구조 모듈

collections 모듈의 기능 : deque / OrderedDict / defaultdict / Counter / namedtuple

 

1. deque

리스트와 비교 시 장점

  • 연결리스트의 특성을 지원 -> 원형 연결 리스트 형태
  • 원형 연결 리스트를 rotate() 등을 사용하여 인덱스 변경 가능

2. OrderedDict

딕셔너리의 키값에 순서를 부여해줌

입력한 순서대로 화면에 출력

from collections import OrderedDict

d = OrderedDict()
d['x'] = 100
d['y'] = 200
d['z'] = 300
d['a'] = 400
print(d)

3. defaultdict

딕셔너리의 변수를 생성할 때 키에 기본 값을 지정

my_dict = {}   #my_dict = dict()
print(my_dict['a'])		# 딕셔너리 기본값이 없으므로 오류 발생
from collections import defaultdict

my_dict = defaultdict(lambda :0)
print(my_dict['a'])

같은 이름을 가진 여러개의 key 값들을 하나로 묶어 표현 가능

from collections import defaultdict

my_list = [('a',10), ('b',20), ('a',100), ('c',30), ('d',40), ('c',300)]
my_dict = defaultdict(list)
for v1,v2 in my_list:
	my_dict[v1].append(v2)

print(my_dict)
print(my_dict.items())

4. Counter

시퀀스 자료형의 데이터 값의 개수를 딕셔너리 형태로 반환

from collections import Counter

text = list("collection chocolate")
print(text)
text_c = Counter(text)
print(text_c)
print(text_c['c'])

특정 단어의 개수 추출 가능 

from collections import Counter

text = "Happy families are all alike; every unhappy family is unhappy in its own way. All happy families are alike; each unhappy family is unhappy in its own way".lower().split()

c_dict = Counter(text)
print(c_dict)

 

파이썬의 유용한 기능

보기 좋은 쉼표 배치

  • 모든 행을 쉼표로 끝맺음
items = ['book', 'pencil', 'notebook']

콘텍스트 매니저와 with 구문

  • 기능의 추상화 및 재사용, 일반적인 리소스 관리 패턴 단순화에 도움
  • 사용 예 : 파일 오픈 시
with open("hello.txt", "r") as f:
	text = f.read()

밑줄문자, 던더 (__)

  • 단일밑줄문자 : _var
  • 이중밑줄문자 : __var

단일밑줄문자

  • 관례적인 의미
  • 해당 변수 또는 메소드가 내부용이라는 의도 내포함
  • from import* 사용시 _ 으로 시작되는 메소드는 호출되지 않음

파이썬 함수는 일급 객체 (first-class object)

  • 변수에 전달, 데이터 구조에 저장, 다른함수의 인자로 전달, 다른 함수의 값에서 반환 가능
  • 함수의 중첩사용 가능

변수에 전달

def greet(text):
	return text.title() + '!!'
    
me_obj = greet

print(me_obj('hello, korea')

데이터 구조에 저장

def greet(text):
	return text.title() + '!!'

me_obj = greet
you_obj = greet
func_list = [me_obj, you_obj, str.lower, str.upper)

print(func_list_

다른 함수의 인자로 전달 및 리터값으로 사용

def greet(obj):
	hello = obj('Hi, This is a python class')
    print(hello)
    
def hello(text):
	return text.lower()
    
greet(hello)	# 함수에 다른 함수 호출 가능

함수의 중첩 - 중첩함수 또는 내부함수는 상위 부모함수 안에서만 호출 및 반환 가능

# 중첩 함수를 감싸는 함수를 외부 또는 부모함수라 함

def speak(text):
	def greet(h):
    	retrun h.title() + '!!'
    print(greet(text))
    
speak('hi, nested function')

# greet 함수가 중첩(내부) 함수로 외부에서 실행 시

def speak(text):
	def greet(h):
    	return h.title() + '!!'
    return greet(text)

hi = speak('nice to see you')
print(hi)
# 중첩함수 예제

def speak(volume):
	def whisper(text):
    	return text.lower() + '....'
    def yell(text):
    	return text.upper() + '!!'
    if volume > 0.5:
    	return yell
    else:
    	return whisper

vol = float(input("Input bolume, 0.0~1.0 >> "))
get_speak = speak(vol)		# speak 함수만 사용하여 yell, whisper 함수의 노출 없이 기능 구현 가능
print(get_speak("Hello, Python Program"))

클로저(Closure)

 

어떤 함수를 함수 자신이 가지고 있는 환경과 함께 저장된 레코드

함수가 가진 프리변수를 클로저가 만들어지는 당시의 값과 레퍼런스에 맵핑하여 주는 역할

자신의 영역 밖에서 호출된 경우에도 캡쳐된 자신의 내부 변수값이나 레퍼런스에 액세스 할 수 있게 도와줌

 

전역변수를 사용하지 않고 내부 데이터에 대한 은닉을 위해 활용

기존의 함수를 수정하지 않고 wrapper 함수를 이용하여 중첩함수 사용 가능

즉, 접근을 제한하고, 외부 노출 또는 수정을 금지하고 싶을 때 사용함

 

프리변수 맵핑 - 코드블록 내에서 사용은 되지만, 선언은 되어 있지 않은 변수. 중첩함수의 기능을 함

def printer(msg):
    text ="Python"
    def inner_print():
        print(text, msg)    # text, msg : 프리변수
    return inner_print

tmp = printer("hello")  # Python hello 출력x
tmp()   # Python hello 출력
tmp2 = printer("hi")
tmp2()  # Python hi 출력
def outer_func(tag):
    def inner_func(txt):
        text = txt
        print('<{0}>{1}<{0}>'.format(tag, text))

    return inner_func

h1_func = outer_func('h1')
p_func = outer_func('p')

h1_func('h1태그의 안입니다.')	# <h1>h1태그의 안입니다.<h1>
p_func('p태그의 안입니다')	# <p>p태그의 안입니다.<p>

객체의 함수화

 

모든 함수는 파이썬에서 객체이지만, 그 역은 성립이 안됨

객체를 함수처럼 호출 가능하게 만들 수 있음

__call__ 의 매직메서드 사용 - 객체가 호출되면 자동 실행

class Call_Object:
    def __init__(self,n):
        self.n = n
    def __call__(self,x):
        return self.n + x

add_3 = Call_Object(3)
print(add_3(5))
print(callable(add_3))	# callable 내장함수로 객체의 호출 여부 판단

디스크립터 (Descriptor)

 

코드의 견고성과 재사용성 높여줌

구현 시 메소드 정의 없이 변수로 처리

 

  • 파이썬에서 하나의 객체(A) 는 다른 객체 (B)를 속성으로 가질 수 있는데, 속성이 되는 객체 (B)의 값을 (1) 읽거나, (2) 쓰거나, (3) 속성에서 삭제하려고 할때 이루어질 동작이 미리 정의된 객체 (B)를 디스크립터라 함
  • 바인딩 동작이 있는 __get__(), __set__(), __delete__() 중 최소 하나가 클래스 객체에 대해 정의 되면 디스크립터
  • __set__() 이나 __delete__()가 있으면 데이터 디스크립터, __get__()만 있으면 비데이터 디스크립터
class YouClass:     	# YouClass : 데이터 디스크립터
    def __init__(self, val=None, name='you'):
        self.val = val
        self.name = name
    
    def __get__(self, obj, objtype):
        print(f'YouClass, {self.name}')
        return self.val

    def __set__(self, obj, val):
        print(f'ReBinding, {self.name}')
        self.val = val
    
class MeClass:
    x = YouClass(100,'x')
    y = 5

me = MeClass()
print(me.x)
me.x = 200

property class

  • 특별한 디스크립터 객체를 생성하는 내장 class
  • getter, setter, delete 메소드
  • 데코레이터 @property 사용 가능
class Property_test:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name_v):
        self._name = name_v

me = Property_test('Korea')
print(me.name)	# Korea
me.name = 'Industrial'
print(me.name)	#Industrial

 

파이썬 실습

 

1. 핸드폰 번호를 입력하면, 뒷 번호 4자리를 제외하고 *로 표시하는 코드

def handphone(number):
    n = len(number)
    answer = number.replace(number[:n-4], "*"*(n-4))    # '*'(n-4) + number[-4:]
    return answer

if __name__ == "__main__":
    num = input("enter phone number >>")
    print(f'origin: {num}, return: {handphone(num)}')

2. datetime을 사용하여 mon, day 두 수를 입력받아 무슨 요일인지 리턴하는 함수 작성, 실행

import datetime

def weekday(mon, day):
    week = ["MON","TUE","WED","THU","FRI","SAT","SUN"]
    return week[datetime.date(2020,mon,day).weekday()]

if __name__ == "__main__":
    mon,day = [int(i) for i in input("월과 일을 입력 : ").split()]
    print(weekday(mon,day))

3. 섬에 갇힌 사람들을 구명보트를 이용하여 구출할 때, 구명보트 한번에 2명씩 가능, 무게 제한도 있는 경우 구명보트의 최솟값 구하기

- 무인도에 갇힌 인원은 1 ~ 5000명 이하

- 각 사람의 몸무게는 40 ~ 160kg 이하

- 구명보트의 무게 제한은 40 ~ 160kg 이하

- 구명보트와 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없음

import random as rd

def island(num,limit):
    result = 0
    num.sort()
    slim,heavy = 0, len(num)-1
    while slim <= heavy:
        if num[slim]+num[heavy] <= limit:
            slim += 1
            heavy -= 1
            result += 1
        else:
            heavy -= 1
            result += 1
    return result
    
if __name__ == "__main__":
    num = [rd.randrange(40,161) for i in range(4)]
    limit = max(num) + 20
    print(f'{num}, {limit}, {island(num,limit)}')

 

'Programming > Python' 카테고리의 다른 글

Python 6주차 - 1  (0) 2020.07.26
Python 5주차  (0) 2020.07.26
Python 4주차 - 1  (0) 2020.07.12
Python 3주차 - 2  (0) 2020.07.12
Python 3주차 - 1  (0) 2020.07.12
Comments