1. CSV 파일이란?

🚀  Comma Separated Values의 약자로 '콤마로 분리한 값들'
🚀  데이터베이스나 스프레드시트 데이터를 저장하기 위해서 사용하는 형식
     

     ⚡️ 내부는 실제 콤마(,)를 이용해서 모든 항목이 구분되어 있으며

          콤마로 구성된 각 항목들이 테이블을 구성하는 각각의 데이터가 되는 방식
     ⚡️ 메모장에서는 텍스트로, 엑셀에서는 각 셀로 나누어서 보임

텍스트 파일
엑셀 파일


🚀  utf-8 형식으로 저장된 csv의 경우, 엑셀에서는 기본읽기로는 한글이 깨지는 경우가 있음
       ➡️  한컴 cell에서는 에러없이 잘 열림



1) 단점 ( 엑셀 형식의 파일과 비교했을 때 )

 

  a.  값에 유형이 없음. 모든 것은 다 문자열
  b.  글꼴 크기나 색상을 설정할 수 없음
  c.  여러 개의 워크시트를 가질 수 없음
  d.  셀의 너비나 높이를 지정할 수 없음
  e.  셀을 병합할 수 없음
  f.  그림이나 차트를 포함할 수 없음



2) 장점


  a.  단순함
 b.  많은 프로그램에서 지원을 하고, 텍스트 편집기에서 볼 수 있으며, 스프레드 시트 데이터를 표현하는 간단한 방법



3) 주의점


  ⚡️  텍스트로 구성되어 있어서, 각 줄에 대해 split(',')을 호출하여 쉼표로 구분된 값에서 문자열 리스트를 얻을 수 있음
         ➡️   csv 파일의 모든 쉼표가 두 셀의 경계를 나타내지 않고, 값의 일부인 경우도 있음
         ➡️  이런 잠재적인 문제 때문에 csv 파일을 읽거나 쓸 때 csv 모듈을 사용하는 것이 좋음

 


 

2. CSV 파일 읽기

🚀  csv 파일은 쉼표(,)로 데이터가 구분되어 있어서 문자열 처리 메소드를 활용하면 별도의 외부 모듈이 없이도 충분히 읽을 수 있음
🚀 
한 줄에 한 데이터가 있기 때문에 readline() 메소드로 한 줄씩 읽음
🚀 
콤마(,)로 분리하기 위해서 split() 메소드를 이용

 

학생명단.csv

student_list = []
with open('../input_2/학생명단.csv', 'rt', encoding='cp949') as file:
    file.readline()  # 학번, 이름, 주소, 연락처
    # readlines()는 한꺼번에 모두 읽고 커서가 맨 끝에 있어 더 이상 읽을 게 없어짐
    while True:
        line = file.readline()
        if not line:  # 더 이상 읽을 내용이 없으면 반복문을 빠져 나옴.
            break
        student = line.split(',')  # 안 넣으면 하나의 문자열로 생성되기 때문
        student_list.append(student)
print(student_list)  # 리스트 안에 리스트가 들어가 있는 형태
'''
[['10101', '김승별', '서울시 영등포구', '010-1111-1111\n'], 
['10102', '박나라', '서울시 여의도구', '010-2222-2222\n'], 
['10103', '최태욱', '서울시 강남구', '010-3333-3333\n'], 
['10104', '민기홍', '인천시 계양구', '010-4444-4444\n'], 
['10105', '이명숙', '경기도 과천시', '010-5555-5555\n']]
'''

 


 

 📌  csv 파일을 사용하다 보면 간혹 큰 따옴표(")를 이용해서 텍스트를 묶는 경우가 있음
        ➡️  큰 따옴표를 제거하기 위해서 회원명에 추가로 strip() 메소드를 사용

회원명단.csv

member_list = []
with open('../input_2/회원명단.csv', 'rt', encoding='cp949') as file:
    file.readline()
    while True:
        line = file.readline()
        if not line:
            break
        member = line.split(',')  
        member[0] = member[0].strip('"')  # 큰 따옴표를 제거
        member_list.append(member)
print(member_list)
'''
[['강나라', '필라테스', '25일\n'], ['나유라', '수영', '25일\n'], ['이상기', '헬스', '15일\n']]
'''

 

  👾  member[0]에는 큰 따옴표가 포함된 회원명이 저장되어 있기 때문에 member[0].strip('"')으로 큰 따옴표를 제거

 


📌  인코딩 시 영어는 문제가 없는데 한글의 경우 표현하는 방식이 2가지
     -  cp949 : 윈도우의 기본 인코딩. 예전 방식. 한글에만 특수화된 한국에서만 사용. 모든 한글을 표현하지 못함.
     -  uft-8 : 파이참의 기본 인코딩. 상대적으로 새로운 방식. 한글 및 기타 외국어 문자를 하나의 인코딩으로 모두 표현하기 개발

 


 

3. CSV 모듈

1) csv 모듈로 csv 파일 생성하기

 

 🚀  import csv 를 통해서 csv 파일을 쉽게 처리할 수 있는 csv 모듈을 사용

import csv

# w모드로 열고 생성된 파일 객체를 csv.writer() 메소드에 전달
# 그러면 csv 파일을 생성할 수 있는 객체가 생성되는데 이 객체를 이용해서
# writerow() 메소드를 호출하면 csv 파일에 데이터를 저장할 수 있음

with open('../output_02/차량관리_01.csv', 'w', newline='', encoding='cp949') as file:
    # delimiter=',' : ,콤마로 데이터 구분. tab을 사용하는 경우도 있음.tsv.
    csv_maker = csv.writer(file, delimiter=',')
    csv_maker.writerow([1, '08러1234', '2020-10-20,14:00'])
    csv_maker.writerow([2, '25다1234', '2020-10-20,14:10'])
    csv_maker.writerow([3, '28하1234', '2020-10-20,14:20'])
print('차량관리_01.csv 파일이 생성되었습니다.')

 


2) csv 모듈로 csv 파일 읽기

 🚀  csv 파일을 읽기 위해서는 r 모드로 파일을 열고 생성된 파일 객체를 csv.reader() 메소드에 전달
 🚀  csv.reader() 메소드는 csv 파일을 읽고 그 내용을 읽고 저장한 객체 iterator를 반환

