21 Sun
[HEAD FIRST PYTHON] 10강 장식자 : 함수 장식하기
웹의 상태
웹은 상태가 없다. 따라서 사용자 인증 정보를 html 폼 또는 python 코드 변수로 처리하고 기억할 수 없다.
웹 서버로 세 개의 요청을 보내면 서버는 이를 세 번의 독립적인 개별 요청으로 간주하고 처리한다.
동일한 IP로 이루어진 요청인데도 불가하고
HTTP 라는 프로토콜의 동작 방식 때문
웹 서버가 모든 요청을 개별 요청으로 취급하도록 강제했다.
웹 서버가 처리해야 할 작업의 양이 최소화되어야 더 많은 요청을 처리할 수 있도록 확장할 수 있기 때문
HTTP는 작업의 양을 최소화 하기 위해
상태
라고 하는 정보를 유지하지 않도록 최적화 되어 있다.이를 stateless 라고 표현한다.
빠른 응답과 빠른 잊기가 웹의 특기
또한 웹 서버는 파이썬 코드를 실행하는 것이 아닌 웹앱 코드를 실행한다.
웹앱 코드가 항상 웹 서버의 메모리에 있는 것이 아니므로 웹앱 코드 상에 있는 변수를 기억할 수 없다.
예를 들어 다음과 같은 코드에서 다음 변수는 문제가 된다.
이 변수는 사용자가 로그인 했는지 안했는지를 알려주는 변수이다.
문제1
웹 서버는 웹앱 코드를 언제든 메모리에서 해제할 수 있으므로 전역 변수에 저장된 값이 사라질 수 있다.
실제로 로그인을 해서
logged_in
이 True가 되더라도 다시 코드를 임포트 했을 경우 False로 되어버린다.
문제2
웹 서버가 유저 마다
logged_in
변수를 가지고 있어야 한다. 또한, 각각의 유저 변수는 간섭받지 않아야 한다.
해결 책
전역 변수를 이용하지 않고 변수를 저장
각각의 사용자 데이터가 서로 간섭받지 않도록 유지
대부분의 웹앱 개발 프레임워크는 두 가지 요구사항을 세션이라는 기술로 해결한다.
세션은 상태가 없는 정보
세션
웹앱은 여전히 상태가 없는 웹에서 수행되지만 세션을 통해 웹앱이 상태를 기억할 수 있는 능력을 얻는다.
플라스크는 웹앱을 실행할 때마다 세션에 저장된 데이터를 사용할 수 있으며, 몇 번을 읽어 들였는지는 상관없다.
여기서 중요한 점은 플라스크가 어떻게 세션 기능을 처리하는 지 보다는 세션 기능을 제공한다는 점이다. 이 때 쿠키 생성에 필요한 비밀키 정보를 제공해야 하며, 비밀키를 이용해 쿠키를 암호화하고 외부 사용자로부터 정보를 보호한다.
1 : session 임포트
3 : 플라스크의 쿠기 생성에 필요한 비밀키 값을 제공
유추하기 어려운 값으로생성하는 것이 좋음
6~8 : session 딕셔너리에
user
변수의 값을 user로 저장10~12 : user키에 할당된 값에 접근하여 문자열 일부를 반환
장식자
장식자를 구현할 때 알아야 할 사실
함수를 구현하는 법
함수를 함수의 인자로 전달하는 법
함수에서 함수를 반환하는 법
다양한 개수와 유형의 함수 인자를 처리하는 법
함수를 함수의 인자로 전달
msg
와 같은 문자열이나hello
와 같은 함수의 이름 자체가 객체이다.이 객체를
id
나type
함수의 인자로 전달할 수 있다.이 때 인자로 전달된 함수를 호출하지는 않았다.
함수에서 함수를 반환하는 법
이러한 기능은 장식자를 구현할 때 필요하다.
또, 함수안에 함수를 중첩할 수 있는데,
결과가 신기하다. inner 함수를 호출하기 위해 outer 함수가 먼저 호출되는 모습
함수가 많은 행의 코드를 포함하는 복잡한 상황에서 함수 코드의 일부를 중첩 함수로 추상화 할 때 사용한다. 그러면 감싸는 코드를 읽기 쉬워진다.
이 때는 함수를 반환한 코드이다.
i
는 outer 함수가 만든 별칭이다.
다양한 개수와 유형의 함수 인자를 처리하는 법
func
라는 함수가 있을 때func(10)
func()
func(10, 20, 30, 40, 50)
등을 처리하기에는 생성자가 있더라도 한계가 있다.
이 때,
*
를 이용해 임의 개수의 인자를 받을 수 있다.
호출할 때도
*
를 쓸 수 있는데, 이는 각각의 인자로 전달하도록 하는 기법이다.
또,
**
를 사용해서 키워드 인자를 처리할 수 있다.
이해가 어려웠던 부분.
참고로
sep
은 print 함수의 인자들 사이에 구분자를 설정하는 키워드 인자이다. 기본값은 한 칸 공백이다.
기본적으로
def func(a, b)
로 함수를 정의하게 되면a와 b의 순서에 맞게 함수를 사용해야 하는데 키워드 인자를 쓸 경우 순서를 무시할 수 있다
func(10, 20)
=>a=10, b=20
func(b=20, a=10)
=>a=10, b=20
이 때 이 키워드를 그대로 사용하고 싶을 수 있고, 이 때 딕셔너리 형태로 사용하겠다는 뜻
다음과 같은 결과가 출력된다.
키워드 인자를 사용하는 모습
호출할 때도
**
를 사용할 수 있다.이미 앞서서 사용했었다
이는 다음처럼 각각의 키워드 인자를 사용한 것과 같은 효과이다.
conn = mysql.connector.connect(host= '127.0.0.1', user= 'vsearch', password= 'vsearchpasswd', database= 'vsearchlogDB'
이제 이를 모두 종합해서 사용 가능하다.
이렇게 되면 일반 인자로 들어올 때는
args
로, 키워드 인자로 들어올 때는kwargs
로 받을 수 있게 된다.
Last updated
Was this helpful?