GET/POST データの操作 – Python

GET・POST リクエストの判定

os モジュールのenviron[‘REQUEST_METHOD’] を使用します。POST でリクエストされると “POST”、GETでリクエストされると “GET” になります。通常は GET リクエストなので “GET” が入ります。

import os 
if os.environ['REQUEST_METHOD'] == 'POST':
print 'POST REQUEST'

GET・POST データの取得

cgi モジュール

リクエストされたデータを取得するには cgi モジュールの FieldStorage() を使用します。 これは、GET、POST の双方のデータを取得する事が出来ます。

data = cgi.FieldStorage()

値にアクセスするには、辞書の get のような動きの getvalue() メソッドがあります。

getvalue(取得したいキー, キーに値がなかった時のデフォルト値)

で使用することが出来ます。

data.getvalue('name', 'not found') 

POST か GET に値があれば name キーの値、なければnot found が返されます。

同じフィールドに複数の値がある場合

例えば、 GET パラメータに name=kingyo を指定、POST も同時に name=bachi とした場合、getvalue() の戻り値は それらを含んだリストに変わります。

getvalue() だと、単一の場合と複数の場合で、リストになったり文字列になったりするので、常にリストで取得したい場合は getlist(name) を使用します。

data.getlist('id')

getlist() は指定された name のフィールドや値がなければ空のリストを返します。

また、逆に常に文字列で取得したい場合は、getfirst(name, default=None) を使用します。

getfirst('id')

getfirst() は、複数の値があったとしても、一番最初の値だけを返します。なにが最初に来るかの順番は、ブラウザによって変わる可能性があるので、並び順は考慮しない作りにしないといけないようです。
name に指定されたフィールドや値がなければ、default に指定された値が返されます。(初期設定では None が返されます)

辞書風にアクセスする

getvalue() や getfirst(), getlist() 等を使わずに、辞書風でアクセスして値を取得する事も出来ます。

data['name'].value

辞書風アクセスは、.value だけでなく、in 演算子で包含検査、keys() や len() もサポートしているようです。

if 'name' in data:
	# True
else:
	# False

data.keys()  # ['name'] 等

len(data)  # 1

参考

http://www.python-izm.com/contents/cgi/request.shtml
http://docs.python.jp/2/library/cgi.html
http://bygzam.seesaa.net/s/article/110314834.html

Python 基本 – クラス

Python で基本的なクラスの使用方法です。

  • クラスの作成
    • 空のクラス
    • インスタンス化
    • 変数の定義
    • 関数の定義
    • プライベートな変数・関数
  • コンストラクタ

クラスの作成

空のクラス

なにも行わない空のクラスを作成するには、以下の用にします

class EmptyClass:
    pass

インスタンス化

作成したクラスをインスタンス化するには、関数を変数に代入するように行います。

empty = EmptyClass()

変数の定義

クラスに変数を定義することが出来ます。いわゆるプロパティです。

class WordClass:
    geeting = 'hello'

インスタンス化してアクセスするには .(ドット・ピリオド) でアクセスします。

word = WordClass()
word.greeting

出力結果は以下になります。

'hello'

関数の定義

クラスに関数を定義することが出来ます。いわゆるメソッドです。作成方法は通常の関数と同様に、def を使用します。

class GreetingClass:
    def sayHello(self):
        print 'hello'  # Python 2
        print('hello') # Python 3 ~

クラス内関数の第一引数には、自分自身を表すオブジェクトが代入されています。 名前はなんでも良いのですが、Python では通例的(?)に self が使われるようです。

※Python 2 では 上の print。Python 3 では下のプリント文を使用します。

メソッドを実行するには、インスタンス名の後に.(ドット・ピリオド)、その後に通常の関数を実行するようにします。

word = GreetingClass()
word.sayHello()

出力結果は以下の用になります。

hello

プライベートな変数・関数の作成

外から完全にアクセスできない、プライベートな変数・関数を作成することが出来ないようです。代わりに、変数・関数の先頭に _(アンダーバー)を付けることで、これはプライベートなものですよ!と認識(コードを読む人が)出来るようにします。

また _(アンダーバー)を2つ付けた場合、簡単なマングリング(難号化)が行われて、_クラス名 が先頭に付加されます。(仕様的には、__で始まり__で終わらないものに対してマングリングが行われます)

class PrivateClass:
    _privateVar = 'private'
    __mangledVar = 'mangled'

上記のクラスの変数にアクセスすると以下の用になります。

pri = PrivateClass()
pri._privateVar
pri._PrivateClass__mangledVar

