def mul_of(m):
def mul(n):
return m * n
return mul
if __name__ == "__main__":
mul3 = mul_of(3)
mul5 = mul_of(5)
print(mul3(10)) # 30 출력
print(mul5(10)) # 50 출력
파이썬에서 위 코드처럼 클래스를 이용한 것과 비슷하게 함수 안에 함수를 담아 반환하여 객체를 만드는 것을 클로저라고 한다.
import time
def decorate(original_func): # 기존 합수를 입력으로 받는다.
def wrapper():
start = time.time()
original_func() # 기존 함수를 수행한다.
end = time.time()
print("함수 수행시간: %f 초" % (end - start))
return wrapper
def myfunc():
""" 데코레이터 확인 함수 """
print("함수가 실행됩니다.")
decorated_myfunc = decorate(myfunc)
decorated_myfunc()
파이썬에서 데코레이터란 기존 함수의 변경 없이 추가적인 기능을 덧붙일 수 있도록 해 주는 함수이다. 위 코드에선 기존 함수인 myfunc()를 decorate()함수에 인자로 주어 decorated_myfunc()이란 함수 실행 시간 기능을 추가한 함수를 만들었다. 공통된 추가 기능을 여러 함수에 추가하고자 할때 유용하다.
import time
def decorate(original_func):
def wrapper():
start = time.time()
original_func()
end = time.time()
print("함수 수행시간: %f 초" % (end - start))
return wrapper
@decorate
def myfunc():
""" 데코레이터 확인 함수 """
print("함수가 실행됩니다.")
# decorated_myfunc = decorate(myfunc) # 데코레이터 어노테이션으로 인해 더이상 필요하지 않다.
# decorated_myfunc()
myfunc()
위 코드처럼 어노테이션을 이용해 더 가독성이 좋게 코드를 관리할 수 있다. 파이썬은 함수명 위의 어노테이션을 데코레이터 함수로 인식한다. 위에서 myfunc()은 decorate()를 거쳐서 수행된다. 이때 데코레이터 함수는 다양한 기존 함수에 대응할 수 있어야하기 때문에 wrapper 함수에 *args, **kwargs를 추가해 호출하도록 할 수 있다.
import time
def decorate(original_func):
def wrapper(*args, **kwargs): # *args, **kwargs 매개변수 추가
start = time.time()
original_func(*args, **kwargs) # 전달받은 *args, **kwargs를 입력파라미터로 기존함수 수행
end = time.time()
print("함수 수행시간: %f 초" % (end - start))
return wrapper
@decorate
def myfunc(msg):
""" 데코레이터 확인 함수 """
print("'%s'을 출력합니다." % msg)
myfunc("You need python")
import time
import functools
def decorate(original_func):
@functools.wraps(original_func)
def wrapper(*args, **kwargs): # *args, **kwargs 입력인수 추가
start = time.time()
original_func(*args, **kwargs) # 전달받은 *args, **kwargs를 입력파라미터로 기존함수 수행
end = time.time()
print("함수 수행시간: %f 초" % (end - start))
return wrapper
@decorate
def myfunc(msg):
""" 데코레이터 확인 함수 """
print("'%s'을 출력합니다." % msg)
데코레이터 작성 시 위처럼 @functools.wraps()를 추가해줘야 함수의 올바른 동작을 보장할 수 있다.
https://wikidocs.net/83687
= 스키마 마이그레이션 = 데이터베이스 변경 관리
데이터베이스 마이그레이션이란 관계 데이터베이스 스키마에 대해 점진적, 가역적 변경을 관리하는 것과 버전 관리하는 것을 의미한다. 데이터베이스 스키마를 새로운/이전 버전으로 업데이트/복구할때 스키마 마이그레이션을 수행한다. 스키마 마이그레이션 도구를 이용해 수행된다.
https://en.wikipedia.org/wiki/Schema_migration
Alembic을 이용해 Flask 응용프로그램에 대해 SQLAlchemy 데이터베이스 마이그레이션을 관리하는 익스텐션이다.
Almebic이란 SQLAlchemy를 이용할때 사용할 수 있는 스키마 마이그레이션 도구이다.
예시)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(128))
위 응용프로그램을 갖고 아래 명령어로 마이그레이션 레포지토리를 생성할 수 있다. 이 레포지토리도 소프트웨어 버전 관리 시 추가해줘야한다.
$ flask db init
이후 마이그레이션을 생성할 수 있다. 데이터베이스 변경을 자동 감지해 리비전 스크립트를 작성하지만 모든 변경이 자동 감지 되지 않기 때문에 데이터베이스 적용전에 스크립트를 확인해줘야한다.
$ flask db migrate -m "migration message"
다음 명령어로 데이터베이스에 마이그레이션을 적용할 수 있다.
$ flask db upgrade
https://flask-migrate.readthedocs.io/en/latest/#example
파이썬에서 데이터베이스를 사용하기 위해 다양한 도구를 제공하는 SQLAlchemy를 자주 사용한다.
Object Relational Mapping
ORM이란 객체 지향 언어를 이용해 호환되지 않는 타입 시스템간 데이터를 변환하는 기술이다. 이 과정에서 가상의 객체 데이터베이스를 생성하게되어 프로그래밍 언어에서 사용 가능해진다.
SQLAlchemy를 이루는 도구 중 하나이다. 유저가 명시한 클래스를 데이터베이스 테이블과, 그 클래스의 객체를 테이블의 인스턴스를 연관 시켜준다. 이때 연관된 객체와 인스턴스의 상태 변화를 동기시켜주는 시스템과 유저가 명시한 클래스와 관계로 데이터베이스 쿼리를 표현하는 시스템을 포함한다.