with open('../output_02/차량관리_01.csv', 'r', newline='', encoding='cp949') as file:
    csv_reader = csv.reader(file, delimiter=',')
    for line in csv_reader:
        print(line)
        
'''
['1', '08러1234', '2020-10-20,14:00']
['2', '25다1234', '2020-10-20,14:10']
['3', '28하1234', '2020-10-20,14:20']
'''

차량관리_01.csv


 

3) reader 객체

 

🚀  csv 모듈은 별도의 설치없이 사용가능

🚀  csv 모듈을 사용해서 csv 파일을 읽으려면 다른 텍스트 파일처럼 open() 함수로 파일을 열어야 함

 

import csv

example_file = open('../input_2/example.csv', encoding='cp949')  # mode를 생략하면 rt가 기본값

# read() 대신 csv.reader() 함수에 전달. reader() 객체가 반환.
example_reader = csv.reader(example_file)

# list로 변환하여 값에 접근.
print(example_reader)  # <_csv.reader object at 0x100eadcb0>
example_data = list(example_reader)
print(example_data)
print(example_data[0][1])  # Apples
example_file.close()  # with 사용한 것이 아니기 때문에 닫아줘야 함

 


 

4)  for 반복문을 활용해 reader 객체로부터 데이터 읽기


🚀  csv 파일이 큰 경우에는 전체 파일을 한 번에 메모리에 로드하지 않고 for 반복문에서 reader 객체 사용
🚀  reader 객체는 한 번만 사용가능하기 때문에 다시 사용하려면 새로 reader 객체 생성

example_file = open('../input_2/example.csv', encoding='cp949')
example_reader = csv.reader(example_file)

print('example.csv 출력')
for row in example_reader:
    # 각 행의 번호를 얻으려면 reader 객체의 line_num 변수를 사용
    print(f'Row #{str(example_reader.line_num)} {str(row)} {str(row[0])}')
example_file.close()
print('=' * 20)

 


5) writer 객체

 

🚀  writer 객체를 사용하면 데이터를 csv 파일에 저장할 수 있음

output_file = open('../output_02/output.csv', 'w', newline='', encoding='cp949')
# newline = '' : 빈줄이 들어가는 것 방지
output_writer = csv.writer(output_file)  # csv.writer에 전달할 객체 생성.
output_writer.writerow(['spam', 'eggs', 'bacon', 'ham'])  # writer.writerow() : 리스트에 인자를 전달
output_writer.writerow(['hello, world!', 'eggs', 'bacaon', 'ham'])
output_writer.writerow([1, 2, 3, 3.141592, 4])
output_file.close()

output.csv


 

4.  키워드 인자 delimiter와 lineterminator

🚀  탭문자로 셀을 구분하고 줄 간격을 한 줄씩 띄우려는 상황이라면 구분자(delimiter)와 줄 끝 문자(lineterminator)를 변경
🚀  delimiter의 기본값은 쉼표이고, lineterminator의 기본값은 개행문자
🚀  셀들이 탭으로 구분되어 있기 때문에 탭으로 구분된 값을 의미하는 .tsv 파일 확장자 사용

csv_file = open('../output_02/example.tsv', 'w', newline='', encoding='cp949')
csv_writer = csv.writer(csv_file, delimiter='\t', lineterminator='\n\n')
csv_writer.writerow(['apples', 'oranges', 'grapes'])
csv_writer.writerow(['eggs', 'bacon', 'ham'])
csv_writer.writerow(['spam', 'spam', 'spam', 'spam', 'spam', 'spam'])
csv_file.close()

 


 

5. csv 객체의 DictReader와 DictWriter

🚀  헤더 행이 있는 csv 파일의 경우 reader나 writer 객체보다 DictReader나 DictWriter 객체를 사용하는 것이 작업하기 편함

 

  ⚡️  DictReader 객체

        a. row를 딕셔너리 객체로 설정하고 

        b. 첫 번째 행에 있는 정보를 건너 뜀 

        c. 첫 번째 행에 있는 정보를 키값으로 사용

example_file = open('../input_2/example_with_header.csv', encoding='cp949')
example_dict_reader = csv.DictReader(example_file)

print('example_with_header.csv 출력')
for row in example_dict_reader:
    #print(row)
    print(f'{row["Timestamp"]}, {row["Fruit"]}, {row["Quantity"]} ')
print('=' * 20)

example_with_header.csv


 

🚀  헤더 행이 없는 파일의 경우  DictReader() 생성자의 두 번째 인자로 헤더 이름을 지어서 전달

example_file = open('../input_2/example.csv')
example_dict_reader = csv.DictReader(example_file, ['time', 'name', 'amount'])
print('example.csv 출력')
for row in example_dict_reader:
    print(f'{row["time"]}, {row["name"]}, {row["amount"]} ')
print('=' * 20)

 


 

 

  ⚡️ DictWriter 객체는 csv 파일을 생성하기 위해 딕셔너리를 사용

       -  파일에 헤더 행을 넣고 싶으면 writeheader()를 호출

       -  writerow() 메서드를 호출하여 각 행을 쓸 수 있는데, 이 때 딕셔너리를 사용
            ➡️ 딕셔너리의 키는 헤더이고, 딕셔너리의 값은 파일에 쓰려는 데이터가 들어감

output_file = open('../output_02/output_with_header.csv', 'w', newline='', encoding='cp949')
output_dict_writer = csv.DictWriter(output_file, ['Name', 'Pet', 'Phone'])

output_dict_writer.writeheader()

output_dict_writer.writerow({'Name': 'Alice', 'Pet': 'cat', 'Phone': '555-1234'})
output_dict_writer.writerow({'Name': 'Bob', 'Phone': '555-9999'})  
# 누락된 키는 빈 상태로 나옴.
output_dict_writer.writerow({'Phone': '555-5555', 'Name': 'Carol', 'Pet': 'dog'})  
# 순서는 중요하지 않음.
output_file.close()

output_with_header.csv

 

 

 


 

1. mutable & immutable

