관리 메뉴

IT journey

Python - 모듈(외장함수) 2편(feat.파일 입출력과 추상클래스...) 본문

개인공부공간/Python

Python - 모듈(외장함수) 2편(feat.파일 입출력과 추상클래스...)

step 2021. 5. 31. 22:38
728x90
반응형

직접 내용 정리하고 만든 예이니 퍼가실 때는 출처를 남겨주세요:)

파일과 관련 모듈을 배우기 앞서, 파일 입출력에 대해 알아봅시다.

먼저, 파일에서 데이터 읽는 방법에 대해  알아봅시다.

  • 먼저 파일을 엽니다.
  • 그 뒤, 파일에 있는 데이터를 읽거나 파일에 쓸 수 있습니다.  
  • 마지막으로, 파일과 관련된 것들이 모두 종료되면 파일을 닫아야 합니다.

이제, 파일 입출력에 대해 알아봅시다.

파일 열기 모드 설명
r/rb 읽기 모드 - 파일을 읽기만 할 때 사용합니다.
r+/rb+ 파일을 읽고 쓸 경우 사용합니다.
r+의 경우 모드 변경하려면 seek()를 호출되어야 합니다.
w/wb 쓰기 모드 - 파일에 내용을 쓸 때 사용합니다.
w+/wb+ 파일을 읽고 쓸 경우 사용(기존파일 삭제)합니다.
a/ab 추가 모드
- 파일의 마지막에 새로운 내용을 추가할 때 사용합니다.
- 파일이 없을 경우에는 새로 만듭니다.
a+/ab+ 파일 끝에 추가(읽기도 가능)
파일이 없을 경우에는 새로 만듭니다.

이 때 b는 바이너리 모드입니다. 바이너리(binary)는 컴퓨터가 처리하는 파일형식입니다.

파일 읽기 모드로 사용하게 되면 파일을 쓰거나 추가 할 수 없고 파일의 내용을 읽을 수만 있습니다.

  • Readline() : 파일의 문장 한 라인을 읽어들입니다.
  • Readlines() : 파일의 모든 라인을 읽어서 각각의 라인을 요소로 갖는 리스트로 리턴합니다.
  • Read() : 파일의 내용 전체를 문자열로 리턴합니다.

파일 쓰기 모드로 사용하게 되면

  • 해당 파일이 이미 존재할 경우 원래 있던 내용이 모두 사라집니다.
  • 해당 파일이 존재하지 않을 경우 새로운 파일이 생성됩니다.
  • writelines() : 한꺼번에 파일의 모든 라인을 씁니다.

파일 읽기 모드와 파일 쓰기 모드의 포인트 위치는 파일 처음에 위치합니다.

 

파일 추가모드를 사용하게 되면 파일을 덮어쓰지 않고 파일 마지막에 내용을 추가합니다.

파일 추가모드의 포인트 위치는 파일의 끝에 위치합니다.

 

모드 활용의 예

파일 읽기 r, r+, w+, a+
파일 쓰기 r+, w, w+, a, a+
없는 파일을 생성하기 w, w+, a, a+
파일 덮어쓰기 w, w+
파일 덧붙이기 앞쪽에 붙이기 : r+
뒤쪽에 붙이기 : a, a+

 

참고로, with open은 파일을 열고 닫는 것을 자동으로 처리할 수 있는 방법입니다.

아래는 파일 입출력에 대한 코드의 예입니다.

#파일 객체 = open(파일이름,파일 열기모드)
file = open("File_example.txt","w")

#file.write("문자열")
file.write("안녕하세요 IT journey입니다.\n")
file.write("안녕하세요 IT journey입니다.2\n")
file.close()

file= open("File_example.txt","a")

file.write("지금은 파일 테스트중입니다.\n")
file.write("지금은 파일 테스트중입니다.2\n")
file.close()

file = open("File_example.txt","r")
print(file.readline(),end="")
print(file.readline(),end="")
file.close()

file=open("File_example.txt","r")
print(file.readlines())
file.close()

#with open("파일명경로","모드") as 객체
with open("File.txt","w") as f2:
  for i in range(5):
    f2.write("안녕하세요 IT journey입니다.\n")
  
file2 = open("File.txt","r")
data = file2.read()
print(data)
file2.close()

참고로, close()는 생략해도 무방하지만 프로그램 종료 시 열린 파일 객체들을 자동으로 닫아줍니다.

