[패스트캠퍼스python] 테이블 데이터의 수정 및 삭제

파이썬 인강 : 테이블 데이터의 수정 및 삭제

데이터베이스 다루기의 기본 명령어 CRUD를 알아야한다

  • C : Create
  • R : Retrieve 조회
  • U : Update 수정
  • D : Delete

1. 데이터베이스 사용 기본 3가지 명령어

데이터베이스를 사용할때 기본이 되는 3가지 명령어가 있다

1
2
3
4
5
6
7
8
# 1. SQLITE 불러오기
import sqlite3

# 2. DB생성(파일)
conn = sqlite3.connect('C:/Users/ratia/Documents/코딩/Fastcampus Python/Python/db/database.db')

# 3. Cursor연결
c = conn.cursor()

무엇을 하든지 위의 3가지는 기본으로 깔고 시작해야한다

2. 데이터 수정

데이터 수정 명령어에는 크게 3가지가 있다
다양한 방법으로 1번로우의 username을 kim에서 seo로 바꾸어보자

1
2
3
4
5
6
7
8
9
10
11
# 1. 데이터 수정1
c.execute("UPDATE users SET username = ? WHERE id = ?", ('seo', 1))
conn.commit()

# 2. 데이터 수정2 : 딕셔너리형태로 수정
c.execute("UPDATE users SET username = :name WHERE id = :id", {"name": 'seo', 'id': 1})
conn.commit()

# 3. 데이터 수정3 : 스트링포맷로 수정
c.execute("UPDATE users SET username = '%s' WHERE id = '%s'" % ('seo', 1))
conn.commit()

3. DB Browser for SQLite를 이용한 데이터 수정

DB Browser for SQLite를 이용해서 손쉽게 데이터를 수정할수도있다
아래 이미지에서 1번 로우의 username을 seo에서 so로 바꾸어보자

  1. 먼저 데이터보기탭에서 username을 더블클릭한 뒤 오른편 인풋창에 so로 바꿔준 후 적용을 클릭한다

  1. 까먹지말고 꼭 SQL실행탭에서 commit을 입력 후 run버튼을 누른다

  2. 아래 터미널에 질의가 성공적으로 실행되었다는 안내메세지가 나타나면 끝!

  1. 수정이 잘되었는지 확인을 위해 아래 명령어를 출력하면 수정이 잘되었음을 확인할 수 있다
1
2
3
4
5
6
7
# 1. 수정한 로우만 확인
c.execute("SELECT * FROM users WHERE id= :Id", {"Id": 1})
print('수정 잘 되었는 감?', c.fetchone())

# 2. 수정한 로우포함 전체 데이터확인
for user in c.execute('SELECT * FROM users'):
print(user)

4. 데이터 삭제

데이터 삭제에도 다양한 방법이 있다

  1. 한 줄 데이터삭제 방법
    먼저 한줄데이터를 삭제해보자
    다음 세가지는 2번째 줄 전체를 삭제하는 명령어이다
1
2
3
4
5
6
7
8
9
10
11
# 1. Row Delete1 #튜플형식
c.execute("DELETE FROM users WHERE id = ?", (2,))
conn.commit()

# 2. Row Delete2 #딕셔너리형식
c.execute("DELETE FROM users WHERE id = :id", {'id': 2})
conn.commit()

# 3. Row Delete3 #스트링포맷
c.execute("DELETE FROM users WHERE id = '%s'" % 2)
conn.commit()
  1. 테이블 전체 데이터 삭제
    이번에는 테이블 전체를 삭제해보자
    간단한 명령어지만 위험하니… 신중히 사용하자 ㅋㅋㅋㅋㅋ
1
print("users db deleted : ", conn.execute("delete from users").rowcount, "rows")

[패스트캠퍼스python] 데이터베이스 연동(SQLite)

파이썬 인강 : 데이터베이스 연동(SQLite)

1. 커서의 위치

데이터베이스는 커서의 위치가 중요하다
데이터를 불러오고 난 다음에 커서는 해당 데이터 뒤에 위치하기때문이다

1
2
3
4
5
6
7
8
# 1개 로우 선택
print('One -> \n', c.fetchone())

# 지정 로우 선택 : size위의 숫자로 로우 갯수를 선택
print('Three -> \n', c.fetchmany(size=3))

# 전체 로우 선택
print('All -> \n', c.fetchall())

위의 명령어를 활용한 예시는 아래 이미지와 같다

터미널에서 볼 수 있듯이 1개 로우 명령어 뒤라서 커서는 1번 로우를 지난 2번로우 앞에 있다
그리고 size=3인 로우를 출력하니 2,3,4번 로우가 터미널에 출력되었음을 알 수 있다

위의 상태에서 전체 로우 print(‘All -> \n’, c.fetchall()) 명령어를 입력하면 어떻게 될까?
커서는 지금 4번로우 뒤에 위치해있기때문에 마지막 로우인 5번 데이터만 출력된다

만약 위의 상태에서 print(‘All -> \n’, c.fetchall())를 한번 더 호출하면 어떻게 될까?
커서의 위치는 마지막 로우인 5번 뒤에 있다. 따라서 호출해도 [] 빈리스트만 터미널에 출력된다.

그렇다면 처음 1번 로우를 호출하고 싶을때는 어떻게 할 수 있을까?
바로 순회하면 된다

2. 순회