👩🏻‍💻  mutable : 생성된 후에도 변경이 가능한 자료형 

        ex. list, set, dict

👩🏻‍💻 immutable : 생성된 후에는 변경이 불가능한 자료형 

        ex. int, float, str, tuple

# mutable
# 할당받는 메모리에 저장된 값을 다른 값으로 바꿀 수 있음
# id() : 객체의 고유값 반환. 메모리 주소를 구별하기 위한 용도로 사용
me = [1, 2, 3]
print(id(me)) # 4370596288
me.append(4)
print(id(me)) # 4370596288 / 할당된 메모리 주소는 변경이 되지 않음

# immutable
# 한 번 생성하면 최초로 저장된 값을 다른 값으로 바꿀 수 없음
obj = 10
print(id(obj)) # 4343431696
obj = obj + 1
print(obj) # 11
print(id(obj)) # 4343431728 / 할당된 메모리 주소가 변경이 됨
# 메모리에 저장된 데이터를 수정하는 것이 아니라, 새로 할당을 받아서 데이터를 저장

 


 

2. % 연산자

      %s : string 

      %f : float

      %d : decimal (십진법)
name = 'Kai'
print('내 이름은 %s 입니다.' % name) # 내 이름은 Kai 입니다. 
print('내 이름은 ', name, '입니다.', sep='')
print('내 이름은 ' + name + '입니다.')

height = 120.5
print('내 키는 %fcm입니다.' % height)  # 내 키는 120.500000cm입니다. 

weight = 23.55
print('내 몸무게는 %.1fkg입니다.' % weight)  # 내 몸무게는 23.6kg입니다.

year, month, day = 2014, 8, 25
print('내 생일은 %d년 %d월 %d일 입니다.' % (year, month, day))
# 내 생일은 2014년 8월 25일 입니다.

 


 

3. 삼항 조건 연산자

👩🏻‍💻  일반적인 삼항 조건 연산자 : 조건식 ? 참 : 거짓
👩🏻‍💻  파이썬 삼항 조건 연산자 : 참 if 조건식 else 거짓

a = 10
b = 20
result = (a - b) if (a >= b) else (b - a)
print('{}과 {}의 차이는 {}입니다.'.format(a, b, result)) # 10과 20의 차이는 10입니다.

 

4. 지역변수/전역변수

1) 지역 변수 local variable

 

  📁  함수 내부에서 선언한 변수는 함수 내부에서만 사용.  함수 외부에서는 지역변수에 접근할 수 없음

def f():
    a = 10
    print(f'f()내부 : {a}')

f()  # f() 내부 : 10
# print(f'f() 외부 : {a}')  # 함수 외부에서는 a 변수를 사용할 수 없음

 


 

2)  전역변수 global variable


📁 함수 외부에서 선언한 변수는 함수 내부나 함수 외부에서 모두 사용할 수 있음

def f():
    print(f'f() 내부 : {b}')  

b = 10 # 전역변수
f() # f() 내부 10
print(f'f() 외부 : {b}')  # f() 외부10

# 1) 전역변수를 단순히 참조만 하는 경우 -> 읽기만 하는 경우
a = 0
def f():
    print(a)  # 함수 f() 내부에서 전역변수 a를 참조

f()  # 0
print(a)  # 0 / 함수 f() 외부에서 전역변수 a를 참조


# 2) 전역변수의 값을 변경하는 경우
a = 0

def f():
    global a  # 전역변수 a를 사용
    a = 10  # 전역변수 a의 값을 변경

f()  # 함수 f() 실행
print(a)  # 10 / 전역변수의 변경된 값을 확인

 

 

 

 

 

[ 내용 참고 :  IT 학원 강의 ]


 

1. 파일

📁  변수는 프로그램을 실행할 때 데이터를 저장하기 좋은 방법
        ➡️  그러나 프로그램을 종료한 후에도 데이터를 유지하고 싶다면, 파일 형태로 저장해야 함

 

1) 파일과 파일 경로

 

   ⚡️  파일에는 파일 이름과 경로라는 두 가지 주요속성이 있다.
          ex. 윈도우 운영체제를 사용하는 노트북 컴퓨터의 C:\Users\al\Documents 라는 경로에

                 project.docx 라는 이름의 파일이 있는 경우
                  ▶️  파일이름 project.docx는 워드 문서이고 Users, al, Documents는 모두 폴더(디렉토리)
                  ▶️  폴더 안에는 파일이나 다른 폴더가 들어 있을 수 있음

   ⚡️ 경로의 C:\는 루트 폴더를 나타내며 모든 폴더가 이 안에 들어 있음
          📌  윈도우에서 루트 폴더의 이름은 "C:\"이며, C 드라이브라고 부름.
          📌  맥os나 리눅스에서 루트 폴더는 "/"
          📌  윈도우, 맥os에서는 폴더이름이나 파일이름의 대소문자를 구분하지 않지만, 리눅스의 경우 이를 구분함

   ⚡️ 윈도우에서의 폴더 구분은 "\" 백슬러시를 사용하고, 맥 os나 리눅스에서는 "/" 슬러시를 사용함.

# 1) Path 객체 사용.
from pathlib import Path
path = Path('spam', 'bacon', 'eggs')  # 운영체제에 맞는 경로 체제를 만들어 줌.
print(path)  # spam/bacon/eggs

# 2) platform.system() 함수 사용.
import platform
my_os = platform.system()
print("OS in my system: ", my_os)  # OS in my system:  Darwin
if my_os == 'Darwin':
    print('Mac 운영체제 입니다.')
else:
    print('Mac 운영체제가 아닙니다.')
# 현재 작업 디렉토리
print(Path.cwd())  # /Users/Desktop/pycharm/pythonProject/part2

 

2) 절대 경로와 상대 경로


⚡️ 절대 경로 : 항상 루트 폴더에서 시작하는 경로
⚡️ 상대 경로 : 현재 작업 디렉토리에 대한 경로 
     📌  '.' : 현재 디렉토리
    📌  '..' : 상위 디렉토리


 

3) 새로운 디렉토리 만들기

 