하지만 될 수 있으면 직접 닫아주는 것이 올바른 방법입니다. 쓰기 모드로 열었던 파일을 닫지 않고 사용하는 경우에는 에러를 발생시키므로 닫아주는 습관을 갖는 것이 좋습니다.

본론으로 들어가 파일 관련 모듈을 알아봅시다.

- pickle

객체의 형태(기본자료형, 클래스)를 그대로 유지하면서 파일에 저장하고 불러 올 수 있는 모듈입니다.

파일명. bin 사용하는 것이 좋으며 , 파일 열기 모드는 wb, rb로 씁니다.

import pickle as p

f = open("P_example.txt","wb")
fruit = {"a":"apple","b":"banana","c":["coconut","cherry","citron"]}

#dump(데이터,파일) 형태로 씁니다.
p.dump(fruit,f) #f에 fruit 그대로 저장
f.close()

f=open("P_example.txt","rb")

a = p.load(open("P_example.txt","rb")) #읽은 것을 a 저장
print(a)
f.close()

- shutil 

파일을 복사해주는 모듈입니다.

이 모듈을 들어가기 앞서, src.txt파일과 dst.txt파일을 만들어봅시다.

src.txt 파일에는 '안녕하세요 IT journy입니다.' 를 입력하여 저장해주고dst.txt 파일에는 '지금 저희는 모듈(외장함수)2편을 보고있습니다.'를 입력하여 저장해주시면 됩니다.그 뒤 파이썬 코드창에 들어와 아래와 같이 씁니다.

import shutil
shutil.copy("src.txt","dst.txt")
#shutil.copy(src,dst) src라는 이름으로 파일을 dst로 복사합니다.
#만약 폴더로 하게 되면, src에 있는 파일을 저장하게 됩니다.

 

- glob

디렉터리에 있는 파일들을 리스트로 만들 때 사용합니다.

import glob
#파일들의 리스트를 뽑을 때 사용합니다.
print(glob.glob("*txt"))

 

- tempfile

임시파일 모듈로, 임시적으로 파일을 만들어 사용할 때 사용할 때 유용하게 쓰이는 모듈입니다.

#temfile.mktemp() : 임시로 파일을 만들어서 돌려주는 함수입니다.
#중복되지 않도록 만들어줍니다.

#temfile.TemporaryFile()
#임시적인 저장공간으로 사용된 파일 객체를 돌려주는 함수로 w+b모드를 갖습니다.

import tempfile
tp = tempfile.mktemp()
tp
t = tempfile.TemporaryFile()
t.close()

 

- sqlite3

데이터베이스와 관련된 모듈입니다.

참고로, DBMS는 데이터베이스(데이터를 저장하고 운용하는 것)의 역할을 합니다. 대표적인 용어로는 테이블(실제 데이터를 담고 있는 것)과 레코드(데이터가 담긴 구조)이 있습니다.

import sqlite3
#connect 데이터베이스를 생성합니다.
conn = sqlite3.connect('sq_test.db')
print(type(conn))
#dir(참조변수,클래스) : 문자열로 안에 있는 값을 반환합니다.
print(dir())
print(dir(conn))

 

메모리 DB접속을 한 것이므로 일회성이며 C 드라이브 안에 DBMS폴더 안에 저장합니다.

참고로, sqlite3의 자료형은 아래와 같습니다.

문자열 text
float real
int integer
None NULL

 

import sqlite3
con = sqlite3.connect('./test.db') #파일 db 접속
cur = con.cursor()
cur.execute("CREATE TABLE Zoo(Animal text,Age num,Feed text);")

#데이터 삽입
#1 기본 String Query 사용
cur.execute("INSERT INTO Zoo values('거북이','20','잡식');")
#2 Named Parameter: Dictionary 사용
animal = 'monkey'
age = '25'
feed = '바나나'
cur = con.cursor()
cur.execute("INSERT INTO ZOO values (:animal,:age,:feed);",{"animal":animal,"age":age,"feed":feed})
#3.Parameter: Tuple 사용
animal = input("동물을 입력해주세요")
age = int(input("나이를 입력해주세요"))
feed = input("먹이를 입력해주세요")
cur = con.cursor()
cur.execute('INSERT INTO Zoo VALUES(?, ?,?);', (animal, age,feed))

이번엔 데이터베이스를 읽어봅시다.

#데이터베이스 읽기 - 저장되어있는 테이블의 데이터를 읽습니다.(select *from  테이블명)
import sqlite3
con = sqlite3.connect('./test.db')
cur = con.cursor()
cur.execute("SELECT * FROM Zoo")

