cgi.FieldStorage와 인스턴스

승톨·2020년 8월 2일
0
post-thumbnail
post-custom-banner

CGI 탐구

이고잉님의 파이썬 코스를 진행하면서 코드를 치다보니까 아래의 cgi.FieldStorage라는 코드가 굉장히 반복적으로 나왔는데, 그러다보니 이 코드의 정확한 의미가 굉장히 궁금해졌다.

form = cgi.FieldStorage()

그래서 python.org의 cgi library 관련 문서를 읽어보았고, 아래의 내용을 찾았다.
FieldStorage에 대해 공부하기 전에 먼저 form data에 대해 살펴보았다.

A CGI script is invoked by an HTTP server, usually to process user input submitted through an HTML FORM
or ISINDEX element.

Most often, CGI scripts live in the server’s special cgi-bin directory. The HTTP server places all sorts of information about the request (such as the client’s hostname, the requested URL, the query string, and lots of other goodies) in the script’s shell environment, executes the script, and sends the script’s output back to the client.

The script’s input is connected to the client too, and sometimes the form data is read this way; at other times the form data is passed via the “query string” part of the URL. This module is intended to take care of the different cases and provide a simpler interface to the Python script. It also provides a number of utilities that help in debugging scripts, and the latest addition is support for file uploads from a form (if your browser supports it).

  • CGI 스크립트는 HTTP 서버에 의해 invoke되고 FORM 요소로 user input이 제출되는 형태인데, 이 input은 다양한 정보를 가질 수 있다.(호스트 네임, URL, 쿼리스트링 등)
  • input이 제출 되면 애플리케이션은 cgi 스크립트를 통해 클라이언트로 스크립트의 아웃풋을 다시 보낸다.

여기서 내가 짠 코드의 form data는 밑에 적혀 있는 "a href=''" 부분 중 URL의 쿼리 스트링 부분이라고 할 수 있다. '?'의 뒷 부분에 대한 데이터를 전송하는 것.

<li><a href="index.py?id=HTML">HTML</a></li>
<li><a href="index.py?id=CSS">CSS</a></li>
<li><a href="index.py?id=JavaScript">JavaScript</a></li>
    

쿼리스트링의 정의는 이 링크를 참고하자.

간략하게 form data라는거에 대해 알아봤으니, 이제 FieldStorage에 대한 부분을 더 읽어보았다.

To get at submitted form data, use the FieldStorage class. If the form contains non-ASCII characters, use the encoding keyword parameter set to the value of the encoding defined for the document. It is usually contained in the META tag in the HEAD section of the HTML document or by the Content-Type header. This reads the form contents from the standard input or the environment (depending on the value of various environment variables set according to the CGI standard). Since it may consume standard input, it should be instantiated only once.

The FieldStorage instance can be indexed like a Python dictionary. It allows membership testing with the in operator, and also supports the standard dictionary method keys() and the built-in function len(). Form fields containing empty strings are ignored and do not appear in the dictionary; to keep such values, provide a true value for the optional keep_blank_values keyword parameter when creating the FieldStorage instance.

A form submitted via POST that also has a query string will contain both FieldStorage and MiniFieldStorage items.

FieldStorage란

설명에 따르면, FieldStorage는 cgi 모듈에 내장되어있는 클래스이다.

위에서도 이야기했지만, 클라이언트 요청으로 받은 form 데이터는 FieldStorage object에 저장되고, 스크립트가 데이터를 처리하면 그 output을 클라이언트에 다시 보내서 HTML을 랜더링하게 되는데, FieldStorage는 HTML의 form 요소에서 넘어오는 데이터들을 쌓아두기 위한 개념(?)이라고 생각하면 될 듯하다.

이때, form data가 non-ASCII로 되어있으면 html meta tag에 encoding keyword parameter 넣어야 한다.(ex. "utf-8"?)

실제로 FieldStorage를 사용할 때는 'instantiated' 하게 되고,
FieldStorage 인스턴스는 파이썬의 딕셔너리 자료형 같이 인덱싱 할 수 있다.
그래서 'in'같은 멤버 연산자가 허용되고, key : value 형태가 허용된다.(즉, key, value 관련 메소드를 사용할 수 있다.)

단, 빈 문자열들을 포함한 데이터는 무시되는데, 이를 허용하려면 keep_blank_value keyword parameter를 허용해야 한다고 한다.

POST 형태로 form을 보내면 FieldStorage, MiniFieldStorage에 포함 될 수 있다.

실제로 내가 만든 FieldStorage instance를 출력해보면
FieldStorage(None, None, [MiniFieldStorage('id', 'CSS')])
라는 내용이 나온다.

저 내용들을 알기 위해 FieldStorage Attribute에 대해 찾아보았다.

  • filename
  • value
  • file
  • type
  • headers
  • name