⚡️ os.makedirs() 함수로 새로운 디렉토리를 만들 수 있음
⚡️ os.path.isdir(path) : path 인자의 디렉토리가 있는지 확인

import os
path = './test'
if not os.path.isdir(path):
    os.makedirs(path)  # 현재 작업 폴더 안에 test라는 폴더 생성.

 

4) 파일 크기와 폴더 내용 확인

 

⚡️ os.path.getsize(path) : path 인자에 해당하는 파일 크기 반환
⚡️ os.listdir(path) : path에 있는 파일 이름 리스트를 반환

path = './input'
print(os.path.getsize(f'{path}/hello.txt'))  # 53
list_dirs = os.listdir(path)
print(list_dirs)  # ['연락처.txt', 'hello.txt', '엄마돼지아기돼지.txt']

 


 

2. 파일 열기

📁  입출력 파일을 지정하는것을 의미 ( 파일 객체 생성 )
📁  파일 입력과 파일 출력 모두 반드시 파일 열기 작업을 가장 먼저 수행

파일객체 = open(파일명, 모드)


1) 파일명

🚀  입출력 작업을 수행할 파일을 의미
🚀  파일명만 작성할 수도 있고 경로를 함께 작성할 수도 있음

# 파일명만 작성하는 경우 : 파이썬 소스 파일과 같은 경로에 존재하는 경우
open('sample.txt')

# 전체 경로를 작성하는 경우 : 빈도가 적음.
open('C:/sample.txt')

# 현재 디렉터리(.)를 기준으로 경로를 결정
open('./sample.txt')
open('./input/hello.txt')

# 상위 디렉터리(..)를 기준으로 경로를 결정
open('../sample.txt')

2) 모드

r (read) 읽기
w (write) 쓰기 (새로 쓰기 모드)
a (append) 추가 (뒤에 이어서 쓰기 모드)
x (exclusive) 배타적 추가 (파일 있으면 오류, 없으면 새로 생성)


🚀  파일의 종류
     - t (text) 텍스트 파일 : 메모장으로 열 수 있는 파일
     - b (binary) 바이너리 파일 (텍스트 파일 외의 모든 파일)


 

3. 파일 닫기

👾  파일을 더 이상 사용하지 않거나 프로그램을 종료하고자 할 때

파일객체.close()

 


 

4. 파일 생성

file = open('./output/my_file.txt', 'wt')  # 빈파일 생성
print('my_file.txt 파일이 생성되었습니다.')
file.close()

# 텍스트 파일을 새로 만들 수 있는 모드인 wt 모드를 사용하여 my_file.txt라는 이름의
# 텍스트 파일을 output 이라는 디렉토리에 생성하는 코드

🚀   with문
    -  close() 메소드를 자동으로 호출할 수 있는 문법을 제공
    -  with문을 사용하면 with문이 끝날 때 언제나 close() 메소드가 자동으로 호출

         ➡️  별도의 예외 처리를 하지 않더라도 프로그램이나 파일의 에러로 close()가 호출이 안되는 상황을 방지

# 기본 구성
with open (파일명, 모드) as 파일객체:
    파일처리코드
with open('./output/my_file_1.txt', 'wt') as file:
    print('my_file_1.txt 파일이 생성되었습니다.')

 

5.  파일 입출력

📁  파일 입출력 : 컴퓨터에 저장된 파일을 읽어 들이는 것은 물론 파일을 생성해서 컴퓨터에 저장하는 것도 가능
    📌 파일 입력 input : 기존의 파일 내용을 읽어 들이는 것
    📌 파일 출력 output : 기존 파일에 새로운 내용을 추가하거나 새로운 파일을 생성하는 것

 

1) 파일 출력 output

# 1. 텍스트 파일 생성하기
file = open('./output/hello.txt', 'wt')

# hello.txt에 글 쓰기.
file.write('안녕하세요.')
file.write('\n')  # 줄 바꿈
file.write('반갑습니다.')
file.write('\n')
print('hello.txt 파일이 생성되었습니다.')  # 진행 상황을 알기 위해서 화면 출력.

file.close()

# 2. 텍스트 파일에 내용 추가하기
# 기존 파일에 내용을 추가할 수 있는 모드는 a 모드
file = open('./output/hello.txt', 'at')

file.write('Hello.\n')
file.write('Nice to meet you.\n')
print('hello.txt 파일에 새로운 내용이 추가되었습니다.')

file.close()

 


2) 파일 입력  input

1)  read() 메소드

📁  파일로부터 데이터를 읽어 들이는 메소드
📁  텍스트 모드와 바이너리 모드에서 다른 방식으로 동작

file.read(size)


    👾  반환값 : 텍스트 모드 - 읽어 들인 문자열, 바이너리 모드 - 읽어 들인 바이트열
    👾  매개변수 size : 텍스트 모드- 읽어 들일 최대 문자의 개수, 바이너리 모드- 읽어 들일 최대 바이트 수
    👾  매개변수 size 생략 : 파일 전체 읽음
    👾  파일의 끝에 도달 : 빈 문자열 ('') 반환

file = open('./input/hello.txt', 'rt', encoding='cp949')

str = file.read()  # 파일 전체를 한 번에 읽어 들임
print(str, end='')

file.close()

 

    💡 'encoding = cp949' 는 맥 os 에서 파일 처리할 때 사용


2)  readline() 메소드

📁  텍스트 파일을 한 줄씩 읽어서 처리하는 메소드
📁  파일이 종료되어 더 이상 읽어 들일 글자가 없으면 빈 문자열('')을 읽어 들임
📁  반복문을 이용해서 여러 번 읽어 들어야 파일 전체를 읽어 들일 수 있음

file = open('./input/hello.txt', 'rt', encoding='cp949')

while True:
    str = file.readline()
    if str == '':
        break
    print(str, end='')

file.close()

3) readlines() 메소드

📁  라인 line 하나가 아니라 전체 라인 lines을 모두 읽어 각 라인 line 단위로 리스트에 저장하는 메소드

file = open('input/hello.txt', 'rt', encoding='cp949')

line_list = file.readlines()
print(line_list) # ['안녕하세요.\n', '반갑습니다.\n', 'Hello.\n', 'Nice to meet you.\n']
for line in line_list:
    print(line, end='')