#fetchone() : 행 단위로 데이터를 읽는 메서드입니다. 그 값은 튜플값으로 반환합니다.
#몇 개가 있는지 알고 있는지 알 수 없으므로 for문을 써주어야 한다.
#또는 fetchall()를 통해 전체 내용을 한 번에 읽어오는 메서드를 쓰면 됩니다.
print(cur.fetchone())
con.commit()
con.close()

참고로, 생성 된 테이블에다 데이터를 추가하는 방법은 insert into 테이블명 values()를 입력해주는 것입니다.

데이터 변경하는 방법은 update 테이블명 set 필드명 where 수정하면 됩니다.

- thinter

GUI 그래픽을 지원하는 모듈입니다.

 

라벨 형태 설정

이름 의미 기본값 속성
width 라벨의 너비 0 상수
height 라벨의 높이 0 상수
relief 라벨의 테두리 모양 flat flat,groove,raised,ridge,solid,sunken
borderwidth = bd 라벨의 테두리 두께 2 상수
background = bg 라벨의 배경 색상 SystemButtonFace color
foreground = fg 라벨의 문자열 색상 SystemButtonFace color
padx 라벨의 테두리와 내용의 가로 여백 1 상수
pady 라벨의 테두리와 내용의 세로 여백 1 상수

로그인 화면만 보여주는 예입니다.

from tkinter import *
#윈도우창을 생성합니다.
win = Tk()
#윈도우 제목입니다.
win.title("login")
#geometry("너비x높이+(또는-)x좌표+(또는-)y좌표")
win.geometry("300x300+100-140")
#resizable(상하,좌우) : 창 크기를 고정한다는 말입니다
win.resizable(False, False)
#Entry 사용자로부터 입력을 받을 때 사용하는 텍스트창으로 입력한 문자열을 가지고 올 수 있습니다
#이벤트 grid(행,열)(row:가로,column:세로)
Label(win,text="ID :",fg='skyblue',bg='black').grid(row=0)
Label(win,text="Password",fg='skyblue',bg='black').grid(row=1)
e1 = Entry(win)
e2 = Entry(win)
e1.grid(row=0,column=1)
e2.grid(row=1,column=1)
def Click():
  if btn['text']=="Please Click":
    btn['text']='Butten was pressed'
  else:
    btn['text']='Please Click'
btn = Button(win, text="Login",fg='skyblue',bg='black',command=Click)
#place(x,y)는 원도우 창에서 x,y 좌표를 잡아서 위젯들을 표시해줍니다.
btn.place(x=260,y=5)
#윈도우창이 종료될 때까지 윈도우를 실행시키겠다는 의미입니다.
win.mainloop()

캔버스 형태 설정

이름 의미 기본값 속성
width 캔버스의 너비 378 상수
height 캔버스의 높이 265 상수
relief 캔버서의 테두리 모양 flat flat,groove,raised,ridge,solid,sunken
borderwidth = bd 캔버스의 테두리 두께 0 상수
borderwidth = bd 캔버스의 배경 색상 SystemButtonFace color
offset 캔버스의 오프셋 설정 0.0 x,y,n,e,w,s, ne, nw, se, sw

사각형 그리는 예입니다.

from tkinter import *
win = Tk()
win.title("Canvas")
win.geometry("300x300+100+100")
win.resizable(False, False)
label=Label(win,text="IT journey",bg='black',fg='skyblue')
#화면배치 관리자
label.pack()
#Canvas 위젯은 스케치북으로 선, 다각형, 원을 그릴 수 있습니다.
#Canvas(원도우창,파라미터1,파라미터2,...)
can=Canvas(win,width=400,height=300,bg='white')
#사각형 그림을 가지고 있는  can
#create_rectangle(시작 x,시작 y,끝 x,끝 y)
can.create_rectangle(10,10,100,100,fill='skyblue')
#윈도우 자체 크기로 압축해서 자동지정합니다. 특별한 지정이 없으면 top입니다.
#참고로 side(LEFT,Right,Top)로 지정가능합니다.
can.pack()
win.mainloop()

바인더(이벤트) 

  • 버튼이나 키 또는 마우스를 눌렀을 때 실행을 도와주는 핸들러입니다.
  • 사용하는 방법은 위젯.bind(event)입니다.
  • 위젯들에서 특정한 상황이 발생했을 때 수행할 수 있는 함수들로 연결하는 기능을 하며, 이벤트 발생시 Event Object 객체가 생성됩니다. 그러므로 event 매개변수는 꼭 작성되어야 합니다.