コンソールでの出力結果は以下になります。

'private'
'mangled'

コンストラクタ

Python のクラスで、インスタンス化したときに初期化を行う、”コンストラクタ” を定義するには __init__ という名前で関数を定義します。

class initClass:
    def __init__(self):
        print('init...')


init = initClass()  # init が出力されます

Python 基本 – リスト(配列)

リストは様々なタイプのデーターをまとめて一つのグループにするために利用されます。
違う種類のデータを同時に格納することが出来ますが、通常は同じタイプを使用します。

基本形

整数

>>> numbers = [100, 200, 300, 400, 500]
>>> numbers
[100, 200, 300, 400, 500]

文字列

>>> string = ['string']

リストの中にリスト

リストは入れ子にすることが出来ます。

>>> images = [['image.jpg', [100, 100]], ['image2.jpg', [150, 100]]]

データの取得

リスト内のデータを取得するにはインデックスを指定します。
戻り値はインデックスにあるデータになります

>>> numbers = [100, 200, 300]
>>> numbers[2]
300

インデックスは 0 から始まります。

>>> numbers = [100, 200, 300]
>>> numbers[0]
100
>>> numbers[1]
200
>>> numbers[2]
300

負数を指定すると後ろからの値を指定出来ます

>>> numbers = [100, 200, 300]
>>> numbers[-1]
300
>>> numbers[-2]
200
>>> numbers[-3]
100

リストの中のリストにアクセスするには [添字] を続けて書きます。

>>> images = [['image.jpg', [100, 100]], ['image2.jpg', [150, 100]]]
>>> images[1][0]
'image2.jpg'

スライス

インデックスを : (コロン)で区切るとリストをスライス(切り取り)をすることが出来ます。
戻り値は指定した範囲のリストになります

>>> numbers = [100, 200, 300]
>>> numbers[0:2]
[100, 200]
>>> numbers[1:3]
[200, 300]

添字は省略することが出来ます。初めを省略すると、初めの値から始まります(0を指定したことと同じですかね)
最後を省略すると一番最後の値を指定していることになります。

>>> numbers = [100, 200, 300]
>>> numbers[:2]
[100, 200]
>>> numbers[1:]
[200, 300]

スライスにリストを代入するとその範囲に新たに値を追加することが出来ます。

>>> numbers = [100, 200, 300]
>>> numbers[1:3] = [150, 200, 250, 300]
>>> numbers
[100, 150, 200, 250, 300]

指定の範囲を削除することも出来ます。

>>> numbers = [150, 200, 250, 300]
>>> numbers[:2] = []
[250, 300]

どちらも省略することも出来ます。これはリストのコピーを作成しているのと同じことになります。

>>> numbers[:]
[100, 200, 300]

全ての削除も可能です

>>> numbers[:] = []
>>> numbers
[]

長さを取得

リストの長さを取得するには組み込み関数の len() を使用します

>>> alphabets = ['a', 'b', 'c', 'd', 'e']
>>> len(alphabets)
5

結合

リストには + 演算子を使用することが出来て、リスト同士を結合させることが出来ます。リスト自体に変更は加えません。

>>> numbers = [100, 200, 300]
>>> numbers + [400, 500, 600]
[100, 200, 300, 400, 500, 600]

繰り返し連結

* 演算子を利用することも出来ます。+ はリスト同士を結合して新たなリストを返しますが、
リスト * i
はリストを i の分繰り返した新たなリストを返します。

>>> numbers = [1, 10, 100]
>>> numbers * 3
[1, 10, 100, 1, 10, 100, 1, 10, 100]

追加(append, extend, insert)

+ 演算子はリストを合わせた新しいリストを作成しますが、リスト自体に追加したい場合もあると思います。リストのリストの最後に新たにリストを値を追加するには append() を使用します。

>>> numbers = [100, 200, 300]
>>> numbers.append(400)
>>> numbers
[100, 200, 300, 400]

以下の表現も同様の意味になります。

numbers[len(numbers):] = [400]

別のリストを追加するには extend() を使用します

>>> numbers = [100, 200, 300]
>>> numbers.extend([400, 500, 600])
[100, 200, 300, 400, 500, 600]

以下の表現も同様の意味になります。

numbers[len(numbers):] = [400, 500, 600]

指定した位置に新しく要素を挿入するには insert(i, x) を使用します。
i にインデックス、x に挿入するデータを指定します。i の値の直前に挿入が行われます。