name: the field name, if specified; otherwise None
filename: the filename, if specified; otherwise None;

출력된 결과 중 None이라고 되어있는 것은 name,filename이다.

결과 상에 MiniFieldStorage라는 것이 나오길래 이것도 찾아보니,
파일 업로드를 하지 않는 경우 MiniFieldStorage를 리턴하는 것 같고, MiniFieldStorage의 name은 딕셔너리의 key 형태처럼 쓰이는 것 같다. (그래서 value로 'CSS'가 나왔다.)

클래스와 인스턴스

마지막으로, 꽤 중요한 개념이라고 생각해서 중간에 나왔던 '인스턴스'에 대해서 좀 더 찾아보았다.

인스턴스에 대해 공부하다보니 , 인스턴스를 이해하려면 클래스를 알아야 한다는 것을 깨달았다.

  • 클래스라는 것은 어떤 개념을 총칭하는 단어이다.

  • 인스턴스는 그 클래스를 하나의 객체로서 정의하는 개념이다.
    (객체를 클래스의 인스턴스라고 한다는데, 이 부분은 사람들마다 의견이 분분한다고 한다.)

  • 예를 들어,'가수'라는 클래스가 존재하면, 우리는 '가수' 클래스로 BTS라는 인스턴스를 만들 수 있다.

이 때 하나 더 배운게 있는데, 바로 '메소드'이다.
클래스 내부에 정의된 함수를 '메소드'라고 한다.

처음에 클래스와 인스턴스를 이해할 때는 플라톤의 이데아 개념을 차용해서 이해했는데, 조금 더 찾아보니 이데아 비유는 클래스와 인스턴스 개념을 100% 설명해주지는 않는다고 한다.

이고잉님의 말씀을 빌리면, 클래스와 인스턴스의 정의는 다음과 같다.

클래스는 서로 연관된 로직들을 다른 로직들과 구분하기 위해서 그룹핑한 것이고 인스턴스는 클래스를 복제해서 각각의 인스턴스가 서로 다른 변수의 값들을 갖도록 한 것이라고 설명하고 있습니다
하나의 클래스를 바탕으로 서로 다른 상태를 가진 인스턴스를 만들면 서로 다른 행동을 하게 된다는 것을 알 수 있다. 하나의 클래스가 여러개의 인스턴스가 될 수 있다는 점이 객체 지향이 제공하는 가장 기본적인 재활용성이라고 할 수 있다.

참고 : https://opentutorials.org/course/1223/5400

또한 아래의 글들을 읽어보니, 인스턴스와 객체는 동일한 실체를 소유하고 있지만 개념적으로는 다를 수 있다는 것을 알게 되었다.
(특히, 첨부한 페이스북 글 링크의 코멘트가 이해에 도움을 주었다.)

추상적으로 존재하는 모든 사물이 Object입니다. 그것을 추상화(Abstraction)한 것이 Type 혹은 Class라 부르는 것이구요. 추상화 과정을 통해 해당하는 사물들을 쉽게 다루는 방법이 생기고, 새로운 것(사물)을 쉽게 만드는 방법이 나오죠. 반대로 (옛날에 그랬듯이) Type없이 일일이 각각의 사물을 만들수도 있습니다.
컴퓨터로 돌아오죠. Object가 하나 메모리에 있습니다. 이것을 만드는 방법은 여러가지가 있겠지요. 메모리를 적당한 사이즈로 잡고 첫번째 영역엔 이름, 두번째엔 몸무게.. 다른 식으론 - 흔히 하는 방법이죠. 타입 혹은 Class를 가지고 new를 합니다.
이때 생기는 Object를 Class의 Instance라고 부르고 이 과정을 Instantiation 이라고 합니다.

참고 :
1. https://blog.naver.com/ktw5724/220201962488
2. https://www.facebook.com/groups/codingeverybody/permalink/569274196446454/
3. https://wikidocs.net/85

정리

배운 내용을 토대로 내가 짠 아래의 코드를 풀이해보자면,
form = cgi.FieldStorage()

  • FieldStorage 클래스에서 인스턴스 하나를 만들어서 form이라는 변수에 저장한다.
  • form(FieldStorage 인스턴스)에는 HTML 요소에서 보내는 form 데이터 들이 쌓인다.
  • 추후 데이터들을 쓰고싶을 때는 특정 value를 가지고 있는 key를 사용하면 된다.

공부할 때 추가로 참고한 링크들 :

https://www.programcreek.com/python/example/352/cgi.FieldStorage

https://sencom.wordpress.com/2014/01/16/파이썬으로-cgi-프로그램-작성하기/

http://epydoc.sourceforge.net/stdlib/cgi.FieldStorage-class.html

profile
소프트웨어 엔지니어링을 연마하고자 합니다.
post-custom-banner

0개의 댓글