순회에는 3가지방법이 있다.

  1. 순회 : 변수선언 후 for in 반복문 사용
    데이터조회 명령어 c.execute(‘SELECT * FROM users’) 뒤에 실행해야 출력된다

    1
    2
    3
    rows = c.fetchall()
    for row in rows:
    print('retrieve1 >', row) # 조회 없음
  2. 순회 : 변수선언 없이 for in 반복문 바로 사용
    데이터조회 명령어 c.execute(‘SELECT * FROM users’) 뒤에 실행해야 출력된다
    간편하기때문에 제일많이 사용된다

    1
    2
    for row in c.fetchall():
    print('retrieve2 >', row) # 조회 없음
  3. 순회
    execute(“SELECT * FROM users)는 users에 있는 전체 데이터를 조회하는 명령어이다 따라서 fetchall() 명령어와 동일한 결과값을 가진다.
    데이터조회 명령어 c.execute(‘SELECT * FROM users’) 까지 포함된 명령어로 데이터조회명령어가 따로 필요없다
    코드가 길어져서 가독성이 떨어지는 지는 단점이 있다.
    “ORDER BY id desc” 명령어를 넣어주면 역순출력이 된다

    1
    2
    for row in c.execute("SELECT * FROM users ORDER BY id desc"):
    print('retrieve3 > ', row)

순회1번과 순회2번은 함께 쓰일수없기때문에
순회2번과 순회3번의 출력값을 아래 이미지와 같다

3. WHERE Retrieve

6가지 방법이 있고 핵심이므로 꼭 다 알고 있어야한다.

  1. WHERE Retrieve1
    튜플형태로 3번로우인 Lee를 출력
    fetchone()에서 3번 로우 하나만 불러왔기때문에 그 다음 명령어로 fetchall()로 전체를 불러와도 [] 빈 리스트만 출력된다

    1
    2
    3
    4
    param1 = (3,) 
    c.execute('SELECT * FROM users WHERE id=?', param1)
    print('param1', c.fetchone())
    print('param1', c.fetchall())
  2. WHERE Retrieve2
    튜플형태로 1번로우인 Kim을 출력
    %s :문자열형, %d:정수형, %f: 실수형
    fetchone()에서 1번 로우 하나만 불러왔기때문에 그 다음 명령어로 fetchall()로 전체를 불러와도 [] 빈 리스트만 출력된다

    1
    2
    3
    4
    param2 = 1
    c.execute("SELECT * FROM users WHERE id='%s'" % param2)
    print('param2', c.fetchone())
    print('param2', c.fetchall())
  3. WHERE Retrieve3
    이번엔 딕셔너리형태로 1번 로우출력
    id= 뒤에 :Id를 넣어준뒤 컴마찍고 딕셔너리형태로 {“Id”: 1} 첫번째로우를 호출하면 된다

    1
    2
    3
    c.execute("SELECT * FROM users WHERE id= :Id", {"Id": 1})
    print('param3', c.fetchone())
    print('param3', c.fetchall())
  4. WHERE Retrieve4
    리스트형태로 파라미터 2개를 받아서 1번로우와 4번로우 출력
    파라미터 여러가지를 가져오려면 IN(?,?)로 넣으면 된다
    이젠 한개가 아니니까 fetchone()은 쓸 수 없고 fetchall()로 출력하면 된다

    1
    2
    3
    param4 = (1, 4)
    c.execute('SELECT * FROM users WHERE id IN(?,?)', param4)
    print('param4', c.fetchall())
  5. WHERE Retrieve5
    위와 똑같은 결과값이지만 다르게 표현할 수 있다 물음표대신 정수값($d)을 넣어주면 된다
    간단하기때문에 많이 사용한다

    1
    2
    c.execute("SELECT * FROM users WHERE id In('%d','%d')" % (1, 4))
    print('param5', c.fetchall())
  6. WHERE Retrieve6
    딕셔너리형태로 1번과 4번로우 출력
    OR 사용

    1
    2
    c.execute("SELECT * FROM users WHERE id= :id1 OR id= :id2", {"id1": 1, "id2": 4})
    print('param6', c.fetchall())

지금까지 id를 이용했지만 username, date등을 이용해서도 출력할수있다

4. Dump 출력

데이터베이스 백업 시 중요하다
아래 명령어를 실행하면 새로운 dump.sql이라는 파일이 형성되고 그 안에 작성한 데이터테이블이 백업된다.
이를 활용하여 sql에 붙여넣으면 다른 컴퓨터나 환경에서도 데이터사용가능하다
실무에서 흔히 ‘덤프떠와’ 라고 말한다.

with문을 사용하면 자동으로 close()를 해줘서 편리하다

  • with open() as f: 를 실행했으므로 f.close()가 자동으로 되었고
  • with conn: 을 실행했으므로 conn.close()가 자동으로 되었다
1
2
3
4
5
with conn: 
with open('본인이 원하는 경로/dump.sql', 'w') as f:
for line in conn.iterdump():
f.write('%s\n' % line)
print('Dump Print Complete.')

위의 코드를 실행시키면 출력값은 아래 이미지와 같다.

[패스트캠퍼스python] 외부파일 CSV, 엑셀 읽기 및 쓰기

파이썬 인강 : 외부파일 CSV, 엑셀 읽기 및 쓰기

1. CSV 읽기, 쓰기