>>> numbers = [100, 200, 300]
>>> numbers.insert(1, 150)
>>> numbers
[100, 150, 200, 300]

削除(remove, del文)

中身の要素を指定して削除するには remove(値) を使用します。 remove は初めに見つかった要素のみを削除します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.remove(200)
>>> numbers
[100, 300, 100, 200, 300]

remove は削除する値を指定しましたが、削除したいインデックスを指定するには del 文を使用します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> del numbers[1]
>>> numbers
[100, 300, 100, 200, 300]

del 文はスライスでも使用できます。

>>> numbers = [100, 200, 300]
>>> del numbers[:2]
>>> numbers
[300]

中身だけを全て削除することもできます。

>>> numbers = [100, 200, 300]
>>> del numbers[:]
>>> numbers
[]

変数自体を削除することも出来ます。この場合は、変数に何かが代入されるまではアクセスするとエラーがでます。

>>> numbers = [100, 200, 300]
>>> del numbers
>>> numbers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'numbers' is not defined

検索(index)

リストのインデックスを値から取得出来ます。初めに見つかったインデックスのみを返します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.index(200)

取り出し: pop([i])

リストの中から指定した値を取り出します。リストから取り出された値は削除されます。i(index) に何も指定しない場合は、リストの末尾の要素を削除して返します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.pop()
300
>>> numbers.pop(2)
300
>>> numbers
[100, 200, 100, 200]

出現回数(count)

指定したリスト内の要素の出現回数をカウントするには count(x) を使用します。

>>> information = ['i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n']
>>> information.count('i')
2

並び替え(sort)

要素の並び替えを行うには sort() を使用します。数字であれば小さい順、文字列であれば文字コードの並び順でソートが行われます。(In place)

>>> numbers = [1, 33, 35, 6, 763, 10]
>>> numbers.sort()
>>> numbers
[1, 6, 10, 33, 35, 763]

逆順(reverse)

要素の並びを逆順にするには reverse() を使用します。
小技として、sort() で並べ替えると”昇順”になるのですが、sort() の後に reverse() を掛けると”降順”になります。

>>> numbers = [1, 6, 10, 33, 35, 763]
>>> numbers.reverse()
>>> numbers
[763, 35, 33, 10, 6, 1]

リストの内包表記

ループを回した結果をリストにする場合に簡単に表記する方法が内包表記です。
例えば 0 ~ 8 までの偶数のリストを作成したい場合、普通に書くと以下の用になります。

>>> evenNumbers = []
>>> for x in range(0, 10, 2):
...     evenNumbers.append(x)
...
>>> evenNumbers
[0, 2, 4, 6, 8]

これを内包表記に変更すると以下の用になります。

>>> evenNumbers = [x for x in range(0, 10, 2)]
>>> evenNumbers
[0, 2, 4, 6, 8]

初めの x がリストの各要素に代入される結果になり、そこで演算することも可能です。それぞれの半分にした値にする場合、以下の用になります。

>>> numbers = [x*0.5 for x in range(0, 10, 2)]
>>> numbers
[0.0, 1.0, 2.0, 3.0, 4.0]

参考

http://docs.python.jp/3.3/tutorial/introduction.html
http://docs.python.jp/3.3/tutorial/datastructures.html

簡易Webサーバーの作成(CGIHTTPServer)

Python の基礎もあまり出来ていませんが、CGIHTTPServer なるものを利用してとりあえず動くものを作成してみようかと思います。
SimpleHTTPServer というものもありますが、CGIHTTPServer は CGI も動くということなのでこちらをを使用します。

サーバースクリプトの作成

サーバーとしての機能を提供する為のスクリプトを作成します。

import CGIHTTPServer
CGIHTTPServer.test()

これだけです。簡単ですね。上記のコードだけで Web サーバーとしての動作をひと通りしてくれます。
ちなみにスクリプトを作成しなくても以下のコマンドを実行するだけで動作してくれます。

python -m CGIHTTPServer

CGIHTTPServer は、実行した時のカレントディレクトリをドキュメントルートとして、ポートは 8000 を、HOST に 0.0.0.0(localhost, 127.0.0.1 ?) として動作するようです。

この時点で http://localhost:8000/ にアクセスすると実行したディレクトリのリストが表示されます。
CGIHTTPServer_01

index.html の設置

実行したディレクトリに index.html を作成して設置します。


<html>
<head>
    <meta charset="utf-8">
    <title>CGIHTTPServer</title>
</head>
<body>
    <h1>CGIHTTPServer のテスト</h1>
</body>

