忍者ブログ
     2008年11月14日 開始
[1] [2] [3]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

これはウェブ上のファイルを読むプログラムです
 

 Example 11.2. Downloading a feed the quick-and-dirty way

>>> import urllib
>>> data = urllib.urlopen('http://diveintomark.org/xml/atom.xml').read()    (1)
>>> print data
<?xml version="1.0" encoding="iso-8859-1"?>
<feed version="0.3"
 xmlns="http://purl.org/atom/ns#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xml:lang="en">
 <title mode="escaped">dive into mark</title>
 <link rel="alternate" type="text/html" href="http://diveintomark.org/"/>
 <-- rest of feed omitted for brevity -->
 


インターネットからファイルのダウンロード
URLとセーブするPathを指定
    import urllib, os.path
    urllib.urlretrieve(ダウンロードするURL, セーブするPath)
 

sample:

 

import urllib, os.path, cPickle

def main():
    mp3='http://hiw.oo.kawai-juku.ac.jp/nyushi/honshi/08/k20-42a.pdf'
#    f = urllib.urlopen(mp3)
#    mp3length = int(f.info()['Content-Length'])
    g=urllib.urlretrieve(mp3, 'C:\data\k20-42a.pdf')

if __name__ == '__main__':
    main()
 

http://www.python.jp/Zope/articles/tips/regex_howto/regex_howto_4

4.3. 取り出さないグループと名前付きグループ

凝った正規表現を書こうとすると、文字列を取り出すためのグループと、正規表現自体を構造化するためのグループを使う場合があります。しかし、複雑な正規表現では、グループ番号を追いかけ続けるのが困難になります。この問題を解決するのに 2 つの方法があります。両方とも正規表現で拡張された、一般的な文法を使うので、まずそれを見ていきましょう。

Perl 5 では、標準の正規表現の他にいくつかの機能が加えられ、Python の re モジュールはそのほとんどをサポートしています。 Perl の正規表現と標準の正規表現が、混乱するような方法で違ったものにならないように、1 文字で入力できる新しいメタ文字や、新しい機能を表すために "\" で始まる特殊なシーケンスを選ぶことは難しかったものです。たとえば、"&" を新しいメタ文字にするとしましょう。ところが古い表記では "&" が通常の文字なので、\&[&] のようにエスケープされていないわけです。選ばれた解決策は、(?...) を拡張文法として使うことでした。括弧直後の "?" は繰り返す対象がないので、シンタックスエラーです。ですから、これは互換性の問題を発生しません。 "?" 直後の文字で、どの拡張が使うかを示すので、(?=foo)(?:foo) は別のものです(それぞれ a positive lookahead assertion と non-capturing group containing the subexpression foo)。

Python では、 Perl の拡張文法に、さらに拡張文法を追加されています。 Python で拡張されたものは、疑問符直後の最初の文字が "P" になっています。現在のところ、そのような拡張は 2 つあります。 (?P<name>...) は名前つきグループを定義し、(?P=name) は名前つきグループを後方参照します。将来 Perl 5 が似たような機能を別の文法で追加すれば、Python 独自の文法は互換性のために残しつつ、re は、Perl の文法をサポートする変更されるでしょう。

ここまで見てきた一般的な拡張文法を踏まえて、複雑な正規表現中のグループを扱うことを単純にする機能に話を戻しましょう。グループは左から右へと番号づけされ、複雑な正規表現では多くのグループを使います。したがって、正しい番号を追いかけるのが難しくなり、そのような複雑な正規表現を修正するのはやっかいです。先頭付近に新しいグループを挿入すれば、それ以降の全ての番号を変更することになるからです。

グループの内容を取得しないけれども、正規表現の一部を集めるために、グループを使いたい場合があります。これを明示するには、非取得グループを示す (?:...) を使います。括弧内にどんな正規表現でも配置できます。

>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
>>> m = re.match("(?:[abc])+", "abc")
>>> m.groups()
()

マッチしたグループの内容を取得できないという事実を除けば、非取得グループは内容を取得できるグループとまったく同じように振舞います。この中に何か別の表現を入れたり、"*" 等の繰り返しメタ文字で繰り返したり、他のグループ (取得でも非取得でも) の入れ子にしたりすることもできます。また、他のグループの番号づけを変更することなく、新しいグループを追加できるので、既に存在するグループを修正するときに (?:...) は特に役に立ちます。グループの内容を取得してもしなくても、探索の性能に違いはありません。どちらも同じ速さで動作します。

より重要な機能は名前付きグループです。グループを番号で参照するのではなく、名前で参照できるのです。