위의 예제를 차근차근 보자
with open(작성한 파일을 저장할장소/저장할 파일명, ‘w’(작성한다는는 의미), newline=’’) as f:

  1. newline=’’
    이 의미는 이 부분이 없으면 한 줄씩 띄어쓰기로 for문을 순회하면서 데이터가 자동저장된다
    하지만 데이터 양이 많을수록 용량도 커지고 쓸데없이 불편할 수 있다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    1,2,3

    4,5,6

    7,8,9,

    10,11,12

    13,14,15

    16,17,18
    그래서 ‘’빈칸을 넣어서 띄어쓰기를 없애는 것이다
    newline=’’을 적용하면 아래와 같이 결과값이 출력된다

  1. writerow()와 writerows()의 차이점
  • writerow()는 한줄씩 띄어쓰기하여 입력된다 -> for문을 썼기에 순회하면서 전체 내용이 출력되었다.
  • writerows() 한줄씩이 아닌 전체데이터가 입력된다.(for문 반복없이 한번에 입력)

한줄씩 순회하면서 입력 방법(writerow)와 한꺼번에 전체데이터를 입력하는 방법(writerows)은 각각의 장점이 있다
예시로 회원가입목록에서 1950년생이하는 빼고 데이터를 출력하고싶을때 if조건문으로 필터링을 걸어줘서 writerow이 유용하게 쓰인다

2. 엑셀 쓰기 읽기

엑셀을 처리하는 오픈소스 : openpyxl, xlsxwriter, xlrd, xlwt, xlutils
여러가지 방법이 있지만 pandas를 가장 많이 사용한다
그 이유는 pandas는 최다사용오픈소스인 openpyxl, 랭킹 1위인 xlrd를 내부적으로 만능으로 사용할 수 있기때문이다

pandas를 이용하기 위해서는 아래 3가지를 다운로드해줘야한다
1. pip install xlrd
2. pip install openpyxl
3. pip install pandas


파이썬 인강 : 데이터베이스 연동(SQLite)

SQLite는 기본적으로 설치가 되어있다. 따라서 따로 설치할 필요없이 바로 import하면 된다

1. 테이블 생성 및 삽입

import datetime
import sqlite3

2. 삽입 날짜 생성

많이 쓰니까 꼭 알기

1
2
now = datetime.datetime.now()
print('now', now)

보기 불편하니까 포맷을 만들면 익숙한 시간형식으로 나타낼수있다

1
2
nowDatetime = now.strftime('%Y-%m-%d %H:%M:%S')
print('nowDatetime', nowDatetime)

3. DB생성 & Autocommit 그리고 커밋

본인 DB 파일 경로로 설정해주면된다
isolation_level=None 을 넣었을 경우 자동으로 커밋 반영(Auto Commit)해준다.
설정하지 않았다면 수정 후 conn.commit() 명령어를 입력해야지만 반영된다

1
conn = sqlite3.connect('본인DB파일경로/database.db', isolation_level=None)

4. Cursor연결

1
2
c = conn.cursor()
print('Cursor Type : ', type(c))

5. 테이블 생성

데이블에서 쓰일 수 있는 Datatype에는 총 5가지가 있다

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • BLOB
1
2
3
c.execute(
"CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username text, email text, phone text, website text, regdate text)")
#AUTOINCREMENT

6. 데이터 삽입

삽입에는 크게 두가지 방식이 있다

  1. 첫번째방법
    ? 를 넣는 이유는 위에서 만들었던 데이터(“nowDatetime,”)를 넣게되면 스트링형식으로 들어가기때문에 ?를 주고 뒤에 매개변수로 튜플형태로 입력한다
1
c.execute("INSERT INTO users VALUES (1 ,'Kim','Kim@naver.com', '010-0000-0000', 'Kim.com', ?)", (nowDatetime,))
  1. 두번째 방법
    ?의 갯수와 삽입할데이터의 갯수를 순서대로 일치시켜줘주면된다
1
c.execute("INSERT INTO users(id, username, email, phone, website, regdate) VALUES (?, ?, ?, ?, ?, ?)", (2, 'Park', 'Park@naver.com', '010-1111-1111', 'Park.com', nowDatetime))

7. Many 삽입(튜플, 리스트형태를 삽입가능)

가장 중요한 부분이다!
Many는 이름 그대로 대용량 데이터를 삽입하는 방법으로 튜플이나 리스트형태를 삽입가능하다

1
2
3
4
5
6
7
userList = (
(3, 'Lee', 'Lee@naver.com', '010-2222-2222', 'Lee.com', nowDatetime),
(4, 'Cho', 'Cho@naver.com', '010-3333-3333', 'Cho.com', nowDatetime),
(5, 'Yoo', 'Yoo@naver.com', '010-4444-4444', 'Yoo.com', nowDatetime)
)

c.executemany("INSERT INTO users(id, username, email, phone, website, regdate) VALUES (?, ?, ?, ?, ?, ?)", userList)

웹상에서 입력받은 데이터를 sqlite를 통해서 장고의 경우, orm을 통해서 대용량데이터를 입력할 수 있다

8.테이블 데이터 삭제

지우는 명령어는 conn.execute(“delete from users”)지만 몇개의 행을 지웠는지까지 확인할 수 있는 아래 명령어를 쓰는 것이 더 좋다

1
print("users db deleted : ", conn.execute("delete from users").rowcount, "rows")

9. 롤백

되돌리기를 뜻하며 커밋한 걸 되돌리는 것이다.

1
conn.rollback()

10. 접속 해제

DB를 다 사용했을때는 꼭 접속 해제 명령어를 입력해줘야한다.

1
conn.close()

[패스트캠퍼스python] 예외처리

파이썬 인강 : 예외처리

완벽한 코딩은 없다. 여러 사람이 함께 작업한다한들 예외는 언제든지 나타날수있다
만약 미세한 코딩으로인해 수백명이 결제하는 회사 시스템에 예외가 발생해버린다면 그 손해는 막심할 것이다.