この状態で再び http://localhost:8000/ にアクセスすると以下の状態になり index.html が綺麗に表示出来ているのが確認出来ると思います。
CGIHTTPServer_02

CGIの作成

静的な html ファイルの表示ができたので CGI のスクリプトを作成してみます。

CGIHTTPServer は /cgi-bin ディレクトリ以下にあるファイルを CGI として実行する設定のようなので初めに cgi-bin ディレクトリを作成します。
そしてその中に simplecgi.py というファイルを作成します。

#!/usr/bin/env python

print 'Content-type: text/html\n'
print 'Simple Python CGI.'

そして http://localhost:8000/cgi-bin/simplecgi.py にアクセスすると Simple Python CGI. が表示されると思います。
CGIHTTPServer_03

これで CGI を作成することが出来ました。後は必要な処理を Python のスクリプトで書いていくことが出来ます。

Python 基本

Python の基本機能です。Python というよりもプログラミング言語に最低限必要な機能一覧です。

コメント文字

# コメントアウトをするには #シャープ を使います。
# これはコメントアウトになります

ブールの表記

True False になります。

変数

PHP の $ 等の必要な文字列はなく、普通に使えます。

# variable という変数に 文字列 'variable' を代入
variable = 'variable'

文字列(ACSII文字)

文字列は ”” (ダブルクォーテーション) または ” (シングルクォーテーション)で囲みます。

'Single Quote'
"Double Quote"

文字列(日本語:マルチバイト)

日本語を扱うにはそのままだと以下の様なエラーが発生します。

UnicodeDecodeError: 'cp932' codec can't decode byte 0x9e in position 209: illegal multibyte sequence

文字コードを指定してあげると問題なく処理出来るようになります。文字コードを指定するにはファイルの先頭に # coding: UTF-8 を追加してあげます。
UTF-8 以外にも Shift_JIS や EUC-JP も指定出来ます。

# coding: UTF-8
'日本語(マルチバイト)を記述してもエラーが発生しなくなります。'

標準出力に出力

標準出力に出力するにはprint()を使用します。

print('hello world')  # hello world と出力されます

リスト(配列)

ディクショナリ(連想配列/hash/map)

ディクショナリの使い方は {‘key’: ‘value’} を利用します。
アクセスするには添字を利用します。a['key']

d = {'key': 'value'}
d['key']  # value が返ります

代入(上書き)

上書きをするには 添字 に代入を行います。

d = {'key': 'value'}
d['key'] = 'VALUE'
d['key']  # VALUE が返ります

追加

追加するには新たなキーになる添字に代入を行います

d = {'key': 'value'}
d['key2'] = 'value2'  # {'key': 'value', 'key2': 'value2} になります

削除

削除するには del dic[添字] を使用します

d = {'key': 'value', 'key2': 'value2'}
del d['key']  # {'key': 'value'} となります

演算子

大体の言語と同じようです

+ - / * %  # 計算
== != < > <= >=  # 比較

などなど…

IF(条件分岐)

if の書き方は以下のようになります。

if 条件:
    # 条件 = True の処理
elif 条件2:
    # 条件2 = True の処理
else:
    # 上記の条件以外の場合の処理

FOR(ループ)

for の書き方は以下の用になります。

for i in range(100):
    # 0 から 99 までループ

リストをループすることが出来ます

fruit = ['apple', 'banana', 'cake']
for f in fruit:
    # 全要素のループ

ディクショナリの場合

dic = {'apple': 'ringo', 'cake': 'ke-ki'}
for key, value in dic.items():
    # key と value 全要素のループ

関数

関数を定義するには以下のようにします

def 関数名(引数):
    # 処理
    return  # 戻り値を指定します

モジュールのインポート(include)

外部のモジュールをインポートするには import 文を使用します

import os
os.getcwd()  # カレントディレクトに取得

クラス

これぐらいで大体のことは出来ますかね…

Python の学習記録 – 目次

Python の学習を初めようと思います。忘れないように記録として残しておくことにしました。
一つの目標として、Python で Web サーバーを作成してメモ帳のようなものを動かしてみようかなと思っています。
SimpleHTTPServer というものがあるのですがそれを利用しない予定です。WSGI アプリケーションを作成してみようかと思います。

  • Python 基本

    Python でのプログラミングに最低限必要だと思われる基本的なこと

  • 簡易Webサーバーの作成(CGIHTTPServer)

    Python に初めから組み込まれているモジュールCGIHTTPServerモジュールを利用して簡易Webサーバーを作成しました。
    (慣れることを目標に…)