
Full Stack = Front-End + Back-End
💡 백엔드의 요소 3가지를 통해 작동 방식이 결정됨
Client
- 브라우저를 이용하는 사용자
- 🪑 레스토랑에서 테이블 구역(브라우저)에 앉는 손님
- 손님이 서버(주방)에 원하는 요리(특정 데이터)를 요청
Server
- 24시간 인터넷에 연결되어 요청을 받을 준비가 되어 있는 컴퓨터
- 🍳 레스토랑의 주방
- 주방에서는 식료품실(데이터베이스)에서 알맞은 재료를 가져와 요리(HTML/CSS/JS 파일로 렌더링)
Database
- 사이트의 모든 정보를 담아두는 곳
- 🥩 레스토랑의 식료품실
Flask : 가장 유명한 파이썬 기반 웹 프레임워크
💡 Library vs Framework
공통점: 직접 작성하지 않은 각종 코드의 묶음으로, 각종 기능이 필요할 때 사용 가능한 툴
차이점:
- 라이브러리
- 특정 작업 시에 사용자가 호출해야 함
- 프레임워크
- 코드를 프레임워크 규칙에 맞게 정의해야 함
- 특정 기능을 실행할 때 프레임워크가 코드를 호출
가장 간단한 양식으로 웹 서버 생성하기
터미널 → pip install Flask 입력⌨️ hello.py
from flask import Flask
app = Flask(__name__) # 플라스크 클래스로 애플리케이션 생성 후 초기화
@app.route("/") # 사용자가 URL 끝에 / 를 붙여 홈페이지로 접속할 때 작동
def hello_world():
return "<p>Hello, World!</p>"
파일 작성 후 터미널에서 명령어 입력
ctrl + c로 서버를 직접 꺼야 한다
html 파일을 작성하지 않아도 자동으로 만들어짐
Terminal
= command line (명령어를 한 줄씩 입력해 컴퓨터를 제어)
= Shell
🥜 운영체제(OS)가 견과류라면
- Kernel : 알맹이, 하드웨어와 상호작용하는 실제 프로그램(OS의 핵심부)
- Shell : 겉껍질, 알맹이와 더불어 하드웨어와 소통하기 위한 사용자 인터페이스
- GUI : 파일탐색기나 파인더를 이용해 파일에 접근
- CLI : 커널과 상호작용하는 또 다른 방식으로, 더 강력한 제어권 보유
(맥의 경우 bash 셸, zsh 셸이 존재 → 더 많은 기능을 제공하고 편리한 zsh 셸이 기본으로 설정됨)
< 기본 명령어 >
| 키워드 | 의미 | 역할 |
|---|---|---|
| pwd | print working directory | 현재 내 위치를 파일 경로로 출력 |
| ls | list | 현재 작업 디렉토리에 있는 파일과 폴더를 전부 나열 |
| cd 폴더명 cd .. | change directory | 해당 디렉토리로 이동(현 위치에서 접근 가능해야 함) 한 단계 상위 폴더로 이동 |
| mkdir 폴더명 | make directory | 해당 이름으로 새 폴더(디렉토리) 생성 |
| touch 파일명.확장자 | 해당 이름으로 새 파일 생성 | |
| rm | remove | 해당 파일 삭제(ls로 먼저 파일이 있는지 확인하기) |
| rm -rf | remove recursively, forcibly | 해당 폴더와 그 안의 내용 모두 삭제(삭제할 폴더 밖에서 실행) |
TIP: 폴더명 등을 입력할 때 앞의 몇 글자만 입력하고 Tap 키 누르기
Emulator
__name__
⌨️ hello.py
from flask import Flask
app = Flask(__name__)
# __name__ 속성의 출력 확인
print(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
if __name__ == "__main__":
# 터미널에 입력했던 [flask --app hello run] 과 같은 작업
# Ctrl + c 대신 파일 실행만 멈추면 플라스크 앱 구동도 멈춤
app.run()
파이썬 함수는 1급 객체(First-class object)
# 인자로 전달할 함수
def add(n1, n2):
return n1 + n2
def subtract(n1, n2):
return n1 - n2
def multiply(n1, n2):
return n1 * n2
def divide(n1, n2):
return n1 / n2
# 함수를 인자로 전달하기
def calculate(calc_function, n1, n2): # 함수를 일반 인자처럼 다른 함수에 전달
return calc_function(n1, n2) # 나중에 함수를 작동시킬 때 괄호를 붙임
result = calculate(add, 2, 3)
print(result)
# 함수를 다른 함수 안에 넣기(중첩 함수)
def outer_function():
print("I'm outer")
def nested_function():
print("I'm inner")
nested_function() # 외부 함수 호출
outer_function() # 외부 함수 안에서 중첩 함수 호출
# 함수의 결과로 다른 함수를 반환
def outer_function():
print("I'm outer")
def nested_function():
print("I'm inner")
return nested_function # 괄호를 빼서 비활성화
inner_function = outer_function() # outer_function()의 출력 할당
inner_function() # inner_function()을 따로 실행 가능
Python Decorator
@
import time
# 간단한 데코레이터 함수
def delay_decorator(function):
def wrapper_function():
# 함수가 작동되기 전에 할 작업
time.sleep(2)
# 함수 작동
function()
function()
# 함수 실행 후에 할 작업
return wrapper_function
# @ syntactic sugar를 사용한 구문
@delay_decorator
def say_hello():
print("Hello")
@delay_decorator
def say_bye():
print("Bye")
say_hello()
say_bye()
# @ syntactic sugar를 사용하지 않은 구문(데코레이터를 바로 호출하여 함수명 넘기기)
def say_greeting():
print("How are you?")
decorated_function = delay_decorator(say_greeting)
decorated_function()
Python Decorators
함수가 실행되는 데 걸리는 시간을 측정하는 자체 데코레이터 함수
time.time(): 1970년 1월 1일 00:00:00부터 현재까지의 시간을 초 단위로 반환- function.__name__ : 해당 함수의 이름을 얻을 수 있음
import time
current_time = time.time()
print(current_time)
def speed_calc_decorator(function):
def wrapper_function():
start_time = time.time()
function()
end_time = time.time()
print(f"{function.__name__} run speed: {end_time - start_time}s")
return wrapper_function
@speed_calc_decorator
def fast_function():
for i in range(1000000):
i * i
@speed_calc_decorator
def slow_function():
for i in range(10000000):
i * i
fast_function()
slow_function()