이름 의미
<Key> 특정 키가 입력되었을 때
<Return> Enter 키가 입력되었을 때
<Cancel> Break 키가 입력되었을 때
<Pause> Pause 키가 입력되었을 때
<BackSpace> 백스페이스 키가 입력되었을 때
<Caps_Lock> 캡스 락 키가 입력되었을 떄
<Escape> 이스케이프 키가 입력되었을 때
<Home> Home 키가 입력되었을 때
<End> End 키가 입력되었을 때
<Insert> Insert 키가 입력되었을 때
<Delete> Delete 키가 입력되었을 때
<Prior> Page Up 키가 입력되었을 때
<Up> 위쪽 방향키가 입력되었을 때
<Down> 아래쪽 방향키가 입력되었을 때
<Right> 오른쪽 방향키가 입력되었을 때
<Left> 왼쪽 방향키가 입력되었을 때
focus_set() 포커스를 틀 위젯을 설정

공 오른쪽 왼쪽 왔다갔다하는 예입니다.

from tkinter import *
def Keyboard_Click(event):
  print("키보드".event.keycode)
win = Tk()
win.title("Canvas")
win.geometry("300x300+100+100")
win.resizable(False, False)
label=Label(win,text="IT journey",bg='black',fg='skyblue')
label.pack()
class roll_ball():
  def __init__(self,x,y,can):
    self.x=x
    self.y=y
    self.can = can
    self.ball = self.can.create_oval(self.x,self.y,20,20,fill='skyblue')
    print("You made a ball")

  #이동을 할 때 메서드
  def move_left(self,event):
    can.move(self.ball,-25,0) #오른쪽으로 25씩 이동 //move(객체,x,y) 이동
    can.after(10) #0.01 기다린다는 의미 // after() : ms 단위로 설정 1초~1000
    can.update() #기존 그림을 지우고 새로 그릴 수 있도록 하는 메서드입니다.

  def move_right(self,event):
    can.move(self.ball,25,0)
    can.after(10)
    can.update()   


can=Canvas(win,width=400,height=300,bg='white')
can.pack()
b1 = roll_ball(10,10,can)
can.bind("<Left>",b1.move_left)
can.bind("<Right>",b1.move_right)
can.focus_set()
win.mainloop()

모듈의 name 속성

#클래스, 변수, 함수를 포함하는 모듈입니다.
int_a = 6
String_b = "IT journey"
Bool_c = True
list_d = [1,2,3,4,5,6]
tuple_e = (7,8,9,10)
dic_f = {0:"apple"}
set_g = set([1,2,3,4])

def module_T():
  print("이것은 모듈 테스트입니다.")