名前付きグループの文法は Python の独自拡張のひとつで、(?P<name>...) と表記します。 name は、もちろん、グループの名前です。グループを名前で関連づけることを除けば、名前付きグループは取得グループと同じように振る舞います。取得グループを扱う、全ての MatchObject のメソッドは、グループに付けられた番号を参照するために整数か、グループ名を受け付けます。名前付きグループは番号付けもされているので、2 通りの方法で、グループの情報を取得することができるのです。

>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'
>>> m.group(1)
'Lots'

名前付きグループを使えば、番号を覚える代わりに、覚えやすい名前で参照できるので便利です。 imaplib モジュールから、正規表現の例を示します。

InternalDate = re.compile(r'INTERNALDATE "'
        r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
        r'(?P<year>[0-9][0-9][0-9][0-9])'
        r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
        r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
        r'"')

m.group('zonem') を取得するほうが、グループ番号 9 を覚えるより、とても簡単です。

(...)\1 のような表記では、後方参照のための文法がグループ番号を参照するので、名前を使う方法ではと自然と不一致が生じます。そこで、Python 独自拡張には (?P=name) があります。これは、name と名付けられたグループの内容が、現在位置に存在することを示します。繰り返される単語を見付ける正規表現、(\b\w+)\s+\1 は、(?P<word>\b\w+)\s+(?P=word) と書くこともできるのです。

>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
>>> p.search('Paris in the the spring').group()
'the the'

みんなのPython(Webアプリ編を読んでいる途中・・・)

Webサーバーを作ったよ

cgiserver.py

import CGIHTTPServer
CGIHTTPServer.test()

#!/usr/bin/env python
# coding: utf-8
import cgi
from datetime import datetime

html_body = u"""
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"
</head>
<body>
%s
</body>
</html>"""

content=''

form=cgi.FieldStorage()
year_str=form.getvalue('year', '')
if not year_str.isdigit():
    content=u"西暦を入力してください"
else:
    year=int(year_str)
    friday13=0
#なんで1~13なの?
 for month in range(1,13):
        date=datetime(year, month, 13)
#月曜日が0になるんだね
        if date.weekday()==4:
            friday13+=1
            content+=u"%d年%d月13日は金曜日です" % (year, date.month)
            content+=u"<br />"

#if fri13:---なにが「真」でなにが「偽」なのかな
    if friday13:
        content+=u"%d年には合計%d日の金曜日があります" % (year, friday13)
    else:
        content+=u"%d年には13日の金曜日がありません"
           
#なんでprint文がHTMLに表示されるの???     
print "Content-type: text/html;charset=utf-8\n"
print (html_body % content).encode('utf-8')
 

真値テストを行うことができます。 以下の値は偽であると見なされます:

①None ②False

③数値型におけるゼロ。例えば 0 、 0L 、 0.0 、 0j

④空のシーケンス型。例えば '' 、 () 、 [] 。

⑤空のマッピング型。例えば {} 。

⑥__nonzero__() または __len__() メソッドが 定義されているようなユーザ定義クラスのインスタンスで、それらのメソッド が整数値ゼロまたは bool 値の False を返すとき。 6


それ以外の値は全て真であると見なされます -- 従って、ほとんどの型 のオブジェクトは常に真です。

3 range() 関数

この関数は算術型の数列が入ったリストを生成します。

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

指定した終端値は生成されるリストには入りません。