file.close()

# enumrate() 함수를 이용하면 라인 번호 line number 도 함께 출력할 수 있다
file = open('input/hello.txt', 'rt', encoding='cp949')

line_list = file.readlines()
for no, line in enumerate(line_list):
    print('{} {}'.format(no + 1, line), end='')

file.close()

# sys 모듈을 이용하면 보다 쉽게 파일을 읽을 수 있다
# sys 모듈에는 표준 입출력을 위한 stdin과 stdout 객체가 포함
# stdout은 출력을 위한 객체이며 화면 출력 메소드인 write()와 writelines() 메소드를 사용할 수 있음
# writelines() 메소드를 사용하면 리스트와 같은 반복 가능한 객체의 각 요소를 한 줄씩 자동으로 출력

import sys

file = open('input/hello.txt', 'rt', encoding='cp949')

line_list = file.readlines()
sys.stdout.writelines(line_list)

file.close()

 


 

6. pickle

📁  텍스트가 아닌 자료형 (리스트나 딕셔너리 자료형등)을 저장하기 위한 방식
📁  import pickle을 통하여 모듈 임포트가 필요
📁  pickle로 데이터를 저장하거나 불러올때는 파일을 바이너리 형식으로 읽거나 써야함 (wb, rb)
📁  모든 파이썬 데이터 객체를 저장하고 읽을 수 있음

import pickle
data = {
    'a': [1, 2.0, 3, 4 + 6j],
    'b': ("character string", "byte string"),
    'c': {None, True, False}
}
print(type(data))  # <class 'dict>

# 1. 일반 텍스트 파일 형식을 사용하는 경우.
# 저장
with open('./output/data.txt', 'w') as file:
    # file.write(data)  # TypeError: write() argument must be str, not dict
    file.write(str(data))  # write() 메서드의 인자는 문자열이어야 함.

# 읽기
with open('./output/data.txt', 'r') as file:
    data_output = file.read()
print(data_output)  
# {'a': [1, 2.0, 3, (4+6j)], 'b': ('character string', 'byte string'), 
# 'c': {False, True, None}}
print(type(data_output))  #  <class 'str'>

# 2. pickle 방식을 사용하는 경우
# 저장
with open('./output/data.my_pickle', 'wb') as file:
    pickle.dump(data, file)

# 읽기
with open('./output/data.my_pickle', 'rb') as file:
    data_output = pickle.load(file)  # 읽음.

print(data_output)  
# {'a': [1, 2.0, 3, (4+6j)], 'b': ('character string', 'byte string'), 
# 'c': {False, True, None}}
print(type(data_output))  # <class 'dict'>
print(data_output.get('a'))  # [1, 2.0, 3, (4+6j)]

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  외부 모듈의 이용

📁  외부 모듈은 다른 사람들이 만들어 배포하는 모듈을 말함

 

1) 패키지

    👾  모듈의 상위 개념으로 모듈의 집합을 의미
    👾  파이썬에서 기본적으로 제공하지 않더라도 외부에서 만들어진 패키지를 이용하면 패키지에 포함된 모듈을 사용할 수 있음


2) 패키지 관리자

    👾  외부 모듈을 사용하기 위해서는 우선 모듈이 포함된 패키지를 추가로 설치
    👾  pip라고 불리는 패키지 관리자를 사용해서 패키지를 추가, 삭제


3) 패키지 설치

💡  보통 관심있는 분야와 관련된 모듈을 검색해서 설치

       📌  맥os 에서는 터미널에 입력하여 설치

 pip install package


    👾  numpy 패키지수치해석과 통계에서 많이 사용

import numpy as np
print(np.sum([1, 2, 3, 4, 5]))  # 15

 


   

    👾  Beautiful Soup는 파이썬 웹 페이지 분석 모듈

# Beautiful Soup 모듈로 날씨 가져오기
from urllib import request
from bs4 import BeautifulSoup

# urlopen() 함수로 기상청의 전국 날씨 읽기
target = request.urlopen("http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108")

# 웹페이지 분석
soup = BeautifulSoup(target, "html.parser")

# location 태그 찾기
for location in soup.select("location"):
    # 내부 city, wf, tmn, tmx 태그를 찾아 출력
    print("도시:", location.select_one("city").string)
    print("날씨:", location.select_one("wf).string)
    print("최저기온:", location.select_one("tmn").string)
    print("최고기온:", location.select_one("tmx").string)
    print()
    
'''
도시: 서울
날씨: 구름많음
최저기온: 3
최고기온: 9

도시: 인천
날씨: 구름많음
최저기온: 2
최고기온: 8

도시: 수원
날씨: 구름많음
최저기온: 2
최고기온: 10
...생략...
'''

 

  📌  urllib는 URL 작업을 위한 여러 모듈을 모은 패키지 

  📌  태그를 여러개 선택할 때 select(), 한 개 선택할 때 select_one() 사용하여 값 추출

 


 

    👾  Django는 다양한 기능을 제공하는 웹 개발 프레임워크, Flask는 작은 기능만을 제공하는 웹 개발 프레임워크

pip install flask
from flask import Flask
app = Flask(__name__)

@app.rout("/")
def hello():
    return "<h1>Hello World!</h1>"
# @app.route() 는 데코레이터

 

# 맥 os 에서 Flask 코드 실행 방법
export FLASK_APP=파일 이름.py
flask run
# 터미널에 입력

 

    ⚡️  프로그램 종료할 때는 Ctrl + C


4) 패키지 삭제

pip uninstall package
ex. pip uninstall numpy

 


 

2. 라이브러리와 프레임워크

📁  라이브러리(library) : 정상적인 제어를 하는 모듈

📁  프레임워크(framework) : 제어 역전이 발생하는 모듈

    

1) 라이브러리

   - 개발자가 모듈의 기능을 호출하는 형태의 모듈

from math import sin, cos, tan, floor, ceil

 