class calucate:  
  def add(self,a,b):
    print("두 개를 더할 때 실행")
    print(a+b)
  
  def sub(self,a,b):
    print("두 개를 뺄 때 실행")
    print(a-b)

  def div(self,a,b):
    print("두 개를 나눌 때 실행")
    print(a/b)

  def floordiv(self,a,b):
    print("두 개를 나눗셈을 한 후 소수점 이하를 버림")
    print(a//b)

if __name__=="__main__":
  print(int_a)
  cal = calucate()
  print(cal.sub(50,40))
  print(module_T)

모든 모듈은 이름을 갖고 있습니다. 모듈의 name 속성을 이용하면 외부로부터 불러들여졌을 때 바로 실행되지 않게 할 수 있습니다. 함수의 속성을 이용하고 싶은 것이기에 위처럼 name을 이용합니다.

name 속성을 이용해서 모듈이 사용자에 의해서 직접 실행되는 경우(name이 main일 경우)에는 해당 모듈의 이름을 알 수 있기 때문에 해당 내용을 출력할 수 있습니다. 그렇지 않은 경우에는 함수만을 사용하기 위해 사용했던 것을 이용할 수 있게 됩니다. 

바이트코드

모듈을 불러올 때 좀 더 빠르게 처리할 수 있도록 하기 위해서 .pyc(바이트 코드 형태의 (컴파일된)) 확장자를 가지는 바이트 코드를 할용합니다. 컴파일 할 때 만들어놓는 파일로, 모듈을 불러올 때 .pyc 파일을 이용하여 불러오게 됩니다. 이러한 바이트 코드는 플랫폼에 구애받지 않고 사용됩니다.

참고로, 파이썬이 저장 디렉터리에 쓰기 권한이 없을 경우에는 생성되지 않습니다.

모듈을 불러와야만 만들 수 있는 클래스(추상클래스)를 알아봅시다.

들어가기 앞서, Python - 클래스 1편 과 Python - 클래스 2편 그리고  Python - 모듈(외장함수) 1편을 참고 부탁드립니다.

이제 추상 클래스 구조와 예에 대해 알아봅시다.

#추상 클래스 구조
from abc import *

class 추상 클래스 이름(methaclass=ABCMeta):
	@abstractmethod
    def 메서드 이름(self):
    	코드
        
#사용한 예
from abc import *

class Animal(metaclass=ABCMeta): #추상메서드
  @abstractmethod
  def Animal_info(self):
    pass

  @abstractmethod
  def eat(self):
    pass

class Monkey(Animal):
  def Animal_info(self): #추상메서드 구현
    print("저는 원숭이입니다.")
    print("제 나이는 20살입니다.")
  
  def eat(self): #추상메서드 구현
    print("제가 좋아하는 먹이는 바나나 입니다.")

monkey = Monkey()
monkey.Animal_info()
monkey.eat()

추상 클래스를 상속받았다면 @abstactmethod가 붙은 추상메서드를 모두 구현해주어야 합니다.

그렇지 않으면 에러가 납니다. 추상 클래스의 추상메서드를 모두 구현했는지 확인하는 시점은 파생 클래스(자식클래스)가 인스턴스를 만들 때입니다. 다시 말해 이 예에서는 monkey = Monkey()에서 확인한다는 말입니다.

 

그렇다면 추상메서드를 빈메서드로 만드는 이유는 호출할 일이 없으므로 빈 메서드로 만듭니다.

추상클래스는 인스턴스로 만들 수가 없습니다. 파생 클래스(자식 클래스)에서 반드시 구현해야 할 메서드를 정해 줄 때 사용하게 됩니다.

 

이번에는 모듈을 계층적(디렉터리 구조)으로 관리해주는 패키지에 대해 알아봅시다.

쉽게 표현하면, 폴더(패키지) 안에 모듈을 담는다고 생각하면 됩니다.

패키지를 사용하는 이유

  • 파이썬 모듈을 사용할 때 관련 있는 모듈을 묶어주기 때문입니다.
  • 모듈 이름이 중복으로 사용되지 않고 구별하기 위해서 입니다.

이번엔 패키지를 만들어봅시다.

AAA 폴더를 만듭니다.

그 아래 BBB 폴더와 test.py를 만듭니다.

#test.py에 아래와 같이 입력합니다.
def show():
  print("안녕하세요")

BBB 폴더 아래 CCC 폴더와 test.py를 만듭니다.

def show():
  print("BBB에 있는 안녕하세요 입니다")

CCC 폴더 아래 test.py를 만듭니다.

def show(): #내장함수
  print("CCC에 있는 안녕하세요 입니다.")

def info():
  print("CCC에 있는 info입니다.")

마지막으로 main.py에 아래와 같이 만듭니다.

import sys
sys.path
sys.path.append("C:\\")
sys.path
import AAA
import AAA.test
AAA.test.show()

import AAA.BBB.test
AAA.BBB.test.show()

import AAA.BBB.CCC.test
AAA.BBB.CCC.test.info() #CCC에 있는 test.py에서 info 부르는 법입니다.

#from 패키지, 패키지(폴더) import *(모듈, 
#'*'의 의미는 모듈 내에 있는 모든 함수들을 의미합니다.)

코드의 내용을 그림으로 다시 한번 보겠습니다.

보기 앞서, CCC는 자식폴더라고 볼 수 있고 BBB는 부모폴더라고 볼 수 있다는 것까지 알고 있다면 한결 쉽게 이해할 수 있을 꺼라고 봅니다. 

이번에는 접근 제어자를 알아봅시다.

  • public : 클래스 안, 밖 모두 접근 가능합니다. (문법을 쓰는 예는 name)
  • private : 클래스 내부에서만 접근 가능합니다. (문법을 쓰는 예는 __name)
  • protected : 해당클래스와 그 하위(자식클래스) 접근 가능합니다. 자식클래스 객체를 생성합니다. (문법을 쓰는 예는 _name)

이전 발행 글

Python - 설치없이 이용하기,실행, 사용법

Python - 모듈(외장함수) 1편

Python - 클래스 2편

Python - 클래스 1편

Python-함수

Python - 제어문

Python-자료형(사전형,집합)

Python-자료형(리스트,튜플)

Python - 자료형 (숫자형,문자열,불린형)

 Python - 내장함수 1편

728x90
반응형
Comments