1. 예외 종류

  • SyntaxError
  • TypeError
  • NameError
  • IndexError
  • ValueError
  • KeyError.. 등등

요즘은 문법적으로 에러는 없지만 코드 실행(런타임) 프로세스에서 발생하는 예외 처리가 중요하다
에디터에서 linter가 문법적인 에러를 잡아주기때문에 걱정없지만 런타임에서 발생하는 에러에 주의해야한다

항상 예외가 발생하지 않을 것으로 가정하고 먼저 코딩
그 후 런타임 예외 발생 시 예외처리 권장(EAFP 코딩 스타일)

1. SyntaxError : 잘못된 문법

문법적인 에러는 보통 linter가 잡아준다

1
2
3
4
5
print('test)     # ' 누락

if True # : 누락
pass
x => y # 작거나 같다는 >=로 해야함

2. NameError : 참조 변수 없음

1
2
3
a = 10
b = 15
print(c) # 예외 발생

3. ZeroDivisionError : 0 나누기 에러

모든 언어에 있는 에러이고 런타임에서 발생하는 에러이기에 중요하다

1
print(10 / 0)

4. IndexError : 인덱스 범위 오버

자주 발생하는 에러

1
2
3
4
5
6
7
8
9
x = [10, 20, 30]

print(x[1])
print(x[3]) # 예외 발생
print(x.pop())
print(x.pop())
print(x.pop())
print(x.pop()) # 예외 발생
print(x.pop(50)) # 예외 발생

5. KeyError

주로 딕셔너리에서 나오는 에러이다

1
2
3
dic = {'name': 'Kim', 'Age': 33, 'City': 'Seoul'}

print(dic['hobby']) # 키가 존재하지 않으면 예외

이런 에러를 방지하기 위해 get매서드를 사용하면 좋다

1
print(dic.get('hobby')) # 안전

6. AttributeError : 모듈, 클래스에 있는 잘못된 속성 사용시에 예외

1
2
3
4
x = [1, 2, 3]
print(x.append(4))
print(x)
print(x.add(10))

출력값은

list는 add가 없기에 AttributeError발생한다

7. ValueError : 참조 값이 없을 때 예외

1
2
3
4
t = (10, 100, 1000)

print(t.index(100))
print(t.index(7)) # 예외 발생

8. FileNotFoundError

외부파일을 불러와서 처리할때 자주 발생

터미널에 보면 디렉토리 내에 찾을 수 없다고 나온다

9. TypeError : 자료형에 맞지 않는 연산을 수행 할 경우

1
2
3
4
5
6
x = [1, 2]
y = (1, 2)
z = 'test'

print(x + y) # 예외 발생(튜플과 리스트를 결합할수없다 -> 그래서 형변환이 중요)
print(sum([1,2,3],10,1)) # 예외 발생(자료형불일치)

2. 예외 처리 기본

아래 예외 처리는 기본중의 기본이므로 꼭 알아둬야한다.

1
2
3
4
5
6
try               에러가 발생 할 가능성이 있는 코드 실행
except 에러명1: 에러가 발생하면 여기서 처리(여러 개 가능)
except 에러명2:
except 에러명3:
else: try 블록의 에러가 없을 경우 실행
finally: 항상 실행

이를 활용한 예시

1
2
3
4
5
6
7
8
try:
z = 'Kim' # 'Cho' 예외 발생
x = name.index(z)
print('{} Found it! {} in name'.format(z, x + 1))
except: # 모든 에러를 처리(Exception)
print('Not found it! - Occurred ValueError!')
else:
print('ok! else!')

[패스트캠퍼스python] 파일 읽기

파이썬 인강 : 파일 읽기

txt파일로 읽거나 쓸 줄 알아야 어플리케이션을 만들었을때 중요한 데이터(결과값)을 저장해놓을 수 있다

  • 읽기 모드 r
  • 쓰기 모드 w : 기존 파일 삭제
  • 추가 모드 a : 파일 생성 또는 추가
  • 상대 경로(‘../‘, ‘./‘)
  • 절대 경로 확인(‘C:...’)

참고 링크

중요한 데이터.txt 파일을을 어떻게 읽을 수 있을까?

1. open()과 close() 방법

파일을 열때는 open()을 사용하고 읽어올 것이기때문에 r을 쓰면 된다
open()했으면 반드시 close 리소스 반환해줘야한다. 즉 close()로 꼭 문 닫아줘야한다.
한 번 사용한 리소스를 꼭 닫아줘야한다.

1
2
3
4
5
f = open('./resource/중요데이터.txt', 'r')
contents = f.read()
print(contents)

f.close()

2. with open()방법

파이썬에서는 open()해놓고 close()는 하지않아도 되는 방법이 있다
바로 with문!

1
2
3
4
5
with open('./resource/중요한데이터.txt', 'r') as f:
c = f.read()
print(iter(c)) #iterator함수로 변환하여 for문에서 사용가능
print(list(c)) #리스트형변환가능
print(c)

read는 전체 내용 읽어준다 ex) read(10) : 10글자 읽기

3. with문과 for문 활용

1
2
3
with open('./resource/중요한데이터.txt', 'r') as f:
for c in f:
print(c)

with문과 for문 출력값

출력값을 보면 한 줄씩(line단위) 출력해준다
한줄씩 뛰어쓰기되어 나오는 것은 끝에 |n이 들어가있기때문이다
제거해주려면 어떻게 하면 될까?