2) 프레임워크

    - 모듈이 개발자가 작성한 코드를 실행하는 형태의 모듈 

         ex. Flask 모듈이 제공하는 명령어를 실행하면  Flask가 내부적으로 서버를 실행한 뒤 지정한 파일을 읽어 들여

               적절한 상황에 스스로 실행하게 됨

    - 개발자가 만든 함수를 모듈이 실행하는 것은 제어가 역전된 것

 


 

3. 데코레이터

 

1) 함수 데코레이터

⚡️  함수에 사용하는 데코레이터

       ➡️  대상 함수의 앞뒤에 꾸밀 부가적인 내용 혹은 반복할 내용을 데코레이터로 정의해서 손쉽게 사용할 수 있도록 한 것

# 함수 데코레이터 생성
def test(function):
    def wrapper():
        print("인사가 시작되었습니다.")
        function()
        print("인사가 종료되었습니다.")
    return wrapper
    
# 데코레이터를 붙여 함수를 만든다
@test
def hello():
    print("hello")
    
# 함수를 호출
hello()

'''
인사가 시작되었습니다.
hello
인사가 종료되었습니다.
'''

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

1. 모듈  module

📁  여러 변수와 함수를 가지고 있는 집합체

📁  파이썬에 기본적으로 내장되어 있는 모듈을 '표준 모듈', 다른 사람들이 만들어 공개한 모듈을 '외부 모듈'

 


 

1) 모듈의 사용

👾 반드시 같은 디렉토리에 있어야 함
👾 모듈에 저장된 함수를 사용하는 방법
      A. 모듈 전체를 가져오는 방법
          - 모듈에 저장된 '모든' 클래스나 함수를 사용하고자 할 때
             ex. import 모듈

# import 모듈이름으로 불러옴

import converter

miles = converter.kilometer_to_miles(150)  # 모듈.함수() 형식으로 호출
print(f'150km={miles}miles')  # 150km=93.20565miles

pounds = converter.gram_to_pounds(1000)
print(f'1000g={pounds}pounds')  # 1000g=2.20462pounds

 

 

      B. 모듈에 포함된 함수 중에서 특정 함수만 골라서 가져오는 방법
            ex. from 모듈 import 함수
                   from 모듈 import 함수1, 함수2
                   from 모듈 import *

from converter import kilometer_to_miles  # 모듈은 가져오지 않고 특정 함수만 가져옴

miles = kilometer_to_miles(150)  # 모듈명을 명시하지 않고 사용
print(f'150km={miles}miles')  # 150km=93.20565miles

print()
from converter import *  # 모듈은 가져오지 않고 모듈의 모든 함수 가져옴

miles = kilometer_to_miles(150)  # 모듈명을 명시하지 않고 사용
print(f'150km={miles}miles')

pounds = gram_to_pounds(1000)
print(f'1000g={pounds}pounds')  # 모듈명을 명시하지 않고 사용

 


 

2) 별명 사용

👾  모듈이나 함수를 import 하는 경우에 원래 이름 대신 별명 alias를 지정하고 사용
👾  모듈이나 함수의 이름이 긴 경우에 주로 짧은 별명을 지정하고 긴 본래 이름 대신 사용
👾  별명을 지정할 때는 as 키워드를 사용

import converter as cvt  # converter 모듈에 cvt라는 별명을 지정

miles = cvt.kilometer_to_miles(150)  # 별명을 이용해서 함수 사용
print(f'150km={miles}miles')

pounds = cvt.gram_to_pounds(1000)
print(f'1000g={pounds}pounds')

print()
from converter import kilometer_to_miles as k_to_m  # 함수에도 별명을 지정 가능

miles = k_to_m(150)  # 함수 이름 대신 별명을 사용
print(f'150km={miles}miles')

 


 

2. math 모듈

📁  말 그대로 수학과 관련된 기능을 가지고 있다

변수 또는 함수 설명
원주율 pi 더 정확한 파이 값을 사용하기 위해
ceil() & floor() 전달된 값을 정수로 올림 처리하거나 내림 처리
trunc() 전달된 값을 정수로 절사, 양수를 처리할 때는 차이가 없지만
음수를 처리할 때는 결과의 차이가 있다
sqrt() 제곱근 구함
pow() 제곱을 구함

 

import math  # import 후 사용

# 1) 원주율 pi
print(math.pi)  # 3.141592653589793

# 2) ceil() 함수와 floor() 함수
print(math.ceil(1.1))  # 2 / 정수로 올림 처리
print(math.floor(1.9))  # 1 / 정수로 내림 처리

# 3) trunc() 함수
print(math.trunc(-1.9))  # -1 / 절사이므로 소수점 이하를 잘라버림
print(math.floor(-1.9))  # -2 / 내림이므로 -1.9 보다 작은 정수로 내림

# 4) sqrt() 함수
print(math.sqrt(25))  # 5.0 / 루트 25를 의미

 

3. random 모듈

📁  난수 random number 를 생성하는 모듈
📁  난수를 통해서 간단한 게임을 제작할 수 있고 확률 처리도 할 수 있다

변수 또는 함수 설명
randint() 전달하는 두 인수 사이의 정수를 임의로 생성
randrange() range() 함수는 특정범위의 정숫값들을 모두 생성할 수 있지만,
randrange() 함수는 그 특정 범위에 속한 정수중 하나만 임의로 생성
random() 0이상 1미만 범위에서 임의의 실수를 생성
0이상 1미만 범위를 백분율로 환산하면 0%이상 100%미만이기 때문에 확률을 처리할 때도 사용
choice(list) 전달된 시퀀스 자료형에 속한 요소 중에서 하나를 임의로 반환
sample(list, k=<숫자>) 전달된 시퀀스 자료형에 속한 요소 중 지정된 개수의 요소를 임의로 반환
반환 결과는 리스트 list 자료형이며 중복없이 임의의 요소가 선택
shuffle(list) 전달된 시퀀스 자료형에 속한 요소의 순서를 임의로 조정하여 다시 재배치하는 함수
호출하면 실제 전달된 시퀀스 자료형의 순서가 재배치

 

import random

# 1) randint() 함수
print(random.randint(1,10))  # 1이상 10이하의 정수