range(10) は 10 個の値からなるリストを生成し、 長さ 10 のシーケンスにおける各項目のインデクスとなります。 range を別の数から開始したり、他の増加量 (負の増加量でさえも; 増加量は時に `ステップ(step)' と呼ばれることもあります) を指定する こともできます:

>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]

 

#!/usr/local/bin/python
# coding: utf-8
## verticalize.py

import cgi
form=cgi.FieldStorage()

html_body = u"""
<html>
  <head>
    <meta http-equiv="content-type"
          content="text/html;charset=utf-8" />
  </head>
  <body>
  %s
  </body>
</html>"""

body_line=[]
body=form.getvalue('body', '')
## unicode()の3つ目の引数'ignore'の意味は?
body=unicode(body, 'utf-8', 'ignore')
for cnt in range(0, len(body), 10):
    line=body[:10]
    line+=''.join(['□' for i in range(len(line), 10)])
    body_line.append(line)
    body=body[10:]
## zip(*body_line) 多次元配列のシーケンスの組み換え(行・列をいれかえる)
## アスタリスク(*)の意味がわかんない
body_line_v=[' '.join(reversed(x)) for x in zip(*body_line)]

print "Content-type: text/html\n"
## 次の行の% の扱いがわかんない
## '<br />'.join(body_line_v) ・・・この意味は確か
## '<br />'の後ろにbody_line_vをjoinするはずだね
print html_body % '<br />'.join(body_line_v)

 

utf-8文字列をunicodeに変換
   (unicode関数を使う )

# -*- coding: utf-8 -*-

name=unicode('utf-8 文字列')
------------------------------------

unicode( [object[, encoding [, errors]]])
以下のモードのうち一つを使って、object のUnicode 文字列バージョンを返します:

もし encoding かつ/または errors が与えられていれば、 unicode() は 8 ビットの文字列または文字列バッファになっているオブジェクトを encoding の codec を使ってデコードします。 encoding パラメタはエンコーディング名を与える文字列です; 未知のエンコーディングの場合、LookupError が送出されます。
 エラー処理は errors に従って行われます; このパラメタは入力エンコーディング中で無効な文字の扱い方を指定します。errors'strict' (標準の設定です) の場合、エラー発生時には ValueError が送出されます。一方、'ignore' では、エラーは暗黙のうちに無視されるようになり、'replace' では公式の置換文字、U+FFFD を使って、デコードできなかった文字を置き換えます。

codecs モジュールについても参照してください。

オプションのパラメタが与えられていない場合、 unicode()str() の動作をまねます。ただし、8 ビット文字列ではなく、 Unicode 文字列を返します。もっと詳しくいえば、 object が Unicode 文字列かそのサブクラスなら、デコード処理を一切介することなく Unicode 文字列を返すということです。

5.2.4 リスト表現

リスト表現は、角括弧で囲われた式の系列です。系列は空の系列であってもかまいません:

 

test ::= or_test | lambda_form
testlist ::= test ( "," test )* [ "," ]
list_display ::= "[" [listmaker] "]"
listmaker ::= expression ( list_for | ( "," expression )* [","] )
list_iter ::= list_for | list_if
list_for ::= "for" expression_list "in" testlist [list_iter]
list_if ::= "if" test [list_iter]
Download entire grammar as text.

リスト表現は、新に作成されたリストオブジェクトを表します。新たなリストの内容は、式のリストを与えるか、リストの内包表記 (list comprehension) で指定します。 カンマで区切られた式のリストを与えた場合、リストの各要素は左から右へと順に評価され、評価された順番にリスト内に配置されます。リストの内包表記を与える場合、内包表記はまず単一の式、続いて少なくとも一つの for 節、続いてゼロ個以上の for 節か、if 節になります。この場合、新たに作成されるリストの各要素は、各々の forif 節を左から右の順にネストしたブロックとみなして実行し、ネストの最内ブロックに到達する度に式を評価した値となります。 5.1

5.3 タプルとシーケンス

リストや文字列には、インデクスやスライスを使った演算のように、数多くの共通の性質があることを見てきました。これらは シーケンス (sequence) データ型 の二つの例です。Python はまだ進歩の過程にある言語なので、他のシーケンスデータ型が追加されるかもしれません。標準のシーケンス型はもう一つあります: タプル (tuple) 型です。

タプルはコンマで区切られたいくつかの値からなります。例えば以下のように書きます:

 

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # タプルを入れ子にしてもよい
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

ご覧のように、タプルは常に丸括弧で囲われています。これは、入れ子になったタプルが正しく解釈されるようにするためです; 入力の際には丸括弧なしでもかまいませんが、結局 (タプルがより大きな式の一部分の場合) たいてい必要となります。

タプルの用途はたくさんあります。例えば、(x, y) 座標対、データベースから取り出した従業員レコードなどです。タプルは文字列と同じく、変更不能です: タプルの個々の要素に代入を行うことはできません (スライスと連結を使って同じ効果を実現することはできますが)。リストのような変更可能なオブジェクトの入ったタプルを作成することもできます。

問題は 0 個または 1 個の項目からなるタプルの構築です: これらの操作を行うため、構文には特別な細工がされています。空のタプルは空の丸括弧ペアで構築できます; 一つの要素を持つタプルは、値の後ろにコンマを続ける (単一の値を丸括弧で囲むだけでは不十分です) ことで構築できます。美しくはないけれども、効果的です。例えば以下のようにします:

 

>>> empty = ()
>>> singleton = 'hello',    # <-- 末尾のコンマに注目
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)

t = 12345, 54321, 'hello!'タプルのパック (tuple packing) の例です: 値 1234554321 、および 'hello!' が一つのタプルにパックされます。逆の演算も可能です:

 

>>> x, y, z = t

この操作は、シーケンスのアンパック (sequence unpacking) とでも呼ぶべきものです。シーケンスのアンパックでは、左辺に列挙されている変数が、右辺のシーケンスの長さと同じであることが要求されます。複数同時の代入が実はタプルのパックとシーケンスのアンパックを組み合わせたものに過ぎないことに注意してください!

この操作にはわずかな非対称性があります: 複数の値をパックすると常にタプルが生成されますが、アンパックはどのシーケンスにも働きます。

 


 

zip( [iterable, ...])
この関数はタプルのリストを返します。このリストの i 番目のタプルは各引数のシーケンスまたはイテレート可能オブジェクト中の i 番目の要素を含みます。返されるリストは引数のシーケンスのうち長さが最小のものの長さに切り詰められます。引数が全て同じ長さの際には、 zip() は初期値引数が Nonemap() と似ています。引数が単一のシーケンスの場合、1 要素のタプルからなるリストを返します。引数を指定しない場合、空のリストを返します。 バージョン 2.0 で 新たに追加 された仕様です。

バージョン 2.4 で 変更 された仕様: これまでは、zip() は少なくとも一つの引数を要求しており、空のリストを返す代わりに TypeError を送出していました

 


 

#!/usr/local/bin/python
# coding: utf-8

## httphandler.py

# 標準モジュールをimportする
import cgi
import os

class Request(object):
    """
    HTTPのリクエストをハンドリングするクラス
    CGI側でインスタンスを生成することによって利用する
    クエリデータや環境変数へのアクセス,主要ヘッダへのアクセス用メソッドを提供
    """

    def __init__(self, environ=os.environ):
        """
        インスタンスの初期化メソッド
        クエリ,環境変数をアトリビュートとして保持する
        """
        self.form=cgi.FieldStorage()
        self.environ=environ

import time

_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
_monthname = [None,
              "Jan", "Feb", "Mar", "Apr", "May", "Jun",
              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

class Response(object):
    """
    HTTPのレスポンスをハンドリングするクラス
    レスポンスを送る前にインスタンスを生成して利用する
    レスポンスやヘッダの内容の保持,ヘッダを含めたレスポンスの送信を行う
    """

    def __init__(self, charset='utf-8'):
        """
        インスタンスの初期化メソッド
        ヘッダ用の辞書,本文用の文字列などを初期化する
        """
        self.headers={'Content-type':'text/html;charset=%s' % charset}
        self.body=""

    def set_header(self, name, value):
        """
        レスポンスのヘッダを設定する
        """
        self.headers[name]=value

    def get_header(self, name):
        """
        設定済みのレスポンス用ヘッダを返す
        """
        return self.headers.get(name, None)

    def set_body(self, bodystr):
        """
        レスポンスとして出力する本文の文字列を返す
        """
        self.body=bodystr

    def make_output(self, timestamp=None):
        """
        ヘッダと本文を含めたレスポンス文字列を作る
        """
        if timestamp is None:
            timestamp = time.time()
        year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
        dtstr="%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
            _weekdayname[wd], day, _monthname[month], year, hh, mm, ss)
        self.set_header("Last-Modified", dtstr)
        headers='\n'.join(["%s: %s" % (k, v)
                        for k,v in self.headers.items()])
        return headers+'\n\n'+self.body
    ## __str__(self)は特殊メソッド
    def __str__(self):
        """
        リクエストを文字列に変換する
        """
        return self.make_output().encode('utf-8')

def get_htmltemplate():
    """
    レスポンスとして返すHTMLのうち,定型部分を返す
    """
    html_body = u"""
    <html>
      <head>
        <meta http-equiv="content-type"
              content="text/html;charset=utf-8" />
      </head>
      <body>
      %s
      </body>
    </html>"""
    return html_body


 __init__ はインスタンスを作った直後に呼ばれる特殊メソッドです(省略可能だが、実質的なコンストラクター)。

特殊メソッド

Pythonのクラスには tex2html_wrap_inline573 のように予め決められた特殊メソッドがあります。その一部を表 1にしました。 tex2html_wrap_inline583 はインタラクティブモードでオブジェクトをダイレクトに入力された時に呼び出されます。 tex2html_wrap_inline585 はオブジェクトが文字列化された時に呼び出されます。これらを使えば、オブジェクトの表示をカスタマイズして分かりやすくする事が出来ます。

tex2html_wrap_inline587 は他のオブジェクトとの比較を行ったときに呼び出されるメソッドで自分自身の参照の他に比較の相手のオブジェクトの参照が引数として渡されます。

tex2html_wrap_inline589tex2html_wrap_inline591 はメンバーの参照やセットが行われた時に呼び出されます。PythonにはC++のようにメンバーのアクセス制限が出来ないのですが、このメソッドを使えばそれに近いことが出来るかも知れません。

 

   table140
Table 1: 特殊メソッド(一部)
 



忍者ブログ [PR]
お天気情報
カレンダー
03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
リンク
フリーエリア
最新CM
最新TB
プロフィール
HN:
No Name Ninja
性別:
非公開
バーコード
ブログ内検索
P R
カウンター
ブログの評価 ブログレーダー