강의 내용을 암기하는 것이 아닌 '파이썬으로 이런것도 할 수 있구나 를 이해하는 것이 학습 목표.
프로젝트 하면서 '파이썬으로 이런 것도 할 수 있었지?' 떠올리면서 강의를 보거나 구글링해서 이용하면 된다.
코딩 컨벤션(Coding conventions) : 코딩 스타일 규약. 규약이 없다면 코드 의도 파악이나 오류를 찾기어려움.
Cmd 터미널로 파이썬 파일 실행 시키기
- 현재 위치가 파일의 위치가 맞는지 확인.
- 명령문 작성. python main.py
- 가상환경을 공부할 때 터미널을 잘 다루어야 하기 때문에 이와 같은 방법으로 실행시킨다.
가상환경(Virtual envirnoment, venv)
- 파이썬은 pip 라는 패키지 인스톨러를 사용해 패키지를 설치하고 관리.
- 패키지를 설치하게 되면 파이썬을 실행하는 모든 환경에 설치하게 됨.
- 프로젝트 마다 사용하는 패키지들이 다를 경우 (A 는 a-1을 사용. B는 a-2) 버전만 다른 a-1, a-2는 충돌을 일으킬 가능성이 있다.
- 그렇기 때문에 프로젝트마다 격리된 환경을 구성 하기 위해 가상환경 사용.
가상환경 만들기
- 명령문 : python -m venv venv
- python -m venv(가상환경 만들거야.) venv(폴더 이름은 이거야.{바꾸어도 됨})
가상환경 활성화
- 명령문 : venv(가상환경 폴더 이름)\Scripts\activate
- 명령문 뜻 : venv 폴더에 있는 Scripts 폴더에 있는 activate 파일 실행.
- tab : 자동완성.
패키지 설치
- 명령문 : pip install (패키지이름)
- venv에 많은 패키지가 설치되어 있어도 venv가 활성화 되어 있지 않다면 사용을 못함.
- 프로젝트 마다 독립된 한경이기 때문에 새 프로젝트라면 다시 설치해주어야 함.
패키지 사용하기
- 명령문 : pip install reqiests (터미널에 명령을 내려야함.)
- 명령문 : import requests
가상환경 비활성화
- 명령문 : deactivate (터미널)
코드 컨벤션
- 각 언어에는맞는 코드 컨벤션이 존재.
- 다른 사람들이 짠 코드를 쉽게 이해하기 위해 스타일을 통일하자는 약속.
- 파이썬은 PEP 8 로 약속 되어 있다.
네이밍 컨벤션
- 함수, 변수, 클래스 등 이름을 지을 때 방식을 말함.
- 함수 , 변수 : Snake 표기법
- 클래스 : Pascal 표기법 (PythonIsVeryGood 각 띄어쓰기마다 대문자로.)
- Camel은 자바에서 주로 사용 : pythonIsVeryGood
- Uper Camel Case :PythonIsVeryGood (pascal과 같다. 파이썬은 주로 camel 표기법을 사용한다도 맞는 말이다. 하지만 Pascal 이라고 주로 부름.)
- Lower Camel Case : pythonIsVeryGood
- Snake 표기법 : python_is_very_good
- 상수 네이밍은 모두 대문자, 길게 정의한다면 Snake를 대문자로 사용.
- 이름만 보고도 내용이 뭔지 추측할 수 있도록 직관적이게 짓는다.
Formetter
- 코드를 컨벤션에 맞게 개행,정렬 해준다.
- 환경설정에 python formatting 검색하고 python > Formatting: Provider를 autopep8 로 설정. format on save를 검색하고 체크해주면 저장 할때 개행,정렬 해준다. autopep8 패키지를 설치해 주어야 한다.
변수 유효 범위(variable scope)
- 변수가 선언된 위치나 키워드에 따라 변수를 사용할 수 있는 범위가 달라짐.
- 유효 범위에 따라 지역변수(local variable), 전역변수(global variable)로 나뉨.
- 지역변수 : 함수 내부에서 선언되며 다른 함수에영향을 끼치지 않음.
- 전역변수 : 함부 밖에서 선언되며 어디서든 접근할 수 있음.
- 지역 변수로 선언된 변수는 global 키워드 사용해 전역 변수호 재선언 할 수 있음.
def func1():
test = 123
# test는 지역변수다.
# 그러므로 다른 함수에 영향을 끼치지 못한다.
def func2():
print(test)
func1()
func2()
NameError: name 'test' is not defined
지역 test와 전역 test는 연관이 없는 코드다.
test = 123
def func1():
test = 456
print(test)
func1()
456
test = 123
def func1():
test = 456
print(test)
def func2():
print(test)
func1()
func2()
456
123
func1의 test를 전역변수로 사용하고 싶을때 global
test = 123
def func1():
global test
test = 456
print(test)
def func2():
print(test)
func1()
func2()
456
456
global를 사용할때 코드가 길어지면 어디서 값이 도출된 것인지 모를때가 많아진다.
그땐 return으로 결과값을 받아와서 사용하는 것이 더 좋다.
test = 123
def func1():
return 456
def func2(value):
print(value)
result = func1()
func2(result)
자주 사용되는 모듈 및 패턴
type() : 값의 자료형 확인
- print(type(변수) 또는 print(a, type(a)) : 변수에 담긴 자료형이 어떤 것인지 알 수 있다.
- 모듈로 값을 받아올 때 어떤 자료형인지 구분하기 어려울 때 사용. 1 인지 '1' 인지..
split() : string을 list로 변환
- split() : 괄호 값 기준으로 문자를 리스트 형태로 쪼갠다.
a = "안녕 친구들!!"
b = a.split(" ")
print(b)
['안녕', '친구들!!']
join() : list를 string으로 변환
- join() : 괄호 값은 리스트가 된다.
- 밑에 예제에서 처럼 큰따옴표 내용을 리스트 사이에 넣어 합치게 된다.. b = " ".join(a)
a = ['안녕', '친구들!!']
b = " ".join(a)
print(b)
replace() : 문자열 바꾸기
- replace("!", "~") : 괄호 왼쪽 값을 오른쪽 값으로 바꾸겠다 라는 뜻이다.
a = "안녕 친구들!!"
b = a.replace("!", "~")
print(b)
안녕 친구들~~
pprint() : 코드 예쁘게 출력하기
- 임포트 해줘야 한다. : from pprint import pprint
from pprint import pprint
sample_data = {
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{"id": "1001", "type": "Regular"},
{"id": "1002", "type": "Chocolate"},
{"id": "1003", "type": "Blueberry"},
{"id": "1004", "type": "Devil's Food"}
]
},
"topping":
[
{"id": "5001", "type": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5005", "type": "Sugar"},
{"id": "5007", "type": "Powdered Sugar"},
{"id": "5006", "type": "Chocolate with Sprinkles"},
{"id": "5003", "type": "Chocolate"},
{"id": "5004", "type": "Maple"}
]
}
pprint(sample_data)
{'batters': {'batter': [{'id': '1001', 'type': 'Regular'},
{'id': '1002', 'type': 'Chocolate'},
{'id': '1003', 'type': 'Blueberry'},
{'id': '1004', 'type': "Devil's Food"}]},
'id': '0001',
'name': 'Cake',
'ppu': 0.55,
'topping': [{'id': '5001', 'type': 'None'},
{'id': '5002', 'type': 'Glazed'},
{'id': '5005', 'type': 'Sugar'},
{'id': '5007', 'type': 'Powdered Sugar'},
{'id': '5006', 'type': 'Chocolate with Sprinkles'},
{'id': '5003', 'type': 'Chocolate'},
{'id': '5004', 'type': 'Maple'}],
'type': 'donut'}
pprint 안쓸때
{'id': '0001', 'type': 'donut', 'name': 'Cake', 'ppu': 0.55, 'batters': {'batter': [{'id': '1001', 'type': 'Regular'}, {'id': '1002', 'type': 'Chocolate'}, {'id': '1003', 'type': 'Blueberry'}, {'id': '1004', 'type': "Devil's Food"}]}, 'topping': [{'id': '5001', 'type': 'None'}, {'id': '5002', 'type': 'Glazed'}, {'id': '5005', 'type': 'Sugar'}, {'id': '5007', 'type': 'Powdered Sugar'}, {'id': '5006', 'type': 'Chocolate with Sprinkles'}, {'id': '5003', 'type': 'Chocolate'}, {'id': '5004', 'type': 'Maple'}]}
random : 랜덤한 로직이 필요할 때
- 임포트 해줘야한다. : import ramdom
- 리스트 무작위로 섞기
import random
a = [1, 2, 3, 4, 5,]
random.shuffle(a)
print(a)
[1, 4, 5, 2, 3]
- 1에서 10까지 무작위 숫자 생성
import random
a = random.randint(1, 10)
print(a)
time : 시간 다루기
- 임포트 해줘야한다. : import time
import time
a = time.time() #시작 시간 저장
time.sleep(1) # 1초간 대기
b = time.time() #종료 시간 저장
print(f"코드 실행 시간 : {b-a:.5f}") #5f는 소수점 다섯째 자리 까지 출력
코드 실행 시간 : 1.00065
datetime : 날짜 다루기
- 임포트 해줘야한다. : from datetime import datetime, timedelta
from datetime import datetime
print(datetime.now()) #현재시간 출력하기
2023-03-23 14:10:19.784002
- datetime은 클래스로 되어있어서 spilt 하거나 join 하거나 하려면 str로 바꿔줘야한다.
from datetime import datetime
a = datetime.now()
b = a.split(" ")
print(b)
AttributeError: 'datetime.datetime' object has no attribute 'split'
from datetime import datetime
a = datetime.now()
print(a, type(a))
2023-03-23 14:21:45.828411 <class 'datetime.datetime'>
from datetime import datetime
a = str(datetime.now())
b = a.split(" ")
print(b)
['2023-03-23', '14:20:40.195673']
strptime() : datetime.datetime 클래스로 변경할 수 있다.
from datetime import datetime, timedelta
date_str = '2023-03-23 14:27'
date_class = datetime.strptime(date_str, "%Y-%m-%d %H:%M")
print(date_class, type(date_class))
2023-03-23 14:27:00 <class 'datetime.datetime'>
%y : 두 자리 연도 / 20, 21, 22
%Y : 네 자리 연도 / 2020, 2021, 2022
%m : 두 자리 월 / 01, 02 ... 11 ,12
%d : 두 자리 일 / 01, 02 ... 30, 31
%I : 12시간제 시간 / 01, 02 ... 12
%H : 24시간제의 시간 / 00, 01 ... 23
%M : 두 자리 분 / 00, 01 ... 58, 59
%S : 두 자리 초 / 00, 01 ... 58, 59
strftime() : datetime.datetime 클래스를 문자열로 변경
date_str = datetime.strftime(now, "%y/%m/%d") 형식은 변경 할 수 있다.
from datetime import datetime, timedelta
now = datetime.now()
date_str = datetime.strftime(now, "%y/%m/%d %H:%M:%S")
print(date_str, type(date_str))
23/03/23 14:33:42 <class 'str'>
timedelta() : 날짜를 더하고 뺄 수 있다.
timedelta를 임포트해줘야함다.
from datetime import datetime, timedelta
tda = datetime.now() - timedelta(days=2)
print(tda, type(tda))
2023-03-21 14:40:18.096321 <class 'datetime.datetime'>
문자열
from datetime import datetime, timedelta
tda = str(datetime.now() - timedelta(days=2))
print(tda, type(tda))
2023-03-21 14:41:10.011829 <class 'str'>
조건문 심화
'''== : 값이 일치하는지 비교'''
"a" == "a" # True
"a" == "b" # False
1 == "1" # False, 값은 동일하지만 자료형이 다르기 때문
'''!= : 값이 일치하지 않는지 비교'''
0 != 1 # True
0 != 0 # False
'''>, < : 값이 큰지 작은지 비교'''
5 > 2 # True
1 < 0 # False
1 > 1 # False
'''>=, <= : 값이 크거나 같은지, 작거나 같은지 비교'''
1 >= 1 # True
'''in : 특정 값이 list / tuple / set에 포함되어 있는지 확인'''
4 in [1, 2, 3] # False
1 in (1, 2, 3) # True
# 모든 비교 연산자의 결과는 print()로 확인할 수 있습니다.
print(1 == 1) # True
If문은 true냐 false 냐에 따라 통과시켜주는 것이다.
a = 20
if a>10:
print('참')
else:
print('거짓')
분기문
a = 25
if a > 20:
print('20이상')
elif a > 10:
print('10이상')
else:
print('나머지')
and : 조건이 다 만족 되어야 참
참이면서 거짓이면 참!
if True and False:
print('통과!!')
or : 한가지만 만족 되어도 참
참이거나 거짓이면 참!
if True or False:
print('통과!!')
통과!!
우선순위 : 괄호로 우선순위를 줄 수 있다.
참이거나 거짓이고 또 참이면 참!
if (True or False) and True:
print('통과!!')
통과!!
비어있는 string, list 등은 False 로 판단.
a = []
b = ""
if not a:
print('a가 거짓이면 참이 되므로 출력된다.')
if not b:
print('b가 거짓이면 참이 되므로 출력된다.')
a가 거짓이면 참이 되므로 출력된다.
b가 거짓이면 참이 되므로 출력된다.
bool() 함수로 참인지 거짓인지 확인하기
print(bool(""))
print(bool(0))
print(bool([]))
print(bool([""]))
print(bool("sample"))
print(bool([1, 2]))
print(bool(1))
print(bool(-1))
False
False
False
True
True
True
True
True
all 과 any
- 리스트를 인자로 받게 된다.
- all은 모든 인자들이 참이어야 통과!
- any는 하나의 인자만 참이어도 통과!
if all([True, False, True]):
print('all이 참이면 출력!')
if any([False, False, True]):
print('any가 참이면 출력!')
any가 참이면 출력!
함수의 인자와 리턴 타입
여러 함수가 있고 비슷해 보여도 사용법이나 리턴 타입이 달라 기능을 알고 사용해야한다.
sort() : 변수를 정렬해준다. 정렬된 값을 다른 변수에 담을 수 없다.
a = [5, 4, 3, 2, 1]
a.sort()
print(a)
[1, 2, 3, 4, 5]
sorted() : 정렬된 값을 return 한다. 변수 a가 정렬 된게 아니다. 다른 변수에 담을 수 있다.
a = [5, 4, 3, 2, 1]
b = sorted(a)
print(b)
[1, 2, 3, 4, 5]
a = [5, 4, 3, 2, 1]
b = a.sort()
print(b)
None
리턴 타입 확인하기
1. 구글링
2. docstring
3. 함수 구현 코드 확인
내장 함수는 속도를 위해 c언어로 컴파일 되어 해당 되지 않을 수 있지만
외부 라이브러리를 이용한다면 구현부 코드를 보고 익히는 것이 좋은 방법이다.
구현 코드 확인 방법은 import 하고 ctrl 누르고 클릭하게 되면 볼 수 있다.
try /execption
- 파이썬은 에러가 발생하면 코드를 중지하게 되어있는데 try/ execption을 사용하면 계속 실행 시킬 수 있다.
- Exception 에러들을 e로 정의하고 그 그 에러를 출력한다.
- 권장하지 않음!
try:
x = int(input("나눌 수를 입력하세요: "))
y = 100 / x
except ZeroDivisionError:
print('0으로는 나눗셈 못해!')
except ValueError:
print('문자열로 나눗셈 못하거든?!')
except Exception as e
print(f"다른 에러들은 여기로! : {e}")
패킹과 언패킹
요소를 묶어주거나 풀어주는 것을 함. list나 dictionary의 값을 함수에 입력할 때 주로 사용.
매개변수 앞에 *은 모든 인자를 args에 집에 넣겠다 라는 뜻이다. args = arguments 인자들을 뜻한다.
인자에 *을 붙인 것은 언패킹을 의미한다.
def add(*args):
result = 0
for i in args:
result += i
return result
numbers = [1, 2, 3, 4]
print(add(*numbers))
10
딕셔너리 형태로 나오게 된다.
def good(**kwargs):
print(kwargs)
good(name='jhon', age=29)
kwargs.get은 인자에 같은 같은 이름의 키값과 고유의 밸류가 있다면 가져가서 딕셔너리로 만든다. 값이 없다면 대시가 나온다.
def set_profile(**kwargs):
profile = {}
profile["name"] = kwargs.get("name", "-")
profile["gender"] = kwargs.get("gender", "-")
profile["birthday"] = kwargs.get("birthday", "-")
profile["age"] = kwargs.get("age", "-")
profile["phone"] = kwargs.get("phone", "-")
profile["email"] = kwargs.get("email", "-")
return profile
user_profile = {
"name": "lee",
"gender": "man",
"age": 32,
"birthday": "01/01",
"email": "python@sparta.com",
}
{'name': 'lee', 'gender': 'man', 'birthday': '01/01', 'age': 32, 'phone': '-', 'email': 'python@sparta.com'}
class 심화
파이썬(Python): 클래스(class) 안 def __init__(self): 와 self 등을 제대로 이해하기
"def __init__(self):" 파이썬python을 약간이라도 다루기 시작한 사람이라면 이내 마주치는 구문이다. 개인적으로는 def __init__(self) 구문은 파이썬에서만 사용하는 함수로 안다. 다른 언어에서 본 적이
writingstudio.tistory.com
클래스는 과자 틀이고, 인스턴스는 과자 틀로 만들어낸 과자다.
init 함수는 인스턴스를 만드는 과정에서 무조건 실행되는 함수.
변수와 인자를 init 함수에 주게되면 객체가 만들어진다.
self 는 클래스 그 자체이다.
어떻게 쓰든 __init__에서 첫 번째로 들어가는 self(첫번째 변수)는 CookieFrame 클래스 스스로를 지칭하게 된다. self를 다른걸로 고쳐도 된다.
class CookieFrame():
def __init__(self, name): #name 이라는 인자를 받는다.
print(f"생성 된 과자의 이름은 {name} 입니다!")
self.name = name #name이라는 변수에 name 인자를 받는다.
cookie1 = CookieFrame("cookie1") #쿠키 1이라는 이름으로 쿠키1 인자를 준다. 객체가 생성되었다.
cookie2 = CookieFrame("cookie2")
print(cookie1.name) #cookie1이라는 변수의 name으로 어떤 인자값을 받았는지 알 수 있다.
print(cookie2.name)
cookie1
cookie2
인자에 디폴트값을 줄 수 있다. 디폴트값 없이 인자 값이 없다면 에러가 난다.
class CookieFrame():
def __init__(self, name="default"):
print(f"생성 된 과자의 이름은 {name} 입니다!")
self.name = name
cookie1 = CookieFrame("")
cookie2 = CookieFrame("cookie2")
print(cookie1.name)
print(cookie2.name)
default
cookie2
class 상속
- 클래스를 생성할 때 다른 클래스의 변수나 메소드 등을 가져와 사용하는 기능.
- 동일한 코드를 여러 클래스에서 조금씩 수정해서 사용하거나 모듈에 내장된 클래스를 변경할 때 주로 사용.
- 상속 해주는 클래스를 부모(parents),슈퍼(super) 클래스. 상속 받는 클래스는 자식(child),서브(sub) 클래스.
모듈 : 파이썬으로 이루어진 파일에는 함수,변수,클래스 등이 있을 것. 이 파일을 import해서 모듈로 사용하는 것.
상속 받은 클래스를 기반으로 새로운 클래스 만들기
class Monster():
def __init__(self, hp):
self.hp = hp
def attack(self, damage):
self.hp -= damage
def status_check(self):
print(f"monster's hp : {self.hp}")
class FireMonster(Monster):
def __init__(self, hp):
self.attribute = "fire"
#init 함수를 실행하면 파이어 속성을 만들고
#부모의 init 함수를 또 사용하여 hp가 있는 객체가 만들어진다.
super().__init__(hp)
# 부모 클래스에 존재하는 status_check 메소드를 overriding 합니다.
#오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는것.
# 더 좋은 코드는self.attribute = "fire"를 출력하도록 하면 메서드를 만들 필요도 없었을 것.
def status_check(self):
print(f"fire monster's hp : {self.hp}")
class IceMonster(Monster):
def __init__(self, hp):
self.attribute = "ice"
super().__init__(hp)
def status_check(self):
print(f"ice monster's hp : {self.hp}")
fire_monster = FireMonster(hp=100)
# FireMonster 클래스에는 attack 메소드가 없지만
# 부모 클래스에서 상속받았기 때문에 별도의 선언 없이 사용 가능합니다.
fire_monster.attack(20)
fire_monster.status_check()
ice_monster = IceMonster(hp=200)
ice_monster.attack(50)
ice_monster.status_check()
상속 받은 클래스의 특정 코드를 변경해 사용하기
- 모듈의 코를 수정하여 사용하는 것 많은 버그를 생기게 할 가능성이 많다.
- 그래서 새로운 클래스를 하나 만들고 오버라이딩 해서 코드를 수정해서 사용하는게 더 효율적이다.
class 객체(object) 다루기
- 객체 = object = 인스턴스
- list와 dict 같은 자료형 데이터를 생성하고 활용 했던 것이 클래스의 객체를 생성하고 매소드를 활용하는 과정.
- 객체에서 사용 가능한 메소드들은 검색,docstring, 구현 코드 등을 확인하여 찾을 수 있다.
- 구현 코드를 확인하는 걸 권장하는 이유는 다른 사람이 짠 코드를 보다보면 새로운 것을 배울 수 있기 때문.
- 구현 코드를 보고 개선할 부분을 찾으면 컨트리뷰터가 될 수 있고 취업에 큰 도움이 된다.
'python' 카테고리의 다른 글
파이썬 기초 부교재 정리. 3 (0) | 2023.03.22 |
---|---|
파이썬 기초 부교재 정리. 2 (0) | 2023.03.22 |
파이썬 기초 부교재 정리. 1 (0) | 2023.03.21 |
파이썬 문법 기초. 2 (0) | 2023.03.20 |
파이썬 문법 기초. 1 (0) | 2023.03.20 |