# 2) randrange() 함수
print(random.randrange(10))  # 0이상 10미만의 정수
print(random.randrange(1,10))  # 1이상 10미만의 정수
print(random.randrange(1,10,2))  # 1이상 10미만의 홀수

# 3) random() 함수
print(random.random())  # 0.1859815803780659

# 50% 확률로 '안녕하세요' 출력
if random.random() < 0.5:
    print('안녕하세요')

rand = random.randint(1,2)
print(rand)
if rand == 1:
    print('안녕하세요')

# 4) choice() 함수
seasons = ['spring', 'summer', 'fall', 'winter']
print(random.choice(seasons))  # fall

idx = random.randint(0, len(seasons) - 1)
print(seasons[idx])

# 5) sample() 함수
print(random.sample(range(1, 46), 6))  # [36, 4, 14, 35, 12, 16]

seasons = ['spring', 'summer', 'fall', 'winter']
print(random.sample(seasons, 3))
seasons = ['summer', 'summer', 'summer', 'winter']
print(random.sample(seasons, 3))

# 6) shuffle() 함수
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print(my_list)  # [4, 2, 3, 1, 5]

 


 

4. sys 모듈

📁  시스템과 관련된 정보를 가지고 있는 모듈

📁  명령 매개변수를 받을 때 많이 사용

import sys

# 명령 매개변수 출력
print(sys.argv)  # ['/Users/Desktop/pycharm/pythonProject/book/1.py']
print("----")

# 컴퓨터 환경과 관련된 정보 출력
print("copyright:", sys.copyright)  
print("----")
print("version:", sys.version)
'''
copyright: Copyright (c) 2001-2023 Python Software Foundation.
All Rights Reserved.
... 생략 ...
----
version: 3.10.13 (main, Sep 11 2023, 08:16:02) [Clang 14.0.6 ]
'''

# 프로그램 강제 종료
sys.exit()

 


 

5. os 모듈

📁  운영체제와 관련된 기능을 가진 모듈

import os

# 기본 정보 출력
print("현재 운영체제:", os.name)
print("현재 폴더:", os.getcwd())
print("현재 폴더 내부의 요소:", os.listdir())
'''
현재 운영체제: posix
현재 폴더: /Users/Desktop/pycharm/pythonProject/book
현재 폴더 내부의 요소: ['1.py']
'''
# 폴더 만들고 제거(폴더가 비어있을 때만 가능)
os.mkdir("hello")
os.rmdir("hello")

# 파일 생성하고 파일 이름 변경
with open("original.txt", "w") as file:
    file.write("hello")
os.rename("original.txt", "new.txt")

# 파일 제거
os.remove("new.txt")

# 시스템 명령어 실행
os.system("dir")

 


 

6. datetime 모듈

📁  날짜와 시간 데이터를 처리할 때 사용

변수 또는 함수 설명
now() 시스템의 현재 날짜와 시간을 반환
date() 특정 날짜를 반환
time() 특정 시간을 반환
날짜/시간 관련 필드값 특정 날짜에 원하는 데이터만 추출하고자 할때 이용
timedelta() 날짜 / 시간 데이터의 연산을 위하여 사용
total_seconds() 어떤 기간에 포함된 총 시간의 초 seconds 로 반환

 

import datetime

# 1) now() 메소드
present = datetime.datetime.now()
print(present)

# 2) date() 함수
birthday = datetime.date(2014, 8, 25)
print(birthday)  # 2014-08-25

# 3) time() 함수
wake = datetime.time(10, 48, 0)
print(wake)  # 10:48:00

# 4) 날짜 / 시간 관련 필드값
today = datetime.datetime.now()
print(today.year)  # 년도
print(today.month)  # 월
print(today.day)  # 일
print(today.hour)  # 시
print(today.minute)  # 분
print(today.second)  # 초

# 5) timedelta() 함수
# 1주 : timedelta(weeks=1)
# 1일 : timedelta(days=1)
# 1시간 : timedelta(hours=1)
# 1분 : timedelta(minutes=1)
# 1초 : timedelta(seconds=1)

today = datetime.datetime.now()
yesterday = today - datetime.timedelta(days=1)  # 어제 구함
tomorrow = today + datetime.timedelta(days=1)  # 내일 구함
print(yesterday)
print(tomorrow)

# 6) total_seconds() 메소드
date1 = datetime.date(2020, 8, 25)
date2 = datetime.date(2020, 8, 26)
print(date2 - date1)  # 1 day, 0:00:00
print((date2 - date1).total_seconds())  # 86400.0 = 60초 * 60분 * 24시간

 


 

7. time 모듈

📁  시간과 관련된 기능 처리

변수 또는 함수 설명
time() 1970년 1월 1일 0시 0분 0초 부터 현재까지 경과된 시간 timestamp을 반환
소수점 이하는 마이크로 초를 의미
ctime() 인수로 전달된 시간 timestamp을 형식에 갖춰 반환
strftime() 인수로 전달된 날짜와 지시자를 이용하여 형식을 갖춘 날짜 데이터가 문자열로 반환
sleep() 인수로 전달된 초 second 만큼 시스템을 일시 정지

 

import time

# 1) time() 함수
print(time.time())  # 1645240996.2733545

# 2) ctime() 함수
print(time.ctime(time.time()))  # Sat Feb 19 12:23:16 2022

# 3) strftime() 함수
# 년 : %y : 2자리 날짜로 표시
# 년 : %Y : 4자리 날짜로 표시
# 월 : %m : 2자리 숫자로 표시 (01 ~ 12)
# 월 : %b : 3자리 영문으로 표시 (Jan ~ Dec)
# 월 : %B : 전체 영문으로 표시 (January ~ December)
# 일 : %d : 2자리 숫자로 표시 (01 ~ 31)
# 요일 : %a : 3자리 영문으로 표시 (Sun ~ Sat)
# 요일 : %A : 전체 영문으로 표시 (Sunday ~ Saturdy)
# 시 : %l : 12시간제로 표시 (01 ~ 12)
# 시 : %H : 24시간제로 표시 (00 ~ 23)
# 분 : %M : 2시간제로 표시 (00 ~ 59)
# 초 : %S : 2시간제로 표시 (00 ~ 59)
# 오전 / 오후 : %p : AM 또는 PM
print(time.strftime('%Y-%m-%d %H:%M:%S'))