1
2
3
with open('./resource/중요한데이터.txt', 'r') as f:
for c in f:
print(c.strip())

|n 입력후 출력

|n을 strip()으로 제거해주면 가독성 좋게 출력된다
위의 출력이미지와 아래의 출력이미지를 보면 가독성이 좋아진 것을 알 수 있다

4. read VS readline VS readline(문자수) VS readlines

  • read : 처음글자부터 끝까지 전체를 다 읽기. read()가 끝나고 나면 커서가 맨 마지막 글자에 있기때문에 한번 출력 후 read()를 또 출력하면 빈 내용이 출력된다
  • readline : 한 줄씩 읽기
  • readline(문자수) : 문자수 읽기
  • readlines : 전체 읽은 후 라인 단위 리스트 저장

응용한 예시를 함께보자
아래 이미지파일과 같은 score.txt파일이 있고 안의 내용의 평균을 for line in으로 구해보자

score.txt파일

1
2
3
4
5
6
7
8
9
10
11
with open('./resource/score.txt', 'r') as f:
score = []
for line in f:
score.append(int(line))
print(score)
print('Average : {:6.3f}'.format(sum(score) / len(score)))
#{6자리고 소수셋째자리까지라는 의미}

# 출력값
[95, 78, 92, 89, 100, 66]
Average : 86.7

5. 파일 쓰기

  1. 빌트인패키지인 random을 이용해서 파일을 써보자
    로또번호와 비슷하게 6개 랜덤번호를 출력하는 예제이다.
1
2
3
4
5
6
7
from random import randint
#랜덤파일로부터 randint함수를 가져와라는 뜻

with open('test2.txt', 'w') as f:
for cnt in range(6): # range(6)은 0~5까지임.
f.write(str(randint(1, 50))) # 1부터50까지
f.write('\n')
  1. writelines : 리스트 -> 파일로 저장

    1
    2
    3
    with open('test3.txt', 'w') as f:
    list = ['Kim\n', 'Park\n', 'Lee\n']
    f.writelines(list)
  2. print로 바로 저장하는 예제이다

    1
    2
    3
    with open('./resource/test3.txt', 'w') as f:
    print('Test Contents!', file=f)
    print('Test Contents!!', file=f)

[패스트캠퍼스python] 모듈과 패키지

파이썬 인강 : 모듈과 패키지

우리가 알게 모르게 사용하고 있었던 모듈에 대해 배워보자

모듈과 패키지

가장 중요한 점은 왜 패키지로 개발/배포/사용해야하는지 그 이유를 명확히 알아야 한다는 점이다.

  • 모듈 : 파일 하나하나가 모듈. 독립적인 파일
  • 패키지 : 모듈들을 파일형태로 관리하는 것을 패키지리고 한다

참고로

  • .. : 부모 디렉토리 이동
  • . : 현재 디렉토리 이동

아래 두가지 파일을 이용해서 모듈과 패키지에 대해 공부해보자
fibonacci.py는 피보나치수열 만드는 파일이다.

fibonacci.py

calculations.py는 아래와같은 세가지의 함수를 가지고 있다

calculations.py

1. 클래스를 가져와서 사용하는 방법

클래스를 가져올 수 있다

  1. 일반적인 방법
1
2
3
4
5
6
7
8
9
10
11
from pkg.fibonacci import Fibonacci #클래스명(fibonacci)

Fibonacci.fib(10)

print("ex1 : ", Fibonacci.fib2(20))
print("ex1 : ", Fibonacci().title) #인스턴스화

# 출력값은
0 1 1 2 3 5 8
ex1 : [0, 1, 1, 2, 3, 5, 8, 13]
ex1 : fibonacci

피보나치수열이 잘 출력되었음을 알수있다.

  1. *을 사용한 방법
    메모리를 많이 사용하기때문에 권장하지 않는 방법이지만 알아둬야한다

별을 이용한 방법

*는 모든 리소스를 다 가져오는 것을 뜻한다.
터미널을 보면 피보나치 수열이 잘 나타남을 확인할 수 있다

  1. as 사용하는 방법
    권장하는 방법으로 계속 class fullname을 사용하는 것보다 가독성이 높기때문이다.
    as는 Alias(엘리아스)의 약자로 별칭이란 뜻이다.
1
2
3
4
5
6
7
8
9
10
11
from pkg.fibonacci import Fibonacci as fb

fb.fib(50)

print("ex3 : ", fb.fib2(60))
print("ex3 : ", fb().title)