# 4) sleep() 함수
time.sleep(1)

 


 

8.  urllib 모듈

📁  URL을 다루는 라이브러리

📁  URL : Uniform Rssource Locator, 네트워크의 자원이 어디에 위치하는지 확인할 때 사용하는 것

       ▶️  웹 브라우저의 주소창에 입력하는 주소

from urllib import request

# urlopen() 함수로 구글 메인페이지를 읽습니다
target = request.urlopen("https://google.com")
output = target.read()

# 출력합니다
print(output)

'''
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" 
lang="ko"><head><meta content="text/html; charset=UTF-8" 
... 생략 ...
'''

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

1. 튜플  tuple

 

📁  리스트와 비슷한 자료형이나 한번 결정된 요소를 바꿀 수 없다는 것이 다르다.

       ➡️  이미 저장된 값 이외에는 추가, 수정, 삭제가 불가능

📁  리스트와 마찬가지로 각 요소를 구분하기 위한 인덱스가 부여되고 슬라이싱도 지원
📁  튜플은 소괄호() 나 tuple() 함수를 이용해서 생성
📁  값들을 콤마(,)로 분리하여 전달하면 자동으로 튜플이 생성

t1 = (1,2,3)
print(t1)  # (1,2,3)

# 괄호 없이 사용 가능
t2 = 1,2,3
print(t2)  #(1,2,3)

def sample():
   return (1,2)

print(sample())  #(1, 2)
# 값이 2개 반환된 것이 아니라 튜플을 자동으로 적용해서 반환함

# 리스트를 튜플로 변경
t3 = tuple([100, 3.14, 'hello'])
print(t3)  # (100, 3.14, 'hello')

# 값을 1개만 보관하는 튜플을 생성할 경우에는 값과 콤마(,)를 반드시 함께 작성
t4 = (100)
print(t4)  # 100  / 값으로 인식
print(type(t4))  # <class 'int'>

t5 = (100, )
print(t5)  # (100, ) / 튜플로 인식
print(type(t5))  # <class 'tuple'>

# 값을 swap 교환
a = 10
b = 20
print(a, b)  # 10 20
a, b = b, a  # (a, b) = (b, a)
print(a, b)  # 20 10

a, b = 100, '홍길동'
print(a)  # 100
print(b)  # 홍길동

 

 


 

2. 람다  lambda

 

📁  함수를 짧게 쓸 수 있는 파이썬의 문법

 

1)  콜백 함수  callback function

    ⚡️  함수의 매개변수에 사용하는 함수

# 매개변수로 받은 함수를 10번 호출하는 함수
def call_10_times(func):
    for i in range(10):
        func()
        
# 간단한 출력하는 함수
def print_hello():
    print("안녕하세요")
    
# 조합하기
call_10_times(print_hello)
# -> print_hello() 함수를 10번 실행

 


 

2) filter() 함수와 map() 함수

⚡️  함수를 매개변수로 사용하는 대표적인 표준함수

⚡️  map() 함수는 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성

⚡️  filter() 함수는 리스트의 요소를 함수에 넣고 리턴된 값이 True인 것으로, 새로운 리스트를 구성

# map()
map(함수, 리스트)

# filter()
filter(함수, 리스트)
def power(item):
    return item * item
def under_3(item):
    return item < 3

list_input_a = [1, 2, 3, 4, 5]

# map() 사용
output_a = map(power, list_input_a)
print(output_a)  # <map object at 0x104c228f0>
print(list(output_a))  # [1, 4, 9, 16, 25]

# filter() 사용
output_b = filter(under_3, list_input_a)
print(output_b)  # <filter object at 0x104c22800>
print(list(output_b))  # [1, 2]

 

  👾  <map object> 와 <filter object> 를 제너레이터라고 부른다.

 


 

3) 람다의 개념

⚡️  간단한 함수를 쉽게 선언하는 방법을 뜻함

# 기본형식
lambda 매개변수: 리턴값
list_input_a = [1, 2, 3, 4, 5]

# map() 함수
output_a = map(lambda x: x * x, list_input_a)
print(output_a)  # <map object at 0x102d12860>
print(list(output_a))  # [1, 4, 9, 16, 25]

# filter() 함수
output_b = filter(lambda x: x < 3, list_input_a)
print(output_b)  # <filter object at 0x102d61810>
print(list(output_b))  # [1, 2]

 


 

3. 제너레이터  generator

📁  이터레이터를 직접 만들 때 사용하는 코드

📁  함수 내부에 yield 키워드를 사용하면 해당 함수는 제너레이터 함수가 된다.

📁  일반 함수와 달리 함수를 호출해도 함수 내부의 코드가 실행되지 않는다.

 

def test():
    print("함수가 호출되었습니다")
    yield "test"
    
print("A 지점 통과")  # A 지점 통과
test()

print("B 지점 통과")  # B 지점 통과
test()
print(test())  # <generator object test at 0x104ceda10>

 

  📌  위 예제에서 test()함수는 출력되지 않고, 제너레이터를 리턴한다.

  📌  제너레이터 객체는 next() 함수를 사용해 함수 내부 코드를 실행한다.

          ➡️  이때 yield 키워드 부분까지만 실행하며, next() 함수의 리턴값으로 yield 키워드 뒤에 입력한 값이 출력된다

 

def test():
    print("A 지점 통과")
    yield 1
    print("B 지점 통과")
    yield 2
    print("C 지점 통과")
  
output = test()

# next() 함수 호출
print("D 지점 통과")
a = next(output)
print(a)
print("E 지점 통과")
b = next(output)
print(b)
print("F 지점 통과")
c = next(output)
print(c)

next(output)

 

 

 

📌  next() 함수를 호출할 때마다 함수 내부의 내용이 진행

📌  next() 함수를 호출한 이후 yield 키워드를 만나지 못하고 함수가 끝나면 StopIteration 이라는 예외가 발생

 

 

 

 

 

 

 

 

 

[ 내용참고 : 책 '혼자 공부하는 파이썬' ]

+ Recent posts