# 출력값
0 1 1 2 3 5 8 13 21 34
ex3 : [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
ex3 : fibonacci

2. 함수를 가져와서 사용하는 방법

  1. import + as 조합
    이번에는 클래스말고 함수를 가져와 사용해보자.

import와 as 조합

클래스를 가져왔던 것과

  1. from + import + as 조합
    권장하는 방법으로 모듈의 많은 함수들 중에서 필요한 함수만 가져와서 쓸수있다
    어떠한 언어를 다루던 리소스를 낭비하지 않도록 명확히 코딩하는 것이 좋다
1
2
3
4
5
6
from pkg.calculations import div as d

print("ex5 : ", int(d(100,10)))

# 출력값은
ex5 : 10

3. builtins(빌트인)

1
2
3
import builtins

print(dir(builtins))

출력값이 너무 길어서 이미지파일로 준비했다

builtins 출력값

우리가 빌트인인지 모르고 사용했던 list함수, type함수등이 들어가 있는 것을 확인할 수 있다

4. __init__.py의 필요성

용도 : 해당 디렉토리가 패키지임을 선언할 때 사용한다.
Python 2.x대를 사용하고 있다면 __init__.py가 필수이다
Python3.x : 파일이 없어도 패키지 인식하지만 3.x보다 하위 버전 호환 위해서 생성하는 것이 안전

5. 단위테스트

독립적으로 만든 파일이 독립적으로 잘 실행되는지는 확인하기 위해서 아래 if name문을 써준다
아래 형태로 쓰도록 딱 정해놓았다.
만든함수()부분에 만들었던 함수들을 넣어 독립적으로 실행되는지 체크할 수 있다
if문이기때문에 import으로 가져온 파일에서는 출력이 안된다 GOOD!

1
2
3
4
5
# 단위 실행(독립적으로 파일 실행)
if __name__ == "__main__":
print("This is", dir())
만든함수()
만든함수()
[패스트캠퍼스python] 상속, 다중상속

[패스트캠퍼스python] 상속, 다중상속

파이썬 인강 : 상속, 다중상속

파이썬 클래스 상세 이해 : 상속, 다중상속

상속은 부모한테서 물려받는 것을 뜻한다
자식이 부모의 속성과 매서드를 사용할 수 있는 것이다

상속과 다중상속

Read More

[패스트캠퍼스python] 클래스의 self의 이해, 클래스, 인스턴스 변수

파이썬 인강 : 클래스의 self의 이해, 클래스, 인스턴스 변수

오늘은 꼭 알아야하면서도 엄청 중요한 개념이라고 할 수 있는 클래스의 self, 클래스, 인스턴스 변수에 대해 공부해보자

1. 클래스의 self의 이해

self 매개변수의 유무에 따른 차이를 아래 예시를 통해 확인해보자

1
2
3
4
5
6
7
8
9
10
print()
class SelfTest: #class SelfTest(): 빈괄호가 있어도되고 없어도 된다
def function1(): # self매개변수없음 = 클래스매서드
print("function1 called!")

def function2(self): # self매개변수있음 = 인스턴스매서드
print(id(self))
print("function2 called!")

self_Test = SelfTest() # 인스턴스 생성

이제 function1을 호출해보자

1
2
3
4
# self_Test.function1()

# 출력값은
TypeError: unction1() takes 0 positional arguments but 1 was given

function1은 클래스매서드이기에 그냥 출력하면 타입에러가 발생한다
아래와 같이 출력해야한다

1
2
3
4
SelfTest.function1()

# 출력값은
function1 called!

잘 출력되는 것을 확인할 수 있다
self매개변수를 선언한 함수는 어떨까?

1
2
3
4
5
6
7
self_Test.function2()
SelfTest.function2()

# 출력값은
function2 called!
TypeError: function2() missing 1 required positional argument: 'self'
#

두번째 방법의 타입에러를 해결하려면 아래 이미지처럼 하면 된다

타입에러 해결

터미널을 확인해보면 id값이 일치하는 것을 확인할 수 있다.

2. 변수 , 인스턴스 변수

클래스변수는 self가 없고 인스턴스변수는 self가 있어야한다
클래스변수는 공용으로 쓸 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
print()
class Warehouse:
# 클래스 변수
stock_num = 0

def __init__(self, name):
# 인스턴스 변수
self.name = name
Warehouse.stock_num += 1

def __del__(self):
Warehouse.stock_num -= 1


user1 = Warehouse('Kim')
user2 = Warehouse('Park')

그리고 유저1과 유저2 그리고 웨어하우스의 네임스페이를 확인해보자

1
2
3
4
5
6
7
8
print(user1.__dict__)
print(user2.__dict__)
print(Warehouse.__dict__) # 클래스 네임스페이스 , 클래스 변수를 공유한다.

# 출력물
{'name': 'Kim'}
{'name': 'Park'}
{'__module__': '__main__', 'stock_num': 2, '__init__': <function Warehouse.__init__ at 0x000001ED3D0C79D0>, '__del__': <function Warehouse.__del__ at 0x000001ED3D0C7A60>, '__dict__': <attribute '__dict__' of 'Warehouse' objects>, '__weakref__': <attribute '__weakref__' of 'Warehouse' objects>, '__doc__': None}

이를 통해 유저1과2에는 이름밖에 없고 웨어하우스에 stock_num이 있다는 것을 알수있다
만약 유저안에서 stock_num을 찾는다면 어떻게 될까?

1
2
3
4
5
6
print(user1.stock_num) 
print(user2.stock_num)

# 출력물
2
2

만약 유저를 한명 더 추가한다면 아래와 같이 출력된다

유저추가

네임스페이스안에 이름밖에 없었기때문에 stock_num을 못찾을것같지만 인스턴스는 자신의 네임스페이스에 없으면 클래스의 네임스페이스에서 찾아서 불러온다
이러한 점을 이용하여 연봉인상율같은 계산등에 활용할 수 있다.

[패스트캠퍼스python] Hint과 클래스 기초

파이썬 인강 : Hint과 클래스 기초

1. Hint

데이터타입을 명시적으로 알려주는 역할을 한다

위의 사진에서와 같이 x : int의 의미는 x는 int형만 와야한다는 의미이고
-> list: 는 리스트형태로 출력될 것이다라는 의미이다.
패키지를 통해 해당 함수를 다른 파일로 빼놓을때 유용하게 사용할 수 있다.

1
2
3
4
5
6
7
8
9
def tot_length1(word: str, num: int) -> int:
return len(word) * num

print('hint exam1 : ', tot_length1("HeavyTalker", 10))
print(len("HeavyTalker"))

# 출력값은
hint exam1 : 110
11

2. 람다식 예제

람다식의 장점은 메모리 절약, 가독성 향상, 코드 간결해진다
함수와 람다의 차이점은

  • 함수는 객체 생성 -> 리소스(메모리) 할당
  • 람다는 즉시 실행 함수(Heap 초기화) -> 메모리 초기화
    즉 함수도 객체이기때문에 메모리에 할당되는 반면에 람다는 즉시실행함수여서 메모리를 효율적으로 사용할 수 있다.
    람다식을 남발하는 경우에는 가독성이 떨어지므로 실무에서는 주로 익명함수를 사용할때 람다식을 쓴다.
  1. 일반적 함수 -> 변수 할당

일반적인 함수에 변수할당법

위의 이미지는 우리가 일반적인 함수를 변수에 할당하는 방법이다
var_func이란 변수에 우리가 만든 def를 대입하면 터미널에서 볼수있듯이 메모리에 할당되어있고 type은 function이다.

1
2
3
4
5
6
7
8
9
print()
def mul_10(x: int) -> int:
return x * 10

mul_func = mul_10

print(mul_func(77))
# 출력값은
770
  1. 람다 함수 -> 할당
    위의 일반함수식과 비교하면
1
2
3
4
5
6
print()
lambda_mul_func = lambda x: x * 10
print(lambda_mul_func(77))

# 출력값은
770

동일한 결과값이 출력되는 것을 확인할수있다.
좀 더 나아가 활용할 수 있는 방법이 있다
함수를 매개변수로 받는 방법이다
위에서 만들었던 lambda_mul_func를 이용한 함수를 만들었다.

1
2
3
4
5
6
7
8
print()
def func_final(x, y, func):
print(x * y * func(7))

func_final(10, 10, lambda_mul_func)

# 출력값은
7000

만들어놓은 람다함수 사용하지않고 즉시 람다식을 넣어서 인자로 함수를 넘길 수 있다
None은 더이상 출력할 값이 없어서 출력되는 것임.

1
2
3
4
5
print(func_final(10,10, lambda x : x * 10))

# 출력값은
7000
None

3. 클래스선언

먼저 클래스를 사용해야 할 이유에 대해 알아보자
방대한 어플리케이션이 운영하기 위해서는 클래스방식의 코딩을 해서 구조화를 시키고 결합을 느슨하게 해서 유지보수에 용이하게 한다.

클래스선언시 첫글자는 대문자여야한다.
클래스는 속성과 매서드로 구분된다.

클래스(객체), 인스턴스 차이는 매우 중요하디

  • 네임스페이스 : 객체를 인스턴스화 할 때 저장된 공간
  • 클래스 변수 : 직접 사용 가능, 객체보다 먼저 생성
  • 인스턴스 변수 : 객체마다 별도로 존재, 인스턴스 생성 후 사용

아래는 클래스를 인스턴스 변수로 사용한 예이다.

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
31
32
33
34
class UserInfo:
def __init__(self, name): #초기화
self.name = name

def print_info(self):
print("Name: " + self.name)

def __del__(self):
print("Instance removed!")

# 인스턴스변수 생성하기
user1 = UserInfo("Kim")
user2 = UserInfo("Park")

print(id(user1))
print(id(user2))

user1.print_info()
user2.print_info()

# 클래스 네임스페이스 확인
print('user1 : ', user1.__dict__)
print('user2 : ', user2.__dict__)

print(user1.name)

# 출력값은
2683366237424
2683366443184
Name: Kim
Name: Park
user1 : {'name': 'Kim'}
user2 : {'name': 'Park'}
Kim

[패스트캠퍼스python] 파이썬 함수식

파이썬 인강 : 파이썬 함수식

함수식과 람다에 대해 자세히 알아보자.
우리가 함수를 사용하는 이유는 반복적이고 중복되는 프로그램을 방지하기위해서다

1. 함수 정의 방법

아래처럼 하면 끝!

1
2
def 함수명(parameter):
code작성하기

여기서 def는 define의 약자이다.

함수를 호출하는 방법은 함수명() 이고 만약 parameter가 있다면 함수명(parameter)로 호출하면 된다

1
2
3
4
5
6
7
def hello(world):
print("Hello, ", world)

hello("Python!")

# 출력값은
Hello, Python!

2. 함수 선언 위치

함수를 선언할때는 선언 위치가 매우 중요하다
파이썬은 항상 위에서부터 아래로 실행되기 때문이다
위의 예제에서 아래 사진처럼 선언 위치를 바꾸면 터미널에 NameError 뜨는 것을 볼 수 있다
hello라는 이름이 정의되어 있지 않다는 에러이다.

리턴이라는 예약어를 통해서 함수를 출력할수도있다
아래 예제를 보자
항상 형변환을 주의하자

1
2
3
4
5
6
7
8
9
def hello_return(world):
value = "Hello, " + str(world)
return value

str = hello_return("천사!")

print(str)
# 출력값은
Hello, 천사!

3. 다중리턴

다중리턴을 사용하면 짜임새있는 함수를 만들 수 있다.
java나 기타언어들은 return값이 하나인 게 원칙인데 파이썬은 다르다
파이썬은 다중리턴을 허용한다

1
2
3
4
5
6
7
8
9
10
11
12
def func_mul1(x):
y1 = x * 2
y2 = x * 4
y3 = x * 6
return y1, y2, y3

val1, val2, val3 = func_mul1(10)

print(val1, val2, val3)

# 출력값은
20 40 60

파이썬의 매력적인 부분은 return값의 데이터 타입 변환이다.
왜냐면 엄청 간단하고 쉽기때문에
위의 예제에서 return의 데이터형태는 int(정수)이다.
만약 데이터형태를 int가 아닌 다른 형태로 나타내고 싶다면 어떻게 하면 될까?

만약 데이터형태를 리스트로 받고싶다면 return[y1, y2, y3]를 적어주면 끝!
만약 튜플로 받고싶다면 return(y1,y2, y3)로 하면 끝!
만약 딕셔너리로 return받고싶다면?

1
2
3
4
5
6
7
8
9
10
11
12
13

def func_mul3(x):
y1 = x * 2
y2 = x * 4
y3 = x * 6
return {'ret1': y1, 'ret2': y2, 'ret3': y3}

dic = func_mul3(8)

print(type(dic), dic, dic.get('ret3'), dic.items(), dic.keys(), dic.values())

# 출력값은
<class 'dict'> {'ret1': 16, 'ret2': 32, 'ret3': 48} 48 dict_items([('ret1', 16), ('ret2', 32), ('ret3', 48)]) dict_keys(['ret1', 'ret2', 'ret3']) dict_values([16, 32, 48])

정말 저세상 간단함!
정말 매력적인 언어다!

4. *args, **kwargs 이해

  1. *args (아스타)
    arguments의 약자로 가변인자(인자의 갯수가 변할 수 있음)를 뜻한다
    다양한 매개변수를 받아서 함수의 흐름이 바뀌게한다
    매개변수를 하나를 넣든 세개를 넣든 튜플의 형태로 출력해준다
    기본적으로 *args라고 적지만 이 매개변수명은 자유롭게 변경 가능하다
    enumerate는 순회라는 의미로 index를 넣어서 나타낼 수 있다. 꼭 알아두자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def args_func(*args):  # 매개변수명 자유롭게 변경 가능
for i, v in enumerate(args):
print(v, i)

args_func('비')
args_func('비', '보')
args_func('비', '보', 'TV')

# 출력값은
0
0
1
0
1
TV 2

만약 출력값을 여러줄 나오는게 싫다! 한 줄로 나타내고 싶다면?
print(v, i)를 print(‘{}’.format(i), v, end=’ ‘)로 바꿔주면 된다

1
2
# 출력값은
0 비 0 비 1 보 0 비 1 보 2 tv

만약 *argsrange()를 같이 사용하면 어떻게 될까?

1
2
3
4
5
6
7
8
9
def args_range(*args):  
for i, v in enumerate(range(3)):
print(i,v)
args_range()

# 출력값은
0 0
1 1
2 2
  1. kwargs
    args와 똑같은 가변인자이나 딕셔너리로 받는다는 차이점이 있다.
    별표가 하나일때는 튜플로 받는데 별표가 두개인경우 딕셔너리로 받는다.
    위의 args와 마찬가지로 매개변수명은 자유롭게 변경 가능하다
1
2
3
4
5
6
7
def kwargs_func(**kwargs):  # 매개변수명 자유롭게 변경 가능
print(kwargs)
kwargs_func(name1='가')
kwargs_func(name1='가', name2='나')
# 출력값은
{'name1': '가'}
{'name1': '가', 'name2': '나'}

딕셔너리형태말고 한 줄에 주르륵 출력하고 싶으면
print(kwargs)를 print(‘{}’.format(v), kwargs[v], end=’ ‘)로 바꿔주면 된다

1
2
# 출력값은
name1 가 name1 가 name2 나
  1. *args*kwargs의 혼합
    효율적인 코딩을 위해 필수이며 꼭 이해를 해야하는 부분이다

아래 터미널처럼 가변인자(args와 kwargs)는 없이 int 10과 20만을 넣어도 출력이 되는 것을 알 수 있다.
가변인자는 값이 없기때문에 빈 튜플과 빈 딕셔너리가 출력된다.

1
2
3
4
5
6
7
def example(arg_1, arg_2, *args, **kwargs):
print(arg_1, arg_2, args, kwargs)

example(10, 20, 'park', 'kim', age1=77, age2=80 )

# 출력값은
10 20 ('park', 'kim') {'age1': 77, 'age2': 80}

실습을 하면서 궁금했던 점은 어떻게 튜플과 딕셔너리를 나누는 지 궁금했는데 완전 초보적인 생각이었다
딕셔너리형태인 address=뭐시기를 넣으면 자동적으로 **kwargs 로 출력된다.
만약 딕셔너리 형태를 순서를 섞어 놓으면

1
example(10, 20, address="Busan", 30, 'park', age1=77, age2=80 )

아래 이미지와 같이 SyntaxError가 발행한다.

SyntaxError

전체적으로 쉽게 설명한 참고링크1

5. 중첩함수

말그래도 함수안에 함수가 있는 것
중첩함수를 잘해둬야 클로저를 잘 해결할 수 있다
클로저를 나아가서 Python decorator도 중급자에서 필수적인 내용이니 꼭 이해하자

1
2
3
4
5
6
7
8
9
10
11
12
def nested_func(num):
def func_in_func(num):
print('언제실행될까? ', num)

print("함수 안에서")
func_in_func(num + 100)

nested_func(1)

# 출력값은
함수 안에서
언제실행될까? 101

혹시 함수안의 함수 func_in_func()를 실행시킬 수 있을까?

1
func_in_func(1)

정답은 실행불가!
아래 이미지처럼 Name Error가 발생한다

Name Error