ナビゲーション

索引

モジュール |

次へ |

Python 2.7ja1 documentation »

Python Documentation contents

What’s New in Python (英語)

What’s New in Python 2.7

Python 2.x の今後

Python 3.1 の機能

PEP 372: collections に順序付き辞書を追加

PEP 378: 1000区切りのための書式指定子

PEP 389: コマンドライン解析のための argparse モジュール

PEP 391: logging の辞書ベースの設定

PEP 3106: 辞書 View

PEP 3137: memoryview オブジェクト

その他の言語の変更

インタプリタの変更

最適化

新しいモジュールと改良されたモジュール

新しいモジュール: importlib

新しいモジュール: sysconfig

ttk: Tk のテーマ付きウィジェット

更新されたモジュール: unittest

更新されたモジュール: ElementTree 1.3

ビルドと C API の変更

カプセル

ポート特有の変更: Windows

ポート特有の変更: Mac OS X

ポート特有の変更: FreeBSD

その他の変更と修正

Python 2.7 への移植

謝辞

What’s New in Python 2.6

Python 3.0

Changes to the Development Process

New Issue Tracker: Roundup

New Documentation Format: reStructuredText Using Sphinx

PEP 343: The ‘with’ statement

Writing Context Managers

The contextlib module

PEP 366: Explicit Relative Imports From a Main Module

PEP 370: Per-user site-packages Directory

PEP 371: The multiprocessing Package

PEP 3101: Advanced String Formatting

PEP 3105: print As a Function

PEP 3110: Exception-Handling Changes

PEP 3112: Byte Literals

PEP 3116: New I/O Library

PEP 3118: Revised Buffer Protocol

PEP 3119: Abstract Base Classes

PEP 3127: Integer Literal Support and Syntax

PEP 3129: Class Decorators

PEP 3141: A Type Hierarchy for Numbers

The fractions Module

Other Language Changes

Optimizations

Interpreter Changes

New and Improved Modules

The ast module

The future_builtins module

The json module: JavaScript Object Notation

The plistlib module: A Property-List Parser

ctypes Enhancements

Improved SSL Support

Deprecations and Removals

Build and C API Changes

Port-Specific Changes: Windows

Port-Specific Changes: Mac OS X

Port-Specific Changes: IRIX

Porting to Python 2.6

Acknowledgements

What’s New in Python 2.5

PEP 308: Conditional Expressions

PEP 309: Partial Function Application

PEP 314: Metadata for Python Software Packages v1.1

PEP 328: Absolute and Relative Imports

PEP 338: Executing Modules as Scripts

PEP 341: Unified try/except/finally

PEP 342: New Generator Features

PEP 343: The ‘with’ statement

Writing Context Managers

The contextlib module

PEP 352: Exceptions as New-Style Classes

PEP 353: Using ssize_t as the index type

PEP 357: The ‘__index__’ method

Other Language Changes

Interactive Interpreter Changes

Optimizations

New, Improved, and Removed Modules

The ctypes package

The ElementTree package

The hashlib package

The sqlite3 package

The wsgiref package

Build and C API Changes

Port-Specific Changes

Porting to Python 2.5

Acknowledgements

What’s New in Python 2.4

PEP 218: Built-In Set Objects

PEP 237: Unifying Long Integers and Integers

PEP 289: Generator Expressions

PEP 292: Simpler String Substitutions

PEP 318: Decorators for Functions and Methods

PEP 322: Reverse Iteration

PEP 324: New subprocess Module

PEP 327: Decimal Data Type

Why is Decimal needed?

The Decimal type

The Context type

PEP 328: Multi-line Imports

PEP 331: Locale-Independent Float/String Conversions

Other Language Changes

Optimizations

New, Improved, and Deprecated Modules

cookielib

doctest

Build and C API Changes

Port-Specific Changes

Porting to Python 2.4

Acknowledgements

Python チュートリアル

1. やる気を高めよう

2. Python インタプリタを使う

2.1. インタプリタを起動する

2.1.1. 引数の受け渡し

2.1.2. 対話モード

2.2. インタプリタとその環境

2.2.1. エラー処理

2.2.2. 実行可能な Python スクリプト

2.2.3. ソースコードの文字コード

2.2.4. 対話モード用の起動時実行ファイル

3. 形式ばらない Python の紹介

3.1. Python を電卓として使う

3.1.1. 数

3.1.2. 文字列

3.1.3. Unicode 文字列

3.1.4. リスト

3.2. プログラミングへの第一歩

4. その他の制御フローツール

4.1. if 文

4.2. for 文

4.3. range() 関数

4.4. break 文と continue 文とループの else 節

4.5. pass 文

4.6. 関数を定義する

4.7. 関数定義についてもう少し

4.7.1. デフォルトの引数値

4.7.2. キーワード引数

4.7.3. 任意引数リスト

4.7.4. 引数リストのアンパック

4.7.5. ラムダ式

4.7.6. ドキュメンテーション文字列

4.8. 間奏曲: コーディングスタイル

5. データ構造

5.1. リスト型についてもう少し

5.1.1. リストをスタックとして使う

5.1.2. リストをキューとして使う

5.1.3. 関数型のプログラミングツール

5.1.4. リストの内包表記

5.1.5. ネストしたリストの内包表記

5.2. del 文

5.3. タプルとシーケンス

5.4. 集合型

5.5. 辞書

5.6. ループのテクニック

5.7. 条件についてもう少し

5.8. シーケンスとその他の型の比較

6. モジュール

6.1. モジュールについてもうすこし

6.2. モジュールをスクリプトとして実行する

6.2.1. モジュール検索パス

6.2.2. “コンパイル” された Python ファイル

6.3. 標準モジュール

6.4. dir() 関数

6.5. パッケージ

6.5.1. パッケージから * を import する

6.5.2. パッケージ内での参照

6.5.3. 複数ディレクトリ中のパッケージ

7. 入力と出力

7.1. ファンシーな出力の書式化

7.1.1. 古い文字列フォーマット方法

7.2. ファイルを読み書きする

7.2.1. ファイルオブジェクトのメソッド

7.2.2. pickle モジュール

8. エラーと例外

8.1. 構文エラー

8.2. 例外

8.3. 例外を処理する

8.4. 例外を送出する

8.5. ユーザ定義の例外

8.6. クリーンアップ動作を定義する

8.7. 定義済みクリーンアップ処理

9. クラス

9.1. 名前とオブジェクトについて

9.2. Python のスコープと名前空間

9.3. クラス初見

9.3.1. クラス定義の構文

9.3.2. クラスオブジェクト

9.3.3. インスタンスオブジェクト

9.3.4. メソッドオブジェクト

9.4. いろいろな注意点

9.5. 継承

9.5.1. 多重継承

9.6. プライベート変数

9.7. 残りのはしばし

9.7.1. 例外はクラスであってもよい

9.8. イテレータ (iterator)

9.9. ジェネレータ (generator)

9.10. ジェネレータ式

10. 標準ライブラリミニツアー

10.1. OSへのインタフェース

10.2. ファイルのワイルドカード表記

10.3. コマンドライン引数

10.4. エラー出力のリダイレクトとプログラムの終了

10.5. 文字列のパターンマッチング

10.6. 数学

10.7. インターネットへのアクセス

10.8. 日付と時刻

10.9. データ圧縮

10.10. パフォーマンスの計測

10.11. 品質管理

10.12. バッテリー同梱

11. 標準ライブラリミニツアー – その 2

11.1. 出力のフォーマット

11.2. 文字列テンプレート

11.3. バイナリデータレコードの操作

11.4. マルチスレッド処理

11.5. ログ記録

11.6. 弱参照

11.7. リスト操作のためのツール

11.8. 10 進浮動小数演算

12. さあ何を？

13. 対話入力編集とヒストリ置換

13.1. 行編集

13.2. ヒストリ置換

13.3. キー割り当て

13.4. インタラクティブインタプタの代替

14. 浮動小数点演算、その問題と制限

14.1. 表現エラー

15. 日本語訳について

15.1. 翻訳者一覧 (敬称略)

Python のセットアップと利用

コマンドラインと環境

コマンドライン

インターフェイスオプション

一般オプション

その他のオプション

使うべきでないオプション

環境変数

デバッグモード変数

Unix プラットフォームで Python を使う

最新バージョンの Python の取得とインストール

Linux

FreeBSD と OpenBSD

OpenSolaris

Python のビルド

Python に関係するパスとファイル

その他

エディタ

Windows で Python を使う

Python のインストール

別のバンドル

Python を構成する

補足: 環境変数の設定

Python 実行ファイルを見つける

モジュールの検索

スクリプトを実行する

PyWin32

Py2exe

WConio

Windows 上で Python をコンパイルする

その他のリソース

Macintosh で Python を使う

MacPython の入手とインストール

Python スクリプトの実行方法

GUI でスクリプトを実行

Configuration

IDE

追加の Python パッケージのインストール

Mac での GUI プログラミング

Mac 上の Python アプリケーションの配布

アプリケーションスクリプティング

他のリソース

このドキュメントについて

翻訳者一覧 (敬称略)

Python 言語リファレンス

導入

別のPythonの実装

本マニュアルにおける表記法

字句解析

行構造

論理行 (logical line)

物理行 (physical line)

コメント

エンコード宣言 (encoding declaration)

明示的な行継続

非明示的な行継続

空行

インデント

トークン間の空白

その他のトークン

識別子 (identifier) およびキーワード (keyword)

キーワード (keyword)

予約済みの識別子種 (reserved classes of identifiers)

リテラル (literal)

文字列リテラル

文字列リテラルの結合 (concatenation)

数値リテラル

整数および長整数リテラル

浮動小数点数リテラル

虚数 (imaginary) リテラル

演算子 (operator)

デリミタ (delimiter)

データモデル

オブジェクト、値、および型

標準型の階層

新スタイルと旧スタイル

特殊メソッド名

基本的なカスタマイズ

属性値アクセスをカスタマイズする

新しい形式のクラスのための別の属性アクセス

デスクリプタ (descriptor) の実装

デスクリプタを呼び出す

__slots__

クラス生成をカスタマイズする

インスタンスのカスタマイズとサブクラスチェック

呼び出し可能オブジェクトをエミュレートする

コンテナをエミュレートする

シーケンス型エミュレーションで使われるその他のメソッド

数値型をエミュレーションする

型強制規則 (coercion rule)

with文とコンテキストマネージャ

旧スタイルクラスの特殊メソッド検索

新スタイルクラスの特殊メソッド検索

実行モデル

名前づけと束縛 (naming and binding)

動的な機能とのやりとり

例外

式 (expression)

算術変換 (arithmetic conversion)

アトム、原子的要素 (atom)

識別子 (identifier、または名前 (name))

リテラル

丸括弧形式 (parenthesized form)

リスト表現

集合と辞書の表現

ジェネレータ式

辞書表現

集合表現

文字列変換

Yield 式

一次語 (primary)

属性参照

添字表記 (subscription)

スライス表記 (slicing)

呼び出し (call)

べき乗演算 (power operator)

単項算術演算とビット単位演算(unary arithmetic and bitwise operation)

二項算術演算 (binary arithmetic operation)

シフト演算 (shifting operation)

ビット単位演算の二項演算 (binary bitwise operation)

比較 (comparison)

ブール演算 (boolean operation)

条件演算 (Conditional Expressions)

ラムダ (lambda)

式のリスト

評価順序

まとめ

単純文 (simple statement)

式文 (expression statement)

代入文 (assignment statement)

累算代入文 (augmented assignment statement)

assert 文

pass 文

del 文

print 文

return 文

yield 文

raise 文

break 文

continue 文

import 文

future 文 (future statement)

global 文

exec 文

複合文 (compound statement)

if 文

while 文

for 文

try 文

with 文

関数定義

クラス定義

トップレベル要素

完全な Python プログラム

ファイル入力

対話的入力

式入力

完全な文法仕様

このドキュメントについて

翻訳者一覧 (敬称略)

Python 標準ライブラリ

1. はじめに

2. 組み込み関数

3. 非必須組み込み関数 (Non-essential Built-in Functions)

4. 組み込み定数

4.1. site モジュールで追加される定数

5. 組み込み型

5.1. 真理値テスト

5.2. ブール演算 — and, or, not

5.3. 比較

5.4. 数値型 int, float, long, complex

5.4.1. 整数型におけるビット列演算

5.4.2. 整数型に対する追加のメソッド

5.4.3. 浮動小数点数に対する追加のメソッド

5.5. イテレータ型

5.5.1. ジェネレータ型

5.6. シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange

5.6.1. 文字列メソッド

5.6.2. 文字列フォーマット操作

5.6.3. XRange 型

5.6.4. 変更可能なシーケンス型

5.7. set（集合）型 — set, frozenset

5.8. マップ型

5.8.1. 辞書ビューオブジェクト

5.9. ファイルオブジェクト

5.10. メモリビュー型

5.11. コンテキストマネージャ型

5.12. 他の組み込み型

5.12.1. モジュール

5.12.2. クラスおよびクラスインスタンス

5.12.3. 関数

5.12.4. メソッド

5.12.5. コードオブジェクト

5.12.6. 型オブジェクト

5.12.7. ヌルオブジェクト

5.12.8. 省略表記オブジェクト

5.12.9. ブール値

5.12.10. 内部オブジェクト

5.13. 特殊な属性

6. 組み込み例外

6.1. 例外のクラス階層

7. 文字列処理

7.1. string — 一般的な文字列操作

7.1.1. 文字列定数

7.1.2. 文字列の書式指定

7.1.3. 書式指定文字列の文法

7.1.3.1. 書式指定ミニ言語仕様 (Format Specification Mini-Language)

7.1.3.2. 書式指定例

7.1.4. テンプレート文字列

7.1.5. 文字列操作関数

7.1.6. 撤廃された文字列関数

7.2. re — 正規表現操作

7.2.1. 正規表現のシンタクス

7.2.2. マッチング vs 検索

7.2.3. モジュールコンテンツ

7.2.4. 正規表現オブジェクト

7.2.5. MatchObject オブジェクト

7.2.6. 例

7.2.6.1. ペアの確認

7.2.6.2. scanf() をシミュレートする

7.2.6.3. 再帰を避ける

7.2.6.4. search() vs. match()

7.2.6.5. 電話帳の作成

7.2.6.6. テキストの秘匿

7.2.6.7. 全ての形容動詞を見つける

7.2.6.8. 全ての形容動詞と、その位置を見つける

7.2.6.9. Raw String記法

7.3. struct — 文字列データをパックされたバイナリデータとして解釈する

7.3.1. 関数と例外

7.3.2. フォーマット文字列

7.3.2.1. バイトオーダ, サイズ, アラインメント

7.3.2.2. フォーマット文字

7.3.2.3. 例

7.3.3. クラス

7.4. difflib — 差分の計算を助ける

7.4.1. SequenceMatcherオブジェクト

7.4.2. SequenceMatcher の例

7.4.3. Differ オブジェクト

7.4.4. Differ の例

7.4.5. difflib のコマンドラインインタフェース

7.5. StringIO — ファイルのように文字列を読み書きする

7.6. cStringIO — 高速化された StringIO

7.7. textwrap — テキストの折り返しと詰め込み

7.8. codecs — codec レジストリと基底クラス

7.8.1. Codec 基底クラス

7.8.1.1. Codec オブジェクト

7.8.1.2. IncrementalEncoder オブジェクト

7.8.1.3. IncrementalDecoder オブジェクト

7.8.1.4. StreamWriter オブジェクト

7.8.1.5. StreamReader オブジェクト

7.8.1.6. StreamReaderWriter オブジェクト

7.8.1.7. StreamRecoder オブジェクト

7.8.2. エンコーディングと Unicode

7.8.3. 標準エンコーディング

7.8.4. encodings.idna — アプリケーションにおける国際化ドメイン名 (IDNA)

7.8.5. encodings.utf_8_sig — BOM 印付き UTF-8

7.9. unicodedata — Unicode データベース

7.10. stringprep — インターネットのための文字列調製

7.11. fpformat — 浮動小数点数の変換

8. データ型

8.1. datetime — 基本的な日付型および時間型

8.1.1. 利用可能なデータ型

8.1.2. timedelta オブジェクト

8.1.3. date オブジェクト

8.1.4. datetime オブジェクト

8.1.5. time オブジェクト

8.1.6. tzinfo オブジェクト

8.1.7. strftime() と strptime() の振る舞い

8.2. calendar — 一般的なカレンダーに関する関数群

8.3. collections — 高性能なコンテナ・データ型

8.3.1. Counter オブジェクト

8.3.2. deque オブジェクト

8.3.3. deque のレシピ

8.3.4. defaultdict オブジェクト

8.3.4.1. defaultdict の使用例

8.3.5. namedtuple() 名前付きフィールドを持つタプルのファクトリ関数

8.3.6. OrderedDict オブジェクト

8.3.6.1. OrderedDict の例とレシピ

8.3.7. ABCs - abstract base classes

8.4. heapq — ヒープキューアルゴリズム

8.4.1. 基本的な例

8.4.2. 優先度キュー実装の注釈

8.4.3. 理論

8.5. bisect — 配列二分法アルゴリズム

8.5.1. ソート済みリストの探索

8.5.2. その他の使用例

8.6. array — 効率のよい数値アレイ

8.7. sets — ユニークな要素の順序なしコレクション

8.7.1. Set オブジェクト

8.7.2. 使用例

8.7.3. 不変に自動変換するためのプロトコル

8.7.4. 組み込み set 型との比較

8.8. sched — イベントスケジューラ

8.8.1. スケジューラオブジェクト

8.9. mutex — 排他制御

8.9.1. mutex オブジェクト

8.10. queue — 同期キュークラス

8.10.1. キューオブジェクト

8.11. weakref — 弱参照

8.11.1. 弱参照オブジェクト

8.11.2. 例

8.12. UserDict — 辞書オブジェクトのためのクラスラッパー

8.13. UserList — リストオブジェクトのためのクラスラッパー

8.14. UserString — 文字列オブジェクトのためのクラスラッパー

8.15. types — 組み込み型の名前

8.16. new — ランタイム内部オブジェクトの作成

8.17. copy — 浅いコピーおよび深いコピー操作

8.18. pprint — データ出力の整然化

8.18.1. PrettyPrinter オブジェクト

8.18.2. pprint の例

8.19. repr — もう一つの repr() の実装

8.19.1. Reprオブジェクト

8.19.2. Reprオブジェクトをサブクラス化する

9. 数値と数学モジュール

9.1. numbers — 数の抽象基底クラス

9.1.1. 数値塔

9.1.2. 型実装者のための注意事項

9.1.2.1. さらに数のABCを追加する

9.1.2.2. 算術演算の実装

9.2. math — 数学関数

9.2.1. 数論および数表現にまつわる関数です

9.2.2. 指数および対数関数

9.2.3. 三角関数

9.2.4. 角度に関する関数

9.2.5. 双曲線関数

9.2.6. 特殊な関数

9.2.7. 定数

9.3. cmath — 複素数のための数学関数

9.3.1. 極座標変換

9.3.2. 指数関数と対数関数

9.3.3. 三角関数

9.3.4. 双曲線関数

9.3.5. 類別関数

9.3.6. 定数

9.4. decimal — 10進固定及び浮動小数点数の算術演算

9.4.1. Quick-start Tutorial

9.4.2. Decimal オブジェクト

9.4.2.1. 論理引数

9.4.3. Context オブジェクト

9.4.4. シグナル

9.4.5. 浮動小数点数に関する注意

9.4.5.1. 精度を上げて丸め誤差を抑制する

9.4.5.2. 特殊値

9.4.6. スレッドを使った処理

9.4.7. レシピ

9.4.8. Decimal FAQ

9.5. fractions — 有理数

9.6. random — 擬似乱数を生成する

9.7. itertools — 効率的なループ実行のためのイテレータ生成関数

9.7.1. Itertool関数

9.7.2. レシピ

9.8. functools — 高階関数と呼び出し可能オブジェクトの操作

9.8.1. partial オブジェクト

9.9. operator — 関数形式の標準演算子

9.9.1. 演算子から関数への対応表

10. ファイルとディレクトリへのアクセス

10.1. os.path — 共通のパス名操作

10.2. fileinput — 複数の入力ストリームをまたいだ行の繰り返し処理をサポートする。

10.3. stat — stat() の返す内容を解釈する

10.4. statvfs — os.statvfs() で使われる定数群

10.5. filecmp — ファイルおよびディレクトリの比較

10.5.1. dircmp クラス

10.6. tempfile — 一時的なファイルやディレクトリの生成

10.7. glob — Unix 形式のパス名のパターン展開

10.8. fnmatch — Unix ファイル名のパターンマッチ

10.9. linecache — テキストラインにランダムアクセスする

10.10. shutil — 高レベルなファイル操作

10.10.1. ディレクトリとファイルの操作

10.10.1.1. copytree の例

10.10.2. アーカイブの操作

10.10.2.1. アーカイブ化の例

10.11. dircache — キャッシュされたディレクトリ一覧の生成

10.12. macpath — Mac OS 9 のパス操作関数

11. データの永続化

11.1. pickle — Python オブジェクトの整列化

11.1.1. 他の Python モジュールとの関係

11.1.2. データストリームの形式

11.1.3. 使用法

11.1.4. 何を pickle 化したり unpickle 化できるのか?

11.1.5. pickle 化プロトコル

11.1.5.1. 通常のクラスインスタンスの pickle 化および unpickle 化

11.1.5.2. 拡張型の pickle 化および unpickle 化

11.1.5.3. 外部オブジェクトの pickle 化および unpickle 化

11.1.6. Unpickler をサブクラス化する

11.1.7. 例

11.2. cPickle — より高速な pickle

11.3. copy_reg — pickle サポート関数を登録する

11.4. shelve — Python オブジェクトの永続化

11.4.1. 制限事項

11.4.2. 使用例

11.5. marshal — 内部使用向けの Python オブジェクト整列化

11.6. anydbm — DBM 形式のデータベースへの汎用アクセスインタフェース

11.7. whichdb — どのDBMモジュールがデータベースを作ったかを推測する

11.8. dbm — UNIX dbmのシンプルなインタフェース

11.9. gdbm — GNU による dbm の再実装

11.10. dbhash — BSD データベースライブラリへの DBM 形式のインタフェース

11.10.1. データベースオブジェクト

11.11. bsddb — Berkeley DB ライブラリへのインタフェース

11.11.1. ハッシュ、BTree、およびレコードオブジェクト

11.12. dumbdbm — 可搬性のある DBM 実装

11.12.1. Dumbdbm オブジェクト

11.13. sqlite3 — SQLite データベースに対する DB-API 2.0 インタフェース

11.13.1. モジュールの関数と定数

11.13.2. Connection オブジェクト

11.13.3. カーソルオブジェクト

11.13.4. Row オブジェクト

11.13.5. SQLite と Python の型

11.13.5.1. 入門編

11.13.5.2. 追加された Python の型を SQLite データベースに格納するために適合関数を使う

11.13.5.2.1. オブジェクト自身で適合するようにする

11.13.5.2.2. 適合関数を登録する

11.13.5.3. SQLite の値を好きな Python 型に変換する

11.13.5.4. デフォルトの適合関数と変換関数

11.13.6. トランザクション制御

11.13.7. sqlite3 の効率的な使い方

11.13.7.1. ショートカットメソッドを使う

11.13.7.2. 位置ではなく名前でカラムにアクセスする

11.13.7.3. コネクションをコンテキストマネージャーとして利用する

11.13.8. 既知の問題

11.13.8.1. マルチスレッド

12. データ圧縮とアーカイブ

12.1. zlib — gzip 互換の圧縮

12.2. gzip — gzip ファイルのサポート

12.2.1. 使い方の例

12.3. bz2 — bzip2 互換の圧縮ライブラリ

12.3.1. ファイルの圧縮/解凍

12.3.2. 逐次的な圧縮/解凍

12.3.3. 一括圧縮/解凍

12.4. zipfile — ZIP アーカイブの処理

12.4.1. ZipFile オブジェクト

12.4.2. PyZipFile オブジェクト

12.4.3. ZipInfo オブジェクト

12.5. tarfile — tar アーカイブファイルを読み書きする

12.5.1. TarFile オブジェクト

12.5.2. TarInfo オブジェクト

12.5.3. 例

12.5.4. サポートされる tar のフォーマット

12.5.5. Unicode に関する問題

13. ファイルフォーマット

13.1. csv — CSV ファイルの読み書き

13.1.1. モジュールの内容

13.1.2. Dialect クラスと書式化パラメタ

13.1.3. reader オブジェクト

13.1.4. writer オブジェクト

13.1.5. 使用例

13.2. ConfigParser — 設定ファイルの構文解析器

13.2.1. RawConfigParser オブジェクト

13.2.2. ConfigParser オブジェクト

13.2.3. SafeConfigParser オブジェクト

13.2.4. 例

13.3. robotparser — robots.txt のためのパーザ

13.4. netrc — netrc ファイルの処理

13.4.1. netrc オブジェクト

13.5. xdrlib — XDR データのエンコードおよびデコード

13.5.1. Packer オブジェクト

13.5.2. Unpacker オブジェクト

13.5.3. 例外

13.6. plistlib — Mac OS X .plist ファイルの生成と解析

13.6.1. 例

14. 暗号関連のサービス

14.1. hashlib — セキュアハッシュおよびメッセージダイジェスト

14.2. hmac — メッセージ認証のための鍵付きハッシュ化

14.3. md5 — MD5 メッセージダイジェストアルゴリズム

14.4. sha — SHA-1 メッセージダイジェストアルゴリズム

15. 汎用オペレーティングシステムサービス

15.1. os — 雑多なオペレーティングシステムインタフェース

15.1.1. プロセスのパラメタ

15.1.2. ファイルオブジェクトの生成

15.1.3. ファイル記述子の操作

15.1.3.1. open() フラグ定数

15.1.4. ファイルとディレクトリ

15.1.5. プロセス管理

15.1.6. 雑多なシステム情報

15.1.7. 雑多な関数

15.2. io — ストリームを扱うコアツール

15.2.1. モジュールインタフェース

15.2.2. I/O 基底クラス

15.2.3. 生ファイルI/O

15.2.4. バッファ付きストリーム

15.2.5. テキスト I/O

15.2.6. 進んだ話題

15.2.6.1. パフォーマンス

15.2.6.1.1. バイナリ I/O

15.2.6.1.2. テキスト I/O

15.2.6.2. マルチスレッディング

15.2.6.3. リエントラント性

15.3. time — 時刻データへのアクセスと変換

15.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー

15.4.1. 例

15.4.1.1. パーサーを作る

15.4.1.2. 引数を追加する

15.4.1.3. 引数をパースする

15.4.2. ArgumentParser オブジェクト

15.4.2.1. description

15.4.2.2. epilog

15.4.2.3. add_help

15.4.2.4. prefix_chars

15.4.2.5. fromfile_prefix_chars

15.4.2.6. argument_default

15.4.2.7. parents

15.4.2.8. formatter_class

15.4.2.9. conflict_handler

15.4.2.10. prog

15.4.2.11. usage

15.4.3. add_argument() メソッド

15.4.3.1. name or flags

15.4.3.2. action

15.4.3.3. nargs

15.4.3.4. const

15.4.3.5. default

15.4.3.6. type

15.4.3.7. choices

15.4.3.8. required

15.4.3.9. help

15.4.3.10. metavar

15.4.3.11. dest

15.4.4. parse_args() メソッド

15.4.4.1. オプション値の文法

15.4.4.2. 不正な引数

15.4.4.3. "-" を含む引数

15.4.4.4. 引数の短縮形

15.4.4.5. sys.argv 以外

15.4.4.6. Namespace オブジェクト

15.4.5. その他のユーティリティ

15.4.5.1. サブコマンド

15.4.5.2. FileType オブジェクト

15.4.5.3. 引数グループ

15.4.5.4. 相互排他

15.4.5.5. パーサーのデフォルト値

15.4.5.6. ヘルプの表示

15.4.5.7. 部分解析

15.4.5.8. ファイル解析のカスタマイズ

15.4.5.9. 終了メソッド

15.4.6. optparse からのアップグレード

15.5. optparse — コマンドラインオプション解析器

15.5.1. 背景

15.5.1.1. 用語集

15.5.1.2. オプションとは何か

15.5.1.3. 固定引数とは何か

15.5.2. チュートリアル

15.5.2.1. オプション・アクションを理解する

15.5.2.2. store アクション

15.5.2.3. ブール値 (フラグ) オプションの処理

15.5.2.4. その他のアクション

15.5.2.5. デフォルト値

15.5.2.6. ヘルプの生成

15.5.2.6.1. オプションをグループ化する

15.5.2.7. バージョン番号の出力

15.5.2.8. optparse のエラー処理法

15.5.2.9. 全てをつなぎ合わせる

15.5.3. リファレンスガイド

15.5.3.1. parserを作る

15.5.3.2. パーザへのオプション追加

15.5.3.3. オプションの定義

15.5.3.4. オプション属性

15.5.3.5. 標準的なオプション・アクション

15.5.3.6. 標準のオプション型

15.5.3.7. 引数の解析

15.5.3.8. オプション解析器への問い合わせと操作

15.5.3.9. オプション間の衝突

15.5.3.10. クリーンアップ

15.5.3.11. その他のメソッド

15.5.4. オプション処理コールバック

15.5.4.1. callbackオプションの定義

15.5.4.2. コールバック関数はどのように呼び出されるか

15.5.4.3. コールバック中で例外を送出する

15.5.4.4. コールバックの例 1: ありふれたコールバック

15.5.4.5. コールバックの例 2: オプションの順番をチェックする

15.5.4.6. コールバックの例 3: オプションの順番をチェックする (汎用的)

15.5.4.7. コールバックの例 4: 任意の条件をチェックする

15.5.4.8. コールバックの例5: 固定引数

15.5.4.9. コールバックの例6: 可変個の引数

15.5.5. optparse の拡張

15.5.5.1. 新しい型の追加

15.5.5.2. 新しいアクションの追加

15.6. getopt — C言語スタイルのコマンドラインオプションパーサ

15.7. logging — Python 用ロギング機能

15.7.1. ロガーオブジェクト

15.7.2. ハンドラオブジェクト

15.7.3. フォーマッタオブジェクト

15.7.4. フィルタオブジェクト

15.7.5. LogRecord オブジェクト

15.7.6. LogRecord 属性

15.7.7. LoggerAdapter オブジェクト

15.7.8. スレッドセーフ性

15.7.9. モジュールレベル関数

15.7.10. warnings モジュールとの統合

15.8. logging.config — ロギングの環境設定

15.8.1. 環境設定のための関数

15.8.2. 環境設定辞書スキーマ

15.8.2.1. 辞書スキーマの詳細

15.8.2.2. 増分設定

15.8.2.3. オブジェクトの接続

15.8.2.4. ユーザ定義オブジェクト

15.8.2.5. 外部オブジェクトへのアクセス

15.8.2.6. 内部オブジェクトへのアクセス

15.8.3. 環境設定ファイルの書式

15.9. logging.handlers — ロギングハンドラ

15.9.1. StreamHandler

15.9.2. FileHandler

15.9.3. NullHandler

15.9.4. WatchedFileHandler

15.9.5. RotatingFileHandler

15.9.6. TimedRotatingFileHandler

15.9.7. SocketHandler

15.9.8. DatagramHandler

15.9.9. SysLogHandler

15.9.10. NTEventLogHandler

15.9.11. SMTPHandler

15.9.12. MemoryHandler

15.9.13. HTTPHandler

15.10. getpass — 可搬性のあるパスワード入力機構

15.11. curses — 文字セル表示のための端末操作

15.11.1. 関数

15.11.2. Window オブジェクト

15.11.3. 定数

15.12. curses.textpad — curses プログラムのためのテキスト入力ウィジェット

15.12.1. Textbox オブジェクト

15.13. curses.wrapper — curses プログラムのための端末ハンドラ

15.14. curses.ascii — ASCII 文字に関するユーティリティ

15.15. curses.panel — curses のためのパネルスタック拡張

15.15.1. 関数

15.15.2. Panel オブジェクト

15.16. platform — 実行中プラットフォームの固有情報を参照する

15.16.1. クロスプラットフォーム

15.16.2. Java プラットフォーム

15.16.3. Windows プラットフォーム

15.16.3.1. Win95/98 固有

15.16.4. Mac OS プラットフォーム

15.16.5. Unix プラットフォーム

15.17. errno — 標準の errno システムシンボル

15.18. ctypes — Pythonのための外部関数ライブラリ

15.18.1. ctypesチュートリアル

15.18.1.1. 動的リンクライブラリをロードする

15.18.1.2. ロードしたdllから関数にアクセスする

15.18.1.3. 関数を呼び出す

15.18.1.4. 基本のデータ型

15.18.1.5. 続・関数を呼び出す

15.18.1.6. 自作のデータ型とともに関数を呼び出す

15.18.1.7. 要求される引数の型を指定する (関数プロトタイプ)

15.18.1.8. 戻り値の型

15.18.1.9. ポインタを渡す(または、パラメータの参照渡し)

15.18.1.10. 構造体と共用体

15.18.1.11. 構造体/共用体アライメントとバイトオーダー

15.18.1.12. 構造体と共用体におけるビットフィールド

15.18.1.13. 配列

15.18.1.14. ポインタ

15.18.1.15. 型変換

15.18.1.16. 不完全型

15.18.1.17. コールバック関数

15.18.1.18. dllからエクスポートされている値へアクセスする

15.18.1.19. 予期しないこと

15.18.1.20. 可変サイズのデータ型

15.18.2. ctypesリファレンス

15.18.2.1. 共有ライブラリを見つける

15.18.2.2. 共有ライブラリをロードする

15.18.2.3. 外部関数

15.18.2.4. 関数プロトタイプ

15.18.2.5. ユーティリティ関数

15.18.2.6. データ型

15.18.2.7. 基本データ型

15.18.2.8. 標準データ型

15.18.2.9. 配列とポインタ

16. オプションのオペレーティングシステムサービス

16.1. select — I/O 処理の完了を待機する

16.1.1. エッジおよびレベルトリガポーリング (epoll) オブジェクト

16.1.2. ポーリングオブジェクト

16.1.3. kqueue オブジェクト

16.1.4. kevent オブジェクト

16.2. threading — 高水準のスレッドインタフェース

16.2.1. Thread オブジェクト

16.2.2. Lock オブジェクト

16.2.3. RLock オブジェクト

16.2.4. Condition オブジェクト

16.2.5. Semaphore オブジェクト

16.2.5.1. Semaphore の例

16.2.6. Event オブジェクト

16.2.7. Timer オブジェクト

16.2.8. with 文でのロック・条件変数・セマフォの使い方

16.2.9. スレッド化されたコード中でのImport

16.3. thread — マルチスレッドのコントロール

16.4. dummy_threading — threading の代替モジュール

16.5. dummy_thread — thread の代替モジュール

16.6. multiprocessing — プロセスベースの “並列処理” インタフェース

16.6.1. はじめに

16.6.1.1. Process クラス

16.6.1.2. プロセス間でのオブジェクト交換

16.6.1.3. プロセス間の同期

16.6.1.4. プロセス間での状態の共有

16.6.1.5. ワーカープロセスのプールを使用

16.6.2. リファレンス

16.6.2.1. Process クラスと例外

16.6.2.2. パイプ (Pipe) とキュー (Queue)

16.6.2.3. その他の関数(Miscellaneous)

16.6.2.4. Connection オブジェクト

16.6.2.5. 同期プリミティブ

16.6.2.6. 共有 ctypes オブジェクト

16.6.2.6.1. multiprocessing.sharedctypes モジュール

16.6.2.7. Managers

16.6.2.7.1. Namespace オブジェクト

16.6.2.7.2. カスタマイズされたマネージャ

16.6.2.7.3. リモートマネージャを使用する

16.6.2.8. Proxy オブジェクト

16.6.2.8.1. クリーンアップ

16.6.2.9. プロセスプール

16.6.2.10. Listeners and Clients

16.6.2.10.1. アドレスフォーマット

16.6.2.11. 認証キー

16.6.2.12. ロギング

16.6.2.13. multiprocessing.dummy モジュール

16.6.3. プログラミングガイドライン

16.6.3.1. 全てのプラットホーム

16.6.3.2. Windows

16.6.4. 例

16.7. mmap — メモリマップファイル

16.8. readline — GNU readline のインタフェース

16.8.1. 例

16.9. rlcompleter — GNU readline向け補完関数

16.9.1. Completerオブジェクト

17. プロセス間通信とネットワーク

17.1. subprocess — サブプロセス管理

17.1.1. subprocess モジュールを使う

17.1.1.1. 便利な関数

17.1.1.2. 例外

17.1.1.3. セキュリティ

17.1.2. Popen オブジェクト

17.1.3. Windows Popen ヘルパ

17.1.3.1. 定数

17.1.4. 古い関数を subprocess モジュールで置き換える

17.1.4.1. /bin/sh シェルのバッククォートを置き換える

17.1.4.2. シェルのパイプラインを置き換える

17.1.4.3. os.system() を置き換える

17.1.4.4. os.spawn 関数群を置き換える

17.1.4.5. os.popen(), os.popen2(), os.popen3() を置き換える

17.1.4.6. popen2 モジュールの関数群を置き換える

17.1.5. 注釈

17.1.5.1. Windows における引数シーケンスから文字列への変換

17.2. socket — 低レベルネットワークインターフェース

17.2.1. socket オブジェクト

17.2.2. 例

17.3. ssl — ソケットオブジェクトに対する TLS/SSL ラッパー

17.3.1. 関数、定数、例外

17.3.2. SSLSocket オブジェクト

17.3.3. 証明書

17.3.4. 例

17.3.4.1. SSLサポートをテストする

17.3.4.2. クライアントサイドの処理

17.3.4.3. サーバーサイドの処理

17.4. signal — 非同期イベントにハンドラを設定する

17.4.1. 例

17.5. popen2 — アクセス可能な I/O ストリームを持つ子プロセス生成

17.5.1. Popen3 および Popen4 オブジェクト

17.5.2. フロー制御の問題

17.6. asyncore — 非同期ソケットハンドラ

17.6.1. asyncoreの例：簡単なHTTPクライアント

17.6.2. 基本的な echo サーバーの例

17.7. asynchat — 非同期ソケットコマンド/レスポンスハンドラ

17.7.1. asynchat - 補助クラス

17.7.2. asynchat 使用例

18. インターネット上のデータの操作

18.1. email — 電子メールと MIME 処理のためのパッケージ

18.1.1. email: 電子メールメッセージの表現

18.1.2. email: 電子メールメッセージを解析(パース)する

18.1.2.1. FeedParser API

18.1.2.2. Parser クラス API

18.1.2.3. 追加事項

18.1.3. email: MIME 文書を生成する

18.1.4. email: 電子メールおよび MIME オブジェクトをゼロから作成する

18.1.5. email: 国際化されたヘッダ

18.1.6. email: 文字セットの表現

18.1.7. email: エンコーダ

18.1.8. email: 例外及び障害クラス

18.1.9. email: 雑用ユーティリティ

18.1.10. email: イテレータ

18.1.11. email: 使用例

18.1.12. パッケージの履歴

18.1.13. mimelib との違い

18.2. json — JSON エンコーダおよびデコーダ

18.2.1. 基本的な使い方

18.2.2. エンコーダおよびデコーダ

18.3. mailcap — mailcap ファイルの操作

18.4. mailbox — 様々な形式のメールボックス操作

18.4.1. Mailbox オブジェクト

18.4.1.1. Maildir

18.4.1.2. mbox

18.4.1.3. MH

18.4.1.4. Babyl

18.4.1.5. MMDF

18.4.2. Message objects

18.4.2.1. MaildirMessage

18.4.2.2. mboxMessage

18.4.2.3. MHMessage

18.4.2.4. BabylMessage

18.4.2.5. MMDFMessage

18.4.3. 例外

18.4.4. 撤廃されたクラスとメソッド

18.4.5. 例

18.5. mhlib — MH のメールボックスへのアクセス機構

18.5.1. MH オブジェクト

18.5.2. Folder オブジェクト

18.5.3. Message オブジェクト

18.6. mimetools — MIME メッセージを解析するためのツール

18.6.1. Message オブジェクトの追加メソッド

18.7. mimetypes — ファイル名を MIME 型へマップする

18.7.1. Mime型オブジェクト

18.8. MimeWriter — 汎用 MIME ファイルライター

18.8.1. MimeWriter オブジェクト

18.9. mimify — 電子メールメッセージの MIME 処理

18.10. multifile — 個別の部分を含んだファイル群のサポート

18.10.1. MultiFile オブジェクト

18.10.2. MultiFile の例

18.11. rfc822 — RFC 2822 準拠のメールヘッダ読み出し

18.11.1. Message オブジェクト

18.11.2. AddressList オブジェクト

18.12. base64 — RFC 3548: Base16, Base32, Base64 データの符号化

18.13. binhex — binhex4 形式ファイルのエンコードおよびデコード

18.13.1. 注記

18.14. binascii — バイナリデータと ASCIIデータとの間での変換

18.15. quopri — MIME quoted-printable 形式データのエンコードおよびデコード

18.16. uu — uuencode形式のエンコードとデコード

19. 構造化マークアップツール

19.1. HTMLParser — HTML および XHTML のシンプルなパーザ

19.1.1. HTML パーザアプリケーションの例

19.2. sgmllib — 単純な SGML パーザ

19.3. htmllib — HTML 文書の解析器

19.3.1. HTMLParser オブジェクト

19.4. htmlentitydefs — HTML 一般エンティティの定義

19.5. xml.parsers.expat — Expat を使った高速な XML 解析

19.5.1. XMLParser Objects

19.5.2. ExpatError 例外

19.5.3. 例

19.5.4. 内容モデルの記述

19.5.5. Expat エラー定数

19.6. xml.dom — 文書オブジェクトモデル (DOM) API

19.6.1. モジュールの内容

19.6.2. DOM 内のオブジェクト

19.6.2.1. DOMImplementation オブジェクト

19.6.2.2. Node オブジェクト

19.6.2.3. NodeList オブジェクト

19.6.2.4. DocumentType オブジェクト

19.6.2.5. Document オブジェクト

19.6.2.6. Element オブジェクト

19.6.2.7. Attr オブジェクト

19.6.2.8. NamedNodeMap Objects

19.6.2.9. Comment オブジェクト

19.6.2.10. Text オブジェクトおよび CDATASection オブジェクト

19.6.2.11. ProcessingInstruction オブジェクト

19.6.2.12. 例外

19.6.3. 適合性

19.6.3.1. 型の対応付け

19.6.3.2. アクセサメソッド

19.7. xml.dom.minidom — 軽量な DOM 実装

19.7.1. DOM オブジェクト

19.7.2. DOM の例

19.7.3. minidom と DOM 標準

19.8. xml.dom.pulldom — 部分的な DOM ツリー構築のサポート

19.8.1. DOMEventStream オブジェクト

19.9. xml.sax — SAX2 パーサのサポート

19.9.1. SAXException オブジェクト

19.10. xml.sax.handler — SAX ハンドラの基底クラス

19.10.1. ContentHandler オブジェクト

19.10.2. DTDHandler オブジェクト

19.10.3. EntityResolver オブジェクト

19.10.4. ErrorHandler オブジェクト

19.11. xml.sax.saxutils — SAX ユーティリティ

19.12. xml.sax.xmlreader — XML パーサのインタフェース

19.12.1. XMLReader オブジェクト

19.12.2. IncrementalParser オブジェクト

19.12.3. Locator オブジェクト

19.12.4. InputSource オブジェクト

19.12.5. The Attributes インタフェース

19.12.6. AttributesNS インタフェース

19.13. xml.etree.ElementTree — ElementTree XML API

19.13.1. 関数

19.13.2. Element オブジェクト

19.13.3. ElementTree オブジェクト

19.13.4. QName オブジェクト

19.13.5. TreeBuilder オブジェクト

19.13.6. XMLParser オブジェクト

20. インターネットプロトコルとその支援

20.1. webbrowser — 便利なウェブブラウザコントローラー

20.1.1. ブラウザコントローラーオブジェクト

20.2. cgi — CGI (ゲートウェイインタフェース規格) のサポート

20.2.1. はじめに

20.2.2. cgi モジュールを使う

20.2.3. 高水準インタフェース

20.2.4. 古いクラス群

20.2.5. 関数

20.2.6. セキュリティへの配慮

20.2.7. CGI スクリプトを Unix システムにインストールする

20.2.8. CGI スクリプトをテストする

20.2.9. CGI スクリプトをデバッグする

20.2.10. よくある問題と解決法

20.3. cgitb — CGI スクリプトのトレースバック管理機構

20.4. wsgiref — WSGI ユーティリティとリファレンス実装

20.4.1. wsgiref.util – WSGI 環境のユーティリティ

20.4.2. wsgiref.headers – WSGI レスポンスヘッダツール群

20.4.3. wsgiref.simple_server – シンプルな WSGI HTTP サーバ

20.4.4. wsgiref.validate — WSGI 準拠チェッカー

20.4.5. wsgiref.handlers – サーバ／ゲートウェイのベースクラス

20.4.6. 例

20.5. urllib — URL による任意のリソースへのアクセス

20.5.1. 高レベルインタフェース

20.5.2. ユーティリティー関数

20.5.3. URL Opener オブジェクト

20.5.4. urllib の制限

20.5.5. 使用例

20.6. urllib2 — URL を開くための拡張可能なライブラリ

20.6.1. Request オブジェクト

20.6.2. OpenerDirector オブジェクト

20.6.3. BaseHandler オブジェクト

20.6.4. HTTPRedirectHandler オブジェクト

20.6.5. HTTPCookieProcessor オブジェクト

20.6.6. ProxyHandler オブジェクト

20.6.7. HTTPPasswordMgr オブジェクト

20.6.8. AbstractBasicAuthHandler オブジェクト

20.6.9. HTTPBasicAuthHandler オブジェクト

20.6.10. ProxyBasicAuthHandler オブジェクト

20.6.11. AbstractDigestAuthHandler オブジェクト

20.6.12. HTTPDigestAuthHandler オブジェクト

20.6.13. ProxyDigestAuthHandler オブジェクト

20.6.14. HTTPHandler オブジェクト

20.6.15. HTTPSHandler オブジェクト

20.6.16. FileHandler オブジェクト

20.6.17. FTPHandler オブジェクト

20.6.18. CacheFTPHandler オブジェクト

20.6.19. UnknownHandler オブジェクト

20.6.20. HTTPErrorProcessor オブジェクト

20.6.21. 例

20.7. httplib — HTTP プロトコルクライアント

20.7.1. HTTPConnection オブジェクト

20.7.2. HTTPResponse オブジェクト

20.7.3. 例

20.8. ftplib — FTPプロトコルクライアント

20.8.1. FTP オブジェクト

20.8.2. FTP_TLS オブジェクト

20.9. poplib — POP3 プロトコルクライアント

20.9.1. POP3 オブジェクト

20.9.2. POP3 の例

20.10. imaplib — IMAP4 プロトコルクライアント

20.10.1. IMAP4 オブジェクト

20.10.2. IMAP4 の使用例

20.11. nntplib — NNTP プロトコルクライアント

20.11.1. NNTP オブジェクト

20.12. smtplib — SMTP プロトコルクライアント

20.12.1. SMTP オブジェクト

20.12.2. SMTP 使用例

20.13. smtpd — SMTP サーバー

20.13.1. SMTPServer オブジェクト

20.13.2. DebuggingServer オブジェクト

20.13.3. PureProxy オブジェクト

20.13.4. MailmanProxy Objects

20.14. telnetlib — Telnet クライアント

20.14.1. Telnet オブジェクト

20.14.2. Telnet Example

20.15. uuid — RFC 4122 に準拠した UUID オブジェクト

20.15.1. 例

20.16. urlparse — URL を解析して構成要素にする

20.16.1. urlparse() および urlsplit() の結果

20.17. SocketServer — ネットワークサーバ構築のためのフレームワーク

20.17.1. サーバ生成に関するノート

20.17.2. Serverオブジェクト

20.17.3. RequestHandlerオブジェクト

20.17.4. 例

20.17.4.1. SocketServer.TCPServer の例

20.17.4.2. SocketServer.UDPServer の例

20.17.4.3. 平行処理の Mix-in

20.18. BaseHTTPServer — 基本的な機能を持つ HTTP サーバ

20.18.1. 他の例

20.19. SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ

20.20. CGIHTTPServer — CGI 実行機能付き HTTP リクエスト処理機構

20.21. cookielib — HTTP クライアント用の Cookie 処理

20.21.1. CookieJar および FileCookieJar オブジェクト

20.21.2. FileCookieJar のサブクラスと web ブラウザとの連携

20.21.3. CookiePolicy オブジェクト

20.21.4. DefaultCookiePolicy オブジェクト

20.21.5. Cookie オブジェクト

20.21.6. 使用例

20.22. Cookie — HTTPの状態管理

20.22.1. Cookieオブジェクト

20.22.2. Morselオブジェクト

20.22.3. 例

20.23. xmlrpclib — XML-RPC クライアントアクセス

20.23.1. ServerProxy オブジェクト

20.23.2. Boolean オブジェクト

20.23.3. DateTime オブジェクト

20.23.4. Binary オブジェクト

20.23.5. Fault オブジェクト

20.23.6. ProtocolError オブジェクト

20.23.7. MultiCall オブジェクト

20.23.8. 補助関数

20.23.9. クライアントのサンプル

20.23.10. クライアントとサーバーの利用例

20.24. SimpleXMLRPCServer — 基本的なXML-RPCサーバー

20.24.1. SimpleXMLRPCServer オブジェクト

20.24.1.1. SimpleXMLRPCServer の例

20.24.2. CGIXMLRPCRequestHandler

20.25. DocXMLRPCServer — セルフ-ドキュメンティング XML-RPC サーバ

20.25.1. DocXMLRPCServer オブジェクト

20.25.2. DocCGIXMLRPCRequestHandler

21. マルチメディアサービス

21.1. audioop — 生の音声データを操作する

21.2. imageop — 生の画像データを操作する

21.3. aifc — AIFFおよびAIFCファイルの読み書き

21.4. sunau — Sun AUファイルの読み書き

21.4.1. AU_read オブジェクト

21.4.2. AU_write オブジェクト

21.5. wave — WAVファイルの読み書き

21.5.1. Wave_read オブジェクト

21.5.2. Wave_write オブジェクト

21.6. chunk — IFFチャンクデータの読み込み

21.7. colorsys — 色体系間の変換

21.8. imghdr — 画像の形式を決定する

21.9. sndhdr — サウンドファイルの識別

21.10. ossaudiodev — OSS互換オーディオデバイスへのアクセス

21.10.1. オーディオデバイスオブジェクト

21.10.2. ミキサデバイスオブジェクト

22. 国際化

22.1. gettext — 多言語対応に関する国際化サービス

22.1.1. GNU gettext API

22.1.2. クラスに基づいた API

22.1.2.1. NullTranslations クラス

22.1.2.2. GNUTranslations クラス

22.1.2.3. Solaris メッセージカタログ機構のサポート

22.1.2.4. Catalog コンストラクタ

22.1.3. プログラムやモジュールを国際化する

22.1.3.1. モジュールを地域化する

22.1.3.2. アプリケーションを地域化する

22.1.3.3. 動作中 (on the fly) に言語を切り替える

22.1.3.4. 翻訳処理の遅延解決

22.1.3.5. gettext() vs. lgettext()

22.1.4. 謝辞

22.2. locale — 国際化サービス

22.2.1. ロケールの背景、詳細、ヒント、助言および補足説明

22.2.2. Python 拡張の作者と、Python を埋め込むようなプログラムに関して

22.2.3. メッセージカタログへのアクセス

23. プログラムのフレームワーク

23.1. cmd — 行指向のコマンドインタープリタのサポート

23.1.1. Cmdオブジェクト

23.2. shlex — 単純な字句解析

23.2.1. モジュールの内容

23.2.2. shlex オブジェクト

23.2.3. 解析規則

24. Tkを用いたグラフィカルユーザインターフェイス

24.1. Tkinter — Tcl/Tk への Python インタフェース

24.1.1. Tkinter モジュール

24.1.2. Tkinter お助け手帳 (life preserver)

24.1.2.1. この節の使い方

24.1.2.2. 簡単なHello Worldプログラム

24.1.3. Tcl/Tk を (本当に少しだけ) 見渡してみる

24.1.4. 基本的な Tk プログラムと Tkinter との対応関係

24.1.5. Tk と Tkinter はどのように関わっているのか

24.1.6. 簡単なリファレンス

24.1.6.1. オプションの設定

24.1.6.2. Packer

24.1.6.3. Packer のオプション

24.1.6.4. ウィジェット変数を関連付ける

24.1.6.5. ウィンドウマネジャ

24.1.6.6. Tk オプションデータ型

24.1.6.7. バインドとイベント

24.1.6.8. index パラメータ

24.1.6.9. 画像

24.2. ttk — Tk themed widgets

24.2.1. Ttk を使う

24.2.2. Ttk ウィジェット

24.2.3. ウィジェット

24.2.3.1. 標準オプション

24.2.3.2. スクロール可能ウィジェットのオプション

24.2.3.3. ラベルオプション

24.2.3.4. 互換性オプション

24.2.3.5. ウィジェットの状態

24.2.3.6. ttk.Widget

24.2.4. コンボボックス

24.2.4.1. オプション

24.2.4.2. 仮想イベント

24.2.4.3. ttk.Combobox

24.2.5. ノートブック

24.2.5.1. オプション

24.2.5.2. タブオプション

24.2.5.3. タブ識別子

24.2.5.4. 仮想イベント

24.2.5.5. ttk.Notebook

24.2.6. プログレスバー

24.2.6.1. オプション

24.2.6.2. ttk.Progressbar

24.2.7. セパレータ

24.2.7.1. オプション

24.2.8. サイズグリップ

24.2.8.1. プラットフォーム固有のメモ

24.2.8.2. バグ

24.2.9. ツリービュー

24.2.9.1. オプション

24.2.9.2. 要素オプション

24.2.9.3. タグオプション

24.2.9.4. カラム識別子

24.2.9.5. 仮想イベント

24.2.9.6. ttk.Treeview

24.2.10. Ttk スタイル

24.2.10.1. レイアウト

24.3. Tix — Tkの拡張ウィジェット

24.3.1. Tixを使う

24.3.2. Tixウィジェット

24.3.2.1. 基本ウィジェット

24.3.2.2. ファイルセレクタ

24.3.2.3. ハイアラキカルリストボックス

24.3.2.4. タビュラーリストボックス

24.3.2.5. 管理ウィジェット

24.3.2.6. 画像タイプ

24.3.2.7. その他のウィジェット

24.3.2.8. ジオメトリマネジャを作る

24.3.3. Tixコマンド

24.4. ScrolledText — スクロールするテキストウィジェット

24.5. turtle — Tkのためのタートルグラフィックス

24.5.1. はじめに

24.5.2. Turtle および Screen のメソッド概観

24.5.2.1. Turtle のメソッド

24.5.2.2. TurtleScreen/Screen のメソッド

24.5.3. RawTurtle/Turtle のメソッドと対応する関数

24.5.3.1. Turtle の動き

24.5.3.2. Turtle の状態を知る

24.5.3.3. 設定と計測

24.5.3.4. Pen の制御

24.5.3.4.1. 描画状態

24.5.3.4.2. 色の制御

24.5.3.4.3. 塗りつぶし

24.5.3.4.4. さらなる描画の制御

24.5.3.5. タートルの状態

24.5.3.5.1. 可視性

24.5.3.5.2. 見た目

24.5.3.6. イベントを利用する

24.5.3.7. 特別な Turtle のメソッド

24.5.3.8. 合成形の使用に関する補遺

24.5.4. TurtleScreen/Screen のメソッドと対応する関数

24.5.4.1. ウィンドウの制御

24.5.4.2. アニメーションの制御

24.5.4.3. スクリーンイベントを利用する

24.5.4.4. 設定と特殊なメソッド

24.5.4.5. Screen 独自のメソッド、TurtleScreen から継承したもの以外

24.5.5. turtle モジュールのパブリッククラス

24.5.6. ヘルプと設定

24.5.6.1. ヘルプの使い方

24.5.6.2. ドキュメント文字列の翻訳

24.5.6.3. Screen および Turtle の設定方法

24.5.7. デモスクリプト

24.6. IDLE

24.6.1. メニュー

24.6.1.1. Fileメニュー

24.6.1.2. Editメニュー

24.6.1.3. Windowsメニュー

24.6.1.4. Debugメニュー( Python シェルウィンドウ内のみ)

24.6.2. 基本的な編集とナビゲーション

24.6.2.1. 自動的な字下げ

24.6.2.2. Python Shellウィンドウ

24.6.3. 構文の色づけ

24.6.4. スタートアップ

24.6.4.1. コマンドラインの使い方

24.7. 他のグラフィカルユーザインタフェースパッケージ

25. 開発ツール

25.1. pydoc — ドキュメント生成とオンラインヘルプシステム

25.2. doctest — 対話的な実行例をテストする

25.2.1. 簡単な利用法: docstring 中の実行例をチェックする

25.2.2. 簡単な利用法: テキストファイル中の実行例をチェックする

25.2.3. doctest のからくり

25.2.3.1. どの docstring が検証されるのか?

25.2.3.2. docstring 内の実行例をどのように認識するのか?

25.2.3.3. 実行コンテキストとは何か?

25.2.3.4. 例外はどう扱えばよいか?

25.2.3.5. オプションフラグとディレクティブ

25.2.3.6. 注意

25.2.4. 基本 API

25.2.5. 単体テスト API

25.2.6. 拡張 API

25.2.6.1. DocTest オブジェクト

25.2.6.2. Example オブジェクト

25.2.6.3. DocTestFinder オブジェクト

25.2.6.4. DocTestParser オブジェクト

25.2.6.5. DocTestRunner オブジェクト

25.2.6.6. OutputChecker オブジェクト

25.2.7. デバッグ

25.2.8. アドバイス

25.3. unittest — ユニットテストフレームワーク

25.3.1. 基礎的な例

25.3.2. コマンドラインインタフェース

25.3.2.1. コマンドラインオプション

25.3.3. テストディスカバリ

25.3.4. テストの構成

25.3.5. 既存テストコードの再利用

25.3.6. テストのスキップと意図的な失敗

25.3.7. クラスと関数

25.3.7.1. テストクラス

25.3.7.1.1. 廃止予定のエイリアス

25.3.7.2. テストのグルーピング

25.3.7.3. テストのロードと起動

25.3.7.3.1. load_tests プロトコル

25.3.8. クラスとモジュールの修正

25.3.8.1. setUpClass と tearDownClass

25.3.8.2. setUpModule と tearDownModule

25.3.9. シグナルハンドリング

25.4. 2to3 - Python 2 から 3 への自動コード変換

25.4.1. 2to3 の使用

25.4.2. 変換プログラム

25.4.3. lib2to3 - 2to3’s library

25.5. test — Python用回帰テストパッケージ

25.5.1. test パッケージのためのユニットテストを書く

25.5.2. コマンドラインインタフェースを利用してテストを実行する

25.5.3. test.test_support — テストのためのユーティリティ関数

26. デバッグとプロファイル

26.1. bdb — デバッガーフレームワーク

26.2. pdb — Python デバッガ

26.3. デバッガコマンド

26.4. Python プロファイラ

26.4.1. プロファイラとは

26.4.2. かんたんユーザマニュアル

26.4.3. 決定論的プロファイリングとは

26.4.4. リファレンスマニュアル – profile と cProfile

26.4.4.1. Stats クラス

26.4.5. 制限事項

26.4.6. キャリブレーション (補正)

26.4.7. 拡張 — プロファイラの改善

26.5. hotshot — ハイパフォーマンス・ロギング・プロファイラ

26.5.1. プロファイル・オブジェクト

26.5.2. hotshot データの利用

26.5.3. 使用例

26.6. timeit — 小さなコード断片の実行時間計測

26.6.1. コマンドライン・インターフェース

26.6.2. 使用例

26.7. trace — Python ステートメント実行のトレースと追跡

26.7.1. コマンドラインからの利用

26.7.1.1. 主要なオプション

26.7.1.2. 修飾的オプション

26.7.1.3. フィルターオプション

26.7.2. プログラミングインターフェース

27. Python ランタイムサービス

27.1. sys — システムパラメータと関数

27.2. sysconfig — Python の構成情報にアクセスする

27.2.1. 構成変数

27.2.2. インストールパス

27.2.3. その他の関数

27.3. __builtin__ — 組み込みオブジェクト

27.4. future_builtins — Python 3 のビルトイン

27.5. __main__ — トップレベルのスクリプト環境

27.6. warnings — 警告の制御

27.6.1. 警告カテゴリ

27.6.2. 警告フィルタ

27.6.2.1. デフォルトの警告フィルタ

27.6.3. 一時的に警告を抑制する

27.6.4. 警告のテスト

27.6.5. コードを新しいバージョンの Python のために更新する

27.6.6. 利用可能な関数

27.6.7. 利用可能なコンテキストマネージャー

27.7. contextlib — with -構文コンテキストのためのユーティリティ

27.8. abc — 抽象基底クラス

27.9. atexit — 終了ハンドラ

27.9.1. atexit の例

27.10. traceback — スタックトレースの表示または取得

27.10.1. トレースバックの例

27.11. __future__ — future 文の定義

27.12. gc — ガベージコレクタインターフェース

27.13. inspect — 活動中のオブジェクトの情報を取得する

27.13.1. 型とメンバー

27.13.2. ソースコードの情報取得

27.13.3. クラスと関数

27.13.4. インタープリタスタック

27.14. site — サイト固有の設定フック

27.15. user — ユーザー設定のフック

27.16. fpectl — 浮動小数点例外の制御

27.16.1. 例

27.16.2. 制限と他に考慮すべきこと

27.17. distutils — Python モジュールの構築とインストール

28. カスタム Python インタプリタ

28.1. code — インタプリタ基底クラス

28.1.1. 対話的なインタプリタオブジェクト

28.1.2. 対話的なコンソールオブジェクト

28.2. codeop — Pythonコードをコンパイルする

29. 制限実行 (restricted execution)

29.1. rexec — 制限実行のフレームワーク

29.1.1. RExec オブジェクト

29.1.2. 制限された環境を定義する

29.1.3. 例

29.2. Bastion — オブジェクトに対するアクセスの制限

30. モジュールのインポート

30.1. imp — import 内部へアクセスする

30.1.1. 例

30.2. importlib – __import__() の便利なラッパー

30.3. imputil — Import ユーティリティ

30.3.1. Examples

30.4. zipimport — Zip アーカイブからモジュールを import する

30.4.1. zipimporter オブジェクト

30.4.2. 使用例

30.5. pkgutil — パッケージ拡張ユーティリティ

30.6. modulefinder — スクリプト中で使われているモジュールを検索する

30.6.1. ModuleFinder の使用例

30.7. runpy — Python モジュールの位置特定と実行

31. Python言語サービス

31.1. parser — Python 解析木にアクセスする

31.1.1. ST オブジェクトを作成する

31.1.2. ST オブジェクトを変換する

31.1.3. ST オブジェクトに対する問い合わせ

31.1.4. 例外とエラー処理

31.1.5. ST オブジェクト

31.1.6. 例: compile() のエミュレーション

31.2. 抽象構文木

31.2.1. Node クラス

31.2.2. 抽象文法 (Abstract Grammar)

31.2.3. ast ヘルパー

31.3. symtable — コンパイラの記号表へのアクセス

31.3.1. 記号表の生成

31.3.2. 記号表の検査

31.4. symbol — Python 解析木と共に使われる定数

31.5. token — Python 解析木と共に使われる定数

31.6. keyword — Python キーワードチェック

31.7. tokenize — Pythonソースのためのトークナイザ

31.8. tabnanny — あいまいなインデントの検出

31.9. pyclbr — Python クラスブラウザサポート

31.9.1. Class オブジェクト

31.9.2. Function オブジェクト

31.10. py_compile — Python ソースファイルのコンパイル

31.11. compileall — Python ライブラリをバイトコンパイル

31.11.1. コマンドラインでの使用

31.11.2. パブリックな関数

31.12. dis — Python バイトコードの逆アセンブラ

31.12.1. Python バイトコード命令

31.13. pickletools — pickle 開発者のためのツール群

32. Python コンパイラパッケージ

32.1. 基本的なインターフェイス

32.2. 制限

32.3. Python 抽象構文

32.3.1. AST ノード

32.3.2. 代入ノード

32.3.3. サンプル

32.4. Visitor を使って AST をわたり歩く

32.5. バイトコード生成

33. 各種サービス

33.1. formatter — 汎用の出力書式化機構

33.1.1. formatter インタフェース

33.1.2. formatter 実装

33.1.3. writer インタフェース

33.1.4. writer 実装

34. MS Windows 固有のサービス

34.1. msilib — Microsoft インストーラーファイルの読み書き

34.1.1. データベースオブジェクト

34.1.2. ビューオブジェクト

34.1.3. サマリー情報オブジェクト

34.1.4. レコードオブジェクト

34.1.5. エラー

34.1.6. CAB オブジェクト

34.1.7. ディレクトリオブジェクト

34.1.8. フィーチャー

34.1.9. GUI クラス

34.1.10. 事前に計算されたテーブル

34.2. msvcrt – MS VC++実行時システムの有用なルーチン群

34.2.1. ファイル操作関連

34.2.2. コンソール I/O 関連

34.2.3. その多の関数

34.3. _winreg – Windows レジストリへのアクセス

34.3.1. 定数

34.3.1.1. HKEY_* 定数

34.3.1.2. アクセス権限

34.3.1.2.1. 64-bit 特有のアクセス権

34.3.1.3. 値の型

34.3.2. レジストリハンドルオブジェクト

34.4. winsound — Windows 用の音声再生インタフェース

35. Unix 固有のサービス

35.1. posix — 最も一般的な POSIX システムコール群

35.1.1. ラージファイルのサポート

35.1.2. 注目すべきモジュールの内容

35.2. pwd — パスワードデータベースへのアクセスを提供する

35.3. spwd — シャドウパスワードデータベース

35.4. grp — グループデータベースへのアクセス

35.5. crypt — Unix パスワードをチェックするための関数

35.6. dl — 共有オブジェクトのC関数の呼び出し

35.6.1. Dlオブジェクト

35.7. termios — POSIX スタイルの端末制御

35.7.1. 使用例

35.8. tty — 端末制御のための関数群

35.9. pty — 擬似端末ユーティリティ

35.10. fcntl — fcntl() および ioctl() システムコール

35.11. pipes — シェルパイプラインへのインタフェース

35.11.1. テンプレートオブジェクト

35.12. posixfile — ロック機構をサポートするファイル類似オブジェクト

35.13. resource — リソース使用状態の情報

35.13.1. リソースの制限

35.13.2. リソースの使用状態

35.14. nis — Sun の NIS (Yellow Pages) へのインタフェース

35.15. syslog — Unix syslog ライブラリルーチン群

35.15.1. 例

35.15.1.1. シンプルな例

35.16. commands — コマンド実行ユーティリティ

36. Mac OS X 固有のサービス

36.1. ic — Mac OS X インターネット設定へのアクセス

36.1.1. IC オブジェクト

36.2. MacOS — Mac OS インタプリタ機能へのアクセス

36.3. macostools — ファイル操作を便利にするルーチン集

36.4. findertools — finder のApple Eventsインターフェース

36.5. EasyDialogs — 基本的な Macintosh ダイアログ

36.5.1. プログレスバーオブジェクト

36.6. FrameWork — 対話型アプリケーション・フレームワーク

36.6.1. アプリケーションオブジェクト

36.6.2. ウィンドウオブジェクト

36.6.3. コントロールウィンドウオブジェクト

36.6.4. スクロールウィンドウオブジェクト

36.6.5. ダイアログウィンドウオブジェクト

36.7. autoGIL — イベントループ中のグローバルインタープリタの取り扱い

36.8. Mac OS ツールボックスモジュール

36.8.1. Carbon.AE — Apple Events

36.8.2. Carbon.AH — Apple ヘルプ

36.8.3. Carbon.App — アピアランスマネージャ

36.8.4. Carbon.Appearance — Appearance Manager 定数

36.8.5. Carbon.CF — Core Foundation

36.8.6. Carbon.CG — Core Graphics

36.8.7. Carbon.CarbonEvt — Carbon Event Manager

36.8.8. Carbon.CarbonEvents — Carbon Event Manager 定数

36.8.9. Carbon.Cm — Component Manager

36.8.10. Carbon.Components — Component Manager constants

36.8.11. Carbon.ControlAccessor — Control Manager accssors

36.8.12. Carbon.Controls — Control Manager constants

36.8.13. Carbon.CoreFounation — CoreFounation constants

36.8.14. Carbon.CoreGraphics — CoreGraphics constants

36.8.15. Carbon.Ctl — Control Manager

36.8.16. Carbon.Dialogs — Dialog Manager constants

36.8.17. Carbon.Dlg — Dialog Manager

36.8.18. Carbon.Drag — Drag and Drop Manager

36.8.19. Carbon.Dragconst — Drag and Drop Manager constants

36.8.20. Carbon.Events — Event Manager constants

36.8.21. Carbon.Evt — Event Manager

36.8.22. Carbon.File — File Manager

36.8.23. Carbon.Files — File Manager constants

36.8.24. Carbon.Fm — Font Manager

36.8.25. Carbon.Folder — Folder Manager

36.8.26. Carbon.Folders — Folder Manager constants

36.8.27. Carbon.Fonts — Font Manager constants

36.8.28. Carbon.Help — Help Manager

36.8.29. Carbon.IBCarbon — Carbon InterfaceBuilder

36.8.30. Carbon.IBCarbonRuntime — Carbon InterfaceBuilder constants

36.8.31. Carbon.Icn — Carbon Icon Manager

36.8.32. Carbon.Icons — Carbon Icon Manager constants

36.8.33. Carbon.Launch — Carbon Launch Services

36.8.34. Carbon.LaunchServices — Carbon Launch Services constants

36.8.35. Carbon.List — List Manager

36.8.36. Carbon.Lists — List Manager constants

36.8.37. Carbon.MacHelp — Help Manager constants

36.8.38. Carbon.MediaDescr — Parsers and generators for Quicktime Media descriptors

36.8.39. Carbon.Menu — Menu Manager

36.8.40. Carbon.Menus — Menu Manager constants

36.8.41. Carbon.Mlte — MultiLingual Text Editor

36.8.42. Carbon.OSA — Carbon OSA Interface

36.8.43. Carbon.OSAconst — Carbon OSA Interface constants

36.8.44. Carbon.QDOffscreen — QuickDraw Offscreen constants

36.8.45. Carbon.Qd — QuickDraw

36.8.46. Carbon.Qdoffs — QuickDraw Offscreen

36.8.47. Carbon.Qt — QuickTime

36.8.48. Carbon.QuickDraw — QuickDraw constants

36.8.49. Carbon.QuickTime — QuickTime constants

36.8.50. Carbon.Res — Resource Manager and Handles

36.8.51. Carbon.Resources — Resource Manager and Handles constants

36.8.52. Carbon.Scrap — スクラップマネージャ

36.8.53. Carbon.Snd — Sound Manager

36.8.54. Carbon.Sound — Sound Manager constants

36.8.55. Carbon.TE — TextEdit

36.8.56. Carbon.TextEdit — TextEdit constants

36.8.57. Carbon.Win — Window Manager

36.8.58. Carbon.Windows — Window Manager constants

36.9. ColorPicker — 色選択ダイアログ

37. MacPython OSA モジュール

37.1. gensuitemodule — OSA スタブ作成パッケージ

37.2. aetools — OSA クライアントのサポート

37.3. aepack — Python変数とAppleEventデータコンテナ間の変換

37.4. aetypes — AppleEvent オブジェクト

37.5. MiniAEFrame — オープンスクリプティングアーキテクチャサーバのサポート

37.5.1. AEServer オブジェクト

38. SGI IRIX 固有のサービス

38.1. al — SGIのオーディオ機能

38.1.1. コンフィギュレーションオブジェクト

38.1.2. ポートオブジェクト

38.2. AL — al モジュールで使われる定数

38.3. cd — SGI システムの CD-ROM へのアクセス

38.3.1. プレーヤーオブジェクト

38.3.2. パーザオブジェクト

38.4. fl — グラフィカルユーザーインターフェースのための FORMS ライブラリ

38.4.1. fl モジュールに定義されている関数

38.4.2. フォームオブジェクト

38.4.3. FORMSオブジェクト

38.5. FL — fl モジュールで使用される定数

38.6. flp — 保存されたFORMSデザインをロードする関数

38.7. fm — Font Manager インターフェース

38.8. gl — Graphics Library インターフェース

38.9. DEVICE — gl モジュールで使われる定数

38.10. GL — gl モジュールで使われる定数

38.11. imgfile — SGI imglib ファイルのサポート

38.12. jpeg — JPEGファイルの読み書きを行う

39. SunOS 固有のサービス

39.1. sunaudiodev — Sun オーディオハードウェアへのアクセス

39.1.1. オーディオデバイスオブジェクト

39.2. SUNAUDIODEV — sunaudiodev で使われる定数

40. ドキュメント化されていないモジュール

40.1. 雑多な有用ユーティリティ

40.2. プラットフォーム固有のモジュール

40.3. マルチメディア関連

40.4. 文書化されていない Mac OS モジュール

40.4.1. applesingle — AppleSingle デコーダー

40.4.2. buildtools — BuildAppletとその仲間のヘルパーモジュール

40.4.3. cfmfile — コードフラグメントリソースを扱うモジュール

40.4.4. icopen — open() と Internet Config の置き換え

40.4.5. macerrors — MacOSのエラー

40.4.6. macresource — スクリプトのリソースを見つける

40.4.7. Nav — NavServices の呼出し

40.4.8. PixMapWrapper — PixMapオブジェクトのラッパー

40.4.9. videoreader — QuickTime ムービーの読み込み

40.4.10. W — FrameWork 上に作られたウイジェット

40.5. 撤廃されたもの

40.6. SGI 固有の拡張モジュール

41. 日本語訳について

41.1. 翻訳者一覧 (敬称略)

Python インタプリタの拡張と埋め込み

1. C や C++ による Python の拡張

1.1. 簡単な例

1.2. 幕間小話: エラーと例外

1.3. 例に戻る

1.4. モジュールのメソッドテーブルと初期化関数

1.5. コンパイルとリンク

1.6. C から Python 関数を呼び出す

1.7. 拡張モジュール関数でのパラメタ展開

1.8. 拡張モジュール関数のキーワードパラメタ

1.9. 任意の値を構築する

1.10. 参照カウント法

1.10.1. Python における参照カウント法

1.10.2. 所有権にまつわる規則

1.10.3. 薄氷

1.10.4. NULL ポインタ

1.11. C++での拡張モジュール作成

1.12. 拡張モジュールに C API を提供する

2. 新しい型を定義する

2.1. 基本的なこと

2.1.1. 基本のサンプルにデータとメソッドを追加する

2.1.2. データ属性をこまかく制御する

2.1.3. 循環ガベージコレクションをサポートする

2.1.4. 他の型のサブクラスを作る

2.2. タイプメソッド

2.2.1. 最終化 (finalization) と解放

2.2.2. オブジェクト表現

2.2.3. 属性を管理する

2.2.3.1. 総称的な属性を管理する

2.2.3.2. 特定の型に特化した属性の管理

2.2.4. オブジェクトの比較

2.2.5. 抽象的なプロトコルのサポート

2.2.6. 弱参照(Weak Reference)のサポート

2.2.7. その他いろいろ

3. distutils による C および C++ 拡張モジュールのビルド

3.1. 拡張モジュールの配布

4. Windows 上での C および C++ 拡張モジュールのビルド

4.1. 型どおりのアプローチ

4.2. Unix と Windows の相違点

4.3. DLL 使用の実際

5. 他のアプリケーションへの Python の埋め込み

5.1. 高水準の埋め込み

5.2. 超高水準の埋め込みから踏み出す: 概要

5.3. 純粋な埋め込み

5.4. 埋め込まれた Python の拡張

5.5. C++による Python の埋め込み

5.6. リンクに関する要件

6. このドキュメントについて

6.1. 翻訳者一覧 (敬称略)

Python/C API リファレンスマニュアル

はじめに

インクルードファイル

オブジェクト、型および参照カウント

参照カウント

参照カウントの詳細

型

例外

Python の埋め込み

デバッグ版ビルド (Debugging Builds)

超高レベルレイヤ

参照カウント

例外処理

Unicode 例外オブジェクト

再帰の管理

標準例外

文字列の例外

ユーティリティ関数

オペレーティングシステム関連のユーティリティ

システム関数

プロセス制御

モジュールの import

データ整列化 (data marshalling) のサポート

引数の解釈と値の構築

文字列の変換と書式化

リフレクション

codec レジストリとサポート関数

コーデック検索API

Unicode エラーハンドラ用レジストリ API

抽象オブジェクトレイヤ (abstract objects layer)

オブジェクトプロトコル (object protocol)

数値型プロトコル (number protocol)

シーケンス型プロトコル (sequence protocol)

マップ型プロトコル (mapping protocol)

イテレータプロトコル (iterator protocol)

古いバッファプロトコル

具象オブジェクト (concrete object) レイヤ

基本オブジェクト (fundamental object)

型オブジェクト (type object)

None オブジェクト

数値型オブジェクト (numeric object)

(通常)整数型オブジェクト (plain integer object)

Bool 型オブジェクト

長整数型オブジェクト (long integer object)

浮動小数点型オブジェクト (floating point object)

浮動小数点オブジェクト (complex number object)

C 構造体としての複素数

Python オブジェクトとしての複素数型

シーケンスオブジェクト (sequence object)

bytearray オブジェクト

型チェックマクロ

ダイレクト API 関数

マクロ

文字列/バイトオブジェクト

Unicode オブジェクトと codec

Unicode オブジェクト

Unicode 型

Unicode 文字プロパティ

Plain Py_UNICODE

wchar_t サポート

組み込み codec (built-in codec)

汎用 codec

UTF-8 Codecs

UTF-32 Codecs

UTF-16 Codecs

UTF-7 Codecs

Unicode-Escape Codecs

Raw-Unicode-Escape Codecs

Latin-1 Codecs

ASCII Codecs

Character Map Codecs

Windows 用の MBCS codec

Methods & Slots

メソッドおよびスロット関数 (slot function)

buffer オブジェクトと memoryview オブジェクト

新スタイル Py_buffer 構造体

バッファ関連関数

memoryview オブジェクト

旧スタイルバッファオブジェクト

タプルオブジェクト (tuple object)

List Objects

マップ型オブジェクト (mapping object)

辞書オブジェクト (dictionary object)

その他のオブジェクト

クラスとインスタンスオブジェクト

関数オブジェクト (Function Objects)

メソッドオブジェクト (method object)

ファイルオブジェクト

モジュールオブジェクト (module object)

イテレータオブジェクト (iterator object)

デスクリプタオブジェクト (descriptor object)

スライスオブジェクト (slice object)

弱参照オブジェクト (weak reference object)

カプセル (Capsules)

Cオブジェクト (CObject)

セルオブジェクト (cell object)

ジェネレータオブジェクト

DateTime オブジェクト

集合オブジェクト (Set Objects)

コードオブジェクト

初期化 (initialization)、終了処理 (finalization)、スレッド

インタプリタの初期化と終了処理

プロセスワイドのパラメータ

スレッド状態 (thread state) とグローバルインタプリタロック (global interpreter lock)

拡張コード内で GIL を解放する

Python 以外で作られたスレッド

高レベルAPI

低レベルAPI

サブインタプリタサポート

バグと注意事項

非同期通知

プロファイルとトレース (profiling and tracing)

高度なデバッガサポート (advanced debugger support)

メモリ管理

概要

メモリインタフェース

例

オブジェクト実装サポート (object implementation support)

オブジェクトをヒープ上にメモリ確保する

共通のオブジェクト構造体 (common object structure)

型オブジェクト

数値オブジェクト構造体

マップ型オブジェクト構造体

シーケンスオブジェクト構造体

バッファオブジェクト構造体 (buffer object structure)

循環参照ガベージコレクションをサポートする

このドキュメントについて

翻訳者一覧 (敬称略)

Python モジュールの配布

Distutilsの紹介

概念と用語

簡単な例

Python 一般の用語

Distutils 固有の用語

setup スクリプトを書く

パッケージを全て列挙する

個々のモジュールを列挙する

拡張モジュールについて記述する

拡張モジュールの名前とパッケージ

拡張モジュールのソースファイル

プリプロセッサオプション

ライブラリオプション

その他のオプション

パッケージと配布物の関係

スクリプトをインストールする

パッケージデータをインストールする

追加のファイルをインストールする

追加のメタデータ

setup スクリプトをデバッグする

setup 設定ファイル (setup configuration file) を書く

ソースコード配布物を作成する

配布するファイルを指定する

マニフェスト (manifest) 関連のオプション

MANIFEST.in テンプレート

原則

コマンド

ビルド済み配布物を作成する

ダム形式のビルド済み配布物を作成する

RPM パッケージを作成する

Windows インストーラを作成する

Windowsでのクロスコンパイル

インストール後実行スクリプト (postinstallation script)

Vista User Access Control (UAC)

パッケージインデクスに登録する

.pypirc ファイル

パッケージを Package Index にアップロードする

PyPI パッケージ表示

例

pure Python 配布物 (モジュール形式)

pure Python 配布物 (パッケージ形式)

単体の拡張モジュール

Distutilsの拡張

新しいコマンドの統合

配布物の種類を追加する

コマンドリファレンス

モジュールをインストールする: install コマンド群

install_data

install_scripts

API リファレンス

distutils.core — Distutils のコア機能

distutils.ccompiler — CCompiler ベースクラス

distutils.unixccompiler — Unix C コンパイラ

distutils.msvccompiler — Microsoft コンパイラ

distutils.bcppcompiler — Borland コンパイラ

distutils.cygwincompiler — Cygwin コンパイラ

distutils.emxccompiler — OS/2 EMX コンパイラ

distutils.archive_util — アーカイブユーティリティ

distutils.dep_util — 依存関係のチェック

distutils.dir_util — ディレクトリツリーの操作

distutils.file_util — 1ファイルの操作

distutils.util — その他のユーティリティ関数

distutils.dist — Distribution クラス

distutils.extension — Extension クラス

distutils.debug — Distutils デバッグモード

distutils.errors — Distutils 例外

distutils.fancy_getopt — 標準 getopt モジュールのラッパ

distutils.filelist — FileList クラス

distutils.log — シンプルな PEP 282 スタイルのロギング

distutils.spawn — サブプロセスの生成

distutils.sysconfig — システム設定情報

distutils.text_file — TextFile クラス

distutils.version — バージョン番号クラス

distutils.cmd — Distutils コマンドの抽象クラス

新しいDistutilsコマンドの作成

distutils.command — Distutils 各コマンド

distutils.command.bdist — バイナリインストーラの構築

distutils.command.bdist_packager — パッケージの抽象ベースクラス

distutils.command.bdist_dumb — “ダム”インストーラを構築

distutils.command.bdist_msi — Microsoft Installer バイナリパッケージをビルドする

distutils.command.bdist_rpm — Redhat RPMとSRPM形式のバイナリディストリビューションを構築

distutils.command.bdist_wininst — Windowsインストーラの構築

distutils.command.sdist — ソース配布物の構築

distutils.command.build — パッケージ中の全ファイルを構築

distutils.command.build_clib — パッケージ中のCライブラリを構築

distutils.command.build_ext — パッケージ中の拡張を構築

distutils.command.build_py — パッケージ中の.py/.pyc ファイルを構築

distutils.command.build_scripts — パッケージ中のスクリプトを構築

distutils.command.clean — パッケージのビルドエリアを消去

distutils.command.config — パッケージの設定

distutils.command.install — パッケージのインストール

distutils.command.install_data — パッケージ中のデータファイルをインストール

distutils.command.install_headers — パッケージから C/C++ ヘッダファイルをインストール

distutils.command.install_lib — パッケージからライブラリファイルをインストール

distutils.command.install_scripts — パッケージからスクリプトファイルをインストール

distutils.command.register — モジュールをPython Package Indexに登録する

distutils.command.check — パッケージのメタデータをチェックする

このドキュメントについて

翻訳者一覧 (敬称略)

Python モジュールのインストール

はじめに

もっとも簡単な場合: ありふれたインストール作業

新しい標準: Distutils

標準的なビルド・インストール作業

プラットフォームによる違い

ビルド作業とインストール作業を分割する

ビルドの仕組み

インストールの仕組み

別の場所へのインストール

別の場所へのインストール: home スキーム

別の場所へのインストール: Unix (prefix スキーム)

別の場所へのインストール (prefix を使う方法): Windows

カスタムのインストール

Python サーチパスの変更

Distutils 設定ファイル

設定ファイルの場所と名前

設定ファイルの構文

拡張モジュールのビルド: 小技と豆知識

コンパイラ/リンカのフラグをいじるには

Windows で非 Microsoft コンパイラを使ってビルドするには

Borland/CodeGear C++

GNU C / Cygwin / MinGW

古いバージョンの Python と MinGW

日本語訳について

このドキュメントについて

翻訳者一覧 (敬称略)

Python のドキュメントの作成

1. 初めに

2. スタイルガイド

2.1. 肯定的な論調

2.2. 簡潔な表現

2.3. コード例

2.4. 等価なコード

2.5. 読者

3. reStructuredText の基礎

3.1. 段落 (Paragraphs)

3.2. インラインマークアップ (Inline markup)

3.3. リストとクォート (Lists and Quotes)

3.4. ソースコード (Source Code)

3.5. ハイパーリンク (Hyperlinks)

3.5.1. 外部リンク (External links)

3.5.2. 内部リンク (Internal links)

3.5.3. セクション

3.6. 明示的なマークアップ (Explicit Markup)

3.7. ディレクティブ (Directives)

3.8. 脚注 (Footnotes)

3.9. コメント (Comments)

3.10. ソースのエンコード (Source encoding)

3.11. 判っていること

4. 拡張マークアップ構成部 (Additional Markup Constructs)

4.1. メタ情報マークアップ (Meta-information markup)

4.2. モジュール用のマークアップ (Module-specific markup)

4.3. 情報単位 (Information units)

4.4. コードサンプルを表示する (Showing code examples)

4.5. インラインマークアップ (Inline markup)

4.6. クロスリンクのマークアップ (Cross-linking markup)

4.7. 段落レベルでのマークアップ (Paragraph-level markup)

4.8. Table-of-contents マークアップ (Table-of-contents markup)

4.9. インデックス生成マークアップ (Index-generating markup)

4.10. 文法導出表記 (Grammar production displays)

4.11. 置換 (Substitutions)

5. LaTeX マークアップとの違い

5.1. インラインマークアップ

5.2. 情報単位 (information units)

5.3. 構造 (Structure)

6. ドキュメントをビルドする

6.1. make を使う方法

6.2. make を使わない方法

7. このドキュメントについて

8. 翻訳者一覧 (敬称略)

Python HOWTO

Python の支援活動 HOWTO

Python を使う理由

書きやすさ

プロトタイプ

シンプルさと理解のしやすさ

Javaでの実装

議論と反論

有用な資料

3.0 への拡張モジュール移植

条件コンパイル

オブジェクト API の変更

str/unicode の統合

long/int の統合

モジュールの初期化と状態情報

ほかの選択肢

Python で Curses プログラミング

curses ってなに?

Python の curses module

curses アプリケーションの起動と終了

ウィンドウとパッド

テキストの表示

属性とカラー

ユーザ入力

より多くの情報

ディスクリプタ HowTo ガイド

概要

定義と導入

ディスクリプタプロトコル

ディスクリプタの呼び出し

ディスクリプタの例

プロパティ

関数とメソッド

静的メソッドとクラスメソッド

Python 良い慣用句、悪い慣用句

使うべきでない構文

from モジュール import *

関数定義の中で

モジュールレベルで

問題ない状況

そのまんまな exec, execfile() と仲間たち

from モジュール import 名前1, 名前2

except:

例外

使い捨てじゃなくて充電池を使う

バックスラッシュで文を続ける

関数型プログラミング HOWTO

はじめに

形式的証明可能性

モジュラー性

デバグやテストの簡単さ

結合性

イテレータ

イテレータ対応のデータ型

ジェネレータ式とリスト内包表記

ジェネレータ

ジェネレータに値を渡す

ビルトイン関数

小さな関数とラムダ式

itertools モジュール

新しいイテレータを作る

要素に対して関数を呼ぶ

要素を選択する

要素をグループ分けする

functools モジュール

operator モジュール

functional モジュール

更新履歴と謝辞

参照資料

一般論

Python 特有の話

Python 文書

ロギング HOWTO

基本ロギングチュートリアル

ロギングを使うべきとき

簡単な例

ファイルへのロギング

複数のモジュールからのロギング

変数データのロギング

表示されるメッセージのフォーマットの変更

メッセージ内での日付と時刻の表示

次のステップ

上級ロギングチュートリアル

ロガー

ハンドラ

フォーマッタ

ロギングの環境設定

環境設定が与えられないとどうなるか

ライブラリのためのロギングの設定

ロギングレベル

カスタムレベル

便利なハンドラ

ログ記録中に発生する例外

任意のオブジェクトをメッセージに使用する

最適化

ロギングクックブック

複数のモジュールでロギングを使う

複数のハンドラとフォーマッタ

複数の出力先にログを出力する

設定サーバの例

ネットワーク越しのロギングイベントの送信と受信

コンテキスト情報をログ記録出力に付加する

LoggerAdapter を使ったコンテキスト情報の伝達

Filter を使ったコンテキスト情報の伝達

複数のプロセスからの単一ファイルへのログ記録

ファイルの循環を使う

正規表現 HOWTO

入門

単純なパターン

文字のマッチング

繰り返し

正規表現を使う

正規表現をコンパイルする

バックスラッシュ感染症

マッチの実行

モジュールレベルの関数

コンパイルフラグ

パターンの能力をさらに

さらなる特殊文字

グルーピング

取り出さないグループと名前つきグループ

先読みアサーション (Lookahead Assertions)

文字列を変更する

文字列の分割

検索と置換

よくある問題

文字列メソッドを利用する

match() 対 search()

貪欲 (greedy) 対非貪欲 (non-greedy)

re.VERBOSE の利用

フィードバック

ソケットプログラミング HOWTO

ソケット

歴史

ソケットの作成

IPC

ソケットの利用

バイナリデータ

切断

ソケットが死ぬと

ノンブロッキングソケット

性能

ソート HOW TO

ソートの基本

Key 関数

operator モジュール関数

昇順と降順

ソートの安定性と複合的なソート

デコレート-ソート-アンデコレート を利用した古いやり方

cmp パラメータを利用した古い方法

残りいくつかとまとめ

Unicode HOWTO

Unicode 入門

文字コードの歴史

定義

エンコーディング

参考文献

Python 2.x の Unicode サポート

Unicode 型

Python ソースコード内の Unicode リテラル

Unicode プロパティ

参考文献

Unicode データを読み書きする

Unicode ファイル名

Unicode 対応のプログラムを書くための Tips

参考文献

更新履歴と謝辞

urllib2 を使ってインターネット上のリソースを取得するには

はじめに

URL を取得する

データ

ヘッダ

例外を処理する

URLError

HTTPError

エラーコード

エラーをラップする

その1

その2

info と geturl

Openers と Handlers

Basic 認証

プロキシ

ソケットとレイヤー

脚注

Python を Web 上で使うには HOWTO

低レベルから見て

Common Gateway Interface

CGI をテストするための単純なスクリプト

自身のサーバで CGI を立ち上げる

CGI スクリプトでの一般的な問題

mod_python

FastCGI と SCGI

FastCGI のセットアップ

mod_wsgi

後ろに下って: WSGI

WSGI サーバ

事例研究: MoinMoin

Model-view-controller

web サイトの構成要素

テンプレート

データの永続性

フレームワーク

いくつかの著名なフレームワーク

Django

TurboGears

他の著名なフレームワーク

このドキュメントについて

翻訳者一覧 (敬称略)

Python よくある質問

一般 Python FAQ

一般情報

現実世界での Python

Python のアップグレード

プログラミング FAQ

一般的な質問

コア言語

数と文字列

シーケンス(タプル/リスト)

辞書

オブジェクト

モジュール

デザインと歴史 FAQ

Python はなぜ文のグループ化にインデンテーションを使うのですか？

なぜ単純な算術演算が奇妙な結果になるのですか？

なぜ浮動小数点演算はこれほど不正確なのですか？

なぜ Python の文字列はイミュータブルなのですか？

なぜメソッドの定義や呼び出しにおいて ‘self’ を明示しなければならないのですか？

式中で代入ができないのはなぜですか？

Python にメソッドを使う機能 (list.index()等) と関数を使う機能 (list.index()等) があるのはなぜですか？

join() がリストやタプルのメソッドではなく文字列のメソッドなのはなぜですか？

例外はどれくらい速いのですか？

Python に switch や case 文がないのはなぜですか？

OS 特有のスレッド実装に依らずにインタプリタでスレッドをエミュレートすることはできないのですか？

ラムダ式が文を含めないのはなぜですか？

Python は C やその他の言語のように機械語にコンパイルできますか？

Python はメモリをどのように管理するのですか？

なぜ Python の終了時にすべてのメモリが開放されるわけではないのですか？

なぜタプルとリストという別のデータ型が用意されているのですか？

リストはどのように実装されているのですか？

辞書はどのように実装されているのですか？

なぜ辞書のキーはイミュータブルでなくてはならないのですか？

なぜ list.sort() はソートされたリストを返さないのですか？

Python ではどのようにインタフェース仕様を特定し適用するのですか？

なぜオブジェクト間でデフォルト値が共有されるのですか？

なぜ goto が無いのですか？

なぜ raw 文字列 (r-strings) はバックスラッシュで終わってはいけないのですか？

属性の代入に “with” 文が使えないのはなぜですか？

if/while/def/class 文にコロンが必要なのはなぜですか？

なぜ Python ではリストやタプルの最後にカンマがあっても良いのですか？

ライブラリと拡張 FAQ

ライブラリ一般の質問

よくある作業

スレッド

入力と出力

ネットワーク/インターネットプログラミング

データベース

数学と数

拡張と埋め込み FAQ

C で独自の関数を作ることはできますか？

C++ で独自の関数を作ることはできますか？

C を書くのは大変です。他の方法はありませんか？

C から任意の Python 文を実行するにはどうしますか？

C から任意の Python 式を評価するにはどうしますか？

Python オブジェクトから C の値を展開するにはどうしますか？

Py_BuildValue() で任意長のタプルを作るにはどうしますか？

C からオブジェクトのメソッドを呼び出すにはどうしますか？

PyErr_Print() (その他 stdout/stderr に印字するもの) からの出力を受け取るにはどうしますか？

C から Python で書かれたモジュールにアクセスするにはどうしますか？

Python から C++ へインタフェースするにはどうしますか？

セットアップファイルでモジュールを追加しようとしたらメイクに失敗しました。なぜですか？

拡張をデバッグするにはどうしますか？

Linux システムで Python モジュールをコンパイルしたいのですが、見つからないファイルがあります。なぜですか？

“SystemError: _PyImport_FixupExtension: module yourmodule not loaded” とはどういう意味ですか？

“不完全 (incomplete) な入力” を “不適切 (invalid) な入力” から区別するにはどうしますか？

未定義の g++ シンボル __builtin_new や __pure_virtual を見つけるにはどうしますか？

メソッドのいくつかは C で、その他は Python で実装されたオブジェクトクラスを (継承などで) 作ることはできますか？

モジュール X をインポートした時に “undefined symbol: PyUnicodeUCS2*” と言われるのはなぜですか？

Windows 上の Python FAQ

Python プログラムを Windows で動かすにはどうしますか？

Python スクリプトを実行可能にするにはどうしますか？

Python の起動に時間がかかることがあるのはなぜですか？

Windows 用の Freeze はどこにありますか？

*.pyd ファイルは DLL と同じですか？

Python を Windows アプリケーションに埋め込むにはどうしたらいいですか？

Python を CGI に使うにはどうしますか？

エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか？

ブロックすることなく押鍵を検出するにはどうしますか？

os.kill() を Windows で模倣するにはどうしますか？

os.path.isdir() が NT で共有されたディレクトリで失敗するのはなぜですか？

cgi.py (その他の CGI プログラミング) が NT や win95 で動かないことがあります！

os.popen() が NT 上の PythonWin で動かないのはなぜですか？

os.popen()/win32pipe.popen() が Win9x で動かないのはなぜですか？

PyRun_SimpleFile() は Windows 上ではクラッシュしますが、Unix 上ではしません。なぜですか？

Windows 95/98 上で _tkinter のインポートに失敗します。なぜですか？

ダウンロードされたドキュメントを Windows 上で展開するにはどうしますか？

cw3215mt.dll がありません(または cw3215.dll がありません)

インストーラからのCTL3D32 version に関する警告

グラフィックユーザインタフェース FAQ

Python のプラットフォーム非依存の GUI ツールキットには何がありますか？

Python のプラットフォーム固有の GUI ツールキットには何がありますか？

Tkinter の質問

“なぜ Python が私のコンピュータにインストールされているのですか？” FAQ

Python とは何ですか？

なぜ Python が私のマシンにインストールされているのですか？

Python を削除してもいいですか？

このドキュメントについて

翻訳者一覧 (敬称略)

用語集

このドキュメントについて

Pythonドキュメント 貢献者

問題を報告する

ドキュメントの問題

Python の課題管理システムを使う

Copyright

History and License

Python の歴史

Terms and conditions for accessing or otherwise using Python

Licenses and Acknowledgements for Incorporated Software

Mersenne Twister

Sockets

Floating point exception control

MD5 message digest algorithm

Asynchronous socket services

Cookie management

Profiling

Execution tracing

UUencode and UUdecode functions

XML Remote Procedure Calls

test_epoll

Select kqueue

strtod and dtoa

OpenSSL

expat

libffi

zlib

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

What’s New in Python (英語)

The “What’s New in Python” series of essays takes tours through the most important changes between major Python versions. They are a “must read” for anyone wishing to stay up-to-date after a new release.

What’s New in Python 2.7

Python 2.x の今後

Python 3.1 の機能

PEP 372: collections に順序付き辞書を追加

PEP 378: 1000区切りのための書式指定子

PEP 389: コマンドライン解析のための argparse モジュール

PEP 391: logging の辞書ベースの設定

PEP 3106: 辞書 View

PEP 3137: memoryview オブジェクト

その他の言語の変更

新しいモジュールと改良されたモジュール

ビルドと C API の変更

その他の変更と修正

Python 2.7 への移植

謝辞

What’s New in Python 2.6

Python 3.0

Changes to the Development Process

PEP 343: The ‘with’ statement

PEP 366: Explicit Relative Imports From a Main Module

PEP 370: Per-user site-packages Directory

PEP 371: The multiprocessing Package

PEP 3101: Advanced String Formatting

PEP 3105: print As a Function

PEP 3110: Exception-Handling Changes

PEP 3112: Byte Literals

PEP 3116: New I/O Library

PEP 3118: Revised Buffer Protocol

PEP 3119: Abstract Base Classes

PEP 3127: Integer Literal Support and Syntax

PEP 3129: Class Decorators

PEP 3141: A Type Hierarchy for Numbers

Other Language Changes

New and Improved Modules

Deprecations and Removals

Build and C API Changes

Porting to Python 2.6

Acknowledgements

What’s New in Python 2.5

PEP 308: Conditional Expressions

PEP 309: Partial Function Application

PEP 314: Metadata for Python Software Packages v1.1

PEP 328: Absolute and Relative Imports

PEP 338: Executing Modules as Scripts

PEP 341: Unified try/except/finally

PEP 342: New Generator Features

PEP 343: The ‘with’ statement

PEP 352: Exceptions as New-Style Classes

PEP 353: Using ssize_t as the index type

PEP 357: The ‘__index__’ method

Other Language Changes

New, Improved, and Removed Modules

Build and C API Changes

Porting to Python 2.5

Acknowledgements

What’s New in Python 2.4

PEP 218: Built-In Set Objects

PEP 237: Unifying Long Integers and Integers

PEP 289: Generator Expressions

PEP 292: Simpler String Substitutions

PEP 318: Decorators for Functions and Methods

PEP 322: Reverse Iteration

PEP 324: New subprocess Module

PEP 327: Decimal Data Type

PEP 328: Multi-line Imports

PEP 331: Locale-Independent Float/String Conversions

Other Language Changes

New, Improved, and Deprecated Modules

Build and C API Changes

Porting to Python 2.4

Acknowledgements

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

What’s New in Python (英語) »

What’s New in Python 2.7

Author: | A.M. Kuchling (amk at amk.ca)
Release: | 2.7ja1
Date: | 2011年 12月 26日

この文書は Python 2.7 の新機能について解説します。 Python 2.7 は 2010 年 7 月 3 日にリリースされました。

数値周りの扱いが、浮動小数点数でも Decimal クラスでもいろいろな点で改良されました、標準ライブラリにいくつかの有用な追加が行われました。 unittest モジュールが大幅に改良され、コマンドラインオプション解析の argpase モジュールが追加され、 collections モジュールに便利な OrderedDict と Counter が追加され、他にもたくさんの改良が行われています。

Python 2.7 は 2.x の最終リリースになることが予定されているので、私たちはこのリリースを長期にわたって良いものになるように努力してきました。 Python 3 への移植を助けるため、いくつかの新機能が Python 3.x から Python 2.7 に取り込まれています。

このドキュメントは新機能の完全な詳細を提供するのではなくて、簡易な概要を提供することを目的にしています。完全な詳細が知りたければ、 http://docs.python.org の Python 2.7 のドキュメントを参照してください。設計と実装の根拠を理解したい場合は、新機能に関する PEP を参照するか、 http://bugs.python.org に議論したい機能について登録してください。可能な限り、 “What’s New in Python” は各変更の bug や patch に対してリンクしています。

Python 2.x の今後

Python 2.7 は 2.x シリーズの最後のメジャーリリースになります。 Python のメンテナは今後は Python 3.x シリーズの開発に集中する予定です。

これは、 2.7 が長期間残り続け、 Python 3.x への対応がされないプロダクションサービスを動かし続けることを意味します。 2.7 が長期的に重要なリリースになるので、2つの結論があります:

これまでの 2.x バージョンに比べて長期間のメンテナンスが行われます。 Python 2.7 は 3.x への移行が行われている間はメンテナンスされ続けます。 Python 開発者はさらにそこから2年のバグフィックスリリースをする予定です。

開発者向けの警告を抑止するポリシーが取られました。 DeprecationWarning とそれを継承した警告は、指定されない限りは無視され、アプリケーションのユーザーがその警告を見ないですむようになりました。この変更は Python 3.2 ブランチにも適用されています。 (stdlib-sig で討議され、 issue 7319 [http://bugs.python.org/issue7319] になりました)

以前のリリースでは、 DeprecationWarning メッセージはデフォルトで有効になっており、 Python 開発者に、将来のバージョンの Python でそのコードのどこが動かなくなるかを明確に知らせていました。

しかし、 Python で開発されたアプリケーションの利用者であって開発には携わっていない人がどんどん増えてきました。 DeprecationWarning メッセージはそれらのユーザーには無関係で、彼らをアプリケーションが本当に正しく動いているのか不安にさせ、ユーザーの質問に応えるための開発者の負担も増やしていました。

DeprecationWarning メッセージの表示を有効にするには、 -Wdefault (短い形式: -Wd) スイッチか、 Python を実行する前に PYTHONWARNINGS 環境変数を "default" (か、 "d")に設定します。 Python コードから有効にする場合は warnings.simplefilter('default') とします。

Python 3.1 の機能

Python 2.6 は Python 3.0 から多くの機能を取り込み、 Python 2.7 は Python 3.1 の新しい機能のいくつかを取り込みました。 2.x シリーズは 3.x シリーズへの移行のためのツールを提供し続けています。

Python 2.7 に取り込まれた 3.1 の機能の不完全なリスト:

集合のリテラル文法 ({1,2,3} は mutable set になります)

辞書と集合の内包表記 ({i: i*2 for i in range(3)}).

1つの with 文で複数のコンテキストマネージャを扱えるように。

io ライブラリの新バージョン。パフォーマンスのためにC言語で描き直されています。

PEP 372: collections に順序付き辞書を追加 で解説されている順序付き辞書

PEP 378: 1000区切りのための書式指定子 で解説されている新しい "," フォーマット指定子

memoryview オブジェクト

importlib モジュールの小さいサブセット。 下に説明があります

float x の repr() が多くの場合に短くなりました。これは x に戻せることが保証される最小の10進文字列です。以前のバージョンの Python では、 float(repr(x)) が x になることだけが保証されていました。

float から文字列、文字列から float への変換が正しく丸められるようになりました。 round() 関数も正しく丸めるようになりました。

拡張モジュールが C API を提供するための、 PyCapsule 型

PyLong_AsLongAndOverflow() C API 関数

新しい Python3 モード Warning:

operator.isCallable() と operator.sequenceIncludes() は 3.x ではサポートされず、 warning になります。

-3 オプションは自動的に -Qwarn スイッチを有効にして、整数や長整数に対する古い形式の除算が警告を出すようになります。

PEP 372: collections に順序付き辞書を追加

通常の Python 辞書は、 key/value ペアを不定の順序でイテレートします。何年にもわたり、いろいろな人が key の挿入順を保存する辞書の別実装を書いてきました。その経験に基づき、 2.7 は collections モジュールに新しい OrderedDict クラスを追加しました。

OrderedDict API は通常の辞書と同じインタフェースを提供していますが、 key/value をイテレートするときに key が最初に挿入された順番になることが保証されています。

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

新しいエントリが既存のエントリを上書きした場合は、元の挿入順序が保持されます。

>>> d['second'] = 4
>>> d.items()
[('first', 1), ('second', 4), ('third', 3)]

エントリを削除して再挿入すると、順序は一番最後に移動します。

>>> del d['second']
>>> d['second'] = 5
>>> d.items()
[('first', 1), ('third', 3), ('second', 5)]

popitem() メソッドは、オプションの last 引数を持ち、でフォルトで True になっています。 last が True の場合、一番最近に追加された key が返され、削除されます。 False の場合、最も古い key が選ばれます。

>>> od = OrderedDict([(x,0) for x in range(20)])
>>> od.popitem()
(19, 0)
>>> od.popitem()
(18, 0)
>>> od.popitem(last=False)
(0, 0)
>>> od.popitem(last=False)
(1, 0)

2つの順序付き辞書を比較するときは、 key/value だけでなく、挿入順も比較されます。

>>> od1 = OrderedDict([('first', 1),
...                    ('second', 2),
...                    ('third', 3)])
>>> od2 = OrderedDict([('third', 3),
...                    ('first', 1),
...                    ('second', 2)])
>>> od1 == od2
False
>>> # Move 'third' key to the end
>>> del od2['third']; od2['third'] = 3
>>> od1 == od2
True

OrderedDict を通常の辞書と比較すると、挿入順は無視されて単に key/value だけが比較されます。

OrderedDict の実装はこうなっています。 key の2重リンクリストを管理し、新しい key が挿入されるときにリストに新しい key を追加します。2つ目の辞書が key を対応するリストノードにマップします。なので、削除時にリンクリストを操作する必要はなく、コストは O(1) に保たれています。

標準ライブラリのいくつかのモジュールで、順序付き辞書の利用がサポートされています。

ConfigParser モジュールはデフォルトで順序付き辞書を使います。設定ファイルを読み込み、編集した後、元の順序で書きなおすことができます。

collections.namedtuple() の _asdict() メソッドは、タプルの順序と同じ順序の順序付き辞書を返すようになりました。

json モジュールのデコーダーが OrderedDict をビルドするのをサポートするために、 JSONDecoder クラスのコンストラクタに object_pairs_hook 引数が追加されました。 PyYAML [http://pyyaml.org/] などの外部のライブラリでもサポートされています。

参考

PEP 372 [http://www.python.org/dev/peps/pep-0372] - Adding an ordered dictionary to collections

PEP written by Armin Ronacher and Raymond Hettinger; implemented by Raymond Hettinger.

PEP 378: 1000区切りのための書式指定子

大きい数値に区切り文字を追加して、 18446744073709551616 の代わりに 18,446,744,073,709,551,616 と出力すると、プログラムの出力を読みやすくできます。

これを行う一般的な方法は locale モジュールを使うことで、複数の区切り文字 (北米では ”,” で、ヨーロッパでは ”.”) を使ったり、複数のグループの大きさを使うことができます。しかし、 locale の利用方法は複雑ですし、スレッドごとに異なるロケールの出力を行うプログラムでは利用することができません。

そのため、シンプルなカンマによるグループ化機構が str.format() メソッドのミニ言語に追加されました。浮動小数点数をフォーマットする場合、シンプルにカンマを幅と精度の間に置きます。

>>> '{:20,.2f}'.format(18446744073709551616.0)
'18,446,744,073,709,551,616.00'

整数をフォーマットする場合は、幅の後にカンマを追加します。

>>> '{:20,d}'.format(18446744073709551616)
'18,446,744,073,709,551,616'

この機構は全く柔軟性を持っていません。区切り文字は常にカンマですし、グループは常に数字3つになります。カンマ書式機構は locale ほど汎用ではありませんが、手軽に使うことができます。

参考

PEP 378 [http://www.python.org/dev/peps/pep-0378] - Format Specifier for Thousands Separator

PEP written by Raymond Hettinger; implemented by Eric Smith.

PEP 389: コマンドライン解析のための argparse モジュール

コマンドライン引数の解析のための argparse モジュールが、 optparse モジュールのより協力な代替として追加されました。

これにより、 Python はコマンドライン引数の解析のために3つの異なるモジュール、 getopt, optparse, argparse を持つことになります。 getopt モジュールは C言語用ライブラリの getopt() 関数に似せてあるので、あとで C 言語で書き直すかもしれないプログラムのプロトタイプを Python で書く場合に役に立ちます。 optparse は冗長になってしまいましたが、まだたくさんのスクリプトが利用していて、それらのスクリプトを自動的に更新する手段が無いので、削除される予定はありません。 (argparse API を optparse のインタフェースに適合させる方法も検討されましたが、多くの複雑さと難点のために却下されました)

古いバージョンの Python との互換性を気にすること無く新しいスクリプトを書く時は、 optparse の代わりに argparse を使ってください。

例:

import argparse

parser = argparse.ArgumentParser(description='Command-line example.')

# Add optional switches
parser.add_argument('-v', action='store_true', dest='is_verbose',
                    help='produce verbose output')
parser.add_argument('-o', action='store', dest='output',
                    metavar='FILE',
                    help='direct output to FILE instead of stdout')
parser.add_argument('-C', action='store', type=int, dest='context',
                    metavar='NUM', default=0,
                    help='display NUM lines of added context')

# Allow any number of additional arguments.
parser.add_argument(nargs='*', action='store', dest='inputs',
                    help='input filenames (default is stdin)')

args = parser.parse_args()
print args.__dict__

オーバーライドしない限り、 -h と --help スイッチが自動的に追加され、綺麗にフォーマットした出力を生成します。

-> ./python.exe argparse-example.py --help
usage: argparse-example.py [-h] [-v] [-o FILE] [-C NUM] [inputs [inputs ...]]

Command-line example.

positional arguments:
  inputs      input filenames (default is stdin)

optional arguments:
  -h, --help  show this help message and exit
  -v          produce verbose output
  -o FILE     direct output to FILE instead of stdout
  -C NUM      display NUM lines of added context

optparse と同じく、コマンドラインスイッチと引数は、 dest 引数の名前の属性をもったオブジェクトとして返されます。

-> ./python.exe argparse-example.py -v
{'output': None,
 'is_verbose': True,
 'context': 0,
 'inputs': []}

-> ./python.exe argparse-example.py -v -o /tmp/output -C 4 file1 file2
{'output': '/tmp/output',
 'is_verbose': True,
 'context': 4,
 'inputs': ['file1', 'file2']}

argparse は optparse よりも多くの便利なバリデーションを持っています。引数の正確な数を整数で指定したり、 '*' で0以上の数を指定したり、 '+' で1以上の数を指定したり、 '?' でオプションにしたりできます。トップレベルのパーサーはサブパーサーを持つことができ、 svn commit, svn update のように異なるオプションを持ったサブコマンドを定義できます。引数のタイプに FileType を指定することで、自動でファイルを開き、 '-' が指定されたときに標準入出力だと判断することができます。

参考

argparse のドキュメント

argparse モジュールのドキュメント

optparse からのアップグレード

optparse を使うコードを変換する方法を説明した Python のドキュメントの一部

PEP 389 [http://www.python.org/dev/peps/pep-0389] - argparse - New Command Line Parsing Module

PEP written and implemented by Steven Bethard.

PEP 391: logging の辞書ベースの設定

logging モジュールは非常に柔軟です。アプリケーションは logging のサブシステムのツリーを定義できます。このツリーの各ロガーはいくつかのメッセージをフィルターし、異なるフォーマットを行い、メッセージを沢山の種類のハンドラーに渡します。

この柔軟性は、多くの設定を必要とします。オブジェクトを生成してプロパティを設定する Python コードを書くこともできますが、複雑なセットアップをしようとすると退屈なコードを書かないといけなくなります。 logging は設定ファイルのパースを行う fileConfig() 関数を提供していますが、このファイルフォーマットはフィルターの設定をサポートしていませんし、プログラムで生成するのはさらに面倒になります。

Python 2.7 は logging の設定のために辞書を使う dictConfig() 関数を追加しました。いろいろな入力から辞書を作成する方法があります。コードで作ったり、 JSON ファイルをパースしたり、YAMLのパーサーをインストールしてあればそれを使うことができます。詳しい情報は 環境設定のための関数 を参照してください。

次の例は2つのロガー、 root logger と “network” という名前の logger root logger に送られたメッセージは syslog プロトコルを利用してシステムに送られ、 “network” logger に送られたメッセージは1MBごとにローテートされる network.log ファイルに書きこまれます。

import logging
import logging.config

configdict = {
 'version': 1,    # Configuration schema in use; must be 1 for now
 'formatters': {
     'standard': {
         'format': ('%(asctime)s %(name)-15s '
                    '%(levelname)-8s %(message)s')}},

 'handlers': {'netlog': {'backupCount': 10,
                     'class': 'logging.handlers.RotatingFileHandler',
                     'filename': '/logs/network.log',
                     'formatter': 'standard',
                     'level': 'INFO',
                     'maxBytes': 1000000},
              'syslog': {'class': 'logging.handlers.SysLogHandler',
                         'formatter': 'standard',
                         'level': 'ERROR'}},

 # Specify all the subordinate loggers
 'loggers': {
             'network': {
                         'handlers': ['netlog']
             }
 },
 # Specify properties of the root logger
 'root': {
          'handlers': ['syslog']
 },
}

# Set up configuration
logging.config.dictConfig(configdict)

# As an example, log two error messages
logger = logging.getLogger('/')
logger.error('Database not found')

netlogger = logging.getLogger('network')
netlogger.error('Connection failed')

他にも、 logging モジュールには Vinary Sajip によって実装された 3 つの改良があります。

SysLogHandler クラスは TCP 経由の syslog をサポートします。コンストラクタの socktype 引数は使用するソケットの種類として、 UDP を使う socket.SOCK_DGRAM と TCP を使う socket.SOCK_STREAM のどちらかを取ります。デフォルトはUDPのままです。

Logger インスタンスに getChild() メソッドが追加されました。これは、相対パスで下位の logger を返します。例えば、 log = getLogger('app') として logger を取得した後、 log.getChild('network.listen') は getLogger('app.network.listen') と同じになります。

LoggerAdapter クラスに isEnabledFor() メソッドが追加されました。 level を引数に取り、ベースの logger がその重要度レベルのメッセージを処理するかどうかを返します。

参考

PEP 391 [http://www.python.org/dev/peps/pep-0391] - Dictionary-Based Configuration For Logging

PEP written and implemented by Vinay Sajip.

PEP 3106: 辞書 View

辞書の keys(), values(), items() メソッドは Python 3.x では動作が代わり、完全に実体化されたリストの代わりに、 view と呼ばれるオブジェクトを返すようになりました。

Python 2.7 では、 keys(), values(), items() の動作を変えてしまうと、既存の大量のコードが動かなくなってしまうので、 Python 3.x と同じ動作に合わせることはできません。なので、 Python 3.x のメソッドと同じ動作をするメソッドを、別の viewkeys(), viewvalues(), viewitems() という名前で追加しました。

>>> d = dict((i*10, chr(65+i)) for i in range(26))
>>> d
{0: 'A', 130: 'N', 10: 'B', 140: 'O', 20: ..., 250: 'Z'}
>>> d.viewkeys()
dict_keys([0, 130, 10, 140, 20, 150, 30, ..., 250])

View はイテレートするだけでなく、 set と似た利用をすることもできます。 & 演算子で共通部分集合を、 | 演算子で話集合を取ることができます。

>>> d1 = dict((i*10, chr(65+i)) for i in range(26))
>>> d2 = dict((i**.5, i) for i in range(1000))
>>> d1.viewkeys() & d2.viewkeys()
set([0.0, 10.0, 20.0, 30.0])
>>> d1.viewkeys() | range(0, 30)
set([0, 1, 130, 3, 4, 5, 6, ..., 120, 250])

view は辞書とその辞書の変化に追随しています。

>>> vk = d.viewkeys()
>>> vk
dict_keys([0, 130, 10, ..., 250])
>>> d[260] = '&'
>>> vk
dict_keys([0, 130, 260, 10, ..., 250])

ただし、 view をイテレートしている間に key の追加や削除ができないことに気を付けてください。

>>> for k in vk:
...     d[k*2] = k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

Python 2.x で view メソッドを利用すると、 2to3 が自動的にそれを通常の keys(), values(), items() メソッドに書き換えてくれます。

参考

PEP 3106 [http://www.python.org/dev/peps/pep-3106] - Revamping dict.keys(), .values() and .items()

PEP written by Guido van Rossum. Backported to 2.7 by Alexandre Vassalotti; issue 1967 [http://bugs.python.org/issue1967].

PEP 3137: memoryview オブジェクト

memoryview オブジェクトは、他のオブジェクトのメモリの内容に対する bytes 型のインタフェースに合わせた view を提供します。

>>> import string
>>> m = memoryview(string.letters)
>>> m
<memory at 0x37f850>
>>> len(m)           # Returns length of underlying object
52
>>> m[0], m[25], m[26]   # Indexing returns one byte
('a', 'z', 'A')
>>> m2 = m[0:26]         # Slicing returns another memoryview
>>> m2
<memory at 0x37f080>

view の内容は bytes 型の文字列か整数のリストに変換することができます。

>>> m2.tobytes()
'abcdefghijklmnopqrstuvwxyz'
>>> m2.tolist()
[97, 98, 99, 100, 101, 102, 103, ... 121, 122]
>>>

memoryview オブジェクトは、対象となる背後のオブジェクトが変更可能 (mutable) な場合は、その変更を許可しています。

>>> m2[0] = 75
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot modify read-only memory
>>> b = bytearray(string.letters)  # Creating a mutable object
>>> b
bytearray(b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
>>> mb = memoryview(b)
>>> mb[0] = '*'         # Assign to view, changing the bytearray.
>>> b[0:5]              # The bytearray has been changed.
bytearray(b'*bcde')
>>>

参考

PEP 3137 [http://www.python.org/dev/peps/pep-3137] - Immutable Bytes and Mutable Buffer

PEP written by Guido van Rossum. Implemented by Travis Oliphant, Antoine Pitrou and others. Backported to 2.7 by Antoine Pitrou; issue 2396 [http://bugs.python.org/issue2396].

その他の言語の変更

Python 言語コアにいくつかの小さな変更が加えられました。

set リテラルのためのシンタックスが Python 3.x からバックポートされました。内容を波括弧で囲うと mutable set になります。 dict リテラルとの区別は、コロンと value が存在しないことで行われます。なので、 {} は引き続き空の dict になります。空の set を作るときには set() を使ってください。

>>> {1, 2, 3, 4, 5}
set([1, 2, 3, 4, 5])
>>> set() # empty set
set([])
>>> {}    # empty dict
{}

Backported by Alexandre Vassalotti; issue 2335 [http://bugs.python.org/issue2335].

dict と set の内包表記も Python 3.x からバックポートされました。 list と generator の内包表記を set と dict にも使えるように一般化させています。

>>> {x: x*x for x in range(6)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
>>> {('a'*x) for x in range(6)}
set(['', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa'])

with 文が1つの文で複数のコンテキストマネージャーを使えるようになりました。コンテキストマネージャーは左から右へ処理され、それぞれが新しい with 文の開始となるように扱われます。つまり:

with A() as a, B() as b:
    ... suite of statements ...

このコードは、次のコードと等しくなります:

with A() as a:
    with B() as b:
        ... suite of statements ...

contextlib.nested() 関数は非常に似た機能を提供していたので、もう必要なくなり廃止予定となりました。

(Proposed in http://codereview.appspot.com/53094; implemented by Georg Brandl.)

浮動小数点数と文字列の間の変換がほとんどのプラットフォームで正しく丸められるようになりました。この変換はいろいろな場面で発生します: float 型や complex 型に対する str() 関数の適用、数値フォーマット、 marshal, pickle, json モジュールを使ってのシリアライズとデシリアライズ、 Python コード中の float や imaginary リテラルの解析、 Decimal から float への変換などです。

これに関連して、 浮動小数点数 x の repr() は、 (round-half-to-even 丸めモードで)正しく丸め処理をした場合に元の x に戻せる最小の 10進文字列になりました。以前は x を17桁の10進文字列に丸めていました。

丸めライブラリが、この改善が Windows や gcc, icc, suncc を使った Unix 環境で動かす役目をおっています。このライブラリの正確な動作が保証できない少しの環境があるので、そういったシステムではこのライブラリは利用されません。 sys.float_repr_style が short なら新しいコードが利用されていて、 legacy なら利用されていません。

Implemented by Eric Smith and Mark Dickinson, using David Gay’s dtoa.c library; issue 7117 [http://bugs.python.org/issue7117].

多倍長整数や通常の整数から浮動小数点への変換でも丸め処理が変更され、元の数に一番近い浮動小数点値が返されるようになりました。これは浮動小数点へ完全に変換できる小さい整数では問題になりませんが、桁数に対して精度がどうしても足りない場合に関係します。 Python 2.7 はより正確に近似するようになりました。例えば、 Python 2.6 では次のように計算されていました:

>>> n = 295147905179352891391
>>> float(n)
2.9514790517935283e+20
>>> n - long(float(n))
65535L

Python 2.7 の浮動小数点への変換結果は元の数値より大きくなりますが、元の値により近くなっています:

>>> n = 295147905179352891391
>>> float(n)
2.9514790517935289e+20
>>> n - long(float(n))
-1L

(Implemented by Mark Dickinson; issue 3166 [http://bugs.python.org/issue3166].)

この丸めの動作により、整数同士の true division (from __future__ import division) の結果もより正確になりました。 (Also implemented by Mark Dickinson; issue 1811 [http://bugs.python.org/issue1811].)

複素数に対する暗黙の型強制は削除されました。インタプリタは complex オブジェクトに対して __coerce__() メソッドを呼び出そうとしません。 (Removed by Meador Inge and Mark Dickinson; issue 5211 [http://bugs.python.org/issue5211].)

str.format() メソッドは置換フィールドに対する自動ナンバリングをサポートするようになりました。これにより str.format() をより %s と同じように使えるようになりました。

>>> '{}:{}:{}'.format(2009, 04, 'Sunday')
'2009:4:Sunday'
>>> '{}:{}:{day}'.format(2009, 4, day='Sunday')
'2009:4:Sunday'

自動ナンバリングは左のフィールドから右のフィールドへと行われるので、最初の {...} 指定は str.format() メソッドの最初の引数を利用し、次の指定は次の引数を利用します。自動ナンバリングと明示的なナンバリングを混ぜて使うことはできず、全ての置換指定に手動でナンバリングするか、全てを自動ナンバリングに任せなければなりません。ただし、上の例の2つめのように、自動ナンバリングと名前フィールドを混ぜて使うことは可能です。 (Contributed by Eric Smith; issue 5237 [http://bugs.python.org/issue5237].)

複素数が format() をサポートするようになりました。デフォルトでは右寄せになります。精度やカンマ区切りの指定は、実部と虚部のそれぞれに対して適用されます。アラインの指定は 1.5+3j のような複素数全体に対して適用されます。 (Contributed by Eric Smith; issue 1588 [http://bugs.python.org/issue1588] and issue 7988 [http://bugs.python.org/issue7988].)

‘F’ 書式符号は常に大文字を使って出力するようになり、 ‘INF’ や ‘NAN’ が出力されるようになりました。 (Contributed by Eric Smith; issue 3382 [http://bugs.python.org/issue3382].)

低レベルな変更: object.__format__() メソッドは PendingDeprecationWarning を発生させるようになりました。 object に対する __format__() メソッドはオブジェクトを文字列表現に変換してそれをフォーマットするからです。以前は、このメソッドは書式文字列を受け取り文字列表現を返していましたが、この仕様は Python コードのミスを隠してしまう可能性がありました。アライメントや精度のようなフォーマット指定情報を渡した時、そのなにかそのオブジェクトに合ったフォーマットがあることを期待しているはずなのに、 object.__format__() メソッドはそれを無視します。 (Fixed by Eric Smith; issue 7994 [http://bugs.python.org/issue7994].)

int() と long() 型に bit_length メソッドが追加されました。このメソッドはその値を2進数で表現したときに何ビット必要になるかを返します:

>>> n = 37
>>> bin(n)
'0b100101'
>>> n.bit_length()
6
>>> n = 2**123-1
>>> n.bit_length()
123
>>> (n+1).bit_length()
124

(Contributed by Fredrik Johansson and Victor Stinner; issue 3439 [http://bugs.python.org/issue3439].)

import 文が、絶対インポート (例: from .os import sep) が失敗したときに相対インポートを試さなくなりました。これはバグ修正ですが、いままでたまたま動いていただけの import 文を動かなくしてしまう可能性があります。(Fixed by Meador Inge; issue 7902 [http://bugs.python.org/issue7902].)

ビルトインの unicode 型のサブクラスが __unicode__() メソッドをオーバーライドできるようになりました。(Implemented by Victor Stinner; issue 1583863 [http://bugs.python.org/issue1583863].)

bytearray 型の translate() メソッドが第一引数に None を受け入れるようになりました。 (Fixed by Georg Brandl; issue 4759 [http://bugs.python.org/issue4759].)

@classmethod や @staticmethod を使ってクラスメソッドやスタティックメソッドを作成した時、そのラッパーオブジェクトがラップ対象となる関数を __func__ 属性で公開するようになりました。(Contributed by Amaury Forgeot d’Arc, after a suggestion by George Sakkis; issue 5982 [http://bugs.python.org/issue5982].)

__slots__ を利用して属性を制限した場合に、設定されていない属性を del したときに AttributeError にならなかったのを修正しました。 (Fixed by Benjamin Peterson; issue 7604 [http://bugs.python.org/issue7604].)

2つの新しいエンコーディングが追加されました: “cp720” は主にアラビア文字に使われます。 “cp858” は cp850 の一種ですが、ユーロ記号を追加しています。 (CP720 contributed by Alexander Belchenko and Amaury Forgeot d’Arc in issue 1616979 [http://bugs.python.org/issue1616979]; CP858 contributed by Tim Hatch in issue 8016 [http://bugs.python.org/issue8016].)

file オブジェクトは、POSIX環境に置いてディレクトリを開こうとした時に発生する IOError 例外に filename 属性を設定するようになりました。 (noted by Jan Kaliszewski; issue 4764 [http://bugs.python.org/issue4764]) また、読み取りのみのファイルに対する書き込みを、Cライブラリ側のエラー検出・報告に頼るのではなく、明示的にチェックするようになりました。 (fixed by Stefan Krah; issue 5677 [http://bugs.python.org/issue5677]).

Python の字句解析機は改行をそれ自身に変換するようになりました。それにより、組み込みの compile() 関数がどの改行コードを利用したコードでも受け付けるようになりました。また、コードの終端の改行も不要になりました。

関数宣言中の余分な丸括弧は Python 3.x では不正になりました。つまり、 def f((x)): pass はsyntax errorになります。 Python3 警告モードでは、 Python 2.7 はこの利用方法について警告を出すようになりました。 (Noted by James Lingard; issue 7362 [http://bugs.python.org/issue7362].)

古いスタイルのクラスのオブジェクトに対して弱参照を作れるようになりました。新スタイルクラスには以前から弱参照を利用できます。(Fixed by Antoine Pitrou; issue 8268 [http://bugs.python.org/issue8268].)

モジュールオブジェクトがGCされたとき、モジュールの辞書は、他にその辞書への参照を持っているものがない場合にのみクリアされるようになりました。(issue 7140 [http://bugs.python.org/issue7140]).

インタプリタの変更

新しい環境変数 PYTHONWARNINGS を使って警告を制御できるようになりました。この環境変数には、 -W スイッチに使われる警告の設定を、カンマ区切りの文字列として指定します。 (Contributed by Brian Curtin; issue 7301 [http://bugs.python.org/issue7301].)

例えば、以下の設定は警告が発生するたびにそれを表示しますが、 Cookie モジュールからの警告はエラーにします。 (環境変数を設定するための文法はOSとシェルに依存します)

export PYTHONWARNINGS=all,error:::Cookie:0

最適化

いくつかの場面でパフォーマンスが向上しています。

with 文の初期セットアップを行うための新しいオペコードが追加されました。 __enter__() と __exit__() メソッドの検索を行います。 (Contributed by Benjamin Peterson.)

たくさんのオブジェクトを開放せずに確保していくという、よくある使い方の 1つにおいて、GCのパフォーマンスが向上しました。以前はこの場合にGCにかかる時間はオブジェクトの数の2乗に比例していました。現在はフルGCの数は増えたヒープ上のオブジェクトの数に比例しています。新しい方式では、3世代中2世代目に対するGCが10回実行されたうえで、 2世代目から3世代目に移ったオブジェクトの数が3世代目のオブジェクトの数の 10%を超えたときにフルGCが発生します。(Suggested by Martin von Löwis and implemented by Antoine Pitrou; issue 4074 [http://bugs.python.org/issue4074].)

GCが循環参照になりえないシンプルなコンテナ型の追跡を避けるようになりました。 Python 2.7 では、アトミックな型(整数、文字列など)のみを含むタプルと辞書は追跡されません。推移的に、アトミックな型のみを含むタプルを含む辞書も、同じく追跡されません。これにより、GCによって巡回されチェックされるオブジェクトの数が減るので、 GCのコストを減らすことができます。 (Contributed by Antoine Pitrou; issue 4688 [http://bugs.python.org/issue4688].)

多倍長整数の内部格納方式が、 2**15 ベースと 2**30 ベースのどちらかをビルド時に選択するようになりました。以前は常に 2**15 ベースで格納していました。 2**30 ベースにすると 64bit マシンに置いては確実にパフォーマンスが向上しますが、 32bit マシンではパフォーマンスが向上する場合も低下する場合もあります。なので、デフォルトでは 64bit マシンでは 2**30 ベースで、 32bit マシンでは 2**15 ベースになるようになります。 Unix では新しい configure オプションとして --enable-big-digis が追加され、このデフォルトの選択をオーバーライドできるようになっています。

この変更はパフォーマンスの向上以外の形ではユーザーに見えないはずですが、 1つだけ例外があります。テストとデバッグを目的として、 sys.long_info というデータが追加され、内部フォーマットとして digit あたりのビット数と、それに使うCのデータ型のバイト数の情報を提供します:

>>> import sys
>>> sys.long_info
sys.long_info(bits_per_digit=30, sizeof_digit=4)

(Contributed by Mark Dickinson; issue 4258 [http://bugs.python.org/issue4258].)

その他の変更により、多倍長整数オブジェクトのサイズは数バイト小さくなりました。 32bit システムでは 2byte, 64bit システムでは 6byte 小さくなりました。 (Contributed by Mark Dickinson; issue 5260 [http://bugs.python.org/issue5260].)

多倍長整数の除算アルゴリズムが、内部のループの軽量化や乗算からシフト演算への置き換え、不要なイテレーションの削除により高速化されました。いくつかのベンチマークによると、多倍長整数の剰余演算は 50% から 150% 高速化されています。 (Contributed by Mark Dickinson; issue 5512 [http://bugs.python.org/issue5512].) ビット演算も高速化されています。(initial patch by Gregory Smith; issue 1087418 [http://bugs.python.org/issue1087418])

% の実装が、左側のオペランドが文字列型かどうかをチェックしてその場合の処理を特殊化しました。これにより文字列に対して % を頻繁に使う、テンプレートライブラリなどのアプリケーションのパフォーマンスが1-3%向上します。 (Implemented by Collin Winter; issue 5176 [http://bugs.python.org/issue5176].)

if 条件付きのリスト内包表記がより高速なバイトコードにコンパイルされるようになりました。(Patch by Antoine Pitrou, back-ported to 2.7 by Jeffrey Yasskin; issue 4715 [http://bugs.python.org/issue4715].)

整数や多倍長整数から10進文字列への変換を、任意の基数をサポートした汎用の変換関数を使う代わりに10進数に特殊化した処理を行うことで高速化しました。 (Patch by Gawain Bolton; issue 6713 [http://bugs.python.org/issue6713].)

文字列等(str, unicode, bytearray) の split(), replace(), rindex(), rpartition(), rsplit() メソッドが、1文字ずつのスキャンの代わりに高速な逆方向スキャンアルゴリズムを使うようになりました。これにより、場合によっては10倍レベルの高速化になります。(Added by Florent Xicluna; issue 7462 [http://bugs.python.org/issue7462] and issue 7622 [http://bugs.python.org/issue7622].)

pickle と cPickle モジュールが、属性名に使われている文字列を自動的にインターンするようになりました。これにより unpickle 後のオブジェクトのメモリ使用量が減ります。(Contributed by Jake McGuire; issue 5084 [http://bugs.python.org/issue5084].)

cPickle モジュールが辞書に対する特殊化を行い、 pickle にかかる時間をおよそ半分に減らしました。 (Contributed by Collin Winter; issue 5670 [http://bugs.python.org/issue5670].)

新しいモジュールと改良されたモジュール

全てのリリースに置いて、 Python の標準ライブラリはたくさんの改良とバグ修正がされてきました。ここでは一部の注目に値する変更を、モジュール名で辞書順ソートしてリストアップしています。可燃な変更が見たければ、ソースツリー内の Misc/NEWS ファイルか、全ての完全な詳細が入っている Subversion のログを参照してください。

bdb モジュールの基底デバッガクラス Bdb に、モジュールをスキップする機能が追加されました。コンストラクタは django.* のような glob スタイルのパターンをもった iterable を引数として受け取ります。デバッガはパターンのどれかにマッチするスタックフレームにステップインしません。 (Contributed by Maru Newby after a suggestion by Senthil Kumaran; issue 5142 [http://bugs.python.org/issue5142].)

binascii モジュールが buffer API をサポートするようになり、 memoryview インスタンスやその他のバッファオブジェクトともに利用できるようになりました。 (Backported from 3.x by Florent Xicluna; issue 7703 [http://bugs.python.org/issue7703].)

bsddb モジュールが the pybsddb package [http://www.jcea.es/programacion/pybsddb.htm] の 4.7.2devel9 から 4.8.4 に更新されました。新しいバージョンはより Python 3.x との互換性がよくなり、いくつかのバグ修正と、いくつかの新しい BerkeleyDB のフラグとメソッドが追加されています。 (Updated by Jesús Cea Avión; issue 8156 [http://bugs.python.org/issue8156]. The pybsddb changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.)

bz2 モジュールの BZ2File がコンテキストマネージャープロトコルをサポートするようになりました。これにより、 with bz2.BZ2File(...) as f: といった書き方ができます。 (Contributed by Hagen Fürstenau; issue 3860 [http://bugs.python.org/issue3860].)

collections モジュールの新しい Counter クラスは、データの数え上げをするときに便利です。 Counter インスタンスは辞書のように振る舞いますが、キーが存在しなかったときに KeyError 例外を発生させる代わりに 0 を返します。

>>> from collections import Counter
>>> c = Counter()
>>> for letter in 'here is a sample of english text':
...   c[letter] += 1
...
>>> c
Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2,
'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1,
'p': 1, 'r': 1, 'x': 1})
>>> c['e']
5
>>> c['z']
0

ConfigParser モジュールのパーサークラスのコンストラクタが allow_no_value 引数を受け取るようになりました。これはデフォルトでは False です。真の場合、値のないオプションが利用できるようになります。例えば:

>>> import ConfigParser, StringIO
>>> sample_config = """
... [mysqld]
... user = mysql
... pid-file = /var/run/mysqld/mysqld.pid
... skip-bdb
... """
>>> config = ConfigParser.RawConfigParser(allow_no_value=True)
>>> config.readfp(StringIO.StringIO(sample_config))
>>> config.get('mysqld', 'user')
'mysql'
>>> print config.get('mysqld', 'skip-bdb')
None
>>> print config.get('mysqld', 'unknown')
Traceback (most recent call last):
  ...
NoOptionError: No option 'unknown' in section: 'mysqld'

(Contributed by Mats Kindahl; issue 7005 [http://bugs.python.org/issue7005].)

contextlib.nested() 関数が廃止予定になりました。これは1つの with 文で1つ以上のコンテキストマネージャーを扱うためのものでしたが、 with 文が複数のコンテキストマネージャーをサポートするようになりました。

cookielib モジュールが不正な、値が整数値ではないバージョンフィールドを持つ cookie を無視するようになりました。(Fixed by John J. Lee; issue 3924 [http://bugs.python.org/issue3924].)

copy モジュールの deepcopy() 関数が、束縛ずみインスタンスメソッドを正しくコピーするようになりました。(Implemented by Robert Collins; issue 1515 [http://bugs.python.org/issue1515].)

ctypes モジュールが、ポインタとして宣言された引数に対して None が渡された場合常に C の NULL ポインタに変換するようになりました。(Changed by Thomas Heller; issue 4606 [http://bugs.python.org/issue4606].) 基盤となっている libffi ライブラリ [http://sourceware.org/libffi/] が 3.0.9 にアップデートされ、いくつかのプラットフォームにおけるいろいろな問題が修正されました。(Updated by Matthias Klose; issue 8142 [http://bugs.python.org/issue8142].)

新しいメソッド: datetime モジュールの timedelta クラスに total_seconds() メソッドが追加されました。これはその期間の秒数を返します。(Contributed by Brian Quinlan; issue 5788 [http://bugs.python.org/issue5788].)

新しいメソッド: Decimal クラスに、浮動小数点数から Decimal への正確な変換を行う from_float() クラスメソッドが追加されました。この正確な変換は、浮動小数点数が示す値に一番近い近似となる10進数を求めます。なので、このメソッドを使ったとしてもある程度の誤差は残ります。例えば、 Decimal.from_float(0.1) は Decimal('0.1000000000000000055511151231257827021181583404541015625') を返します。 (Implemented by Raymond Hettinger; issue 4796 [http://bugs.python.org/issue4796].)

Decimal のインスタンスと浮動小数点数の比較は、オペランドの値に応じた賢い結果を返すようになりました。以前はこの比較は Python のデフォルトのオブジェクト比較にフォールバックし、オペランドの型に応じて不定な結果が返されていました。ただし、 Decimal と浮動小数点数を加算などの他の演算で組み合わせることはいまでも許可されていません。浮動小数点数と Decimal の間の変換方法を明示的に指定するべきです。(Fixed by Mark Dickinson; issue 2531 [http://bugs.python.org/issue2531].)

Decimal のコンストラクタが浮動小数点数を受け入れるようになりました。 (added by Raymond Hettinger; issue 8257 [http://bugs.python.org/issue8257]) また、アラビア・インド数字などの、ヨーロッパ以外の Unicode 文字も受け入れるようになりました。 (contributed by Mark Dickinson; issue 6595 [http://bugs.python.org/issue6595]).

Context クラスのほとんどのメソッドが Decimal インスタンスと同じく整数を受け入れるようになりました。例外は caonical() と is_canonical() メソッドだけです。 (Patch by Juan José Conti; issue 7633 [http://bugs.python.org/issue7633].)

Decimal インスタンスを文字列の format() メソッドで利用した場合、デフォルトのアライメントが左揃えから、数値型に適した右揃えに変更されました。 (Changed by Mark Dickinson; issue 6857 [http://bugs.python.org/issue6857].)

signaling NaN (あるいは sNAN) との比較は、暗黙に比較演算に応じて真偽値を返すのではなく、 InvalidOperation 例外を発生させるようになりました。 Quiet NaN (あるいは NAN) はハッシュ可能になりました。 (Fixed by Mark Dickinson; issue 7279 [http://bugs.python.org/issue7279].)

difflib モジュールの出力が、ファイル名を含むヘッダのセパレータにスペースではなくタブ文字を使うようになり、最近の diff/patch ツールとの互換性が高くなりました。(Fixed by Anatoly Techtonik; issue 7585 [http://bugs.python.org/issue7585].)

Distutils sdist コマンドが、 MANIFEST.in や setup.py ファイルが変更されていなくても、ユーザーが作成したかもしれない新しいファイルが含まれるようにするために、毎回 MANIFEST ファイルを再生成するようになりました。 (Fixed by Tarek Ziadé; issue 8688 [http://bugs.python.org/issue8688].)

doctest モジュールの IGNORE_EXCEPTION_DETAIL フラグが、テストされている例外を含むモジュールの名前を無視するようになりました。 (Patch by Lennart Regebro; issue 7490 [http://bugs.python.org/issue7490].)

email モジュールの Message クラスが Uniode値のペイロードを受け入れるようになり、自動的に output_charset で指定されたエンコーディングに変換するようになりました。 (Added by R. David Murray; issue 1368247 [http://bugs.python.org/issue1368247].)

Fraction クラスが、コンストラクタの引数として、 1つの float 値、 Decimal インスタンス、 2つの有理数を受け入れるようになりました。(Implemented by Mark Dickinson; rationals added in issue 5812 [http://bugs.python.org/issue5812], and float/decimal in issue 8294 [http://bugs.python.org/issue8294].)

fraction と complex 数の間の順序比較演算 (<, <=, >, >=) が TypeError 例外を発生させるようになりました。これは過失を修正し、 Fraction を他の数値型とマッチさせます。

新しいクラス: FTP_TLS が ftplib に追加されました。認証とその後の制御・データ転送をTLSカプセル化することでセキュアなFTP接続を提供します。 (Contributed by Giampaolo Rodola; issue 2054 [http://bugs.python.org/issue2054].)

バイナリデータのアップロードを行う storbinary() に rest 引数が追加され、アップロードのリスタートができるようになりました。 (patch by Pablo Mouzo; issue 6845 [http://bugs.python.org/issue6845].)

新しいクラスデコレータ: functools モジュールに total_ordering() が追加されました。 __eq__() と、 __lt__(), __le__(), __gt__(), __ge__() のいづれか1つを定義したクラスを受け取り、残りの比較メソッドを生成します。 __cmp__() メソッドが Python 3.x では廃止されたので、順序のあるクラスを定義するのを簡単にするためにこのデコレータがあります。 (Added by Raymond Hettinger; issue 5479 [http://bugs.python.org/issue5479].)

新しい関数: cmp_to_key() 関数は、古いスタイルの2引数を受け取る比較関数を受け取り、 sorted(), min(), max() などの key 引数に利用できる呼び出し可能オブジェクトを返します。この関数の主な目的は、古いコードを Python 3.x へ対応させるのを手助けすることです。 (Added by Raymond Hettinger.)

新しい関数: gc モジュールに is_tracked() 関数が追加されました。渡されたオブジェクトがGCに追跡されている場合に True を、そうでない場合に False を返します。 (Contributed by Antoine Pitrou; issue 4688 [http://bugs.python.org/issue4688].)

gzip モジュールの GzipFile がコンテキストマネージャープロトコルをサポートしました。 with gzip.GzipFile(...) as f: と書くことができます。(contributed by Hagen Fürstenau; issue 3860 [http://bugs.python.org/issue3860] また、 io.BufferedIOBase ABC を実装しています。なので、より高速な処理のために io.BufferedReader でラップすることができます。 (contributed by Nir Aides; issue 7471 [http://bugs.python.org/issue7471]). さらに、コンストラクタにオプションのタイムスタンプを指定することで、 gzip ファイル内の変更時間レコードをオーバーライドすることができるようになりました。 (Contributed by Jacques Frechet; issue 4272 [http://bugs.python.org/issue4272].)

gzip ファイルフォーマットのファイルは最後にゼロバイトによるパディングができるようになりました。 gzip モジュールは末尾のゼロバイトを消費します。(Fixed by Tadek Pietraszek and Brian Curtin; issue 2846 [http://bugs.python.org/issue2846].)

新しい属性: hashlib モジュールに algorithms 属性が追加されました。これはサポートしているアルゴリズムを含むタプルです。 Python 2.7 では、 hashlib.algorithms は ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') が含まれています。 (Contributed by Carl Chenet; issue 7418 [http://bugs.python.org/issue7418].)

httplib モジュールで使われているデフォルトの HTTPResponse クラスがバッファリングをサポートし、HTTPレスポンスをより高速に読み込めるようになりました。 (Contributed by Kristján Valur Jónsson; issue 4879 [http://bugs.python.org/issue4879].)

HTTPConnection と HTTPSConnection クラスが source_address 引数として (host, port) の2要素タプルを受け取るようになりました。これは接続のソースアドレスとして利用されます。 (Contributed by Eldon Ziegler; issue 3972 [http://bugs.python.org/issue3972].)

ihooks モジュールが相対 import をサポートしました。 ihooks import をカスタマイズするための古いモジュールで、 Python 2.0 で追加された imputil モジュールに取って変わられていることに注意してください。 (Relative import support added by Neil Schemenauer.)

imaplib モジュールが IPv6 アドレスをサポートするようになりました。 (Contributed by Derek Morr; issue 1655 [http://bugs.python.org/issue1655].)

inspect モジュールに getcallargs() 関数が追加されました。 callable とその位置引数、キーワード引数を受け取り、 callable のどの仮引数がどの実引数を受け取るかを計算し、引数名から値へマップする辞書を返します。例えば:

>>> from inspect import getcallargs
>>> def f(a, b=1, *pos, **named):
...     pass
>>> getcallargs(f, 1, 2, 3)
{'a': 1, 'b': 2, 'pos': (3,), 'named': {}}
>>> getcallargs(f, a=2, x=4)
{'a': 2, 'b': 1, 'pos': (), 'named': {'x': 4}}
>>> getcallargs(f)
Traceback (most recent call last):
...
TypeError: f() takes at least 1 argument (0 given)

Contributed by George Sakkis; issue 3135 [http://bugs.python.org/issue3135].

更新されたモジュール: io ライブラリが、Python 3.1 に同梱されるバージョンに更新されました。 3.1 では、I/O ライブラリは完全に C で書き直され、処理されるタスクに依って 2 から 20 倍速くなりました。元の Python バージョンは _pyio モジュールに改名されました。

結果の軽微な変更: io.TextIOBase クラスは、エンコーディングやデコーディングのエラーに使われるエラー設定 ('strict', 'replace', 'ignore' のいずれか) を与える errors 属性を持つようになりました。

io.FileIO クラスは、無効なファイルディスクリプタを渡されたときに OSError を送出するようになりました。(Implemented by Benjamin Peterson; issue 4991 [http://bugs.python.org/issue4991].) truncate() メソッドは、ファイル位置を保存するようになりました。以前は、ファイル位置を新しいファイルの末尾に変更しました。(Fixed by Pascal Chambon; issue 6939 [http://bugs.python.org/issue6939].)

新しい関数: itertools.compress(data, selectors) は、2 つのイテレータを取ります。 data の要素は、 selectors の対応する値が真であれば返されます:

itertools.compress('ABCDEF', [1,0,1,0,1,1]) =>
  A, C, E, F

新しい関数: itertools.combinations_with_replacement(iter, r) は、 iter から、すべての可能な長さ r の要素の組合せを返します。 combinations() とは異なり、生成された組合せに個別の要素が繰り返し出現できます:

itertools.combinations_with_replacement('abc', 2) =>
  ('a', 'a'), ('a', 'b'), ('a', 'c'),
  ('b', 'b'), ('b', 'c'), ('c', 'c')

なお要素は、実際の値ではなく、その入力内での位置に依って一意であるとみなされます。

itertools.count() 関数は、1 以外の値を増分できるように、 step 引数を追加しました。 count() はまた、キーワード引数に対応し、さらに浮動小数点数や Decimal インスタンスのような、非整数の値を使えるようになりました。(Implemented by Raymond Hettinger; issue 5032 [http://bugs.python.org/issue5032].)

itertools.combinations() および itertools.product() は、以前は入力のイテレート可能オブジェクトより大きい r に ValueError を返していました。これは仕様エラーと認められ、空のイテレータを返すようになりました。(Fixed by Raymond Hettinger; issue 4816 [http://bugs.python.org/issue4816].)

更新されたモジュール: json モジュールが、エンコーディングやデコーディングを高速化する C 拡張を含んだ、 simplejson パッケージのバージョン 2.0.9 にアップグレードされました。 (Contributed by Bob Ippolito; issue 4136 [http://bugs.python.org/issue4136].)

新しい collections.OrderedDict 型をサポートするために、 json.load() はオプションとして、任意のオブジェクトリテラルに対して呼び出され、ペアのリストにデコードする object_pairs_hook パラメタを追加しました。(Contributed by Raymond Hettinger; issue 5381 [http://bugs.python.org/issue5381].)

mailbox モジュールの Maildir クラスは、読み込むディレクトリのタイムスタンプを記録し、その後に更新時刻が変わった場合にのみ再読み込みするようになりました。これは不必要なディレクトリ走査を避けることでパフォーマンスを向上させます。 A.M. Kuchling and Antoine Pitrou; issue 1607951 [http://bugs.python.org/issue1607951], issue 6896 [http://bugs.python.org/issue6896].)

新しい関数: math モジュールは、誤差関数と相補誤差関数 erf() および erfc() 、 e**x - 1 を exp() から 1 を引くのよりも高い精度で計算する expm1() 、ガンマ関数 gamma() 、そしてガンマ関数の自然対数 lgamma() を追加しました。 (Contributed by Mark Dickinson and nirinA raseliarison; issue 3366 [http://bugs.python.org/issue3366].)

multiprocessing モジュールの Manager* クラスに、サブプロセスの開始時に呼び出される呼び出し可能オブジェクトと、それに渡される引数群を渡すことができるようになりました。 (Contributed by lekma; issue 5585 [http://bugs.python.org/issue5585].)

ワーカプロセスのプールを制御する Pool クラスに、オプションの maxtasksperchild パラメタが追加されました。ワーカプロセスはこれで指定された数のタスクを処理したら、退出して Pool に新しいワーカーを開始させます。これは、タスクがメモリその他のリソースをリークし得るときや、ワーカをとても大きくしてしまうようなタスクがあるときに便利です。 (Contributed by Charles Cazabon; issue 6963 [http://bugs.python.org/issue6963].)

nntplib モジュールは、IPv6 アドレスをサポートするようになりました。 (Contributed by Derek Morr; issue 1664 [http://bugs.python.org/issue1664].)

新しい関数: os モジュールは、以下の POSIX システムコールをラップします: real, effective, および saved GID と UID を返す、 getresgid() と getresuid() 、 real, effective, および saved GID と UID を新しく設定する、 setresgid() と setresuid() 、現在のプロセスにグループアクセスリストを初期化する initgroups() 。 (GID/UID functions contributed by Travis H.; issue 6508 [http://bugs.python.org/issue6508]. Support for initgroups added by Jean-Paul Calderone; issue 7333 [http://bugs.python.org/issue7333].)

os.fork() 関数は、子プロセス中で import ロックを再初期化するようになりました。これは、Solaris における fork() がスレッドから呼び出された時の問題を修正します。(Fixed by Zsolt Cserna; issue 7242 [http://bugs.python.org/issue7242].)

os.path モジュールの、 normpath() および abspath() 関数は、Unicode を保存するようになりました。入力パスが Unicode なら、戻り値も Unicode 文字列になります。 (normpath() fixed by Matt Giuca in issue 5827 [http://bugs.python.org/issue5827]; abspath() fixed by Ezio Melotti in issue 3426 [http://bugs.python.org/issue3426].)

pydoc モジュールは、Python が使う様々なシンボルのヘルプを追加しました。例えば、 help('<<') や help('@') とできるようになりました。(Contributed by David Laban; issue 4739 [http://bugs.python.org/issue4739].)

re モジュールの split(), sub(), および subn() は、モジュールの他の関数との一貫性のため、オプションの flags 引数を受け付けるようになりました。 (Added by Gregory P. Smith.)

新しい関数: runpy モジュールの run_path() は、与えられた path 引数のコードを実行します。 path は Python ソースファイルのパス (example.py)、コンパイル済みバイトコードファイル (example.pyc)、ディレクトリ (./package/)、または zip アーカイブ (example.zip) にできます。ディレクトリか zip パスが与えられると、それが sys.path の最初に加えられ、モジュール __main__ が import されます。これは、ディレクトリや zip が __main__.py を含むことを期待します。なければ、他の __main__.py が sys.path の後の部分から import されることがあります。これにより、Python のコマンドラインが明示的なパス名を処理する方法を真似たいようなスクリプトに、 runpy のより多くの機構が利用できるようになります。 (Added by Nick Coghlan; issue 6816 [http://bugs.python.org/issue6816].)

新しい関数: shutil モジュールの make_archive() は、ファイル名、アーカイブ型 (zip または tar-format)、およびディレクトリパスを取って、そのディレクトリの内容を含むアーカイブを生成します。(Added by Tarek Ziadé.)

shutil‘s の copyfile() および copytree() 関数は、名前付きパイプのコピーを求められたときに SpecialFileError 例外を送出する様になりました。以前は、コードは、名前付きパイプを、通常のファイルのように読み込み用に開いて扱い、いつまでもブロックしていました。 (Fixed by Antoine Pitrou; issue 3002 [http://bugs.python.org/issue3002].)

signal モジュールは、シグナルハンドラを本当に必要でない限り再インストールしなくなりました。これで、EINTR シグナルを強く捕えられないバグが修正されました。(Fixed by Charles-Francois Natali; issue 8354 [http://bugs.python.org/issue8354].)

新しい関数: site モジュールの、新しい関数群は様々なサイトおよびユーザに特有のパスを返します。 getsitepackages() は、全てのグローバル site-packages ディレクトリを含むリストを返します。 getusersitepackages() は、ユーザの site-packages ディレクトリのパスを返します。そして、 getuserbase() は、データの保存に使えるディレクトリへのパスを与える、 USER_BASE 環境変数の値を返します。 (Contributed by Tarek Ziadé; issue 6693 [http://bugs.python.org/issue6693].)

site モジュールは sitecustomize モジュールが import されたときに例外を報告するようになり、 KeyboardInterrupt 例外が捕捉されて飲み込まれることはなくなりました。 (Fixed by Victor Stinner; issue 3137 [http://bugs.python.org/issue3137].)

create_connection() 関数は、接続に使われるソースアドレスを与える (host, port) の 2-タプル、 source_address パラメタを追加しました。 (Contributed by Eldon Ziegler; issue 3972 [http://bugs.python.org/issue3972].)

recv_into() および recvfrom_into() メソッドは、バッファ API をサポートするオブジェクト、最も便利なのは bytearray や memoryview 、に書きこむようになりました。 (Implemented by Antoine Pitrou; issue 8104 [http://bugs.python.org/issue8104].)

SocketServer モジュールの TCPServer クラスは、ソケットタイムアウトと Nagle アルゴリズムの無効化をサポートするようになりました。 disable_nagle_algorithm クラス属性は、デフォルトで False です。上書きされて True になると、新しいリクエスト接続は、TCP_NODELAY オプションを設定され、一つの TCP パケットにたくさんの小さな送信がバッファリングされることを防ぎます。 timeout クラス属性は、リクエストソケットに適用されるタイムアウトを秒で保持できます。その時間内にリクエストが受け付けられなければ、 handle_timeout() が呼び出され、 handle_request() が返されます。 (Contributed by Kristján Valur Jónsson; issue 6192 [http://bugs.python.org/issue6192] and issue 6267 [http://bugs.python.org/issue6267].)

更新されたモジュール: sqlite3 モジュールが pysqlite package [http://code.google.com/p/pysqlite/] のバージョン 2.6.0 にアップデートされました。バージョン 2.6.0 はいくつかのバグ修正を含み、共有ライブラリから SQLite 拡張をロードできるようになりました。拡張を有効にするには enable_load_extension(True) メソッドを呼び出し、そして特定の共有ライブラリをロードするには enable_load_extension(True) を呼び出してください。 (Updated by Gerhard Häring.)

ssl モジュールの SSLSocket オブジェクトは、バッファ API をサポートするようになりました。これは、テストスイートの障害を修正します (fix by Antoine Pitrou; issue 7133 [http://bugs.python.org/issue7133])。また、OpenSSL の SSL_MODE_AUTO_RETRY を自動的に設定することで、 recv() 演算によって SSL 再ネゴシエーションを引き起こすエラーコードが返されるのを防ぎます (fix by Antoine Pitrou; issue 8222 [http://bugs.python.org/issue8222])。

ssl.wrap_socket() コンストラクタ関数は、許可される暗号化アルゴリズムを列挙する文字列である ciphers 引数を取るようになりました。この文字列の書式は、 OpenSSL ドキュメントで [http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT]. 解説されています。 (Added by Antoine Pitrou; issue 8322 [http://bugs.python.org/issue8322].)

その他の変更により、拡張はOpenSSL の全ての暗号をロードし、それらすべてが利用できるようアルゴリズムを消化します。SSL 暗号化の中には検証できないものもあり、”unknown algorithm” エラーを報告します。 (Reported by Beda Kosata, and fixed by Antoine Pitrou; issue 8484 [http://bugs.python.org/issue8484].)

OpenSSL の、使われるバージョンは、モジュール属性 ssl.OPENSSL_VERSION (文字列)、 ssl.OPENSSL_VERSION_INFO (5-タプル)、および ssl.OPENSSL_VERSION_NUMBER (整数) として利用できるようになりました。 (Added by Antoin Pitrou; issue 8321 [http://bugs.python.org/issue8321].)

struct モジュールは、値が特定の整数フォーマットコード (bBhHiIlLqQ のいずれか) に対して大きすぎるときに、オーバーフローエラーを静かに無視しなくなりました。これは必ず struct.error 例外を送出するようになりました。 (Changed by Mark Dickinson; issue 1523 [http://bugs.python.org/issue1523].) pack() 関数は、非整数を変換してパックするのに、 __int__() メソッドを試したりエラーを報告したりする前に、 __index__() の使用も試すようになりました。 (Changed by Mark Dickinson; issue 8300 [http://bugs.python.org/issue8300].)

新しい関数: subprocess モジュールの check_output() は、指定された引数群でコマンドを実行し、コマンドがエラーを起こさずに実行したらコマンドの出力を文字列として返し、そうでなければ CalledProcessError 例外を送出します。

>>> subprocess.check_output(['df', '-h', '.'])
'Filesystem     Size   Used  Avail Capacity  Mounted on\n
/dev/disk0s2    52G    49G   3.0G    94%    /\n'

>>> subprocess.check_output(['df', '-h', '/bogus'])
  ...
subprocess.CalledProcessError: Command '['df', '-h', '/bogus']' returned non-zero exit status 1

(Contributed by Gregory P. Smith.)

subprocess モジュールは、 EINTR シグナルを受け取り次第内部システムコールを最施行するようになりました。(Reported by several people; final patch by Gregory P. Smith in issue 1068268 [http://bugs.python.org/issue1068268].)

新しい関数: symtable モジュールの is_declared_global() は、明示的に global と宣言された引数には真、暗示的に global である引数には偽を返します。 (Contributed by Jeremy Hylton.)

syslog モジュールは、識別子として、以前デフォルトであった 'python' の値ではなく、 sys.argv[0] の値を使うようになりました。 (Changed by Sean Reifschneider; issue 8451 [http://bugs.python.org/issue8451].)

sys.version_info の値は、属性名 major, minor, micro, releaselevel, および serial を持つ名前付きタプルになりました。

sys.getwindowsversion() もまた、属性名 major, minor, build, platform, service_pack, service_pack_major, service_pack_minor, suite_mask, および product_type を持つ名前付きタプルを返します。(Contributed by Brian Curtin; issue 7766 [http://bugs.python.org/issue7766].)

tarfile モジュールのデフォルトエラー処理が変更され、致命的なエラーを抑制しないようになりました。デフォルトのエラーレベルは以前は 0 で、エラーはメッセージとしてデバッグログに書き込まれるだけでしたが、デバッグログはデフォルトでは活性化されていないため、エラーは顧みられませんでした。デフォルトのエラーレベルは 1 になり、エラーがあれば例外が送出されます。 (Changed by Lars Gustäbel; issue 7357 [http://bugs.python.org/issue7357].)

tarfile は、tar ファイルに追加される TarInfo オブジェクトのフィルタリングをサポートするようになりました。 add() を呼び出したとき、オプションの呼び出し可能オブジェクトである filter 引数を与えることができます。 filter オブジェクトには、ファイルが追加される度に TarInfo を渡され、これを変形して返せます。このオブジェクトが None を返したら、そのファイルは結果のアーカイブから除かれます。これは既存の exclude 引数より強力で、それゆえこれは非推奨となります。 (Added by Lars Gustäbel; issue 6856 [http://bugs.python.org/issue6856].) TarFile クラスはまた、コンテキストマネージャプロトコルもサポートするようになりました。 (Added by Lars Gustäbel; issue 7232 [http://bugs.python.org/issue7232].)

threading.Event クラスの wait() メソッドは、終了時に内部フラグを返すようになりました。 wait() は内部フラグが真になるまでブロックすることを想定されているため、この関数は通常真を返すことになります。この戻り値は、タイムアウトが与えられ、オペレーションがタイムアウトした時のみ偽になります。 (Contributed by Tim Lesher; issue 1674032 [http://bugs.python.org/issue1674032].)

unicodedata モジュールに提供される Unicode データベースは、どの文字が数字や空白文字か、または改行を表すかを決定するために、内部で使われるようになりました。このデータベースはまた、 Unihan.txt データファイルからの情報も含みます (patch by Anders Chrigström and Amaury Forgeot d’Arc; issue 1571184 [http://bugs.python.org/issue1571184])。また、バージョン 5.2.0 にアップデートされました (updated by Florent Xicluna; issue 8024 [http://bugs.python.org/issue8024])。

urlparse モジュールの urlsplit() は、未知の URL スキームを RFC 3986 [http://tools.ietf.org/html/rfc3986.html] に応じた方法で処理します。 URL が "<something>://..." の形式なら、 :// の前のテキストを、それがモジュールの知らない作り物のスキームであってさえ、スキームとして扱います。この変更は、古い働きを使って動作していたコードを破壊することがあります。例えば、Python 2.6.4 や 2.5 は以下を返します:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', '', '//host/filename?query', '', '')

Python 2.7 (や Python 2.6.5) は以下を返します:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', 'host', '/filename?query', '', '')

(Python 2.7 では、これは普通のタプルではなく名前付きタプルを返すので、実際は微妙に異なる出力をします。)

urlparse モジュールは、 RFC 2732 [http://tools.ietf.org/html/rfc2732.html] で定義された IPv6 リテラルアドレスもサポートします (contributed by Senthil Kumaran; issue 2987 [http://bugs.python.org/issue2987])。:

>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',
            path='/foo', params='', query='', fragment='')

新しいクラス: weakref モジュールの WeakSet クラスは、その要素の弱参照だけを保持する集合です。要素は、それを指す参照がなくなり次第除去されます。 (Originally implemented in Python 3.x by Raymond Hettinger, and backported to 2.7 by Michael Foord.)

エレメントツリーライブラリ、 xml.etree は、 (<?xml-stylesheet href="#style1"?> のような) 命令や (<!-- comment --> のような) コメントを処理する XML を出力するとき、アンパサンドや山括弧をエスケープしなくなりました。 (Patch by Neil Muller; issue 2746 [http://bugs.python.org/issue2746].)

xmlrpclib と SimpleXMLRPCServer によって提供される XML-RPC クライアントおよびサーバは、HTTP/1.1 keep-alive をサポートし、場合によっては gzip エンコーディングを使って XML の送受を圧縮することで、パフォーマンスが向上しました。gzip 圧縮は SimpleXMLRPCRequestHandler の encode_threshold 属性によって制御されます。これはバイト数で、これより大きな応答は圧縮されます。 (Contributed by Kristján Valur Jónsson; issue 6267 [http://bugs.python.org/issue6267].)

zipfile モジュールの ZipFile は、コンテキストマネジメントプロトコルをサポートし、 with zipfile.ZipFile(...) as f: と書けるようになりました。 (Contributed by Brian Curtin; issue 5511 [http://bugs.python.org/issue5511].)

zipfile は、空のディレクトリのアーカイブ化をサポートするようになり、これを正しく解凍します。(Fixed by Kuba Wieczorek; issue 4710 [http://bugs.python.org/issue4710].) アーカイブ内のファイルの読み込みが速くなり、 read() および readline() の割り込みが正しく働くようになりました。(Fixed by Kuba Wieczorek; issue 4710 [http://bugs.python.org/issue4710].)

is_zipfile() 関数は、以前受け付けられていたパス名に加え、ファイルオブジェクトも受け付けるようになりました。 (Contributed by Gabriel Genellina; issue 4756 [http://bugs.python.org/issue4756].)

writestr() メソッドは、 ZipFile コンストラクタで指定されたデフォルトの圧縮メソッドをオーバライドする、オプションの compress_type パラメタを追加しました。 (Contributed by Ronald Oussoren; issue 6003 [http://bugs.python.org/issue6003].)

新しいモジュール: importlib

Python 3.1 は、根底の Python の import 文のロジックの最実装である importlib パッケージを含みます。 importlib は、Python インタプリタの実装者や、import プロセスに関与する新しいインポータを書きたいと願うユーザにとって便利です。 Python 2.7 は importlib パッケージを完全には含みませんが、代わりに 1 つの関数 import_module() を含む小さなサブセットがあります。

import_module(name, package=None) はモジュールを import します。 name はモジュールまたはパッケージの名前を含む文字列です。 ..utils.errors のように . 文字で始まる文字列を与えることで、相対 import も可能です。相対 import では、 package 引数は必ず与えられなければならず、相対 import のアンカーとして使われるパッケージの名前でなければなりません。 import_module() は、 import されたモジュールを sys.modules に挿入し、モジュールオブジェクトを返すこともします。

ここに例があります:

>>> from importlib import import_module
>>> anydbm = import_module('anydbm')  # Standard absolute import
>>> anydbm
<module 'anydbm' from '/p/python/Lib/anydbm.py'>
>>> # Relative import
>>> file_util = import_module('..file_util', 'distutils.command')
>>> file_util
<module 'distutils.file_util' from '/python/Lib/distutils/file_util.pyc'>

importlib は、Brett Cannon によって実装され、 Python 3.1 に導入されました。

新しいモジュール: sysconfig

sysconfig モジュールが Distutils パッケージから引き抜かれ、新しいトップレベルモジュールになりました。 sysconfig は、Python のビルドプロセスについての以下の情報を得るための関数群を提供しています。コンパイラスイッチ、インストレーションパス、プラットフォーム名、そして Python がソースディレクトリから実行されているかどうかです。

モジュールの関数のいくつかを紹介すると:

get_config_var() は、Python の Makefile と pyconfig.h ファイルから変数を返します。

get_config_vars() は、すべての環境設定変数を含む辞書を返します。

get_path() は、特定のタイプのモジュール、つまり標準ライブラリ、サイト特有のモジュール、プラットフォーム特有のライブフラリなど、への設定されたパスを返します。

is_python_build() は、Python ソースツリーからバイナリを起動していれば真を、そうでなければ偽を返します。

詳細と関数の完全な一覧は sysconfig ドキュメントを参照してください。

Distutils パッケージと sysconfig は Tarek Ziadé によってメンテナンスされていて、彼は Distutils の新世代版を開発するために Distutils2 パッケージ (source repository at http://hg.python.org/distutils2/) も開始しました。

ttk: Tk のテーマ付きウィジェット

Tcl/Tk 8.5 は、基本的な Tk ウィジェットを最実装しながらより自由な外観のカスタマイズが広がり、よりネイティブなプラットフォームのウィジェットに似たテーマ付きウィジェット群を含みます。このウィジェット群は、元は Tile と呼ばれていましたが、Tcl/Tck リリース 8.5 への追加の際に (“themed Tk” を略して) Ttk に改名されました。

詳しく知るには、 ttk モジュールのドキュメントをお読みください。 http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm にある、Ttk テーマエンジンを解説した Tcl/Tk マニュアルページを読むのもいいでしょう。 Python/Ttk コードを動かしているスクリーンショットは http://code.google.com/p/python-ttk/wiki/Screenshots にあります。

ttk モジュールは Guilherme Polo によって書かれ、 issue 2983 [http://bugs.python.org/issue2983] に追加されました。 Tile.py と呼ばれる別バージョン Tile.py は、 Martin Franklin によって書かれ、Kevin Walzer によってメンテナンスされているもので、組み込みが issue 2618 [http://bugs.python.org/issue2618] で提案されましたが、著者は Guilherme Polo の作品のほうがより包括的であると主張しました。

更新されたモジュール: unittest

unittest モジュールが大幅に改善されました。多くの新機能が追加されました。それらの機能のほとんどは、特に注釈のない限り、 Michael Foord によって実装されました。このモジュールの改善された版は、 Python バージョン 2.4 から 2.6 で使うために、 http://pypi.python.org/pypi/unittest2 から unittest2 パッケージとして別にダウンロードできます。

コマンドラインから使われるとき、このモジュールはテストを自動的に発見します。これは py.test [http://pytest.org] や nose [http://code.google.com/p/python-nose/] ほど派手ではありませんが、テストをパッケージディレクトリに保持されたテストを簡潔に実行する方法を提供します。例えば、以下のコマンドは test/ サブディレクトリから test*.py という名前の import できるテストファイル検索します:

python -m unittest discover -s test

詳細は、 unittest モジュールのドキュメントを参照してください。 (Developed in issue 6001 [http://bugs.python.org/issue6001].)

main() 関数は、その他幾つかの新しいオプションを提供します:

-b や --buffer は、標準出力や標準エラーストリームをそれぞれのテストの間バッファに入れます。テストが通れば、結果の出力は全て捨てられます。失敗したら、バッファに入れられた出力が表示されます。

-c や --catch は、control-C による中断をより上品にします。テストプロセスを即座に中断するのではなく、現在実行中のテストは完了させ、中断までの部分的な結果は報告されます。待ちきれなければ、control-C をもう一度押せば、即座に中断されます。

この control-C ハンドラは、コードがテストされているときや、実行されているテストが独自のシグナルハンドラを定義したとき、シグナルハンドラがすでに設定されていてそして呼び出されたということを知らせることで、問題を起こさないようにします。これがまずいなら、 removeHandler() デコレータを使って、テストが control-C ハンドリングを無効にするべきであると示せます。

-f や --failfast は、テストが失敗したとき、他のテストを続けるのではなく、テストの実行を即座に停止します。 (Suggested by Cliff Dyer and implemented by Michael Foord; issue 8074 [http://bugs.python.org/issue8074].)

進捗メッセージは、verbose モードで実行したとき、期待された失敗に ‘x’ を、期待されない成功に ‘u’ を表示するようになりました。 (Contributed by Benjamin Peterson.)

テストケースは、テストをスキップするために SkipTest 例外を送出します。(issue 1034053 [http://bugs.python.org/issue1034053]).

assertEqual(), assertTrue(), および assertFalse() 失敗のメッセージは、提供する情報量が増えました。 TestCase クラスの longMessage 属性を True に設定すると、失敗時に、標準のエラーメッセージと追加して提供したメッセージの両方が表示されます。(Added by Michael Foord; issue 5663 [http://bugs.python.org/issue5663].)

assertRaises() メソッドは、実行する呼び出し可能オブジェクトを与えずに呼び出されたとき、コンテキストハンドラを返すようになりました。例えば、こう書くことができます:

with self.assertRaises(KeyError):
    {}['foo']

(Implemented by Antoine Pitrou; issue 4444 [http://bugs.python.org/issue4444].)

モジュールレベルおよびクラスレベルの設定と、ティアダウンフィクスチャがサポートされました。モジュールは、 setUpModule() および tearDownModule() 関数を含むことができます。クラスは setUpClass() および tearDownClass() メソッドを含むことができ、これらは (@classmethod や透過なものを使って) クラスメソッドとして定義しなければなりません。これらの関数とメソッドは、テストランナーが別のモジュールやクラスのテストケースに切り替えるときに呼び出されます。

メソッド addCleanup() および doCleanups() が追加されました。 addCleanup() で、無条件に呼び出されるクリーンアップ関数を (setUp() が失敗したら setUp() の後に、そうでなければ tearDown() の後に) 追加できるようにします。これにより、テスト中のリソースの配置と開放が簡潔になります。(issue 5679 [http://bugs.python.org/issue5679]).

より特化したテストを提供するメソッドがいくつか追加されました。これらのメソッドの多くは、Google のエンジニアたちによってそのテストスイートのために書かれました。Gregory P. Smith, Michael Foord, and GvR が、これを unittest の Python 版にマージしました。

assertIsNone() および assertIsNotNone() はひとつの式を取り、その結果が NONE であるか、またはないかを確かめます。

assertIs() および assertIsNot() は、2 つの値を取り、その評価が同一のオブジェクトであるか、またはないかを確かめます。 (Added by Michael Foord; issue 2578 [http://bugs.python.org/issue2578].)

assertIsInstance() および assertNotIsInstance() は、結果のオブジェクトが特定のクラス、またはタプルにあるクラスのいずれかのインスタンスであるかを調べます。(Added by Georg Brandl; issue 7031 [http://bugs.python.org/issue7031].)

assertGreater(), assertGreaterEqual(), assertLess(), および assertLessEqual() は、二つの量を比較します。

assertMultiLineEqual() は 2 つの文字列を比較し、等しくなければ、2 文字列の差分をハイライトする有益な比較を表示します。この比較は、Unicode 文字列が assertEqual() で比較されるときのデフォルトに使われるようになりました。

assertRegexpMatches() および assertNotRegexpMatches() は、第一引数が第二引数として与えられた正規表現にマッチする、またはしない文字列であるかどうかを調べます。

assertRaisesRegexp() は、特定の式が送出されるかを調べ、そしてまたその式の文字列表現が与えられた正規表現にマッチするかを調べます。

assertIn() および assertNotIn() は、 first が second に属するか、または属さないかを調べます。

assertItemsEqual() は、2 つの与えられたシーケンスが同じ要素を含むかを調べます。

assertSetEqual() は、2 つの集合が等しいか比較し、エラーの場合のみ、集合間の差分を報告します。

同様に、 assertListEqual() および assertTupleEqual() は、指定された型を比較し、差分を説明しますが、完全な値を表示するとはかぎりません。これらのメソッドは、リストやタプルを assertEqual() で比較するときにデフォルトで使われるようになりました。より一般的には、 assertSequenceEqual() は 2 つのシーケンスを比較し、必要なら両方のシーケンスが特定の型であるかを調べます。

assertDictEqual() は、二つの辞書を比較し、差分を報告します。これは、辞書を assertEqual() で比較するときにデフォルトで使われるようになりました。 assertDictContainsSubset() は、 first に属するキー/値の対の全てが second に現れるかを調べます。

assertAlmostEqual() および assertNotAlmostEqual() は、 first と second がほぼ等しいかを判定します。このメソッドは、オプションで指定された places (デフォルトは 7) の数に差を丸めてそれをゼロと比べるか、差が与えられた delta の値より小さいことを要求します。

loadTestsFromName() は、 TestLoader の suiteClass 属性を適切に受け入れます。(Fixed by Mark Roddy; issue 6866 [http://bugs.python.org/issue6866].)

新しいフックにより、 assertEqual() メソッドを拡張して新しいデータ型を扱わせられます。 addTypeEqualityFunc() メソッドは型オブジェクトと関数を取ります。この関数は、比較される両方のオブジェクトが特定の型であるときに使われます。この関数は、2 つのオブジェクトを比較し、マッチしなければ例外を送出するべきです。この関数が、新しいシーケンス比較メソッドがするように、2 つのオブジェクトがなぜマッチしないのかについて追加の情報を提供するのがいいアイデアです。

unittest.main() はオプションの exit 引数を取るようになりました。 False なら、 main() は sys.exit() を呼び出さず、これにより対話型インタプリタから main() が使えるようになります。 (Contributed by J. Pablo Fernández; issue 3379 [http://bugs.python.org/issue3379].)

TestResult に、テストランの直前と直後に呼び出される startTestRun() および stopTestRun() が追加されました。 (Contributed by Robert Collins; issue 5728 [http://bugs.python.org/issue5728].)

これら一連の変更により、 unittest.py は無様に大きくなったので、モジュールはパッケージとなり、コードは複数のファイルに分割されました (by Benjamin Peterson)。これは、モジュールをインポートして使う方法には影響しません。

参考

http://www.voidspace.org.uk/python/articles/unittest2.shtml

Describes the new features, how to use them, and the rationale for various design decisions. (By Michael Foord.)

更新されたモジュール: ElementTree 1.3

Python に同梱される ElementTree ライブラリのバージョンが、バージョン 1.3 にアップデートされました。新機能の一部は:

様々な解析関数が、使われる XMLParser インスタンスを与える parser キーワード引数を取るようになりました。これにより、ファイルの内部エンコーディングをオーバーライドできるようになりました:

p = ET.XMLParser(encoding='utf-8')
t = ET.XML("""<root/>""", parser=p)

XML を解析するときのエラーは、 ParseError 例外を送出するようになりました。この例外のインスタンスは、問題の位置を与える (line, column) タプルを含む position 属性を持ちます。

ツリーを文字列に変換する ElementTree のコードが大幅に改善され、多くの場合でおおよそ 2 倍速くなりました。 ElementTree write() および Element write() メソッドは、 method パラメタを追加し、これは “xml” (デフォルト), “html”, または “text” にできます。 HTML モードは、空の要素を <empty/> ではなく <empty></empty> として出力し、text モードは要素を無視し、テキストのチャンクのみ出力します。要素の tag 属性を None に設定してその子はそのままにすると、ツリーが書き出されるとき、その要素は省かれるので、それ以上再編成することなく要素を一つ取り除けます。

名前空間の操作も改善されました。すべての xmlns:<whatever> 宣言は、結果の XML に散らばるのではなく、ルート要素に出力されます。 default_namespace 属性を設定することでデフォルトの名前空間を設定でき、 register_namespace() で新しい接頭辞を登録できます。 XML モードでは、XML 宣言を抑制するために真/偽の xml_declaration パラメタを使えます。

新しい Element メソッド: extend() はシーケンスから項目の子に要素を追加します。要素それ自体はシーケンスのように振る舞うので、子をある要素から別の要素に移すのが簡単です:

from xml.etree import ElementTree as ET

t = ET.XML("""<list>
  <item>1</item> <item>2</item>  <item>3</item>
</list>""")
new = ET.XML('<root/>')
new.extend(t)

# Outputs <root><item>1</item>...</root>
print ET.tostring(new)

新しい Element メソッド: iter() は、要素の子をジェネレータとして与えます。また、 for child in elem: と書いて要素の子に渡ってループできます。既存のメソッド getiterator() と、子のリストを構成して返す getchildren() は、非推奨になりました。

新しい Element メソッド: itertext() は、その要素の子孫であるテキストのチャンクを全て与えます。例えば:

t = ET.XML("""<list>
  <item>1</item> <item>2</item>  <item>3</item>
</list>""")

# Outputs ['\n  ', '1', ' ', '2', '  ', '3', '\n']
print list(t.itertext())

非推奨: 要素をブール値として使う (すなわち、 if elem:) と、要素が子を持てば真を、子を持たなければ偽を返します。この振る舞いは紛らわしいです – ですから、 FutureWarning を引き起こすようになりました。コードでは、明示するべきです。子の数に興味があるなら len(elem) != 0 と、または elem is not None と書いてください。

Fredrik Lundh は ElementTree を開発し、1.3 バージョンを作成しました。 1.3 を解説した彼の記事を http://effbot.org/zone/elementtree-13-intro.htm で読めます。 Florent Xicluna は、python-dev および issue 6472 [http://bugs.python.org/issue6472] での議論の後、 Python に含まれるバージョンをアップデートしました。

ビルドと C API の変更

パイソンのビルド過程と C API に以下のような変更がなされました:

GNU デバッガ、GDB 7、の最新のリリースは Python を使って書けます [http://sourceware.org/gdb/current/onlinedocs/gdb/Python.html] 実行可能なプログラム P のデバッグを始めるとき、GDB は P-gdb.py という名前のファイルをロックし、それを自動的に読み込みます。Dave Malcolm は Python 自体をデバッグするときに便利ないくつかのコマンドを加える python-gdb.py に貢献しました。例えば、 py-up および py-down は、通常いくつかの C スタックフレームに対応する、 Python のスタックフレームを上がったり下がったりします。 py-print は、Python 変数の値を表示し、 py-bt は、 Python スタックトレースを表示します。(Added as a result of issue 8032 [http://bugs.python.org/issue8032].)

Python に備え付けの .gdbinit ファイルを使うと、デバッグされているスレッドが GIL をほじしていないとき、2.7 バージョンの “pyo” マクロが正常に動くようになりました。このマクロは、表示の前にこれを取得するようになりました。 (Contributed by Victor Stinner; issue 3632 [http://bugs.python.org/issue3632].)

Py_AddPendingCall() はスレッドセーフになり、ワーカスレッドがメイン Python スレッドに通知を投入することができるようになりました。これは特に、非同時性の IO 処理に便利です。 (Contributed by Kristján Valur Jónsson; issue 4293 [http://bugs.python.org/issue4293].)

新しい関数: PyCode_NewEmpty() は、空のコードオブジェクトを生成します。要求されるのは、ファイル名、関数名、そして最初の行番号だけです。これは、より便利なトレースバックスタックを構成しようとする拡張モジュールに便利です。以前は、このような拡張はより多くの引数を必要とする PyCode_New() を呼び出す必要がありました。(Added by Jeffrey Yasskin.)

新しい関数: PyErr_NewExceptionWithDoc() は、既存の PyErr_NewException() と同じように新しい例外クラスを生成しますが、新しい例外クラスの docstring を含む、追加の char * 引数を取ります。(Added by ‘lekma’ on the Python bug tracker; issue 7033 [http://bugs.python.org/issue7033].)

新しい関数: PyFrame_GetLineNumber() はフレームオブジェクトを取り、そのフレームが現在実行している行番号を返します。以前は、コードは現在実行しているバイトコード命令のインデクスを得て、それからそのアドレスに対応する行番号を探索する必要がありました。 (Added by Jeffrey Yasskin.)

新しい関数: PyLong_AsLongAndOverflow() および PyLong_AsLongLongAndOverflow() は、C の long や long long のような Python の長整数に近いです。この数が出力型に適合するには大きすぎるなら、 overflow フラグが設定され、呼び出し元に返されます。 (Contributed by Case Van Horsen; issue 7528 [http://bugs.python.org/issue7528] and issue 7767 [http://bugs.python.org/issue7767].)

新しい関数: 文字列から浮動小数点数への変換から由来する、新しい PyOS_string_to_double() 関数が追加されました。古い PyOS_ascii_strtod() および PyOS_ascii_atof() は、非推奨となりました。

新しい関数: PySys_SetArgvEx() は、 sys.argv の値を設定し、 updatepath に依ってオプションで sys.path を更新して sys.argv[0] で指名されたスクリプトを含むディレクトリを含めることができます。

この関数は、Python を埋め込んだアプリケーションのセキュリティホールを塞ぐために追加されました。古い関数 PySys_SetArgv() は、必ず sys.path を更新し、これはカレントディレクトリを追加することがあります。これにより、Python を埋め込んだアプリケーションを別の誰かが制御するディレクトリで実行すると、攻撃者がディレクトリにトロイの木馬モジュール (例えば、 os.py という名前のファイル) を仕込み、インポートさせ実行させる事ができました。

Python を埋め込んだアプリケーションを保守しているなら、 PySys_SetArgv() を呼び出していないか調べ、 updatepath を偽に設定した PySys_SetArgvEx() を使うべきかよく考えてください。

issue 5753 [http://bugs.python.org/issue5753] で CVE-2008-5983 [http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983] として報告され、Antoine Pitrou によって修正されたたセキュリティ問題です。

新しいマクロ: Python ヘッダファイルは、以下のマクロを定義しました: Py_ISALNUM, Py_ISALPHA, Py_ISDIGIT, Py_ISLOWER, Py_ISSPACE, Py_ISUPPER, Py_ISXDIGIT, Py_TOLOWER, および Py_TOUPPER 。これらすべての関数は、文字を分類する C の標準マクロと類似ですが、 Python は文字をロケールに依らず文字を分析したいときがあるため、現在のロケール設定を無視します。(Added by Eric Smith; issue 5793 [http://bugs.python.org/issue5793].)

取り除かれた関数: PyEval_CallObject は、マクロとしてのみ利用できるようになりました。関数版は、ABI リンク互換性を保つために残されましたが、それは 1997 年のことです。今となっては削除するべきです。 (Removed by Antoine Pitrou; issue 8276 [http://bugs.python.org/issue8276].)

新しいフォーマットコード: PyFormat_FromString(), PyFormat_FromStringV(), および PyErr_Format() 関数は、 C の long long 型を表示する %lld および %llu フォーマットを受け付けるようになりました。 (Contributed by Mark Dickinson; issue 7228 [http://bugs.python.org/issue7228].)

スレッドとプロセスのフォークの間の複雑な相互関係が変更されました。以前は、 os.fork() によって生成された子プロセスは失敗していました。これは、子は動作しているスレッド 1 つだけで生成され、そのスレッドが os.fork() を処理するからです。他のスレッドが、Python のインポートロックのような、ロックを保持していたら、フォークが実行されたとき、ロックは新しいプロセスでも “held” としてマークされたままです。しかし、子プロセスでは、他のスレッドは複製されないため、ロックを開放するものは何もないので、子プロセスは import の実行を続けることができません。

Python 2.7 は、 os.fork() を実行する前に import ロックを取得し、また threading モジュールを使って生成された全てのロックをクリーンアップします。内部ロックを持っていたり、自身で fork() を呼び出したりするような C 拡張モジュールは、このクリーンアップの恩恵を受けません。

(Fixed by Thomas Wouters; issue 1590864 [http://bugs.python.org/issue1590864].)

Py_Finalize() 関数は、内部の threading._shutdown() 関数を呼び出します。これにより、インタプリタがシャトダウンするときに送出が防がれる例外があります。 (Patch by Adam Olsen; issue 1722344 [http://bugs.python.org/issue1722344].)

PyMemberDef 構造を使って型の属性を定義するとき、それ以上 T_STRING_INPLACE 属性を削除または設定できなくなります。

ctypes によって定義されたグローバルシンボルには、 Py または _ctypes が接頭されるようになりました。(Implemented by Thomas Heller; issue 3102 [http://bugs.python.org/issue3102].)

新しい設定オプション: --with-system-expat スイッチにより、 pyexpat モジュールをビルドして、システム Expat ライブラリを使えます。 (Contributed by Arfrever Frehtes Taifersar Arahesis; issue 7609 [http://bugs.python.org/issue7609].)

新しい設定オプション: --with-valgrind オプションは、 Valgrind メモリエラー検出器が正しく分析するのが難しい pymalloc アロケータを無効にするようになりました。ですから Valgrind は、メモリリークやオーバーランをより検出できます。 (Contributed by James Henstridge; issue 2422 [http://bugs.python.org/issue2422].)

新しい設定オプション: --with-dbmliborder= に空の文字列を与えて様々な DBM モジュールを全て無効にできます。 (Added by Arfrever Frehtes Taifersar Arahesis; issue 6491 [http://bugs.python.org/issue6491].)

configure スクリプトは、ある種の 32-bit Intel チップ上の浮動小数点丸めバグを調べ、 X87_DOUBLE_ROUNDING プリプロセッサ定義を定義します。現在この定義を使うコードはありませんが、使うことを望む人がいたら使えます。(Added by Mark Dickinson; issue 2937 [http://bugs.python.org/issue2937].)

configure はまた、C++ リンクをサポートする LDCXXSHARED Makefile を設定するようになりました。 (Contributed by Arfrever Frehtes Taifersar Arahesis; issue 1222585 [http://bugs.python.org/issue1222585].)

ビルドプロセスは、pkg-config サポートに必要なファイルを生成するようになりました。(Contributed by Clinton Roy; issue 3585 [http://bugs.python.org/issue3585].)

ビルドプロセスは、Subversion 1.7 をサポートするようになりました。 (Contributed by Arfrever Frehtes Taifersar Arahesis; issue 6094 [http://bugs.python.org/issue6094].)

カプセル

Python 3.1 は、拡張モジュールに C API を提供する新しい C データ型 PyCapsule を追加しました。カプセルは、本質的には C の void * ポインタのホルダであり、モジュール属性として利用できるようになります。例えば、 socket モジュールの API は socket.CAPI として公開されていて、 unicodedata は ucnhash_CAPI を公開しています。その他の拡張はモジュールを import し、辞書にアクセスしてカプセルオブジェクトを取得し、そしてモジュールの様々な API 関数へのポインタの配列を指す void * ポインタを取得できます。

これに使われる既存のデータ型 PyCObject がありますが、これは型安全性を提供しません。pure Python で書かれた邪悪なコードは、 PyCObject をモジュール A から取り、どうにかしてそれをモジュール B の PyCObject で代えることで、セグメンテーション違反を起こし得ます。カプセルは自身の名前を知っていて、ポインタを得るには名前を提供しなければなりません:

void *vtable;

if (!PyCapsule_IsValid(capsule, "mymodule.CAPI") {
        PyErr_SetString(PyExc_ValueError, "argument type invalid");
        return NULL;
}

vtable = PyCapsule_GetPointer(capsule, "mymodule.CAPI");

vtable が期待どおりのものを指すことが保証されます。異なるカプセルが渡されたら、 PyCapsule_IsValid() は不適合な名前を検知し、偽を返します。これらのオブジェクトの使用について、より詳しい情報は、 拡張モジュールに C API を提供する を参照してください。

Python 2.7 は、様々な拡張モジュール API を提供するためにカプセルを内部的に使うようになりましたが、カプセルを処理するために PyCObject_AsVoidPtr() が変更され、 CObject インタフェースとのコンパイル時互換性は保たれます。 PyCObject_AsVoidPtr() を使うと PendingDeprecationWarning が合図されますが、デフォルトでは言及されません。

Implemented in Python 3.1 and backported to 2.7 by Larry Hastings; discussed in issue 5630 [http://bugs.python.org/issue5630].

ポート特有の変更: Windows

msvcrt モジュールは、 crtassem.h からのいくつかの定数を追加しました。 CRT_ASSEMBLY_VERSION, VC_ASSEMBLY_PUBLICKEYTOKEN, および LIBRARIES_ASSEMBLY_NAME_PREFIX. (Contributed by David Cournapeau; issue 4365 [http://bugs.python.org/issue4365].)

レジストリへのアクセスのための _winreg モジュールは、以前サポートされていた関数群の引数を増やした拡張版である CreateKeyEx() および DeleteKeyEx() を実装しました。 DisableReflectionKey(), EnableReflectionKey(), および QueryReflectionKey() もテストされ、ドキュメント化されました。 (Implemented by Brian Curtin: issue 7347 [http://bugs.python.org/issue7347].)

新しい _beginthreadex() API がスレッドの開始に使われ、ネイティブのスレッドローカルストレージ間数が使われるようになりました。 (Contributed by Kristján Valur Jónsson; issue 3582 [http://bugs.python.org/issue3582].)

os.kill() 関数が Windows で働くようになりました。このシグナル値は定数 CTRL_C_EVENT, CTRL_BREAK_EVENT, その他の整数にできます。最初の 2 定数は Control-C および Control-Break 打鍵イベントをサブプロセスに送ります。その他の値は、 TerminateProcess() API を使います。(Contributed by Miki Tebeka; issue 1220212 [http://bugs.python.org/issue1220212].)

os.listdir() 関数は、空のパスに対してちゃんと失敗するようになりました。 (Fixed by Hirokazu Yamamoto; issue 5913 [http://bugs.python.org/issue5913].)

mimelib モジュールは、初期化の際に Windows レジストリから MIME データベースを正しく読みこむようになりました。 (Patch by Gabriel Genellina; issue 4969 [http://bugs.python.org/issue4969].)

ポート特有の変更: Mac OS X

追加されたパッケージを、システムインストレーションとユーザがインストールした同じバージョンのコピーで共有するために、 sys.path に /Library/Python/2.7/site-packages が追加されました。 (Changed by Ronald Oussoren; issue 4865 [http://bugs.python.org/issue4865].)

ポート特有の変更: FreeBSD

FreeBSD 7.1 の、他のルーティングテーブルを選択するための getsockopt()/setsockopt() で使われている SO_SETFIB 定数が、 socket モジュールで使えるようになりました。(Added by Kyle VanderBeek; issue 8235 [http://bugs.python.org/issue8235].)

その他の変更と修正

ベンチマークスクリプトの 2 つ、 iobench および ccbench, が Tools ディレクトリに追加されました。 iobench は、様々な演算を実行している間 open() によって返された組み込みファイル I/O オブジェクトの速度を計測し、 ccbench は、変化する数のスレッドを使っていくつかのタスクを処理するときの計算スループット、スレッド切り替えレイテンシ、IO 処理バンド幅の計測を試みる同時実行ベンチマークです。

Tools/i18n/msgfmt.py スクリプトは、複数の形式の .po ファイルを理解できるようになりました。(Fixed by Martin von Löwis; issue 5464 [http://bugs.python.org/issue5464].)

既存の対応する .py が存在する .pyc または .pyo ファイルからモジュールを import するとき、結果のコードオブジェクトの co_filename 属性は、元のファイル名が廃止されたとき、上書きされます。これは、ファイルがリネーム、移動、異なるパスを通したアクセスをされたときに起こりえます。(Patch by Ziga Seilnacht and Jean-Paul Calderone; issue 1180193 [http://bugs.python.org/issue1180193].)

regrtest.py スクリプトは、テストを乱順に実行する -r オプションの、ランダムシードに使われる整数を取る --randseed= スイッチを取るようになりました。 -r オプションは、使われたシードも報告します。 (Added by Collin Winter.)

もう一つの regrtest.py スイッチは -j で、いくつのテストを並行して実行するかを指定する整数です。これにより、マルチコア機での合計実行時間を短縮できます。このオプションは、実行時間を長くすることで知られている -R スイッチなど、いくつかの他のオプションと互換です。 (Added by Antoine Pitrou, issue 6152 [http://bugs.python.org/issue6152].) これはまた、選ばれたテストを失敗するまでループして実行する -F スイッチとも同時に使えます。(Added by Antoine Pitrou; issue 7312 [http://bugs.python.org/issue7312].)

スクリプトとして実行されるとき、 py_compile.py モジュールは標準入力を読み込んでコンパイルするファイル名のリストとする '-' を引数として受け付けるようになりました。(Contributed by Piotr Ożarowski; issue 8233 [http://bugs.python.org/issue8233].)

Python 2.7 への移植

この説では、先に説明した変更その他のバグ修正の中で、コードの変更を必要とするかもしれないものを列挙します:

range() 関数は、引数をより一貫して処理するようになりました。浮動小数点数でもなく整数でもない引数が与えられたら、その __int__() を呼び出すようになりました。(Fixed by Alexander Belopolsky; issue 1533 [http://bugs.python.org/issue1533].)

文字列 format() メソッドは浮動小数点数および複素数に使われるデフォルトの精度を、 str() で使われる精度に合わせ、小数第 6 位から 12 位に変更しました。 (Changed by Eric Smith; issue 5920 [http://bugs.python.org/issue5920].)

with 文の最適化のため、特殊メソッド __enter__() および __exit__() はオブジェクトの型に属さなければならず、オブジェクトのインスタンスには直接取り付けられません。これは (object から導出された) 新スタイルクラスと C 拡張型に影響します。 (issue 6101 [http://bugs.python.org/issue6101].)

Python 2.6 におけるバグのため、 __exit__() の exc_value パラメタははよく、例外のインスタンスではなく文字列表現になっていました。これは 2.7 では修正され、 exc_value は期待通りインスタンスになります。 (Fixed by Florent Xicluna; issue 7853 [http://bugs.python.org/issue7853].)

__slots__ を使って属性の制限が設定されたとき、設定されていない属性を削除しても AttributeError が送出されないように修正されました。 (Fixed by Benjamin Peterson; issue 7604 [http://bugs.python.org/issue7604].)

標準ライブラリでは:

年がサポートされている範囲外にはみ出るような datetime インスタンスの演算が、 OverflowError を送出しないことがありました。このようなエラーはより注意深く調べられ、例外を送出するようになりました。(Reported by Mark Leander, patch by Anand B. Pillai and Alexander Belopolsky; issue 7150 [http://bugs.python.org/issue7150].)

Decimal インスタンスを文字列の format() メソッドに使うとき、デフォルトの揃えは以前は左揃えでした。これは右揃えに変更され、プログラムの出力が変わるかもしれません。 (Changed by Mark Dickinson; issue 6857 [http://bugs.python.org/issue6857].)

signaling NaN 値 (または sNAN) を含む比較は、比較演算子に依って静かに真や偽となるのではなく、 InvalidOperation を合図するようになりました。quiet NaN 値 (または NaN) はハッシュ可能になりました。(Fixed by Mark Dickinson; issue 7279 [http://bugs.python.org/issue7279].)

ElementTree ライブラリ xml.etree は、 (<?xml-stylesheet href=”#style1”?> のような) 命令や (<!– comment –> のような) コメントを処理する XML を出力するときにアンパサンドおよび角括弧をエスケープしなくなりました。 (Patch by Neil Muller; issue 2746 [http://bugs.python.org/issue2746].)

StringIO オブジェクトの readline() メソッドは、ファイル風のオブジェクトのように、負の長さが要求されたとき、何もしなくなりました。(issue 7348 [http://bugs.python.org/issue7348])

syslog モジュールは、識別子として以前のデフォルト値である 'python' ではなく、 sys.argv[0] の値を使うようになりました。 (Changed by Sean Reifschneider; issue 8451 [http://bugs.python.org/issue8451].)

tarfile モジュールのデフォルトエラー処理が変更され、致命的なエラーを抑制しないようになりました。デフォルトのエラーレベルは以前は 0 で、エラーはメッセージとしてデバッグログに書き込まれるだけでしたが、デバッグログはデフォルトでは活性化されていないため、エラーは顧みられませんでした。デフォルトのエラーレベルは 1 になり、エラーがあれば例外が送出されます。 (Changed by Lars Gustäbel; issue 7357 [http://bugs.python.org/issue7357].)

urlparse モジュールの urlsplit() は、未知の URL スキームを RFC 3986 [http://tools.ietf.org/html/rfc3986.html] に応じた方法で処理します。 URL が "<something>://..." の形式なら、 :// の前のテキストを、それがモジュールの知らない作り物のスキームであってさえ、スキームとして扱います。この変更は、古い働きを使って動作していたコードを破壊することがあります。例えば、Python 2.6.4 や 2.5 は以下を返します:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', '', '//host/filename?query', '', '')

Python 2.7 (や Python 2.6.5) は以下を返します:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', 'host', '/filename?query', '', '')

(Python 2.7 では、これは普通のタプルではなく名前付きタプルを返すので、実際は微妙に異なる出力をします。)

C 拡張では:

PyArg_Parse* 系統の関数で整数フォーマットコードを使う C 拡張は、 DeprecationWarning を引き起こすのではなく、 TypeError 例外を送出するようになりました。(issue 5080 [http://bugs.python.org/issue5080])

非推奨となった古い PyOS_ascii_strtod() および PyOS_ascii_atof() 関数の代わりに、新しい PyOS_string_to_double() 関数を使ってください。

Python を埋め込んだアプリケーションでは:

PySys_SetArgvEx() 関数が追加され、既存の PySys_SetArgv() 関数が使われた時のセキュリティホールをを塞ぐことができるようになりました。 PySys_SetArgv() を呼び出していないか調べ、 updatepath を偽に設定した PySys_SetArgvEx() を使うべきかよく考えてください。

謝辞

著者は、以下の方々がこの記事の多くの草稿に提案、修正、そして助力を差し伸べてくださったことに感謝の意を表したいと思います: Nick Coghlan, Philip Jenvey, Ryan Lovett, R. David Murray, Hugh Secker-Walker.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

What’s New in Python (英語) »

What’s New in Python 2.6

Author: | A.M. Kuchling (amk at amk.ca)
Release: | 2.7ja1
Date: | 2011年 12月 26日

This article explains the new features in Python 2.6, released on October 1 2008. The release schedule is described in PEP 361 [http://www.python.org/dev/peps/pep-0361].

The major theme of Python 2.6 is preparing the migration path to Python 3.0, a major redesign of the language. Whenever possible, Python 2.6 incorporates new features and syntax from 3.0 while remaining compatible with existing code by not removing older features or syntax. When it’s not possible to do that, Python 2.6 tries to do what it can, adding compatibility functions in a future_builtins module and a -3 switch to warn about usages that will become unsupported in 3.0.

Some significant new packages have been added to the standard library, such as the multiprocessing and json modules, but there aren’t many new features that aren’t related to Python 3.0 in some way.

Python 2.6 also sees a number of improvements and bugfixes throughout the source. A search through the change logs finds there were 259 patches applied and 612 bugs fixed between Python 2.5 and 2.6. Both figures are likely to be underestimates.

This article doesn’t attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.6. If you want to understand the rationale for the design and implementation, refer to the PEP for a particular new feature. Whenever possible, “What’s New in Python” links to the bug/patch item for each change.

Python 3.0

The development cycle for Python versions 2.6 and 3.0 was synchronized, with the alpha and beta releases for both versions being made on the same days. The development of 3.0 has influenced many features in 2.6.

Python 3.0 is a far-ranging redesign of Python that breaks compatibility with the 2.x series. This means that existing Python code will need some conversion in order to run on Python 3.0. However, not all the changes in 3.0 necessarily break compatibility. In cases where new features won’t cause existing code to break, they’ve been backported to 2.6 and are described in this document in the appropriate place. Some of the 3.0-derived features are:

A __complex__() method for converting objects to a complex number.

Alternate syntax for catching exceptions: except TypeError as exc.

The addition of functools.reduce() as a synonym for the built-in reduce() function.

Python 3.0 adds several new built-in functions and changes the semantics of some existing builtins. Functions that are new in 3.0 such as bin() have simply been added to Python 2.6, but existing builtins haven’t been changed; instead, the future_builtins module has versions with the new 3.0 semantics. Code written to be compatible with 3.0 can do from future_builtins import hex, map as necessary.

A new command-line switch, -3, enables warnings about features that will be removed in Python 3.0. You can run code with this switch to see how much work will be necessary to port code to 3.0. The value of this switch is available to Python code as the boolean variable sys.py3kwarning, and to C extension code as Py_Py3kWarningFlag.

参考

The 3xxx series of PEPs, which contains proposals for Python 3.0. PEP 3000 [http://www.python.org/dev/peps/pep-3000] describes the development process for Python 3.0. Start with PEP 3100 [http://www.python.org/dev/peps/pep-3100] that describes the general goals for Python 3.0, and then explore the higher-numbered PEPS that propose specific features.

Changes to the Development Process

While 2.6 was being developed, the Python development process underwent two significant changes: we switched from SourceForge’s issue tracker to a customized Roundup installation, and the documentation was converted from LaTeX to reStructuredText.

New Issue Tracker: Roundup

For a long time, the Python developers had been growing increasingly annoyed by SourceForge’s bug tracker. SourceForge’s hosted solution doesn’t permit much customization; for example, it wasn’t possible to customize the life cycle of issues.

The infrastructure committee of the Python Software Foundation therefore posted a call for issue trackers, asking volunteers to set up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: Jira [http://www.atlassian.com/software/jira/], Launchpad [http://www.launchpad.net], Roundup [http://roundup.sourceforge.net/], and Trac [http://trac.edgewall.org/]. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that offers no-cost hosted instances to free-software projects; Roundup is an open-source project that requires volunteers to administer it and a server to host it.

After posting a call for volunteers, a new Roundup installation was set up at http://bugs.python.org. One installation of Roundup can host multiple trackers, and this server now also hosts issue trackers for Jython and for the Python web site. It will surely find other uses in the future. Where possible, this edition of “What’s New in Python” links to the bug/patch item for each change.

Hosting of the Python bug tracker is kindly provided by Upfront Systems [http://www.upfrontsystems.co.za/] of Stellenbosch, South Africa. Martin von Loewis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at http://svn.python.org/view/tracker/importer/ and may be useful to other projects wishing to move from SourceForge to Roundup.

参考

http://bugs.python.org

The Python bug tracker.

http://bugs.jython.org:

The Jython bug tracker.

http://roundup.sourceforge.net/

Roundup downloads and documentation.

http://svn.python.org/view/tracker/importer/

Martin von Loewis’s conversion scripts.

New Documentation Format: reStructuredText Using Sphinx

The Python documentation was written using LaTeX since the project started around 1989. In the 1980s and early 1990s, most documentation was printed out for later study, not viewed online. LaTeX was widely used because it provided attractive printed output while remaining straightforward to write once the basic rules of the markup were learned.

Today LaTeX is still used for writing publications destined for printing, but the landscape for programming tools has shifted. We no longer print out reams of documentation; instead, we browse through it online and HTML has become the most important format to support. Unfortunately, converting LaTeX to HTML is fairly complicated and Fred L. Drake Jr., the long-time Python documentation editor, spent a lot of time maintaining the conversion process. Occasionally people would suggest converting the documentation into SGML and later XML, but performing a good conversion is a major task and no one ever committed the time required to finish the job.

During the 2.6 development cycle, Georg Brandl put a lot of effort into building a new toolchain for processing the documentation. The resulting package is called Sphinx, and is available from http://sphinx.pocoo.org/.

Sphinx concentrates on HTML output, producing attractively styled and modern HTML; printed output is still supported through conversion to LaTeX. The input format is reStructuredText, a markup syntax supporting custom extensions and directives that is commonly used in the Python community.

Sphinx is a standalone package that can be used for writing, and almost two dozen other projects (listed on the Sphinx web site [http://sphinx.pocoo.org/examples.html]) have adopted Sphinx as their documentation tool.

参考

Python のドキュメントの作成

Describes how to write for Python’s documentation.

Sphinx [http://sphinx.pocoo.org/]

Documentation and code for the Sphinx toolchain.

Docutils [http://docutils.sf.net]

The underlying reStructuredText parser and toolset.

PEP 343: The ‘with’ statement

The previous version, Python 2.5, added the ‘with‘ statement as an optional feature, to be enabled by a from __future__ import with_statement directive. In 2.6 the statement no longer needs to be specially enabled; this means that with is now always a keyword. The rest of this section is a copy of the corresponding section from the “What’s New in Python 2.5” document; if you’re familiar with the ‘with‘ statement from Python 2.5, you can skip this section.

The ‘with‘ statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. In this section, I’ll discuss the statement as it will commonly be used. In the next section, I’ll examine the implementation details and show how to write objects for use with this statement.

The ‘with‘ statement is a control-flow structure whose basic structure is:

with expression [as variable]:
    with-block

The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has __enter__() and __exit__() methods).

The object’s __enter__() is called before with-block is executed and therefore can run set-up code. It also may return a value that is bound to the name variable, if given. (Note carefully that variable is not assigned the result of expression.)

After execution of the with-block is finished, the object’s __exit__() method is called, even if the block raised an exception, and can therefore run clean-up code.

Some standard Python objects now support the context management protocol and can be used with the ‘with‘ statement. File objects are one example:

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line
        ... more processing code ...

After this statement has executed, the file object in f will have been automatically closed, even if the for loop raised an exception part- way through the block.

ノート

In this case, f is the same object created by open(), because file.__enter__() returns self.

The threading module’s locks and condition variables also support the ‘with‘ statement:

lock = threading.Lock()
with lock:
    # Critical section of code
    ...

The lock is acquired before the block is executed and always released once the block is complete.

The localcontext() function in the decimal module makes it easy to save and restore the current decimal context, which encapsulates the desired precision and rounding characteristics for computations:

from decimal import Decimal, Context, localcontext

# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()

with localcontext(Context(prec=16)):
    # All code in this block uses a precision of 16 digits.
    # The original context is restored on exiting the block.
    print v.sqrt()

Writing Context Managers

Under the hood, the ‘with‘ statement is fairly complicated. Most people will only use ‘with‘ in company with existing objects and don’t need to know these details, so you can skip the rest of this section if you like. Authors of new objects will need to understand the details of the underlying implementation and should keep reading.

A high-level explanation of the context management protocol is:

The expression is evaluated and should result in an object called a “context manager”. The context manager must have __enter__() and __exit__() methods.

The context manager’s __enter__() method is called. The value returned is assigned to VAR. If no as VAR clause is present, the value is simply discarded.

The code in BLOCK is executed.

If BLOCK raises an exception, the context manager’s __exit__() method is called with three arguments, the exception details (type, value, traceback, the same values returned by sys.exc_info(), which can also be None if no exception occurred). The method’s return value controls whether an exception is re-raised: any false value re-raises the exception, and True will result in suppressing it. You’ll only rarely want to suppress the exception, because if you do the author of the code containing the ‘with‘ statement will never realize anything went wrong.

If BLOCK didn’t raise an exception, the __exit__() method is still called, but type, value, and traceback are all None.

Let’s think through an example. I won’t present detailed code but will only sketch the methods necessary for a database that supports transactions.

(For people unfamiliar with database terminology: a set of changes to the database are grouped into a transaction. Transactions can be either committed, meaning that all the changes are written into the database, or rolled back, meaning that the changes are all discarded and the database is unchanged. See any database textbook for more information.)

Let’s assume there’s an object representing a database connection. Our goal will be to let the user write code like this:

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... more operations ...

The transaction should be committed if the code in the block runs flawlessly or rolled back if there’s an exception. Here’s the basic interface for DatabaseConnection that I’ll assume:

class DatabaseConnection:
    # Database interface
    def cursor(self):
        "Returns a cursor object and starts a new transaction"
    def commit(self):
        "Commits current transaction"
    def rollback(self):
        "Rolls back current transaction"

The __enter__() method is pretty easy, having only to start a new transaction. For this application the resulting cursor object would be a useful result, so the method will return it. The user can then add as cursor to their ‘with‘ statement to bind the cursor to a variable name.

class DatabaseConnection:
    ...
    def __enter__(self):
        # Code to start a new transaction
        cursor = self.cursor()
        return cursor

The __exit__() method is the most complicated because it’s where most of the work has to be done. The method has to check if an exception occurred. If there was no exception, the transaction is committed. The transaction is rolled back if there was an exception.

In the code below, execution will just fall off the end of the function, returning the default value of None. None is false, so the exception will be re-raised automatically. If you wished, you could be more explicit and add a return statement at the marked location.

class DatabaseConnection:
    ...
    def __exit__(self, type, value, tb):
        if tb is None:
            # No exception, so commit
            self.commit()
        else:
            # Exception occurred, so rollback.
            self.rollback()
            # return False

The contextlib module

The contextlib module provides some functions and a decorator that are useful when writing objects for use with the ‘with‘ statement.

The decorator is called contextmanager(), and lets you write a single generator function instead of defining a new class. The generator should yield exactly one value. The code up to the yield will be executed as the __enter__() method, and the value yielded will be the method’s return value that will get bound to the variable in the ‘with‘ statement’s as clause, if any. The code after the yield will be executed in the __exit__() method. Any exception raised in the block will be raised by the yield statement.

Using this decorator, our database example from the previous section could be written as:

from contextlib import contextmanager

@contextmanager
def db_transaction(connection):
    cursor = connection.cursor()
    try:
        yield cursor
    except:
        connection.rollback()
        raise
    else:
        connection.commit()

db = DatabaseConnection()
with db_transaction(db) as cursor:
    ...

The contextlib module also has a nested(mgr1, mgr2, ...) function that combines a number of context managers so you don’t need to write nested ‘with‘ statements. In this example, the single ‘with‘ statement both starts a database transaction and acquires a thread lock:

lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
    ...

Finally, the closing() function returns its argument so that it can be bound to a variable, and calls the argument’s .close() method at the end of the block.

import urllib, sys
from contextlib import closing

with closing(urllib.urlopen('http://www.yahoo.com')) as f:
    for line in f:
        sys.stdout.write(line)

参考

PEP 343 [http://www.python.org/dev/peps/pep-0343] - The “with” statement

PEP written by Guido van Rossum and Nick Coghlan; implemented by Mike Bland, Guido van Rossum, and Neal Norwitz. The PEP shows the code generated for a ‘with‘ statement, which can be helpful in learning how the statement works.

The documentation for the contextlib module.

PEP 366: Explicit Relative Imports From a Main Module

Python’s -m switch allows running a module as a script. When you ran a module that was located inside a package, relative imports didn’t work correctly.

The fix for Python 2.6 adds a __package__ attribute to modules. When this attribute is present, relative imports will be relative to the value of this attribute instead of the __name__ attribute.

PEP 302-style importers can then set __package__ as necessary. The runpy module that implements the -m switch now does this, so relative imports will now work correctly in scripts running from inside a package.

PEP 370: Per-user site-packages Directory

When you run Python, the module search path sys.path usually includes a directory whose path ends in "site-packages". This directory is intended to hold locally-installed packages available to all users using a machine or a particular site installation.

Python 2.6 introduces a convention for user-specific site directories. The directory varies depending on the platform:

Unix and Mac OS X: ~/.local/

Windows: %APPDATA%/Python

Within this directory, there will be version-specific subdirectories, such as lib/python2.6/site-packages on Unix/Mac OS and Python26/site-packages on Windows.

If you don’t like the default directory, it can be overridden by an environment variable. PYTHONUSERBASE sets the root directory used for all Python versions supporting this feature. On Windows, the directory for application-specific data can be changed by setting the APPDATA environment variable. You can also modify the site.py file for your Python installation.

The feature can be disabled entirely by running Python with the -s option or setting the PYTHONNOUSERSITE environment variable.

参考

PEP 370 [http://www.python.org/dev/peps/pep-0370] - Per-user site-packages Directory

PEP written and implemented by Christian Heimes.

PEP 371: The multiprocessing Package

The new multiprocessing package lets Python programs create new processes that will perform a computation and return a result to the parent. The parent and child processes can communicate using queues and pipes, synchronize their operations using locks and semaphores, and can share simple arrays of data.

The multiprocessing module started out as an exact emulation of the threading module using processes instead of threads. That goal was discarded along the path to Python 2.6, but the general approach of the module is still similar. The fundamental class is the Process, which is passed a callable object and a collection of arguments. The start() method sets the callable running in a subprocess, after which you can call the is_alive() method to check whether the subprocess is still running and the join() method to wait for the process to exit.

Here’s a simple example where the subprocess will calculate a factorial. The function doing the calculation is written strangely so that it takes significantly longer when the input argument is a multiple of 4.

import time
from multiprocessing import Process, Queue

def factorial(queue, N):
    "Compute a factorial."
    # If N is a multiple of 4, this function will take much longer.
    if (N % 4) == 0:
        time.sleep(.05 * N/4)

    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Put the result on the queue
    queue.put(fact)

if __name__ == '__main__':
    queue = Queue()

    N = 5

    p = Process(target=factorial, args=(queue, N))
    p.start()
    p.join()

    result = queue.get()
    print 'Factorial', N, '=', result

A Queue is used to communicate the input parameter N and the result. The Queue object is stored in a global variable. The child process will use the value of the variable when the child was created; because it’s a Queue, parent and child can use the object to communicate. (If the parent were to change the value of the global variable, the child’s value would be unaffected, and vice versa.)

Two other classes, Pool and Manager, provide higher-level interfaces. Pool will create a fixed number of worker processes, and requests can then be distributed to the workers by calling apply() or apply_async() to add a single request, and map() or map_async() to add a number of requests. The following code uses a Pool to spread requests across 5 worker processes and retrieve a list of results:

from multiprocessing import Pool

def factorial(N, dictionary):
    "Compute a factorial."
    ...
p = Pool(5)
result = p.map(factorial, range(1, 1000, 10))
for v in result:
    print v

This produces the following output:

1
39916800
51090942171709440000
8222838654177922817725562880000000
33452526613163807108170062053440751665152000000000
...

The other high-level interface, the Manager class, creates a separate server process that can hold master copies of Python data structures. Other processes can then access and modify these data structures using proxy objects. The following example creates a shared dictionary by calling the dict() method; the worker processes then insert values into the dictionary. (Locking is not done for you automatically, which doesn’t matter in this example. Manager‘s methods also include Lock(), RLock(), and Semaphore() to create shared locks.)

import time
from multiprocessing import Pool, Manager

def factorial(N, dictionary):
    "Compute a factorial."
    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Store result in dictionary
    dictionary[N] = fact

if __name__ == '__main__':
    p = Pool(5)
    mgr = Manager()
    d = mgr.dict()         # Create shared dictionary

    # Run tasks using the pool
    for N in range(1, 1000, 10):
        p.apply_async(factorial, (N, d))

    # Mark pool as closed -- no more tasks can be added.
    p.close()

    # Wait for tasks to exit
    p.join()

    # Output results
    for k, v in sorted(d.items()):
        print k, v

This will produce the output:

1 1
11 39916800
21 51090942171709440000
31 8222838654177922817725562880000000
41 33452526613163807108170062053440751665152000000000
51 15511187532873822802242430164693032110632597200169861120000...

参考

The documentation for the multiprocessing module.

PEP 371 [http://www.python.org/dev/peps/pep-0371] - Addition of the multiprocessing package

PEP written by Jesse Noller and Richard Oudkerk; implemented by Richard Oudkerk and Jesse Noller.

PEP 3101: Advanced String Formatting

In Python 3.0, the % operator is supplemented by a more powerful string formatting method, format(). Support for the str.format() method has been backported to Python 2.6.

In 2.6, both 8-bit and Unicode strings have a .format() method that treats the string as a template and takes the arguments to be formatted. The formatting template uses curly brackets ({, }) as special characters:

>>> # Substitute positional argument 0 into the string.
>>> "User ID: {0}".format("root")
'User ID: root'
>>> # Use the named keyword arguments
>>> "User ID: {uid}   Last seen: {last_login}".format(
...    uid="root",
...    last_login = "5 Mar 2008 07:20")
'User ID: root   Last seen: 5 Mar 2008 07:20'

Curly brackets can be escaped by doubling them:

>>> "Empty dict: {{}}".format()
"Empty dict: {}"

Field names can be integers indicating positional arguments, such as {0}, {1}, etc. or names of keyword arguments. You can also supply compound field names that read attributes or access dictionary keys:

>>> import sys
>>> print 'Platform: {0.platform}\nPython version: {0.version}'.format(sys)
Platform: darwin
Python version: 2.6a1+ (trunk:61261M, Mar  5 2008, 20:29:41)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)]'

>>> import mimetypes
>>> 'Content-type: {0[.mp4]}'.format(mimetypes.types_map)
'Content-type: video/mp4'

Note that when using dictionary-style notation such as [.mp4], you don’t need to put any quotation marks around the string; it will look up the value using .mp4 as the key. Strings beginning with a number will be converted to an integer. You can’t write more complicated expressions inside a format string.

So far we’ve shown how to specify which field to substitute into the resulting string. The precise formatting used is also controllable by adding a colon followed by a format specifier. For example:

>>> # Field 0: left justify, pad to 15 characters
>>> # Field 1: right justify, pad to 6 characters
>>> fmt = '{0:15} ${1:>6}'
>>> fmt.format('Registration', 35)
'Registration    $    35'
>>> fmt.format('Tutorial', 50)
'Tutorial        $    50'
>>> fmt.format('Banquet', 125)
'Banquet         $   125'

Format specifiers can reference other fields through nesting:

>>> fmt = '{0:{1}}'
>>> width = 15
>>> fmt.format('Invoice #1234', width)
'Invoice #1234  '
>>> width = 35
>>> fmt.format('Invoice #1234', width)
'Invoice #1234                      '

The alignment of a field within the desired width can be specified:

Character | Effect
< (default) | Left-align
> | Right-align
^ | Center
= | (For numeric types only) Pad after the sign.

Format specifiers can also include a presentation type, which controls how the value is formatted. For example, floating-point numbers can be formatted as a general number or in exponential notation:

>>> '{0:g}'.format(3.75)
'3.75'
>>> '{0:e}'.format(3.75)
'3.750000e+00'

A variety of presentation types are available. Consult the 2.6 documentation for a complete list; here’s a sample:

b | Binary. Outputs the number in base 2.
c | Character. Converts the integer to the corresponding Unicode character before printing.
d | Decimal Integer. Outputs the number in base 10.
o | Octal format. Outputs the number in base 8.
x | Hex format. Outputs the number in base 16, using lower-case letters for the digits above 9.
e | Exponent notation. Prints the number in scientific notation using the letter ‘e’ to indicate the exponent.
g | General format. This prints the number as a fixed-point number, unless the number is too large, in which case it switches to ‘e’ exponent notation.
n | Number. This is the same as ‘g’ (for floats) or ‘d’ (for integers), except that it uses the current locale setting to insert the appropriate number separator characters.
% | Percentage. Multiplies the number by 100 and displays in fixed (‘f’) format, followed by a percent sign.

Classes and types can define a __format__() method to control how they’re formatted. It receives a single argument, the format specifier:

def __format__(self, format_spec):
    if isinstance(format_spec, unicode):
        return unicode(str(self))
    else:
        return str(self)

There’s also a format() builtin that will format a single value. It calls the type’s __format__() method with the provided specifier:

>>> format(75.6564, '.2f')
'75.66'

参考

書式指定文字列の文法

The reference documentation for format fields.

PEP 3101 [http://www.python.org/dev/peps/pep-3101] - Advanced String Formatting

PEP written by Talin. Implemented by Eric Smith.

PEP 3105: print As a Function

The print statement becomes the print() function in Python 3.0. Making print() a function makes it possible to replace the function by doing def print(...) or importing a new function from somewhere else.

Python 2.6 has a __future__ import that removes print as language syntax, letting you use the functional form instead. For example:

>>> from __future__ import print_function
>>> print('# of entries', len(dictionary), file=sys.stderr)

The signature of the new function is:

def print(*args, sep=' ', end='\n', file=None)

The parameters are:

args: positional arguments whose values will be printed out.

sep: the separator, which will be printed between arguments.

end: the ending text, which will be printed after all of the arguments have been output.

file: the file object to which the output will be sent.

参考

PEP 3105 [http://www.python.org/dev/peps/pep-3105] - Make print a function

PEP written by Georg Brandl.

PEP 3110: Exception-Handling Changes

One error that Python programmers occasionally make is writing the following code:

try:
    ...
except TypeError, ValueError:  # Wrong!
    ...

The author is probably trying to catch both TypeError and ValueError exceptions, but this code actually does something different: it will catch TypeError and bind the resulting exception object to the local name "ValueError". The ValueError exception will not be caught at all. The correct code specifies a tuple of exceptions:

try:
    ...
except (TypeError, ValueError):
    ...

This error happens because the use of the comma here is ambiguous: does it indicate two different nodes in the parse tree, or a single node that’s a tuple?

Python 3.0 makes this unambiguous by replacing the comma with the word “as”. To catch an exception and store the exception object in the variable exc, you must write:

try:
    ...
except TypeError as exc:
    ...

Python 3.0 will only support the use of “as”, and therefore interprets the first example as catching two different exceptions. Python 2.6 supports both the comma and “as”, so existing code will continue to work. We therefore suggest using “as” when writing new Python code that will only be executed with 2.6.

参考

PEP 3110 [http://www.python.org/dev/peps/pep-3110] - Catching Exceptions in Python 3000

PEP written and implemented by Collin Winter.

PEP 3112: Byte Literals

Python 3.0 adopts Unicode as the language’s fundamental string type and denotes 8-bit literals differently, either as b'string' or using a bytes constructor. For future compatibility, Python 2.6 adds bytes as a synonym for the str type, and it also supports the b'' notation.

The 2.6 str differs from 3.0’s bytes type in various ways; most notably, the constructor is completely different. In 3.0, bytes([65, 66, 67]) is 3 elements long, containing the bytes representing ABC; in 2.6, bytes([65, 66, 67]) returns the 12-byte string representing the str() of the list.

The primary use of bytes in 2.6 will be to write tests of object type such as isinstance(x, bytes). This will help the 2to3 converter, which can’t tell whether 2.x code intends strings to contain either characters or 8-bit bytes; you can now use either bytes or str to represent your intention exactly, and the resulting code will also be correct in Python 3.0.

There’s also a __future__ import that causes all string literals to become Unicode strings. This means that \u escape sequences can be used to include Unicode characters:

from __future__ import unicode_literals

s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
     '\u3081\u3000\u751f\u305f\u307e\u3054')

print len(s)               # 12 Unicode characters

At the C level, Python 3.0 will rename the existing 8-bit string type, called PyStringObject in Python 2.x, to PyBytesObject. Python 2.6 uses #define to support using the names PyBytesObject(), PyBytes_Check(), PyBytes_FromStringAndSize(), and all the other functions and macros used with strings.

Instances of the bytes type are immutable just as strings are. A new bytearray type stores a mutable sequence of bytes:

>>> bytearray([65, 66, 67])
bytearray(b'ABC')
>>> b = bytearray(u'\u21ef\u3244', 'utf-8')
>>> b
bytearray(b'\xe2\x87\xaf\xe3\x89\x84')
>>> b[0] = '\xe3'
>>> b
bytearray(b'\xe3\x87\xaf\xe3\x89\x84')
>>> unicode(str(b), 'utf-8')
u'\u31ef \u3244'

Byte arrays support most of the methods of string types, such as startswith()/endswith(), find()/rfind(), and some of the methods of lists, such as append(), pop(), and reverse().

>>> b = bytearray('ABC')
>>> b.append('d')
>>> b.append(ord('e'))
>>> b
bytearray(b'ABCde')

There’s also a corresponding C API, with PyByteArray_FromObject(), PyByteArray_FromStringAndSize(), and various other functions.

参考

PEP 3112 [http://www.python.org/dev/peps/pep-3112] - Bytes literals in Python 3000

PEP written by Jason Orendorff; backported to 2.6 by Christian Heimes.

PEP 3116: New I/O Library

Python’s built-in file objects support a number of methods, but file-like objects don’t necessarily support all of them. Objects that imitate files usually support read() and write(), but they may not support readline(), for example. Python 3.0 introduces a layered I/O library in the io module that separates buffering and text-handling features from the fundamental read and write operations.

There are three levels of abstract base classes provided by the io module:

RawIOBase defines raw I/O operations: read(), readinto(), write(), seek(), tell(), truncate(), and close(). Most of the methods of this class will often map to a single system call. There are also readable(), writable(), and seekable() methods for determining what operations a given object will allow.

Python 3.0 has concrete implementations of this class for files and sockets, but Python 2.6 hasn’t restructured its file and socket objects in this way.

BufferedIOBase is an abstract base class that buffers data in memory to reduce the number of system calls used, making I/O processing more efficient. It supports all of the methods of RawIOBase, and adds a raw attribute holding the underlying raw object.

There are five concrete classes implementing this ABC. BufferedWriter and BufferedReader are for objects that support write-only or read-only usage that have a seek() method for random access. BufferedRandom objects support read and write access upon the same underlying stream, and BufferedRWPair is for objects such as TTYs that have both read and write operations acting upon unconnected streams of data. The BytesIO class supports reading, writing, and seeking over an in-memory buffer.

TextIOBase: Provides functions for reading and writing strings (remember, strings will be Unicode in Python 3.0), and supporting universal newlines. TextIOBase defines the readline() method and supports iteration upon objects.

There are two concrete implementations. TextIOWrapper wraps a buffered I/O object, supporting all of the methods for text I/O and adding a buffer attribute for access to the underlying object. StringIO simply buffers everything in memory without ever writing anything to disk.

(In Python 2.6, io.StringIO is implemented in pure Python, so it’s pretty slow. You should therefore stick with the existing StringIO module or cStringIO for now. At some point Python 3.0’s io module will be rewritten into C for speed, and perhaps the C implementation will be backported to the 2.x releases.)

In Python 2.6, the underlying implementations haven’t been restructured to build on top of the io module’s classes. The module is being provided to make it easier to write code that’s forward-compatible with 3.0, and to save developers the effort of writing their own implementations of buffering and text I/O.

参考

PEP 3116 [http://www.python.org/dev/peps/pep-3116] - New I/O

PEP written by Daniel Stutzbach, Mike Verdone, and Guido van Rossum. Code by Guido van Rossum, Georg Brandl, Walter Doerwald, Jeremy Hylton, Martin von Loewis, Tony Lownds, and others.

PEP 3118: Revised Buffer Protocol

The buffer protocol is a C-level API that lets Python types exchange pointers into their internal representations. A memory-mapped file can be viewed as a buffer of characters, for example, and this lets another module such as re treat memory-mapped files as a string of characters to be searched.

The primary users of the buffer protocol are numeric-processing packages such as NumPy, which expose the internal representation of arrays so that callers can write data directly into an array instead of going through a slower API. This PEP updates the buffer protocol in light of experience from NumPy development, adding a number of new features such as indicating the shape of an array or locking a memory region.

The most important new C API function is PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags), which takes an object and a set of flags, and fills in the Py_buffer structure with information about the object’s memory representation. Objects can use this operation to lock memory in place while an external caller could be modifying the contents, so there’s a corresponding PyBuffer_Release(Py_buffer *view) to indicate that the external caller is done.

The flags argument to PyObject_GetBuffer() specifies constraints upon the memory returned. Some examples are:

PyBUF_WRITABLE indicates that the memory must be writable.

PyBUF_LOCK requests a read-only or exclusive lock on the memory.

PyBUF_C_CONTIGUOUS and PyBUF_F_CONTIGUOUS requests a C-contiguous (last dimension varies the fastest) or Fortran-contiguous (first dimension varies the fastest) array layout.

Two new argument codes for PyArg_ParseTuple(), s* and z*, return locked buffer objects for a parameter.

参考

PEP 3118 [http://www.python.org/dev/peps/pep-3118] - Revising the buffer protocol

PEP written by Travis Oliphant and Carl Banks; implemented by Travis Oliphant.

PEP 3119: Abstract Base Classes

Some object-oriented languages such as Java support interfaces, declaring that a class has a given set of methods or supports a given access protocol. Abstract Base Classes (or ABCs) are an equivalent feature for Python. The ABC support consists of an abc module containing a metaclass called ABCMeta, special handling of this metaclass by the isinstance() and issubclass() builtins, and a collection of basic ABCs that the Python developers think will be widely useful. Future versions of Python will probably add more ABCs.

Let’s say you have a particular class and wish to know whether it supports dictionary-style access. The phrase “dictionary-style” is vague, however. It probably means that accessing items with obj[1] works. Does it imply that setting items with obj[2] = value works? Or that the object will have keys(), values(), and items() methods? What about the iterative variants such as iterkeys()? copy() and update()? Iterating over the object with iter()?

The Python 2.6 collections module includes a number of different ABCs that represent these distinctions. Iterable indicates that a class defines __iter__(), and Container means the class defines a __contains__() method and therefore supports x in y expressions. The basic dictionary interface of getting items, setting items, and keys(), values(), and items(), is defined by the MutableMapping ABC.

You can derive your own classes from a particular ABC to indicate they support that ABC’s interface:

import collections

class Storage(collections.MutableMapping):
    ...

Alternatively, you could write the class without deriving from the desired ABC and instead register the class by calling the ABC’s register() method:

import collections

class Storage:
    ...

collections.MutableMapping.register(Storage)

For classes that you write, deriving from the ABC is probably clearer. The register() method is useful when you’ve written a new ABC that can describe an existing type or class, or if you want to declare that some third-party class implements an ABC. For example, if you defined a PrintableType ABC, it’s legal to do:

# Register Python's types
PrintableType.register(int)
PrintableType.register(float)
PrintableType.register(str)

Classes should obey the semantics specified by an ABC, but Python can’t check this; it’s up to the class author to understand the ABC’s requirements and to implement the code accordingly.

To check whether an object supports a particular interface, you can now write:

def func(d):
    if not isinstance(d, collections.MutableMapping):
        raise ValueError("Mapping object expected, not %r" % d)

Don’t feel that you must now begin writing lots of checks as in the above example. Python has a strong tradition of duck-typing, where explicit type-checking is never done and code simply calls methods on an object, trusting that those methods will be there and raising an exception if they aren’t. Be judicious in checking for ABCs and only do it where it’s absolutely necessary.

You can write your own ABCs by using abc.ABCMeta as the metaclass in a class definition:

from abc import ABCMeta, abstractmethod

class Drawable():
    __metaclass__ = ABCMeta

    @abstractmethod
    def draw(self, x, y, scale=1.0):
        pass

    def draw_doubled(self, x, y):
        self.draw(x, y, scale=2.0)

class Square(Drawable):
    def draw(self, x, y, scale):
        ...

In the Drawable ABC above, the draw_doubled() method renders the object at twice its size and can be implemented in terms of other methods described in Drawable. Classes implementing this ABC therefore don’t need to provide their own implementation of draw_doubled(), though they can do so. An implementation of draw() is necessary, though; the ABC can’t provide a useful generic implementation.

You can apply the @abstractmethod decorator to methods such as draw() that must be implemented; Python will then raise an exception for classes that don’t define the method. Note that the exception is only raised when you actually try to create an instance of a subclass lacking the method:

>>> class Circle(Drawable):
...     pass
...
>>> c = Circle()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Circle with abstract methods draw
>>>

Abstract data attributes can be declared using the @abstractproperty decorator:

from abc import abstractproperty
...

@abstractproperty
def readonly(self):
   return self._x

Subclasses must then define a readonly() property.

参考

PEP 3119 [http://www.python.org/dev/peps/pep-3119] - Introducing Abstract Base Classes

PEP written by Guido van Rossum and Talin. Implemented by Guido van Rossum. Backported to 2.6 by Benjamin Aranguren, with Alex Martelli.

PEP 3127: Integer Literal Support and Syntax

Python 3.0 changes the syntax for octal (base-8) integer literals, prefixing them with “0o” or “0O” instead of a leading zero, and adds support for binary (base-2) integer literals, signalled by a “0b” or “0B” prefix.

Python 2.6 doesn’t drop support for a leading 0 signalling an octal number, but it does add support for “0o” and “0b”:

>>> 0o21, 2*8 + 1
(17, 17)
>>> 0b101111
47

The oct() builtin still returns numbers prefixed with a leading zero, and a new bin() builtin returns the binary representation for a number:

>>> oct(42)
'052'
>>> future_builtins.oct(42)
'0o52'
>>> bin(173)
'0b10101101'

The int() and long() builtins will now accept the “0o” and “0b” prefixes when base-8 or base-2 are requested, or when the base argument is zero (signalling that the base used should be determined from the string):

>>> int ('0o52', 0)
42
>>> int('1101', 2)
13
>>> int('0b1101', 2)
13
>>> int('0b1101', 0)
13

参考

PEP 3127 [http://www.python.org/dev/peps/pep-3127] - Integer Literal Support and Syntax

PEP written by Patrick Maupin; backported to 2.6 by Eric Smith.

PEP 3129: Class Decorators

Decorators have been extended from functions to classes. It’s now legal to write:

@foo
@bar
class A:
  pass

This is equivalent to:

class A:
  pass

A = foo(bar(A))

参考

PEP 3129 [http://www.python.org/dev/peps/pep-3129] - Class Decorators

PEP written by Collin Winter.

PEP 3141: A Type Hierarchy for Numbers

Python 3.0 adds several abstract base classes for numeric types inspired by Scheme’s numeric tower. These classes were backported to 2.6 as the numbers module.

The most general ABC is Number. It defines no operations at all, and only exists to allow checking if an object is a number by doing isinstance(obj, Number).

Complex is a subclass of Number. Complex numbers can undergo the basic operations of addition, subtraction, multiplication, division, and exponentiation, and you can retrieve the real and imaginary parts and obtain a number’s conjugate. Python’s built-in complex type is an implementation of Complex.

Real further derives from Complex, and adds operations that only work on real numbers: floor(), trunc(), rounding, taking the remainder mod N, floor division, and comparisons.

Rational numbers derive from Real, have numerator and denominator properties, and can be converted to floats. Python 2.6 adds a simple rational-number class, Fraction, in the fractions module. (It’s called Fraction instead of Rational to avoid a name clash with numbers.Rational.)

Integral numbers derive from Rational, and can be shifted left and right with << and >>, combined using bitwise operations such as & and |, and can be used as array indexes and slice boundaries.

In Python 3.0, the PEP slightly redefines the existing builtins round(), math.floor(), math.ceil(), and adds a new one, math.trunc(), that’s been backported to Python 2.6. math.trunc() rounds toward zero, returning the closest Integral that’s between the function’s argument and zero.

参考

PEP 3141 [http://www.python.org/dev/peps/pep-3141] - A Type Hierarchy for Numbers

PEP written by Jeffrey Yasskin.

Scheme’s numerical tower [http://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower], from the Guile manual.

Scheme’s number datatypes [http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2] from the R5RS Scheme specification.

The fractions Module

To fill out the hierarchy of numeric types, the fractions module provides a rational-number class. Rational numbers store their values as a numerator and denominator forming a fraction, and can exactly represent numbers such as 2/3 that floating-point numbers can only approximate.

The Fraction constructor takes two Integral values that will be the numerator and denominator of the resulting fraction.

>>> from fractions import Fraction
>>> a = Fraction(2, 3)
>>> b = Fraction(2, 5)
>>> float(a), float(b)
(0.66666666666666663, 0.40000000000000002)
>>> a+b
Fraction(16, 15)
>>> a/b
Fraction(5, 3)

For converting floating-point numbers to rationals, the float type now has an as_integer_ratio() method that returns the numerator and denominator for a fraction that evaluates to the same floating-point value:

>>> (2.5) .as_integer_ratio()
(5, 2)
>>> (3.1415) .as_integer_ratio()
(7074029114692207L, 2251799813685248L)
>>> (1./3) .as_integer_ratio()
(6004799503160661L, 18014398509481984L)

Note that values that can only be approximated by floating-point numbers, such as 1./3, are not simplified to the number being approximated; the fraction attempts to match the floating-point value exactly.

The fractions module is based upon an implementation by Sjoerd Mullender that was in Python’s Demo/classes/ directory for a long time. This implementation was significantly updated by Jeffrey Yasskin.

Other Language Changes

Some smaller changes made to the core Python language are:

Directories and zip archives containing a __main__.py file can now be executed directly by passing their name to the interpreter. The directory or zip archive is automatically inserted as the first entry in sys.path. (Suggestion and initial patch by Andy Chu, subsequently revised by Phillip J. Eby and Nick Coghlan; issue 1739468 [http://bugs.python.org/issue1739468].)

The hasattr() function was catching and ignoring all errors, under the assumption that they meant a __getattr__() method was failing somehow and the return value of hasattr() would therefore be False. This logic shouldn’t be applied to KeyboardInterrupt and SystemExit, however; Python 2.6 will no longer discard such exceptions when hasattr() encounters them. (Fixed by Benjamin Peterson; issue 2196 [http://bugs.python.org/issue2196].)

When calling a function using the ** syntax to provide keyword arguments, you are no longer required to use a Python dictionary; any mapping will now work:

>>> def f(**kw):
...    print sorted(kw)
...
>>> ud=UserDict.UserDict()
>>> ud['a'] = 1
>>> ud['b'] = 'string'
>>> f(**ud)
['a', 'b']

(Contributed by Alexander Belopolsky; issue 1686487 [http://bugs.python.org/issue1686487].)

It’s also become legal to provide keyword arguments after a *args argument to a function call.

>>> def f(*args, **kw):
...     print args, kw
...
>>> f(1,2,3, *(4,5,6), keyword=13)
(1, 2, 3, 4, 5, 6) {'keyword': 13}

Previously this would have been a syntax error. (Contributed by Amaury Forgeot d’Arc; issue 3473 [http://bugs.python.org/issue3473].)

A new builtin, next(iterator, [default]) returns the next item from the specified iterator. If the default argument is supplied, it will be returned if iterator has been exhausted; otherwise, the StopIteration exception will be raised. (Backported in issue 2719 [http://bugs.python.org/issue2719].)

Tuples now have index() and count() methods matching the list type’s index() and count() methods:

>>> t = (0,1,2,3,4,0,1,2)
>>> t.index(3)
3
>>> t.count(0)
2

(Contributed by Raymond Hettinger)

The built-in types now have improved support for extended slicing syntax, accepting various combinations of (start, stop, step). Previously, the support was partial and certain corner cases wouldn’t work. (Implemented by Thomas Wouters.)

Properties now have three attributes, getter, setter and deleter, that are decorators providing useful shortcuts for adding a getter, setter or deleter function to an existing property. You would use them like this:

class C(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

class D(C):
    @C.x.getter
    def x(self):
        return self._x * 2

    @x.setter
    def x(self, value):
        self._x = value / 2

Several methods of the built-in set types now accept multiple iterables: intersection(), intersection_update(), union(), update(), difference() and difference_update().

>>> s=set('1234567890')
>>> s.intersection('abc123', 'cdf246')  # Intersection between all inputs
set(['2'])
>>> s.difference('246', '789')
set(['1', '0', '3', '5'])

(Contributed by Raymond Hettinger.)

Many floating-point features were added. The float() function will now turn the string nan into an IEEE 754 Not A Number value, and +inf and -inf into positive or negative infinity. This works on any platform with IEEE 754 semantics. (Contributed by Christian Heimes; issue 1635 [http://bugs.python.org/issue1635].)

Other functions in the math module, isinf() and isnan(), return true if their floating-point argument is infinite or Not A Number. (issue 1640 [http://bugs.python.org/issue1640])

Conversion functions were added to convert floating-point numbers into hexadecimal strings (issue 3008 [http://bugs.python.org/issue3008]). These functions convert floats to and from a string representation without introducing rounding errors from the conversion between decimal and binary. Floats have a hex() method that returns a string representation, and the float.fromhex() method converts a string back into a number:

>>> a = 3.75
>>> a.hex()
'0x1.e000000000000p+1'
>>> float.fromhex('0x1.e000000000000p+1')
3.75
>>> b=1./3
>>> b.hex()
'0x1.5555555555555p-2'

A numerical nicety: when creating a complex number from two floats on systems that support signed zeros (-0 and +0), the complex() constructor will now preserve the sign of the zero. (Fixed by Mark T. Dickinson; issue 1507 [http://bugs.python.org/issue1507].)

Classes that inherit a __hash__() method from a parent class can set __hash__ = None to indicate that the class isn’t hashable. This will make hash(obj) raise a TypeError and the class will not be indicated as implementing the Hashable ABC.

You should do this when you’ve defined a __cmp__() or __eq__() method that compares objects by their value rather than by identity. All objects have a default hash method that uses id(obj) as the hash value. There’s no tidy way to remove the __hash__() method inherited from a parent class, so assigning None was implemented as an override. At the C level, extensions can set tp_hash to PyObject_HashNotImplemented(). (Fixed by Nick Coghlan and Amaury Forgeot d’Arc; issue 2235 [http://bugs.python.org/issue2235].)

The GeneratorExit exception now subclasses BaseException instead of Exception. This means that an exception handler that does except Exception: will not inadvertently catch GeneratorExit. (Contributed by Chad Austin; issue 1537 [http://bugs.python.org/issue1537].)

Generator objects now have a gi_code attribute that refers to the original code object backing the generator. (Contributed by Collin Winter; issue 1473257 [http://bugs.python.org/issue1473257].)

The compile() built-in function now accepts keyword arguments as well as positional parameters. (Contributed by Thomas Wouters; issue 1444529 [http://bugs.python.org/issue1444529].)

The complex() constructor now accepts strings containing parenthesized complex numbers, meaning that complex(repr(cplx)) will now round-trip values. For example, complex('(3+4j)') now returns the value (3+4j). (issue 1491866 [http://bugs.python.org/issue1491866])

The string translate() method now accepts None as the translation table parameter, which is treated as the identity transformation. This makes it easier to carry out operations that only delete characters. (Contributed by Bengt Richter and implemented by Raymond Hettinger; issue 1193128 [http://bugs.python.org/issue1193128].)

The built-in dir() function now checks for a __dir__() method on the objects it receives. This method must return a list of strings containing the names of valid attributes for the object, and lets the object control the value that dir() produces. Objects that have __getattr__() or __getattribute__() methods can use this to advertise pseudo-attributes they will honor. (issue 1591665 [http://bugs.python.org/issue1591665])

Instance method objects have new attributes for the object and function comprising the method; the new synonym for im_self is __self__, and im_func is also available as __func__. The old names are still supported in Python 2.6, but are gone in 3.0.

An obscure change: when you use the locals() function inside a class statement, the resulting dictionary no longer returns free variables. (Free variables, in this case, are variables referenced in the class statement that aren’t attributes of the class.)

Optimizations

The warnings module has been rewritten in C. This makes it possible to invoke warnings from the parser, and may also make the interpreter’s startup faster. (Contributed by Neal Norwitz and Brett Cannon; issue 1631171 [http://bugs.python.org/issue1631171].)

Type objects now have a cache of methods that can reduce the work required to find the correct method implementation for a particular class; once cached, the interpreter doesn’t need to traverse base classes to figure out the right method to call. The cache is cleared if a base class or the class itself is modified, so the cache should remain correct even in the face of Python’s dynamic nature. (Original optimization implemented by Armin Rigo, updated for Python 2.6 by Kevin Jacobs; issue 1700288 [http://bugs.python.org/issue1700288].)

By default, this change is only applied to types that are included with the Python core. Extension modules may not necessarily be compatible with this cache, so they must explicitly add Py_TPFLAGS_HAVE_VERSION_TAG to the module’s tp_flags field to enable the method cache. (To be compatible with the method cache, the extension module’s code must not directly access and modify the tp_dict member of any of the types it implements. Most modules don’t do this, but it’s impossible for the Python interpreter to determine that. See issue 1878 [http://bugs.python.org/issue1878] for some discussion.)

Function calls that use keyword arguments are significantly faster by doing a quick pointer comparison, usually saving the time of a full string comparison. (Contributed by Raymond Hettinger, after an initial implementation by Antoine Pitrou; issue 1819 [http://bugs.python.org/issue1819].)

All of the functions in the struct module have been rewritten in C, thanks to work at the Need For Speed sprint. (Contributed by Raymond Hettinger.)

Some of the standard built-in types now set a bit in their type objects. This speeds up checking whether an object is a subclass of one of these types. (Contributed by Neal Norwitz.)

Unicode strings now use faster code for detecting whitespace and line breaks; this speeds up the split() method by about 25% and splitlines() by 35%. (Contributed by Antoine Pitrou.) Memory usage is reduced by using pymalloc for the Unicode string’s data.

The with statement now stores the __exit__() method on the stack, producing a small speedup. (Implemented by Jeffrey Yasskin.)

To reduce memory usage, the garbage collector will now clear internal free lists when garbage-collecting the highest generation of objects. This may return memory to the operating system sooner.

Interpreter Changes

Two command-line options have been reserved for use by other Python implementations. The -J switch has been reserved for use by Jython for Jython-specific options, such as switches that are passed to the underlying JVM. -X has been reserved for options specific to a particular implementation of Python such as CPython, Jython, or IronPython. If either option is used with Python 2.6, the interpreter will report that the option isn’t currently used.

Python can now be prevented from writing .pyc or .pyo files by supplying the -B switch to the Python interpreter, or by setting the PYTHONDONTWRITEBYTECODE environment variable before running the interpreter. This setting is available to Python programs as the sys.dont_write_bytecode variable, and Python code can change the value to modify the interpreter’s behaviour. (Contributed by Neal Norwitz and Georg Brandl.)

The encoding used for standard input, output, and standard error can be specified by setting the PYTHONIOENCODING environment variable before running the interpreter. The value should be a string in the form <encoding> or <encoding>:<errorhandler>. The encoding part specifies the encoding’s name, e.g. utf-8 or latin-1; the optional errorhandler part specifies what to do with characters that can’t be handled by the encoding, and should be one of “error”, “ignore”, or “replace”. (Contributed by Martin von Loewis.)

New and Improved Modules

As in every release, Python’s standard library received a number of enhancements and bug fixes. Here’s a partial list of the most notable changes, sorted alphabetically by module name. Consult the Misc/NEWS file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details.

The asyncore and asynchat modules are being actively maintained again, and a number of patches and bugfixes were applied. (Maintained by Josiah Carlson; see issue 1736190 [http://bugs.python.org/issue1736190] for one patch.)

The bsddb module also has a new maintainer, Jesús Cea Avion, and the package is now available as a standalone package. The web page for the package is www.jcea.es/programacion/pybsddb.htm [http://www.jcea.es/programacion/pybsddb.htm]. The plan is to remove the package from the standard library in Python 3.0, because its pace of releases is much more frequent than Python’s.

The bsddb.dbshelve module now uses the highest pickling protocol available, instead of restricting itself to protocol 1. (Contributed by W. Barnes.)

The cgi module will now read variables from the query string of an HTTP POST request. This makes it possible to use form actions with URLs that include query strings such as “/cgi-bin/add.py?category=1”. (Contributed by Alexandre Fiori and Nubis; issue 1817 [http://bugs.python.org/issue1817].)

The parse_qs() and parse_qsl() functions have been relocated from the cgi module to the urlparse module. The versions still available in the cgi module will trigger PendingDeprecationWarning messages in 2.6 (issue 600362 [http://bugs.python.org/issue600362]).

The cmath module underwent extensive revision, contributed by Mark Dickinson and Christian Heimes. Five new functions were added:

polar() converts a complex number to polar form, returning the modulus and argument of the complex number.

rect() does the opposite, turning a modulus, argument pair back into the corresponding complex number.

phase() returns the argument (also called the angle) of a complex number.

isnan() returns True if either the real or imaginary part of its argument is a NaN.

isinf() returns True if either the real or imaginary part of its argument is infinite.

The revisions also improved the numerical soundness of the cmath module. For all functions, the real and imaginary parts of the results are accurate to within a few units of least precision (ulps) whenever possible. See issue 1381 [http://bugs.python.org/issue1381] for the details. The branch cuts for asinh(), atanh(): and atan() have also been corrected.

The tests for the module have been greatly expanded; nearly 2000 new test cases exercise the algebraic functions.

On IEEE 754 platforms, the cmath module now handles IEEE 754 special values and floating-point exceptions in a manner consistent with Annex ‘G’ of the C99 standard.

A new data type in the collections module: namedtuple(typename, fieldnames) is a factory function that creates subclasses of the standard tuple whose fields are accessible by name as well as index. For example:

>>> var_type = collections.namedtuple('variable',
...             'id name type size')
>>> # Names are separated by spaces or commas.
>>> # 'id, name, type, size' would also work.
>>> var_type._fields
('id', 'name', 'type', 'size')

>>> var = var_type(1, 'frequency', 'int', 4)
>>> print var[0], var.id    # Equivalent
1 1
>>> print var[2], var.type  # Equivalent
int int
>>> var._asdict()
{'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
>>> v2 = var._replace(name='amplitude')
>>> v2
variable(id=1, name='amplitude', type='int', size=4)

Several places in the standard library that returned tuples have been modified to return namedtuple instances. For example, the Decimal.as_tuple() method now returns a named tuple with sign, digits, and exponent fields.

(Contributed by Raymond Hettinger.)

Another change to the collections module is that the deque type now supports an optional maxlen parameter; if supplied, the deque’s size will be restricted to no more than maxlen items. Adding more items to a full deque causes old items to be discarded.

>>> from collections import deque
>>> dq=deque(maxlen=3)
>>> dq
deque([], maxlen=3)
>>> dq.append(1) ; dq.append(2) ; dq.append(3)
>>> dq
deque([1, 2, 3], maxlen=3)
>>> dq.append(4)
>>> dq
deque([2, 3, 4], maxlen=3)

(Contributed by Raymond Hettinger.)

The Cookie module’s Morsel objects now support an httponly attribute. In some browsers. cookies with this attribute set cannot be accessed or manipulated by JavaScript code. (Contributed by Arvin Schnell; issue 1638033 [http://bugs.python.org/issue1638033].)

A new window method in the curses module, chgat(), changes the display attributes for a certain number of characters on a single line. (Contributed by Fabian Kreutz.)

# Boldface text starting at y=0,x=21
# and affecting the rest of the line.
stdscr.chgat(0, 21, curses.A_BOLD)

The Textbox class in the curses.textpad module now supports editing in insert mode as well as overwrite mode. Insert mode is enabled by supplying a true value for the insert_mode parameter when creating the Textbox instance.

The datetime module’s strftime() methods now support a %f format code that expands to the number of microseconds in the object, zero-padded on the left to six places. (Contributed by Skip Montanaro; issue 1158 [http://bugs.python.org/issue1158].)

The decimal module was updated to version 1.66 of the General Decimal Specification [http://www2.hursley.ibm.com/decimal/decarith.html]. New features include some methods for some basic mathematical functions such as exp() and log10():

>>> Decimal(1).exp()
Decimal("2.718281828459045235360287471")
>>> Decimal("2.7182818").ln()
Decimal("0.9999999895305022877376682436")
>>> Decimal(1000).log10()
Decimal("3")

The as_tuple() method of Decimal objects now returns a named tuple with sign, digits, and exponent fields.

(Implemented by Facundo Batista and Mark Dickinson. Named tuple support added by Raymond Hettinger.)

The difflib module’s SequenceMatcher class now returns named tuples representing matches, with a, b, and size attributes. (Contributed by Raymond Hettinger.)

An optional timeout parameter, specifying a timeout measured in seconds, was added to the ftplib.FTP class constructor as well as the connect() method. (Added by Facundo Batista.) Also, the FTP class’s storbinary() and storlines() now take an optional callback parameter that will be called with each block of data after the data has been sent. (Contributed by Phil Schwartz; issue 1221598 [http://bugs.python.org/issue1221598].)

The reduce() built-in function is also available in the functools module. In Python 3.0, the builtin has been dropped and reduce() is only available from functools; currently there are no plans to drop the builtin in the 2.x series. (Patched by Christian Heimes; issue 1739906 [http://bugs.python.org/issue1739906].)

When possible, the getpass module will now use /dev/tty to print a prompt message and read the password, falling back to standard error and standard input. If the password may be echoed to the terminal, a warning is printed before the prompt is displayed. (Contributed by Gregory P. Smith.)

The glob.glob() function can now return Unicode filenames if a Unicode path was used and Unicode filenames are matched within the directory. (issue 1001604 [http://bugs.python.org/issue1001604])

A new function in the heapq module, merge(iter1, iter2, ...), takes any number of iterables returning data in sorted order, and returns a new generator that returns the contents of all the iterators, also in sorted order. For example:

>>> list(heapq.merge([1, 3, 5, 9], [2, 8, 16]))
[1, 2, 3, 5, 8, 9, 16]

Another new function, heappushpop(heap, item), pushes item onto heap, then pops off and returns the smallest item. This is more efficient than making a call to heappush() and then heappop().

heapq is now implemented to only use less-than comparison, instead of the less-than-or-equal comparison it previously used. This makes heapq‘s usage of a type match the list.sort() method. (Contributed by Raymond Hettinger.)

An optional timeout parameter, specifying a timeout measured in seconds, was added to the httplib.HTTPConnection and HTTPSConnection class constructors. (Added by Facundo Batista.)

Most of the inspect module’s functions, such as getmoduleinfo() and getargs(), now return named tuples. In addition to behaving like tuples, the elements of the return value can also be accessed as attributes. (Contributed by Raymond Hettinger.)

Some new functions in the module include isgenerator(), isgeneratorfunction(), and isabstract().

The itertools module gained several new functions.

izip_longest(iter1, iter2, ...[, fillvalue]) makes tuples from each of the elements; if some of the iterables are shorter than others, the missing values are set to fillvalue. For example:

>>> tuple(itertools.izip_longest([1,2,3], [1,2,3,4,5]))
((1, 1), (2, 2), (3, 3), (None, 4), (None, 5))

product(iter1, iter2, ..., [repeat=N]) returns the Cartesian product of the supplied iterables, a set of tuples containing every possible combination of the elements returned from each iterable.

>>> list(itertools.product([1,2,3], [4,5,6]))
[(1, 4), (1, 5), (1, 6),
 (2, 4), (2, 5), (2, 6),
 (3, 4), (3, 5), (3, 6)]

The optional repeat keyword argument is used for taking the product of an iterable or a set of iterables with themselves, repeated N times. With a single iterable argument, N-tuples are returned:

>>> list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
 (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]

With two iterables, 2N-tuples are returned.

>>> list(itertools.product([1,2], [3,4], repeat=2))
[(1, 3, 1, 3), (1, 3, 1, 4), (1, 3, 2, 3), (1, 3, 2, 4),
 (1, 4, 1, 3), (1, 4, 1, 4), (1, 4, 2, 3), (1, 4, 2, 4),
 (2, 3, 1, 3), (2, 3, 1, 4), (2, 3, 2, 3), (2, 3, 2, 4),
 (2, 4, 1, 3), (2, 4, 1, 4), (2, 4, 2, 3), (2, 4, 2, 4)]

combinations(iterable, r) returns sub-sequences of length r from the elements of iterable.

>>> list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]
>>> list(itertools.combinations('123', 3))
[('1', '2', '3')]
>>> list(itertools.combinations('1234', 3))
[('1', '2', '3'), ('1', '2', '4'),
 ('1', '3', '4'), ('2', '3', '4')]

permutations(iter[, r]) returns all the permutations of length r of the iterable’s elements. If r is not specified, it will default to the number of elements produced by the iterable.

>>> list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
 (2, 1), (2, 3), (2, 4),
 (3, 1), (3, 2), (3, 4),
 (4, 1), (4, 2), (4, 3)]

itertools.chain(*iterables) is an existing function in itertools that gained a new constructor in Python 2.6. itertools.chain.from_iterable(iterable) takes a single iterable that should return other iterables. chain() will then return all the elements of the first iterable, then all the elements of the second, and so on.

>>> list(itertools.chain.from_iterable([[1,2,3], [4,5,6]]))
[1, 2, 3, 4, 5, 6]

(All contributed by Raymond Hettinger.)

The logging module’s FileHandler class and its subclasses WatchedFileHandler, RotatingFileHandler, and TimedRotatingFileHandler now have an optional delay parameter to their constructors. If delay is true, opening of the log file is deferred until the first emit() call is made. (Contributed by Vinay Sajip.)

TimedRotatingFileHandler also has a utc constructor parameter. If the argument is true, UTC time will be used in determining when midnight occurs and in generating filenames; otherwise local time will be used.

Several new functions were added to the math module:

isinf() and isnan() determine whether a given float is a (positive or negative) infinity or a NaN (Not a Number), respectively.

copysign() copies the sign bit of an IEEE 754 number, returning the absolute value of x combined with the sign bit of y. For example, math.copysign(1, -0.0) returns -1.0. (Contributed by Christian Heimes.)

factorial() computes the factorial of a number. (Contributed by Raymond Hettinger; issue 2138 [http://bugs.python.org/issue2138].)

fsum() adds up the stream of numbers from an iterable, and is careful to avoid loss of precision through using partial sums. (Contributed by Jean Brouwers, Raymond Hettinger, and Mark Dickinson; issue 2819 [http://bugs.python.org/issue2819].)

acosh(), asinh() and atanh() compute the inverse hyperbolic functions.

log1p() returns the natural logarithm of 1+x (base e).

trunc() rounds a number toward zero, returning the closest Integral that’s between the function’s argument and zero. Added as part of the backport of PEP 3141’s type hierarchy for numbers.

The math module has been improved to give more consistent behaviour across platforms, especially with respect to handling of floating-point exceptions and IEEE 754 special values.

Whenever possible, the module follows the recommendations of the C99 standard about 754’s special values. For example, sqrt(-1.) should now give a ValueError across almost all platforms, while sqrt(float('NaN')) should return a NaN on all IEEE 754 platforms. Where Annex ‘F’ of the C99 standard recommends signaling ‘divide-by-zero’ or ‘invalid’, Python will raise ValueError. Where Annex ‘F’ of the C99 standard recommends signaling ‘overflow’, Python will raise OverflowError. (See issue 711019 [http://bugs.python.org/issue711019] and issue 1640 [http://bugs.python.org/issue1640].)

(Contributed by Christian Heimes and Mark Dickinson.)

mmap objects now have a rfind() method that searches for a substring beginning at the end of the string and searching backwards. The find() method also gained an end parameter giving an index at which to stop searching. (Contributed by John Lenton.)

The operator module gained a methodcaller() function that takes a name and an optional set of arguments, returning a callable that will call the named function on any arguments passed to it. For example:

>>> # Equivalent to lambda s: s.replace('old', 'new')
>>> replacer = operator.methodcaller('replace', 'old', 'new')
>>> replacer('old wine in old bottles')
'new wine in new bottles'

(Contributed by Georg Brandl, after a suggestion by Gregory Petrosyan.)

The attrgetter() function now accepts dotted names and performs the corresponding attribute lookups:

>>> inst_name = operator.attrgetter(
...        '__class__.__name__')
>>> inst_name('')
'str'
>>> inst_name(help)
'_Helper'

(Contributed by Georg Brandl, after a suggestion by Barry Warsaw.)

The os module now wraps several new system calls. fchmod(fd, mode) and fchown(fd, uid, gid) change the mode and ownership of an opened file, and lchmod(path, mode) changes the mode of a symlink. (Contributed by Georg Brandl and Christian Heimes.)

chflags() and lchflags() are wrappers for the corresponding system calls (where they’re available), changing the flags set on a file. Constants for the flag values are defined in the stat module; some possible values include UF_IMMUTABLE to signal the file may not be changed and UF_APPEND to indicate that data can only be appended to the file. (Contributed by M. Levinson.)

os.closerange(low, high) efficiently closes all file descriptors from low to high, ignoring any errors and not including high itself. This function is now used by the subprocess module to make starting processes faster. (Contributed by Georg Brandl; issue 1663329 [http://bugs.python.org/issue1663329].)

The os.environ object’s clear() method will now unset the environment variables using os.unsetenv() in addition to clearing the object’s keys. (Contributed by Martin Horcicka; issue 1181 [http://bugs.python.org/issue1181].)

The os.walk() function now has a followlinks parameter. If set to True, it will follow symlinks pointing to directories and visit the directory’s contents. For backward compatibility, the parameter’s default value is false. Note that the function can fall into an infinite recursion if there’s a symlink that points to a parent directory. (issue 1273829 [http://bugs.python.org/issue1273829])

In the os.path module, the splitext() function has been changed to not split on leading period characters. This produces better results when operating on Unix’s dot-files. For example, os.path.splitext('.ipython') now returns ('.ipython', '') instead of ('', '.ipython'). (issue 1115886 [http://bugs.python.org/issue1115886])

A new function, os.path.relpath(path, start='.'), returns a relative path from the start path, if it’s supplied, or from the current working directory to the destination path. (Contributed by Richard Barran; issue 1339796 [http://bugs.python.org/issue1339796].)

On Windows, os.path.expandvars() will now expand environment variables given in the form “%var%”, and “~user” will be expanded into the user’s home directory path. (Contributed by Josiah Carlson; issue 957650 [http://bugs.python.org/issue957650].)

The Python debugger provided by the pdb module gained a new command: “run” restarts the Python program being debugged and can optionally take new command-line arguments for the program. (Contributed by Rocky Bernstein; issue 1393667 [http://bugs.python.org/issue1393667].)

The pdb.post_mortem() function, used to begin debugging a traceback, will now use the traceback returned by sys.exc_info() if no traceback is supplied. (Contributed by Facundo Batista; issue 1106316 [http://bugs.python.org/issue1106316].)

The pickletools module now has an optimize() function that takes a string containing a pickle and removes some unused opcodes, returning a shorter pickle that contains the same data structure. (Contributed by Raymond Hettinger.)

A get_data() function was added to the pkgutil module that returns the contents of resource files included with an installed Python package. For example:

>>> import pkgutil
>>> print pkgutil.get_data('test', 'exception_hierarchy.txt')
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
 ...

(Contributed by Paul Moore; issue 2439 [http://bugs.python.org/issue2439].)

The pyexpat module’s Parser objects now allow setting their buffer_size attribute to change the size of the buffer used to hold character data. (Contributed by Achim Gaedke; issue 1137 [http://bugs.python.org/issue1137].)

The Queue module now provides queue variants that retrieve entries in different orders. The PriorityQueue class stores queued items in a heap and retrieves them in priority order, and LifoQueue retrieves the most recently added entries first, meaning that it behaves like a stack. (Contributed by Raymond Hettinger.)

The random module’s Random objects can now be pickled on a 32-bit system and unpickled on a 64-bit system, and vice versa. Unfortunately, this change also means that Python 2.6’s Random objects can’t be unpickled correctly on earlier versions of Python. (Contributed by Shawn Ligocki; issue 1727780 [http://bugs.python.org/issue1727780].)

The new triangular(low, high, mode) function returns random numbers following a triangular distribution. The returned values are between low and high, not including high itself, and with mode as the most frequently occurring value in the distribution. (Contributed by Wladmir van der Laan and Raymond Hettinger; issue 1681432 [http://bugs.python.org/issue1681432].)

Long regular expression searches carried out by the re module will check for signals being delivered, so time-consuming searches can now be interrupted. (Contributed by Josh Hoyt and Ralf Schmitt; issue 846388 [http://bugs.python.org/issue846388].)

The regular expression module is implemented by compiling bytecodes for a tiny regex-specific virtual machine. Untrusted code could create malicious strings of bytecode directly and cause crashes, so Python 2.6 includes a verifier for the regex bytecode. (Contributed by Guido van Rossum from work for Google App Engine; issue 3487 [http://bugs.python.org/issue3487].)

The rlcompleter module’s Completer.complete() method will now ignore exceptions triggered while evaluating a name. (Fixed by Lorenz Quack; issue 2250 [http://bugs.python.org/issue2250].)

The sched module’s scheduler instances now have a read-only queue attribute that returns the contents of the scheduler’s queue, represented as a list of named tuples with the fields (time, priority, action, argument). (Contributed by Raymond Hettinger; issue 1861 [http://bugs.python.org/issue1861].)

The select module now has wrapper functions for the Linux epoll() and BSD kqueue() system calls. modify() method was added to the existing poll objects; pollobj.modify(fd, eventmask) takes a file descriptor or file object and an event mask, modifying the recorded event mask for that file. (Contributed by Christian Heimes; issue 1657 [http://bugs.python.org/issue1657].)

The shutil.copytree() function now has an optional ignore argument that takes a callable object. This callable will receive each directory path and a list of the directory’s contents, and returns a list of names that will be ignored, not copied.

The shutil module also provides an ignore_patterns() function for use with this new parameter. ignore_patterns() takes an arbitrary number of glob-style patterns and returns a callable that will ignore any files and directories that match any of these patterns. The following example copies a directory tree, but skips both .svn directories and Emacs backup files, which have names ending with ‘~’:

shutil.copytree('Doc/library', '/tmp/library',
                ignore=shutil.ignore_patterns('*~', '.svn'))

(Contributed by Tarek Ziadé; issue 2663 [http://bugs.python.org/issue2663].)

Integrating signal handling with GUI handling event loops like those used by Tkinter or GTk+ has long been a problem; most software ends up polling, waking up every fraction of a second to check if any GUI events have occurred. The signal module can now make this more efficient. Calling signal.set_wakeup_fd(fd) sets a file descriptor to be used; when a signal is received, a byte is written to that file descriptor. There’s also a C-level function, PySignal_SetWakeupFd(), for setting the descriptor.

Event loops will use this by opening a pipe to create two descriptors, one for reading and one for writing. The writable descriptor will be passed to set_wakeup_fd(), and the readable descriptor will be added to the list of descriptors monitored by the event loop via select() or poll(). On receiving a signal, a byte will be written and the main event loop will be woken up, avoiding the need to poll.

(Contributed by Adam Olsen; issue 1583 [http://bugs.python.org/issue1583].)

The siginterrupt() function is now available from Python code, and allows changing whether signals can interrupt system calls or not. (Contributed by Ralf Schmitt.)

The setitimer() and getitimer() functions have also been added (where they’re available). setitimer() allows setting interval timers that will cause a signal to be delivered to the process after a specified time, measured in wall-clock time, consumed process time, or combined process+system time. (Contributed by Guilherme Polo; issue 2240 [http://bugs.python.org/issue2240].)

The smtplib module now supports SMTP over SSL thanks to the addition of the SMTP_SSL class. This class supports an interface identical to the existing SMTP class. (Contributed by Monty Taylor.) Both class constructors also have an optional timeout parameter that specifies a timeout for the initial connection attempt, measured in seconds. (Contributed by Facundo Batista.)

An implementation of the LMTP protocol (RFC 2033 [http://tools.ietf.org/html/rfc2033.html]) was also added to the module. LMTP is used in place of SMTP when transferring e-mail between agents that don’t manage a mail queue. (LMTP implemented by Leif Hedstrom; issue 957003 [http://bugs.python.org/issue957003].)

SMTP.starttls() now complies with RFC 3207 [http://tools.ietf.org/html/rfc3207.html] and forgets any knowledge obtained from the server not obtained from the TLS negotiation itself. (Patch contributed by Bill Fenner; issue 829951 [http://bugs.python.org/issue829951].)

The socket module now supports TIPC (http://tipc.sf.net), a high-performance non-IP-based protocol designed for use in clustered environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; issue 1646 [http://bugs.python.org/issue1646].)

A new function, create_connection(), takes an address and connects to it using an optional timeout value, returning the connected socket object. This function also looks up the address’s type and connects to it using IPv4 or IPv6 as appropriate. Changing your code to use create_connection() instead of socket(socket.AF_INET, ...) may be all that’s required to make your code work with IPv6.

The base classes in the SocketServer module now support calling a handle_timeout() method after a span of inactivity specified by the server’s timeout attribute. (Contributed by Michael Pomraning.) The serve_forever() method now takes an optional poll interval measured in seconds, controlling how often the server will check for a shutdown request. (Contributed by Pedro Werneck and Jeffrey Yasskin; issue 742598 [http://bugs.python.org/issue742598], issue 1193577 [http://bugs.python.org/issue1193577].)

The sqlite3 module, maintained by Gerhard Haering, has been updated from version 2.3.2 in Python 2.5 to version 2.4.1.

The struct module now supports the C99 _Bool type, using the format character '?'. (Contributed by David Remahl.)

The Popen objects provided by the subprocess module now have terminate(), kill(), and send_signal() methods. On Windows, send_signal() only supports the SIGTERM signal, and all these methods are aliases for the Win32 API function TerminateProcess(). (Contributed by Christian Heimes.)

A new variable in the sys module, float_info, is an object containing information derived from the float.h file about the platform’s floating-point support. Attributes of this object include mant_dig (number of digits in the mantissa), epsilon (smallest difference between 1.0 and the next largest value representable), and several others. (Contributed by Christian Heimes; issue 1534 [http://bugs.python.org/issue1534].)

Another new variable, dont_write_bytecode, controls whether Python writes any .pyc or .pyo files on importing a module. If this variable is true, the compiled files are not written. The variable is initially set on start-up by supplying the -B switch to the Python interpreter, or by setting the PYTHONDONTWRITEBYTECODE environment variable before running the interpreter. Python code can subsequently change the value of this variable to control whether bytecode files are written or not. (Contributed by Neal Norwitz and Georg Brandl.)

Information about the command-line arguments supplied to the Python interpreter is available by reading attributes of a named tuple available as sys.flags. For example, the verbose attribute is true if Python was executed in verbose mode, debug is true in debugging mode, etc. These attributes are all read-only. (Contributed by Christian Heimes.)

A new function, getsizeof(), takes a Python object and returns the amount of memory used by the object, measured in bytes. Built-in objects return correct results; third-party extensions may not, but can define a __sizeof__() method to return the object’s size. (Contributed by Robert Schuppenies; issue 2898 [http://bugs.python.org/issue2898].)

It’s now possible to determine the current profiler and tracer functions by calling sys.getprofile() and sys.gettrace(). (Contributed by Georg Brandl; issue 1648 [http://bugs.python.org/issue1648].)

The tarfile module now supports POSIX.1-2001 (pax) tarfiles in addition to the POSIX.1-1988 (ustar) and GNU tar formats that were already supported. The default format is GNU tar; specify the format parameter to open a file using a different format:

tar = tarfile.open("output.tar", "w",
                   format=tarfile.PAX_FORMAT)

The new encoding and errors parameters specify an encoding and an error handling scheme for character conversions. 'strict', 'ignore', and 'replace' are the three standard ways Python can handle errors,; 'utf-8' is a special value that replaces bad characters with their UTF-8 representation. (Character conversions occur because the PAX format supports Unicode filenames, defaulting to UTF-8 encoding.)

The TarFile.add() method now accepts an exclude argument that’s a function that can be used to exclude certain filenames from an archive. The function must take a filename and return true if the file should be excluded or false if it should be archived. The function is applied to both the name initially passed to add() and to the names of files in recursively-added directories.

(All changes contributed by Lars Gustäbel).

An optional timeout parameter was added to the telnetlib.Telnet class constructor, specifying a timeout measured in seconds. (Added by Facundo Batista.)

The tempfile.NamedTemporaryFile class usually deletes the temporary file it created when the file is closed. This behaviour can now be changed by passing delete=False to the constructor. (Contributed by Damien Miller; issue 1537850 [http://bugs.python.org/issue1537850].)

A new class, SpooledTemporaryFile, behaves like a temporary file but stores its data in memory until a maximum size is exceeded. On reaching that limit, the contents will be written to an on-disk temporary file. (Contributed by Dustin J. Mitchell.)

The NamedTemporaryFile and SpooledTemporaryFile classes both work as context managers, so you can write with tempfile.NamedTemporaryFile() as tmp: .... (Contributed by Alexander Belopolsky; issue 2021 [http://bugs.python.org/issue2021].)

The test.test_support module gained a number of context managers useful for writing tests. EnvironmentVarGuard() is a context manager that temporarily changes environment variables and automatically restores them to their old values.

Another context manager, TransientResource, can surround calls to resources that may or may not be available; it will catch and ignore a specified list of exceptions. For example, a network test may ignore certain failures when connecting to an external web site:

with test_support.TransientResource(IOError,
                                errno=errno.ETIMEDOUT):
    f = urllib.urlopen('https://sf.net')
    ...

Finally, check_warnings() resets the warning module’s warning filters and returns an object that will record all warning messages triggered (issue 3781 [http://bugs.python.org/issue3781]):

with test_support.check_warnings() as wrec:
    warnings.simplefilter("always")
    # ... code that triggers a warning ...
    assert str(wrec.message) == "function is outdated"
    assert len(wrec.warnings) == 1, "Multiple warnings raised"

(Contributed by Brett Cannon.)

The textwrap module can now preserve existing whitespace at the beginnings and ends of the newly-created lines by specifying drop_whitespace=False as an argument:

>>> S = """This  sentence  has a bunch   of
...   extra   whitespace."""
>>> print textwrap.fill(S, width=15)
This  sentence
has a bunch
of    extra
whitespace.
>>> print textwrap.fill(S, drop_whitespace=False, width=15)
This  sentence
  has a bunch
   of    extra
   whitespace.
>>>

(Contributed by Dwayne Bailey; issue 1581073 [http://bugs.python.org/issue1581073].)

The threading module API is being changed to use properties such as daemon instead of setDaemon() and isDaemon() methods, and some methods have been renamed to use underscores instead of camel-case; for example, the activeCount() method is renamed to active_count(). Both the 2.6 and 3.0 versions of the module support the same properties and renamed methods, but don’t remove the old methods. No date has been set for the deprecation of the old APIs in Python 3.x; the old APIs won’t be removed in any 2.x version. (Carried out by several people, most notably Benjamin Peterson.)

The threading module’s Thread objects gained an ident property that returns the thread’s identifier, a nonzero integer. (Contributed by Gregory P. Smith; issue 2871 [http://bugs.python.org/issue2871].)

The timeit module now accepts callables as well as strings for the statement being timed and for the setup code. Two convenience functions were added for creating Timer instances: repeat(stmt, setup, time, repeat, number) and timeit(stmt, setup, time, number) create an instance and call the corresponding method. (Contributed by Erik Demaine; issue 1533909 [http://bugs.python.org/issue1533909].)

The Tkinter module now accepts lists and tuples for options, separating the elements by spaces before passing the resulting value to Tcl/Tk. (Contributed by Guilherme Polo; issue 2906 [http://bugs.python.org/issue2906].)

The turtle module for turtle graphics was greatly enhanced by Gregor Lingl. New features in the module include:

Better animation of turtle movement and rotation.

Control over turtle movement using the new delay(), tracer(), and speed() methods.

The ability to set new shapes for the turtle, and to define a new coordinate system.

Turtles now have an undo() method that can roll back actions.

Simple support for reacting to input events such as mouse and keyboard activity, making it possible to write simple games.

A turtle.cfg file can be used to customize the starting appearance of the turtle’s screen.

The module’s docstrings can be replaced by new docstrings that have been translated into another language.

(issue 1513695 [http://bugs.python.org/issue1513695])

An optional timeout parameter was added to the urllib.urlopen() function and the urllib.ftpwrapper class constructor, as well as the urllib2.urlopen() function. The parameter specifies a timeout measured in seconds. For example:

>>> u = urllib2.urlopen("http://slow.example.com",
                        timeout=3)
Traceback (most recent call last):
  ...
urllib2.URLError: <urlopen error timed out>
>>>

(Added by Facundo Batista.)

The Unicode database provided by the unicodedata module has been updated to version 5.1.0. (Updated by Martin von Loewis; issue 3811 [http://bugs.python.org/issue3811].)

The warnings module’s formatwarning() and showwarning() gained an optional line argument that can be used to supply the line of source code. (Added as part of issue 1631171 [http://bugs.python.org/issue1631171], which re-implemented part of the warnings module in C code.)

A new function, catch_warnings(), is a context manager intended for testing purposes that lets you temporarily modify the warning filters and then restore their original values (issue 3781 [http://bugs.python.org/issue3781]).

The XML-RPC SimpleXMLRPCServer and DocXMLRPCServer classes can now be prevented from immediately opening and binding to their socket by passing True as the bind_and_activate constructor parameter. This can be used to modify the instance’s allow_reuse_address attribute before calling the server_bind() and server_activate() methods to open the socket and begin listening for connections. (Contributed by Peter Parente; issue 1599845 [http://bugs.python.org/issue1599845].)

SimpleXMLRPCServer also has a _send_traceback_header attribute; if true, the exception and formatted traceback are returned as HTTP headers “X-Exception” and “X-Traceback”. This feature is for debugging purposes only and should not be used on production servers because the tracebacks might reveal passwords or other sensitive information. (Contributed by Alan McIntyre as part of his project for Google’s Summer of Code 2007.)

The xmlrpclib module no longer automatically converts datetime.date and datetime.time to the xmlrpclib.DateTime type; the conversion semantics were not necessarily correct for all applications. Code using xmlrpclib should convert date and time instances. (issue 1330538 [http://bugs.python.org/issue1330538]) The code can also handle dates before 1900 (contributed by Ralf Schmitt; issue 2014 [http://bugs.python.org/issue2014]) and 64-bit integers represented by using <i8> in XML-RPC responses (contributed by Riku Lindblad; issue 2985 [http://bugs.python.org/issue2985]).

The zipfile module’s ZipFile class now has extract() and extractall() methods that will unpack a single file or all the files in the archive to the current directory, or to a specified directory:

z = zipfile.ZipFile('python-251.zip')

# Unpack a single file, writing it relative
# to the /tmp directory.
z.extract('Python/sysmodule.c', '/tmp')

# Unpack all the files in the archive.
z.extractall()

(Contributed by Alan McIntyre; issue 467924 [http://bugs.python.org/issue467924].)

The open(), read() and extract() methods can now take either a filename or a ZipInfo object. This is useful when an archive accidentally contains a duplicated filename. (Contributed by Graham Horler; issue 1775025 [http://bugs.python.org/issue1775025].)

Finally, zipfile now supports using Unicode filenames for archived files. (Contributed by Alexey Borzenkov; issue 1734346 [http://bugs.python.org/issue1734346].)

The ast module

The ast module provides an Abstract Syntax Tree representation of Python code, and Armin Ronacher contributed a set of helper functions that perform a variety of common tasks. These will be useful for HTML templating packages, code analyzers, and similar tools that process Python code.

The parse() function takes an expression and returns an AST. The dump() function outputs a representation of a tree, suitable for debugging:

import ast

t = ast.parse("""
d = {}
for i in 'abcdefghijklm':
    d[i + i] = ord(i) - ord('a') + 1
print d
""")
print ast.dump(t)

This outputs a deeply nested tree:

Module(body=[
  Assign(targets=[
    Name(id='d', ctx=Store())
   ], value=Dict(keys=[], values=[]))
  For(target=Name(id='i', ctx=Store()),
      iter=Str(s='abcdefghijklm'), body=[
    Assign(targets=[
      Subscript(value=
        Name(id='d', ctx=Load()),
          slice=
          Index(value=
            BinOp(left=Name(id='i', ctx=Load()), op=Add(),
             right=Name(id='i', ctx=Load()))), ctx=Store())
     ], value=
     BinOp(left=
      BinOp(left=
       Call(func=
        Name(id='ord', ctx=Load()), args=[
          Name(id='i', ctx=Load())
         ], keywords=[], starargs=None, kwargs=None),
       op=Sub(), right=Call(func=
        Name(id='ord', ctx=Load()), args=[
          Str(s='a')
         ], keywords=[], starargs=None, kwargs=None)),
       op=Add(), right=Num(n=1)))
    ], orelse=[])
   Print(dest=None, values=[
     Name(id='d', ctx=Load())
   ], nl=True)
 ])

The literal_eval() method takes a string or an AST representing a literal expression, parses and evaluates it, and returns the resulting value. A literal expression is a Python expression containing only strings, numbers, dictionaries, etc. but no statements or function calls. If you need to evaluate an expression but cannot accept the security risk of using an eval() call, literal_eval() will handle it safely:

>>> literal = '("a", "b", {2:4, 3:8, 1:2})'
>>> print ast.literal_eval(literal)
('a', 'b', {1: 2, 2: 4, 3: 8})
>>> print ast.literal_eval('"a" + "b"')
Traceback (most recent call last):
  ...
ValueError: malformed string

The module also includes NodeVisitor and NodeTransformer classes for traversing and modifying an AST, and functions for common transformations such as changing line numbers.

The future_builtins module

Python 3.0 makes many changes to the repertoire of built-in functions, and most of the changes can’t be introduced in the Python 2.x series because they would break compatibility. The future_builtins module provides versions of these built-in functions that can be imported when writing 3.0-compatible code.

The functions in this module currently include:

ascii(obj): equivalent to repr(). In Python 3.0, repr() will return a Unicode string, while ascii() will return a pure ASCII bytestring.

filter(predicate, iterable), map(func, iterable1, ...): the 3.0 versions return iterators, unlike the 2.x builtins which return lists.

hex(value), oct(value): instead of calling the __hex__() or __oct__() methods, these versions will call the __index__() method and convert the result to hexadecimal or octal. oct() will use the new 0o notation for its result.

The json module: JavaScript Object Notation

The new json module supports the encoding and decoding of Python types in JSON (Javascript Object Notation). JSON is a lightweight interchange format often used in web applications. For more information about JSON, see http://www.json.org.

json comes with support for decoding and encoding most built-in Python types. The following example encodes and decodes a dictionary:

>>> import json
>>> data = {"spam" : "foo", "parrot" : 42}
>>> in_json = json.dumps(data) # Encode the data
>>> in_json
'{"parrot": 42, "spam": "foo"}'
>>> json.loads(in_json) # Decode into a Python object
{"spam" : "foo", "parrot" : 42}

It’s also possible to write your own decoders and encoders to support more types. Pretty-printing of the JSON strings is also supported.

json (originally called simplejson) was written by Bob Ippolito.

The plistlib module: A Property-List Parser

The .plist format is commonly used on Mac OS X to store basic data types (numbers, strings, lists, and dictionaries) by serializing them into an XML-based format. It resembles the XML-RPC serialization of data types.

Despite being primarily used on Mac OS X, the format has nothing Mac-specific about it and the Python implementation works on any platform that Python supports, so the plistlib module has been promoted to the standard library.

Using the module is simple:

import sys
import plistlib
import datetime

# Create data structure
data_struct = dict(lastAccessed=datetime.datetime.now(),
                   version=1,
                   categories=('Personal','Shared','Private'))

# Create string containing XML.
plist_str = plistlib.writePlistToString(data_struct)
new_struct = plistlib.readPlistFromString(plist_str)
print data_struct
print new_struct

# Write data structure to a file and read it back.
plistlib.writePlist(data_struct, '/tmp/customizations.plist')
new_struct = plistlib.readPlist('/tmp/customizations.plist')

# read/writePlist accepts file-like objects as well as paths.
plistlib.writePlist(data_struct, sys.stdout)

ctypes Enhancements

Thomas Heller continued to maintain and enhance the ctypes module.

ctypes now supports a c_bool datatype that represents the C99 bool type. (Contributed by David Remahl; issue 1649190 [http://bugs.python.org/issue1649190].)

The ctypes string, buffer and array types have improved support for extended slicing syntax, where various combinations of (start, stop, step) are supplied. (Implemented by Thomas Wouters.)

All ctypes data types now support from_buffer() and from_buffer_copy() methods that create a ctypes instance based on a provided buffer object. from_buffer_copy() copies the contents of the object, while from_buffer() will share the same memory area.

A new calling convention tells ctypes to clear the errno or Win32 LastError variables at the outset of each wrapped call. (Implemented by Thomas Heller; issue 1798 [http://bugs.python.org/issue1798].)

You can now retrieve the Unix errno variable after a function call. When creating a wrapped function, you can supply use_errno=True as a keyword parameter to the DLL() function and then call the module-level methods set_errno() and get_errno() to set and retrieve the error value.

The Win32 LastError variable is similarly supported by the DLL(), OleDLL(), and WinDLL() functions. You supply use_last_error=True as a keyword parameter and then call the module-level methods set_last_error() and get_last_error().

The byref() function, used to retrieve a pointer to a ctypes instance, now has an optional offset parameter that is a byte count that will be added to the returned pointer.

Improved SSL Support

Bill Janssen made extensive improvements to Python 2.6’s support for the Secure Sockets Layer by adding a new module, ssl, that’s built atop the OpenSSL [http://www.openssl.org/] library. This new module provides more control over the protocol negotiated, the X.509 certificates used, and has better support for writing SSL servers (as opposed to clients) in Python. The existing SSL support in the socket module hasn’t been removed and continues to work, though it will be removed in Python 3.0.

To use the new module, you must first create a TCP connection in the usual way and then pass it to the ssl.wrap_socket() function. It’s possible to specify whether a certificate is required, and to obtain certificate info by calling the getpeercert() method.

参考

The documentation for the ssl module.

Deprecations and Removals

String exceptions have been removed. Attempting to use them raises a TypeError.

Changes to the Exception interface as dictated by PEP 352 [http://www.python.org/dev/peps/pep-0352] continue to be made. For 2.6, the message attribute is being deprecated in favor of the args attribute.

(3.0-warning mode) Python 3.0 will feature a reorganized standard library that will drop many outdated modules and rename others. Python 2.6 running in 3.0-warning mode will warn about these modules when they are imported.

The list of deprecated modules is: audiodev, bgenlocations, buildtools, bundlebuilder, Canvas, compiler, dircache, dl, fpformat, gensuitemodule, ihooks, imageop, imgfile, linuxaudiodev, mhlib, mimetools, multifile, new, pure, statvfs, sunaudiodev, test.testall, and toaiff.

The gopherlib module has been removed.

The MimeWriter module and mimify module have been deprecated; use the email package instead.

The md5 module has been deprecated; use the hashlib module instead.

The posixfile module has been deprecated; fcntl.lockf() provides better locking.

The popen2 module has been deprecated; use the subprocess module.

The rgbimg module has been removed.

The sets module has been deprecated; it’s better to use the built-in set and frozenset types.

The sha module has been deprecated; use the hashlib module instead.

Build and C API Changes

Changes to Python’s build process and to the C API include:

Python now must be compiled with C89 compilers (after 19 years!). This means that the Python source tree has dropped its own implementations of memmove() and strerror(), which are in the C89 standard library.

Python 2.6 can be built with Microsoft Visual Studio 2008 (version 9.0), and this is the new default compiler. See the PCbuild directory for the build files. (Implemented by Christian Heimes.)

On Mac OS X, Python 2.6 can be compiled as a 4-way universal build. The configure script can take a --with-universal-archs=[32-bit|64-bit|all] switch, controlling whether the binaries are built for 32-bit architectures (x86, PowerPC), 64-bit (x86-64 and PPC-64), or both. (Contributed by Ronald Oussoren.)

A new function added in Python 2.6.6, PySys_SetArgvEx(), sets the value of sys.argv and can optionally update sys.path to include the directory containing the script named by sys.argv[0] depending on the value of an updatepath parameter.

This function was added to close a security hole for applications that embed Python. The old function, PySys_SetArgv(), would always update sys.path, and sometimes it would add the current directory. This meant that, if you ran an application embedding Python in a directory controlled by someone else, attackers could put a Trojan-horse module in the directory (say, a file named os.py) that your application would then import and run.

If you maintain a C/C++ application that embeds Python, check whether you’re calling PySys_SetArgv() and carefully consider whether the application should be using PySys_SetArgvEx() with updatepath set to false. Note that using this function will break compatibility with Python versions 2.6.5 and earlier; if you have to continue working with earlier versions, you can leave the call to PySys_SetArgv() alone and call PyRun_SimpleString("sys.path.pop(0)\n") afterwards to discard the first sys.path component.

Security issue reported as CVE-2008-5983 [http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983]; discussed in issue 5753 [http://bugs.python.org/issue5753], and fixed by Antoine Pitrou.

The BerkeleyDB module now has a C API object, available as bsddb.db.api. This object can be used by other C extensions that wish to use the bsddb module for their own purposes. (Contributed by Duncan Grisby.)

The new buffer interface, previously described in the PEP 3118 section, adds PyObject_GetBuffer() and PyBuffer_Release(), as well as a few other functions.

Python’s use of the C stdio library is now thread-safe, or at least as thread-safe as the underlying library is. A long-standing potential bug occurred if one thread closed a file object while another thread was reading from or writing to the object. In 2.6 file objects have a reference count, manipulated by the PyFile_IncUseCount() and PyFile_DecUseCount() functions. File objects can’t be closed unless the reference count is zero. PyFile_IncUseCount() should be called while the GIL is still held, before carrying out an I/O operation using the FILE * pointer, and PyFile_DecUseCount() should be called immediately after the GIL is re-acquired. (Contributed by Antoine Pitrou and Gregory P. Smith.)

Importing modules simultaneously in two different threads no longer deadlocks; it will now raise an ImportError. A new API function, PyImport_ImportModuleNoBlock(), will look for a module in sys.modules first, then try to import it after acquiring an import lock. If the import lock is held by another thread, an ImportError is raised. (Contributed by Christian Heimes.)

Several functions return information about the platform’s floating-point support. PyFloat_GetMax() returns the maximum representable floating point value, and PyFloat_GetMin() returns the minimum positive value. PyFloat_GetInfo() returns an object containing more information from the float.h file, such as "mant_dig" (number of digits in the mantissa), "epsilon" (smallest difference between 1.0 and the next largest value representable), and several others. (Contributed by Christian Heimes; issue 1534 [http://bugs.python.org/issue1534].)

C functions and methods that use PyComplex_AsCComplex() will now accept arguments that have a __complex__() method. In particular, the functions in the cmath module will now accept objects with this method. This is a backport of a Python 3.0 change. (Contributed by Mark Dickinson; issue 1675423 [http://bugs.python.org/issue1675423].)

Python’s C API now includes two functions for case-insensitive string comparisons, PyOS_stricmp(char*, char*) and PyOS_strnicmp(char*, char*, Py_ssize_t). (Contributed by Christian Heimes; issue 1635 [http://bugs.python.org/issue1635].)

Many C extensions define their own little macro for adding integers and strings to the module’s dictionary in the init* function. Python 2.6 finally defines standard macros for adding values to a module, PyModule_AddStringMacro and PyModule_AddIntMacro(). (Contributed by Christian Heimes.)

Some macros were renamed in both 3.0 and 2.6 to make it clearer that they are macros, not functions. Py_Size() became Py_SIZE(), Py_Type() became Py_TYPE(), and Py_Refcnt() became Py_REFCNT(). The mixed-case macros are still available in Python 2.6 for backward compatibility. (issue 1629 [http://bugs.python.org/issue1629])

Distutils now places C extensions it builds in a different directory when running on a debug version of Python. (Contributed by Collin Winter; issue 1530959 [http://bugs.python.org/issue1530959].)

Several basic data types, such as integers and strings, maintain internal free lists of objects that can be re-used. The data structures for these free lists now follow a naming convention: the variable is always named free_list, the counter is always named numfree, and a macro Py<typename>_MAXFREELIST is always defined.

A new Makefile target, “make patchcheck”, prepares the Python source tree for making a patch: it fixes trailing whitespace in all modified .py files, checks whether the documentation has been changed, and reports whether the Misc/ACKS and Misc/NEWS files have been updated. (Contributed by Brett Cannon.)

Another new target, “make profile-opt”, compiles a Python binary using GCC’s profile-guided optimization. It compiles Python with profiling enabled, runs the test suite to obtain a set of profiling results, and then compiles using these results for optimization. (Contributed by Gregory P. Smith.)

Port-Specific Changes: Windows

The support for Windows 95, 98, ME and NT4 has been dropped. Python 2.6 requires at least Windows 2000 SP4.

The new default compiler on Windows is Visual Studio 2008 (version 9.0). The build directories for Visual Studio 2003 (version 7.1) and 2005 (version 8.0) were moved into the PC/ directory. The new PCbuild directory supports cross compilation for X64, debug builds and Profile Guided Optimization (PGO). PGO builds are roughly 10% faster than normal builds. (Contributed by Christian Heimes with help from Amaury Forgeot d’Arc and Martin von Loewis.)

The msvcrt module now supports both the normal and wide char variants of the console I/O API. The getwch() function reads a keypress and returns a Unicode value, as does the getwche() function. The putwch() function takes a Unicode character and writes it to the console. (Contributed by Christian Heimes.)

os.path.expandvars() will now expand environment variables in the form “%var%”, and “~user” will be expanded into the user’s home directory path. (Contributed by Josiah Carlson; issue 957650 [http://bugs.python.org/issue957650].)

The socket module’s socket objects now have an ioctl() method that provides a limited interface to the WSAIoctl() system interface.

The _winreg module now has a function, ExpandEnvironmentStrings(), that expands environment variable references such as %NAME% in an input string. The handle objects provided by this module now support the context protocol, so they can be used in with statements. (Contributed by Christian Heimes.)

_winreg also has better support for x64 systems, exposing the DisableReflectionKey(), EnableReflectionKey(), and QueryReflectionKey() functions, which enable and disable registry reflection for 32-bit processes running on 64-bit systems. (issue 1753245 [http://bugs.python.org/issue1753245])

The msilib module’s Record object gained GetInteger() and GetString() methods that return field values as an integer or a string. (Contributed by Floris Bruynooghe; issue 2125 [http://bugs.python.org/issue2125].)

Port-Specific Changes: Mac OS X

When compiling a framework build of Python, you can now specify the framework name to be used by providing the --with-framework-name= option to the configure script.

The macfs module has been removed. This in turn required the macostools.touched() function to be removed because it depended on the macfs module. (issue 1490190 [http://bugs.python.org/issue1490190])

Many other Mac OS modules have been deprecated and will removed in Python 3.0: _builtinSuites, aepack, aetools, aetypes, applesingle, appletrawmain, appletrunner, argvemulator, Audio_mac, autoGIL, Carbon, cfmfile, CodeWarrior, ColorPicker, EasyDialogs, Explorer, Finder, FrameWork, findertools, ic, icglue, icopen, macerrors, MacOS, macfs, macostools, macresource, MiniAEFrame, Nav, Netscape, OSATerminology, pimp, PixMapWrapper, StdSuites, SystemEvents, Terminal, and terminalcommand.

Port-Specific Changes: IRIX

A number of old IRIX-specific modules were deprecated and will be removed in Python 3.0: al and AL, cd, cddb, cdplayer, CL and cl, DEVICE, ERRNO, FILE, FL and fl, flp, fm, GET, GLWS, GL and gl, IN, IOCTL, jpeg, panelparser, readcd, SV and sv, torgb, videoreader, and WAIT.

Porting to Python 2.6

This section lists previously described changes and other bugfixes that may require changes to your code:

Classes that aren’t supposed to be hashable should set __hash__ = None in their definitions to indicate the fact.

String exceptions have been removed. Attempting to use them raises a TypeError.

The __init__() method of collections.deque now clears any existing contents of the deque before adding elements from the iterable. This change makes the behavior match list.__init__().

object.__init__() previously accepted arbitrary arguments and keyword arguments, ignoring them. In Python 2.6, this is no longer allowed and will result in a TypeError. This will affect __init__() methods that end up calling the corresponding method on object (perhaps through using super()). See issue 1683368 [http://bugs.python.org/issue1683368] for discussion.

The Decimal constructor now accepts leading and trailing whitespace when passed a string. Previously it would raise an InvalidOperation exception. On the other hand, the create_decimal() method of Context objects now explicitly disallows extra whitespace, raising a ConversionSyntax exception.

Due to an implementation accident, if you passed a file path to the built-in __import__() function, it would actually import the specified file. This was never intended to work, however, and the implementation now explicitly checks for this case and raises an ImportError.

C API: the PyImport_Import() and PyImport_ImportModule() functions now default to absolute imports, not relative imports. This will affect C extensions that import other modules.

C API: extension data types that shouldn’t be hashable should define their tp_hash slot to PyObject_HashNotImplemented().

The socket module exception socket.error now inherits from IOError. Previously it wasn’t a subclass of StandardError but now it is, through IOError. (Implemented by Gregory P. Smith; issue 1706815 [http://bugs.python.org/issue1706815].)

The xmlrpclib module no longer automatically converts datetime.date and datetime.time to the xmlrpclib.DateTime type; the conversion semantics were not necessarily correct for all applications. Code using xmlrpclib should convert date and time instances. (issue 1330538 [http://bugs.python.org/issue1330538])

(3.0-warning mode) The Exception class now warns when accessed using slicing or index access; having Exception behave like a tuple is being phased out.

(3.0-warning mode) inequality comparisons between two dictionaries or two objects that don’t implement comparison methods are reported as warnings. dict1 == dict2 still works, but dict1 < dict2 is being phased out.

Comparisons between cells, which are an implementation detail of Python’s scoping rules, also cause warnings because such comparisons are forbidden entirely in 3.0.

For applications that embed Python:

The PySys_SetArgvEx() function was added in Python 2.6.6, letting applications close a security hole when the existing PySys_SetArgv() function was used. Check whether you’re calling PySys_SetArgv() and carefully consider whether the application should be using PySys_SetArgvEx() with updatepath set to false.

Acknowledgements

The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this article: Georg Brandl, Steve Brown, Nick Coghlan, Ralph Corderoy, Jim Jewett, Kent Johnson, Chris Lambacher, Martin Michlmayr, Antoine Pitrou, Brian Warner.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

What’s New in Python (英語) »

What’s New in Python 2.5

Author:
A.M. Kuchling

This article explains the new features in Python 2.5. The final release of Python 2.5 is scheduled for August 2006; PEP 356 [http://www.python.org/dev/peps/pep-0356] describes the planned release schedule.

The changes in Python 2.5 are an interesting mix of language and library improvements. The library enhancements will be more important to Python’s user community, I think, because several widely-useful packages were added. New modules include ElementTree for XML processing (xml.etree), the SQLite database module (sqlite), and the ctypes module for calling C functions.

The language changes are of middling significance. Some pleasant new features were added, but most of them aren’t features that you’ll use every day. Conditional expressions were finally added to the language using a novel syntax; see section PEP 308: Conditional Expressions. The new ‘with‘ statement will make writing cleanup code easier (section PEP 343: The ‘with’ statement). Values can now be passed into generators (section PEP 342: New Generator Features). Imports are now visible as either absolute or relative (section PEP 328: Absolute and Relative Imports). Some corner cases of exception handling are handled better (section PEP 341: Unified try/except/finally). All these improvements are worthwhile, but they’re improvements to one specific language feature or another; none of them are broad modifications to Python’s semantics.

As well as the language and library additions, other improvements and bugfixes were made throughout the source tree. A search through the SVN change logs finds there were 353 patches applied and 458 bugs fixed between Python 2.4 and 2.5. (Both figures are likely to be underestimates.)

This article doesn’t try to be a complete specification of the new features; instead changes are briefly introduced using helpful examples. For full details, you should always refer to the documentation for Python 2.5 at http://docs.python.org. If you want to understand the complete implementation and design rationale, refer to the PEP for a particular new feature.

Comments, suggestions, and error reports for this document are welcome; please e-mail them to the author or open a bug in the Python bug tracker.

PEP 308: Conditional Expressions

For a long time, people have been requesting a way to write conditional expressions, which are expressions that return value A or value B depending on whether a Boolean value is true or false. A conditional expression lets you write a single assignment statement that has the same effect as the following:

if condition:
    x = true_value
else:
    x = false_value

There have been endless tedious discussions of syntax on both python-dev and comp.lang.python. A vote was even held that found the majority of voters wanted conditional expressions in some form, but there was no syntax that was preferred by a clear majority. Candidates included C’s cond ? true_v : false_v, if cond then true_v else false_v, and 16 other variations.

Guido van Rossum eventually chose a surprising syntax:

x = true_value if condition else false_value

Evaluation is still lazy as in existing Boolean expressions, so the order of evaluation jumps around a bit. The condition expression in the middle is evaluated first, and the true_value expression is evaluated only if the condition was true. Similarly, the false_value expression is only evaluated when the condition is false.

This syntax may seem strange and backwards; why does the condition go in the middle of the expression, and not in the front as in C’s c ? x : y? The decision was checked by applying the new syntax to the modules in the standard library and seeing how the resulting code read. In many cases where a conditional expression is used, one value seems to be the ‘common case’ and one value is an ‘exceptional case’, used only on rarer occasions when the condition isn’t met. The conditional syntax makes this pattern a bit more obvious:

contents = ((doc + '\n') if doc else '')

I read the above statement as meaning “here contents is usually assigned a value of doc+'\n'; sometimes doc is empty, in which special case an empty string is returned.” I doubt I will use conditional expressions very often where there isn’t a clear common and uncommon case.

There was some discussion of whether the language should require surrounding conditional expressions with parentheses. The decision was made to not require parentheses in the Python language’s grammar, but as a matter of style I think you should always use them. Consider these two statements:

# First version -- no parens
level = 1 if logging else 0

# Second version -- with parens
level = (1 if logging else 0)

In the first version, I think a reader’s eye might group the statement into ‘level = 1’, ‘if logging’, ‘else 0’, and think that the condition decides whether the assignment to level is performed. The second version reads better, in my opinion, because it makes it clear that the assignment is always performed and the choice is being made between two values.

Another reason for including the brackets: a few odd combinations of list comprehensions and lambdas could look like incorrect conditional expressions. See PEP 308 [http://www.python.org/dev/peps/pep-0308] for some examples. If you put parentheses around your conditional expressions, you won’t run into this case.

参考

PEP 308 [http://www.python.org/dev/peps/pep-0308] - Conditional Expressions

PEP written by Guido van Rossum and Raymond D. Hettinger; implemented by Thomas Wouters.

PEP 309: Partial Function Application

The functools module is intended to contain tools for functional-style programming.

One useful tool in this module is the partial() function. For programs written in a functional style, you’ll sometimes want to construct variants of existing functions that have some of the parameters filled in. Consider a Python function f(a, b, c); you could create a new function g(b, c) that was equivalent to f(1, b, c). This is called “partial function application”.

partial() takes the arguments (function, arg1, arg2, ... kwarg1=value1, kwarg2=value2). The resulting object is callable, so you can just call it to invoke function with the filled-in arguments.

Here’s a small but realistic example:

import functools

def log (message, subsystem):
    "Write the contents of 'message' to the specified subsystem."
    print '%s: %s' % (subsystem, message)
    ...

server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')

Here’s another example, from a program that uses PyGTK. Here a context- sensitive pop-up menu is being constructed dynamically. The callback provided for the menu option is a partially applied version of the open_item() method, where the first argument has been provided.

...
class Application:
    def open_item(self, path):
       ...
    def init (self):
        open_func = functools.partial(self.open_item, item_path)
        popup_menu.append( ("Open", open_func, 1) )

Another function in the functools module is the update_wrapper(wrapper, wrapped)() function that helps you write well- behaved decorators. update_wrapper() copies the name, module, and docstring attribute to a wrapper function so that tracebacks inside the wrapped function are easier to understand. For example, you might write:

def my_decorator(f):
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    functools.update_wrapper(wrapper, f)
    return wrapper

wraps() is a decorator that can be used inside your own decorators to copy the wrapped function’s information. An alternate version of the previous example would be:

def my_decorator(f):
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    return wrapper

参考

PEP 309 [http://www.python.org/dev/peps/pep-0309] - Partial Function Application

PEP proposed and written by Peter Harris; implemented by Hye-Shik Chang and Nick Coghlan, with adaptations by Raymond Hettinger.

PEP 314: Metadata for Python Software Packages v1.1

Some simple dependency support was added to Distutils. The setup() function now has requires, provides, and obsoletes keyword parameters. When you build a source distribution using the sdist command, the dependency information will be recorded in the PKG-INFO file.

Another new keyword parameter is download_url, which should be set to a URL for the package’s source code. This means it’s now possible to look up an entry in the package index, determine the dependencies for a package, and download the required packages.

VERSION = '1.0'
setup(name='PyPackage',
      version=VERSION,
      requires=['numarray', 'zlib (>=1.1.4)'],
      obsoletes=['OldPackage']
      download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
                    % VERSION),
     )

Another new enhancement to the Python package index at http://cheeseshop.python.org is storing source and binary archives for a package. The new upload Distutils command will upload a package to the repository.

Before a package can be uploaded, you must be able to build a distribution using the sdist Distutils command. Once that works, you can run python setup.py upload to add your package to the PyPI archive. Optionally you can GPG-sign the package by supplying the --sign and --identity options.

Package uploading was implemented by Martin von Löwis and Richard Jones.

参考

PEP 314 [http://www.python.org/dev/peps/pep-0314] - Metadata for Python Software Packages v1.1

PEP proposed and written by A.M. Kuchling, Richard Jones, and Fred Drake; implemented by Richard Jones and Fred Drake.

PEP 328: Absolute and Relative Imports

The simpler part of PEP 328 was implemented in Python 2.4: parentheses could now be used to enclose the names imported from a module using the from ... import ... statement, making it easier to import many different names.

The more complicated part has been implemented in Python 2.5: importing a module can be specified to use absolute or package-relative imports. The plan is to move toward making absolute imports the default in future versions of Python.

Let’s say you have a package directory like this:

pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py

This defines a package named pkg containing the pkg.main and pkg.string submodules.

Consider the code in the main.py module. What happens if it executes the statement import string? In Python 2.4 and earlier, it will first look in the package’s directory to perform a relative import, finds pkg/string.py, imports the contents of that file as the pkg.string module, and that module is bound to the name string in the pkg.main module’s namespace.

That’s fine if pkg.string was what you wanted. But what if you wanted Python’s standard string module? There’s no clean way to ignore pkg.string and look for the standard module; generally you had to look at the contents of sys.modules, which is slightly unclean. Holger Krekel’s py.std package provides a tidier way to perform imports from the standard library, import py ; py.std.string.join(), but that package isn’t available on all Python installations.

Reading code which relies on relative imports is also less clear, because a reader may be confused about which module, string or pkg.string, is intended to be used. Python users soon learned not to duplicate the names of standard library modules in the names of their packages’ submodules, but you can’t protect against having your submodule’s name being used for a new module added in a future version of Python.

In Python 2.5, you can switch import‘s behaviour to absolute imports using a from __future__ import absolute_import directive. This absolute- import behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default, import string will always find the standard library’s version. It’s suggested that users should begin using absolute imports as much as possible, so it’s preferable to begin writing from pkg import string in your code.

Relative imports are still possible by adding a leading period to the module name when using the from ... import form:

# Import names from pkg.string
from .string import name1, name2
# Import pkg.string
from . import string

This imports the string module relative to the current package, so in pkg.main this will import name1 and name2 from pkg.string. Additional leading periods perform the relative import starting from the parent of the current package. For example, code in the A.B.C module can do:

from . import D                 # Imports A.B.D
from .. import E                # Imports A.E
from ..F import G               # Imports A.F.G

Leading periods cannot be used with the import modname form of the import statement, only the from ... import form.

参考

PEP 328 [http://www.python.org/dev/peps/pep-0328] - Imports: Multi-Line and Absolute/Relative

PEP written by Aahz; implemented by Thomas Wouters.

http://codespeak.net/py/current/doc/index.html

The py library by Holger Krekel, which contains the py.std package.

PEP 338: Executing Modules as Scripts

The -m switch added in Python 2.4 to execute a module as a script gained a few more abilities. Instead of being implemented in C code inside the Python interpreter, the switch now uses an implementation in a new module, runpy.

The runpy module implements a more sophisticated import mechanism so that it’s now possible to run modules in a package such as pychecker.checker. The module also supports alternative import mechanisms such as the zipimport module. This means you can add a .zip archive’s path to sys.path and then use the -m switch to execute code from the archive.

参考

PEP 338 [http://www.python.org/dev/peps/pep-0338] - Executing modules as scripts

PEP written and implemented by Nick Coghlan.

PEP 341: Unified try/except/finally

Until Python 2.5, the try statement came in two flavours. You could use a finally block to ensure that code is always executed, or one or more except blocks to catch specific exceptions. You couldn’t combine both except blocks and a finally block, because generating the right bytecode for the combined version was complicated and it wasn’t clear what the semantics of the combined statement should be.

Guido van Rossum spent some time working with Java, which does support the equivalent of combining except blocks and a finally block, and this clarified what the statement should mean. In Python 2.5, you can now write:

try:
    block-1 ...
except Exception1:
    handler-1 ...
except Exception2:
    handler-2 ...
else:
    else-block
finally:
    final-block

The code in block-1 is executed. If the code raises an exception, the various except blocks are tested: if the exception is of class Exception1, handler-1 is executed; otherwise if it’s of class Exception2, handler-2 is executed, and so forth. If no exception is raised, the else-block is executed.

No matter what happened previously, the final-block is executed once the code block is complete and any raised exceptions handled. Even if there’s an error in an exception handler or the else-block and a new exception is raised, the code in the final-block is still run.

参考

PEP 341 [http://www.python.org/dev/peps/pep-0341] - Unifying try-except and try-finally

PEP written by Georg Brandl; implementation by Thomas Lee.

PEP 342: New Generator Features

Python 2.5 adds a simple way to pass values into a generator. As introduced in Python 2.3, generators only produce output; once a generator’s code was invoked to create an iterator, there was no way to pass any new information into the function when its execution is resumed. Sometimes the ability to pass in some information would be useful. Hackish solutions to this include making the generator’s code look at a global variable and then changing the global variable’s value, or passing in some mutable object that callers then modify.

To refresh your memory of basic generators, here’s a simple example:

def counter (maximum):
    i = 0
    while i < maximum:
        yield i
        i += 1

When you call counter(10), the result is an iterator that returns the values from 0 up to 9. On encountering the yield statement, the iterator returns the provided value and suspends the function’s execution, preserving the local variables. Execution resumes on the following call to the iterator’s next() method, picking up after the yield statement.

In Python 2.3, yield was a statement; it didn’t return any value. In 2.5, yield is now an expression, returning a value that can be assigned to a variable or otherwise operated on:

val = (yield i)

I recommend that you always put parentheses around a yield expression when you’re doing something with the returned value, as in the above example. The parentheses aren’t always necessary, but it’s easier to always add them instead of having to remember when they’re needed.

(PEP 342 [http://www.python.org/dev/peps/pep-0342] explains the exact rules, which are that a yield-expression must always be parenthesized except when it occurs at the top-level expression on the right-hand side of an assignment. This means you can write val = yield i but have to use parentheses when there’s an operation, as in val = (yield i) + 12.)

Values are sent into a generator by calling its send(value)() method. The generator’s code is then resumed and the yield expression returns the specified value. If the regular next() method is called, the yield returns None.

Here’s the previous example, modified to allow changing the value of the internal counter.

def counter (maximum):
    i = 0
    while i < maximum:
        val = (yield i)
        # If value provided, change counter
        if val is not None:
            i = val
        else:
            i += 1

And here’s an example of changing the counter:

>>> it = counter(10)
>>> print it.next()
0
>>> print it.next()
1
>>> print it.send(8)
8
>>> print it.next()
9
>>> print it.next()
Traceback (most recent call last):
  File "t.py", line 15, in ?
    print it.next()
StopIteration

yield will usually return None, so you should always check for this case. Don’t just use its value in expressions unless you’re sure that the send() method will be the only method used to resume your generator function.

In addition to send(), there are two other new methods on generators:

throw(type, value=None, traceback=None)() is used to raise an exception inside the generator; the exception is raised by the yield expression where the generator’s execution is paused.

close() raises a new GeneratorExit exception inside the generator to terminate the iteration. On receiving this exception, the generator’s code must either raise GeneratorExit or StopIteration. Catching the GeneratorExit exception and returning a value is illegal and will trigger a RuntimeError; if the function raises some other exception, that exception is propagated to the caller. close() will also be called by Python’s garbage collector when the generator is garbage-collected.

If you need to run cleanup code when a GeneratorExit occurs, I suggest using a try: ... finally: suite instead of catching GeneratorExit.

The cumulative effect of these changes is to turn generators from one-way producers of information into both producers and consumers.

Generators also become coroutines, a more generalized form of subroutines. Subroutines are entered at one point and exited at another point (the top of the function, and a return statement), but coroutines can be entered, exited, and resumed at many different points (the yield statements). We’ll have to figure out patterns for using coroutines effectively in Python.

The addition of the close() method has one side effect that isn’t obvious. close() is called when a generator is garbage-collected, so this means the generator’s code gets one last chance to run before the generator is destroyed. This last chance means that try...finally statements in generators can now be guaranteed to work; the finally clause will now always get a chance to run. The syntactic restriction that you couldn’t mix yield statements with a try...finally suite has therefore been removed. This seems like a minor bit of language trivia, but using generators and try...finally is actually necessary in order to implement the with statement described by PEP 343. I’ll look at this new statement in the following section.

Another even more esoteric effect of this change: previously, the gi_frame attribute of a generator was always a frame object. It’s now possible for gi_frame to be None once the generator has been exhausted.

参考

PEP 342 [http://www.python.org/dev/peps/pep-0342] - Coroutines via Enhanced Generators

PEP written by Guido van Rossum and Phillip J. Eby; implemented by Phillip J. Eby. Includes examples of some fancier uses of generators as coroutines.

Earlier versions of these features were proposed in PEP 288 [http://www.python.org/dev/peps/pep-0288] by Raymond Hettinger and PEP 325 [http://www.python.org/dev/peps/pep-0325] by Samuele Pedroni.

http://en.wikipedia.org/wiki/Coroutine

The Wikipedia entry for coroutines.

http://www.sidhe.org/~dan/blog/archives/000178.html

An explanation of coroutines from a Perl point of view, written by Dan Sugalski.

PEP 343: The ‘with’ statement

The ‘with‘ statement clarifies code that previously would use try...finally blocks to ensure that clean-up code is executed. In this section, I’ll discuss the statement as it will commonly be used. In the next section, I’ll examine the implementation details and show how to write objects for use with this statement.

The ‘with‘ statement is a new control-flow structure whose basic structure is:

with expression [as variable]:
    with-block

The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has __enter__() and __exit__() methods.

The object’s __enter__() is called before with-block is executed and therefore can run set-up code. It also may return a value that is bound to the name variable, if given. (Note carefully that variable is not assigned the result of expression.)

After execution of the with-block is finished, the object’s __exit__() method is called, even if the block raised an exception, and can therefore run clean-up code.

To enable the statement in Python 2.5, you need to add the following directive to your module:

from __future__ import with_statement

The statement will always be enabled in Python 2.6.

Some standard Python objects now support the context management protocol and can be used with the ‘with‘ statement. File objects are one example:

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line
        ... more processing code ...

After this statement has executed, the file object in f will have been automatically closed, even if the for loop raised an exception part- way through the block.

ノート

In this case, f is the same object created by open(), because file.__enter__() returns self.

The threading module’s locks and condition variables also support the ‘with‘ statement:

lock = threading.Lock()
with lock:
    # Critical section of code
    ...

The lock is acquired before the block is executed and always released once the block is complete.

The new localcontext() function in the decimal module makes it easy to save and restore the current decimal context, which encapsulates the desired precision and rounding characteristics for computations:

from decimal import Decimal, Context, localcontext

# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()

with localcontext(Context(prec=16)):
    # All code in this block uses a precision of 16 digits.
    # The original context is restored on exiting the block.
    print v.sqrt()

Writing Context Managers

Under the hood, the ‘with‘ statement is fairly complicated. Most people will only use ‘with‘ in company with existing objects and don’t need to know these details, so you can skip the rest of this section if you like. Authors of new objects will need to understand the details of the underlying implementation and should keep reading.

A high-level explanation of the context management protocol is:

The expression is evaluated and should result in an object called a “context manager”. The context manager must have __enter__() and __exit__() methods.

The context manager’s __enter__() method is called. The value returned is assigned to VAR. If no 'as VAR' clause is present, the value is simply discarded.

The code in BLOCK is executed.

If BLOCK raises an exception, the __exit__(type, value, traceback)() is called with the exception details, the same values returned by sys.exc_info(). The method’s return value controls whether the exception is re-raised: any false value re-raises the exception, and True will result in suppressing it. You’ll only rarely want to suppress the exception, because if you do the author of the code containing the ‘with‘ statement will never realize anything went wrong.

If BLOCK didn’t raise an exception, the __exit__() method is still called, but type, value, and traceback are all None.

Let’s think through an example. I won’t present detailed code but will only sketch the methods necessary for a database that supports transactions.

(For people unfamiliar with database terminology: a set of changes to the database are grouped into a transaction. Transactions can be either committed, meaning that all the changes are written into the database, or rolled back, meaning that the changes are all discarded and the database is unchanged. See any database textbook for more information.)

Let’s assume there’s an object representing a database connection. Our goal will be to let the user write code like this:

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... more operations ...

The transaction should be committed if the code in the block runs flawlessly or rolled back if there’s an exception. Here’s the basic interface for DatabaseConnection that I’ll assume:

class DatabaseConnection:
    # Database interface
    def cursor (self):
        "Returns a cursor object and starts a new transaction"
    def commit (self):
        "Commits current transaction"
    def rollback (self):
        "Rolls back current transaction"

The __enter__() method is pretty easy, having only to start a new transaction. For this application the resulting cursor object would be a useful result, so the method will return it. The user can then add as cursor to their ‘with‘ statement to bind the cursor to a variable name.

class DatabaseConnection:
    ...
    def __enter__ (self):
        # Code to start a new transaction
        cursor = self.cursor()
        return cursor

The __exit__() method is the most complicated because it’s where most of the work has to be done. The method has to check if an exception occurred. If there was no exception, the transaction is committed. The transaction is rolled back if there was an exception.

In the code below, execution will just fall off the end of the function, returning the default value of None. None is false, so the exception will be re-raised automatically. If you wished, you could be more explicit and add a return statement at the marked location.

class DatabaseConnection:
    ...
    def __exit__ (self, type, value, tb):
        if tb is None:
            # No exception, so commit
            self.commit()
        else:
            # Exception occurred, so rollback.
            self.rollback()
            # return False

The contextlib module

The new contextlib module provides some functions and a decorator that are useful for writing objects for use with the ‘with‘ statement.

The decorator is called contextmanager(), and lets you write a single generator function instead of defining a new class. The generator should yield exactly one value. The code up to the yield will be executed as the __enter__() method, and the value yielded will be the method’s return value that will get bound to the variable in the ‘with‘ statement’s as clause, if any. The code after the yield will be executed in the __exit__() method. Any exception raised in the block will be raised by the yield statement.

Our database example from the previous section could be written using this decorator as:

from contextlib import contextmanager

@contextmanager
def db_transaction (connection):
    cursor = connection.cursor()
    try:
        yield cursor
    except:
        connection.rollback()
        raise
    else:
        connection.commit()

db = DatabaseConnection()
with db_transaction(db) as cursor:
    ...

The contextlib module also has a nested(mgr1, mgr2, ...)() function that combines a number of context managers so you don’t need to write nested ‘with‘ statements. In this example, the single ‘with‘ statement both starts a database transaction and acquires a thread lock:

lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
    ...

Finally, the closing(object)() function returns object so that it can be bound to a variable, and calls object.close at the end of the block.

import urllib, sys
from contextlib import closing

with closing(urllib.urlopen('http://www.yahoo.com')) as f:
    for line in f:
        sys.stdout.write(line)

参考

PEP 343 [http://www.python.org/dev/peps/pep-0343] - The “with” statement

PEP written by Guido van Rossum and Nick Coghlan; implemented by Mike Bland, Guido van Rossum, and Neal Norwitz. The PEP shows the code generated for a ‘with‘ statement, which can be helpful in learning how the statement works.

The documentation for the contextlib module.

PEP 352: Exceptions as New-Style Classes

Exception classes can now be new-style classes, not just classic classes, and the built-in Exception class and all the standard built-in exceptions (NameError, ValueError, etc.) are now new-style classes.

The inheritance hierarchy for exceptions has been rearranged a bit. In 2.5, the inheritance relationships are:

BaseException       # New in Python 2.5
|- KeyboardInterrupt
|- SystemExit
|- Exception
   |- (all other current built-in exceptions)

This rearrangement was done because people often want to catch all exceptions that indicate program errors. KeyboardInterrupt and SystemExit aren’t errors, though, and usually represent an explicit action such as the user hitting Control-C or code calling sys.exit(). A bare except: will catch all exceptions, so you commonly need to list KeyboardInterrupt and SystemExit in order to re-raise them. The usual pattern is:

try:
    ...
except (KeyboardInterrupt, SystemExit):
    raise
except:
    # Log error...
    # Continue running program...

In Python 2.5, you can now write except Exception to achieve the same result, catching all the exceptions that usually indicate errors but leaving KeyboardInterrupt and SystemExit alone. As in previous versions, a bare except: still catches all exceptions.

The goal for Python 3.0 is to require any class raised as an exception to derive from BaseException or some descendant of BaseException, and future releases in the Python 2.x series may begin to enforce this constraint. Therefore, I suggest you begin making all your exception classes derive from Exception now. It’s been suggested that the bare except: form should be removed in Python 3.0, but Guido van Rossum hasn’t decided whether to do this or not.

Raising of strings as exceptions, as in the statement raise "Error occurred", is deprecated in Python 2.5 and will trigger a warning. The aim is to be able to remove the string-exception feature in a few releases.

参考

PEP 352 [http://www.python.org/dev/peps/pep-0352] - Required Superclass for Exceptions

PEP written by Brett Cannon and Guido van Rossum; implemented by Brett Cannon.

PEP 353: Using ssize_t as the index type

A wide-ranging change to Python’s C API, using a new Py_ssize_t type definition instead of int, will permit the interpreter to handle more data on 64-bit platforms. This change doesn’t affect Python’s capacity on 32-bit platforms.

Various pieces of the Python interpreter used C’s int type to store sizes or counts; for example, the number of items in a list or tuple were stored in an int. The C compilers for most 64-bit platforms still define int as a 32-bit type, so that meant that lists could only hold up to 2**31 - 1 = 2147483647 items. (There are actually a few different programming models that 64-bit C compilers can use – see http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion – but the most commonly available model leaves int as 32 bits.)

A limit of 2147483647 items doesn’t really matter on a 32-bit platform because you’ll run out of memory before hitting the length limit. Each list item requires space for a pointer, which is 4 bytes, plus space for a PyObject representing the item. 2147483647*4 is already more bytes than a 32-bit address space can contain.

It’s possible to address that much memory on a 64-bit platform, however. The pointers for a list that size would only require 16 GiB of space, so it’s not unreasonable that Python programmers might construct lists that large. Therefore, the Python interpreter had to be changed to use some type other than int, and this will be a 64-bit type on 64-bit platforms. The change will cause incompatibilities on 64-bit machines, so it was deemed worth making the transition now, while the number of 64-bit users is still relatively small. (In 5 or 10 years, we may all be on 64-bit machines, and the transition would be more painful then.)

This change most strongly affects authors of C extension modules. Python strings and container types such as lists and tuples now use Py_ssize_t to store their size. Functions such as PyList_Size() now return Py_ssize_t. Code in extension modules may therefore need to have some variables changed to Py_ssize_t.

The PyArg_ParseTuple() and Py_BuildValue() functions have a new conversion code, n, for Py_ssize_t. PyArg_ParseTuple()‘s s# and t# still output int by default, but you can define the macro PY_SSIZE_T_CLEAN before including Python.h to make them return Py_ssize_t.

PEP 353 [http://www.python.org/dev/peps/pep-0353] has a section on conversion guidelines that extension authors should read to learn about supporting 64-bit platforms.

参考

PEP 353 [http://www.python.org/dev/peps/pep-0353] - Using ssize_t as the index type

PEP written and implemented by Martin von Löwis.

PEP 357: The ‘__index__’ method

The NumPy developers had a problem that could only be solved by adding a new special method, __index__(). When using slice notation, as in [start:stop:step], the values of the start, stop, and step indexes must all be either integers or long integers. NumPy defines a variety of specialized integer types corresponding to unsigned and signed integers of 8, 16, 32, and 64 bits, but there was no way to signal that these types could be used as slice indexes.

Slicing can’t just use the existing __int__() method because that method is also used to implement coercion to integers. If slicing used __int__(), floating-point numbers would also become legal slice indexes and that’s clearly an undesirable behaviour.

Instead, a new special method called __index__() was added. It takes no arguments and returns an integer giving the slice index to use. For example:

class C:
    def __index__ (self):
        return self.value

The return value must be either a Python integer or long integer. The interpreter will check that the type returned is correct, and raises a TypeError if this requirement isn’t met.

A corresponding nb_index slot was added to the C-level PyNumberMethods structure to let C extensions implement this protocol. PyNumber_Index(obj)() can be used in extension code to call the __index__() function and retrieve its result.

参考

PEP 357 [http://www.python.org/dev/peps/pep-0357] - Allowing Any Object to be Used for Slicing

PEP written and implemented by Travis Oliphant.

Other Language Changes

Here are all of the changes that Python 2.5 makes to the core Python language.

The dict type has a new hook for letting subclasses provide a default value when a key isn’t contained in the dictionary. When a key isn’t found, the dictionary’s __missing__(key)() method will be called. This hook is used to implement the new defaultdict class in the collections module. The following example defines a dictionary that returns zero for any missing key:

class zerodict (dict):
    def __missing__ (self, key):
        return 0

d = zerodict({1:1, 2:2})
print d[1], d[2]   # Prints 1, 2
print d[3], d[4]   # Prints 0, 0

Both 8-bit and Unicode strings have new partition(sep)() and rpartition(sep)() methods that simplify a common use case.

The find(S)() method is often used to get an index which is then used to slice the string and obtain the pieces that are before and after the separator. partition(sep)() condenses this pattern into a single method call that returns a 3-tuple containing the substring before the separator, the separator itself, and the substring after the separator. If the separator isn’t found, the first element of the tuple is the entire string and the other two elements are empty. rpartition(sep)() also returns a 3-tuple but starts searching from the end of the string; the r stands for ‘reverse’.

Some examples:

>>> ('http://www.python.org').partition('://')
('http', '://', 'www.python.org')
>>> ('file:/usr/share/doc/index.html').partition('://')
('file:/usr/share/doc/index.html', '', '')
>>> (u'Subject: a quick question').partition(':')
(u'Subject', u':', u' a quick question')
>>> 'www.python.org'.rpartition('.')
('www.python', '.', 'org')
>>> 'www.python.org'.rpartition(':')
('', '', 'www.python.org')

(Implemented by Fredrik Lundh following a suggestion by Raymond Hettinger.)

The startswith() and endswith() methods of string types now accept tuples of strings to check for.

def is_image_file (filename):
    return filename.endswith(('.gif', '.jpg', '.tiff'))

(Implemented by Georg Brandl following a suggestion by Tom Lynn.)

The min() and max() built-in functions gained a key keyword parameter analogous to the key argument for sort(). This parameter supplies a function that takes a single argument and is called for every value in the list; min()/max() will return the element with the smallest/largest return value from this function. For example, to find the longest string in a list, you can do:

L = ['medium', 'longest', 'short']
# Prints 'longest'
print max(L, key=len)
# Prints 'short', because lexicographically 'short' has the largest value
print max(L)

(Contributed by Steven Bethard and Raymond Hettinger.)

Two new built-in functions, any() and all(), evaluate whether an iterator contains any true or false values. any() returns True if any value returned by the iterator is true; otherwise it will return False. all() returns True only if all of the values returned by the iterator evaluate as true. (Suggested by Guido van Rossum, and implemented by Raymond Hettinger.)

The result of a class’s __hash__() method can now be either a long integer or a regular integer. If a long integer is returned, the hash of that value is taken. In earlier versions the hash value was required to be a regular integer, but in 2.5 the id() built-in was changed to always return non-negative numbers, and users often seem to use id(self) in __hash__() methods (though this is discouraged).

ASCII is now the default encoding for modules. It’s now a syntax error if a module contains string literals with 8-bit characters but doesn’t have an encoding declaration. In Python 2.4 this triggered a warning, not a syntax error. See PEP 263 [http://www.python.org/dev/peps/pep-0263] for how to declare a module’s encoding; for example, you might add a line like this near the top of the source file:

# -*- coding: latin1 -*-

A new warning, UnicodeWarning, is triggered when you attempt to compare a Unicode string and an 8-bit string that can’t be converted to Unicode using the default ASCII encoding. The result of the comparison is false:

>>> chr(128) == unichr(128)   # Can't convert chr(128) to Unicode
__main__:1: UnicodeWarning: Unicode equal comparison failed
  to convert both arguments to Unicode - interpreting them
  as being unequal
False
>>> chr(127) == unichr(127)   # chr(127) can be converted
True

Previously this would raise a UnicodeDecodeError exception, but in 2.5 this could result in puzzling problems when accessing a dictionary. If you looked up unichr(128) and chr(128) was being used as a key, you’d get a UnicodeDecodeError exception. Other changes in 2.5 resulted in this exception being raised instead of suppressed by the code in dictobject.c that implements dictionaries.

Raising an exception for such a comparison is strictly correct, but the change might have broken code, so instead UnicodeWarning was introduced.

(Implemented by Marc-André Lemburg.)

One error that Python programmers sometimes make is forgetting to include an __init__.py module in a package directory. Debugging this mistake can be confusing, and usually requires running Python with the -v switch to log all the paths searched. In Python 2.5, a new ImportWarning warning is triggered when an import would have picked up a directory as a package but no __init__.py was found. This warning is silently ignored by default; provide the -Wd option when running the Python executable to display the warning message. (Implemented by Thomas Wouters.)

The list of base classes in a class definition can now be empty. As an example, this is now legal:

class C():
    pass

(Implemented by Brett Cannon.)

Interactive Interpreter Changes

In the interactive interpreter, quit and exit have long been strings so that new users get a somewhat helpful message when they try to quit:

>>> quit
'Use Ctrl-D (i.e. EOF) to exit.'

In Python 2.5, quit and exit are now objects that still produce string representations of themselves, but are also callable. Newbies who try quit() or exit() will now exit the interpreter as they expect. (Implemented by Georg Brandl.)

The Python executable now accepts the standard long options --help and --version; on Windows, it also accepts the /? option for displaying a help message. (Implemented by Georg Brandl.)

Optimizations

Several of the optimizations were developed at the NeedForSpeed sprint, an event held in Reykjavik, Iceland, from May 21–28 2006. The sprint focused on speed enhancements to the CPython implementation and was funded by EWT LLC with local support from CCP Games. Those optimizations added at this sprint are specially marked in the following list.

When they were introduced in Python 2.4, the built-in set and frozenset types were built on top of Python’s dictionary type. In 2.5 the internal data structure has been customized for implementing sets, and as a result sets will use a third less memory and are somewhat faster. (Implemented by Raymond Hettinger.)

The speed of some Unicode operations, such as finding substrings, string splitting, and character map encoding and decoding, has been improved. (Substring search and splitting improvements were added by Fredrik Lundh and Andrew Dalke at the NeedForSpeed sprint. Character maps were improved by Walter Dörwald and Martin von Löwis.)

The long(str, base)() function is now faster on long digit strings because fewer intermediate results are calculated. The peak is for strings of around 800–1000 digits where the function is 6 times faster. (Contributed by Alan McIntyre and committed at the NeedForSpeed sprint.)

It’s now illegal to mix iterating over a file with for line in file and calling the file object’s read()/readline()/readlines() methods. Iteration uses an internal buffer and the read*() methods don’t use that buffer. Instead they would return the data following the buffer, causing the data to appear out of order. Mixing iteration and these methods will now trigger a ValueError from the read*() method. (Implemented by Thomas Wouters.)

The struct module now compiles structure format strings into an internal representation and caches this representation, yielding a 20% speedup. (Contributed by Bob Ippolito at the NeedForSpeed sprint.)

The re module got a 1 or 2% speedup by switching to Python’s allocator functions instead of the system’s malloc() and free(). (Contributed by Jack Diederich at the NeedForSpeed sprint.)

The code generator’s peephole optimizer now performs simple constant folding in expressions. If you write something like a = 2+3, the code generator will do the arithmetic and produce code corresponding to a = 5. (Proposed and implemented by Raymond Hettinger.)

Function calls are now faster because code objects now keep the most recently finished frame (a “zombie frame”) in an internal field of the code object, reusing it the next time the code object is invoked. (Original patch by Michael Hudson, modified by Armin Rigo and Richard Jones; committed at the NeedForSpeed sprint.) Frame objects are also slightly smaller, which may improve cache locality and reduce memory usage a bit. (Contributed by Neal Norwitz.)

Python’s built-in exceptions are now new-style classes, a change that speeds up instantiation considerably. Exception handling in Python 2.5 is therefore about 30% faster than in 2.4. (Contributed by Richard Jones, Georg Brandl and Sean Reifschneider at the NeedForSpeed sprint.)

Importing now caches the paths tried, recording whether they exist or not so that the interpreter makes fewer open() and stat() calls on startup. (Contributed by Martin von Löwis and Georg Brandl.)

New, Improved, and Removed Modules

The standard library received many enhancements and bug fixes in Python 2.5. Here’s a partial list of the most notable changes, sorted alphabetically by module name. Consult the Misc/NEWS file in the source tree for a more complete list of changes, or look through the SVN logs for all the details.

The audioop module now supports the a-LAW encoding, and the code for u-LAW encoding has been improved. (Contributed by Lars Immisch.)

The codecs module gained support for incremental codecs. The codec.lookup() function now returns a CodecInfo instance instead of a tuple. CodecInfo instances behave like a 4-tuple to preserve backward compatibility but also have the attributes encode, decode, incrementalencoder, incrementaldecoder, streamwriter, and streamreader. Incremental codecs can receive input and produce output in multiple chunks; the output is the same as if the entire input was fed to the non-incremental codec. See the codecs module documentation for details. (Designed and implemented by Walter Dörwald.)

The collections module gained a new type, defaultdict, that subclasses the standard dict type. The new type mostly behaves like a dictionary but constructs a default value when a key isn’t present, automatically adding it to the dictionary for the requested key value.

The first argument to defaultdict‘s constructor is a factory function that gets called whenever a key is requested but not found. This factory function receives no arguments, so you can use built-in type constructors such as list() or int(). For example, you can make an index of words based on their initial letter like this:

words = """Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura
che la diritta via era smarrita""".lower().split()

index = defaultdict(list)

for w in words:
    init_letter = w[0]
    index[init_letter].append(w)

Printing index results in the following output:

defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'],
        'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'],
        'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'],
        'p': ['per'], 's': ['selva', 'smarrita'],
        'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}

(Contributed by Guido van Rossum.)

The deque double-ended queue type supplied by the collections module now has a remove(value)() method that removes the first occurrence of value in the queue, raising ValueError if the value isn’t found. (Contributed by Raymond Hettinger.)

New module: The contextlib module contains helper functions for use with the new ‘with‘ statement. See section The contextlib module for more about this module.

New module: The cProfile module is a C implementation of the existing profile module that has much lower overhead. The module’s interface is the same as profile: you run cProfile.run('main()') to profile a function, can save profile data to a file, etc. It’s not yet known if the Hotshot profiler, which is also written in C but doesn’t match the profile module’s interface, will continue to be maintained in future versions of Python. (Contributed by Armin Rigo.)

Also, the pstats module for analyzing the data measured by the profiler now supports directing the output to any file object by supplying a stream argument to the Stats constructor. (Contributed by Skip Montanaro.)

The csv module, which parses files in comma-separated value format, received several enhancements and a number of bugfixes. You can now set the maximum size in bytes of a field by calling the csv.field_size_limit(new_limit)() function; omitting the new_limit argument will return the currently-set limit. The reader class now has a line_num attribute that counts the number of physical lines read from the source; records can span multiple physical lines, so line_num is not the same as the number of records read.

The CSV parser is now stricter about multi-line quoted fields. Previously, if a line ended within a quoted field without a terminating newline character, a newline would be inserted into the returned field. This behavior caused problems when reading files that contained carriage return characters within fields, so the code was changed to return the field without inserting newlines. As a consequence, if newlines embedded within fields are important, the input should be split into lines in a manner that preserves the newline characters.

(Contributed by Skip Montanaro and Andrew McNamara.)

The datetime class in the datetime module now has a strptime(string, format)() method for parsing date strings, contributed by Josh Spoerri. It uses the same format characters as time.strptime() and time.strftime():

from datetime import datetime

ts = datetime.strptime('10:13:15 2006-03-07',
                       '%H:%M:%S %Y-%m-%d')

The SequenceMatcher.get_matching_blocks() method in the difflib module now guarantees to return a minimal list of blocks describing matching subsequences. Previously, the algorithm would occasionally break a block of matching elements into two list entries. (Enhancement by Tim Peters.)

The doctest module gained a SKIP option that keeps an example from being executed at all. This is intended for code snippets that are usage examples intended for the reader and aren’t actually test cases.

An encoding parameter was added to the testfile() function and the DocFileSuite class to specify the file’s encoding. This makes it easier to use non-ASCII characters in tests contained within a docstring. (Contributed by Bjorn Tillenius.)

The email package has been updated to version 4.0. (Contributed by Barry Warsaw.)

The fileinput module was made more flexible. Unicode filenames are now supported, and a mode parameter that defaults to "r" was added to the input() function to allow opening files in binary or universal-newline mode. Another new parameter, openhook, lets you use a function other than open() to open the input files. Once you’re iterating over the set of files, the FileInput object’s new fileno() returns the file descriptor for the currently opened file. (Contributed by Georg Brandl.)

In the gc module, the new get_count() function returns a 3-tuple containing the current collection counts for the three GC generations. This is accounting information for the garbage collector; when these counts reach a specified threshold, a garbage collection sweep will be made. The existing gc.collect() function now takes an optional generation argument of 0, 1, or 2 to specify which generation to collect. (Contributed by Barry Warsaw.)

The nsmallest() and nlargest() functions in the heapq module now support a key keyword parameter similar to the one provided by the min()/max() functions and the sort() methods. For example:

>>> import heapq
>>> L = ["short", 'medium', 'longest', 'longer still']
>>> heapq.nsmallest(2, L)  # Return two lowest elements, lexicographically
['longer still', 'longest']
>>> heapq.nsmallest(2, L, key=len)   # Return two shortest elements
['short', 'medium']

(Contributed by Raymond Hettinger.)

The itertools.islice() function now accepts None for the start and step arguments. This makes it more compatible with the attributes of slice objects, so that you can now write the following:

s = slice(5)     # Create slice object
itertools.islice(iterable, s.start, s.stop, s.step)

(Contributed by Raymond Hettinger.)

The format() function in the locale module has been modified and two new functions were added, format_string() and currency().

The format() function’s val parameter could previously be a string as long as no more than one %char specifier appeared; now the parameter must be exactly one %char specifier with no surrounding text. An optional monetary parameter was also added which, if True, will use the locale’s rules for formatting currency in placing a separator between groups of three digits.

To format strings with multiple %char specifiers, use the new format_string() function that works like format() but also supports mixing %char specifiers with arbitrary text.

A new currency() function was also added that formats a number according to the current locale’s settings.

(Contributed by Georg Brandl.)

The mailbox module underwent a massive rewrite to add the capability to modify mailboxes in addition to reading them. A new set of classes that include mbox, MH, and Maildir are used to read mailboxes, and have an add(message)() method to add messages, remove(key)() to remove messages, and lock()/unlock() to lock/unlock the mailbox. The following example converts a maildir-format mailbox into an mbox-format one:

import mailbox

# 'factory=None' uses email.Message.Message as the class representing
# individual messages.
src = mailbox.Maildir('maildir', factory=None)
dest = mailbox.mbox('/tmp/mbox')

for msg in src:
    dest.add(msg)

(Contributed by Gregory K. Johnson. Funding was provided by Google’s 2005 Summer of Code.)

New module: the msilib module allows creating Microsoft Installer .msi files and CAB files. Some support for reading the .msi database is also included. (Contributed by Martin von Löwis.)

The nis module now supports accessing domains other than the system default domain by supplying a domain argument to the nis.match() and nis.maps() functions. (Contributed by Ben Bell.)

The operator module’s itemgetter() and attrgetter() functions now support multiple fields. A call such as operator.attrgetter('a', 'b') will return a function that retrieves the a and b attributes. Combining this new feature with the sort() method’s key parameter lets you easily sort lists using multiple fields. (Contributed by Raymond Hettinger.)

The optparse module was updated to version 1.5.1 of the Optik library. The OptionParser class gained an epilog attribute, a string that will be printed after the help message, and a destroy() method to break reference cycles created by the object. (Contributed by Greg Ward.)

The os module underwent several changes. The stat_float_times variable now defaults to true, meaning that os.stat() will now return time values as floats. (This doesn’t necessarily mean that os.stat() will return times that are precise to fractions of a second; not all systems support such precision.)

Constants named os.SEEK_SET, os.SEEK_CUR, and os.SEEK_END have been added; these are the parameters to the os.lseek() function. Two new constants for locking are os.O_SHLOCK and os.O_EXLOCK.

Two new functions, wait3() and wait4(), were added. They’re similar the waitpid() function which waits for a child process to exit and returns a tuple of the process ID and its exit status, but wait3() and wait4() return additional information. wait3() doesn’t take a process ID as input, so it waits for any child process to exit and returns a 3-tuple of process-id, exit-status, resource-usage as returned from the resource.getrusage() function. wait4(pid)() does take a process ID. (Contributed by Chad J. Schroeder.)

On FreeBSD, the os.stat() function now returns times with nanosecond resolution, and the returned object now has st_gen and st_birthtime. The st_flags member is also available, if the platform supports it. (Contributed by Antti Louko and Diego Pettenò.)

The Python debugger provided by the pdb module can now store lists of commands to execute when a breakpoint is reached and execution stops. Once breakpoint #1 has been created, enter commands 1 and enter a series of commands to be executed, finishing the list with end. The command list can include commands that resume execution, such as continue or next. (Contributed by Grégoire Dooms.)

The pickle and cPickle modules no longer accept a return value of None from the __reduce__() method; the method must return a tuple of arguments instead. The ability to return None was deprecated in Python 2.4, so this completes the removal of the feature.

The pkgutil module, containing various utility functions for finding packages, was enhanced to support PEP 302’s import hooks and now also works for packages stored in ZIP-format archives. (Contributed by Phillip J. Eby.)

The pybench benchmark suite by Marc-André Lemburg is now included in the Tools/pybench directory. The pybench suite is an improvement on the commonly used pystone.py program because pybench provides a more detailed measurement of the interpreter’s speed. It times particular operations such as function calls, tuple slicing, method lookups, and numeric operations, instead of performing many different operations and reducing the result to a single number as pystone.py does.

The pyexpat module now uses version 2.0 of the Expat parser. (Contributed by Trent Mick.)

The Queue class provided by the Queue module gained two new methods. join() blocks until all items in the queue have been retrieved and all processing work on the items have been completed. Worker threads call the other new method, task_done(), to signal that processing for an item has been completed. (Contributed by Raymond Hettinger.)

The old regex and regsub modules, which have been deprecated ever since Python 2.0, have finally been deleted. Other deleted modules: statcache, tzparse, whrandom.

Also deleted: the lib-old directory, which includes ancient modules such as dircmp and ni, was removed. lib-old wasn’t on the default sys.path, so unless your programs explicitly added the directory to sys.path, this removal shouldn’t affect your code.

The rlcompleter module is no longer dependent on importing the readline module and therefore now works on non-Unix platforms. (Patch from Robert Kiendl.)

The SimpleXMLRPCServer and DocXMLRPCServer classes now have a rpc_paths attribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only '/' and '/RPC2'. Setting rpc_paths to None or an empty tuple disables this path checking.

The socket module now supports AF_NETLINK sockets on Linux, thanks to a patch from Philippe Biondi. Netlink sockets are a Linux-specific mechanism for communications between a user-space process and kernel code; an introductory article about them is at http://www.linuxjournal.com/article/7356. In Python code, netlink addresses are represented as a tuple of 2 integers, (pid, group_mask).

Two new methods on socket objects, recv_into(buffer)() and recvfrom_into(buffer)(), store the received data in an object that supports the buffer protocol instead of returning the data as a string. This means you can put the data directly into an array or a memory-mapped file.

Socket objects also gained getfamily(), gettype(), and getproto() accessor methods to retrieve the family, type, and protocol values for the socket.

New module: the spwd module provides functions for accessing the shadow password database on systems that support shadow passwords.

The struct is now faster because it compiles format strings into Struct objects with pack() and unpack() methods. This is similar to how the re module lets you create compiled regular expression objects. You can still use the module-level pack() and unpack() functions; they’ll create Struct objects and cache them. Or you can use Struct instances directly:

s = struct.Struct('ih3s')

data = s.pack(1972, 187, 'abc')
year, number, name = s.unpack(data)

You can also pack and unpack data to and from buffer objects directly using the pack_into(buffer, offset, v1, v2, ...)() and unpack_from(buffer, offset)() methods. This lets you store data directly into an array or a memory- mapped file.

(Struct objects were implemented by Bob Ippolito at the NeedForSpeed sprint. Support for buffer objects was added by Martin Blais, also at the NeedForSpeed sprint.)

The Python developers switched from CVS to Subversion during the 2.5 development process. Information about the exact build version is available as the sys.subversion variable, a 3-tuple of (interpreter-name, branch-name, revision-range). For example, at the time of writing my copy of 2.5 was reporting ('CPython', 'trunk', '45313:45315').

This information is also available to C extensions via the Py_GetBuildInfo() function that returns a string of build information like this: "trunk:45355:45356M, Apr 13 2006, 07:42:19". (Contributed by Barry Warsaw.)

Another new function, sys._current_frames(), returns the current stack frames for all running threads as a dictionary mapping thread identifiers to the topmost stack frame currently active in that thread at the time the function is called. (Contributed by Tim Peters.)

The TarFile class in the tarfile module now has an extractall() method that extracts all members from the archive into the current working directory. It’s also possible to set a different directory as the extraction target, and to unpack only a subset of the archive’s members.

The compression used for a tarfile opened in stream mode can now be autodetected using the mode 'r|*'. (Contributed by Lars Gustäbel.)

The threading module now lets you set the stack size used when new threads are created. The stack_size([*size*])() function returns the currently configured stack size, and supplying the optional size parameter sets a new value. Not all platforms support changing the stack size, but Windows, POSIX threading, and OS/2 all do. (Contributed by Andrew MacIntyre.)

The unicodedata module has been updated to use version 4.1.0 of the Unicode character database. Version 3.2.0 is required by some specifications, so it’s still available as unicodedata.ucd_3_2_0.

New module: the uuid module generates universally unique identifiers (UUIDs) according to RFC 4122 [http://tools.ietf.org/html/rfc4122.html]. The RFC defines several different UUID versions that are generated from a starting string, from system properties, or purely randomly. This module contains a UUID class and functions named uuid1(), uuid3(), uuid4(), and uuid5() to generate different versions of UUID. (Version 2 UUIDs are not specified in RFC 4122 [http://tools.ietf.org/html/rfc4122.html] and are not supported by this module.)

>>> import uuid
>>> # make a UUID based on the host ID and current time
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

>>> # make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

>>> # make a random UUID
>>> uuid.uuid4()
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

(Contributed by Ka-Ping Yee.)

The weakref module’s WeakKeyDictionary and WeakValueDictionary types gained new methods for iterating over the weak references contained in the dictionary. iterkeyrefs() and keyrefs() methods were added to WeakKeyDictionary, and itervaluerefs() and valuerefs() were added to WeakValueDictionary. (Contributed by Fred L. Drake, Jr.)

The webbrowser module received a number of enhancements. It’s now usable as a script with python -m webbrowser, taking a URL as the argument; there are a number of switches to control the behaviour (-n for a new browser window, -t for a new tab). New module-level functions, open_new() and open_new_tab(), were added to support this. The module’s open() function supports an additional feature, an autoraise parameter that signals whether to raise the open window when possible. A number of additional browsers were added to the supported list such as Firefox, Opera, Konqueror, and elinks. (Contributed by Oleg Broytmann and Georg Brandl.)

The xmlrpclib module now supports returning datetime objects for the XML-RPC date type. Supply use_datetime=True to the loads() function or the Unmarshaller class to enable this feature. (Contributed by Skip Montanaro.)

The zipfile module now supports the ZIP64 version of the format, meaning that a .zip archive can now be larger than 4 GiB and can contain individual files larger than 4 GiB. (Contributed by Ronald Oussoren.)

The zlib module’s Compress and Decompress objects now support a copy() method that makes a copy of the object’s internal state and returns a new Compress or Decompress object. (Contributed by Chris AtLee.)

The ctypes package

The ctypes package, written by Thomas Heller, has been added to the standard library. ctypes lets you call arbitrary functions in shared libraries or DLLs. Long-time users may remember the dl module, which provides functions for loading shared libraries and calling functions in them. The ctypes package is much fancier.

To load a shared library or DLL, you must create an instance of the CDLL class and provide the name or path of the shared library or DLL. Once that’s done, you can call arbitrary functions by accessing them as attributes of the CDLL object.

import ctypes

libc = ctypes.CDLL('libc.so.6')
result = libc.printf("Line of output\n")

Type constructors for the various C types are provided: c_int(), c_float(), c_double(), c_char_p() (equivalent to char *), and so forth. Unlike Python’s types, the C versions are all mutable; you can assign to their value attribute to change the wrapped value. Python integers and strings will be automatically converted to the corresponding C types, but for other types you must call the correct type constructor. (And I mean must; getting it wrong will often result in the interpreter crashing with a segmentation fault.)

You shouldn’t use c_char_p() with a Python string when the C function will be modifying the memory area, because Python strings are supposed to be immutable; breaking this rule will cause puzzling bugs. When you need a modifiable memory area, use create_string_buffer():

s = "this is a string"
buf = ctypes.create_string_buffer(s)
libc.strfry(buf)

C functions are assumed to return integers, but you can set the restype attribute of the function object to change this:

>>> libc.atof('2.71828')
-1783957616
>>> libc.atof.restype = ctypes.c_double
>>> libc.atof('2.71828')
2.71828

ctypes also provides a wrapper for Python’s C API as the ctypes.pythonapi object. This object does not release the global interpreter lock before calling a function, because the lock must be held when calling into the interpreter’s code. There’s a py_object() type constructor that will create a PyObject * pointer. A simple usage:

import ctypes

d = {}
ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
          ctypes.py_object("abc"),  ctypes.py_object(1))
# d is now {'abc', 1}.

Don’t forget to use py_object(); if it’s omitted you end up with a segmentation fault.

ctypes has been around for a while, but people still write and distribution hand-coded extension modules because you can’t rely on ctypes being present. Perhaps developers will begin to write Python wrappers atop a library accessed through ctypes instead of extension modules, now that ctypes is included with core Python.

参考

http://starship.python.net/crew/theller/ctypes/

The ctypes web page, with a tutorial, reference, and FAQ.

The documentation for the ctypes module.

The ElementTree package

A subset of Fredrik Lundh’s ElementTree library for processing XML has been added to the standard library as xml.etree. The available modules are ElementTree, ElementPath, and ElementInclude from ElementTree 1.2.6. The cElementTree accelerator module is also included.

The rest of this section will provide a brief overview of using ElementTree. Full documentation for ElementTree is available at http://effbot.org/zone/element-index.htm.

ElementTree represents an XML document as a tree of element nodes. The text content of the document is stored as the text and tail attributes of (This is one of the major differences between ElementTree and the Document Object Model; in the DOM there are many different types of node, including TextNode.)

The most commonly used parsing function is parse(), that takes either a string (assumed to contain a filename) or a file-like object and returns an ElementTree instance:

from xml.etree import ElementTree as ET

tree = ET.parse('ex-1.xml')

feed = urllib.urlopen(
          'http://planet.python.org/rss10.xml')
tree = ET.parse(feed)

Once you have an ElementTree instance, you can call its getroot() method to get the root Element node.

There’s also an XML() function that takes a string literal and returns an Element node (not an ElementTree). This function provides a tidy way to incorporate XML fragments, approaching the convenience of an XML literal:

svg = ET.XML("""<svg width="10px" version="1.0">
             </svg>""")
svg.set('height', '320px')
svg.append(elem1)

Each XML element supports some dictionary-like and some list-like access methods. Dictionary-like operations are used to access attribute values, and list-like operations are used to access child nodes.

Operation | Result
elem[n] | Returns n’th child element.
elem[m:n] | Returns list of m’th through n’th child elements.
len(elem) | Returns number of child elements.
list(elem) | Returns list of child elements.
elem.append(elem2) | Adds elem2 as a child.
elem.insert(index, elem2) | Inserts elem2 at the specified location.
del elem[n] | Deletes n’th child element.
elem.keys() | Returns list of attribute names.
elem.get(name) | Returns value of attribute name.
elem.set(name, value) | Sets new value for attribute name.
elem.attrib | Retrieves the dictionary containing attributes.
del elem.attrib[name] | Deletes attribute name.

Comments and processing instructions are also represented as Element nodes. To check if a node is a comment or processing instructions:

if elem.tag is ET.Comment:
    ...
elif elem.tag is ET.ProcessingInstruction:
    ...

To generate XML output, you should call the ElementTree.write() method. Like parse(), it can take either a string or a file-like object:

# Encoding is US-ASCII
tree.write('output.xml')

# Encoding is UTF-8
f = open('output.xml', 'w')
tree.write(f, encoding='utf-8')

(Caution: the default encoding used for output is ASCII. For general XML work, where an element’s name may contain arbitrary Unicode characters, ASCII isn’t a very useful encoding because it will raise an exception if an element’s name contains any characters with values greater than 127. Therefore, it’s best to specify a different encoding such as UTF-8 that can handle any Unicode character.)

This section is only a partial description of the ElementTree interfaces. Please read the package’s official documentation for more details.

参考

http://effbot.org/zone/element-index.htm

Official documentation for ElementTree.

The hashlib package

A new hashlib module, written by Gregory P. Smith, has been added to replace the md5 and sha modules. hashlib adds support for additional secure hashes (SHA-224, SHA-256, SHA-384, and SHA-512). When available, the module uses OpenSSL for fast platform optimized implementations of algorithms.

The old md5 and sha modules still exist as wrappers around hashlib to preserve backwards compatibility. The new module’s interface is very close to that of the old modules, but not identical. The most significant difference is that the constructor functions for creating new hashing objects are named differently.

# Old versions
h = md5.md5()
h = md5.new()

# New version
h = hashlib.md5()

# Old versions
h = sha.sha()
h = sha.new()

# New version
h = hashlib.sha1()

# Hash that weren't previously available
h = hashlib.sha224()
h = hashlib.sha256()
h = hashlib.sha384()
h = hashlib.sha512()

# Alternative form
h = hashlib.new('md5')          # Provide algorithm as a string

Once a hash object has been created, its methods are the same as before: update(string)() hashes the specified string into the current digest state, digest() and hexdigest() return the digest value as a binary string or a string of hex digits, and copy() returns a new hashing object with the same digest state.

参考

The documentation for the hashlib module.

The sqlite3 package

The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded database, has been added to the standard library under the package name sqlite3.

SQLite is a C library that provides a lightweight disk-based database that doesn’t require a separate server process and allows accessing the database using a nonstandard variant of the SQL query language. Some applications can use SQLite for internal data storage. It’s also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle.

pysqlite was written by Gerhard Häring and provides a SQL interface compliant with the DB-API 2.0 specification described by PEP 249 [http://www.python.org/dev/peps/pep-0249].

If you’re compiling the Python source yourself, note that the source tree doesn’t include the SQLite code, only the wrapper module. You’ll need to have the SQLite libraries and headers installed before compiling Python, and the build process will compile the module when the necessary headers are available.

To use the module, you must first create a Connection object that represents the database. Here the data will be stored in the /tmp/example file:

conn = sqlite3.connect('/tmp/example')

You can also supply the special name :memory: to create a database in RAM.

Once you have a Connection, you can create a Cursor object and call its execute() method to perform SQL commands:

c = conn.cursor()

# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')

# Insert a row of data
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")

Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack.

Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.) For example:

# Never do this -- insecure!
symbol = 'IBM'
c.execute("... where symbol = '%s'" % symbol)

# Do this instead
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)

# Larger example
for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
         ):
    c.execute('insert into stocks values (?,?,?,?,?)', t)

To retrieve data after executing a SELECT statement, you can either treat the cursor as an iterator, call the cursor’s fetchone() method to retrieve a single matching row, or call fetchall() to get a list of the matching rows.

This example uses the iterator form:

>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
...    print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>

For more information about the SQL dialect supported by SQLite, see http://www.sqlite.org.

参考

http://www.pysqlite.org

The pysqlite web page.

http://www.sqlite.org

The SQLite web page; the documentation describes the syntax and the available data types for the supported SQL dialect.

The documentation for the sqlite3 module.

PEP 249 [http://www.python.org/dev/peps/pep-0249] - Database API Specification 2.0

PEP written by Marc-André Lemburg.

The wsgiref package

The Web Server Gateway Interface (WSGI) v1.0 defines a standard interface between web servers and Python web applications and is described in PEP 333 [http://www.python.org/dev/peps/pep-0333]. The wsgiref package is a reference implementation of the WSGI specification.

The package includes a basic HTTP server that will run a WSGI application; this server is useful for debugging but isn’t intended for production use. Setting up a server takes only a few lines of code:

from wsgiref import simple_server

wsgi_app = ...

host = ''
port = 8000
httpd = simple_server.make_server(host, port, wsgi_app)
httpd.serve_forever()

参考

http://www.wsgi.org

A central web site for WSGI-related resources.

PEP 333 [http://www.python.org/dev/peps/pep-0333] - Python Web Server Gateway Interface v1.0

PEP written by Phillip J. Eby.

Build and C API Changes

Changes to Python’s build process and to the C API include:

The Python source tree was converted from CVS to Subversion, in a complex migration procedure that was supervised and flawlessly carried out by Martin von Löwis. The procedure was developed as PEP 347 [http://www.python.org/dev/peps/pep-0347].

Coverity, a company that markets a source code analysis tool called Prevent, provided the results of their examination of the Python source code. The analysis found about 60 bugs that were quickly fixed. Many of the bugs were refcounting problems, often occurring in error-handling code. See http://scan.coverity.com for the statistics.

The largest change to the C API came from PEP 353 [http://www.python.org/dev/peps/pep-0353], which modifies the interpreter to use a Py_ssize_t type definition instead of int. See the earlier section PEP 353: Using ssize_t as the index type for a discussion of this change.

The design of the bytecode compiler has changed a great deal, no longer generating bytecode by traversing the parse tree. Instead the parse tree is converted to an abstract syntax tree (or AST), and it is the abstract syntax tree that’s traversed to produce the bytecode.

It’s possible for Python code to obtain AST objects by using the compile() built-in and specifying _ast.PyCF_ONLY_AST as the value of the flags parameter:

from _ast import PyCF_ONLY_AST
ast = compile("""a=0
for i in range(10):
    a += i
""", "<string>", 'exec', PyCF_ONLY_AST)

assignment = ast.body[0]
for_loop = ast.body[1]

No official documentation has been written for the AST code yet, but PEP 339 [http://www.python.org/dev/peps/pep-0339] discusses the design. To start learning about the code, read the definition of the various AST nodes in Parser/Python.asdl. A Python script reads this file and generates a set of C structure definitions in Include/Python-ast.h. The PyParser_ASTFromString() and PyParser_ASTFromFile(), defined in Include/pythonrun.h, take Python source as input and return the root of an AST representing the contents. This AST can then be turned into a code object by PyAST_Compile(). For more information, read the source code, and then ask questions on python-dev.

The AST code was developed under Jeremy Hylton’s management, and implemented by (in alphabetical order) Brett Cannon, Nick Coghlan, Grant Edwards, John Ehresman, Kurt Kaiser, Neal Norwitz, Tim Peters, Armin Rigo, and Neil Schemenauer, plus the participants in a number of AST sprints at conferences such as PyCon.

Evan Jones’s patch to obmalloc, first described in a talk at PyCon DC 2005, was applied. Python 2.4 allocated small objects in 256K-sized arenas, but never freed arenas. With this patch, Python will free arenas when they’re empty. The net effect is that on some platforms, when you allocate many objects, Python’s memory usage may actually drop when you delete them and the memory may be returned to the operating system. (Implemented by Evan Jones, and reworked by Tim Peters.)

Note that this change means extension modules must be more careful when allocating memory. Python’s API has many different functions for allocating memory that are grouped into families. For example, PyMem_Malloc(), PyMem_Realloc(), and PyMem_Free() are one family that allocates raw memory, while PyObject_Malloc(), PyObject_Realloc(), and PyObject_Free() are another family that’s supposed to be used for creating Python objects.

Previously these different families all reduced to the platform’s malloc() and free() functions. This meant it didn’t matter if you got things wrong and allocated memory with the PyMem() function but freed it with the PyObject() function. With 2.5’s changes to obmalloc, these families now do different things and mismatches will probably result in a segfault. You should carefully test your C extension modules with Python 2.5.

The built-in set types now have an official C API. Call PySet_New() and PyFrozenSet_New() to create a new set, PySet_Add() and PySet_Discard() to add and remove elements, and PySet_Contains() and PySet_Size() to examine the set’s state. (Contributed by Raymond Hettinger.)

C code can now obtain information about the exact revision of the Python interpreter by calling the Py_GetBuildInfo() function that returns a string of build information like this: "trunk:45355:45356M, Apr 13 2006, 07:42:19". (Contributed by Barry Warsaw.)

Two new macros can be used to indicate C functions that are local to the current file so that a faster calling convention can be used. Py_LOCAL(type)() declares the function as returning a value of the specified type and uses a fast-calling qualifier. Py_LOCAL_INLINE(type)() does the same thing and also requests the function be inlined. If PY_LOCAL_AGGRESSIVE() is defined before python.h is included, a set of more aggressive optimizations are enabled for the module; you should benchmark the results to find out if these optimizations actually make the code faster. (Contributed by Fredrik Lundh at the NeedForSpeed sprint.)

PyErr_NewException(name, base, dict)() can now accept a tuple of base classes as its base argument. (Contributed by Georg Brandl.)

The PyErr_Warn() function for issuing warnings is now deprecated in favour of PyErr_WarnEx(category, message, stacklevel)() which lets you specify the number of stack frames separating this function and the caller. A stacklevel of 1 is the function calling PyErr_WarnEx(), 2 is the function above that, and so forth. (Added by Neal Norwitz.)

The CPython interpreter is still written in C, but the code can now be compiled with a C++ compiler without errors. (Implemented by Anthony Baxter, Martin von Löwis, Skip Montanaro.)

The PyRange_New() function was removed. It was never documented, never used in the core code, and had dangerously lax error checking. In the unlikely case that your extensions were using it, you can replace it by something like the following:

range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll",
                              start, stop, step);

Port-Specific Changes

MacOS X (10.3 and higher): dynamic loading of modules now uses the dlopen() function instead of MacOS-specific functions.

MacOS X: an --enable-universalsdk switch was added to the configure script that compiles the interpreter as a universal binary able to run on both PowerPC and Intel processors. (Contributed by Ronald Oussoren; issue 2573 [http://bugs.python.org/issue2573].)

Windows: .dll is no longer supported as a filename extension for extension modules. .pyd is now the only filename extension that will be searched for.

Porting to Python 2.5

This section lists previously described changes that may require changes to your code:

ASCII is now the default encoding for modules. It’s now a syntax error if a module contains string literals with 8-bit characters but doesn’t have an encoding declaration. In Python 2.4 this triggered a warning, not a syntax error.

Previously, the gi_frame attribute of a generator was always a frame object. Because of the PEP 342 [http://www.python.org/dev/peps/pep-0342] changes described in section PEP 342: New Generator Features, it’s now possible for gi_frame to be None.

A new warning, UnicodeWarning, is triggered when you attempt to compare a Unicode string and an 8-bit string that can’t be converted to Unicode using the default ASCII encoding. Previously such comparisons would raise a UnicodeDecodeError exception.

Library: the csv module is now stricter about multi-line quoted fields. If your files contain newlines embedded within fields, the input should be split into lines in a manner which preserves the newline characters.

Library: the locale module’s format() function’s would previously accept any string as long as no more than one %char specifier appeared. In Python 2.5, the argument must be exactly one %char specifier with no surrounding text.

Library: The pickle and cPickle modules no longer accept a return value of None from the __reduce__() method; the method must return a tuple of arguments instead. The modules also no longer accept the deprecated bin keyword parameter.

Library: The SimpleXMLRPCServer and DocXMLRPCServer classes now have a rpc_paths attribute that constrains XML-RPC operations to a limited set of URL paths; the default is to allow only '/' and '/RPC2'. Setting rpc_paths to None or an empty tuple disables this path checking.

C API: Many functions now use Py_ssize_t instead of int to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid warnings and to support 64-bit machines. See the earlier section PEP 353: Using ssize_t as the index type for a discussion of this change.

C API: The obmalloc changes mean that you must be careful to not mix usage of the PyMem_*() and PyObject_*() families of functions. Memory allocated with one family’s *_Malloc() must be freed with the corresponding family’s *_Free() function.

Acknowledgements

The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this article: Georg Brandl, Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond Hettinger, Ralf W. Grosse- Kunstleve, Kent Johnson, Iain Lowe, Martin von Löwis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

What’s New in Python (英語) »

What’s New in Python 2.4

Author:
A.M. Kuchling

This article explains the new features in Python 2.4.1, released on March 30, 2005.

Python 2.4 is a medium-sized release. It doesn’t introduce as many changes as the radical Python 2.2, but introduces more features than the conservative 2.3 release. The most significant new language features are function decorators and generator expressions; most other changes are to the standard library.

According to the CVS change logs, there were 481 patches applied and 502 bugs fixed between Python 2.3 and 2.4. Both figures are likely to be underestimates.

This article doesn’t attempt to provide a complete specification of every single new feature, but instead provides a brief introduction to each feature. For full details, you should refer to the documentation for Python 2.4, such as the Python Library Reference and the Python Reference Manual. Often you will be referred to the PEP for a particular new feature for explanations of the implementation and design rationale.

PEP 218: Built-In Set Objects

Python 2.3 introduced the sets module. C implementations of set data types have now been added to the Python core as two new built-in types, set(iterable)() and frozenset(iterable)(). They provide high speed operations for membership testing, for eliminating duplicates from sequences, and for mathematical operations like unions, intersections, differences, and symmetric differences.

>>> a = set('abracadabra')              # form a set from a string
>>> 'z' in a                            # fast membership testing
False
>>> a                                   # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a)                          # convert back into a string
'arbcd'

>>> b = set('alacazam')                 # form a second set
>>> a - b                               # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b                               # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                               # letters in both a and b
set(['a', 'c'])
>>> a ^ b                               # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])

>>> a.add('z')                          # add a new element
>>> a.update('wxy')                     # add multiple new elements
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x')                       # take one element out
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

The frozenset() type is an immutable version of set(). Since it is immutable and hashable, it may be used as a dictionary key or as a member of another set.

The sets module remains in the standard library, and may be useful if you wish to subclass the Set or ImmutableSet classes. There are currently no plans to deprecate the module.

参考

PEP 218 [http://www.python.org/dev/peps/pep-0218] - Adding a Built-In Set Object Type

Originally proposed by Greg Wilson and ultimately implemented by Raymond Hettinger.

PEP 237: Unifying Long Integers and Integers

The lengthy transition process for this PEP, begun in Python 2.2, takes another step forward in Python 2.4. In 2.3, certain integer operations that would behave differently after int/long unification triggered FutureWarning warnings and returned values limited to 32 or 64 bits (depending on your platform). In 2.4, these expressions no longer produce a warning and instead produce a different result that’s usually a long integer.

The problematic expressions are primarily left shifts and lengthy hexadecimal and octal constants. For example, 2 << 32 results in a warning in 2.3, evaluating to 0 on 32-bit platforms. In Python 2.4, this expression now returns the correct answer, 8589934592.

参考

PEP 237 [http://www.python.org/dev/peps/pep-0237] - Unifying Long Integers and Integers

Original PEP written by Moshe Zadka and GvR. The changes for 2.4 were implemented by Kalle Svensson.

PEP 289: Generator Expressions

The iterator feature introduced in Python 2.2 and the itertools module make it easier to write programs that loop through large data sets without having the entire data set in memory at one time. List comprehensions don’t fit into this picture very well because they produce a Python list object containing all of the items. This unavoidably pulls all of the objects into memory, which can be a problem if your data set is very large. When trying to write a functionally-styled program, it would be natural to write something like:

links = [link for link in get_all_links() if not link.followed]
for link in links:
    ...

instead of

for link in get_all_links():
    if link.followed:
        continue
    ...

The first form is more concise and perhaps more readable, but if you’re dealing with a large number of link objects you’d have to write the second form to avoid having all link objects in memory at the same time.

Generator expressions work similarly to list comprehensions but don’t materialize the entire list; instead they create a generator that will return elements one by one. The above example could be written as:

links = (link for link in get_all_links() if not link.followed)
for link in links:
    ...

Generator expressions always have to be written inside parentheses, as in the above example. The parentheses signalling a function call also count, so if you want to create an iterator that will be immediately passed to a function you could write:

print sum(obj.count for obj in list_all_objects())

Generator expressions differ from list comprehensions in various small ways. Most notably, the loop variable (obj in the above example) is not accessible outside of the generator expression. List comprehensions leave the variable assigned to its last value; future versions of Python will change this, making list comprehensions match generator expressions in this respect.

参考

PEP 289 [http://www.python.org/dev/peps/pep-0289] - Generator Expressions

Proposed by Raymond Hettinger and implemented by Jiwon Seo with early efforts steered by Hye-Shik Chang.

PEP 292: Simpler String Substitutions

Some new classes in the standard library provide an alternative mechanism for substituting variables into strings; this style of substitution may be better for applications where untrained users need to edit templates.

The usual way of substituting variables by name is the % operator:

>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'

When writing the template string, it can be easy to forget the i or s after the closing parenthesis. This isn’t a big problem if the template is in a Python module, because you run the code, get an “Unsupported format character” ValueError, and fix the problem. However, consider an application such as Mailman where template strings or translations are being edited by users who aren’t aware of the Python language. The format string’s syntax is complicated to explain to such users, and if they make a mistake, it’s difficult to provide helpful feedback to them.

PEP 292 adds a Template class to the string module that uses $ to indicate a substitution:

>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'

If a key is missing from the dictionary, the substitute() method will raise a KeyError. There’s also a safe_substitute() method that ignores missing keys:

>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'

参考

PEP 292 [http://www.python.org/dev/peps/pep-0292] - Simpler String Substitutions

Written and implemented by Barry Warsaw.

PEP 318: Decorators for Functions and Methods

Python 2.2 extended Python’s object model by adding static methods and class methods, but it didn’t extend Python’s syntax to provide any new way of defining static or class methods. Instead, you had to write a def statement in the usual way, and pass the resulting method to a staticmethod() or classmethod() function that would wrap up the function as a method of the new type. Your code would look like this:

class C:
   def meth (cls):
       ...

   meth = classmethod(meth)   # Rebind name to wrapped-up class method

If the method was very long, it would be easy to miss or forget the classmethod() invocation after the function body.

The intention was always to add some syntax to make such definitions more readable, but at the time of 2.2’s release a good syntax was not obvious. Today a good syntax still isn’t obvious but users are asking for easier access to the feature; a new syntactic feature has been added to meet this need.

The new feature is called “function decorators”. The name comes from the idea that classmethod(), staticmethod(), and friends are storing additional information on a function object; they’re decorating functions with more details.

The notation borrows from Java and uses the '@' character as an indicator. Using the new syntax, the example above would be written:

class C:

   @classmethod
   def meth (cls):
       ...

The @classmethod is shorthand for the meth=classmethod(meth) assignment. More generally, if you have the following:

@A
@B
@C
def f ():
    ...

It’s equivalent to the following pre-decorator code:

def f(): ...
f = A(B(C(f)))

Decorators must come on the line before a function definition, one decorator per line, and can’t be on the same line as the def statement, meaning that @A def f(): ... is illegal. You can only decorate function definitions, either at the module level or inside a class; you can’t decorate class definitions.

A decorator is just a function that takes the function to be decorated as an argument and returns either the same function or some new object. The return value of the decorator need not be callable (though it typically is), unless further decorators will be applied to the result. It’s easy to write your own decorators. The following simple example just sets an attribute on the function object:

>>> def deco(func):
...    func.attr = 'decorated'
...    return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>

As a slightly more realistic example, the following decorator checks that the supplied argument is an integer:

def require_int (func):
    def wrapper (arg):
        assert isinstance(arg, int)
        return func(arg)

    return wrapper

@require_int
def p1 (arg):
    print arg

@require_int
def p2(arg):
    print arg*2

An example in PEP 318 [http://www.python.org/dev/peps/pep-0318] contains a fancier version of this idea that lets you both specify the required type and check the returned type.

Decorator functions can take arguments. If arguments are supplied, your decorator function is called with only those arguments and must return a new decorator function; this function must take a single function and return a function, as previously described. In other words, @A @B @C(args) becomes:

def f(): ...
_deco = C(args)
f = A(B(_deco(f)))

Getting this right can be slightly brain-bending, but it’s not too difficult.

A small related change makes the func_name attribute of functions writable. This attribute is used to display function names in tracebacks, so decorators should change the name of any new function that’s constructed and returned.

参考

PEP 318 [http://www.python.org/dev/peps/pep-0318] - Decorators for Functions, Methods and Classes

Written by Kevin D. Smith, Jim Jewett, and Skip Montanaro. Several people wrote patches implementing function decorators, but the one that was actually checked in was patch #979728, written by Mark Russell.

http://www.python.org/moin/PythonDecoratorLibrary

This Wiki page contains several examples of decorators.

PEP 322: Reverse Iteration

A new built-in function, reversed(seq)(), takes a sequence and returns an iterator that loops over the elements of the sequence in reverse order.

>>> for i in reversed(xrange(1,4)):
...    print i
...
3
2
1

Compared to extended slicing, such as range(1,4)[::-1], reversed() is easier to read, runs faster, and uses substantially less memory.

Note that reversed() only accepts sequences, not arbitrary iterators. If you want to reverse an iterator, first convert it to a list with list().

>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
...   print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
  ...

参考

PEP 322 [http://www.python.org/dev/peps/pep-0322] - Reverse Iteration

Written and implemented by Raymond Hettinger.

PEP 324: New subprocess Module

The standard library provides a number of ways to execute a subprocess, offering different features and different levels of complexity. os.system(command)() is easy to use, but slow (it runs a shell process which executes the command) and dangerous (you have to be careful about escaping the shell’s metacharacters). The popen2 module offers classes that can capture standard output and standard error from the subprocess, but the naming is confusing. The subprocess module cleans this up, providing a unified interface that offers all the features you might need.

Instead of popen2‘s collection of classes, subprocess contains a single class called Popen whose constructor supports a number of different keyword arguments.

class Popen(args, bufsize=0, executable=None,
            stdin=None, stdout=None, stderr=None,
            preexec_fn=None, close_fds=False, shell=False,
            cwd=None, env=None, universal_newlines=False,
            startupinfo=None, creationflags=0):

args is commonly a sequence of strings that will be the arguments to the program executed as the subprocess. (If the shell argument is true, args can be a string which will then be passed on to the shell for interpretation, just as os.system() does.)

stdin, stdout, and stderr specify what the subprocess’s input, output, and error streams will be. You can provide a file object or a file descriptor, or you can use the constant subprocess.PIPE to create a pipe between the subprocess and the parent.

The constructor has a number of handy options:

close_fds requests that all file descriptors be closed before running the subprocess.

cwd specifies the working directory in which the subprocess will be executed (defaulting to whatever the parent’s working directory is).

env is a dictionary specifying environment variables.

preexec_fn is a function that gets called before the child is started.

universal_newlines opens the child’s input and output using Python’s universal newline feature.

Once you’ve created the Popen instance, you can call its wait() method to pause until the subprocess has exited, poll() to check if it’s exited without pausing, or communicate(data)() to send the string data to the subprocess’s standard input. communicate(data)() then reads any data that the subprocess has sent to its standard output or standard error, returning a tuple (stdout_data, stderr_data).

call() is a shortcut that passes its arguments along to the Popen constructor, waits for the command to complete, and returns the status code of the subprocess. It can serve as a safer analog to os.system():

sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
    # Success
    ...
else:
    # dpkg returned an error
    ...

The command is invoked without use of the shell. If you really do want to use the shell, you can add shell=True as a keyword argument and provide a string instead of a sequence:

sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)

The PEP takes various examples of shell and Python code and shows how they’d be translated into Python code that uses subprocess. Reading this section of the PEP is highly recommended.

参考

PEP 324 [http://www.python.org/dev/peps/pep-0324] - subprocess - New process module

Written and implemented by Peter Åstrand, with assistance from Fredrik Lundh and others.

PEP 327: Decimal Data Type

Python has always supported floating-point (FP) numbers, based on the underlying C double type, as a data type. However, while most programming languages provide a floating-point type, many people (even programmers) are unaware that floating-point numbers don’t represent certain decimal fractions accurately. The new Decimal type can represent these fractions accurately, up to a user-specified precision limit.

Why is Decimal needed?

The limitations arise from the representation used for floating-point numbers. FP numbers are made up of three components:

The sign, which is positive or negative.

The mantissa, which is a single-digit binary number followed by a fractional part. For example, 1.01 in base-2 notation is 1 + 0/2 + 1/4, or 1.25 in decimal notation.

The exponent, which tells where the decimal point is located in the number represented.

For example, the number 1.25 has positive sign, a mantissa value of 1.01 (in binary), and an exponent of 0 (the decimal point doesn’t need to be shifted). The number 5 has the same sign and mantissa, but the exponent is 2 because the mantissa is multiplied by 4 (2 to the power of the exponent 2); 1.25 * 4 equals 5.

Modern systems usually provide floating-point support that conforms to a standard called IEEE 754. C’s double type is usually implemented as a 64-bit IEEE 754 number, which uses 52 bits of space for the mantissa. This means that numbers can only be specified to 52 bits of precision. If you’re trying to represent numbers whose expansion repeats endlessly, the expansion is cut off after 52 bits. Unfortunately, most software needs to produce output in base 10, and common fractions in base 10 are often repeating decimals in binary. For example, 1.1 decimal is binary 1.0001100110011 ...; .1 = 1/16 + 1/32 + 1/256 plus an infinite number of additional terms. IEEE 754 has to chop off that infinitely repeated decimal after 52 digits, so the representation is slightly inaccurate.

Sometimes you can see this inaccuracy when the number is printed:

>>> 1.1
1.1000000000000001

The inaccuracy isn’t always visible when you print the number because the FP-to- decimal-string conversion is provided by the C library, and most C libraries try to produce sensible output. Even if it’s not displayed, however, the inaccuracy is still there and subsequent operations can magnify the error.

For many applications this doesn’t matter. If I’m plotting points and displaying them on my monitor, the difference between 1.1 and 1.1000000000000001 is too small to be visible. Reports often limit output to a certain number of decimal places, and if you round the number to two or three or even eight decimal places, the error is never apparent. However, for applications where it does matter, it’s a lot of work to implement your own custom arithmetic routines.

Hence, the Decimal type was created.

The Decimal type

A new module, decimal, was added to Python’s standard library. It contains two classes, Decimal and Context. Decimal instances represent numbers, and Context instances are used to wrap up various settings such as the precision and default rounding mode.

Decimal instances are immutable, like regular Python integers and FP numbers; once it’s been created, you can’t change the value an instance represents. Decimal instances can be created from integers or strings:

>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")

You can also provide tuples containing the sign, the mantissa represented as a tuple of decimal digits, and the exponent:

>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")

Cautionary note: the sign bit is a Boolean value, so 0 is positive and 1 is negative.

Converting from floating-point numbers poses a bit of a problem: should the FP number representing 1.1 turn into the decimal number for exactly 1.1, or for 1.1 plus whatever inaccuracies are introduced? The decision was to dodge the issue and leave such a conversion out of the API. Instead, you should convert the floating-point number into a string using the desired precision and pass the string to the Decimal constructor:

>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")

Once you have Decimal instances, you can perform the usual mathematical operations on them. One limitation: exponentiation requires an integer exponent:

>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
  ...
decimal.InvalidOperation: x ** (non-integer)

You can combine Decimal instances with integers, but not with floating- point numbers:

>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
  ...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>

Decimal numbers can be used with the math and cmath modules, but note that they’ll be immediately converted to floating-point numbers before the operation is performed, resulting in a possible loss of precision and accuracy. You’ll also get back a regular floating-point number and not a Decimal.

>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j

Decimal instances have a sqrt() method that returns a Decimal, but if you need other things such as trigonometric functions you’ll have to implement them.

>>> d.sqrt()
Decimal("351364.1828820134592177245001")

The Context type

Instances of the Context class encapsulate several settings for decimal operations:

prec is the precision, the number of decimal places.

rounding specifies the rounding mode. The decimal module has constants for the various possibilities: ROUND_DOWN, ROUND_CEILING, ROUND_HALF_EVEN, and various others.

traps is a dictionary specifying what happens on encountering certain error conditions: either an exception is raised or a value is returned. Some examples of error conditions are division by zero, loss of precision, and overflow.

There’s a thread-local default context available by calling getcontext(); you can change the properties of this context to alter the default precision, rounding, or trap handling. The following example shows the effect of changing the precision of the default context:

>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")

The default action for error conditions is selectable; the module can either return a special value such as infinity or not-a-number, or exceptions can be raised:

>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
  ...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>

The Context instance also has various methods for formatting numbers such as to_eng_string() and to_sci_string().

For more information, see the documentation for the decimal module, which includes a quick-start tutorial and a reference.

参考

PEP 327 [http://www.python.org/dev/peps/pep-0327] - Decimal Data Type

Written by Facundo Batista and implemented by Facundo Batista, Eric Price, Raymond Hettinger, Aahz, and Tim Peters.

http://www.lahey.com/float.htm

The article uses Fortran code to illustrate many of the problems that floating- point inaccuracy can cause.

http://www2.hursley.ibm.com/decimal/

A description of a decimal-based representation. This representation is being proposed as a standard, and underlies the new Python decimal type. Much of this material was written by Mike Cowlishaw, designer of the Rexx language.

PEP 328: Multi-line Imports

One language change is a small syntactic tweak aimed at making it easier to import many names from a module. In a from module import names statement, names is a sequence of names separated by commas. If the sequence is very long, you can either write multiple imports from the same module, or you can use backslashes to escape the line endings like this:

from SimpleXMLRPCServer import SimpleXMLRPCServer,\
            SimpleXMLRPCRequestHandler,\
            CGIXMLRPCRequestHandler,\
            resolve_dotted_attribute

The syntactic change in Python 2.4 simply allows putting the names within parentheses. Python ignores newlines within a parenthesized expression, so the backslashes are no longer needed:

from SimpleXMLRPCServer import (SimpleXMLRPCServer,
                                SimpleXMLRPCRequestHandler,
                                CGIXMLRPCRequestHandler,
                                resolve_dotted_attribute)

The PEP also proposes that all import statements be absolute imports, with a leading . character to indicate a relative import. This part of the PEP was not implemented for Python 2.4, but was completed for Python 2.5.

参考

PEP 328 [http://www.python.org/dev/peps/pep-0328] - Imports: Multi-Line and Absolute/Relative

Written by Aahz. Multi-line imports were implemented by Dima Dorfman.

PEP 331: Locale-Independent Float/String Conversions

The locale modules lets Python software select various conversions and display conventions that are localized to a particular country or language. However, the module was careful to not change the numeric locale because various functions in Python’s implementation required that the numeric locale remain set to the 'C' locale. Often this was because the code was using the C library’s atof() function.

Not setting the numeric locale caused trouble for extensions that used third- party C libraries, however, because they wouldn’t have the correct locale set. The motivating example was GTK+, whose user interface widgets weren’t displaying numbers in the current locale.

The solution described in the PEP is to add three new functions to the Python API that perform ASCII-only conversions, ignoring the locale setting:

PyOS_ascii_strtod(str, ptr)() and PyOS_ascii_atof(str, ptr)() both convert a string to a C double.

PyOS_ascii_formatd(buffer, buf_len, format, d)() converts a double to an ASCII string.

The code for these functions came from the GLib library (http://library.gnome.org/devel/glib/stable/), whose developers kindly relicensed the relevant functions and donated them to the Python Software Foundation. The locale module can now change the numeric locale, letting extensions such as GTK+ produce the correct results.

参考

PEP 331 [http://www.python.org/dev/peps/pep-0331] - Locale-Independent Float/String Conversions

Written by Christian R. Reis, and implemented by Gustavo Carneiro.

Other Language Changes

Here are all of the changes that Python 2.4 makes to the core Python language.

Decorators for functions and methods were added (PEP 318 [http://www.python.org/dev/peps/pep-0318]).

Built-in set() and frozenset() types were added (PEP 218 [http://www.python.org/dev/peps/pep-0218]). Other new built-ins include the reversed(seq)() function (PEP 322 [http://www.python.org/dev/peps/pep-0322]).

Generator expressions were added (PEP 289 [http://www.python.org/dev/peps/pep-0289]).

Certain numeric expressions no longer return values restricted to 32 or 64 bits (PEP 237 [http://www.python.org/dev/peps/pep-0237]).

You can now put parentheses around the list of names in a from module import names statement (PEP 328 [http://www.python.org/dev/peps/pep-0328]).

The dict.update() method now accepts the same argument forms as the dict constructor. This includes any mapping, any iterable of key/value pairs, and keyword arguments. (Contributed by Raymond Hettinger.)

The string methods ljust(), rjust(), and center() now take an optional argument for specifying a fill character other than a space. (Contributed by Raymond Hettinger.)

Strings also gained an rsplit() method that works like the split() method but splits from the end of the string. (Contributed by Sean Reifschneider.)

>>> 'www.python.org'.split('.', 1)
['www', 'python.org']
'www.python.org'.rsplit('.', 1)
['www.python', 'org']

Three keyword parameters, cmp, key, and reverse, were added to the sort() method of lists. These parameters make some common usages of sort() simpler. All of these parameters are optional.

For the cmp parameter, the value should be a comparison function that takes two parameters and returns -1, 0, or +1 depending on how the parameters compare. This function will then be used to sort the list. Previously this was the only parameter that could be provided to sort().

key should be a single-parameter function that takes a list element and returns a comparison key for the element. The list is then sorted using the comparison keys. The following example sorts a list case-insensitively:

>>> L = ['A', 'b', 'c', 'D']
>>> L.sort()                 # Case-sensitive sort
>>> L
['A', 'D', 'b', 'c']
>>> # Using 'key' parameter to sort list
>>> L.sort(key=lambda x: x.lower())
>>> L
['A', 'b', 'c', 'D']
>>> # Old-fashioned way
>>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
>>> L
['A', 'b', 'c', 'D']

The last example, which uses the cmp parameter, is the old way to perform a case-insensitive sort. It works but is slower than using a key parameter. Using key calls lower() method once for each element in the list while using cmp will call it twice for each comparison, so using key saves on invocations of the lower() method.

For simple key functions and comparison functions, it is often possible to avoid a lambda expression by using an unbound method instead. For example, the above case-insensitive sort is best written as:

>>> L.sort(key=str.lower)
>>> L
['A', 'b', 'c', 'D']

Finally, the reverse parameter takes a Boolean value. If the value is true, the list will be sorted into reverse order. Instead of L.sort() ; L.reverse(), you can now write L.sort(reverse=True).

The results of sorting are now guaranteed to be stable. This means that two entries with equal keys will be returned in the same order as they were input. For example, you can sort a list of people by name, and then sort the list by age, resulting in a list sorted by age where people with the same age are in name-sorted order.

(All changes to sort() contributed by Raymond Hettinger.)

There is a new built-in function sorted(iterable)() that works like the in-place list.sort() method but can be used in expressions. The differences are:

the input may be any iterable;

a newly formed copy is sorted, leaving the original intact; and

the expression returns the new sorted copy

>>> L = [9,7,8,3,2,4,1,6,5]
>>> [10+i for i in sorted(L)]       # usable in a list comprehension
[11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> L                               # original is left unchanged
[9,7,8,3,2,4,1,6,5]
>>> sorted('Monty Python')          # any iterable may be an input
[' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']

>>> # List the contents of a dict sorted by key values
>>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
>>> for k, v in sorted(colormap.iteritems()):
...     print k, v
...
black 4
blue 2
green 3
red 1
yellow 5

(Contributed by Raymond Hettinger.)

Integer operations will no longer trigger an OverflowWarning. The OverflowWarning warning will disappear in Python 2.5.

The interpreter gained a new switch, -m, that takes a name, searches for the corresponding module on sys.path, and runs the module as a script. For example, you can now run the Python profiler with python -m profile. (Contributed by Nick Coghlan.)

The eval(expr, globals, locals)() and execfile(filename, globals, locals)() functions and the exec statement now accept any mapping type for the locals parameter. Previously this had to be a regular Python dictionary. (Contributed by Raymond Hettinger.)

The zip() built-in function and itertools.izip() now return an empty list if called with no arguments. Previously they raised a TypeError exception. This makes them more suitable for use with variable length argument lists:

>>> def transpose(array):
...    return zip(*array)
...
>>> transpose([(1,2,3), (4,5,6)])
[(1, 4), (2, 5), (3, 6)]
>>> transpose([])
[]

(Contributed by Raymond Hettinger.)

Encountering a failure while importing a module no longer leaves a partially- initialized module object in sys.modules. The incomplete module object left behind would fool further imports of the same module into succeeding, leading to confusing errors. (Fixed by Tim Peters.)

None is now a constant; code that binds a new value to the name None is now a syntax error. (Contributed by Raymond Hettinger.)

Optimizations

The inner loops for list and tuple slicing were optimized and now run about one-third faster. The inner loops for dictionaries were also optimized, resulting in performance boosts for keys(), values(), items(), iterkeys(), itervalues(), and iteritems(). (Contributed by Raymond Hettinger.)

The machinery for growing and shrinking lists was optimized for speed and for space efficiency. Appending and popping from lists now runs faster due to more efficient code paths and less frequent use of the underlying system realloc(). List comprehensions also benefit. list.extend() was also optimized and no longer converts its argument into a temporary list before extending the base list. (Contributed by Raymond Hettinger.)

list(), tuple(), map(), filter(), and zip() now run several times faster with non-sequence arguments that supply a __len__() method. (Contributed by Raymond Hettinger.)

The methods list.__getitem__(), dict.__getitem__(), and dict.__contains__() are are now implemented as method_descriptor objects rather than wrapper_descriptor objects. This form of access doubles their performance and makes them more suitable for use as arguments to functionals: map(mydict.__getitem__, keylist). (Contributed by Raymond Hettinger.)

Added a new opcode, LIST_APPEND, that simplifies the generated bytecode for list comprehensions and speeds them up by about a third. (Contributed by Raymond Hettinger.)

The peephole bytecode optimizer has been improved to produce shorter, faster bytecode; remarkably, the resulting bytecode is more readable. (Enhanced by Raymond Hettinger.)

String concatenations in statements of the form s = s + "abc" and s += "abc" are now performed more efficiently in certain circumstances. This optimization won’t be present in other Python implementations such as Jython, so you shouldn’t rely on it; using the join() method of strings is still recommended when you want to efficiently glue a large number of strings together. (Contributed by Armin Rigo.)

The net result of the 2.4 optimizations is that Python 2.4 runs the pystone benchmark around 5% faster than Python 2.3 and 35% faster than Python 2.2. (pystone is not a particularly good benchmark, but it’s the most commonly used measurement of Python’s performance. Your own applications may show greater or smaller benefits from Python 2.4.)

New, Improved, and Deprecated Modules

As usual, Python’s standard library received a number of enhancements and bug fixes. Here’s a partial list of the most notable changes, sorted alphabetically by module name. Consult the Misc/NEWS file in the source tree for a more complete list of changes, or look through the CVS logs for all the details.

The asyncore module’s loop() function now has a count parameter that lets you perform a limited number of passes through the polling loop. The default is still to loop forever.

The base64 module now has more complete RFC 3548 support for Base64, Base32, and Base16 encoding and decoding, including optional case folding and optional alternative alphabets. (Contributed by Barry Warsaw.)

The bisect module now has an underlying C implementation for improved performance. (Contributed by Dmitry Vasiliev.)

The CJKCodecs collections of East Asian codecs, maintained by Hye-Shik Chang, was integrated into 2.4. The new encodings are:

Chinese (PRC): gb2312, gbk, gb18030, big5hkscs, hz

Chinese (ROC): big5, cp950

Japanese: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,

iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift-jis-2004

Korean: cp949, euc-kr, johab, iso-2022-kr

Some other new encodings were added: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154, and TIS-620.

The UTF-8 and UTF-16 codecs now cope better with receiving partial input. Previously the StreamReader class would try to read more data, making it impossible to resume decoding from the stream. The read() method will now return as much data as it can and future calls will resume decoding where previous ones left off. (Implemented by Walter Dörwald.)

There is a new collections module for various specialized collection datatypes. Currently it contains just one type, deque, a double- ended queue that supports efficiently adding and removing elements from either end:

>>> from collections import deque
>>> d = deque('ghi')        # make a new deque with three items
>>> d.append('j')           # add a new entry to the right side
>>> d.appendleft('f')       # add a new entry to the left side
>>> d                       # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop()                 # return and remove the rightmost item
'j'
>>> d.popleft()             # return and remove the leftmost item
'f'
>>> list(d)                 # list the contents of the deque
['g', 'h', 'i']
>>> 'h' in d                # search the deque
True

Several modules, such as the Queue and threading modules, now take advantage of collections.deque for improved performance. (Contributed by Raymond Hettinger.)

The ConfigParser classes have been enhanced slightly. The read() method now returns a list of the files that were successfully parsed, and the set() method raises TypeError if passed a value argument that isn’t a string. (Contributed by John Belmonte and David Goodger.)

The curses module now supports the ncurses extension use_default_colors(). On platforms where the terminal supports transparency, this makes it possible to use a transparent background. (Contributed by Jörg Lehmann.)

The difflib module now includes an HtmlDiff class that creates an HTML table showing a side by side comparison of two versions of a text. (Contributed by Dan Gass.)

The email package was updated to version 3.0, which dropped various deprecated APIs and removes support for Python versions earlier than 2.3. The 3.0 version of the package uses a new incremental parser for MIME messages, available in the email.FeedParser module. The new parser doesn’t require reading the entire message into memory, and doesn’t throw exceptions if a message is malformed; instead it records any problems in the defect attribute of the message. (Developed by Anthony Baxter, Barry Warsaw, Thomas Wouters, and others.)

The heapq module has been converted to C. The resulting tenfold improvement in speed makes the module suitable for handling high volumes of data. In addition, the module has two new functions nlargest() and nsmallest() that use heaps to find the N largest or smallest values in a dataset without the expense of a full sort. (Contributed by Raymond Hettinger.)

The httplib module now contains constants for HTTP status codes defined in various HTTP-related RFC documents. Constants have names such as OK, CREATED, CONTINUE, and MOVED_PERMANENTLY; use pydoc to get a full list. (Contributed by Andrew Eland.)

The imaplib module now supports IMAP’s THREAD command (contributed by Yves Dionne) and new deleteacl() and myrights() methods (contributed by Arnaud Mazin).

The itertools module gained a groupby(iterable[, *func*])() function. iterable is something that can be iterated over to return a stream of elements, and the optional func parameter is a function that takes an element and returns a key value; if omitted, the key is simply the element itself. groupby() then groups the elements into subsequences which have matching values of the key, and returns a series of 2-tuples containing the key value and an iterator over the subsequence.

Here’s an example to make this clearer. The key function simply returns whether a number is even or odd, so the result of groupby() is to return consecutive runs of odd or even numbers.

>>> import itertools
>>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
>>> for key_val, it in itertools.groupby(L, lambda x: x % 2):
...    print key_val, list(it)
...
0 [2, 4, 6]
1 [7]
0 [8]
1 [9, 11]
0 [12, 14]
>>>

groupby() is typically used with sorted input. The logic for groupby() is similar to the Unix uniq filter which makes it handy for eliminating, counting, or identifying duplicate elements:

>>> word = 'abracadabra'
>>> letters = sorted(word)   # Turn string into a sorted list of letters
>>> letters
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
>>> for k, g in itertools.groupby(letters):
...    print k, list(g)
...
a ['a', 'a', 'a', 'a', 'a']
b ['b', 'b']
c ['c']
d ['d']
r ['r', 'r']
>>> # List unique letters
>>> [k for k, g in groupby(letters)]
['a', 'b', 'c', 'd', 'r']
>>> # Count letter occurrences
>>> [(k, len(list(g))) for k, g in groupby(letters)]
[('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]

(Contributed by Hye-Shik Chang.)

itertools also gained a function named tee(iterator, N)() that returns N independent iterators that replicate iterator. If N is omitted, the default is 2.

>>> L = [1,2,3]
>>> i1, i2 = itertools.tee(L)
>>> i1,i2
(<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)
>>> list(i1)               # Run the first iterator to exhaustion
[1, 2, 3]
>>> list(i2)               # Run the second iterator to exhaustion
[1, 2, 3]

Note that tee() has to keep copies of the values returned by the iterator; in the worst case, it may need to keep all of them. This should therefore be used carefully if the leading iterator can run far ahead of the trailing iterator in a long stream of inputs. If the separation is large, then you might as well use list() instead. When the iterators track closely with one another, tee() is ideal. Possible applications include bookmarking, windowing, or lookahead iterators. (Contributed by Raymond Hettinger.)

A number of functions were added to the locale module, such as bind_textdomain_codeset() to specify a particular encoding and a family of l*gettext() functions that return messages in the chosen encoding. (Contributed by Gustavo Niemeyer.)

Some keyword arguments were added to the logging package’s basicConfig() function to simplify log configuration. The default behavior is to log messages to standard error, but various keyword arguments can be specified to log to a particular file, change the logging format, or set the logging level. For example:

import logging
logging.basicConfig(filename='/var/log/application.log',
    level=0,  # Log all messages
    format='%(levelname):%(process):%(thread):%(message)')

Other additions to the logging package include a log(level, msg)() convenience method, as well as a TimedRotatingFileHandler class that rotates its log files at a timed interval. The module already had RotatingFileHandler, which rotated logs once the file exceeded a certain size. Both classes derive from a new BaseRotatingHandler class that can be used to implement other rotating handlers.

(Changes implemented by Vinay Sajip.)

The marshal module now shares interned strings on unpacking a data structure. This may shrink the size of certain pickle strings, but the primary effect is to make .pyc files significantly smaller. (Contributed by Martin von Löwis.)

The nntplib module’s NNTP class gained description() and descriptions() methods to retrieve newsgroup descriptions for a single group or for a range of groups. (Contributed by Jürgen A. Erhard.)

Two new functions were added to the operator module, attrgetter(attr)() and itemgetter(index)(). Both functions return callables that take a single argument and return the corresponding attribute or item; these callables make excellent data extractors when used with map() or sorted(). For example:

>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
>>> map(operator.itemgetter(0), L)
['c', 'd', 'a', 'b']
>>> map(operator.itemgetter(1), L)
[2, 1, 4, 3]
>>> sorted(L, key=operator.itemgetter(1)) # Sort list by second tuple item
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

(Contributed by Raymond Hettinger.)

The optparse module was updated in various ways. The module now passes its messages through gettext.gettext(), making it possible to internationalize Optik’s help and error messages. Help messages for options can now include the string '%default', which will be replaced by the option’s default value. (Contributed by Greg Ward.)

The long-term plan is to deprecate the rfc822 module in some future Python release in favor of the email package. To this end, the email.Utils.formatdate() function has been changed to make it usable as a replacement for rfc822.formatdate(). You may want to write new e-mail processing code with this in mind. (Change implemented by Anthony Baxter.)

A new urandom(n)() function was added to the os module, returning a string containing n bytes of random data. This function provides access to platform-specific sources of randomness such as /dev/urandom on Linux or the Windows CryptoAPI. (Contributed by Trevor Perrin.)

Another new function: os.path.lexists(path)() returns true if the file specified by path exists, whether or not it’s a symbolic link. This differs from the existing os.path.exists(path)() function, which returns false if path is a symlink that points to a destination that doesn’t exist. (Contributed by Beni Cherniavsky.)

A new getsid() function was added to the posix module that underlies the os module. (Contributed by J. Raynor.)

The poplib module now supports POP over SSL. (Contributed by Hector Urtubia.)

The profile module can now profile C extension functions. (Contributed by Nick Bastin.)

The random module has a new method called getrandbits(N)() that returns a long integer N bits in length. The existing randrange() method now uses getrandbits() where appropriate, making generation of arbitrarily large random numbers more efficient. (Contributed by Raymond Hettinger.)

The regular expression language accepted by the re module was extended with simple conditional expressions, written as (?(group)A|B). group is either a numeric group ID or a group name defined with (?P<group>...) earlier in the expression. If the specified group matched, the regular expression pattern A will be tested against the string; if the group didn’t match, the pattern B will be used instead. (Contributed by Gustavo Niemeyer.)

The re module is also no longer recursive, thanks to a massive amount of work by Gustavo Niemeyer. In a recursive regular expression engine, certain patterns result in a large amount of C stack space being consumed, and it was possible to overflow the stack. For example, if you matched a 30000-byte string of a characters against the expression (a|b)+, one stack frame was consumed per character. Python 2.3 tried to check for stack overflow and raise a RuntimeError exception, but certain patterns could sidestep the checking and if you were unlucky Python could segfault. Python 2.4’s regular expression engine can match this pattern without problems.

The signal module now performs tighter error-checking on the parameters to the signal.signal() function. For example, you can’t set a handler on the SIGKILL signal; previous versions of Python would quietly accept this, but 2.4 will raise a RuntimeError exception.

Two new functions were added to the socket module. socketpair() returns a pair of connected sockets and getservbyport(port)() looks up the service name for a given port number. (Contributed by Dave Cole and Barry Warsaw.)

The sys.exitfunc() function has been deprecated. Code should be using the existing atexit module, which correctly handles calling multiple exit functions. Eventually sys.exitfunc() will become a purely internal interface, accessed only by atexit.

The tarfile module now generates GNU-format tar files by default. (Contributed by Lars Gustaebel.)

The threading module now has an elegantly simple way to support thread-local data. The module contains a local class whose attribute values are local to different threads.

import threading

data = threading.local()
data.number = 42
data.url = ('www.python.org', 80)

Other threads can assign and retrieve their own values for the number and url attributes. You can subclass local to initialize attributes or to add methods. (Contributed by Jim Fulton.)

The timeit module now automatically disables periodic garbage collection during the timing loop. This change makes consecutive timings more comparable. (Contributed by Raymond Hettinger.)

The weakref module now supports a wider variety of objects including Python functions, class instances, sets, frozensets, deques, arrays, files, sockets, and regular expression pattern objects. (Contributed by Raymond Hettinger.)

The xmlrpclib module now supports a multi-call extension for transmitting multiple XML-RPC calls in a single HTTP operation. (Contributed by Brian Quinlan.)

The mpz, rotor, and xreadlines modules have been removed.

cookielib

The cookielib library supports client-side handling for HTTP cookies, mirroring the Cookie module’s server-side cookie support. Cookies are stored in cookie jars; the library transparently stores cookies offered by the web server in the cookie jar, and fetches the cookie from the jar when connecting to the server. As in web browsers, policy objects control whether cookies are accepted or not.

In order to store cookies across sessions, two implementations of cookie jars are provided: one that stores cookies in the Netscape format so applications can use the Mozilla or Lynx cookie files, and one that stores cookies in the same format as the Perl libwww library.

urllib2 has been changed to interact with cookielib: HTTPCookieProcessor manages a cookie jar that is used when accessing URLs.

This module was contributed by John J. Lee.

doctest

The doctest module underwent considerable refactoring thanks to Edward Loper and Tim Peters. Testing can still be as simple as running doctest.testmod(), but the refactorings allow customizing the module’s operation in various ways

The new DocTestFinder class extracts the tests from a given object’s docstrings:

def f (x, y):
    """>>> f(2,2)
4
>>> f(3,2)
6
    """
    return x*y

finder = doctest.DocTestFinder()

# Get list of DocTest instances
tests = finder.find(f)

The new DocTestRunner class then runs individual tests and can produce a summary of the results:

runner = doctest.DocTestRunner()
for t in tests:
    tried, failed = runner.run(t)

runner.summarize(verbose=1)

The above example produces the following output:

1 items passed all tests:
   2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.

DocTestRunner uses an instance of the OutputChecker class to compare the expected output with the actual output. This class takes a number of different flags that customize its behaviour; ambitious users can also write a completely new subclass of OutputChecker.

The default output checker provides a number of handy features. For example, with the doctest.ELLIPSIS option flag, an ellipsis (...) in the expected output matches any substring, making it easier to accommodate outputs that vary in minor ways:

def o (n):
    """>>> o(1)
<__main__.C instance at 0x...>
>>>
"""

Another special string, <BLANKLINE>, matches a blank line:

def p (n):
    """>>> p(1)
<BLANKLINE>
>>>
"""

Another new capability is producing a diff-style display of the output by specifying the doctest.REPORT_UDIFF (unified diffs), doctest.REPORT_CDIFF (context diffs), or doctest.REPORT_NDIFF (delta-style) option flags. For example:

def g (n):
    """>>> g(4)
here
is
a
lengthy
>>>"""
    L = 'here is a rather lengthy list of words'.split()
    for word in L[:n]:
        print word

Running the above function’s tests with doctest.REPORT_UDIFF specified, you get the following output:

**********************************************************************
File "t.py", line 15, in g
Failed example:
    g(4)
Differences (unified diff with -expected +actual):
    @@ -2,3 +2,3 @@
     is
     a
    -lengthy
    +rather
**********************************************************************

Build and C API Changes

Some of the changes to Python’s build process and to the C API are:

Three new convenience macros were added for common return values from extension functions: Py_RETURN_NONE, Py_RETURN_TRUE, and Py_RETURN_FALSE. (Contributed by Brett Cannon.)

Another new macro, Py_CLEAR(obj), decreases the reference count of obj and sets obj to the null pointer. (Contributed by Jim Fulton.)

A new function, PyTuple_Pack(N, obj1, obj2, ..., objN)(), constructs tuples from a variable length argument list of Python objects. (Contributed by Raymond Hettinger.)

A new function, PyDict_Contains(d, k)(), implements fast dictionary lookups without masking exceptions raised during the look-up process. (Contributed by Raymond Hettinger.)

The Py_IS_NAN(X) macro returns 1 if its float or double argument X is a NaN. (Contributed by Tim Peters.)

C code can avoid unnecessary locking by using the new PyEval_ThreadsInitialized() function to tell if any thread operations have been performed. If this function returns false, no lock operations are needed. (Contributed by Nick Coghlan.)

A new function, PyArg_VaParseTupleAndKeywords(), is the same as PyArg_ParseTupleAndKeywords() but takes a va_list instead of a number of arguments. (Contributed by Greg Chapman.)

A new method flag, METH_COEXISTS, allows a function defined in slots to co-exist with a PyCFunction having the same name. This can halve the access time for a method such as set.__contains__(). (Contributed by Raymond Hettinger.)

Python can now be built with additional profiling for the interpreter itself, intended as an aid to people developing the Python core. Providing ----enable-profiling to the configure script will let you profile the interpreter with gprof, and providing the ----with-tsc switch enables profiling using the Pentium’s Time-Stamp- Counter register. Note that the ----with-tsc switch is slightly misnamed, because the profiling feature also works on the PowerPC platform, though that processor architecture doesn’t call that register “the TSC register”. (Contributed by Jeremy Hylton.)

The tracebackobject type has been renamed to PyTracebackObject.

Port-Specific Changes

The Windows port now builds under MSVC++ 7.1 as well as version 6. (Contributed by Martin von Löwis.)

Porting to Python 2.4

This section lists previously described changes that may require changes to your code:

Left shifts and hexadecimal/octal constants that are too large no longer trigger a FutureWarning and return a value limited to 32 or 64 bits; instead they return a long integer.

Integer operations will no longer trigger an OverflowWarning. The OverflowWarning warning will disappear in Python 2.5.

The zip() built-in function and itertools.izip() now return an empty list instead of raising a TypeError exception if called with no arguments.

You can no longer compare the date and datetime instances provided by the datetime module. Two instances of different classes will now always be unequal, and relative comparisons (<, >) will raise a TypeError.

dircache.listdir() now passes exceptions to the caller instead of returning empty lists.

LexicalHandler.startDTD() used to receive the public and system IDs in the wrong order. This has been corrected; applications relying on the wrong order need to be fixed.

fcntl.ioctl() now warns if the mutate argument is omitted and relevant.

The tarfile module now generates GNU-format tar files by default.

Encountering a failure while importing a module no longer leaves a partially- initialized module object in sys.modules.

None is now a constant; code that binds a new value to the name None is now a syntax error.

The signals.signal() function now raises a RuntimeError exception for certain illegal values; previously these errors would pass silently. For example, you can no longer set a handler on the SIGKILL signal.

Acknowledgements

The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this article: Koray Can, Hye- Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル

Release: | 2.7
Date: | 2011年 12月 26日

Python は簡単に習得でき、それでいて強力な言語の一つです。 Python は高レベルなデータ構造を効率的に実装していて、オブジェクト指向プログラミングに対しても、単純ながら効果的なアプローチをとっています。洗練された文法とデータ型を動的に決定する機能、そしてインタプリタであるという特徴から、 Python はほとんどのプラットフォームの幅広い対象領域において、スクリプティングや迅速なアプリケーション開発のための理想的な言語になっています。

Pythonインタプリタ自体と膨大な標準ライブラリは、ソースコード形式や、主要なプラットフォーム向けのバイナリ形式で、Python Web サイト http://www.python.org/ から無料で入手でき、かつ無料で再配布できます。また、Python Webサイトでは、無料で手に入るたくさんのサードパーティ製 Python モジュールから、プログラム、ツール類、その他のドキュメントに至るまで、配布物やポインタの情報を公開しています。

Python インタプリタは、 C 言語や C++ 言語 (あるいはその他の C 言語から呼び出せる言語) で実装された新たな関数やデータ構造を組み込んで簡単に拡張できます。 Python はまた、カスタマイズ可能なアプリケーションを作るための拡張機能記述言語としても適しています。

このチュートリアルでは、Python の言語仕様と仕組みについて、基本的な概念と機能をざっと紹介します。 Python インタプリタが手元にあれば、自分で試しながら学ぶ助けになりますが、例題は全て自己完結しているので、オフラインでも十分読めます。

標準のオブジェクトやモジュールの記述については、 Python 標準ライブラリ を参照してください。 Python 言語リファレンス には、より形式的な言語の定義が書いてあります。 C 言語や C++ 言語で拡張モジュールを書くなら、 Python インタプリタの拡張と埋め込み や Python/C API リファレンスマニュアル を参照してください。他にも、 Python について広く深くカバーしている書籍はいくつかあります。

このチュートリアルは網羅的な内容を目指しているわけではありませんし、 Pythonの個別の機能や、よく使われる機能でさえ完全にカバーしてはいません。その代わり、このチュートリアルではPythonの特筆すべき機能をたくさん紹介して、この言語の持ち味やスタイルについて好印象を持ってもらうつもりです。このチュートリアルを読んだ後には、読者のみなさんは Python のモジュールやプログラムを読み書きできるようになり、 Python 標準ライブラリに記述されているさまざまな Python ライブラリモジュールについて学べるようになるでしょう。

用語集 もまた役に立つはずです。

1. やる気を高めよう

2. Python インタプリタを使う

2.1. インタプリタを起動する

2.1.1. 引数の受け渡し

2.1.2. 対話モード

2.2. インタプリタとその環境

2.2.1. エラー処理

2.2.2. 実行可能な Python スクリプト

2.2.3. ソースコードの文字コード

2.2.4. 対話モード用の起動時実行ファイル

3. 形式ばらない Python の紹介

3.1. Python を電卓として使う

3.1.1. 数

3.1.2. 文字列

3.1.3. Unicode 文字列

3.1.4. リスト

3.2. プログラミングへの第一歩

4. その他の制御フローツール

4.1. if 文

4.2. for 文

4.3. range() 関数

4.4. break 文と continue 文とループの else 節

4.5. pass 文

4.6. 関数を定義する

4.7. 関数定義についてもう少し

4.7.1. デフォルトの引数値

4.7.2. キーワード引数

4.7.3. 任意引数リスト

4.7.4. 引数リストのアンパック

4.7.5. ラムダ式

4.7.6. ドキュメンテーション文字列

4.8. 間奏曲: コーディングスタイル

5. データ構造

5.1. リスト型についてもう少し

5.1.1. リストをスタックとして使う

5.1.2. リストをキューとして使う

5.1.3. 関数型のプログラミングツール

5.1.4. リストの内包表記

5.1.5. ネストしたリストの内包表記

5.2. del 文

5.3. タプルとシーケンス

5.4. 集合型

5.5. 辞書

5.6. ループのテクニック

5.7. 条件についてもう少し

5.8. シーケンスとその他の型の比較

6. モジュール

6.1. モジュールについてもうすこし

6.2. モジュールをスクリプトとして実行する

6.2.1. モジュール検索パス

6.2.2. “コンパイル” された Python ファイル

6.3. 標準モジュール

6.4. dir() 関数

6.5. パッケージ

6.5.1. パッケージから * を import する

6.5.2. パッケージ内での参照

6.5.3. 複数ディレクトリ中のパッケージ

7. 入力と出力

7.1. ファンシーな出力の書式化

7.1.1. 古い文字列フォーマット方法

7.2. ファイルを読み書きする

7.2.1. ファイルオブジェクトのメソッド

7.2.2. pickle モジュール

8. エラーと例外

8.1. 構文エラー

8.2. 例外

8.3. 例外を処理する

8.4. 例外を送出する

8.5. ユーザ定義の例外

8.6. クリーンアップ動作を定義する

8.7. 定義済みクリーンアップ処理

9. クラス

9.1. 名前とオブジェクトについて

9.2. Python のスコープと名前空間

9.3. クラス初見

9.3.1. クラス定義の構文

9.3.2. クラスオブジェクト

9.3.3. インスタンスオブジェクト

9.3.4. メソッドオブジェクト

9.4. いろいろな注意点

9.5. 継承

9.5.1. 多重継承

9.6. プライベート変数

9.7. 残りのはしばし

9.7.1. 例外はクラスであってもよい

9.8. イテレータ (iterator)

9.9. ジェネレータ (generator)

9.10. ジェネレータ式

10. 標準ライブラリミニツアー

10.1. OSへのインタフェース

10.2. ファイルのワイルドカード表記

10.3. コマンドライン引数

10.4. エラー出力のリダイレクトとプログラムの終了

10.5. 文字列のパターンマッチング

10.6. 数学

10.7. インターネットへのアクセス

10.8. 日付と時刻

10.9. データ圧縮

10.10. パフォーマンスの計測

10.11. 品質管理

10.12. バッテリー同梱

11. 標準ライブラリミニツアー – その 2

11.1. 出力のフォーマット

11.2. 文字列テンプレート

11.3. バイナリデータレコードの操作

11.4. マルチスレッド処理

11.5. ログ記録

11.6. 弱参照

11.7. リスト操作のためのツール

11.8. 10 進浮動小数演算

12. さあ何を？

13. 対話入力編集とヒストリ置換

13.1. 行編集

13.2. ヒストリ置換

13.3. キー割り当て

13.4. インタラクティブインタプタの代替

14. 浮動小数点演算、その問題と制限

14.1. 表現エラー

15. 日本語訳について

15.1. 翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

1. やる気を高めよう

コンピュータを使って様々な作業をしていたら、自動化したい作業が出てくるでしょう。たとえば、たくさんのテキストファイルで検索-置換操作を行いたい、大量の写真ファイルを込み入ったやりかたでリネームまたは整理したいといったものです。ひょっとすると、小さなカスタムデータベースや、何かに特化したGUIアプリケーション、シンプルなゲームを作りたいかもしれません。

もしあなたがプロのソフト開発者なら、C/C++/Java ライブラリを扱う必要があって、通常の write/compile/test/re-compile サイクルが遅すぎると感じるかもしれません。ひょっとするとそのようなライブラリのテストスイートを書いていて、テスト用のコードを書くのにうんざりしているかもしれません。拡張言語を使えるプログラムを書いていて、アプリケーションのために新しい言語一式の設計と実装をしたくないと思っているかもしれません。

Pythonはそんなあなたのための言語です。

それらの作業の幾つかは、 Unix シェルスクリプトや Windows バッチファイルで書くこともできますが、シェルスクリプトはファイル操作やテキストデータの操作には向いているもののGUIアプリケーションやゲームにはむいていません。 C/C++/Java プログラムを書くこともできますが、最初の試し書きにすらかなりの時間がかかってしまいます。Pythonは簡単に利用でき、Windows、 Mac OS X、そして Unix オペレーティングシステムで動作し、あなたの作業を素早く行う助けになるでしょう。

Pyhon は簡単に利用できますが、本物のプログラミング言語であり、シェルスクリプトやバッチファイルで提供されるよりもたくさんの、大規模プログラム向けの構造やサポートを提供しています。一方、 Python は C よりたくさんのエラーチェックを提供しており、超高級言語(very-high-level language) であり、可変長配列や辞書などの高級な型を組込みで持っています。そのような型は一般的なため、 Python は Awk や Perl が扱うものより (多くの場合、少なくともそれらの言語と同じくらい簡単に)大規模な問題に利用できます。

Python ではプログラムをモジュールに分割して他の Python プログラムで再利用できます。 Python には膨大な標準モジュールが付属していて、プログラムを作る上での基盤として、あるいは Python プログラミングを学ぶためのサンプルとして利用できます。組み込みモジュールではまた、ファイル I/O 、システムコール、ソケットといった機能や、 Tk のようなグラフィカルユーザインタフェースツールキットを使うためのインタフェースなども提供しています。

Python はインタプリタ言語です。コンパイルやリンクが必要ないので、プログラムを開発する際にかなりの時間を節約できます。インタプリタは対話的な使い方もできます。インタプリタは対話的にも使えるので、言語の様々な機能について実験してみたり、書き捨てのプログラムを書いたり、ボトムアップでプログラムを開発する際に関数をテストしたりといったことが簡単にできます。便利な電卓にもなります。

Python では、とてもコンパクトで読みやすいプログラムを書けます。 Python で書かれたプログラムは大抵、同じ機能を提供する C 言語, C++ 言語や Java のプログラムよりもはるかに短くなります。これには以下のようないくつかの理由があります:

高レベルのデータ型によって、複雑な操作を一つの実行文で表現できます。

実行文のグループ化を、グループの開始や終了の括弧ではなくインデントで行えます。

変数や引数の宣言が不要です。

Python は 拡張 できます: C 言語でプログラムを書く方法を知っているなら、新たな組み込み関数やモジュールを簡単にインタプリタに追加できます。これによって、処理速度を決定的に左右する操作を最大速度で動作するように実現したり、(ベンダ特有のグラフィクスライブラリのように) バイナリ形式でしか手に入らないライブラリを Python にリンクしたりできます。その気になれば、Python インタプリタを C で書かれたアプリケーションにリンクして、アプリケーションに対する拡張言語や命令言語としても使えます。

ところで、この言語は BBC のショー番組、”モンティパイソンの空飛ぶサーカス (Monty Python’s Flying Circus)” から取ったもので、爬虫類とは関係ありません。このドキュメントでは、モンティパイソンの寸劇への参照が許可されているだけでなく、むしろ推奨されています！

さて、皆さんはもう Python にワクワクして、もうちょっと詳しく調べてみたくなったはずです。プログラミング言語を習得する最良の方法は使ってみることですから、このチュートリアルではみなさんが読んだ内容を Python インタプリタで試してみることをおすすめします。

次の章では、まずインタプリタを使うための機微を説明します。これはさして面白みのない情報なのですが、後に説明する例題を試してみる上で不可欠なことです。

チュートリアルの残りの部分では、Python プログラム言語と実行システムの様々な機能を例題を交えて紹介します。単純な式、実行文、データ型から始めて、関数とモジュールを経て、最後には例外処理やユーザ定義クラスといったやや高度な概念にも触れます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

2. Python インタプリタを使う

2.1. インタプリタを起動する

Python が使えるコンピュータなら、インタプリタは大抵 /usr/local/bin/python にインストールされています。Unix シェルの検索パスに /usr/local/bin を入れれば、シェルで

python

とコマンドを入力すれば使えるようになります。

どのディレクトリに Python インタプリタをインストールするかはインストール時に選択できるので、インタプリタは他のディレクトリにあるかもしれません; 身近な Python に詳しい人か、システム管理者に聞いてみてください。 (例えば、その他の場所としては /usr/local/python が一般的です。)

Windows では、 Python は大抵の場合 C:\Python27 にインストールされますが、インストーラ実行時に変更することができます。このディレクトリをあなたのパスに追加するには、以下のコマンドをコマンドプロンプトで実行してください。

set path=%path%;C:\python27

ファイル終端文字 (Unixでは Control-D 、DOS や Windows では Control-Z) を一次プロンプト (訳注: ‘>>>’ のこと) に入力すると、インタプリタが終了ステータス 0 で終了します。もしこの操作がうまく働かないなら、コマンド: quit() と入力すればインタプリタを終了できます。

通常、インタプリタの行編集機能は、あまり洗練されたものではありません。 Unix では、インタプリタをインストールした誰かが GNU readline ライブラリのサポートを有効にしていれば、洗練された対話的行編集やヒストリ機能が利用できます。コマンドライン編集機能がサポートされているかを最も手っ取り早く調べる方法は、おそらく最初に表示された Python プロンプトに Control-P を入力してみることでしょう。ビープ音が鳴るなら、コマンドライン編集機能があります。編集キーについての解説は付録対話入力編集とヒストリ置換 を参照してください。何も起こらないように見えるか、 ^P がエコーバックされるなら、コマンドライン編集機能は利用できません。この場合、現在編集中の行から文字を削除するにはバックスペースを使うしかありません。

インタプリタはさながら Unix シェルのように働きます。標準入力が端末に接続された状態で呼び出されると、コマンドを対話的に読み込んで実行します。ファイル名を引数にしたり、標準入力からファイルを入力すると、インタプリタはファイルからスクリプト を読み込んで実行します。

インタプリタを起動する第二の方法は python -c command [arg] ... です。この形式では、シェルの -c オプションと同じように、 command に指定した文を実行します。 Python 文には、スペースなどのシェルにとって特殊な意味をもつ文字がしばしば含まれるので、 command 全体をシングルクォート(訳注: ')で囲っておいたほうが良いでしょう。

Python のモジュールには、スクリプトとしても便利に使えるものがあります。 python -m module [arg] ... のようにすると、 module のソースファイルを、フルパスを指定して起動したかのように実行できます。

スクリプトファイルが使われた場合、スクリプトを走らせて、そのまま対話モードに入れると便利なことがあります。これには -i をスクリプトの前に追加します。 (前の段落で述べたのと同じ理由から、スクリプトを標準入力から読み込んだ場合には、このオプションはうまく働きません。)

2.1.1. 引数の受け渡し

スクリプト名と引数を指定してインタプリタを起動した場合、スクリプト名やスクリプト名以後に指定した引数は、文字列のリストに変換されて sys モジュールの argv 変数に格納されます。 import sys することでこのリストにアクセスすることができます。 sys.argv には少なくとも一つ要素が入っています。スクリプト名も引数も指定しなければ sys.argv[0] は空の文字列になります。スクリプト名の代わりに '-' (標準入力を意味します) を指定すると、 sys.argv[0] は '-' になります。 -c command を使うと、 sys.argv[0] は '-c' になります。 -m module を使った場合、 sys.argv[0] はモジュールのフルパスになります。 -c command や -m module の後ろにオプションを指定した場合、 Python インタプリタ自体はこれらの引数を処理せず、 sys.argv を介して command や module から扱えるようになります。

2.1.2. 対話モード

インタプリタが命令を端末 (tty) やコマンドプロンプトから読み取っている場合、インタプリタは 対話モード (interactive mode) で動作しているといいます。このモードでは、インタプリタは 一次プロンプト (primary prompt) を表示して、ユーザにコマンドを入力するよう促します。一次プロンプトは普通、三つの「大なり記号」 (>>>) です。一つの入力が次の行まで続く (行継続: continuation line を行う) 場合、インタプリタは二次プロンプト (secondary prompt) を表示します。二次プロンプトは、デフォルトでは三つのドット (...) です。インタプリタは、最初のプロンプトを出す前にバージョン番号と著作権表示から始まる起動メッセージを出力します。

python
Python 2.7 (#1, Feb 28 2010, 00:02:06)
Type "help", "copyright", "credits" or "license" for more information.
>>>

行継続は、例えば以下の if 文のように、複数の行からなる構文を入力するときに必要です。

>>> the_world_is_flat = 1
>>> if the_world_is_flat:
...     print "Be careful not to fall off!"
...
Be careful not to fall off!

2.2. インタプリタとその環境

2.2.1. エラー処理

エラーが発生すると、インタプリタはエラーメッセージとスタックトレース (stack trace) を出力します。対話モードにいるときは、インタプリタは一次プロンプトに戻ります; スクリプトをファイルから実行しているときは、インタプリタはスタックトレースを出力した後、非ゼロの終了ステータスで終了します。 (try 文の except 節で処理された例外は、ここでいうエラーにはあたりません。) いくつかのエラーは常に致命的であり、非ゼロの終了ステータスとなるプログラムの終了を引き起こします。例えばインタプリタ内部の矛盾やある種のメモリ枯渇が当てはまります。エラーメッセージは全て標準エラー出力に書き込まれます; これに対して、通常は実行した命令から出力される内容は標準出力に書き込まれます。

割り込み文字 (interrupt character、普通は Control-C か DEL) を一次または二次プロンプトに対してタイプすると、入力が取り消されて一次プロンプトに戻ります。 [1] コマンドの実行中に割り込み文字をタイプすると KeyboardInterrupt 例外が送出されます。この例外は try 文で処理できます。

2.2.2. 実行可能な Python スクリプト

BSD 風の Unix システムでは、Python スクリプトはシェルスクリプトのように直接実行可能にできます。これを行うには、以下の行

#! /usr/bin/env python

(ここではインタプリタがユーザの PATH 上にあると仮定しています) をスクリプトの先頭に置き、スクリプトファイルに実行可能モードを設定します。 #! はファイルの最初の２文字でなければなりません。プラットフォームによっては、この最初の行を終端する改行文字が Windows 形式 ('\r\n') ではなく、 Unix形式('\n')でなければならないことがあります。ハッシュまたはポンド文字、すなわち '#' は、Python ではコメントを書き始めるために使われていることに注意してください。

chmod コマンドを使えば、スクリプトに実行モード (または実行権) を与えることができます。

$ chmod +x myscript.py

Windows では、”実行モード” のような概念はありません。 Python のインストーラーは自動的に .py ファイルを python.exe に関連付けるので、 Python ファイルをダブルクリックするとそれをスクリプトとして実行します。 .pyw 拡張子も(訳注: pythonw.exe に)関連付けられ、通常コンソールウィンドウを抑制して実行します。

2.2.3. ソースコードの文字コード

ASCII 形式でない文字コードエンコーディング を Python ソースコードファイル中で使うことができます。最良の方法は、 #! 行の直後にもう一行特殊なコメントを挿入して、ソースファイルのエンコーディングを指定するというものです。

# -*- coding: エンコーディング -*-

このように宣言しておくと、ソースファイル中の全ての文字は エンコーディングという文字コードでエンコードされているものとして扱われ、Unicode 文字列リテラルを指定したエンコードで直接記述できます。実際に利用できるエンコードのリストは Python ライブラリリファレンスの codecs の節にあります。

ノート

訳注: エンコーディング の部分には、実際には utf-8 や cp932 など、そのソースコードのエンコーディングを記述します。

プログラムから日本語を扱う場合には、必ずある程度の文字コードの知識が必要になります。もし文字コードについてよく判らないのであれば、まずは英語だけ扱いながらチュートリアルを読み進めて、並行して文字コードについても勉強してみましょう。

現在は、 Unicode の扱い易さの観点から、推奨される文字コードは utf-8 です。ただし、 utf-8 でソースを書いた場合、 utf-8 を表示できない Windows のコマンドプロンプトは print "こんにちは" を実行すると文字化けを起こすでしょう。その場合は、互換性のために古い cp932 エンコーディングを使うか、 print u"こんにちは" のように Unicode 文字列を使います。

例えばユーロ通貨記号を含む Unicode リテラルを書くために、 ISO-8859-15 エンコーディングを使えます。 ISO-8859-15 では、ユーロ通過記号の序数 (ordinal) は 164 です。以下のスクリプトは 8364 という値 (Unicode でユーロ記号に対応するコードポイントの値) を出力して終了します。

# -*- coding: iso-8859-15 -*-

currency = u"€"
print ord(currency)

利用しているエディタがファイルを UTF-8 バイト整列記号 (通称 BOM: Byte Order Mark) 付きの UTF-8 で保存できる場合、エンコード宣言の代わりに使うことができます。 IDLE は Options/General/Default Source Encoding/UTF-8 が設定されている場合、 UTF-8 でエンコードされたファイルの識別機能をサポートします。ただし、 (2.2 以前の) 古い Python リリースは UTF-8 シグネチャを理解しませんし、オペレーティングシステムは (Unix システムでしか使われていませんが) #! の行を含むスクリプトファイルを判別できなくなるので注意してください。

UTF-8 を (シグネチャやエンコーディング宣言を行って) 使うと、世界中のほとんどの言語で使われている文字を文字列リテラルやコメントの中に同時に使うことができます。識別子に対する非 ASCII 文字の使用はサポートされていません。全ての文字を正しく表示できるようにするには、使っているエディタがファイルを UTF-8 であると認識することができなければならず、かつファイル内で使われている全ての文字をサポートするようなフォントを使わなければなりません。

2.2.4. 対話モード用の起動時実行ファイル

Python を対話的に使うときには、インタプリタが起動する度に実行される何らかの標準的なコマンドがあると便利なことがよくあります。これを行うには、 PYTHONSTARTUP と呼ばれる環境変数を、インタプリタ起動時に実行されるコマンドが入ったファイル名に設定します。この機能は Unix シェルの .profile に似ています。

このファイルは対話セッションのときだけ読み出されます。 Python がコマンドをスクリプトから読み出しているときや、 /dev/tty がコマンドの入力元として明示的に指定されている(この場合対話的セッションのように動作します) わけではない 場合にはこのファイルは読み出されません。ファイル内のコマンドは、対話的コマンドが実行される名前空間と同じ名前空間内で実行されます。このため、ファイル内で定義されていたり import されたオブジェクトは、そのまま対話セッション内で使うことができます。また、このファイル内で sys.ps1 や sys.ps2 を変更して、プロンプトを変更することもできます。

もし現在のディレクトリから追加でスタートアップファイルを読み出したいのなら、グローバルのスタートアップファイルの中に if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py') のようなプログラムを書くことができます。スクリプト中でスタートアップファイルを使いたいのなら、以下のようにしてスクリプト中で明示的に実行しなければなりません。

import os
filename = os.environ.get('PYTHONSTARTUP')
if filename and os.path.isfile(filename):
    execfile(filename)

注記

[1]
GNU Readline パッケージに関する問題のせいで妨げられることがあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

3. 形式ばらない Python の紹介

以下の例では、入力と出力は (>>> や ...) といったプロンプトがあるかないかで区別します。例を実際に試してみるためには、プロンプトが表示されているときに、例中のプロンプトよりも後ろの内容全てをタイプ入力しなければなりません。プロンプトが先頭にない行はインタプリタからの出力です。

例中には二次プロンプトだけが表示されている行がありますが、これは空行を入力しなければならないことを意味しています。空行の入力は複数の行からなる命令の終わりをインタプリタに教えるために使われます。

このマニュアルにある例の多くは、対話プロンプトで入力されるものでもコメントを含んでいます。 Python におけるコメント文はハッシュ文字 # で始まり、物理行の終わりまで続きます。コメントは行の先頭にも、空白やコードの後にも書くことができますが、文字列リテラルの内部に置くことはできません。文字列リテラル中のハッシュ文字はただのハッシュ文字です。

コメントはコードを明快にするためのものであり、Pythonはコメントを解釈しません。なので、コードサンプルを実際に入力して試して見るときは、コメントをを省いても大丈夫です。

例:

# これは１番目のコメント
SPAM = 1                 # そしてこれは２番目のコメント
                         # ... そしてこれは３番目!
STRING = "# これはコメントではありません。"

3.1. Python を電卓として使う

それでは、簡単な Python コマンドをいくつか試しましょう。インタプリタを起動して、一次プロンプト、 >>> が現れるのを待ちます。 (そう長くはかからないはずです)

3.1.1. 数

インタプリタは単純な電卓のように動作します: 式を入力すると、その結果が表示されます。式の文法は素直なものです: 演算子 +, -, *, / は (Pascal や C といった) 他のほとんどの言語と同じように動作します。丸括弧をグループ化に使うこともできます。例えば、

>>> 2+2
4
>>> # これはコメント
... 2+2
4
>>> 2+2  # そしてこれはコードと同じ行にあるコメント
4
>>> (50-5*6)/4
5
>>> # 整数の除算は floor (実数の解を越えない最大の整数) を返す:
... 7/3
2
>>> 7/-3
-3

等号 ('=') は変数に値を代入するときに使います。代入を行っても、その結果が次のプロンプトの前に出力されたりはしません。

>>> width = 20
>>> height = 5*9
>>> width * height
900

複数の変数に同時に値を代入することができます。

>>> x = y = z = 0  # x と y と z をゼロにする
>>> x
0
>>> y
0
>>> z
0

変数は、利用する前に(値を代入することによって) “定義” しなければなりません。定義していない変数を利用しようとするとエラーが発生します。

>>> # 未定義変数にアクセスする
... n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

浮動小数点を完全にサポートしています。演算対象の値(オペランド)の型が統一されていない場合、演算子は整数のオペランドを浮動小数点型に変換します。

>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5

複素数もサポートされています。虚数は接尾辞 j または J を付けて書き表します。ゼロでない実数部をもつ複素数は (実数部+虚数部j) のように書き表すか、 complex(実数部, 虚数部) 関数で生成できます。

>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0,1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)

複素数は、常に実数部と虚数部に相当する二つの浮動小数点数で表されます。複素数 z からそれぞれの部分を取り出すには、 z.real と z.imag を使います。

>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5

浮動小数点数や整数へと変換する関数 (float(), int(), long()) は複素数に対しては動作しません — 複素数を実数に変換する方法には、ただ一つの正解というものがないからです。絶対値 (magnitude) を (浮動小数点数として) 得るには abs(z) を使い、実数部を得るには z.real を使ってください。

>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
5.0

対話モードでは、最後に表示された結果は変数 _ に代入されます。このことを利用すると、 Python を電卓として使うときに、計算を連続して行う作業が多少楽になります。以下に例を示します。

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

ユーザはこの変数を読取り専用の値として扱うべきです。この変数に明示的な代入を行ってはいけません — そんなことをすれば、同じ名前で元の特別な動作をする組み込み変数を覆い隠してしまうような、別のローカルな変数が生成されてしまいます。

3.1.2. 文字列

数のほかに、Python は文字列も操作できます。文字列はいくつもの方法で表現できます。文字列はシングルまたはダブルのクォートで囲みます。

>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'

インタプリタは、文字列操作の結果となる文字列を、それを入力する時と同じ方法で表示します。つまり、クォート記号で囲み、値を正確に表示するために文字列中のクォート記号やその他の特別な文字はバックスラッシュでエスケープします。文字列を囲うクォート記号は通常はシングルクォート(')ですが、文字列がシングルクォートを含みダブルクォート(")を含まない場合は、ダブルクォートで囲います。

文字列リテラルはいくつかの方法で複数行にまたがって記述できます。一つ目の方法は継続行を使うことで、これには行の末尾の文字をバックスラッシュにします。こうすることで、次の行が現在の行と論理的に継続していることを示します。

hello = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
    Note that whitespace at the beginning of the line is\
 significant."

print hello

\n を使って文字列に改行位置を埋め込まなくてはならないことに注意してください。末尾のバックスラッシュの後ろにある改行文字は無視されます。従って、上の例は以下のような出力を行います。

This is a rather long string containing
several lines of text just as you would do in C.
    Note that whitespace at the beginning of the line is significant.

別の方法として、対になった三重クォート """ または ''' で文字列を囲むこともできます。三重クォートを使っているときには、行末をエスケープする必要はありません。代わりに、行末の改行文字も文字列に含まれることになります。

print """
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
"""

は以下のような出力を行います。

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

文字列リテラルを “raw” 文字列にすると、 \n のようなエスケープシーケンスは改行に変換されません。逆に、行末のバックスラッシュやソースコード中の改行文字が文字列データに含められます。つまり、以下の例:

hello = r"This is a rather long string containing\n\
several lines of text much as you would do in C."

print hello

は、以下のような出力を行います。

This is a rather long string containing\n\
several lines of text much as you would do in C.

インタプリタは、文字列演算の結果を、タイプして入力する時と同じ方法で出力します。文字列はクオート文字で囲い、クオート文字自体やその他の特別な文字は、正しい文字が表示されるようにバックスラッシュでエスケープします。文字列がシングルクオートを含み、かつダブルクオートを含まない場合には、全体をダブルクオートで囲います。そうでない場合にはシングルクオートで囲みます。 (後で述べる print 文を使って、クオートやエスケープのない文字列を表示することができます。)

文字列は + 演算子で連結させる (くっつけて一つにする) ことができ、 * 演算子で反復させることができます。

>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'

隣あった二つの文字列リテラルは自動的に連結されます: 例えば、上記の最初の行は word = 'Help' 'A' と書くこともできました; この機能は二つともリテラルの場合にのみ働くもので、任意の文字列表現で使うことができるわけではありません。

>>> 'str' 'ing'             #  <-  これは ok
'string'
>>> 'str'.strip() + 'ing'   #  <-  これは ok
'string'
>>> 'str'.strip() 'ing'     #  <-  これはダメ
  File "<stdin>", line 1, in ?
    'str'.strip() 'ing'
                  ^
SyntaxError: invalid syntax

文字列は添字表記 (インデクス表記) することができます; C 言語と同じく、文字列の最初の文字の添字 (インデクス) は 0 となります。独立した文字型というものはありません; 単一の文字は、単にサイズが 1 の文字列です。 Icon 言語と同じく、部分文字列を スライス表記: コロンで区切られた二つのインデクスで指定することができます。

>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'

スライスのインデクスには便利なデフォルト値があります; 最初のインデクスを省略すると、0 と見なされます。第 2 のインデクスを省略すると、スライスしようとする文字列のサイズとみなされます。

>>> word[:2]    # 最初の 2 文字
'He'
>>> word[2:]    # 最初の 2 文字を除くすべて
'lpA'

C 言語の文字列と違い、Python の文字列は変更できません。インデックス指定された文字列中のある位置に代入を行おうとするとエラーになります。

>>> word[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support item assignment
>>> word[:1] = 'Splat'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support slice assignment

一方、文字列同士の内容を組み合わせた新しい文字列の生成は、簡単で効率的です。

>>> 'x' + word[1:]
'xelpA'
>>> 'Splat' + word[4]
'SplatA'

スライス演算には便利な不変式があります: s[:i] + s[i:] は s に等しくなります。

>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'

スライス表記に行儀の悪いインデクス指定をしても、値はたしなみよく処理されます: インデクスが大きすぎる場合は文字列のサイズと置き換えられます。スライスの下境界 (文字列の左端) よりも小さいインデクス値を上境界 (文字列の右端) に指定すると、空文字列が返されます。

>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''

インデクスを負の数にして、右から数えることもできます。例えば、

>>> word[-1]     # 末尾の文字
'A'
>>> word[-2]     # 末尾から 2 つめの文字
'p'
>>> word[-2:]    # 末尾の 2 文字
'pA'
>>> word[:-2]    # 末尾の 2 文字を除くすべて
'Hel'

-0 は 0 と全く同じなので、右から数えることができません。注意してください!

>>> word[-0]     # (-0 は 0 に等しい)
'H'

負で、かつ範囲外のインデクスをスライス表記で行うと、インデクスは切り詰められます。しかし、単一の要素を指定する (スライスでない) インデクス指定でこれを行ってはいけません:

>>> word[-100:]
'HelpA'
>>> word[-10]    # エラー
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: string index out of range

スライスの働きかたをおぼえる良い方法は、インデクスが文字と文字の あいだ (between) を指しており、最初の文字の左端が 0 になっていると考えることです。そうすると、 n 文字からなる文字列中の最後の文字の右端はインデクス n となります。例えば、

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

といった具合です。

数が記された行のうち、最初の方の行は、文字列中のインデクス 0...5 の位置を表します; 次の行は、対応する負のインデクスを表しています。 i から j までのスライスは、それぞれ i, j とラベル付けされたけられた境界の間のすべての文字からなります。

非負のインデクス対の場合、スライスされたシーケンスの長さは、スライスの両端のインデクスが範囲内にあるかぎり、インデクス間の差になります。例えば、 word[1:3] の長さは 2 になります。

組込み関数 len() は文字列の長さ (length) を返します。

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

参考

シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange

次節で記述されている文字列および Unicode 文字列は シーケンス型 の例であり、シーケンス型でサポートされている共通の操作をサポートしています。

文字列メソッド

(バイト)文字列や Unicode 文字列では、基本的な変換や検索を行うための数多くのメソッドをサポートしています。

文字列の書式指定

str.format() を使った文字列のフォーマットについて、ここで解説されています。

文字列フォーマット操作

(バイト)文字列や Unicode 文字列が % 演算子の左オペランドである場合に呼び出される(古い)フォーマット操作については、ここで詳しく記述されています。

3.1.3. Unicode 文字列

Python 2.0 から、プログラマはテキスト・データを格納するための新しいデータ型、 Unicode オブジェクトを利用できるようになりました。 Unicode オブジェクトを使うと、Unicode データ (http://www.unicode.org/ 参照) を記憶したり、操作したりできます。また、 Unicode オブジェクトは既存の文字列オブジェクトとよく統合されていて、必要に応じて自動変換されます。

Unicode には、古今のテキストで使われているあらゆる書き文字のあらゆる文字について、対応付けを行うための一つの序数を規定しているという利点があります。これまでは、書き文字のために利用可能な序数は 256 個しかなく、テキストは書き文字の対応付けを行っているコードページに束縛されているのが通常でした。このことは、とりわけソフトウェアの国際化 (internationalization. よく、 i18n と書かれます — 'i' + 18 文字 + 'n' の意) に対して大きな混乱をもたらしました。Unicode では、すべての書き文字に対して単一のコードページを定義することで、これらの問題を解決しています。

Python では、Unicode 文字列の作成は通常の文字列を作成するのと同じように単純なものです。

>>> u'Hello World !'
u'Hello World !'

クオートの前にある小文字の 'u' は、Unicode 文字列を生成することになっていることを示します。文字列に特殊な文字を含めたければ、Python の Unicode-Escape エンコーディングを使って行えます。以下はその方法を示しています。

>>> u'Hello\u0020World !'
u'Hello World !'

エスケープシーケンス \u0020 は、序数の値 0x0020 を持つ Unicode 文字 (スペース文字) を、指定場所に挿入することを示します。

他の文字は、それぞれの序数値をそのまま Unicode の序数値に用いて解釈されます。多くの西洋諸国で使われている標準 Latin-1 エンコーディングのリテラル文字列があれば、Unicode の下位 256 文字が Latin-1 の 256 文字と同じになっていて便利だと思うことでしょう。

上級者のために、通常の文字列の場合と同じく raw モードもあります。これには、文字列を開始するクオート文字の前に ‘ur’ を付けて、 Python に Raw-Unicode-Escape エンコーディングを使わせなければなりません。このモードでは、上記の \uXXXX の変換は、小文字の ‘u’ の前に奇数個のバックスラッシュがあるときにだけ適用されます。

>>> ur'Hello\u0020World !'
u'Hello World !'
>>> ur'Hello\\u0020World !'
u'Hello\\\\u0020World !'

raw モードは、正規表現を記述する時のように、沢山のバックスラッシュを入力しなければならないときとても役に立ちます。

これら標準のエンコーディングにとは別に、Python では、既知の文字エンコーディングに基づいて Unicode 文字列を生成する一連の手段を提供しています。

組込み関数 unicode() は、登録されているすべての Unicode codecs (COder: エンコーダと DECoder デコーダ) へのアクセス機能を提供します。codecs が変換できるエンコーディングには、よく知られているものとして Latin-1, ASCII, UTF-8 および UTF-16 があります。後者の二つは可変長のエンコードで、各 Unicode 文字を 1 バイトまたはそれ以上のバイト列に保存します。デフォルトのエンコーディングは通常 ASCIIに設定されています。ASCIIでは 0 から 127 の範囲の文字だけを通過させ、それ以外の文字は受理せずエラーを出します。 Unicode 文字列を印字したり、ファイルに書き出したり、 str() で変換すると、デフォルトのエンコーディングを使った変換が行われます。

>>> u"abc"
u'abc'
>>> u"あいう"
u'\x82\xa0\x82\xa2\x82\xa4'
>>> str(u"あいう")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5:
ordinal not in range(128)

ノート

訳注: IDLE をはじめ、ほとんどの Python 2 用のインタラクティブシェルは、非ASCII 文字を含む Unicode リテラルを利用することができません。このサンプルを実行するには、インタプリタ内蔵のインタラクティブシェルを利用する必要があります。

この問題は Python 3 では解決されています。

特定のエンコーディングを使って Unicode 文字列を 8 ビットの文字列に変換するために、Unicode オブジェクトは encode() メソッドを提供しています。このメソッドは第一引数としてエンコーディングの名前をとります。エンコーディング名には小文字の使用が推奨されています。

>>> u"あいう".encode('utf-8')
'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'

特定のエンコーディングで書かれているデータがあり、そこから Unicode 文字列を生成したいなら、 unicode() を使い、第 2 引数にエンコーディング名を指定します。

>>> unicode('\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86', 'utf-8')
u'\u3042\u3044\u3046'

3.1.4. リスト

Python は数多くの 複合 (compound) データ型を備えており、別々の値を一まとめにするために使えます。最も汎用的なデータ型は リスト(list) で、コンマで区切られた値からなるリストを各カッコで囲んだものとして書き表されます。リストの要素をすべて同じ型にする必要はありません。

>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]

文字列のインデクスと同じく、リストのインデクスは 0 から開始します。また、スライス、連結なども行えます。

>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boo!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']

すべてのスライス演算は、要求された要素を含む新しいリストを返します。これは、以下のスライスがリスト a の浅いコピーを返すことを意味します。

>>> a[:]
['spam', 'eggs', 100, 1234]

不変(immutable) な文字列型と違い、リストは個々の要素を変更することができます。

>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]

スライスに代入することもできます。スライスの代入を行って、リストのサイズを変更したり、完全に消すことさえできます。

>>> # いくつかの項目を置換する:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # いくつかの項目を除去する:
... a[0:2] = []
>>> a
[123, 1234]
>>> # いくつかの項目を挿入する:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # それ自身 (のコピー) を先頭に挿入する
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # リストをクリアする: 全てのアイテムを空のリストに置換する
>>> a[:] = []
>>> a
[]

組込み関数 len() はリストにも適用できます。

>>> a = ['a', 'b', 'c', 'd']
>>> len(a)
4

リストを入れ子にする (ほかのリストを含むリストを造る) ことも可能です。例えば、

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')     # 5.1節を参照
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']

最後の例では、 p[1] と q が実際には同一のオブジェクトを参照していることに注意してください! オブジェクトの意味付け(semantics) については、後ほど触れることにします。

3.2. プログラミングへの第一歩

もちろん、2 たす 2 よりももっと複雑な仕事にも Python を使うことができます。 Fibonacci 級数列の先頭の部分列は次のようにして書くことができます。

>>> # Fibonacci 級数:
... # 二つの要素の和が次の要素を定義する
... a, b = 0, 1
>>> while b < 10:
...     print b
...     a, b = b, a+b
...
1
1
2
3
5
8

上の例では、いくつか新しい機能を取り入れています。

最初の行には 複数同時の代入 (multiple assignment) が入っています: 変数 a と b は、それぞれ同時に新しい値 0 と 1 になっています。この代入は最後の行でも再度使われており、代入が行われる前に右辺の式がまず評価されます。右辺の式は左から右へと順番に評価されます。

while は、条件 (ここでは b < 10) が真である限り実行を繰り返し (ループし) ます。Python では、C 言語と同様に、ゼロでない整数値は真となり、ゼロは偽です。条件式は文字列値やリスト値、実際には任意のシーケンス型でもかまいません。 1つ以上の長さのシーケンスは真で、空のシーケンスは偽になります。例中で使われている条件テストはシンプルな比較です。標準的な比較演算子は C 言語と同様です: すなわち、 < (より小さい)、 > (より大きい)、 == (等しい)、 <= (より小さいか等しい)、 >= (より大きいか等しい)、および != (等しくない)、です。

ループの 本体 (body) は インデント (indent, 字下げ) されています: インデントは Python において実行文をグループにまとめる方法です。Python は (いまだに!) 賢い入力行編集機能を提供していないので、インデントされた各行を入力するにはタブや (複数個の) スペースを使わなければなりません。実際には、Python へのより複雑な入力を準備するにはテキストエディタを使うことになるでしょう; ほとんどのテキストエディタは自動インデント機能を持っています。複合文を対話的に入力するときには、(パーザはいつ最後の行を入力したのか推し量ることができないので) 入力の完了を示すために最後に空行を続けなければなりません。基本ブロックの各行は同じだけインデントされていなければならないので注意してください。

print は指定した (1つまたは複数の) 式の値を書き出します。 print は、(電卓の例でしたように) 単に値を出力したい式を書くのとは、複数の式や文字列を扱う方法が違います。文字列は引用符無しで出力され、複数の要素の間にはスペースが挿入されるので、以下のように出力をうまく書式化できます。

>>> i = 256*256
>>> print 'The value of i is', i
The value of i is 65536

末尾にコンマを入れると、出力を行った後に改行されません。

>>> a, b = 0, 1
>>> while b < 1000:
...     print b,
...     a, b = b, a+b
...
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

インタプリタは、最後に入力した行がまだ完全な文になっていない場合、改行をはさんで次のプロンプトを出力することに注意してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

4. その他の制御フローツール

先ほど紹介した while 文の他にも、 Python は他の言語でおなじみの制御フロー文を備えていますが、これらには多少ひねりを加えてあります。

4.1. if 文

おそらく最もおなじみの文型は if 文でしょう。例えば、

>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print 'Negative changed to zero'
... elif x == 0:
...      print 'Zero'
... elif x == 1:
...      print 'Single'
... else:
...      print 'More'
...
More

ゼロ個以上の elif 部を使うことができ、 else 部を付けることもできます。キーワード ‘elif‘ は ‘else if’ を短くしたもので、過剰なインデントを避けるのに役立ちます。一連の if ... elif ... elif ... は、他の言語における switch 文や case 文の代用となります。

4.2. for 文

Python の for 文は、読者が C 言語や Pascal 言語で使いなれているかもしれない for 文とは少し違います。 (Pascal のように) 常に算術型の数列にわたる反復を行ったり、 (C のように) 繰返しステップと停止条件を両方ともユーザが定義できるようにするのとは違い、Python の for 文は、任意のシーケンス型 (リストまたは文字列) にわたって反復を行います。反復の順番はシーケンス中に要素が現れる順番です。例えば、

>>> # いくつかの文字列の長さを測る:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
...     print x, len(x)
...
cat 3
window 6
defenestrate 12

反復操作の対象になっているシーケンスをループの中で書き換える操作 (リストのような、変更可能 (mutable) なシーケンス型でおきます) は、安全ではありません。もし反復処理を行う対象とするリスト型を変更したいのなら、 (対象の要素を複製するなどして) コピーに対して反復を行わなければなりません。この操作にはスライス表記を使うと特に便利です。

>>> for x in a[:]: # リスト全体のスライス・コピーを作る
...    if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

4.3. range() 関数

数列にわたって反復を行う必要がある場合、組み込み関数 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]

あるシーケンスにわたってインデクスで反復を行うには、 range() と len() を次のように組み合わせられます。

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb

しかし、多くの場合は enumerate() 関数を使う方が便利です。ループのテクニック を参照してください。

4.4. break 文と continue 文とループの else 節

break 文は、C 言語と同じく、最も内側の for または while ループを中断します。

continue 文は、これもまた C 言語から借りてきたものですが、ループを次の反復処理に飛ばします。

ループ文は else 節を持つことができます。 else 節は、 (for で) 反復処理対象のリストを使い切ってループが終了したとき、または (while で) 条件が偽になったときに実行されますが、 break 文でループが終了したときは実行されません。この動作を、素数を探す下記のループを例にとって示します。

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...            print n, 'equals', x, '*', n/x
...            break
...     else:
...          # 因数が見つからずにループが終了
...          print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

4.5. pass 文

pass 文は何もしません。 pass は、文を書くことが構文上要求されているが、プログラム上何の動作もする必要がない時に使われます。

>>> while True:
...     pass # キーボード割り込み (keyboard interrupt, Ctrl+C) をビジーウェイトする。
...

これは最小のクラスを作るときによく使われる方法です。

>>> class MyEmptyClass:
...     pass
...

pass が使われるもう1つの場所は、新しいコードを書いている時の関数や条件文の中身です。こうすることで、具体的なコードを書かないで抽象的なレベルで考えることができます。 pass は何もすることなく無視されます。

>>> def initlog(*args):
...     pass   # 忘れずにここを実装すること!
...

4.6. 関数を定義する

フィボナッチ数列 (Fibonacci series) を任意の上限値まで書き出すような関数を作成できます。

>>> def fib(n):    # n までのフィボナッチ級数を出力する
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print a,
...         a, b = b, a+b
...
>>> # 今しがた定義した関数を呼び出す:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

def は関数の 定義 (definition) を導くキーワードです。 def の後には、関数名と仮引数を丸括弧で囲んだリストを続けなければなりません。関数の実体を構成する実行文は次の行から始め、インデントされていなければなりません。

関数の本体の記述する文の最初の行は文字列リテラルにすることもできます。その場合、この文字列は関数のドキュメンテーション文字列 (documentation string)、または docstring と呼ばれます。 (docstring については ドキュメンテーション文字列 でさらに扱っています。) ドキュメンテーション文字列を使ったツールには、オンライン文書や印刷文書を自動的に生成したり、ユーザが対話的にコードから直接閲覧できるようにするものがあります。自分が書くコードにドキュメンテーション文字列を入れるのはよい習慣です。書く癖をつけてください。

関数を 実行 (execution) するとき、関数のローカル変数のために使われる新たなシンボルテーブル (symbol table) が用意されます。もっと正確にいうと、関数内で変数への代入を行うと、その値はすべてこのローカルなシンボルテーブルに記憶されます。一方、変数の参照を行うと、まずローカルなシンボルテーブルが検索され、次にさらに外側の関数 [1] のローカルなシンボルテーブルを検索し、その後グローバルなシンボルテーブルを調べ、最後に組み込みの名前テーブルを調べます。従って、関数の中では、グローバルな変数を参照することはできますが、直接値を代入することは (global 文で名前を挙げておかない限り)できません。

関数を呼び出す際の実際のパラメタ (引数) は、関数が呼び出されるときに関数のローカルなシンボルテーブル内に取り込まれます。そうすることで、引数は 値渡し (call by value) で関数に渡されることになります (ここでの 値 (value) とは常にオブジェクトへの 参照(reference) をいい、オブジェクトの値そのものではありません) [2] 。ある関数がほかの関数を呼び出すときには、新たな呼び出しのためにローカルなシンボルテーブルが新たに作成されます。

関数の定義を行うと、関数名は現在のシンボルテーブル内に取り入れられます。関数名の値は、インタプリタからはユーザ定義関数 (user-defined function) として認識される型を持ちます。この値は別の名前に代入して、後にその名前を関数として使うこともできます。これは一般的な名前変更のメカニズムとして働きます。

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

他の言語出身の人からは、 fib は値を返さないので関数ではなく手続き (procedure) だと異論があるかもしれませんね。技術的に言えば、実際には return 文を持たない関数もややつまらない値ですが値を返しています。この値は None と呼ばれます (これは組み込みの名前です)。 None だけを書き出そうとすると、インタプリタは通常出力を抑制します。本当に出力したいのなら、以下のように print を使うと見ることができます。

>>> fib(0)
>>> print fib(0)
None

フィボナッチ数列の数からなるリストを出力する代わりに、値を返すような関数を書くのは簡単です。

>>> def fib2(n): #  n までのフィボナッチ級数を返す
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a)    # 下記参照
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100)    # 関数を呼び出す
>>> f100                # 結果を出力する
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

この例は Python の新しい機能を示しています。

return 文では、関数から一つ値を返します。 return の引数となる式がない場合、 None が返ります。関数が終了したときにも None が返ります。

文 result.append(a) では、リストオブジェクト result の メソッド (method) を呼び出しています。メソッドとは、オブジェクトに ‘属している’ 関数のことで、 obj を何らかのオブジェクト (式であっても構いません)、 methodname をそのオブジェクトで定義されているメソッド名とすると、 obj.methodname と書き表されます。異なる型は異なるメソッドを定義しています。異なる型のメソッドで同じ名前のメソッドを持つことができ、あいまいさを生じることはありません。 (クラス (class) を使うことで、自前のオブジェクト型とメソッドを定義することもできます。 クラス 参照) 例で示されているメソッド append() は、リストオブジェクトで定義されています; このメソッドはリストの末尾に新たな要素を追加します。この例での append() は result = result + [a] と等価ですが、より効率的です。

4.7. 関数定義についてもう少し

可変個の引数を伴う関数を定義することもできます。引数の定義方法には 3 つの形式があり、それらを組み合わせることができます。

4.7.1. デフォルトの引数値

もっとも便利なのは、一つ以上の引数に対してデフォルトの値を指定する形式です。この形式を使うと、定義されている引数より少ない個数の引数で呼び出せる関数を作成します。

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = raw_input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print complaint

この関数はいくつかの方法で呼び出せます。

必須の引数のみ与える: ask_ok('Do you really want to quit?')

一つのオプション引数を与える: ask_ok('OK to overwrte the file?', 2)

全ての引数を与える: ask_ok('OK to overwrte the file?', 2, 'Come on, only yes or no!')

この例では in キーワードが導入されています。このキーワードはシーケンスが特定の値を含んでいるかどうか調べるのに使われます。

デフォルト値は、関数が定義された時点で、関数を 定義している 側のスコープ (scope) で評価されるので、

i = 5

def f(arg=i):
    print arg

i = 6
f()

は 5 を出力します。

重要な警告: デフォルト値は 1 度だけしか評価されません。デフォルト値がリストや辞書のような変更可能なオブジェクトの時にはその影響がでます。例えば以下の関数は、後に続く関数呼び出しで関数に渡されている引数を累積します。

def f(a, L=[]):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)

このコードは、

[1]
[1, 2]
[1, 2, 3]

を出力します。

後続の関数呼び出しでデフォルト値を共有したくなければ、代わりに以下のように関数を書くことができます。

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

4.7.2. キーワード引数

関数を keyword = value という形式のキーワード引数を使って呼び出すこともできます。例えば、以下の関数は、

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"

以下のいずれの方法でも呼び出せます。

parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

しかし、以下の呼び出しはすべて不正なものです。

parrot()                     # 必要な引数がない
parrot(voltage=5.0, 'dead')  # キーワード引数の後に非キーワード引数がある
parrot(110, voltage=220)     # 引数に対して値が重複している
parrot(actor='John Cleese')  # 未知のキーワードを使用している

一般に、引数リストでは、固定引数 (positional argument) の後ろにキーワード引数を置かねばならず、キーワードは仮引数名から選ばなければなりません。仮引数がデフォルト値を持っているかどうかは重要ではありません。引数はいずれも一つ以上の値を受け取りません — 同じ関数呼び出しの中では、固定引数に対応づけられた仮引数名をキーワードとして使うことはできません。この制限のために実行が失敗する例を以下に示します。

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'

仮引数の最後に **name の形式のものがあると、それまでの仮引数に対応したものを除くすべてのキーワード引数が入った辞書 (マップ型を参照) を受け取ります。 **name は *name の形式をとる、仮引数のリストを超えた位置指定引数の入ったタプルを受け取る引数 (次の節で述べます) と組み合わせることができます。 (*name は **name より前になければなりません)。例えば、ある関数の定義を以下のようにすると、

def cheeseshop(kind, *arguments, **keywords):
    print "-- Do you have any", kind, "?"
    print "-- I'm sorry, we're all out of", kind
    for arg in arguments:
        print arg
    print "-" * 40
    keys = sorted(keywords.keys())
    for kw in keys:
        print kw, ":", keywords[kw]

呼び出しは以下のようになり、

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

もちろん以下のように出力されます。

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

キーワード引数名のリストを、キーワード辞書の keys() メソッドの結果をソートして作成していることに注目してください。 sort() が呼び出されていないと、引数が出力される順番は不確定となります。

4.7.3. 任意引数リスト

最後に、最も使うことの少ない選択肢として、関数が任意の個数の引数で呼び出せるよう指定する方法があります。これらの引数はタプル (タプルとシーケンス を参照) に格納されます。可変個の引数の前に、ゼロ個かそれ以上の引数があっても構いません。

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

4.7.4. 引数リストのアンパック

引数がすでにリストやタプルになっていて、個別な固定引数を要求する関数呼び出しに渡すためにアンパックする必要がある場合には、逆の状況が起こります。例えば、組み込み関数 range() は引数 start と stop を別に与える必要があります。個別に引数を与えることができない場合、関数呼び出しを * 演算子を使って書き、リストやタプルから引数をアンパックします。

>>> range(3, 6)             # 個別の引数を使った通常の呼び出し
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # リストからアンパックされた引数での呼び出し
[3, 4, 5]

同じやりかたで、 ** オペレータを使って辞書でもキーワード引数を渡すことができます。

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

4.7.5. ラムダ式

多くの人の要望により、Lispのような関数型プログラミング言語によくあるいくつかの機能が Python に加えられました。キーワード lambda を使うと、名前のない小さな関数を生成できます。例えば lambda a, b: a+b は、二つの引数の和を返す関数です。ラムダ式(lambda form) は、関数オブジェクトが要求されている場所にならどこでも使うことができます。ラムダ式は、構文上単一の式に制限されています。意味付け的には、ラムダ形式はただ通常の関数に構文的な糖衣をかぶせたものに過ぎません。入れ子構造になった関数定義と同様、ラムダ式もそれを取り囲むスコープから変数を参照することができます。

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

4.7.6. ドキュメンテーション文字列

ドキュメンテーション文字列については、その内容と書式に関する慣習ができつつあります。

最初の行は、常に対象物の目的を短く簡潔にまとめたものでなくてはなりません。簡潔に書くために、対象物の名前や型を明示する必要はありません。名前や型は他の方法でも得られるからです (名前がたまたま関数の演算内容を記述する動詞である場合は例外です)。最初の行は大文字で始まり、ピリオドで終わっていなければなりません。

ドキュメンテーション文字列中にさらに記述すべき行がある場合、二行目は空行にし、まとめの行と残りの記述部分を視覚的に分離します。つづく行は一つまたはそれ以上の段落で、対象物の呼び出し規約や副作用について記述します。

Python のパーザは複数行にわたる Python 文字列リテラルからインデントを剥ぎ取らないので、ドキュメントを処理するツールでは必要に応じてインデントを剥ぎ取らなければなりません。この処理は以下の規約に従って行います。最初の行の 後にある 空行でない最初の行が、ドキュメント全体のインデントの量を決めます。 (最初の行は通常、文字列を開始するクオートに隣り合っているので、インデントが文字列リテラル中に現れないためです。) このインデント量と “等価な” 空白が、文字列のすべての行頭から剥ぎ取られます。インデントの量が少ない行を書いてはならないのですが、もしそういう行があると、先頭の空白すべてが剥ぎ取られます。インデントの空白の大きさが等しいかどうかは、タブ文字を (通常は 8 文字のスペースとして) 展開した後に調べられます。

以下に複数行のドキュメンテーション文字列の例を示します。

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print my_function.__doc__
Do nothing, but document it.

    No, really, it doesn't do anything.

4.8. 間奏曲: コーディングスタイル

これからより長くより複雑な Python のコードを書いていくので、そろそろコーディングスタイル について語っても良い頃です。ほとんどの言語は様々なスタイルで書け (もっと簡潔に言えば フォーマットでき)、スタイルによって読み易さが異なります。他人にとって読み易いコードにしようとするのはどんなときでも良い考えであり、良いコーディングスタイルを採用することが非常に強力な助けになります。

Python には、ほとんどのプロジェクトが守っているスタイルガイドとして PEP 8 [http://www.python.org/dev/peps/pep-0008] があります。それは非常に読み易く目に優しいコーディングスタイルを推奨しています。全ての Python 開発者はある時点でそれを読むべきです。ここに最も重要な点を抜き出しておきます。

インデントには空白 4 つを使い、タブは使わないこと。

空白 4 つは (深くネストできる) 小さいインデントと (読み易い) 大きいインデントのちょうど中間に当たります。タブは混乱させるので、使わずにおくのが良いです。

ソースコードの幅が 79 文字を越えないように行を折り返すこと。

こうすることで小さいディスプレイを使っているユーザも読み易くなり、大きなディスプレイではソースコードファイルを並べることもできるようになります。

関数やクラスや関数内の大きめのコードブロックの区切りに空行を使いなさい。

可能なら、コメントはコードと同じ行に書きなさい。

docstring を使いなさい。

演算子の前後とコンマの後には空白を入れ、括弧類のすぐ内側には空白を入れないこと: a = f(1, 2) + g(3, 4)

クラスや関数に一貫性のある名前を付けなさい。慣習では CamelCase をクラス名に使い、 lower_case_with_underscores を関数名やメソッド名に使います。常に self をメソッドの第 1 引数の名前 (クラスやメソッドについては クラス初見 を見よ) として使いなさい。

あなたのコードを世界中で使ってもらうつもりなら、風変りなエンコーディングは使わないこと。どんな場合でも ASCII が最も上手くいきます。

注記

[1]
訳注: Pythonでは関数内で関数を定義することができ、内側の関数から外側の関数のローカル変数を参照することができます。

[2]
実際には、 オブジェクトへの参照渡し (call by object reference) と書けばよいのかもしれません。というのは、変更可能なオブジェクトが渡されると、関数の呼び出し側は、呼び出された側の関数がオブジェクトに (リストに値が挿入されるといった) 何らかの変更に出くわすことになるからです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

5. データ構造

この章では、すでに学んだことについてより詳しく説明するとともに、いくつか新しいことを追加します。

5.1. リスト型についてもう少し

リストデータ型には、他にもいくつかメソッドがあります。リストオブジェクトのすべてのメソッドを以下に示します。

list.append(x)

リストの末尾に要素を一つ追加します。 a[len(a):] = [x] と等価です。

list.extend(L)

指定したリスト中のすべての要素を対象のリストに追加し、リストを拡張します。 a[len(a):] = L と等価です。

list.insert(i, x)

指定した位置に要素を挿入します。第 1 引数は、リストのインデクスで、そのインデクスを持つ要素の直前に挿入が行われます。従って、 a.insert(0, x) はリストの先頭に挿入を行います。また a.insert(len(a), x) は a.append(x) と等価です。

list.remove(x)

リスト中で、値 x を持つ最初の要素を削除します。該当する項目がなければエラーとなります。

list.pop([i])

リスト中の指定された位置にある要素をリストから削除して、その要素を返します。インデクスが指定されなければ、 a.pop() はリストの末尾の要素を削除して返します。この場合も要素は削除されます。 (メソッドの用法 (signature) で i の両側にある角括弧は、この引数がオプションであることを表しているだけなので、角括弧を入力する必要はありません。この表記法は Python Library Reference の中で頻繁に見ることになるでしょう。)

list.index(x)

リスト中で、値 x を持つ最初の要素のインデクスを返します。該当する項目がなければエラーとなります。

list.count(x)

リストでの x の出現回数を返します。

list.sort()

リストの項目を、インプレース演算 (in place、元のデータを演算結果で置き換えるやりかた) でソートします。

list.reverse()

リストの要素を、インプレース演算で逆順にします。

以下にリストのメソッドをほぼ全て使った例を示します。

>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x')
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]

5.1.1. リストをスタックとして使う

リスト型のメソッドのおかげで、簡単にリストをスタックとして使えます。スタックでは、最後に追加された要素が最初に取り出されます (“last-in, first-out”)。スタックの一番上に要素を追加するには append() を使います。スタックの一番上から要素を取り出すには pop() をインデクスを指定せずに使います。例えば以下のようにします。

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

5.1.2. リストをキューとして使う

リストをキュー (queue) として使うことも可能です。この場合、最初に追加した要素を最初に取り出します (“first-in, first-out”)。しかし、リストでは効率的にこの目的を達成することが出来ません。追加（append）や取り出し（pop）をリストの末尾に対しておこなうと速いのですが、挿入（insert）や取り出し（pop）をリストの先頭に対しておこなうと遅くなってしまいます（他の要素をひとつずつずらす必要があるからです）。

キューの実装には、 collections.deque を使うと良いでしょう。このクラスは良く設計されていて、高速な追加（append）と取り出し（pop）を両端に対して実現しています。例えば以下のようにします。

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

5.1.3. 関数型のプログラミングツール

組み込み関数には、リストに対して使うと非常に便利なものが三つあります。 filter(), map(), reduce() です。

filter(function, sequence) は、シーケンス sequence 中の要素 item から、 function(item) が真となるような要素からなるシーケンスを返します。もし sequence が string か tuple なら、返り値も同じ型になります。そうでなければ list になります。例えば、次のコードは25までの素数を計算します。

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

map(function, sequence) は、シーケンス sequence の各要素 item に対して function(item) を呼び出し、その戻り値からなるリストを返します。例えば、三乗された値の列を計算するには以下のようにします。

>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

複数のシーケンスを渡すこともできます。その場合、第一引数の関数はシーケンスの数と等しい数の引数を受け取る必要があり、各シーケンスの値が渡されます。 (幾つかのシーケンスが他のシーケンスよりも短かった場合は、その場所には None が渡されます。) 例です。

>>> seq = range(8)
>>> def add(x, y): return x+y
...
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]

reduce(function, sequence) は単一の値を返します。この値は 2 つの引数をとる関数 function をシーケンス sequence の最初の二つの要素を引数として呼び出し、次にその結果とシーケンスの次の要素を引数にとり、以降これを繰り返していきます。例えば、 1 から 10 までの数の総和を計算するには以下のようにします。

>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55

シーケンス中にただ一つしか要素がなければ、その値自体が返されます。シーケンスが空なら、例外が送出されます。

3 つめの引数をわたして、初期値を指定することもできます。この場合、空のシーケンスを渡すと初期値が返されます。それ以外の場合には、まず初期値とシーケンス中の最初の要素に対して関数が適用され、次いでその結果とシーケンスの次の要素に対して適用され、以降これが繰り返されます。例えば以下のようになります。

>>> def sum(seq):
...     def add(x,y): return x+y
...     return reduce(add, seq, 0)
...
>>> sum(range(1, 11))
55
>>> sum([])
0

実際には、上の例のように sum() を定義しないでください。数値の合計は広く必要とされている操作なので、すでに組み込み関数 sum(sequence) が提供されており、上の例と全く同様に動作します。

バージョン 2.3 で追加.

5.1.4. リストの内包表記

リストの内包表記 (list comprehension) は、 map() や filter() や lambda を使わずにリストを生成するための簡潔な方法を提供しています。内包表記によるリストの定義は、たいてい map(), filter(), lambda を使ってリストを生成するコードよりも明快になります。リストの内包表記は、式、続いて for 節、そしてその後ろに続くゼロ個以上の for 節または if 節からなります。結果として得られるリストの要素は、式を、それに続く for と if 節のコンテキストで評価した値になります。式をタプルとして評価したいなら、丸括弧で囲わなければなりません。

>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]
>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]
>>> [[x,x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
>>> [x, x**2 for x in vec]  # エラー - タプルには丸かっこが必要
  File "<stdin>", line 1, in ?
    [x, x**2 for x in vec]
               ^
SyntaxError: invalid syntax
>>> [(x, x**2) for x in vec]
[(2, 4), (4, 16), (6, 36)]
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> # 訳注: 上記の内包表記をループで書きなおすと、こうなります。
>>> L = []
>>> for x in vec1:
...     for y in vec2:
...         L.append(x*y)
...
>>> L
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]

ノート

訳注: 内包表記の中に for や if が複数回現れる場合、左側の for, if が、内包表記ではなくループで書いた場合の外側のブロックになります。上の例はまだ判りやすいですが、複雑な内包表記はすぐに読みにくくなってしまうので、その場合はループで書き下した方が良いでしょう。

リストの内包表記は map() よりもはるかに柔軟性があり、複雑な式や入れ子になった関数でも利用できます。

>>> [str(round(355/113.0, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

5.1.5. ネストしたリストの内包表記

もし望むなら、リストの内包表記はネストさせることができます。ネストしたリストの内包表記はとても強力な道具なのですが – 全ての強力な道具がそうであるように – とにかく気を付けて使う必要があります。

1行を1つのリストに対応させた3つのリストからなるリストで、3行3列の行列を表現した例を考えます。

>>> mat = [
...        [1, 2, 3],
...        [4, 5, 6],
...        [7, 8, 9],
...       ]

ここで、行と列を入れ換えたいとしたときにリストの内包表記が使えます。

>>> print [[row[i] for row in mat] for i in [0, 1, 2]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

ネストした リストの内包表記は特に気を付けて使わなければなりません。

リストの内包表記を怖がらずにネストするためには、右から左へ読んでください。

このコードの断片のより冗長なバージョンを見ると処理の流れがはっきりします。

for i in [0, 1, 2]:
    for row in mat:
        print row[i],
    print

実際には複雑な流れの式よりも組み込み関数を使う方が良いです。この場合 zip() 関数が良い仕事をしてくれるでしょう。

>>> zip(*mat)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

この行にあるアスタリスクの詳細については 引数リストのアンパックを参照してください。

5.2. del 文

リストから要素を削除する際、値を指定する代わりにインデックスを指定する方法があります。それが del 文です。これは pop() メソッドと違い、値を返しません。 del 文はリストからスライスを除去したり、リスト全体を削除することもできます(以前はスライスに空のリストを代入して行っていました)。例えば以下のようにします。

>>> a
[-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del は変数全体の削除にも使えます。

>>> del a

この文の後で名前 a を参照すると、(別の値を a に代入するまで) エラーになります。 del の別の用途についてはまた後で取り上げます。

5.3. タプルとシーケンス

リストや文字列には、インデクスやスライスを使った演算のように、数多くの共通の性質があることを見てきました。これらは シーケンス (sequence) データ型 (シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange を参照) の二つの例です。 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) の例です。値 12345, 54321, 'hello!' が一つのタプルにパックされます。逆の演算も可能です。

>>> x, y, z = t

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

5.4. 集合型

Python には、 集合 (set) を扱うためのデータ型もあります。集合とは、重複する要素をもたない、順序づけられていない要素の集まりです。 Set オブジェクトは、結合 (union)、交差 (intersection)、差分 (difference)、対称差 (symmetric difference)といった数学的な演算もサポートしています。

簡単なデモンストレーションを示します。

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> fruit = set(basket)               # 重複のない集合を作成
>>> fruit
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruit                 # 高速なメンバシップテスト
True
>>> 'crabgrass' in fruit
False

>>> # 二つの単語の文字を例にした集合間の演算
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # a 内の一意な文字
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b                              # a にあって b にない文字
set(['r', 'd', 'b'])
>>> a | b                              # a か b にある文字
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                              # a と b の双方にある文字
set(['a', 'c'])
>>> a ^ b                              # a または b の片方だけにある文字
set(['r', 'd', 'b', 'm', 'z', 'l'])

5.5. 辞書

もう一つ、有用な型が Python に組み込まれています。それは 辞書 (dictionary) (マップ型 を参照)です。辞書は他の言語にも “連想記憶 (associated memory)” や “連想配列 (associative array)” という名前で存在することがあります。ある範囲の数でインデクス化されているシーケンスと異なり、辞書は キー (key) でインデクス化されています。このキーは何らかの変更不能な型になります。文字列、数値は常にキーにすることができます。タプルは、文字列、数値、その他のタプルのみを含む場合はキーにすることができます。直接、あるいは間接的に変更可能なオブジェクトを含むタプルはキーにできません。リストをキーとして使うことはできません。これは、リストにスライスやインデクス指定の代入を行ったり、 append() や extend() のようなメソッドを使うと、インプレースで変更することができるためです。

辞書は順序付けのされていない キー(key): 値(value) のペアの集合であり、キーが (辞書の中で)一意でければならない、と考えるとよいでしょう。波括弧 (brace) のペア: {} は空の辞書を生成します。カンマで区切られた key: value のペアを波括弧ペアの間に入れると、辞書の初期値となる key: value が追加されます; この表現方法は出力時に辞書が書き出されるのと同じ方法です。

辞書での主な操作は、ある値を何らかのキーを付けて記憶することと、キーを指定して値を取り出すことです。 del で key: value のペアを削除することもできます。すでに使われているキーを使って値を記憶すると、以前そのキーに関連づけられていた値は忘れ去られてしまいます。存在しないキーを使って値を取り出そうとするとエラーになります。

辞書オブジェクトの keys() メソッドは、辞書で使われている全てのキーからなるリストを適当な順番で返します (ソートされたリストが欲しい場合は、このキーのリストに sorted() を使ってください)。ある単一のキーが辞書にあるかどうか調べるには、 in キーワードを使います。

以下に、辞書を使った簡単な例を示します。

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> 'guido' in tel
True

dict() コンストラクタは、キーと値のペアのタプルを含むリストから辞書を生成します。キーと値のペアがあるパターンをなしているなら、リストの内包表現を使えばキーと値のリストをコンパクトに指定できます。

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> dict([(x, x**2) for x in (2, 4, 6)])     # リスト内包表現を利用
{2: 4, 4: 16, 6: 36}

後ほど、 key, value ペアを dict() コンストラクタに渡すのにより適した、ジェネレータ式について学習します。

キーが単純な文字列の場合、キーワード引数を使って定義する方が単純な場合もあります。

>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}

5.6. ループのテクニック

辞書に対してループを行う際、 iteritems() メソッドを使うと、キーとそれに対応する値を同時に取り出せます。

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
...     print k, v
...
gallahad the pure
robin the brave

シーケンスにわたるループを行う際、 enumerate() 関数を使うと、要素のインデックスと要素を同時に取り出すことができます。

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print i, v
...
0 tic
1 tac
2 toe

二つまたはそれ以上のシーケンス型を同時にループするために、関数 zip() を使って各要素をひと組みにすることができます。

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print 'What is your {0}?  It is {1}.'.format(q, a)
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

シーケンスを逆方向に渡ってループするには、まずシーケンスの範囲を順方向に指定し、次いで関数 reversed() を呼び出します。

>>> for i in reversed(xrange(1,10,2)):
...     print i
...
9
7
5
3
1

シーケンスをソートされた順序でループするには、 sorted() 関数を使います。この関数は元の配列を変更せず、ソート済みの新たな配列を返します。

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print f
...
apple
banana
orange
pear

5.7. 条件についてもう少し

while や if 文で使った条件 (condiction) には、値の比較だけでなく、他の演算子も使うことができます、

比較演算子 in および not in は、ある値があるシーケンス中に存在するか (または存在しないか) どうかを調べます。演算子 is および is not は、二つのオブジェクトが実際に同じオブジェクトであるかどうかを調べます。この比較は、リストのような変更可能なオブジェクトにだけ意味があります。全ての比較演算子は同じ優先順位を持っており、ともに数値演算子よりも低い優先順位となります。

ノート

訳注: is は、 is None のように、シングルトンの変更不能オブジェクトとの比較に用いる場合もあります。(「変更可能なオブジェクトにだけ意味があります」の部分を削除することを Doc-SIG に提案中。)

比較は連結させることができます。例えば、 a < b == c は、 a が b より小さく、かつ b と c が等しいかどうかをテストします。

ブール演算子 and や or で比較演算を組み合わせることができます。そして、比較演算 (あるいは何らかのブール式) の結果の否定は not でとれます。これらの演算子は全て、比較演算子よりも低い優先順位になっています。 A and not B or C と (A and (not B)) or C が等価になるように、ブール演算子の中で、 not の優先順位が最も高く、 or が最も低くなっています。もちろん、丸括弧を使えば望みの組み合わせを表現できます。

ブール演算子 and と or は、いわゆる 短絡 (short-circuit) 演算子です。これらの演算子の引数は左から右へと順に評価され、結果が確定した時点で評価を止めます。例えば、 A と C は真で B が偽のとき、 A and B and C は式 C を評価しません。一般に、短絡演算子の戻り値をブール値ではなくて一般的な値として用いると、値は最後に評価された引数になります。

比較や他のブール式の結果を変数に代入することもできます。例えば、

>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'

Python では、C 言語と違って、式の内部で代入を行えないので注意してください。 C 言語のプログラマは不満に思うかもしれませんが、この仕様は、 C 言語プログラムで遭遇する、式の中で == のつもりで = とタイプしてしまうといったありふれた問題を回避します。

5.8. シーケンスとその他の型の比較

シーケンスオブジェクトは同じシーケンス型の他のオブジェクトと比較できます。比較には 辞書的な (lexicographical) 順序が用いられます。まず、最初の二つの要素を比較し、その値が等しくなければその時点で比較結果が決まります。等しければ次の二つの要素を比較し、以降シーケンスの要素が尽きるまで続けます。比較しようとする二つの要素がいずれも同じシーケンス型であれば、そのシーケンス間での辞書比較を再帰的に行います。二つのシーケンスの全ての要素の比較結果が等しくなれば、シーケンスは等しいとみなされます。片方のシーケンスがもう一方の先頭部分にあたる部分シーケンスならば、短い方のシーケンスが小さいシーケンスとみなされます。文字列に対する辞書的な順序づけには、個々の文字ごとに ASCII 順序を用います。以下に、同じ型のオブジェクトを持つシーケンス間での比較を行った例を示します。

(1, 2, 3)              < (1, 2, 4)
[1, 2, 3]              < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4)           < (1, 2, 4)
(1, 2)                 < (1, 2, -1)
(1, 2, 3)             == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab'))   < (1, 2, ('abc', 'a'), 4)

違う型のオブジェクト間の比較は認められていることに注意してください。比較結果は決定性がありますが、その決め方は、型は型の名前で順番づけられる、という恣意的なものです。従って、リスト (list) 型は常に文字列 (string) 型よりも小さく、文字列型は常にタプル (tuple) よりも小さい、といった具合になります。 [1] 型混合の数値の比較は、数値そのものに従って比較されるので、例えば 0 は 0.0 と等しい、という結果になります。

注記

[1]
異なる型のオブジェクトを比較するための規則を今後にわたって当てにしてはなりません。 Python 言語の将来のバージョンでは変更されるかもしれません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

6. モジュール

Python インタプリタを終了させ、再び起動すると、これまでに行ってきた定義 (関数や変数) は失われています。ですから、より長いプログラムを書きたいなら、テキストエディタを使ってインタプリタへの入力を用意しておき、手作業の代わりにファイルを入力に使って動作させるとよいでしょう。この作業を スクリプト (script) の作成と言います。プログラムが長くなるにつれ、メンテナンスを楽にするために、スクリプトをいくつかのファイルに分割したくなるかもしれません。また、いくつかのプログラムで書いてきた便利な関数について、その定義をコピーすることなく個々のプログラムで使いたいと思うかもしれません。

こういった要求をサポートするために、Python では定義をファイルに書いておき、スクリプトの中やインタプリタの対話インスタンス上で使う方法があります。このファイルを モジュール (module) と呼びます。モジュールにある定義は、他のモジュールや main モジュール (実行のトップレベルや電卓モードでアクセスできる変数の集まりを指します) に import (取り込み) することができます。

モジュールは Python の定義や文が入ったファイルです。ファイル名はモジュール名に接尾語 .py がついたものになります。モジュールの中では、(文字列の) モジュール名をグローバル変数 __name__ で取得できます。例えば、お気に入りのテキストエディタを使って、現在のディレクトリに以下の内容のファイル fibo.py を作成してみましょう。

# フィボナッチ数列モジュール

def fib(n):    # nまでのフィボナッチ級数を出力
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b

def fib2(n): # nまでのフィボナッチ級数を返す
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

次に Python インタプリタに入り、モジュールを以下のコマンドで import しましょう。

>>> import fibo

この操作では、 fibo で定義された関数の名前を直接現在のシンボルテーブルに入力することはありません。単にモジュール名 fibo だけをシンボルテーブルに入れます。関数にはモジュール名を使ってアクセスします。

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

関数を度々使うのなら、ローカルな名前に代入できます。

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1. モジュールについてもうすこし

モジュールには、関数定義に加えて実行文を入れることができます。これらの実行文はモジュールを初期化するためのものです。これらの実行文は、モジュールがどこかで 最初に import された時にだけ実行されます。 [1]

各々のモジュールは、自分のプライベートなシンボルテーブルを持っていて、モジュールで定義されている関数はこのテーブルをグローバルなシンボルテーブルとして使います。したがって、モジュールの作者は、ユーザのグローバル変数と偶然的な衝突が起こる心配をせずに、グローバルな変数をモジュールで使うことができます。一方、自分が行っている操作をきちんと理解していれば、モジュール内の関数を参照するのと同じ表記法 modname.itemname で、モジュールのグローバル変数をいじることもできます。

モジュールが他のモジュールを import することもできます。 import 文は全てモジュールの(さらに言えばスクリプトでも)先頭に置きますが、これは慣習であって必須ではありません。 import されたモジュール名は import を行っているモジュールのグローバルなシンボルテーブルに置かれます。

import 文には、あるモジュール内の名前を、import を実行しているモジュールのシンボルテーブル内に直接取り込むという変型があります。例えば、

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

この操作は、import の対象となるモジュール名をローカルなシンボルテーブル内に取り入れることはありません (従って上の例では、 fibo は定義されません)。

モジュールで定義されている名前を全て import するという変型もあります。

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

上の操作は、アンダースコア (_) で開始する名前以外の全ての名前を import します。

一般的には、モジュールやパッケージから * を import するというやり方には賛同できません。というのは、この操作を行うとしばしば可読性に乏しいコードになるからです。しかし、対話セッションでキータイプの量を減らすために使うのは構わないでしょう。

ノート

実行効率上の理由で、各モジュールはインタープリタの 1 セッションごとに 1 回だけ import されます。従って、モジュールを修正した場合には、インタープリタを再起動させなければなりません – もしくは、その場で手直ししてテストしたいモジュールが 1 つだった場合には、例えば reload(modulename) のように reload() を使ってください。

6.2. モジュールをスクリプトとして実行する

Python モジュールを

python fibo.py <arguments>

と実行すると、 __name__ に __main__ が設定されている点を除いて import したときと同じようにモジュール内のコードが実行されます。つまりモジュールの末尾に、

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

このコードを追加することで、このファイルが import できるモジュールであると同時にスクリプトとしても使えるようになります。なぜならモジュールが “main” ファイルとして起動されたときだけ、コマンドラインを解釈するコードが実行されるからです。

$ python fibo.py 50
1 1 2 3 5 8 13 21 34

モジュールが import された場合は、そのコードは実行されません。

>>> import fibo
>>>

この方法はモジュールに便利なユーザインターフェースを提供したり、テストのために (スクリプトをモジュールとして起動しテストスイートを実行して) 使われます。

6.2.1. モジュール検索パス

spam という名前のモジュールが import されると、インタプリタは spam.py という名前のファイルを現在のディレクトリ内で探し、次に環境変数 PYTHONPATH に指定されているディレクトリのリストから探します。 PYTHONPATH はシェル変数 PATH と同じ構文、すなわちディレクトリ名を並べたものです。 PYTHONPATH が設定されていないか、探しているファイルが見つからなかった場合は、検索対象をインストール方法に依存するデフォルトのパスにして続けます。 Unixでは、このパスは通常 .:/usr/locall/lib/python です。

実際には、モジュールは変数 sys.path で指定されたディレクトリのリストから検索されます。 sys.path は、入力とするスクリプトの入ったディレクトリ (現在のディレクトリ)、 PYTHONPATH 、およびインストール方法依存のデフォルト値を使って初期化されます。 Python プログラマは、自分の行っている操作を理解しているなら、この変数を使ってモジュール検索パスを修正したり置き換えたりすることができます。起動しようとするスクリプトの入ったディレクトリが検索パス上にあるため、スクリプトが標準モジュールと同じ名前をもたないようにすることが重要です。さもなければ、Python が標準モジュールを import するときにスクリプトをモジュールとして import しようと試みてしまうので注意してください。このような誤りを犯すと、通常はエラーになります。詳しくは 標準モジュール を参照してください。

6.2.2. “コンパイル” された Python ファイル

たくさんの標準モジュールを使うような短いプログラムの起動時間を大きく高速化するために、 spam.py が見つかったディレクトリに spam.pyc という名前のファイルがあった場合には、このファイルをモジュール spam の “バイトコンパイルされた” バージョンであると仮定します。 spam.pyc を生成するのに使われたバージョンの spam.py のファイル修正時刻が spam.pyc に記録されており、この値が一致しなければ spam.pyc ファイルは無視されます。

通常、 spam.pyc ファイルを生成するために何かをする必要はありません。 spam.py が無事コンパイルされると、常にコンパイルされたバージョンを spam.pyc へ書き出すよう試みます。この試みが失敗してもエラーにはなりません。何らかの理由でファイルが完全に書き出されなかった場合、作成された smap.pyc は無効であるとみなされ、それ以後無視されます。 spam.pyc ファイルの内容はプラットフォームに依存しないので、 Python のモジュールのディレクトリは異なるアーキテクチャのマシン間で共有することができます。

エキスパート向けのTips:

Python インタプリタを -O フラグ付きで起動すると、最適化されたコードが生成されて .pyo ファイルに保存されます。最適化機構は今のところあまり役に立っていません。最適化機構は assert 文と SET_LINENO 命令を除去しているだけです。 -O を使うと、 すべての バイトコード (bytecode) が最適化されます。 .pyc ファイルは無視され、 .py ファイルは最適化されたバイトコードにコンパイルされます。

二つの -O フラグ (-OO) を Python インタプリタへ渡すと、バイトコードコンパイラは、まれにプログラムが正しく動作しなくなるかもしれないような最適化を実行します。現状では、ただ __doc__ 文字列をバイトコードから除去して、よりコンパクトな .pyo ファイルにするだけです。この文字列が利用できることをあてにしているプログラムがあるかもしれないので、自分の行っている操作が何かわかっているときにだけこのオプションを使うべきです。

.pyc ファイルや .pyo ファイルから読み出されたとしても、プログラムは何ら高速に動作するわけではありません。 .pyc ファイルや .pyo ファイルで高速化されるのは、読み込まれるときの速度だけです。

スクリプトの名前をコマンドラインで指定して実行した場合、そのスクリプトのバイトコードが .pyc や .pyo に書き出されることはありません。従って、スクリプトのほとんどのコードをモジュールに移し、そのモジュールを import する小さなブートストラップスクリプトを作れば、スクリプトの起動時間を短縮できるときがあります。 .pyc または .pyo ファイルの名前を直接コマンドラインに指定することもできます。

一つのモジュールについて、ファイル spam.py のない spam.pyc (-O を使ったときは spam.pyo) があってもかまいません。この仕様は、Python コードでできたライブラリをリバースエンジニアリングがやや困難な形式で配布するために使えます。

compileall は、 .pyc ファイル (または -O を使ったときは .pyo ファイル) をディレクトリ内の全てのモジュールに対して生成することができます。

6.3. 標準モジュール

Python には標準モジュールのライブラリが付属しています。ライブラリは独立したドキュメント Python ライブラリリファレンス (以降 “ライブラリリファレンス”)で記述されています。モジュールによってはインタプリタに組み込まれたものがあります。インタプリタに組み込まれているモジュールが提供しているのは、言語の中核の部分ではありませんが、効率化のためや、システムコールのようなオペレーティングシステムの根本機能へのアクセス手段を提供するための操作です。これらのモジュールのセットは設定時に選択可能で、またプラットフォームにも依存します。例えば、 winreg モジュールは、 Windows でのみ提供されます。とりわけ、注目に値するモジュールが一つあります。 sys はどの Python インタプリタにも組み込まれています。変数 sys.ps1 と sys.ps2 は、それぞれ一次プロンプトと二次プロンプトとして使われる文字列を定義しています。

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>

これらの二つの変数は、インタプリタが対話モードにあるときだけ定義されています。

変数 sys.path は文字列からなるリストで、インタプリタがモジュールを検索するときのパスを決定します。 sys.path は環境変数 PYTHONPATH から得たデフォルトパスに、 PYTHONPATH が設定されていなければ組み込みのデフォルト値に設定されます。標準的なリスト操作で変更することができます。

>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')

6.4. dir() 関数

組込み関数 dir() は、あるモジュールがどんな名前を定義しているか調べるために使われます。 dir() はソートされた文字列のリストを返します。

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
 '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
 'builtin_module_names', 'byteorder', 'callstats', 'copyright',
 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook',
 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache',
 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
 'version', 'version_info', 'warnoptions']

引数がなければ、 dir() は現在定義している名前を列挙します。

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']

変数、モジュール、関数、その他の、すべての種類の名前をリストすることに注意してください。

dir() は、組込みの関数や変数の名前はリストしません。これらの名前からなるリストが必要なら、標準モジュール __builtin__ で定義されています。

>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning',
 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError',
 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
 'NotImplementedError', 'OSError', 'OverflowError',
 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',
 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError',
 'UserWarning', 'ValueError', 'Warning', 'WindowsError',
 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
 '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer',
 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile',
 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview',
 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range',
 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set',
 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

6.5. パッケージ

パッケージ (package) は、Python のモジュール名前空間を “ドット付きモジュール名” を使って構造化する手段です。例えば、モジュール名 A.B は、 A というパッケージのサブモジュール B を表します。ちょうど、モジュールを利用すると、別々のモジュールの著者が互いのグローバル変数名について心配しなくても済むようになるのと同じように、ドット付きモジュール名を利用すると、 NumPy や Python Imaging Library のように複数モジュールからなるパッケージの著者が、互いのモジュール名について心配しなくても済むようになります。

音声ファイルや音声データを一様に扱うためのモジュールのコレクション (“パッケージ”) を設計したいと仮定しましょう。音声ファイルには多くの異なった形式がある (通常は拡張子、例えば .wav, .aiff, .au などで認識されます) ので、様々なファイル形式間で変換を行うためのモジュールからなる、次第に増えていくモジュールのコレクションを作成したりメンテナンスしたりする必要があるかもしれません。また、音声データに対して実行したい様々な独自の操作 (ミキシング、エコーの追加、イコライザ関数の適用、人工的なステレオ効果の作成など) があるかもしれません。そうなると、こうした操作を実行するモジュールを果てしなく書くことになるでしょう。以下に (階層的なファイルシステムで表現した) パッケージの構造案を示します。

sound/                          トップレベルのパッケージ
      __init__.py               サウンドパッケージを初期化する
      formats/                  ファイルフォーマット変換用の下位パッケージ
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  サウンド効果用の下位パッケージ
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  フィルタ用の下位パッケージ
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

パッケージを import する際、 Python は sys.path 上のディレクトリを検索して、トップレベルのパッケージの入ったサブディレクトリを探します。

あるディレクトリを、パッケージが入ったディレクトリとしてPython に扱わせるには、ファイル __init__.py が必要です。このファイルを置かなければならないのは、 string のようなよくある名前のディレクトリにより、モジュール検索パスの後の方で見つかる正しいモジュールが意図せず隠蔽されてしまうのを防ぐためです。最も簡単なケースでは __init__.py はただの空ファイルで構いませんが、 __init__.py ではパッケージのための初期化コードを実行したり、後述の __all__ 変数を設定してもかまいません。

パッケージのユーザは、個々のモジュールをパッケージから import することができます。例えば、

import sound.effects.echo

この操作はサブモジュール sound.effects.echo をロードします。このモジュールは、以下のように完全な名前で参照しなければなりません。

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

サブモジュールを import するもう一つの方法を示します。

from sound.effects import echo

これもサブモジュール echo をロードし、 echo をパッケージ名を表す接頭辞なしで利用できるようにします。従って以下のように用いることができます。

echo.echofilter(input, output, delay=0.7, atten=4)

さらにもう一つのバリエーションとして、必要な関数や変数を直接 import する方法があります。

from sound.effects.echo import echofilter

この操作も同様にサブモジュール echo をロードしますが、 echofilter() を直接利用できるようにします。

echofilter(input, output, delay=0.7, atten=4)

from package import item を使う場合、 item はパッケージ package のサブモジュール (またはサブパッケージ) でもかまいませんし、関数やクラス、変数のような、 package で定義されている別の名前でもかまわないことに注意してください。 import 文はまず、 item がパッケージ内で定義されているかどうか調べます。定義されていなければ、 item はモジュール名であると仮定して、モジュールをロードしようと試みます。もしモジュールが見つからなければ、 ImportError が送出されます。

反対に、 import item.subitem.subsubitem のような構文を使った場合、最後の subsubitem を除く各要素はパッケージでなければなりません。最後の要素はモジュールかパッケージにできますが、一つ前の要素で定義されているクラスや関数や変数にはできません。

6.5.1. パッケージから * を import する

それでは、ユーザが from sound.effects import * と書いたら、どうなるのでしょうか？理想的には、何らかの方法でファイルシステムが調べられ、そのパッケージにどんなサブモジュールがあるかを調べ上げ、全てを import する、という処理を望むことでしょう。これには長い時間がかかってしまうこともありますし、あるサブモジュールを import することで、そのモジュールが明示的に import されたときのみ発生して欲しい副作用が起きてしまうかもしれません。

唯一の解決策は、パッケージの作者にパッケージの索引を明示的に提供させるというものです。 import 文は次の規約を使います: パッケージの __init__.py コードに __all__ という名前のリストが定義されていれば、 from package import * が現れたときに import するリストとして使います。新たなパッケージがリリースされるときにリストを最新の状態に更新するのはパッケージの作者の責任となります。自分のパッケージから * を import するという使い方に同意できなければ、パッケージの作者はこの使い方をサポートしないことにしてもかまいません。例えば、ファイル sounds/effects/__init__.py には、次のようなコードを入れてもよいかもしれません。

__all__ = ["echo", "surround", "reverse"]

この例では、 from sound.effects import * とすると、 sound パッケージから指定された 3つのサブモジュールが import されることになっている、ということを意味します。

もしも __all__ が定義されていなければ、実行文 from sound.effects import * は、パッケージ sound.effects の全てのサブモジュールを現在の名前空間の中へ import しません 。この文は単に(場合によっては初期化コード __init__.py を実行して) パッケージ sound.effects が import されたということを確認し、そのパッケージで定義されている名前を全て import するだけです。 import される名前には、 __init__.py で定義された名前 (と、明示的にロードされたサブモジュール) が含まれます。パッケージのサブモジュールで、以前の import 文で明示的にロードされたものも含みます。以下のコードを考えてください。

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

上の例では、 echo と surround モジュールが現在の名前空間に import されます。これらのモジュールは from...import 文が実行された際に sound.effects 内で定義されているからです (この機構は __all__ が定義されているときにも働きます)。

特定のモジュールでは import * を使ったときに、特定のパターンに従った名前のみを公開 (export) するように設計されてはいますが、それでもやはり製品のコードでは良いことではないと考えます。

from package import specific_submodule を使っても何も問題はないことに留意してください！実際この表記法は、import を行うモジュールが他のパッケージと同じ名前を持つサブモジュールを使わなければならない場合を除いて推奨される方式です。

6.5.2. パッケージ内での参照

サブモジュール同士で互いに参照を行う必要がしばしば起こります。例えば、 surround モジュールは echo モジュールを使うかもしれません。このような参照はよくあることなので、 import 文を実行すると、まず最初に import 文の入っているパッケージを検索し、その後になって標準のモジュール検索パスを見に行きます。なので、 surround モジュールは単に import echo や from echo import echofilter を使うことができます。 import されたモジュールが現在のパッケージ(現在のモジュールをサブモジュールにしているパッケージ) 内に見つからなかった場合、 import 文は指定した名前のトップレベルのモジュールを検索します。

パッケージが (前述の例の sound パッケージのように) サブパッケージの集まりに構造化されている場合、絶対 import を使って兄弟関係にあるパッケージを参照できます。例えば、モジュール sound.filters.vocoder で sound.effects パッケージの echo モジュールを使いたいとすると、 from sound.effects import echo を使うことができます。

Python 2.5 からは、上で説明した暗黙の相対importに加えて、明示的な相対importを from module import name の形式の import 文で利用できます。この明示的な相対 import では、先頭のドットで現在および親パッケージを指定します。 surround モジュールの例では、以下のように記述できます。

from . import echo
from .. import formats
from ..filters import equalizer

明示的および暗黙的な相対 import のどちらも現在のモジュール名をベースにすることに注意してください。メインモジュールの名前は常に "__main__" なので、 Python アプリケーションのメインモジュールとして利用されることを意図しているモジュールでは絶対 import を利用するべきです。

6.5.3. 複数ディレクトリ中のパッケージ

パッケージはもう一つ特別な属性として __path__ をサポートしています。この属性は、パッケージの __init__.py 中のコードが実行されるよりも前に、 __init__.py の収められているディレクトリ名の入ったリストになるよう初期化されます。この変数は変更することができます。変更を加えると、以降そのパッケージに入っているモジュールやサブパッケージの検索に影響します。

この機能はほとんど必要にはならないのですが、パッケージ内存在するモジュール群を拡張するために使うことができます。

注記

[1]
実際には、関数定義も ‘実行’ される ‘文’ です。モジュールレベルの関数定義を実行すると、関数名はモジュールのグローバルなシンボルテーブルに入ります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

7. 入力と出力

プログラムから出力を行う方法がいくつかあります。データは人間が読める形で出力することも、将来使うためにファイルに書くこともできます。この章では、こうした幾つかの出力の方法について話します。

7.1. ファンシーな出力の書式化

これまでのところ、値を出力する二つの方法: 式文 (expression statement) と print 文が出てきました。 (第三はファイルオブジェクトの write() メソッドを使う方法です。標準出力を表すファイルは sys.stdout で参照できます。詳細はライブラリリファレンスを参照してください。)

出力を書式化する際に、単に値をスペースで区切って出力するよりももっときめ細かな制御をしたいと思うことがあるでしょう。出力を書式化するには二つの方法があります。第一の方法は、全ての文字列を自分で処理するというものです。文字列のスライスや結合といった操作を使えば、思い通りのレイアウトを作成することができます。文字列オブジェクトは、文字列を指定されたカラム幅に揃えるための幾つかの便利なメソッドを提供しています。これらのメソッドについてはすぐ後で簡単に説明します。もうひとつの方法は str.format() メソッドを利用することです。

string モジュールの Template クラスは文字列中の値を置換する別の方法を提供しています。

もちろん、一つ問題があります。値をどうやって文字列に変換したらいいのでしょうか？幸運なことに、Python には値を文字列に変換する方法があります。値を repr() か str() 関数に渡してください。

str() 関数は、値を表現するときに人間にとって読みやすい形式の文字列を返します。一方、 repr() は、インタプリタが読めるような (あるいは、等価な値を表現するための構文がない場合には SyntaxError を送出させる) 表現にするためのものです。人間が利用するための特別な表現をもたないオブジェクトでは、 str() は repr() と同じ値を返します。数値や、リストや辞書などの構造体のような多くの値は、どちらの関数でも同じ表現になります。文字列と浮動小数点は特別で、二つの別個の表現となります。

下にいくつか例を挙げます。

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(1.0/7.0)
'0.142857142857'
>>> repr(1.0/7.0)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print s
The value of x is 32.5, and y is 40000...
>>> # 文字列への repr() はクォートとバックスラッシュが付加される。
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print hellos
'hello, world\n'
>>> # repr() の引数は Python オブジェクトの場合もある:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"

以下に 2 乗と 3 乗の値からなる表を書く二つの方法を示します。

>>> for x in range(1, 11):
...     print repr(x).rjust(2), repr(x*x).rjust(3),
...     # 上の行の末尾のコンマに注意
...     print repr(x*x*x).rjust(4)
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

>>> for x in range(1,11):
...     print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

(最初の例で、各カラムの間のスペース一個は print の働きで追加されていることに注意してください。 print は引数間に常に空白を追加します。)

この例では、文字列の str.rjust() メソッドの使い方を示しています。 str.rjust() は文字列を指定された幅のフィールド内に右詰めで入るように、左に空白を追加します。同様のメソッドとして、 str.ljust() と str.center() があります。これらのメソッドは何か出力を行うわけではなく、ただ新しい文字列を返します。入力文字列が長すぎる場合、文字列を切り詰めることはせず、ただ値をそのまま返します。この仕様のためにカラムのレイアウトが滅茶苦茶になるかもしれませんが、嘘の値が代わりに書き出されるよりはましです。(本当に切り詰めを行いたいのなら、全てのカラムに x.ljust(n)[:n] のようにスライス表記を加えることもできます。)

もう一つのメソッド、 str.zfill() は、数値文字列の左側をゼロ詰めします。このメソッドは正と負の符号を正しく扱います。

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

str.format() メソッドの基本的な使い方は次のようなものです。

>>> print 'We are the {} who say "{}!"'.format('knights', 'Ni')
We are the knights who say "Ni!"

括弧とその中の文字(これをフォーマットフィールドと呼びます)は、 str.format() メソッドに渡されたオブジェクトに置換されます。括弧の中の数字は str.format() メソッドに渡されたオブジェクトの位置を表します。

>>> print '{0} and {1}'.format('spam', 'eggs')
spam and eggs
>>> print '{1} and {0}'.format('spam', 'eggs')
eggs and spam

str.format() メソッドにキーワード引数が渡された場合、その値はキーワード引数の名前によって参照されます。

>>> print 'This {food} is {adjective}.'.format(
...       food='spam', adjective='absolutely horrible')
This spam is absolutely horrible.

順序引数とキーワード引数を組み合わせて使うこともできます。

>>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
...                                                    other='Georg')
The story of Bill, Manfred, and Georg.

str() を適応する '!s' や repr() を適応する '!r' を使って、値をフォーマットする前に変換することができます。

>>> import math
>>> print 'The value of PI is approximately {}.'.format(math.pi)
The value of PI is approximately 3.14159265359.
>>> print 'The value of PI is approximately {!r}.'.format(math.pi)
The value of PI is approximately 3.141592653589793.

オプションの ':' とフォーマット指定子を、フィールド名の後ろに付けることができます。フォーマット指定子によって値がどうフォーマットされるかを制御することができます。次の例では、円周率πを、小数点以下3桁でまるめてフォーマットしています。

>>> import math
>>> print 'The value of PI is approximately {0:.3f}.'.format(math.pi)
The value of PI is approximately 3.142.

':' の後ろに整数をつけると、そのフィールドの最低の文字幅を指定できます。この機能は綺麗なテーブルを作るのに便利です。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print '{0:10} ==> {1:10d}'.format(name, phone)
...
Jack       ==>       4098
Dcab       ==>       7678
Sjoerd     ==>       4127

もしも長い書式化文字列があり、それを分割したくない場合には、変数を引数の位置ではなく変数の名前で参照できるとよいでしょう。これは、辞書を引数に渡して、角括弧 '[]' を使って辞書のキーを参照することで可能です。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print ('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
...        'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

table を ‘**’ 記法を使ってキーワード引数として渡す方法もあります。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

全てのローカルな変数が入った辞書を返す組み込み関数 vars() と組み合わせると特に便利です。

str.format() による文字列フォーマットの完全な解説は、 書式指定文字列の文法を参照してください。

7.1.1. 古い文字列フォーマット方法

% 演算しを使って文字列フォーマットをする方法もあります。これは、演算子の左側の sprintf() スタイルのフォーマット文字列に、演算子の右側の値を適用し、その結果の文字列を返します。例えば:

::

>>> import math
>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.

str.format() は最近導入された機能なので、多くの Python のコードがまだ % 演算子を利用しています。ですが、古い方法はいつか削除されるかもしれないので、普通は str.format() を使うのが良いでしょう。

より詳しい情報は 文字列フォーマット操作 にあります。

7.2. ファイルを読み書きする

open() はファイルオブジェクトを返します。大抵、 open(filename, mode) のように二つの引数を伴って呼び出されます。

>>> f = open('/tmp/workfile', 'w')
>>> print f
<open file '/tmp/workfile', mode 'w' at 80a0960>

最初の引数はファイル名の入った文字列です。二つめの引数も文字列で、ファイルをどのように使うかを示す数個の文字が入っています。 mode は、ファイルが読み出し専用なら 'r' 、書き込み専用 (同名の既存のファイルがあれば消去されます) なら 'w' とします。 'a' はファイルを追記用に開きます。ファイルに書き込まれた内容は自動的にファイルの終端に追加されます。 'r+' はファイルを読み書き両用に開きます。 mode 引数は省略可能で、省略された場合には 'r' であると仮定します。

Windows では、 mode に 'b' を追加するとファイルをバイナリモードで開きます。したがって、 'rb', 'wb', 'r+b' といったモードがあります。 Windows 上で動くPython はテキストファイルとバイナリファイルを区別しています。テキストファイルでは、読み書きの際に行末文字が自動的に少し変更されます。この舞台裏でのファイルデータ変更は、ASCII でできたテキストファイルでは差し支えないものですが、 JPEG や EXE ファイルのようなバイナリデータは破損してしまうことになるでしょう。こうしたファイルを読み書きする際にはバイナリモードを使うよう十分注意してください。 Unix では、 'b' を追加しても何も影響がないので、バイナリフォーマットを扱うためのプラットフォーム非依存な方法として利用できます。

7.2.1. ファイルオブジェクトのメソッド

この節の以降の例は、 f というファイルオブジェクトが既に生成されているものと仮定します。

ファイルの内容を読み出すには、 f.read(size) を呼び出します。このメソッドはある量のデータを読み出して、文字列として返します。 size は省略可能な数値引数です。 size が省略されたり負の数であった場合、ファイルの内容全てを読み出して返します。ただし、ファイルがマシンのメモリの二倍の大きさもある場合にはどうなるかわかりません。 size が負でない数ならば、最大で size バイトを読み出して返します。ファイルの終端にすでに達していた場合、 f.read() は空の文字列 ("") を返します。

>>> f.read()
'This is the entire file.\n'
>>> f.read()
''

f.readline() はファイルから 1 行だけを読み取ります。改行文字 (\n) は読み出された文字列の終端に残ります。改行が省略されるのは、ファイルが改行で終わっていない場合の最終行のみです。これは、戻り値があいまいでないようにするためです; f.readline() が空の文字列を返したら、ファイルの終端に達したことが分かります。一方、空行は '\n' 、すなわち改行 1 文字だけからなる文字列で表現されます。

>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''

f.readlines() は、ファイルに入っているデータの全ての行からなるリストを返します。省略可能な引数 sizehint が指定されていれば、ファイルから指定されたバイト数を読み出し、さらに一行を完成させるのに必要なだけを読み出して、読み出された行からなるリストを返します。このメソッドは巨大なファイルを行単位で効率的に読み出すためによく使われます。未完成の行が返されることはありません。

>>> f.readlines()
['This is the first line of the file.\n', 'Second line of the file\n']

行を読む別のアプローチは、ファイルオブジェクトについてループをおこなうことです。これは省メモリで、速く、コードがよりシンプルになります。

>>> for line in f:
        print line,

This is the first line of the file.
Second line of the file

この方法はシンプルですが細かなコントロールをすることができません。行バッファを管理する方法が異なるので、これらを混在させて使うことはできません。

f.write(string) は、 string の内容をファイルに書き込み、 None を返します。

>>> f.write('This is a test\n')

文字列以外のものを出力したい場合、まず文字列に変換してやる必要があります。

>>> value = ('the answer', 42)
>>> s = str(value)
>>> f.write(s)

f.tell() は、ファイルオブジェクトが指しているあるファイル中の位置を示す整数を、ファイルの先頭からのバイト数で図った値で返します。ファイルオブジェクトの位置を変更するには、 f.seek(offset,  from_what) を使います。ファイル位置は基準点 (reference point) にオフセット値 offset を足して計算されます。参照点は from_what 引数で選びます。 from_what の値が 0 ならばファイルの先頭から測り、 1 ならば現在のファイル位置を使い、2 ならばファイルの終端を参照点として使います。 from_what は省略することができ、デフォルトの値は 0 、すなわち参照点としてファイルの先頭を使います。

>>> f = open('/tmp/workfile', 'r+')
>>> f.write('0123456789abcdef')
>>> f.seek(5)     # ファイルの第6バイトへ行く
>>> f.read(1)
'5'
>>> f.seek(-3, 2) # 終端から前へ第3バイトへ行く
>>> f.read(1)
'd'

ファイルが用済みになったら、 f.close() を呼び出してファイルを閉じ、ファイルを開くために取られていたシステム資源を解放します。 f.close() を呼び出した後、そのファイルオブジェクトを使おうとすると自動的に失敗します。

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file

ファイルオブジェクトを扱うときに with キーワードを使うのは良い習慣です。 with を使うと、処理中に例外が発生しても必ず最後にファイルを閉じることができます。同じことを try-finally を使って書くよりずっと簡潔に書けます。

>>> with open('/tmp/workfile', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

ファイルオブジェクトには、他にも isatty() や truncate() といった、あまり使われないメソッドがあります。ファイルオブジェクトについての完全なガイドは、ライブラリリファレンスを参照してください。

7.2.2. pickle モジュール

文字列をファイルに読み書きするのは簡単にできます。数値だとほんのわずかに手間が増えます。というのは、 read() は文字列だけを返すので、 '123' のような文字列を受け取って、その数値 123 を返す int() のような関数に文字列を渡してやらなければならないからです。ところが、リストや辞書、クラスのインスタンスのように、もっと複雑なデータ型を保存したいなら、事態はもっと複雑になります。

複雑なデータ型を保存するためのコードを毎回毎回書いてデバッグする代わりに、 Python では pickle という標準モジュールを用意しています。 pickle は驚くべきモジュールで、ほとんどどんな Python オブジェクトでも (ある形式の Python コードでさえも!) 受け取って文字列表現へ変換できます。この変換過程は pickling (ピクルス (漬物) 化、以降 pickle 化) と呼ばれます。文字列表現からオブジェクトを再構成する操作は unpickling (逆 pickle 化) と呼びます。 pickle 化してから unpickle 化するまでの間、オブジェクトを表現する文字列は、ファイルやデータに保存したり、ネットワーク接続を介して離れたマシンに送信したりできます。

オブジェクト x と、書込み用に開かれているファイルオブジェクト f があると仮定すると、オブジェクトを pickle 化する最も簡単な方法は、たった一行のコードです。

pickle.dump(x, f)

逆 pickle 化して再びオブジェクトに戻すには、 f を読取り用に開かれているファイル・オブジェクトと仮定して、

x = pickle.load(f)

とします。

(pickle / 逆 pickle 化にはいくつか方法があり、たくさんのオブジェクトを pickle 化したり、 pickle 化されたデータをファイルに書きたくないときに使われます。完全なドキュメントについては、ライブラリリファレンスの pickle を調べてください。)

pickle は、 Python のオブジェクトを保存できるようにし、他のプログラムや、同じプログラムが将来起動されたときに再利用できるようにする標準の方法です。技術的な用語でいうと persistent (永続性) オブジェクトです。 pickle はとても広範に使われているので、 Python 拡張モジュールの多くの作者は、行列のような新たなデータ型が正しく pickle / 逆 pickle 化できるよう気をつけています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

8. エラーと例外

これまでエラーメッセージについては簡単に触れるだけでしたが、チュートリアル中の例を自分で試していたら、実際にいくつかのエラーメッセージを見ていることでしょう。エラーには (少なくとも) 二つのはっきり異なる種類があります。それは 構文エラー (syntax error) と 例外 (exception) です。

8.1. 構文エラー

構文エラーは構文解析エラー (parsing error) としても知られており、 Python を勉強している間に最もよく遭遇する問題の一つでしょう。

>>> while True print 'Hello world'
  File "<stdin>", line 1, in ?
    while True print 'Hello world'
                   ^
SyntaxError: invalid syntax

パーサは違反の起きている行を表示し、小さな「矢印」を表示して、行中でエラーが検出された最初の位置を示します。エラーは矢印の 直前の トークンでひき起こされています (または、少なくともそこで検出されています)。上記の例では、エラーは print で検出されています。コロン (':') がその前に無いからです。入力がスクリプトから来ている場合は、どこを見ればよいか分かるようにファイル名と行番号が出力されます。

8.2. 例外

たとえ文や式が構文的に正しくても、実行しようとしたときにエラーが発生するかもしれません。実行中に検出されたエラーは 例外 (exception) と呼ばれ、常に致命的とは限りません。これから、 Python プログラムで例外をどのように扱うかを学んでいきます。ほとんどの例外はプログラムで処理されず、以下に示されるようなメッセージになります。

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot concatenate 'str' and 'int' objects

エラーメッセージの最終行は何が起こったかを示しています。例外は様々な型 (type) で起こり、その型がエラーメッセージの一部として出力されます。上の例での型は ZeroDivisionError, NameError, TypeError です。例外型として出力される文字列は、発生した例外の組み込み名です。これは全ての組み込み例外について成り立ちますが、ユーザ定義の例外では (成り立つようにするのは有意義な慣習ですが) 必ずしも成り立ちません。標準例外の名前は組み込みの識別子です (予約語ではありません)。

残りの行は例外の詳細で、その例外の型と何が起きたかに依存します。

エラーメッセージの先頭部分では、例外が発生した実行コンテキスト (context) を、スタックのトレースバック (stack traceback) の形式で示しています。一般には、この部分にはソースコード行をリストしたトレースバックが表示されます。しかし、標準入力から読み取られたコードは表示されません。

組み込み例外 には、組み込み例外とその意味がリストされています。

8.3. 例外を処理する

例外を選別して処理するようなプログラムを書くことができます。以下の例を見てください。この例では、有効な文字列が入力されるまでユーザに入力を促しますが、ユーザがプログラムに (Control-C か、またはオペレーティングシステムがサポートしている何らかのキーを使って) 割り込みをかけてプログラムを中断させることができるようにしています。ユーザが生成した割り込みは、 KeyboardInterrupt 例外が送出されることで通知されるということに注意してください。

>>> while True:
...     try:
...         x = int(raw_input("Please enter a number: "))
...         break
...     except ValueError:
...         print "Oops!  That was no valid number.  Try again..."
...

try 文は下記のように動作します。

まず、 try 節 (try clause) (キーワード try と except の間の文) が実行されます。

何も例外が発生しなければ、 except 節 をスキップして try 文の実行を終えます。

try 節内の実行中に例外が発生すると、その節の残りは飛ばされます。次に、例外型が except キーワードの後に指定されている例外に一致する場合、except 節が実行された後、 try 文の後ろへ実行が継続されます。

もしも except 節で指定された例外と一致しない例外が発生すると、その例外は try 文の外側に渡されます。例外に対するハンドラ (handler、処理部) がどこにもなければ、 処理されない例外 (unhandled exception) となり、上記に示したようなメッセージを出して実行を停止します。

一つの try 文に複数の except 節を設けて、さまざまな例外に対するハンドラを指定することができます。同時に一つ以上のハンドラが実行されることはありません。ハンドラは対応する try 節内で発生した例外だけを処理し、同じ try 節内の別の例外ハンドラで起きた例外は処理しません。 except 節には複数の例外を丸括弧で囲ったタプルにして渡すことができます。例えば以下のようにします。

... except (RuntimeError, TypeError, NameError):
...     pass

最後の except 節では例外名を省いて、ワイルドカード (wildcard、総称記号) にすることができます。ワイルドカードの except 節は非常に注意して使ってください。というのは、ワイルドカードは通常のプログラムエラーをたやすく隠してしまうからです！ワイルドカードの except 節はエラーメッセージを出力した後に例外を再送出する (関数やメソッドの呼び出し側が同様にして例外を処理できるようにする) 用途にも使えます。

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

try ... except 文には、オプションで else 節 (else clause) を設けることができます。 else 節を設ける場合、全ての except 節よりも後ろに置かねばなりません。 else 節は try 節で全く例外が送出されなかったときに実行されるコードを書くのに役立ちます。例えば次のようにします。

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

追加のコードを追加するのは try 節の後ろよりも else 節の方がよいでしょう。なぜなら、そうすることで try ... except 文で保護したいコードから送出されたもの以外の例外を偶然に捕捉してしまうという事態を避けられるからです。

例外が発生するとき、例外は関連付けられた値を持つことができます。この値は例外の 引数 (argument) とも呼ばれます。引数の有無および引数の型は、例外の型に依存します。

except 節では、例外名 (または例外名タプル) の後に変数を指定することができます。この変数は例外インスタンスに結び付けられており、 instance.args に例外インスタンス生成時の引数が入っています。例外インスタンスには __str__() が定義されており、 .args を参照しなくても引数を直接印字できるように利便性が図られています。

必要なら、例外を送出する前にインスタンス化して、任意の属性を追加できます。

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print type(inst)     # 例外インスタンス
...    print inst.args      # .args に記憶されている引数
...    print inst           # __str__ により引数を直接出力できる
...    x, y = inst          # __getitem__ により引数を直接アンパックできる
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

例外が引数を持っていれば、それは処理されない例外のメッセージの最後の部分 (「詳細説明」) に出力されます。

例外ハンドラは、 try 節の直接内側で発生した例外を処理するだけではなく、その try 節から (たとえ間接的にでも) 呼び出された関数の内部で発生した例外も処理します。例えば

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError, detail:
...     print 'Handling run-time error:', detail
...
Handling run-time error: integer division or modulo by zero

8.4. 例外を送出する

raise 文を使って、特定の例外を発生させることができます。例えば、

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: HiThere

raise は送出したい例外を引数として取ります。これは例外クラス(Exception を継承したクラス)か、例外クラスのインスタンスです。

例外が発生したかどうかを判定したいだけで、その例外を処理するつもりがなければ、単純な形式の raise 文を使って例外を再送出させることができます。

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print 'An exception flew by!'
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
NameError: HiThere

8.5. ユーザ定義の例外

プログラム上で新しい例外クラスを作成することで、独自の例外を指定することができます (Python のクラスについては クラス 参照)。例外は、典型的に Exception クラスから、直接または間接的に派生したものです。例を示します。

>>> class MyError(Exception):
...     def __init__(self, value):
...         self.value = value
...     def __str__(self):
...         return repr(self.value)
...
>>> try:
...     raise MyError(2*2)
... except MyError as e:
...     print 'My exception occurred, value:', e.value
...
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

この例では Exception のデフォルト __init__() がオーバーライドされています。新しい振る舞いでは、単に value 属性を作ります。これは、デフォルトの args 属性を作成する振る舞いを置き換えています。

例外クラスでは、普通のクラスができることなら何でも定義することができますが、通常は単純なものにしておきます。大抵は、いくつかの属性だけを提供し、例外が発生したときにハンドラがエラーに関する情報を取り出せるようにする程度にとどめます。複数の別個の例外を送出するようなモジュールを作成する際には、そのモジュールで定義されている例外の基底クラスを作成するのが一般的なプラクティスです。

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expr -- input expression in which the error occurred
        msg  -- explanation of the error
    """

    def __init__(self, expr, msg):
        self.expr = expr
        self.msg = msg

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        prev -- state at beginning of transition
        next -- attempted new state
        msg  -- explanation of why the specific transition is not allowed
    """

    def __init__(self, prev, next, msg):
        self.prev = prev
        self.next = next
        self.msg = msg

ほとんどの例外は、標準の例外の名前付けと同様に、 “Error” で終わる名前で定義されています。

多くの標準モジュールでは、モジュールで定義されている関数内で発生する可能性のあるエラーを報告させるために、独自の例外を定義しています。クラスについての詳細な情報は クラス 章で提供されています。

8.6. クリーンアップ動作を定義する

try 文にはもう一つオプションの節があります。この節はクリーンアップ動作を定義するためのもので、どんな状況でも必ず実行されます。例を示します。

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print 'Goodbye, world!'
...
Goodbye, world!
KeyboardInterrupt

finally 節 (finally clause) は、例外が発生したかどうかに関わらず、 try 文を抜ける前に常に実行されます。 try 節の中で例外が発生して、 except 節で処理されていない場合、または except 節か else 節で例外が発生した場合は、 finally 節を実行した後、その例外を再送出します。 finally 節はまた、 try 節から break 文や continue 文、 return 文経由で抜ける際にも、 “抜ける途中で” 実行されます。より複雑な例です (except 節や finally 節が同じ try 文の中にあって、 Python 2.5 以降で動作します)。

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print "division by zero!"
...     else:
...         print "result is", result
...     finally:
...         print "executing finally clause"
...
>>> divide(2, 1)
result is 2
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

見てわかるとおり、 finally 節はどの場合にも実行されています。文字列を割り算することで発生した TypeError は except 節で処理されていないので、 finally 節実行後に再度送出されています。

実世界のアプリケーションでは、 finally 節は(ファイルやネットワーク接続などの)外部リソースを、利用が成功したかどうかにかかわらず解放するために便利です。

8.7. 定義済みクリーンアップ処理

オブジェクトのなかには、その利用の成否にかかわらず、不要になった際に実行される標準的なクリーンアップ処理が定義されているものがあります。以下の、ファイルをオープンして内容を画面に表示する例をみてください。

for line in open("myfile.txt"):
    print line

このコードの問題点は、コードが実行された後に不定の時間ファイルを開いたままでいることです。これは単純なスクリプトでは問題になりませんが、大きなアプリケーションでは問題になりえます。 with 文はファイルのようなオブジェクトが常に、即座に正しくクリーンアップされることを保証します。

with open("myfile.txt") as f:
    for line in f:
        print line

この文が実行されたあとで、たとえ行の処理中に問題があったとしても、ファイル f は常に close されます。他の定義済みクリーンアップ処理を持つオブジェクトについては、それぞれのドキュメントで示されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

9. クラス

Python は、他のプログラミング言語と比て、最小限の構文と意味付けを使ってクラスを言語に追加しています。 Python のクラスは、 C++ と Modula-3 のクラスメカニズムを混ぜたものです。 Python のクラス機構はオブジェクト指向プログラミングの標準的な機能を全て提供しています。クラスの継承メカニズムは、複数の基底クラスを持つことができ、派生クラスで基底クラスの任意のメソッドをオーバライドすることができます。メソッドでは、基底クラスのメソッドを同じ名前で呼び出すことができます。オブジェクトには任意の種類と数のデータを格納することができます。モジュールと同じく、クラス機構も Python の動的な性質に従うように設計されています。クラスは実行時に生成され、生成後に変更することができます。

C++ の用語で言えば、通常のクラスメンバ (データメンバも含む) は (プライベート変数 に書かれている例外を除いて) public であり、メンバ関数はすべて 仮想関数(virtual) です。 Module-3 にあるような、オブジェクトのメンバをメソッドから参照するための短縮した記法は使えません: メソッド関数の宣言では、オブジェクト自体を表す第一引数を明示せねばなりません。第一引数のオブジェクトはメソッド呼び出しの際に暗黙の引数として渡されます。 Smalltalk に似て、クラスはそれ自体がオブジェクトです。そのため、 import や名前変更といった操作が可能です。 C++ や Modula-3 と違って、ユーザーは組込み型を基底クラスにして拡張を行えます。また、C++ とは同じで Modula-3 とは違う点として、特別な構文を伴うほとんどの組み込み演算子 (算術演算子 (arithmetic operator) や添字表記) はクラスインスタンスで使うために再定義できます。

(クラスに関して普遍的な用語定義がないので、 Smalltalk と C++ の用語を場合に応じて使っていくことにします。 C++ よりも Modula-3 の方がオブジェクト指向の意味論が Python に近いので、 Modula-3 の用語を使いたいのですが、ほとんどの読者は Modula-3 についてしらないでしょうから。)

9.1. 名前とオブジェクトについて

オブジェクトには個体性があり、同一のオブジェクトに(複数のスコープから) 複数の名前を割り当てることができます。この機能は他の言語では 別名づけ(ailias) として知られています。 Python を一見しただけでは、別名づけの重要性は分からないことが多く、変更不能な基本型 (数値、文字列、タプル)を扱うときには無視して差し支えありません。しかしながら、別名付けは、リストや辞書や他の多くの型など、変更可能な型を扱う Python コード上で驚くべき効果があります。別名付けはいくつかの点でポインタのように振舞い、このことは通常はプログラムに利するように使われます。例えば、オブジェクトの受け渡しは、実装上はポインタが渡されるだけなのでコストの低い操作になります。また、関数があるオブジェクトを引数として渡されたとき、関数の呼び出し側からオブジェクトに対する変更を見ることができます — これにより、 Pascal にあるような二つの引数渡し機構をもつ必要をなくしています。

9.2. Python のスコープと名前空間

クラスを紹介する前に、Python のスコープのルールについてあることを話しておかなければなりません。クラス定義は巧みなトリックを名前空間に施すので、何が起こっているのかを完全に理解するには、スコープと名前空間がどのように動作するかを理解する必要があります。ちなみに、この問題に関する知識は全ての Python プログラマにとって有用です。

まず定義から始めましょう。

名前空間 (namespace) とは、名前からオブジェクトへの対応付け (mapping) です。ほとんどの名前空間は、現状では Python の辞書として実装されていますが、そのことは通常は (パフォーマンス以外では) 目立つことはないし、将来は変更されるかもしれません。名前空間の例には、組込み名の集合 (abs() 等の関数や組込み例外名)、モジュール内のグローバルな名前、関数を呼び出したときのローカルな名前があります。オブジェクトの属性からなる集合もまた、ある意味では名前空間です。名前空間について知っておくべき重要なことは、異なった名前空間にある名前の間には全く関係がないということです。例えば、二つの別々のモジュールの両方で関数 maximize という関数を定義することができ、定義自体は混同されることはありません — モジュールのユーザは名前の前にモジュール名をつけなければなりません。

ところで、 属性 という言葉は、ドットに続く名前すべてに対して使っています — 例えば式 z.real で、 real はオブジェクト z の属性です。厳密にいえば、モジュール内の名前に対する参照は属性の参照です。式 modname.funcname では、 modname はあるモジュールオブジェクトで、 funcname はその属性です。この場合には、モジュールの属性とモジュールの中で定義されているグローバル名の間には、直接的な対応付けがされます。これらの名前は同じ名前空間を共有しているのです！ [1]

属性は読取り専用にも、書込み可能にもできます。書込み可能であれば、属性に代入することができます。モジュール属性は書込み可能で、 modname.the_answer = 42 と書くことができます。書込み可能な属性は、 del 文で削除することもできます。例えば、 del modname.the_answer は、 modname で指定されたオブジェクトから属性 the_answer を除去します。

名前空間は様々な時点で作成され、その寿命も様々です。組み込みの名前が入った名前空間は Python インタプリタが起動するときに作成され、決して削除されることはありません。モジュールのグローバルな名前空間は、モジュール定義が読み込まれたときに作成されます。通常、モジュールの名前空間は、インタプリタが終了するまで残ります。インタプリタのトップレベルで実行された文は、スクリプトファイルから読み出されたものでも対話的に読み出されたものでも、 __main__ という名前のモジュールの一部分であるとみなされるので、独自の名前空間を持つことになります。 (組み込みの名前は実際にはモジュール内に存在します。そのモジュールは __builtin__ と呼ばれています。)

関数のローカルな名前空間は、関数が呼び出されたときに作成され、関数から戻ったときや、関数内で例外が送出され、かつ関数内で処理されなかった場合に削除されます。 (実際には、忘れられる、と言ったほうが起きていることをよく表しています。) もちろん、再帰呼出しのときには、各々の呼び出しで各自のローカルな名前空間があります。

スコープ (scope) とは、ある名前空間が直接アクセスできるような、 Python プログラムのテキスト上の領域です。 “直接アクセス可能” とは、修飾なしに (訳注: spam.egg ではなく単に egg のように) 名前を参照した際に、その名前空間から名前を見つけようと試みることを意味します。

スコープは静的に決定されますが、動的に使用されます。実行中はいつでも、直接名前空間にアクセス可能な、少なくとも三つの入れ子になったスコープがあります。

最初に探される、最も内側のスコープは、ローカルな名前を持っています。

外側の(enclosing)関数のスコープは、近いほうから順に探され、ローカルでもグローバルでもない名前を持っています。

次のスコープは、現在のモジュールのグローバルな名前を持っています。

一番外側の(最後に検索される)スコープはビルトイン名を持っています。

名前が global と宣言されている場合、その名前に対する参照や代入は全て、モジュールのグローバルな名前の入った中間のスコープに対して直接行われます。そうでない場合、最も内側のスコープより外側にある変数は全て読み出し専用となります。 (そのような変数に対する書き込みは、単に 新しい ローカル変数をもっとも内側のスコープで作成し、外部のスコープの値は変化しません)

通常、ローカルスコープは (プログラムテキスト上の) 現在の関数のローカルな名前を参照します。関数の外側では、ローカルスコープはグローバルな名前空間と同じ名前空間、モジュールの名前空間を参照します。クラス定義では、ローカルスコープの中にもう一つ名前空間が置かれます。

スコープはテキスト上で決定されていると理解することが重要です。モジュール内で定義される関数のグローバルなスコープは、関数がどこから呼び出されても、どんな別名をつけて呼び出されても、そのモジュールの名前空間になります。反対に、実際の名前の検索は実行時に動的に行われます — とはいえ、言語の定義は、”コンパイル” 時の静的な名前解決の方向に進化しているので、動的な名前解決に頼ってはいけません！ (事実、ローカルな変数は既に静的に決定されています。)

Python 特有の癖として、代入を行うと – どの global 文も有効でない場合は – 名前がいつも最も内側のスコープに入るというものがあります。代入はデータのコピーを行いません — 単に名前をオブジェクトに結びつける (bind) だけです。オブジェクトの削除でも同じです: del x は、 x をローカルスコープが参照している名前空間から削除します。実際、新たな名前を導入する操作は全てローカルスコープを用います。とりわけ、 import 文や関数定義は、モジュールや関数の名前をローカルスコープに結び付けます。(global 文を使えば、特定の変数がグローバルスコープにあることを示せます。)

9.3. クラス初見

クラスでは、新しい構文を少しと、三つの新たなオブジェクト型、そして新たな意味付けをいくつか取り入れています。

9.3.1. クラス定義の構文

クラス定義の最も単純な形式は、次のようになります。

class ClassName:
    <文-1>
    .
    .
    .
    <文-N>

関数定義 (def 文) と同様、クラス定義が効果をもつにはまず実行しなければなりません。 (クラス定義を if 文の分岐先や関数内部に置くことも、考え方としてはありえます。)

実際には、クラス定義の内側にある文は、通常は関数定義になりますが、他の文を書くこともでき、それが役に立つこともあります — これについては後で述べます。クラス内の関数定義は通常、メソッドの呼び出し規約で決められた独特の形式の引数リストを持ちます — これについても後で述べます。

クラス定義に入ると、新たな名前空間が作成され、ローカルな名前空間として使われます — 従って、ローカルな変数に対する全ての代入はこの新たな名前空間に入ります。特に、関数定義を行うと、新たな関数の名前はこの名前空間に結び付けられます。

クラス定義から普通に (定義の終端に到達して) 抜けると、クラスオブジェクト (class object) が生成されます。クラスオブジェクトは、基本的にはクラス定義で作成された名前空間の内容をくるむラッパ (wrapper) です。クラスオブジェクトについては次の節で詳しく学ぶことにします。 (クラス定義に入る前に有効だった) 元のローカルスコープが復帰し、生成されたクラスオブジェクトは復帰したローカルスコープにクラス定義のヘッダで指定した名前 (上の例では ClassName) で結び付けられます。

9.3.2. クラスオブジェクト

クラス・オブジェクトでは２種類の演算、属性参照とインスタンス生成をサポートしています。

属性参照 (attribute reference) は、Python におけるすべての属性参照で使われている標準的な構文、 obj.name を使います。クラスオブジェクトが生成された際にクラスの名前空間にあった名前すべてが有効な属性名です。従って、以下のようなクラス定義では、

class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

MyClass.i と MyClass.f は妥当な属性参照であり、それぞれ整数と関数オブジェクトを返します。クラス属性に代入を行うこともできます。従って、 MyClass.i の値を代入して変更できます。 __doc__ も有効な属性で、そのクラスに属している docstring、この場合は "A simple example class" を返します。

クラスの インスタンス生成 (instantiation) には関数のような表記法を使います。クラスオブジェクトのことを、単にクラスの新しいインスタンスを返すパラメタを持たない関数かのように扱います。例えば (上記のクラスでいえば)、

x = MyClass()

は、クラスの新しい インスタンス (instance) を生成し、そのオブジェクトをローカル変数 x へ代入します。

このクラスのインスタンス生成操作 (クラスオブジェクトの “呼出し”) を行うと、空のオブジェクトを生成します。多くのクラスは、オブジェクトを作成する際に、カスタマイズされた特定の初期状態になってほしいと望んでいます。そのために、クラスには __init__() という名前の特別なメソッド定義することができます。例えば次のようにします。

def __init__(self):
    self.data = []

クラスが __init__() メソッドを定義している場合、クラスのインスタンスを生成すると、新しく生成されたクラスインスタンスに対して自動的に __init__() を呼び出します。従って、この例では、新たな初期済みのインスタンスを次のようにして得ることができます。

x = MyClass()

もちろん、より大きな柔軟性を持たせるために、 __init__() メソッドに複数の引数をもたせることができます。その場合、次の例のように、クラスのインスタンス生成操作に渡された引数は __init__() に渡されます。

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

9.3.3. インスタンスオブジェクト

ところで、インスタンスオブジェクトを使うと何ができるのでしょうか？インスタンスオブジェクトが理解できる唯一の操作は、属性の参照です。有効な属性の名前には二種類(データ属性およびメソッド)あります。

データ属性 (data attribute) は、これは Smalltalk の “インスタンス変数” や C++の “データメンバ” に相当します。データ属性を宣言する必要はありません。ローカルな変数と同様に、これらの属性は最初に代入された時点で湧き出てきます。例えば、上で生成した MyClass のインスタンス x に対して、次のコードを実行すると、値 16 を印字し、 x の痕跡は残りません。

x.counter = 1
while x.counter < 10:
    x.counter = x.counter * 2
print x.counter
del x.counter

もうひとつのインスタンス属性は メソッド (method) です。メソッドとは、オブジェクトに “属している” 関数のことです。(Python では、メソッドという用語はクラスインスタンスだけのものではありません。オブジェクト型にもメソッドを持つことができます。例えば、リストオブジェクトには、 append, insert, remove, sort などといったメソッドがあります。とはいえ、以下では特に明記しない限り、クラスのインスタンスオブジェクトのメソッドだけを意味するものとして使うことにします。)

インスタンスオブジェクトで有効なメソッド名は、そのクラスによります。定義により、クラスの全てのo関数オブジェクトである属性がインスタンスオブジェクトの妥当なメソッド名に決まります。従って、例では、 MyClass.f は関数なので、 x.f はメソッドの参照として有効です。しかし、 MyClass.i は関数ではないので、 x.i はメソッドの参照として有効ではありません。 x.f は MyClass.f と同じものではありません — 関数オブジェクトではなく、メソッドオブジェクト (method object) です。

9.3.4. メソッドオブジェクト

普通、メソッドはバインドされた直後に呼び出されます。

x.f()

MyClass の例では、上のコードは文字列 'hello world' を返すでしょう。しかしながら、必ずしもメソッドをその場で呼び出さなければならないわけではありません。 x.f はメソッドオブジェクトであり、どこかに記憶しておいて後で呼び出すことができます。例えば次のコードは、

xf = x.f
while True:
    print xf()

hello world を時が終わるまで印字し続けるでしょう。

メソッドが呼び出されるときには実際には何が起きているのでしょうか？ f() の関数定義では引数を一つ指定していたにもかかわらず、上の例では x.f が引数なしで呼び出されています。引数はどうなったのでしょうか？たしか、引数が必要な関数を引数無しで呼び出すと、 Python が例外を送出するはずです — たとえその引数が実際には使われなくても…。

もう答は想像できているかもしれませんね。メソッドについて特別なこととして、オブジェクトが関数の第1引数として渡されます。例では、 x.f() という呼び出しは、 MyClass.f(x) と厳密に等価なものです。一般に、 n 個の引数リストもったメソッドの呼出しは、そのメソッドのオブジェクトを最初の引数の前に挿入した引数リストでメソッドに対応する関数を呼び出すことと等価です。

もしまだメソッドの動作を理解できなければ、一度実装を見てみると事情がよく分かるかもしれません。データ属性ではないインスタンス属性が参照された時は、そのクラスが検索されます。その名前が有効なクラス属性を表している関数オブジェクトなら、インスタンスオブジェクトと見つかった関数オブジェクト (へのポインタ) を抽象オブジェクト、すなわちメソッドオブジェクトにパックして作成します。メソッドオブジェクトが引数リストと共に呼び出されるとき、インスタンスオブジェクトと渡された引数リストから新しい引数リストを作成して、元の関数オブジェクトを新しい引数リストで呼び出します。

9.4. いろいろな注意点

データ属性は同じ名前のメソッド属性を上書きしてしまいます。大規模なプログラムでみつけにくいバグを引き起こすことがあるこの偶然的な名前の衝突を避けるには、衝突の可能性を最小限にするような規約を使うのが賢明です。可能な規約としては、メソッド名を大文字で始める、データ属性名の先頭に短い一意な文字列 (あるいはただの下線) をつける、またメソッドには動詞、データ属性には名詞を用いる、などがあります。

データ属性は、メソッドから参照できると同時に、通常のオブジェクトのユーザ (“クライアント”) からも参照できます。言い換えると、クラスは純粋な抽象データ型として使うことができません。実際、 Python では、データ隠蔽を補強するための機構はなにもありません — データの隠蔽はすべて規約に基づいています。 (逆に、C 言語で書かれた Python の実装では実装の詳細を完全に隠蔽し、必要に応じてオブジェクトへのアクセスを制御できます。この機構は C 言語で書かれた Python 拡張で使うことができます。)

クライアントはデータ属性を注意深く扱うべきです — クライアントは、メソッドが維持しているデータ属性の不変式を踏みにじり、台無しにするかもしれません。クライアントは、名前の衝突が回避されている限り、メソッドの有効性に影響を及ぼすことなくインスタンスに独自の属性を追加することができる、ということに注意してください — ここでも、名前付けの規約は頭痛の種を無くしてくれます。

メソッドの中から、データ属性を (または別のメソッドも！) 参照するための短縮された記法はありません。私は、この仕様がメソッドの可読性を高めていると感じています。あるメソッドを眺めているときにローカルな変数とインスタンス変数をはっきり区別できるからです。

よく、メソッドの最初の引数を self と呼びます。この名前付けは単なる慣習でしかありません。 self という名前は、 Python では何ら特殊な意味を持ちません。とはいえ、この慣行に従わないと、コードは他の Python プログラマにとってやや読みにくいものとなります。また、 クラスブラウザ (class browser) プログラムがこの慣行をあてにして書かれているかもしれません。

クラス属性である関数オブジェクトはいずれも、そのクラスのインスタンスのためのメソッドを定義しています。関数定義は、テキスト上でクラス定義の中に入っている必要はありません。関数オブジェクトをクラスのローカルな変数の中に代入するのも OK です。例えば以下のコードのようにします。

# クラスの外側で定義された関数
def f1(self, x, y):
    return min(x, x+y)

class C:
    f = f1
    def g(self):
        return 'hello world'
    h = g

これで、 f 、 g 、および h は、すべて C の属性であり関数オブジェクトを参照しています。従って、これら全ては、 C のインスタンスのメソッドとなります — h は g と全く等価です。これを実践しても、大抵は単にプログラムの読者に混乱をもたらすだけなので注意してください。

メソッドは、 self 引数のメソッド属性を使って、他のメソッドを呼び出すことができます。

class Bag:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def addtwice(self, x):
        self.add(x)
        self.add(x)

メソッドは、通常の関数と同じようにしてグローバルな名前を参照します。 (クラス自体はグローバルなスコープとして用いられることはありません。) メソッドでグローバルなデータを使う良い理由はほとんどありませんが、グローバルなスコープを使うべき場面は多々あります。一つ挙げると、メソッド内から、グローバルなスコープに import された関数やモジュールや、そのモジュール中で定義された関数やクラスを使うことができます。通常、メソッドの入っているクラス自体はグローバルなスコープ内で定義されています。次の節では、メソッドが自分のクラスを参照する理由として正当なものを見てみましょう。

個々の値はオブジェクトなので、 クラス (型 とも言います) を持っています。それは object.__class__ に保持されています。

9.5. 継承

言うまでもなく、継承の概念をサポートしない言語機能は “クラス” と呼ぶに値しません。派生クラス (derived class) を定義する構文は次のようになります。

class DerivedClassName(BaseClassName):
    <文-1>
    .
    .
    .
    <文-N>

基底クラス (base class) の名前 BaseClassName は、派生クラス定義の入っているスコープで定義されていなければなりません。基底クラス名のかわりに任意の式を入れることもできます。これは次の例のように、基底クラスが別モジュールで定義されているときに便利なことがあります。

class DerivedClassName(modname.BaseClassName):

派生クラス定義の実行は、基底クラスの場合と同じように進められます。クラスオブジェクトが構築される時、基底クラスが記憶されます。記憶された基底クラスは、属性参照を解決するために使われます。要求された属性がクラスに見つからなかった場合、基底クラスに検索が進みます。この規則は、基底クラスが他の何らかのクラスから派生したものであった場合、再帰的に適用されます。

派生クラスのインスタンス化では、特別なことは何もありません。 DerivedClassName() はクラスの新たなインスタンスを生成します。メソッドの参照は次のようにしてい解決されます。まず対応するクラス属性が検索されます。検索は、必要に応じ、基底クラス連鎖を下って行われ、検索の結果として何らかの関数オブジェクトがもたらされた場合、メソッド参照は有効なものとなります。

派生クラスは基底クラスのメソッドを上書き (override) することができます。メソッドは同じオブジェクトの別のメソッドを呼び出す際に何ら特殊な権限を持ちません。このため、ある基底クラスのメソッドが、同じ基底クラスで定義されているもう一つのメソッド呼び出しを行っている場合、派生クラスで上書きされた何らかのメソッドが呼び出されることになるかもしれません。 (C++ プログラマへ: Python では、すべてのメソッドは事実上 virtual です。)

派生クラスで上書きしているメソッドでは、基底クラスの同名のメソッドを置き換えるのではなく、拡張したいのかもしれません。基底クラスのメソッドを直接呼び出す簡単な方法があります。単に BaseClassName.methodname(self, arguments) を呼び出すだけです。この仕様は、場合によってはクライアントでも役に立ちます。 (この呼び出し方が動作するのは、基底クラスがグローバルスコープの BaseClassName という名前でアクセスできるときだけです。)

Python には継承に関係する 2 つの組み込み関数があります。

isinstance() を使うとインスタンスの型が調べられます。 isinstance(obj, int) は obj.__class__ が int や int の派生クラスの場合に限り True になります。

issubclass() を使うとクラスの継承関係が調べられます。 bool は int のサブクラスなので issubclass(bool, int) は True です。しかし、 unicode は str のサブクラスではない (単に共通の祖先 basestring を共有している) ので issubclass(unicode, str) は False です。

9.5.1. 多重継承

Python では、限られた形式の多重継承 (multiple inheritance) もサポートしています。複数の基底クラスをもつクラス定義は次のようになります。

class DerivedClassName(Base1, Base2, Base3):
    <文-1>
    .
    .
    .
    <文-N>

旧形式のクラスでは、名前解決規則は単に、深さ優先、左から右へ、だけです。従って、ある属性が DerivedClassName で見つからなければ Base1 で検索され、次に Base1 の基底クラスで (再帰的に) 検索されます。それでも見つからなければはじめて Base2 で検索される、といった具合です。

(人によっては、幅優先 (breadth first) — Base2 と Base3 を検索してから Base1 の基底クラスで検索する — のほうが自然に思うかもしれません。しかしながら、幅優先の検索では、 Base1 の特定の属性のうち、実際に定義されているのが Base1 なのか、その基底クラスなのかを知らなければ、 Base2 の属性との名前衝突がどんな結果をもたらすのか分からないことになります。深さ優先規則では、 Base1 の直接の属性と継承された属性とを区別しません。)

新スタイルクラス(new-style class) では、協調的な super() の呼び出しのためにメソッドの解決順序は動的に変更されます。このアプローチは他の多重継承のある言語で call-next-method として知られており、単一継承しかない言語の super 呼び出しよりも強力です。

新スタイルクラスについて、多重継承の全ての場合に 1 つかそれ以上のダイヤモンド継承 (少なくとも 1 つの祖先クラスに対し最も下のクラスから到達する経路が複数ある状態) があるので、動的順序付けが必要です。例えば、全ての新形式のクラスは object を継承しているので、どの多重継承でも object へ到達するための道は複数存在します。基底クラスが複数回アクセスされないようにするために、動的アルゴリズムで検索順序を直列化し、各クラスで指定されている祖先クラスどうしの左から右への順序は崩さず、各祖先クラスを一度だけ呼び出し、かつ一様になる (つまり祖先クラスの順序に影響を与えずにサブクラス化できる) ようにします。まとめると、これらの特徴のおかげで信頼性と拡張性のある多重継承したクラスを設計することができるのです。さらに詳細を知りたければ、 http://www.python.org/download/releases/2.3/mro/ を見てください。

9.6. プライベート変数

オブジェクトの中からしかアクセス出来ない “プライベート” インスタンス変数は、 Python にはありません。しかし、ほとんどの Python コードが従っている慣習があります。アンダースコアで始まる名前 (例えば _spam) は、 (関数であれメソッドであれデータメンバであれ) 非 public なAPIとして扱います。これらは、予告なく変更されるかもしれない実装の詳細として扱われるべきです。

クラスのプライベートメンバについて適切なユースケース(特にサブクラスで定義された名前との衝突を避ける場合)があるので、 マングリング(name mangling) と呼ばれる、限定されたサポート機構があります。 __spam (先頭に二個以上の下線文字、末尾に一個以下の下線文字) という形式の識別子は、 _classname__spam へとテキスト置換されるようになりました。ここで classname は、現在のクラス名から先頭の下線文字をはぎとった名前になります。このような難号化 (mangle) は、識別子の文法的な位置にかかわらず行われるので、クラス定義内に現れた識別子全てに対して実行されます。

難号化の規則は主に不慮の事故を防ぐためのものだということに注意してください; 確信犯的な方法で、プライベートとされている変数にアクセスしたり変更することは依然として可能なのです。デバッガのような特殊な状況では、この仕様は便利ですらあります。

exec や eval() や execfile() へ渡されたコードでは、呼出し元のクラス名を現在のクラスと見なさないことに注意してください。この仕様は global 文の効果と似ており、その効果もまた同様に、バイトコンパイルされたコードに制限されています。同じ制約が getattr() と setattr() と delattr() にも適用されます。また、 __dict__ を直接参照するときにも適用されます。

9.7. 残りのはしばし

Pascal の “レコード (record)” や、C 言語の “構造体 (struct)” のような、名前つきのデータ要素を一まとめにするデータ型があると便利なことがあります。空のクラス定義を使うとうまくできます。

class Employee:
    pass

john = Employee() # 空の従業員レコードを造る

# レコードのフィールドを設定する
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000

ある特定の抽象データ型を要求する Python コードの断片に、そのデータ型のメソッドをエミュレーションするクラスを代わりに渡すことができます。例えば、ファイルオブジェクトから何らかのデータを構築する関数がある場合、 read() と readline() を持つクラスを定義して、ファイルではなく文字列バッファからデータを取得するようにしておき、引数として渡すことができます。

インスタンスメソッドオブジェクトにも属性があります。 m.im_self はメソッド m() の属しているインスタンスオブジェクトで、 m.im_func はメソッドに対応する関数オブジェクトです。

9.7.1. 例外はクラスであってもよい

ユーザ定義の例外をクラスとして識別することもできます。このメカニズムを使って、拡張可能な階層化された例外を作成することができます。

新しい二つの (意味付け的な) 形式の raise 文があります。

raise Class, instance

raise instance

第一の形式では、 instance は Class またはその派生クラスのインスタンスでなければなりません。第二の形式は以下の表記の短縮された記法です。

raise instance.__class__, instance

except 節のクラスは、例外と同じクラスか基底クラスのときに互換 (compatible)となります。 (逆方向では成り立ちません — 派生クラスの例外がリストされている except 節は基底クラスの例外と互換ではありません)。例えば、次のコードは、 B, C, D を順序通りに出力します。

class B:
    pass
class C(B):
    pass
class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print "D"
    except C:
        print "C"
    except B:
        print "B"

except 節が逆に並んでいた場合 (except B が最初にくる場合)、 B, B, B と出力されるはずだったことに注意してください — 最初に一致した except 節が駆動されるのです。

処理されないクラスの例外に対してエラーメッセージが出力されるとき、まずクラス名が出力され、続いてコロン、スペース、最後に組み込み関数 str() を使って文字列に変換したインスタンスが出力されます。

9.8. イテレータ (iterator)

すでに気づいているでしょうが、 for 文を使うとほとんどのコンテナオブジェクトにわたってループを行うことができます。

for element in [1, 2, 3]:
    print element
for element in (1, 2, 3):
    print element
for key in {'one':1, 'two':2}:
    print key
for char in "123":
    print char
for line in open("myfile.txt"):
    print line

こうしたアクセス方法は明確で、簡潔で、かつ便利なものです。イテレータの使用は Python 全体に普及していて、統一性をもたらしています。背後では、 for 文はコンテナオブジェクトの iter() を呼び出しています。この関数は next() メソッドの定義されたイテレータオブジェクトを返します。 next() メソッドは一度コンテナ内の要素に一度に一つづつアクセスします。コンテナ内にアクセスすべき要素がなくなると、 next() は StopIteration 例外を送出し、 for ループを終了させます。実際にどのように動作するかを以下の例に示します。

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> it.next()
'a'
>>> it.next()
'b'
>>> it.next()
'c'
>>> it.next()

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
    it.next()
StopIteration

イテレータプロトコルの背後にあるメカニズムを一度目にすれば、自作のクラスにイテレータとしての振る舞いを追加するのは簡単です。 __iter__() メソッドを定義して、 next() メソッドを持つオブジェクトを返すようにしてください。クラス自体で next() を定義している場合、 __iter__() では単に self を返すようにできます。

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print char
...
m
a
p
s

9.9. ジェネレータ (generator)

ジェネレータ(generator)は、イテレータを作成するための簡潔で強力なツールです。ジェネレータは通常の関数のように書かれますが、何らかのデータを返すときには yield 文を使います。 next() が呼び出されるたびに、ジェネレータは以前に中断した処理を再開します (ジェネレータは、全てのデータ値と最後にどの文が実行されたかを記憶しています)。以下の例を見れば、ジェネレータがとても簡単に作成できることがわかります。

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

>>> for char in reverse('golf'):
...     print char
...
f
l
o
g

ジェネレータを使ってできることは、前節で記述したクラスベースのイテレータを使ってもできます。ジェネレータを使うとコンパクトに記述できるのは、 __iter__() と next() メソッドが自動的に作成されるからです。

ジェネレータのもう一つの重要な機能は、呼び出しごとにローカル変数と実行状態が自動的に保存されるということです。これにより、 self.index や self.data といったインスタンス変数を使ったアプローチよりも簡単に関数を書くことができるようになります。

メソッドを自動生成したりプログラムの実行状態を自動保存するほかに、ジェネレータは終了時に自動的に StopIteration を送出します。これらの機能を組み合わせると、通常の関数を書くのと同じ労力で、簡単にイテレータを生成できます。

9.10. ジェネレータ式

単純なジェネレータなら、式を使って簡潔にコードする方法があります。リスト内包に似た構文の式ですが、各括弧ではなく丸括弧を使います。ジェネレータ式は、関数の中でジェネレータをすぐに使いたいような状況のために用意されています。ジェネレータ式はコンパクトですが、完全なジェネレータに比べてちょっと融通の効かないところがありますが、同じ内容を返すリスト内包よりはメモリに優しいことが多いという利点があります。

例:

>>> sum(i*i for i in range(10))                 # 平方和を求める
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # 内積を求める
260

>>> from math import pi, sin
>>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))

>>> unique_words = set(word  for line in page  for word in line.split())

>>> valedictorian = max((student.gpa, student.name) for student in graduates)

>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1,-1,-1))
['f', 'l', 'o', 'g']

注記

[1]
例外が一つあります。モジュールオブジェクトには、秘密の読取り専用の属性 __dict__ があり、モジュールの名前空間を実装するために使われている辞書を返します; __dict__ という名前は属性ですが、グローバルな名前ではありません。この属性を利用すると名前空間の実装に対する抽象化を侵すことになるので、プログラムを検死するデバッガのような用途に限るべきです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

10. 標準ライブラリミニツアー

10.1. OSへのインタフェース

os モジュールは、オペレーティングシステムと対話するための何ダースもの関数を提供しています。

>>> import os
>>> os.getcwd()      # 現在の作業ディレクトリを返す
'C:\\Python26'
>>> os.chdir('/server/accesslogs')   # 作業ディレクトリを変更する.
>>> os.system('mkdir today')   # システムのシェルで mkdir コマンドを実行する
0

from os import * ではなく、 import os 形式を使うようにしてください。そうすることで、動作が大きく異なる組み込み関数 open() が os.open() で隠蔽されるのを避けられます。

組み込み関数 dir() および help() は、 os のような大規模なモジュールで作業をするときに、対話的な操作上の助けになります。

>>> import os
>>> dir(os)
<モジュール内の関数全てを含むリストを返す>
>>> help(os)
<モジュールの docstring から作られた広範囲に渡るマニュアルページを返す>

ファイルやディレクトリの日常的な管理作業のために、より簡単に使える高レベルインタフェースが shutil モジュールで提供されています。

>>> import shutil
>>> shutil.copyfile('data.db', 'archive.db')
>>> shutil.move('/build/executables', 'installdir')

10.2. ファイルのワイルドカード表記

glob モジュールでは、ディレクトリのワイルドカード検索からファイルのリストを生成するための関数を提供しています。

>>> import glob
>>> glob.glob('*.py')
['primes.py', 'random.py', 'quote.py']

10.3. コマンドライン引数

一般的なユーティリティスクリプトでは、よくコマンドライン引数を扱う必要があります。コマンドライン引数は sys モジュールの argv 属性にリストとして保存されています。例えば、以下の出力は、 python demo.py one two three とコマンドライン上で起動した時に得られるものです。

>>> import sys
>>> print sys.argv
['demo.py', 'one', 'two', 'three']

getopt モジュールは、 sys.argv を Unix の getopt() 関数の慣習に従って処理します。より強力で柔軟性のあるコマンドライン処理機能は、 argparse モジュールで提供されています。

10.4. エラー出力のリダイレクトとプログラムの終了

sys モジュールには、 stdin, stdout, stderr を表す属性も存在します。 stderr は、警告やエラーメッセージを出力して、 stdout がリダイレクトされた場合でも読めるようにするために便利です。

>>> sys.stderr.write('Warning, log file not found starting a new one\n')
Warning, log file not found starting a new one

sys.exit() は、スクリプトを終了させるもっとも直接的な方法です。

10.5. 文字列のパターンマッチング

re モジュールでは、より高度な文字列処理のための正規表現を提供しています。正規表現は複雑な一致検索や操作に対して簡潔で最適化された解決策を提供します。

>>> import re
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'

最小限の機能だけが必要なら、読みやすくデバッグしやすい文字列メソッドの方がお勧めです。

>>> 'tea for too'.replace('too', 'two')
'tea for two'

10.6. 数学

math モジュールは、浮動小数点演算のための C 言語ライブラリ関数にアクセスする手段を提供しています。

>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757
>>> math.log(1024, 2)
10.0

random モジュールは、乱数に基づいた要素選択のためのツールを提供しています。

>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(xrange(100), 10)   # 要素を戻さないサンプリング
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random()    # ランダムな浮動小数点数
0.17970987693706186
>>> random.randrange(6)    # range(6) からランダムに選ばれた整数
4

10.7. インターネットへのアクセス

インターネットにアクセスしたり、インターネットプロトコルを処理したりするための数多くのモジュールがあります。その中でも特にシンプルなモジュールとして、URL を指定してデータを取得するための urllib2 と、メールを送信するための smtplib があります。

>>> import urllib2
>>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
...     if 'EST' in line or 'EDT' in line:      # EST(東部標準時)を見る
...         print line

<BR>Nov. 25, 09:43:32 PM EST

>>> import smtplib
>>> server = smtplib.SMTP('localhost')
>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
... """To: jcaesar@example.org
... From: soothsayer@example.org
...
... Beware the Ides of March.
... """)
>>> server.quit()

(2つ目の例は localhost でメールサーバーが動いている必要があることに注意してください。)

10.8. 日付と時刻

datetime モジュールは、日付や時刻を操作するためのクラスを、単純な方法と複雑な方法の両方で提供しています。日付や時刻に対する算術がサポートされている一方、実装では出力の書式化や操作のための効率的なデータメンバ抽出に重点を置いています。このモジュールでは、タイムゾーンに対応したオブジェクトもサポートしています。

>>> # 日付は簡単に生成して書式化することができます。
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December'

>>> # date 型はカレンダー計算をサポートしています。
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday
>>> age.days
14368

10.9. データ圧縮

データの書庫化や圧縮で広く使われている形式については、 zlib, gzip, bz2, zipfile, tarfile といったモジュールで直接サポートしています。

>>> import zlib
>>> s = 'witch which has which witches wrist watch'
>>> len(s)
41
>>> t = zlib.compress(s)
>>> len(t)
37
>>> zlib.decompress(t)
'witch which has which witches wrist watch'
>>> zlib.crc32(s)
226805979

10.10. パフォーマンスの計測

Python ユーザの中には、同じ問題を異なったアプローチで解いた際の相対的なパフォーマンスについて知りたいという深い興味を持っている人がいます。 Python は、そういった疑問に即座に答える計測ツールを提供しています。

例えば、引数の入れ替え操作に対して、伝統的なアプローチの代わりにタプルのパックやアンパックを使ってみたいと思うかもしれません。 timeit モジュールを使えば、パフォーマンスがほんの少し良いことがすぐに分かります。

>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791

timeit では小さい粒度を提供しているのに対し、 profile や pstats モジュールではより大きなコードブロックにおいて律速となる部分を判定するためのツールを提供しています。

10.11. 品質管理

高い品質のソフトウェアを開発するための一つのアプローチは、各関数に対して開発と同時にテストを書き、開発の過程で頻繁にテストを走らせるというものです。

doctest モジュールでは、モジュールを検索してプログラムの docstring に埋め込まれたテストの評価を行うためのツールを提供しています。テストの作り方は単純で、典型的な呼び出し例とその結果を docstring にカット&ペーストするだけです。この作業は、ユーザに使用例を与えるという意味でドキュメントの情報を増やすと同時に、ドキュメントに書かれているコードが正しい事を確認できるようになります。

def average(values):
    """Computes the arithmetic mean of a list of numbers.

    >>> print average([20, 30, 70])
    40.0
    """
    return sum(values, 0.0) / len(values)

import doctest
doctest.testmod()   # 組み込まれたテストを自動的に検証する。

unittest モジュールは doctest モジュールほど気楽に使えるものではありませんが、より網羅的なテストセットを別のファイルで管理することができます。

import unittest

class TestStatisticalFunctions(unittest.TestCase):

    def test_average(self):
        self.assertEqual(average([20, 30, 70]), 40.0)
        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
        self.assertRaises(ZeroDivisionError, average, [])
        self.assertRaises(TypeError, average, 20, 30, 70)

unittest.main() # コマンドラインから呼び出すと全てのテストを実行する。

10.12. バッテリー同梱

Python には “バッテリー同梱 (batteries included)” 哲学があります。この哲学は、洗練され、安定した機能を持つ Python の膨大なパッケージ群に如実に表れています。例えば、

The xmlrpclib および SimpleXMLRPCServer モジュールは、遠隔手続き呼び出し (remote procedure call) を全く大したことのない作業に変えてしまいます。モジュール名とは違い、XML を扱うための直接的な知識は必要ありません。

The email パッケージは、MIME やその他の RFC 2822 に基づくメッセージ文書を含む電子メールメッセージを管理するためのライブラリです。実際にメッセージを送信したり受信したりする smtplib や poplib と違って、email パッケージには (添付文書を含む) 複雑なメッセージ構造の構築やデコードを行ったり、インターネット標準のエンコードやヘッダプロトコルの実装を行ったりするための完全なツールセットを備えています。

xml.dom および xml.sax パッケージでは、一般的なデータ交換形式である XML を解析するための頑健なサポートを提供しています。同様に、 csv モジュールでは、広く用いられているデータベース形式のデータを直接読み書きする機能をサポートしています。これらのモジュールやパッケージを利用することで、Python アプリケーションと他のツール群との間でのデータ交換が劇的に簡単になります。

国際化に関する機能は、 gettext, locale, codecs パッケージといったモジュール群でサポートされています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

11. 標準ライブラリミニツアー – その 2

2回目のツアーでは、プロフェッショナルプログラミングを支えるもっと高度なモジュールをカバーします。ここで挙げるモジュールは、小さなスクリプトの開発ではほとんど使いません。

11.1. 出力のフォーマット

repr モジュールは、大きなコンテナや、深くネストしたコンテナを省略して表示するバージョンの repr() を提供しています。

>>> import repr
>>> repr.repr(set('supercalifragilisticexpialidocious'))
"set(['a', 'c', 'd', 'e', 'f', 'g', ...])"

pprint モジュールを使うと、組み込み型やユーザ定義型がより洗練された形式で出力されるよう制御できます。出力が複数行にわたる場合には、 “pretty printer” が改行を追加して、入れ子構造を理解しやすいようにインデントを挿入します。

>>> import pprint
>>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
...     'yellow'], 'blue']]]
...
>>> pprint.pprint(t, width=30)
[[[['black', 'cyan'],
   'white',
   ['green', 'red']],
  [['magenta', 'yellow'],
   'blue']]]

textwrap モジュールは、一段落の文を指定したスクリーン幅にぴったり収まるように調整します。

>>> import textwrap
>>> doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines."""
...
>>> print textwrap.fill(doc, width=40)
The wrap() method is just like fill()
except that it returns a list of strings
instead of one big string with newlines
to separate the wrapped lines.

locale モジュールは、文化ごとに特化したデータ表現形式のデータベースにアクセスします。 locale の format() 関数の grouping 属性を使えば、数値の各桁を適切な区切り文字でグループ化してフォーマットできます。

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv()          # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d", x, grouping=True)
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
...                      conv['frac_digits'], x), grouping=True)
'$1,234,567.80'

11.2. 文字列テンプレート

string モジュールには、柔軟で、エンドユーザが簡単に編集できる簡単な構文を備えた Template クラスが入っています。このクラスを使うと、ユーザがアプリケーションを修正することなしにアプリケーションの出力をカスタマイズできるようになります。

テンプレートでは、 $ と有効な Python 識別子名 (英数字とアンダースコア) からなるプレースホルダ名を使います。プレースホルダの周りを丸括弧で囲えば、間にスペースをはさまなくても後ろに英数文字を続けられます。 $$ のようにすると、 $ 自体をエスケープできます。

>>> from string import Template
>>> t = Template('${village}folk send $$10 to $cause.')
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'

substitute() メソッドは、プレースホルダに相当する値が辞書やキーワード引数にない場合に KeyError を送出します。メールマージ型アプリケーションの場合、ユーザが入力するデータは不完全なことがあるので、欠落したデータがあるとプレースホルダをそのままにして出力する safe_substitute() メソッドを使う方が適切でしょう。

>>> t = Template('Return the $item to $owner.')
>>> d = dict(item='unladen swallow')
>>> t.substitute(d)
Traceback (most recent call last):
  . . .
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.'

Template をサブクラス化すると、区切り文字を自作できます。例えば、画像ブラウザ用にバッチで名前を変更するユーティリティを作っていたとして、現在の日付や画像のシーケンス番号、ファイル形式といったプレースホルダにパーセント記号を選んだとします。

>>> import time, os.path
>>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
>>> class BatchRename(Template):
...     delimiter = '%'
>>> fmt = raw_input('Enter rename style (%d-date %n-seqnum %f-format):  ')
Enter rename style (%d-date %n-seqnum %f-format):  Ashley_%n%f

>>> t = BatchRename(fmt)
>>> date = time.strftime('%d%b%y')
>>> for i, filename in enumerate(photofiles):
...     base, ext = os.path.splitext(filename)
...     newname = t.substitute(d=date, n=i, f=ext)
...     print '{0} --> {1}'.format(filename, newname)

img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
img_1077.jpg --> Ashley_2.jpg

テンプレートのもう一つの用途は、複数ある出力様式からのプログラムロジックの分離です。テンプレートを使えば、カスタムのテンプレートを XML ファイル用や平文テキストのレポート、 HTML で書かれた web レポート用などに置き換えられます。

11.3. バイナリデータレコードの操作

struct モジュールでは、可変長のバイナリレコード形式を操作する pack() や unpack() といった関数を提供しています。以下の例では、 zipfile モジュールを使わずに、ZIPファイルのヘッダ情報を巡回する方法を示しています "H" と "I" というパック符号は、それぞれ2バイトと4バイトの符号無し整数を表しています。 "<" は、そのパック符号が通常のサイズであり、バイトオーダーがリトルエンディアンであることを示しています。

import struct

data = open('myfile.zip', 'rb').read()
start = 0
for i in range(3):                      # 最初の3ファイルのヘッダを表示する
    start += 14
    fields = struct.unpack('<IIIHH', data[start:start+16])
    crc32, comp_size, uncomp_size, filenamesize, extra_size = fields

    start += 16
    filename = data[start:start+filenamesize]
    start += filenamesize
    extra = data[start:start+extra_size]
    print filename, hex(crc32), comp_size, uncomp_size

    start += extra_size + comp_size     # 次のヘッダまでスキップする。

11.4. マルチスレッド処理

スレッド処理 (threading) とは、順序的な依存関係にない複数のタスクを分割するテクニックです。スレッドは、ユーザの入力を受け付けつつ、背後で別のタスクを動かすようなアプリケーションの応答性を高めます。主なユースケースには、 I/O を別のスレッドの計算処理と並列して動作させるというものがあります。

以下のコードでは、高水準のモジュール threading でメインのプログラムを動かしながら背後で別のタスクを動作させられるようにする方法を示しています。

import threading, zipfile

class AsyncZip(threading.Thread):
    def __init__(self, infile, outfile):
        threading.Thread.__init__(self)
        self.infile = infile
        self.outfile = outfile
    def run(self):
        f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
        f.write(self.infile)
        f.close()
        print 'Finished background zip of: ', self.infile

background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print 'The main program continues to run in foreground.'

background.join()    # Wait for the background task to finish
print 'Main program waited until background was done.'

マルチスレッドアプリケーションを作る上で最も難しい問題は、データやリソースを共有するスレッド間の調整 (coordination)です。この問題を解決するため、 threading モジュールではロックやイベント、状態変数、セマフォといった数々の同期プリミティブを提供しています。

こうしたツールは強力な一方、ちょっとした設計上の欠陥で再現困難な問題を引き起こすことがあります。したがって、タスク間調整では Queue モジュールを使って他のスレッドから一つのスレッドにリクエストを送り込み、一つのリソースへのアクセスをできるだけ一つのスレッドに集中させるアプローチを勧めます。スレッド間の通信や調整に Queue.Queue オブジェクトを使うと、設計が容易になり、可読性が高まり、信頼性が増します。

11.5. ログ記録

logging モジュールでは、数多くの機能をそなえた柔軟性のあるログ記録システムを提供しています。最も簡単な使い方では、ログメッセージをファイルや sys.stderr に送信します。

import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')

上記のコードは以下のような出力になります:

WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down

デフォルトでは、単なる情報やデバッグメッセージの出力は抑制され、出力は標準エラーに送信されます。選択可能な送信先には、email、データグラム、ソケット、 HTTP サーバへの送信などがあります。新たにフィルタを作成すると、 DEBUG, INFO, WARNING, ERROR, CRITICAL といったメッセージのプライオリティに従って配送先を変更できます。

ログ記録システムは Python から直接設定できますし、アプリケーションを変更しなくてもカスタマイズできるよう、ユーザが編集できる設定ファイルでも設定できます。

11.6. 弱参照

Python は自動的にメモリを管理します (ほとんどのオブジェクトは参照カウント方式で管理し、ガベージコレクション(garbage collection)で循環参照を除去します)。オブジェクトに対する最後の参照がなくなってしばらくするとメモリは解放されます。

このようなアプローチはほとんどのアプリケーションでうまく動作しますが、中にはオブジェクトをどこか別の場所で利用している間だけ追跡しておきたい場合もあります。残念ながら、オブジェクトを追跡するだけでオブジェクトに対する恒久的な参照を作ることになってしまいます。 weakref モジュールでは、オブジェクトへの参照を作らずに追跡するためのツールを提供しています。弱参照オブジェクトが不要になると、弱参照 (weakref) テーブルから自動的に除去され、コールバック関数がトリガされます。弱参照を使う典型的な応用例には、作成コストの大きいオブジェクトのキャッシュがあります。

>>> import weakref, gc
>>> class A:
...     def __init__(self, value):
...         self.value = value
...     def __repr__(self):
...         return str(self.value)
...
>>> a = A(10)                   # 参照を作成する.
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a            # 参照を作成しない.
>>> d['primary']                # オブジェクトが生きていれば取得する.
10
>>> del a                       # 参照を1つ削除する.
>>> gc.collect()                # ガベージコレクションを実行する.
0
>>> d['primary']                # エントリが自動的に削除されている.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    d['primary']                # entry was automatically removed
  File "C:/python26/lib/weakref.py", line 46, in __getitem__
    o = self.data[key]()
KeyError: 'primary'

11.7. リスト操作のためのツール

多くのデータ構造は、組み込みリスト型を使った実装で事足ります。とはいえ、時には組み込みリストとは違うパフォーマンス上のトレードオフを持つような実装が必要になこともあります。

array モジュールでは、同じ形式のデータだけをコンパクトに保存できる、リスト型に似た array() オブジェクトを提供しています。以下の例では、通常 1 要素あたり 16 バイトを必要とする Python 整数型のリストの代りに、2 バイトの符号無しの 2 進数 (タイプコード "H")を使っている数値配列を示します。

>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])

collections モジュールでは、リスト型に似た deque() オブジェクトを提供しています。 deque() オブジェクトでは、データの追加と左端からの取り出しが高速な半面、中間にある値の検索が低速になります。こうしたオブジェクトはキューの実装や幅優先のツリー探索に向いています。

>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print "Handling", d.popleft()
Handling task1

unsearched = deque([starting_node])
def breadth_first_search(unsearched):
    node = unsearched.popleft()
    for m in gen_moves(node):
        if is_goal(m):
            return m
        unsearched.append(m)

リストの代わりの実装以外にも、標準ライブラリにはソート済みのリストを操作するための関数を備えた bisect のようなツールも提供しています。

>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]

heapq モジュールでは、通常のリストでヒープを実装するための関数を提供しています。ヒープでは、最も低い値をもつエントリがつねにゼロの位置に配置されます。ヒープは、毎回リストをソートすることなく、最小の値をもつ要素に繰り返しアクセスするようなアプリケーションで便利です。

>>> from heapq import heapify, heappop, heappush
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data)                      # rearrange the list into heap order
>>> heappush(data, -5)                 # add a new entry
>>> [heappop(data) for i in range(3)]  # fetch the three smallest entries
[-5, 0, 1]

11.8. 10 進浮動小数演算

decimal では、 10 進浮動小数の算術演算をサポートする Decimal データ型を提供しています。組み込みの 2 進浮動小数の実装である float に比べて、このクラスがとりわけ便利なのは、

財務アプリケーションやその他の正確な10進表記が必要なアプリケーション、

精度の制御、

法的または規制上の理由に基づく値丸めの制御、

有効桁数の追跡が必要になる場合、

ユーザが手計算の結果と同じ演算結果を期待するようなアプリケーション

の場合です。

例えば、 70 セントの電話代にかかる 5% の税金を計算しようとすると、 10 進の浮動小数点値と 2 進の浮動小数点値では違う結果になってしまいます。計算結果を四捨五入してセント単位にしようとすると違いがはっきり現れます。

>>> from decimal import *
>>> x = Decimal('0.70') * Decimal('1.05')
>>> x
Decimal('0.7350')
>>> x.quantize(Decimal('0.01'))  # 一番近い 1/100 単位にまとめる.
Decimal('0.74')
>>> round(.70 * 1.05, 2)         # 同じ計算を float ですると.
0.73

Decimal を使った計算では、末尾桁のゼロが保存されており、有効数字2桁の被乗数から自動的に有効数字を 4 桁と判断しています。 Decimal は手計算と同じ方法で計算を行い、 2 進浮動小数点が 10 進小数成分を正確に表現できないことによって起きる問題を回避しています。

Decimal クラスは厳密な値を表現できるため、2 進浮動小数点数では期待通りに計算できないようなモジュロの計算や等値テストも実現できます。

>>> Decimal('1.00') % Decimal('.10')
Decimal('0.00')
>>> 1.00 % 0.10
0.09999999999999995

>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
True
>>> sum([0.1]*10) == 1.0
False

decimal モジュールを使うと、必要なだけの精度で算術演算を行えます。

>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

12. さあ何を？

このチュートリアルを読んだことで、おそらく Python を使ってみようという関心はますます強くなったことでしょう — 現実世界の問題を解決するために、Python を適用してみたくなったはずです。さて、それではどこで勉強をしたらよいのでしょうか？

このチュートリアルは Python のドキュメンテーションセットの一部です。セットの中の他のドキュメンテーションをいくつか紹介します。

Python 標準ライブラリ:

このマニュアルをざっと眺めておくと便利です。このマニュアルは型、関数、標準ライブラリのモジュールについての完全なリファレンスです。標準的なPython配布物は たくさんの 追加コードを含んでいます。 Unix メールボックスの読み込み、HTTPによるドキュメント取得、乱数の生成、コマンドラインオプションの構文解析、CGIプログラムの作成、データ圧縮やその他たくさんのタスクのためのモジュールがあります。ライブラリリファレンスをざっと見ることで、何が利用できるかのイメージをつかむことができます。

Python モジュールのインストール は、他のPythonユーザによって書かれた外部モジュールをどうやってインストールするかを説明しています。

Python 言語リファレンス: Pythonの文法とセマンティクスを詳しく説明しています。読むのは大変ですが、言語の完全なガイドとして有用です。

さらなる Python に関するリソース:

http://www.python.org: メインの Python Web サイト。このサイトには、コード、ドキュメント、そして Web のあちこちの Python に関連したページへのポインタがあります。この Web サイトは世界のあちこちのさまざまな場所、例えばヨーロッパ、日本、オーストラリアなどでミラーされています。地理的な位置によっては、メインのサイトよりミラーのほうが速いかもしれません。

http://docs.python.org: Pythonドキュメントへの素早いアクセスを提供します。

http://pypi.python.org: Python パッケージインデックス、以前は Cheese Shop という愛称でも呼ばれていました。これは、ユーザ作成のダウンロードできる Python モジュールの索引です。コードのリリースをしたら、ここに登録することで他の人が見つけられます。

http://aspn.activestate.com/ASPN/Python/Cookbook/: Python クックブックはコード例、モジュール、実用的なスクリプトの巨大なコレクションです。主要なものは同名の本Python Cookbook (O’Reilly & Associates, ISBN 0-596-00797-3.)に収録されています。

Python に関する質問をしたり、問題を報告するために、ニュースグループ comp.lang.python に投稿したり、 python-list@python.org のメーリングリストに送信することができます。ニュースグループとメーリングリストは相互接続されているので、どちらかにポストされたメッセージは自動的にもう一方にも転送されます。一日に約 120 通程度(ピーク時は数百通)の、質問(とその回答)、新機能の提案、新たなモジュールのアナウンスが投稿されています。投稿する前に、必ず よく出される質問 [http://www.python.org/doc/faq/] (Frequently Asked Questions, FAQ とも言います)のリストを確認するか、 Python ソースコード配布物の Misc/ ディレクトリを探すようにしてください。メーリングリストのアーカイブは http://mail.python.org/pipermail/ で入手することができます。 FAQ では、何度も繰り返し現れる質問の多くに答えています。読者の抱えている問題に対する解答がすでに入っているかもしれません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

13. 対話入力編集とヒストリ置換

あるバージョンの Python インタプリタでは、Korn シェルや GNU Bash シェルに見られる機能に似た、現在の入力行に対する編集機能やヒストリ置換機能をサポートしています。この機能は GNU Readline [http://tiswww.case.edu/php/chet/readline/rltop.html] ライブラリを使って実装されています。このライブラリは Emacs スタイルと vi スタイルの編集をサポートしています。ライブラリには独自のドキュメントがあり、ここでそれを繰り返すつもりはありません。とはいえ、基本について簡単に解説することにします。ここで述べる対話的な編集とヒストリについては、 Unix 版と Cygwin 版のインタプリタでオプションとして利用することができます。

この章では、Mark Hammond の PythonWin パッケージや、 Python とともに配布される Tk ベースの環境である IDLE にある編集機能については解説 しません 。 NT 上の DOS ボックスやその他の DOS および Windows 類で働くコマンド行ヒストリ呼出しもまた別のものです。

13.1. 行編集

入力行の編集がサポートされている場合、インタプリタが一次または二次プロンプトを出力している際にはいつでも有効になっています。現在の行は、慣例的な Emacs 制御文字を使って編集することができます。そのうち最も重要なものとして、次のようなキーがあります。 C-A (Control-A)はカーソルを行の先頭へ移動させます。 C-E は末尾へ移動させます。 C-B は逆方向へ一つ移動させます。 C-F は順方向へ移動させます。 Backspace は逆方向に向かって文字を消します。 C-D は順方向に向かって消します。 C-K は順方向に向かって行の残りを kill し (消し) ます、 C-Y は最後に kill された文字列を再び yank し (取り出し) ます。 C-underscore 最後の変更を元に戻します。これは、繰り返してどんどんさかのぼることができます。

13.2. ヒストリ置換

ヒストリ置換は次のように働きます。入力された行のうち、空行でない実行された行はすべてヒストリバッファに保存されます。そして、プロンプトが提示されるときには、ヒストリバッファの最も下の新たな行に移動します。 C-P はヒストリバッファの中を一行だけ上に移動し (戻し) ます。 C-N は 1 行だけ下に移動します。ヒストリバッファのどの行も編集することができます。行が編集されると、それを示すためにプロンプトの前にアスタリスクが表示されます [1] 。 Return キーを押すと現在行がインタプリタへ渡されます。 C-R はインクリメンタルな逆方向サーチ (reverse search) を開始し、 C-S は順方向サーチ (forward search)を開始します。

13.3. キー割り当て

Readline ライブラリのキー割り当て (key binding) やその他のパラメタは、 ~/.inputrc という初期化ファイル [2] にコマンドを置くことでカスタマイズできます。キー割り当ての形式は

key-name: function-name

または

"string": function-name

で、オプションの設定方法は

set option-name value

です。例えば、以下のように設定します。

# vi スタイルの編集を選択する:
set editing-mode vi

# 一行だけを使って編集する:
set horizontal-scroll-mode On

# いくつかのキーを再束縛する:
Meta-h: backward-kill-word
"\C-u": universal-argument
"\C-x\C-r": re-read-init-file

Python では、 Tab に対するデフォルトの割り当ては TAB の挿入です。 Readline のデフォルトであるファイル名補完関数ではないので注意してください。もし、どうしても Readline のデフォルトを割り当てたいのなら、 ~/.inputrc に

Tab: complete

を入れれば設定を上書きすることができます。 (もちろん、 Tab を使ってインデントするのに慣れている場合、この設定を行うとインデントされた継続行を入力しにくくなります。)

変数名とモジュール名の自動的な補完がオプションとして利用できます。補完をインタプリタの対話モードで有効にするには、以下の設定をスタートアップファイルに追加します。 [3]

import rlcompleter, readline
readline.parse_and_bind('tab: complete')

この設定は、 Tab キーを補完関数に束縛します。従って、 Tab キーを二回たたくと補完候補が示されます。補完機能は Python の文の名前、現在のローカル変数、および利用可能なモジュール名を検索します。 string.a のようなドットで区切られた式については、最後の '.' までの式を評価し、結果として得られたオブジェクトの属性から補完候補を示します。 __getattr__() メソッドを持ったオブジェクトが式に含まれている場合、 __getattr__() がアプリケーション定義のコードを実行するかもしれないので注意してください。

より良くできたスタートアップファイルは以下例のようになります。この例では、作成した名前が不要になると削除されるのに注目してください。これは、スタートアップファイルが対話コマンドと同じ名前空間で実行されているので、不要な名前を除去して対話環境に副作用を生まないようにするためです。 import されたモジュールのうち、 os のようなインタプリタのほとんどのセッションで必要なものについては、残しておくと便利に思うかもしれません。

# Add auto-completion and a stored history file of commands to your Python
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
# to it:  "export PYTHONSTARTUP=~/.pystartup" in bash.

import atexit
import os
import readline
import rlcompleter

historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
    import readline
    readline.write_history_file(historyPath)

if os.path.exists(historyPath):
    readline.read_history_file(historyPath)

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath

13.4. インタラクティブインタプタの代替

この機能は、初期の版のインタプリタに比べれば大きな進歩です。とはいえ、まだいくつかの要望が残されています。例えば、行を継続するときに正しいインデントが提示されたら快適でしょう (パーサは次の行でインデントトークンが必要かどうかを知っています)。補完機構がインタプリタのシンボルテーブルを使ってもよいかもしれません。括弧やクォートなどの対応をチェックする (あるいは指示する) コマンドも有用でしょう。

より優れたインタラクティブインタプリタの代替の一つに IPython [http://ipython.scipy.org/] があります。このインタプリタは、様々なところで使われていて、タブ補完、オブジェクト探索や先進的な履歴管理といった機能を持っています。他のアプリケーションにカスタマイズされたり、組込まれこともあります。別の優れたインタラクティブ環境としては bpython [http://www.bpython-interpreter.org/] があります。

注記

[1]
訳注: これはデフォルト設定の Readline では現れません。 set mark-modified-lines on という行を ~/.inputrc または環境変数 INPUTRC が指定するファイルに置くことによって現れるようになります。

[2]
訳注: このファイル名は環境変数 INPUTRC がもしあればその指定が優先されます。

[3]
Python は、対話インタプリタを開始する時に PYTHONSTARTUP 環境変数が指定するファイルの内容を実行します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

14. 浮動小数点演算、その問題と制限

浮動小数点数は、計算機ハードウェアの中では、基数を 2 とする (2進法の) 分数として表現されています。例えば、小数

0.125

は、 1/10 + 2/100 + 5/1000 という値を持ちますが、これと同様に、 2 進法の分数

0.001

は 0/2 + 0/4 + 1/8 という値になります。これら二つの分数は同じ値を持っていますが、ただ一つ、最初の分数は基数 10 で記述されており、二番目の分数は基数 2 で記述されていることが違います。

残念なことに、ほとんどの小数は 2 進法の分数として正確に表わすことができません。その結果、一般に、入力した 10 進の浮動小数点数は、 2 進法の浮動小数点数で近似された後、実際にマシンに記憶されます。

最初は基数 10 を使うと問題を簡単に理解できます。分数 1/3 を考えてみましょう。分数 1/3 は、基数 10 の分数として、以下のように近似することができます。

0.3

さらに正確な近似は、

0.33

です。さらに正確に近似すると、

0.333

となり、以後同様です。何個桁数を増やして書こうが、結果は決して厳密な 1/3 にはなりません。しかし、少しづつ正確な近似にはなっていくでしょう。

同様に、基数を 2 とした表現で何桁使おうとも、10 進数の 0.1 は基数を 2 とした小数で正確に表現することはできません。基数 2 では、1/10 は循環小数 (repeating fraction) となります。

0.0001100110011001100110011001100110011001100110011...

どこか有限の桁で止めると、近似値を得ることになります。

Python を実行する典型的なコンピュータでは、 Python の float 型は 53bit の精度を持っています。この場合、10進数で 0.1 と書いたときに内部では次のような2進の小数が格納されます。

0.00011001100110011001100110011001100110011001100110011010

これは、 1/10 に近いですが、厳密に同じ値ではありません。

Python は格納されている値の10進小数での近似値を表示するので、格納されている値が元の10進小数の近似値でしか無いことを忘れがちです。もし Python が2進数で近似された 0.1 の近似値をそのまま10進数で表示していたら、その結果は次のようになったでしょう。

>>> 0.1
0.1000000000000000055511151231257827021181583404541015625

これは、ほとんどの人が必要と感じるよりも多すぎる桁数です。なので、 Python は丸めた値を表示することで、桁数を扱いやすい範囲にとどめます。

>>> 0.1
0.1

現実には、上の表示は錯覚であると気づくのは重要なことです。マシン内の値は厳密に 1/10 ではなく、単に真のマシン内の 表示される値を丸めているだけなのです。このことは、これらの値に対して演算を行うとすぐに顕在化します。

>>> 0.1 + 0.2
0.30000000000000004

この動作は2進数の浮動小数点にとってはごく自然なものです。これは Python のバグではありませんし、あなたのコードのバグでもありません。ハードウェアの浮動小数点演算をサポートしている全ての言語で同じ種類の問題を見つけることができます。 (いくつかの言語ではデフォルトの、あるいはどの出力モードを選んでも、この差を 表示 しないかもしれませんが)

他にも期待と異なるかもしれない場合があります。例えば、 2.675 という値を小数点以下2桁で丸めようとすると、次のような結果になります。

>>> round(2.675, 2)
2.67

組み込み関数 round() のドキュメントには、もっとも近い値に丸め、中央値の場合は 0 から遠い方に丸めると書かれています。10進数の 2.675 は 2.67 と 2.68 のちょうど真ん中なので、結果として 2.68 (の2進数による近似値) を期待するかもしれません。しかし、 10進数の 2.675 は2進数の近似値に変換され、その正確な値は次のようになります。

2.67499999999999982236431605997495353221893310546875

この近似値は 2.68 よりすこし 2.67 に近いので、 2.67 に丸められます。

10 進数で中央値になる値がどちらに丸められるかを制御しないといけない場合は、 decimal モジュールを使うことを検討するべきです。ちなみに、 decimal モジュールは Python の float 値に格納された正確な値を見るためにも利用できます。

>>> from decimal import Decimal
>>> Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')

別の重要な例として、 0.1 が正確には 1/10 でないために、 0.1 を10回足しても正確には 1.0 にならないというものがあります。

>>> sum = 0.0
>>> for i in range(10):
...     sum += 0.1
...
>>> sum
0.9999999999999999

2 進の浮動小数点数に対する算術演算は、このような意外性をたくさん持っています。 “0.1” に関する問題は、以下の “表現エラー” の章で詳細に説明します。 2 進法の浮動小数点演算にともなうその他のよく知られた意外な事象に関しては The Perils of Floating Point [http://www.lahey.com/float.htm] を参照してください。

究極的にいうと、”容易な答えはありません”。ですが、浮動小数点数のことを過度に警戒しないでください！ Python の float 型操作におけるエラーは浮動小数点処理ハードウェアから受けついたものであり、ほとんどのマシン上では一つの演算あたり高々 2**53 分の 1 です。この誤差はほとんどの作業で充分以上のものですが、浮動小数点演算は 10 進の演算ではなく、浮動小数点の演算を新たに行うと、新たな丸め誤差の影響を受けることを心にとどめておいてください。

異常なケースが存在する一方で、普段の浮動小数点演算の利用では、単に最終的な結果の値を必要な 10 進の桁数に丸めて表示するのなら、最終的には期待通りの結果を得ることになるでしょう。 float の表示についてきめ細かな制御をしたければ、 書式指定文字列の文法 にある str.format() メソッドのフォーマット仕様を参照してください。

14.1. 表現エラー

この章では、”0.1” の例について詳細に説明し、このようなケースに対してどのようにすれば正確な分析を自分で行えるかを示します。ここでは、 2 進法表現の浮動小数点数についての基礎的な知識があるものとして話を進めます。

表現エラー(Representation error)は、いくつかの (実際にはほとんどの) 10 進の小数が 2 進法 (基数 2 )の分数として表現できないという事実に関係しています。これは Python (あるいは Perl、 C、 C++、Japa、Fortran 、およびその他多く) が期待通りの正確な 10 進数を表示できない主要な理由です。

>>> 0.1 + 0.2
0.30000000000000004

なぜこうなるのでしょうか？ 1/10 と 2/10 は 2 進法の小数で厳密に表現することができません。今日 (2010年7月) のマシンは、ほとんどすべて IEEE-754 浮動小数点演算を使用しており、ほとんどすべてのプラットフォームでは Python の浮動小数点を IEEE-754 における “倍精度(double precision)” に対応付けます。754 の double には 53 ビットの精度を持つ数が入るので、計算機に入力を行おうとすると、可能な限り 0.1 を最も近い値の分数に変換し、 J/2**N の形式にしようと努力します。 J はちょうど 53 ビットの精度の整数です。

1 / 10 ~= J / (2**N)

を書き直すと、

J ~= 2**N / 10

となります。 J は厳密に 53 ビットの精度を持っている (>= 2**52 だが < 2**53 ) ことを思い出すと、 N として最適な値は 56 になります。

>>> 2**52
4503599627370496
>>> 2**53
9007199254740992
>>> 2**56/10
7205759403792793

すなわち、56 は J をちょうど 53 ビットの精度のままに保つ N の唯一の値です。 J の取りえる値はその商を丸めたものです。

>>> q, r = divmod(2**56, 10)
>>> r
6

残りは 10 の半分以上なので、最良の近似は丸め値を一つ増やした (round up) ものになります。

>>> q+1
7205759403792794

従って、754 倍精度における 1/10 の取りえる最良の近似は 2**56 以上の値、もしくは

7205759403792794 / 72057594037927936

となります。丸め値を 1 増やしたので、この値は実際には 1/10 より少し小さいことに注意してください; 丸め値を 1 増やさない場合、商は 1/10 よりもわずかに小さくなります。しかし、どちらにしろ 厳密に 1/10 ではありません！

つまり、計算機は 1/10 を “理解する” ことは決してありません。計算機が理解できるのは、上記のような厳密な分数であり、 754 の倍精度浮動小数点数で得られるもっともよい近似は:

>>> .1 * 2**56
7205759403792794.0

となります。

この分数に 10**30 を掛ければ、有効数字 30 桁の十進数の (切り詰められた) 値を見ることができます。

>>> 7205759403792794 * 10**30 // 2**56
100000000000000005551115123125L

これは、計算機が記憶している正確な数値が、10 進数値 0.100000000000000005551115123125 にほぼ等しいということです。 Python 2.7 と Python 3.1 より前のバージョンでは、 Python はこの値を小数点以下 17桁に丸めて ‘0.10000000000000001’ になっていました。現在のバージョンの Python は、元の2進数に正確に戻すことのできる最小の桁数の小数を表示するので、結果は ‘0.1’ になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python チュートリアル »

15. 日本語訳について

この文書は、Pythonドキュメント翻訳プロジェクトによる Python Tutorial の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

15.1. 翻訳者一覧 (敬称略)

1.3 和訳: SUZUKI Hisao <suzuki at acm.org> (August 27, 1995)

1.4 和訳: SUZUKI Hisao <suzuki at acm.org> (April 20, 1997)

1.5.1 和訳: SUZUKI Hisao <suzuki at acm.org> (August 23, 1998)

2.1 和訳: SUZUKI Hisao <suzuki at acm.org> (June 10, 2001)

2.2.3 差分和訳: sakito <sakito at s2.xrea.com> (August 10, 2003)

2.2.3 敬体訳: ymasuda <y.masuda at acm.org> (September 5, 2003)

2.3 差分和訳: sakito <sakito at s2.xrea.com> (August 30, 2003)

2.3 敬体訳: ymasuda <y.masuda at acm.org> (November 30, 2003)

2.3.3 差分訳: ymasuda <y.masuda at acm.org> (Devember 25, 2003)

2.4 差分訳: ymasuda <y.masuda at acm.org>, G. Yoshida (etale) (March 20, 2006)

2.4 差分訳: moriwaka <moriwaka at gmail.com> (September 11, 2007)

2.5 差分訳: moriwaka <moriwaka at gmail.com> (September 12, 2007)

2.6 差分訳: cocoatomo, INADA Naoki

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用

このドキュメントでは 異なるプラットフォームでのPython環境のセットアップの一般的な方法、インタプリタの起動とPythonでの作業を楽にする方法を説明します。

コマンドラインと環境

コマンドライン

インターフェイスオプション

一般オプション

その他のオプション

使うべきでないオプション

環境変数

デバッグモード変数

Unix プラットフォームで Python を使う

最新バージョンの Python の取得とインストール

Linux

FreeBSD と OpenBSD

OpenSolaris

Python のビルド

Python に関係するパスとファイル

その他

エディタ

Windows で Python を使う

Python のインストール

別のバンドル

Python を構成する

補足: 環境変数の設定

Python 実行ファイルを見つける

モジュールの検索

スクリプトを実行する

PyWin32

Py2exe

WConio

Windows 上で Python をコンパイルする

その他のリソース

Macintosh で Python を使う

MacPython の入手とインストール

Python スクリプトの実行方法

GUI でスクリプトを実行

Configuration

IDE

追加の Python パッケージのインストール

Mac での GUI プログラミング

Mac 上の Python アプリケーションの配布

アプリケーションスクリプティング

他のリソース

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用 »

コマンドラインと環境

CPython インタプリタはコマンドラインと環境を読み取って様々な設定を行ないます。

CPython implementation detail: 他の実装のコマンドラインスキームは CPython とは異なります。さらなる情報は 別のPythonの実装 を参照してください。

コマンドライン

Python を起動するとき、以下のうち任意のオプションを指定できます。

python [-BdEiOQsStuUvVWxX3?] [-c command | -m module-name | script | - ] [args]

もちろん、もっとも一般的な利用方法は、シンプルにスクリプトを実行するものです。

python myscript.py

インターフェイスオプション

インタプリタのインターフェイスは UNIX シェルに似ていますが、より多くのの実行方法を提供しています。

tty デバイスに接続された標準入力とともに起動された場合、 EOF (end-of-file 文字。 UNIX では Ctrl-D で、Windows では Ctrl-Z, Enter で入力可能) を受け取るまで、コマンドを受け取り、それを実行します。

ファイル名引数を指定されるか、ファイルを標準入力に渡された場合は、そのファイルから読み込んだスクリプトを実行します。

ディレクトリ名を引数に受け取ったときは、そのディレクトリから適切な名前のスクリプトファイルを読み込んで実行します。

-c コマンド オプションを利用して起動された場合、 コマンド として渡された Python の文を実行します。 コマンド の部分には改行で区切られた複数行を指定することもできます。行の先頭の空白文字は Python 文の重要要素です！

-m モジュール名 として Python モジュールパスにあるモジュールを指定された場合、そのモジュールをスクリプトとして実行します。

非インタラクティブモードでは、入力の全体が実行前にパースされます。

インタプリタによって消費されるオプションリストが終了したあと、継続する全ての引数は sys.argv に渡ります。 – ただし、添字 0 の先頭要素(sys.argv[0]) はプログラムのソース自体を示す文字列です。

-c <command>

command 内の Python コードを実行します。 command は改行によって区切られた1行以上の文です。通常のモジュールのコードと同じく、行頭の空白文字は意味を持ちます。

このオプションが指定された場合、 sys.argv の先頭要素は "-c" になり、カレントディレクトリが sys.path の先頭に追加されます。 (そのディレクトリにあるモジュールをトップレベルモジュールとして import することが可能になります。)

-m <module-name>

sys.path から指定されたモジュール名のモジュールを探し、その内容を __main__ モジュールとして実行します。

引数は module 名なので、拡張子 (.py) を含めてはいけません。 module-name は有効な Python のモジュール名であるべきですが、実装がそれを強制しているとは限りません。 (例えば、ハイフンを名前に含める事を許可するかもしれません。)

パッケージ名を指定することもできます。通常のモジュールの代わりにパッケージ名を指定された場合、インタープリタは <pkg>.__main__ をメインモジュールとして実行します。この動作はインタープリタのスクリプト引数としてディレクトリやzipファイルを指定された時の動作と意図的に似せています。

ノート

このオプションはビルトインモジュールや C で書かれた拡張モジュールには利用できません。 Python モジュールファイルを持っていないからです。しかし、コンパイル済みのモジュールは、たとえ元のソースファイルがなくても利用可能です。

このオプションが指定された場合、 sys.argv の先頭要素はモジュールファイルのフルパスになります。 -c オプションのように、カレントディレクトリが sys.path の先頭に追加されます。

多くの標準ライブラリモジュールが、スクリプトとして実行された時のコードを持っています。例えば、 timeit モジュールは次のように実行可能です。

python -mtimeit -s 'setup here' 'benchmarked code here'
python -mtimeit -h # for details

参考

runpy.run_module() Python コードから直接利用できる同等の機能

PEP 338 [http://www.python.org/dev/peps/pep-0338] – Executing modules as scripts

バージョン 2.4 で追加.

バージョン 2.5 で変更: パッケージ内のモジュールを指定できるようになりました。

バージョン 2.7 で変更: パッケージ名を指定したときに __main__ サブモジュールを実行するようにしました。そのモジュールを検索している間の sys.argv[0] は "-m" に設定されるようになりました。 (以前は間違って "-c" が設定されていました)

-

標準入力 (sys.stdin) からコマンドを読み込みます。標準入力がターミナルだった場合、 -i オプションを含みます。

このオプションが指定された場合、 sys.argv の最初の要素は "-" で、カレントディレクトリが sys.path の先頭に追加されます。

<script>

script 内の Python コードを実行します。 script は、 Python ファイル、 __main__.py ファイルを含むディレクトリ、 __main__.py ファイルを含む zip ファイルのいづれかの、ファイルシステム上の (絶対あるいは相対)パスでなければなりません。

このオプションが指定された場合、 sys.argv の先頭要素は、コマンドラインで指定されたスクリプト名になります。

スクリプト名が Python ファイルを直接指定していた場合、そのファイルを含むディレクトリが sys.path の先頭に追加され、そのファイルは __main__ モジュールとして実行されます。

スクリプト名がディレクトリか zip ファイルを指定していた場合、スクリプト名が sys.path に追加され、その中の __main__.py ファイルが __main__ モジュールとして実行されます。

バージョン 2.5 で変更: トップレベルに __main__.py ファイルを持つディレクトリや zip ファイルが有効な Python スクリプトとなりました。

インターフェイスオプションが与えられなかった場合、 -i が暗黙的に指定され、 sys.argv[0] は空白文字列 ("")で、カレントディレクトリが sys.path の先頭に追加されます。

参考

インタプリタを起動する

一般オプション

-?

-h

--help

全てのコマンドラインオプションの短い説明を表示します。

バージョン 2.5 で変更: --help 形式

-V

--version

Python のバージョン番号を表示して終了します。出力の例:

Python 2.5.1

バージョン 2.5 で変更: --version 形式

その他のオプション

-B

Python は import したソースモジュールの .pyc や .pyo ファイルの作成を試みません。 PYTHONDONTWRITEBYTECODE 環境変数も参照してください。

バージョン 2.6 で追加.

-d

パーサーのデバッグ出力を有効にします。(魔法使い専用です。コンパイルオプションに依存します)。 PYTHONDEBUG も参照してください。

-E

全ての PYTHON* 環境変数を無視します。例えば、 PYTHONPATH と PYTHONHOME などです。

バージョン 2.2 で追加.

-i

最初の引数にスクリプトが指定された場合や -c オプションが利用された場合、 sys.stdin がターミナルに出力されない場合も含めて、スクリプトかコマンドを実行した後にインタラクティブモードに入ります。 PYTHONSTARTUP ファイルは読み込みません。

このオプションはグローバル変数や、スクリプトが例外を発生させるときにそのスタックトレースを調べるのに便利です。 PYTHONINSPECT も参照してください。

-O

基本的な最適化を有効にします。コンパイル済み (bytecode) ファイルの拡張子を .pyc から .pyo に変更します。 PYTHONOPTIMIZE も参照してください。

-OO

-O の最適化に加えて、ドキュメンテーション文字列の除去も行ないます。

-Q <arg>

除算制御。引数は以下のうち1つでなければなりません:

old

int/int と long/long の除算は、 int か long を返します。 (デフォルト)

new

新しい除算方式。 int/int や long/long の除算が float を返します。

warn

古い除算方式で、 int/int や long/long 除算に警告を表示します。

warnall

古い除算方式で、全ての除算演算子に対して警告を表示します。

参考

Tools/scripts/fixdiv.py warnall を使っています.

PEP 238 [http://www.python.org/dev/peps/pep-0238] – Changing the division operator

-s

sys.path にユーザー site ディレクトリを追加しません。

バージョン 2.6 で追加.

参考

PEP 370 [http://www.python.org/dev/peps/pep-0370] – Per user site-packages directory

-S

site モジュールのインポートを無効にし、そのモジュールで行われている場所独自の sys.path 操作を無効にします。

-t

ソースファイルが、タブ幅に依存して意味が変わるような方法でタブ文字とスペースを混ぜて含んでいる場合に警告を発生させます。このオプションを2重にする (-tt) とエラーになります。

-u

stdin, stdout, stderr のバッファを強制的に無効にします。関係するシステムでは、 stdin, stdout, stderr をバイナリモードにします。

file.readlines() や ファイルオブジェクト (for line in sys.stdin) はこのオプションに影響されない内部バッファリングをしています。これを回避したい場合は、 while 1: ループの中で file.readline() します。

PYTHONUNBUFFERED も参照してください。

-v

モジュールが初期化されるたびに、それがどこ(ファイル名やビルトインモジュール) からロードされたのかを示すメッセージを表示します。 2重に指定された場合(-vv)は、モジュールを検索するときにチェックされた各ファイルに対してメッセージを表示します。また、終了時のモジュールクリーンアップに関する情報も提供します。 PYTHONVERBOSE も参照してください。

-W arg

警告制御。 Python の警告機構はデフォルトでは警告メッセージを sys.stderr に表示します。典型的な警告メッセージは次の形をしています:

file:line: category: message

デフォルトでは、各警告は発生したソース業ごとに一度だけ表示されます。このオプションは、警告をどれくらいの頻度で表示するかを制御します。

複数の -W オプションを指定することができます。警告が1つ以上のオプションとマッチしたときは、最後にマッチしたオプションのアクションが有効になります。不正な -W オプションは無視されます。(最初の警告が発生したときに、不正なオプションに対する警告メッセージが表示されます。)

Python 2.7 から、 DeprecationWarning とその子クラスはデフォルトで無視されます。 -Wd オプションを指定して有効にすることができます。

警告は Python プログラムの中から warnings モジュールを利用して制御することができます。

引数の一番シンプルな形は、以下のアクション文字列(かそのユニークな短縮形) を単体で利用するものです。

ignore

全ての警告を無視する。

default

明示的にデフォルトの動作(ソース行ごとに1度警告を表示する)を要求する。

all

警告が発生するたびに表示する (これは、ループの中などで同じソース行により繰り返し警告が発生された場合に、大量のメッセージを表示します。)

module

各モジュールで最初に発生した警告を表示する。

once

プログラムで最初に発生した警告だけを表示する。

error

警告メッセージを表示する代わりに例外を発生させる。

引数の完全形は次のようになります:

action:message:category:module:line

ここで、 action は上で説明されたものですが、残りのフィールドにマッチしたメッセージにだけ適用されます。空のフィールドは全ての値にマッチします。空のフィールドの後ろは除外されます。 message フィールドは表示される警告メッセージの先頭に、大文字小文字を無視してマッチします。 category フィールドは警告カテゴリにマッチします。これはクラス名でなければなりません。 category のマッチは、メッセージの実際の警告カテゴリーが指定された警告カテゴリーのサブクラスかどうかをチェックします。完全なクラス名を指定しなければなりません。 module フィールドは、(完全正規形(fully-qualified)の) モジュール名に対してマッチします。このマッチは大文字小文字を区別します。 line フィールドは行番号にマッチします。 0 は全ての行番号にマッチし、省略した時と同じです。

参考

warnings – the warnings module

PEP 230 [http://www.python.org/dev/peps/pep-0230] – Warning framework

PYTHONWARNINGS

-x

Unix 以外の形式の #!cmd を使うために、ソースの最初の行をスキップします。これは、DOS専用のハックのみを目的としています。

ノート

エラーメッセージ内の行番号は -1 されます。

-3

Python 3.x との、 2to3 によって簡単に解決できない互換性の問題について警告します。以下のものが該当します。

dict.has_key()

apply()

callable()

coerce()

execfile()

reduce()

reload()

これらを使うと、 DeprecationWarning を発生させます。

バージョン 2.6 で追加.

使うべきでないオプション

-J

Jython [http://jython.org] のために予約されています。

-U

全ての文字列リテラルを、全部 unicode にします。このオプションはあなたの世界を破壊してしまうかもしれないので、このオプションを使おうとしないでください。これは、通常とは違うマジックナンバーを使って .pyc ファイルを生成します。ファイルの先頭に次のように書いて、このオプションの代わりにモジュール単位で unicode リテラルを有効にできます。

from __future__ import unicode_literals

詳細は __future__ を参照してください。

-X

別の Python の実装が独自の目的で利用するために予約されています。

環境変数

以下の環境変数は Python の動作に影響します。

PYTHONHOME

標準 Python ライブラリの場所を変更します。デフォルトでは、ライブラリは prefix/lib/pythonversion と exec_prefix/lib/pythonversion から探されます。ここで、 prefix と exec_prefix はインストール依存のディレクトリで、両方共デフォルトでは /usr/local です。

PYTHONHOME が1つのディレクトリに設定されている場合、その値は prefix と exec_prefix の両方を置き換えます。それらに別々の値を指定したい場合は、 PYTHONHOME を prefix:exec_prefix のように指定します。

PYTHONPATH

モジュールファイルのデフォルトの検索パスを追加します。この環境変数のフォーマットはシェルの PATH と同じで、 os.pathsep (Unix ならコロン、 Windows ならセミコロン) で区切られた1つ以上のディレクトリパスです。存在しないディレクトリは警告なしに無視されます。

通常のディレクトリに加えて、 PYTHONPATH のエントリはピュアPython モジュール(ソース形式でもコンパイルされた形式でも) を含む zip ファイルを参照することもできます。拡張モジュールは zip ファイルの中から import することはできません。

デフォルトの検索パスはインストール依存ですが、通常は prefix/lib/pythonversion で始まります。 (上の PYTHONHOME を参照してください。) これは 常に PYTHONPATH に追加されます。

上の インターフェイスオプション で説明されているように、追加の検索パスディレクトリが PYTHONPATH の手前に追加されます。検索パスは Python プログラムから sys.path 変数として操作することができます。

PYTHONSTARTUP

もし読込み可能ファイルの名前であれば、インタラクティブモードで最初のプロンプトを表示する前にそのファイル内の Python コマンドを実行します。このファイルはインタラクティブコマンドが実行されるのと同じ名前空間の中で実行されるので、このファイル内で定義されたり import されたオブジェクトはインタラクティブセッションから制限無しに利用することができます。このファイルで sys.ps1 と sys.ps2 を変更してプロンプトを変更することもできます。

PYTHONY2K

この変数に空でない文字列を設定すると、 time モジュールが文字列で指定される日付に4桁の年を含むことを要求するようになります。そうでなければ、2桁の年は time モジュールのドキュメントに書かれているルールで変換されます。

PYTHONOPTIMIZE

この変数に空でない文字列を設定すると、 -O オプションを指定したのと同じになります。整数を指定した場合、 -O を複数回指定したのと同じになります。

PYTHONDEBUG

この変数に空でない文字列を設定すると、 -d オプションを指定したのと同じになります。整数を指定した場合、 -d を複数回指定したのと同じになります。

PYTHONINSPECT

この変数に空でない文字列を設定すると、 -i オプションを指定したのと同じになります。

この変数は Python コードから os.environ を使って変更して、プログラム終了時のインスペクトモードを強制することができます。

PYTHONUNBUFFERED

この変数に空でない文字列を設定すると、 -u オプションを指定したのと同じになります。

PYTHONVERBOSE

この変数に空でない文字列を設定すると、 -v オプションを指定したのと同じになります。整数を指定した場合、 -v を複数回指定したのと同じになります。

PYTHONCASEOK

この環境変数が設定されていると、 Python は import 文で大文字/小文字を区別しません。これは Windows でのみ動作します。

PYTHONDONTWRITEBYTECODE

この環境変数が設定されていると、 Python はソースモジュールの import 時に .pyc, .pyo ファイルを生成しません。

バージョン 2.6 で追加.

PYTHONIOENCODING

stdin/stdout/stderr のエンコーディングを強制します。シンタックスは encodingname:errorhandler です。 :errorhandler の部分はオプションで、 str.encode() の引数と同じ意味です。

バージョン 2.6 で追加.

PYTHONNOUSERSITE

この環境変数が設定されている場合、 Python はユーザー site ディレクトリを sys.path に追加しません。

バージョン 2.6 で追加.

参考

PEP 370 [http://www.python.org/dev/peps/pep-0370] – Per user site-packages directory

PYTHONUSERBASE

ユーザー site ディレクトリのベースディレクトリを設定します。

バージョン 2.6 で追加.

参考

PEP 370 [http://www.python.org/dev/peps/pep-0370] – Per user site-packages directory

PYTHONEXECUTABLE

この環境変数が設定されていると、 sys.argv[0] に、 C ランタイムから取得した値の代わりにこの環境変数の値が設定されます。 Mac OS X でのみ動作します。

PYTHONWARNINGS

これは -W オプションと同じです。カンマ区切りの文字列が設定されたとき、その動作は -W を複数回指定されたのと同じになります。

デバッグモード変数

以下の環境変数は、 --with-pydebug ビルドオプションを指定して構成されたデバッグビルド版の Python でのみ効果があります。

PYTHONTHREADDEBUG

設定された場合、 Python はスレッドデバッグ情報を表示します。

バージョン 2.6 で変更: 以前は、この変数は THREADDEBUG という名前でした。

PYTHONDUMPREFS

設定された場合、 Python はインタプリタのシャットダウン後に残っているオブジェクトとリファレンスカウントをダンプします。

PYTHONMALLOCSTATS

設定された場合、 Python は、新しいオブジェクトアリーナを作成するときと、シャットダウン時に、メモリアロケーション統計情報を表示します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用 »

Unix プラットフォームで Python を使う

最新バージョンの Python の取得とインストール

Linux

ほとんどの Linux ディストリビューションでは Python はプリインストールされており、それ以外の Linux ディストリビューションでも パッケージとして利用可能です。しかし、ディストリビューションのパッケージでは、利用したい機能が使えない場合があります。最新版の Python をソースから簡単にコンパイルすることができます。

Python がプリインストールされておらず、リポジトリにも無い場合、ディストリビューション用のパッケージを簡単につくることができます。以下のリンクを参照してください。

参考

http://www.linux.com/articles/60383

for Debian users

http://linuxmafia.com/pub/linux/suse-linux-internals/chapter35.html

for OpenSuse users

http://docs.fedoraproject.org/drafts/rpm-guide-en/ch-creating-rpms.html

for Fedora users

http://www.slackbook.org/html/package-management-making-packages.html

for Slackware users

FreeBSD と OpenBSD

FreeBSD ユーザーは、 Python のパッケージを追加するために次のようにしてください。

pkg_add -r python

OpenBSD ユーザーはこうです。

pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/4.2/packages/<アーキテクチャ>/python-<バージョン>.tgz

たとえば、 i386 ユーザーが Python 2.5.1 を取得するには、次のようにします。

pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/4.2/packages/i386/python-2.5.1p2.tgz

OpenSolaris

OpenSolaris に最新版の Python をインストールするには、 blastwave (http://www.blastwave.org/howto.html) をインストールして、プロンプトから “pkg_get -i python” とタイプしてください。

Python のビルド

CPython を自分でコンパイルしたい場合、最初にするべきことはソース [http://python.org/download/source/] を取得することです。最新リリース版のソースか、新しいチェックアウト [http://www.python.org/dev/faq/#how-do-i-get-a-checkout-of-the-repository-read-only-and-read-write] をダウンロードすることができます。

ビルド手順は通常次のステップで構成されます。

./configure
make
make install

configure のオプションと特定の Unix プラットフォームにおける注意点は Python のソースツリーのルートにある README の中に細かく記載されています。

警告

make install は python バイナリを上書きまたは覆い隠すかもしれません。そのため、 make install の代わりに exec_prefix/bin/pythonversion しかインストールしない make altinstall が推奨されます。

Python に関係するパスとファイル

これらはローカルインストール時の規約に応じて変化します; prefix (${prefix}) と exec_prefix (${exec_prefix}) はインストール状況に依存していて、GNU ソフトウェアによって解釈されます; この二つは同じかもしれません。

例えば、ほとんどの Linux システムでは、デフォルトでは両方が /usr です。

ファイル/ディレクトリ | 意味
exec_prefix/bin/python | インタプリタの推奨される場所
prefix/lib/pythonversion, exec_prefix/lib/pythonversion | 標準モジュールを格納するディレクトリの、推奨される場所
prefix/include/pythonversion, exec_prefix/include/pythonversion | Python 拡張や Python の埋込みに必要となる include ファイルを格納するディレクトリの推奨される場所
~/.pythonrc.py | user モジュールによって読み込まれる、ごとの初期化ファイル。デフォルトでは、ほとんどのアプリケーションは利用しません。

その他

Python スクリプトを Unix で簡単に使うために、例えば次のようにして、そのスクリプトを実行ファイルにし

$ chmod +x script

そして適切な shebang 行をスクリプトの先頭に置きます。たいていの場合良い方法は

#!/usr/bin/env python

で、 PATH 全体から Python インタプリタを探します。しかし、幾つかの Unix は env コマンドをもっていないので、インタプリタのパスを /usr/bin/python のようにハードコードしなければならないかもしれません。

シェルコマンドを Python スクリプトから使うには、 subprocess モジュールを参照してください。

エディタ

Vim と Emacs は Python をよくサポートした、素晴らしいエディタです。これらのエディタで Python のコードを書く方法についての詳しい情報は、次の場所を参照してください。

http://www.vim.org/scripts/script.php?script_id=790

http://sourceforge.net/projects/python-mode

Geany はたくさんの言語をサポートした素晴らしい IDE です。さらなる情報は、 http://geany.uvena.de/ を読んでください。

Komodo edit も非常に良い IDE です。これもたくさんの言語をサポートしています。さらなる情報は、 http://www.activestate.com/store/productdetail.aspx?prdGuid=20f4ed15-6684-4118-a78b-d37ff4058c5f を読んでください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用 »

Windows で Python を使う

このドキュメントは、 Python を Microsoft Windows で使うときに知っておくべき、 Windows 独特の動作についての概要を伝えることを目的としています。

Python のインストール

ほとんどの Unix システムやサービスと異なり、 Windows は Python に依存しておらず、プリインストールの Python はありません。しかし、 CPython チームは長年にわたり、コンパイル済みの Windows インストーラ (MSI パッケージ)を リリース [http://www.python.org/download/releases/] 毎に用意しています。

Python の継続的な開発の中で、過去にサポートされていた幾つかのプラットフォームが (ユーザーと開発者の不足のために) サポートされなくなっています。全てのサポートされないプラットフォームについての詳細は PEP 11 [http://www.python.org/dev/peps/pep-0011] をチェックしてください。

DOS と Windows 3.x は Python 2.0 から廃止予定になり、Python 2.1 でこれらのシステム専用のコードは削除されました。

2.5 まで、 Python は Windows 95, 98, ME で動きました (ですが、すでにインストール時に廃止予定の警告をだしていました)。 Python 2.6 (とその後の全てのリリース) は、これらの OS のサポートが止められ、新しいリリースは Windows NT ファミリーしか考慮されていません。

Windows CE [http://pythonce.sourceforge.net/] は今でもサポートされています。

Cygwin [http://cygwin.com/] インストーラも Python インタープリタ [http://cygwin.com/packages/python] のインストールを提供しています。これは “Interpreters” の下に置かれています。(cf. Cygwin package source [ftp://ftp.uni-erlangen.de/pub/pc/gnuwin32/cygwin/mirrors/cygnus/release/python], Maintainer releases [http://www.tishler.net/jason/software/python/])

コンパイル済みインストーラが提供されているプラットフォームについての詳細な情報は Python for Windows (and DOS) [http://www.python.org/download/windows/] を参照してください。

参考

Python on XP [http://www.richarddooling.com/index.php/2006/03/14/python-on-xp-7-minutes-to-hello-world/]

“7 Minutes to “Hello World!”” by Richard Dooling, 2006

Installing on Windows [http://diveintopython.org/installing_python/windows.html]

in “Dive into Python: Python from novice to pro [http://diveintopython.org/index.html]” by Mark Pilgrim, 2004, ISBN 1-59059-356-1

For Windows users [http://swaroopch.com/text/Byte_of_Python:Installing_Python#For_Windows_users]

in “Installing Python” in “A Byte of Python [http://www.byteofpython.info]” by Swaroop C H, 2003

別のバンドル

標準の CPython の配布物の他に、追加の機能を持っている修正されたパッケージがあります。以下は人気のあるバージョンとそのキーとなる機能です。

ActivePython [http://www.activestate.com/Products/activepython/]

マルチプラットフォーム互換のインストーラー、ドキュメント、 PyWin32

Enthought Python Distribution [http://www.enthought.com/products/epd.php]

(PyWin32 などの) 人気のあるモジュールとそのドキュメント、 Python の拡張をビルドするためのツールスイート

これらのパッケージは 古い バージョンの Python をインストールするかもしれないことに気をつけてください。

Python を構成する

Python を完全に動かすために、幾つかの環境設定を変更しなければならないかもしれません。

補足: 環境変数の設定

Windows は環境変数を変更するためのビルトインのダイアログを持っています。 (以降のガイドは XP のクラシカルビューに適用されます。) マシンのアイコン(たいていデスクトップにあって “マイ コンピュータ” と呼ばれます) を右クリックして、そこにある プロパティ を選択します。詳細設定 タブを開いて、 環境変数 ボタンをクリックします。

ここまでのパスをまとめると:

マイ コンピュータ ‣ プロパティ ‣ 詳細設定 ‣ 環境変数

このダイアログで、ユーザーとシステムの環境変数を追加したり修正できます。システム変数を変更するには、マシンへの無制限アクセス(管理者権限)が必要です。

環境に変数を追加するもう一つの方法は、 set コマンドを使うことです。

set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib

この設定を永続化するために、このコマンドラインを autoexec.bat に追加することができます。 msconfig はこのファイルを編集するGUIです。

もっと直接的な方法で環境変数を見ることができます。コマンドプロンプトはパーセント記号で囲まれた文字列を自動的に展開します。

echo %PATH%

この動作についての詳細は set /? を見てください。

参考

http://support.microsoft.com/kb/100843

Windows NT の環境変数

http://support.microsoft.com/kb/310519

Windows XP での環境変数の管理方法

http://www.chem.gla.ac.uk/~louis/software/faq/q1.html

Setting Environment variables, Louis J. Farrugia

Python 実行ファイルを見つける

スタートメニューに自動的に作られた Python interpreter のメニューエントリを使うのと別に、DOSプロンプトから Python を実行したいかもしれません。そのためには、 %PATH% 環境変数に Python ディストリビューションのディレクトリを、セミコロンで他のエントリと区切って含めるように設定する必要があります。変数の設定例は次のようになります (最初の2つのエントリが Windows のデフォルトだと仮定します):

C:\WINDOWS\system32;C:\WINDOWS;C:\Python26

コマンドプロンプトから python をタイプすると、 Python インタプリタを起動します。これで、スクリプトをコマンドラインオプション付きで実行することも可能です。 コマンドライン ドキュメントを参照してください。

モジュールの検索

Python は通常そのライブラリ(と site-packages フォルダ)をインストールしたディレクトリに格納する。なので、 Python を C:\Python\ ディレクトリにインストールしたとすると、デフォルトのライブラリは C:\Python\Lib\ に存在し、サードパーティーのモジュールは C:\Python\Lib\site-packages\ に格納されます。

以下は、 Windows で sys.path が構築される方法です。

最初に空のエントリが追加されます。これはカレントディレクトリを指しています。

その次に、 PYTHONPATH 環境変数が存在するとき、 環境変数 で解説されているように追加されます。 Windows ではドライブ識別子 (C:\ など)と区別するために、この環境変数に含まれるパスの区切り文字はセミコロンでなければならない事に注意してください。

追加で “アプリケーションのパス” を HKEY_CURRENT_USER か HKEY_LOCAL_MACHINE の中の \SOFTWARE\Python\PythonCore\version\PythonPath のサブキーとして登録することができます。サブキーはデフォルト値としてセミコロンで区切られたパス文字列を持つことができ、書くパスが sys.path に追加されます。 (既存のインストーラーは全て HKLM しか利用しないので、 HKCU は通常空です)

PYTHONHOME が設定されている場合、それは “Python Home” として扱われます。それ以外の場合、 “Python Home” を推定するために Python の実行ファイルのパスから “目標ファイル” (Lib\os.py) が探されます。 Python home が見つかった場合、そこからいくつかのサブディレクトリ (Lib, plat-win, など) が sys.path に追加されます。見つからなかった場合、 core Python path はレジストリに登録された PythonPath から構築されます。

Python Home が見つからず、環境変数 PYTHONPATH が指定されず、レジストリエントリが見つからなかった場合、関連するデフォルトのパスが利用されます。 (例: .\Lib;.\plat-win など)

結果としてこうなります:

python.exe かそれ以外の Python ディレクトリにある .exe ファイルを実行したとき (インストールされている場合でも PCbuild から直接実行されている場合でも) core path が利用され、レジストリ内の core path は無視されます。それ以外のレジストリの “application paths” は常に読み込まれます。

Python が他の .exe ファイル (他のディレクトリに存在する場合や、COM経由で組み込まれる場合など) にホストされている場合は、 “Python Home” は推定されず、レジストリにある core path が利用されます。それ以外のレジストリの “application paths” は常に読み込まれます。

Python が Python home ディレクトリを見つけられずレジストリも存在しない場合 (例: freeze された .exe, いくつかのとても奇妙なインストール構成)、デフォルトの、ただし相対パスが利用されます。

追加のフォルダを Python の import 機構の検索対象に含めることもできます。 PYTHONPATH を 環境変数 で解説されているように利用し、 sys.path を変更してください。 Windowsでは、 ドライブ識別子 (C:\ など) と区別するために、パスはセミコロンで区切られています。

モジュール検索パスの変更は、レジストリの HKLM\SOFTWARE\Python\PythonCore\version\PythonPath キーからも可能です。このキーのデフォルト値と同じように、セミコロンで区切られたパス文字列を持ったサブキーがあれば、その各パスを探します。複数のサブキーを作成することができ、 path に辞書順で追加されます。便利なレジストリエディタは regedit です。 (スタート ‣ ファイル名を指定して実行 から “regedit” とタイプすることで起動することができます。)

スクリプトを実行する

Python スクリプト (.py 拡張子を持ったファイル) はデフォルトで python.exe に起動されます。この実行ファイルは、プログラムがGUIを使う場合でもターミナルを開きます。ターミナル無しでスクリプトを実行したい場合は、拡張子 .pyw を使うとそのスクリプトがデフォルトでは pythonw.exe で実行されるようになります。 (2つの実行ファイルは両方とも Python をインストールしたディレクトリの直下にあります。) pythonw.exe は起動時にターミナルを開きません。

You can also make all .py scripts execute with pythonw.exe, setting this through the usual facilities, for example (might require administrative rights): 全ての .py スクリプトを pythonw.exe で実行するように設定することもできます。例えば (管理者権限が必要):

コマンドプロンプトを起動する

.py スクリプトに正しいファイルグループを関連付ける:

assoc .py=Python.File

全ての Python ファイルを新しい実行ファイルにリダイレクトする:

ftype Python.File=C:\Path\to\pythonw.exe "%1" %*

Additional modules 追加のモジュール =================

Python は全プラットフォーム互換を目指していますが、 Windows にしかないユニークな機能もあります。標準ライブラリと外部のライブラリの両方で、幾つかのモジュールと、そういった機能を使うためのスニペットがあります。

Windows 専用の標準モジュールは、 MS Windows 固有のサービス に書かれています。

PyWin32

The PyWin32 [http://python.net/crew/mhammond/win32/] module by Mark Hammond is a collection of modules for advanced Windows-specific support. This includes utilities for: Mark Hammond によって開発された PyWin32 [http://python.net/crew/mhammond/win32/] モジュールは、進んだ Windows 専用のサポートをするモジュール群です。このモジュールは以下のユーティリティを含んでいます。

Component Object Model [http://www.microsoft.com/com/] (COM)

Win32 API 呼び出し

レジストリ

イベントログ

Microsoft Foundation Classes [http://msdn.microsoft.com/en-us/library/fe1cf721%28VS.80%29.aspx] (MFC) ユーザーインターフェイス

PythonWin [http://web.archive.org/web/20060524042422/http://www.python.org/windows/pythonwin/] は PyWin32 に付属している、サンプルのMFCアプリケーションです。これはビルトインのデバッガを含む、組み込み可能なIDEです。

参考

Win32 How Do I...? [http://timgolden.me.uk/python/win32_how_do_i.html]

by Tim Golden

Python and COM [http://www.boddie.org.uk/python/COM.html]

by David and Paul Boddie

Py2exe

Py2exe [http://www.py2exe.org/] は distutils 拡張 (Distutilsの拡張を参照) で、 Python スクリプトを Windows 実行可能プログラム (*.exe ファイル) にラップします。これを使えば、ユーザーに Python のインストールをさせなくても、アプリケーションを配布することができます。

WConio

Python の進んだターミナル制御レイヤである curses は、 Unix ライクシステムでしか使うことができません。逆に Windows 専用のライブラリ、 Windows Console I/O for Python があります。

WConio [http://newcenturycomputers.net/projects/wconio.html] は Turbo-C の CONIO.H のラッパーで、テキストユーザーインタフェースを作成するために利用することができます。

Windows 上で Python をコンパイルする

CPython を自分でコンパイルしたい場合、最初にすることはソース [http://python.org/download/source/] を取得することです。最新版リリースのソースをダウンロードするか、最新の チェックアウト [http://www.python.org/dev/faq/#how-do-i-get-a-checkout-of-the-repository-read-only-and-read-write] を取得することができます。

公式の Python リリースをビルドするのに使われている Microsoft Visual C++ コンパイラのために、ソースツリーは ソリューション・プロジェクトファイルを含んでいます。適切なディレクトリにある readme.txt を参照してください。

ディレクトリ | MSVC バージョン | Visual Studio バージョン
PC/VC6/ | 6.0 | 97
PC/VS7.1/ | 7.1 | 2003
PC/VS8.0/ | 8.0 | 2005
PCbuild/ | 9.0 | 2008

これらのビルドディレクトリの全てが完全にサポートされているわけではありません。使用しているバージョンの公式リリースが利用しているコンパイラのバージョンについては、リリースノートを参照してください。

ビルドプロセスに関する一般的な情報は PC/readme.txt をチェックしてください。

拡張モジュールについては、 Windows 上での C および C++ 拡張モジュールのビルド を参照してください。

参考

Python + Windows + distutils + SWIG + gcc MinGW [http://sebsauvage.net/python/mingw.html]

or “Creating Python extensions in C/C++ with SWIG and compiling them with MinGW gcc under Windows” or “Installing Python extension with distutils and without Microsoft Visual C++” by Sébastien Sauvage, 2003

MingW – Python extensions [http://oldwiki.mingw.org/index.php/Python%20extensions]

by Trent Apted et al, 2007

その他のリソース

参考

Python Programming On Win32 [http://www.oreilly.com/catalog/pythonwin32/]

“Help for Windows Programmers” by Mark Hammond and Andy Robinson, O’Reilly Media, 2000, ISBN 1-56592-621-8

A Python for Windows Tutorial [http://www.imladris.com/Scripts/PythonForWindows.html]

by Amanda Birmingham, 2004

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用 »

Macintosh で Python を使う

Author:
Bob Savage <bobsavage@mac.com>

Mac OS X が動作している Macintosh 上の Python は原則的には他の Unix プラットフォーム上の Python と非常によく似ていますが、 IDE やパッケージ・マネージャなどの指摘すべき追加要素があります。

Mac 特有のモジュールについては Mac OS X 固有のサービス に書かれています。

Mac OS 9 もしくはそれ以前の Mac 上の Python は Unix や Windows 上の Python とは大きく掛け離れていますが、そのプラットフォームは既にサポートされておらずこのマニュアルで扱う範囲を越えているので、Python 2.4 以降を扱うことにします。 Mac OS 9 用の最新のバージョン 2.3 リリースのインストーラやそのドキュメントについては http://www.cwi.nl/~jack/macpython を参照してください。

MacPython の入手とインストール

Mac OS X 10.5 には Apple によって Python 2.5.1 がプリインストールされています。 Python の Web サイト (http://www.python.org) から最新バージョンの Python を取得しインストールすることもできます。新しい Intel の CPU でも古い PPC の CPU でもネイティブに動作する “ユニバーサル・バイナリ” ビルドの最新のものがあります。

インストールを行うといくつかのものが手に入ります:

Applications フォルダにある MacPython 2.5 フォルダ. 公式の Python ディストリビューションに含まれる開発環境 IDLE; Finder から Python スクリプトをダブルクリックしたときに起動する PythonLauncher; Python スクリプトを単独のアプリケーションに変換する “Build Applet” ツールがここにあります.

Python 実行ファイルやライブラリを含む /Library/Frameworks/Python.framework フレームワーク。インストーラはシェルのパスにこの場所を追加します。 MacPython をアンインストールするには、これら 3 つを削除すればよいだけです。 Python 実行ファイルへのシンボリックリンクは /usr/local/bin/ に置かれています。

Apple が提供している Python は /System/Library/Frameworks/Python.framework と /usr/bin/python にそれぞれインストールされています。これらは Apple が管理しているものであり Apple やサードパーティのソフトウェアが使用するので、編集したり削除してはいけません。 python.org から新しいバージョンの Python をインストールすることにした場合には、異なるが動作する 2 つの Python 環境があなたのコンピュータにあることに注意し、パスの設定や Python の使い方と実際にしたいこととが食い違っていないことが重要です。

IDLE にはヘルプメニューがあり Python のドキュメントにアクセスすることができます。もし Python が全くの初めての場合にはドキュメントのチュートリアルを最初から読み進めることをおすすめします。

もし他の Unix プラットフォーム上の Python に慣れている場合は Unix シェルからの Python スクリプトの実行についての節を読むことをおすすめします。

Python スクリプトの実行方法

Mac OS X で Python を始める最良の方法は統合開発環境である IDLE を使うことです、 IDE 節を参照し IDE を実行しているときにヘルプメニューを使ってください。

もし Python スクリプトをターミナルのコマンドラインや Finder から実行したい場合は最初にエディタでスクリプトを作る必要があります。 Mac OS X には vim や emacs などの Unix の標準のラインエディタが備わっています。もしもっと Mac らしいエディタが欲しい場合には、Bare Bones Software (http://www.barebones.com/products/bbedit/index.shtml を参照) の BBEdit や TextWrangler もしくは TextMate (see http://macromates.com/) は良い選択候補です。他には Gvim (http://macvim.org) や Aquamacs (http://aquamacs.org/) などがあります。

ターミナルからスクリプトを実行するには /usr/local/bin がシェルのパスに含まれていることを確認してください。

Finder からスクリプトを実行するのには 2 つの方法があります:

PythonLauncher へドラッグする

Finder の情報ウィンドウから PythonLauncher をそのスクリプト (もしくは .py スクリプト全て) を開くデフォルトのアプリケーションとして選び、スクリプトファイルをダブルクリックしてください。 PythonLauncher の環境設定にはどのようにスクリプトを実行するかを管理する様々な設定があります。 option キーを押しながらドラッグすることで実行するごとにこれらの設定を変えられますし、環境設定メニューから全ての実行に対して設定変更することもできます。

GUI でスクリプトを実行

古いバージョンの Python について、気を付けておくべき Mac OS X の癖があります: Aqua ウィンドウマネージャとやりとりをする (別の言い方をすると GUI を持つ) プログラムは特別な方法で実行する必要があります。そのようなスクリプトを実行するには python ではな pythonw を使ってください。

Python 2.5 では、 python も pythonw も使えます。

Configuration

OS X 上の Python では PYTHONPATH のような全ての標準の Unix 環境変数が使えますが、Finder からプログラムを起動する場合このような環境変数を設定する方法は非標準であり Finder は起動時に .profile や .cshrc を読み込みません。 ~/.MacOSX/environment.plist ファイルを作る必要があります。詳細については Apple の Technical Document QA1067 を参照してください。

MacPython の Python パッケージのインストールについてのさらなる情報は、 追加の Python パッケージのインストール 節を参照してください。

IDE

MacPython には標準の IDLE 開発環境が付いてきます。 http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html に IDLE を使うための良い入門があります。

追加の Python パッケージのインストール

追加の Python パッケージをインストールする方法がいくつかあります:

http://pythonmac.org/packages/ には Python 2.5、2.4、2.3 用のコンパイルされたパッケージがあります。

パッケージは Python の標準の distutils モードを使ってインストールすることができます (python setup.py install)。

多くのパッケージは setuptools 拡張を使ってもインストールできます。

Mac での GUI プログラミング

Python で Mac 上の GUI アプリケーションをビルドする方法がいくつかあります。

PyObjC は Mac の最新の開発基盤である Apple の Objective-C/Cocoa フレームワークへの Python バインディングです。 PyObjC の情報は http://pyobjc.sourceforge.net にあります。

標準の Python の GUI ツールキットは Tkinter で、クロスプラットフォームの Tk ツールキット (http://www.tcl.tk) をベースにしています。 Aqua ネイティブ版の Tk は OS X に入っており、最新バージョンが http://www.activestate.com からダウンロードおよびインストールできます; またソースからビルドすることもできます。

wxPython は別の人気のあるクロスプラットフォームの GUI ツールキットで Mac OS X 上でネイティブに動作します。パッケージとドキュメントは http://www.wxpython.org から利用できます。

PyQt は別の人気のあるクロスプラットフォームの GUI ツールキットで Mac OS X 上でネイティブに動作します。さらなる情報は http://www.riverbankcomputing.co.uk/software/pyqt/intro にあります。

Mac 上の Python アプリケーションの配布

フォルダ MacPython 2.5 にある “Built Applet” ツールはあなたのマシンの小さな Python スクリプトを標準の Mac アプリケーションとして実行できるようなパッケージを作るのに優れています。しかし、このツールは Python アプリケーションを他のユーザに配布するのには向いていません。

Mac 上の単独の Python アプリケーションをデプロイする標準のツールは py2app です。 py2app のインストールと使用法に関する情報は http://undefined.org/python/#py2app にあります。

アプリケーションスクリプティング

Python は Apple の Open Scripting Architecture (OSA) を通して他の Mac アプリケーションのスクリプトとしても使えます; http://appscript.sourceforge.net を参照してください。 Appscript は高水準でユーザに優しい Apple event ブリッジで普通の Python スクリプトを使って Mac OS X アプリケーションを操作することができます。 Appscript は Mac の自動操作を行うための Apple 自身による言語 AppleScript の代わりとして本格的に使えます。それに関連するパッケージ PyOSA は Python のための OSA 言語コンポーネントで、それを使うことで Python のコードをどんな OSA 対応のアプリケーション (Script Editor、Mail、 iTunes など) からも実行できます。 PyOSA によって Python は完全な AppleScript との通信端末になります。

他のリソース

MacPython メーリングリストは Mac での Python ユーザや開発者にとって素晴しいサポートリソースです:

http://www.python.org/community/sigs/current/pythonmac-sig/

他の役に立つリソースは MacPython wiki です:

http://wiki.python.org/moin/MacPython

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のセットアップと利用 »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる “Using Python” の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

masaki

INADA Naoki <inada-n at klab.jp>

cocoatomo

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス

Release: | 2.7
Date: | 2011年 12月 26日

このリファレンスマニュアルでは、Python 言語の文法と、 “コアとなるセマンティクス” について記述します。このマニュアルはそっけない書き方かもしれませんが、正確さと完全さを優先しています。必須でない組み込みオブジェクト型や組み込み関数、組み込みモジュールに関するセマンティクスは、 Python 標準ライブラリ で述べられています。形式ばらない Python 言語入門には、 Python チュートリアルを参照してください。 C 言語あるいはC++プログラマ向けには、このマニュアルとは別に二つのマニュアルがあります。 Python インタプリタの拡張と埋め込み では、Python 拡張モジュールを書くための高レベルな様式について述べています。また、 Python/C API リファレンスマニュアル では、C/C++ プログラマが利用できるインタフェースについて詳細に記述しています。

導入

別のPythonの実装

本マニュアルにおける表記法

字句解析

行構造

その他のトークン

識別子 (identifier) およびキーワード (keyword)

リテラル (literal)

演算子 (operator)

デリミタ (delimiter)

データモデル

オブジェクト、値、および型

標準型の階層

新スタイルと旧スタイル

特殊メソッド名

実行モデル

名前づけと束縛 (naming and binding)

例外

式 (expression)

算術変換 (arithmetic conversion)

アトム、原子的要素 (atom)

一次語 (primary)

べき乗演算 (power operator)

単項算術演算とビット単位演算(unary arithmetic and bitwise operation)

二項算術演算 (binary arithmetic operation)

シフト演算 (shifting operation)

ビット単位演算の二項演算 (binary bitwise operation)

比較 (comparison)

ブール演算 (boolean operation)

条件演算 (Conditional Expressions)

ラムダ (lambda)

式のリスト

評価順序

まとめ

単純文 (simple statement)

式文 (expression statement)

代入文 (assignment statement)

assert 文

pass 文

del 文

print 文

return 文

yield 文

raise 文

break 文

continue 文

import 文

global 文

exec 文

複合文 (compound statement)

if 文

while 文

for 文

try 文

with 文

関数定義

クラス定義

トップレベル要素

完全な Python プログラム

ファイル入力

対話的入力

式入力

完全な文法仕様

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

導入

このリファレンスマニュアルは、Python プログラミング言語自体に関する記述です。チュートリアルとして書かれたものではありません。

私は本マニュアルをできるだけ正確に書こうとする一方で、文法や字句解析以外の全てについて、形式化された仕様記述ではなく英語を使うことにしました。そうすることで、このドキュメントが平均的な読者にとってより読みやすくなっているはずですが、ややあいまいな部分も残っていることでしょう。従って、もし読者のあなたが火星から来ている人で、このドキュメントだけから Python を再度実装しようとしているのなら、色々と推測しなければならないことがあり、実際にはおそらく全く別の言語を実装する羽目になるでしょう。逆に、あなたが Python を利用しており、Python 言語のある特定の領域において、厳密な規則が何か疑問に思った場合、その答えはこのドキュメントで確実に見つけられることでしょう。

もしより形式化された言語定義をお望みなら、あなたの時間を提供していただいてかまいません — もしくは、クローン生成装置でも発明してください :-) 。

実装に関する詳細を言語リファレンスのドキュメントに載せすぎるのは危険なことです — 実装は変更されるかもしれず、同じ言語でも異なる実装は異なった動作をするかもしれないからです。一方、広く使われている Python 実装は現在のところ唯一 (今や別の実装もいくつか存在しますが！) なので、特定のクセについては、特に実装によって何らかの制限が加えられている場合には、触れておく価値があります。従って、このテキスト全体にわたって短い “実装に関する注釈 (imprementation notes)” がちりばめられています。

Python 実装はいずれも、数々の組み込みモジュールと標準モジュールが付属します。それらについては、 Python 標準ライブラリ でドキュメント化されています。いくつかの組み込みモジュールについては、言語定義と重要なかかわりをもっているときについて触れています。

別のPythonの実装

Pythonの実装としては，群を抜いて有名な実装がひとつ存在しています。それ以外の実装に関しても、特定のユーザ間で興味が持たれています。

よく知られている実装には以下のものがあります:

CPython

これは最も保守されている初代のPython実装で、C言語で書かれています。ほとんどの場合、言語の新機能がいち早く実装されます。

Jython

Javaで実装されたPythonです。この実装はJavaアプリケーションのためのスクリプト言語として，もしくはJavaクラスライブラリを使ったアプリケーションを作成するために使用することができます。また、Javaライブラリのテストを作成するためにもしばしば使用されています。さらなる情報については the Jython website [http://www.jython.org/] を参照してください。

Python for .NET

この実装は内部ではCPythonを使用していますが、 .NETアプリケーションによって管理されているので、 .NETライブラリを参照することが可能です。この実装はBrian Lloydによって作成されました。さならる情報については、 Python for .NET home page [http://pythonnet.sourceforge.net] を参照してください。

IronPython

.NETでPythonを使用するためのもう一つの実装です。 Python.NETとは異なり、完全にILを生成することができるPythonの実装あり、直接Pythonコードを.NETアセンブリにコンパイルします。これはJythonの初代の開発者であるJim Huguninによって作られました。さらなる情報については the IronPython website [http://www.ironpython.com/] を参照してください。

PyPy

完全にPythonで書かれたPythonの実装です。他の実装には見られない、スタックレスのサポートや、実行時 (Just in Time) コンパイラなどの高度な機能をサポートしています。このプロジェクトの一つの目的は、（Pythonで書かれていることによって、）インタプリタを簡単に修正できるようにして、言語自体での実験を後押しすることです。さらなる情報は the PyPy project’s home page [http://pypy.org/] にあります。

これらの各実装はこのマニュアルで文書化された言語とは多少異なっている、もしくは、標準のPythonドキュメントと何処が異なっているかを定めた情報が公開されているでしょう。あなたが使用している実装上で、代替手段を使う必要があるかどうかを判断するためには、各実装の仕様書を参照してください。

本マニュアルにおける表記法

字句解析と構文に関する記述では、BNF 文法記法に手を加えたものを使っています。この記法では、以下のような記述形式をとります:

name      ::=  lc_letter (lc_letter | "_")*
lc_letter ::=  "a"..."z"

最初の行は、 name が lc_letter の後ろにゼロ個またはそれ以上の lc_letter とアンダースコアが続いたものであることを示しています。そして、 lc_letter は 'a' から 'z' までの何らかの文字一字であることを示します (この規則は、このドキュメントに記述されている字句規則と構文規則において定義されている名前 (name) で一貫して使われています)。

各規則は name (規則によって定義されているものの名前) と ::= から始まります。垂直線 (|) は、複数の選択項目を分かち書きするときに使います; この記号は、この記法において最も結合優先度の低い演算子です。アスタリスク (*) は、直前にくる要素のゼロ個以上の繰り返しを表します; 同様に、プラス (+) は一個以上の繰り返しで、角括弧 ([ ]) に囲われた字句は、字句がゼロ個か一個出現する (別の言い方をすれば、囲いの中の字句はオプションである) ことを示します。 * および + 演算子の結合範囲は可能な限り狭くなっています; 字句のグループ化には丸括弧を使います。リテラル文字列はクオートで囲われます。空白はトークンを分割しているときのみ意味を持ちます。規則は通常、一行中に収められています; 多数の選択肢のある規則は、最初の行につづいて、垂直線の後ろに各々別の行として記述されます。

(上の例のような) 字句定義では、他に二つの慣習が使われています: 三つのドットで区切られている二つのリテラル文字は、二つの文字の ASCII 文字コードにおける (包含的な) 範囲から文字を一字選ぶことを示します。各カッコ中の字句 (<...>) は、定義済みのシンボルを記述する非形式的なやりかたです; 例えば、 ‘制御文字’ を書き表す必要があるときなどに使われることがあります。

字句と構文規則の定義の間で使われている表記はほとんど同じですが、その意味には大きな違いがあります: 字句定義は入力ソース中の個々の文字を取り扱いますが、構文定義は字句解析で生成された一連のトークンを取り扱います。次節 (“字句解析”) における BNF はすべて字句定義のためのものです; それ以降の章では、構文定義のために使っています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

字句解析

Python で書かれたプログラムは パーザ (parser) に読み込まれます。パーザへの入力は、 字句解析器 (lexical analyzer) によって生成された一連の トークン (token) からなります。この章では、字句解析器がファイルをトークン列に分解する方法について解説します。

Python は 7-bit の ASCII 文字セットをプログラムのテキストに使います。

バージョン 2.3 で追加: エンコード宣言を使って、文字列リテラルやコメントに ASCII ではない文字セットが使われていることを明示できます。.

以前のバージョンとの互換性のために、Python は 8-bit 文字が見つかっても警告を出すだけにとどめます; こうした警告は、エンコーディングを明示したり、バイナリデータの場合には文字ではなくエスケープシーケンスを使うことで解決できます。

実行時の文字セットは、プログラムが接続されている I/O デバイスにもよりますが、通常 ASCIIのサブセットです。

将来のバージョンとの互換性に関する注意: 8-bit 文字に対する文字セットを ISO Latin-1 (ラテン語系アルファベットを用いるほとんどの西欧言語をカバーするASCII の上位セット) とみなしたい気にもなるかもしれません。しかし、おそらく Unicode を編集できるテキストエディタが将来一般的になるはずです。こうしたエディタでは一般的に UTF-8 エンコードを使いますが、UTF-8 エンコードは ASCII の上位セットではあるものの、文字序数 (ordinal) 128-255 の扱いが非常に異なります。この問題に関してはまだ合意が得られていませんが、 Latin-1 と UTF-8 のどちらかとみなすのは、たとえ現在の実装が Latin-1 びいきのように思えたとしても賢明とはいえません。これはソースコード文字セットと実行時の文字セットのどちらにも該当します。

行構造

Python プログラムは多数の 論理行 (logical lines) に分割されます。

論理行 (logical line)

論理行の終端は、トークン NEWLINE で表されます。構文上許されている場合 (複合文: compound statement 中の実行文: statement) を除いて、実行文は論理行間にまたがることはできません。論理行は一行またはそれ以上の 物理行(physical line) からなり、物理行の末尾には明示的または非明示的な 行連結(line joining) 規則が続きます。

物理行 (physical line)

物理行とは、行終端コードで区切られた文字列のことです。ソースコード内では、各プラットフォームごとの標準の行終端コードを使用することができます。 Unix形式ではASCII LF (行送り: linefeed)文字、 Windows形式ではASCII 配列の CR LF (復帰: return に続いて行送り) 、 Macintosh形式ではASCII CR (復帰) 文字です。これら全ての形式のコードは、違うプラットフォームでも等しく使用することができます。

Pythonに埋め込む場合には、標準のC言語の改行文字の変換規則 (ASCII LFを表現した文字コード \n が行終端となります) に従って、 Python APIにソースコードを渡す必要があります。

コメント

コメントは文字列リテラル内に入っていないハッシュ文字 (#) から始まり、同じ物理行の末端で終わります。非明示的な行継続規則が適用されていない限り、コメントは論理行を終端させます。コメントは構文上無視されます; コメントはトークンになりません。

エンコード宣言 (encoding declaration)

Python スクリプト中の最初の行か、二行目にあるコメントが正規表現 coding[=:]\s*([-\w.]+) にマッチする場合、コメントはエンコード宣言 (encoding declaration) として処理されます; 表現に対する最初のマッチグループがソースコードファイルのエンコードを指定します。エンコード宣言式として推奨する形式は、GNU Emacs が認識できる形式

# -*- coding: <encoding-name> -*-

または、Bram Moolenar による VIM が認識できる形式

# vim:fileencoding=<encoding-name>

です。さらに、ファイルの先頭のバイト列が UTF-8 バイトオーダ記号 ('\xef\xbb\xbf') の場合、ファイルのエンコードは UTF-8 と宣言されているものとします (この機能は Microsoft の notepad やその他のエディタでサポートされています)。

エンコードが宣言されている場合、Python はそのエンコード名を認識できなければなりません。宣言されたエンコードは全ての字句解析、特に文字列の終端を検出する際や Unicode リテラルの内容を翻訳する上で用いられます。文字列リテラルは文法的な解析を行うために Unicode に変換され、解釈が行われる前に元のエンコードに戻されます。エンコード宣言は宣言全体が一行に収まっていなければなりません。

明示的な行継続

二つまたはそれ以上の物理行を論理行としてつなげるためには、バックスラッシュ文字 (\) を使って以下のようにします: 物理行が文字列リテラルやコメント中の文字でないバックスラッシュで終わっている場合、後続する行とつなげて一つの論理行を構成し、バックスラッシュおよびバックスラッシュの後ろにある行末文字を削除します。例えば:

if 1900 < year < 2100 and 1 <= month <= 12 \
   and 1 <= day <= 31 and 0 <= hour < 24 \
   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
        return 1

となります。

バックスラッシュで終わる行にはコメントを入れることはできません。また、バックスラッシュを使ってコメントを継続することはできません。バックスラッシュが文字列リテラル中にある場合を除き、バックスラッシュの後ろにトークンを継続することはできません (すなわち、物理行内の文字列リテラル以外のトークンをバックスラッシュを使って分断することはできません)。上記以外の場所では、文字列リテラル外にあるバックスラッシュはどこにあっても不正となります。

非明示的な行継続

丸括弧 (parentheses)、角括弧 (square bracket) 、および波括弧 (curly brace) 内の式は、バックスラッシュを使わずに一行以上の物理行に分割することができます。例えば:

month_names = ['Januari', 'Februari', 'Maart',      # These are the
               'April',   'Mei',      'Juni',       # Dutch names
               'Juli',    'Augustus', 'September',  # for the months
               'Oktober', 'November', 'December']   # of the year

非明示的に継続された行にはコメントを含めることができます。継続行のインデントは重要ではありません。空の継続行を書くことができます。非明示的な継続行中には、NEWLINE トークンは存在しません。非明示的な行の継続は、三重クオートされた文字列 (下記参照) でも発生します; この場合には、コメントを含めることができません。

空行

スペース、タブ、フォームフィード、およびコメントのみを含む論理行は無視されます (すなわち、NEWLINE トークンは生成されません)。文を対話的に入力している際には、空行の扱いは行読み込み-評価-出力 (read-eval-print) ループの実装によって異なるかもしれません。標準的な実装では、完全な空行でできた論理行 (すなわち、空白文字もコメントも全く含まない空行) は、複数行からなる実行文の終端を示します。

インデント

論理行の行頭にある、先頭の空白 (スペースおよびタブ) の連なりは、その行のインデントレベルを計算するために使われます。インデントレベルは、実行文のグループ化方法を決定するために用いられます。

まず、タブは (左から右の方向に) 1 つから 8 つのスペースで置き換えられ、置き換え後の文字列の終わりの位置までの文字数が 8 の倍数になるように調整されます (Unixで使われている規則と同じになるよう意図されています)。次に、空白文字でない最初の文字までのスペースの総数から、その行のインデントを決定します。バックスラッシュを使ってインデントを複数の物理行に分割することはできません; 最初のバックスラッシュまでの空白がインデントを決定します。

プラットフォーム間の互換性に関する注意: 非 UNIX プラットフォームにおけるテキストエディタの性質上、一つのソースファイル内でタブとインデントを混在させて使うのは賢明ではありません。また、プラットフォームによっては、最大インデントレベルを明示的に制限しているかもしれません。

フォームフィード文字が行の先頭にあっても構いません; フォームフィード文字は上のインデントレベル計算時には無視されます。フォームフィード文字が先頭の空白中の他の場所にある場合、その影響は未定義です (例えば、スペースの数を 0 にリセットするかもしれません)。

連続する行における各々のインデントレベルは、 INDENT および DEDENT トークンを生成するために使われます。トークンの生成はスタックを用いて以下のように行われます。

ファイル中の最初の行を読み出す前に、スタックにゼロが一つ積まれ (push され) ます; このゼロは決して除去 (pop) されることはありません。スタックの先頭に積まれてゆく数字は、常にスタックの末尾から先頭にかけて厳密に増加するようになっています。各論理行の開始位置において、その行のインデントレベル値がスタックの先頭の値と比較されます。値が等しければ何もしません。インデントレベル値がスタック上の値よりも大きければ、インデントレベル値はスタックに積まれ、INDENT トークンが一つ生成されます。インデントレベル値がスタック上の値よりも小さい場合、その値はスタック内のいずれかの値と 等しくなければなりません ; スタック上のインデントレベル値よりも大きい値はすべて除去され、値が一つ除去されるごとに DEDENT トークンが一つ生成されます。ファイルの末尾では、スタックに残っているゼロより大きい値は全て除去され、値が一つ除去されるごとに DEDENT トークンが一つ生成されます。

以下の例に正しく (しかし当惑させるように) インデントされた Python コードの一部を示します:

def perm(l):
        # Compute the list of all permutations of l
    if len(l) <= 1:
                  return [l]
    r = []
    for i in range(len(l)):
             s = l[:i] + l[i+1:]
             p = perm(s)
             for x in p:
              r.append(l[i:i+1] + x)
    return r

以下の例は、様々なインデントエラーになります:

 def perm(l):                       # error: first line indented
for i in range(len(l)):             # error: not indented
    s = l[:i] + l[i+1:]
        p = perm(l[:i] + l[i+1:])   # error: unexpected indent
        for x in p:
                r.append(l[i:i+1] + x)
            return r                # error: inconsistent dedent

(実際は、最初の 3 つのエラーはパーザによって検出されます; 最後のエラーのみが字句解析器で見つかります — return r のインデントは、スタックから逐次除去されていくどのインデントレベル値とも一致しません)

トークン間の空白

論理行の先頭や文字列の内部にある場合を除き、空白文字であるスペース、タブ、およびフォームフィードは、トークンを分割するために自由に利用することができます。二つのトークンを並べて書くと別のトークンとしてみなされてしまうような場合には、トークンの間に空白が必要となります (例えば、ab は一つのトークンですが、 a b は二つのトークンとなります)。

その他のトークン

NEWLINE、INDENT、および DEDENT の他、以下のトークンのカテゴリ: 識別子 (identifier), キーワード(keyword), リテラル, 演算子 (operator), デリミタ (delimiter) が存在します。空白文字 (上で述べた行終端文字以外) はトークンではありませんが、トークンを区切る働きがあります。トークンの解析にあいまいさが生じた場合、トークンは左から右に読んで不正でないトークンを構築できる最長の文字列を含むように構築されます。

識別子 (identifier) およびキーワード (keyword)

識別子 (または 名前 (name)) は、以下の字句定義で記述されます:

identifier ::=  (letter|"_") (letter | digit | "_")*
letter     ::=  lowercase | uppercase
lowercase  ::=  "a"..."z"
uppercase  ::=  "A"..."Z"
digit      ::=  "0"..."9"

識別子の長さには制限がありません。大小文字は区別されます。

キーワード (keyword)

以下の識別子は、予約語、または Python 言語における キーワード (keyword) として使われ、通常の識別子として使うことはできません。キーワードは厳密に下記の通りに綴らなければなりません:

and       del       from      not       while
as        elif      global    or        with
assert    else      if        pass      yield
break     except    import    print
class     exec      in        raise
continue  finally   is        return
def       for       lambda    try

バージョン 2.4 で変更: このバージョンから None は定数になり、組み込みオブジェクト None の名前としてコンパイラに認識されるようになりました。これは予約語ではありませんが、これに他のオブジェクトを割り当てることはできません。

バージョン 2.5 で変更: with_statement 機能をfuture文によって有効にしたときにのみ、キーワード as と with は認識されます。この機能はPython 2.6で正式に有効になる予定です。詳しくは、 with 文 節を参照してください。 as と with を識別子として使用した場合は、たとえfuture文で with_statement が有効になっていなかったとしても常にワーニングが表示されます。

予約済みの識別子種 (reserved classes of identifiers)

ある種の (キーワードを除く) 識別子には、特殊な意味があります。これらの識別子種は、先頭や末尾にあるアンダースコア文字のパターンで区別されます:

_*

この識別子は from module import * で import されません。対話インタプリタでは、最も最近行われた値評価の結果を記憶するために特殊な識別子 _ が使われます; この識別子は __builtin__ モジュール内に記憶されます。対話モードでない場合、 _ には特殊な意味はなく、定義されていません。 import 文 を参照してください。

ノート

名前 _ は、しばしば国際化 (internationalization) と共に用いられます; この慣習についての詳しい情報は、 gettext 参照してください。

__*__

システムで定義された (system-defined) 名前です。これらの名前はインタプリタと (標準ライブラリを含む) 実装上で定義されています; 現行のシステムでの名前は 特殊メソッド名 などで話題に挙げられています。 Python の将来のバージョンではより多くの名前が定義されることになります。あらゆる __*__ の名前の利用は、文脈に関わらず、明示的に記録されまないので、警告無く損害に合う危険に晒すことになります。

__*

クラスプライベート (class-private) な名前です。このカテゴリに属する名前は、クラス定義のコンテキスト上で用いられた場合、基底クラスと派生クラスの “プライベートな” 属性間で名前衝突が起こるのを防ぐために書き直されます。 識別子 (identifier、または名前 (name)) を参照してください。

リテラル (literal)

リテラル (literal) とは、いくつかの組み込み型の定数を表記したものです。

文字列リテラル

文字列リテラルは以下の字句定義で記述されます:

stringliteral   ::=  [stringprefix](shortstring | longstring)
stringprefix    ::=  "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"
                     | "b" | "B" | "br" | "Br" | "bR" | "BR"
shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''"
                     | '"""' longstringitem* '"""'
shortstringitem ::=  shortstringchar | escapeseq
longstringitem  ::=  longstringchar | escapeseq
shortstringchar ::=  <any source character except "\" or newline or the quote>
longstringchar  ::=  <any source character except "\">
escapeseq       ::=  "\" <any ASCII character>

上記の生成規則で示されていない文法的な制限が一つあります。それは文字列リテラルの stringprefix と残りの部分の間に空白を入れてはならないということです。ソースコード文字セット (source character set) はエンコード宣言で決まります．エンコード宣言がない場合には ASCII になります． エンコード宣言 (encoding declaration) 節を参照してください．

より平易な説明: 文字列リテラルは、対応する一重引用符 (') または二重引用符 (") で囲われます。また、対応する三連の一重引用符や二重引用符で囲うこともできます (通常、 三重クオート文字列: triple-quoted string として参照されます)。バックスラッシュ (\) 文字を使って、ある文字を例えば改行文字やバックスラッシュ自体、クオート文字といった別の意味を持つようにエスケープすることができます。文字列リテラルの前には、オプションとして 'r' または 'R' 一文字を接頭してもかまいません; このような文字列は raw 文字列 (raw string) と呼ばれ、バックスラッシュによるエスケープシーケンスの解釈規則が異なります。 'u' や 'U' を接頭すると、文字列は Unicode 文字列 (Unicode string) になります。Unicode 文字列は Unicode コンソーシアムおよび ISO 10646 で定義されている Unicode 文字セットを使います。Unicode 文字列では、文字セットに加えて、以下で説明するようなエスケープシーケンスを利用できます。 'b' または 'B' の接頭辞は Python 2 では無視されます。これは、(例えば、コードが 2to3 で自動的に変換されるときなどに) Python 3 でバイト列リテラルとなるべきであることを示します。 'u' または 'b' 接頭辞のあとに 'r' 接頭辞を続けることもできます。

三重クオート文字列中には、三連のエスケープされないクオート文字で文字列を終端してしまわないかぎり、エスケープされていない改行やクオートを書くことができます (さらに、それらはそのまま文字列中に残ります)。 (ここでいう “クオート” とは、文字列の囲みを開始するときに使った文字を示し、 ' か " のいずれかです)。

'r' または 'R' 接頭文字がつかないかぎり、文字列中のエスケープシーケンスは標準 C で使われているのと同様の法則にしたがって解釈されます。以下に Python で認識されるエスケープシーケンスを示します:

エスケープシーケンス | 意味 | 備考
\newline | 無視 |
\\ | バックスラッシュ (\) |
\' | 一重引用符 (') |
\" | 二重引用符 (") |
\a | ASCII 端末ベル (BEL) |
\b | ASCII バックスペース (BS) |
\f | ASCII フォームフィード (FF) |
\n | ASCII 行送り (LF) |
\N{name} | Unicode データベース中で名前 name を持つ文字 (Unicode のみ) |
\r | ASCII 復帰 (CR) |
\t | ASCII 水平タブ (TAB) |
\uxxxx | 16-bit の 16 進数値 xxxx を持つ文字 (Unicode のみ) | (1)
\Uxxxxxxxx | 32-bit の 16 進数値 xxxxxxxx を持つ文字 (Unicode のみ) | (2)
\v | ASCII 水平タブ (VT) |
\ooo | 8 進数値 ooo を持つ文字 | (3,5)
\xhh | 16 進数値 hh を持つ文字 | (4,5)

備考:

サロゲートペアの断片を形成する個々のコード単位は、このエスケープシーケンスでエンコードすることができます。

Unicode 文字はすべてこの方法でエンコードできますが、 Python が 16-bit コード単位を扱うようにコンパイルされている (デフォルトの設定です) 場合、基本多言語面 (Basic Multilingual Plane, BMP) 外の文字はサロゲートペア (surrogate pair) を使ってエンコードすることになります。サロゲートペアの断片を形成する個々のコード単位はこのエスケープシーケンスを使ってエンコードすることができます。

標準 C と同じく、最大で 3 桁の 8 進数まで受理します。

標準 C とは違い、ちょうど 2 桁の 16 進数しか受理されません。

文字列リテラル中では， 16 進および 8 進エスケープはエスケープの示すバイト文字になります．そのバイト文字がソース文字セットでエンコードされている保証はありません．Unicode リテラル中では，エスケープ文字はエスケープ文字の表現する値を持つ Unicode 文字になります．

標準の C とは違い、認識されなかったエスケープシーケンスはそのまま文字列中に残されます。すなわち。 バックスラッシュも文字列中に残ります。 (この挙動はデバッグの際に便利です: エスケープシーケンスを誤入力した場合、その結果として出力に失敗しているのが用意にわかります) テーブル中で “(Unicode のみ)” と書かれたエスケープシーケンスは、非 Unicode 文字列リテラル中では認識されないエスケープシーケンスのカテゴリに分類されるので注意してください。

接頭文字 'r' または 'R' がある場合、バックスラッシュの後にくる文字はそのまま文字列中に入り、 バックスラッシュは全て文字列中に残されます 。例えば、文字列リテラル r"\n" は二つの文字: バックスラッシュと小文字の 'n' からなる文字列を表すことになります。引用符はバックスラッシュでエスケープすることができますが、バックスラッシュ自体も残ってしまいます; 例えば、 r"\"" は不正でない文字列リテラルで、バックスラッシュと二重引用符からなる文字列を表します; r"\" は正しくない文字列リテラルです (raw 文字列を奇数個連なったバックスラッシュで終わらせることはできません)。厳密にいえば、 (バックスラッシュが直後のクオート文字をエスケープしてしまうため) raw文字列を単一のバックスラッシュで終わらせることはできないということになります。また、バックスラッシュの直後に改行がきても、行継続を意味する のではなく、それら二つの文字として解釈されるので注意してください。

'r' および 'R' 接頭文字を 'u' や 'U' と合わせて使った場合、 \uXXXX および \UXXXXXXXX エスケープシーケンスは処理されますが、 その他のバックスラッシュはすべて文字列中に残されます 。例えば、文字列リテラル ur"\u0062\n" は、3つの Unicode 文字: ‘LATIN SMALL LETTER B’ (ラテン小文字 B)、’REVERSE SOLIDUS’ (逆向き斜線)、および ‘LATIN SMALL LETTER N’ (ラテン小文字 N) を表します。バックスラッシュの前にバックスラッシュをつけてエスケープすることはできます; しかし、バックスラッシュは両方とも文字列中に残されます。その結果、 \uXXXX エスケープシーケンスは、バックスラッシュが奇数個連なっている場合にのみ認識されます。

文字列リテラルの結合 (concatenation)

複数の文字列リテラルは、互いに異なる引用符を使っていても (空白文字で区切って) 隣接させることができ、その意味は各々の文字列を結合したものと同じになります。したがって、 "hello" 'world' は "helloworld" と同じになります。この機能を使うと、長い文字列を分離して、複数行にまたがらせる際に便利です。また、部分文字列ごとにコメントを追加することもできます。例えば:

re.compile("[A-Za-z_]"       # letter or underscore
           "[A-Za-z0-9_]*"   # letter, digit or underscore
          )

この機能は文法レベルで定義されていますが、スクリプトをコンパイルする際の処理として実現されることに注意してください。実行時に文字列表現を結合したければ、 ‘+’ 演算子を使わなければなりません。また、リテラルの結合においては、結合する各要素に異なる引用符形式を使える (raw 文字列と三重引用符を混ぜることさえできます) ので注意してください。

数値リテラル

数値リテラルは 4 種類あります: 整数 (plain integer)、長整数 (long integer)、浮動小数点数 (floating point number)、そして虚数 (imaginary number) です。複素数のためのリテラルはありません (複素数は実数と虚数の和で作ることができます)。

数値リテラルには符号が含まれていないことに注意してください; -1 のような句は、実際には単項演算子 (unary operator) ‘-‘ とリテラル 1 を組み合わせたものです。

整数および長整数リテラル

整数および長整数リテラルは以下の字句定義で記述されます:

longinteger    ::=  integer ("l" | "L")
integer        ::=  decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::=  nonzerodigit digit* | "0"
octinteger     ::=  "0" ("o" | "O") octdigit+ | "0" octdigit+
hexinteger     ::=  "0" ("x" | "X") hexdigit+
bininteger     ::=  "0" ("b" | "B") bindigit+
nonzerodigit   ::=  "1"..."9"
octdigit       ::=  "0"..."7"
bindigit       ::=  "0" | "1"
hexdigit       ::=  digit | "a"..."f" | "A"..."F"

長整数を表す末尾の文字は小文字の 'l' でも大文字の 'L' でもかまいませんが、 'l' は '1' に良く似ているので、常に 'L' を使うよう強く勧めます。

整数で表現できる最大の値よりも大きい整数のリテラル (例えば 32-bit 整数を使っている場合には 2147483647) は、長整数として表現できる値であれば受理されます。 [1] 値がメモリ上に収まるかどうかという問題を除けば、長整数リテラルには値域の制限がありません。

整数リテラル (最初の行) と長整数リテラル (二行目および三行目) の例を以下に示します:

7     2147483647                        0177
3L    79228162514264337593543950336L    0377L   0x100000000L
      79228162514264337593543950336             0xdeadbeef

浮動小数点数リテラル

浮動小数点数リテラルは以下の字句定義で記述されます:

floatnumber   ::=  pointfloat | exponentfloat
pointfloat    ::=  [intpart] fraction | intpart "."
exponentfloat ::=  (intpart | pointfloat) exponent
intpart       ::=  digit+
fraction      ::=  "." digit+
exponent      ::=  ("e" | "E") ["+" | "-"] digit+

浮動小数点数における整数部と指数部は 8 進数のように見えることもありますが、10 を基数として解釈されるので注意してください。例えば、 077e010 は正しい表記であり、 77e10 と同じ数を表します。浮動小数点数リテラルの取りうる値の範囲は実装に依存します。浮動小数点数リテラルの例をいくつか示します:

3.14    10.    .001    1e100    3.14e-10    0e0

数値リテラルには符号が含まれていないことに注意してください; -1 のような句は、実際には単項演算子 (unary operator) ‘-‘ とリテラル 1 を組み合わせたものです。

虚数 (imaginary) リテラル

虚数リテラルは以下のような字句定義で記述されます:

imagnumber ::=  (floatnumber | intpart) ("j" | "J")

虚数リテラルは、実数部が 0.0 の複素数を表します。複素数は二つ組の浮動小数点型の数値で表され、それぞれの数値は浮動小数点型と同じ定義域の範囲を持ちます。実数部がゼロでない浮動小数点を生成するには、 (3+4j) のように虚数リテラルに浮動小数点数を加算します。以下に虚数リテラルの例をいくつか示します:

3.14j   10.j    10j     .001j   1e100j  3.14e-10j

演算子 (operator)

以下のトークンは演算子です:

+       -       *       **      /       //      %
<<      >>      &       |       ^       ~
<       >       <=      >=      ==      !=      <>

比較演算子 <> と != は、同じ演算子について別の書き方をしたものです。書き方としては != を推奨します; <> は時代遅れの書き方です。

デリミタ (delimiter)

以下のトークンは文法上のデリミタとして働きます:

(       )       [       ]       {       }      @
,       :       .       `       =       ;
+=      -=      *=      /=      //=     %=
&=      |=      ^=      >>=     <<=     **=

浮動小数点数や虚数リテラル中にピリオドがあってもかまいません。ピリオド三つの列はスライス表記における省略符号 (ellipsis) として特別な意味を持っています。リスト後半の累算代入演算子 (augmented assignment operator) は、字句的にはデリミタとして振舞いますが、演算も行います。

以下の印字可能 ASCII 文字は、他のトークンの一部として特殊な意味を持っていたり、字句解析器にとって重要な意味を持っています:

'       "       #       \

以下の印字可能 ASCII 文字は、Python では使われていません。これらの文字が文字列リテラルやコメントの外にある場合、無条件にエラーとなります:

$       ?

注記

[1]
バージョン 2.4 以前の Python では， 8 進および 16 進のリテラルのうち，通常の整数型として表現可能な値より大きく，かつ符号無しの 32-bit (32-bit 演算を使う計算機の場合) 整数で表現できる最大値，すなわち 4294967296 よりも小さな数は，リテラルを符号無し整数として表現した値から 4294967296 を引いて得られる負の整数として扱っていました．

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

データモデル

オブジェクト、値、および型

Python における オブジェクト (object) とは、データを抽象的に表したものです。Python プログラムにおけるデータは全て、オブジェクトまたはオブジェクト間の関係として表されます。(ある意味では、プログラムコードもまたオブジェクトとして表されます。これはフォン・ノイマン: Von Neumann の “プログラム記憶方式コンピュータ: stored program computer” のモデルに適合します。)

オブジェクトはアイデンティティ値 (identity) 、型 (type) 、そして値 (value) を持ちます。オブジェクトが一度生成されると、そのオブジェクトの アイデンティティ値 は決して変化することがありません; アイデンティティ値をオブジェクトのメモリ上のアドレスと考えてもかまいません。演算子 ‘is‘ は、二つのオブジェクト間のアイデンティティ値を比較します; 関数 id() は、オブジェクトのアイデンティティ値を表す整数 (現在の実装ではオブジェクトのメモリ上のアドレス) を返します。オブジェクトの 型 もまた変わることがありません。 [1] オブジェクトの型は、そのオブジェクトのサポートする操作 (“長さを持っているか？” など) を決定し、その型のオブジェクトが取りうる値について定義しています。 type() 関数は、オブジェクトの型 (型自体も一つのオブジェクトです) を返します。オブジェクトによっては、 値 (value) を変えることができます。値を変えることができるオブジェクトは変更可能 (mutable) であるといいます; 値を一度設定すると、その後は変えることができないオブジェクトは 変更不能 (immutable) であると呼びます。 (変更不能なコンテナオブジェクトが変更可能なオブジェクトへの参照を含んでいる場合、その値は後者のオブジェクトの変更によって変わる場合があります; その場合でも、コンテナの含んでいるオブジェクトの集まりは変わらないため、コンテナは変更不能と考えます。したがって、変更不能性 (immutability) は、厳密には変更できない値を持っていることとは違い、もっと微妙な概念です。) オブジェクトの変更可能性は型で決定されます; 例えば、数値、文字列、およびタプルは変更不能であり、辞書やリストは変更可能です。

オブジェクトを明示的に破壊することはできません; しかし、オブジェクトに到達不能 (unreachable) になると、ガベージコレクション (garbage-collection) によって処理されます。実装では、ごみ収集を遅らせたり、全く行わないようにすることができます — 到達可能なオブジェクトをごみ収集処理してしまわないかぎり、どう実装するかは実装品質の問題です。

CPython implementation detail: 現在の CPython 実装では参照カウント(reference-counting) 方式を使っており、(オプションとして) 循環参照を行っているごみオブジェクトを遅延検出します。この実装ではほとんどのオブジェクトを到達不能になると同時に処理することができますが、循環参照を含むごみオブジェクトの収集が確実に行われるよう保証しているわけではありません。循環参照を持つごみオブジェクト収集の制御については、 gc モジュールを参照してください。 CPython以外の実装は別の方式を使っており、CPythonも将来は別の方式を使うかもしれません。オブジェクトが到達不能になったときに即座に終了処理されることに頼らないでください (例えば、ファイルは必ず閉じてください)。

実装のトレース機能やデバッグ機能を使えば、通常は収集されてしまうようなオブジェクトを生かしておくことがあるので注意してください。また、 ‘try...except‘ 文を使って例外を捕捉できるようにすると、オブジェクトを生かしておくことがあります。

オブジェクトによっては、開かれたファイルやウィンドウといった、 “外部 (external) の” リソースに対する参照を行っています。これらのリソースは、オブジェクトがごみ収集された際に解放されるものと理解されていますが、ごみ収集が行われる保証はないので、こうしたオブジェクトでは外部リソースを明示的に解放する方法、大抵は close() メソッドを提供しています。こうしたオブジェクトは明示的に close するよう強く奨めます。操作をする際には、’try...finally‘ 文を使うと便利です。

他のオブジェクトに対する参照をもつオブジェクトもあります; これらは コンテナ (container) と呼ばれます。コンテナオブジェクトの例として、タプル、リスト、および辞書が挙げられます。オブジェクトへの参照自体がコンテナの値の一部です。ほとんどの場合、コンテナの値というと、コンテナに入っているオブジェクトの値のことを指し、それらオブジェクトのアイデンティティではありません; しかしながら、コンテナの変更可能性について述べる場合、今まさにコンテナに入っているオブジェクトのアイデンティティのことを指します。したがって、 (タプルのように) 変更不能なオブジェクトが変更可能なオブジェクトへの参照を含む場合、その値が変化するのは変更可能なオブジェクトが変更された時、ということになります。

型はオブジェクトの動作のほとんど全てに影響します。オブジェクトのアイデンティティが重要かどうかでさえ、ある意味では型に左右されます: 変更不能な型では、新たな値を計算するような操作を行うと、実際には同じ型と値を持った既存のオブジェクトへの参照を返すことがありますが、変更可能なオブジェクトではそのような動作は起こりえません。例えば、 a = 1; b = 1 とすると、 a と b は値 1 を持つ同じオブジェクトを参照するときもあるし、そうでないときもあります。これは実装に依存します。しかし、 c = []; d = [] とすると、 c と d はそれぞれ二つの異なった、互いに一意な、新たに作成された空のリストを参照することが保証されています。 (c = d = [] とすると、 c と d の両方に同じオブジェクトを代入します)

標準型の階層

以下は Python に組み込まれている型のリストです。(C、Java、または実装に使われているその他の言語で書かれた) 拡張モジュールでは、その他に新たな型を定義することができます。将来のバージョンの Python では、型の階層に新たな型 (整数を使って効率的に記憶される有理数型、など) を追加することができるかもしれません。

以下に説明する型のいくつかには、’特殊属性 (special attribute)’ と題された段落が連ねられています。これらの属性は実装へのアクセス手段を提供するもので、一般的な用途に利用するためのものではありません。特殊属性の定義は将来変更される可能性があります。

None

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 None でアクセスされます。このオブジェクトは、様々な状況で値が存在しないことをしめします。例えば、明示的に値を返さない関数は None を返します。 None の真値 (truth value) は 偽 (false) です。

NotImplemented

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 NotImplemented でアクセスされます。数値演算に関するメソッドや拡張比較 (rich comparison) メソッドは、被演算子が該当する演算を行うための実装をもたない場合、この値を返すことがあります。(演算子によっては、インタプリタが関連のある演算を試したり、他の代替操作を行います。) 真値は真 (true) です。

Ellipsis

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 Ellipsis でアクセスされます。スライス内に ... 構文がある場合に使われます。真値は真 (true)です。

numbers.Number

数値リテラルによって作成されたり、算術演算や組み込みの算術関数によって返されるオブジェクトです。数値オブジェクトは変更不能です; 一度値が生成されると、二度と変更されることはありません。Python の数値オブジェクトはいうまでもなく数学で言うところの数値と強く関係していますが、コンピュータ内で数値を表現する際に伴う制限を受けています。

Python は整数、浮動小数点数、複素数の間で区別を行っています:

numbers.Integral (整数)

整数型は、整数(正の数および負の数)を表す数学的集合内における要素を表現する型です。

以下に三つの整数型を示します:

(通常の) 整数型 (plain integer)

-2147483648 から 2147483647 までの整数を表現します (基本ワードサイズ: natural word size がより大きなマシンではより大きな定義域になることもあります。より小さくなることはありません。) 演算の結果が定義域を超えた値になった場合、結果は通常長整数で返されます (場合によっては、 OverflowError が送出されます) 。シフト演算やマスク演算のために、整数は 32 ビット以上の 2 の補数で表されたバイナリ表現を持つ (すなわち、4294967296 の異なったビットパターン全てが異なる値を持つ) と仮定されています。

長整数型 (long integer)

長整数は無限の定義域を持ち、利用可能な (仮想) メモリサイズの制限のみをうけます。長整数はシフト演算やマスク演算のためにバイナリ表現をもつものと仮定されます。負の数は符号ビットが左に無限に延びているような錯覚を与える 2 の補数表現の変型で表されます。

ブール型 (boolean)

ブール型は、真値 False または True を表現します。ブール型のオブジェクトは False と True を表現する二つのオブジェクトだけです。ブール型は整数のサブタイプで、ほとんどの演算コンテキストにおいてブール型値はそれぞれ 0 または 1 のように振舞います。ただし、文字列に変換されたときのみ、それぞれ文字列 "False" および "True" が返されます。

整数表現に関する規則は、シフト演算やマスク演算において、負の整数も含めて最も有意義な解釈ができるように、かつ通常の整数と長整数との間で定義域を切り替える際にできるだけ混乱しないように決められています。すべての演算で、演算結果がオーバフローを起こさずに整数の定義域の値になる場合は、長整数を使った場合でも、被演算子に整数と長整数を混合した場合でも同じ結果になります。定義域の切り替えはプログラマに対して透過的に(意識させることなく)行われます。

numbers.Real (float) (実数)

この型は計算機レベルで倍精度とされている浮動小数点数を表現します。表現可能な値の範囲やオーバフローの扱いは、根底にある計算機アーキテクチャ (と C または Java 実装) 次第です。 Python は単精度の浮動小数点数をサポートしません; 単精度の数を使う理由は、通常プロセッサやメモリ使用量の節約ですが、こうした節約は Python でオブジェクトを扱う際のオーバヘッドに比べれば微々たるものにすぎません。従って、わざわざ浮動小数点型を 2 つも定義してPython 言語を難解にする理由はどこにもないのです。

numbers.Complex (複素数)

この型は、計算機レベルで倍精度とされている浮動小数点を 2 つ一組にして複素数を表現します。浮動小数点について述べたのと同じ性質が当てはまります。複素数 z の実数部および虚数部は、それぞれ読み出し専用属性 z.real および z.imag で取り出すことができます。

シーケンス型 (sequence)

この型は、有限の順序集合 (ordered set) を表現します。要素は非負の整数でインデクス化されています。組み込み関数 len() を使うと、シーケンスの要素数を返します。シーケンスの長さが n の場合、インデクスは 0, 1, ..., n -1 からなる集合です。シーケンス a の要素 i は a[i] で選択します。

シーケンスはスライス操作 (slice) もサポートしています: a[i:j] とすると、 i <= k < j であるインデクス k をもつ全ての要素を選択します。式表現としてスライスを用いた場合、スライスは同じ型をもつ新たなシーケンスを表します。新たなシーケンス内では、インデクス集合が 0 から始まるようにインデクスの値を振りなおします。

シーケンスによっては、第三の “ステップ (step)” パラメタを持つ “拡張スライス (extended slice)” もサポートしています: a[i:j:k] は、 x = i + n*k, n >= 0 かつ i <= x < j であるようなインデクス x を持つような a 全ての要素を選択します。

シーケンスは、変更可能なものか、そうでないかで区別されています:

変更不能なシーケンス (immutable sequence)

変更不能なシーケンス型のオブジェクトは、一度生成されるとその値を変更することができません。 (オブジェクトに他のオブジェクトへの参照が入っている場合、参照されているオブジェクトは変更可能なオブジェクトでもよく、その値は変更される可能性があります; しかし、変更不能なオブジェクトが直接参照しているオブジェクトの集合自体は、変更することができません。)

以下の型は変更不能なシーケンス型です:

文字列型 (string)

文字列の各要素は文字 (character) です。文字型 (character type) は存在しません; 単一の文字は、要素が一つだけの文字列として表現されます。各文字は (少なくとも) 8-bit のバイト列を表現します。組み込み関数 chr() および ord() を使うと、文字と非負の整数で表されたバイト値の間で変換を行えます。0-127 の値を持つバイト値は、通常 同じ ASCII 値をもつ文字を表現していますが、値をどう解釈するかはプログラムにゆだねられています。文字列データ型はまた、例えばファイルから読み出されたデータを記憶するといった用途で、バイト値のアレイを表現するために用いられます。

(ネイティブの文字セットが ASCIIでないシステムでは、 chr() や ord() が ASCII と EBCDIC との間で対応付けを行っており、文字列間の比較で ASCII 順が守られる限り、文字列の内部表現として EBCDIC を使ってもかまいません。誰か他にもっとましなルールをお持ちですか?)

Unicode 文字列型

Unicode オブジェクトの各要素は Unicode コード単位です。 Unicode コード単位とは、単一の Unicode オブジェクトで、Unicode 序数を表現する 16-bit または 32-bit の値を保持できるものです (この序数の最大値は sys.maxunicode で与えられており、コンパイル時に Python がどう設定されているかに依存します)。 Unicode オブジェクト内にサロゲートペア (surrogate pair) があってもよく、Python はサロゲートペアを二つの別々の Unicode 要素として報告します。組み込み関数 unichr() および ord() は、コード単位と非負の整数で表された Unicode 標準 3.0 で定義された Unicode 序数との間で変換を行います。他の文字エンコード形式との相互変換は、 Unicode メソッド encode() および組み込み関数 unicode() で行うことができます。

タプル型 (tuple)

タプルの要素は任意の Python オブジェクトにできます。二つまたはそれ以上の要素からなるタプルは、個々の要素を表現する式をカンマで区切って構成します。単一の要素からなるタプル (単集合 ‘singleton’) を作るには、要素を表現する式の直後にカンマをつけます (単一の式だけではタプルを形成しません。これは、式をグループ化するのに丸括弧を使えるようにしなければならないからです) 。要素の全くない丸括弧の対を作ると空のタプルになります。

変更可能なシーケンス型 (mutable sequence)

変更可能なシーケンスは、作成した後で変更することができます。変更可能なシーケンスでは、添字表記やスライス表記を使って指定された要素に代入を行うことができ、 del (delete) 文を使って要素を削除することができます。

Python に最初から組み込まれている変更可能なシーケンス型は、今のところ二つです:

リスト型 (list)

リストの要素は任意の Python オブジェクトにできます。リストは、角括弧の中にカンマで区切られた式を並べて作ります。 (長さが 0 や 1 のシーケンスを作るために特殊な場合分けは必要ないことに注意してください。)

Byte Arrays

bytearray オブジェクトは変更可能な配列です。組み込みの bytearray() コンストラクタによって作成されます。変更可能なことを除けば (つまりハッシュ化できない)、 byte array は変更不能な bytes オブジェクトと同じインターフェースと機能を提供します。

拡張モジュール array では、別の変更可能なシーケンス型を提供しています。

集合型

集合型は、順序のない、ユニークで不変なオブジェクトの有限集合を表現します。そのため、(配列の)添字を使ったインデックスアクセスはできません。ただし、イテレートは可能で、ビルトイン関数 len() は集合の要素数を返します。集合型の一般的な使い方は、集合に属しているかの高速なテスト、シーケンスからの重複の排除、共通集合・和集合・差・対称差といった数学的な演算の計算です。

集合の要素には、辞書のキーと同じ普遍性に関するルールが適用されます。数値型は通常の数値比較のルールに従うことに注意してください。もし2つの数値の比較結果が同値である(例えば、 1 と 1.0)なら、そのうちの1つのみを集合に含めることができます。

現在、2つのビルトイン集合型があります:

Sets

変更可能な集合型です。ビルトインの set() コンストラクタによって作成され、 add() などの幾つかのメソッドを利用して変更されます。

Frozen sets

不変な集合型です。ビルトインの frozenset() コンストラクタによって作成されます。 frozenset は不変でハッシュ可能(hashable)なので、別の集合型の要素になったり、辞書のキーにすることができます。

マップ型 (mapping)

任意のインデクス集合でインデクス化された、有限のオブジェクトからなる集合を表現します。添字表記 a[k] は、 k でインデクス指定された要素を a から選択します; 選択された要素は式の中で使うことができ、代入や del 文の対象にすることができます。組み込み関数 len() は、マップ内の要素数を返します。

Python に最初から組み込まれているマップ型は、今のところ一つだけです:

辞書型 (dictionary)

ほとんどどんな値でもインデクスとして使えるような、有限個のオブジェクトからなる集合を表します。キー値 (key) として使えない値は、リストや辞書を含む値や、アイデンティティではなく値でオブジェクトが比較される、その他の変更可能な型です。これは、辞書型を効率的に実装する上で、キーのハッシュ値が一定であることが必要だからです。数値型をキーに使う場合、キー値は通常の数値比較における規則に従います: 二つの値が等しくなる場合 (例えば 1 と 1.0)、互いに同じ辞書のエントリを表すインデクスとして使うことができます。

辞書は変更可能な型です; 辞書は {...} 表記で生成します (辞書表現 を参照してください)。

拡張モジュール dbm 、 gdbm 、および bsddb では、別のマップ型を提供しています。

呼び出し可能型 (callable type)

関数呼び出し操作 (呼び出し (call) 参照) を行うことができる型です:

ユーザ定義関数 (user-defined function)

ユーザ定義関数オブジェクトは、関数定義を行うことで生成されます (関数定義 参照)。関数は、仮引数 (formal parameter) リストと同じ数の要素が入った引数リストとともに呼び出されます。

特殊属性:

Attribute | Meaning |
func_doc | 関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります。 | 書き込み可能
__doc__ | func_doc の別名です。 | 書き込み可能
func_name | 関数の名前です。 | 書き込み可能
__name__ | func_name の別名です。 | 書き込み可能
__module__ | 関数が定義されているモジュールの名前です。モジュール名がない場合は None になります。 | 書き込み可能
func_defaults | デフォルト値を持つ引数に対するデフォルト値が収められたタプルで、デフォルト値を持つ引数がない場合には None になります。 | 書き込み可能
func_code | コンパイルされた関数本体を表現するコードオブジェクトです。 | 書き込み可能
func_globals | 関数のグローバル変数の入った辞書 (への参照) です — この辞書は、関数が定義されているモジュールのグローバルな名前空間を決定します。 | 読み出し専用
func_dict | 任意の関数属性をサポートするための名前空間が収められています。 | 書き込み可能
func_closure | None または関数の個々の自由変数 (引数以外の変数) に対して値を結び付けているセル (cell) 群からなるタプルになります。 | 読み出し専用

「書き込み可能」とラベルされている属性のほとんどは、代入された値の型をチェックします。

バージョン 2.4 で変更: func_name は書き込み可能になりました.

関数オブジェクトはまた、任意の属性を設定したり取得したりできます。この機能は、例えば関数にメタデータを付与したい場合などに使えます。関数の get や set には、通常のドット表記を使います。 現在の実装では、ユーザ定義の関数でのみ属性をサポートしているので注意して下さい。組み込み関数の属性は将来サポートする予定です。

関数定義に関するその他の情報は、関数のコードオブジェクトから得られます; 後述の内部型 (internal type) に関する説明を参照してください。

ユーザ定義メソッド (user-defined method)

ユーザ定義のメソッドオブジェクトは、クラスやクラスインスタンス (あるいは None) を任意の呼び出し可能オブジェクト (通常はユーザ定義関数) と結合し (combine) ます。

読み出し専用の特殊属性: im_self はクラスインスタンスオブジェクトで、 im_func は関数オブジェクトです; im_class は結合メソッド (bound method) において im_self が属しているクラスか、あるいは非結合メソッド (unbound method) において、要求されたメソッドを定義しているクラスです; __doc__ はメソッドのドキュメンテーション文字列 (im_func.__doc__ と同じ) です; __name__ はメソッドの名前 (im_func.__name__ と同じ) です; __module__ はメソッドが定義されているモジュールの名前になるか、モジュール名がない場合は None になります。

バージョン 2.2 で変更: メソッドを定義しているクラスを参照するために im_self が使われていました.

バージョン 2.6 で変更: 3.0 との前方互換性のために、 im_func の代わりに __func__ も、 im_self の代わりに __self__ も使うことができます。

メソッドもまた、根底にある関数オブジェクトの任意の関数属性に (値の設定はできませんが) アクセスできます。

クラスの属性を (おそらくクラスのインスタンスを介して) 取得する際には、その属性がユーザ定義の関数オブジェクト、非結合 (unbound) のユーザ定義メソッドオブジェクト、あるいはクラスメソッドオブジェクトであれば、ユーザ定義メソッドオブジェクトが生成されることがあります。属性がユーザ定義メソッドオブジェクトの場合、属性を取得する対象のオブジェクトが属するクラスがもとのメソッドオブジェクトが定義されているクラスと同じクラスであるか、またはそのサブクラスであれば、新たなメソッドオブジェクトだけが生成されます。それ以外の場合には、もとのメソッドオブジェクトがそのまま使われます。

クラスからユーザ定義関数オブジェクトを取得する方法でユーザ定義メソッドオブジェクトを生成すると、 im_self 属性は None になり、メソッドオブジェクトは非結合 (unbound) であるといいます。クラスのインスタンスからユーザ定義関数オブジェクトを取得する方法でユーザ定義メソッドオブジェクトを生成すると、 im_self 属性はインスタンスになり、メソッドオブジェクトは結合 (bound) であるといいます。どちらの場合も、新たなメソッドの im_class 属性は、メソッドの取得が行われたクラスになり、 im_func 属性はもとの関数オブジェクトになります。

クラスやインスタンスから他のユーザ定義メソッドオブジェクトを取得する方法でユーザ定義メソッドオブジェクトを生成した場合、その動作は関数オブジェクトの場合と同様ですが、新たなインスタンスの im_func 属性はもとのメソッドオブジェクトの属性ではなく、新たなインスタンスの属性になります。

クラスやインスタンスからクラスメソッドオブジェクトを取得する方法でユーザ定義メソッドオブジェクトを生成した場合、 im_self 属性はクラス自体 (im_class 属性と同じ) となり、 im_func 属性はクラスメソッドの根底にある関数オブジェクトになります。

非結合ユーザ定義メソッドオブジェクトの呼び出しの際には、根底にある関数 (im_func) が呼び出されます。このとき、最初の引数は適切なクラス (im_class) またはサブクラスのインスタンスでなければならないという制限が課されています。

結合ユーザ定義メソッドオブジェクトの呼び出しの際には、根底にある関数 (im_func) が呼び出されます。このとき、クラスインスタンス (im_self) が引数の先頭に挿入されます。例えば、関数 f() の定義が入ったクラスを C とし、 x を C のインスタンスとすると、 x.f(1) の呼び出しは C.f(x, 1) と同じになります。

ユーザ定義メソッドオブジェクトがクラスオブジェクトから派生した際、 im_self に記憶されている “クラスインスタンス” はクラス自体になります。これは、 x.f(1) や C.f(1) の呼び出しが根底にある関数を f としたときの呼び出し f(C,1) と等価になるようにするためです。

関数オブジェクトから (結合または非結合の) メソッドオブジェクトへの変換は、クラスやインスタンスから属性を取り出すたびに行われるので注意してください。場合によっては、属性をローカルな変数に代入しておき、その変数を使って関数呼び出しを行うと効果的な最適化になります。また、上記の変換はユーザ定義関数に対してのみ起こるので注意してください; その他の呼び出し可能オブジェクト (および呼び出し可能でない全てのオブジェクト) は、変換を受けずに取り出されます。それから、クラスインスタンスの属性になっているユーザ定義関数は、結合メソッドに変換できないと知っておくことも重要です; 結合メソッドへの変換が行われるのは、関数がクラスの一属性である場合 だけ です。

ジェネレータ関数 (generator function)

yield 文 (yield 文 参照) を使う関数またはメソッドは、ジェネレータ関数(generator function) と呼ばれます。このような関数は、呼び出された際に、常にイテレータオブジェクトを返します。このイテレータオブジェクトは関数の本体を実行するために用いられます: イテレータの next() メソッドを呼び出すと、 yield 文で値を出力する処理まで関数の実行が行われます。関数が return 文を実行するか、関数を最後まで実行し終えると、 StopIteration 例外が送出され、イテレータが返す値の集合はそこで終わります。

組み込み関数 (built-in function)

組み込み関数オブジェクトはC関数へのラッパです。組み込み関数の例は len() や math.sin() (math は標準の組み込みモジュール) です。引数の数や型は C 関数で決定されています。読み出し専用の特殊属性: __doc__ は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります; __name__ は関数の名前です; __self__ は None に設定されています (組み込みメソッドの節も参照してください); __module__ は、関数が定義されているモジュールの名前です。モジュール名がない場合は None になります。

組み込みメソッド (built-in method)

実際には組み込み関数を別の形で隠蔽したもので、こちらの場合には C 関数に渡される何らかのオブジェクトを非明示的な外部引数として持っています。組み込みメソッドの例は、 alist をリストオブジェクトとしたときの alist.append() です。この場合には、読み出し専用の属性 __self__ は alist で表されるオブジェクトになります。

クラス型 (class type)

クラス型、あるいは “新しいクラス型 (new-style class)” や呼び出し可能オブジェクトです。クラス型オブジェクトは通常、そのクラスの新たなインスタンスを生成する際のファクトリクラスとして振舞いますが、 __new__() をオーバライドして、バリエーションを持たせることもできます。呼び出しの際に使われた引数は __new__() に渡され、さらに典型的な場合では新たなインスタンスを初期化するために __init__() に渡されます。

旧クラス型 (classic class)

(旧) クラスオブジェクトは後で詳しく説明します。クラスオブジェクトが呼び出されると、新たにクラスインスタンス (後述) が生成され、返されます。この操作には、クラスの __init__() メソッドの呼び出し (定義されている場合) が含まれています。呼び出しの際に使われた引数は、すべて __init__() メソッドに渡されます。 __init__() メソッドがない場合、クラスは引数なしで呼び出さなければなりません。

クラスインスタンス (class instance)

クラスインスタンスは後で詳しく説明します。クラスインスタンスはクラスが __call__() メソッドを持っている場合にのみ呼び出すことができます; x(arguments) とすると、 x.__call__(arguments) 呼び出しを短く書けます。

モジュール (module)

モジュールは import 文で import します (import 文 参照)。モジュールオブジェクトは、辞書オブジェクト (モジュール内で定義されている関数が func_globals 属性で参照している辞書です) で実装された名前空間を持っています。属性への参照は、この辞書に対する検索 (lookup) に翻訳されます。例えば、 m.x は m.__dict__["x"] と同じです。モジュールオブジェクトには、モジュールを初期化するために使われるコードオブジェクトは入っていません (一度初期化が終わればもう必要ないからです)。

属性の代入を行うと、モジュールの名前空間辞書の内容を更新します。例えば、 m.x = 1 は m.__dict__["x"] = 1 と同じです。

読み出し専用の特殊属性: __dict__ はモジュールの名前空間で、辞書オブジェクトです。

CPython implementation detail: CPython がモジュール辞書を削除する方法から、モジュール辞書はモジュールがスコープから外れた時、その辞書が生きた参照を持っていてさえ、削除されます。これを避けるには、辞書をコピーするか、辞書を直接使っている間、モジュールを確保してください。

定義済みの (書き込み可能な) 属性: __name__ はモジュールの名前です; __doc__ は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります; モジュールがファイルからロードされた場合、 __file__ はロードされたモジュールファイルのパス名です。インタプリタに静的にリンクされている C モジュールの場合、 __file__ 属性はありません; 共有ライブラリから動的にロードされた拡張モジュールの場合、この属性は共有ライブラリファイルのパス名になります。

クラス

2種類のクラス、 type (新スタイルクラス) と class object (旧スタイルクラス) の両方とも、通常はクラス定義 (クラス定義 参照) で生成されます。

クラスは辞書で実装された名前空間を持っています。クラス属性への参照は、この辞書に対する検索 (lookup) に翻訳されます。例えば、 C.x は C.__dict__["x"] と同じです。(ただし、特に新スタイルクラスにおいて、属性参照の意味を変えられる幾つかのフックがあります)

属性がこの検索で見つからない場合、現在のクラスの基底クラスへと検索を続けます。旧スタイルクラスの場合、検索は深さ優先 (depth-first)、かつ基底クラスの挙げられているリスト中の左から右 (left-to-right) の順番で行われます。新スタイルクラスは、より複雑な、C3メソッド解決順序(MRO=method resolution order) を利用していて、複数の継承パスが共通の祖先にたどり着く「ダイアモンド継承」があっても正しく動作します。 C3 MRO についてのより詳細な情報は、2.3リリースに付属するドキュメントにあります。 (http://www.python.org/download/releases/2.3/mro/)

クラス (C とします) への属性参照で、要求している属性がユーザ定義関数オブジェクトや、 C やその基底クラスに関連付けられている非結合のユーザ定義メソッドオブジェクトである場合、 im_class 属性が C であるような非結合ユーザ定義メソッドオブジェクトに変換されます。要求している属性がクラスメソッドオブジェクトの場合、 im_class とその im_self 属性がどちらも C であるようなユーザ定義メソッドオブジェクトに変換されます。要求している属性が静的メソッドオブジェクトの場合、静的メソッドオブジェクトでラップされたオブジェクトに変換されます。クラスから取り出した属性と実際に __dict__ に入っているものが異なるような他の場合については、 デスクリプタ (descriptor) の実装 を参照してください。 (新スタイルクラスだけがディスクリプタをサポートしていることに注意してください)

クラス属性を代入すると、そのクラスの辞書だけが更新され、基底クラスの辞書は更新しません。

クラスオブジェクトを呼び出す (上記を参照) と、クラスインスタンスを生成します (下記を参照)。

特殊属性: __name__ はクラス名です; __module__ はクラスが定義されているモジュールの名前です; __dict__ はクラスの名前空間が入った辞書です; __bases__ は基底クラスの入った (空、あるいは単要素を取りえる) タプルで、基底クラスリストの順番になっています; __doc__ はクラスのドキュメンテーション文字列です。ドキュメンテーション文字列がない場合には None になります。

クラスインスタンス

クラスインスタンスはクラスオブジェクト (上記参照) を呼び出して生成します。クラスインスタンスは辞書で実装された名前空間を持っており、属性参照の時にはこの辞書が最初に検索されます。辞書内に属性が見つからず、かつインスタンスのクラスに該当する属性名がある場合、検索はクラス属性にまで広げられます。見つかったクラス属性がユーザ定義関数オブジェクトや、インスタンスのクラス (C とします) やその基底クラスに関連付けられている非結合のユーザ定義メソッドオブジェクトの場合、 im_class 属性が C で im_self 属性がインスタンスになっている結合ユーザ定義メソッドオブジェクトに変換されます。静的メソッドやクラスメソッドオブジェクトもまた、 C から取り出した場合と同様に変換されます; 上記の “クラス” を参照してください。クラスから取り出した属性と実際に __dict__ に入っているものが異なるような他の場合については、デスクリプタ (descriptor) の実装 節を参照してください。クラス属性が見つからず、かつオブジェクトのクラスが __getattr__() メソッドを持っている場合、このメソッドを呼び出して属性名の検索を充足させます。

属性の代入や削除を行うと、インスタンスの辞書を更新しますが、クラスの辞書を更新することはありません。クラスで __setattr__() や __delattr__() メソッドが定義されている場合、直接インスタンスの辞書を更新する代わりにこれらのメソッドが呼び出されます。

クラスインスタンスは、ある特定の名前のメソッドを持っている場合、数値型やシーケンス型、あるいはマップ型のように振舞うことができます。特殊メソッド名 を参照してください。

特殊属性: __dict__ は属性の辞書です; __class__ はインスタンスのクラスです。

ファイル (file)

ファイルオブジェクトは開かれたファイルを表します。ファイルオブジェクトは組み込み関数 open() や、 os.popen(), os.fdopen(), および socke オブジェクトの makefile() メソッド (その他の拡張モジュールで提供されている関数やメソッド) で生成されます。 sys.stdin, sys.stdout および sys.stderr といったオブジェクトは、インタプリタの標準入力、標準出力、および標準エラー出力ストリームに対応するよう初期化されます。ファイルオブジェクトに関する完全な記述については、 ファイルオブジェクトを参照してください。

内部型 (internal type)

インタプリタが内部的に使っているいくつかの型は、ユーザに公開されています。これらの定義は将来のインタプリタのバージョンでは変更される可能性がありますが、ここでは記述の完全性のために触れておきます。

コードオブジェクト

コードオブジェクトは バイトコンパイルされた (byte-compiled) 実行可能な Python コード、別名バイトコード(bytecode) を表現します。コードオブジェクトと関数オブジェクトの違いは、関数オブジェクトが関数のグローバル変数 (関数を定義しているモジュールのグローバル) に対して明示的な参照を持っているのに対し、コードオブジェクトにはコンテキストがないということです; また、関数オブジェクトではデフォルト引数値を記憶できますが、コードオブジェクトではできません (実行時に計算される値を表現するため)。関数オブジェクトと違い、コードオブジェクトは変更不可能で、変更可能なオブジェクトへの参照を (直接、間接に関わらず) 含みません。

読み出し専用の特殊属性: co_name は関数名を表します; co_argcount は固定引数 (positional argument) の数です; co_nlocals は関数が使う (引数を含めた) ローカル変数の数です; co_varnames はローカル変数名の入ったタプルです (引数名から始まっています); co_cellvars はネストされた関数で参照されているローカル変数の名前が入ったタプルです; co_freevars は自由変数の名前が入ったタプルです。 co_code はバイトコード列を表現している文字列です; co_consts はバイトコードで使われているリテラルの入ったタプルです; co_names はバイトコードで使われている名前の入ったタプルです; co_filename はバイトコードのコンパイルが行われたファイル名です; co_firstlineno は関数の最初の行番号です; co_lnotab はバイトコードオフセットから行番号への対応付けをコード化した文字列です (詳細についてはインタプリタのソースコードを参照してください); co_stacksize は関数で (ローカル変数の分も含めて) 必要なスタックサイズです; co_flags はインタプリタ用の様々なフラグをコード化した整数です。

以下のフラグビットが co_flags で定義されています: 0x04 ビットは、関数が *arguments 構文を使って任意の数の固定引数を受理できる場合に立てられます; 0x08 ビットは、関数が **keywords 構文を使ってキーワード引数を受理できる場合に立てられます; 0x20 ビットは、関数がジェネレータである場合に立てられます。

将来機能 (future feature) 宣言 (from __future__ import division) もまた、 co_flags のビットを立てることで、コードオブジェクトが特定の機能を有効にしてコンパイルされていることを示します: 0x2000 ビットは、関数が将来機能を有効にしてコンパイルされている場合に立てられます; 以前のバージョンの Python では、 0x10 および 0x1000 ビットが使われていました。

co_flags のその他のビットは将来に内部的に利用するために予約されています。

コードオブジェクトが関数を表現している場合、 co_consts の最初の要素は関数のドキュメンテーション文字列になります。ドキュメンテーション文字列が定義されていない場合には None になります。

フレーム (frame) オブジェクト

フレームオブジェクトは実行フレーム (execution frame) を表します。実行フレームはトレースバックオブジェクト内に出現します (下記参照)。

読み出し専用の特殊属性: f_back は (呼び出し側にとっての) 以前のスタックフレームです。呼び出し側がスタックフレームの最下段である場合には None です; f_code は現在のフレームで実行しようとしているコードオブジェクトです; f_locals はローカル変数を検索するために使われる辞書です; f_globals はグローバル変数用です; f_builtins は組み込みの (Python 固有の) 名前です; f_restricted は、関数が制限つき実行 (restricted execution) モードで実行されているかどうかを示すフラグです; f_lasti は厳密な命令コード (コードオブジェクト中のバイトコード文字列へのインデクス) です。

書き込み可能な特殊属性: f_trace が None でない場合、各ソースコード行の先頭で呼び出される関数になります; f_exc_type, f_exc_value, f_exc_traceback は、現在のフレームが以前に引き起こした例外が提供する親フレーム内でもっとも最近捕捉された例外を表します (それ以外の場合は、これらはNoneになります。); f_lineno はフレーム中における現在の行番号です — トレース関数 (trace function) 側でこの値に書き込みを行うと、指定した行にジャンプします (最下段の実行フレームにいるときのみ) 。デバッガでは、 f_fileno を書き込むことで、ジャンプ命令 (Set Next Statement 命令とも呼ばれます) を実装できます。

トレースバック (traceback) オブジェクト

トレースバックオブジェクトは例外のスタックトレースを表現します。トレースバックオブジェクトは例外が発生した際に生成されます。例外ハンドラを検索して実行スタックを戻っていく際、戻ったレベル毎に、トレースバックオブジェクトが現在のトレースバックの前に挿入されます。例外ハンドラに入ると、スタックトレースをプログラム側で利用できるようになります (try 文 を参照)。トレースバックは sys.exc_traceback として得ることができ、 sys.exc_info() が返すタプルの三番目の要素としても得られます. インタフェースとしては後者の方が推奨されていますが、これはプログラムがマルチスレッドを使っている場合に正しく動作するからです。プログラムに適切なハンドラがない場合、スタックトレースは (うまく書式化されて) 標準エラーストリームに書き出されます; インタプリタが対話的に実行されている場合、 sys.last_traceback として得ることもできます。

読み出し専用の特殊属性: tb_next はスタックトレース内の (例外の発生しているフレームに向かって) 次のレベルです。次のレベルが存在しない場合には None になります; tb_frame は現在のレベルにおける実行フレームを指します; tb_lineno は例外の発生した行番号です; tb_lasti は厳密な命令コードです。トレースバック内の行番号や最後に実行された命令は、 try 文内で例外が発生し、かつ対応する except 節や finally 節がない場合には、フレームオブジェクト内の行番号とは異なるかもしれません。

スライス (slice) オブジェクト

スライスオブジェクトは 拡張スライス構文 (extended slice syntax) が使われた際にスライスを表現するために使われます。拡張スライス構文とは、二つのコロンや、コンマで区切られた複数のスライスや省略符号 (ellipse) を使ったスライスで、例えば a[i:j:step] 、 a[i:j, k:l] 、あるいは a[..., i:j] です。スライスオブジェクトは組み込み関数 slice() で生成されます。

読み出し専用の特殊属性: start は下境界 (lower bound) です; stop は上境界 (upper bound) です; step はステップ値 (step value) です; それぞれ省略されている場合には None になります。これらの属性は任意の型の値をとることができます。

スライスオブジェクトはメソッドを一つサポートします:

slice.indices(self, length)

このメソッドは単一の整数引数 length を取り、 length 個の要素からなるシーケンスに適用した際にスライスオブジェクトから提供することになる、拡張スライスに関する情報を計算します。このメソッドは三つの整数からなるタプルを返します; それぞれ start および stop のインデクスと、 step またはスライス間の幅に対応します。インデクス値がないか、範囲外の値である場合、通常のスライスに対して一貫性のあるやりかたで扱われます。

バージョン 2.3 で追加.

静的メソッド (static method) オブジェクト

静的メソッドは、上で説明したような関数オブジェクトからメソッドオブジェクトへの変換を阻止するための方法を提供します。静的メソッドオブジェクトは他の何らかのオブジェクト、通常はユーザ定義メソッドオブジェクトを包むラッパです。静的メソッドをクラスやクラスインスタンスから取得すると、実際に返されるオブジェクトはラップされたオブジェクトになり、それ以上は変換の対象にはなりません。静的メソッドオブジェクトは通常呼び出し可能なオブジェクトをラップしますが、静的オブジェクト自体は呼び出すことができません。静的オブジェクトは組み込みコンストラクタ staticmethod() で生成されます。

クラスメソッドオブジェクト

クラスメソッドオブジェクトは、静的メソッドオブジェクトに似て、別のオブジェクトを包むラッパであり、そのオブジェクトをクラスやクラスインスタンスから取り出す方法を代替します。このようにして取得したクラスメソッドオブジェクトの動作については、上の “ユーザ定義メソッド (user- defined method)” で説明されています。クラスメソッドオブジェクトは組み込みのコンストラクタ classmethod() で生成されます。

新スタイルと旧スタイル

クラスとインスタンスは好みに合わせて2種類の方法で記述することができます: 旧スタイル(もしくはクラシックスタイル)と新スタイルです。

Python 2.1以降では、ユーザが好んで指定した場合のみ旧スタイルが使用されます。 (旧スタイルの)クラスの概念と型の概念には関連性があります: もし x が旧スタイルのクラスのインスタンスだった場合、 x.__class__ というコードはクラス x を指定しますが、 type(x) は常に <type'instance'> となります。これは、すべての旧スタイルのインスタンスが、それらのクラスがどのクラスであるかにかかわらず、 instance と呼ばれる一つの内蔵型として実行されるということを反映しています。

新スタイルのクラスは、クラスと型を統一するためにPython 2.2で導入されました。新スタイルのクラスはユーザ定義型と少しも変わりません。もし、 x が新スタイルクラスのインスタンスであった場合、 type(x) は x.__class__ と同じになります。 (ただし、これは保証されている動作ではありません。新スタイルクラスのインスタンスは、 x.__class__ で返る値をオーバーライドすることができます。)

新スタイルクラスを導入する一番の理由は、メタモデルを用いた統一的なオブジェクトモデルを提供することにあります。また、ほとんどの組み込み型のサブクラスが作成できる、属性を計算するための”デスクリプタ”の導入できる等の利点があります。

互換性のために、デフォルトではクラスは旧スタイルになります。新スタイルのクラスは、他の新スタイルクラス (すなわち型)を親クラスとして定義する、もしくは、他の親クラスが必要ない場合に “最上位型” object を継承することで作成することができます。新スタイルクラスの動作は旧スタイルクラスの動作とは、 type() が何を返すかといったことをはじめ、何点か重要な部分が異なります。特殊メソッドの呼び出しなど、これらの変更は新オブジェクトモデルの基盤となっています。それ以外の部分は、多重継承時のメソッドの解決順などのように、互換性の問題で以前は実装が不可能であった”修正”が新クラスに含まれています。

このマニュアルは Python のクラスメカニズムに関する総合的な情報を提供しようとしていますが、新スタイルクラスについては、まだ足りない部分があるかもしれません。より詳細な情報を得たい場合は、 http://www.python.org/doc/newstyle/ を参照してください。

Python 3.0 では旧スタイルクラスが削除されて、新スタイルクラスが唯一のクラスになりました。

特殊メソッド名

特殊な名前をもったメソッドを定義することで、特殊な構文 (算術演算や添え字表記、スライス表記のような) 特定の演算をクラスで実装することができます。これは、個々のクラスが Python 言語で提供されている演算子に対応した独自の振る舞いをできるようにするための、演算子のオーバロード (operator overloading) に対する Python のアプローチです。例えば、あるクラスが __getitem__() という名前のメソッドを定義しており、 x がこのクラスのインスタンスであるとすると、 x[i] は旧スタイルクラスの場合 x.__getitem__(i) と、新スタイルクラスの場合 type(x).__getitem__(x, i) とほぼ等価になります。特に注釈のない限り、適切なメソッドが定義されていない場合にこのような演算を行おうとすると例外が送出されます。 (発生する例外はたいてい、 AttributeError か TypeError です。)

組み込み型をエミュレーションするようなクラスを実装する際には、エミューレーションの実装をモデル化しようとしているオブジェクトで意味のある範囲だけにとどめることが重要です。例えば、シーケンスによっては個々の要素の取り出し操作が意味のある操作である一方、スライスの抽出が意味をなさないことがあります。 (W3C ドキュメントオブジェクトモデルにおける NodeList インタフェースがその一例です。)

基本的なカスタマイズ

object.__new__(cls[, args...])

クラス cls の新しいインスタンスを作るために呼び出されます。 __new__() は静的メソッドで (このメソッドは特別扱いされているので、明示的に静的メソッドと宣言する必要はありません)、インスタンスを生成するよう要求されているクラスを第一引数にとります。残りの引数はオブジェクトのコンストラクタの式 (クラスの呼び出し文) に渡されます。 __new__() の戻り値は新しいオブジェクトのインスタンス (通常は cls のインスタンス) でなければなりません。

典型的な実装では、クラスの新たなインスタンスを生成するときには super(currentclass, cls).__new__(cls[, ...]) に適切な引数を指定してスーパクラスの __new__() メソッドを呼び出し、新たに生成されたインスタンスに必要な変更を加えてから返します。

__new__() が cls のインスタンスを返した場合、 __init__(self[, ...]) のようにしてインスタンスの __init__() が呼び出されます。このとき、 self は新たに生成されたインスタンスで、残りの引数は __new__() に渡された引数と同じになります。

__new__() が cls のインスタンスを返さない場合、インスタンスの __init__() メソッドは呼び出されません。

__new__() の主な目的は、変更不能な型 (int, str, tuple など) のサブクラスでインスタンス生成をカスタマイズすることにあります。また、クラス生成をカスタマイズするために、カスタムのメタクラスでよくオーバーライドされます。

object.__init__(self[, ...])

インスタンスが生成された際に呼び出されるコンストラクタ (constructor) です。引数はそのクラスのコンストラクタ式に渡した引数になります。基底クラスが __init__() メソッドを持っている場合、派生クラスの __init__() メソッドでは、例えば BaseClass.__init__(self, [args...]) のように、必要ならば明示的に基底クラスの __init__() メソッドを呼び出して、インスタンスの基底クラスに関わる部分が正しく初期化されるようにしなければなりません。コンストラクタには、値を返してはならないという特殊な制限があります; 値を返すようにすると、実行時に TypeError の送出を引き起こします。

object.__del__(self)

インスタンスが消滅させられる際に呼び出されます。このメソッドはデストラクタ (destructor) とも呼ばれます。基底クラスが __del__() メソッドを持っている場合、派生クラスの __del__() メソッドでは、必要ならば明示的に基底クラスの __del__() メソッドを呼び出して、インスタンスの基底クラスに関わる部分が正しく消滅処理されるようにしなければなりません。 __del__() メソッドでインスタンスに対する新たな参照を作ることで、インスタンスの消滅を遅らせることができます (とはいえ、推奨しません！)。このようにすると、新たに作成された参照がその後削除された際にもう一度 __del__() メソッドが呼び出されます。インタプリタが終了する際に残っているオブジェクトに対して、 __del__() メソッドが呼び出される保証はありません。

ノート

del x は直接 x.__del__() を呼び出しません — 前者は x への参照カウント (reference count) を 1 つ減らし、後者は x への参照カウントがゼロになった際にのみ呼び出されます。オブジェクトへの参照カウントがゼロになるのを妨げる可能性のあるよくある状況には、以下のようなものがあります: 複数のオブジェクト間における循環参照 (二重リンクリストや、親と子へのポインタを持つツリーデータ構造); 例外を捕捉した関数におけるスタックフレーム上にあるオブジェクトへの参照 (sys.exc_traceback に記憶されているトレースバックが、スタックフレームを生き延びさせます); または、対話モードでハンドルされなかった例外を送出したスタックフレーム上にあるオブジェクトへの参照 (sys.last_traceback に記憶されているトレースバックが、スタックフレームを生き延びさせます); 最初の状況については、明示的に循環参照を壊すしか解決策はありません; 後者の二つの状況は、 None を sys.exc_traceback や sys.last_traceback に入れることで解決できます。ごみオブジェクトと化した循環参照は、オプションの循環参照検出機構 (cycle detector) が有効にされている場合 (これはデフォルトの設定です) には検出されますが、検出された循環参照を消去するのは Python レベルで __del__() メソッドが定義されていない場合だけです。 __del__() メソッドが循環参照検出機構でどのように扱われるか、とりわけ garbage 値の記述に関しては、 gc モジュールのドキュメントを参照してください。

警告

__del__() メソッドの呼び出しが起きるのは不安定な状況下なので、 __del__() の実行中に発生した例外は無視され、代わりに sys.stderr に警告が出力されます。また、 (例えばプログラムの実行終了による) モジュールの削除に伴って __del__() が呼び出される際には、 __del__() メソッドが参照している他のグローバル変数はすでに削除されていたり、削除中(例えば、import機構のシャットダウン中)かもしれません。この理由から、 __del__() メソッドでは外部の不変関係を維持する上で絶対最低限必要なことだけをすべきです。バージョン 1.5 からは、単一のアンダースコアで始まるようなグローバル変数は、他のグローバル変数が削除される前にモジュールから削除されるように Python 側で保証しています; これらのアンダースコア付きグローバル変数は、 __del__() が呼び出された際に、import されたモジュールがまだ残っているか確認する上で役に立ちます。

object.__repr__(self)

組み込み関数 repr() や、文字列への変換 (逆クオート表記: reverse quote) の際に呼び出され、オブジェクトを表す “公式の (official)” 文字列を計算します。可能な場合には、この値は同じ値を持ったオブジェクトを (適切な環境で) 再生成するために使えるような有効な Python 式に似せるべきです。それが不可能なら、 <...some useful description...> 形式の文字列を返してください。戻り値は文字列オブジェクトでなければなりません。クラスが __repr__() を定義しているが __str__() を定義していない場合、そのクラスのインスタンスに対する “非公式の (informal)” 文字列表現が必要なときにも __repr__() が使われます。

この関数はデバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要です。

object.__str__(self)

組み込み関数 str() および print 文によって呼び出され、オブジェクトを表す “非公式の” 文字列を計算します。このメソッドは、有効な Python 式を返さなくても良いという点で、 __repr__() と異なります: その代わり、より便利で分かりやすい表現を返すようにしてください。戻り値は文字列オブジェクトでなければなりません。

object.__lt__(self, other)

object.__le__(self, other)

object.__eq__(self, other)

object.__ne__(self, other)

object.__gt__(self, other)

object.__ge__(self, other)

バージョン 2.1 で追加.

これらのメソッドは “拡張比較 (rich comparison)” メソッドと呼ばれ、下記の __cmp__() に優先して呼び出されます。演算子シンボルとメソッド名の対応は以下の通りです: x<y は x.__lt__(y) を呼び出します; x<=y は x.__le__(y) を呼び出します; x==y は x.__eq__(y) を呼び出します; x!=y および x<>y は x.__ne__(y) を呼び出します; x>y は x.__gt__(y) を呼び出します; x>=y は x.__ge__(y) を呼び出します。

拡張比較メソッドは、与えられた引数のペアに対する操作を実装していないときに、 NotImplemented というシングルトンを返すかもしれません。慣例として、正常に比較が行われたときには False か True を返します。しかし、これらのメソッドは任意の値を返すことができるので、比較演算子がブール値のコンテキスト(たとえば、 if 文の条件部分)で使われた場合、 Python はその値に対して bool() を呼び出して結果の真偽を判断します。

比較演算子間には、暗黙的な論理関係はありません。すなわち、 x==y が真である場合、暗黙のうちに x!=y が偽になるわけではありません。従って、 __eq__() を実装する際、演算子が期待通りに動作するようにするために __ne__() も定義する必要があります。カスタムの比較演算をサポートしていて、辞書のキーに使うことができるハッシュ可能(hashable) オブジェクトを作るときの重要な注意点について、 __hash__() のドキュメント内に書かれているので参照してください。

これらのメソッドには、(左引数が演算をサポートしないが、右引数はサポートする場合に用いられるような) 鏡像となる (引数を入れ替えた) バージョンは存在しません; むしろ、 __lt__() と __gt__() は互いに鏡像であり、 __le__() と __ge__() 、および __eq__() と __ne__() はそれぞれ互いに鏡像です。

拡張比較メソッドの引数には型強制 (coerce) が起こりません。

単一の基本演算から順序付けするための演算を自動的に生成したい場合には、 functools.total_ordering() を参照してください。

object.__cmp__(self, other)

拡張比較 (上参照) が定義されていない場合、比較演算によって呼び出されます。 self < other である場合には負の値、 self == other ならばゼロ、 self > other であれば正の値を返さなければなりません。演算 __cmp__() 、 __eq__() および __ne__() がいずれも定義されていない場合、クラスインスタンスはオブジェクトのアイデンティティ(“アドレス”) で比較されます。自作の比較演算をサポートするオブジェクトや、辞書のキーとして使えるオブジェクトを生成するには、 __hash__() に関する記述を参照してください。 (注意: __cmp__() が例外を伝播しないという制限は Python 1.5 から除去されました。)

object.__rcmp__(self, other)

バージョン 2.1 で変更: もはやサポートされていません.

object.__hash__(self)

ビルトインの hash() 関数や、 set, frozenset, dict のようなハッシュを使ったコレクション型の要素に対する操作から呼び出されます。 __hash__() は整数を返さなければなりません。このメソッドに必要な性質は、比較結果が等しいオブジェクトは同じハッシュ値を持つということです。オブジェクトを比較するときに利用する要素のそれぞれのハッシュ値を、(排他的論理和等の) なんらかの方法で合成することをおすすめします。

クラスが __cmp__() や __eq__() メソッドを定義していない場合、 __hash__() メソッドも定義してはなりません; クラスが __cmp__() または __eq__() を定義しているが、 __hash__() を定義していない場合、インスタンスを辞書のキーとして使うことはできません。クラスが変更可能なオブジェクトを定義しており、 __cmp__() または __eq__() メソッドを実装している場合、 __hash__() を定義してはなりません。これは、辞書の実装においてハッシュ値が変更不能であることが要求されているからです (オブジェクトのハッシュ値が変化すると、キーが誤ったハッシュバケツ: hash bucket に入っていることになってしまいます)。

ユーザー定義クラスはデフォルトで __cmp__() と __hash__() メソッドを持っています。これらは、同一以外のすべてのオブジェクトに対して比較結果が偽になり、 x.__hash__() は id(x) を返します。

親クラスから __hash__() メソッドを継承して、 __cmp__() か __eq__() の意味を変更している(例えば、値ベースの同値関係から同一性ベースの同値関係に変更する) クラスのハッシュ値は妥当ではなくなるので、 __hash__ = None をクラス定義に書く事で、明示的にハッシュ不可能であることを宣言できます。こうすると、プログラムがそのクラスのインスタンスのハッシュ値を取得しようとしたときに適切な TypeError 例外を送出するようになるだけでなく、 (TypeError を発生させる __hash__() メソッドを持つクラスと違って) isinstance(obj, collections.Hashable) をチェックしたときに、ハッシュ不可能と判定されるようになります。

バージョン 2.5 で変更: __hash__() は現在では長整数オブジェクトも返せるようになりました。 32ビット整数はこのオブジェクトのハッシュから導出されます。

バージョン 2.6 で変更: クラスのインスタンスがハッシュ不可能であることを明示的に宣言するために、 __hash__ に None を設定することができるようになりました。

object.__nonzero__(self)

真値テストや組み込み演算 bool() を実現するために呼び出されます; False または True か、等価な整数値 0 または 1 を返さなければなりません。このメソッドが定義されていない場合、 __len__() が定義されていれば呼び出され、その結果が nonzero であれば真になります。 __len__() と __nonzero__() のどちらもクラスで定義されていない場合、そのクラスのインスタンスはすべて真の値を持つものとみなされます。

object.__unicode__(self)

組み込み関数 unicode() を実現するために呼び出されます。Unicode オブジェクトを返さなければなりません。このメソッドが定義されていなければ、文字列への変換が試みられ、その結果がデフォルトの文字エンコードを用いて Unicode に変換されます。

属性値アクセスをカスタマイズする

以下のメソッドを定義して、クラスインスタンスへの属性値アクセス ( 属性値の使用、属性値への代入、 x.name の削除) の意味をカスタマイズすることができます。

object.__getattr__(self, name)

属性値の検索を行った結果、通常の場所に属性値が見つからなかった場合 (すなわち、 self のインスタンス属性でなく、かつクラスツリーにも見つからなかった場合) に呼び出されます。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出しなければなりません。

通常のメカニズムを介して属性値が見つかった場合、 __getattr__() は呼び出されないので注意してください。(これは、 __getattr__() と __setattr__() の間に意図的に導入された非対称性です。) これは、効率性のためと、こうしなければ __getattr__() がインスタンスの他の属性値にアクセスする方法がなくなるためです。少なくともインスタンス変数に対しては、値をインスタンスの属性値辞書に挿入しないようにして (代わりに他のオブジェクトに挿入することで) 属性値が完全に制御されているように見せかけられることに注意してください。新スタイルクラスで実際に完全な制御を行う方法は、以下の __getattribute__() メソッドを参照してください。

object.__setattr__(self, name, value)

属性値への代入が試みられた際に呼び出されます。このメソッドは通常の代入メカニズム (すなわち、インスタンス辞書への値の代入) の代わりに呼び出されます。 name は属性名で、 value はその属性に代入する値です。

__setattr__() の中でインスタンス属性値への代入が必要な場合、単に self.name = value としてはなりません — このようにすると、自分自身に対する再帰呼び出しがおきてしまいます。その代わりに、インスタンス属性の辞書に値を挿入してください。例えば、 self.__dict__[name] = value とします。新しい形式のクラスでは、インスタンス辞書にアクセスするのではなく、基底クラスのメソッドを同じ属性名で呼び出します。例えば、 object.__setattr__(self, name, value) とします。

object.__delattr__(self, name)

__setattr__() に似ていますが、代入ではなく値の削除を行います。このメソッドを実装するのは、オブジェクトにとって del obj.name が意味がある場合だけにしなければなりません。

新しい形式のクラスのための別の属性アクセス

以下のメソッドは新しい形式のクラス (new-style class) のみに適用されます。

object.__getattribute__(self, name)

クラスのインスタンスに対する属性アクセスを実装するために、無条件に呼び出されます。クラスが __getattr__() も定義している場合、 __getattr__() は、 __getattribute__() で明示的に呼び出すか、 AttributeError 例外を送出しない限り呼ばれません。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出します。このメソッドが再帰的に際限なく呼び出されてしまうのを防ぐため、実装の際には常に、必要な属性全てへのアクセスで、例えば object.__getattribute__(self, name) のように基底クラスのメソッドを同じ属性名を使って呼び出さなければなりません。

ノート

ビルトイン関数や言語構文により暗黙的に特殊メソッドが検索されるときは、このメソッドの呼び出しはバイパスされるでしょう。新スタイルクラスの特殊メソッド検索 を参照してください。

デスクリプタ (descriptor) の実装

以下のメソッドは、このメソッド含むクラス (いわゆるディスクリプタ(descriptor) クラス) のインスタンスがオーナ (owner) クラスに存在するときにのみ適用されます。 (ディスクリプタは、オーナのクラス辞書か、その親のいずれかのクラス辞書になければなりません。) 以下の例での “属性” は、名前がオーナクラスの __dict__ のプロパティ (porperty) のキーであるような属性を指します。

object.__get__(self, instance, owner)

オーナクラスやの属性を取得する (クラス属性へのアクセス) 際や、オーナクラスのインスタンスの属性を取得する (インスタンス属性へのアクセス) 場合に呼び出されます。 owner は常にオーナクラスです。一方、 instance は属性へのアクセスを仲介するインスタンスか属性が owner を介してアクセスされる場合は None になります。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出しなければなりません。

object.__set__(self, instance, value)

オーナクラスのインスタンス instance 上の属性を新たな値 value に設定する際に呼び出されます。

object.__delete__(self, instance)

オーナクラスのインスタンス instance 上の属性を削除する際に呼び出されます。

デスクリプタを呼び出す

一般にデスクリプタとは、特殊な “束縛に関する動作 (binding behaviour)” をもつオブジェクト属性のことです。デスクリプタは、デスクリプタプロトコル (descriptor protocol) のメソッド: __get__(), __set__(), および __delete__() を使って、属性アクセスをオーバライドしているものです。これらのメソッドのいずれかがオブジェクトに対して定義されている場合、オブジェクトはデスクリプタであるといいます。

属性アクセスのデフォルトの動作は、オブジェクトの辞書から値を取り出したり、値を設定したり、削除したりするというものです。例えば、 a.x による属性の検索では、まず a.__dict__['x'] 、次に type(a).__dict__['x'] 、そして type(a) の基底クラスでメタクラスでないものに続く、といった具合に連鎖が起こります。

しかしながら、検索対象となる値が、デスクリプタメソッドのいずれかを定義しているオブジェクトの属性値である場合、Python はデフォルトの動作をオーバライドして、デスクリプタメソッドの方を呼び出します。

前後する呼び出し連鎖の中のどこでデスクリプタメソッドが呼び出されるかは、どのデスクリプタメソッドが定義されているかと、どうやってデスクリプタメソッドが呼ばれるかに依存します。デスクリプタは新しい形式のオブジェクトやクラス (object() や type() をサブクラス化したもの) だけに対して呼び出されるので注意してください。

デスクリプタ呼び出しの基点となるのは、属性名への束縛 (binding) 、すなわち a.x です。引数がどのようにデスクリプタに結合されるかは a に依存します:

直接呼出し (Direct Call)

最も単純で、かつめったに使われない呼び出し操作は、コード中で直接デスクリプタメソッドの呼び出し: x.__get__(a) を行うというものです。

インスタンス束縛 (Instance Binding)

新しい形式のクラスのインスタンスに対する束縛では、 a.x は呼び出し: type(a).__dict__['x'].__get__(a, type(a)) に変換されます。

クラス束縛 (Class Binding)

新しい形式のクラスに対する束縛では、 A.x は呼び出し: A.__dict__['x'].__get__(None, A) に変換されます。

スーパクラス束縛 (Super Binding)

a が super のインスタンスである場合、束縛 super(B, obj).m() を行うとまず A 、続いて B に対して obj.__class_.__mro__ を検索し、次に呼び出し: A.__dict__['m'].__get__(obj, obj.__class__) でデスクリプタを呼び出します。

インスタンス束縛では、デスクリプタ呼び出しの優先順位はどのデスクリプタが定義されているかに依存します。データデスクリプタは、 __get__() と __set__() 、 __delete__() の任意の組合せを定義することができます。 __get__() が定義されない場合には、その属性にアクセスすると、そのオブジェクトのインスタンス辞書にその値がある場合を除けば、デスクリプタオブジェクト自身が返ってきます。デスクリプタが __set__() と __delete__() またはそのどちらかを定義していれば、データデスクリプタとなります; もし両方とも定義しなければ、非データデスクリプタです。通常、データデスクリプタでは、 __get__() と __set__() を定義し、一方、非データデスクリプタには __get__() メソッドしかありません。インスタンス辞書内で属性値が再定義されても、データデスクリプタは常にこの値をオーバライドします。対照的に、非データデスクリプタの場合には、属性値はインスタンス側でオーバライドされます。

(staticmethod() や classmethod() を含む) Python メソッドは、非データデスクリプタとして実装されています。その結果、インスタンスではメソッドを再定義したりオーバライドできます。このことにより、個々のインスタンスが同じクラスの他のインスタンスと互いに異なる動作を獲得することができます。

property() 関数はデータデスクリプタとして実装されています。従って、インスタンスはあるプロパティの動作をオーバライドすることができません。

__slots__

デフォルトでは、新旧どちらのクラスも、属性の記憶領域として使うための辞書を持っています。この仕様は、ほとんどインスタンス変数を持たないようなオブジェクトの場合には記憶領域の無駄遣いになります。記憶領域の消費量は、大量のインスタンスを生成する際には深刻です。

このデフォルトの設定は、新たな形式のクラス定義において __slots__ を定義することでオーバライドできます。 __slots_ 宣言はインスタンス変数のシーケンスを受け取ります。各々のインスタンス上には、各変数の値を記憶するのにちょうど必要な量だけの記憶領域を確保します。各々のインスタンスに対して __dict__ が生成されることがないので、記憶領域が節約されます。

__slots__

このクラス変数には、文字列、反復可能オブジェクト、あるいはインスタンスが用いる変数名を表す文字列からなるシーケンスを代入することができます。この変数が新しい形式のクラスで定義されている場合、 __slots__ は、各インスタンスに対して宣言された変数に必要な記憶領域を確保し、 __dict__ と __weakref__ が自動的に生成されないようにします。

バージョン 2.2 で追加.

__slots__ を利用する際の注意

__slots__ を持たないクラスから継承する場合、 __dict__ 属性は常にアクセス可能なので、サブクラスで __slots__ を定義しても意味がありません。

__dict__ 変数がない場合、 __slots__ に列挙されていない新たな変数をインスタンスに代入することはできません。列挙されていない変数名を使って代入しようとした場合、 AttributeError が送出されます。新たな変数を動的に代入したいのなら、 __slots__ を宣言する際に '__dict__' を変数名のシーケンスに追加してください。

バージョン 2.3 で変更: これまでは、 '__dict__' を __slots__ 宣言に追加しても、インスタンス変数名として他にリストされていない新たな属性の代入はできませんでした。

__slots__ を定義しているクラスの各インスタンスに __weakref__ 変数がない場合、インスタンスに対する弱参照 (weak reference) はサポートされません。弱参照のサポートが必要なら、 __slots__ を宣言する際に '__weakref__' を変数名のシーケンスに追加してください。

バージョン 2.3 で変更: これまでは、 '__weakref__' を __slots__ 宣言に追加しても、弱参照のサポートを有効にできませんでした。

__slots__ は、クラスのレベルで各変数に対するデスクリプタ (デスクリプタ (descriptor) の実装 を参照) を使って実装されます。その結果、 __slots__ に定義されているインスタンス変数のデフォルト値はクラス属性を使って設定できなくなっています; そうしないと、デスクリプタによる代入をクラス属性が上書きしてしまうからです。

__slots__ 宣言が動作するのは、定義が行われたクラスだけに限られています。その結果、サブクラスでは、 __slots__ を定義しない限り __dict__ を持つことになります。

あるクラスで、基底クラスですでに定義されているスロットを定義した場合、基底クラスのスロットで定義されているインスタンス変数は (デスクリプタを基底クラスから直接取得しない限り) アクセスできなくなります。これにより、プログラムの趣意が不定になってしまいます。将来は、この問題を避けるために何らかのチェックが追加されるかもしれません。

空でない __slots__ は、 long 、 str 、および tuple といった、”可変長 (variable-length)” の組み込み型から派生したクラスでは動作しません。

__slots__ には、文字列でない反復可能オブジェクトを代入することができます。辞書型も使うことができます; しかし将来、辞書の各キーに相当する値に何らかの特殊な意味が割り当てられるかもしれません。

__class__ への代入は、両方のクラスが同じ __slots__ を持っているときのみ動作します。

バージョン 2.6 で変更: 以前は、新旧どちらかのクラスが __slots__ を持っていたら __class__ への代入はエラーを発生していました。

クラス生成をカスタマイズする

デフォルトでは、新スタイルクラスは type() を使って構築されます。クラス定義が別の名前空間に読み込まれ、クラス名は type(name, bases, dict) の結果に結合されます。

クラス定義が読み込まれる際、 __metaclass__ が定義されていれば、 type() の代わりに __metaclass__ が指している呼び出し可能オブジェクトが呼び出されます。これによって、

クラスが生成される前にクラス辞書を変更する

他のクラスのインスタンスを返す – 本質的にはファクトリ関数の役割を果たす

といった、クラス生成のプロセスを監視したり置き換えたりするクラスや関数を書くことができます。

これらのステップは、メタクラスの __new__() メソッドで実行されなければなりません。 – このメソッドから他の属性を持ったクラスを作るには、 type.__new__() を呼び出すことができます。次の例ではクラスを生成する前に新しい要素をクラス辞書に追加しています。

class metacls(type):
    def __new__(mcs, name, bases, dict):
        dict['foo'] = 'metacls was here'
        return type.__new__(mcs, name, bases, dict)

もちろん、他のクラスメソッドをオーバーライドする(または新しいメソッドを追加する)こともできます。例えば、カスタムの __call__() メソッドをメタクラスに定義して、新しいインスタンスを常には造らないといったカスタムの動作を実装できます。

__metaclass__

この変数は name 、 bases 、および dict を引数として取るような任意の呼び出し可能オブジェクトにできます。クラス生成の際、組み込みの type() の代わりに、指定された呼び出しオブジェクトが呼び出されます。

バージョン 2.2 で追加.

以下に優先順で並んだ規則によって、適切なメタクラスが決定されます:

dict['__metaclass__'] があればそれを使います。

それ以外の場合で、最低でも一つ基底クラスを持っているなら、基底クラスのメタクラス (__class__ 属性を探し、なければ基底クラスの型) を使います。

それ以外の場合で、__metaclass__ という名前のグローバル変数があれば、それをつかいます。

それ以外の場合には、旧スタイルのメタクラス (types.ClassType) を使います。

メタクラスは限りない潜在的利用価値を持っています。これまで試されてきたアイデアには、ログ記録、インタフェースのチェック、自動デリゲーション、自動プロパティ生成、プロキシ、フレームワーク、そして自動リソースロック／同期といったものがあります。

インスタンスのカスタマイズとサブクラスチェック

バージョン 2.6 で追加.

以下のメソッドは組み込み関数 isinstance() と issubclass() のデフォルトの動作を上書きするのに利用します。

特に、 abc.ABCMeta メタクラスは、抽象基底クラス (ABCs) を”仮想基底クラス (virtual base classes)” として、他の ABC を含む、任意のクラスや (組み込み型を含む) 型に追加するために、これらのメソッドを実装しています。

class.__instancecheck__(self, instance)

instance が (直接、または間接的に) class のインスタンスと考えられる場合に true を返します。定義されていれば、 isinstance(instance, class) の実装のために呼び出されます。

class.__subclasscheck__(self, subclass)

subclass が (直接、または間接的に) class のサブクラスと考えられる場合に true を返します。定義されていれば、 issubclass(subclass, class) の実装のために呼び出されます。

なお、これらのメソッドは、クラスの型 (メタクラス) 上で検索されます。実際のクラスにクラスメソッドとして定義することはできません。これは、インスタンスそれ自体がクラスであるこの場合にのみ、インスタンスに呼び出される特殊メソッドの検索と一貫しています。

参考

PEP 3119 [http://www.python.org/dev/peps/pep-3119] - Introducing Abstract Base Classes

__instancecheck__() と __subclasscheck__() を通して、 isinstance() と issubclass() の動作をカスタマイズする仕様が、言語に抽象基底クラス (abc モジュールを参照してください) を追加するという背景に基いた動機づけとともに載っています。

呼び出し可能オブジェクトをエミュレートする

object.__call__(self[, args...])

インスタンスが関数として “呼ばれた” 際に呼び出されます; このメソッドが定義されている場合、 x(arg1, arg2, ...) は x.__call__(arg1, arg2, ...) を短く書いたものになります。

コンテナをエミュレートする

以下のメソッドを定義して、コンテナオブジェクトを実装することができます。コンテナは通常、(リストやタプルのような) シーケンスや、(辞書のような) マップ型を指しますが、他のコンテナも同じように表現することができます。最初の一連のメソッドは、シーケンスをエミュレートしたり、マップ型をエミュレートするために使われます; その違いとして、シーケンスの場合には、キーとして許されているのが、シーケンスの長さが N であるときの 0 <= k < N なる整数 k か、あるいは要素の範囲を表すスライスオブジェクトでなければならないということです。 (後方互換性のため、 __getslice__() (以下参照) を定義して、拡張されていない単純なスライスを扱うようにもできます。)

変更可能なシーケンスでは、Python の標準リストオブジェクトのように、メソッド append(), count(), index(), extend(), insert(), pop(), remove(), reverse(),および sort() を提供しなければなりません。

マップ型でも、Python の標準辞書オブジェクトのように、 keys(), values(), items(), has_key(), get(), clear(), setdefault(), iterkeys(), itervalues(), iteritems(), pop(), popitem(), copy(),および update() といったメソッドをマップ型で提供するよう推奨しています。 UserDict モジュールでは、これらのメソッドを __getitem__(), __setitem__(), __delitem__(),および keys() といった基本セットから作成する上で役に立つ DictMixin クラスを提供しています。

最後に、シーケンス型では以下に述べるメソッド群 __add__(), __radd__(), __iadd__(), __mul__(), __rmul__(),および __imul__() を定義して、 (シーケンス間の結合を意味する) 加算操作と (要素の繰り返しを意味する) 乗算操作を実装しなければなりません; __coerce__() や、その他の数値演算子を定義してはなりません。

マップでもシーケンスでも、 in 演算子が有効利用できるように __contains__() メソッドの定義を推奨します; マップ型では、 in は has_key() と等価でなければなりません; シーケンスでは、シーケンス内の値にわたって検索を行わなければなりません。さらに、マップでもシーケンスでも、コンテナ内にわたる反復操作ができるようにするため、 __iter__() を実装するよう勧めます; マップ型の場合、 __iter__() は iterkeys() と等価でなければなりません; シーケンスの場合、シーケンス内の値にわたって反復操作を行わなければなりません。

object.__len__(self)

組み込み関数 len() を実現するために呼び出されます。オブジェクトの長さを >= 0 である整数で返さなければなりません。また、オブジェクトが __nonzero__() メソッドを定義しておらず、 __len__() メソッドがゼロを返す場合には、ブール演算コンテキストでは偽であるとみなされます。

object.__getitem__(self, key)

self[key] の値評価 (evaluation) を実現するために呼び出されます。シーケンスの場合、キーとして整数とスライスオブジェクトを受理できなければなりません。 (シーケンス型をエミュレートする場合) 負のインデクスの解釈は __getitem__() メソッド次第となります。 key が不適切な型であった場合、 TypeError を送出してもかまいません; (負のインデクス値に対して何らかの解釈を行った上で) key がシーケンスのインデクス集合外の値である場合、 IndexError を送出しなければなりません。マップ型の場合は、 key に誤りがある場合（コンテナに含まれていない場合）、 IndexError を送出しなければなりません。

ノート

for ループでは、シーケンスの終端を正しく検出できるようにするために、不正なインデクスに対して IndexError が送出されるものと期待しています。

object.__setitem__(self, key, value)

self[key] に対する代入を実現するために呼び出されます。 __getitem__() と同じ注意事項があてはまります。このメソッドを実装できるのは、あるキーに対する値の変更をサポートしているか、新たなキーを追加できるようなマップの場合と、ある要素を置き換えることができるシーケンスの場合だけです。不正な key に対しては、 __getitem__() メソッドと同様の例外の送出を行わなければなりません。

object.__delitem__(self, key)

self[key] の削除を実現するために呼び出されます。 __getitem__() と同じ注意事項があてはまります。このメソッドを実装できるのは、キーの削除をサポートしているマップの場合と、要素を削除できるシーケンスの場合だけです。不正な key に対しては、 __getitem__() メソッドと同様の例外の送出を行わなければなりません。

object.__iter__(self)

このメソッドは、コンテナに対してイテレータが要求された際に呼び出されます。このメソッドは、コンテナ内の全てのオブジェクトにわたる反復処理ができるような、新たなイテレータオブジェクトを返さなければなりません。マップの場合、コンテナ内のキーに渡る反復処理でなければならず、かつ iterkeys() によって利用できなければなりません。

イテレータオブジェクトでもこのメソッドを実装する必要があります; イテレータの場合、自分自身を返さなければなりません。イテレータオブジェクトに関するより詳細な情報は、 イテレータ型 を参照してください。

object.__reversed__(self)

reversed() ビルトイン関数が逆方向イテレーションを実装するために、(存在すれば)呼び出します。コンテナ内の全要素を逆順にイテレートする、新しいイテレータを返すべきです。

メンバシップテスト演算子 (in および not in) は通常、シーケンスに渡る反復処理を使って実装されます。しかし、コンテナオブジェクトで以下の特殊メソッドを定義して、より効率的な実装を行ったり、オブジェクトがシーケンスでなくてもよいようにできます。

object.__contains__(self, item)

メンバシップテスト演算を実現するために呼び出されます。 item が self 内に存在する場合には真を、そうでない場合には偽を返さなければなりません。マップオブジェクトの場合、値やキーと値の組ではなく、キーに対するメンバシップテストを考えなければなりません。

__contains__() を定義しないオブジェクトに対しては、メンバシップテストはまず、 __iter__() を使った反復を試みます、次に古いシーケンス反復プロトコル __getitem__() を使います、言語レファレンスのこの節 を参照して下さい。

シーケンス型エミュレーションで使われるその他のメソッド

以下のオプションとなるメソッドを定義して、シーケンスオブジェクトをより高度にエミュレーションできます。変更不能なシーケンスのメソッドでは、 __getslice__() が定義できるだけです; 変更可能なシーケンスでは三つのメソッド全てを定義できます。

object.__getslice__(self, i, j)

バージョン 2.0 で撤廃: スライスオブジェクトは __getitem__() メソッドのパラメタとしてサポートするようになりました。 (しかし、現在の CPython はいまだに __getslice__() を実装しています。なので、派生クラスでスライスを実装する場合は、このメソッドをオーバーライドしなければなりません。)

self[i:j] の値評価を実現するために呼び出されます。返されるオブジェクトは self と同じ型でなければなりません。スライス表記で i や j がない場合には、それぞれゼロや sys.maxint に置き換えられるので注意してください。スライスに負のインデクスが用いられた場合、シーケンスの長さがインデクス値に加算されます。インスタンスが __len__() メソッドを実装していない場合には、 AttributeError が送出されます。この計算の結果、インデクス値が負でなくなるという保証はありません。シーケンスの長さよりも大きなインデクス値は修正されません。 __getslice__() が定義されていない場合、代わりにスライスオブジェクトが生成されて __getitem__() に渡されます。

object.__setslice__(self, i, j, sequence)

self[i:j] への代入を実現するために呼び出されます。 i および j に関しては、 __getslice__() と同じ注釈があてはまります。

このメソッドは撤廃されています。 __setslice__() がないか、 self[i:j:k] 形式の拡張スライスの場合には、 __setslice__() が呼ばれる代わりにスライスオブジェクトが生成され、 __setitem__() に渡されます。

object.__delslice__(self, i, j)

self[i:j] の削除を実現するために呼び出されます。 i および j に関しては、 __getslice__() と同じ注釈があてはまります。

このメソッドは撤廃されています。 __delslice__() がないか、 self[i:j:k] 形式の拡張スライスの場合には、 __delslice__() が呼ばれる代わりにスライスオブジェクトが生成され、 __delitem__() に渡されます。

これらのメソッドは、単一のコロンを使った単一のスライスで、かつスライスメソッドが利用できるときにだけ呼び出されることに注意してください。拡張スライス表記を含んでいるスライス表記や、スライスメソッドがない場合、 __getitem__() 、 __setitem__() 、あるいは __delitem__() がスライスオブジェクトを引数として呼び出されます。

以下の例は、プログラムやモジュールを以前のバージョンの Python に対して互換性を持たせる方法を示したものです (__getitem__() 、 __setitem__() 、および __delitem__() は引数としてスライスオブジェクトをサポートするものと仮定します):

class MyClass:
    ...
    def __getitem__(self, index):
        ...
    def __setitem__(self, index, value):
        ...
    def __delitem__(self, index):
        ...

    if sys.version_info < (2, 0):
        # They won't be defined if version is at least 2.0 final

        def __getslice__(self, i, j):
            return self[max(0, i):max(0, j):]
        def __setslice__(self, i, j, seq):
            self[max(0, i):max(0, j):] = seq
        def __delslice__(self, i, j):
            del self[max(0, i):max(0, j):]
    ...

max() を呼び出していることに注意してください; この呼び出し __*slice__() メソッド呼び出される前に、負のインデクス値を処理しておくために必要です。負のインデクス値が使われた場合、 __*item__() メソッドは与えられた値をそのまま使いますが、 __*slice__() メソッドは “調理済みの (cooked)” 形式になったインデクス値を受け取ります。負のインデクス値が使われると、メソッドを呼び出す前に、常にシーケンスの長さをインデクス値に加算します (加算してもまだ負の値となっていてもかまいません); これは、組み込みシーケンス型における慣習的な負のインデクス処理方法で、 __*item__() メソッドでも同様の処理を行うよう期待しています。しかし、ここではすでに負のインデクス値の処理を行っているので、負のインデクスを渡すべきではありません; インデクス値は、 __*item__() メソッドに渡される前に、シーケンスのインデクス集合の境界に制限されていなければなりません。 max(0, i) を呼び出せば、適切な値を返すので便利です。

数値型をエミュレーションする

以下のメソッドを定義して、数値型オブジェクトをエミュレートすることができます。特定の種類の数値型ではサポートされていないような演算に対応するメソッド (非整数の数値に対するビット単位演算など) は、未定義のままにしておかなければなりません。

object.__add__(self, other)

object.__sub__(self, other)

object.__mul__(self, other)

object.__floordiv__(self, other)

object.__mod__(self, other)

object.__divmod__(self, other)

object.__pow__(self, other[, modulo])

object.__lshift__(self, other)

object.__rshift__(self, other)

object.__and__(self, other)

object.__xor__(self, other)

object.__or__(self, other)

これらのメソッドは、二項算術演算 (+, -, *, //, %, divmod(), pow(), **, <<, >>, &, ^, |) を実現するために呼び出されます。例えば、式 x + y の場合、 x が __add__() メソッドをもつクラスのインスタンスであれば、 x.__add__(y) が呼び出されます。 __divmod__() メソッドは、 __floordiv__() と __mod__() を使った場合と等価にならなければなりません; __truediv__() (下記参照) と関連づける必要はありません。組み込みの三項演算子バージョンの関数 pow() をサポートする場合には、 __pow__() は、オプションとなる第三の引数を受け取れなくてはなりません。

こらのメソッドが渡された引き数に対する操作を提供していない場合には、 NotImplemented を送出しなければなりません。

object.__div__(self, other)

object.__truediv__(self, other)

除算演算 (/) は、これらのメソッドで実現されています。 __truediv__() は、 __future__.division が有効であるときに使われます。それ以外の場合には __div__() が使われますs。二つのメソッドのうち一方しか定義されていなければ、オブジェクトは他方の演算コンテキストをサポートしなくなります; このとき、 TypeError が送出されます。

object.__radd__(self, other)

object.__rsub__(self, other)

object.__rmul__(self, other)

object.__rdiv__(self, other)

object.__rtruediv__(self, other)

object.__rfloordiv__(self, other)

object.__rmod__(self, other)

object.__rdivmod__(self, other)

object.__rpow__(self, other)

object.__rlshift__(self, other)

object.__rrshift__(self, other)

object.__rand__(self, other)

object.__rxor__(self, other)

object.__ror__(self, other)

これらのメソッドは二項算術演算 (+, -, *, /, %, divmod(), pow(), **, <<, >>, &, ^, |) を実現しますが、メソッド呼び出しが行われる被演算子が逆転して (reflected, swapped: 入れ替えられて) います。これらの関数は、左側の被演算子が対応する演算をサポートしておらずかつ両者の演算子が異なる場合にのみ呼び出されます。 [2]

例えば、 x - y の式を評価する場合、 y が __rsub__() メソッドを持つクラスのインスタンスであって、しかも x.__sub__(y) が NotImplemented を返す場合には、 y.__rsub__(x) が呼び出されます。

ただし、三項演算子 pow() が __rpow__() を呼ぶことはないので注意してください (型強制の規則が非常に難解になるからです)。

ノート

右側の被演算子の型が左側の被演算子の型のサブクラスであり、このサブクラスであるメソッドに対する逆転メソッドが定義されている場合には、左側の被演算子の非逆転メソッドが呼ばれる前に、このメソッドが呼ばれます。この振る舞いにより、サブクラスが親の操作をオーバーライドすることが可能になります。

object.__iadd__(self, other)

object.__isub__(self, other)

object.__imul__(self, other)

object.__idiv__(self, other)

object.__itruediv__(self, other)

object.__ifloordiv__(self, other)

object.__imod__(self, other)

object.__ipow__(self, other[, modulo])

object.__ilshift__(self, other)

object.__irshift__(self, other)

object.__iand__(self, other)

object.__ixor__(self, other)

object.__ior__(self, other)

これらのメソッドは、累算算術代入 (augmented arithmetic assignments, +=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=) を実現するために呼び出されます。これらのメソッドは、演算をその場で(self を変更する形で) 行うよう試み、その結果(変更された self またはその代わりのもの)を返さなければなりません。特定のメソッドが定義されていない場合、その累算算術演算は通常のメソッドで代用されます。例えば、 x += y を評価する際、 x が __iadd__() メソッドを持つクラスのインスタンスであれば、 x.__iadd__(y) が呼び出されます。逆に、 x が __iadd() メソッドを持たないクラスのインスタンスであれば、 x + y の評価と同じように x.__add__(y) および y.__radd__(x) を考慮します。

object.__neg__(self)

object.__pos__(self)

object.__abs__(self)

object.__invert__(self)

単項算術演算 (-, +, abs() および ~) を実現するために呼び出されます。

object.__complex__(self)

object.__int__(self)

object.__long__(self)

object.__float__(self)

組み込み関数 complex(), int(), long(), および float() を実現するために呼び出されます。適切な型の値を返さなければなりません。

object.__oct__(self)

object.__hex__(self)

組み込み関数 oct() および hex() を実現するために呼び出されます。文字列型を返さなければなりません。

object.__index__(self)

operator.index() を実装するために呼び出されます。また、（スライシング）のように Python が整数オブジェクトを必要とする場合には何処でも呼び出されます。整数（int もしくは long）を返す必要があります。

バージョン 2.5 で追加.

object.__coerce__(self, other)

“型混合モード (mixed-mode)” での数値間の算術演算を実現するために呼び出されます。 self と other を共通の数値型に変換して、 2 要素のタプルにして返すか、不可能な場合には None を返さなければなりません。共通の型が other の型になる場合、 None を返すだけで十分です。この場合、インタプリタはもう一方のオブジェクトを調べて型強制を行おうとするからです (とはいえ、もう一方の値の型が実装上変更できない場合には、ここで self を other の型に変換しておいた方が便利です)。戻り値に NotImplemented を使うのは、 None を返すのと同じです。

型強制規則 (coercion rule)

本節では、型強制 (coercion) に関する規則について記述します。プログラム言語が進化するにつれ、型強制規則について正確に記述するのは難しくなってゆきます; 従って、あるバージョンのある実装について記述するのは望ましくありません。その代わりに、型強制に関する非公式的なガイドラインを示しておきます。 Python 3.0 からは、型強制がサポートされなくなる予定です。

% 演算子の左被演算子が文字列か Unicode オブジェクトの場合、型強制は起きず、文字列としての書式化操作が呼び出されます。

型強制演算の定義はもはや推奨されていません。型強制を定義していない混合型 (mixed-mode) 演算は、もとの引数をそのまま演算操作に渡すようになっています。

新しい形式のクラス (object から派生したもの) が、二項演算子に対して __coerce__() メソッドを呼び出すことはありません。; __coerce__() が呼び出されるのは、組み込み関数 coerce() が呼び出されたときだけです。

事実上、 NotImplemented を返す演算子は、全く実装されていないものとして扱われます。

以下の説明では、 __op__() および __rop__() は、演算子に相当する一般的なメソッド名を表すために使われます; __iop__() はインプレース演算子を表します。例えば、演算子 ‘+‘ の場合、 __add__() および __radd__() がそれぞれ左右の被演算子用の二項演算子として使われ、 __iadd__() がインプレース演算用の演算子として使われる、といった具合です。

オブジェクト x および y に対して、まず x.__op__(y) が試されます。この演算が実装されていないか、 NotImplemented を返す場合、次に y.__rop__(x) が試されます。この演算も実装されていないか、 NotImplemented を返すなら、 TypeError 例外が送出されます。ただし、以下の例外があるので参照してください:

前項に対する例外: 左被演算子が組み込み型や新スタイルクラスのインスタンスであり、かつ右被演算子が左被演算子と同じクラスか適切なサブクラスのインスタンスであり、さらに親クラスの __rop__() メソッドをオーバライドしている場合、左被演算子の __op__() メソッドを試す前に 右被演算子の __rop__() が試されます。これは、サブクラス側で二項演算子を完全にオーバライドできるようにするためです。そうしなければ、常に左被演算子の __op__() メソッドが右被演算子を受理してしまいます: あるクラスのインスタンスが被演算子になるとされている場合、そのサブクラスのインスタンスもまた受理可能だからです。

双方の被演算子が型強制を定義している場合、型強制は被演算子の型の __op__() や __rop__() メソッドが呼び出される前に呼び出され、それより早くなることはありません。型強制の結果、型強制を行うことになったいずれの被演算子とも異なる型が返された場合、返されたオブジェクトの新たな型を使って、この過程が部分的に再度行われます。

(‘+=‘ のような) インプレース型の演算子を用いる際、左被演算子が __iop__() を実装していれば、 __iop__() が呼び出され、型強制は一切行われません。演算が __op__() かつ/または __rop__() に帰着した場合、通常の型強制規則が適用されます。

x + y において、 x が結合 (concatenation) 演算を実装しているシーケンスであれば、シーケンスの結合が実行されます。

x * y において、一方の演算子が繰り返し (repeat) 演算を実装しているシーケンスであり、かつ他方が整数 (int または long) である場合、シーケンスの繰り返しが実行されます。

(__eq__() などのメソッドで実装されている) 拡張比較は、決して型強制を行いません。(__cmp__() で実装されている) 三値比較 (three-way comparison) は、他の二項演算子で行われているのと同じ条件で型強制を受けます。

現在の実装では、組み込み数値型 int, long, float および complex は型強制を行いません; これらの型は全て、関数 coerce() から利用するための __coerce__() メソッドを実装しています。

バージョン 2.7 で変更.

with文とコンテキストマネージャ

バージョン 2.5 で追加.

コンテキストマネージャ(context manager) とは、 with 文の実行時にランタイムコンテキストを定義するオブジェクトです。コンテキストマネージャは、コードブロックを実行するために必要な入り口および出口の処理を扱います。コンテキストマネージャは通常、 with 文（ with 文 の章を参照）により起動されますが、これらのメソッドを直接呼び出すことで起動することもできます。

コンテキストマネージャの代表的な使い方としては、様々なグローバル情報の保存および更新、リソースのロックとアンロック、ファイルのオープンとクローズなどが挙げられます。

コンテキストマネージャについてのさらなる情報については、 コンテキストマネージャ型 を参照してください。

object.__enter__(self)

コンテキストマネージャのの入り口で実行される処理です。 with 文は、文の as 節で規定された値を返すこのメソッドを呼び出します。

object.__exit__(self, exc_type, exc_value, traceback)

コンテキストマネージャの出口で実行される処理です。パラメータは、コンテキストが終了した原因となった例外について説明しています。コンテキストが例外を送出せず終了した場合は、全ての引き数に None が設定されます。

もし、例外が送出され、かつメソッドが例外を抑制したい場合（すなわち、例外が伝播されるのを防ぎたい場合）、このメソッドは True を返す必要があります。そうでなければ、このメソッドの終了後、例外は通常通り伝播することになります。

__exit__() メソッドは受け取った例外を再度送出すべきではありません。これは、呼び出し側の責任でおこなってください。

参考

PEP 0343 [http://www.python.org/dev/peps/pep-0343] - The “with” statement

Python の with 文の仕様、背景、および例が記載されています。

旧スタイルクラスの特殊メソッド検索

旧スタイルクラスにおいて、特殊メソッドは常に他のメソッドや属性と同じ方法で検索されます。これは、メソッドが x.__getitem__(i) のように明示的に検索された時も、 x[i] のように暗黙的に検索された時も同じです。

これにより、1つの旧スタイルクラスの異なるインスタンスが、それぞれ別の適切な特殊属性を持っている場合、異なる動作をすることになります。

>>> class C:
...     pass
...
>>> c1 = C()
>>> c2 = C()
>>> c1.__len__ = lambda: 5
>>> c2.__len__ = lambda: 9
>>> len(c1)
5
>>> len(c2)
9

新スタイルクラスの特殊メソッド検索

新スタイルクラスでは、特殊メソッドの暗黙的な呼び出しは、オブジェクトインスタンスの辞書ではなく、 type の辞書で定義されているときにのみ正しく動作することが保証されます。この動作は、以下のコードが(旧スタイルクラスの同等な例と異なり)例外を発生させる理由です。

>>> class C(object):
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()

この動作の背景となる理由は、 __hash__() と __repr__() といった type オブジェクトを含むすべてのオブジェクトで定義されている特殊メソッドにあります。これらのメソッドの暗黙の検索が通常の検索プロセスを使った場合、 type オブジェクト自体に対して実行されたときに失敗してしまいます。

>>> 1.__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument

クラスの非結合メソッドをこのようにして実行しようとすることは、 ‘metaclass confusion’ と呼ばれることもあり、特殊メソッドを検索するときはインスタンスをバイパスすることで回避されます。

>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True

正確性のためにインスタンス属性をスキップするのに加えて、特殊メソッド検索はオブジェクトのメタクラスを含めて、 __getattribute__() メソッドもバイパスします。

>>> class Meta(type):
...    def __getattribute__(*args):
...       print "Metaclass getattribute invoked"
...       return type.__getattribute__(*args)
...
>>> class C(object):
...     __metaclass__ = Meta
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print "Class getattribute invoked"
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

このように __getattribute__() 機構をバイパスすることで、特殊メソッドの扱いに関するある程度の自由度(特殊メソッドはインタプリタから確実に実行されるためにクラスオブジェクトに設定 しなければならない。)と引き換えに、インタープリタを高速化するための大きな余地を手に入れています。

注記

[1]
特定の条件が満たされた場合、オブジェクトの type を変更することが できます 。これは、正しく扱われなかった場合にとても奇妙な動作を引き起こすので、一般的には良い考えではありません。

[2]
同じ型の操作に対しては、(__add__() のような)逆転できないメソッドが失敗した時と同じような想定のもと処理されます。これは、逆転したメソッドを呼び出すことができないからです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

実行モデル

名前づけと束縛 (naming and binding)

名前 (name) とは、オブジェクトを参照するものを指します。名前への束縛 (name binding) 操作を行うと、名前を導入できます。プログラムテキスト中に名前が出現するたびに、その名前が使われている最も内側の関数ブロック中で作成された 束縛 (binding) を使って名前の参照が行われます。

ブロック(block)は、Python のプログラムテキストからなる断片で、一つの実行単位となるものです。モジュール、関数本体、そしてクラス定義はブロックです。また、対話的に入力された個々のコマンドもブロックです。スクリプトファイル (インタプリタに標準入力として与えたり、コマンドラインの第一引数として指定したファイル) は、コードブロックです。スクリプトコマンド (インタプリタのコマンドライン上で ‘-c‘ オプションを使って指定したコマンド) もコードブロックです。組み込み関数 eval() や exec 文に渡した文字列もコードブロックになります。組み込み関数 input() から読み取られ、評価される式もまた、コードブロックです。

コードブロックは、実行フレーム(execution frame) 上で実行されます。実行フレームには、 (デバッグに使われる) 管理情報が収められています。また、現在のコードブロックの実行が完了した際に、どのようにプログラムの実行を継続するかを決定しています。

スコープ(scope)は、ある名前があるブロック内で参照できるかどうかを決めます。ローカル変数があるブロック内で定義されている場合、変数のスコープはそのブロックを含みます。関数ブロック内で名前の定義を行った場合、その名前に対して別の束縛を行っているブロックを除いた、関数内の全てのブロックを含むようにスコープが拡張されます。クラス内で定義された名前のスコープは、クラスのブロック内に制限されます; スコープがメソッドのコードブロックを含むよう拡張されることはありません。 – ジェネレータ式も関数スコープを利用して実装されているのでスコープの拡張範囲外です。つまり、次のようなコードは失敗します。

class A:
    a = 42
    b = list(a + i for i in range(10))

ある名前がコードブロック内で使われると、その名前を最も近傍から囲うようなスコープ (最内スコープ: nearest enclosing scope) を使って束縛の解決を行います。こうしたスコープからなる、あるコードブロック内で参照できるスコープ全ての集合は、ブロックの環境(environment)と呼ばれます。

ある名前がブロック内で束縛されている場合、名前はそのブロックにおけるローカル変数 (local variable) です。ある名前がモジュールレベルで束縛されている場合、名前はグローバル変数 (global variable) です。 (モジュールコードブロックの変数は、ローカル変数でもあるし、グローバル変数でもあります。) ある変数がコードブロック内で使われているが、そのブロックでは定義されていない場合、変数は自由変数(free variable)です。

ある名前の定義がどこにもない場合、 NameError 例外が送出されます。名前がまだ束縛されていないローカルな変数を参照した場合、 UnboundLocalError 例外が送出されます。 UnboundLocalError は、 NameError のサブクラスです。

名前への束縛は、以下の文構成(construct)で行われます: 関数の仮引数 (formal parameter) 指定、 import 文、クラスや関数の定義 (定義を行ったブロック中で、クラスや関数名の束縛が行われます)、代入時に代入対象が識別子である場合、 for ループのヘッダ、 except 文ヘッダの第二要素、 with 文の中の as の後ろ。

“from...import *” 形式の import 文は、 import しようとするモジュール内で定義されている名前について、アンダースコアから始まっている名前以外の全てを束縛します。この形式は、モジュールレベルでしか使うことができません。

del 文で指定された対象は、(del の意味付けは、実際は名前の解放 (unbind) ですが) 文の目的上、束縛済みのものとみなされます。外側のスコープで参照されている名前の解放は、不正な操作になります; コンパイラは SyntaxError を報告するでしょう。

代入文や import 文はいずれも、クラスや関数定義、モジュールレベル (トップレベルのコードブロック) 内で起こります。

ある名前束縛操作がコードブロック内のどこかにある場合、ブロック内でその名前を使うと、全て現在のブロックで束縛されている名前を指すものとみなされます。このため、ある名前が束縛される前にブロック内で使われるとエラーを引き起こす可能性があります。

この規則はやや微妙です。Python には宣言文がなく、コードブロックのどこで名前束縛操作を行ってもかまいません。あるコードブロックにおけるローカル変数は、ブロック全体から名前束縛操作が行われている部分を走査して決定します。

global 文で指定された名前がブロック内にある場合、その名前は常にトップレベルの名前空間で束縛された名前を参照します。それらの名前はグローバル名前空間、すなわちコードブロックが収められているモジュールの名前空間とモジュール名 __builtin__ で表される組み込み名前空間、を検索することによって、トップレベルの名前空間で解決されます。グローバル名前空間は、常に最初に検索されます。名前がグローバル名前空間中に見つからない場合、組み込み名前空間が検索されます。global 文は、その名前が使われている全ての文に先立って記述されていなければなりません。

あるコードブロックの実行時に関連付けられる組み込み名前空間は、実際にはコードブロックのグローバル名前空間内に入っている名前 __builtins__ を参照する形になっています; __builtins__ は辞書かモジュール (後者の場合にはモジュールの辞書が使われます) でなければなりません。デフォルトで __main__ モジュール中においては、 __builtins__ は組み込みモジュール __builtin__ です (注意: ‘s’ なし)；それ以外のモジュールでは、 __builtins__ は __builtin__ モジュールそれ自身の辞書のエイリアスです。 __builtins__ はユーザが作成した辞書を設定して、弱い形態の制限実行 を作成することが可能です。

CPython implementation detail: ユーザは __builtins__ に触れるべきではありません；これはくれぐれも実装の詳細であるのです。組み込みの名前空間の中の値をオーバーライドしたいユーザは、 __builtin__ (‘s’はありません) モジュールを import して、その属性を好きに変更するべきです。

あるモジュールの名前空間は、そのモジュールが最初に import された時に自動的に作成されます。スクリプトの主モジュール (main module)は常に __main__ と呼ばれます。

global 文は、同じブロックの束縛操作と同じスコープを持ちます。ある自由変数の最内スコープに global 文がある場合、その自由変数はグローバル変数とみなされます。

クラス定義は一つの実行文で、名前の使用や定義を行います。クラス定義への参照は、通常の名前解決規則に従います。クラス定義の名前空間は、そのクラスの属性辞書になります。クラスのスコープで定義された名前は、メソッドからは見えません。

動的な機能とのやりとり

自由変数の入った入れ子スコープ (nested scope) を併用すると、 Python の文が不正な文になる場合がいくつかあります。

ある変数がスコープの外側から参照された場合、その名前に対する削除操作は不正になります。この場合、コンパイル時にエラーが報告されることになります。

ワイルドカード形式の import 文 — import * — を関数内で使った場合や、関数が自由変数を含んでいたり、自由変数を伴う入れ子ブロックである場合、コンパイラは SyntaxError を送出します。

exec が関数内で使われており、関数が自由変数を含んでいたり、自由変数を伴う入れ子ブロックである場合、 exec に明示的にローカル名前空間を指定しないかぎりコンパイラは SyntaxError を送出します。 (別の言い方をすれば、 exec obj は不正になることがあり、 exec obj in ns はならない、ということです。)

eval() 、 execfile() 、および input() 関数、そして exec 文は、名前の解決を行う際に、現在の環境に対して完全にアクセスできるわけではありません。名前が呼び出し側のローカル名前空間やグローバル名前空間から解決されることはあります。自由変数は最内名前空間ではなく、グローバル名前空間から解決されます。 [1]

exec 文と、関数 eval() および execfile() にはオプションの引数があり、グローバルおよびローカル名前空間をオーバライドできます。名前空間を一つしか指定しなければ、両方の名前空間として使われます。

例外

例外とは、コードブロックの通常の制御フローを中断して、エラーやその他の例外的な状況を処理できるようにするための手段です。例外はエラーが検出された時点で送出 (raise) されます; 例外は、エラーが発生部の周辺のコードブロックか、エラーが発生したコードブロック直接または間接的に呼び出しているコードブロックで 処理 (handle) することができます。

Python インタプリタは、ランタイムエラー (ゼロによる除算など) が検出されると例外を送出します。Python プログラムから、 raise 文を使って明示的に例外を送出することもできます。例外ハンドラ (exception handler) は、 try ... except 文で指定することができます。 try 文の finally 節を使うとクリーンアップコード (cleanup code) を指定できます。このコードは例外は処理しませんが、先行するコードブロックで例外が起きても起きなくても実行されます。

Python は、エラー処理に “プログラムの終了 (termination)” モデルを用いています: 例外ハンドラは、プログラムに何が発生したかを把握することができ、ハンドラの外側のレベルに処理を継続することはできますが、(問題のあったコード部分を最初から実行しなおすのでない限り) エラーの原因を修復したり、実行に失敗した操作をやり直すことはできません。

例外が全く処理されない場合、インタプリタはプログラムの実行を終了させるか、対話メインループに処理を戻します。どちらの場合も、例外が SystemExit でない限りバックトレース (backtrace) を出力します。

例外は、クラスインスタンスによって識別されます。 except 節はインスタンスのクラスにもとづいて選択されます：これはインスタンスのクラスか、そのベースクラスを参照します。このインスタンスはハンドラによって受け取られ、例外条件に関する追加情報を伝えることができます。

例外は文字列 (strings) によっても識別することができ、このような場合には except 節はオブジェクトの同一性によって選択されます。任意の値をハンドラに渡される識別文字列に伴って送出することができます。

ノート

例外に対するメッセージは、Python API 仕様には含まれていません。メッセージの内容は、ある Python のバージョンから次のバージョンになるときに、警告なしに変更される可能性があります。したがって、複数バージョンのインタプリタで動作するようなコードにおいては、例外メッセージの内容に依存した記述をすべきではありません。

try 文については、 try 文 節、 raise 文については raise 文節も参照してください。

注記

[1]
この制限は、上記の操作によって実行されるコードが、モジュールをコンパイルしたときには利用できないために起こります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

式 (expression)

この章では、Python の式における個々の要素の意味について解説します。

表記法に関する注意: この章と以降の章での拡張BNF (extended BNF) 表記は、字句解析規則ではなく、構文規則を記述するために用いられています。ある構文規則 (のある表現方法) が、以下の形式

name ::=  othername

で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name の形式をとる構文の意味付けは othername の意味付けと同じになります。

算術変換 (arithmetic conversion)

以下の算術演算子の記述で、「数値引数は共通の型に変換されます」と書かれている場合、引数は 型強制規則 (coercion rule) に記載されている型強制規則に基づいて型強制されます。引数がいずれも標準の数値型である場合、以下の型強制が適用されます:

片方の引数が複素数型であれば、他方は複素数型に変換されます;

それ以外の場合で、片方の引数が浮動小数点数であれば、他方は浮動小数点型に変換されます;

それ以外の場合で、片方の引数が長整数型であれば、他方は長整数型に変換されます;

それ以外の場合で、両方の引数が通常の整数型であれば、変換の必要はありません。

特定の演算子 (文字列を左引数とする ‘%’ 演算子など) では、さらに別の規則が適用されます。拡張をおこなうことで、個々の演算子に対する型強制を定義できます。

アトム、原子的要素 (atom)

アトム (原子的要素: atom) は、式を構成する基本単位です。もっとも単純なアトムは、識別子またはリテラルになります。逆クオートや丸括弧、波括弧、または角括弧で囲われた形式 (form) もまた、文法的にはアトムに分類されます。アトムの構文定義は以下のようになります:

atom      ::=  identifier | literal | enclosure
enclosure ::=  parenth_form | list_display
               | generator_expression | dict_display | set_display
               | string_conversion | yield_atom

識別子 (identifier、または名前 (name))

アトムの形になっている識別子 (identifier) は名前 (name) です。字句定義については 識別子 (identifier) およびキーワード (keyword) 節を、名前付けや束縛については 名前づけと束縛 (naming and binding) 節を参照してください。

名前があるオブジェクトに束縛されている場合、名前アトムを評価するとそのオブジェクトになります。名前が束縛されていない場合、アトムを評価しようとすると NameError 例外を送出します。

プライベートな名前の難号化 (mangling): クラス定義内にテキストの形で書かれた識別子で、二つ以上のアンダースコアから始まり、末尾が二つ以上のアンダースコアになっていないものは、そのクラスの プライベートな名前 (private name) とみなされます。プライベートな名前は、コードが生成される前に、より長い形式の名前に変換されます。この変換では、クラス名の先頭にあるアンダースコアを全てはぎとり、先頭にアンダースコアを一つ挿入して、名前の前に付加します。例えば、クラス Ham 内の識別子 __spam は、 _Ham__spam に変換されます。変換は識別子が使われている構文的コンテキストとは独立しています。変換された名前が非常に長い (255 文字以上) の場合には、実装によっては名前の切り詰めが起きるかもしれません。クラス名がアンダースコアだけから成り立つ場合には、変換は行われません。

リテラル

Python では、文字列リテラルと、様々な数値リテラルをサポートしています:

literal ::=  stringliteral | integer | longinteger
             | floatnumber | imagnumber

リテラルを評価すると、指定した型 (文字列、整数、長整数、浮動小数点数、複素数) の指定した値を持つオブジェクトになります。浮動小数点や虚数 (複素数) リテラルの場合、値は近似値になる場合があります。詳しくは リテラル (literal) を参照してください。リテラルは全て変更不能なデータ型に対応します。このため、オブジェクトのアイデンティティはオブジェクトの値ほど重要ではありません。同じ値を持つ複数のリテラルを評価した場合、(それらのリテラルがプログラムの同じ場所由来のものであっても、そうでなくても) 同じオブジェクトを指しているか、まったく同じ値を持つ別のオブジェクトになります。

丸括弧形式 (parenthesized form)

丸括弧形式とは、式リストの一形態で、丸括弧で囲ったものです:

parenth_form ::=  "(" [expression_list] ")"

丸括弧で囲われた式のリストは、個々の式が表現するものになります: リスト内に少なくとも一つのカンマが入っていた場合、タプルになります; そうでない場合、式のリストを構成している単一の式自体の値になります。

中身が空の丸括弧のペアは、空のタプルオブジェクトを表します。タプルは変更不能なので、リテラルと同じ規則が適用されます (すなわち、空のタプルが二箇所で使われると、それらは同じオブジェクトになることもあるし、ならないこともあります)。

タプルは丸括弧で作成されるのではなく、カンマによって作成されることに注意してください。例外は空のタプルで、この場合には丸括弧が 必要です — 丸括弧のつかない “何も記述しない式 (nothing)” を使えるようにしてしまうと、文法があいまいなものになってしまい、よくあるタイプミスが検出されなくなってしまいます。

リスト表現

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

list_display        ::=  "[" [expression_list | list_comprehension] "]"
list_comprehension  ::=  expression list_for
list_for            ::=  "for" target_list "in" old_expression_list [list_iter]
old_expression_list ::=  old_expression [("," old_expression)+ [","]]
old_expression      ::=  or_test | old_lambda_form
list_iter           ::=  list_for | list_if
list_if             ::=  "if" old_expression [list_iter]

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

集合と辞書の表現

Python は、集合や辞書を構成するために、”表現 (display)” と呼ばれる特殊な構文を、それぞれ二種類づつ提供していて、コンテナの内容は:

明示的に列挙される、または

内包表記 (comprehension) と呼ばれる、ループ処理とフィルター処理の命令の組み合わせを通じて計算されます。

内包表記の共通の構文要素はこの通りです:

comprehension ::=  expression comp_for
comp_for      ::=  "for" target_list "in" or_test [comp_iter]
comp_iter     ::=  comp_for | comp_if
comp_if       ::=  "if" expression_nocond [comp_iter]

内包表記はまず単一の式、続いて for 節、さらに続いて 0 個以上の for 節や if 節からなります。この場合、新たなコンテナの各要素は、各々の for や if 節を、左から右にネストしたブロックとみなして実行し、ネストの最内のブロックに到達する度に式を評価することで作成されたものになります。

なお、これらの内包表記は別のスコープで実行されるので、対象のリスト内で代入された名前が外側のスコープに “漏れる” ことはありません。

ジェネレータ式

ジェネレータ式 (generator expression) とは、丸括弧を使ったコンパクトなジェネレータ表記法です:

generator_expression ::=  "(" expression comp_for ")"

ジェネレータ式は新たなジェネレータオブジェクトを与えます。この構文は内包表記とほぼ同じですが、角括弧や波括弧ではなく、丸括弧で囲まれます。

ジェネレータ式で使われる変数は、ジェネレータオブジェクトに next() メソッドが呼び出されたときに遅延評価されます (通常のジェネレータと同じ流儀です)。しかし、最も左に位置する for 節は直ちに評価されるため、そこで生じたエラーは、ジェネレータ式を扱うコードで起こりえる他のエラーの前に現れることがあります。その後に続く for 節は、その前の for ループに依存しているため、直ちには評価されません。例: (x*y for x in range(10) for y in bar(x))

関数の唯一の引数として渡す場合には、丸括弧を省略できます。詳しくは 呼び出し (call) 節を参照してください。

辞書表現

辞書表現は、波括弧で囲われた、キーと値のペアからなる系列です。系列は空の系列であってもかまいません:

dict_display       ::=  "{" [key_datum_list | dict_comprehension] "}"
key_datum_list     ::=  key_datum ("," key_datum)* [","]
key_datum          ::=  expression ":" expression
dict_comprehension ::=  expression ":" expression comp_for

辞書表現は、新たな辞書オブジェクトを表します。

カンマ区切りの一連のキー/データの対が与えられたときは、その要素は左から右へ評価され、辞書の項目を定義します。すなわち、それぞれのキーオブジェクトが、辞書内で対応するデータを保存するキーとして使われます。これにより、キー/データリストの中で同じキーを複数回指定することができ、そのキーに対する最終的な辞書の値は、最後に与えられたものになります。

辞書内包表記は、リストや集合の内包表記とは対照的に、通常の “for” や “if” 節の前に、コロンで分けられた 2 つの式が必要です。内包表記が起動すると、結果のキーと値の要素が、作られた順に新しい辞書に挿入されます。

キーの値として使える型に関する制限は 標準型の階層 節ですでに列挙しています。(一言でいうと、キーは変更可能なオブジェクトを全て排除した hashable でなければなりません。) 重複するキー間で衝突が起きても、衝突が検出されることはありません; あるキーに対して、最後に渡されたデータ (プログラムテキスト上では、辞書表記の最も右側値となるもの) が使われます。

集合表現

集合表現は波括弧で表され、キーと値を分けるコロンがないことで辞書表現と区別されます:

set_display ::=  "{" (expression_list | comprehension) "}"

集合表示は、一連の式または内包表記によって指定された内容の、ミュータブルな集合オブジェクトを与えます。カンマ区切りの一連の式が与えられたときは、その要素は左から右へ順に評価され、集合オブジェクトに加えられます。内包表記が与えられたときは、内包表記の結果となる要素で集合が構成されます。

空集合は {} で構成できません。このリテラルは空の辞書を構成します。

文字列変換

文字列変換は、逆クオート (reverse quite, 別名バッククオート: backward quote) で囲われた式のリストです:

string_conversion ::=  "'" expression_list "'"

文字列変換は、逆クオート内の式リストを評価して、評価結果のオブジェクトを各オブジェクトの型特有の規則に従って文字列に変換します。

オブジェクトが文字列、数値、 None か、それらの型のオブジェクトのみを含むタプル、リストまたは辞書の場合、評価結果の文字列は有効な Python 式となり、組み込み関数 eval() に渡した場合に同じ値となります (浮動小数点が含まれている場合には近似値の場合もあります)。

(特に、文字列を変換すると、値を安全に出力するために文字列の両側にクオートが付けられ、”変 (funny) な” 文字はエスケープシーケンスに変換されます。)

再帰的な構造をもつオブジェクト (例えば自分自身を直接または間接的に含むリストや辞書) では ... を使って再帰的参照であることが示され、オブジェクトの評価結果は eval() に渡しても等価な値を得ることができません (SyntaxError が送出されます)。

組み込み関数 repr() は、括弧内の引数に対して、逆クオート表記で囲われた中身と全く同じ変換を実行します。組み込み関数 str() は似たような動作をしますが、もっとユーザフレンドリな変換になります。

Yield 式

yield_atom       ::=  "(" yield_expression ")"
yield_expression ::=  "yield" [expression_list]

バージョン 2.5 で追加.

yield 式はジェネレータ関数を定義するときにその関数の内部でのみ使用されます。関数内で yield 式を使用すると、普通の関数ではなくジェネレータ関数が作成されます。

ジェネレータ関数が呼び出されるとき、ジェネレータとしてのイテレータを返します。そのジェネレータはジェネレータ関数の実行を制御します。ジェネレータのメソッドが呼び出されるときに実行が開始されます。メソッドを呼び出すと、実行は yield の最初の位置まで処理されて一時停止します。そして、ジェネレータの呼び出し元へ expression_list の値を返します。ここで言う一時停止とは、ローカル変数の束縛、命令ポインタや内部の評価スタックを含めたローカルの全ての状態が保持されることを指します。再度、ジェネレータのメソッドを呼び出して実行を再開するとき、そのジェネレータ関数はまさに yield 式がただの外部呼び出しであったかのように処理が継続されます。再開した後の yield 式の値は実行を再開するメソッドに依存します。

これまで説明した内容から、ジェネレータ関数はコルーチンにとてもよく似ています。ジェネレータ関数は何度も生成し、1つ以上のエントリポイントを持ち、その実行は一時停止されます。ジェネレータ関数は yield した後で実行の継続を制御できないことが唯一の違いです。その制御は常にジェネレータの呼び出し元へ移されます。

以下のジェネレータメソッドはジェネレータ関数の実行を制御するために使用されます。

generator.next()

ジェネレータ関数の実行を開始する、または最後に yield 式が実行された位置から再開します。ジェネレータ関数が next() メソッドで再開されるとき、カレントの yield は常に None に対して評価されます。それから実行は、次の yield 式の位置まで継続されて、再度そのジェネレータは一時停止します。そして expression_list の値が next() の呼び出し元へ返されます。ジェネレータが値を生成することなく終了すると StopIteration が発生します。

generator.send(value)

ジェネレータ関数の内部へ値を “送り”、実行を再開します。引数の value はカレントの yield 式の結果になります。 send() メソッドはジェネレータが生成した次の値、またはジェネレータが値を生成することなく終了すると StopIteration が発生します。ジェネレータが再開するために send() を呼び出すときは、引数として None を指定しなければなりません。そうしないと、値を受け取る yield 式が存在しないからです。

generator.throw(type[, value[, traceback]])

ジェネレータが中断した位置で type 型の例外を発生させて、ジェネレータ関数が生成する次の値を返します。ジェネレータが値を生成することなく終了すると StopIteration が発生します。ジェネレータ関数が渡された例外を捕捉しない、もしくは違う例外を発生させるなら、その例外は呼び出し元へ伝搬されます。

generator.close()

ジェネレータ関数が中断した位置で GeneratorExit を発生させます。ジェネレータ関数が (通常の終了または既にクローズされたことで) StopIteration 、もしくは (例外を捕捉しないことで) GeneratorExit を発生させる場合 close() は呼び出し元へ返されます。ジェネレータが値を生成する場合 RuntimeError が発生します。 close() はジェネレータが通常の終了または例外により既に終了している場合は何もしません。

以下の簡単なサンプルはジェネレータとジェネレータ関数の振る舞いを実際に紹介します:

>>> def echo(value=None):
...     print "Execution starts when 'next()' is called for the first time."
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception, e:
...                 value = e
...     finally:
...         print "Don't forget to clean up when 'close()' is called."
...
>>> generator = echo(1)
>>> print generator.next()
Execution starts when 'next()' is called for the first time.
1
>>> print generator.next()
None
>>> print generator.send(2)
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

参考

PEP 0342 [http://www.python.org/dev/peps/pep-0342] - 拡張されたジェネレータを用いたコルーチン

シンプルなコルーチンとして利用できるように、ジェネレータの構文と API を拡張する提案です。

一次語 (primary)

一次語は、言語において最も結合の強い操作を表します。文法は以下のようになります:

primary ::=  atom | attributeref | subscription | slicing | call

属性参照

属性参照は、一次語の後ろにピリオドと名前を連ねたものです:

attributeref ::=  primary "." identifier

一次語の値評価結果は、例えばモジュール、リスト、インスタンスといった、属性参照をサポートする型でなければなりません。オブジェクトは次に、指定した名前が識別子名となっているような属性を生成するよう問い合わせされます。問い合わせた属性が得られない場合、例外 AttributeError が送出されます。それ以外の場合、オブジェクトは属性オブジェクトの型と値を決定し、生成して返します。同じ属性参照を複数回評価したとき、互いに異なる属性オブジェクトになることがあります。

添字表記 (subscription)

添字表記は、シーケンス (文字列、タプルまたはリスト) やマップ (辞書) オブジェクトから、要素を一つ選択します:

subscription ::=  primary "[" expression_list "]"

一次語の値評価結果は、シーケンス型かマップ型のオブジェクトでなければなりません。

一次語がマップであれば、式リストの値評価結果はマップ内のいずれかのキー値に相当するオブジェクトにならなければなりません。添字表記は、そのキーに対応するマップ内の値 (value) を選択します。 (式リストの要素が単独である場合を除き、式リストはタプルでなければなりません。)

一次語がシーケンスの場合、式 (リスト) の値評価結果は (通常の) 整数でなければなりません。値が負の場合、シーケンスの長さが加算されます (x[-1] が x の最後の要素を指すことになります)。加算結果はシーケンス内の要素数よりも小さな非負の整数とならなければなりません。添字表記は、添字と同じシーケンス中の (ゼロから数えた) インデクスを持つ要素を選択します。

文字列型の要素は文字 (character) です。文字は個別の型ではなく、 1 文字だけからなる文字列です。

スライス表記 (slicing)

スライス表記はシーケンスオブジェクト (文字列、タプルまたはリスト) におけるある範囲の要素を選択します。スライス表記は式として用いたり、代入や del 文の対象として用いたりできます。スライス表記の構文は以下のようになります:

slicing          ::=  simple_slicing | extended_slicing
simple_slicing   ::=  primary "[" short_slice "]"
extended_slicing ::=  primary "[" slice_list "]"
slice_list       ::=  slice_item ("," slice_item)* [","]
slice_item       ::=  expression | proper_slice | ellipsis
proper_slice     ::=  short_slice | long_slice
short_slice      ::=  [lower_bound] ":" [upper_bound]
long_slice       ::=  short_slice ":" [stride]
lower_bound      ::=  expression
upper_bound      ::=  expression
stride           ::=  expression
ellipsis         ::=  "..."

上記の形式的な構文法にはあいまいさがあります: 式リストに見えるものは、スライスリストにも見えるため、添字表記はスライス表記としても解釈されうるということです。この場合には、(スライスリストの評価結果が、適切なスライスや省略表記 (ellipsis) にならない場合)、スライス表記としての解釈よりも添字表記としての解釈の方が高い優先順位を持つように定義することで、構文法をより難解にすることなくあいまいさを取り除いています。同様に、スライスリストが厳密に一つだけの短いスライスで、末尾にカンマが続いていない場合、拡張スライスとしての解釈より、単純なスライスとしての解釈が優先されます。

単純なスライスに対する意味付けは以下のようになります。一次語の値評価結果は、シーケンス型のオブジェクトでなければなりません。下境界および上境界を表す式がある場合、それらの値評価結果は整数でなくてはなりません; デフォルトの値は、それぞれゼロと sys.maxint です。どちらかの境界値が負である場合、シーケンスの長さが加算されます。こうして、スライスは i および j をそれぞれ指定した下境界、上境界として、インデクス k が i <= k < j となる全ての要素を選択します。選択の結果、空のシーケンスになることもあります。 i や j が有効なインデクス範囲の外側にある場合でも、エラーにはなりません (範囲外の要素は存在しないので、選択されないだけです)。

拡張スライスに対する意味付けは、以下のようになります。一次語の値評価結果は、辞書型のオブジェクトでなければなりません。また、辞書は以下に述べるようにしてスライスリストから生成されたキーによってインデクス指定できなければなりません。スライスリストに少なくとも一つのカンマが含まれている場合、キーは各スライス要素を値変換したものからなるタプルになります; それ以外の場合、単一のスライス要素自体を値変換したものがキーになります。一個の式でできたスライス要素の変換は、その式になります。省略表記スライス要素の変換は、組み込みの Ellipsis オブジェクトになります。適切なスライスの変換は、スライスオブジェクト (標準型の階層 参照) で start, stop および step 属性は、それぞれ指定した下境界、上境界、およびとび幅 (stride) になります。式がない場合には None に置き換えられます。

呼び出し (call)

呼び出し (call) は、呼び出し可能オブジェクト (callable object, 例えば関数など) を、引数列とともに呼び出します。引数列は空のシーケンスでもかまいません:

call                 ::=  primary "(" [argument_list [","]
                          | expression genexpr_for] ")"
argument_list        ::=  positional_arguments ["," keyword_arguments]
                            ["," "*" expression] ["," keyword_arguments]
                            ["," "**" expression]
                          | keyword_arguments ["," "*" expression]
                            ["," "**" expression]
                          | "*" expression ["," "*" expression] ["," "**" expression]
                          | "**" expression
positional_arguments ::=  expression ("," expression)*
keyword_arguments    ::=  keyword_item ("," keyword_item)*
keyword_item         ::=  identifier "=" expression

固定引数やキーワード引数の後ろにカンマをつけてもかまいません。構文の意味付けに影響を及ぼすことはありません。

一次語の値評価結果は、呼び出し可能オブジェクトでなければなりません (ユーザ定義関数、組み込み関数、組み込みオブジェクトのメソッド、クラスオブジェクト、クラスインスタンスのメソッド、そして特定のクラスインスタンス自体が呼び出し可能です; 拡張によって、その他の呼び出し可能オブジェクト型を定義することができます)。引数式は全て、呼び出しを試みる前に値評価されます。仮引数 (formal parameter) リストの構文については 関数定義 を参照してください。

キーワード引数が存在する場合、以下のようにして最初に固定引数 (positional argument) に変換されます。まず、値の入っていないスロットが仮引数に対して生成されます。N 個の固定引数がある場合、固定引数は先頭の N スロットに配置されます。次に、各キーワード引数について、識別子を使って対応するスロットを決定します (識別子が最初の仮引数パラメタ名と同じなら、最初のスロットを使う、といった具合です)。スロットがすでにすべて埋まっていたなら TypeError 例外が送出されます。それ以外の場合、引数値をスロットに埋めていきます。 (式が None であっても、その式でスロットを埋めます)。全ての引数が処理されたら、まだ埋められていないスロットをそれぞれに対応する関数定義時のデフォルト値で埋めます。(デフォルト値は、関数が定義されたときに一度だけ計算されます; 従って、リストや辞書のような変更可能なオブジェクトがデフォルト値として使われると、対応するスロットに引数を指定しない限り、このオブジェクトが全ての呼び出しから共有されます; このような状況は通常避けるべきです。) デフォルト値が指定されていない、値の埋められていないスロットが残っている場合 TypeError 例外が送出されます。そうでない場合、値の埋められたスロットからなるリストが呼び出しの引数として使われます。

CPython implementation detail: 実際の実装では、名前を持たない固定引数を受け取る組み込み関数を提供するかもしれません。そういった組み込み関数がドキュメント化の目的で ‘名前’ を設けていたとしても、実際には持っていないのでキーワードによって提供されません。 CPython では、C 言語で実装された関数の名前を持たない固定引数を解析するために PyArg_ParseTuple() を使用します。

仮引数スロットの数よりも多くの固定引数がある場合、構文 *identifier を使って指定された仮引数がないかぎり、 TypeError 例外が送出されます; 仮引数 *identifier がある場合、この仮引数は余分な固定引数が入ったタプル (もしくは、余分な固定引数がない場合には空のタプル) を受け取ります。

キーワード引数のいずれかが仮引数名に対応しない場合、構文 **identifier を使って指定された仮引数がない限り、 TypeError 例外が送出されます; 仮引数 **identifier がある場合、この仮引数は余分なキーワード引数が入った (キーワードをキーとし、引数値をキーに対応する値とした) 辞書を受け取ります。余分なキーワード引数がない場合には、空の (新たな) 辞書を受け取ります。

関数呼び出しの際に *expression 構文が使われる場合、 expression の値評価結果はシーケンスでなくてはなりません。このシーケンスの要素は、追加の固定引数のように扱われます; すなわち、固定引数 x1 ,..., xN と、 y1 ,..., yM になるシーケンス expression を使った場合、M+N 個の固定引数 x1 ,..., xN , y1 ,..., yM を使った呼び出しと同じになります。

*expression 構文はキーワード引数の 後ろ で指定しても良いですが、キーワード引数よりも 前 で指定されたものとして処理されます ( **expression 引数を指定したときの振る舞いは以下を参照)。従って:

>>> def f(a, b):
...  print a, b
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2

となります。

キーワード引数と *expression 構文を同じ呼び出しで一緒に使うことはあまりないので、実際に上記のような混乱が生じることはありません。

関数呼び出しで **expression 構文が使われた場合、 expression の値評価結果はマップ型でなければなりません。辞書の内容は追加のキーワード引数として扱われます。明示的なキーワード引数が expression 内のキーワードと重複した場合には TypeError 例外が送出されます。

*identifier や **identifier 構文を使った仮引数は、固定引数スロットやキーワード引数名にすることができません。 (sublist) 構文を使った仮引数は、キーワード引数名には使えません; sublist は、リスト全体が一つの無名の引数スロットに対応しており、sublist 中の引数は、他の全てのパラメタに対する処理が終わった後に、通常のタプル形式の代入規則を使ってスロットに入れられます。

呼び出しを行うと、例外を送出しない限り、常に何らかの値を返します。 None を返す場合もあります。戻り値がどのように算出されるかは、呼び出し可能オブジェクトの形態によって異なります。

呼び出し可能オブジェクトが。。。

ユーザ定義関数のとき:

関数のコードブロックに引数リストが渡され、実行されます。コードブロックは、まず仮引数を実引数に結合 (bind) します; この動作については関数定義 で記述しています。コードブロックで return 文が実行される際に、関数呼び出しの戻り値 (return value) が決定されます。

組み込み関数や組み込みメソッドのとき:

結果はインタプリタに依存します; 組み込み関数やメソッドの詳細は 組み込み関数 を参照してください。

クラスオブジェクトのとき:

そのクラスの新しいインスタンスが返されます。

クラスインスタンスメソッドのとき:

対応するユーザ定義の関数が呼び出されます。このとき、呼び出し時の引数リストより一つ長い引数リストで呼び出されます: インスタンスが引数リストの先頭に追加されます。

クラスインスタンスのとき:

クラスで __call__() メソッドが定義されていなければなりません; __call__() メソッドが呼び出された場合と同じ効果をもたらします。

べき乗演算 (power operator)

べき乗演算は、左側にある単項演算子よりも強い結合優先順位があります; 一方、右側にある単項演算子よりは低い結合優先順位になっています。構文は以下のようになります:

power ::=  primary ["**" u_expr]

従って、べき乗演算子と単項演算子からなる演算列が丸括弧で囲われていない場合、演算子は右から左へと評価されます (この場合は演算子の評価順序を強制しません。つまり -1**2 は -1 になります)。

べき乗演算子は、二つの引数で呼び出される組み込み関数 pow() と同じ意味付けを持っています。引数はまず共通の型に変換されます。結果の型は、型強制後の引数の型になります。

引数型を混合すると、二項算術演算における型強制規則が適用されます。整数や長整数の被演算子の場合、第二引数が負でない限り、結果は (型強制後の) 被演算子と同じになります; 第二引数が負の場合、全ての引数は浮動小数点型に変換され、浮動小数点型が返されます。例えば 10**2 は 100 を返しますが、 10**-2 は 0.01 を返します。 (上述の仕様のうち、最後のものは Python 2.2 で追加されました。 Python 2.1 以前では、双方の引数が整数型で、第二引数が負の場合、例外が送出されていました。)

0.0 を負の数でべき乗すると ZeroDivisionError を送出します。負の数を小数でべき乗すると ValueError になります。

単項算術演算とビット単位演算(unary arithmetic and bitwise operation)

全ての単項算術演算とビット単位演算は、同じ優先順位を持っています:

u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr

単項演算子 - (マイナス) は、引数となる数値の符号を反転 (invert) します。

単項演算子 + (プラス) は、数値引数を変更しません。

単項演算子 ~ (反転) は、整数または長整数の引数をビット単位反転 (bitwise invert) します。 x のビット単位反転は、 -(x+1) として定義されています。この演算子は整数にのみ適用されます。

上記の三つはいずれも、引数が正しい型でない場合には TypeError 例外が送出されます。

二項算術演算 (binary arithmetic operation)

二項算術演算は、慣習的な優先順位を踏襲しています。演算子のいずれかは、特定の非数値型にも適用されるので注意してください。べき乗 (power) 演算子を除き、演算子には二つのレベル、すなわち乗算的 (multiplicatie) 演算子と加算的 (additie) 演算子しかありません:

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr
            | m_expr "%" u_expr
a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

* (乗算: multiplication) 演算は、引数間の積になります。引数の組は、双方ともに数値型であるか、片方が整数 (通常の整数または長整数) 型で他方がシーケンス型かのどちらかでなければなりません。前者の場合、数値は共通の型に変換された後乗算されます。後者の場合、シーケンスの繰り返し操作が行われます。繰り返し数を負にすると、空のシーケンスになります。

/ (除算: division) および // (切り捨て除算: floor division) は、引数間の商になります。数値引数はまず共通の型に変換されます。整数または長整数の除算結果は、同じ型の整数になります; この場合、結果は数学的な除算に関数 ‘floor’ を適用したものになります。ゼロによる除算を行うと ZeroDivisionError 例外を送出します。

% (モジュロ: modulo) 演算は、第一引数を第二引数で除算したときの剰余になります。数値引数はまず共通の型に変換されます。右引数値がゼロの場合には ZeroDivisionError 例外が送出されます。引数値は浮動小数点でもよく。例えば 3.14%0.7 は 0.34 になります (3.14 は 4*0.7 + 0.34 だからです)。モジュロ演算子は常に第二引数と同じ符号 (またはゼロ) の結果になります; モジュロ演算の結果の絶対値は、常に第二引数の絶対値よりも小さくなります。 [2]

整数による除算演算やモジュロ演算は、恒等式: x == (x/y)*y + (x%y) と関係しています。整数除算やモジュロはまた、組み込み関数 divmod(): divmod(x, y) == (x/y, x%y) と関係しています。これらの恒等関係は浮動小数点の場合には維持されません; x/y が floor(x/y) や floor(x/y) - 1 に置き換えられた場合、これらの恒等式は近似性を維持します。 [3]

数値に対するモジュロ演算の実行に加えて % 演算子は文字列 (string) とユニコードオブジェクトにオーバーロードされ、文字列の書式化 (文字列の挿入としても知られる) を行います。文字列の書式化の構文は Python ライブラリリファレンス 文字列フォーマット操作 節を参照してください。

バージョン 2.3 で撤廃: 切り捨て除算演算子、モジュロ演算子、および divmod() 関数は、複素数に対してはもはや定義されていません。目的に合うならば、代わりに abs() を使って浮動小数点に変換してください。

+ (加算) 演算は、引数を加算した値を返します。引数は双方とも数値型か、双方とも同じ型のシーケンスでなければなりません。前者の場合、数値は共通の型に変換され、加算されます。後者の場合、シーケンスは結合 (concatenate) されます。

- (減算) 演算は、引数間で減算を行った値を返します。数値引数はまず共通の型に変換されます。

シフト演算 (shifting operation)

シフト演算は、算術演算よりも低い優先順位を持っています:

shift_expr ::=  a_expr | shift_expr ( "<<" | ">>" ) a_expr

シフトの演算子は整数または長整数を引数にとります。引数は共通の型に変換されます。シフト演算では、最初の引数を二つ目の引数に応じたビット数だけ、左または右にビットシフトします。

n ビットの右シフトは pow(2,n) による除算として定義されています。 n ビットの左シフトは pow(2,n) による乗算として定義されます。負のビット数でシフトを行うと ValueError 例外を送出します。

ノート

現在の実装では、右辺被演算子は最大でも sys.maxsize でなければなりません。右辺被演算子が sys.maxsize よりも大きいと、 OverflowError 例外が送出されます。

ビット単位演算の二項演算 (binary bitwise operation)

以下の三つのビット単位演算には、それぞれ異なる優先順位レベルがあります:

and_expr ::=  shift_expr | and_expr "&" shift_expr
xor_expr ::=  and_expr | xor_expr "^" and_expr
or_expr  ::=  xor_expr | or_expr "|" xor_expr

& 演算子は、引数間でビット単位の AND をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

^ 演算子は、引数間でビット単位の XOR (排他的 OR) をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

| 演算子は、引数間でビット単位の OR (非排他的 OR) をとった値になります。引数は整数または長整数でなければなりません。引数は共通の型に変換されます。

比較 (comparison)

C 言語と違って、Python における比較演算子は同じ優先順位をもっており、全ての算術演算子、シフト演算子、ビット単位演算子よりも低くなっています。また a < b < c が数学で伝統的に用いられているのと同じ解釈になる点も C 言語と違います:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
                   | "is" ["not"] | ["not"] "in"

比較演算の結果はブール値: True または False になります。

比較はいくらでも連鎖することができます。例えば x < y <= z は x < y and y <= z と等価になります。ただしこの場合、前者では y はただ一度だけ評価される点が異なります (どちらの場合でも、 x < y が偽になると z の値はまったく評価されません)。

形式的には、 a, b, c, ..., y, z が式で op1, op2, ..., opN が比較演算子である場合、 a op1 b op2 c ... y opN z は a op1 b and b op2 c and ... y opN z と等価になります。ただし、前者では各式は多くても一度しか評価されません。

a op1 b op2 c と書いた場合、 a から c までの範囲にあるかどうかのテストを指すのではないことに注意してください。例えば x < y > z は (きれいな書き方ではありませんが) 完全に正しい文法です。

<> と != の二つの形式は等価です; C との整合性を持たせるためには != を推奨します; 以下で != について触れている部分では <> を使うこともできます。 <> のような書き方は、現在では古い書き方とみなされています。

演算子 <, >, ==, >=, <=, および != は、二つのオブジェクト間の値を比較します。オブジェクトは同じ型である必要はありません。双方のオブジェクトが数値であれば、共通型への変換が行われます。それ以外の場合、異なる型のオブジェクトは 常に 不等であるとみなされ、一貫してはいるが規定されていない方法で並べられます。組み込み型でないオブジェクト比較の振る舞いは __cmp__ メソッドや __gt__ といったリッチな比較メソッドを定義することでコントロールすることができます。これは 特殊メソッド名 セクションで説明されています。

(このような比較演算の変則的な定義は、ソートのような操作や in および not in といった演算子の定義を単純化するためのものです。将来、異なる型のオブジェクト間における比較規則は変更されるかもしれません。)

同じ型のオブジェクト間における比較は、型によって異なります:

数値間の比較では、算術的な比較が行われます。

文字列間の比較では、各文字に対する等価な数値型 (組み込み関数 ord() の結果) を使って辞書的な (lexicographically) 比較が行われます。Unicode および 8 ビット文字列は、この動作に関しては完全に互換です。 [4]

タプルやリスト間の比較では、対応する各要素の比較結果を使って辞書的な比較が行われます。このため、二つのシーケンスを等価にするためには、各要素が完全に等価でなくてはならず、シーケンスは同じ型で同じ長さをもっていなければなりません。

二つのシーケンスが等価でない場合、異なる値を持つ最初の要素間での比較に従った順序関係になります。例えば cmp([1,2,x], [1,2,y]) は cmp(x,y) と等しい結果を返します。片方の要素に対応する要素が他方にない場合、より短いシーケンスが前に並びます (例えば、 [1,2] < [1,2,3] となります)。

マップ (辞書) 間の比較では、(key, value) からなるリストをソートしたものが等しい場合に等価になります。 [5] 等価性評価以外の結果は一貫したやりかたで解決されるか、定義されないかのいずれかです。 [6]

その他のほとんどの組み込み型のオブジェクト比較では、同じオブジェクトでないかぎり等価にはなりません；あるオブジェクトの他のオブジェクトに対する大小関係は任意に決定され、一つのプログラムの実行中は一貫したものとなります。

演算子 in および not in は、コレクション型の要素であるかどうか (メンバシップ、membership) を調べます。 x in s は、 x がコレクション型 s のメンバである場合には真となり、それ以外の場合には偽となります。 x not in s は x in s の否定 (negation) を返します。コレクション型のメンバシップテストは、伝統的にはシーケンス型に限定されてきました; すなわち、あるオブジェクトがコレクション型のメンバとなるのは、そのコレクション型がシーケンスであり、シーケンスがオブジェクトと等価な要素を含む場合でした。しかし、他の多くのオブジェクトのためにシーケンスでなくてもメンバシップテストをサポートしています。特に、辞書型では、(キーのための)メンバシップテストをサポートしています。

リストやタプル型について x in y は x == y[i] となるようなインデクス i が存在するとき、かつそのときに限り真になります。

Unicode 文字列または文字列型については、 x in y は x が y の部分文字列であるとき、かつそのときに限り真になります。この演算と等価なテストは y.find(x) != -1 です。 x および y は同じ型である必要はないので注意してください。すなわち u'ab' in 'abc' は True を返すことになります。空文字列は、他のどんな文字列に対しても常に部分文字列とみなされます。従って "" in "abc" は True を返すことになります。

バージョン 2.3 で変更: 以前は、 x は長さ 1 の文字列型でなければなりませんでした.

__contains__() メソッドの定義されたユーザ定義クラスでは、 x in y が真となるのは y.__contains__(x) が真となるとき、かつそのときに限ります。

__contains__() を定義していないが __iter__() は定義しているユーザ定義クラスでは、 x in y は x == z となるようなある値 z が y 内にわたる反復で生成された場合、 true となります。もし、反復の間に例外が発生すれば、 in が例外を発生させたようにみえます。

最終的には、旧式の反復プロトコルの実行を試みます、もし __getitem__() を定義しているようなユーザ定義クラスでは、 x in y は x == y[i] となるような非負の整数インデクス i が存在するとき、かつそのときにかぎり真となります。インデクス i が負である場合に IndexError 例外が送出されることはありません。 (別の何らかの例外が送出された場合、例外は in から送出されたかのようになります)。

演算子 not in は in の真値を反転した値として定義されています。

演算子 is および is not は、オブジェクトのアイデンティティに対するテストを行います: x is y は、 x と y が同じオブジェクトを指すとき、かつそのときに限り真になります。 x is not y は is の真値を反転したものになります。 [7]

ブール演算 (boolean operation)

or_test  ::=  and_test | or_test "or" and_test
and_test ::=  not_test | and_test "and" not_test
not_test ::=  comparison | "not" not_test

ブール演算のコンテキストや、式が制御フロー文中で使われる最には、以下の値: False 、 None 、すべての型における数値のゼロ、空の文字列とコンテナ (文字列、タプル、リスト、辞書、set、frozenset を含む) は偽 (false) であると解釈されます。それ以外の値は真 (true) であると解釈されます。 (この振る舞いを変更する方法については特殊メソッド __nonzero__() を参照してください)

演算子 not は、引数が偽である場合には 1 を、それ以外の場合には 0 になります。

式 x and y は、まず x を評価します; x が偽なら x の値を返します; それ以外の場合には、 y の値を評価し、その結果を返します。

式 x or y は、まず x を評価します; x が真なら x の値を返します; それ以外の場合には、 y の値を評価し、その結果を返します。

(and も not も、返す値を 0 や 1 に制限するのではなく、最後に評価した引数の値を返すので注意してください。この仕様は、例えば s を文字列として s が空文字列の場合にデフォルトの値に置き換えるような場合に、 s or 'foo' と書くと期待通りの値になるために便利なことがあります。 not は、式の値でなく独自に値を作成して返すので、引数と同じ型の値を返すような処理に煩わされることはありません。例えば、 not 'foo' は、 '' ではなく 0 になります)

条件演算 (Conditional Expressions)

バージョン 2.5 で追加.

conditional_expression ::=  or_test ["if" or_test "else" expression]
expression             ::=  conditional_expression | lambda_form

条件演算式 (しばしば、”三項演算子” と呼ばれます) は最も優先度が低いPython の操作です。

x if C else y という式は最初に条件 C (x では ありません) を評価します; C が true の場合 x が評価され値が返されます; それ以外の場合には y が評価され返されます。

条件演算に関してより詳しくは PEP 308 [http://www.python.org/dev/peps/pep-0308] を参照してください。

ラムダ (lambda)

lambda_form     ::=  "lambda" [parameter_list]: expression
old_lambda_form ::=  "lambda" [parameter_list]: old_expression

ラムダ形式 (lambda form, ラムダ式 (lambda expression)) は、構文法的には式と同じ位置付けになります。ラムダは、無名関数を作成できる省略記法です; 式 lambda arguments: expression は、関数オブジェクトになります。ラムダが表す無名オブジェクトは、以下のコード

def name(arguments):
    return expression

で定義された関数と同様に動作します。

引数リストの構文法については 関数定義 節を参照してください。ラムダ形式で作成された関数は、実行文 (statement) を含むことができないので注意してください。

式のリスト

expression_list ::=  expression ( "," expression )* [","]

少なくとも一つのカンマを含む式のリストは、タプルになります。タプルの長さは、リスト中の式の数に等しくなります。リスト中の式は左から右へと順に評価されます。

単一要素のタプル (別名 単集合 (singleton) ) を作りたければ、末尾にカンマが必要です。単一の式だけで、末尾にカンマをつけない場合には、タプルではなくその式の値になります (空のタプルを作りたいなら、中身が空の丸括弧ペア: () を使います。)

評価順序

Python は、式を左から右へと順に評価してゆきます。ただし、代入式を評価する最には、代入演算子の右側項が左側項よりも先に評価されるので注意してください。

以下に示す実行文の各行での評価順序は、添え字の数字順序と同じになります:

expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2

まとめ

以下の表は、Python における演算子を、優先順位 の最も低い (結合度が最も低い) ものから最も高い (結合度が最も高い) ものの順に並べたものです。同じボックス内に示された演算子は同じ優先順位を持ちます。演算子の文法が示されていないかぎり、演算子は全て二項演算子です。同じボックス内の演算子は、左から右へとグループ化されます (値のテストを含む比較演算子を除きます。比較演算子は、左から右に連鎖します — 比較 (comparison) を参照してください。また、べき乗演算子も除きます。べき乗演算子は右から左にグループ化されます)。

演算子 | 説明
lambda | ラムダ式
if – else | 条件演算
or | ブール演算 OR
and | ブール演算 AND
not x | ブール演算 NOT
== in, not in, is, is not, <, <=, >, >=, <>, !=, == | メンバシップテスト、アイデンティティテストを含めた比較
| | ビット単位 OR
^ | ビット単位 XOR
& | ビット単位 AND
<<, >> | シフト演算
+, - | 加算および減算
*, /, //, % | 乗算、除算、剰余
+x, -x, ~x | 正符号、負符号、ビット単位 NOT
** | べき乗 [8]
x[index], x[index:index], x(arguments...), x.attribute | 添字指定、スライス操作属性参照
(expressions...), [expressions...], {key:datum...}, `expressions...` | 式結合またはタプル表現、リスト表現、辞書表現、文字列への型変換

注記

[1]
Python 2.3 以降のリスト内包は for の中で使う制御変数を内包表記内のスコープに「リーク」します。しかし、この挙動は廃止予定です。Python 3.0 ではこの挙動に依存したコードは動作しなくなります。

[2]
abs(x%y) < abs(y) は数学的には真となりますが、浮動小数点に対する演算の場合には、値丸め (roundoff) のために数値計算的に真にならない場合があります。例えば、Python の浮動小数点型が IEEE754 倍精度数型になっているプラットフォームを仮定すると、 -1e-100 % 1e100 は 1e100 と同じ符号になるはずなのに、計算結果は -1e-100 + 1e100 となります。これは数値計算的には厳密に 1e100 と等価です。関数 math.fmod() は、最初の引数と符号が一致するような値を返すので、上記の場合には -1e-100 を返します。どちらのアプローチが適切かは、アプリケーションに依存します。

[3]
x が y の整数倍に非常に近い場合、丸め誤差によって floor(x/y) は (x-x%y)/y よりも大きな値になる可能性があります。そのような場合、 Python は divmod(x,y)[0] * y + x % y が x に非常に近くなるという関係を保つために、後者の値を返します。

[4]
ユニコード文字列間の比較はバイトレベルでは当然とはいえ、ユーザにとっては直感的ではないかもしれません。例えば、文字列 u"\u00C7" と u"\u0043\u0327" の比較は、両方の文字列が同じユニコード文字(LATIN CAPITAL LETTER C WITH CEDILLA)で表されたとしても違います。人間が分かり易い方法で文字列を比較するために unicodedata.normalize() を使用して比較してください。

[5]
実装では、この演算をリストを構築したりソートしたりすることなく効率的に行います。

[6]
Python の初期のバージョンでは、ソートされた (key, value) のリストに対して辞書的な比較を行っていましたが、これは等価性の計算のようなよくある操作を実現するには非常にコストの高い操作でした。もっと以前のバージョンの Python では、辞書はアイデンティティだけで比較されていました。しかしこの仕様は、 {} との比較によって辞書が空であるか確かめられると期待していた人々を混乱させていました。

[7]
自動的なガベージコレクション、フリーリスト、ディスクリプタの動的特性のために、インスタンスメソッドや定数の比較を行うようなときに is 演算子の利用は、一見すると普通ではない振る舞いだと気付くかもしれません。詳細はそれぞれのドキュメントを確認してください。

[8]
% 演算子は文字列フォーマットにも使われ、同じ優先順位が当てはまります。

[9]
べき乗演算子 ** はその右側にある単項演算子かビット単位演算子よりも優先して束縛されます。つまり 2**-1 は 0.5 になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

単純文 (simple statement)

単純文とは、単一の論理行内に収められる文です。単一の行内には、複数の単純文をセミコロンで区切って入れることができます。単純文の構文は以下の通りです:

simple_stmt ::=  expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | print_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | global_stmt
                 | exec_stmt

式文 (expression statement)

式文は、 (主に対話的な使い方では) 値を計算して出力するために使ったり、(通常は) プロシジャ (procedure: 有意な結果を返さない関数のことです; Python では、プロシジャは値 None を返します) を呼び出すために使います。その他の使い方でも式文を使うことができますし、有用なこともあります。式文の構文は以下の通りです:

expression_stmt ::=  expression_list

式文は式のリスト (単一の式のこともあります) を値評価します。

対話モードでは、値が None でない場合、値を組み込み関数 repr() で文字列に変換して、その結果のみからなる一行を標準出力に書き出します ( print 文 節参照)。 (None になる式文の値は書き出されないので、プロシジャ呼び出しを行っても出力は得られません。)

代入文 (assignment statement)

代入文は、名前を値に (再) 束縛したり、変更可能なオブジェクトの属性や要素を変更したりするために使われます:

assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)
target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" target_list ")"
                     | "[" target_list "]"
                     | attributeref
                     | subscription
                     | slicing

(末尾の三つのシンボルの構文については 一次語 (primary) 節を参照してください。)

代入文は式のリスト (これは単一の式でも、カンマで区切られた式リストでもよく、後者はタプルになることを思い出してください) を評価し、得られた単一の結果オブジェクトをターゲット (target) のリストに対して左から右へと代入してゆきます。

代入はターゲット (リスト) の形式に従って再帰的に行われます。ターゲットが変更可能なオブジェクト (属性参照、添字表記、またはスライス) の一部である場合、この変更可能なオブジェクトは最終的に代入を実行して、その代入が有効な操作であるか判断しなければなりません。代入が不可能な場合には例外を発行することもできます。型ごとにみられる規則や、送出される例外は、そのオブジェクト型定義で与えられています ( 標準型の階層 節を参照してください).

ターゲットリストへのオブジェクトの代入は、以下のようにして再帰的に定義されています。

ターゲットリストが単一のターゲットからなる場合: オブジェクトはそのターゲットに代入されます。

ターゲットリストが、カンマで区切られた複数のターゲットからなるリストの場合: オブジェクトはターゲットリスト中のターゲット数と同じ数の要素からなるイテレート可能オブジェクトでなければならず、その各要素は左から右へと対応するターゲットに代入されます。

単一のターゲットへの単一のオブジェクトの代入は、以下のようにして再帰的に定義されています。

ターゲットが識別子 (名前) の場合:

名前が現在のコードブロック内の global 文に書かれていない場合: 名前は現在のローカル名前空間内のオブジェクトに束縛されます。

それ以外の場合: 名前は現在のグローバル名前空間内のオブジェクトに束縛されます。

名前がすでに束縛済みの場合、再束縛 (rebind) がおこなわれます。再束縛によって、以前その名前に束縛されていたオブジェクトの参照カウント (reference count) がゼロになった場合、オブジェクトは解放 (deallocate) され、デストラクタ (destructor) が (存在すれば) 呼び出されます。

ターゲットが丸括弧や角括弧で囲われたターゲットリストの場合: オブジェクトはターゲットリスト中のターゲット数と同じ数の要素からなるイテレート可能オブジェクトでなければならず、その各要素は左から右へと対応するターゲットに代入されます。

ターゲットが属性参照の場合: 参照されている一次語の式が値評価されます。値は代入可能な属性を伴うオブジェクトでなければなりません; そうでなければ、 TypeError が送出されます。次に、このオブジェクトに対して、被代入オブジェクトを指定した属性に代入してよいか問い合わせます; 代入を実行できない場合、例外 (通常は AttributeError ですが、必然ではありません) を送出します。

注意: オブジェクトがクラスインスタンスで、代入演算子の両辺に属性参照があるとき、右辺式の a.x はインスタンスの属性と (インスタンスの属性が存在しなければ) クラス属性のどちらにもアクセスする可能性があります。左辺のターゲット a.x は常にインスタンスの属性として割り当てられ、必要ならば生成されます。このとおり、現れる二つの a.x は同じ値を参照するとは限りません: 右辺式はクラス属性を参照し、左辺は新しいインスタンス属性を代入のターゲットとして生成するようなとき:

class Cls:
    x = 3             # class variable
inst = Cls()
inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3

このことは、 property() で作成されたプロパティのようなデスクリプタ属性に対しては、必ずしもあてはまるとは限りません、

ターゲットが添字表記の場合: 参照されている一次語の式が値評価されます。まず、値は変更可能な (リストのような) シーケンスオブジェクトか、 (辞書のような) マップオブジェクトでなければなりません。次に、添字表記の表す式が値評価されます。

一次語が変更可能な (リストのような) シーケンスオブジェクトの場合、まず添字は整数でなければなりません。添字が負数の場合、シーケンスの長さが加算されます。添字は最終的に、シーケンスの長さよりも小さな非負の整数でなくてはなりません。次に、添字をインデクスに持つ要素に非代入オブジェクトを代入してよいか、シーケンスに問い合わせます。範囲を超えたインデクスに対しては IndexError が送出されます (添字指定されたシーケンスに代入を行っても、リスト要素の新たな追加はできません)。

一次語が (辞書のような) マップオブジェクトの場合、まず添字はマップのキー型と互換性のある型でなくてはなりません。次に、添字を被代入オブジェクトに関連付けるようなキー/データの対を生成するようマップオブジェクトに問い合わせます。この操作では、既存のキー/値の対を同じキーと別の値で置き換えてもよく、(同じ値を持つキーが存在しない場合) 新たなキー/値の対を挿入してもかまいません。

ターゲットがスライスの場合: 参照されている一次語の式が値評価されます。まず、値は変更可能な (リストのような) シーケンスオブジェクトでなければなりません。被代入オブジェクトは同じ型を持ったシーケンスオブジェクトでなければなりません。次に、スライスの下境界と上境界を示す式があれば評価されます; デフォルト値はそれぞれゼロとシーケンスの長さです。上下境界は整数にならなければなりません。いずれかの境界が負数になった場合、シーケンスの長さが加算されます。最終的に、境界はゼロからシーケンスの長さまでの内包になるようにクリップされます。最後に、スライスを被代入オブジェクトで置き換えてよいかシーケンスオブジェクトに問い合わせます。オブジェクトで許されている限り、スライスの長さは被代入シーケンスの長さと異なっていてよく、この場合にはターゲットシーケンスの長さが変更されます。

CPython implementation detail: 現在の実装では、ターゲットの構文は式の構文と同じであるとみなされており、無効な構文はコード生成フェーズ中に詳細なエラーメッセージを伴って拒否されます。

警告: 代入の定義では、左辺値と右辺値がオーバラップするような代入 (例えば、 a, b = b, a を行うと、二つの変数を入れ替えます) を定義しても ‘安全 (safe)’ に代入できますが、代入対象となる変数群 の間で オーバラップがある場合は安全ではありません！例えば、以下のプログラムは [0, 2] を出力してしまいます:

x = [0, 1]
i = 0
i, x[i] = 1, 2
print x

累算代入文 (augmented assignment statement)

累算代入文は、二項演算と代入文を組み合わせて一つの文にしたものです:

augmented_assignment_stmt ::=  augtarget augop (expression_list | yield_expression)
augtarget                 ::=  identifier | attributeref | subscription | slicing
augop                     ::=  "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

累算代入文は、ターゲット (通常の代入文と違って、アンパックは起こりません) と式リストを評価し、それら二つの被演算子間で特定の累算代入型の二項演算を行い、結果をもとのターゲットに代入します。ターゲットは一度しか評価されません。

x += 1 のような累算代入式は、 x = x + 1 のように書き換えてほぼ同様の動作にできますが、厳密に等価にはなりません。累算代入の方では、 x は一度しか評価されません。また、実際の処理として、可能ならば インプレース (in-place) 演算が実行されます。これは、代入時に新たなオブジェクトを生成してターゲットに代入するのではなく、以前のオブジェクトの内容を変更するということです。

累算代入文で行われる代入は、タプルへの代入や、一文中に複数のターゲットが存在する場合を除き、通常の代入と同じように扱われます。同様に、累算代入で行われる二項演算は、場合によって インプレース演算 が行われることを除き、通常の二項演算と同じです。

属性参照のターゲットの場合、 クラスとインスタンスの属性についての注意 と同様に通常の代入が適用されます。

assert 文

assert 文は、プログラム内にデバッグ用アサーション (debugging assertion) を仕掛けるための便利な方法です:

assert_stmt ::=  "assert" expression ["," expression]

単純な形式 assert expression は、

if __debug__:
   if not expression: raise AssertionError

と等価です。拡張形式 assert expression1, expression2 は、

if __debug__:
   if not expression1: raise AssertionError(expression2)

と等価です。

上記の等価関係は、 __debug__ と AssertionError が、同名の組み込み変数を参照しているという前提の上に成り立っています。現在の実装では、組み込み変数 __debug__ は通常の状況では True であり、最適化がリクエストされた場合（コマンドラインオプション -O）は False です。現状のコード生成器は、コンパイル時に最適化が要求されていると assert 文に対するコードを全く出力しません。実行に失敗した式のソースコードをエラーメッセージ内に入れる必要はありません; コードはスタックトレース内で表示されます。

__debug__ への代入は不正な操作です。組み込み変数の値は、インタプリタが開始するときに決定されます。

pass 文

pass_stmt ::=  "pass"

pass はヌル操作 (null operation) です — pass が実行されても、何も起きません。 pass は、例えば:

def f(arg): pass    # a function that does nothing (yet)

class C: pass       # a class with no methods (yet)

のように、構文法的には文が必要だが、コードとしては何も実行したくない場合のプレースホルダとして有用です。

del 文

del_stmt ::=  "del" target_list

オブジェクトの削除 (deletion) は、代入の定義と非常に似た方法で再帰的に定義されています。ここでは完全な詳細を記述するよりもいくつかのヒントを述べるにとどめます。

ターゲットリストに対する削除は、各々のターゲットを左から右へと順に再帰的に削除します。

名前に対して削除を行うと、ローカルまたはグローバル名前空間でのその名前の束縛を解除します。どちらの名前空間かは、名前が同じコードブロック内の global 文で宣言されているかどうかによります。名前が未束縛 (unbound) であるばあい、 NameError 例外が送出されます。

ネストしたブロック中で自由変数になっているローカル名前空間上の名前に対する削除は不正な操作になります

属性参照、添字表記、およびスライスの削除操作は、対象となる一次語オブジェクトに渡されます; スライスの削除は一般的には適切な型の空のスライスを代入するのと等価です (が、この仕様自体もスライスされるオブジェクトで決定されています)。

print 文

print_stmt ::=  "print" ([expression ("," expression)* [","]]
                | ">>" expression [("," expression)+ [","]])

print は、式を逐次的に評価し、得られたオブジェクトを標準出力に書き出します。オブジェクトが文字列でなければ、まず文字列変換規則を使って文字列に変換され、次いで (得られた文字列か、オリジナルの文字列が) 書き出されます。出力系の現在の書き出し位置が行頭にあると考えられる場合を除き、各オブジェクトの出力前にスペースが一つ出力されます。行頭にある場合とは、(1) 標準出力にまだ何も書き出されていない場合、(2) 標準出力に最後に書き出された文字が ' ' を除く空白である、または (3) 標準出力に対する最後の書き出し操作が print 文によるものではない場合、です。(こうした理由から、場合によっては空文字を標準出力に書き出すと便利なことがあります。)

ノート

組み込みのファイルオブジェクトでない、ファイルオブジェクトに似た動作をするオブジェクトでは、組み込みのファイルオブジェクトが持つ上記の性質を適切にエミュレートしていないことがあるため、当てにしないほうがよいでしょう。

print 文がカンマで終了していない限り、末尾には文字 '\n' が書き出されます。この仕様は、文に予約語 print がある場合のみの動作です。

標準出力は、組み込みモジュール sys 内で stdout という名前のファイルオブジェクトとして定義されています。該当するオブジェクトが存在しないか、オブジェクトに write() メソッドがない場合、 RuntimeError 例外が送出されます。.

print には、上で説明した構文の第二形式で定義されている拡張形式があります。この形式は、”山形 print 表記 (print chevron)” と呼ばれます。この形式では、 >> の直後にくる最初の式の値評価結果は “ファイル類似 (file-like)” なオブジェクト、とりわけ上で述べたように write() メソッドを持つオブジェクトでなければなりません。この拡張形式では、ファイルオブジェクトを指定する式よりも後ろの式が、指定されたファイルオブジェクトに出力されます。最初の式の値評価結果が None になった場合、 sys.stdout が出力ファイルとして使われます。

return 文

return_stmt ::=  "return" [expression_list]

return は、関数定義内で構文法的にネストして現れますが、ネストしたクラス定義内には現れません。

式リストがある場合、リストが値評価されます。それ以外の場合は None で置き換えられます。

return を使うと、式リスト (または None) を戻り値として、現在の関数呼び出しから抜け出します。

return によって、 finally 節をともなう try 文の外に処理が引き渡されると、実際に関数から抜ける前に finally 節が実行されます。

ジェネレータ関数の場合には、 return 文の中に expression_list を入れることはできません。ジェネレータ関数の処理コンテキストでは、単体の return はジェネレータ処理を終了し StopIteration を送出させることを示します。

yield 文

yield_stmt ::=  yield_expression

yield 文は、ジェネレータ関数 (generator function) を定義するときだけ使われ、かつジェネレータ関数の本体の中でだけ用いられます。関数定義中で yield 文を使うだけで、関数定義は通常の関数でなくジェネレータ関数になります。

ジェネレータ関数が呼び出されると、ジェネレータイテレータ (generator iterator)、一般的にはジェネレータ (generator) を返します。ジェネレータ関数の本体は、ジェネレータの next() が例外を発行するまで繰り返し呼び出して実行します。

yield 文が実行されると、現在のジェネレータの状態は凍結 (freeze) され、 expression_list の値が next() の呼び出し側に返されます。ここでの “凍結” は、ローカルな変数への束縛、命令ポインタ (instruction pointer)、および内部実行スタック (internal evaluation stack) を含む、全てのローカルな状態が保存されることを意味します: すなわち、必要な情報を保存しておき、次に next() が呼び出された際に、関数が yield 文をあたかももう一つの外部呼出しであるかのように処理できるようにします。

Python バージョン 2.5 では、 yield 文が try ... finally 構造における try 節で許されるようになりました。ジェネレータが終了（finalized）される（参照カウントがゼロになるか、ガベージコレクションされる) までに再開されなければ、ジェネレータ-イテレータの close() メソッドが呼ばれ、留保されている finally 節が実行できるようになります。

ノート

Python 2.2 では、 generators 機能が有効になっている場合にのみ yield 文を使えました。この機能を有効にするための __future__ import 文は次のとおりでした。

from __future__ import generators

参考

PEP 0255 [http://www.python.org/dev/peps/pep-0255] - 単純なジェネレータ

Python へのジェネレータと yield 文の導入提案

PEP 0342 [http://www.python.org/dev/peps/pep-0342] - 改善されたジェネレータによるコルーチン (Coroutine)

その他のジェネレータの改善と共に、 yield が try ... finally ブロックの中に存在することを可能にするための提案

raise 文

raise_stmt ::=  "raise" [expression ["," expression ["," expression]]]

式を伴わない場合、 raise は現在のスコープで最終的に有効になっている例外を再送出します。そのような例外が現在のスコープでアクティブでない場合、 TypeError 例外が送出されて、これがエラーであることを示します (IDLE で実行した場合は、代わりに exceptionQueue.Empty 例外を送出します)。

それ以外の場合、 raise は式を値評価して、三つのオブジェクトを取得します。このとき、 None を省略された式の値として使います。最初の二つのオブジェクトは、例外の 型 (type) と例外の 値 (value) を決定するために用いられます。

最初のオブジェクトがインスタンスである場合、例外の型はインスタンスのクラスになり、インスタンス自体が例外の値になります。このとき第二のオブジェクトは None でなければなりません。

最初のオブジェクトがクラスの場合、例外の型になります。第二のオブジェクトは、例外の値を決めるために使われます: 第二のオブジェクトがインスタンスならば、そのインスタンスが例外の値になります。第二のオブジェクトがタプルの場合、クラスのコンストラクタに対する引数リストとして使われます; None なら、空の引数リストとして扱われ、それ以外の型ならコンストラクタに対する単一の引数として扱われます。このようにしてコンストラクタを呼び出して生成したインスタンスが例外の値になります。

第三のオブジェクトが存在し、かつ None でなければ、オブジェクトはトレースバック オブジェクトでなければなりません ( 標準型の階層 節参照)。また、例外が発生した場所は現在の処理位置に置き換えられます。第三のオブジェクトが存在し、オブジェクトがトレースバックオブジェクトでも None でもなければ、 TypeError 例外が送出されます。 raise の三連式型は、 except 節から透過的に例外を再送出するのに便利ですが、再送出すべき例外が現在のスコープで発生した最も新しいアクティブな例外である場合には、式なしの raise を使うよう推奨します。

例外に関する追加情報は 例外 節にあります。また、例外処理に関する情報は try 文 節にあります。

break 文

break_stmt ::=  "break"

break 文は、構文としては for ループや while ループの内側でのみ出現することができますが、ループ内の関数定義やクラス定義の内側には出現できません。

break 文は、文を囲う最も内側のループを終了させ、ループにオプションの else 節がある場合にはそれをスキップします。

for ループを break によって終了すると、ループ制御ターゲットはその時の値を保持します。

break が finally 節を伴う try 文の外側に処理を渡す際には、ループを実際に抜ける前にその finally 節が実行されます。

continue 文

continue_stmt ::=  "continue"

continue 文は for ループや while ループ内のネストで構文法的にのみ現れますが、ループ内の関数定義やクラス定義、 finally 句の中には現れません。 continue 文は、文を囲う最も内側のループの次の周期に処理を継続します。

continue が finally 句を持った try 文を抜けるとき、その finally 句が次のループサイクルを始める前に実行されます。

import 文

import_stmt     ::=  "import" module ["as" name] ( "," module ["as" name] )*
                     | "from" relative_module "import" identifier ["as" name]
                     ( "," identifier ["as" name] )*
                     | "from" relative_module "import" "(" identifier ["as" name]
                     ( "," identifier ["as" name] )* [","] ")"
                     | "from" module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+
name            ::=  identifier

import 文は、(1) モジュールを探し、必要なら初期化 (initialize) する; (import 文のあるスコープにおける) ローカルな名前空間で名前を定義する、の二つの段階を踏んで初期化されます。 import 文には、 from を使うか使わないかの2種類の形式があります。第一形式 (from のない形式) は、上記の段階をリスト中にある各識別子に対して繰り返し実行していきます。 from のある形式では、(1) を一度だけ行い、次いで (2) を繰り返し実行します。

ステップ(1)がどのように行われるのかを理解するには、まず、 Python が階層的なモジュール名をどう扱うのかを理解する必要があります。モジュールを組織化し名前に階層を持たせるために、Python は パッケージ という概念を持っています。モジュールが他のモジュールやパッケージを含むことができないのに対して、パッケージは他のパッケージやモジュールを含むことができます。ファイルシステムの視点から見ると、パッケージはディレクトリでモジュールはファイルです。オリジナルの specification for packages [http://www.python.org/doc/essays/packages.html] は今でも読むことができますが、小さい詳細部分はこのドキュメントが書かれた後に変更されています。

モジュール名(特に記述していない場合は、 “モジュール” とはパッケージとモジュール両方を指しています)が判ったとき、モジュールかパッケージの検索が始まります。最初にチェックされる場所は、それまでにインポートされたすべてのモジュールのキャッシュである sys.modules です。もしモジュールがそこで見つかれば、それが import のステップ(2)で利用されます。

キャッシュにモジュールが見つからなかった場合、次は sys.meta_path が検索されます。 (sys.meta_path の仕様は PEP 302 [http://www.python.org/dev/peps/pep-0302] に見つけることができます。) これは finder オブジェクトのリストで、そのモジュールを読み込む方法を知っているかどうかをその find_module() メソッドをモジュール名を引数として呼び出すことで、順番に問い合せていきます。モジュールがパッケージに含まれていた(モジュール名の中にドットが含まれていた)場合、 find_module() の第2引数に親パッケージの __path__ 属性が渡されます。 (モジュール名の最後のドットより前のすべてがインポートされます) finder はモジュールを見つけたとき、(後で解説する) loader か None を返します。

sys.meta_path に含まれるすべての finder が module を見つけられない場合、幾つかの暗黙的に定義されている finder に問い合わせられます。どんな暗黙の meta path finder が定義されているかは Python の実装によって様々です。すべての実装が定義しなければならない1つの finder は、 sys.path_hooks を扱います。

この暗黙の finder は要求されたモジュールを、2箇所のどちらかで定義されている “paths” から探します。 (“paths” がファイルシステムパスである必要はありません) インポートしようとしているモジュールがパッケージに含まれている場合、親パッケージの __path__ が find_module() の第2引数として渡され、それが paths として扱われます。モジュールがパッケージに含まれていない場合、 sys.path が paths として扱われます。

paths が決定されたら、それを巡回してその path を扱える finder を探します。 sys.path_importer_cache 辞書は path に対する finder をキャッシュしており、 finder を探すときにチェックされます。 path がキャッシュに登録されていない場合は、 sys.path_hooks の各オブジェクトを 1つの引数 path で呼び出します。各オブジェクトは finder を返すか、 ImportError を発生させます。 finder が返された場合、それを sys.path_importer_cache にキャッシュして、その path に対してその finder を使います。 finder が見つからず、 path が存在している場合、 None が sys.path_importer_cache に格納されて、暗黙の、単一のファイルとしてモジュールが格納されているとしてあつかうファイルベースの finder をその path に対して利用することを示します。その path が存在しなかった場合、常に None を返す finder がその path に対するキャッシュとして格納されます。

全ての finder がそのモジュールを見つけられないときは、 ImportError が発生します。そうでなければ、どれかの finder が loader を返し、その load_module() メソッドがモジュール名を引数に呼び出されてロードを行ないます。 (ローダーのオリジナルの定義については PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。) loader はロードするモジュールに対して幾つかの責任があります。まず、そのモジュールがすでに sys.modules にあれば、 (ローダーが import 機構の外から呼ばれた場合に有り得ます) そのモジュールを初期化に使い、新しいモジュールを使いません。 sys.modules にそのモジュールがなければ、初期化を始める前に sys.modules に追加します。 sys.modules に追加したあと、モジュールのロード中にエラーが発生した場合は、その辞書から削除します。モジュールが既に sys.modules にあった場合は、エラーが発生してもその辞書に残しておきます。

ローダーは幾つかの属性をモジュールに設定しなければなりません。モジュール名を __name__ に設定します。ファイルの “path” を __file__ に設定しますが、ビルトインモジュール (sys.builtin_module_names にリストされている) の場合にはその属性を設定しません。インポートしているのがパッケージだった場合は、そのパッケージが含むモジュールやパッケージを探す場所の path のリストを __path_ に設定します。 __package__ はオプションですが、そのモジュールやパッケージを含むパッケージ名(パッケージに含まれていないモジュールには空文字列)を設定するべきです。 __loader__ もオプションですが、そのモジュールをロードした loader オブジェクトを設定するべきです。

ロード中にエラーが発生した場合、他の例外がすでに伝播していないのであれば、 loader は ImportError を発生させます。それ以外の場合は、 loader はロードして初期化したモジュールを返します。

段階 (1) が例外を送出することなく完了したなら、段階 (2) を開始します。

import 文の第一形式は、ローカルな名前空間に置かれたモジュール名をモジュールオブジェクトに束縛し、import すべき次の識別子があればその処理に移ります。モジュール名の後ろに as がある場合、 as の後ろの名前はモジュールのローカルな名前として使われます。

from 形式は、モジュール名の束縛を行いません: from 形式では、段階 (1) で見つかったモジュール内から、識別子リストの各名前を順に検索し、見つかったオブジェクトを識別子の名前でローカルな名前空間において束縛します。 import の第一形式と同じように、”as localname” で別名を与えることができます。指定された名前が見つからない場合、 ImportError が送出されます。識別子のリストを星印 ('*') で置き換えると、モジュールで公開されている名前 (public name) 全てを import 文のある場所のローカルな名前空間に束縛します。

モジュールで 公開されている名前 (public names) は、モジュールの名前空間内にある __all__ という名前の変数を調べて決定します; __all__ が定義されている場合、 __all__ はモジュールで定義されていたり、import されているような名前の文字列からなるシーケンスでなければなりません。 __all__ 内にある名前は、全て公開された名前であり、実在するものとみなされます。 __all__ が定義されていない場合、モジュールの名前空間に見つかった名前で、アンダースコア文字 ('_') で始まっていない全ての名前が公開された名前になります。 __all__ には、公開されている API 全てを入れなければなりません。 __all__ には、(モジュール内で import されて使われているライブラリモジュールのように) API を構成しない要素を意に反して公開してしまうのを避けるという意図があります。

* を使った from 形式は、モジュールのスコープ内だけに作用します。関数内でワイルドカードの import 文 — import * — を使い、関数が自由変数を伴うネストされたブロックであったり、ブロックを含んでいる場合、コンパイラは SyntaxError を送出します。

インポートするモジュールを指定するとき、そのモジュールの絶対名(absolute name) を指定する必要はありません。モジュールやパッケージが他のパッケージに含まれている場合、共通のトップパッケージからそのパッケージ名を記述することなく相対インポートすることができます。 from の後に指定されるモジュールやパッケージの先頭に複数個のドットを付けることで、正確な名前を指定することなしに現在のパッケージ階層からいくつ上の階層へ行くかを指定することができます。先頭のドットが1つの場合、 import をおこなっているモジュールが存在する現在のパッケージを示します。 3つのドットは2つ上のレベルを示します。なので、 pkg パッケージの中のモジュールで from . import mod を実行すると、 pkg.mod をインポートすることになります。 pkg.subpkg1 の中から from ..subpkg2 import mod を実行すると、 pkg.subpkg2.mod をインポートします。相対インポートの仕様は PEP 328 [http://www.python.org/dev/peps/pep-0328] に含まれています。

どのモジュールがロードされるべきかを動的に決めたいアプリケーションのために、組み込み関数 importlib.import_module() が提供されています;

future 文 (future statement)

future 文 は、将来の特定の Python のリリースで利用可能になるような構文や意味付けを使って、特定のモジュールをコンパイルさせるための、コンパイラに対する指示句 (directive) です。 future 文は、言語仕様に非互換性がもたらされるような、将来の Python のバージョンに容易に移行できるよう意図されています。 future 文によって、新たな機能が標準化されたリリースが出される前に、その機能をモジュール単位で使えるようにします。

future_statement ::=  "from" "__future__" "import" feature ["as" name]
                      ("," feature ["as" name])*
                      | "from" "__future__" "import" "(" feature ["as" name]
                      ("," feature ["as" name])* [","] ")"

future 文は、モジュールの先頭周辺に書かなければなりません。 future 文の前に書いてよい内容は:

モジュールのドキュメンテーション文字列(あれば)

コメント

空行

その他の future 文

です。

Python 2.6 が認識する機能は、 unicode_literals, print_function, absolute_import, division, generators, nested_scopes, with_statement です。 generators, with_statement, nested_scopes は Python 2.6 以上では常に有効なので冗長です。

future 文は、コンパイル時に特別なやり方で認識され、扱われます: 言語の中核をなす構文構成 (construct) に対する意味付けが変更されている場合、変更部分はしばしば異なるコードを生成することで実現されています。新たな機能によって、(新たな予約語のような) 互換性のない新たな構文が取り入れられることさえあります。この場合、コンパイラはモジュールを別のやりかたで解析する必要があるかもしれません。こうしたコード生成に関する決定は、実行時まで先延ばしすることはできません。

これまでの全てのリリースにおいて、コンパイラはどの機能が定義済みかを知っており、future 文に未知の機能が含まれている場合にはコンパイル時エラーを送出します。

future 文の実行時における直接的な意味付けは、import 文と同じです。標準モジュール __future__ があり、これについては後で述べます。 __future__ は、future 文が実行される際に通常の方法で import されます。

future 文の実行時における特別な意味付けは、future 文で有効化される特定の機能によって変わります。

以下の文:

import __future__ [as name]

には、何ら特殊な意味はないので注意してください。

これは future 文ではありません; この文は通常の import 文であり、その他の特殊な意味付けや構文的な制限はありません。

future 文の入ったモジュール M 内で使われている exec 文、組み込み関数 compile() や execfile() によってコンパイルされるコードは、デフォルトの設定では、 future 文に関係する新たな構文や意味付けを使うようになっています。 Python 2.2 からは、この仕様を compile() のオプション引数で制御できるようになりました — 詳細はこの関数に関するドキュメントを参照してください。

対話的インタプリタのプロンプトでタイプ入力した future 文は、その後のインタプリタセッション中で有効になります。インタプリタを -i オプションで起動して実行すべきスクリプト名を渡し、スクリプト中に future 文を入れておくと、新たな機能はスクリプトが実行された後に開始する対話セッションで有効になります。

参考

PEP 236 [http://www.python.org/dev/peps/pep-0236] - Back to the __future__ __future__ 機構の原案

global 文

global_stmt ::=  "global" identifier ("," identifier)*

global 文は、現在のコードブロック全体で維持される宣言文です。 global 文は、列挙した識別子をグローバル変数として解釈するよう指定することを意味します。 global を使わずにグローバル変数に代入を行うことは不可能ですが、自由変数を使えばその変数をグローバルであると宣言せずにグローバル変数を参照することができます。

global 文で列挙する名前は、同じコードブロック中で、プログラムテキスト上 global 文より前に使ってはなりません。

global 文で列挙する名前は、 for ループのループ制御ターゲットや、 class 定義、関数定義、 import 文内で仮引数として使ってはなりません。

CPython implementation detail: 現在の実装では、後ろ二つの制限については強制していませんが、プログラムでこの緩和された仕様を乱用すべきではありません。将来の実装では、この制限を強制したり、暗黙のうちにプログラムの意味付けを変更したりする可能性があります。

プログラマのための注意点: global はパーザに対する指示句 (directive) です。この指示句は、 global 文と同時に読み込まれたコードに対してのみ適用されます。特に、 exec 文内に入っている global 文は、 exec 文を 含んでいるコードブロック内に効果を及ぼすことはなく、 exec 文内に含まれているコードは、 exec 文を含むコード内での global 文に影響を受けません。同様のことが、関数 eval() 、 execfile() 、および compile() にも当てはまります。

exec 文

exec_stmt ::=  "exec" or_expr ["in" expression ["," expression]]

この文は、Python コードの動的な実行をサポートします。最初の式の値評価結果は文字列か、開かれたファイルオブジェクトか、コードオブジェクトでなければなりません。文字列の場合、一連の Python 実行文として解析し、(構文エラーが生じない限り) 実行します。 [1] 開かれたファイルであれば、ファイルを EOF まで読んで解析し、実行します。コードオブジェクトなら、単にこれを実行します。全ての場合で、実行されたコードはファイル入力として有効であることが期待されます (セクション ファイル入力 を参照)。 return と yield 文は、 exec 文に渡されたコードの文脈中においても関数定義の外では使われない点に注意してください。

いずれの場合でも、オプションの部分が省略されると、コードは現在のスコープ内で実行されます。 in の後ろに一つだけ式を指定する場合、その式は辞書でなくてはならず、グローバル変数とローカル変数の両方に使われます。これらはそれぞれグローバル変数とローカル変数として使われます。 locals を指定する場合は何らかのマップ型オブジェクトにせねばなりません．

バージョン 2.4 で変更: 以前は locals は辞書でなければなりませんでした.

exec の副作用として実行されるコードで設定された変数名に対応する名前の他に、追加のキーを辞書に追加することがあります。例えば、現在の実装では、組み込みモジュール __builtin__ の辞書に対する参照を、 __builtins__ (!) というキーで追加することがあります。

プログラマのためのヒント: 式の動的な評価は、組み込み関数 eval() でサポートされています組み込み関数 globals() および locals() は、それぞれ現在のグローバル辞書とローカル辞書を返すので、 exec に渡して使うと便利です。

注記

[1]
パーサーは Unix スタイルの行末の慣習しか許可しないことに注意してください。コードをファイルから読み込む場合、Windows や Mac スタイルの改行を変換するために必ずユニバーサル改行モード(universal newline mode)を利用してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

複合文 (compound statement)

複合文には、他の文 (のグループ) が入ります; 複合文は、中に入っている他の文の実行の制御に何らかのやり方で影響を及ぼします。一般的には、複合文は複数行にまたがって書かれますが、全部の文を一行に連ねた単純な書き方もあります。

if 、 while 、および for 文は、伝統的な制御フロー構成を実現します。 try は例外処理および/または一連の文に対するクリーンアップコードを指定します。関数とクラス定義もまた、構文法的には複合文です。

複合文は、一つまたはそれ以上の ‘節 (clause)’ からなります。一つの節は、ヘッダと ‘スイート (suite)’ からなります。特定の複合文を構成する節のヘッダ部分は、全て同じインデントレベルになります。各々の節ヘッダ行は一意に識別されるキーワードから始まり、コロンで終わります。スイートは、ヘッダのコロンの後ろにセミコロンで区切られた一つまたはそれ以上の単純文を並べるか、ヘッダ行後のインデントされた文の集まりです。後者の形式のスイートに限り、ネストされた複合文を入れることができます; 以下の文は、 else 節がどの if 節に属するかがはっきりしないという理由から不正になります:

if test1: if test2: print x

また、このコンテキスト中では、セミコロンはコロンよりも強い結合を表すことにも注意してください。従って、以下の例では、 print は全て実行されるか、されないかのどちらかです:

if x < y < z: print x; print y; print z

まとめると、以下のようになります:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

文は常に NEWLINE か、その後に DEDENT が続いたもので終了することに注意してください。また、オプションの継続節は常にあるキーワードから始まり、このキーワードから複合文を開始することはできないため、曖昧さは存在しないことにも注意してください (Python では、 ‘ぶら下がり(dangling) else‘ 問題を、ネストされた if 文はインデントさせること解決しています)。

以下の節における文法規則の記述方式は、明確さのために、各節を別々の行に書くようにしています。

if 文

if 文は、条件分岐を実行するために使われます:

if_stmt ::=  "if" expression ":" suite
             ( "elif" expression ":" suite )*
             ["else" ":" suite]

if 文は、式を一つ一つ評価してゆき、真になるまで続けて、真になった節のスイートだけを選択します (真: true と偽: false の定義については、 ブール演算 (boolean operation) 節を参照してください); 次に、選択したスイートを実行します (そして、 if 文の他の部分は、実行や評価をされません)。全ての式が偽になった場合、 else 節があれば、そのスイートが実行されます。

while 文

while 文は、式の値が真である間、実行を繰り返すために使われます:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

while 文は式を繰り返し真偽評価し、真であれば最初のスイートを実行します。式が偽であれば (最初から偽になっていることもありえます)、 else 節がある場合にはそれを実行し、ループを終了します。

最初のスイート内で break 文が実行されると、 else 節のスイートを実行することなくループを終了します。 continue 文が最初のスイート内で実行されると、スイート内にある残りの文の実行をスキップして、式の真偽評価に戻ります。

for 文

for 文は、シーケンス (文字列、タプルまたはリスト) や、その他の反復可能なオブジェクト (iterable object) 内の要素に渡って反復処理を行うために使われます:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

式リストは一度だけ評価されます; 結果はイテレーション可能オブジェクトにならねばなりません。 expression_list の結果に対してイテレータを生成し、その後、シーケンスの各要素についてインデクスの小さい順に一度だけスイートを実行します。このときシーケンス内の要素が通常の代入規則を使ってターゲットリストに代入され、その後スイートが実行されます。全ての要素を使い切ると (シーケンスが空の場合にはすぐに)、 else 節があればそれが実行され、ループを終了します。

最初のスイート内で break 文が実行されると、 else 節のスイートを実行することなくループを終了します。 continue 文が最初のスイート内で実行されると、スイート内にある残りの文の実行をスキップして、式の真偽評価に戻ります。

スイートの中では、ターゲットリスト内の変数に代入を行えます; この代入によって、次に代入される要素に影響を及ぼすことはありません。

ループが終了してもターゲットリストは削除されませんが、シーケンスが空の場合には、ループでの代入は全く行われません。ヒント: 組み込み関数 range() は、 Pascal 言語における for i := a to b do の効果をエミュレートするのに適した数列を返します; すなわち、 range(3) はリスト [0, 1, 2] を返します。

ノート

ループ中のシーケンスの変更には微妙な問題があります (これは変更可能なシーケンス、すなわちリストで起こります)。どの要素が次に使われるかを追跡するために、内部的なカウンタが使われており、このカウンタは反復処理を行うごとに加算されます。このカウンタがシーケンスの長さに達すると、ループは終了します。このことは、スイート中でシーケンスから現在の (または以前の) 要素を除去すると、(次の要素のインデクスは、すでに取り扱った要素のインデクスになるために) 次の要素が飛ばされることを意味します。同様に、スイート中でシーケンス中の現在の要素以前に要素を挿入すると、ループ中で現在の要素が再度扱われることになります。こうした仕様は、厄介なバグになります。シーケンス全体に相当するスライスを使って一時的なコピーを作ると、これを避けることができます。

for x in a[:]:
    if x < 0: a.remove(x)

try 文

try 文は、ひとまとめの文に対して、例外処理および/またはクリーンアップコードを指定します:

try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
               ("except" [expression [("as" | ",") target]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
               "finally" ":" suite

バージョン 2.5 で変更: 以前のバージョンの Python では、 try...except...finally が機能しませんでした。 try...except は try...finally 中でネストされなければいけません。.

except 節は一つまたはそれ以上の例外ハンドラを指定します。 try 節内で全く例外が起きなければ、どの例外ハンドラも実行されません。 try スイート内で例外が発生すると、例外ハンドラの検索が開始されます。この検索では、 except 節を逐次調べて、発生した例外に合致するまで続けます。式を伴わない except 節を使う場合、最後に書かなければなりません; この except 節は全ての例外に合致します。式を伴う except 節に対しては、式が値評価され、返されたオブジェクトが例外と “互換である (compatible)” 場合にその節が合致します。ある例外に対してオブジェクトが互換であるのは、それが例外オブジェクトのクラスかベースクラスの場合、または例外と互換性のある要素が入ったタプルである場合、または、 (非推奨であるところの) 文字列による例外の場合は、送出された文字列そのものである場合です (注意点として、オブジェクトのアイデンティティが一致しなければいけません。つまり、同じ文字列オブジェクトなのであって、単なる同じ値を持つ文字列ではありません)。

例外がどの except 節にも合致しなかった場合、現在のコードを囲うさらに外側、そして呼び出しスタックへと検索を続けます。 [1]

except 節のヘッダにある式を値評価するときに例外が発生すると、元々のハンドラ検索はキャンセルされ、新たな例外に対する例外ハンドラの検索を現在の except 節の外側のコードや呼び出しスタックに対して行います (try 文全体が例外を発行したかのように扱われます)。

合致する except 節が見つかると、その except 節はその except 節で指定されているターゲットに代入されて、もし存在する場合、加えて except 節スイートが実行されます。全ての except 節は実行可能なブロックを持っていなければなりません。このブロックの末尾に到達すると、通常は try 文全体の直後に実行を継続します。(このことは、同じ例外に対してネストした二つの例外ハンドラが存在し、内側のハンドラ内の try 節で例外が発生した場合、外側のハンドラは例外を処理しないことを意味します。)

except 節のスイートが実行される前に、例外に関する詳細が sys モジュール内の三つの変数に代入されます: sys.exc_type は、例外を示すオブジェクトを受け取ります; sys.exc_value は例外のパラメタを受け取ります; sys.exc_traceback は、プログラム上の例外が発生した位置を識別するトレースバックオブジェクト (標準型の階層 参照) を受け取ります。これらの詳細はまた、関数 sys.exc_info() を介して入手することもできます。この関数はタプル (exc_type, exc_value, exc_traceback) を返します。ただしこの関数に対応する変数の使用は、スレッドを使ったプログラムで安全に使えないため撤廃されています。 Python 1.5 からは、例外を処理した関数から戻るときに、以前の値 (関数呼び出し前の値) に戻されます。

オプションの else 節は、実行の制御が try 節の末尾に到達した場合に実行されます。 [2] else 節内で起きた例外は、 else 節に先行する except 節で処理されることはありません。

finally が存在する場合、これは ‘クリーンアップ’ ハンドラを指定しています。 except や else 節を含む try 節が実行されます。それらの節のいずれかで例外が発生して処理されない場合、その例外は一時的に保存されます。 finally 節が実行されます。もし保存された例外が存在する場合、それは finally 節の最後で再送出されます。 finally 節で別の例外が送出されたり、 return や break 節が実行された場合、保存されていた例外は失われます。例外情報は、 finally 節の実行中にはプログラムで取得することができません。

try...finally 文の try スイート内で return 、 break 、または continue 文が実行された場合、 finally 節も ‘抜け出る途中に (on the way out)’ 実行されます。 finally 節での continue 文の使用は不正です。 (理由は現在の実装上の問題です – この制限は将来解消されるかもしれません)。

例外に関するその他の情報は 例外 節にあります。また、 raise 文の使用による例外の生成に関する情報は、 raise 文 節にあります。

with 文

バージョン 2.5 で追加.

with 文は、ブロックの実行を、コンテキストマネージャによって定義されたメソッドでラップするために使われます（ with文とコンテキストマネージャ セクションを参照してください）。これにより、よくある try...except...finally 利用パターンをカプセル化して便利に再利用することができます。

with_stmt ::=  "with" with_item ("," with_item)* ":" suite
with_item ::=  expression ["as" target]

一つの “要素” を持つ with 文の実行は以下のように進行します:

コンテキスト式 (with_item で与えられた式) を評価することで、コンテキストマネージャを取得します。

コンテキストマネージャの __enter__() メソッドが、後で使うためにロードされます。

コンテキストマネージャの __enter__() メソッドが呼ばれます。

with 文に ターゲットが含まれていたら、それに __enter__() からの戻り値が代入されます。

ノート

with 文は、 __enter__() メソッドがエラーなく終了した場合には __exit__() が常に呼ばれることを保証します。ですので、もしエラーがターゲットリストへの代入中にエラーが発生した場合には、これはそのスイートの中で発生したエラーと同じように扱われます。以下のステップ 6 を参照してください。

スイートが実行されます。

コンテキストマネージャの __exit__() メソッドが呼ばれます。もし例外がスイートを終了させる場合、その型、値、そしてトレースバックが __exit__() へ引数として渡されます。そうでなければ、 3 つの None 引数が与えられます。

スイートが例外により終了され、 __exit__() メソッドからの戻り値が偽（false）ならば、例外が再送出されます。この戻り値が真（true）ならば例外は抑制され、実行は with 文の次の文から続きます。

もしそのスイートが例外でない何らかの理由で終了した場合、その __exit__() からの戻り値は無視されて、実行は発生した終了の種類に応じた通常の位置から継続します。

複数の要素があるとき、コンテキストマネージャは複数の with 文がネストされたかのように進行します:

with A() as a, B() as b:
    suite

は、以下と同等です:

with A() as a:
    with B() as b:
        suite

ノート

Python 2.5 では、 with 文は with_statement 機能が有効にされた場合にだけ利用できます。 Python 2.6 では常に利用できます。

バージョン 2.7 で変更: 複数のコンテキスト式をサポートしました。

参考

PEP 0343 [http://www.python.org/dev/peps/pep-0343] - The “with” statement

Python の with 文の仕様、背景、そして実例

関数定義

関数定義は、ユーザ定義関数オブジェクトを定義します ( 標準型の階層 節参照):

decorated      ::=  decorators (classdef | funcdef)
decorators     ::=  decorator+
decorator      ::=  "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
funcdef        ::=  "def" funcname "(" [parameter_list] ")" ":" suite
dotted_name    ::=  identifier ("." identifier)*
parameter_list ::=  (defparameter ",")*
                    (  "*" identifier [, "**" identifier]
                    | "**" identifier
                    | defparameter [","] )
defparameter   ::=  parameter ["=" expression]
sublist        ::=  parameter ("," parameter)* [","]
parameter      ::=  identifier | "(" sublist ")"
funcname       ::=  identifier

関数定義は実行可能な文です。関数定義を実行すると、現在のローカルな名前空間内で関数名を関数オブジェクト (関数の実行可能コードをくるむラッパ) に束縛します。この関数オブジェクトには、関数が呼び出された際に使われるグローバルな名前空間として、現在のグローバルな名前空間への参照が入っています。

関数定義は関数本体を実行しません; 関数本体は関数が呼び出された時にのみ実行されます。 [3]

関数定義は一つ以上のデコレータ (decorator) 式でラップできます。デコレータ式は関数を定義するとき、関数定義の入っているスコープで評価されます。その結果は、関数オブジェクトを唯一の引数にとる呼び出し可能オブジェクトでなければなりません。関数オブジェクトの代わりに、返された値が関数名に束縛されます。複数のデコレータはネストして適用されます。例えば、以下のようなコード:

@f1(arg)
@f2
def func(): pass

は、

def func(): pass
func = f1(arg)(f2(func))

と同じです。

一つ以上のトップレベルのパラメタに parameter = expression の形式がある場合、関数は “デフォルトのパラメタ値 (default parameter values)” を持つといいます。デフォルト値を伴うパラメタに対しては、関数呼び出しの際に対応するパラメタが省略されると、パラメタの値はデフォルト値で置き換えられます。あるパラメタがデフォルト値を持つ場合、それ以後のパラメタは全てデフォルト値を持たなければなりません — これは文法的には表現されていない構文上の制限です。

デフォルトパラメタ値は関数定義を実行する際に値評価されます。 これは、デフォルトパラメタの式は関数を定義するときにただ一度だけ評価され、同じ “計算済みの” 値が全ての呼び出しで使われることを意味します。デフォルトパラメタ値がリストや辞書のような変更可能なオブジェクトである場合、この使用を理解しておくことは特に重要です: 関数でこのオブジェクトを (例えばリストに要素を追加して) 変更すると、実際のデフォルト値が変更されてしまいます。一般には、これは意図しない動作です。このような動作を避けるには、デフォルト値に None を使い、この値を関数本体の中で明示的にテストします。例えば以下のようにします:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin

関数呼び出しの意味付けに関する詳細は、 呼び出し (call) 節で述べられています。関数呼び出しを行うと、パラメタリストに記述された全てのパラメタに対して、固定引数、キーワード引数、デフォルト引数のいずれかから値を代入します。”*identifier” 形式が存在する場合、余った固定引数を受け取るタプルに初期化されます。この変数のデフォルト値は空のタプルです。”**identifier” 形式が存在する場合、余ったキーワード引数を受け取るタプルに初期化されます。デフォルト値は空の辞書です。

式で直接使うために、無名関数 (名前に束縛されていない関数) を作成することも可能です。無名関数の作成には、 ラムダ (lambda) 節で記述されているラムダ形式 (lambda form) を使います。ラムダ形式は、単純化された関数定義を行うための略記法にすぎません; “def” 文で定義された関数は、ラムダ形式で定義された関数と全く同様に引渡したり、他の名前に代入したりできます。実際には、”def” 形式は複数の式を実行できるという点でより強力です。

プログラマのための注釈: 関数は一級の (first-class) オブジェクトです。関数定義内で”def” 形式を実行すると、戻り値として返したり引き渡したりできるローカルな関数を定義します。ネストされた関数内で自由変数を使うと、 def 文の入っている関数のローカル変数にアクセスすることができます。詳細は 名前づけと束縛 (naming and binding) 節を参照してください。

クラス定義

クラス定義は、クラスオブジェクトを定義します ( 標準型の階層 節参照):

classdef    ::=  "class" classname [inheritance] ":" suite
inheritance ::=  "(" [expression_list] ")"
classname   ::=  identifier

クラス定義は実行可能な文です。クラス定義では、まず継承リストがあればそれを評価します。継承リストの各要素の値評価結果はクラスオブジェクトか、サブクラス可能なクラス型でなければなりません。次にクラスのスイートが新たな実行フレーム内で、新たなローカル名前空間と元々のグローバル名前空間を使って実行されます (名前づけと束縛 (naming and binding) 節を参照してください)。 (通常、スイートには関数定義のみが含まれます) クラスのスイートを実行し終えると、実行フレームは無視されますが、ローカルな名前空間は保存されます。次に、基底クラスの継承リストを使ってクラスオブジェクトが生成され、ローカルな名前空間を属性値辞書として保存します。最後に、もとのローカルな名前空間において、クラス名がこのクラスオブジェクトに束縛されます。

プログラマのための注釈: クラス定義内で定義された変数はクラス変数です; クラス変数は全てのインスタンス間で共有されます。インスタンス変数を作成するには、メソッドの中で self.name = value でセットできます。クラス変数もインスタンス変数も “self.name” 表記でアクセスすることができます。この表記でアクセスする場合、インスタンス変数は同名のクラス変数を隠蔽します。クラス変数は、インスタンス変数のデフォルト値として使えますが、変更可能な値をそこに使うと予期せぬ結果につながります。新スタイルクラス(new-style class)では、デスクリプタを使ってインスタンス変数の振舞いを変更できます。

クラス定義は、関数定義と同じように、1つ以上のデコレータ(decorator)式でラップすることができます。デコレータ式の評価規則は関数と同じです。結果はクラスオブジェクトでなければならず、それがクラス名に束縛されます。

注記

[1]
例外は、例外を打ち消す finally 節が無い場合にのみ呼び出しスタックへ伝わります。

[2]
現在、制御が “末尾に到達する” のは、例外が発生したり、 return, continue, または break 文が実行される場合を除きます。

[3]
関数の本体の最初の文として現われる文字列リテラルは、その関数の __doc__ 属性に変換され、その関数のドキュメンテーション文字列(docstring) になります。

[4]
クラスの本体の最初の文として現われる文字列リテラルは、その名前空間の __doc__ 要素となり、そのクラスのドキュメンテーション文字列(docstring)になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

トップレベル要素

Python インタプリタは、標準入力や、プログラムの引数として与えられたスクリプト、対話的にタイプ入力された命令、モジュールのソースファイルなど、様々な入力源から入力を得ることができます。この章では、それぞれの場合に用いられる構文法について説明しています。

完全な Python プログラム

言語仕様の中では、その言語を処理するインタプリタがどのように起動されるかまで規定する必要はないのですが、完全な Python プログラムについての概念を持っておくと役に立ちます。完全な Python プログラムは、最小限に初期化された環境: 全ての組み込み変数と標準モジュールが利用可能で、かつ sys (様々なシステムサービス)、 __builtin__ (組み込み関数、例外、および None)、 __main__ の 3 つを除く全てのモジュールが初期化されていない状態で動作します。 __main__ は、完全なプログラムを実行する際に、ローカルおよびグローバルな名前空間を提供するために用いられます。

完全な Python プログラムの構文は、下の節で述べるファイル入力のためのものです。

インタプリタは、対話的モード (interactive mode) で起動されることもあります; この場合、インタプリタは完全なプログラムを読んで実行するのではなく、一度に単一の実行文 (複合文のときもあります) を読み込んで実行します。初期状態の環境は、完全なプログラムを実行するときの環境と同じです; 各実行文は、 __main__ の名前空間内で実行されます。

Unixの環境下では、完全なプログラムをインタプリタに渡すには三通りの方法があります: 第一は、 -c string コマンドラインオプションを使う方法、第二はファイルを第一コマンドライン引数として指定する方法、そして最後は標準入力から入力する方法です。ファイルや標準入力が tty (端末) デバイスの場合、インタプリタは対話モードに入ります; そうでない場合、ファイルを完全なプログラムとして実行します。

ファイル入力

非対話的なファイルから読み出された入力は、全て同じ形式:

file_input ::=  (NEWLINE | statement)*

をとります。この構文法は、以下の状況で用いられます:

(ファイルや文字列内の) 完全な Python プログラムを構文解析するとき;

モジュールを構文解析するとき;

exec で渡された文字列を構文解析するとき;

対話的入力

対話モードでの入力は、以下の文法の下に構文解析されます:

interactive_input ::=  [stmt_list] NEWLINE | compound_stmt NEWLINE

対話モードでは、(トップレベルの) 複合文の最後に空白行を入れなくてはならないことに注意してください; これは、複合文の終端をパーザが検出するための手がかりとして必要です。

式入力

式入力には二つの形式があります。双方とも、先頭の空白を無視します。 eval() に対する文字列引数は、以下の形式をとらなければなりません:

eval_input ::=  expression_list NEWLINE*

input() で読み込まれる入力行は、以下の形式をとらなければなりません:

input_input ::=  expression_list NEWLINE

注意: 文としての解釈を行わない ‘生の (raw)’ 入力行を読み出すためには、組み込み関数 raw_input() や、ファイルオブジェクトの readline() メソッドを使うことができます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

完全な文法仕様

これは、パーサージェネレータが読み込んで、 Python のソースファイルを解析するために使われる、完全な Python の文法です。

# Grammar for Python

# Note:  Changing the grammar specified in this file will most likely
#        require corresponding changes in the parser module
#        (../Modules/parsermodule.c).  If you can't make the changes to
#        that module yourself, please co-ordinate the required changes
#        with someone who can; ask around on python-dev for help.  Fred
#        Drake <fdrake@acm.org> will probably be listening there.

# NOTE WELL: You should also follow all the steps listed in PEP 306,
# "How to Change Python's Grammar"

# Commands for Kees Blom's railroad program
#diagram:token NAME
#diagram:token NUMBER
#diagram:token STRING
#diagram:token NEWLINE
#diagram:token ENDMARKER
#diagram:token INDENT
#diagram:output\input python.bla
#diagram:token DEDENT
#diagram:output\textwidth 20.04cm\oddsidemargin  0.0cm\evensidemargin 0.0cm
#diagram:rules

# Start symbols for the grammar:
#	single_input is a single interactive statement;
#	file_input is a module or sequence of commands read from an input file;
#	eval_input is the input for the eval() and input() functions.
# NB: compound_stmt in single_input is followed by extra NEWLINE!
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
eval_input: testlist NEWLINE* ENDMARKER

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef)
funcdef: 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')'
varargslist: ((fpdef ['=' test] ',')*
              ('*' NAME [',' '**' NAME] | '**' NAME) |
              fpdef ['=' test] (',' fpdef ['=' test])* [','])
fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | exec_stmt | assert_stmt)
expr_stmt: testlist (augassign (yield_expr|testlist) |
                     ('=' (yield_expr|testlist))*)
augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
            '<<=' | '>>=' | '**=' | '//=')
# For normal assignments, additional restrictions enforced by the interpreter
print_stmt: 'print' ( [ test (',' test)* [','] ] |
                      '>>' test [ (',' test)+ [','] ] )
del_stmt: 'del' exprlist
pass_stmt: 'pass'
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
break_stmt: 'break'
continue_stmt: 'continue'
return_stmt: 'return' [testlist]
yield_stmt: yield_expr
raise_stmt: 'raise' [test [',' test [',' test]]]
import_stmt: import_name | import_from
import_name: 'import' dotted_as_names
import_from: ('from' ('.'* dotted_name | '.'+)
              'import' ('*' | '(' import_as_names ')' | import_as_names))
import_as_name: NAME ['as' NAME]
dotted_as_name: dotted_name ['as' NAME]
import_as_names: import_as_name (',' import_as_name)* [',']
dotted_as_names: dotted_as_name (',' dotted_as_name)*
dotted_name: NAME ('.' NAME)*
global_stmt: 'global' NAME (',' NAME)*
exec_stmt: 'exec' expr ['in' test [',' test]]
assert_stmt: 'assert' test [',' test]

compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
try_stmt: ('try' ':' suite
           ((except_clause ':' suite)+
	    ['else' ':' suite]
	    ['finally' ':' suite] |
	   'finally' ':' suite))
with_stmt: 'with' test [ with_var ] ':' suite
with_var: 'as' expr
# NB compile.c makes sure that the default except clause is last
except_clause: 'except' [test [('as' | ',') test]]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

# Backward compatibility cruft to support:
# [ x for x in lambda: True, lambda: False if x() ]
# even while also allowing:
# lambda x: 5 if x else 2
# (But not a mix of the two)
testlist_safe: old_test [(',' old_test)+ [',']]
old_test: or_test | old_lambdef
old_lambdef: 'lambda' [varargslist] ':' old_test

test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_gexp] ')' |
       '[' [listmaker] ']' |
       '{' [dictmaker] '}' |
       '`' testlist1 '`' |
       NAME | NUMBER | STRING+)
listmaker: test ( list_for | (',' test)* [','] )
testlist_gexp: test ( gen_for | (',' test)* [','] )
lambdef: 'lambda' [varargslist] ':' test
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
dictmaker: test ':' test (',' test ':' test)* [',']

classdef: 'class' NAME ['(' [testlist] ')'] ':' suite

arglist: (argument ',')* (argument [',']
                         |'*' test (',' argument)* [',' '**' test]
                         |'**' test)
argument: test [gen_for] | test '=' test  # Really [keyword '='] test

list_iter: list_for | list_if
list_for: 'for' exprlist 'in' testlist_safe [list_iter]
list_if: 'if' old_test [list_iter]

gen_iter: gen_for | gen_if
gen_for: 'for' exprlist 'in' or_test [gen_iter]
gen_if: 'if' old_test [gen_iter]

testlist1: test (',' test)*

# not used in grammar, but may appear in "node" passed from Parser to Compiler
encoding_decl: NAME

yield_expr: 'yield' [testlist]

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 言語リファレンス »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる Python Language Reference の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

Yasushi Masuda <y.masuda at acm.org> (Feb 3, 2004)

Yasushi Masuda (May 20, 2006)

Toshiyuki Kawanishi

hkurosawa

INADA Naoki

森本哲也

Arihiro TAKASE <hinaclegear at gmail.com>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ

Release: | 2.7
Date: | 2011年 12月 26日

Python 言語リファレンス ではプログラミング言語 Python の厳密な構文とセマンティクスについて説明されていますが、このライブラリリファレンスマニュアルでは Python とともに配付されている標準ライブラリについて説明します。また Python 配布物に収められていることの多いオプションのコンポーネントについても説明します。

Python の標準ライブラリはとても拡張性があり、下の長い目次のリストで判るように幅広いものを用意しています。このライブラリには、例えばファイル I/O のように、Python プログラマが直接アクセスできないシステム機能へのアクセス機能を提供する (Cで書かれた) 組み込みモジュールや、日々のプログラミングで生じる多くの問題に標準的な解決策を提供するPython で書かれたモジュールが入っています。これら数多くのモジュールには、プラットフォーム固有の事情をプラットフォーム独立な API へと昇華させることにより、Pythonプログラムに移植性を持たせ、それを高めるという明確な意図があります。

Windows 向けの Python インストーラはたいてい標準ライブラリのすべてを含み、しばしばそれ以外の追加のコンポーネントも含んでいます。Unix 系のオペレーティングシステムの場合は Python は一揃いのパッケージとして提供されるのが普通で、オプションのコンポーネントを手に入れるにはオペレーティングシステムのパッケージツールを使うことになるでしょう。

標準ライブラリに加えて、数千のコンポーネントが (独立したプログラムやモジュールからパッケージ、アプリケーション開発フレームワークまで) 成長し続けるコレクションとしてPython Package Index [http://pypi.python.org/pypi] から入手可能です。

1. はじめに

2. 組み込み関数

3. 非必須組み込み関数 (Non-essential Built-in Functions)

4. 組み込み定数

4.1. site モジュールで追加される定数

5. 組み込み型

5.1. 真理値テスト

5.2. ブール演算 — and, or, not

5.3. 比較

5.4. 数値型 int, float, long, complex

5.5. イテレータ型

5.6. シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange

5.7. set（集合）型 — set, frozenset

5.8. マップ型

5.9. ファイルオブジェクト

5.10. メモリビュー型

5.11. コンテキストマネージャ型

5.12. 他の組み込み型

5.13. 特殊な属性

6. 組み込み例外

6.1. 例外のクラス階層

7. 文字列処理

7.1. string — 一般的な文字列操作

7.2. re — 正規表現操作

7.3. struct — 文字列データをパックされたバイナリデータとして解釈する

7.4. difflib — 差分の計算を助ける

7.5. StringIO — ファイルのように文字列を読み書きする

7.6. cStringIO — 高速化された StringIO

7.7. textwrap — テキストの折り返しと詰め込み

7.8. codecs — codec レジストリと基底クラス

7.9. unicodedata — Unicode データベース

7.10. stringprep — インターネットのための文字列調製

7.11. fpformat — 浮動小数点数の変換

8. データ型

8.1. datetime — 基本的な日付型および時間型

8.2. calendar — 一般的なカレンダーに関する関数群

8.3. collections — 高性能なコンテナ・データ型

8.4. heapq — ヒープキューアルゴリズム

8.5. bisect — 配列二分法アルゴリズム

8.6. array — 効率のよい数値アレイ

8.7. sets — ユニークな要素の順序なしコレクション

8.8. sched — イベントスケジューラ

8.9. mutex — 排他制御

8.10. queue — 同期キュークラス

8.11. weakref — 弱参照

8.12. UserDict — 辞書オブジェクトのためのクラスラッパー

8.13. UserList — リストオブジェクトのためのクラスラッパー

8.14. UserString — 文字列オブジェクトのためのクラスラッパー

8.15. types — 組み込み型の名前

8.16. new — ランタイム内部オブジェクトの作成

8.17. copy — 浅いコピーおよび深いコピー操作

8.18. pprint — データ出力の整然化

8.19. repr — もう一つの repr() の実装

9. 数値と数学モジュール

9.1. numbers — 数の抽象基底クラス

9.2. math — 数学関数

9.3. cmath — 複素数のための数学関数

9.4. decimal — 10進固定及び浮動小数点数の算術演算

9.5. fractions — 有理数

9.6. random — 擬似乱数を生成する

9.7. itertools — 効率的なループ実行のためのイテレータ生成関数

9.8. functools — 高階関数と呼び出し可能オブジェクトの操作

9.9. operator — 関数形式の標準演算子

10. ファイルとディレクトリへのアクセス

10.1. os.path — 共通のパス名操作

10.2. fileinput — 複数の入力ストリームをまたいだ行の繰り返し処理をサポートする。

10.3. stat — stat() の返す内容を解釈する

10.4. statvfs — os.statvfs() で使われる定数群

10.5. filecmp — ファイルおよびディレクトリの比較

10.6. tempfile — 一時的なファイルやディレクトリの生成

10.7. glob — Unix 形式のパス名のパターン展開

10.8. fnmatch — Unix ファイル名のパターンマッチ

10.9. linecache — テキストラインにランダムアクセスする

10.10. shutil — 高レベルなファイル操作

10.11. dircache — キャッシュされたディレクトリ一覧の生成

10.12. macpath — Mac OS 9 のパス操作関数

11. データの永続化

11.1. pickle — Python オブジェクトの整列化

11.2. cPickle — より高速な pickle

11.3. copy_reg — pickle サポート関数を登録する

11.4. shelve — Python オブジェクトの永続化

11.5. marshal — 内部使用向けの Python オブジェクト整列化

11.6. anydbm — DBM 形式のデータベースへの汎用アクセスインタフェース

11.7. whichdb — どのDBMモジュールがデータベースを作ったかを推測する

11.8. dbm — UNIX dbmのシンプルなインタフェース

11.9. gdbm — GNU による dbm の再実装

11.10. dbhash — BSD データベースライブラリへの DBM 形式のインタフェース

11.11. bsddb — Berkeley DB ライブラリへのインタフェース

11.12. dumbdbm — 可搬性のある DBM 実装

11.13. sqlite3 — SQLite データベースに対する DB-API 2.0 インタフェース

12. データ圧縮とアーカイブ

12.1. zlib — gzip 互換の圧縮

12.2. gzip — gzip ファイルのサポート

12.3. bz2 — bzip2 互換の圧縮ライブラリ

12.4. zipfile — ZIP アーカイブの処理

12.5. tarfile — tar アーカイブファイルを読み書きする

13. ファイルフォーマット

13.1. csv — CSV ファイルの読み書き

13.2. ConfigParser — 設定ファイルの構文解析器

13.3. robotparser — robots.txt のためのパーザ

13.4. netrc — netrc ファイルの処理

13.5. xdrlib — XDR データのエンコードおよびデコード

13.6. plistlib — Mac OS X .plist ファイルの生成と解析

14. 暗号関連のサービス

14.1. hashlib — セキュアハッシュおよびメッセージダイジェスト

14.2. hmac — メッセージ認証のための鍵付きハッシュ化

14.3. md5 — MD5 メッセージダイジェストアルゴリズム

14.4. sha — SHA-1 メッセージダイジェストアルゴリズム

15. 汎用オペレーティングシステムサービス

15.1. os — 雑多なオペレーティングシステムインタフェース

15.2. io — ストリームを扱うコアツール

15.3. time — 時刻データへのアクセスと変換

15.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー

15.5. optparse — コマンドラインオプション解析器

15.6. getopt — C言語スタイルのコマンドラインオプションパーサ

15.7. logging — Python 用ロギング機能

15.8. logging.config — ロギングの環境設定

15.9. logging.handlers — ロギングハンドラ

15.10. getpass — 可搬性のあるパスワード入力機構

15.11. curses — 文字セル表示のための端末操作

15.12. curses.textpad — curses プログラムのためのテキスト入力ウィジェット

15.13. curses.wrapper — curses プログラムのための端末ハンドラ

15.14. curses.ascii — ASCII 文字に関するユーティリティ

15.15. curses.panel — curses のためのパネルスタック拡張

15.16. platform — 実行中プラットフォームの固有情報を参照する

15.17. errno — 標準の errno システムシンボル

15.18. ctypes — Pythonのための外部関数ライブラリ

16. オプションのオペレーティングシステムサービス

16.1. select — I/O 処理の完了を待機する

16.2. threading — 高水準のスレッドインタフェース

16.3. thread — マルチスレッドのコントロール

16.4. dummy_threading — threading の代替モジュール

16.5. dummy_thread — thread の代替モジュール

16.6. multiprocessing — プロセスベースの “並列処理” インタフェース

16.7. mmap — メモリマップファイル

16.8. readline — GNU readline のインタフェース

16.9. rlcompleter — GNU readline向け補完関数

17. プロセス間通信とネットワーク

17.1. subprocess — サブプロセス管理

17.2. socket — 低レベルネットワークインターフェース

17.3. ssl — ソケットオブジェクトに対する TLS/SSL ラッパー

17.4. signal — 非同期イベントにハンドラを設定する

17.5. popen2 — アクセス可能な I/O ストリームを持つ子プロセス生成

17.6. asyncore — 非同期ソケットハンドラ

17.7. asynchat — 非同期ソケットコマンド/レスポンスハンドラ

18. インターネット上のデータの操作

18.1. email — 電子メールと MIME 処理のためのパッケージ

18.2. json — JSON エンコーダおよびデコーダ

18.3. mailcap — mailcap ファイルの操作

18.4. mailbox — 様々な形式のメールボックス操作

18.5. mhlib — MH のメールボックスへのアクセス機構

18.6. mimetools — MIME メッセージを解析するためのツール

18.7. mimetypes — ファイル名を MIME 型へマップする

18.8. MimeWriter — 汎用 MIME ファイルライター

18.9. mimify — 電子メールメッセージの MIME 処理

18.10. multifile — 個別の部分を含んだファイル群のサポート

18.11. rfc822 — RFC 2822 準拠のメールヘッダ読み出し

18.12. base64 — RFC 3548: Base16, Base32, Base64 データの符号化

18.13. binhex — binhex4 形式ファイルのエンコードおよびデコード

18.14. binascii — バイナリデータと ASCIIデータとの間での変換

18.15. quopri — MIME quoted-printable 形式データのエンコードおよびデコード

18.16. uu — uuencode形式のエンコードとデコード

19. 構造化マークアップツール

19.1. HTMLParser — HTML および XHTML のシンプルなパーザ

19.2. sgmllib — 単純な SGML パーザ

19.3. htmllib — HTML 文書の解析器

19.4. htmlentitydefs — HTML 一般エンティティの定義

19.5. xml.parsers.expat — Expat を使った高速な XML 解析

19.6. xml.dom — 文書オブジェクトモデル (DOM) API

19.7. xml.dom.minidom — 軽量な DOM 実装

19.8. xml.dom.pulldom — 部分的な DOM ツリー構築のサポート

19.9. xml.sax — SAX2 パーサのサポート

19.10. xml.sax.handler — SAX ハンドラの基底クラス

19.11. xml.sax.saxutils — SAX ユーティリティ

19.12. xml.sax.xmlreader — XML パーサのインタフェース

19.13. xml.etree.ElementTree — ElementTree XML API

20. インターネットプロトコルとその支援

20.1. webbrowser — 便利なウェブブラウザコントローラー

20.2. cgi — CGI (ゲートウェイインタフェース規格) のサポート

20.3. cgitb — CGI スクリプトのトレースバック管理機構

20.4. wsgiref — WSGI ユーティリティとリファレンス実装

20.5. urllib — URL による任意のリソースへのアクセス

20.6. urllib2 — URL を開くための拡張可能なライブラリ

20.7. httplib — HTTP プロトコルクライアント

20.8. ftplib — FTPプロトコルクライアント

20.9. poplib — POP3 プロトコルクライアント

20.10. imaplib — IMAP4 プロトコルクライアント

20.11. nntplib — NNTP プロトコルクライアント

20.12. smtplib — SMTP プロトコルクライアント

20.13. smtpd — SMTP サーバー

20.14. telnetlib — Telnet クライアント

20.15. uuid — RFC 4122 に準拠した UUID オブジェクト

20.16. urlparse — URL を解析して構成要素にする

20.17. SocketServer — ネットワークサーバ構築のためのフレームワーク

20.18. BaseHTTPServer — 基本的な機能を持つ HTTP サーバ

20.19. SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ

20.20. CGIHTTPServer — CGI 実行機能付き HTTP リクエスト処理機構

20.21. cookielib — HTTP クライアント用の Cookie 処理

20.22. Cookie — HTTPの状態管理

20.23. xmlrpclib — XML-RPC クライアントアクセス

20.24. SimpleXMLRPCServer — 基本的なXML-RPCサーバー

20.25. DocXMLRPCServer — セルフ-ドキュメンティング XML-RPC サーバ

21. マルチメディアサービス

21.1. audioop — 生の音声データを操作する

21.2. imageop — 生の画像データを操作する

21.3. aifc — AIFFおよびAIFCファイルの読み書き

21.4. sunau — Sun AUファイルの読み書き

21.5. wave — WAVファイルの読み書き

21.6. chunk — IFFチャンクデータの読み込み

21.7. colorsys — 色体系間の変換

21.8. imghdr — 画像の形式を決定する

21.9. sndhdr — サウンドファイルの識別

21.10. ossaudiodev — OSS互換オーディオデバイスへのアクセス

22. 国際化

22.1. gettext — 多言語対応に関する国際化サービス

22.2. locale — 国際化サービス

23. プログラムのフレームワーク

23.1. cmd — 行指向のコマンドインタープリタのサポート

23.2. shlex — 単純な字句解析

24. Tkを用いたグラフィカルユーザインターフェイス

24.1. Tkinter — Tcl/Tk への Python インタフェース

24.2. ttk — Tk themed widgets

24.3. Tix — Tkの拡張ウィジェット

24.4. ScrolledText — スクロールするテキストウィジェット

24.5. turtle — Tkのためのタートルグラフィックス

24.6. IDLE

24.7. 他のグラフィカルユーザインタフェースパッケージ

25. 開発ツール

25.1. pydoc — ドキュメント生成とオンラインヘルプシステム

25.2. doctest — 対話的な実行例をテストする

25.3. unittest — ユニットテストフレームワーク

25.4. 2to3 - Python 2 から 3 への自動コード変換

25.5. test — Python用回帰テストパッケージ

26. デバッグとプロファイル

26.1. bdb — デバッガーフレームワーク

26.2. pdb — Python デバッガ

26.3. デバッガコマンド

26.4. Python プロファイラ

26.5. hotshot — ハイパフォーマンス・ロギング・プロファイラ

26.6. timeit — 小さなコード断片の実行時間計測

26.7. trace — Python ステートメント実行のトレースと追跡

27. Python ランタイムサービス

27.1. sys — システムパラメータと関数

27.2. sysconfig — Python の構成情報にアクセスする

27.3. __builtin__ — 組み込みオブジェクト

27.4. future_builtins — Python 3 のビルトイン

27.5. __main__ — トップレベルのスクリプト環境

27.6. warnings — 警告の制御

27.7. contextlib — with -構文コンテキストのためのユーティリティ

27.8. abc — 抽象基底クラス

27.9. atexit — 終了ハンドラ

27.10. traceback — スタックトレースの表示または取得

27.11. __future__ — future 文の定義

27.12. gc — ガベージコレクタインターフェース

27.13. inspect — 活動中のオブジェクトの情報を取得する

27.14. site — サイト固有の設定フック

27.15. user — ユーザー設定のフック

27.16. fpectl — 浮動小数点例外の制御

27.17. distutils — Python モジュールの構築とインストール

28. カスタム Python インタプリタ

28.1. code — インタプリタ基底クラス

28.2. codeop — Pythonコードをコンパイルする

29. 制限実行 (restricted execution)

29.1. rexec — 制限実行のフレームワーク

29.2. Bastion — オブジェクトに対するアクセスの制限

30. モジュールのインポート

30.1. imp — import 内部へアクセスする

30.2. importlib – __import__() の便利なラッパー

30.3. imputil — Import ユーティリティ

30.4. zipimport — Zip アーカイブからモジュールを import する

30.5. pkgutil — パッケージ拡張ユーティリティ

30.6. modulefinder — スクリプト中で使われているモジュールを検索する

30.7. runpy — Python モジュールの位置特定と実行

31. Python言語サービス

31.1. parser — Python 解析木にアクセスする

31.2. 抽象構文木

31.3. symtable — コンパイラの記号表へのアクセス

31.4. symbol — Python 解析木と共に使われる定数

31.5. token — Python 解析木と共に使われる定数

31.6. keyword — Python キーワードチェック

31.7. tokenize — Pythonソースのためのトークナイザ

31.8. tabnanny — あいまいなインデントの検出

31.9. pyclbr — Python クラスブラウザサポート

31.10. py_compile — Python ソースファイルのコンパイル

31.11. compileall — Python ライブラリをバイトコンパイル

31.12. dis — Python バイトコードの逆アセンブラ

31.13. pickletools — pickle 開発者のためのツール群

32. Python コンパイラパッケージ

32.1. 基本的なインターフェイス

32.2. 制限

32.3. Python 抽象構文

32.4. Visitor を使って AST をわたり歩く

32.5. バイトコード生成

33. 各種サービス

33.1. formatter — 汎用の出力書式化機構

34. MS Windows 固有のサービス

34.1. msilib — Microsoft インストーラーファイルの読み書き

34.2. msvcrt – MS VC++実行時システムの有用なルーチン群

34.3. _winreg – Windows レジストリへのアクセス

34.4. winsound — Windows 用の音声再生インタフェース

35. Unix 固有のサービス

35.1. posix — 最も一般的な POSIX システムコール群

35.2. pwd — パスワードデータベースへのアクセスを提供する

35.3. spwd — シャドウパスワードデータベース

35.4. grp — グループデータベースへのアクセス

35.5. crypt — Unix パスワードをチェックするための関数

35.6. dl — 共有オブジェクトのC関数の呼び出し

35.7. termios — POSIX スタイルの端末制御

35.8. tty — 端末制御のための関数群

35.9. pty — 擬似端末ユーティリティ

35.10. fcntl — fcntl() および ioctl() システムコール

35.11. pipes — シェルパイプラインへのインタフェース

35.12. posixfile — ロック機構をサポートするファイル類似オブジェクト

35.13. resource — リソース使用状態の情報

35.14. nis — Sun の NIS (Yellow Pages) へのインタフェース

35.15. syslog — Unix syslog ライブラリルーチン群

35.16. commands — コマンド実行ユーティリティ

36. Mac OS X 固有のサービス

36.1. ic — Mac OS X インターネット設定へのアクセス

36.2. MacOS — Mac OS インタプリタ機能へのアクセス

36.3. macostools — ファイル操作を便利にするルーチン集

36.4. findertools — finder のApple Eventsインターフェース

36.5. EasyDialogs — 基本的な Macintosh ダイアログ

36.6. FrameWork — 対話型アプリケーション・フレームワーク

36.7. autoGIL — イベントループ中のグローバルインタープリタの取り扱い

36.8. Mac OS ツールボックスモジュール

36.9. ColorPicker — 色選択ダイアログ

37. MacPython OSA モジュール

37.1. gensuitemodule — OSA スタブ作成パッケージ

37.2. aetools — OSA クライアントのサポート

37.3. aepack — Python変数とAppleEventデータコンテナ間の変換

37.4. aetypes — AppleEvent オブジェクト

37.5. MiniAEFrame — オープンスクリプティングアーキテクチャサーバのサポート

38. SGI IRIX 固有のサービス

38.1. al — SGIのオーディオ機能

38.2. AL — al モジュールで使われる定数

38.3. cd — SGI システムの CD-ROM へのアクセス

38.4. fl — グラフィカルユーザーインターフェースのための FORMS ライブラリ

38.5. FL — fl モジュールで使用される定数

38.6. flp — 保存されたFORMSデザインをロードする関数

38.7. fm — Font Manager インターフェース

38.8. gl — Graphics Library インターフェース

38.9. DEVICE — gl モジュールで使われる定数

38.10. GL — gl モジュールで使われる定数

38.11. imgfile — SGI imglib ファイルのサポート

38.12. jpeg — JPEGファイルの読み書きを行う

39. SunOS 固有のサービス

39.1. sunaudiodev — Sun オーディオハードウェアへのアクセス

39.2. SUNAUDIODEV — sunaudiodev で使われる定数

40. ドキュメント化されていないモジュール

40.1. 雑多な有用ユーティリティ

40.2. プラットフォーム固有のモジュール

40.3. マルチメディア関連

40.4. 文書化されていない Mac OS モジュール

40.5. 撤廃されたもの

40.6. SGI 固有の拡張モジュール

41. 日本語訳について

41.1. 翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

1. はじめに

この “Python ライブラリ” には様々な内容が収録されています。

このライブラリには、数値型やリスト型のような、通常は言語の “核” をなす部分とみなされるデータ型が含まれています。 Python 言語のコア部分では、これらの型に対してリテラル表現形式を与え、意味づけ上のいくつかの制約を与えていますが、完全にその意味づけを定義しているわけではありません。 (一方で、言語のコア部分では演算子のスペルや優先順位のような構文法的な属性を定義しています。) このライブラリにはまた、組み込み関数と例外が納められています — 組み込み関数および例外は、全ての Python で書かれたコード上で、 import 文を使わずに使うことができるオブジェクトです。これらの組み込み要素のうちいくつかは言語のコア部分で定義されていますが、大半は言語コアの意味づけ上不可欠なものではないのでここでしか記述されていません。

とはいえ、このライブラリの大部分に収録されているのはモジュールのコレクションです。このコレクションを細分化する方法はいろいろあります。あるモジュールは C 言語で書かれ、 Python インタプリタに組み込まれています; 一方別のモジュールは Python で書かれ、ソースコードの形式で取り込まれます。またあるモジュールは、例えば実行スタックの追跡結果を出力するといった、 Python に非常に特化したインタフェースを提供し、一方他のモジュールでは、特定のハードウェアにアクセスするといった、特定のオペレーティングシステムに特化したインタフェースを提供し、さらに別のモジュールでは WWW (ワールドワイドウェブ) のような特定のアプリケーション分野に特化したインタフェースを提供しています。モジュールによっては全てのバージョン、全ての移植版の Python で利用することができたり、背後にあるシステムがサポートしている場合にのみ使えたり、 Python をコンパイルしてインストールする際に特定の設定オプションを選んだときにのみ利用できたりします。

このマニュアルの構成は “内部から外部へ:” つまり、最初に組み込みのデータ型を記述し、組み込みの関数および例外、そして最後に各モジュールといった形になっています。モジュールは関係のあるものでグループ化して一つの章にしています。章の順番付けや各章内のモジュールの順番付けは、大まかに重要性の高いものから低いものになっています。

つまり、このマニュアルを最初から読み始め、読み飽き始めたところで次の章に進めば、 Python ライブラリで利用できるモジュールやサポートしているアプリケーション領域の概要をそこそこ理解できるということです。もちろん、このマニュアルを小説のように読む必要は ありません — (マニュアルの先頭部分にある) 目次にざっと目を通したり、 (最後尾にある) 索引でお目当ての関数やモジュール、用語を探すことだってできます。もしランダムな項目について勉強してみたいのなら、ランダムにページを選び (random 参照)、そこから 1, 2 節読むこともできます。このマニュアルの各節をどんな順番で読むかに関わらず、 組み込み関数 の章から始めるとよいでしょう。マニュアルの他の部分は、この節の内容について知っているものとして書かれているからです。

それでは、ショーの始まりです！

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

2. 組み込み関数

Python インタプリタは数多くの組み込み関数を持っていて、いつでも利用することができます。それらの関数をアルファベット順に挙げます。

|  | 組み込み関数 |  |
abs() | divmod() | input() | open() | staticmethod()
all() | enumerate() | int() | ord() | str()
any() | eval() | isinstance() | pow() | sum()
basestring() | execfile() | issubclass() | print() | super()
bin() | file() | iter() | property() | tuple()
bool() | filter() | len() | range() | type()
bytearray() | float() | list() | raw_input() | unichr()
callable() | format() | locals() | reduce() | unicode()
chr() | frozenset() | long() | reload() | vars()
classmethod() | getattr() | map() | repr() | xrange()
cmp() | globals() | max() | reversed() | zip()
compile() | hasattr() | memoryview() | round() | __import__()
complex() | hash() | min() | set() | apply()
delattr() | help() | next() | setattr() | buffer()
dict() | hex() | object() | slice() | coerce()
dir() | id() | oct() | sorted() | intern()

abs(x)

数値の絶対値を返します。引数として通常の整数、長整数、浮動小数点数をとることができます。引数が複素数の場合、その大きさ (magnitude) が返されます。

all(iterable)

iterable の全ての要素が真ならば (もしくは iterable が空ならば) True を返します。以下のコードと等価です。

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

バージョン 2.5 で追加.

any(iterable)

iterable のいずれかの要素が真ならば True を返します。 iterable が空なら False を返します。以下のコードと等価です。

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

バージョン 2.5 で追加.

basestring()

この抽象型は、 str および unicode のスーパークラスです。この型は呼び出したりインスタンス化したりはできませんが、オブジェクトが str や unicode のインスタンスであるかどうかを調べる際に利用できます。 isinstance(obj, basestring) は isinstance(obj, (str, unicode)) と等価です。

バージョン 2.3 で追加.

bin(x)

整数値をバイナリ文字列に変換します。結果は正常な Python の表現となります。 x が Python の int オブジェクトでない場合、整数値を返す __index__() メソッドが定義されていなければなりません。

バージョン 2.6 で追加.

bool([x])

標準の真値テストを使って、値をブール値に変換します。 x が偽か省略された場合、 False を返します; そうでなければ True を返します。 bool はクラスでもあり、 int のサブクラスになります。 bool クラスはそれ以上サブクラス化できません。このクラスのインスタンスは False および True だけです。

バージョン 2.2.1 で追加.

バージョン 2.3 で変更: 引数が与えられなかった場合、この関数は False を返します。

bytearray([source[, encoding[, errors]]])

新しいバイトの配列を返します。 bytearray 型は範囲 0 <= x < 256 の整数のミュータブルなシーケンスです。これは、 変更可能なシーケンス型 で書かれているような、ミュータブルなシーケンスの通常のメソッドのほとんどを持ちますし、 文字列メソッド にあるような、 str 型が持つメソッドのほとんども持っています。

オプションの source パラメタは、配列をいくつかの異なる方法で初期化するのに使われます。

これが 文字列 なら、 encoding (と、オプションの errors) パラメタも与えなければなりません。このとき bytearray() は文字列を str.encode() でバイト列に変換して返します。

これが 整数 なら、配列はそのサイズになり、null バイトで初期化されます。

これが バッファ インタフェースに適合するオブジェクトなら、そのオブジェクトの読み込み専用バッファがバイト配列の初期化に使われます。

これが イテラブル なら、それは範囲 0 <= x < 256 内の整数のイテラブルであることが必要で、それらが配列の初期の内容になります。

引数がなければ、長さ 0 の配列が生成されます。

callable(object)

引数 object が呼び出し可能オブジェクトであれば、 True を返します。そうでなければ、 False を返します。この関数が真を返しても object の呼び出しは失敗する可能性がありますが、偽を返した場合は決して成功することはありません。クラスは呼び出し可能 (クラスを呼び出すと新しいインスタンスを返します) なことと、クラスのインスタンスがメソッド __call__() を持つ場合には呼び出しが可能なことに注意してください。

chr(i)

ASCII コードが整数 i となるような文字 1 字からなる文字列を返します。例えば、 chr(97) は文字列 'a' を返します。この関数は ord() の逆です。引数は [0..255] の両端を含む範囲内に収まらなければなりません; i が範囲外の値のときには ValueError が送出されます。 unichr() も参照下さい。

classmethod(function)

function のクラスメソッドを返します。

クラスメソッドは、インスタンスメソッドが暗黙の第一引数としてインスタンスをとるように、第一引数としてクラスをとります。クラスメソッドを宣言するには、以下の書きならわしを使います。:

class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...

@classmethod は関数 decorator (デコレータ)形式です。詳しくは 関数定義 の関数定義についての説明を参照してください。

このメソッドはクラスで呼び出すこと (例えば C.f() ) も、インスタンスとして呼び出すこと (例えば C().f()) もできます。インスタンスはそのクラスが何であるかを除いて無視されます。クラスメソッドが派生クラスに対して呼び出された場合、派生したクラスオブジェクトが暗黙の第一引数として渡されます。

クラスメソッドは C++ や Java における静的メソッドとは異なります。そのような機能を求めているなら、 staticmethod() を参照してください。

クラスメソッドについてさらに情報が必要ならば、 標準型の階層 の型階層の項を参照下さい。

バージョン 2.2 で追加.

バージョン 2.4 で変更: 関数デコレータ構文を追加しました.

cmp(x, y)

二つのオブジェクト x および y を比較し、その結果に従って整数を返します。戻り値は x < y のときには負、 x == y の時にはゼロ、 x > y には厳密に正の値になります。

compile(source, filename, mode[, flags[, dont_inherit]])

source をコード、もしくは、 AST オブジェクトにコンパイルします。コードオブジェクトは exec 文により実行したり、 eval() で評価したりすることができます。 source は、文字列と AST オブジェクトのどちらでもかまいません。 AST オブジェクトへの、また、 AST オブジェクトからのコンパイルの方法は、 _ast モジュールのドキュメントを参照下さい。

引数 filename には、コードの読み出し元のファイルを与えなければなりません; ファイルから読み出されたもので無い場合は、認識可能な値を渡して下さい ('<string>' が一般的に使われます ) 。

引数 mode は、どのような種類のコードがコンパイルされるべきかを指定します。 ; もし、 source が一連の文から成る場合、 'exec' 、単一の式の場合、 'eval' 、単一の対話的文の場合 'single' が指定できます ( 後者の場合、 None 以外のものを評価する式が印字されます ) 。

オプションの引数 flags および dont_inherit (Python 2.2 で新たに追加) は、 string のコンパイル時にどの future 文 (PEP 236 [http://www.python.org/dev/peps/pep-0236] 参照) の影響を及ぼすかを制御します。どちらも省略した場合 (または両方ともゼロの場合)、コンパイルを呼び出している側のコードで有効になっている future 文の内容を有効にして string をコンパイルします。 flags が指定されていて、かつ dont_inherit が指定されていない (またはゼロ) の場合、上の場合に加えて flags に指定された future 文を使います。 dont_inherit がゼロでない整数の場合、 flags の値そのものを使い、この関数呼び出し周辺での future 文の効果は無視します。

future 文はビットで指定され、互いにビット単位の論理和を取って複数の文を指定できます。ある機能を指定するために必要なビットフィールドは、 __future__ モジュールの _Feature インスタンスにおける compiler_flag 属性で得られます。

この関数は、コンパイルするソースが不正である場合、 SyntaxError を送出します。ソースがNull Byteを含む場合、 TypeError を送出します。

ノート

複数行に渡るコードの文字列を 'single' や 'eval' モードでコンパイルするとき、入力は少なくともひとつの改行文字で終端されなければなりません。これは code モジュールで、文が不完全か完全かをわかりやすくするためです。

バージョン 2.3 で追加: flags と dont_inherit 引数が追加されました。

バージョン 2.6 で追加: AST オブジェクトのコンパイルをサポートしました。

バージョン 2.7 で変更: Windows や Mac の改行文字を使えるようになりました。また、 'exec' モードで改行文字は必要なくなりました。 optimize パラメタを追加しました。

complex([real[, imag]])

値 real + imag*j の複素数型数を生成するか、文字列または数値を複素数型に変換します。最初の引数が文字列の場合、文字列を複素数として変換します。この場合関数は二つ目の引数無しで呼び出さなければなりません。二つ目の引数は文字列であってはなりません。それぞれの引数は (複素数を含む) 任意の数値型をとることができます。 imag が省略された場合、標準の値はゼロで、関数は int() 、 long() および float() のような数値型への変換関数として動作します。全ての引数が省略された場合、 0j を返します。

複素数型については 数値型 int, float, long, complex に説明があります。

delattr(object, name)

setattr() の親戚となる関数です。引数はオブジェクトと文字列です。文字列はオブジェクトの属性のどれか一つの名前でなければなりません。この関数は与えられた名前の属性を削除しますが、オブジェクトがそれを許す場合に限ります。例えば、 delattr(x, 'foobar') は del x.foobar と等価です。

dict([arg])

新しい辞書型データを作成します。オプションとして引数 arg が与えることができます。辞書型については、 マップ型 に説明があります。

他のコンテナについては、組み込みクラスの list 、 set 、 tuple 、および、モジュールの collections を参照下さい。

dir([object])

引数がない場合、現在のローカルスコープにある名前のリストを返します。引数がある場合、そのオブジェクトの有効な属性からなるリストを返そうと試みます。

もし、オブジェクトが __dir__() メソッドを持つなら、このメソッドが呼び出され、属性のリストを必ず返します。これにより、 dir() がオブジェクトの属性を返す方法をカスタマイズするために、 __getattr__() や __getattribute__() といったカスタム関数を実装することができます。

オブジェクトが __dir__() を提供していない場合、オブジェクトの __dict__ 属性が定義されていれば、そこから収集しようと試みます。また、定義されていれば型オブジェクトからも集められます。リストは完全なものになるとは限りません。また、カスタム関数 __getattr__() を持つ場合、不正確になるでしょう。

デフォルトの dir() メカニズムの振る舞いは、異なる型のオブジェクトでは、異なります。それは、完全というよりは、より関連のある情報を生成しようとするためです。

オブジェクトがモジュールオブジェクトの場合、リストにはモジュール属性の名前が含まれます。

オブジェクトが型オブジェクトやクラスオブジェクトの場合、リストにはそれらの属性が含まれ、かつそれらの基底クラスの属性も再帰的にたどられて含まれます。

それ以外の場合には、リストにはオブジェクトの属性名、クラス属性名、再帰的にたどった基底クラスの属性名が含まれます。

返されるリストはアルファベット順に並べられています。例えば

>>> import struct
>>> dir()   # doctest: +SKIP
['__builtins__', '__doc__', '__name__', 'struct']
>>> dir(struct)   # doctest: +NORMALIZE_WHITESPACE
['Struct', '__builtins__', '__doc__', '__file__', '__name__',
 '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
 'unpack', 'unpack_from']
>>> class Foo(object):
...     def __dir__(self):
...         return ["kan", "ga", "roo"]
...
>>> f = Foo()
>>> dir(f)
['ga', 'kan', 'roo']

ノート

dir() は主に対話プロンプトのために提供されているので、厳密さや一貫性をもって定義された名前のセットよりも、むしろ興味深い名前のセットを与えようとします。また、この関数の細かい動作はリリース間で変わる可能性があります。例えば、引数がクラスである場合、メタクラス属性は結果のリストに含まれません。

divmod(a, b)

2 つの (複素数でない) 数値を引数として取り、整数の除法を行ったときの商と剰余からなるペアを返します。被演算子が型混合である場合、 2 進算術演算子での規則が適用されます。通常の整数と長整数の場合、結果は (a // b, a % b) と同じです。浮動小数点数の場合、結果は (q, a % b) であり、 q は通常 math.floor(a / b) ですが、そうではなく 1 になることもあります。いずれにせよ、 q * b + a % b は a に非常に近い値になり、 a % b がゼロでない値の場合、その符号は b と同じで、 0 <= abs(a % b) < abs(b) になります。

バージョン 2.3 で変更: 複素数に対する divmod() の使用は廃用されました。

enumerate(sequence[, start=0])

列挙オブジェクトを返します。 sequence はシーケンス型、イテレータ型、反復をサポートする他のオブジェクト型のいずれかでなければなりません。 enumerate() が返すイテレータの next() メソッドは、 (ゼロから始まる) カウント値と、値だけ iterable を反復操作して得られる、対応するオブジェクトを含むタプルを返します。 enumerate() はインデクス付けされた値の列: (0, seq[0]), (1, seq[1]), (2, seq[2]), ... を得るのに便利です。例 :

>>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']):
...     print i, season
0 Spring
1 Summer
2 Fall
3 Winter

バージョン 2.3 で追加.

バージョン 2.6 で追加: start 引数が追加されました。

eval(expression[, globals[, locals]])

文字列とオプションの引数 globals 、 locals をとります。 globals を指定する場合には辞書でなくてはなりません。 locals は任意のマップ型にできます。

バージョン 2.4 で変更: 以前は locals も辞書でなければなりませんでした.

引数 expression は Python の表現式 (技術的にいうと、条件のリストです) として構文解釈され、評価されます。このとき辞書 globals および locals はそれぞれグローバルおよびローカルな名前空間として使われます。 global 辞書が存在するが、 ‘__builtins__’ が欠けている場合、 expression を解析する前に現在のグローバル変数を globals にコピーします。このことから、 expression は通常、標準の __builtin__ モジュールへの完全なアクセスを有し、制限された環境が伝播するようになっています。 locals 辞書が省略された場合、標準の値として globals に設定されます。辞書が両方とも省略された場合、表現式は eval() が呼び出されている環境の下で実行されます。構文エラーは例外として報告されます。

以下に例を示します :

>>> x = 1
>>> print eval('x+1')
2

この関数は (compile() で生成されるような) 任意のコードオブジェクトを実行するために利用することもできます。この場合、文字列の代わりにコードオブジェクトを渡します。このコードオブジェクトが、引数 mode を 'exec' としてコンパイルされている場合、 eval() が返す値は、 None になります。

ヒント: 文の動的な実行は exec 文でサポートされています。ファイルからの文の実行は関数 execfile() でサポートされています。関数 globals() および locals() は、それぞれ現在のグローバルおよびローカルな辞書を返すので、 eval() や execfile() で使うことができます。

リテラルだけを含む式の文字列を安全に評価できる関数、 ast.literal_eval() も参照してください。

execfile(filename[, globals[, locals]])

この関数は exec 文に似ていますが、文字列の代わりにファイルに対して構文解釈を行います。 import 文と違って、モジュール管理機構を使いません — この関数はファイルを無条件に読み込み、新たなモジュールを生成しません。 [1]

引数は文字列とオプションの 2 つの辞書からなります。 file は読み込まれ、 (モジュールのように) Python 文の列として評価されます。このとき globals および locals がそれぞれグローバル、および、ローカルな名前空間として使われます。 locals は任意のマップ型に指定できます。

バージョン 2.4 で変更: 以前は locals も辞書でなければなりませんでした.

locals 辞書が省略された場合、標準の値として globals に設定されます。辞書が両方とも省略された場合、表現式は execfiles() が呼び出されている環境の下で実行されます。戻り値は None です。

ノート

標準では locals は後に述べる関数 locals() のように動作します: 標準の locals 辞書に対する変更を試みてはいけません。 execfile() の呼び出しが返る時にコードが locals に与える影響を知りたいなら、明示的に loacals 辞書を渡してください。 execfile() は関数のローカルを変更するための信頼性のある方法として使うことはできません。

file(filename[, mode[, bufsize]])

file 型のコンストラクタです。詳しくはファイルオブジェクト 節を参照してください。コンストラクタの引数は後述の open() 組み込み関数と同じです。

ファイルを開くときは、このコンストラクタを直接呼ばずに open() を呼び出すのが望ましい方法です。 file は型テストにより適しています (たとえば isinstance(f, file) と書くような)。

バージョン 2.2 で追加.

filter(function, iterable)

iterable のうち、 function が真を返すような要素からなるリストを構築します。 iterable はシーケンスか、反復をサポートするコンテナか、イテレータです。 iterable が文字列型かタプル型の場合、結果も同じ型になります。そうでない場合はリストとなります。 function が None の場合、恒等関数を仮定します。すなわち、 iterable の偽となる要素は除去されます。

function が None ではない場合、 filter(function, iterable) は [item for item in iterable if function(item)] と同等です。 function が None の場合 [item for item in iterable if item] と同等です。

この関数のイテレータ版である itertools.ifilter() と itertools.ifilterfalse() についても参照して下さい、変種として function が false を返す場合に要素を返す変種も含んでいます。

float([x])

文字列または数値を浮動小数点数に変換します。引数が文字列の場合、十進の数または浮動小数点数を含んでいなければなりません。符号が付いていてもかまいません。また、空白文字中に埋め込まれていてもかまいません。引数は [+|-]nan 、 [+|-]inf であっても構いません。それ以外の場合、引数は通常整数、長整数、または浮動小数点数をとることができ、同じ値の浮動小数点数が (Python の浮動小数点精度で) 返されます。引数が指定されなかった場合、 0.0 を返します。

ノート

文字列で値を渡す際、背後の C ライブラリによって NaN および Infinity が返されるかもしれません。 float は文字列、 nan 、 inf 、および -inf を、それぞれ、 NaN 、正の無限大、負の無限大として解釈します。大文字小文字の違い、 + 記号、および、 nan に対する - 記号は無視されます。

浮動小数点数型については、 数値型 int, float, long, complex も参照下さい。

format(value[, format_spec])

value を format_spec で制御される “フォーマット化” 表現に変換します。 format_spec の評価は value 引数の型に依存しますが、ほとんどのビルト組み込み型で使われる標準的な構文が存在します 書式指定ミニ言語仕様 (Format Specification Mini-Language) 。

ノート

format(value, format_spec) は単に value.__format__(format_spec) を呼び出すだけです。

バージョン 2.6 で追加.

frozenset([iterable])

frozenset オブジェクトを返します。オプションで iterable から要素を取得します。 frozenset 型については、 set（集合）型 — set, frozenset も参照下さい。

他のコンテナ型については、組み込みクラスの dict, list, および , tuple と、 collections モジュールを参照下さい。

バージョン 2.4 で追加.

getattr(object, name[, default])

指定された object の属性を返します。 name は文字列でなくてはなりません。文字列がオブジェクトの属性名の一つであった場合、戻り値はその属性の値になります。例えば、 getattr(x, 'foobar') は x.foobar と等価です。指定された属性が存在しない場合、 default が与えられている場合にはそれが返されます。そうでない場合には AttributeError が送出されます。

globals()

現在のグローバルシンボルテーブルを表す辞書を返します。常に現在のモジュールの辞書になります (関数またはメソッドの中ではそれらを定義しているモジュールを指し、この関数を呼び出したモジュールではありません)。

hasattr(object, name)

引数はオブジェクトと文字列です。文字列がオブジェクトの属性名の一つであった場合 True を、そうでない場合 False を返します (この関数は getattr(object, name) を呼び出し、例外を送出するかどうかを調べることで実装されています)。

hash(object)

オブジェクトのハッシュ値を (存在すれれば) 返します。ハッシュ値は整数です。これらは辞書を検索する際に辞書のキーを高速に比較するために使われます。等しい値となる数値は等しいハッシュ値を持ちます (1 と 1.0 のように型が異なっていてもです)。

help([object])

組み込みヘルプシステムを起動します (この関数は対話的な使用のためのものです)。引数が与えられていない場合、対話的ヘルプシステムはインタプリタコンソール上で起動します。引数が文字列の場合、文字列はモジュール、関数、クラス、メソッド、キーワード、またはドキュメントの項目名として検索され、ヘルプページがコンソール上に印字されます。引数が何らかのオブジェクトの場合、そのオブジェクトに関するヘルプページが生成されます。

この関数は、 site モジュールから、組み込みの名前空間に移されました。

バージョン 2.2 で追加.

hex(x)

(任意のサイズの) 整数を16進の文字列に変換します。結果は Python の式としても使える形式になります。

ノート

浮動小数点数の16進文字列表記を得たい場合には、 float.hex() メソッドを使って下さい。

バージョン 2.4 で変更: 以前は符号なしのリテラルしか返しませんでした.

id(object)

オブジェクトの “識別値” を返します。この値は整数 (または長整数) で、このオブジェクトの有効期間は一意かつ定数であることが保証されています。オブジェクトの有効期間が重ならない 2 つのオブジェクトは同じ id() 値を持つかもしれません。

input([prompt])

eval(raw_input(prompt)) と同じです。

警告

この関数はユーザのエラーに対して安全ではありません ! この関数は、入力は有効な Python の式であると期待しています; 入力が構文的に正しくない場合、 SyntaxError が送出されます。式を評価する際にエラーが生じた場合、他の例外も送出されるかもしれません。 (一方、この関数はまさに、ときどき熟練者がすばやくスクリプトを書く際に必要とするものです)

readline モジュールが読み込まれていれば、 input() は精緻な行編集およびヒストリ機能を提供します。

一般的なユーザからの入力のための関数としては raw_input() を使うことを検討してください。

int([x[, base]])

文字列または数値を通常の整数に変換します。引数が文字列の場合、 Python 整数として表現可能な十進の数でなければなりません。符号が付いていてもかまいません。また、空白文字中に埋め込まれていてもかまいません。 base 引数は変換の基数 (デフォルト値は10です) を表し、範囲 [2, 36] の整数またはゼロをとることができます。 base がゼロの場合、文字列の内容から適切な基数を推測します; 変換は整数リテラルと同じです (数値リテラル を参照下さい) 。 base が指定されており、 x が文字列でない場合、 TypeError が送出されます。それ以外の場合、引数は通常整数、長整数、または浮動小数点数をとることができます。浮動小数点数から整数へ変換では (ゼロ方向に) 値を丸めます。引数が通常整数の範囲を超えている場合、長整数が代わりに返されます。引数が与えられなかった場合、 0 を返します。

整数型については、 数値型 int, float, long, complex も参照下さい。

isinstance(object, classinfo)

引数 object が引数 classinfo のインスタンスであるか、 (直接または間接的な) サブクラスのインスタンスの場合に真を返します。また、 classinfo が型オブジェクト (新しい形式のクラス) であり、 object がその型のオブジェクトであるか、または、 (直接的または間接的な) サブクラスの場合にも真を返します。 object がクラスインスタンスや与えられた型のオブジェクトでない場合、この関数は常に偽を返します。 classinfo をクラスオブジェクトでも型オブジェクトにもせず、クラスや型オブジェクトからなるタプルや、そういったタプルを再帰的に含むタプル (他のシーケンス型は受理されません) でもかまいません。 classinfo がクラス、型、クラスや型からなるタプル、そういったタプルが再帰構造をとっているタプルのいずれでもない場合、例外 TypeError が送出されます。

バージョン 2.2 で変更: 型情報をタプルにした形式のサポートが追加されました。

issubclass(class, classinfo)

class が classinfo の (直接または間接的な) サブクラスである場合に真を返します。クラスはそれ自身のサブクラスとみなされます。 classinfo はクラスオブジェクトからなるタプルでもよく、この場合には classinfo のすべてのエントリが調べられます。その他の場合では、例外 TypeError が送出されます。

バージョン 2.3 で変更: 型情報からなるタプルへのサポートが追加されました.

iter(o[, sentinel])

iterator (イテレータ)オブジェクトを返します。 2 つ目の引数があるかどうかで、最初の引数の解釈は非常に異なります。 2 つ目の引数がない場合、 o は反復プロトコル (__iter__() メソッド) か、シーケンス型プロトコル (引数が 0 から開始する __getitem__() メソッド) をサポートする集合オブジェクトでなければなりません。これらのプロトコルが両方ともサポートされていない場合、 TypeError が送出されます。 2 つ目の引数 sentinel が与えられていれば、 o は呼び出し可能なオブジェクトでなければなりません。この場合に生成されるイテレータは、 next() を呼ぶ毎に o を引数無しで呼び出します。返された値が sentinel と等しければ、 StopIteration が送出されます。そうでない場合、戻り値がそのまま返されます。

ファイルの行を特定の行にたどりつくまで読むのに iter() の第2の形式の便利に応用できます。以下の例では "STOP" にたどりつくまでファイルを読みます:

with open("mydata.txt") as fp:
    for line in iter(fp.readline, "STOP"):
    process_line(line)

バージョン 2.2 で追加.

len(s)

オブジェクトの長さ (要素の数) を返します。引数はシーケンス型 (文字列、タプル、またはリスト) か、マップ型 (辞書) です。

list([iterable])

iterable の要素と同じ要素をもち、かつ順番も同じなリストを返します。 sequence はシーケンス、反復処理をサポートするコンテナ、あるいはイテレータオブジェクトです。 sequence がすでにリストの場合、 iterable[:] と同様にコピーを作成して返します。例えば、 list('abc') は ['a', 'b', 'c'] および list((1, 2, 3)) は [1, 2, 3] を返します。引数が与えられなかった場合、新しい空のリスト [] を返します。

list は変更可能なシーケンス型であり、 シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange に記述があります。他のコンテナ型については組み込み型の dict, set, および tuple クラスと、 collections モジュールを参照下さい。

locals()

現在のローカルシンボルテーブルを表す辞書を更新して返します。関数ブロックで locals() を呼び出した場合自由変数が返されます、クラスブロックでは返されません。

ノート

この辞書の内容は変更してはいけません; 値を変更しても、インタプリタが使うローカル変数や自由変数の値には影響しません。

long([x[, base]])

文字列または数値を長整数値に変換します。引数が文字列の場合、 Python 整数として表現可能な十進の数でなければなりません。符号が付いていてもかまいません。また、空白文字中に埋め込まれていてもかまいません。 base 引数は int() と同じように解釈され、 x が文字列の時だけ与えることができます。それ以外の場合、引数は通常整数、長整数、または浮動小数点数をとることができ、同じ値の長整数が返されます。浮動小数点数から整数へ変換では (ゼロ方向に) 値を丸めます。引数が与えられなかった場合、 0L を返します。

長整数型については、 数値型 int, float, long, complex も参照下さい。

map(function, iterable, ...)

function を iterable の全ての要素に適用し、返された値からなるリストを返します。追加の iterable 引数を与えた場合、 function はそれらを引数として取らなければならず、関数はそのリストの全ての要素について個別に適用されます; 他のリストより短いリストがある場合、要素 None で延長されます。 function が None の場合、恒等関数であると仮定されます; すなわち、複数のリスト引数が存在する場合、 map() は全てのリスト引数に対し、対応する要素からなるタプルからなるリストを返します (転置操作のようなものです)。 list 引数はどのようなシーケンス型でもかまいません; 結果は常にリストになります。

max(iterable[, args...][key])

引数が iterable だけの場合、空でないシーケンス (文字列、タプルまたはリスト) の要素のうち最大のものを返します。 1 個よりも引数が多い場合、引数間で最大のものを返します。

オプションの key 引数には list.sort() で使われるのと同じような 1 引数の順序付け関数を指定します。 key を指定する場合はキーワード形式でなければなりません (たとえば max(a,b,c,key=func))。

バージョン 2.5 で変更: オプションの key 引数が追加されました.

memoryview(obj)

与えられたオブジェクトから作られた “メモリビュー” オブジェクトを返します。詳しくは メモリビュー型 を参照してください。

min(iterable[, args...][key])

引数が iterable だけの場合、空でないシーケンス (文字列、タプルまたはリスト) の要素のうち最小のものを返します。 1 個よりも引数が多い場合、引数間で最小のものを返します。

オプションの key 引数には list.sort() で使われるのと同じような 1 引数の順序付け関数を指定します。 key を指定する場合はキーワード形式でなければなりません (たとえば min(a,b,c,key=func))。

バージョン 2.5 で変更: オプションの key 引数が追加されました.

next(iterator[, default])

iterator から、 next() メソッドにより、次の要素を取得します。もし、 default が与えられると、イテレータが空である場合に、それが返されます。それ以外の場合は、 StopIteration が送出されます。

バージョン 2.6 で追加.

object()

ユーザ定義の属性やメソッドを持たない、新しいオブジェクトを返します。 object() は新スタイルのクラスの、基底クラスです。これは、新スタイルのクラスのインスタンスに共通のメソッド群を持ちます。

バージョン 2.2 で追加.

バージョン 2.3 で変更: この関数はいかなる引数も受け付けません。以前は、引数を受理しましたが無視していました。

oct(x)

(任意のサイズの) 整数を 8 進の文字列に変換します。結果は Python の式としても使える形式になります。

バージョン 2.4 で変更: 以前は符号なしのリテラルしか返しませんでした.

open(filename[, mode[, bufsize]])

ファイルを開いて、 ファイルオブジェクト にて説明される、 file オブジェクトを返します。もし、ファイルが開けないなら、 IOError が送出されます。ファイルを開くときは file のコンストラクタを直接呼ばずに open() を使うのが望ましい方法です。

最初の 2 つの引数は stdio の fopen() と同じです: filename は開きたいファイルの名前で、 mode はファイルをどのようにして開くかを指定します。

最もよく使われる mode の値は、読み出しの 'r' 、書き込み (ファイルがすでに存在すれば切り詰められます) の 'w' 、追記書き込みの 'a' です ( いくつかの Unix システムでは、 全て の書き込みが現在のファイルシーク位置に関係なくファイルの末尾に追加されます)。 mode が省略された場合、標準の値は 'r' になります。デフォルトではテキストモードでファイルを開きます。 '\n' 文字は、プラットフォームでの改行の表現に変換されます。移植性を高めるために、バイナリファイルを開くときには、 mode の値に 'b' を追加しなければなりません。(バイナリファイルとテキストファイルを区別なく扱うようなシステムでも、ドキュメンテーションの代わりになるので便利です。) 他に mode に与えられる可能性のある値については後述します。

オプションの bufsize 引数は、ファイルのために必要とするバッファのサイズを指定します: 0 は非バッファリング、 1 は行単位バッファリング、その他の正の値は指定した値 (の近似値) のサイズをもつバッファを使用することを意味します。 bufsize の値が負の場合、システムの標準を使います。通常、tty 端末は行単位のバッファリングであり、その他のファイルは完全なバッファリングです。省略された場合、システムの標準の値が使われます。 [2]

'r+', 'w+', および 'a+' はファイルを更新モードで開きます ('w+' はファイルがすでに存在すれば切り詰めるので注意してください)。バイナリとテキストファイルを区別するシステムでは、ファイルをバイナリモードで開くためには 'b' を追加してください (区別しないシステムでは 'b' は無視されます)。

標準の fopen() における mode の値に加えて、 'U' または 'rU' を使うことができます。 Python が全改行文字サポートを行っている (標準ではしています) 場合、ファイルがテキストファイルで開かれますが、行末文字として Unix における慣行である '\n' 、Macintosh における慣行である '\r' 、 Windows における慣行である '\r\n' のいずれを使うこともできます。これらの改行文字の外部表現はどれも、 Python プログラムからは '\n' に見えます。 Python が全改行文字サポートなしで構築されている場合、 mode 'U' は通常のテキストモードと同様になります。開かれたファイルオブジェクトはまた、 newlines と呼ばれる属性を持っており、その値は None (改行が見つからなかった場合)、 '\n', '\r', '\r\n', または見つかった全ての改行タイプを含むタプルになります。

'U' を取り除いた後のモードは 'r', 'w', 'a' のいずれかで始まる、というのが Python における規則です。

Python では、 fileinput, os, os.path, tempfile, shutil などの多数のファイル操作モジュールが提供されています。

バージョン 2.5 で変更: モード文字列の先頭についての制限が導入されました.

ord(c)

長さ 1 の与えられた文字列に対し、その文字列が unicode オブジェクトならば Unicode コードポイントを表す整数を、 8 ビット文字列ならばそのバイトの値を返します。たとえば、 ord('a') は整数 97 を返し、 ord(u'\u2020') は 8224 を返します。この値は 8 ビット文字列に対する chr() の逆であり、 unicode オブジェクトに対する unichr() の逆です。引数が unicode で Python が UCS2 Unicode 対応版ならば、その文字のコードポイントは両端を含めて [0..65535] の範囲に入っていなければなりません。この範囲から外れると文字列の長さが 2 になり、 TypeError が送出されることになります。

pow(x, y[, z])

x の y 乗を返します; z があれば、 x の y 乗に対する z のモジュロを返します (pow(x, y)% z より効率よく計算されます)。引数二つの pow(x, y) という形式は、冪乗演算子を使った x**y と等価です。

引数は数値型でなくてはなりません。型混合の場合、 2 進算術演算における型強制規則が適用されます。通常整数、および、長整数の被演算子に対しては、二つ目の引数が負の数でない限り、結果は (型強制後の) 被演算子と同じ型になります; 負の場合、全ての引数は浮動小数点型に変換され、浮動小数点型の結果が返されます。例えば、 10**2 は 100 を返しますが、 10**-2 は 0.01 を返します。 (最後に述べた機能は Python 2.2 で追加されたものです。 Python 2.1 以前では、双方の引数が整数で二つ目の値が負の場合、例外が送出されます。) 二つ目の引数が負の場合、三つめの引数は無視されます。 z がある場合、 x および y は整数型でなければならず、 y は非負の値でなくてはなりません (この制限は Python 2.2 で追加されました。 Python 2.1 以前では、 3 つの浮動小数点引数を持つ pow() は浮動小数点の丸めに関する偶発誤差により、プラットフォーム依存の結果を返します)。

print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout])

object (複数でも可) を sep で区切りながらストリーム、 file に表示し、最後に end を表示します。 sep, end そして file が与えられる場合、キーワード引数として与えられる必要があります。

キーワードなしの引数は、 str() がするように、すべて、文字列に変換され、 sep で区切られながらストリームに書き出され、最後に end を書き出します。 sep と end の両方とも、文字列でなければなりません。; デフォルトの値を指定するために、 None であっても構いません。もし、 object が与えられなければ、 print() は、単純に end だけ書き出します。

file 引数は、 write(string) メソッドを持つオブジェクトでなければなりません。指定されないか、 None であった場合には、 sys.stdout が使われます。

ノート

この関数は print という名前が print ステートメントとして解釈されるため、通常は使用できません。ステートメントを無効化して、 print() 関数を使うためには、以下の future ステートメントをモジュールの最初に書いて下さい。:

from __future__ import print_function

バージョン 2.6 で追加.

property([fget[, fset[, fdel[, doc]]]])

new-style class (新しい形式のクラス) (object から派生したクラス) におけるプロパティ属性を返します。

fget は属性値を取得するための関数で、同様に fset は属性値を設定するための関数です。また、 fdel は属性を削除するための関数です。以下に属性 x を扱う典型的な利用法を示します。:

class C(object):
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x
    def setx(self, value):
        self._x = value
    def delx(self):
        del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

もし c が C のインスタンスならば、 c.x は getter を呼び出し、 c.x = value は setter を、 del c.x は deleter を呼び出します。

doc がもし与えられたならばそれがプロパティ属性のドキュメント文字列になります。与えられない場合、プロパティは fget のドキュメント文字列(もしあれば)をコピーします。これにより、読み取り専用プロパティを property() を decorator (デコレータ)として使って容易に作れるようになります。:

class Parrot(object):
    def __init__(self):
        self._voltage = 100000

    @property
    def voltage(self):
        """Get the current voltage."""
        return self._voltage

のようにすると、 voltage() が同じ名前の読み取り専用属性の “getter” になります。

プロパティオブジェクトは getter, setter, および deleter メソッドを備えています。これらのメソッドは属性のコピーを生成するデコレータに適していて、デコレートした関数を対応する属性参照関数に割り当てます。これを説明するには、以下の例が最適でしょう。:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

このコードは、最初の例と等価です。追加の関数に、元々の属性と同じ名前 (この例では、 x です) を与えることに注意して下さい。

返される属性も、コンストラクタの引数を反映した、 fget, fset, そして fdel 属性を持ちます。

バージョン 2.2 で追加.

バージョン 2.5 で変更: doc が与えられない場合に fget のドキュメント文字列を使う。

バージョン 2.6 で変更: getter, setter そして deleter 属性が追加されました。

range([start], stop[, step])

等差数列を含むリストを生成するための多機能関数です。 for ループでよく使われます。引数は通常の整数でなければなりません。 step 引数が無視された場合、標準の値 1 になります。 start 引数が省略された場合、標準の値 0 になります。完全な形式では、通常の整数列 [start, start + step, start + 2 * step, ...] を返します。 step が正の値の場合、最後の要素は stop よりも小さい start + i * step の最大値になります; step が負の値の場合、最後の要素は stop よりも大きい start + i * step の最小値になります。 step はゼロであってはなりません (さもなければ ValueError が送出されます)。以下に例を示します。:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]

raw_input([prompt])

引数 prompt が存在する場合、末尾の改行を除いて標準出力に出力されます。次に、この関数は入力から 1 行を読み込んで文字列に変換して (末尾の改行を除いて) 返します。 EOF が読み込まれると EOFError が送出されます。以下に例を示します。:

>>> s = raw_input('--> ')
--> Monty Python's Flying Circus
>>> s
"Monty Python's Flying Circus"

readline モジュールが読み込まれていれば、 input() は精緻な行編集およびヒストリ機能を提供します。

reduce(function, iterable[, initializer])

iterable の要素に対して、iterableを単一の値に短縮するような形で 2 つの引数をもつ function を左から右に累積的に適用します。例えば、 reduce(labmda x, y: x+y, [1, 2, 3, 4, 5]) は ((((1+2)+3)+4)+5) を計算します。左引数 x は累計の値になり、右引数 y は iterable から取り出した更新値になります。オプションの initializer が存在する場合、計算の際に iterable の先頭に置かれます。また、 iterable が空の場合には標準の値になります。 initializer が与えられておらず、 iterable が単一の要素しか持っていない場合、最初の要素が返されます。

reload(module)

すでにインポートされた module を再解釈し、再初期化します。引数はモジュールオブジェクトでなければならないので、予めインポートに成功していなければなりません。この関数はモジュールのソースコードファイルを外部エディタで編集して、 Python インタプリタから離れることなく新しいバージョンを試したい際に有効です。戻り値は (module 引数と同じ) モジュールオブジェクトです。

reload(module) を実行すると、以下の処理が行われます:

Python モジュールのコードは再コンパイルされ、モジュールレベルのコードは再度実行されます。モジュールの辞書中にある、何らかの名前に結び付けられたオブジェクトを新たに定義します。拡張モジュール中の init 関数が二度呼び出されることはありません。

Python における他のオブジェクトと同様、以前のオブジェクトのメモリ領域は、参照カウントがゼロにならないかぎり再利用されません。

モジュール名前空間内の名前は新しいオブジェクト (または更新されたオブジェクト) を指すよう更新されます。

以前のオブジェクトが (外部の他のモジュールなどからの) 参照を受けている場合、それらを新たなオブジェクトに再束縛し直すことはないので、必要なら自分で名前空間を更新せねばなりません。

いくつか補足説明があります:

モジュールは文法的に正しいが、その初期化には失敗した場合、そのモジュールの最初の import 文はモジュール名をローカルにはバインドしませんが、(部分的に初期化された) モジュールオブジェクトを sys.modules に記憶します。従って、そのモジュールをロードしなおすには、 reload() する前にまず import (モジュールの名前を部分的に初期化されたオブジェクトにバインドします) を再度行わなければなりません。

モジュールが再ロードされた再、その辞書 (モジュールのグローバル変数を含みます) はそのまま残ります。名前の再定義を行うと、以前の定義を上書きするので、一般的には問題はありません。新たなバージョンのモジュールが古いバージョンで定義された名前を定義していない場合、古い定義がそのまま残ります。辞書がグローバルテーブルやオブジェクトのキャッシュを維持していれば、この機能をモジュールを有効性を引き出すために使うことができます — つまり、 try 文を使えば、必要に応じてテーブルがあるかどうかをテストし、その初期化を飛ばすことができます。:

try:
    cache
except NameError:
    cache = {}

組み込みモジュールや動的にロードされるモジュールを再ロードすることは、不正なやり方ではありませんが、一般的にそれほど便利ではありません。例外は sys, __main__ および __builtin__ です。しかしながら、多くの場合、拡張モジュールは 1 度以上初期化されるようには設計されておらず、再ロードされた場合には何らかの理由で失敗するかもしれません。

一方のモジュールが from ... import ... を使って、オブジェクトを他方のモジュールからインポートしているなら、他方のモジュールを reload() で呼び出しても、そのモジュールからインポートされたオブジェクトを再定義することはできません — この問題を回避する一つの方法は、 from 文を再度実行することで、もう一つの方法は from 文の代わりに import と限定的な名前 (module.*name*) を使うことです。

あるモジュールがクラスのインスタンスを生成している場合、そのクラスを定義しているモジュールの再ロードはそれらインスタンスのメソッド定義に影響しません — それらは古いクラス定義を使いつづけます。これは派生クラスの場合でも同じです。

repr(object)

オブジェクトの印字可能な表現を含む文字列を返します。これは型変換で得られる (逆クオートの) 値と同じです。通常の関数としてこの操作にアクセスできるとたまに便利です。この関数は多くの型について、 eval() に渡されたときに同じ値を持つようなオブジェクトを表す文字列を生成しようとします。そうでない場合は、角括弧に囲まれたオブジェクトの型の名前と追加の情報 (大抵の場合はオブジェクトの名前とアドレスを含みます) を返します。クラスは、 __repr__() メソッドを定義することで、この関数によりそのクラスのインスタンスが返すものを制御することができます。

reversed(seq)

要素を逆順に取り出すイテレータ (reverse iterator) を返します。 seq は __reversed__() メソッドを持つオブジェクトであるか、シーケンス型プロトコル (__len__() メソッド、および、 0 から始まる整数を引数にとる __getitem__() メソッド) をサポートしていなければなりません。

バージョン 2.4 で追加.

バージョン 2.6 で変更: カスタムの __reversed__() メソッドを書く可能性を追加しました。

round(x[, n])

x を小数点以下 n 桁で丸めた浮動小数点数の値を返します。 n が省略されると、標準の値はゼロになります。結果は浮動小数点数です。値は最も近い 10 のマイナス n の倍数に丸められます。二つの倍数との距離が等しい場合、ゼロから離れる方向に丸められます (従って、例えば round(0.5) は 1.0 になり、 round(-0.5) は -1.0 になります)。

ノート

浮動小数点数に対する round() の振る舞いは意外なものかもしれません: 例えば、 round(2.675, 2) は予想通りの 2.68 ではなく 2.67 を与えます。これはバグではありません: これはほとんどの少数が浮動小数点数で正確に表せないことの結果です。詳しくは浮動小数点演算、その問題と制限 を参照してください。

set([iterable])

新しいセット型オブジェクトを返します。オプションで iterable からとった要素を持たせることもできます。 set 型については、 set（集合）型 — set, frozenset に説明があります。

他のコンテナについては、組み込みクラスの dict, list, および tuple クラス、および、 collections モジュールを参照下さい。

バージョン 2.4 で追加.

setattr(object, name, value)

getattr() と対をなす関数です。引数はそれぞれオブジェクト、文字列、そして任意の値です。文字列はすでに存在する属性の名前でも、新たな属性の名前でもかまいません。この関数は指定した値を指定した属性に関連付けますが、指定したオブジェクトにおいて可能な場合に限ります。例えば、 setattr(x, 'foobar', 123) は x.foobar = 123 と等価です。

slice([start], stop[, step])

range(start, stop, step) で指定されるインデクスの集合を表すスライス(slice)オブジェクトを返します。 range(start) スライスオブジェクトを返します。引数 start および step は標準では None です。スライスオブジェクトは読み出し専用の属性 start, stop および step を持ち、これらは単に引数で使われた値 (または標準の値) を返します。これらの値には、その他のはっきりとした機能はありません; しかしながら、これらの値は Numerical Python および、その他のサードパーティによる拡張で利用されています。スライスオブジェクトは拡張されたインデクス指定構文が使われる際にも生成されます。例えば: a[start:stop:step] や a[start:stop, i] です。イテレータを返すもうひとつの関数、 itertools.islice() も参照下さい。

sorted(iterable[, cmp[, key[, reverse]]])

iterable の要素をもとに、並べ替え済みの新たなリストを生成して返します。

オプション引数 cmp, key, および reverse の意味は list.sort() メソッドと同じです。 (変更可能なシーケンス型 節に説明があります。)

cmp は2つの引数 (iterable の要素) からなるカスタムの比較関数を指定します。これは始めの引数が 2 つ目の引数に比べて小さい、等しい、大きいかに応じて負数、ゼロ、正数を返します。 cmp=lambda x,y: cmp(x.lower(), y.lower()) 。デフォルト値は None です。

key は 1 つの引数からなる関数を指定します。これは個々のリストの要素から比較のキーを取り出すのに使われます。 key=str.lower 。デフォルト値は None です (要素を直接比較します)。

reverse は真偽値です。 True がセットされた場合、リストの要素は個々の比較が反転したものとして並び替えられます。

一般的に、 key および reverse の変換プロセスは同等の cmp 関数を指定するより早く動作します。これは key および reverse がそれぞれの要素に一度だけ触れる間に、 cmp はリストのそれぞれの要素に対して複数回呼ばれることによるものです。旧式の cmp 関数を key 関数に変換するには functools.cmp_to_key() を使用してください。

並ベ替えの例と簡潔なチュートリアルとして、 Sorting HowTo [http://wiki.python.org/moin/HowTo/Sorting/] を参照して下さい。

バージョン 2.4 で追加.

staticmethod(function)

function の静的メソッドを返します。

静的メソッドは暗黙の第一引数を受け取りません。静的メソッドの宣言は、以下のように書き慣わされます:

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@staticmethod は関数 decorator (デコレータ)形式です。詳しくは 関数定義 の関数定義についての説明を参照してください。

このメソッドはクラスで呼び出すこと (例えば C.f() ) も、インスタンスとして呼び出すこと (例えば C().f()) もできます。インスタンスはそのクラスが何であるかを除いて無視されます。

Python における静的メソッドは Java や C++ における静的メソッドと類似しています。より進んだ概念については、 classmethod() を参照してください。

もっと静的メソッドについての情報が必要ならば、 標準型の階層 の標準型階層についてのドキュメントを繙いてください。

バージョン 2.2 で追加.

バージョン 2.4 で変更: 関数デコレータ構文を追加しました.

str([object])

オブジェクトをうまく印字可能な形に表現したものを含む文字列を返します。文字列に対してはその文字列自体を返します。 repr(object) との違いは、 str(object) は常に eval() が受理できるような文字列を返そうと試みるわけではないという点です; この関数の目的は印字可能な文字列を返すところにあります。引数が与えられなかった場合、空の文字列 '' を返します。

文字列についての詳細は、シーケンスの機能についての説明、シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange を参照下さい(文字列はシーケンスです)。また、文字列特有のメソッドについては、 文字列メソッド を参照下さい。整形した文字列を出力するためには、テンプレート文字列か、文字列フォーマット操作 にて説明される % 演算子を使用して下さい。さらには、 文字列処理 と unicode() も参照下さい。

sum(iterable[, start])

start と iterable の要素を左から右へ合計し、総和を返します。 start はデフォルトで 0 です。 iterable の要素は通常は数値で、start の値は文字列であってはなりません。

使う場面によっては、 sum() よりもいい選択肢があります。文字列からなるシーケンスを結合する高速かつ望ましい方法は ''.join(sequence) を呼ぶことです。浮動小数点数値を拡張された精度で加算するには、 math.fsum() を参照下さい。一連のイテラブルを連結するには、 itertools.chain() の使用を考えてください。

super([type[, object-or-type]])

メソッドの呼び出しを type の親または兄弟クラスに委譲する、プロキシオブジェクトを返します。これはクラスの中でオーバーライドされた継承メソッドにアクセスするのに便利です。探索の順序は、 type 自身が飛ばされるのをのぞいて getattr() と同じです。

type の __mro__ 属性は、 getattr() と super() の両方で使われる、メソッド解決の探索順序を列記します。この属性は動的で、継承の階層構造が更新されれば、随時変化します。

第 2 引数が省かれたなら、返されるスーパーオブジェクトは束縛されません。第 2 引数がオブジェクトであれば、 isinstance(obj, type) は真でなければなりません。第 2 引数が型であれば、 issubclass(type2, type) は真でなければなりません (これはクラスメソッドに役に立つでしょう)。

super の典型的な用途は 2 つあります。単一の継承をしているクラス階層構造では、 super は名前を明示することなく親クラスを参照するのに使え、これでコードはメンテナンスしやすくなります。この用途の super は他のプログラミング言語で見られるものと近い方向性です。

2 つ目の用途は、動的な実行環境下での複数の継承の共同をサポートすることです。この用途は Python 特有で、静的にコンパイルされる言語や、単一の継承しかサポートしない言語では見られないものです。これは複数の基底クラスが同じメソッドを実装する “diamond diagram” を実装できるようにします。良い設計のために、このメソッドがすべての場合に同じ形式で呼び出せるべきです (呼び出しの順序が実行時に決定されることや、順序がクラスの階層の変更に対応することや、その順序には実行時まで未知の兄弟クラスが含まれえることが理由です)。

両方のケースにおいて、典型的なスーパークラスの呼び出しはこのようになるでしょう。

class C(B):
    def method(self, arg):
        super(C, self).method(arg)

super() は super(C, self).__getitem__(name) のような明示的なドット表記による属性参照の一部として使うように実装されていることに注意して下さい。これは、 __getattribute__() メソッドを、協調的な多重継承をサポートするための予測可能な順序でクラスを検索するように実装することで実現されています。従って、 super() は super()[name] のような文や演算子を使った非明示的な属性参照向けには定義されていないので注意してください。

また、 super() の使用がメソッド内部に限定されないことにも注目して下さい。引数を2つ渡す形式の呼び出しは、必要な要素を正確に指定するので、適当な参照を作ることができます。

バージョン 2.2 で追加.

tuple([iterable])

iterable の要素と要素が同じで、かつ順番も同じになるタプルを返します。 iterable はシーケンス型、反復をサポートするコンテナ型、およびイテレータオブジェクトをとることができます。 iterable がすでにタプルの場合、そのタプルを変更せずに返します。例えば、 tuple('abc') は ('a', 'b', 'c') を返し、 tuple([1, 2, 3]) は (1, 2, 3) を返します。

tuple クラスは、不変のシーケンス型で、 シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange にて説明されます。他のコンテナ型については、組み込みクラスの dict, list, および set と、 collections モジュールを参照下さい。

type(object)

object の型を返します。オブジェクトの型の検査には isinstance() 組み込み関数を使うことが推奨されます。

3 引数で呼び出された場合には type() 関数は後述するようにコンストラクタとして働きます。

type(name, bases, dict)

新しい型オブジェクトを返します。本質的には class 文の動的な形です。 name 文字列はクラス名で、 __name__ 属性になります。 bases タプルは基底クラスの羅列で、 __bases__ 属性になります。 dict 辞書はクラス本体の定義を含む名前空間で、 __dict__ 属性になります。たとえば、以下の二つの文は同じ type オブジェクトを作ります。 :

>>> class X(object):
...     a = 1
...
>>> X = type('X', (object,), dict(a=1))

バージョン 2.2 で追加.

unichr(i)

Unicode におけるコードが整数 i になるような文字 1 文字からなる Unicode 文字列を返します。例えば、 unichr(97) は文字列 u'a' を返します。この関数は Unicode 文字列に対する ord() の逆です。引数の正当な範囲は Python がどのように構成されているかに依存しています — UCS2 ならば [0..0xFFFF] であり UCS4 ならば [0..0x10FFFF] であり、このどちらかです。それ以外の値に対しては ValueError が送出されます。ASCIIの 8 ビットの文字列に対しては、 chr() を参照下さい。

バージョン 2.0 で追加.

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 文字列を返すということです。

__unicode__() メソッドを提供しているオブジェクトの場合、 unicode() はこのメソッドを引数なしで呼び出して Unicode 文字列を生成します。それ以外のオブジェクトの場合、 8 ビットの文字列か、オブジェクトのデータ表現 (representation) を呼び出し、その後デフォルトエンコーディングで 'strict' モードの codec を使って Unicode 文字列に変換します。

Unicode 文字列についてのさらなる情報については、シーケンス型の機能についての説明、 シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange を参照下さい(Unicode 文字列はシーケンスです)。また、文字列特有のメソッドについては、文字列メソッド を参照下さい。整形した文字列を出力するためには、テンプレート文字列か、 文字列フォーマット操作 にて説明される % 演算子を使用して下さい。さらには、 文字列処理 と str() も参照下さい。

バージョン 2.0 で追加.

バージョン 2.2 で変更: __unicode__() のサポートが追加されました.

vars([object])

引数無しでは、 locals() のように動作します。

モジュール、クラス、またはクラスインスタンスオブジェクト (またはその他 __dict__ 属性を持つもの) を引数として与えた場合、その属性を返します。

ノート

返される辞書は変更すべきではありません: 変更が対応するシンボルテーブルにもたらす影響は未定義です。 [3]

xrange([start], stop[, step])

この関数は range() に非常によく似ていますが、リストの代わりに “xrange オブジェクト” を返します。このオブジェクトは不透明なシーケンス型で、対応するリストと同じ値を持ちますが、それらの値全てを同時に記憶しません。 ragne() に対する xrange() の利点は微々たるものです (xrange() は要求に応じて値を生成するからです) ただし、メモリ量の厳しい計算機で巨大な範囲の値を使う時や、(ループがよく break で中断されるといったように) 範囲中の全ての値を使うとは限らない場合はその限りではありません。

CPython implementation detail: xrange() はシンプルさと速度のために定義されている関数であり、その実現のために実装上の制限を課している場合があります。 Python の C 実装では、全ての引数をネイティブの C long 型 (Python の “short” 整数型) に制限しており、要素数がネイティブの C long 型の範囲内に収まるよう要求しています。もし大きな範囲が必要ならば、別の実装である itertools モジュールの、 islice(count(start, step), (stop-start+step-1+2*(step<0))//step) を使うのが巧い方法かも知れません。

zip([iterable, ...])

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

iterable の、左から右への評価順序が保証されます。そのため zip(*[iter(s)]*n) を使ってデータ系列を n 長のグループにするクラスタリングすることができます。

* 演算子と共の論理積に対して、リストを upzip するために zip() を使うこともできます。

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True

バージョン 2.0 で追加.

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

__import__(name[, globals[, locals[, fromlist[, level]]]])

ノート

これは日々の Python プログラミングでは必要ではない、高等な関数です。

この関数は import ステートメントにより呼び出されます。これは (__builtin__ モジュールをインポートし、 __builtin__.__import__ を割り当てることで) import ステートメントの意味を変更するための置き換えが可能ですが、今では、フックをインポートするほうが、大抵の場合簡単です (PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照下さい)。 __import__() を直接使用することは稀で、例外は、実行時に名前が決定するモジュールをインポートするときです。

この関数は、モジュール、 name をインポートし、 globals と locals が与えられれば、パッケージのコンテキストで名前をどう解釈するか決定するのに使います。 fromlist はオブジェクト、もしくは、サブモジュールの名前を与え、 name で与えられるモジュールからインポートされる必要があります。標準的な実装では、 locals 引数はまったく使われず、 globals だけが import ステートメントのパッケージコンテキストを決定するために使われます。

level は絶対、もしくは、相対のどちらのインポートを使うかを指定します。デフォルトは -1 で絶対、相対インポートの両方を試みます。 0 は絶対インポートのみ実行します。正の level の値は、 __import__() を呼び出したディレクトリから検索対象となる親ディレクトリの階層を示します。

name は通常、 package.module の形式となり、 name で与えられた名前 ではなく 最上位のパッケージ (最初のドットまでの名前) が返されます。しかしながら、空でない fromlist 引数が与えられると、 name で与えられた名前が返されます。

例えば、 import spam ステートメントは、以下のようなバイトコードに帰結します。

spam = __import__('spam', globals(), locals(), [], -1)

import spam.ham ステートメントは、以下となります。

spam = __import__('spam.ham', globals(), locals(), [], -1)

ここで __import__() がどのように最上位モジュールを返しているかに注意して下さい。 import ステートメントにより、名前が飛び越されたオブジェクトになっています。

一方で、 from spam.ham import eggs, sausage as saus ステートメントは、以下となります。

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
eggs = _temp.eggs
saus = _temp.sausage

ここで、 spam.ham モジュールが __import__() より返されます。このオブジェクトからインポートされる名前が取り出され、それぞれの名前として割り当てられます。

単純にモジュールをインポートする場合(パッケージの範囲内であるかも知れません)、 __import__() を呼び出して、 sys.modules から見付けることもできます。

>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from >
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from >

バージョン 2.5 で変更: level パラメータが追加されました。

バージョン 2.5 で変更: Keyword サポートパラメータが追加されました。

3. 非必須組み込み関数 (Non-essential Built-in Functions)

いくつかの組み込み関数は、現代的な Python プログラミングを行う場合には、必ずしも学習したり、知っていたり、使ったりする必要がなくなりました。こうした関数は古いバージョンの Python 向け書かれたプログラムとの互換性を維持するだけの目的で残されています。

Python のプログラマ、教官、学生、そして本の著者は、こうした関数を飛ばしてもかまわず、その際に何か重要なことを忘れていると思う必要もありません。

apply(function, args[, keywords])

引数 function は呼び出しができるオブジェクト (ユーザ定義および組み込みの関数またはメソッド、またはクラスオブジェクト) でなければなりません。 args はシーケンス型でなくてはなりません。 function は引数リスト args を使って呼び出されます; 引数の数はタプルの長さになります。オプションの引数 keywords を与える場合、 keywords は文字列のキーを持つ辞書でなければなりません。これは引数リストの最後に追加されるキーワード引数です。 apply() の呼び出しは、単なる function(args) の呼び出しとは異なります。というのは、 apply() の場合、引数は常に一つだからです。 apply() は function(*args, **keywords) を使うのと等価です。

バージョン 2.3 で撤廃: *args と **keywords を使った拡張呼び出し構文を使ってください。

buffer(object[, offset[, size]])

引数 object は (文字列、アレイ、バッファといった) バッファ呼び出しインタフェースをサポートするオブジェクトでなければなりません。引数 object を参照する新たなバッファオブジェクトが生成されます。返されるバッファオブジェクトは object の先頭 (または offset) からのスライスになります。スライスの末端は object の末端まで (または引数 size で与えられた長さになるまで) です。

coerce(x, y)

二つの数値型の引数を共通の型に変換して、変換後の値からなるタプルを返します。変換に使われる規則は算術演算における規則と同じです。型変換が不可能である場合、 TypeError を送出します。

intern(string)

string を “隔離” された文字列のテーブルに入力し、隔離された文字列を返します – この文字列は string 自体かコピーです。隔離された文字列は辞書検索のパフォーマンスを少しだけ向上させるのに有効です – 辞書中のキーが隔離されており、検索するキーが隔離されている場合、 (ハッシュ化後の) キーの比較は文字列の比較ではなくポインタの比較で行うことができるからです。通常、 Python プログラム内で利用されている名前は自動的に隔離され、モジュール、クラス、またはインスタンス属性を保持するための辞書は隔離されたキーを持っています。

バージョン 2.3 で変更: 隔離された文字列の有効期限は (Python 2.2 またはそれ以前は永続的でしたが) 永続的ではなくなりました; intern() の恩恵を受けるためには、 intern() の返す値に対する参照を保持しなければなりません。

注記

[1]
この関数は比較的利用されない関数なので、構文になるかどうかは保証できません。

[2]
現状では、 setvbuf() を持っていないシステムでは、バッファサイズを指定しても効果はありません。バッファサイズを指定するためのインタフェースは setvbuf() を使っては行われていません。何らかの I/O が実行された後で呼び出されるとコアダンプすることがあり、どのような場合にそうなるかを決定する信頼性のある方法がないからです。

[3]
現在の実装では、ローカルな値のバインディングは通常は影響を受けませんが、 (モジュールのような) 他のスコープから取り出した値は影響を受けるかもしれません。またこの実装は変更されるかもしれません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

4. 組み込み定数

組み込み空間には少数の定数があります。以下にそれらの定数を示します。

False

bool 型における、偽を表す値です。

バージョン 2.3 で追加.

True

bool 型における、真を表す値です。

バージョン 2.3 で追加.

None

types.NoneType の唯一の値です。 None は、例えば関数にデフォルト値が渡されないときのように、値がないことを表すためにしばしば用いられます。

バージョン 2.4 で変更: None に対する代入は不正であり、 SyntaxError を送出します。

NotImplemented

“拡張比較 (rich comparison)” を行う特殊メソッド (__eq__(), __lt__(), およびその仲間) によって返される特別な値で、もう片方の型に対しては比較が実装されていないことを示します。

Ellipsis

拡張スライス文と同時に用いられる特殊な値です。

__debug__

この定数は Python が -O オプションを有効にして開始されていないときに真となります。 assert 文も参照して下さい。

ノート

None と __debug__ という名前は再代入できないので (これらに対する代入は、たとえ属性名としてであっても SyntaxError が送出されます)、これらは「真の」定数であると考えることができます。

バージョン 2.7 で変更: 属性名としての __debug__ への代入が禁止されました。

4.1. site モジュールで追加される定数

site モジュール (コマンドラインオプションとして -S が指定されない限り、開始時に自動的にインポートされます) はいくつかの定数を組み込みの名前空間に追加します。それらは対話的インタープリタシェルにとって有用であり、プログラムから使うべきではありません。

quit([code=None])

exit([code=None])

表示されたときに “Use quit() or Ctrl-D (i.e. EOF) to exit” のようなメッセージを出力し、呼び出されたときには指定された終了コードを伴って SystemExit を送出するオブジェクトです。

copyright

license

credits

表示されたときに “Type license() to see the full license text” のようなメッセージを出力し、呼び出されたときにはそれぞれのテキストをページャのような形式で (1画面分づつ) 表示するオブジェクトです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

5. 組み込み型

以下のセクションでは、インタプリタに組み込まれている標準の型について記述します。

ノート

これまでの (リリース 2.2 までの) Python の歴史では、組み込み型はオブジェクト指向における継承を行う際に雛型にできないという点で、ユーザ定義型とは異なっていました。いまではこのような制限はなくなっています。

主要な組み込み型は数値型、シーケンス型、マッピング型、ファイル、クラス、インスタンス型、および例外です。

演算によっては、複数の型でサポートされているものがあります; 特に、ほぼ全てのオブジェクトについて、比較、真理値テスト、 (repr() 関数や、わずかに異なる str() 関数による) 文字列への変換を行うことができます。オブジェクトが print() 関数によって書かれていると、後の方の文字列への変換が暗黙に行われます。

5.1. 真理値テスト

どのオブジェクトも if または while 条件文の中や、以下のブール演算における被演算子として真理値テストを行うことができます。以下の値は偽であると見なされます:

None

False

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

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

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

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

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

ブール値の結果を返す演算および組み込み関数は、特に注釈のない限り常に偽値として 0 または False を返し、真値として 1 または True を返します (重要な例外: ブール演算 or および and は常に被演算子の中の一つを返します)。

5.2. ブール演算 — and, or, not

以下にブール演算子を示します。優先度の低いものから順に並んでいます。:

演算 | 結果 | 注釈
x or y | x が偽なら y, そうでなければ x | (1)
x and y | x が偽なら x, そうでなければ y | (2)
not x | x が偽なら True, そうでなければ False | (3)

注釈:

これは、短絡的な演算子であり、一つめの引数が False のときにのみ、二つめの引数を評価します。

これは、短絡的な演算子であり、一つめの引数が True のときにのみ、二つめの引数を評価します。

not は非ブール演算子よりも低い演算優先度なので、 not a == b は not (a == b) と評価され、 a == not b は構文エラーとなります。

5.3. 比較

比較演算は全てのオブジェクトでサポートされています。比較演算子は全て同じ演算優先度を持っています (ブール演算より高い演算優先度です)。比較は任意の形で連鎖させることができます; 例えば、 x < y <= z は x < y and y <= z と等価で、違うのは y が一度だけしか評価されないということです (どちらの場合でも、 x < y が偽となった場合には z は評価されません)。

以下のテーブルに比較演算をまとめます:

演算 | 意味
< | より小さい
<= | 以下
> | より大きい
>= | 以上
== | 等しい
!= | 等しくない
is | 同一のオブジェクトである
is not | 同一のオブジェクトでない

数値型間の比較か文字列間の比較でないかぎり、異なる型のオブジェクトを比較しても等価になることはありません; これらのオブジェクトの順番付けは一貫してはいますが任意のものです (従って要素の型が一様でないシーケンスをソートした結果は一貫したものになります)。さらに、 (例えばファイルオブジェクトのように) 型によっては、その型の 2 つのオブジェクトの不等性だけの、縮退した比較の概念しかサポートしないものもあります。繰り返しますが、そのようなオブジェクトも任意の順番付けをされていますが、それは一貫したものです。被演算子が複素数の場合、演算子 <, <=, > および >= は例外 TypeError を送出します。

あるクラスのインスタンス間の比較は、そのクラスで __cmp__() メソッドが定義されていない限り等しくなりません。このメソッドを使ってオブジェクトの比較方法に影響を及ぼすための情報については 基本的なカスタマイズ を参照してください。

CPython implementation detail: 数値型を除き、異なる型のオブジェクトは型の名前で順番付けされます; 適当な比較をサポートしていないある型のオブジェクトはアドレスによって順番付けされます。

同じ優先度を持つ演算子としてさらに 2 つ、シーケンス型でのみ in および not in がサポートされています (以下を参照)。

5.4. 数値型 int, float, long, complex

4 つの異なる数値型があります: 通常の整数型, 長整数型, 浮動小数点型, 複素数型 です。さらに、真偽値(Boolean)型も通常の整数型のサブタイプです。通常の整数 (単に整数型 とも呼ばれます) は C言語の long 型を使って実装されており、少なくとも 32 ビットの精度があります (sys.maxint は常に通常の整数の各プラットフォームにおける最大値にセットされており、最小値は -sys.maxint - 1 になります)。長整数型には精度の制限がありません。浮動小数点型はたいていは C の double を使って実装されています; あなたのプログラムが動作するマシンでの浮動小数点型の精度と内部表現は、 sys.float_info から利用できます。複素数型は実部と虚部を持ち、それぞれ浮動小数点数です。複素数 z から実部および虚部を取り出すには、 z.real および z.imag を使ってください。 (標準ライブラリには、追加の数値型、分数を保持する fractions や、ユーザ定義の精度の浮動小数点数を保持する decimal があります。)

数値は、数値リテラルや組み込み関数や演算子の戻り値として生成されます。修飾のない整数リテラル ( 2 進表現や、 16 進表現や 8 進表現の値も含みます) は、通常の整数値を表します。値が通常の整数で表すには大きすぎる場合、 'L' または 'l' が末尾につく整数リテラルは長整数型を表します ('L' が望ましいです。というのは 1l は 11 と非常に紛らわしいからです!) 小数点または指数表記のある数値リテラルは浮動小数点数を表します。数値リテラルに 'j' または 'J' をつけると実数部がゼロの複素数を表します。複素数の数値リテラルは実数部と虚数部を足したものです。

Python は型混合の演算を完全にサポートします: ある 2 項演算子が互いに異なる数値型の被演算子を持つ場合、より “制限された” 型の被演算子は他方の型に合わせて広げられます。ここで通常の整数は長整数より制限されており、長整数は浮動小数点数より制限されており、浮動小数点は複素数より制限されています。型混合の数値間での比較も同じ規則に従います。 [2] コンストラクタ int(), long(), float(), および complex() を使って、特定の型の数を生成することができます。

全ての組み込み数値型は以下の演算をサポートします。演算子の優先度については、 べき乗演算 (power operator),および、あとのセクションを参照下さい。

演算 | 結果 | 注釈
x + y | x と y の和 |
x - y | x と y の差 |
x * y | x と y の積 |
x / y | x と y の商 | (1)
x // y | x と y の商(を切り下げたもの) | (4)(5)
x % y | x / y の剰余 | (4)
-x | x の符号反転 |
+x | x の符号不変 |
abs(x) | x の絶対値または大きさ | (3)
int(x) | x の通常整数への変換 | (2)
long(x) | x の長整数への変換 | (2)
float(x) | x の浮動小数点数への変換 | (6)
complex(re,im) | 実数部 re, 虚数部 im の複素数。 im のデフォルト値はゼロ。 |
c.conjugate() | 複素数 c の共役複素数(実数部に依存する) |
divmod(x, y) | (x // y, x % y) からなるペア | (3)
pow(x, y) | x の y 乗 | (3)(7)
x ** y | x の y 乗 | (7)

注釈:

(通常および長) 整数の割り算では、結果は整数になります。この場合値は常にマイナス無限大の方向に丸められます: つまり、1/2 は 0、 (-1)/2 は -1、1/(-1) は -1、そして (-1)/(-2) は 0 になります。被演算子の両方が長整数の場合、計算値に関わらず結果は長整数で返されるので注意してください。

浮動小数点数から int(),または、 long() を使った変換では、関連する関数、 math.trunc() のようにゼロ方向へ丸められます。下方向への丸めには math.floor() を使い、上方向への丸めには math.ceil() を使って下さい。

完全な記述については、 組み込み関数,を参照してください。

複素数の切り詰め除算演算子、モジュロ演算子、および divmod() 。

バージョン 2.3 で撤廃: 複素数の切り詰め除算演算子、モジュロ演算子、および divmod() 関数は、複素数には定義されなくなりました。複素数型には使えません。適切なら代わりに abs() で浮動小数点型に変換してください。

整数の除算とも呼ばれます。結果の値は整数ですが、整数型(int)とは限りません。

浮動小数点数は、文字列、オプションの接頭辞 “+” または “-” と共に “nan” と “inf” を、非数 (Not a Number (NaN)) や正、負の無限大として受け付けます。

バージョン 2.6 で追加.

Python はプログラム言語一般でそうであるように、 pow(0, 0),および、 0 ** 0 を 1 と定義します。

全ての numbers.Real 型 (int, long,および、 float) は以下の演算を含みます。 :

演算 | 結果 | 備考
math.trunc(x) | x を整数に切り捨てます。 |
round(x[, n]) | x を n 桁に丸めます。丸め方は偶数丸めです。 n が省略されれば 0 がデフォルトとなります。 |
math.floor(x) | x 以下の最大の整数を浮動少数点数で返します。 |
math.ceil(x) | x 以上の最小の整数を浮動小数点数で返します。 |

5.4.1. 整数型におけるビット列演算

通常および長整数型ではさらに、ビット列に対してのみ意味のある演算をサポートしています。負の数はその値の 2 の補数の値として扱われます (長整数の場合、演算操作中にオーバフローが起こらないように十分なビット数があるものと仮定します) 。

2 進のビット単位演算は全て、数値演算よりも低く、比較演算子よりも高い優先度です; 単項演算 ~ は他の単項数値演算 (+ および -) と同じ優先度です。

以下のテーブルでは、ビット列演算を優先度の低いものから順に並べています。 :

演算 | 結果 | 注釈
x | y | ビット単位の x と y の 論理和 |
x ^ y | ビット単位の x と y の排他的論理和 |
x & y | ビット単位の x と y の 論理積 |
x << n | x の n ビット左シフト | (1)(2)
x >> n | x の n ビット右シフト | (1)(3)
~x | x のビット反転 |

注釈:

負値のシフト数は不正であり、 ValueError が送出されます。

n ビットの左シフトは、 pow(2, n) による乗算と等価です。結果が通常の整数の範囲を越えるときには、長整数が返されます。

n ビットの右シフトは、 pow(2, n) による除算と等価です。

5.4.2. 整数型に対する追加のメソッド

整数型は numbers.Integral abstract base class を実装します。さらに、追加のメソッドを一つ提供します。

int.bit_length()

long.bit_length()

整数を、符号と先頭の 0 は除いて二進法で表すために必要なビットの数を返します:

>>> n = -37
>>> bin(n)
'-0b100101'
>>> n.bit_length()
6

正確には、 x が非 0 なら、 x.bit_length() は 2**(k-1) <= abs(x) < 2**k を満たす唯一の正の整数 k です。同様に、 abs(x) が十分小さくて対数を適切に丸められるとき、 k = 1 + int(log(abs(x), 2)) です。 x が 0 なら、 x.bit_length() は 0 を返します。

以下と等価です:

def bit_length(self):
    s = bin(self)       # binary representation:  bin(-37) --> '-0b100101'
    s = s.lstrip('-0b') # remove leading zeros and minus sign
    return len(s)       # len('100101') --> 6

バージョン 2.7 で追加.

5.4.3. 浮動小数点数に対する追加のメソッド

浮動小数点数型は、 numbers.Real 抽象基底クラス (abstract base class) を実装しています。浮動小数点型はまた、以下の追加のメソッドを持ちます。

float.as_integer_ratio()

比が元の浮動小数点数とちょうど同じで分母が正である、一対の整数を返します。無限大に対しては、 OverflowError を、非数 (NaN) に対しては ValueError を送出します。

バージョン 2.6 で追加.

float.is_integer()

浮動小数点数インスタンスが有限の整数値なら True を、そうでなければ False を返します:

>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False

バージョン 2.6 で追加.

16 進表記の文字列へ、または、 16 進表記からの変換をサポートするメソッドは二つあります。 Python の浮動小数点数は内部的には2進数で保持され、若干の丸め誤差を持って 10進数 へ、または、 10進数 から変換されます。それに対し、 16 進表記では浮動小数点数を、正確に表現することができます。これはデバッグのときや、数学的な用途に便利でしょう。

float.hex()

浮動小数点数の 16 進文字列表現を返します。有限の浮動小数点数に対し、この表現は常に 0x で始まり p と指数が続きます。

バージョン 2.6 で追加.

float.fromhex(s)

16 進文字列表現 s で表される、浮動小数点数を返すクラスメソッドです。文字列 s は、前や後にホワイトスペースを含んでいても構いません。

バージョン 2.6 で追加.

float.fromhex() はクラスメソッドですが、 float.hex() はインスタンスメソッドであることに注意して下さい。

16 進文字列表現は以下の書式となります:

[符号] ['0x'] 整数部 ['.' 小数部] ['p' 指数部]

符号 はオプションで、 + と - のどちらでも構いません。整数部 と 小数部 は 16 進数の文字列で、 指数部 はオプションで符号がつけられる 10 進数です。大文字・小文字は区別されず、最低でも 1 つの 16 進数文字を整数部もしくは小数部に含む必要があります。この制限は C99 規格のセクション 6.4.4.2 で規定されます。また、 Java 1.5 以降で使われます。特に、 float.hex() は C や Java コード中で、浮動小数点数の 16 進表記として役に立つでしょう。また、 C の %a 書式や、 Java の Double.toHexString で書きだされた文字列は float.fromhex() で受け取ることができます。

指数部が 16 進数ではなく、 10 進数で書かれ、 2 の累乗となることに注意して下さい。例えば、 16 進文字列表現 0x3.a7p10 は浮動小数点数 (3 + 10./16 + 7./16**2) * 2.0**10 もしくは 3740.0 を表します。:

>>> float.fromhex('0x3.a7p10')
3740.0

逆変換を 3740.0 に適用すると、元とは異なる 16 進文字列表現を返します。:

>>> float.hex(3740.0)
'0x1.d380000000000p+11'

5.5. イテレータ型

バージョン 2.2 で追加.

Python はコンテナの内容にわたって反復処理を行う概念をサポートしています。この概念は 2 つの別々のメソッドを使って実装されています; これらのメソッドはユーザ定義のクラスで反復を行えるようにするために使われます。後に詳しく述べるシーケンス型はすべて反復処理メソッドをサポートしています。

以下はコンテナオブジェクトに反復処理をサポートさせるために定義しなければならないメソッドです:

container.__iter__()

イテレータオブジェクトを返します。イテレータオブジェクトは以下で述べるイテレータプロトコルをサポートする必要があります。あるコンテナが異なる形式の反復処理をサポートする場合、それらの反復処理形式のイテレータを特定的に要求するようなメソッドを追加することができます (複数の形式での反復処理をサポートするようなオブジェクトとして木構造の例があります。木構造は幅優先走査と深さ優先走査の両方をサポートします)。このメソッドは Python/C API において Python オブジェクトを表す型構造体の tp_iter スロットに対応します。

イテレータオブジェクト自体は以下の 2 のメソッドをサポートする必要があります。これらのメソッドは 2 つ合わせて イテレータプロトコル を成します:

iterator.__iter__()

イテレータオブジェクト自体を返します。このメソッドはコンテナとイテレータの両方を for および in 文で使えるようにするために必要です。このメソッドは Python/C API において Python オブジェクトを表す型構造体の tp_iter スロットに対応します。

iterator.next()

コンテナ内の次の要素を返します。もう要素が残っていない場合、例外 StopIteration を送出します。このメソッドは Python/C API において Python オブジェクトを表す型構造体の tp_iternext スロットに対応します。

Python では、いくつかのイテレータオブジェクトを定義しています。これらは一般的および特殊化されたシーケンス型、辞書型、そして他のさらに特殊化された形式をサポートします。特殊型であることはイテレータプロトコルの実装が特殊になること以外は重要なことではありません。

このプロトコルの趣旨は、一度イテレータの next() メソッドが StopIteration 例外を送出した場合、以降の呼び出しでもずっと例外を送出しつづけるところにあります。この特性に従わないような実装は変則であるとみなされます (この制限は Python 2.3 で追加されました; Python 2.2 では、この規則に従うと多くのイテレータが変則となります)。

5.5.1. ジェネレータ型

Python における generator (ジェネレータ) は、イテレータプロトコルを実装する簡便な方法を提供します。コンテナオブジェクトの __iter__() メソッドがジェネレータとして実装されていれば、メソッドは __iter__() および next() メソッドを提供するイテレータオブジェクト (技術的にはジェネレータオブジェクト) を自動的に返します。 yield 式についてのドキュメント により多くの情報があります。

5.6. シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange

シーケンス型には 7 つあります: 文字列、Unicode 文字列、リスト、タプル、、バイト配列 (bytearray)、バッファ、そして xrange オブジェクトです。

他のコンテナ型については、組み込みクラスの dict および set を参照下さい。

文字列リテラルは 'xyzzy' , "frobozz" といったように、単引用符または二重引用符の中に書かれます。文字列リテラルについての詳細は、 文字列リテラル を参照下さい。 Unicode 文字列はほとんど文字列と同じですが、 u'abc' , u"def" といったように先頭に文字 'u' を付けて指定します。リストは [a, b, c] のように要素をコンマで区切り角括弧で囲って生成します。タプルは a, b, c のようにコンマ演算子で区切って生成します (角括弧の中には入れません)。丸括弧で囲っても囲わなくてもかまいませんが、空のタプルは () のように丸括弧で囲わなければなりません。要素が一つのタプルでは、例えば (d,) のように、要素の後ろにコンマをつけなければなりません。

バイト配列は、組み込み関数 bytearray() で構成されます。

バッファオブジェクトは Python の構文上では直接サポートされていませんが、組み込み関数 buffer() で生成することができます。バッファオブジェクトは結合や反復をサポートしていません。

xrange オブジェクトは、オブジェクトを生成するための特殊な構文がない点でバッファに似ていて、関数 xrange() で生成します。 xrange オブジェクトはスライス、結合、反復をサポートせず、 in , not in , min() または max() は効率的ではありません。

ほとんどのシーケンス型は以下の演算操作をサポートします。 in および not in は比較演算とおなじ優先度を持っています。 + および * は対応する数値演算とおなじ優先度です。 [3] 変更可能なシーケンス型 で追加のメソッドが提供されています。

以下のテーブルはシーケンス型の演算を優先度の低いものから順に挙げたものです (同じボックス内の演算は同じ優先度です)。テーブル内の s および t は同じ型のシーケンスです; n , i および j は整数です:

演算 | 結果 | 注釈
x in s | s のある要素 x と等しい場合 True , そうでない場合 False | (1)
x not in s | s のある要素が x と等しい場合 False, そうでない場合 True | (1)
s + t | s および t の結合 | (6)
s * n, n * s | s の浅いコピー n 個からなる結合 | (2)
s[i] | s の 0 から数えて i 番目の要素 | (3)
s[i:j] | s の i 番目から j 番目までのスライス | (3)(4)
s[i:j:k] | s の i 番目から j 番目まで、 k 毎のスライス | (3)(5)
len(s) | s の長さ |
min(s) | s の最小の要素 |
max(s) | s の最大の要素 |
s.index(i) | s 中で最初に i が現れる場所のインデクス |
s.count(i) | s 中に i が現れる数 |

シーケンス型は比較演算子もサポートします。特にタプルとリストは相当する要素による辞書編集方式的に比較されます。つまり、等しいということは、ふたつのシーケンスの長さ、型が同じであり、全ての要素が等しいということです (詳細は言語リファレンスの 比較 (comparison) を参照下さい) 。

注釈:

s が文字列または Unicode 文字列の場合、演算操作 in および not in は部分文字列の一致テストと同じように動作します。バージョン 2.3 以前の Python では、 x は長さ 1 の文字列でした。 Python 2.3 以降では、 x はどの長さでもかまいません。

n が 0 以下の値の場合、 0 として扱われます (これは s と同じ型の空のシーケンスを表します)。コピーは浅いコピーなので注意してください; 入れ子になったデータ構造はコピーされません。これは Python に慣れていないプログラマをよく悩ませます。例えば以下のコードを考えます:

>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]

上のコードでは、 lists はリスト [[]] (空のリストを唯一の要素として含んでいるリスト) の3つのコピーを要素とするリストです。しかし、リスト内の要素に含まれているリストは各コピー間で共有されています。以下のようにすると、異なるリストを要素とするリストを生成できます: 上のコードで、 [[]] は空のリストを要素として含んでいるリストですから、 [[]] * 3 の3つの要素の全てが、空のリスト（への参照）になります。 lists のいずれかの要素を修正することでこの単一のリストが変更されます。以下のようにすると、異なる個別のリストを生成できます:

>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]

i または j が負の数の場合、インデクスは文字列の末端からの相対インデクスになります: len(s) + i または len(s) + j が代入されます。しかし -0 は 0 のままなので注意してください。

s の i から j へのスライスは i <= k < j となるようなインデクス k を持つ要素からなるシーケンスとして定義されます。 i または j が len(s) よりも大きい場合、 len(s) を使います。 i が省略されるか None だった場合、 0 を使います。 j が省略されるか None だった場合、 len(s) を使います。 i が j 以上の場合、スライスは空のシーケンスになります。

s の i 番目から j 番目まで k 毎のスライスは、 0 <= n < (j-i)/k となるような、インデクス x = i + n*k を持つ要素からなるシーケンスとして定義されます。言い換えるとインデクスは i, i+k, i+2*k, i+3*k などであり、 j に達したところ (しかし j は含みません)でストップします。 i または j が len(s) より大きい場合、 len(s) を使います。 i または j を省略するか None だった場合、”最後” (k の符号に依存) を示す値を使います。 k はゼロにできないので注意してください。 k が None だった場合、 1 として扱われます。

CPython implementation detail: s と t の両者が文字列であるとき、 CPython のような実装では、 s=s+t や s+=t という書式で代入をするのに in-place optimization が働きます。このような時、最適化は二乗の実行時間の低減をもたらします。この最適化はバージョンや実装に依存します。実行効率が必要なコードでは、バージョンと実装が変わっても、直線的な連結の実行効率を保証する str.join() を使うのがより望ましいでしょう。

バージョン 2.4 で変更: 以前、文字列の連結はin-placeで再帰されませんでした.

5.6.1. 文字列メソッド

Below ar8-bit 文字列と Unicode オブジェクトは、どちらも以下に挙げるメソッドに対応しています。この中には、 bytearray オブジェクトで使えるものもあります。

さらに、 Python の文字列は シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange に記載されるシーケンス型のメソッドもサポートします。書式指定して文字列を出力するためには、テンプレート文字列を使うか、文字列フォーマット操作 に記載される % 演算子を使います。正規表現に基づく文字列操作関数については、 re モジュールを参照下さい。

str.capitalize()

最初の文字のみを大文字にした文字列のコピーを返します。

8ビット文字列では、メソッドはロケール依存になります。

str.center(width[, fillchar])

width の長さをもつ中央寄せされた文字列を返します。パディングには fillchar で指定された値 (デフォルトではスペース) が使われます。

バージョン 2.4 で変更: 引数 fillchar に対応.

str.count(sub[, start[, end]])

[start, end] の範囲に、部分文字列 sub が出現する回数を返します。オプション引数 start および end はスライス表記と同じように解釈されます。

str.decode([encoding[, errors]])

codec に登録された文字コード系 encoding を使って文字列をデコードします。 encoding は標準でデフォルトの文字列エンコーディングになります。標準とは異なるエラー処理を行うために errors を与えることができます。標準のエラー処理は 'strict' で、エンコードに関するエラーは UnicodeError を送出します。他に利用できる値は 'ignore', 'replace' および関数 codecs.register_error() によって登録された名前です。これについてはセクション Codec 基底クラス 節を参照してください。

バージョン 2.2 で追加.

バージョン 2.3 で変更: その他のエラーハンドリングスキーマがサポートされました.

バージョン 2.7 で変更: キーワード引数のサポートが追加されました。

str.encode([encoding[, errors]])

文字列のエンコードされたバージョンを返します。標準のエンコーディングは現在のデフォルト文字列エンコーディングです。標準とは異なるエラー処理を行うために errors を与えることができます。標準のエラー処理は 'strict' で、エンコードに関するエラーは UnicodeError を送出します。他に利用できる値は 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' および関数 codecs.register_error() によって登録された名前です。これについてはセクション Codec 基底クラス を参照してください。利用可能なエンコーディングの一覧は、セクション標準エンコーディング を参照してください。

バージョン 2.0 で追加.

バージョン 2.3 で変更: 'xmlcharrefreplace', 'backslashreplace' およびその他のエラーハンドリングスキーマがサポートされました.

str.endswith(suffix[, start[, end]])

文字列の一部が suffix で終わるときに True を返します。そうでない場合 False を返します。 suffix は見つけたい複数の接尾語のタプルでも構いません。オプション引数 start がある場合、文字列の start から比較を始めます。 end がある場合、文字列の end で比較を終えます。

バージョン 2.5 で変更: suffix でタプルを受け付けるようになりました.

str.expandtabs([tabsize])

カラム数と与えられるタブサイズに依存し、全てのタブ文字をひとつ以上の空白で置換して文字列のコピーを返します。カラム数は文字列中に改行文字が現れる度に 0 にリセットされます。他の非表示文字や制御文字は解釈しません。

str.find(sub[, start[, end]])

文字列のスライス s[start, end] に sub が含まれる場合、その最小のインデクスを返します。オプション引数 start および end はスライス表記と同様に解釈されます。 sub が見つからなかった場合 -1 を返します。

ノート

find() メソッドは、 sub の位置を知りたいときにのみ使うべきです。 sub が部分文字列であるかどうかのみを調べるには、 in 演算子を使ってください:

>>> 'Py' in 'Python'
True

str.format(*args, **kwargs)

文字列の書式操作を行います。このメソッドを呼び出す文字列は通常の文字、または、 {} で区切られた置換フィールドを含みます。それぞれの置換フィールドは位置引数のインデックスナンバー、または、キーワード引数の名前を含みます。返り値は、引数に応じて置換されたあとの文字列のコピーです。

>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'

書式指定のオプションについては、書式指定文字列を規定する書式指定文字列の文法 を参照下さい。

この文字列書式指定のメソッドは Python 3.0 での新しい標準であり、新しいコードでは、 文字列フォーマット操作 で規定される % を使った書式指定より好ましい書き方です。

バージョン 2.6 で追加.

str.index(sub[, start[, end]])

find() と同様ですが、 sub が見つからなかった場合 ValueError を送出します。

str.isalnum()

文字列中の全ての文字が英数文字で、かつ 1 文字以上ある場合には真を返し、そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.isalpha()

文字列中の全ての文字が英文字で、かつ 1 文字以上ある場合には真を返し、そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.isdigit()

文字列中に数字しかない場合には真を返し、その他の場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.islower()

文字列中の大小文字の区別のある文字全てが小文字で、かつ 1 文字以上ある場合には真を返し、そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.isspace()

文字列が空白文字だけからなり、かつ 1 文字以上ある場合には真を返し、そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.istitle()

文字列がタイトルケース文字列であり、かつ 1 文字以上ある場合、例えば大文字は大小文字の区別のない文字の後にのみ続き、小文字は大小文字の区別のある文字の後ろにのみ続く場合には真を返します。そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.isupper()

文字列中の大小文字の区別のある文字全てが大文字で、かつ 1 文字以上ある場合には真を返し、そうでない場合は偽を返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.join(iterable)

iterable iterable 中の文字列を結合した文字列を返します。文字列を結合するときの区切り文字は、このメソッドを適用する対象の文字列になります。

str.ljust(width[, fillchar])

width の長さをもつ左寄せした文字列を返します。パディングには fillchar で指定された文字(デフォルトではスペース)が使われます。 width が len(s) よりも小さい場合、元の文字列が返されます。

バージョン 2.4 で変更: 引数 fillchar が追加されました.

str.lower()

文字列をコピーし、小文字に変換して返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.lstrip([chars])

文字列の先頭部分を除去したコピーを返します。引数 chars は除去される文字集合を指定する文字列です。 chars が省略されるか None の場合、空白文字が除去されます。 chars 文字列は接頭語ではなく、そこに含まれる文字の組み合わせ全てがはぎ取られます。:

>>> '   spacious   '.lstrip()
'spacious   '
>>> 'www.example.com'.lstrip('cmowz.')
'example.com'

バージョン 2.2.2 で変更: 引数 chars をサポートしました.

str.partition(sep)

文字列を sep の最初の出現位置で区切り、 3 要素のタプルを返します。タプルの内容は、区切りの前の部分、区切り文字列そのもの、そして区切りの後ろの部分です。もし区切れなければ、タプルには元の文字列そのものとその後ろに二つの空文字列が入ります。

バージョン 2.5 で追加.

str.replace(old, new[, count])

文字列をコピーし、部分文字列 old のある部分全てを new に置換して返します。オプション引数 count が与えられている場合、先頭から count 個の old だけを置換します。

str.rfind(sub[, start[, end]])

文字列中の領域 s[start, end] に sub が含まれる場合、その最大のインデクスを返します。オプション引数 start および end はスライス表記と同様に解釈されます。 sub が見つからなかった場合 -1 を返します。

str.rindex(sub[, start[, end]])

rfind() と同様ですが、 sub が見つからなかった場合 ValueError を送出します。

str.rjust(width[, fillchar])

width の長さをもつ右寄せした文字列を返します。パディングには fillchar で指定された文字(デフォルトではスペース)が使われます。 width が len(s) よりも小さい場合、元の文字列が返されます。

バージョン 2.4 で変更: 引数 fillchar が追加されました.

str.rpartition(sep)

文字列を sep の最後の出現位置で区切り、 3 要素のタプルを返します。タプルの内容は、区切りの前の部分、区切り文字列そのもの、そして区切りの後ろの部分です。もし区切れなければ、タプルには二つの空文字列とその後ろに元の文字列そのものが入ります。

バージョン 2.5 で追加.

str.rsplit([sep[, maxsplit]])

sep を区切り文字とした、文字列中の単語のリストを返します。 maxsplit が与えられた場合、最大で maxsplit 個になるように分割が行なわれます、 最も右側 (の単語)は 1 つになります。 sep が指定されていない、あるいは None のとき、全ての空白文字が区切り文字となります。右から分割していくことを除けば、 rsplit() は後ほど詳しく述べる split() と同様に振る舞います。

バージョン 2.4 で追加.

str.rstrip([chars])

文字列の末尾部分を除去したコピーを返します。引数 chars は除去される文字集合を指定する文字列です。 chars が省略されるか None の場合、空白文字が除去されます。 chars 文字列は接尾語ではなく、そこに含まれる文字の組み合わせ全てがはぎ取られます。:

>>> '   spacious   '.rstrip()
'   spacious'
>>> 'mississippi'.rstrip('ipz')
'mississ'

バージョン 2.2.2 で変更: 引数 chars をサポートしました.

str.split([sep[, maxsplit]])

sep を単語の境界として文字列を単語に分割し、分割された単語からなるリストを返します。 maxsplit が与えられた場合、最大で maxsplit 回の分割が行われます (したがって返されるリストは maxsplit+1 の要素を持ちます) 。 maxsplit が指定されない場合、無制限に分割が行なわれます(全ての可能な分割が行なわれる)。

sep が与えられた場合、連続した区切り文字はグループ化されず、空の文字列を区切っていると判断されます(例えば '1,,2'.split(',') は ['1', '', '2'] を返します)。引数 sep は複数の文字にもできます (例えば '1<>2<>3'.split('<>') は ['1', '2', '3'] を返します)。区切り文字を指定して空の文字列を分割すると、 [''] を返します。

sep が指定されていないか None が指定されている場合、異なる分割アルゴリズムが適用されます。: 連続する空白文字はひとつの分割子とみなされます。そして、分割対象の文字列の先頭、または、末尾に空白文字があっても、分割結果の最初、または、最後に空文字列を含みません。空文字列や、空白文字だけからなる文字列を None 分割子で分割すると [] が返されます。

例えば、 ' 1  2   3  '.split() は ['1', '2', '3'] を返し、 '  1  2   3  '.split(None, 1) は ['1', '2   3  '] を返します。

str.splitlines([keepends])

文字列を改行部分で分解し、各行からなるリストを返します。 keepends が与えられていて、かつその値が真でない限り、返されるリストには改行文字は含まれません。

8 ビット文字列では、メソッドはロケール依存になります。

str.startswith(prefix[, start[, end]])

文字列の一部が prefix で始まるときに True を返します。そうでない場合 False を返します。 prefix は複数の接頭語のタプルにしても構いません。オプション引数 start がある場合、文字列の start から比較を始めます。 end がある場合、文字列の end で比較を終えます。

バージョン 2.5 で変更: prefix でタプルを受け付けるようになりました.

str.strip([chars])

文字列の先頭および末尾部分を除去したコピーを返します。引数 chars は除去される文字集合を指定する文字列です。 chars が省略されるか None の場合、空白文字が除去されます。 chars 文字列は接頭語でも接尾語でもなく、そこに含まれる文字の組み合わせ全てがはぎ取られます。:

>>> '   spacious   '.strip()
'spacious'
>>> 'www.example.com'.strip('cmowz.')
'example'

バージョン 2.2.2 で変更: 引数 chars をサポートしました.

str.swapcase()

文字列をコピーし、大文字は小文字に、小文字は大文字に変換して返します。

8 ビット文字列では、メソッドはロケール依存になります。

str.title()

文字列を、単語ごとに大文字から始まり、残りの文字のうち大小文字の区別があるものは全て小文字にする、タイトルケースにして返します。

このアルゴリズムは単語の定義として連続した文字列の集まりという単純な言語によってはうまくいかない定義を使います。この定義は多くの状況ではうまく機能しますが、短縮形や所有格のアポストロフィは単語の境界を形成してしまうため、望みの結果を得られない場合があります。

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

正規表現を使うことでアポストロフィに対応することができます。

>>> import re
>>> def titlecase(s):
        return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
                      lambda mo: mo.group(0)[0].upper() +
                                 mo.group(0)[1:].lower(),
                      s)

>>> titlecase("they're bill's friends.")
"They're Bill's Friends."

8 ビット文字列では、メソッドはロケール依存になります。

str.translate(table[, deletechars])

文字列をコピーし、オプション引数の文字列 deletechars の中に含まれる文字を全て除去します。その後、残った文字を変換テーブル table に従ってマップして返します。変換テーブルは長さ 256 の文字列でなければなりません。

トランスレーションテーブル作成のために、 string モジュールの maketrans() 補助関数を使うこともできます。文字列型オブジェクトに対しては、 table 引数に None を与えることで、文字の削除だけを実施します。:

>>> 'read this short text'.translate(None, 'aeiou')
'rd ths shrt txt'

バージョン 2.6 で追加: None の table 引数をサポートしました。

Unicode オブジェクトの場合、 translate() メソッドはオプションの deletechars 引数を受理しません。その代わり、メソッドはすべての文字が与えられた変換テーブルで対応付けされている s のコピーを返します。この変換テーブルは Unicode 順 (ordinal) から Unicode 順、 Unicode 文字列、または None への対応付けでなくてはなりません。対応付けされていない文字は何もせず放置されます。 None に対応付けられた文字は削除されます。ちなみに、より柔軟性のあるアプローチは、自作の文字対応付けを行う codec を codecs モジュールを使って作成することです (例えば encodings.cp1251 を参照してください。)

str.upper()

文字列をコピーし、大文字に変換して返します。

8ビット文字列では、メソッドはロケール依存になります。

str.zfill(width)

数値文字列の左側をゼロ詰めし、幅 width にして返します。符号接頭辞も正しく扱われます。 width が len(s) よりも短い場合もとの文字列自体が返されます。

バージョン 2.2.2 で追加.

以下のメソッドは、 Unicode オブジェクトにのみ実装されます:

unicode.isnumeric()

数字を表す文字のみで構成される場合、 True を返します。それ以外の場合は False を返します。数字を表す文字には、 0 から 9 までの数字と、 Unicode の数字プロパティを持つ全ての文字が含まれます。 (e.g. U+2155, VULGAR FRACTION ONE FIFTH)

unicode.isdecimal()

10 進数文字のみで構成される場合、 True を返します。それ以外の場合は、 False を返します。 10 進数文字には 0 から 9 までの数字と、 10 進基数表記に使われる全ての文字が含まれます。 (e.g. U+0660, ARABIC-INDIC DIGIT ZERO)

5.6.2. 文字列フォーマット操作

文字列および Unicode オブジェクトには固有の操作: % 演算子 (モジュロ) があります。この演算子は文字列 フォーマット化 または 補間 演算としても知られています。 format % values (format は文字列または Unicode オブジェクト) とすると、 format 中の % 変換指定は values 中のゼロ個またはそれ以上の要素で置換されます。この動作は C 言語における sprintf() に似ています。 format が Unicode オブジェクトであるか、または %s 変換を使って Unicode オブジェクトが変換される場合、その結果も Unicode オブジェクトになります。

format が単一の引数しか要求しない場合、 values はタプルでない単一のオブジェクトでもかまいません。 [4] それ以外の場合、 values はフォーマット文字列中で指定された項目と正確に同じ数の要素からなるタプルか、単一のマップオブジェクトでなければなりません。

一つの変換指定子は 2 またはそれ以上の文字を含み、その構成要素は以下からなりますが、示した順に出現しなければなりません:

変換指定子が開始することを示す文字 '%' 。

マップキー (オプション)。丸括弧で囲った文字列からなります (例えば (someone)) 。

変換フラグ (オプション)。一部の変換型の結果に影響します。

最小のフィールド幅 (オプション)。 '*' (アスタリスク) を指定した場合、実際の文字列幅が values タプルの次の要素から読み出されます。タプルには最小フィールド幅やオプションの精度指定の後に変換したいオブジェクトがくるようにします。

精度 (オプション)。 '.' (ドット) とその後に続く精度で与えられます。 '*' (アスタリスク) を指定した場合、精度の桁数はタプルの次の要素から読み出されます。タプルには精度指定の後に変換したい値がくるようにします。

精度長変換子 (オプション)。

変換型。

% 演算子の右側の引数が辞書の場合 (またはその他のマップ型の場合), 文字列中のフォーマットには、辞書に挿入されているキーを丸括弧で囲い、文字 '%' の直後にくるようにしたものが含まれていなければ なりません。マップキーはフォーマット化したい値をマップから選び出します。例えば:

>>> print '%(language)s has %(number)03d quote types.' % \
...       {"language": "Python", "number": 2}
Python has 002 quote types.

この場合、 * 指定子をフォーマットに含めてはいけません (* 指定子は順番付けされたパラメタのリストが必要だからです。)

変換フラグ文字を以下に示します:

フラグ | 意味
'#' | 値の変換に (下で定義されている) “別の形式” を使います。
'0' | 数値型に対してゼロによるパディングを行います。
'-' | 変換された値を左寄せにします ('0' と同時に与えた場合、 '0' を上書きします) 。
' ' | (スペース) 符号付きの変換で正の数の場合、前に一つスペースを空けます (そうでない場合は空文字になります) 。
'+' | 変換の先頭に符号文字 ('+' または '-') を付けます(“スペース” フラグを上書きします) 。

精度長変換子(h, l,または L) を使うことができますが、 Python では必要ないため無視されます。 – つまり、例えば %ld は %d と等価です。

変換型を以下に示します:

変換 | 意味 | 注釈
'd' | 符号付き 10 進整数。 |
'i' | 符号付き 10 進整数。 |
'o' | 符号なし 8 進数。 | (1)
'u' | 符号なし 10 進数。 |
'x' | 符号なし 16 進数 (小文字)。 | (2)
'X' | 符号なし 16 進数 (大文字)。 | (2)
'e' | 指数表記の浮動小数点数 (小文字)。 | (3)
'E' | 指数表記の浮動小数点数 (大文字)。 | (3)
'f' | 10 進浮動小数点数。 | (3)
'F' | 10 進浮動小数点数。 | (3)
'g' | 浮動小数点数。指数部が -4 以上または精度以下の場合には指数表記、それ以外の場合には10進表記。 | (4)
'G' | 浮動小数点数。指数部が -4 以上または精度以下の場合には指数表記、それ以外の場合には10進表記。 | (4)
'c' | 文字一文字 (整数または一文字からなる文字列を受理します)。 |
'r' | 文字列 (Python オブジェクトを repr() で変換します)。 | (5)
's' | 文字列 (Python オブジェクトを str() で変換します)。 | (6)
'%' | 引数を変換せず、返される文字列中では文字 '%' になります。 |

注釈:

この形式の出力にした場合、変換結果の先頭の数字がゼロ ('0') でないときには、数字の先頭と左側のパディングとの間にゼロを挿入します。

この形式にした場合、変換結果の先頭の数字がゼロでないときには、数字の先頭と左側のパディングとの間に '0x' または '0X' (フォーマット文字が 'x' か 'X' かに依存します) が挿入されます。

この形式にした場合、変換結果には常に小数点が含まれ、それはその後ろに数字が続かない場合にも適用されます。

指定精度は小数点の後の桁数を決定し、そのデフォルトは 6 です。

この形式にした場合、変換結果には常に小数点が含まれ他の形式とは違って末尾の 0 は取り除かれません。

指定精度は小数点の前後の有効桁数を決定し、そのデフォルトは 6 です。

%r 変換は Python 2.0 で追加されました。

指定精度は最大文字数を決定します。

オブジェクトや与えられた書式が unicode 文字列の場合、変換後の文字列も unicode になります。

指定精度は最大文字数を決定します。

PEP 237 [http://www.python.org/dev/peps/pep-0237] を参照してください。

Python 文字列には明示的な長さ情報があるので、 %s 変換において '\0' を文字列の末端と仮定したりはしません。

バージョン 2.7 で変更: 絶対値が 1e50 を超える数の %f 変換は、 %g による変換に置き換えられなくなりました。

その他の文字列操作は標準モジュール string および re で定義されています。

5.6.3. XRange 型

xrange 型は値の変更不能なシーケンスで、広範なループ処理に使われています。 xrange 型の利点は、 xrange オブジェクトは表現する値域の大きさにかかわらず常に同じ量のメモリしか占めないということです。はっきりしたパフォーマンス上の利点はありません。

XRange オブジェクトは非常に限られた振る舞い、すなわち、インデクス検索、反復、 len() 関数のみをサポートしています。

5.6.4. 変更可能なシーケンス型

リストとバイト配列 (bytearray) オブジェクトは、オブジェクトをインプレースに変更できるようにする追加の操作をサポートします。他のミュータブルなシーケンス型 (を言語に追加するとき) も、それらの操作をサポートするべきです。文字列およびタプルはイミュータブルなシーケンス型です: これらのオブジェクトは一度生成されたら変更できません。ミュータブルなシーケンス型では以下の操作が定義されています (ここで x は任意のオブジェクトとします)。

操作 | 結果 | 注釈
s[i] = x | s の要素 s を x と入れ替えます |
s[i:j] = t | s の i から j 番目までのスライスをイテラブル t の内容に入れ替えます |
del s[i:j] | s[i:j] = [] と同じです |
s[i:j:k] = t | s[i:j:k] の要素を t と入れ替えます | (1)
del s[i:j:k] | リストから s[i:j:k] の要素を削除します |
s.append(x) | s[len(s):len(s)] = [x] と同じです | (2)
s.extend(x) | s[len(s):len(s)] = x と同じです | (3)
s.count(x) | s[i] == x となる i の個数を返します |
s.index(x[, i[, j]]) | s[k] == x かつ i <= k < j となる最小の k を返します。 | (4)
s.insert(i, x) | i >= 0 の場合の s[i:i] = [x] と同じです | (5)
s.pop([i]) | x = s[i]; del s[i]; return x と同じです | (6)
s.remove(x) | del s[s.index(x)] と同じです | (4)
s.reverse() | s の値の並びを反転します | (7)
s.sort([cmp[, key[, reverse]]]) | s の要素を並べ替えます | (7), (8), (9), (10)

Notes:

t は入れ替えるスライスと同じ長さでなければいけません。

かつての Python の C 実装では、複数パラメタを受理し、非明示的にそれらをタプルに結合していました。この間違った機能は Python 1.4 で廃用され、 Python 2.0 の導入とともにエラーにするようになりました。

x は任意のイテラブル (繰り返し可能オブジェクト) にできます。

x が s 中に見つからなかった場合 ValueError を送出します。負のインデクスが二番目または三番目のパラメタとして index() メソッドに渡されると、これらの値にはスライスのインデクスと同様にリストの長さが加算されます。加算後もまだ負の場合、その値はスライスのインデクスと同様にゼロに切り詰められます。

バージョン 2.3 で変更: 以前は、 index() は開始位置や終了位置を指定するのに負の数を使うことができませんでした。

insert() の最初のパラメタとして負のインデクスが渡された場合、スライスのインデクスと同じく、リストの長さが加算されます。それでも負の値を取る場合、スライスのインデクスと同じく、 0 に丸められます。

バージョン 2.3 で変更: 以前は、すべての負値は 0 に丸められていました。

pop() メソッドはリストおよびアレイ型のみでサポートされています。オプションの引数 i は標準で -1 なので、標準では最後の要素をリストから除去して返します。

sort() および reverse() メソッドは大きなリストを並べ替えたり反転したりする際、容量の節約のためにリストを直接変更します。副作用があることをユーザに思い出させるために、これらの操作は並べ替えまたは反転されたリストを返しません。

sort() メソッドは、比較を制御するためにオプションの引数をとります。

cmp は2つの引数 (list items) からなるカスタムの比較関数を指定します。これは始めの引数が 2 つ目の引数に比べて小さい、等しい、大きいかに応じて負数、ゼロ、正数を返します。 cmp=lambda x,y: cmp(x.lower(), y.lower()) 。デフォルト値は None です。

key は1つの引数からなる関数を指定します。これは個々のリストの要素から比較のキーを取り出すのに使われます。 key=str.lower 。デフォルト値は None です。

reverse は真偽値です。 True がセットされた場合、リストの要素は個々の比較が反転したものとして並び替えられます。

一般的に、 key および reverse の変換プロセスは同等の cmp 関数を指定するより早く動作します。これは key および reverse がそれぞれの要素に一度だけ触れる間に、 cmp はリストのそれぞれの要素に対して複数回呼ばれることによるものです。旧式の cmp 関数を key 関数に変換するには functools.cmp_to_key() を使用してください。

バージョン 2.3 で変更: None を渡すのと、 cmp を省略した場合とで、同等に扱うサポートを追加.

バージョン 2.4 で変更: key および reverse のサポートを追加.

Python2.3 以降、 sort() メソッドは安定していることが保証されています。ソートは等しいとされた要素の相対オーダーが変更されないことが保証されれば、安定しています — これは複合的なパス（例えば部署ごとにソートして、それを給与の等級）でソートを行なうのに役立ちます。

CPython implementation detail: リストが並べ替えられている間は、リストの変更はもとより、その値の閲覧すらその結果は未定義です。 Python 2.3 以降の C 実装では、この間リストは空に見えるようになり、並べ替え中にリストが変更されたことが検出されると ValueError が送出されます。

5.7. set（集合）型 — set, frozenset

set オブジェクトは順序付けされていない hashable (ハッシュ可能な) オブジェクトのコレクションです。よくある使い方には、メンバーシップのテスト、数列から重複を削除する、そして論理積、論理和、差集合、対称差など数学的演算の計算が含まれます。 (他のコンテナ型については、組み込みクラスの dict, list, tuple,および、モジュール collections を参照下さい)

バージョン 2.4 で追加.

他のコレクションと同様、 sets は x in set, len(set) および for x in set をサポートします。順序を持たないコレクションとして、 sets は要素の位置と (要素の) 挿入位置を保持しません。したがって、 sets はインデックス、スライス、その他のシーケンス的な振る舞いをサポートしません。

set および frozenset という、2つの組み込みset型があります。 set は変更可能な — add() や remove() のようなメソッドを使って内容を変更できます。変更可能なため、ハッシュ値を持たず、また辞書のキーや他のsetの要素として用いることができません。 frozenset 型はイミュータブルで、ハッシュ化可能 (hashable) です — 作成後に内容を改変できません。そのため、辞書のキーや他の集合の要素として使えます。

Python 2.7 では、空でない set (frozenset ではない) は、 set コンストラクタに加え、要素を波カッコ中にカンマで区切って列挙することでも生成できます。例: {'jack', 'sjoerd'}.

両方のクラスのコンストラクタの働きは同じです:

class set([iterable])

class frozenset([iterable])

iterable から要素と取り込んだ、新しい set もしくは frozenset オブジェクトを返します。 set の要素はハッシュ可能なものでなくてはなりません。 set の set, つまり内部 set は frozenset オブジェクトでなくてはなりません。もし、 iterable が指定されないならば、新しい空の set が返されます。

set および frozenset のインスタンスは以下の操作を提供します:

len(s)

set s の要素数を返します。

x in s

x が s のメンバーに含まれるか確認します。

x not in s

x が s のメンバーに含まれていないことを確認します。

isdisjoint(other)

set が other と共通の要素を持たないとき、 True を返します。 set はそれらの積集合が空集合となるときのみ、互いに素となります。

バージョン 2.6 で追加.

issubset(other)

set <= other

set の全ての要素が、 other に含まれるか確認します。

set < other

set が other の真部分集合であるかを確認します。つまり、 set <= other and set != other と等価です。

issuperset(other)

set >= other

other の全ての要素が、 set に含まれるか確認します。

set > other

set が other の真上位集合であるかを確認します。つまり、 set >= other and set != other と等価です。

union(other, ...)

set | other | ...

set と全ての other の要素からなる新しい set を返します。

バージョン 2.6 で変更: 複数のイテラブルからの入力を受け入れるようになりました。

intersection(other, ...)

set & other & ...

set と全ての other に共通する要素を持つ、新しい set を返します。

バージョン 2.6 で変更: 複数のイテラブルからの入力を受け入れるようになりました。

difference(other, ...)

set - other - ...

set に含まれて、かつ、全ての other に含まれない要素を持つ、新しい set を返します。

バージョン 2.6 で変更: 複数のイテラブルからの入力を受け入れるようになりました。

symmetric_difference(other)

set ^ other

set もしくは other のいずれか一方だけに含まれる要素を持つ新しい set を返します。

copy()

s の浅いコピーを新しい set として返します。

演算子でないバージョンの union(), intersection(), difference(), symmetric_difference(), issubset(), issuperset() メソッドはいかなるイテラブルをも引数としてとることに注意して下さい。それとは対照的に、それらの演算子版では set であることを要求します。これは、より読みやすい set('abc').intersection('cbs') のような書き方を支持し、 set('abc') & 'cbs' のような、間違った構文を予防します。

set と frozenset の両方とも、 set と set の比較をサポートします。二つの set は、それぞれの set の要素が互いに等しい場合にのみ等しくなります (互いに、他方の部分集合になっている場合です) 。一つめの set が二つめの set の真部分集合になっているときのみ、一つめ set は二つめの set より小さくなります (つまり、部分集合であり、かつ、等しくない場合です) 。

set のインスタンスは、 frozenset のインスタンスとの比較は、それぞれの要素に基づいて行われます。例えば、 set('abc') == frozenset('abc') や set('abc') in set([frozenset('abc')]) は True を返します。

部分集合と等価性の比較は順序関数には拡張されません。例えば、互いに素 (等しくなく、互いに部分集合でもない) である集合は、以下の全てに、 False を返します : a<b, a==b, および a>b 。そのため、 set は __cmp__() メソッドを実装しません。

set は不完全な順序の定義(部分集合の関係)しか持たないため、 list.sort() メソッドの出力は set のリストに対して定義されません。

set の要素は、辞書のキーのように、 hashable (ハッシュ可能) でなければなりません。

set インスタンスと frozenset インスタンスを取り混ぜてのバイナリ演算は、ひとつめの演算対象の型のインスタンスを返します。例えば : frozenset('ab') | set('bc') は frozenset インスタンスを返します。

以下の内容を更新する操作は set に適用されますが、変更不可である frozenset のインスタンスには適用されません :

update(other, ...)

set |= other | ...

全ての other の要素を追加し、 set を更新します。

バージョン 2.6 で変更: 複数の入力イテラブルを受け付けるようになりました。

intersection_update(other, ...)

set &= other & ...

元の set と 全ての other に共通する要素だけを残して set を更新します。

バージョン 2.6 で変更: 複数の入力イテラブルを受け付けるようになりました。

difference_update(other, ...)

set -= other | ...

other に含まれる要素を取り除き、 set を更新します。

バージョン 2.6 で変更: 複数の入力イテラブルを受け付けるようになりました。

symmetric_difference_update(other)

set ^= other

どちらかにのみ含まれて、共通には持たない要素のみで set を更新します。

add(elem)

要素 elem を set に追加します。

remove(elem)

要素 elem を set から取り除きます。もし elem が set に含まれなければ KeyError を送出します。

discard(elem)

要素 elem が set に含まれていれば、取り除きます。

pop()

任意に要素を set から返し、それを set から取り除きます。 set が空であれば、 KeyError を送出します。

clear()

set の全ての要素を取り除きます。

非演算子版の update(), intersection_update(), difference_update(), および symmetric_difference_update() メソッドはどんなイテラブルでも引数として受け付けることに注意して下さい。

__contains__(), remove(), および discard() メソッドの引数 elem は set であっても構いません。等価な frozenset の検索をサポートするために、 elem set は一時的に検索の間は変化させられ、その後、復元されます。検索の間は意味のある値を持たなくなるため、 elem set を読み出したり、変更してはいけません。

参考

組み込み set 型との比較

sets モジュールと組み込み set 型の違い

5.8. マップ型

マップ型 (mapping) オブジェクトは hashable (ハッシュ可能) な値を任意のオブジェクトに割り付けます。マップ型は変更可能なオブジェクトです。現時点では、ひとつだけの標準マップ型として辞書型 (dictionary) があります (他のコンテナ型については組み込みクラスの list, set, および tuple と、 collections モジュールを参照下さい) 。

辞書型のキーは ほぼ 任意の値です。ハッシュ可能(hashable)でない、つまり、リストや辞書型を含む、変更可能な型 (値ではなく、オブジェクトの同一性で比較されます) はキーとして使用できません。数値型は通常の数値比較のルールに従ってキーとして使われます　: もしふたつの数値を比較し、等しければ (例えば 1 と 1.0 のように) 同じ辞書型に対しインデックスとして同じものとして使用できます (しかしながら、コンピュータ上では近似値を浮動小数点数として保管されることに注意して下さい。これは大抵の場合、辞書型のキーとして使用するのに良い方法ではありません) 。

辞書型は key: value の形式の対の値をカンマ区切りのリストを波括弧でくくることで作成できます。例えば : {'jack': 4098, 'sjoerd': 4127} あるいは {4098: 'jack', 4127: 'sjoerd'} 。あるいは、 dict のコンストラクタでも作成できます。

class dict([arg])

オプションのポジション引数、もしくは、一連のキーワード引数で初期化された新しい辞書型を返します。引数が無い場合は、空の辞書型を返します。もし、ポジション引数 arg がマップ型オブジェクトであれば、もとのマップ型オブジェクトと同じ値に同じキーを割り当てた辞書型を返します。そうでない場合は、ポジション引数はイテレーションをサポートするシーケンスか、イテレータオブジェクトでなければなりません。引数の要素もまた、それと同様でなくてはならず、かつ、それぞれがちょうどふたつのオブジェクトを持っている必要があります。最初のものが新しい辞書型において、キーとして使われます。ふたつめのものがキーの値として使われます。もし、与えられたキーが二度以上現れた場合は、最後に現れた値が新しい辞書型において採用されます。

キーワード引数が与えられた場合、キーワード自身がその値として辞書型に加えられます。もしキーがポジション引数において、キーワード引数を規定した場合、キーワードに値が割り当てられ辞書に追加されます。例えば以下は全て {"one": 1, "two": 2} と等しい辞書型インスタンスを返します :

dict(one=1, two=2)

dict({'one': 1, 'two': 2})

dict(zip(('one', 'two'), (1, 2)))

dict([['two', 2], ['one', 1]])

最初の例では、 Python の識別子として有効なキーに対してのみ機能します ; 他の例はキーとして有効なものであればいかなるキーに対しても機能します。

バージョン 2.3 で変更: キーワード引数からの辞書型の作成のサポートが追加されました。

以下は辞書型がサポートする操作です (それゆえ、カスタムのマップ型もこれらの操作をサポートするべきです):

len(d)

辞書 d に含まれる項目数を返します。

d[key]

d のキー key の項目を返します。もし key が存在しなければ、 KeyError を送出します。

バージョン 2.5 で追加.

d[key] = value

d[key] に value を設定します。

del d[key]

d から d[key] を削除します。もし key が存在しなければ、 KeyError を送出します。

key in d

d がキー key を持っていれば、 True を返します。そうでなければ、 False を返します。

バージョン 2.2 で追加.

key not in d

not key in d と等価です。

バージョン 2.2 で追加.

iter(d)

辞書 d の全てのキーに渡って、イテレータを返します。これは iterkeys() メソッドへのショートカットです。

clear()

辞書の全ての項目を消去します。

copy()

辞書の浅いコピーを返します。

fromkeys(seq[, value])

seq をキーとし、 value を値に設定した、新しい辞書を作成します。

fromkeys() は新しい辞書を返すクラスメソッドです。 value のデフォルト値は None です。

バージョン 2.3 で追加.

get(key[, default])

もし key が辞書にあれば、 key に対する値を返します。そうでなければ、 default を返します。 default が与えられなかった場合、デフォルトでは None となります。そのため、このメソッドは KeyError を送出することはありません。

has_key(key)

辞書に key が存在するかを確認します。 has_key() は key in d と同じことです。

items()

辞書のコピーを (key, value) の対のリストとして返します。

CPython implementation detail: キーと値のリストは任意の順序で返されますが、ランダムではなく、 Python の実装と、辞書への挿入、および、削除操作の来歴によって決まります。

もし、 items(), keys(), values(), iteritems(), iterkeys() および itervalues() が辞書を変更することなく呼び出されたら、リストは一致するでしょう。これにより、 (value, key) の対を zip() または pairs = zip(d.values(), d.keys()) を使って生成するとができます。同じ関係が、 iterkeys() および itervalues() メソッドにもあてはまります : pairs = zip(d.itervalues(), d.iterkeys()) は pairs と同じ値を返します。 pairs = [(v, k) for (k, v) in d.iteritems()] も同様です。

iteritems()

辞書の (key, value) の対をイテレータで返します。 dict.items() の Note も参照下さい。

iteritems() を辞書の項目の追加や削除と同時に行うと、 RuntimeError を送出されるか全ての項目に対する反復に失敗することになります。

バージョン 2.2 で追加.

iterkeys()

辞書のキーをイテレータで返します。 dict.items() の Note も参照下さい。

iterkeys() を辞書の項目の追加や削除と同時に行うと、 RuntimeError を送出されるか全ての項目に対する反復に失敗することになります。

バージョン 2.2 で追加.

itervalues()

辞書の値をイテレータで返します。 dict.items() の Note も参照下さい。

itervalues() を辞書の項目の追加や削除と同時に行うと、 RuntimeError を送出されるか全ての項目に対する反復に失敗することになります。

バージョン 2.2 で追加.

keys()

辞書のキーのリストのコピーを返します。 dict.items() の Note も参照下さい。

pop(key[, default])

もし key が辞書に存在すれば、その値を辞書から除去して返します。そうでなければ、 default を返します。 default が与えらず、かつ、 key が辞書に存在しなければ KeyError を送出します。

バージョン 2.3 で追加.

popitem()

任意の (key, value) の対を辞書から除去して返します。

set のアルゴリズムで使われるのと同じように popitem() は辞書に繰り返し適用して消去するのに便利です。もし辞書が空であれば、 popitem() の呼び出しは KeyError を送出します。

setdefault(key[, default])

もし、 key が辞書に存在すれば、その値を返します。そうでなければ、値を default として key を挿入し、 default を返します。 default のデフォルト値は None です。

update([other])

辞書の内容を other のキーと値で更新します。既存のキーは上書きされます。返り値は None です。

update() は、他の辞書オブジェクトでもキーと値の対のイテラブル (タプル、もしくは、長さが2のイテラブル) でも、どちらでも受け付けます。キーワード引数が指定されれば、そのキーと値で辞書を更新します。 : d.update(red=1, blue=2)

バージョン 2.4 で変更: キーと値の対のイテラブル、および、キーワード引数を引数として与えることができるようになりました。

values()

辞書の値のリストのコピーを返します。 dict.items() の Note も参照下さい。

viewitems()

辞書の要素 ((key, value) の対) の新しいビューを返します。ビューオブジェクトのドキュメントは下を参照してください。

バージョン 2.7 で追加.

viewkeys()

辞書のキーの新しいビューを返します。ビューオブジェクトのドキュメントは下を参照してください。

バージョン 2.7 で追加.

viewvalues()

辞書の値の新しいビューを返します。ビューオブジェクトのドキュメントは下を参照してください。

バージョン 2.7 で追加.

5.8.1. 辞書ビューオブジェクト

dict.keys() 、 dict.values() 、 dict.items() によって返されるオブジェクトは、 ビューオブジェクト です。これらは、辞書の項目の動的なビューを提供し、辞書が変更された時、ビューはその変更を反映します。

辞書ビューを通して反復することで、対応するデータを産出できます。また、帰属検査をサポートしています。

len(dictview)

辞書の項目数を返します。

iter(dictview)

辞書のキー、値、または ((key, value) のタプルとして表される) 要素に渡るイテレータを返します。

キーと値のリストは任意の順序で反復されますが、ランダムではなく、 Python の実装によって変わり、辞書への挿入や削除の履歴に依存します。キー、値、要素のビューを通して、辞書の変更を挟まずにイテレートされたら、その要素の順序は完全に一致します。これにより、 (value, key) の対を zip() で作成できます: pairs = zip(d.values(), d.keys()) 。同じリストを作成する他の方法は、 pairs = [(v, k) for (k, v) in d.items()] です。

辞書の項目の追加や削除中にビューをイテレートすると、 RuntimeError を送出したり、すべての項目に渡ってイテレートできなかったりします。

x in dictview

x が下にある辞書のキー、値、または要素 (要素の場合、 x は (key, value) タプルであるべきです) にあるとき True を返します。

キーのビューは、項目が一意的でハッシュ可能であるという点で、集合に似ています。すべての値がハッシュ可能なら、 (key, value) の対も一意的でハッシュ可能であり、要素のビューも集合に似ています。(値のビューは、要素が一般に一意的でないことから、集合に似ているとは考えられません。) ですから、これらの集合演算が利用できます。 (“other” は別のビューか集合です):

dictview & other

辞書ビューと別のオブジェクトの共通部分を新しい集合として返します。

dictview | other

辞書ビューと別のオブジェクトの合併集合を新しい集合として返します。

dictview - other

辞書ビューと別のオブジェクトの差集合 (dictview に属して other に属さないすべての要素) を新しい集合として返します。

dictview ^ other

辞書ビューと別のオブジェクトの対称差 (dictview と other のどちらかに属すが両方には属さないすべての要素) を新しい集合として返します。

辞書ビューの使用法の例:

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.viewkeys()
>>> values = dishes.viewvalues()

>>> # iteration
>>> n = 0
>>> for val in values:
...     n += val
>>> print(n)
504

>>> # keys and values are iterated over in the same order
>>> list(keys)
['eggs', 'bacon', 'sausage', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['spam', 'bacon']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}

5.9. ファイルオブジェクト

ファイルオブジェクト は C の stdio パッケージを使って実装されており、組み込み関数の open() で生成することができます。ファイルオブジェクトはまた、 os.popen() や os.fdopen(), ソケットオブジェクトの makefile() メソッドのような、他の組み込み関数およびメソッドによっても返されます。一時ファイルは tempfile モジュールを使って生成でき、ファイルやディレクトリのコピー、移動、消去などの高次の操作は shutil モジュールで行います。

ファイル操作が I/O 関連の理由で失敗した場合例外 IOError が送出されます。この理由には例えば seek() を端末デバイスに行ったり、読み出し専用で開いたファイルに書き込みを行うといった、何らかの理由によってそのファイルで定義されていない操作を行ったような場合も含まれます。

ファイルは以下のメソッドを持ちます:

file.close()

ファイルを閉じます。閉じられたファイルはそれ以後読み書きすることはできません。ファイルが開かれていることが必要な操作は、ファイルが閉じられた後はすべて ValueError を送出します。 close() を一度以上呼び出してもかまいません。

Python 2.5 から with 文を使えばこのメソッドを直接呼び出す必要はなくなりました。たとえば、以下のコードは f を with ブロックを抜ける際に自動的に閉じます。

from __future__ import with_statement # これは Python 2.6 では不要です

with open("hello.txt") as f:
    for line in f:
        print line

古いバージョンの Python では同じ効果を得るために次のようにしなければいけませんでした。

f = open("hello.txt")
try:
    for line in f:
        print line
finally:
    f.close()

ノート

全ての Python の “ファイル的” 型が with 文用のコンテキスト・マネージャとして使えるわけではありません。もし、全てのファイル的オブジェクトで動くようにコードを書きたいのならば、オブジェクトを直接使うのではなく contextlib にある contextlib.closing() 関数を使うと良いでしょう。

file.flush()

stdio の fflush() のように、内部バッファをフラッシュします。ファイル類似のオブジェクトによっては、この操作は何も行いません。

ノート

flush() は必ずしもファイルのデータをディスクに書き込むとは限りません。そのような挙動を保証するには flush() の後に os.fsync() を使って下さい。

file.fileno()

背後にある実装系がオペレーティングシステムに I/O 操作を要求するために用いる、整数の “ファイル記述子” を返します。この値は他の用途として、 fcntl モジュールや os.read() やその仲間のような、ファイル記述子を必要とする低レベルのインタフェースで役に立ちます。

ノート

ファイル類似のオブジェクトが実際のファイルに関連付けられていない場合、このメソッドを提供すべきでは ありません 。

file.isatty()

ファイルが tty (または類似の) デバイスに接続されている場合 True を返し、そうでない場合 False を返します。

ノート

ファイル類似のオブジェクトが実際のファイルに関連付けられていない場合、このメソッドを実装すべきでは ありません 。

file.next()

ファイルオブジェクトはそれ自身がイテレータです。すなわち、 iter(f) は (f が閉じられていない限り) f を返します。 for ループ (例えば for line in f: print line) のようにファイルがイテレータとして使われた場合、 next() メソッドが繰り返し呼び出されます。ファイルが読み出しモードで開かれている場合、このメソッドは次の入力行を返すか、または、 EOF に到達したときに StopIteration を送出します (ファイルが書き込みモードで開かれている場合、動作は未定義です) 。ファイル内の各行に対する for ループ (非常によくある操作です) を効率的な方法で行うために、 next() メソッドは隠蔽された先読みバッファを使います。先読みバッファを使った結果として、 (readline() のような) 他のファイルメソッドと next() を組み合わせて使うとうまく動作しません。しかし、 seek() を使ってファイル位置を絶対指定しなおすと、先読みバッファは消去されます。

バージョン 2.3 で追加.

file.read([size])

最大で size バイトをファイルから読み込みます (size バイトを取得する前に EOF に到達した場合、それ以下の長さになります) 。 size 引数が負であるか省略された場合、 EOF に到達するまでの全てのデータを読み込みます。読み出されたバイト列は文字列オブジェクトとして返されます。直後に EOF に到達した場合、空の文字列が返されます。 (端末のようなある種のファイルでは、 EOF に到達した後でファイルを読みつづけることにも意味があります) 。このメソッドは、 size バイトに可能な限り近くデータを取得するために、背後の C 関数 fread() を 1 度以上呼び出すかもしれないので注意してください。また、非ブロック・モードでは、 size パラメータが与えられなくても、要求されたよりも少ないデータが返される場合があることに注意してください。

ノート

この関数は単純に、背後の C 関数、 fread() のラッパーです。そのため、 EOF が見つからない場合など、特殊な状況では同様に振る舞います。

file.readline([size])

ファイルから一行全部を読み込みます。終末の改行文字は文字列に残ります (しかし、ファイルが不完全な行で終わっていたら、存在しないかもしれません)。 [5] size 引数が与えられ、負でなければ、それが (終末の改行文字を含む) 最大バイト数となり、不完全な行でも返されます。 size が 0 でなければ、空の文字列が返されるのは、即座に EOF に到達したとき だけ です。

ノート

stdio の fgets() と違い、入力中にヌル文字 ('\0') が含まれていれば、ヌル文字を含んだ文字列が返されます。

file.readlines([sizehint])

readline() を使ってに到達するまで読み出し、 EOF 読み出された行を含むリストを返します。オプションの sizehint 引数が存在すれば、 EOF まで読み出す代わりに完全な行を全体で大体 sizehint バイトになるように (おそらく内部バッファサイズを切り詰めて) 読み出します。ファイル類似のインタフェースを実装しているオブジェクトは、 sizehint を実装できないか効率的に実装できない場合には無視してもかまいません。

file.xreadlines()

このメソッドは iter(f) と同じ結果を返します。

バージョン 2.1 で追加.

バージョン 2.3 で撤廃: 代わりに for line in file を使ってください。

file.seek(offset[, whence])

stdio の fseek() と同様に、ファイルの現在位置を設定します。 whence 引数はオプションで、標準の値は os.SEEK_SET もしくは 0 (絶対位置指定) です; 他に取り得る値は os.SEEK_CUR もしくは 1 (現在のファイル位置から相対的に seek する) および os.SEEK_END もしくは 2 (ファイルの末端から相対的に seek する) です。戻り値はありません。

例えば、 f.seek(2, os.SEEK_CUR) 位置を2つ進めます。 f.seek(-3, os.SEEK_END) では終端の3つ手前に設定します。

ファイルを追記モード (モード 'a' または 'a+') で開いた場合、書き込みを行うまでに行った seek() 操作はすべて元に戻されるので注意してください。ファイルが追記のみの書き込みモード ('a') で開かれた場合、このメソッドは実質何も行いませんが、読み込みが可能な追記モード ('a+') で開かれたファイルでは役に立ちます。ファイルをテキストモードで ('b' なしで) 開いた場合、 tell() が返すオフセットのみが正しい値になります。他のオフセット値を使った場合、その振る舞いは未定義です。

全てのファイルオブジェクトが seek できるとは限らないので注意してください。

file.tell()

stdio の ftell() と同様、ファイルの現在位置を返します。

ノート

Windows では、(fgets() の後で) Unix-スタイルの改行のファイルを読むときに tell() が不正な値を返すことがあります。この問題に遭遇しないためにはバイナリーモード ('rb') を使うようにしてください。

file.truncate([size])

ファイルのサイズを切り詰めます。オプションの size が存在すれば、ファイルは (最大で) 指定されたサイズに切り詰められます。標準設定のサイズの値は、現在のファイル位置までのファイルサイズです。現在のファイル位置は変更されません。指定されたサイズがファイルの現在のサイズを越える場合、その結果はプラットフォーム依存なので注意してください: 可能性としては、ファイルは変更されないか、指定されたサイズまでゼロで埋められるか、指定されたサイズまで未定義の新たな内容で埋められるか、があります。利用可能な環境: Windows, 多くの Unix 系。

file.write(str)

文字列をファイルに書き込みます。戻り値はありません。バッファリングによって、 flush() または close() が呼び出されるまで実際にファイル中に文字列が書き込まれないこともあります。

file.writelines(sequence)

文字列からなるシーケンスをファイルに書き込みます。シーケンスは文字列を生成する反復可能なオブジェクトなら何でもかまいません。よくあるのは文字列からなるリストです。戻り値はありません。 (関数の名前は readlines() と対応づけてつけられました; writelines() は行間の区切りを追加しません)

ファイルはイテレータプロトコルをサポートします。各反復操作では file.readline() と同じ結果を返し、反復は readline() メソッドが空文字列を返した際に終了します。

ファイルオブジェクトはまた、多くの興味深い属性を提供します。これらはファイル類似オブジェクトでは必要ではありませんが、特定のオブジェクトにとって意味を持たせたいなら実装しなければなりません。

file.closed

現在のファイルオブジェクトの状態を示すブール値です。この値は読み出し専用の属性です; close() メソッドがこの値を変更します。全てのファイル類似オブジェクトで利用可能とは限りません。

file.encoding

このファイルが使っているエンコーディングです。 Unicode 文字列がファイルに書き込まれる際、 Unicode 文字列はこのエンコーディングを使ってバイト文字列に変換されます。さらに、ファイルが端末に接続されている場合、この属性は端末が使っているとおぼしきエンコーディング (この情報は端末がうまく設定されていない場合には不正確なこともあります) を与えます。この属性は読み出し専用で、すべてのファイル類似オブジェクトにあるとは限りません。またこの値は None のこともあり、この場合、ファイルは Unicode 文字列の変換のためにシステムのデフォルトエンコーディングを使います。

バージョン 2.3 で追加.

file.errors

エンコーディングに用いられる、 Unicode エラーハンドラです。

バージョン 2.6 で追加.

file.mode

ファイルの I/O モードです。ファイルが組み込み関数 open() で作成された場合、この値は引数 mode の値になります。この値は読み出し専用の属性で、全てのファイル類似オブジェクトに存在するとは限りません。

file.name

ファイルオブジェクトが open() を使って生成された時のファイルの名前です。そうでなければ、ファイルオブジェクト生成の起源を示す何らかの文字列になり、 <...> の形式をとります。この値は読み出し専用の属性で、全てのファイル類似オブジェクトに存在するとは限りません。

file.newlines

Python がユニバーサル改行モードを (デフォルトどおり) 有効にしてビルドされているなら、この読み込み専用属性が存在し、ファイルがユニバーサル改行モードで開かれたファイルで、ファイルの読み込み中にあった改行の種類を記録します。取り得る値は '\r', '\n', '\r\n', None (不明であるか、まだ改行を読み込んでいない)、または、複数の改行方式の種類が存在したことを表す、見つかったすべての改行の種類を含むタプルです。ユニバーサル改行モードで開かれたのでないファイルに対しては、この属性の値は None になります。

file.softspace

print 文を使った場合、他の値を出力する前にスペース文字を出力する必要があるかどうかを示すブール値です。ファイルオブジェクトをシミュレート仕様とするクラスは書き込み可能な softspace 属性を持たなければならず、この値はゼロに初期化されなければなりません。この値は Python で実装されているほとんどのクラスで自動的に初期化されます (属性へのアクセス手段を上書きするようなオブジェクトでは注意が必要です); C で実装された型では、書き込み可能な softspace 属性を提供しなければなりません。

ノート

この属性は print 文を制御するために用いられますが、 print の内部状態を乱さないために、その実装を行うことはできません。

5.10. メモリビュー型

memoryview オブジェクトは、Python コードがバッファプロトコルをコピーすることなく対応しているオブジェクトの内部データにアクセス出来るようにします。メモリは通常、単純なバイト列として解釈されます。

class memoryview(obj)

obj を参照する memoryview を作成します。 obj はバッファプロトコルをサポートしていなければなりません。バッファプロトコルをサポートする組み込みオブジェクトには、 str 、 bytearray などがあります (ただし、 unicode は違います)。

memoryview には 要素 の概念があり、それが起源のオブジェクト obj によって扱われる原子的なメモリの単位になります。多くの単純なオブジェクト、例えば str や bytearray では、要素は単バイトになりますが、他のサードパーティの型では、要素はより大きくなりえます。

len(view) は、メモリビュー view の要素の総数を返します。 itemsize 属性は、一つの要素内のバイト数を与えます。

memoryview はスライスしてデータを晒すことに対応しています。一つのインデクスを取ると、一つの要素を str オブジェクトとして返します。完全なスライシングは部分ビューになります:

>>> v = memoryview('abcefg')
>>> v[1]
'b'
>>> v[-1]
'g'
>>> v[1:4]
<memory at 0x77ab28>
>>> v[1:4].tobytes()
'bce'

メモリビューが基にしているオブジェクトがデータの変更に対応していれば、メモリビューはスライス代入に対応します:

>>> data = bytearray('abcefg')
>>> v = memoryview(data)
>>> v.readonly
False
>>> v[0] = 'z'
>>> data
bytearray(b'zbcefg')
>>> v[1:4] = '123'
>>> data
bytearray(b'z123fg')
>>> v[2] = 'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot modify size of memoryview object

この通り、メモリビューオブジェクトの長さは変えられません。

memoryview には 2 つのメソッドがあります。

tobytes()

バッファ中のデータをバイト文字列 (クラス str のオブジェクト) として返します:

>>> m = memoryview("abc")
>>> m.tobytes()
'abc'

tolist()

バッファ中のデータを整数のリストとして返します:

>>> memoryview("abc").tolist()
[97, 98, 99]

読み込み専用の属性もいくつか使えます:

format

ビューのそれぞれの要素に対する、(struct モジュールのスタイルでの) フォーマットを含む文字列です。デフォルトは 'B' で、単純なバイト文字列です。

itemsize

メモリビューのそれぞれの要素のバイト数です。

shape

メモリの形状を N 次元配列として与える、長さ ndim の整数のタプルです。

ndim

メモリが表す多次元配列が何次元かを示す整数です。

strides

配列のそれぞれの次元に対して、それぞれの要素にアクセスするのに必要なバイト数を表す、長さ ndim の整数のタプルです。

readonly

メモリが読み込み専用かを表すブールです。

5.11. コンテキストマネージャ型

バージョン 2.5 で追加.

Python の with 文はコンテキストマネージャによって定義される実行時コンテキストの概念をサポートします。これは、ユーザ定義クラスが文の本体が実行される前に進入し文の終わりで脱出する実行時コンテキストを定義することを許す二つの別々のメソッドを使って実装されます。

コンテキスト管理プロトコル (context management protocol) は実行時コンテキストを定義するコンテキストマネージャオブジェクトが提供すべき一対のメソッドから成ります。

contextmanager.__enter__()

実行時コンテキストに入り、このオブジェクトまたは他の実行時コンテキストに関連したオブジェクトを返します。このメソッドが返す値はこのコンテキストマネージャを使う with 文の as 節の識別子に束縛されます。

自分自身を返すコンテキストマネージャの例としてファイルオブジェクトがあります。ファイルオブジェクトは __enter__() から自分自身を返して open() が with 文のコンテキスト式として使われるようにします。

関連オブジェクトを返すコンテキストマネージャの例としては decimal.localcontext() が返すものがあります。このマネージャはアクティブな10進数コンテキストをオリジナルのコンテキストのコピーにセットしてそのコピーを返します。こうすることで, with 文の本体の内部で、外側のコードに影響を与えずに、 10進数コンテキストを変更できます。

contextmanager.__exit__(exc_type, exc_val, exc_tb)

実行時コンテキストから抜け、例外 (がもし起こっていたとしても) を抑制することを示すブール値フラグを返します。 with 文の本体を実行中に例外が起こったならば、引数にはその例外の型と値とトレースバック情報を渡します。そうでなければ、引数は全て None です。

このメソッドから真となる値が返されると with 文は例外の発生を抑え、 with 文の直後の文に実行を続けます。そうでなければ、このメソッドの実行を終えると例外の伝播が続きます。このメソッドの実行中に起きた例外は with 文の本体の実行中に起こった例外を置き換えてしまいます。

渡された例外を直接的に再送出すべきではありません。その代わりに、このメソッドが偽の値を返すことでメソッドの正常終了と送出された例外を抑制しないことを伝えるべきです。このようにすれば (contextlib.nested のような) コンテキストマネージャは __exit__() メソッド自体が失敗したのかどうかを簡単に見分けることができます。

Python は幾つかのコンテキストマネージャを、易しいスレッド同期・ファイルなどのオブジェクトの即時クローズ・単純化されたアクティブな10進算術コンテキストのサポートのために用意しています。各型はコンテキスト管理プロトコルを実装しているという以上の特別の取り扱いを受けるわけではありません。例については contextlib モジュールを参照下さい。

Python のジェネレータ (generator) と contextlib.contextmanager デコレータ (decorator) はこのプロトコルの簡便な実装方法を提供します。ジェネレータ関数を contextlib.contextmanager でデコレートすると、デコレートしなければ返されるイテレータを返す代わりに、必要な __enter__() および __exit__() メソッドを実装したコンテキストマネージャを返すようになります。

これらのメソッドのために Python/C API の中の Python オブジェクトの型構造体に特別なスロットが作られたわけではないことに注意してください。これらのメソッドを定義したい拡張型については通常の Python からアクセスできるメソッドとして提供しなければなりません。実行時コンテキストを準備することに比べたら、一つのクラスの辞書引きは無視できるオーバーヘッドです。

5.12. 他の組み込み型

インタプリタはその他の種類のオブジェクトをいくつかサポートします。これらのほとんどは 1 または 2 つの演算だけをサポートします。

5.12.1. モジュール

モジュールに対する唯一の特殊な演算は属性へのアクセス: m.name です。ここで m はモジュールで、 name は m のシンボルテーブル上に定義された名前にアクセスします。モジュール属性も代入することができます。 (import 文は、厳密にいえば、モジュールオブジェクトに対する演算です; import foo は foo と名づけられたモジュールオブジェクトが存在することを必要とはせず、むしろ foo と名づけられた (外部の) モジュールの 定義 を必要とします。)

各モジュールの特殊なメンバは __dict__ です。これはモジュールのシンボルテーブルを含む辞書です。この辞書を修正すると、実際にはモジュールのシンボルテーブルを変更しますが、 __dict__ 属性を直接代入することはできません (m.__dict__['a'] = 1 と書いて m.a を 1 に定義することはできますが、 m.__dict__ = {} と書くことはできません) 。 __dict__ を直接編集するのは推奨されません。

インタプリタ内に組み込まれたモジュールは、 <module 'sys' (built-in)> のように書かれます。ファイルから読み出された場合、 <module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'> と書かれます。

5.12.2. クラスおよびクラスインスタンス

これらについては オブジェクト、値、および型 および クラス定義 を参照下さい。

5.12.3. 関数

関数オブジェクトは関数定義によって生成されます。関数オブジェクトに対する唯一の操作は、それを呼び出すことです: func(argument-list)

関数オブジェクトには実際には 2 つの種: 組み込み関数とユーザ定義関数があります。両方とも同じ操作 (関数の呼び出し) をサポートしますが、実装は異なるので、オブジェクトの型も異なります。

詳細は、 関数定義 を参照下さい。

5.12.4. メソッド

メソッドは属性表記を使って呼び出される関数です。メソッドには二つの種類があります: (リストへの append() のような) 組み込みメソッドと、クラスインスタンスのメソッドです。組み込みメソッドはそれをサポートする型と一緒に記述されています。

実装では、クラスインスタンスのメソッドに 2 つの読み込み専用の属性を追加しています: m.im_self はメソッドが操作するオブジェクトで、 m.im_func はメソッドを実装している関数です。 m(arg-1, arg-2, ..., arg-n) の呼び出しは、 m.im_func(m.im_self, arg-1, arg-2, ..., arg-n) の呼び出しと完全に等価です。

クラスインスタンスメソッドには、メソッドがインスタンスからアクセスされるかクラスからアクセスされるかによって、それぞれ バインド または 非バインド があります。メソッドが非バインドメソッドの場合、 im_self 属性は None になるため、呼び出す際には self オブジェクトを明示的に第一引数として指定しなければなりません。この場合、 self は非バインドメソッドのクラス (サブクラス) のインスタンスでなければならず、そうでなければ TypeError が送出されます。

関数オブジェクトと同じく、メソッドオブジェクトは任意の属性を取得できます。しかし、メソッド属性は実際には背後の関数オブジェクト (meth.im_func) に記憶されているので、バインド、非バインド、メソッドへのメソッド属性の設定は許されていません。メソッド属性の設定を試みると TypeError が送出されます。メソッド属性を設定するためには、その背後の関数オブジェクトで明示的に:

class C:
    def method(self):
        pass

c = C()
c.method.im_func.whoami = 'my name is c'

詳細は、 標準型の階層 を参照下さい。

5.12.5. コードオブジェクト

コードオブジェクトは、関数本体のような “擬似コンパイルされた” Python の実行可能コードを表すために実装系によって使われます。コードオブジェクトはグローバルな実行環境への参照を持たない点で関数オブジェクトとは異なります。コードオブジェクトは組み込み関数 compile() によって返され、関数オブジェクトの func_code 属性として取り出すことができます。 code も参照下さい。

コードオブジェクトは exec 文や組み込み関数 eval() に (ソースコード文字列の代わりに) 渡すことで、実行したり値評価したりすることができます。

詳細は、 標準型の階層 を参照下さい。

5.12.6. 型オブジェクト

型オブジェクトは様々なオブジェクト型を表します。オブジェクトの型は組み込み関数 type() でアクセスされます。型オブジェクトには特有の操作はありません。標準モジュール types には全ての組み込み型名が定義されています。

型は <type 'int'> のように書き表されます。

5.12.7. ヌルオブジェクト

このオブジェクトは明示的に値を返さない関数によって返されます。このオブジェクトには特有の操作はありません。ヌルオブジェクトは一つだけで、 None (組み込み名) と名づけられています。

None と書き表されます。

5.12.8. 省略表記オブジェクト

このオブジェクトは拡張スライス表記によって使われます (スライス表記 (slicing) を参照下さい)。特殊な操作は何もサポートしていません。省略表記オブジェクトは一つだけで、その名前は Ellipsis (組み込み名) です。

Ellipsis と書き表されます。

5.12.9. ブール値

ブール値とは二つの定数オブジェクト False および True です。これらは真偽値を表すために使われます (他の値も偽または真とみなされます) 数値処理のコンテキスト (例えば算術演算子の引数として使われた場合) では、これらはそれぞれ 0 および 1 と同様に振舞います。任意の値に対して真偽値を変換できる場合、組み込み関数 bool() は値をブール値にキャストするのに使われます (真理値テストの節を参照してください) 。

これらはそれぞれ False および True と書き表されます。

5.12.10. 内部オブジェクト

スタックフレームオブジェクト、トレースバックオブジェクト、スライスオブジェクト関しては、 標準型の階層 を参照下さい。

5.13. 特殊な属性

実装では、いくつかのオブジェクト型に対して、数個の読み出し専用の特殊な属性を追加しています。それぞれ:

object.__dict__

オブジェクトの (書き込み可能な) 属性を保存するために使われる辞書または他のマップ型オブジェクトです。

object.__methods__

バージョン 2.2 で撤廃: オブジェクトの属性からなるリストを取得するには、組み込み関数 dir() を使ってください。この属性はもう利用できません。

object.__members__

バージョン 2.2 で撤廃: オブジェクトの属性からなるリストを取得するには、組み込み関数 dir() を使ってください。この属性はもう利用できません。

instance.__class__

クラスインスタンスが属しているクラスです。

class.__bases__

クラスオブジェクトの基底クラスからなるタプルです。

class.__name__

クラスまたは型の名前です。

以下の属性は、新しいクラス (new-style class) でのみサポートされます。

class.__mro__

この属性はメソッドの解決に探索される基底クラスのタプルです。

class.mro()

このメソッドは、メタクラスによって、そのインスタンスのメソッド解決の順序をカスタマイズするために、上書きされるかも知れません。これは、クラスインスタンスの作成と呼び、その結果は __mro__ に格納されます。

class.__subclasses__()

それぞれの新しいクラスは、それ自身の直接のサブクラスへの弱参照を保持します。このメソッドはそれらの参照のうち、生存しているもののリストを返します。例

>>> int.__subclasses__()
[<type 'bool'>]

注記

[1]
これらの特殊なメソッドのさらなる情報は、 Python リファレンスマニュアル (基本的なカスタマイズ) を参照下さい。

[2]
この結果として、リスト [1, 2] は [1.0, 2.0] と等しいと見なされます。タプルの場合も同様です。

[3]
パーザが被演算子の型を識別できるようにするために、このような優先度でなければならないのです。

[4]
従って、一個のタプルだけをフォーマット出力したい場合には出力したいタプルを唯一の要素とする単一のタプルを values に与えなくてはなりません。

[5]
改行を残す利点は、空の文字列が返ると EOF を示し、紛らわしくなくなるからです。また、ファイルの最後の行が改行で終わっているかそうでない (ありえることです!) か (例えば、ファイルを行単位で読みながらその完全なコピーを作成した場合には問題になります) を調べることができます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

6. 組み込み例外

例外はクラスオブジェクトです。例外はモジュール exceptions で定義されています。このモジュールを明示的にインポートする必要はありません。例外は exceptions モジュールと同様に組み込み名前空間で与えられます。

try 文の中で、 except 節を使って特定の例外クラスについて記述した場合、その節は指定した例外クラスから派生したクラスも扱います (指定した例外クラスの派生元のクラスは含みません)。サブクラス化の関係にない 2 つの例外クラスは、それらが同じ名前だったとしても等しくなることはありません。

以下に列挙した組み込み例外はインタプリタや組み込み関数によって生成されます。特に注記しないかぎり、これらの例外はエラーの詳しい原因を示している、 “関連値 (associated value)” を持ちます。この値は文字列または複数の情報 (例えばエラーコードや、エラーコードを説明する文字列) を含むタプルです。この関連値は raise 文の 2 番目の引数です。例外が標準のルートクラスである BaseException の派生クラスであれば、関連値は例外インスタンスの args 属性中に置かれます。

ユーザによるコードも組み込み例外を送出することができます。これは例外処理をテストしたり、インタプリタがある例外を送出する状況と “ちょうど同じような” エラー条件であることを報告させるために使うことができます。しかし、ユーザが適切でないエラーを送出するようコードすることを妨げる方法はないので注意してください。

組み込み例外クラスは新たな例外を定義するためにサブクラス化することができます。新しい例外は、少なくとも Exception クラスから派生することをお勧めします。 BaseException からは派生しないで下さい。例外を定義する上での詳しい情報は、 Python チュートリアルの ユーザ定義の例外 の項目にあります。

以下の例外クラスは他の例外クラスの基底クラスとしてのみ使われます。

exception BaseException

全ての組み込み例外のルートクラスです。ユーザ定義例外が直接このクラスを継承することは意図していません (そうした場合は Exception を使ってください)。このクラスに対して str() や unicode() が呼ばれた場合、引数の文字列表現か、引数が無い時には空文字列が返されます。

バージョン 2.5 で追加.

args

例外コンストラクタに与えられた引数のタプルです。組み込み例外は普通、エラーメッセージを与える一つの文字列だけを引数として呼ばれますが、中には (IOError など) いくつかの引数を必要とし、このタプルの要素に特別な意味を込めるものもあります。

exception Exception

全ての組み込み例外のうち、システム終了でないものはこのクラスから導出されています。全てのユーザ定義例外はこのクラスの派生クラスであるべきです。

バージョン 2.5 で変更: BaseException を継承するように変更されました.

exception StandardError

StopIteration, SystemExit, KeyboardInterrupt, SystemExit 以外の、全ての組み込み例外の基底クラスです。 StandardError 自体は Exception の派生クラスです。

exception ArithmeticError

算術上の様々なエラーにおいて送出される組み込み例外 OverflowError, ZeroDivisionError, FloatingPointError の基底クラスです。

exception BufferError

バッファ (buffer) に関連する演算が行えなかったときに送出されます。

exception LookupError

マップ型またはシーケンス型に使われたキーやインデックスが無効な場合に送出される例外 IndexError および KeyError の基底クラスです。 codecs.lookup() によって直接送出されることもあります。

exception EnvironmentError

Python システムの外部で起こる可能性のある例外 IOError および OSError の基底クラスです。この型の例外が 2 つの要素を持つタプルで生成された場合、 1 番目の要素はインスタンスの errno 属性で得ることができます (この値はエラー番号と見なされます)。 2 番目の要素は strerror 属性です (この値は通常、エラーに関連するメッセージです)。タプル自体は args 属性から得ることもできます。

バージョン 1.5.2 で追加.

EnvironmentError 例外が 3 要素のタプルで生成された場合、最初の 2 つの要素は上記と同様に値を得ることができ、さらに 3 番目の要素は filename 属性で得ることができます。しかしながら、以前のバージョンとの互換性のために、 args 属性にはコンストラクタに渡した最初の 2 つの引数からなる 2 要素のタプルしか含みません。

この例外が 3 つ以外の引数で生成された場合、 filename 属性は None になります。この例外が 2 つまたは 3 つ以外の引数で生成された場合、 errno および strerror 属性も None になります。後者のケースでは、 args がコンストラクタに与えた引数をそのままタプルの形で含んでいます。

以下の例外は実際に送出される例外です。

exception AssertionError

assert 文が失敗した場合に送出されます。

exception AttributeError

属性の参照 (属性参照 を参照) や代入が失敗した場合に送出されます (オブジェクトが属性の参照や属性の代入をまったくサポートしていない場合には TypeError が送出されます)。

exception EOFError

組み込み関数 (input() または raw_input()) のいずれかで、データを全く読まないうちにファイルの終端 (EOF) に到達した場合に送出されます (注意: file.read() および file.readline() メソッドの場合、データを読まないうちに EOF にたどり着くと空の文字列を返します)。

exception FloatingPointError

浮動小数点演算が失敗した場合に送出されます。この例外は Python のどのバージョンでも常に定義されていますが、 Python が --with-fpectl オプションを有効にしてコンパイルされているか、 pyconfig.h ファイルにシンボル WANT_SIGFPE_HANDLER が定義されている場合にのみ送出されます。

exception GeneratorExit

ジェネレータ (generator) の close() メソッドが呼び出されたときに送出されます。この例外は厳密にはエラーではないので、 StandardError ではなく BaseException を直接継承しています。

バージョン 2.5 で追加.

バージョン 2.6 で変更: BaseException を継承するように変更されました。

exception IOError

(print 文、組み込みの open() またはファイルオブジェクトに対するメソッドといった) I/O 操作が、例えば “ファイルが存在しません” や “ディスクの空き領域がありません” といった I/O に関連した理由で失敗した場合に送出されます。

このクラスは EnvironmentError の派生クラスです。この例外クラスのインスタンス属性に関する情報は上記の EnvironmentError に関する議論を参照してください。

バージョン 2.6 で変更: socket.error は、この例外を基底クラスとして使うように変更されました。

exception ImportError

import 文でモジュール定義を見つけられなかった場合や、 from ... import 文で指定した名前をインポートすることができなかった場合に送出されます。

exception IndexError

シーケンスのインデックス指定がシーケンスの範囲を超えている場合に送出されます　(スライスのインデックスはシーケンスの範囲に収まるように暗黙のうちに調整されます; インデックスが通常の整数でない場合、 TypeError が送出されます)。

exception KeyError

マップ型 (辞書型) オブジェクトのキーが、オブジェクトのキー集合内に見つからなかった場合に送出されます。

exception KeyboardInterrupt

ユーザが割り込みキー (通常は Control-C または Delete キー) を押した場合に送出されます。割り込みが起きたかどうかはインタプリタの実行中に定期的に調べられます。組み込み関数 input() や raw_input() がユーザの入力を待っている間に割り込みキーを押してもこの例外が送出されます。この例外は Exception を処理するコードに誤って捕捉されてインタプリタの終了が阻害されないように BaseException を継承しています。

バージョン 2.5 で変更: BaseException を継承するように変更されました.

exception MemoryError

ある操作中にメモリが不足したが、その状況は (オブジェクトをいくつか消去することで) まだ復旧可能かもしれない場合に送出されます。例外の関連値は、どんな種類の (内部) 操作がメモリ不足になっているかを示す文字列です。背後にあるメモリ管理アーキテクチャ (C の malloc() 関数) によっては、インタプリタが常にその状況を完璧に復旧できるとはかぎらないので注意してください; プログラムの暴走が原因の場合にも、やはり実行スタックの追跡結果を出力できるようにするために例外が送出されます。

exception NameError

ローカルまたはグローバルの名前が見つからなかった場合に送出されます。これは非限定の名前のみに適用されます。関連値は見つからなかった名前を含むエラーメッセージです。

exception NotImplementedError

この例外は RuntimeError から派生しています。ユーザ定義の基底クラスにおいて、抽象メソッドが派生クラスでオーバライドされることを要求する場合、この例外を送出しなくてはなりません。

バージョン 1.5.2 で追加.

exception OSError

このクラスは EnvironmentError から派生しています。関数がシステムに関連したエラーを返した場合に送出されます (引数の型が間違っている場合や、他の偶発的なエラーは除きます)。 errno 属性は errno に基づく数字のエラーコードで、 strerror 属性は C の perror() 関数で表示されるような文字列です。オペレーティングシステムに依存したエラーコードの定義と名前については、 errno モジュールを参照して下さい。

ファイルシステムのパスに関係する例外 (chdir() や unlink() など) では、例外インスタンスは 3 番目の属性 filename を持ちます。これは関数に渡されたファイル名です。

バージョン 1.5.2 で追加.

exception OverflowError

算術演算の結果が表現できない大きな値になった場合に送出されます。これは long integer の演算と通常の整数に関するほとんどの操作では起こりません (long integer の演算ではむしろ MemoryError が送出されることになるでしょう)。整数に関するほとんどの操作では、代わりに long integer が返されます。 C の浮動小数点演算の例外処理は標準化されていないので、ほとんどの浮動小数点演算もチェックされません。

exception ReferenceError

weakref.proxy() によって生成された弱参照 (weak reference) プロキシを使って、ガーベジコレクションによって回収された後の参照対象オブジェクトの属性にアクセスした場合に送出されます。弱参照については weakref モジュールを参照してください。

バージョン 2.2 で追加: 以前は weakref.ReferenceError 例外として知られていました。

exception RuntimeError

他のカテゴリに分類できないエラーが検出された場合に送出されます。関連値は、何が問題だったのかをより詳細に示す文字列です (この例外はほとんど過去のバージョンのインタプリタにおける遺物です。今ではあまり使われることはありません)。

exception StopIteration

イテレータ (iterator) の next() メソッドにより、それ以上要素がないことを知らせるために送出されます。この例外は、通常の利用方法ではエラーとはみなされないため、 StandardError ではなく Exception から派生しています。

バージョン 2.2 で追加.

exception SyntaxError

パーザが構文エラーに遭遇した場合に送出されます。この例外は import 文、 exec 文、組み込み関数 evel() や input() 、初期化スクリプトの読み込みや標準入力で (対話的な実行時にも) 起こる可能性があります。

このクラスのインスタンスは、例外の詳細に簡単にアクセスできるようにするために、属性 filename, lineno, offset, text を持ちます。例外インスタンスに対する str() はメッセージのみを返します。

exception IndentationError

正しくないインデントに関する構文エラーの基底クラスです。これは SyntaxError のサブクラスです。

exception TabError

タブとスペースを一貫しない方法でインデントに使っているときに送出されます。これは IndentationError のサブクラスです。

exception SystemError

インタプリタが内部エラーを発見したが、その状況は全ての望みを棄てさせるほど深刻ではないように思われる場合に送出されます。関連値は (下位層の言葉で) 何がまずいのかを示す文字列です。

Python の作者か、あなたの Python インタプリタを保守している人にこのエラーを報告してください。このとき、 Python インタプリタのバージョン (sys.version; Python の対話的セッションを開始した際にも出力されます)、正確なエラーメッセージ (例外の関連値) を忘れずに報告してください。そしてもし可能ならエラーを引き起こしたプログラムのソースコードを報告してください。

exception SystemExit

この例外は sys.exit() 関数によって送出されます。この例外が処理されなかった場合、スタックのトレースバックを全く表示することなく Python インタプリタは終了します。関連値が通常の整数であれば、システム終了ステータスを表します (exit() 関数に渡されます)。値が None の場合、終了ステータスは 0 です。 (文字列のような) 他の型の場合、そのオブジェクトの値が表示され、終了ステータスは 1 になります。

この例外のインスタンスは属性 code を持ちます。この値は終了ステータスまたはエラーメッセージ (標準では None) に設定されます。また、この例外は厳密にはエラーではないため、 StandardError ではなく BaseException から派生しています。

sys.exit() は、クリーンアップのための処理 (try 文の finally 節) が実行されるようにするため、またデバッガが制御不能になるリスクを冒さずにスクリプトを実行できるようにするために例外に翻訳されます。即座に終了することが真に強く必要であるとき (例えば、 fork() を呼んだ後の子プロセス内) には os._exit() 関数を使うことができます。

この例外は Exception を捕まえるコードに間違って捕まえられないように、 StandardError や Exception からではなく BaseException を継承しています。これにより、この例外は着実に呼出し元の方に伝わっていってインタプリタを終了させます。

バージョン 2.5 で変更: BaseException を継承するように変更されました。

exception TypeError

組み込み演算または関数が適切でない型のオブジェクトに対して適用された際に送出されます。関連値は型の不整合に関して詳細を述べた文字列です。

exception UnboundLocalError

関数やメソッド内のローカルな変数に対して参照を行ったが、その変数には値が代入されていなかった場合に送出されます。 NameError のサブクラスです。

バージョン 2.0 で追加.

exception UnicodeError

Unicode に関するエンコードまたはデコードのエラーが発生した際に送出されます。 ValueError のサブクラスです。

バージョン 2.0 で追加.

exception UnicodeEncodeError

Unicode 関連のエラーがエンコード中に発生した際に送出されます。 UnicodeError のサブクラスです。

バージョン 2.3 で追加.

exception UnicodeDecodeError

Unicode 関連のエラーがデコード中に発生した際に送出されます。 UnicodeError のサブクラスです。

バージョン 2.3 で追加.

exception UnicodeTranslateError

Unicode 関連のエラーがコード翻訳に発生した際に送出されます。 UnicodeError のサブクラスです。

バージョン 2.3 で追加.

exception ValueError

組み込み演算や関数が、正しい型だが適切でない値を受け取った場合や、 IndexError のような詳細な説明のできない状況で送出されます。

exception VMSError

VMS においてのみ利用可能です。 VMS 特有のエラーが起こったときに送出されます。

exception WindowsError

Windows 特有のエラーか、エラー番号が errno 値に対応しない場合に送出されます。 winerrno および strerror の値は Windows プラットフォーム API の関数 GetLastError() と FormatMessage() の戻り値から生成されます。 errno の値は winerror の値を対応する errno.h の値にマップしたものです。 OSError のサブクラスです。

バージョン 2.0 で追加.

バージョン 2.5 で変更: 以前のバージョンは GetLastError() のコードを errno に入れていました。

exception ZeroDivisionError

除算またモジュロ演算における 2 番目の引数が 0 であった場合に送出されます。関連値は文字列で、その演算における被演算子と演算子の型を示します。

以下の例外は警告カテゴリとして使われます。詳細については warnings モジュールを参照してください。

exception Warning

警告カテゴリの基底クラスです。

exception UserWarning

ユーザコードによって生成される警告の基底クラスです。

exception DeprecationWarning

廃止された機能に対する警告の基底クラスです。

exception PendingDeprecationWarning

将来廃止される予定の機能に対する警告の基底クラスです。

exception SyntaxWarning

曖昧な構文に対する警告の基底クラスです。

exception RuntimeWarning

あいまいなランタイム挙動に対する警告の基底クラスです。

exception FutureWarning

将来意味構成が変わることになっている文の構成に対する警告の基底クラスです。

exception ImportWarning

モジュールインポートの誤りと思われるものに対する警告の基底クラスです。

バージョン 2.5 で追加.

exception UnicodeWarning

Unicode に関連した警告の基底クラスです。

バージョン 2.5 で追加.

6.1. 例外のクラス階層

組み込み例外のクラス階層は以下のようになっています:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
      |    +-- ImportError
      |    +-- LookupError
      |    |    +-- IndexError
      |    |    +-- KeyError
      |    +-- MemoryError
      |    +-- NameError
      |    |    +-- UnboundLocalError
      |    +-- ReferenceError
      |    +-- RuntimeError
      |    |    +-- NotImplementedError
      |    +-- SyntaxError
      |    |    +-- IndentationError
      |    |         +-- TabError
      |    +-- SystemError
      |    +-- TypeError
      |    +-- ValueError
      |         +-- UnicodeError
      |              +-- UnicodeDecodeError
      |              +-- UnicodeEncodeError
      |              +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
	   +-- ImportWarning
	   +-- UnicodeWarning
	   +-- BytesWarning

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理

この章で解説されているモジュールは文字列を操作するさまざまな処理を提供します。

それに加えて、Python の組み込み文字列クラスたちは シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange で説明されたシーケンス型のメソッドをサポートし、また 文字列メソッドで説明された文字列固有のメソッドもサポートします。フォーマットされた文字列の出力にはテンプレート文字列、つまり 文字列フォーマット操作で説明された % 演算子を使います。また、正規表現に基づいた文字列関数については re モジュールを参照してください。

7.1. string — 一般的な文字列操作

7.1.1. 文字列定数

7.1.2. 文字列の書式指定

7.1.3. 書式指定文字列の文法

7.1.3.1. 書式指定ミニ言語仕様 (Format Specification Mini-Language)

7.1.3.2. 書式指定例

7.1.4. テンプレート文字列

7.1.5. 文字列操作関数

7.1.6. 撤廃された文字列関数

7.2. re — 正規表現操作

7.2.1. 正規表現のシンタクス

7.2.2. マッチング vs 検索

7.2.3. モジュールコンテンツ

7.2.4. 正規表現オブジェクト

7.2.5. MatchObject オブジェクト

7.2.6. 例

7.2.6.1. ペアの確認

7.2.6.2. scanf() をシミュレートする

7.2.6.3. 再帰を避ける

7.2.6.4. search() vs. match()

7.2.6.5. 電話帳の作成

7.2.6.6. テキストの秘匿

7.2.6.7. 全ての形容動詞を見つける

7.2.6.8. 全ての形容動詞と、その位置を見つける

7.2.6.9. Raw String記法

7.3. struct — 文字列データをパックされたバイナリデータとして解釈する

7.3.1. 関数と例外

7.3.2. フォーマット文字列

7.3.2.1. バイトオーダ, サイズ, アラインメント

7.3.2.2. フォーマット文字

7.3.2.3. 例

7.3.3. クラス

7.4. difflib — 差分の計算を助ける

7.4.1. SequenceMatcherオブジェクト

7.4.2. SequenceMatcher の例

7.4.3. Differ オブジェクト

7.4.4. Differ の例

7.4.5. difflib のコマンドラインインタフェース

7.5. StringIO — ファイルのように文字列を読み書きする

7.6. cStringIO — 高速化された StringIO

7.7. textwrap — テキストの折り返しと詰め込み

7.8. codecs — codec レジストリと基底クラス

7.8.1. Codec 基底クラス

7.8.1.1. Codec オブジェクト

7.8.1.2. IncrementalEncoder オブジェクト

7.8.1.3. IncrementalDecoder オブジェクト

7.8.1.4. StreamWriter オブジェクト

7.8.1.5. StreamReader オブジェクト

7.8.1.6. StreamReaderWriter オブジェクト

7.8.1.7. StreamRecoder オブジェクト

7.8.2. エンコーディングと Unicode

7.8.3. 標準エンコーディング

7.8.4. encodings.idna — アプリケーションにおける国際化ドメイン名 (IDNA)

7.8.5. encodings.utf_8_sig — BOM 印付き UTF-8

7.9. unicodedata — Unicode データベース

7.10. stringprep — インターネットのための文字列調製

7.11. fpformat — 浮動小数点数の変換

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.1. string — 一般的な文字列操作

string モジュールには便利な定数やクラスが数多く入っています。また、現在は文字列のメソッドとして利用できる、すでに撤廃された古い関数も入っています。さらに、 Python の組み込み文字列クラスは シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange 節に記載のシーケンス型のメソッドと、 文字列メソッド 節に記載の文字列メソッドもサポートします。出力の書式指定には、テンプレート文字列、または、文字列フォーマット操作 に記載の % 演算子を使用して下さい。正規表現に関する文字列操作の関数は re を参照してください。

参考

最新のバージョンの string モジュール Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/string.py?view=markup]

7.1.1. 文字列定数

このモジュールでは以下の定数を定義しています。

string.ascii_letters

後述の ascii_lowercase と ascii_uppercase を合わせたもの。この値はロケールに依存しません。

string.ascii_lowercase

小文字 'abcdefghijklmnopqrstuvwxyz' 。この値はロケールに依存せず、固定です。

string.ascii_uppercase

大文字 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 。この値はロケールに依存せず、固定です。

string.digits

文字列 '0123456789' です。

string.hexdigits

文字列 '0123456789abcdefABCDEF' です。

string.letters

後述の lowercase と uppercase を合わせた文字列です。具体的な値はロケールに依存しており、 locale.setlocale() が呼ばれたときに更新されます。

string.lowercase

小文字として扱われる文字全てを含む文字列です。ほとんどのシステムでは文字列 'abcdefghijklmnopqrstuvwxyz' です。具体的な値はロケールに依存しており、 locale.setlocale() が呼ばれたときに更新されます。

string.octdigits

文字列 '01234567' です。

string.punctuation

C ロケールにおいて、句読点として扱われる ASCII 文字の文字列です。

string.printable

印刷可能な文字で構成される文字列です。 digits, letters, punctuation および whitespace を組み合わせたものです。

string.uppercase

大文字として扱われる文字全てを含む文字列です。ほとんどのシステムでは 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' です。具体的な値はロケールに依存しており、 locale.setlocale() が呼ばれたときに更新されます。

string.whitespace

空白 (whitespace) として扱われる文字全てを含む文字列です。ほとんどのシステムでは、これはスペース (space)、タブ (tab)、改行 (linefeed)、復帰 (return)、改頁 (formfeed)、垂直タブ (vertical tab) です。

7.1.2. 文字列の書式指定

バージョン 2.6 で追加.

組み込みの str 、および、 unicode クラスは、 PEP 3101 [http://www.python.org/dev/peps/pep-3101] に記載される str.format() メソッドによる、複雑な変数置換と値の書式指定を提供します。 string モジュールの Formatter クラスは組み込みの format() メソッドと同じ実装で、文字列の書式指定の作成とカスタマイズを可能にします。

class string.Formatter

Formatter クラスは、以下のメソッドを持ちます。 :

format(format_string, *args, **kwargs)

format() は主たる API メソッドです。引数は、書式指定テンプレート文字列、および、任意のポジション、キーワード引数をとります。 format() は、 vformat() を呼び出すだけのラッパーです。

vformat(format_string, args, kwargs)

この関数は、書式指定の操作を行います。 *args や **kwds を使った書式で辞書をアンパックやリパックするのではなく、予め定義された辞書を引数として与えたいときなどでは、独立した関数として露出されます。 vformat() は書式テンプレート文字列を、文字データや置換フィールドに展開します。この関数は、以下の様々なメソッドを呼び出します。

付け加えると、 Formatter はサブクラスで置き換えるためのいくつかのメソッドを定義します。 :

parse(format_string)

format_stringを探査し、タプル、 (literal_text, field_name, format_spec, conversion) のイテラブルを返します。これは vformat() が文字列を文字としての文字データや置換フィールドに展開するために使用されます。

タプルの値は、概念的に文字としての文字データと、それに続く単一の置換フィールドを表現します。文字としての文字データが無い場合は (ふたつの置換フィールドが連続した場合などに起き得ます) 、 literal_text は長さが 0 の文字列となります。置換フィールドが無い場合は、 field_name, format_spec および conversion が None となります。

get_field(field_name, args, kwargs)

引数として与えた parse() (上記参照) により返される field_name を書式指定対象オブジェクトに変換します。返り値はタプル、 (obj, used_key) です。デフォルトでは PEP 3101 [http://www.python.org/dev/peps/pep-3101] に規定される “0[name]” や “label.title” のような形式の文字列を引数としてとります。 args と kwargs は vformat() に渡されます。返り値 used_key は、 get_value() の key 引数と同じ意味を持ちます。

get_value(key, args, kwargs)

与えられたフィールドの値を取り出します。 key 引数は整数でも文字列でも構いません。整数の場合は、ポジション引数 args のインデックス番号を示します。文字列の場合は、名前付きの引数 kwargs を意味します。

args 引数は、 vformat() へのポジション引数のリストに設定され、 kwargs 引数は、キーワード引数の辞書に設定されます。

複合したフィールド名に対しては、これらの関数はフィールド名の最初の要素に対してのみ呼び出されます ; あとに続く要素は通常の属性、および、インデックス処理へと渡されます。

つまり、例えば、フィールドが ‘0.name’ と表現されるとき、 get_value() は、 key 引数が 0 として呼び出されます。属性 name は、組み込みの getattr() 関数が呼び出され、 get_value() が返されたのちに検索されます。

もし、インデックス、もしくは、キーワードが存在しないアイテムを参照したら、 IndexError 、もしくは、 KeyError が送出されます。

check_unused_args(used_args, args, kwargs)

希望に応じ、未使用の引数がないか確認する機能を実装します。この関数への引数は、書式指定文字列で参照される全てのキー引数の set 、 (ポジション引数への整数、名前付き引数への文字列) 、そして vformat に渡される args と kwargs への参照です。使用されない引数の set は、それらのパラメータから計算されます。 check_unused_args() は、確認の結果が偽であると、例外を送出するものとみなされます。

format_field(value, format_spec)

format_field() は単純に組み込みのグローバル関数 format() を呼び出します。このメソッドは、サブクラスをオーバーライドするために提供されます。

convert_field(value, conversion)

(get_field() が返す) 値を、与えられた conversion 型に (parse() がタプルを返すように) 変換します。デフォルトでは ‘r’(repr) と ‘s’(str) 変換型を解釈できます。

7.1.3. 書式指定文字列の文法

str.format() メソッドと、 Formatter クラスは、文字列の書式指定に同じ文法を共有します (しかしながら、 Formatter サブクラスの場合、それ自身の書式指定文法を定義することが可能です) 。

書式指定文字列は波括弧 {} に囲まれた “置換フィールド” を含みます。波括弧に囲まれた部分以外は全て単純な文字として扱われ、変更を加えることなく出力へコピーされます。波括弧を文字として扱う必要がある場合は、二重にすることでエスケープすることができます: {{ および }}

置換フィールドの文法は以下です:

replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
arg_name          ::=  [identifier | integer]
attribute_name    ::=  identifier
element_index     ::=  integer | index_string
index_string      ::=  <any source character except "]"> +
conversion        ::=  "r" | "s"
format_spec       ::=  <described in the next section>

もっと簡単にいうと、置換フィールドは field_name で始められます。これによって指定したオブジェクトの値が、置換フィールドの代わりに書式化され出力に挿入されます。その後に、感嘆符 '!' を挟んで conversion フィールドを続けることができます。最後にコロン ':' を挟んで、 format_spec を書くことができます。これは、置換される値の非デフォルトの書式を指定します。

書式指定ミニ言語仕様 (Format Specification Mini-Language) 節も参照して下さい。

field_name 自体は、数字かキーワードである arg_name で始まります。数字である場合、ポジション引数を参照します。キーワードである場合、指名されたキーワード引数を参照します。書式指定文字列中の数の arg_name が 0, 1, 2, ... と並んでいるなら、これらは (一部ではなく) すべて省略でき、数 0, 1, 2, ... がその順に自動的に挿入されます。 arg_name の後に数字インデックスや属性式を続けることができます。 '.name' 形式の式の場合、 getattr() 使って指名された属性が選択され、 '[index]' 形式の式の場合、 __getitem__() を使ってインデックス検索されます。

バージョン 2.7 で変更: ポジション引数指定子は省略できるようになりました。 '{} {}' は '{0} {1}' と等価です。

簡単な書式指定文字列の例を挙げます:

"First, thou shalt count to {0}" # 最初のポジション引数を参照します
"Bring me a {}"                  # 暗示的に第一ポジション引数を参照します
"From {} to {}"                  # "From {0} to {1}" と同じです
"My quest is {name}"             # キーワード引数 'name' を参照します
"Weight in tons {0.weight}"      # 最初のポジション引数の属性 'weight' を参照します
"Units destroyed: {players[0]}"  # キーワード引数 'players' の最初の要素を参照します

置換 (conversion) フィールドにより書式変換前に型の強制変換が実施されます。通常、値の書式変換は __format__() によって実施されます。しかしながら、場合によっては、文字列として変換することを強制したり、書式指定の定義をオーバーライドしたくなることもあります。 __format__() の呼び出し前に値を文字列に変換すると、通常の書式変換の処理は飛ばされます。

現時点では、二種類の変換フラグがサポートされています: 値に対して str() を呼び出す '!s' と、 repr() を呼び出す '!r' です。

例:

"Harold's a clever {0!s}"        # 引数に対して、最初に str() を呼び出します
"Bring out the holy {name!r}"    # 引数に対して、最初に repr() を呼び出します

format_spec フィールドは、フィールド幅、文字揃え、埋め方、精度などの、値を表現する仕様を含みます。それぞれの値の型は、 “formatting mini-language” 、または、 format_spec の実装で定義されます。

ほとんどの組み込み型は、共通の次のセクションに記載の formatting mini-language をサポートします。

format_spec フィールドは入れ子になった置換フィールドを含むこともできます。入れ子になった置換フィールドはフィールド名だけを含むことができます; 変換フラグや書式指定は不可です。 format_spec 中の置換フィールドは format_spec 文字列が解釈される前に置き換えられます。これにより、値の書式動的に指定することが可能になります。

書式指定例 のいくつかの例も参照して下さい。

7.1.3.1. 書式指定ミニ言語仕様 (Format Specification Mini-Language)

書式指定 (“Format specifications”) は書式指定文字列の個々の値を表現する方法を指定するための、置換フィールドで使用されます (書式指定文字列の文法 を参照下さい) 。それらは、組み込み関数の format() 関数に直接渡されます。それぞれの書式指定可能な型について、書式指定がどのように解釈されるかが規定されます。

多くの組み込み型は、書式指定に関して以下のオプションを実装します。しかしながら、いくつかの書式指定オプションは数値型でのみサポートされます。

一般的な取り決めとして、空の書式指定文字列 ("") は、値に対して str() を呼び出したときと同じ結果を与えます。通常、空でない書式指定文字列はその結果を変更します。

一般的な書式指定子 (standard format specifier) の書式は以下です:

format_spec   ::=  [[fill]align][sign][#][0][width][,][.precision][type]
fill(詰め方)     ::=  <'}'以外の文字>
align(整列)     ::=  "<" | ">" | "=" | "^"
sign(符号)      ::=  "+" | "-" | " "
width(幅)      ::=  整数
precision(精度) ::=  整数
type          ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

fill 文字は、’{‘ と ‘}’ 以外のどんな文字でもかまいません。 fill 文字があることは、 align オプションが続くことで示されます。もし、 format_spec の二つめの文字が align オプションで無い場合は、 fill と align の両方のオプションが無いものと解釈されます。

様々な align オプションの意味は以下のとおりです :

オプション | 意味
'<' | 利用可能なスペースにおいて、左詰めを強制します。 (ほとんどのオブジェクトにおいてのデフォルト)
'>' | 利用可能なスペースにおいて、右詰めを強制します。 (いくつかのオブジェクトにおいてのデフォルト)
'=' | 符号 (があれば) の後ろを埋めます。 ‘+000000120’ のような形で表示されます。このオプションは数値型に対してのみ有効です。
'^' | 資料可能なスペースにおいて、中央寄せを強制します。

最小のフィールド幅が定義されない限り、フィールド幅はデータを表示するために必要な幅と同じになることに注意して下さい。そのため、その場合には、 align オプションは意味を持ちません。

sign オプションは数値型に対してのみ有効ですであり、以下のうちのひとつとなります :

オプション | 意味
'+' | 符号の使用を、正数、負数の両方に対して指定します。
'-' | 符号の使用を、負数に対してのみ指定します。 (デフォルトの挙動です)
空白 | 空白を正数の前に付け、負号を負数の前に使用することを指定します。

'#' オプションは、整数、かつ、2進数、8進数、16進数の出力に対してのみ有効です。指定されれば、出力は、 '0b', '0o', もしくは '0x', のプリフィックスが付与されます。

',' オプションは、千の位のセパレータにカンマを使うことを合図します。ロケール依存のセパレータには、代わりに 'n' の整数表現形式を使ってください。

バージョン 2.7 で変更: ',' オプションを追加しました (PEP 378 [http://www.python.org/dev/peps/pep-0378] も参照してください)。

width は10進数の整数で、最小のフィールド幅を規程します。もし指定されなければ、フィールド幅は内容により規程されます。

もし width フィールドがゼロ ('0') で始まる場合、ゼロ埋めとなります。これは、 alignment 型が '=' で、 fill 文字が '0' であることと等価です。

precision は10進数で、 'f' および 'F' 、あるいは、 'g' および 'G' で指定される浮動小数点数の、小数点以下に続く桁数を指定します。非数型に対しては、最大フィールド幅を規程します。言い換えると、フィールドの内容から、何文字使用するかを規程します。 precision は整数型に対しては、許されません。

最後に、 type は、データがどのように表現されるかを規程します。

利用可能な文字列の表現型は以下です：

型 | 意味
's' | 文字列。デフォルトの値で多くの場合省略されます
空白 | 's' と同じです。

利用可能な整数の表現型は以下です :

型 | 意味
'b' | 2進数。出力される数値は2を基数とします。
'c' | 文字。数値を対応するユニコード文字に変換します。
'd' | 10進数。出力される数値は10を基数とします。
'o' | 8進数。出力される数値は8を基数とします。
'x' | 16進数。出力される数値は16を基数とします。 10進で9を越える数字には小文字が使われます。
'X' | 16進数。出力される数値は16を基数とします。 10進で9を越える数字には大文字が使われます。
'n' | 数値。現在のロケールに従い、区切り文字を挿入することを除けば、 'd' と同じです。
空白 | 'd' と同じです。

これらの表現型に加えて、整数は ('n' と空白を除く) 以下の浮動小数点型の表現型で書式指定できます。そうすることで整数は書式変換される前に float() を使って浮動小数点数に変換されます。

利用可能な浮動小数点数と10進数の表現型は以下です :

型
意味

'e'
指数指定です。指数を示す ‘e’ を使って数値を表示します。

'E'
指数指定です。大文字の ‘E’ を使うことを除いては、 'e' と同じです。

'f'
固定小数点数です。数値を固定小数点数として表示します。

'F'
固定小数点数です。 'f' と同じです。

'g'

標準フォーマットです。精度を p >= 1 の数値で与えた場合、数値を有効桁 p で丸め、桁に応じて固定小数点か指数指定で表示します。

精度のルールは以下のように決まっています: 書式指定の結果が 'e' 型で p-1 の精度の場合、指数は exp になると仮定します。そうすると、 -4 <= exp < p のとき数値は表現型 'f' で精度 p-1-exp に書式変換されます。それ以外の場合、数値は 'e' 型で精度 p-1 に書式指定されます。この両方の場合で重要でない、連続した 0 は取り除かれます, そして残った桁が無い場合小数点は取り除かれます。

正と負の無限大と 0 および NaN は精度に関係なくそれぞれ inf, -inf, 0, -0 および nan となります。

0 の精度は 1 の精度と同等に扱われます。

'G'
標準フォーマットです。数値が大きくなったとき、 'E' に切り替わることを除き、 'g' と同じです。無限大と NaN の表示も大文字になります。

'n'
数値です。現在のロケールに合わせて、数値分割文字が挿入されることを除き、 'g' と同じです。

'%'
パーセンテージです。数値は 100 倍され、固定小数点数フォーマット ('f') でパーセント記号付きで表示されます。

None
'g' と同じです。

7.1.3.2. 書式指定例

この節には新しい書式指定構文と古い %-書式の比較例が載っています。

多くの場合、 % の代わりに {} を加えることで新構文は古い %-書式に類似した書式になります。例えば、 '%03.2f' は '{:03.2f}' に翻訳できます。

以下の例で示すように、新構文はさらに新たに様々なオプションもサポートしています、

ポジション引数を使ったアクセス:

>>> '{0}, {1}, {2}'.format('a', 'b', 'c')
'a, b, c'
>>> '{}, {}, {}'.format('a', 'b', 'c')  # 2.7+ 専用
'a, b, c'
>>> '{2}, {1}, {0}'.format('a', 'b', 'c')
'c, b, a'
>>> '{2}, {1}, {0}'.format(*'abc')      # 引数シークエンスをアンパック
'c, b, a'
>>> '{0}{1}{0}'.format('abra', 'cad')   # 引数のインデクスは繰り返すことができます
'abracadabra'

名前を使ったアクセス:

>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
'Coordinates: 37.24N, -115.81W'
>>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'}
>>> 'Coordinates: {latitude}, {longitude}'.format(**coord)
'Coordinates: 37.24N, -115.81W'

引数の属性へのアクセス:

>>> c = 3-5j
>>> ('The complex number {0} is formed from the real part {0.real} '
...  'and the imaginary part {0.imag}.').format(c)
'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.'
>>> class Point(object):
...     def __init__(self, x, y):
...         self.x, self.y = x, y
...     def __str__(self):
...         return 'Point({self.x}, {self.y})'.format(self=self)
...
>>> str(Point(4, 2))
'Point(4, 2)'

引数の要素へのアクセス:

>>> coord = (3, 5)
>>> 'X: {0[0]};  Y: {0[1]}'.format(coord)
'X: 3;  Y: 5'

%s と %r の置換:

>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"

テキストの幅を指定した整列:

>>> '{:<30}'.format('left aligned')
'left aligned                  '
>>> '{:>30}'.format('right aligned')
'                 right aligned'
>>> '{:^30}'.format('centered')
'           centered           '
>>> '{:*^30}'.format('centered')  # 詰め文字に '*' を使う
'***********centered***********'

%+f と %-f, % f の置換、そして符号の指定:

>>> '{:+f}; {:+f}'.format(3.14, -3.14)  # 常に表示する
'+3.140000; -3.140000'
>>> '{: f}; {: f}'.format(3.14, -3.14)  # 正の数にはスペースを表示
' 3.140000; -3.140000'
>>> '{:-f}; {:-f}'.format(3.14, -3.14)  # マイナスだけを表示 -- '{:f}; {:f}' と同じ
'3.140000; -3.140000'

%x と %o の置換、そして値に対する異なる底の変換:

>>> # format also supports binary numbers
>>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'

千の位のセパレータにカンマを使用する:

>>> '{:,}'.format(1234567890)
'1,234,567,890'

パーセントを表示する:

>>> points = 19.5
>>> total = 22
>>> 'Correct answers: {:.2%}.'.format(points/total)
'Correct answers: 88.64%'

型特有の書式指定を使う:

>>> import datetime
>>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)
>>> '{:%Y-%m-%d %H:%M:%S}'.format(d)
'2010-07-04 12:15:58'

引数をネストする、さらに複雑な例:

>>> for align, text in zip('<^>', ['left', 'center', 'right']):
...     '{:{align}{fill}16}'.format(text, fill=align, align=align)
...
'left<<<<<<<<<<<<'
'^^^^^center^^^^^'
'>>>>>>>>>>>right'
>>>
>>> octets = [192, 168, 0, 1]
>>> '{:0X}{:02X}{:02X}{:02X}'.format(*octets)
'C0A80001'
>>> int(_, 16)
3232235521
>>>
>>> width = 5
>>> for num in range(5,12):
...     for base in 'dXob':
...         print '{0:{width}{base}}'.format(num, base=base, width=width),
...     print
...
    5     5     5   101
    6     6     6   110
    7     7     7   111
    8     8    10  1000
    9     9    11  1001
   10     A    12  1010
   11     B    13  1011

7.1.4. テンプレート文字列

バージョン 2.4 で追加.

テンプレート (template) を使うと、 PEP 292 [http://www.python.org/dev/peps/pep-0292] で解説されているようにより簡潔に文字列置換 (string substitution) を行えるようになります。通常の % ベースの置換に代わって、テンプレートでは以下のような規則に従った $ ベースの置換をサポートしています:

$$ はエスケープ文字です; $ 一つに置換されます。

$identifier は置換プレースホルダの指定で、 "identifier" というキーへの対応付けに相当します。デフォルトは、 "identifier" の部分には Python の識別子が書かれていなければなりません。 $ の後に識別子に使えない文字が出現すると、そこでプレースホルダ名の指定が終わります。

${identifier} は $identifier と同じです。プレースホルダ名の後ろに識別子として使える文字列が続いていて、それをプレースホルダ名の一部として扱いたくない場合、例えば "${noun}ification" のような場合に必要な書き方です。

上記以外の書き方で文字列中に $ を使うと ValueError を送出します。

string モジュールでは、上記のような規則を実装した Template クラスを提供しています。 Template のメソッドを以下に示します:

class string.Template(template)

コンストラクタはテンプレート文字列になる引数を一つだけ取ります。

substitute(mapping[, **kws])

テンプレート置換を行い、新たな文字列を生成して返します。 mapping はテンプレート中のプレースホルダに対応するキーを持つような任意の辞書類似オブジェクトです。辞書を指定する代わりに、キーワード引数も指定でき、その場合にはキーワードをプレースホルダ名に対応させます。 mapping と kws の両方が指定され、内容が重複した場合には、 kws に指定したプレースホルダを優先します。

safe_substitute(mapping[, **kws])

substitute() と同じですが、プレースホルダに対応するものを mapping や kws から見つけられなかった場合に、 KeyError 例外を送出する代わりにもとのプレースホルダがそのまま入ります。また、 substitute() とは違い、規則外の書き方で $ を使った場合でも、 ValueError を送出せず単に $ を返します。

その他の例外も発生し得る一方で、このメソッドが「安全 (safe) 」と呼ばれているのは、置換操作が常に例外を送出する代わりに利用可能な文字列を返そうとするからです。別の見方をすれば、 safe_substitute() は区切り間違いによるぶら下がり (dangling delimiter) や波括弧の非対応、 Python の識別子として無効なプレースホルダ名を含むような不正なテンプレートを何も警告せずに無視するため、安全とはいえないのです。

Template のインスタンスは、次のような public な属性を提供しています:

template

コンストラクタの引数 template に渡されたオブジェクトです。通常、この値を変更すべきではありませんが、読み込み専用アクセスを強制しているわけではありません。

Templateの使い方の例を以下に示します:

>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'
>>> d = dict(who='tim')
>>> Template('Give $who $100').substitute(d)
Traceback (most recent call last):
[...]
ValueError: Invalid placeholder in string: line 1, col 10
>>> Template('$who likes $what').substitute(d)
Traceback (most recent call last):
[...]
KeyError: 'what'
>>> Template('$who likes $what').safe_substitute(d)
'tim likes $what'

さらに進んだ使い方: Template のサブクラスを派生して、プレースホルダの書式、区切り文字、テンプレート文字列の解釈に使われている正規表現全体をカスタマイズできます。こうした作業には、以下のクラス属性をオーバライドします:

delimiter – プレースホルダの開始を示すリテラル文字列です。デフォルトの値は $ です。実装系はこの文字列に対して必要に応じて re.escape() を呼び出すので、正規表現を表すような文字列にしては なりません 。

idpattern – 波括弧でくくらない形式のプレースホルダの表記パターンを示す正規表現です (波括弧は自動的に適切な場所に追加されます)　。デフォルトの値は [_a-z][_a-z0-9]* という正規表現です。

他にも、クラス属性 pattern をオーバライドして、正規表現パターン全体を指定できます。オーバライドを行う場合、 pattern の値は 4 つの名前つきキャプチャグループ (capturing group) を持った正規表現オブジェクトでなければなりません。これらのキャプチャグループは、上で説明した規則と、無効なプレースホルダに対する規則に対応しています:

escaped – このグループはエスケープシーケンス、すなわちデフォルトパターンにおける $$ に対応します。

named – このグループは波括弧でくくらないプレースホルダ名に対応します; キャプチャグループに区切り文字を含めてはなりません。

braced – このグループは波括弧でくくったプレースホルダ名に対応します; キャプチャグループに区切り文字を含めてはなりません。

invalid – このグループはそのほかの区切り文字のパターン (通常は区切り文字一つ) に対応し、正規表現の末尾に出現せねばなりません。

7.1.5. 文字列操作関数

以下の関数は文字列または Unicode オブジェクトを操作できます。これらの関数は文字列型のメソッドにはありません。

string.capwords(s[, sep])

split() を使って引数を単語に分割し、 capitalize() を使ってそれぞれの単語の先頭の文字を大文字に変換し、 join() を使ってつなぎ合わせます。オプションの第2引数 sep が与えられないか None の場合、この置換処理は文字列中の連続する空白文字をスペース一つに置き換え、先頭と末尾の空白を削除します、それ以外の場合には sep は split と join に使われます。

string.maketrans(from, to)

translate() に渡すのに適した変換テーブルを返します。このテーブルは、 from 内の各文字を to の同じ位置にある文字に対応付けます; from と to は同じ長さでなければなりません。

ノート

lowercase と uppercase から取り出した文字列を引数に使ってはなりません; ロケールによっては、これらは同じ長さになりません。大文字小文字の変換には、常に str.lower() または str.upper() を使ってください。

7.1.6. 撤廃された文字列関数

以下の一連の関数は、文字列型や Unicode 型のオブジェクトのメソッドとしても定義されています; 詳しくは、それらの 文字列メソッド の項を参照してください。ここに挙げた関数は Python 3.0 で削除されることはないはずですが、撤廃された関数とみなして下さい。このモジュールで定義されている関数は以下の通りです:

string.atof(s)

バージョン 2.0 で撤廃: 組み込み関数 float() を使ってください。

文字列を浮動小数点型の数値に変換します。文字列は Python における標準的なの浮動小数点リテラルの文法に従っていなければなりません。先頭に符号 (+ または -)が付くのは構いません。この関数に文字列を渡した場合は、組み込み関数 float() と同じように振舞います。

ノート

文字列を渡した場合、根底にある C ライブラリによって NaN や Infinity を返す場合があります。こうした値を返させるのがどんな文字列の集合であるかは、全て C ライブラリに依存しており、ライブラリによって異なると知られています。

string.atoi(s[, base])

バージョン 2.0 で撤廃: 組み込み関数 int() を使ってください。

文字列 s を、 base を基数とする整数に変換します。文字列は 1 桁またはそれ以上の数字からなっていなければなりません。先頭に符号 (+ または -) が付くのは構いません。 base のデフォルト値は 10 です。 base が 0 の場合、 (符号を剥ぎ取った後の) 文字列の先頭にある文字列に従ってデフォルトの基数を決定します。 0x か 0X なら 16 、 0 なら 8 、その他の場合は 10 が基数になります。 base が 16 の場合、先頭の 0x や 0X が付いていても受け付けますが、必須ではありません。文字列を渡す場合、この関数は組み込み関数 int() と同じように振舞います。 (数値リテラルをより柔軟に解釈したい場合には、組み込み関数 eval() を使ってください。)

string.atol(s[, base])

バージョン 2.0 で撤廃: 組み込み関数 long() を使ってください。

文字列 s を、 base を基数とする長整数に変換します。文字列は 1 桁またはそれ以上の数字からなっていなければなりません。先頭に符号 (+ または -) が付くのは構いません。 base は atoi() と同じ意味です。基数が 0 の場合を除き、文字列末尾に l や L を付けてはなりません。 base を指定しないか、 10 を指定して文字列を渡した場合には、この関数は組み込み関数 long() と同じように振舞います。

string.capitalize(word)

先頭文字だけ大文字にした word のコピーを返します。

string.expandtabs(s[, tabsize])

現在のカラムと指定タブ幅に従って文字列中のタブを展開し、一つまたはそれ以上のスペースに置き換えます。文字列中に改行が出現するたびにカラム番号は 0 にリセットされます。この関数は、他の非表示文字やエスケープシーケンスを解釈しません。タブ幅のデフォルトは 8 です。

string.find(s, sub[, start[, end]])

s[start:end] の中で、部分文字列 sub が完全な形で入っている場所のうち、最初のものを s のインデクスで返します。見つからなかった場合は -1 を返します。 start と end のデフォルト値、および、負の値を指定した場合の解釈は文字列のスライスと同じです。

string.rfind(s, sub[, start[, end]])

find() と同じですが、最後に見つかったもののインデックスを返します。

string.index(s, sub[, start[, end]])

find() と同じですが、部分文字列が見つからなかったときに ValueError を送出します。

string.rindex(s, sub[, start[, end]])

rfind() と同じですが、部分文字列が見つからなかったときに ValueError 送出します。

string.count(s, sub[, start[, end]])

s[start:end] における、部分文字列 sub の (重複しない) 出現回数を返します。 start と end のデフォルト値、および、負の値を指定した場合の解釈は文字列のスライスと同じです。

string.lower(s)

s のコピーを大文字を小文字に変換して返します。

string.split(s[, sep[, maxsplit]])

文字列 s 内の単語からなるリストを返します。オプションの第二引数 sep を指定しないか、または None にした場合、空白文字 (スペース、タブ、改行、リターン、改頁) からなる任意の文字列で単語に区切ります。 sep を None 以外の値に指定した場合、単語の分割に使う文字列の指定になります。戻り値のリストには、文字列中に分割文字列が重複せずに出現する回数より一つ多い要素が入るはずです。オプションの第三引数 maxsplit はデフォルトで 0 です。この値がゼロでない場合、最大でも maxsplit 回の分割しか行わず、リストの最後の要素は未分割の残りの文字列になります (従って、リスト中の要素数は最大でも maxsplit+1 です)。

空文字列に対する分割を行った場合の挙動は sep の値に依存します。 sep を指定しないか None にした場合、結果は空のリストになります。 sep に文字列を指定した場合、空文字列一つの入ったリストになります。

string.rsplit(s[, sep[, maxsplit]])

s 中の単語からなるリストを s の末尾から検索して生成し返します。関数の返す語のリストは全ての点で split() の返すものと同じになります。ただし、オプションの第三引数 maxsplit をゼロでない値に指定した場合には必ずしも同じにはなりません。 maxsplit がゼロでない場合には、最大で maxsplit 個の分割を 右端から 行います - 未分割の残りの文字列はリストの最初の要素として返されます (従って、リスト中の要素数は最大でも maxsplit+1 です)。

バージョン 2.4 で追加.

string.splitfields(s[, sep[, maxsplit]])

この関数は split() と同じように振舞います。 (以前は split() は単一引数の場合にのみ使い、 splitfields() は引数 2 つの場合でのみ使っていました)。

string.join(words[, sep])

単語のリストやタプルを間に sep を入れて連結します。 sep のデフォルト値はスペース文字 1 つです。 string.join(string.split(s, sep), sep) は常に s になります。

string.joinfields(words[, sep])

この関数は join() と同じふるまいをします (以前は、 join() を使えるのは引数が 1 つの場合だけで、 joinfields() は引数 2 つの場合だけでした)。文字列オブジェクトには joinfields() メソッドがないので注意してください。代わりに join() メソッドを使ってください。

string.lstrip(s[, chars])

文字列の先頭から文字を取り除いたコピーを生成して返します。 chars を指定しない場合や None にした場合、先頭の空白を取り除きます。 chars を None 以外の値にする場合、 chars は文字列でなければなりません。

バージョン 2.2.3 で変更: chars パラメタを追加しました。初期の 2.2 バージョンでは、 chars パラメータを渡せませんでした。

string.rstrip(s[, chars])

文字列の末尾から文字を取り除いたコピーを生成して返します。 chars を指定しない場合や None にした場合、末尾の空白を取り除きます。 chars を None 以外の値にする場合、 chars は文字列でなければなりません。

バージョン 2.2.3 で変更: chars パラメタを追加しました。初期の 2.2 バージョンでは、 chars パラメータを渡せませんでした。

string.strip(s[, chars])

文字列の先頭と末尾から文字を取り除いたコピーを生成して返します。 chars を指定しない場合や None にした場合、先頭と末尾の空白を取り除きます。 chars を None 以外に指定する場合、 chars は文字列でなければなりません。

バージョン 2.2.3 で変更: chars パラメタを追加しました。初期の 2.2 バージョンでは、 chars パラメータを渡せませんでした。

string.swapcase(s)

s の大文字と小文字を入れ替えたものを返します。

string.translate(s, table[, deletechars])

s の中から、 (もし指定されていれば) deletechars に入っている文字を削除し、 table を使って文字変換を行って返します。 table は 256 文字からなる文字列で、各文字はそのインデクスを序数とする文字に対する変換先の文字の指定になります。もし、 table が None であれば、文字削除のみが行われます。

string.upper(s)

s に含まれる小文字を大文字に置換して返します。

string.ljust(s, width[, fillchar])

string.rjust(s, width[, fillchar])

string.center(s, width[, fillchar])

文字列を指定した文字幅のフィールド中でそれぞれ左寄せ、右寄せ、中央寄せします。これらの関数は指定幅になるまで文字列 s の左側、右側、および、両側のいずれかに fillchar （デフォルトでは空白）を追加して、少なくとも width 文字からなる文字列にして返します。文字列を切り詰めることはありません。

string.zfill(s, width)

数値を表現する文字列の左側に、指定の幅になるまでゼロを付加します。符号付きの数字も正しく処理します。

string.replace(str, old, new[, maxreplace])

s 内の部分文字列 old を全て new に置換したものを返します。 maxreplace を指定した場合、最初に見つかった maxreplace 個分だけ置換します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.2. re — 正規表現操作

このモジュールでは、 Perl で見られるものと同様な正規表現マッチング操作を提供しています。パターンと検索対象文字列の両方について、 8 ビット文字列と Unicode 文字列を同じように扱えます。

正規表現では、特殊な形式を表したり、特殊文字の持つ特別な意味を呼び出さずにその特殊な文字を使えるようにするために、バックスラッシュ文字 ('\') を使います。こうしたバックスラッシュの使い方は、 Python の文字列リテラルにおける同じバックスラッシュ文字と衝突を起こします。例えば、バックスラッシュ自体にマッチさせるには、パターン文字列として '\\\\' と書かなければなりません、というのも、正規表現は \\ でなければならず、さらに正規な Python 文字列リテラルでは各々のバックスラッシュを \\ と表現せねばならないからです。

正規表現パターンに Python の raw string 記法を使えばこの問題を解決できます。 'r' を前置した文字列リテラル内ではバックスラッシュを特別扱いしません。従って、 "\n" が改行一文字の入った文字列になるのに対して、 r"\n" は '\' と 'n' という二つの文字の入った文字列になります。通常、 Python コード中では、パターンをこの raw string 記法を使って表現します。

大抵の正規表現操作がモジュールレベルの関数と、 RegexObject のメソッドとして提供されることに注意して下さい。関数は正規表現オブジェクトのコンパイルを必要としない近道ですが、いくつかのチューニング変数を失います。

参考

Mastering Regular Expressions 詳説正規表現

Jeffrey Friedl 著、O’Reilly 刊の正規表現に関する本です。この本の第2版ではPyhonについては触れていませんが、良い正規表現パターンの書き方を非常にくわしく説明しています。

7.2.1. 正規表現のシンタクス

正規表現 (すなわち RE) は、表現にマッチ (match) する文字列の集合を表しています。このモジュールの関数を使えば、ある文字列が指定の正規表現にマッチするか (または指定の正規表現がある文字列にマッチするか、つまりは同じことですが) を検査できます。

正規表現を連結すると新しい正規表現を作れます。 A と B がともに正規表現であれば AB も正規表現です。一般的に、文字列 p が A　とマッチし、別の文字列 q が B とマッチすれば、文字列 pq は AB にマッチします。ただし、この状況が成り立つのは、 A と B との間に境界条件がある場合や、番号付けされたグループ参照のような、優先度の低い演算を A や B が含まない場合だけです。かくして、ここで述べるような、より簡単でプリミティブな正規表現から、複雑な正規表現を容易に構築できます。正規表現に関する理論と実装の詳細については上記の Friedl 本か、コンパイラの構築に関する教科書を調べて下さい。

以下で正規表現の形式に関する簡単な説明をしておきます。より詳細な情報やよりやさしい説明に関しては、 正規表現 HOWTO を参照下さい。

正規表現には、特殊文字と通常文字の両方を含められます。 'A' 、 'a' 、あるいは '0' のようなほとんどの通常文字は最も簡単な正規表現になります。こうした文字は、単純にその文字自体にマッチします。通常の文字は連結できるので、 last は文字列 'last' とマッチします。 (この節の以降の説明では、正規表現を引用符を使わずに この表示スタイル: special style で書き、マッチ対象の文字列は、 '引用符で括って' 書きます。)

'|' や '(' といったいくつかの文字は特殊文字です。特殊文字は通常の文字の種別を表したり、あるいは特殊文字の周辺にある通常の文字に対する解釈方法に影響します。正規表現パターン文字列には、 null byte を含めることができませんが、 \number 記法や、 '\x00' などとして指定することができます。

特殊文字を以下に示します:

'.'

(ドット) デフォルトのモードでは改行以外の任意の文字にマッチします。 DOTALL フラグが指定されていれば改行も含むすべての文字にマッチします。

'^'

(キャレット) 文字列の先頭とマッチします。 MULTILINE モードでは各改行の直後にマッチします。

'$'

文字列の末尾、あるいは文字列の末尾の改行の直前にマッチします。例えば、 foo は ‘foo’ と ‘foobar’ の両方にマッチします。一方、正規表現 foo$ は ‘foo’ だけとマッチします。興味深いことに、 'foo1\nfoo2\n' を foo.$ で検索した場合、通常のモードでは ‘foo2’ だけにマッチし、 MULTILINE モードでは ‘foo1’ にもマッチします。 $ だけで 'foo\n' を検索した場合、2箇所 (内容は空) でマッチします: 1つは、改行の直前で、もう1つは、文字列の最後です。

'*'

直前にある RE に作用して、 RE を 0 回以上できるだけ多く繰り返したものにマッチさせるようにします。例えば ab* は ‘a’、’ab’、あるいは ‘a’ に任意個数の’b’ を続けたものにマッチします。

'+'

直前にある RE に作用して、 RE を、1 回以上繰り返したものにマッチさせるようにします。例えば ab+ は ‘a’ に一つ以上の ‘b’ が続いたものにマッチし、 ‘a’ 単体にはマッチしません。

'?'

直前にある RE に作用して、 RE を 0 回か 1 回繰り返したものにマッチさせるようにします。例えば ab? は ‘a’ あるいは ‘ab’ にマッチします。

*?, +?, ??

'*' 、 '+' 、 '?' といった修飾子は、すべて 貪欲 (greedy) マッチ、すなわちできるだけ多くのテキストにマッチするようになっています。時にはこの動作が望ましくない場合もあります。例えば正規表現 <.*> を '<H1>title</H1>' にマッチさせると、 '<H1>' だけにマッチするのではなく全文字列にマッチしてしまいます。 '?' を修飾子の後に追加すると、 非貪欲 (non-greedy) あるいは最小一致 (minimal) のマッチになり、できるだけ 少ない 文字数のマッチになります。例えば上の式で .*? を使うと '<H1>' だけにマッチします。

{m}

前にある RE の m 回の正確なコピーとマッチすべきであることを指定します；マッチ回数が少なければ、RE 全体ではマッチしません。例えば、 a{6} は、正確に 6個の 'a' 文字とマッチしますが、 5個ではマッチしません。

{m,n}

結果の RE は、前にある RE を、 m 回から n 回まで繰り返したもので、できるだけ多く繰り返したものとマッチするように、マッチします。例えば、 a{3,5} は、3個から 5個の 'a' 文字とマッチします。 m を省略するとマッチ回数の下限として0を指定した事になり、 n を省略することは、上限が無限であることを指定します； a{4,}b は aaaab や、千個の 'a' 文字に b が続いたものとマッチしますが、 aaab とはマッチしません。コンマは省略できません、そうでないと修飾子が上で述べた形式と混同されてしまうからです。

{m,n}?

結果の RE は、前にある RE の m 回から n 回まで繰り返したもので、できるだけ 少なく繰り返したものとマッチするように、マッチします。これは、前の修飾子の控え目バージョンです。例えば、 6文字文字列 'aaaaaa' では、 a{3,5} は、5個の 'a' 文字とマッチしますが、 a{3,5}? は3個の文字とマッチするだけです。

'\'

特殊文字をエスケープする( '*' や '?' 等のような文字とのマッチをできるようにする) か、あるいは、特殊シーケンスの合図です; 特殊シーケンスは後で議論します。

もしパターンを表現するのに raw string を使用していないのであれば、 Python も、バックスラッシュを文字列リテラルでのエスケープシーケンスとして使っていることを覚えていて下さい；もしエスケープシーケンスを Python の構文解析器が認識して処理しなければ、そのバックスラッシュとそれに続く文字は、結果の文字列にそのまま含まれます。しかし、もし Python が結果のシーケンスを認識するのであれば、バックスラッシュを 2回繰り返さなければいけません。このことは複雑で理解しにくいので、最も簡単な表現以外は、すべて raw string を使うことをぜひ勧めます。

[]

文字の集合を指定するのに使用します。文字は個々にリストするか、文字の範囲を、2つの文字と '-' でそれらを分離して指定することができます。特殊文字は集合内では有効ではありません。例えば、 [akm$] は、文字 'a' 、 'k' 、 'm' 、あるいは '$' のどれかとマッチします； [a-z] は、任意の小文字と、 [a-zA-Z0-9] は、任意の文字や数字とマッチします。 (以下で定義する) \w や \S のような文字クラスも、範囲に含めることができます。しかしながら、それら文字クラスのマッチは有効になっている LOCALE 、もしくは、 UNICODE のモードに依存します。もし文字集合に ']' や '-' を含めたいのなら、その前にバックスラッシュを付けるか、それを最初の文字として指定します。たとえば、パターン []] は ']' とマッチします。

範囲内にない文字とは、その集合の 補集合をとること でマッチすることができます。これは、集合の最初の文字として '^' を含めることで表すことができます；他の場所にある '^' は、単純に '^' 文字とマッチするだけです。例えば、 [^5] は、 '5' 以外の任意の文字とマッチし、 [^^] は、 '^' 以外の任意の文字とマッチします。

[] の中では、特殊な形式や特殊文字が、その意味を失い、ここに記述された書式だけが有効であることに注意して下さい。例えば、 +, *, (, ), などは [] の中では文字通りに扱われ、後方参照は [] の中では使用できません。

'|'

A|B は、ここで A と B は任意の RE ですが、 A か B のどちらかとマッチする正規表現を作成します。任意個数の RE を、こういう風に '|' で分離することができます。これはグループ (以下参照) 内部でも同様に使えます。検査対象文字列をスキャンする中で、 '|' で分離された RE は左から右への順に検査されます。一つでも完全にマッチしたパターンがあれば、そのパターン枝が受理されます。このことは、もし A がマッチすれば、たとえ B によるマッチが全体としてより長いマッチになったとしても、 B を決して検査しないことを意味します。言いかえると、 '|' 演算子は決して貪欲 (greedy) ではありません。文字通りの '|' とマッチするには、 \| を使うか、あるいはそれを [|] のように文字クラス内に入れます。

(...)

丸括弧の中にどのような正規表現があってもマッチし、またグループの先頭と末尾を表します；グループの中身は、マッチが実行された後に検索され、後述する \number 特殊シーケンス付きの文字列内で、後でマッチされます。文字通りの '(' や ')' とマッチするには、 \( あるいは \) を使うか、それらを文字クラス内に入れます： [(] [)] 。

(?...)

これは拡張記法です ('(' に続く '?' は他には意味がありません) 。 '?' の後の最初の文字が、この構造の意味とこれ以上のシンタクスがどういうものであるかを決定します。拡張記法は普通新しいグループを作成しません； (?P<name>...) がこの規則の唯一の例外です。以下に現在サポートされている拡張記法を示します。

(?iLmsux)

( 集合 'i', 'L', 'm', 's', 'u', 'x' から1文字以上) 。グループは空文字列ともマッチします；文字は、正規表現全体の対応するフラグ (re.I (大文字・小文字を区別しない), re.L (ロケール依存), re.M (MULTILINEモード), re.S (DOTALLモード), re.U (Unicode依存), re.X (冗長) ) を設定します。 (フラグについては、 モジュールコンテンツ に記述があります) これは、もし flag 引数を re.compile() 関数に渡さずに、そのフラグを正規表現の一部として含めたいならば役に立ちます。

(?x) フラグは、式が構文解析される方法を変更することに注意して下さい。これは式文字列内の最初か、あるいは1つ以上の空白文字の後で使うべきです。もしこのフラグの前に非空白文字があると、その結果は未定義です。

(?:...)

正規表現の丸括弧の取り込まないバージョンです。どのような正規表現が丸括弧内にあってもマッチしますが、グループによってマッチされたサブ文字列は、マッチを実行したあと検索されることも、あるいは後でパターンで参照されることも できません 。

(?P<name>...)

正規表現の丸括弧と同様ですが、グループによってマッチされたサブ文字列は、正規表現の残りの部分から name という記号グループ名を利用してアクセスできます。グループ名は、正しい Python 識別子でなければならず、各グループ名は、正規表現内で一度だけ定義されなければなりません。記号グループは、グループに名前が付けられていない場合のように、番号付けされたグループでもあります。そこで下の例で id という名前がついたグループは、番号グループ 1 として参照することもできます。

たとえば、もしパターンが (?P<id>[a-zA-Z_]\w*) であれば、このグループは、マッチオブジェクトのメソッドへの引数に、 m.group('id') あるいは m.end('id') のような名前で、また同じ正規表現内 (例えば、 (?P=id)) や置換テキスト内 (\g<id> のように) で名前で参照することができます。

(?P=name)

前に name と名前付けされたグループにマッチした、いかなるテキストにもマッチします。

(?#...)

コメントです；括弧の内容は単純に無視されます。

(?=...)

もし ... が次に続くものとマッチすればマッチしますが、文字列をまったく消費しません。これは先読みアサーション (lookahead assertion) と呼ばれます。例えば、 Isaac (?=Asimov) は、 'Isaac ' に 'Asimov' が続く場合だけ、 'Isaac ' とマッチします。

(?!...)

もし ... が次に続くものとマッチしなければマッチします。これは否定先読みアサーション (negative lookahead assertion) です。例えば、 Isaac (?!Asimov) は、 'Isaac ' に 'Asimov' が続か ない 場合のみマッチします。

(?<=...)

もし文字列内の現在位置の前に、現在位置で終わる ... とのマッチがあれば、マッチします。これは 肯定後読みアサーション (positive lookbehind assertion) と呼ばれます。 (?<=abc)def は、 abcdef にマッチを見つけます、というのは後読みが3文字をバックアップして、含まれているパターンとマッチするかどうか検査するからです。含まれるパターンは、固定長の文字列にのみマッチしなければなりません、ということは、 abc や a|b は許されますが、 a* や a{3,4} は許されないことを意味します。肯定後読みアサーションで始まるパターンは、検索される文字列の先頭とは決してマッチしないことに注意して下さい；多分、 match() 関数よりは search() 関数を使いたいでしょう:

>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

この例ではハイフンに続く単語を探します:

>>> m = re.search('(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'

(?<!...)

もし文字列内の現在位置の前に ... とのマッチがないならば、マッチします。これは 否定後読みアサーション(negative lookbehind assertion) と呼ばれます。肯定後読みアサーションと同様に、含まれるパターンは固定長さの文字列だけにマッチしなければいけません。否定後読みアサーションで始まるパターンは、検索される文字列の先頭とマッチすることができます。

(?(id/name)yes-pattern|no-pattern)

グループに id が与えられている、もしくは name があるとき、 yes-pattern とマッチします。存在しないときには no-pattern とマッチします。 no-pattern はオプションで省略できます。例えば (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) はemailアドレスとマッチする最低限のパターンです。これは '<user@host.com>' や 'user@host.com' にはマッチしますが、 '<user@host.com' にはマッチしません。

バージョン 2.4 で追加.

特殊シーケンスは '\' と以下のリストにある文字から構成されます。もしリストにあるのが通常文字でないならば、結果の RE は2番目の文字とマッチします。例えば、 \$ は文字 '$' とマッチします。

\number

同じ番号のグループの中身とマッチします。グループは1から始まる番号をつけられます。例えば、 (.+) \1 は、 'the the' あるいは '55 55' とマッチしますが、 'the end' とはマッチしません(グループの後のスペースに注意して下さい)。この特殊シーケンスは最初の 99 グループのうちの一つとマッチするのに使うことができるだけです。もし number の最初の桁が 0 である、すなわち number が 3 桁の8進数であれば、それはグループのマッチとは解釈されず、 8進数値 number を持つ文字として解釈されます。文字クラスの '[' と ']' の中の数値エスケープは、文字として扱われます。

\A

文字列の先頭だけにマッチします。

\b

空文字列とマッチしますが、単語の先頭か末尾の時だけです。単語は英数字あるいは下線文字の並んだものとして定義されていますので、単語の末尾は空白あるいは非英数字、非下線文字によって表されます。 \b は、 \w と \W の間の境界として定義されているので、英数字であると見なされる文字の正確な集合は、 UNICODE と LOCALE フラグの値に依存することに注意して下さい。文字の範囲の中では、 \b は、 Python の文字列リテラルと互換性を持たせるために、後退 (backspace)文字を表します。

\B

空文字列とマッチしますが、それが単語の先頭あるいは末尾に ない 時だけです。これは \b のちょうど反対ですので、同じように LOCALE と UNICODE の設定に影響されます。

\d

UNICODE フラグが指定されていない場合、任意の十進数とマッチします；これは集合 [0-9] と同じ意味です。 UNICODE がある場合、Unicode 文字特性データベースで十進数字と分類されているものにマッチします。

\D

UNICODE フラグが指定されていない場合、任意の非数字文字とマッチします；これは集合 [^0-9] と同じ意味です。 UNICODE がある場合、これは Unicode 文字特性データベースで数字とマーク付けされている文字以外にマッチします。

\s

LOCALE と UNICODE フラグが指定されていない場合、任意の空白文字とマッチします；これは集合 [\t\n\r\f\v] と同じ意味です。

LOCALE がある場合、これはこの集合に加えて現在のロケールで空白と定義されている全てにマッチします。 UNICODE が設定されると、これは [ \t\n\r\f\v] と Unicode 文字特性データベースで空白と分類されている全てにマッチします。

\S

LOCALE と UNICODE がフラグが指定されていない場合、任意の非空白文字とマッチします；これは集合 [^\t\n\r\f\v] と同じ意味です。 LOCALE がある場合、これはこの集合に無い文字と、現在のロケールで空白と定義されていない文字にマッチします。 UNICODE が設定されていると、 [ \t\n\r\f\v] でない文字と、 Unicode 文字特性データベースで空白とマーク付けされていないものにマッチします。

\w

LOCALE と UNICODE フラグが指定されていない時は、任意の英数文字および下線とマッチします；これは、集合 [a-zA-Z0-9_] と同じ意味です。 LOCALE が設定されていると、集合 [0-9_] プラス現在のロケール用に英数字として定義されている任意の文字とマッチします。もし UNICODE が設定されていれば、文字 [0-9_] プラス Unicode 文字特性データベースで英数字として分類されているものとマッチします。

\W

LOCALE と UNICODE フラグが指定されていない時、任意の非英数文字とマッチします；これは集合 [^a-zA-Z0-9_] と同じ意味です。 LOCALE が指定されていると、集合 [0-9_] になく、現在のロケールで英数字として定義されていない任意の文字とマッチします。もし UNICODE がセットされていれば、これは [0-9_] および Unicode 文字特性データベースで英数字として表されている文字以外のものとマッチします。

\Z

文字列の末尾とのみマッチします。

Python 文字列リテラルによってサポートされている標準エスケープのほとんども、正規表現パーザに認識されます:

\a      \b      \f      \n
\r      \t      \v      \x
\\

8進エスケープは制限された形式で含まれています：もし第1桁が 0 であるか、もし8進3桁であれば、それは 8進エスケープとみなされます。そうでなければ、それはグループ参照です。文字列リテラルについて、 8進エスケープはほとんどの場合3桁長になります。

7.2.2. マッチング vs 検索

Python は、正規表現に基づく、2つの異なるプリミティブな操作を提供しています。 search が文字列のすべての場所で、一致するかを確認する (これは Perl のデフォルト動作です) のに対し、 match は、文字列の先頭で一致するかを確認します。

マッチは、 '^' で始まる正規表現を使ったとしても、検索と異なる動作になるかもしれないことに注意して下さい： '^' は文字列の先頭、もしくは、 MULTILINE モードでは改行の直後ともマッチします。 “マッチ” 操作は、もしそのパターンが、モードに拘らず文字列の先頭とマッチするか、あるいは改行がその前にあるかどうかに拘らず、省略可能な pos 引数によって与えられる先頭位置でマッチする場合のみ成功します。

>>> re.match("c", "abcdef")  # マッチしない
>>> re.search("c", "abcdef") # マッチする
<_sre.SRE_Match object at ...>

7.2.3. モジュールコンテンツ

このモジュールは幾つかの関数、定数、例外を定義します。この関数のいくつかはコンパイル済み正規表現向けの完全版のメソッドを簡略化したバージョンです。それなりのアプリケーションのほとんどで、コンパイルされた形式が用いられるのが普通です。

re.compile(pattern[, flags])

正規表現パターンを正規表現オブジェクトにコンパイルします。このオブジェクトは、以下で述べる match() と search() メソッドを使って、マッチングに使うことができます。

式の動作は、 flags の値を指定することで加減することができます。値は以下の変数を、ビットごとの OR ( | 演算子)を使って組み合わせることができます。

シーケンス

prog = re.compile(pattern)
result = prog.match(string)

は、

result = re.match(pattern, string)

と同じ意味ですが、 re.compile() を使ってその結果の正規表現オブジェクトを再利用した方が、その式を一つのプログラムで何回も使う時にはより効率的です。

ノート

最後に re.match(), re.search(), re.compile() に渡されたパターンのコンパイルされたものがキャッシュとして残ります。そのため、正規表現をひとつだけしか使わないプログラムは正規表現のコンパイルを気にする必要はありません。

re.I

re.IGNORECASE

大文字・小文字を区別しないマッチングを実行します； [A-Z] のような式は、小文字にもマッチします。これは現在のロケールには影響されません。

re.L

re.LOCALE

\w 、 \W 、 \b および、 \B 、 \s と \S を、現在のロケールに従わさせます。

re.M

re.MULTILINE

指定されると、パターン文字 '^' は、文字列の先頭および各行の先頭(各改行の直後)とマッチします；そしてパターン文字 '$' は文字列の末尾および各行の末尾 (改行の直前) とマッチします。デフォルトでは、 '^' は、文字列の先頭とだけマッチし、 '$' は、文字列の末尾および文字列の末尾の改行の直前(がもしあれば)とマッチします。

re.S

re.DOTALL

特殊文字 '.' を、改行を含む任意の文字と、とにかくマッチさせます；このフラグがなければ、 '.' は、改行 以外の 任意の文字とマッチします。

re.U

re.UNICODE

\w 、 \W 、 \b 、 \B 、 \d 、 \D 、 \s と \S を、 Unicode 文字特性データベースに従わさせます。

バージョン 2.0 で追加.

re.X

re.VERBOSE

このフラグによって、より見やすく正規表現を書くことができます。パターン内の空白は、文字クラス内にあるかエスケープされていないバックスラッシュが前にある時以外は無視されます。また、行に、文字クラス内にもなく、エスケープされていないバックスラッシュが前にもない '#' がある時は、そのような '#' の左端からその行の末尾までが無視されます。

つまり、数字にマッチする下記のふたつの正規表現オブジェクトは、機能的に等価です。:

a = re.compile(r"""\d +  # 整数部
                   \.    # 小数点
                   \d *  # 小数点以下""", re.X)
b = re.compile(r"\d+\.\d*")

re.search(pattern, string[, flags])

string 全体を走査して、正規表現 pattern がマッチを発生する位置を探して、対応する MatchObject インスタンスを返します。もし文字列内に、そのパターンとマッチする位置がないならば、 None を返します；これは、文字列内のある点で長さゼロのマッチを探すこととは異なることに注意して下さい。

re.match(pattern, string[, flags])

もし string の先頭で 0 個以上の文字が正規表現 pattern とマッチすれば、対応する MatchObject インスタンスを返します。もし文字列がパターンとマッチしなければ、 None を返します；これは長さゼロのマッチとは異なることに注意して下さい。

ノート

もし string のどこかにマッチを位置付けたいのであれば、代わりに search() を使って下さい。

re.split(pattern, string[, maxsplit=0, flags=0])

string を、 pattern があるたびに分割します。もし括弧のキャプチャが pattern で使われていれば、パターン内のすべてのグループのテキストも結果のリストの一部として返されます。 maxsplit がゼロでなければ、高々 maxsplit 個の分割が発生し、文字列の残りは、リストの最終要素として返されます。 (非互換性ノート：オリジナルの Python 1.5 リリースでは、 maxsplit は無視されていました。これはその後のリリースでは修正されました。)

>>> re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

もし、捕捉するグループが分割パターンに含まれ、それが文字列の先頭にあるならば、分割結果は、空文字列から始まります。文字列最後においても同様です。

>>> re.split('(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

その場合、常に、分割要素が、分割結果のリストの相対的なインデックスに現れます。 (例えば、分割子の中に捕捉するグループが一つだけあれば、0番目、2番目、そして、4番目です)

split は空のパターンマッチでは、文字列を分割しないことに注意して下さい。例えば:

>>> re.split('x*', 'foo')
['foo']
>>> re.split("(?m)^$", "foo\n\nbar\n")
['foo\n\nbar\n']

バージョン 2.7 で変更: オプションの flags 引数が追加されました。

re.findall(pattern, string[, flags])

pattern の string へのマッチのうち、重複しない全てのマッチを文字列のリストとして返します。 string は左から右へと走査され、マッチは見つかった順番で返されます。パターン中に何らかのグループがある場合、グループのリストを返します。グループが複数定義されていた場合、タプルのリストになります。他のマッチの開始部分に接触しないかぎり、空のマッチも結果に含められます。

バージョン 1.5.2 で追加.

バージョン 2.4 で変更: オプションの flags 引数を追加しました.

re.finditer(pattern, string[, flags])

string 内の RE pattern の重複しないマッチを MatchObject インスタンスを返す iterator を返します。 string は左から右へと走査され、マッチは見つかった順番で返されます。他のマッチの開始部分に接触しないかぎり、空のマッチも結果に含められます。

バージョン 2.2 で追加.

バージョン 2.4 で変更: Added the optional flags argument.

re.sub(pattern, repl, string[, count, flags])

string 内で、 pattern と重複しないマッチの内、一番左にあるものを置換 repl で置換して得られた文字列を返します。もしパターンが見つからなければ、 string を変更せずに返します。 repl は文字列でも関数でも構いません；もしそれが文字列であれば、それにある任意のバックスラッシュエスケープは処理されます。すなわち、 \n は単一の改行文字に変換され、 \r は、行送りコードに変換されます、等々。 \j のような未知のエスケープはそのままにされます。 \6 のような後方参照(backreference)は、パターンのグループ 6 とマッチしたサブ文字列で置換されます。例えば:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s* \(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

もし repl が関数であれば、重複しない pattern が発生するたびにその関数が呼ばれます。この関数は一つのマッチオブジェクト引数を取り、置換文字列を返します。例えば:

>>> def dashrepl(matchobj):
...     if matchobj.group(0) == '-': return ' '
...     else: return '-'
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'

パターンは、文字列でも RE オブジェクトでも構いません。

省略可能な引数 count は、置換されるパターンの出現回数の最大値です； count は非負の整数でなければなりません。もし省略されるかゼロであれば、出現したものがすべて置換されます。パターンのマッチが空であれば、以前のマッチと隣合わせでない時だけ置換されますので、 sub('x*', '-', 'abc') は '-a-b-c-' を返します。

上で述べた文字エスケープや後方参照の他に、 \g<name> は、 (?P<name>...) のシンタクスで定義されているように、 name という名前のグループとマッチしたサブ文字列を使います。 \g<number> は対応するグループ番号を使います；それゆえ \g<2> は \2 と同じ意味ですが、 \g<2>0 のような置換でもあいまいではありません。 \20 は、グループ 20 への参照として解釈されますが、グループ 2 にリテラル文字 '0' が続いたものへの参照としては解釈されません。後方参照 \g<0> は、 RE とマッチするサブ文字列全体を置き換えます。

バージョン 2.7 で変更: オプションの flags 引数が追加されました。

re.subn(pattern, repl, string[, count, flags])

sub() と同じ操作を行いますが、タプル (new_string、 number_of_subs_made) を返します。

バージョン 2.7 で変更: オプションの flags 引数が追加されました。

re.escape(string)

バックスラッシュにすべての非英数字をつけた string を返します；これはもし、その中に正規表現のメタ文字を持つかもしれない任意のリテラル文字列とマッチしたいとき、役に立ちます。

re.purge()

正規表現キャッシュをクリアします。

exception re.error

ここでの関数の一つに渡された文字列が、正しい正規表現ではない時 (例えば、その括弧が対になっていなかった)、あるいはコンパイルやマッチングの間になんらかのエラーが発生したとき、発生する例外です。たとえ文字列がパターンとマッチしなくても、決してエラーではありません。

7.2.4. 正規表現オブジェクト

class re.RegexObject

RegexObject クラスは以下のメソッドと属性をサポートします:

search(string[, pos[, endpos]])

string を走査して、この正規表現がマッチする場所を探し、対応する MatchObject インスタンスを返します。 string のどこにもマッチしない場合は None を返します。これは、 string 内のどこかで長さ0でマッチした場合と異なることに注意してください。

省略可能な、2つ目の引数 pos は、 string のどこから探し始めるかを指定する index で、デフォルトでは 0 です。これは、文字列をスライスしてから検索するのと、完全には同じではありません。パターン文字 '^' は本当の文字列の先頭と、改行の直後にマッチしますが、検索を開始する index がマッチするとは限りません。

省略可能な引数 endpos は string のどこまでを検索するかを制限します。これは string の長さが endpos 文字だった場合と同じように動作します。つまり、 pos から endpos - 1 の範囲の文字に対してパターンマッチします。 endpos が pos よりも小さい場合は、マッチは見つかりません。それ以外の場合は、 rx がコンパイルされた正規表現として、 rx.search(string, 0, 50) は rx.search(string[:50], 0) と同じです。

>>> pattern = re.compile("d")
>>> pattern.search("dog")     # Match at index 0
<_sre.SRE_Match object at ...>
>>> pattern.search("dog", 1)  # No match; search doesn't include the "d"

match(string[, pos[, endpos]])

もし string の 先頭の 0 個以上の文字がこの正規表現とマッチすれば、対応する MatchObject インスタンスを返します。もし文字列がパタンーとマッチしなければ、 None を返します。これは長さゼロのマッチとは異なることに注意して下さい。

省略可能な引数 pos と endpos 引数は、 search() メソッドと同じ意味を持ちます。

ノート

string のどこにでもマッチさせたければ、代わりに search() を使って下さい。

>>> pattern = re.compile("o")
>>> pattern.match("dog")      # "o" は文字列 "dog." の先頭にないため、マッチしません
>>> pattern.match("dog", 1)   # "o" が文字列 "dog" の2番目にあるので、マッチします
<_sre.SRE_Match object at ...>

split(string[, maxsplit= 0])

split() 関数と同様で、コンパイルしたパターンを使います。ただし、 match() と同じように、省略可能な pos, endpos 引数で検索範囲を指定することができます。

findall(string[, pos[, endpos]])

findall() 関数と同様で、コンパイルしたパターンを使います。ただし、 match() と同じように、省略可能な pos, endpos 引数で検索範囲を指定することができます。

finditer(string[, pos[, endpos]])

finditer() 関数と同様で、コンパイルしたパターンを使います。ただし、 match() と同じように、省略可能な pos, endpos 引数で検索範囲を指定することができます。

sub(repl, string[, count=0])

sub() 関数と同様で、コンパイルしたパターンを使います。

subn(repl, string[, count=0])

subn() 関数と同様で、コンパイルしたパターンを使います。

flags

RE オブジェクトがコンパイルされたとき使われた flags 引数です。もし flags が何も提供されなければ 0 です。

groups

パターンにあるキャプチャグループの数です。

groupindex

(?P<id>) で定義された任意の記号グループ名の、グループ番号への辞書マッピングです。もし記号グループがパターン内で何も使われていなければ、辞書は空です。

pattern

RE オブジェクトがそれからコンパイルされたパターン文字列です。

7.2.5. MatchObject オブジェクト

class re.MatchObject

MatchObject は、常に真偽値 True を持ちます。そのため、例えば match() がマッチしたかどうかを単純な if 文で確認することができます。 MatchObject は以下のメソッドと、属性を持ちます。

expand(template)

テンプレート文字列 template に、 sub() メソッドがするようなバックスラッシュ置換をして得られる文字列を返します。 \n のようなエスケープは適当な文字に変換され、数値の後方参照 (\1, \2) と名前付きの後方参照 (\g<1>, \g<name>) は、対応するグループの内容で置き換えられます。

group([group1, ...])

マッチした1個以上のサブグループを返します。もし引数で一つであれば、その結果は一つの文字列です。複数の引数があれば、その結果は、引数ごとに一項目を持つタプルです。引数がなければ、 group1 はデフォールトでゼロです(マッチしたものすべてが返されます)。もし groupN 引数がゼロであれば、対応する戻り値は、マッチする文字列全体です。もしそれが範囲 [1..99] 内であれば、それは、対応する丸括弧つきグループとマッチする文字列です。もしグループ番号が負であるか、あるいはパターンで定義されたグループの数より大きければ、 IndexError 例外が発生します。グループがマッチしなかったパターンの一部に含まれていれば、対応する結果は None です。グループが、複数回マッチしたパターンの一部に含まれていれば、最後のマッチが返されます。

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)       # マッチした全体
'Isaac Newton'
>>> m.group(1)       # ひとつめのパターン化されたサブグループ
'Isaac'
>>> m.group(2)       # ふたつめのパターン化されたサブグループ
'Newton'
>>> m.group(1, 2)    # 複数の引数を与えるとタプルが返る
('Isaac', 'Newton')

もし正規表現が (?P<name>...) シンタックスを使うならば、 groupN 引数は、それらのグループ名によってグループを識別する文字列であっても構いません。もし文字列引数がパターンのグループ名として使われていないものであれば、 IndexError 例外が発生します。

適度に複雑な例題:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcom Reynolds")
>>> m.group('first_name')
'Malcom'
>>> m.group('last_name')
'Reynolds'

名前の付けられたグループは、そのインデックスによっても参照できます。

>>> m.group(1)
'Malcom'
>>> m.group(2)
'Reynolds'

もし、グループが複数回マッチする場合、最後のマッチだけが利用可能となります。

>>> m = re.match(r"(..)+", "a1b2c3")  # 3回マッチする
>>> m.group(1)                        # 最後のマッチだけが返る
'c3'

groups([default])

マッチの、1からパターン内にある全グループ数までのすべてのサブグループを含むタプルを返します。 default 引数は、マッチに加わらなかったグループ用に使われ、デフォールトでは None です。 (非互換性ノート：オリジナルの Python 1.5 リリースでは、たとえタプルが一要素長であっても、その代わりに文字列を返していました。 (1.5.1 以降の)後のバージョンでは、そのような場合には、要素がひとつのタプルが返されます。)

例えば:

>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')

もし、整数部にのみ着目し、あとの部分をオプションとした場合、マッチの中に現れないグループがあるかも知れません。それらのグループは、 default 引数が与えられていない場合、デフォルトでは None になります。

>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups()      # ふたつめのグループはデフォルトでは None になる
('24', None)
>>> m.groups('0')   # この場合、ふたつめのグループのデフォルトは 0 になる
('24', '0')

groupdict([default])

マッチの、すべての 名前つきの サブグループを含む、サブグループ名でキー付けされた辞書を返します。 default 引数はマッチに加わらなかったグループに使われ、デフォールトでは None です。例えば、

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcom Reynolds")
>>> m.groupdict()
{'first_name': 'Malcom', 'last_name': 'Reynolds'}

start([group])

end([group])

group とマッチした部分文字列の先頭と末尾のインデックスを返します。 group は、デフォルトでは(マッチした部分文字列全体を意味する）ゼロです。 group が存在してもマッチに寄与しなかった場合は、 -1 を返します。マッチオブジェクト m および、マッチに寄与しなかったグループ g があって、グループ g とマッチしたサブ文字列 ( m.group(g) と同じ意味ですが ) は:

m.string[m.start(g):m.end(g)]

です。もし group が空文字列とマッチすれば、 m.start(group) が m.end(group) と等しくなることに注意して下さい。例えば、 m = re.search('b(c?)', 'cba') とすると、 m.start(0) は 1 で、 m.end(0) は 2 であり、 m.start(1) と m.end(1) はともに 2 であり、 m.start(2) は IndexError 例外を発生します。

例として、電子メールのアドレスから remove_this を取り除く場合を示します。

>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'

span([group])

MatchObject m について、大きさ2のタプル (m.start(group), m.end(group)) を返します。もし group がマッチに寄与しなかったら、これは (-1, -1) です。また group はデフォルトでゼロです。

pos

RegexObject の search() か match() に渡された pos の値です。これは RE エンジンがマッチを探し始める位置の文字列のインデックスです。

endpos

RegexObject の search() か match() に渡された endpos の値です。これは RE エンジンがそれ以上は進まない位置の文字列のインデックスです。

lastindex

最後にマッチした取り込みグループの整数インデックスです。もしどのグループも全くマッチしなければ None です。例えば、 (a)b, ((a)(b)) や ((ab)) といった表現が 'ab' に適用された場合、 lastindex == 1 となり、同じ文字列に (a)(b) が適用された場合には lastindex == 2 となるでしょう。

lastgroup

最後にマッチした取り込みグループの名前です。もしグループに名前がないか、あるいはどのグループも全くマッチしなければ None です。

re

この MatchObject インスタンスを match() あるいは search() メソッドで生成した正規表現オブジェクトです。

string

match() あるいは search() に渡された文字列です。

7.2.6. 例

7.2.6.1. ペアの確認

この例では、マッチオブジェクトの表示を少し美しくするために、下記の補助関数を使用します :

def displaymatch(match):
    if match is None:
        return None
    return '<Match: %r, groups=%r>' % (match.group(), match.groups())

あなたがポーカープログラムを書いているとします。プレイヤーの持ち札はそれぞれの文字が1枚のカードを意味する5文字の文字列によって表現されます。 “a” はエース、 “k” はキング、 “q” はクイーン、 “j” はジャック “0” は10、そして “1” から “9” はそれぞれの数字のカードを表します。

与えられた文字列が、持ち札として有効かを確認するために、下記のようにするかも知れません。 :

>>> valid = re.compile(r"[0-9akqj]{5}$")
>>> displaymatch(valid.match("ak05q"))  # Valid.
"<Match: 'ak05q', groups=()>"
>>> displaymatch(valid.match("ak05e"))  # Invalid.
>>> displaymatch(valid.match("ak0"))    # Invalid.
>>> displaymatch(valid.match("727ak"))  # Valid.
"<Match: '727ak', groups=()>"

最後の持ち札 "727ak" は、ペアを含んでいます。言い換えると同じ値のカードが2枚あります。これを正規表現にマッチさせるために、後方参照を使う場合もあります :

>>> pair = re.compile(r".*(.).* \1")
>>> displaymatch(pair.match("717ak"))     # 7 のペア
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak"))     # ペア無し
>>> displaymatch(pair.match("354aa"))     # エースのペア
"<Match: '354aa', groups=('a',)>"

どのカードのペアになっているかを調べるため、下記のように MatchObject の group() メソッドを使う場合があります。

>>> pair.match("717ak").group(1)
'7'

# re.match() が group() メソッドを持たない None を返すため、エラーとなる :
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    re.match(r".*(.).* \1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'

>>> pair.match("354aa").group(1)
'a'

7.2.6.2. scanf() をシミュレートする

Python には現在のところ、 scanf() に相当するものがありません。正規表現は、 scanf() のフォーマット文字列よりも、一般的により強力であり、また冗長でもあります。以下の表に、 scanf() のフォーマットトークンと正規表現の大体同等な対応付けを示します。

scanf() トークン | 正規表現
%c | .
%5c | .{5}
%d | [-+]?\d+
%e, %E, %f, %g | [-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?
%i | [-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)
%o | 0[0-7]*
%s | \S+
%u | \d+
%x, %X | 0[xX][\dA-Fa-f]+

/usr/sbin/sendmail - 0 errors, 4 warnings

のような文字列からファイル名と数値を抽出するには、

%s - %d errors, %d warnings

のように scanf() フォーマットを使うでしょう。それと同等な正規表現は

(\S+) - (\d+) errors, (\d+) warnings

7.2.6.3. 再帰を避ける

エンジンに大量の再帰を要求するような正規表現を作成すると、 maximum recursion limit exceeded (最大再帰制限を超過した) というメッセージを持つ RuntimeError 例外に出くわすかもしれません。たとえば、

>>> s = "Begin" + 1000 * 'a very long string' + 'end'
>>> re.match('Begin (\w| )*? end', s).end()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.5/re.py", line 132, in match
    return _compile(pattern, flags).match(string)
RuntimeError: maximum recursion limit exceeded

再帰を避けるように正規表現を組みなおせることはよくあります。

Python 2.3 からは、再帰を避けるために *? パターンの利用が特別扱いされるようになりました。したがって、上の正規表現は Begin[a-zA-Z0-9_ ]*?end に書き直すことで再帰を防ぐことができます。それ以上の恩恵として、そのような正規表現は、再帰的な同等のものよりもより速く動作します。

7.2.6.4. search() vs. match()

簡単に言えば、 match() は文字列の先頭でのみパターンにマッチしようとします。対して、 search() は文字列のどこででもパターンにマッチしようとします。例えば :

>>> re.match("o", "dog")  # "o" は文字列 "dog" の最初の文字ではないのでマッチしません
>>> re.search("o", "dog") # search() では、文字列のどこであってもマッチする
<_sre.SRE_Match object at ...>

ノート

以下は、 re.compile("pattern") により生成された正規表現オブジェクトにのみ当てはまります。 re.match(pattern, string) や re.search(pattern, string) などには当てはまりません。

match() は、検索開始インデックスを指定するための、オプショナルな2つめのパラメータをとります。

>>> pattern = re.compile("o")
>>> pattern.match("dog")      # "o" が "dog" の先頭にないのでマッチしない

# 検索開始インデックスのデフォルト値が 0 であるため上記と等価 :
>>> pattern.match("dog", 0)

# "o" が "dog" の2番目の文字なのでマッチする ( インデックス 0 が最初の文字である ) :
>>> pattern.match("dog", 1)
<_sre.SRE_Match object at ...>
>>> pattern.match("dog", 2)   # "o" は "dog" の3番目の文字ではないのでマッチしない

7.2.6.5. 電話帳の作成

split() は文字列を与えられたパターンで分割し、リストにして返します。下記の、電話帳作成の例のように、このメソッドはテキストデータを読みやすくしたり、 Python で編集したりしやすくする際に、非常に役に立ちます。

最初に、入力を示します。通常、これはファイルからの入力になるでしょう。ここでは、3重引用符の書式とします :

>>> input = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""

個々の記録は、1つ以上の改行で区切られています。まずは、文字列から空行を除き、記録ごとのリストに変換しましょう。

>>> entries = re.split("\n+", input)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']

そして、各記録を、名、姓、電話番号、そして、住所に分割してリストにします。分割のためのパターンに使っている空白文字が、住所には含まれるため、 split() の maxsplit 引数を使います。 :

>>> [re.split(":? ", entry, 3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

パターン、 :? は姓に続くコロンにマッチします。そのため、コロンは分割結果のリストには現れません。 maxsplit を 4 にすれば、ハウスナンバーと、ストリート名を分割することができます。 :

>>> [re.split(":? ", entry, 4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]

7.2.6.6. テキストの秘匿

sub() はパターンにマッチした部分を文字列や関数の返り値で置き換えます。この例では、”秘匿” する文字列に、関数と共に sub() を適用する例を示します。言い換えると、最初と最後の文字を除く、単語中の文字の位置をランダム化します。

>>> def repl(m):
...   inner_word = list(m.group(2))
...   random.shuffle(inner_word)
...   return m.group(1) + "".join(inner_word) + m.group(3)
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'

7.2.6.7. 全ての形容動詞を見つける

findall() はパターンにマッチする 全てに マッチします。 search() がそうであるように、最初のものだけに、ではありません。例えば、なにかの文章の全ての副詞を見つけたいとき、下記のように findall() を使います。 :

>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly", text)
['carefully', 'quickly']

7.2.6.8. 全ての形容動詞と、その位置を見つける

もし、パターンにマッチするものについて、マッチしたテキスト以上の情報を得たいと考えたとき、文字列ではなく MatchObject のインスタンスを返す finditer() が便利です。以下に例を示すように、なにかの文章の全ての副詞と、 その位置を 調べたいと考えたとき、下記のように finditer() を使います。 :

>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly", text):
...     print '%02d-%02d: %s' % (m.start(), m.end(), m.group(0))
07-16: carefully
40-47: quickly

7.2.6.9. Raw String記法

Raw string記法 (r"text") により、バックスラッシュ ('\') を個々にバックスラッシュでエスケープすることなしに、正規表現を正常な状態に保ちます。例えば、下記の2つのコードは機能的に等価です。 :

>>> re.match(r"\W(.)\1\W", " ff ")
<_sre.SRE_Match object at ...>
>>> re.match("\\W(.)\\1\\W", " ff ")
<_sre.SRE_Match object at ...>

文字通りのバックスラッシュにマッチさせたいなら、正規表現中ではエスケープする必要があります。 Raw string記法では、 r"\\" ということになります。 Raw string記法を用いない場合、 "\\\\" としなくてはなりません。下記のコードは機能的に等価です。 :

>>> re.match(r"\\", r"\\")
<_sre.SRE_Match object at ...>
>>> re.match("\\\\", r"\\")
<_sre.SRE_Match object at ...>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.3. struct — 文字列データをパックされたバイナリデータとして解釈する

このモジュールは、 Python の値と Python 上で文字列データとして表される C の構造体データとの間の変換を実現します。このモジュールは特に、ファイルに保存されたり、ネットワーク接続を経由したバイナリデータを扱うときに使われます。このモジュールでは、C 構造体のレイアウトおよび Python の値との間で行いたい変換をコンパクトに表現するために、フォーマット文字列 を使います。

ノート

デフォルトでは、与えられた C の構造体をパックする際に、関連する C データ型を適切にアラインメント(alignment)するために数バイトのパディングを行うことがあります。この挙動が選択されたのは、パックされた構造体のバイト表現を対応する C 構造体のメモリレイアウトに正確に対応させるためです。プラットフォーム独立のデータフォーマットを扱ったり、隠れたパディングを排除したりするには、サイズ及びアラインメントとして native の代わりに standard を使うようにします: 詳しくは バイトオーダ, サイズ, アラインメント を参照して下さい。

7.3.1. 関数と例外

このモジュールは以下の例外と関数を定義しています:

exception struct.error

様々な状況で送出された例外です; 引数は何が問題かを記述する文字列です。

struct.pack(fmt, v1, v2, ...)

値 v1, v2, ... が与えられたフォーマットで含まれる文字列データを返します。引数は指定したフォーマットが要求する型と正確に一致していなければなりません。

struct.pack_into(fmt, buffer, offset, v1, v2, ...)

v1, v2, ... を与えられたフォーマットに従ってパックし、そのバイト列を書き込み可能な buffer の offset を先頭に書き込みます。 offset が省略できないことに注意してください。

バージョン 2.5 で追加.

struct.unpack(fmt, string)

(おそらく pack(fmt, ...) でパックされた) 文字列データを与えられた書式に従ってアンパックします。値が一つしかない場合を含め、結果はタプルで返されます。文字列データにはフォーマットが要求するだけのデータが正確に含まれていなければなりません (len(string) が calcsize(fmt) と一致しなければなりません)。

struct.unpack_from(fmt, buffer[, offset=0])

buffer を与えられたフォーマットでアンパックします。値が一つしかない場合を含め、結果はタプルで返されます。 buffer には最低でも format に要求されるサイズのデータが必要です。 (len(buffer[offset:]) は calcsize(fmt) 以上でなければなりません)。

バージョン 2.5 で追加.

struct.calcsize(fmt)

与えられたフォーマットに対応する構造体のサイズ (すなわち文字列データのサイズ) を返します。

7.3.2. フォーマット文字列

フォーマット文字列はデータをパックしたりアンパックしたりするときの期待されるレイアウトを指定するためのメカニズムです。文字列はパック/アンパックされるデータの型を指定するフォーマット文字 から組み立てられます。さらに、 バイトオーダ, サイズ, アラインメント を制御するための特殊文字もあります。

7.3.2.1. バイトオーダ, サイズ, アラインメント

デフォルトでは、C での型はマシンのネイティブ (native) の形式およびバイトオーダ (byte order) で表され、適切にアラインメント (alignment) するために、必要に応じて数バイトのパディングを行ってスキップします (これは C コンパイラが用いるルールに従います)。

これに代わって、フォーマット文字列の最初の文字を使って、バイトオーダやサイズ、アラインメントを指定することができます。指定できる文字を以下のテーブルに示します:

文字 | バイトオーダ | サイズ | アラインメント
@ | ネイティブ | native | native
= | ネイティブ | standard | none
< | リトルエンディアン | standard | none
> | ビッグエンディアン | standard | none
! | ネットワーク (= ビッグエンディアン) | standard | none

フォーマット文字列の最初の文字が上のいずれかでない場合、 '@' であるとみなされます。

ネイティブのバイトオーダはビッグエンディアンかリトルエンディアンで、ホスト計算機に依存します。例えば、Intel x86 および AMD64 (x86-64) はリトルエンディアンです。Motorola 68000 および PowerPC G5 はビッグエンディアンです。 ARM および Intel Itanium はエンディアンを切り替えられる機能を備えています (バイエンディアン)。使っているシステムでのエンディアンは sys.byteorder を使って調べて下さい。

ネイティブのサイズおよびアラインメントは C コンパイラの sizeof 式で決定されます。ネイティブのサイズおよびアラインメントはネイティブのバイトオーダと同時に使われます。

標準サイズはフォーマット文字だけで決まります。 フォーマット文字 の表を参照して下さい。

'@' と '=' の違いに注意してください: 両方ともネイティブのバイトオーダですが、後者のバイトサイズとアラインメントは標準のものに合わせてあります。

'!' 表記法はネットワークバイトオーダがビッグエンディアンかリトルエンディアンか忘れちゃったという熱意に乏しい人向けに用意されています。

バイトオーダに関して、「(強制的にバイトスワップを行う)ネイティブの逆」を指定する方法はありません。 '<' または '>' のうちふさわしい方を選んでください。

注意:

パディングは構造体のメンバの並びの中にだけ自動で追加されます。最初や最後にパディングが追加されることはありません。

ネイティブでないサイズおよびアラインメントが使われる場合にはパディングは行われません。 (たとえば ‘<’, ‘>’, ‘=’, ‘!’ を使った場合です。)

特定の型によるアラインメント要求に従うように構造体の末端をそろえるには、繰り返し回数をゼロにした特定の型でフォーマットを終端します。例 を参照して下さい。

7.3.2.2. フォーマット文字

フォーマット文字 (format character) は以下の意味を持っています; C と Python の間の変換では、値は正確に以下に指定された型でなくてはなりません: 「標準のサイズ」列は standard サイズ使用時にパックされた値が何バイトかを示します。つまり、フォーマット文字列が '<', '>', '!', '=' のいずれかで始まっている場合のものです。native サイズ使用時にはパックされた値の大きさはプラットフォーム依存です。

フォーマット | C での型 | Python 型 | 標準のサイズ | 備考
x | pad byte | no value |  |
c | char | 長さ 1 の文字列 | 1 |
b | signed char | 整数型 (integer) | 1 | (3)
B | unsigned char | 整数型 | 1 | (3)
? | _Bool | 真偽値型(bool) | 1 | (1)
h | short | 整数型 | 1 | (3)
H | unsigned short | 整数型 | 2 | (3)
i | int | 整数型 | 4 | (3)
I | unsigned int | 整数型 | 4 | (3)
l | long | 整数型 | 4 | (3)
L | unsigned long | 整数型 | 4 | (3)
q | long long | 整数型 | 8 | (2), (3)
Q | unsigned long long | 整数型 | 8 | (2), (3)
f | float | 浮動小数点型 | 4 | (4)
d | double | 浮動小数点型 | 8 | (4)
s | char[] | 文字列 |  |
p | char[] | 文字列 |  |
P | void * | 整数型 |  | (5), (3)

注意事項:

'?' 変換コードは C99 で定義された _Bool 型に対応します。その型が利用できない場合は、 char で代用されます。標準モードでは常に1バイトで表現されます。

バージョン 2.6 で追加.

フォーマット文字 'q' および 'Q' は、プラットフォームの C コンパイラが C の long long 型、 Windows では __int64 をサポートする場合にのみ、プラットフォームネイティブの値との変換を行うモードだけで利用することができます。

バージョン 2.2 で追加.

整数変換コードで非整数をパックしようとするとき、その非整数が __index__() メソッドを持っていると、パッキングの前に、そのメソッドが変数を整数に変換するために呼び出されます。 __index__() メソッドが存在しないか、 __index__() メソッドの呼び出しが TypeError を送出したら、次に __int__() メソッドが試されます。しかし、 __int__() の使用は非推奨で、 DeprecationWarning を送出します。

バージョン 2.7 で変更: 非整数への __index__() メソッド の使用は 2.7 で追加されました。

バージョン 2.7 で変更: バージョン 2.7 以前では、すべての整数変換コードが変換に __int__() メソッドを使うわけではなく、浮動小数点の引数にのみ DeprecationWarning が送出されていました。

'f' および 'd' 変換コードについて、パックされた表現は IEEE 754 binary32 ('f' の場合) または binary64 ('d' の場合) フォーマットが、プラットフォームにおける浮動小数点数のフォーマットに関係なく使われます。

'P' フォーマット文字はネイティブバイトオーダでのみ利用可能です (デフォルトのネットワークバイトオーダに設定するか、 '@' バイトオーダ指定文字を指定しなければなりません)。 '=' を指定した場合、ホスト計算機のバイトオーダに基づいてリトルエンディアンとビッグエンディアンのどちらを使うかを決めます。 struct モジュールはこの設定をネイティブのオーダ設定として解釈しないので、 'P' を使うことはできません。

フォーマット文字の前に整数をつけ、繰り返し回数 (count) を指定することができます。例えば、フォーマット文字列 '4h' は 'hhhh' と全く同じ意味です。

フォーマット文字間の空白文字は無視されます; count とフォーマット文字の間にはスペースを入れてはいけません。

フォーマット文字 's' では、count は文字列のサイズとして扱われます。他のフォーマット文字のように繰り返し回数ではありません; 例えば、 '10c' が 10 個のキャラクタを表すのに対して、 '10s' は 10 バイトの長さを持った 1 個の文字列です。文字列をパックする際には、指定した長さにフィットするように、必要に応じて切り詰められたりヌル文字で穴埋めされたりします。また特殊なケースとして、('0c' が 0 個のキャラクタを表すのに対して) '0s' は 1 個の空文字列を意味します。

フォーマット文字 'p' は “Pascal 文字列 (pascal string)” をコードします。Pascal 文字列は count で与えられる 固定長のバイト列 に収められた短い可変長の文字列です。このデータの先頭の 1 バイトには文字列の長さか255 のうち、小さい方の数が収められます。その後に文字列のバイトデータが続きます。 pack() に渡された Pascal 文字列の長さが長すぎた (count-1 よりも長い) 場合、先頭の count-1 バイトが書き込まれます。文字列が count-1 よりも短い場合、指定した count バイトに達するまでの残りの部分はヌルで埋められます。 unpack() では、フォーマット文字 'p' は指定された count バイトだけデータを読み込みますが、返される文字列は決して 255 文字を超えることはないので注意してください。

フォーマット文字 'P' では、返される値は Python 整数型または long 整数型で、これはポインタの値を Python での整数にキャストする際に、値を保持するために必要なサイズに依存します。 NULL ポインタは常に Python 整数型の 0 になります。ポインタ型のサイズを持った値をパックする際には、Python 整数型および long 整数型オブジェクトを使うことができます。例えば、 Alpha および Merced プロセッサは 64 bit のポインタ値を使いますが、これはポインタを保持するために Python long 整数型が使われることを意味します; 32 bit ポインタを使う他のプラットフォームでは Python 整数型が使われます。

フォーマット文字 '?' では、返される値は True か False のどちらかです。パック時にはオブジェクトの真偽値が利用されます。 0 か 1 のネイティブもしくは標準のbool表現がパックされます。そしてアンパック時には非ゼロの値は True になります。

7.3.2.3. 例

ノート

全ての例は、ビッグエンディアンのマシンで、ネイティブのバイトオーダ、サイズおよびアラインメントを仮定します。

基本的な例として、三つの整数をパック/アンパックします:

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8

アンパックした結果のフィールドは、変数に割り当てるか named tuple でラップすることによって名前を付けることができます:

>>> record = 'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name='raymond   ', serialnum=4658, school=264, gradelevel=8)

アラインメントの要求を満たすために必要なパディングが異なるという理由により、フォーマット文字の順番がサイズの違いを生み出すことがあります:

>>> pack('ci', '*', 0x12131415)
'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, '*')
'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5

以下のフォーマット 'llh0l' は、 long 型が 4 バイトを境界としてそろえられていると仮定して、末端に 2 バイトをパディングします:

>>> pack('llh0l', 1, 2, 3)
'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

この例はネイティブのサイズとアラインメントが使われているときだけ思った通りに動きます。標準のサイズとアラインメントはアラインメントの設定ではいかなるアラインメントも行いません。

参考

Module array

一様なデータ型からなるバイナリ記録データのパック

Module xdrlib

XDR データのパックおよびアンパック。

7.3.3. クラス

struct モジュールは次の型を定義します:

class struct.Struct(format)

フォーマット文字列 format に従ってバイナリデータを読み書きする、新しい Struct オブジェクトを返します。 Struct オブジェクトを一度作ってからそのメソッドを使うと、フォーマット文字列のコンパイルが一度で済むので、 struct モジュールの関数を同じフォーマットで何度も呼び出すよりも効率的です。

バージョン 2.5 で追加.

コンパイルされた Struct オブジェクトは以下のメソッドと属性をサポートします:

pack(v1, v2, ...)

pack() 関数と同じ、コンパイルされたフォーマットを利用するメソッドです。 (len(result) は self.size と等しいでしょう)

pack_into(buffer, offset, v1, v2, ...)

pack_into() 関数と同じ、コンパイルされたフォーマットを利用するメソッドです。

unpack(string)

unpack() 関数と同じ、コンパイルされたフォーマットを利用するメソッドです。 (len(string) は self.size と等しくなければなりません)。

unpack_from(buffer[, offset=0])

unpack_from() 関数と同じ、コンパイルされたフォーマットを利用するメソッドです。 (len(buffer[offset:]) は self.size 以上でなければなりません)。

format

この Struct オブジェクトを作成する時に利用されたフォーマット文字列です。

size

format に対応する struct (とそれによる文字列) のサイズを計算したものです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.4. difflib — 差分の計算を助ける

バージョン 2.1 で追加.

このモジュールは、シーケンスを比較するためのクラスや関数を提供しています。例えば、ファイルの差分を計算して、それを HTML や context diff, unified diff などいろいろなフォーマットで出力するために、このモジュールを利用することができます。ディレクトリやファイル群を比較するためには、 filecmp モジュールも参照してください。

class difflib.SequenceMatcher

柔軟性のあるクラスで、二つのシーケンスの要素は、ハッシュ化できる(hashable)型である限り何でも比較可能です。基本的なアルゴリズムは、1980年代の後半に発表された Ratcliff と Obershelp による”ゲシュタルトパターンマッチング”と大げさに名づけられたアルゴリズム以前から知られている、やや凝ったアルゴリズムです。その考え方は、”junk” 要素を含まない最も長い互いに隣接したマッチ列を探すことです (Ratcliff と Obershelp のアルゴリズムでは junk を示しません)。このアイデアは、マッチ列から左または右に伸びる断片に対して再帰的にあてはめられます。この方法では編集を最小にする列は取り出されませんが、人間の目からみて「正しい感じ」にマッチする傾向があります。

実行時間: 基本的な Ratcliff-Obershelp アルゴリズムは、最悪の場合3乗、期待値で2乗となります。 SequenceMatcher オブジェクトでは、最悪のケースで2乗、期待値は比較されるシーケンス中に共通に現れる要素数に非常にややこしく依存しています。最良の場合は線形時間になります。

自動 junk ヒューリスティック: SequenceMatcher は、シーケンスの特定の要素を自動的に junk として扱うヒューリスティックをサポートしています。このヒューリスティックは、各個要素がシーケンス内に何回現れるかを数えます。ある要素の重複数が (最初のものは除いて) 合計でシーケンスの 1% 以上になり、そのシーケンスが 200 要素以上なら、その要素は “popular” であるものとしてマークされ、シーケンスのマッチングの目的からは junk として扱われます。このヒューリスティックは、 SequenceMatcher の作成時に autojunk パラメタを False に設定することで無効化できます。

バージョン 2.7.1 で追加: autojunk パラメタ。

class difflib.Differ

テキスト行からなるシーケンスを比較するクラスです。人が読むことのできる差分を作成します。 Differ クラスは SequenceMatcher クラスを利用して、行からなるシーケンスを比較したり、(ほぼ)同一の行内の文字を比較したりします。

Differ クラスによる差分の各行は、2文字のコードで始まります。

コード | 意味
'- ' | 行はシーケンス1にのみ存在する
'+ ' | 行はシーケンス2にのみ存在する
'  ' | 行は両方のシーケンスで同一
'? ' | 行は入力シーケンスのどちらにも存在しない

‘? ‘で始まる行は、行内のどこに差異が存在するかに注意を向けようとします。その行は、入力されたシーケンスのどちらにも存在しません。シーケンスがタブ文字を含むとき、これらの行は判別しづらいものになることがあります。

class difflib.HtmlDiff

このクラスは、二つのテキストを左右に並べて比較表示し、行間あるいは行内の変更点を強調表示するような HTML テーブル (またはテーブルの入った完全な HTML ファイル) を生成するために使います。テーブルは完全差分モード、コンテキスト差分モードのいずれでも生成できます。

このクラスのコンストラクタは以下のようになっています:

__init__([tabsize][, wrapcolumn][, linejunk][, charjunk])

HtmlDiff のインスタンスを初期化します。

tabsize はオプションのキーワード引数で、タブストップ幅を指定します。デフォルトは 8 です。

wrapcolumn はオプションのキーワード引数で、テキストを折り返すカラム幅を指定します。デフォルトは None で折り返しを行いません。

linejunk および charjunk はオプションのキーワード引数で、 ndiff() (HtmlDiff はこの関数を使って左右のテキストの差分を HTML で生成します) に渡されます。それぞれの引数のデフォルト値および説明は ndiff() のドキュメントを参照してください。

以下のメソッドが public になっています:

make_file(fromlines, tolines [, fromdesc][, todesc][, context][, numlines])

fromlines と tolines (いずれも文字列のリスト) を比較し、行間または行内の変更点が強調表示された行差分の入った表を持つ完全な HTML ファイルを文字列で返します。

fromdesc および todesc はオプションのキーワード引数で、差分表示テーブルにおけるそれぞれ差分元、差分先ファイルのカラムのヘッダになる文字列を指定します (いずれもデフォルト値は空文字列です)。

context および numlines はともにオプションのキーワード引数です。 context を True にするとコンテキスト差分を表示し、デフォルトの False にすると完全なファイル差分を表示します。 numlines のデフォルト値は 5 で、 context が True の場合、 numlines は強調部分の前後にあるコンテキスト行の数を制御します。 context が False の場合、 numlines は “next” と書かれたハイパーリンクをたどった時に到達する場所が次の変更部分より何行前にあるかを制御します (値をゼロにした場合、”next” ハイパーリンクを辿ると変更部分の強調表示がブラウザの最上部に表示されるようになります)。

make_table(fromlines, tolines [, fromdesc][, todesc][, context][, numlines])

fromlines と tolines (いずれも文字列のリスト) を比較し、行間または行内の変更点が強調表示された行差分の入った完全な HTML テーブルを文字列で返します。

このメソッドの引数は、 make_file() メソッドの引数と同じです。

Tools/scripts/diff.py はこのクラスへのコマンドラインフロントエンドで、使い方を学ぶ上で格好の例題が入っています。

バージョン 2.4 で追加.

difflib.context_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm])

a と b (文字列のリスト) を比較し、差分 (差分形式の行を生成するジェネレータ(generator)) を、 context diff のフォーマット(以下「コンテクスト形式」)で返します。

コンテクスト形式は、変更があった行に前後数行を加えてある、コンパクトな表現方法です。変更箇所は、変更前/変更後に分けて表します。コンテクスト (変更箇所前後の行) の行数は n で指定し、デフォルト値は 3 です。

デフォルトでは、diff の制御行 (*** や --- を含む行) の最後には、改行文字が付加されます。この場合、入出力とも、行末に改行文字を持つので、 file.readlines() で得た入力から生成した差分を、 file.writelines() に渡す場合に便利です。

行末に改行文字を持たない入力に対しては、出力でも改行文字を付加しないように lineterm 引数に "" を渡してください。

コンテクスト形式は、通常、ヘッダにファイル名と変更時刻を持っています。この情報は、文字列 fromfile, tofile, fromfiledate, tofiledate で指定できます。変更時刻の書式は、通常、ISO 8601 フォーマットで表されます。指定しなかった場合のデフォルト値は、空文字列です。

>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
>>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n']
>>> for line in context_diff(s1, s2, fromfile='before.py', tofile='after.py'):
...     sys.stdout.write(line)  # doctest: +NORMALIZE_WHITESPACE
*** before.py
--- after.py
***************
*** 1,4 ****
! bacon
! eggs
! ham
  guido
--- 1,4 ----
! python
! eggy
! hamster
  guido

より詳細な例は、 difflib のコマンドラインインタフェース を参照してください。

バージョン 2.3 で追加.

difflib.get_close_matches(word, possibilities[, n][, cutoff])

「十分」なマッチの上位のリストを返します。 word はマッチさせたいシーケンス (大概は文字列) です。 possibilities は word にマッチさせるシーケンスのリスト (大概は文字列のリスト) です。

オプションの引数 n (デフォルトでは 3)はメソッドの返すマッチの最大数です。 n は 0 より大きくなければなりません。

オプションの引数 cutoff (デフォルトでは 0.6)は、区間 [0, 1] に入る小数の値です。 word との一致率がそれ未満の possibilities の要素は無視されます。

possibilities の要素でマッチした上位(多くても n 個)は、類似度のスコアに応じて(一番似たものを先頭に)ソートされたリストとして返されます。

>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
['apple', 'ape']
>>> import keyword
>>> get_close_matches('wheel', keyword.kwlist)
['while']
>>> get_close_matches('apple', keyword.kwlist)
[]
>>> get_close_matches('accept', keyword.kwlist)
['except']

difflib.ndiff(a, b[, linejunk[, charjunk]])

a と b (文字列のリスト) を比較し、差分 (差分形式の行を生成するジェネレータ(generator)) を、 Differ のスタイルで返します。

オプションのキーワードパラメータ linejunk と charjunk は、フィルタ関数を渡します (使わないときは None)。

linejunk: 文字列型の引数ひとつを受け取る関数で、文字列が junk ならば真を、違うときには偽を返します。 Python 2.3 以降、デフォルトでは(None)になります。それまでは、モジュールレべルの関数 IS_LINE_JUNK() であり、それは高々ひとつのシャープ記号('#')を除いて可視のキャラクタを含まない行をフィルタリングするものです。 Python 2.3 から、下位にある SequenceMatcher クラスが、雑音となるくらい頻繁に登場する行であるか否かを、動的に分析します。これは、バージョン 2.3 以前のデフォルト値よりたいていうまく動作します。

charjunk: 文字(長さ1の文字列)を受け取る関数です。デフォルトでは、モジュールレべルの関数 IS_CHARACTER_JUNK() であり、これは空白文字類 (空白またはタブ、注：改行文字をこれに含めるのは悪いアイデア！) をフィルタリングします。

Tools/scripts/ndiff.py は、この関数のコマンドラインのフロントエンド（インターフェイス）です。

>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
...              'ore\ntree\nemu\n'.splitlines(1))
>>> print ''.join(diff),
- one
?  ^
+ ore
?  ^
- two
- three
?  -
+ tree
+ emu

difflib.restore(sequence, which)

差分を生成した元の二つのシーケンスのうち一つを返します。

Differ.compare() または ndiff() によって生成された sequence を与えられると、行頭のプレフィクスを取りのぞいてファイル 1 または 2 (引数 which で指定される) に由来する行を復元します。

例:

>>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1),
...              'ore\ntree\nemu\n'.splitlines(1))
>>> diff = list(diff) # materialize the generated delta into a list
>>> print ''.join(restore(diff, 1)),
one
two
three
>>> print ''.join(restore(diff, 2)),
ore
tree
emu

difflib.unified_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm])

a と b (文字列のリスト) を比較し、差分 (差分形式の行を生成するジェネレータ(generator)) を、 unified diff フォーマット(以下「ユニファイド形式」)で返します。

ユニファイド形式は変更があった行に前後数行を加えた、コンパクトな表現方法です。変更箇所は (変更前/変更後を分離したブロックではなく) インライン・スタイルで表されます。コンテクスト（変更箇所前後の行）の行数は、 n で指定し、デフォルト値は 3 です。

デフォルトでは、diff の制御行 (---, +++, @@ を含む行) は行末の改行を含めて生成されます。このようにしてあると、入出力とも行末に改行文字を持つので、 file.readlines() で得た入力を処理して生成した差分を、 file.writelines() に渡す場合に便利です。

行末に改行文字を持たない入力には、出力も同じように改行なしになるように、 lineterm 引数を "" にセットしてください

ユニファイド形式は、通常、ヘッダにファイル名と変更時刻を持っています。この情報は、文字列 fromfile, tofile, fromfiledate, tofiledate で指定できます。変更時刻の書式は、通常、ISO 8601 フォーマットで表されます。指定しなかった場合のデフォルト値は、空文字列です。

>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
>>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n']
>>> for line in unified_diff(s1, s2, fromfile='before.py', tofile='after.py'):
...     sys.stdout.write(line)   # doctest: +NORMALIZE_WHITESPACE
--- before.py
+++ after.py
@@ -1,4 +1,4 @@
-bacon
-eggs
-ham
+python
+eggy
+hamster
 guido

もっと詳細な例は、 difflib のコマンドラインインタフェース を参照してください。

バージョン 2.3 で追加.

difflib.IS_LINE_JUNK(line)

無視できる行のとき真を返します。行 line は空白、または '#' ひとつのときに無視できます。それ以外のときには無視できません。 Python 2.3 以前は ndiff() の引数 linkjunk にデフォルトで使用されました。

difflib.IS_CHARACTER_JUNK(ch)

無視できる文字のとき真を返します。文字 ch が空白、またはタブ文字のときには無視できます。それ以外の時には無視できません。 ndiff() の引数 charjunk としてデフォルトで使用されます。

参考

Pattern Matching: The Gestalt Approach （パターンマッチング: 全体アプローチ） [http://www.ddj.com/184407970?pgno=5]

John W. Ratcliff と D. E. Metzener による類似のアルゴリズムに関する議論。 Dr. Dobb’s Journal [http://www.ddj.com/] 1988年7月号掲載。

7.4.1. SequenceMatcherオブジェクト

SequenceMatcher クラスには、以下のようなコンストラクタがあります。

class difflib.SequenceMatcher([isjunk[, a[, b[, autojunk=True]]]])

オプションの引数 isjunk は、 None (デフォルトの値です) にするか、単一の引数をとる関数にせねばなりません。後者の場合、関数はシーケンスの要素を受け取り、要素が junk であり、無視すべきである場合に限り真をかえすようにせねばなりません。 isjunk に None を渡すと、 lambda x: 0 を渡したのと同じになります; すなわち、いかなる要素も無視しなくなります。例えば以下のような引数を渡すと、空白とタブ文字を無視して文字のシーケンスを比較します。

lambda x: x in " \t"

オプションの引数 a と b は、比較される文字列で、デフォルトでは空の文字列です。両方のシーケンスの要素は、ハッシュ化可能(hashable)である必要があります。

オプションの引数 autojunk は、自動 junk ヒューリスティックを無効にするために使えます。

バージョン 2.7.1 で追加: autojunk パラメタ。

SequenceMatcher オブジェクトは以下のメソッドを持ちます。

set_seqs(a, b)

比較される2つの文字列を設定します。

SequenceMatcher オブジェクトは、2つ目のシーケンスについての詳細な情報を計算し、キャッシュします。 1つのシーケンスをいくつものシーケンスと比較する場合、まず set_seq2() を使って文字列を設定しておき、別の文字列を1つずつ比較するために、繰り返し set_seq1() を呼び出します。

set_seq1(a)

比較を行う1つ目のシーケンスを設定します。比較される2つ目のシーケンスは変更されません。

set_seq2(b)

比較を行う2つ目のシーケンスを設定します。比較される1つ目のシーケンスは変更されません。

find_longest_match(alo, ahi, blo, bhi)

a[alo:ahi] と b[blo: bhi] の中から、最長のマッチ列を探します。

isjunk が省略されたか None の時、 get_longest_match() は a[i:i+k] が b[j:j+k] と等しいような (i, j, k) を返します。その値は alo <= i <= i+k <=  ahi かつ blo <= j <= j+k <=  bhi となります。 (i', j', k') でも、同じようになります。さらに k >= k', i <= i' が i == i', j <= j' でも同様です。言い換えると、いくつものマッチ列すべてのうち、 a 内で最初に始まるものを返します。そしてその a 内で最初のマッチ列すべてのうち b 内で最初に始まるものを返します。

>>> s = SequenceMatcher(None, " abcd", "abcd abcd")
>>> s.find_longest_match(0, 5, 0, 9)
Match(a=0, b=4, size=5)

引数 isjunk が与えられている場合、上記の通り、はじめに最長のマッチ列を判定します。ブロック内に junk 要素が見当たらないような追加条件の際はこれに該当しません。次にそのマッチ列を、その両側の junk 要素にマッチするよう、できる限り広げていきます。そのため結果となる列は、探している列のたまたま直前にあった同一の junk 以外の junk にはマッチしません。

以下は前と同じサンプルですが、空白を junk とみなしています。これは ' abcd' が2つ目の列の末尾にある ' abcd' にマッチしないようにしています。代わりに 'abcd' にはマッチします。そして 2つ目の文字列中、一番左の 'abcd' にマッチします。

>>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
>>> s.find_longest_match(0, 5, 0, 9)
Match(1, 0, 4)

どんな列にもマッチしない時は、 (alo, blo, 0) を返します。

バージョン 2.6 で変更: このメソッドは、名前付きタプル(named tuple)で Match(a, b, size) を返すようになりました。

get_matching_blocks()

マッチしたシーケンス中で個別にマッチしたシーケンスをあらわす、 3つの値のリストを返します。それぞれの値は (i, j, n) という形式であらわされ、 a[i:i+n] == b[j:j+n] という関係を意味します。 3つの値は i と j の間で単調に増加します。

最後のタプルはダミーで、 (len(a), len(b), 0) という値を持ちます。これは n==0 である唯一のタプルです。

もし (i, j, n) と (i', j', n') がリストで並んでいる3つ組で、 2つ目が最後の3つ組でなければ、 i+n != i' または j+n != j' です。言い換えると並んでいる3つ組は常に隣接していない同じブロックを表しています。

バージョン 2.5 で変更: 隣接する3つ組は常に隣接しないブロックを表すと保証するようになりました.

>>> s = SequenceMatcher(None, "abxcd", "abcd")
>>> s.get_matching_blocks()
[Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)]

get_opcodes()

a を b にするための方法を記述する5つのタプルを返します。それぞれのタプルは (tag, i1, i2, j1, j2) という形式であらわされます。最初のタプルは i1 == j1 == 0 であり、 i1 はその前にあるタプルの i2 と同じ値です。同様に j1 は前の j2 と同じ値になります。

tag の値は文字列であり、次のような意味です。

値 | 意味
'replace' | a[i1:i2] は b[ j1:j2] に置き換えられる
'delete' | a[i1:i2] は削除される。この時、 j1 == j2 である
'insert' | b[j1:j2] が a [i1:i1] に挿入される。この時 i1 == i2 である。
'equal' | a[i1:i2] == b[j1:j2] (この部分シーケンスは同値)

例)

>>> a = "qabxcd"
>>> b = "abycdf"
>>> s = SequenceMatcher(None, a, b)
>>> for tag, i1, i2, j1, j2 in s.get_opcodes():
...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
 delete a[0:1] (q) b[0:0] ()
  equal a[1:3] (ab) b[0:2] (ab)
replace a[3:4] (x) b[2:3] (y)
  equal a[4:6] (cd) b[3:5] (cd)
 insert a[6:6] () b[5:6] (f)

get_grouped_opcodes([n])

最大 n 行までのコンテクストを含むグループを生成するような、ジェネレータ(generator)を返します。

このメソッドは、 get_opcodes() で返されるグループの中から、似たような差異のかたまりに分け、間に挟まっている変更の無い部分を省きます。

グループは get_opcodes() と同じ書式で返されます。

バージョン 2.3 で追加.

ratio()

[0, 1] の範囲の浮動小数点数で、シーケンスの類似度を測る値を返します。

T が2つのシーケンスの要素数の総計だと仮定し、M をマッチした数とすると、この値は 2.0*M / T であらわされます。もしシーケンスがまったく同じ場合、値は 1.0 となり、まったく異なる場合には 0.0 となります。

このメソッドは get_matching_blocks() または get_opcodes() がまだ呼び出されていない場合には非常にコストが高いです。この場合、上限を素早く計算するために、 quick_ratio() もしくは real_quick_ratio() を最初に試してみる方がいいかもしれません。

quick_ratio()

ratio() の上界を、より高速に計算します。

real_quick_ratio()

ratio() の上界を、非常に高速に計算します。

この文字列全体のマッチ率を返す3つのメソッドは、精度の異なる近似値を返します。 quick_ratio() と real_quick_ratio() は、常に ratio() 以上の値を返します。

>>> s = SequenceMatcher(None, "abcd", "bcde")
>>> s.ratio()
0.75
>>> s.quick_ratio()
0.75
>>> s.real_quick_ratio()
1.0

7.4.2. SequenceMatcher の例

この例は2つの文字列を比較します。空白を junk とします。

>>> s = SequenceMatcher(lambda x: x == " ",
...                     "private Thread currentThread;",
...                     "private volatile Thread currentThread;")

ratio() は、[0, 1] の範囲の値を返し、シーケンスの類似度を測ります。経験によると、 ratio() の値が0.6を超えると、シーケンスがよく似ていることを示します。

>>> print round(s.ratio(), 3)
0.866

シーケンスのどこがマッチしているかにだけ興味のある時には get_matching_blocks() が手軽でしょう。

>>> for block in s.get_matching_blocks():
...     print "a[%d] and b[%d] match for %d elements" % block
a[0] and b[0] match for 8 elements
a[8] and b[17] match for 21 elements
a[29] and b[38] match for 0 elements

get_matching_blocks() が返す最後のタプルが常にダミーであることに注目してください。このダミーは (len(a), len(b), 0) であり、これはタプルの最後の要素（マッチする要素の数）がゼロとなる唯一のケースです。

はじめのシーケンスがどのようにして2番目のものになるのかを知るには、 get_opcodes() を使います。

>>> for opcode in s.get_opcodes():
...     print "%6s a[%d:%d] b[%d:%d]" % opcode
 equal a[0:8] b[0:8]
insert a[8:8] b[8:17]
 equal a[8:29] b[17:38]

参考

SequenceMatcher を使った、シンプルで使えるコードを知るには、このモジュールの関数 get_close_matches() を参照してください。

Simple version control recipe [http://code.activestate.com/recipes/576729/] SequenceMatcher で作った小規模アプリケーション。

7.4.3. Differ オブジェクト

Differ オブジェクトによって生成された差分が 最小 であるなどとは言いません。むしろ、最小の差分はしばしば直観に反しています。その理由は、どこでもできるとなれば一致を見いだしてしまうからで、ときには思いがけなく100ページも離れたマッチになってしまうのです。一致点を互いに隣接したマッチに制限することで、場合によって長めの差分を出力するというコストを掛けることにはなっても、ある種の局所性を保つことができるのです。

Differ は、以下のようなコンストラクタを持ちます。

class difflib.Differ([linejunk[, charjunk]])

オプションのパラメータ linejunk と charjunk はフィルタ関数の指定用です (もしくは None を指定)。

linejunk: ひとつの文字列引数を受け取る関数です。文字列が junk のときに真を返します。デフォルトでは、 None であり、どんな行であっても junk とは見なされません。

charjunk: この関数は文字(長さ1の文字列)を引数として受け取り、文字が junk であるときに真を返します。デフォルトは None であり、どんな文字も junk とは見なされません。

Differ オブジェクトは、以下の1つのメソッドを通して利用されます。（差分を生成します）。

compare(a, b)

文字列からなる2つのシーケンスを比較し、差分（を表す文字列からなるシーケンス）を生成します。

それぞれのシーケンスは、改行文字によって終了する、独立したひと連なりの文字列でなければなりません。そのようなシーケンスは、ファイル形式オブジェクトの readlines() メソッドによって得ることができます。（得られる）差分は改行文字で終了する文字列として得られ、ファイル形式オブジェクトの writelines() メソッドによって出力できる形になっています。

7.4.4. Differ の例

この例では2つのテキストを比較します。初めに、改行文字で終了する独立した1行の連続した (ファイル形式オブジェクトの readlines() メソッドによって得られるような) テキストを用意します。

>>> text1 = '''  1. Beautiful is better than ugly.
...   2. Explicit is better than implicit.
...   3. Simple is better than complex.
...   4. Complex is better than complicated.
... '''.splitlines(1)
>>> len(text1)
4
>>> text1[0][-1]
'\n'
>>> text2 = '''  1. Beautiful is better than ugly.
...   3.   Simple is better than complex.
...   4. Complicated is better than complex.
...   5. Flat is better than nested.
... '''.splitlines(1)

次に Differ オブジェクトをインスタンス化します。

>>> d = Differ()

注意： Differ オブジェクトをインスタンス化するとき、行 junk と文字 junk をフィルタリングする関数を渡すことができます。詳細は Differ() コンストラクタを参照してください。

最後に、2つを比較します。

>>> result = list(d.compare(text1, text2))

result は文字列のリストなので、pretty-printしてみましょう。

>>> from pprint import pprint
>>> pprint(result)
['    1. Beautiful is better than ugly.\n',
 '-   2. Explicit is better than implicit.\n',
 '-   3. Simple is better than complex.\n',
 '+   3.   Simple is better than complex.\n',
 '?     ++\n',
 '-   4. Complex is better than complicated.\n',
 '?            ^                     ---- ^\n',
 '+   4. Complicated is better than complex.\n',
 '?           ++++ ^                      ^\n',
 '+   5. Flat is better than nested.\n']

これは、複数行の文字列として、次のように出力されます。

>>> import sys
>>> sys.stdout.writelines(result)
    1. Beautiful is better than ugly.
-   2. Explicit is better than implicit.
-   3. Simple is better than complex.
+   3.   Simple is better than complex.
?     ++
-   4. Complex is better than complicated.
?            ^                     ---- ^
+   4. Complicated is better than complex.
?           ++++ ^                      ^
+   5. Flat is better than nested.

7.4.5. difflib のコマンドラインインタフェース

この例は、 difflib を使って diff に似たユーティリティーを作成する方法を示します。これは、 Python のソース配布物にも、 Tools/scripts/diff.py として含まれています。

""" Command line interface to difflib.py providing diffs in four formats:

* ndiff:    lists every line and highlights interline changes.
* context:  highlights clusters of changes in a before/after format.
* unified:  highlights clusters of changes in an inline format.
* html:     generates side by side comparison with change highlights.

"""

import sys, os, time, difflib, optparse

def main():
     # Configure the option parser
    usage = "usage: %prog [options] fromfile tofile"
    parser = optparse.OptionParser(usage)
    parser.add_option("-c", action="store_true", default=False,
                      help='Produce a context format diff (default)')
    parser.add_option("-u", action="store_true", default=False,
                      help='Produce a unified format diff')
    hlp = 'Produce HTML side by side diff (can use -c and -l in conjunction)'
    parser.add_option("-m", action="store_true", default=False, help=hlp)
    parser.add_option("-n", action="store_true", default=False,
                      help='Produce a ndiff format diff')
    parser.add_option("-l", "--lines", type="int", default=3,
                      help='Set number of context lines (default 3)')
    (options, args) = parser.parse_args()

    if len(args) == 0:
        parser.print_help()
        sys.exit(1)
    if len(args) != 2:
        parser.error("need to specify both a fromfile and tofile")

    n = options.lines
    fromfile, tofile = args # as specified in the usage string

    # we're passing these as arguments to the diff function
    fromdate = time.ctime(os.stat(fromfile).st_mtime)
    todate = time.ctime(os.stat(tofile).st_mtime)
    fromlines = open(fromfile, 'U').readlines()
    tolines = open(tofile, 'U').readlines()

    if options.u:
        diff = difflib.unified_diff(fromlines, tolines, fromfile, tofile,
                                    fromdate, todate, n=n)
    elif options.n:
        diff = difflib.ndiff(fromlines, tolines)
    elif options.m:
        diff = difflib.HtmlDiff().make_file(fromlines, tolines, fromfile,
                                            tofile, context=options.c,
                                            numlines=n)
    else:
        diff = difflib.context_diff(fromlines, tolines, fromfile, tofile,
                                    fromdate, todate, n=n)

    # we're using writelines because diff is a generator
    sys.stdout.writelines(diff)

if __name__ == '__main__':
    main()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.5. StringIO — ファイルのように文字列を読み書きする

このモジュールは、(メモリファイル としても知られている) 文字列のバッファに対して読み書きを行うファイルのようなクラス、 StringIO を実装しています。 (通常の文字列については、 str と unicode を参照してください)

操作方法についてはファイルオブジェクトの説明を参照してください(セクション ファイルオブジェクト)。

class StringIO.StringIO([buffer])

StringIO オブジェクトを作る際に、コンストラクターに文字列を渡すことで初期化することができます。文字列を渡さない場合、最初は StringIO はカラです。どちらの場合でも最初のファイル位置は 0 から始まります。

StringIO オブジェクトはユニコードも 8-bit の文字列も受け付けますが、この2つを混ぜることには少し注意が必要です。この2つが一緒に使われると、 getvalue() が呼ばれたときに、 (8th ビットを使っている)7-bit ASCII に解釈できない 8-bit の文字列は、 UnicodeError を引き起こします。

次にあげる StringIO オブジェクトのメソッドには特別な説明が必要です:

StringIO.getvalue()

StringIO オブジェクトの close() メソッドが呼ばれる前ならいつでも、 “file” の中身全体を返します。ユニコードと 8-bit の文字列を混ぜることの説明は、上の注意を参照してください。この2つの文字コードを混ぜると、このメソッドは UnicodeError を引き起こすかもしれません。

StringIO.close()

メモリバッファを解放します。 close された後の StringIO オブジェクトを操作しようとすると ValueError が送出されます。

使用例:

import StringIO

output = StringIO.StringIO()
output.write('First line.\n')
print >>output, 'Second line.'

# ファイルの内容を取り出す -- ここでは
# 'First line.\nSecond line.\n'
contents = output.getvalue()

# オブジェクトを閉じてメモリバッファを解放する --
# .getvalue() は例外を送出するようになる。
output.close()

7.6. cStringIO — 高速化された StringIO

cStringIO モジュールは StringIO モジュールと同様のインターフェースを提供しています。 StringIO.StringIO オブジェクトを酷使する場合、このモジュールにある StringIO() 関数をかわりに使うと効果的です。

cStringIO.StringIO([s])

読み書きのための StringIO 類似ストリームを返します。

組み込み型オブジェクトを返す factory 関数なので、サブクラス化して独自の関数を組むことはできません。属性の追加もできません。これらをするにはオリジナルの StringIO モジュールを使ってください。

StringIO モジュールで実装されているメモリファイルとは異なり、このモジュールで提供されているものは、プレイン ASCII 文字列にエンコードできないユニコードを受け付けることができません。

Unicode文字列を使って StringIO() を呼び出すと、文字列をエンコードするのではなく Unicode 文字列の buffer 表現が利用されます。

また、引数に文字列を指定して StringIO() 呼び出すと読み出し専用のオブジェクトが生成されますが、この場合 cStringIO.StringIO() では write()メソッドを持たないオブジェクトを生成します。これらのオブジェクトは普段は見えません。トレースバックに StringI と StringO として表示されます。

次にあげるデータオブジェクトも提供されています:

cStringIO.InputType

文字列をパラメーターに渡して StringIO() を呼んだときに作られるオブジェクトのオブジェクト型。

cStringIO.OutputType

パラメーターを渡さすに StringIO() を呼んだときに返されるオブジェクトのオブジェクト型。

このモジュールには C API もあります。詳しくはこのモジュールのソースを参照してください。

使用例:

import cStringIO

output = cStringIO.StringIO()
output.write('First line.\n')
print >>output, 'Second line.'

# ファイルの内容を取り出す -- ここでは
# 'First line.\nSecond line.\n'
contents = output.getvalue()

# オブジェクトを閉じてメモリバッファを解放する --
# 以降 .getvalue() は例外を送出するようになる。
output.close()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.7. textwrap — テキストの折り返しと詰め込み

バージョン 2.3 で追加.

textwrap モジュールでは、二つの簡易関数 wrap() と fill() 、そして作業のすべてを行うクラス TextWrapper とユーティリティ関数 dedent() を提供しています。単に一つや二つのテキスト文字列の折り返しまたは詰め込みを行っているならば、簡易関数で十分間に合います。そうでなければ、効率のために TextWrapper のインスタンスを使った方が良いでしょう。

参考

最新バージョンの textwrap モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/textwrap.py?view=markup]

textwrap.wrap(text[, width[, ...]])

text (文字列)内の段落を一つだけ折り返しを行います。したがって、すべての行が高々 width 文字の長さになります。最後に改行が付かない出力行のリストを返します。

オプションのキーワード引数は、以下で説明する TextWrapper のインスタンス属性に対応しています。 width はデフォルトで 70 です。

textwrap.fill(text[, width[, ...]])

text 内の段落を一つだけ折り返しを行い、折り返しが行われた段落を含む一つの文字列を返します。 fill() は

"\n".join(wrap(text, ...))

の省略表現です。

特に、 fill() は wrap() とまったく同じ名前のキーワード引数を受け取ります。

wrap() と fill() の両方ともが TextWrapper インスタンスを作成し、その一つのメソッドを呼び出すことで機能します。そのインスタンスは再利用されません。したがって、たくさんのテキスト文字列を折り返し/詰め込みを行うアプリケーションのためには、あなた自身の TextWrapper オブジェクトを作成することでさらに効率が良くなるでしょう。

テキストはなるべく空白か、ハイフンを含む語のハイフンの直後で折り返されます。 TextWrapper.break_long_words が偽に設定されていなければ、必要な場合に長い語が分解されます。

追加のユーティリティ関数である dedent() は、不要な空白をテキストの左側に持つ文字列からインデントを取り去ります。

textwrap.dedent(text)

text の各行に対し、共通して現れる先頭の空白を削除します。

この関数は通常、三重引用符で囲われた文字列をスクリーン/その他の左端にそろえ、なおかつソースコード中ではインデントされた形式を損なわないようにするために使われます。

タブとスペースはともにホワイトスペースとして扱われますが、同じではないことに注意してください: "  hello" という行と "\thello" 　は、同じ先頭の空白文字をもっていないとみなされます。(このふるまいは Python 2.5で導入されました。古いバージョンではこのモジュールは不正にタブを展開して共通の先頭空白文字列を探していました）

以下に例を示します:

def test():
    # end first line with \ to avoid the empty line!
    s = '''\
    hello
      world
    '''
    print repr(s)          # prints '    hello\n      world\n    '
    print repr(dedent(s))  # prints 'hello\n  world\n'

class textwrap.TextWrapper(...)

TextWrapper コンストラクタはたくさんのオプションのキーワード引数を受け取ります。それぞれの引数は一つのインスタンス属性に対応します。したがって、例えば、

wrapper = TextWrapper(initial_indent="* ")

は

wrapper = TextWrapper()
wrapper.initial_indent = "* "

と同じです。

あなたは同じ TextWrapper オブジェクトを何回も再利用できます。また、使用中にインスタンス属性へ代入することでそのオプションのどれでも変更できます。

TextWrapper インスタンス属性(とコンストラクタのキーワード引数)は以下の通りです:

width

(デフォルト: 70) 折り返しが行われる行の最大の長さ。入力行に width より長い単一の語が無い限り、 TextWrapper は width 文字より長い出力行が無いことを保証します。

expand_tabs

(デフォルト: True) もし真ならば、そのときは text 内のすべてのタブ文字は text の expand_tabs() メソッドを用いて空白に展開されます。

replace_whitespace

(デフォルト: True) もし真ならば、タブ展開の後に残る(string.whitespace に定義された)空白文字のそれぞれが一つの空白と置き換えられます。

ノート

expand_tabs が偽で replace_whitespace が真ならば、各タブ文字は1つの空白に置き換えられます。それはタブ展開と同じでは ありません 。

ノート

replace_whitespace が偽の場合、改行が行の途中で現れることで出力がおかしくなることがあります。このため、テキストを(str.splitlines() などを使って)段落ごとに分けて別々に wrap する必要があります。

drop_whitespace

(デフォルト: True) 真の場合、ラップ後に行末や行頭にあるスペースが削除されます。 (最初の行の先頭の空白は残ります)

バージョン 2.6 で追加: 過去のバージョンでは、空白は常に削除されていました。

initial_indent

(デフォルト: '') 折り返しが行われる出力の一行目の先頭に付けられる文字列。一行目の折り返しまでの長さにカウントされます。

subsequent_indent

(デフォルト: '') 一行目以外の折り返しが行われる出力のすべての行の先頭に付けられる文字列。一行目以外の各行の折り返しまでの長さにカウントされます。

fix_sentence_endings

(デフォルト: False) もし真ならば、 TextWrapper は文の終わりを見つけようとし、確実に文がちょうど二つの空白で常に区切られているようにします。これは一般的に固定スペースフォントのテキストに対して望ましいです。しかし、文の検出アルゴリズムは完全ではありません: 文の終わりには、後ろに空白がある '.', '!' または '?' の中の一つ、ことによると '"' あるいは ''' が付随する小文字があると仮定しています。これに伴う一つの問題は

[...] Dr. Frankenstein's monster [...]

の”Dr.”と

[...] See Spot. See Spot run [...]

の”Spot.”の間の差異を検出できないアルゴリズムです。

fix_sentence_endings はデフォルトで偽です。

文検出アルゴリズムは”小文字”の定義のために string.lowercase に依存し、同一行の文を区切るためにピリオドの後に二つの空白を使う慣習に依存しているため、英文テキストに限定されたものです。

break_long_words

(デフォルト: True) もし真ならば、そのとき width より長い行が確実にないようにするために、 width より長い語は切られます。偽ならば、長い語は切られないでしょう。そして、 width より長い行があるかもしれません。 (width を超える分を最小にするために、長い語は単独で一行に置かれるでしょう。)

break_on_hyphens

(デフォルト: True) 真の場合、英語で一般的なように、ラップ処理は空白か合成語に含まれるハイフンの直後で行われます。偽の場合、空白だけが改行に適した位置として判断されます。ただし、本当に語の途中で改行が行われないようにするためには、 break_long_words 属性を真に設定する必要があります。過去のバージョンでのデフォルトの振る舞いは、常にハイフンの直後での改行を許していました。

バージョン 2.6 で追加.

TextWrapper はモジュールレベルの簡易関数に類似した二つの公開メソッドも提供します:

wrap(text)

text (文字列)内の段落を一つだけ折り返しを行います。したがって、すべての行は高々 width 文字です。すべてのラッピングオプションは TextWrapper インスタンスのインスタンス属性から取られています。最後に改行の無い出力された行のリストを返します。

fill(text)

text 内の段落を一つだけ折り返しを行い、折り返しが行われた段落を含む一つの文字列を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.8. codecs — codec レジストリと基底クラス

このモジュールでは、内部的な Python codec レジストリに対するアクセス手段を提供しています。codec レジストリは、標準の Python codec(エンコーダとデコーダ)の基底クラスを定義し、 codec およびエラー処理の検索手順を管理しています。

codecs では以下の関数を定義しています:

codecs.register(search_function)

codec 検索関数を登録します。検索関数は第 1 引数にアルファベットの小文字から成るエンコーディング名を取り、以下の属性を持つ

CodecInfo オブジェクトを返します。

name エンコーディング名

encode 内部状態を持たないエンコード関数

decode 内部状態を持たないデコード関数

incrementalencoder 漸増的エンコーダクラスまたはファクトリ関数

incrementaldecoder 漸増的デコーダクラスまたはファクトリ関数

streamwriter ストリームライタクラスまたはファクトリ関数

streamreader ストリームリーダクラスまたはファクトリ関数

種々の関数やクラスが以下の引数をとります。

encode と decode: これらの引数は、 Codec インスタンスの encode() と decode() (Codec Interface 参照) と同じインタフェースを持つ関数、またはメソッドでなければなりません。これらの関数・メソッドは内部状態を持たずに動作する (stateless mode) と想定されています。

incrementalencoder と incrementaldecoder: これらは以下のインタフェースを持つファクトリ関数でなければなりません。

factory(errors='strict')

ファクトリ関数は、それぞれ基底クラスの IncrementalEncoder や IncrementalDecoder が定義しているインタフェースを提供するオブジェクトを返さねばなりません。漸増的 codecs は内部状態を維持できます。

streamreader と streamwriter: これらの引数は、次のようなインタフェースを持つファクトリ関数でなければなりません:

factory(stream, errors='strict')

ファクトリ関数は、基底クラスの StreamWriter や StreamReader が定義しているインタフェースを提供するオブジェクトを返さねばなりません。ストリーム codecs は内部状態を維持できます。

errors が取り得る値は

'strict' エンコーディングエラーの際に例外を発生

'replace' 奇形データを '?' や '\ufffd' 等の適切な文字で置換

'ignore' 奇形データを無視し何も通知せずに処理を継続

'xmlcharrefreplace' 適切な XML 文字参照で置換 (エンコーディングのみ))

'backslashreplace' (バックスラッシュつきのエスケープシーケンス (エンコーディングのみ))

と register_error() で定義されたその他のエラー処理名になります。

検索関数は、与えられたエンコーディングを見つけられなかった場合、 None を返さねばなりません。

codecs.lookup(encoding)

Python codec レジストリから codec 情報を探し、上で定義したような CodecInfo オブジェクトを返します。

エンコーディングの検索は、まずレジストリのキャッシュから行います。見つからなければ、登録されている検索関数のリストから探します。 CodecInfo オブジェクトが一つも見つからなければ LookupError を送出します。見つかったら、その CodecInfo オブジェクトはキャッシュに保存され、呼び出し側に返されます。

さまざまな codec へのアクセスを簡便化するために、このモジュールは以下のような関数を提供しています。これらの関数は、 codec の検索に lookup() を使います。

codecs.getencoder(encoding)

encoding に指定した codec を検索し、エンコーダ関数を返します。

encoding が見つからなければ LookupError を送出します。

codecs.getdecoder(encoding)

encoding に指定した codec を検索し、デコーダ関数を返します。

encoding が見つからなければ LookupError を送出します。

codecs.getincrementalencoder(encoding)

encoding に指定した codec を検索し、漸増的エンコーダクラス、また

はファクトリ関数を返します。

encoding が見つからない、もしくは codec が漸増的エンコーダをサポー

トしないとき LookupError を送出します。

バージョン 2.5 で追加.

codecs.getincrementaldecoder(encoding)

encoding に指定した codec を検索し、漸増的デコーダクラス、または

ファクトリ関数を返します。

encoding が見つからない、もしくは codec が漸増的デコーダをサポー

トしないとき LookupError を送出します。

バージョン 2.5 で追加.

codecs.getreader(encoding)

encoding に指定した codec を検索し、StreamReader クラス、またはファ

クトリ関数を返します。

encoding が見つからなければ LookupError を送出します。

codecs.getwriter(encoding)

encoding に指定した codec を検索し、 StreamWriter クラス、または

ファクトリ関数を返します。

encoding が見つからなければ LookupError を送出します。

codecs.register_error(name, error_handler)

エラー処理関数 error_handler を名前 name で登録します。エンコード中およびデコード中にエラーが送出された場合、 errors パラメタに name を指定していれば error_handler を呼び出すようになります。

error_handler はエラーの場所に関する情報の入った UnicodeEncodeError インスタンスとともに呼び出されます。エラー処理関数はこの例外を送出するか、別の例外を送出するか、または入力のエンコードができなかった部分の代替文字列とエンコードを再開する場所の指定が入ったタプルを返すかしなければなりません。最後の場合、エンコーダは代替文字列をエンコードし、元の入力中の指定位置からエンコードを再開します。位置を負の値にすると、入力文字列の末端からの相対位置として扱われます。境界の外側にある位置を返した場合には IndexError が送出されます。

デコードと翻訳は同様に働きますが、エラー処理関数に渡されるのが UnicodeDecodeError か UnicodeTranslateError である点と、エラー処理関数の置換した内容が直接出力になる点が異なります。

codecs.lookup_error(name)

名前 name で登録済みのエラー処理関数を返します。

エラー処理関数が見つからなければ LookupError を送出します。

codecs.strict_errors(exception)

strict エラー処理の実装です: エンコード又はデコードエラーは各々 UnicodeError を送出します.

codecs.replace_errors(exception)

replace エラー処理の実装です: 奇形データは適切な文字列に置換されます。バイト文字列では '?' 、 Unicode 文字列では '\ufffd' に置換されます。

codecs.ignore_errors(exception)

ignore エラー処理の実装です: 奇形データは無視されエンコード又はデコードは何も通知せず、継続されます。

codecs.xmlcharrefreplace_errors(exception)

xmlcharrefreplace エラー処理の実装です(エンコードのみ): エンコードできなかった文字は適切な XML 文字参照に置き換えます。

codecs.backslashreplace_errors(exception)

backslashreplace エラー処理の実装です (エンコードのみ): エンコードできなかった文字はバックスラッシュつきのエスケープシーケンスに置き換えられます。

エンコードされたファイルやストリームの処理を簡便化するため、このモジュールは次のようなユーティリティ関数を定義しています。

codecs.open(filename, mode[, encoding[, errors[, buffering]]])

mode でエンコードされたファイルを開き、透過的にエンコード・デコー

ドを行うようにラップしたファイルオブジェクトを返します。デフォルトのファイルモードは 'r' 、つまり、読み出しモードでファイルを開きます。

ノート

ラップ版のファイルオブジェクトを操作する関数は、該当する codec が定義している形式のオブジェクトだけを受け付けます。多くの組み込み codec では Unicode オブジェクトです。関数の戻り値も codec に依存し、通常は Unicode オブジェクトです。

ノート

非バイナリモードが指定されても、ファイルは常にバイナリモードで開かれます。これは、 8-bit の値を使うエンコーディングでデータが消失するのを防ぐためです。つまり、読み出しや書き込み時に、 '\n' の自動変換はされないということです。

encoding にはファイルのエンコーディングを指定します。

errors を指定して、エラー処理を定義することもできます。デフォルト

では 'strict' で、エンコード時にエラーがあれば ValueError を送出します。

buffering は、組み込み関数 open() と同じです。デフォルトで

は行バッファリングです。

codecs.EncodedFile(file, input[, output[, errors]])

ラップしたファイルオブジェクトを返します。このオブジェクトは透過なエンコード変換を提供します。

ラップされたファイルに書かれた文字列は、 input に指定したエンコーディングに従って変換され、 output に指定したエンコーディングを使って string 型に変換され、ファイルに書き込まれます。中間エンコーディングは指定された codecs に依存しますが、普通は Unicode です。

output が与えられなければ、 input がデフォルトになります。

errors を与えて、エラー処理を定義することもできます。デフォルトで

は 'strict' で、エンコード時にエラーがあれば ValueError を送出します。

codecs.iterencode(iterable, encoding[, errors])

漸増的エンコーダを使って、 iterable から供給される入力を反復的にエンコードします。この関数は generator です。 errors は (そして他のキーワード引数も同様に) 漸増的エンコーダにそのまま引き渡されます。

バージョン 2.5 で追加.

codecs.iterdecode(iterable, encoding[, errors])

漸増的デコーダを使って、 iterable から供給される入力を反復的にデコードします。この関数は generator です。 errors は (そして他のキーワード引数も同様に) 漸増的デコーダにそのまま引き渡されます。

バージョン 2.5 で追加.

このモジュールは以下のような定数も定義しています。プラットフォーム依存なファイルを読み書きするのに役立ちます。

codecs.BOM

codecs.BOM_BE

codecs.BOM_LE

codecs.BOM_UTF8

codecs.BOM_UTF16

codecs.BOM_UTF16_BE

codecs.BOM_UTF16_LE

codecs.BOM_UTF32

codecs.BOM_UTF32_BE

codecs.BOM_UTF32_LE

ここで定義された定数は、様々なエンコーディングの Unicode のバイトオーダマーカ (BOM) で、 UTF-16 と UTF-32 におけるデータストリームやファイルストリームのバイトオーダを指定したり、 UTF-8 における Unicode signature として使われます。 BOM_UTF16 は BOM_UTF16_BE と BOM_UTF16_LE のいずれかで、プラットフォームのネイティブバイトオーダに依存します。 BOM は BOM_UTF16 の別名です。同様に BOM_LE は BOM_UTF16_LE の、 BOM_BE は BOM_UTF16_BE の別名です。他は UTF-8 と UTF-32 エンコーディングの BOM を表します。

7.8.1. Codec 基底クラス

codecs モジュールでは、 codec のインタフェースを定義する一連の基底クラスを用意して、 Python 用 codec を簡単に自作できるようにしています。

Python で何らかの codec を使えるようにするには、状態なしエンコーダ、状態なしデコーダ、ストリームリーダ、ストリームライタの 4 つのインタフェースを定義せねばなりません。通常は、状態なしエンコーダとデコーダを再利用してストリームリーダとライタのファイル・プロトコルを実装します。

Codec クラスは、状態なしエンコーダ・デコーダのインタフェースを定義しています。

エラー処理の簡便化と標準化のため、 encode() メソッドと decode() メソッドでは、 errors 文字列引数を指定した場合に別のエラー処理を行うような仕組みを実装してもかまいません。全ての標準 Python codec では以下の文字列が定義され、実装されています。

Value | Meaning
'strict' | UnicodeError (または、そのサブクラス) を送出します – デフォルトの動作です。
'ignore' | その文字を無視し、次の文字から変換を再開します。
'replace' | 適当な文字で置換します – Python の組み込み Unicode codec のデコード時には公式の U+FFFD REPLACEMENT CHARACTER を、エンコード時には ‘?’ を使います。
'xmlcharrefreplace' | 適切な XML 文字参照で置換します (エンコードのみ)
'backslashreplace' | バックスラッシュつきのエスケープシーケンスで置換します (エンコードのみ)

codecs がエラーハンドラとして受け入れる値は register_error() を使って追加できます。

7.8.1.1. Codec オブジェクト

Codec クラスは以下のメソッドを定義します。これらのメソッドは、内部状態を持たないエンコーダ／デコーダ関数のインタフェースを定義します。

Codec.encode(input[, errors])

オブジェクト input エンコードし、(出力オブジェクト, 消費した長さ) のタプルを返します。 codecs は Unicode 専用ではありませんが、 Unicode の文脈では、エンコーディングは Unicode オブジェクトを特定の文字集合エンコーディング(たとえば cp1252 や iso-8859-1) を使って文字列オブジェクトに変換します。

errors は適用するエラー処理を定義します。 'strict' 処理がデフォルトです。

このメソッドは Codec に内部状態を保存してはなりません。効率よくエンコード／デコードするために状態を保持しなければならないような codecs には StreamCodec を使ってください。

エンコーダは長さが 0 の入力を処理できねばなりません。この場合、空のオブジェクトを出力オブジェクトとして返さねばなりません。

Codec.decode(input[, errors])

オブジェクト input をデコードし、(出力オブジェクト, 消費した長さ) のタプルを返します。 Unicode の文脈では、デコードは特定の文字集合エンコーディングでエンコードされた文字列を Unicode オブジェクトに変換します。

input は bf_getreadbuf バッファスロットを提供するオブジェクトでなければなりません。バッファスロットを提供しているオブジェクトには Python 文字列オブジェクト、バッファオブジェクト、メモリマップファイルがあります。

errors は適用するエラー処理を定義します。 'strict' がデフォルト値です。

このメソッドは、 Codec インスタンスに内部状態を保存してはなりません。効率よくエンコード／デコードするために状態を保持しなければならないような codecs には StreamCodec を使ってください。

デコーダは長さが 0 の入力を処理できねばなりません。この場合、空のオブジェクトを出力オブジェクトとして返さねばなりません。

IncrementalEncoder クラスおよび IncrementalDecoder クラスはそれぞれ漸増的エンコーディングおよびデコーディングのための基本的なインタフェースを提供します。エンコーディング／デコーディングは内部状態を持たないエンコーダ／デコーダを一度呼び出すことで行なわれるのではなく、漸増的エンコーダ／デコーダの encode()/decode() メソッドを複数回呼び出すことで行なわれます。漸増的エンコーダ／デコーダはメソッド呼び出しの間エンコーディング／デコーディング処理の進行を管理します。 encode()/decode() メソッド呼び出しの出力結果をまとめたものは、入力をひとまとめにして内部状態を持たないエンコーダ／デコーダでエンコード／デコードしたものと同じになります。

7.8.1.2. IncrementalEncoder オブジェクト

バージョン 2.5 で追加.

IncrementalEncoder クラスは入力を複数ステップでエンコードするのに使われます。全ての漸増的エンコーダが Python codec レジストリと互換性を持つために定義すべきメソッドとして、このクラスには以下のメソッドが定義されています。

class codecs.IncrementalEncoder([errors])

IncrementalEncoder インスタンスのコンストラクタ。

全ての漸増的エンコーダはこのコンストラクタインタフェースを提供しなければなりません。さらにキーワード引数を付け加えるのは構いませんが、 Python codec レジストリで利用されるのはここで定義されているものだけです。

IncrementalEncoder は errors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです。

'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

'ignore' 一文字無視して次に進みます。

'replace' 適当な代替文字で置き換えます。

'xmlcharrefreplace' 適切な XML 文字参照に置き換えます。

'backslashreplace' バックスラッシュ付きのエスケープシーケンスで置き換えます。

引数 errors は同名の属性に割り当てられます。属性に割り当てることで IncrementalEncoder オブジェクトが生きている間にエラー取扱戦略を違うものに切り替えることができるようになります。

errors 引数に許される値の集合は register_error() で拡張できます。

encode(object[, final])

object を(エンコーダの現在の状態を考慮に入れて)エンコードし、得られたエンコードされたオブジェクトを返します。 encode() 呼び出しがこれで最後という時には final は真でなければなりません(デフォルトは偽です)。

reset()

エンコーダを初期状態にリセットします。

7.8.1.3. IncrementalDecoder オブジェクト

IncrementalDecoder クラスは入力を複数ステップでデコードするのに使われます。全ての漸増的デコーダが Python codec レジストリと互換性を持つために定義すべきメソッドとして、このクラスには以下のメソッドが定義されています。

class codecs.IncrementalDecoder([errors])

IncrementalDecoder インスタンスのコンストラクタ。

全ての漸増的デコーダはこのコンストラクタインタフェースを提供しなければなりません。さらにキーワード引数を付け加えるのは構いませんが、 Python codec レジストリで利用されるのはここで定義されているものだけです。

IncrementalDecoder は errors キーワード引数を提供して異なったエラー取扱方法を実装することもできます。あらかじめ定義されているパラメータは以下の通りです。

'strict' ValueError (またはそのサブクラス) を送出します。これがデフォルトです。

'ignore' 一文字無視して次に進みます。

'replace' 適当な代替文字で置き換えます。

引数 errors は同名の属性に割り当てられます。属性に割り当てることで IncrementalDecoder オブジェクトが生きている間にエラー取扱戦略を違うものに切り替えることができるようになります。

errors 引数に許される値の集合は register_error() で拡張できます。

decode(object[, final])

object を(デコーダの現在の状態を考慮に入れて)デコードし、得られたデコードされたオブジェクトを返します。 decode() 呼び出しがこれで最後という時には final は真でなければなりません(デフォルトは偽です)。もし final が真ならばデコーダは入力をデコードし切り全てのバッファをフラッシュしなければなりません。そうできない場合(たとえば入力の最後に不完全なバイト列があるから)、デコーダは内部状態を持たない場合と同じようにエラーの取り扱いを開始しなければなりません(例外を送出するかもしれません)。

reset()

デコーダを初期状態にリセットします。

StreamWriter と StreamReader クラスは、新しいエンコーディングモジュールを、非常に簡単に実装するのに使用できる、一般的なインターフェイス提供します。実装例は encodings.utf_8 をご覧ください。

7.8.1.4. StreamWriter オブジェクト

StreamWriter クラスは Codec のサブクラスで、以下のメソッドを定義しています。全てのストリームライタは、 Python の codec レジストリとの互換性を保つために、これらのメソッドを定義する必要があります。

class codecs.StreamWriter(stream[, errors])

StreamWriter インスタンスのコンストラクタです。

全てのストリームライタはコンストラクタとしてこのインタフェースを提供せねばなりません。キーワード引数を追加しても構いませんが、 Python の codec レジストリはここで定義されている引数だけを使います。

stream は、(バイナリで) 書き込み可能なファイル類似のオブジェクトでなくてはなりません。

StreamWriter は、 errors キーワード引数を受けて、異なったエラー処理の仕組みを実装しても構いません。定義済みのパラメタを以下に示します。

'strict' ValueError (または、そのサブクラス) 送出します。デフォルトの動作です。

'ignore' 文字を無視して、次の文字から続けます。

'replace' 適切な置換文字で置換します。

'xmlcharrefreplace' 適切な XML 文字参照で置換します。

'backslashreplace' バックスラッシュ付きのエスケープシーケンスで置換します。

errors 引数は、同名の属性に代入されます。この属性を変更すると、 StreamWriter オブジェクトが生きている間に、異なるエラー処理に変更できます。

errors 引数が取り得る値の種類は register_error() で拡張できます。

write(object)

object の内容をエンコードしてストリームに書き出します。

writelines(list)

文字列からなるリストを連結して、(必要に応じて write() を何度も使って) ストリームに書き出します。

reset()

状態保持に使われていた codec のバッファを強制的に出力してリセットします。

このメソッドが呼び出された場合、出力先データをきれいな状態にし、わざわざストリーム全体を再スキャンして状態を元に戻さなくても新しくデータを追加できるようにせねばなりません。

ここまでで挙げたメソッドの他にも、 StreamWriter では背後にあるストリームの他の全てのメソッドや属性を継承せねばなりません。

7.8.1.5. StreamReader オブジェクト

StreamReader クラスは Codec のサブクラスで、以下のメソッドを定義しています。全てのストリームリーダは、 Python の codec レジストリとの互換性を保つために、これらのメソッドを定義する必要があります。

class codecs.StreamReader(stream[, errors])

StreamReader インスタンスのコンストラクタです。

全てのストリームリーダはコンストラクタとしてこのインタフェースを提供せねばなりません。キーワード引数を追加しても構いませんが、 Python の codec レジストリはここで定義されている引数だけを使います。

stream は、(バイナリで) 読み出し可能なファイル類似のオブジェクトでなくてはなりません。

StreamReader は、 errors キーワード引数を受けて、異なったエラー処理の仕組みを実装しても構いません。定義済みのパラメタを以下に示します。

'strict' ValueError (または、そのサブクラス) を送出します。デフォルトの処理です。

'ignore' 文字を無視して、次の文字から続けます。

'replace' 適切な置換文字で置換します。

errors 引数は、同名の属性に代入されます。この属性を変更すると、 StreamReader オブジェクトが生きている間に、異なるエラー処理に変更できます。

errors 引数が取り得る値の種類は register_error() で拡張できます。

read([size[, chars[, firstline]]])

ストリームからのデータをデコードし、デコード済のオブジェクトを返します。

chars はストリームから読み込む文字数です。 read() は chars 以上の文字を返しませんが、それより少ない文字しか取得できない場合には chars 以下の文字を返します。

size は、デコードするためにストリームから読み込む、およその最大バイト数を意味します。デコーダはこの値を適切な値に変更できます。デフォルト値 -1 にすると可能な限りたくさんのデータを読み込みます。 size の目的は、巨大なファイルの一括デコードを防ぐことにあります。

firstline は、1行目さえ返せばその後の行でデコードエラーがあっても無視して十分だ、ということを示します。

このメソッドは貪欲な読み込み戦略を取るべきです。すなわち、エンコーディング定義と size の値が許す範囲で、できるだけ多くのデータを読むべきだということです。たとえば、ストリーム上にエンコーディングの終端や状態の目印があれば、それも読み込みます。

バージョン 2.4 で変更: 引数 chars が追加されました。

バージョン 2.4.2 で変更: 引数 firstline が追加されました。

readline([size[, keepends]])

入力ストリームから1行読み込み、デコード済みのデータを返します。

size が与えられた場合、ストリームにおける readline() の size 引数に渡されます。

keepends が偽の場合には行末の改行が削除された行が返ります。

バージョン 2.4 で変更: 引数 keepends が追加されました。

readlines([sizehint[, keepends]])

入力ストリームから全ての行を読み込み、行のリストとして返します。

keepends が真なら、改行は、 codec のデコーダメソッドを使って実装され、リスト要素の中に含まれます。

sizehint が与えられた場合、ストリームの read() メソッドに size 引数として渡されます。

reset()

状態保持に使われた codec のバッファをリセットします。

ストリームの読み位置を再設定してはならないので注意してください。このメソッドはデコードの際にエラーから復帰できるようにするためのものです。

ここまでで挙げたメソッドの他にも、 StreamReader では背後にあるストリームの他の全てのメソッドや属性を継承せねばなりません。

次に挙げる2つの基底クラスは、利便性のために含まれています。codec レジストリは、これらを必要としませんが、実際のところ、あると有用なものでしょう。

7.8.1.6. StreamReaderWriter オブジェクト

StreamReaderWriter を使って、読み書き両方に使えるストリームをラップできます。

lookup() 関数が返すファクトリ関数を使って、インスタンスを生成するという設計です。

class codecs.StreamReaderWriter(stream, Reader, Writer, errors)

StreamReaderWriter インスタンスを生成します。 stream はファイル類似のオブジェクトです。 Reader と Writer は、それぞれ StreamReader と StreamWriter インタフェースを提供するファクトリ関数かファクトリクラスでなければなりません。エラー処理は、ストリームリーダとライタで定義したものと同じように行われます。

StreamReaderWriter インスタンスは、 StreamReader クラスと StreamWriter クラスを合わせたインタフェースを継承します。元になるストリームからは、他のメソッドや属性を継承します。

7.8.1.7. StreamRecoder オブジェクト

StreamRecoder はエンコーディングデータの、フロントエンド-バックエンドを観察する機能を提供します。異なるエンコーディング環境を扱うとき、便利な場合があります。

lookup() 関数が返すファクトリ関数を使って、インスタンスを生成するという設計になっています。

class codecs.StreamRecoder(stream, encode, decode, Reader, Writer, errors)

双方向変換を実装する StreamRecoder インスタンスを生成します。 encode と decode はフロントエンド (read() への入力と write() からの出力) を処理し、 Reader と Writer はバックエンド (ストリームに対する読み書き) を処理します。

これらのオブジェクトを使って、たとえば、 Latin-1 から UTF-8 、あるいは逆向きの変換を、透過に記録できます。

stream はファイル的オブジェクトでなくてはなりません。

encode と decode は Codec のインタフェースに忠実でなくてはならず、 Reader と Writer は、それぞれ StreamReader と StreamWriter のインタフェースを提供するオブジェクトのファクトリ関数かクラスでなくてはなりません。

encode と decode はフロントエンドの変換に必要で、 Reader と Writer はバックエンドの変換に必要です。中間のフォーマットはコデックの組み合わせによって決定されます。たとえば、 Unicode コデックは中間エンコーディングに Unicode を使います。

エラー処理はストリーム・リーダやライタで定義されている方法と同じように行われます。

StreamRecoder インスタンスは、 StreamReader と StreamWriter クラスを合わせたインタフェースを定義します。また、元のストリームのメソッドと属性も継承します。

7.8.2. エンコーディングと Unicode

Unicode 文字列は内部的にはコードポイントのシーケンスとして格納されます (正確に言えば Py_UNICODE 配列です)。 Python がどのようにコンパイルされたか (デフォルトである --enable-unicode=ucs2 かまたは --enable-unicode=ucs4 のどちらか) によって、 Py_UNICODE は16ビットまたは32ビットのデータ型です。 Unicode オブジェクトが CPU とメモリの外で使われることになると、 CPU のエンディアンやこれらの配列がバイト列としてどのように格納されるかが問題になってきます。 Unicode オブジェクトをバイト列に変換することをエンコーディングと呼び、バイト列から Unicode オブジェクトを再生することをデコーディングと呼びます。どのようにこの変換を行うかには多くの異なった方法があります (これらの方法のこともエンコーディングと言います) 。最も単純な方法はコードポイント 0-255 をバイト 0x0-0xff に写すことです。これは U+00FF より上のコードポイントを持つ Unicode オブジェクトはこの方法ではエンコードできないということを意味します (この方法を 'latin-1' とか 'iso-8859-1' と呼びます)。 unicode.encode() は次のような UnicodeEncodeError を送出することになります: UnicodeEncodeError: 'latin-1' codec can't encode character u'\u1234' in position 3: ordinal not in range(256)

他のエンコーディングの一群 (charmap エンコーディングと呼ばれます)がありますが、 Unicode コードポイントの別の部分集合とこれらがどのように 0x0-0xff のバイトに写されるかを選んだものです。これがどのように行なわれるかを知るには、単にたとえば encodings/cp1252.py (主に Windows で使われるエンコーディングです) を開いてみてください。256 文字のひとつの文字列定数がありどの文字がどのバイト値に写されるかを示しています。

上に挙げた全てのエンコーディングは Unicode に定義された65536(あるいは 1114111) あるコードポイント中256文字しかエンコードできません。全ての Unicode コードポイントを収める単純明快な方法は、それぞれのコードポイントを二つの引き続くバイトに収めるものです。二つの可能性があります。すなわちビッグエンディアンかリトルエンディアンか。これら二つのエンコーディングはそれぞれ UTF-16-BE あるいは UTF-16-LE と呼ばれます。欠点は、たとえば UTF-16-BE をリトルエンディアンの機械で使うときに、エンコーディングでもデコーディングでも常に二つのバイトを交換しなければならないことです。 UTF-16 はこの問題を解消します。バイトはいつでも自然なエンディアンに従います。これらのバイトが異なるエンディアンの CPU で読まれる時は、結局交換しない訳にはいきません。 UTF-16 のバイト列のエンディアンを検知できるようにするために、いわゆる BOM (“Byte Order Mark”) があります。 Unicode 文字で言うと U+FEFF です。この文字は全ての UTF-16 バイト列の先頭に付加されます。この文字のバイト位置を交換したもの (0xFFFE) は Unicode テキストに出現しないはずの違法な文字です。そこで、 UTF-16 バイト列の一文字目が U+FFFE に見えたなら、デコーディングの際にバイトを交換しなければなりません。不幸なことに、 Unicode 4.0 までは文字 U+FEFF には第二の目的 ZERO WIDTH NO-BREAK SPACE (幅を持たず単語が分割されるのを許さない文字) がありました。たとえばリガチャ(合字)アルゴリズムに対するヒントを与えるために使われることがあり得ます。 Unicode 4.0 になって U+FEFF の ZERO WIDTH NO-BREAK SPACE としての使用法は撤廃されました (U+2060 (WORD JOINER) にこの役割を譲りました)。しかしながら、 Unicode ソフトウェアは依然として U+FEFF の二つの役割を扱えなければなりません。一つは BOM として、エンコードされたバイトの記憶装置上のレイアウトを決め、バイト列が Unicode 文字列にデコードされた暁には消え去るものという役割。もう一つは ZERO WIDTH NO-BREAK SPACE として、通常の文字と同じようにデコードされる文字という役割です。

さらにもう一つ Unicode 文字全てをエンコードできるエンコーディングがあり、 UTF-8 と呼ばれています。UTF-8 は8ビットエンコーディングで、したがって UTF-8 にはバイト順の問題はありません。UTF-8 バイト列の各バイトは二つのパートから成ります。二つはマーカ(上位数ビット)とペイロードです。マーカは0ビットから6ビットの1の列に0のビットが一つ続いたものです。 Unicode 文字は次のようにエンコードされます (x はペイロードを表わし、連結されると一つの Unicode 文字を表わします):

範囲 | エンコーディング
U-00000000 ... U-0000007F | 0xxxxxxx
U-00000080 ... U-000007FF | 110xxxxx 10xxxxxx
U-00000800 ... U-0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 ... U-001FFFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 ... U-03FFFFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 ... U-7FFFFFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

Unicode 文字の最下位ビットとは最も右にある x のビットです。

UTF-8 は8ビットエンコーディングなので BOM は必要とせず、デコードされた Unicode 文字列中の U+FEFF は(たとえ最初の文字であったとしても) ZERO WIDTH NO-BREAK SPACE として扱われます。

外部からの情報無しには、 Unicode 文字列のエンコーディングにどのエンコーディングが使われたのか信頼できる形で決定することは不可能です。どの charmap エンコーディングもどんなランダムなバイト列でもデコードできます。しかし UTF-8 では、任意のバイト列が許される訳ではないような構造を持っているので、そのようなことは可能ではありません。 UTF-8 エンコーディングであることを検知する信頼性を向上させるために、 Microsoft は Notepad プログラム用に UTF-8 の変種 (Python 2.5 はで "utf-8-sig" と呼んでいます) を考案しました。まだ Unicode 文字がファイルに書き込まれない前に UTF-8 でエンコードした BOM (バイト列では 0xef, 0xbb, 0xbf のように見えます) を書き込んでしまいます。このようなバイト値で charmap エンコードされたファイルが始まることはほとんどあり得ない(たとえば iso-8859-1 では

LATIN SMALL LETTER I WITH DIAERESIS

RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK

INVERTED QUESTION MARK

のようになる)ので、 utf-8-sig エンコーディングがバイト列から正しく推測される確率を高めます。つまりここでは BOM はバイト列を生成する際のバイト順を決定できるように使われているのではなく、エンコーディングを推測する助けになる印として使われているのです。 utf-8-sig codec はエンコーディングの際ファイルに最初の3文字として 0xef, 0xbb, 0xbf を書き込みます。デコーディングの際はファイルの先頭に現れたこれら3バイトはスキップします。

7.8.3. 標準エンコーディング

Python には数多くの codec が組み込みで付属します。これらは C 言語の関数、対応付けを行うテーブルの両方で提供されています。以下のテーブルでは codec と、いくつかの良く知られている別名と、エンコーディングが使われる言語を列挙します。別名のリスト、言語のリストともしらみつぶしに網羅されているわけではありません。大文字と小文字、またはアンダースコアの代りにハイフンにしただけの綴りも有効な別名です; そのため例として 'utf-8' は 'utf_8' codec の正当な別名です。

多くの文字セットは同じ言語をサポートしています。これらの文字セットは個々の文字 (例えば、 EURO SIGN がサポートされているかどうか) や、文字のコード部分への割り付けが異なります。特に欧州言語では、典型的に以下の変種が存在します:

ISO 8859 コードセット

Microsoft Windows コードページで、 8859 コード形式から導出されているが、制御文字を追加のグラフィック文字と置き換えたもの

IBM EBCDIC コードページ

ASCII 互換の IBM PC コードページ

Codec | 別名 | 言語
ascii | 646, us-ascii | 英語
big5 | big5-tw, csbig5 | 繁体字中国語
big5hkscs | big5-hkscs, hkscs | 繁体字中国語
cp037 | IBM037, IBM039 | 英語
cp424 | EBCDIC-CP-HE, IBM424 | ヘブライ語
cp437 | 437, IBM437 | 英語
cp500 | EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500 | 西ヨーロッパ言語
cp720 |  | アラビア語
cp737 |  | ギリシャ語
cp775 | IBM775 | バルト沿岸国
cp850 | 850, IBM850 | 西ヨーロッパ
cp852 | 852, IBM852 | 中央および東ヨーロッパ
cp855 | 855, IBM855 | ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア
cp856 |  | ヘブライ語
cp857 | 857, IBM857 | トルコ語
cp858 | 858, IBM858 | 西ヨーロッパ
cp860 | 860, IBM860 | ポルトガル語
cp861 | 861, CP-IS, IBM861 | アイスランド語
cp862 | 862, IBM862 | ヘブライ語
cp863 | 863, IBM863 | カナダ
cp864 | IBM864 | アラビア語
cp865 | 865, IBM865 | デンマーク、ノルウェー
cp866 | 866, IBM866 | ロシア語
cp869 | 869, CP-GR, IBM869 | ギリシャ語
cp874 |  | タイ語
cp875 |  | ギリシャ語
cp932 | 932, ms932, mskanji, ms-kanji | 日本語
cp949 | 949, ms949, uhc | 韓国語
cp950 | 950, ms950 | 繁体字中国語
cp1006 |  | Urdu
cp1026 | ibm1026 | トルコ語
cp1140 | ibm1140 | 西ヨーロッパ
cp1250 | windows-1250 | 中央および東ヨーロッパ
cp1251 | windows-1251 | ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア
cp1252 | windows-1252 | 西ヨーロッパ
cp1253 | windows-1253 | ギリシャ
cp1254 | windows-1254 | トルコ
cp1255 | windows-1255 | ヘブライ
cp1256 | windows-1256 | アラビア
cp1257 | windows-1257 | バルト沿岸国
cp1258 | windows-1258 | ベトナム
euc_jp | eucjp, ujis, u-jis | 日本語
euc_jis_2004 | jisx0213, eucjis2004 | 日本語
euc_jisx0213 | eucjisx0213 | 日本語
euc_kr | euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001 | 韓国語
gb2312 | chinese, csiso58gb231280, euc- cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso- ir-58 | 簡体字中国語
gbk | 936, cp936, ms936 | 簡体字中国語
gb18030 | gb18030-2000 | 簡体字中国語
hz | hzgb, hz-gb, hz-gb-2312 | 簡体字中国語
iso2022_jp | csiso2022jp, iso2022jp, iso-2022-jp | 日本語
iso2022_jp_1 | iso2022jp-1, iso-2022-jp-1 | 日本語
iso2022_jp_2 | iso2022jp-2, iso-2022-jp-2 | 日本語, 韓国語, 簡体字中国語, 西欧, ギリシャ語
iso2022_jp_2004 | iso2022jp-2004, iso-2022-jp-2004 | 日本語
iso2022_jp_3 | iso2022jp-3, iso-2022-jp-3 | 日本語
iso2022_jp_ext | iso2022jp-ext, iso-2022-jp-ext | 日本語
iso2022_kr | csiso2022kr, iso2022kr, iso-2022-kr | 韓国語
latin_1 | iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1 | 西ヨーロッパ
iso8859_2 | iso-8859-2, latin2, L2 | 中央および東ヨーロッパ
iso8859_3 | iso-8859-3, latin3, L3 | エスペラント、マルタ
iso8859_4 | iso-8859-4, latin4, L4 | バルト沿岸国
iso8859_5 | iso-8859-5, cyrillic | ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア
iso8859_6 | iso-8859-6, arabic | アラビア語
iso8859_7 | iso-8859-7, greek, greek8 | ギリシャ語
iso8859_8 | iso-8859-8, hebrew | ヘブライ語
iso8859_9 | iso-8859-9, latin5, L5 | トルコ語
iso8859_10 | iso-8859-10, latin6, L6 | 北欧
iso8859_13 | iso-8859-13, latin7, L7 | バルト沿岸国
iso8859_14 | iso-8859-14, latin8, L8 | ケルト
iso8859_15 | iso-8859-15, latin9, L9 | 西ヨーロッパ
iso8859_16 | iso-8859-16, latin10, L10 | 南東ヨーロッパ
johab | cp1361, ms1361 | 韓国語
koi8_r |  | ロシア語
koi8_u |  | ウクライナ
mac_cyrillic | maccyrillic | ブルガリア、ベラルーシ、マケドニア、ロシア、セルビア
mac_greek | macgreek | ギリシャ
mac_iceland | maciceland | アイスランド
mac_latin2 | maclatin2, maccentraleurope | 中央および東ヨーロッパ
mac_roman | macroman | 西ヨーロッパ
mac_turkish | macturkish | トルコ語
ptcp154 | csptcp154, pt154, cp154, cyrillic-asian | カザフ
shift_jis | csshiftjis, shiftjis, sjis, s_jis | 日本語
shift_jis_2004 | shiftjis2004, sjis_2004, sjis2004 | 日本語
shift_jisx0213 | shiftjisx0213, sjisx0213, s_jisx0213 | 日本語
utf_32 | U32, utf32 | 全ての言語
utf_32_be | UTF-32BE | 全ての言語
utf_32_le | UTF-32LE | 全ての言語
utf_16 | U16, utf16 | 全ての言語
utf_16_be | UTF-16BE | 全ての言語 (BMP only)
utf_16_le | UTF-16LE | 全ての言語 (BMP only)
utf_7 | U7, unicode-1-1-utf-7 | 全ての言語
utf_8 | U8, UTF, utf8 | 全ての言語
utf_8_sig |  | 全ての言語

codec のいくつかは Python 特有のものなので、それらの codec 名は Python の外では無意味なものとなります。これらの codec の中には Unicode 文字列からバイト文字列への変換を行わず、むしろ単一の引数をもつ全写像関数はエンコーディングとみなせるという Python codec の性質を利用したものもあります。

以下に列挙した codec では、”エンコード” 方向の結果は常にバイト文字列方向です。”デコード” 方向の結果はテーブル内の被演算子型として列挙されています。

Codec | 別名 | 被演算子の型 | 目的
base64_codec | base64, base-64 | byte string | 被演算子を MIME base64 に変換します。
bz2_codec | bz2 | byte string | 被演算子をbz2を使って圧縮します。
hex_codec | hex | byte string | 被演算子をバイトあたり 2 桁の 16 進数の表現に変換します。
idna |  | Unicode string | RFC 3490 [http://tools.ietf.org/html/rfc3490.html] の実装です。 encodings.idna も参照してください。
mbcs | dbcs | Unicode string | Windows のみ: 被演算子を ANSI コードページ (CP_ACP) に従ってエンコードします。
palmos |  | Unicode string | PalmOS 3.5 のエンコーディングです。
punycode |  | Unicode string | RFC 3492 [http://tools.ietf.org/html/rfc3492.html] を実装しています。
quopri_codec | quopri, quoted-printable, quotedprintable | byte string | 被演算子を MIME quoted printable 形式に変換します。
raw_unicode_escape |  | Unicode string | Python ソースコードにおける raw Unicode リテラルとして適切な文字列を生成します。
rot_13 | rot13 | Unicode string | 被演算子のシーザー暗号 (Caesar- cypher) を返します。
string_escape |  | byte string | Python ソースコードにおける文字列リテラルとして適切な文字列を生成します。
undefined |  | any | 全ての変換に対して例外を送出します。バイト列と Unicode 文字列との間で coercion (強制型変換) をおこないたくない時にシステムエンコーディングとして使うことができます。
unicode_escape |  | Unicode string | Python ソースコードにおける Unicode リテラルとして適切な文字列を生成します。
unicode_internal |  | Unicode string | 被演算子の内部表現を返します。
uu_codec | uu | byte string | 被演算子を uuencode を用いて変換します。
zlib_codec | zip, zlib | byte string | 被演算子を gzip を用いて圧縮します。

バージョン 2.3 で追加: The idna and punycode encodings.

7.8.4. encodings.idna — アプリケーションにおける国際化ドメイン名 (IDNA)

バージョン 2.3 で追加.

このモジュールでは RFC 3490 [http://tools.ietf.org/html/rfc3490.html] (アプリケーションにおける国際化ドメイン名、 IDNA: Internationalized Domain Names in Applications) および RFC 3492 [http://tools.ietf.org/html/rfc3492.html] (Nameprep: 国際化ドメイン名 (IDN) のための stringprep プロファイル) を実装しています。このモジュールは punycode エンコーディングおよび stringprep の上に構築されています。

これらの RFC はともに、非 ASCII 文字の入ったドメイン名をサポートするためのプロトコルを定義しています。 (‘’www.Alliancefrançaise.nu’’ のような) 非 ASCII 文字を含むドメイン名は、 ASCII と互換性のあるエンコーディング (ACE、 ‘’www.xn–alliancefranaise-npb.nu’’ のような形式) に変換されます。ドメイン名の ACE 形式は、 DNS クエリ、 HTTP Host フィールドなどといった、プロトコル中で任意の文字を使えないような全ての局面で用いられます。この変換はアプリケーション内で行われます; 可能ならユーザからは不可視となります: アプリケーションは Unicode ドメインラベルをワイヤ上に載せる際に IDNA に、 ACE ドメインラベルをユーザに提供する前に Unicode に、それぞれ透過的に変換しなければなりません。

Python ではこの変換をいくつかの方法でサポートします: idna codec は Unicode と ACE 間の変換を行い、入力文字列を RFC 3490 [http://tools.ietf.org/html/rfc3490.html] の section 3.1 [http://tools.ietf.org/html/rfc3490#section-3.1] (1) で定義されている区切り文字に基づいてラベルに分解し、各ラベルを要求通りに ACE に変換します。逆に、入力のバイト文字列を . 区切り文字でラベルに分解し、 ACE ラベルを Unicode に変換します。さらに、 socket モジュールは Unicode ホスト名を ACE に透過的に変換するため、アプリケーションはホスト名を socket モジュールに渡す際にホスト名の変換に煩わされることがありません。その上で、ホスト名を関数パラメタとして持つ、 httplib や ftplib のようなモジュールでは Unicode ホスト名を受理します (httplib でもまた、 Host: フィールドにある IDNA ホスト名を、フィールド全体を送信する場合に透過的に送信します)。

(逆引きなどによって) ワイヤ越しにホスト名を受信する際、 Unicode への自動変換は行われません: こうしたホスト名をユーザに提供したいアプリケーションでは、 Unicode にデコードしてやる必要があります。

encodings.idna ではまた、 nameprep 手続きを実装しています。 nameprep はホスト名に対してある正規化を行って、国際化ドメイン名で大小文字を区別しないようにするとともに、類似の文字を一元化します。 nameprep 関数は必要なら直接使うこともできます。

encodings.idna.nameprep(label)

label を nameprep したバージョンを返します。現在の実装ではクエリ文字列を仮定しているので、 AllowUnassigned は真です。

encodings.idna.ToASCII(label)

RFC 3490 [http://tools.ietf.org/html/rfc3490.html] 仕様に従ってラベルを ASCIIに変換します。 UseSTD3ASCIIRules は偽であると仮定します。

encodings.idna.ToUnicode(label)

RFC 3490 [http://tools.ietf.org/html/rfc3490.html] 仕様に従ってラベルを Unicode に変換します。

7.8.5. encodings.utf_8_sig — BOM 印付き UTF-8

バージョン 2.5 で追加.

このモジュールは UTF-8 codec の変種を実装します。この変種はエンコーディング時に UTF-8 でエンコードされた BOM を UTF-8 でエンコードされたバイト列の前に追加します。内部状態を持つエンコーダにとって、これは一度だけ(バイトストリームの最初の書き込み時) 行なわれます。デコーディングに際してはデータ開始の UTF-8 でエンコードされた BOM がもしあったらスキップします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.9. unicodedata — Unicode データベース

このモジュールは、全ての Unicode 文字の属性を定義している Unicode 文字データベースへのアクセスを提供します。このデータベース内のデータは、ftp://ftp.unicode.org/ で公開されている UnicodeData.txt ファイルのバージョン 5.2.0 に基づいています。

このモジュールは、UnicodeData ファイルフォーマット 5.2.0 (http://www.unicode.org/reports/tr44/tr44-4.html を参照) で定義されているものと、同じ名前と記号を使います。このモジュールで定義されている関数は、以下のとおりです。

unicodedata.lookup(name)

名前に対応する文字を探します。その名前の文字が見つかった場合、その Unicode 文字が返されます。見つからなかった場合には、 KeyError を発生させます。

unicodedata.name(unichr[, default])

Unicode 文字 unichr に付いている名前を、文字列で返します。名前が定義されていない場合には default が返されますが、この引数が与えられていなければ ValueError を発生させます。

unicodedata.decimal(unichr[, default])

Unicode 文字 unichr に割り当てられている十進数を、整数で返します。この値が定義されていない場合には default が返されますが、この引数が与えられていなければ ValueError を発生させます。

unicodedata.digit(unichr[, default])

Unicode 文字 unichr に割り当てられている二進数を、整数で返します。この値が定義されていない場合には default が返されますが、この引数が与えられていなければ ValueError を発生させます。

unicodedata.numeric(unichr[, default])

Unicode 文字 unichr に割り当てられている数値を、float 型で返します。この値が定義されていない場合には default が返されますが、この引数が与えられていなければ ValueError を発生させます。

unicodedata.category(unichr)

Unicode 文字 unichr に割り当てられた、汎用カテゴリを返します。

unicodedata.bidirectional(unichr)

Unicode 文字 unichr に割り当てられた、双方向カテゴリを返します。そのような値が定義されていない場合、空の文字列が返されます。

unicodedata.combining(unichr)

Unicode 文字 unichr に割り当てられた正規結合クラスを返します。結合クラス定義されていない場合、 0 が返されます。

unicodedata.east_asian_width(unichr)

unichr as string. ユニコード文字 unichr に割り当てられたeast asian widthを文字列で返します。

バージョン 2.4 で追加.

unicodedata.mirrored(unichr)

Unicode 文字 unichr に割り当てられた、鏡像化のプロパティを返します。その文字が双方向テキスト内で鏡像化された文字である場合には 1 を、それ以外の場合には 0 を返します。

unicodedata.decomposition(unichr)

Unicode 文字 unichr に割り当てられた、文字分解マッピングを、文字列型で返します。そのようなマッピングが定義されていない場合、空の文字列が返されます。

unicodedata.normalize(form, unistr)

Unicode 文字列 unistr の正規形 form を返します。 form の有効な値は、’NFC’、’NFKC’、’NFD’、’NFKD’ です。

Unicode 規格は標準等価性 (canonical equivalence) と互換等価性 (compatibility equivalence) に基づいて、様々な Unicode文字列の正規形を定義します。Unicode では、複数の方法で表現できる文字があります。たとえば、文字 U+00C7 (LATIN CAPITAL LETTER C WITH CEDILLA) は、U+0327 (COMBINING CEDILLA) U+0043 (LATIN CAPITAL LETTER C) というシーケンスとしても表現できます。

各文字には2つの正規形があり、それぞれ正規形 C と正規形 D といいます。正規形 D (NFD) は標準分解 (canonical decomposition) としても知られており、各文字を分解された形に変換します。正規形 C (NFC) は標準分解を適用した後、結合済文字を再構成します。

互換等価性に基づいて、2つの正規形が加えられています。Unicode では、一般に他の文字との統合がサポートされている文字があります。たとえば、U+2160 (ROMAN NUMERAL ONE) は事実上 U+0049 (LATIN CAPITAL LETTER I) と同じものです。しかし、Unicode では、既存の文字集合 (たとえば gb2312) との互換性のために、これがサポートされています。

正規形 KD (NFKD) は、互換分解 (compatibility decomposition) を適用します。すなわち、すべての互換文字を、等価な文字で置換します。正規形 KC (NFKC) は、互換分解を適用してから、標準分解を適用します。

2つのunicode文字列が正規化されていて人間の目に同じに見えても、片方が結合文字を持っていてもう片方が持っていない場合、それらは完全に同じではありません。

バージョン 2.3 で追加.

更に、本モジュールは以下の定数を公開します。

unicodedata.unidata_version

このモジュールで使われている Unicode データベースのバージョン。

バージョン 2.3 で追加.

unicodedata.ucd_3_2_0

これはモジュール全体と同じメソッドを具えたオブジェクトですが、Unicode データベースバージョン 3.2 を代わりに使っており、この特定のバージョンの Unicode データベースを必要とするアプリケーション(IDNA など)のためものです。

バージョン 2.5 で追加.

例:

>>> import unicodedata
>>> unicodedata.lookup('LEFT CURLY BRACKET')
u'{'
>>> unicodedata.name(u'/')
'SOLIDUS'
>>> unicodedata.decimal(u'9')
9
>>> unicodedata.decimal(u'a')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: not a decimal
>>> unicodedata.category(u'A')  # 'L'etter, 'u'ppercase
'Lu'
>>> unicodedata.bidirectional(u'\u0660') # 'A'rabic, 'N'umber
'AN'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.10. stringprep — インターネットのための文字列調製

バージョン 2.3 で追加.

(ホスト名のような) インターネット上にある存在に識別名をつける際、しばしば識別名間の “等価性” 比較を行う必要があります。厳密には、例えば大小文字の区別をするかしないかいったように、比較をどのように行うかはアプリケーションの領域に依存します。また、例えば “印字可能な” 文字で構成された識別名だけを許可するといったように、可能な識別名を制限することも必要となるかもしれません。

RFC 3454 [http://tools.ietf.org/html/rfc3454.html] では、インターネットプロトコル上で Unicode 文字列を “調製 (prepare)” するためのプロシジャを定義しています。文字列は通信路に載せられる前に調製プロシジャで処理され、その結果ある正規化された形式になります。RFC ではあるテーブルの集合を定義しており、それらはプロファイルにまとめられています。各プロファイルでは、どのテーブルを使い、 stringprep プロシジャのどのオプション部分がプロファイルの一部になっているかを定義しています。 stringprep プロファイルの一つの例は nameprep で、国際化されたドメイン名に使われます。

stringprep は RFC 3453 のテーブルを公開しているに過ぎません。これらのテーブルは辞書やリストとして表　現するにはバリエーションが大きすぎるので、このモジュールでは Unicode 文字データベースを内部的に利用しています。モジュールソースコード自体は mkstringprep.py ユーティリティを使って生成されました。

その結果、これらのテーブルはデータ構造体ではなく、関数として公開されています。RFC には 2 種類のテーブル: 集合およびマップ、が存在します。集合については、 stringprep は “特性関数 (characteristic function)” 、すなわち引数が集合の一部である場合に真を返す関数を提供します。マップに対しては、マップ関数: キーが与えられると、それに関連付けられた値を返す関数、を提供します。以下はこのモジュールで利用可能な全ての関数を列挙したものです。

stringprep.in_table_a1(code)

code がテーブル A.1 (Unicode 3.2 における未割り当てコード点: unassigned code point) かどうか判定します。

stringprep.in_table_b1(code)

code がテーブル B.1 (一般には何にも対応付けられていない: commonly mapped to nothing) かどうか判定します。

stringprep.map_table_b2(code)

テーブル B.2 (NFKC で用いられる大小文字の対応付け) に従って、 code に対応付けられた値を返します。

stringprep.map_table_b3(code)

テーブル B.3 (正規化を伴わない大小文字の対応付け) に従って、 code に対応付けられた値を返します。

stringprep.in_table_c11(code)

code がテーブル C.1.1 (ASCII スペース文字) かどうか判定します。

stringprep.in_table_c12(code)

code がテーブル C.1.2 (非 ASCII スペース文字) かどうか判定します。

stringprep.in_table_c11_c12(code)

code がテーブル C.1 (スペース文字、C.1.1 および C.1.2 の和集合) かどうか判定します。

stringprep.in_table_c21(code)

code がテーブル C.2.1 (ASCII 制御文字) かどうか判定します。

stringprep.in_table_c22(code)

code がテーブル C.2.2 (非 ASCII 制御文字) かどうか判定します。

stringprep.in_table_c21_c22(code)

code がテーブル C.2 (制御文字、C.2.1 および C.2.2 の和集合) かどうか判定します。

stringprep.in_table_c3(code)

code がテーブル C.3 (プライベート利用) かどうか判定します。

stringprep.in_table_c4(code)

code がテーブル C.4 (非文字コード点: non-character code points) かどうか判定します。

stringprep.in_table_c5(code)

code がテーブル C.5 (サロゲーションコード) かどうか判定します。

stringprep.in_table_c6(code)

code がテーブル C.6 (平文:plain text として不適切) かどうか判定します。

stringprep.in_table_c7(code)

code がテーブル C.7 (標準表現:canonical representation として不適切) かどうか判定します。

stringprep.in_table_c8(code)

code がテーブル C.8 (表示プロパティの変更または撤廃) かどうか判定します。

stringprep.in_table_c9(code)

code がテーブル C.9 (タグ文字) かどうか判定します。

stringprep.in_table_d1(code)

code がテーブル D.1 (双方向プロパティ “R” または “AL” を持つ文字) かどうか判定します。

stringprep.in_table_d2(code)

code がテーブル D.2 (双方向プロパティ “L” を持つ文字) かどうか判定します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

7. 文字列処理 »

7.11. fpformat — 浮動小数点数の変換

バージョン 2.6 で撤廃: fpformat は Python 3.0 で削除されました。

fpformat モジュールは浮動小数点数の表示を 100% 純粋に Python だけで行うための関数を定義しています。

ノート

このモジュールは必要ありません: このモジュールのすべてのことは、文字列フォーマット操作 節で説明されている % を使った文字列の補間演算により実現可能です。

fpformat モジュールは次にあげる関数と例外を定義しています。

fpformat.fix(x, digs)

x を [-]ddd.ddd の形にフォーマットします。小数点の後ろに digs 桁と、小数点の前に少なくとも1桁です。 digs <= 0 の場合、小数点以下は切り捨てられます。

x は数字か数字を表した文字列です。 digs は整数です。

返り値は文字列です。

fpformat.sci(x, digs)

x を [-]d.dddE[+-]ddd の形にフォーマットします。小数点の後ろに digs 桁と、小数点の前に1桁だけです。 digs <= 0 の場合、1桁だけ残され、小数点以下は切り捨てられます。

x は実数か実数を表した文字列です。 digs は整数です。

返り値は文字列です。

exception fpformat.NotANumber

fix() や sci() にパラメータとして渡された文字列 x が数字として認識できなかった場合、例外が発生します。標準の例外が文字列の頃から、この例外は ValueError のサブクラスです。例外値は、例外を発生させた不適切にフォーマットされた文字列です。

例:

>>> import fpformat
>>> fpformat.fix(1.23, 1)
'1.2'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型

この章で解説されるモジュールは日付や時間、型が固定された配列、ヒープキュー、同期キュー、集合のような種々の特殊なデータ型を提供します。

Python にはその他にもいくつかの組み込みデータ型があります。特に、 dict 、 list 、 set (frozenset とともに古い sets モジュールを置き換えます)、そして tuple があります。 str クラスはバイナリデータや８ビットテキストを扱うことができ、 unicode クラスは Unicode テキストを扱うことができます。

この章で解説されるモジュールの完全な一覧は:

8.1. datetime — 基本的な日付型および時間型

8.1.1. 利用可能なデータ型

8.1.2. timedelta オブジェクト

8.1.3. date オブジェクト

8.1.4. datetime オブジェクト

8.1.5. time オブジェクト

8.1.6. tzinfo オブジェクト

8.1.7. strftime() と strptime() の振る舞い

8.2. calendar — 一般的なカレンダーに関する関数群

8.3. collections — 高性能なコンテナ・データ型

8.3.1. Counter オブジェクト

8.3.2. deque オブジェクト

8.3.3. deque のレシピ

8.3.4. defaultdict オブジェクト

8.3.4.1. defaultdict の使用例

8.3.5. namedtuple() 名前付きフィールドを持つタプルのファクトリ関数

8.3.6. OrderedDict オブジェクト

8.3.6.1. OrderedDict の例とレシピ

8.3.7. ABCs - abstract base classes

8.4. heapq — ヒープキューアルゴリズム

8.4.1. 基本的な例

8.4.2. 優先度キュー実装の注釈

8.4.3. 理論

8.5. bisect — 配列二分法アルゴリズム

8.5.1. ソート済みリストの探索

8.5.2. その他の使用例

8.6. array — 効率のよい数値アレイ

8.7. sets — ユニークな要素の順序なしコレクション

8.7.1. Set オブジェクト

8.7.2. 使用例

8.7.3. 不変に自動変換するためのプロトコル

8.7.4. 組み込み set 型との比較

8.8. sched — イベントスケジューラ

8.8.1. スケジューラオブジェクト

8.9. mutex — 排他制御

8.9.1. mutex オブジェクト

8.10. queue — 同期キュークラス

8.10.1. キューオブジェクト

8.11. weakref — 弱参照

8.11.1. 弱参照オブジェクト

8.11.2. 例

8.12. UserDict — 辞書オブジェクトのためのクラスラッパー

8.13. UserList — リストオブジェクトのためのクラスラッパー

8.14. UserString — 文字列オブジェクトのためのクラスラッパー

8.15. types — 組み込み型の名前

8.16. new — ランタイム内部オブジェクトの作成

8.17. copy — 浅いコピーおよび深いコピー操作

8.18. pprint — データ出力の整然化

8.18.1. PrettyPrinter オブジェクト

8.18.2. pprint の例

8.19. repr — もう一つの repr() の実装

8.19.1. Reprオブジェクト

8.19.2. Reprオブジェクトをサブクラス化する

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.1. datetime — 基本的な日付型および時間型

バージョン 2.3 で追加.

datetime モジュールでは、日付や時間データを簡単な方法と複雑な方法の両方で操作するためのクラスを提供しています。日付や時刻を対象にした四則演算がサポートされている一方で、このモジュールの実装では出力の書式化や操作を目的としたデータメンバの効率的な取り出しに焦点を絞っています。機能については、 time および calendar も参照下さい。

日付および時刻オブジェクトには、 “naive” および “aware” の 2 種類があります。この区別はオブジェクトがタイムゾーンや夏時間、あるいはその他のアルゴリズム的、政治的な理由による時刻の修正に関する何らかの表記をもつかどうかによるものです。特定の数字がメートルか、マイルか、質量を表すかといったことがプログラムの問題であるように、 naive な datetime オブジェクトが標準世界時 (UTC: Coordinated Universal time) を表現するか、ローカルの時刻を表現するか、あるいは他のいずれかのタイムゾーンにおける時刻を表現するかは純粋にプログラムの問題となります。 naive な datetime オブジェクトは、現実世界のいくつかの側面を無視するという犠牲のもとに、理解しやすく、かつ利用しやすくなっています。

より多くの情報を必要とするアプリケーションのために、 datetime および time オブジェクトはオプションのタイムゾーン情報メンバ、 tzinfo を持っています。このメンバには抽象クラス tzinfo のサブクラスのインスタンスが入っています。 tzinfo オブジェクトは UTC 時刻からのオフセット、タイムゾーン名、夏時間が有効になっているかどうか、といった情報を記憶しています。 datetime モジュールでは具体的な tsinfo クラスを提供していないので注意してください。必要な詳細仕様を備えたタイムゾーン機能を提供するのはアプリケーションの責任です。世界各国における時刻の修正に関する法則は合理的というよりも政治的なものであり、全てのアプリケーションに適した標準というものが存在しないのです。

datetime モジュールでは以下の定数を公開しています:

datetime.MINYEAR

date や datetime オブジェクトで許されている、年を表現する最小の数字です。 MINYEAR は 1 です。

datetime.MAXYEAR

date や datetime オブジェクトで許されている、年を表現する最大の数字です。 MAXYEAR は 9999 です。

参考

Module calendar

汎用のカレンダー関連関数。

Module time

時刻へのアクセスと変換。

8.1.1. 利用可能なデータ型

class datetime.date

理想化された naive な日付表現で、実質的には、これまでもこれからも現在のグレゴリオ暦 (Gregorian calender) であると仮定しています。属性: year, month,および day 。

class datetime.time

理想化された時刻表現で、あらゆる特定の日における影響から独立しており、毎日厳密に 24*60*60 秒であると仮定します (“うるう秒: leap seconds” の概念はありません)。属性: hour, minute, second, microsecond, および tzinfo 。

class datetime.datetime

日付と時刻を組み合わせたもの。属性: year, month, day, hour, minute, second, microsecond, および tzinfo 。

class datetime.timedelta

date, time,あるいは datetime クラスの二つのインスタンス間の時間差をマイクロ秒精度で表す経過時間値です。

class datetime.tzinfo

タイムゾーン情報オブジェクトの抽象基底クラスです。 datetime および time クラスで用いられ、カスタマイズ可能な時刻修正の概念 (たとえばタイムゾーンや夏時間の計算）を提供します。

これらの型のオブジェクトは変更不可能 (immutable) です。

date 型のオブジェクトは常に naive です。

time や datetime 型のオブジェクト d は naive にも aware にもできます。 d は d.tzinfo が None でなく、かつ d.tzinfo.utcoffset(d) が None を返さない場合に aware となります。 d.tzinfo が None の場合や、 d.tzinfo は None ではないが d.tzinfo.utcoffset(d) が None を返す場合には、 d は naive となります。

naive なオブジェクトと aware なオブジェクトの区別は timedelta オブジェクトにはあてはまりません。

サブクラスの関係は以下のようになります:

object
    timedelta
    tzinfo
    time
    date
        datetime

8.1.2. timedelta オブジェクト

timedelta オブジェクトは経過時間、すなわち二つの日付や時刻間の差を表します。

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

全ての引数がオプションで、デフォルト値は 0 です。引数は整数、長整数、浮動小数点数にすることができ、正でも負でもかまいません。

days, seconds および microseconds のみが内部に記憶されます。

引数は以下のようにして変換されます:

1 ミリ秒は 1000 マイクロ秒に変換されます。

1 分は 60 秒に変換されます。

1 時間は 3600 秒に変換されます。

1 週間は 7 日に変換されます。

その後、日、秒、マイクロ秒は値が一意に表されるように、

0 <= microseconds < 1000000

0 <= seconds < 3600*24 (一日中の秒数)

-999999999 <= days <= 999999999

で正規化されます。

引数のいずれかが浮動小数点であり、小数のマイクロ秒が存在する場合、小数のマイクロ秒は全ての引数から一度取り置かれ、それらの和は最も近いマイクロ秒に丸められます。浮動小数点の引数がない場合、値の変換と正規化の過程は厳密な (失われる情報がない) ものとなります。

日の値を正規化した結果、指定された範囲の外側になった場合には、 OverflowError が送出されます。

負の値を正規化すると、一見混乱するような値になります。例えば、

>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

クラス属性を以下に示します:

timedelta.min

最小の値を表す timedelta オブジェクトで、 timedelta(-999999999) です。

timedelta.max

最大の値を表す timedelta オブジェクトで、 timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999) です。

timedelta.resolution

timedelta オブジェクトが等しくならない最小の時間差で、 timedelta(microseconds=1) です。

正規化のために、 timedelta.max > -timedelta.min となるので注意してください。 -timedelta.max は timedelta オブジェクトとして表現することができません。

以下に (読み出し専用の) インスタンス属性を示します:

属性 | 値
days | 両端値を含む -999999999 から 999999999 の間
seconds | 両端値を含む 0 から 86399 の間
microseconds | 両端値を含む 0 から 999999 の間

サポートされている操作を以下に示します:

演算 | 結果
t1 = t2 + t3 | t2 と t3 を加算します。演算後、 t1-t2 == t3 および t1-t3 == t2 は真になります。 (1)
t1 = t2 - t3 | t2 と t3 の差分です。演算後、 t1 == t2 - t3 および t2 == t1 + t3 は真になります。 (1)
t1 = t2 * i or t1 = i * t2 | 整数や長整数による乗算です。演算後、 t1 // i == t2 は i != 0 であれば真となります。
| 一般的に、 t1 * i == t1 * (i-1) + t1 は真となります。(1)
t1 = t2 // i | 端数を切り捨てて除算され、剰余 (がある場合) は捨てられます。(3)
+t1 | 同じ値を持つ timedelta オブジェクトを返します。(2)
-t1 | timedelta(-t1.days, -t1.seconds, -t1.microseconds)、および t1* -1 と同じです。 (1)(4)
abs(t) | t.days >= 0 のときには +*t*, t.days < 0 のときには -t となります。(2)
str(t) | [D day[s], ][H]H:MM:SS[.UUUUUU] という形式の文字列を返します。 t が負の値の場合は D は負の値となります。(5)
repr(t) | datetime.timedelta(D[, S[, U]]) という形式の文字列を返します。 t が負の場合は D は負の値となります。(5)

注釈:

この操作は厳密ですが、オーバフローするかもしれません。

この操作は厳密であり、オーバフローしないはずです。

0 による除算は ZeroDivisionError を送出します。

-timedelta.max は timedelta オブジェクトで表現することができません。

timedelta オブジェクトの文字列表現は内部表現に類似した形に正規化されます。そのため負の timedelta はいくぶん珍しい結果となります。例えば:

>>> timedelta(hours=-5)
datetime.timedelta(-1, 68400)
>>> print(_)
-1 day, 19:00:00

上に列挙した操作に加えて、 timedelta オブジェクトは date および datetime オブジェクトとの間で加減算をサポートしています (下を参照してください)。

timedelta オブジェクト間の比較はサポートされており、より小さい経過時間を表す timedelta オブジェクトがより小さい timedelta と見なされます。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、 timedelta オブジェクトと異なる型のオブジェクトが比較されると、比較演算子が == または != でないかぎり TypeError が送出されます。後者の場合、それぞれ False または True を返します。

timedelta オブジェクトはハッシュ可能(hashable) つまり、辞書のキーとして利用可能) であり、効率的な pickle 化をサポートします。また、ブール演算コンテキストでは、 timedelta オブジェクトは timedelta(0) に等しくない場合かつそのときに限り真となります。

インスタンスメソッド:

timedelta.total_seconds()

この期間に含まれるトータルの秒数を返します。 true division が有効な場合の、 (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 と同じです。

非常に長い期間 (多くのプラットフォームでは270年以上) については、このメソッドはマイクロ秒の精度を失うことがあることに注意してください。

バージョン 2.7 で追加.

使用例:

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)  # 365日になるように足し算
>>> year.total_seconds()
31536000.0
>>> year == another_year
True
>>> ten_years = 10 * year
>>> ten_years, ten_years.days // 365
(datetime.timedelta(3650), 10)
>>> nine_years = ten_years - year
>>> nine_years, nine_years.days // 365
(datetime.timedelta(3285), 9)
>>> three_years = nine_years // 3;
>>> three_years, three_years.days // 365
(datetime.timedelta(1095), 3)
>>> abs(three_years - ten_years) == 2 * three_years + year
True

8.1.3. date オブジェクト

date オブジェクトは日付 (年、月、および日) を表します。日付は理想的なカレンダー、すなわち現在のグレゴリオ暦を過去と未来の両方向に無限に延長したもので表されます。 1 年の 1 月 1 日は日番号 1, 1 年 1 月 2 日は日番号 2,となっていきます。この暦法は、全ての計算における基本カレンダーである、 Dershowitz と Reingold の書籍 Calendrical Calculations における”予期的グレゴリオ (proleptic Gregorian)” 暦の定義に一致します。

class datetime.date(year, month, day)

全ての引数が必要です。引数は整数でも長整数でもよく、以下の範囲に入らなければなりません:

MINYEAR <= year <= MAXYEAR

1 <= month <= 12

1 <= day <= 指定された月と年における日数

範囲を超えた引数を与えた場合、 ValueError が送出されます。

他のコンストラクタ、および全てのクラスメソッドを以下に示します:

classmethod date.today()

現在のローカルな日付を返します。 date.fromtimestamp(time.time()) と等価です。

classmethod date.fromtimestamp(timestamp)

time.time() が返すような POSIX タイムスタンプに対応する、ローカルな日付を返します。タイムスタンプがプラットフォームにおける C 関数 localtime() でサポートされている範囲を超えている場合には ValueError を送出します。この値はよく 1970 年から 2038 年に制限されていることがあります。うるう秒がタイムスタンプの概念に含まれている非 POSIX システムでは、 fromtimestamp() はうるう秒を無視します。

classmethod date.fromordinal(ordinal)

予期的グレゴリオ暦順序に対応する日付を表し、 1 年 1 月 1 日が序数 1 となります。 1 <= ordinal <= date.max.toordinal() でない場合、 ValueError が送出されます。任意の日付 d に対し、 date.fromordinal(d.toordinal()) ==  d となります。

以下にクラス属性を示します:

date.min

表現できる最も古い日付で、 date(MINYEAR, 1, 1) です。

date.max

表現できる最も新しい日付で、 date(MAXYEAR, 12, 31) です。

date.resolution

等しくない日付オブジェクト間の最小の差で、 timedelta(days=1) です。

以下に (読み出し専用の) インスタンス属性を示します:

date.year

両端値を含む MINYEAR から MAXYEAR までの値です。

date.month

両端値を含む 1 から 12 までの値です。

date.day

1 から与えられた月と年における日数までの値です。

サポートされている操作を以下に示します:

演算 | 結果
date2 = date1 + timedelta | date2 はから date1 から timedelta.days 日移動した日付です。 (1)
date2 = date1 - timedelta | date2 + timedelta == date1 であるような日付 date2 を計算します。 (2)
timedelta = date1 - date2 | (3)
date1 < date2 | date1 が時刻として date2 よりも前を表す場合に、 date1 は date2 よりも小さいと見なされます。 (4)

注釈:

date2 は timedelta.days > 0 の場合進む方向に、 timedelta.days < 0 の場合戻る方向に移動します。演算後は、 date2 - date1 == timedelta.days となります。 timedelta.seconds および timedelta.microseconds は無視されます。 date2.year が MINYEAR になってしまったり、 MAXYEAR より大きくなってしまう場合には OverflowError が送出されます。

この操作は date1 + (-timedelta) と等価ではありません。なぜならば、 date1 - timedelta がオーバフローしない場合でも、 -timedelta 単体がオーバフローする可能性があるからです。 timedelta.seconds および timedelta.microseconds は無視されます。

この演算は厳密で、オーバフローしません。 timedelta.seconds および timedelta.microseconds は 0 で、演算後には date2 + timedelta == date1 となります。

別の言い方をすると、 date1.toordinal() < date2.toordinal() であり、かつそのときに限り date1 < date2 となります。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、 timedelta オブジェクトと異なる型のオブジェクトが比較されると TypeError が送出されます。しかしながら、被比較演算子のもう一方が timetuple() 属性を持つ場合には NotImplemented が返されます。このフックにより、他種の日付オブジェクトに型混合比較を実装するチャンスを与えています。そうでない場合、 timedelta オブジェクトと異なる型のオブジェクトが比較されると、比較演算子が == または != でないかぎり TypeError が送出されます。後者の場合、それぞれ False または True を返します。

date オブジェクトは辞書のキーとして用いることができます。ブール演算コンテキストでは、全ての date オブジェクトは真であるとみなされます。

以下にインスタンスメソッドを示します:

date.replace(year, month, day)

キーワード引数で指定されたデータメンバが置き換えられることを除き、同じ値を持つ date オブジェクトを返します。例えば、 d == date(2002, 12, 31) とすると、 d.replace(day=26) == date(2002, 12, 26) となります。

date.timetuple()

time.localtime() が返す形式の time.struct_time を返します。時間、分、および秒は 0 で、DST フラグは -1 になります。 d.timetuple() は次の値と同値です: time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1)) ただし yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 が 1月1日 に 1 で始まる現在の年の日を表す

date.toordinal()

予測的グレゴリオ暦における日付序数を返します。 1 年の 1 月 1 日が序数 1 となります。任意の date オブジェクト d について、 date.fromordinal(d.toordinal()) == d となります。

date.weekday()

月曜日を 0、日曜日を 6 として、曜日を整数で返します。例えば、 date(2002, 12, 4).weekday() == 2 であり、水曜日を示します。 isoweekday() も参照してください。

date.isoweekday()

月曜日を 1,日曜日を 7 として、曜日を整数で返します。例えば、 date(2002, 12, 4).weekday() == 3 であり、水曜日を示します。 weekday(), isocalendar() も参照してください。

date.isocalendar()

3 要素のタプル (ISO 年、ISO 週番号、ISO 曜日) を返します。

ISO カレンダーはグレゴリオ暦の変種として広く用いられています。細かい説明については http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm を参照してください。

ISO 年は完全な週が 52 または 53 週あり、週は月曜から始まって日曜に終わります。 ISO 年でのある年における最初の週は、その年の木曜日を含む最初の (グレゴリオ暦での) 週となります。この週は週番号 1 と呼ばれ、この木曜日での ISO 年はグレゴリオ暦における年と等しくなります。

例えば、 2004 年は木曜日から始まるため、ISO 年の最初の週は 2003 年 12 月 29 日、月曜日から始まり、 2004 年 1 月 4 日、日曜日に終わります。従って、 date(2003, 12, 29).isocalendar() == (2004, 1, 1) であり、かつ date(2004, 1, 4).isocalendar() == (2004, 1, 7) となります。

date.isoformat()

ISO 8601 形式、 ‘YYYY-MM-DD’ の日付を表す文字列を返します。例えば、 date(2002, 12, 4).isoformat() == '2002-12-04' となります。

date.__str__()

date オブジェクト d において、 str(d) は d.isoformat() と等価です。

date.ctime()

日付を表す文字列を、例えば date(2002, 12, 4).ctime() == 'Wed Dec 4 00:00:00 2002' のようにして返します。ネイティブの C 関数 ctime() (time.ctime() はこの関数を呼び出しますが、 date.ctime() は呼び出しません) が C 標準に準拠しているプラットフォームでは、 d.ctime() は time.ctime(time.mktime(d.timetuple())) と等価です。

date.strftime(format)

明示的な書式化文字列で制御された、日付を表現する文字列を返します。時間、分、秒を表す書式化コードは値 0 になります。 strftime() と strptime() の振る舞い も参照下さい。

イベントまでの日数を数える例を示します:

>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> if my_birthday < today:
...     my_birthday = my_birthday.replace(year=today.year + 1)
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202

date と併用する例を示します:

>>> from datetime import date
>>> d = date.fromordinal(730920) # 西暦1年1月1日を1日目として730920日目
>>> d
datetime.date(2002, 3, 11)
>>> t = d.timetuple()
>>> for i in t:
...     print i
2002                # 年
3                   # 月
11                  # 日
0
0
0
0                   # 曜日 (0 = 月曜日)
70                  # 一年の中で70日目
-1
>>> ic = d.isocalendar()
>>> for i in ic:
...     print i
2002                # ISO 年
11                  # ISO 週番号
1                   # ISO 曜日番号 ( 1 = 月曜日 )
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'

8.1.4. datetime オブジェクト

datetime オブジェクトは date オブジェクトおよび time オブジェクトの全ての情報が入っている単一のオブジェクトです。 date オブジェクトと同様に、 datetime は現在のグレゴリオ暦が両方向に延長されているものと仮定します; また、 time オブジェクトと同様に, datetime は毎日が厳密に 3600*24 秒であると仮定します。

以下にコンストラクタを示します:

class datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])

年、月、および日の引数は必須です。 tzinfo は None または tzinfo クラスのサブクラスのインスタンスにすることができます。残りの引数は整数または長整数で、以下のような範囲に入ります:

MINYEAR <= year <= MAXYEAR

1 <= month <= 12

1 <= day <= 与えられた年と月における日数

0 <= hour < 24

0 <= minute < 60

0 <= second < 60

0 <= microsecond < 1000000

引数がこれらの範囲外にある場合、 ValueError が送出されます。

その他のコンストラクタ、およびクラスメソッドを以下に示します:

classmethod datetime.today()

現在のローカルな datetime を tzinfo が None であるものとして返します。これは datetime.fromtimestamp(time.time()) と等価です。 now(), fromtimestamp() も参照してください。

classmethod datetime.now([tz])

現在のローカルな日付および時刻を返します。オプションの引数 tz が None であるか指定されていない場合、このメソッドは today() と同様ですが、可能ならば time.time() タイムスタンプを通じて得ることができる、より高い精度で時刻を提供します (例えば、プラットフォームが C 関数 gettimeofday() をサポートする場合には可能なことがあります)。

そうでない場合、 tz はクラス tzinfo のサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。この場合、結果は tz.fromutc(datetime.utcnow().replace(tzinfo=tz)) と等価になります。 today(), utcnow() も参照してください。

classmethod datetime.utcnow()

現在の UTC における日付と時刻を、 tzinfo が None であるものとして返します。このメソッドは now() に似ていますが、現在の UTC における日付と時刻を naive な datetime オブジェクトとして返します。 now() も参照してください。

classmethod datetime.fromtimestamp(timestamp[, tz])

time.time() が返すような、 POSIX タイムスタンプに対応するローカルな日付と時刻を返します。オプションの引数 tz が None であるか、指定されていない場合、タイムスタンプはプラットフォームのローカルな日付および時刻に変換され、返される datetime オブジェクトは naive なものになります。

そうでない場合、 tz はクラス tzinfo のサブクラスのインスタンスでなければならず、現在の日付および時刻は tz のタイムゾーンに変換されます。この場合、結果は tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)) と等価になります。

タイムスタンプがプラットフォームの C 関数 localtime() や gmtime() でサポートされている範囲を超えた場合、 fromtimestamp() は ValueError を送出することがあります。この範囲はよく 1970 年から 2038 年に制限されています。うるう秒がタイムスタンプの概念に含まれている非 POSIX システムでは、 fromtimestamp() はうるう秒を無視します。このため、秒の異なる二つのタイムスタンプが同一の datetime オブジェクトとなることが起こり得ます。 utcfromtimestamp() も参照してください。

classmethod datetime.utcfromtimestamp(timestamp)

time.time() が返すような POSIX タイムスタンプに対応する、 UTC での datetime オブジェクトを返します。タイムスタンプがプラットフォームにおける C 関数 localtime() でサポートされている範囲を超えている場合には ValueError を送出します。この値はよく 1970 年から 2038 年に制限されていることがあります。 fromtimestamp() も参照してください。

classmethod datetime.fromordinal(ordinal)

1 年 1 月 1 日を序数 1 とする予測的グレゴリオ暦序数に対応する datetime オブジェクトを返します。 1 <= ordinal <= datetime.max.toordinal() でないかぎり ValueError が送出されます。結果として返されるオブジェクトの時間、分、秒、およびマイクロ秒はすべて 0 となり、 tzinfo は None となります。

classmethod datetime.combine(date, time)

与えられた date オブジェクトと同じデータメンバを持ち、時刻と tzinfo メンバが与えられた time オブジェクトと等しい、新たな datetime オブジェクトを返します。任意の datetime オブジェクト d について、 d == datetime.combine(d.date(), d.timetz()) となります。 date が datetime オブジェクトの場合、その時刻と tzinfo は無視されます。

classmethod datetime.strptime(date_string, format)

date_string に対応した datetime をかえします。 format にしたがって構文解析されます。これは、 datetime(*(time.strptime(date_string, format)[0:6])) と等価です。 date_stringとformatが time.strptime() で構文解析できない場合や、この関数が時刻タプルを返してこない場合には ValueError を送出します。セクション strftime() と strptime() の振る舞い を参照して下さい。

バージョン 2.5 で追加.

以下にクラス属性を示します:

datetime.min

表現できる最も古い datetime で、 datetime(MINYEAR, 1, 1, tzinfo=None) です。

datetime.max

表現できる最も新しい datetime で、 datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None) です。

datetime.resolution

等しくない datetime オブジェクト間の最小の差で、 timedelta(microseconds=1) です。

以下に (読み出し専用の) インスタンス属性を示します:

datetime.year

両端値を含む MINYEAR から MAXYEAR までの値です。

datetime.month

両端値を含む 1 から 12 までの値です。

datetime.day

1 から与えられた月と年における日数までの値です。

datetime.hour

range(24) 内の値です。

datetime.minute

range(60) 内の値です。

datetime.second

range(60) 内の値です。

datetime.microsecond

range(1000000) 内の値です。

datetime.tzinfo

datetime コンストラクタに tzinfo 引数として与えられたオブジェクトになり、何も渡されなかった場合には None になります。

以下にサポートされている演算を示します:

演算 | 結果
datetime2 = datetime1 + timedelta | (1)
datetime2 = datetime1 - timedelta | (2)
timedelta = datetime1 - datetime2 | (3)
datetime1 < datetime2 | datetime を datetime と比較します。 (4)

datetime2 は datetime1 から時間 timedelta 移動したもので、 timedelta.days > 0 の場合進む方向に、 timedelta.days < 0 の場合戻る方向に移動します。結果は入力の datetime と同じ tzinfo を持ち、演算後には datetime2 - datetime1 == timedelta となります。 datetime2.year が MINYEAR よりも小さいか、 MAXYEAR より大きい場合には OverflowError が送出されます。入力が aware なオブジェクトの場合でもタイムゾーン修正は全く行われません。

datetime2 + timedelta == datetime1 となるような datetime2 を計算します。ちなみに、結果は入力の datetime と同じ tzinfo メンバを持ち、入力が aware でもタイムゾーン修正は全く行われません。この操作は date1 + (-timedelta) と等価ではありません。なぜならば、 date1 - timedeltaがオーバフローしない場合でも、-timedelta 単体がオーバフローする可能性があるからです。

datetime から datetime の減算は両方の被演算子が naive であるか、両方とも aware である場合にのみ定義されています。片方が aware でもう一方が naive の場合、 TypeError が送出されます。

両方とも naive か、両方とも aware で同じ tzinfo メンバを持つ場合、 tzinfo メンバは無視され、結果は datetime2 + t == datetime1 であるような timedelta オブジェクト t となります。この場合タイムゾーン修正は全く行われません。

両方が aware で異なる tzinfo メンバを持つ場合、 a-b は a および b をまず naive な UTC datetime オブジェクトに変換したかのようにして行います。演算結果は決してオーバフローを起こさないことを除き、 (a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset()) と同じになります。

datetime1 が時刻として datetime2 よりも前を表す場合に、 datetime1 は datetime2 よりも小さいと見なされます。

被演算子の片方が naive でもう一方が aware の場合、 TypeError が送出されます。両方の被演算子が aware で、同じ tzinfo メンバを持つ場合、共通の tzinfo メンバは無視され、基本の datetime 間の比較が行われます。両方の被演算子が aware で異なる tzinfo メンバを持つ場合、被演算子はまず (self.utcoffset() で得られる) UTC オフセットで修正されます。

ノート

型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために、被演算子のもう一方が datatime オブジェクトと異なる型のオブジェクトの場合には TypeError が送出されます。しかしながら、被比較演算子のもう一方が timetuple() 属性を持つ場合には NotImplemented が返されます。このフックにより、他種の日付オブジェクトに型混合比較を実装するチャンスを与えています。そうでない場合, datetime オブジェクトと異なる型のオブジェクトが比較されると、比較演算子が == または != でないかぎり TypeError が送出されます。後者の場合、それぞれ False または True を返します。

datetime オブジェクトは辞書のキーとして用いることができます。ブール演算コンテキストでは、全ての datetime オブジェクトは真であるとみなされます。

インスタンスメソッドを以下に示します:

datetime.date()

同じ年、月、日の date オブジェクトを返します。

datetime.time()

同じ時、分、秒、マイクロ秒を持つ time オブジェクトを返します。 tzinfo は None です。 timetz() も参照してください。

datetime.timetz()

同じ時、分、秒、マイクロ秒、および tzinfo メンバを持つ time オブジェクトを返します。 time() メソッドも参照してください。

datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])

キーワード引数で指定したメンバの値を除き、同じ値をもつ datetime オブジェクトを返します。メンバに対する変換を行わずに aware な datetime オブジェクトから naive な datetime オブジェクトを生成するために、 tzinfo=None を指定することもできます。

datetime.astimezone(tz)

datetime オブジェクトを返します。返されるオブジェクトは新たな tzinfo メンバ tz を持ちます。 tz は日付および時刻を調整して、オブジェクトが self と同じ UTC 時刻を持つが、 tz におけるローカルな時刻を表すようにします。

tz は tzinfo のサブクラスのインスタンスでなければならず、インスタンスの utcoffset() および dst() メソッドは None を返してはなりません。 self は aware でなくてはなりません (self.tzinfo が None であってはならず、かつ self.utcoffset() は None を返してはなりません)。

self.tzinfo が tz の場合、 self.astimezone(tz) は self に等しくなります: 日付および時刻データメンバに対する調整は行われません。そうでない場合、結果はタイムゾーン tz におけるローカル時刻で、 self と同じ UTC 時刻を表すようになります: astz = dt.astimezone(tz) とした後、 astz - astz.utcoffset() は通常 dt - dt.utcoffset() と同じ日付および時刻データメンバを持ちます。 tzinfo クラスに関する議論では、夏時間 (Daylight Saving time) の遷移境界では上の等価性が成り立たないことを説明しています (tz が標準時と夏時間の両方をモデル化している場合のみの問題です)。

単にタイムゾーンオブジェクト tz を datetime オブジェクト dt に追加したいだけで、日付や時刻データメンバへの調整を行わないのなら、 dt.replace(tzinfo=tz) を使ってください。単に aware な datetime オブジェクト dt からタイムゾーンオブジェクトを除去したいだけで、日付や時刻データメンバの変換を行わないのなら、 dt.replace(tzinfo=None) を使ってください。

デフォルトの tzinfo.fromutc() メソッドを tzinfo のサブクラスで上書きして, astimezone() が返す結果に影響を及ぼすことができます。エラーの場合を無視すると、 astimezone() は以下のように動作します:

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # 自身を UTC に変換し、新しいタイムゾーンオブジェクトをアタッチします
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # UTC から tz のローカルタイムに変換します
    return tz.fromutc(utc)

datetime.utcoffset()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.utcoffset(self) を返します。後者の式が None か、1 日以下の大きさを持つ経過時間を表す timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

datetime.dst()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.dst(self) を返します。後者の式が None か、1 日以下の大きさを持つ経過時間を表す timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

datetime.tzname()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.tzname(self) を返します。後者の式が None か文字列オブジェクトのいずれかを返さない場合には例外を送出します。

datetime.timetuple()

time.localtime() が返す形式の time.struct_time を返します。 d.timetuple() は次の値と等価です: time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst)), ただし yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1 は 1月1日が 1 で始まるその年の中の日の数.

返されるタプルの tm_isdst フラグは dst() メソッドに従って設定されます: tzinfo が None か dst() が None を返す場合、 tm_isdst は -1 に設定されます; そうでない場合、 dst() がゼロでない値を返すと, tm_isdst は 1 となります; それ以外の場合には tm_isdst は 0 に設定されます。

datetime.utctimetuple()

datetime インスタンス d が naive の場合、このメソッドは d.timetuple() と同じであり、 d.dst() の返す内容にかかわらず tm_isdst が 0 に強制される点だけが異なります。 DST が UTC 時刻に影響を及ぼすことは決してありません。

d が aware の場合、 d から d.utcoffset() が差し引かれて UTC 時刻に正規化され、正規化された時刻の time.struct_time を返します。 tm_isdst は 0 に強制されます。 d.year が MINYEAR や MAXUEAR で、UTC への修正の結果表現可能な年の境界を越えた場合には、戻り値の tm_year メンバは MINYEAR-1 または MAXYEAR+1 になることがあります。

datetime.toordinal()

予測的グレゴリオ暦における日付序数を返します。 self.date().toordinal() と同じです。

datetime.weekday()

月曜日を 0、日曜日を 6 として、曜日を整数で返します。 self.date().weekday() と同じです。 isoweekday() も参照してください。

datetime.isoweekday()

月曜日を 1、日曜日を 7 として、曜日を整数で返します。 self.date().isoweekday() と等価です。 weekday() 、 isocalendar() も参照してください。

datetime.isocalendar()

3 要素のタプル (ISO 年、ISO 週番号、ISO 曜日) を返します。 self.date().isocalendar() と等価です。

datetime.isoformat([sep])

日付と時刻を ISO 8601 形式、すなわち YYYY-MM-DDTHH:MM:SS.mmmmmm か、 microsecond が 0 の場合には YYYY-MM-DDTHH:MM:SS で表した文字列を返します。 utcoffset() が None を返さない場合、 UTC からのオフセットを時間と分を表した (符号付きの) 6 文字からなる 文字列が追加されます: すなわち、 YYYY-MM- DDTHH:MM:SS.mmmmmm+HH:MM となるか、 microsecond がゼロの場合には YYYY-MM- DDTHH:MM:SS+HH:MM となります。オプションの引数 sep (デフォルトでは 'T' です) は 1 文字のセパレータで、結果の文字列の日付と時刻の間に置かれます。例えば、

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     def utcoffset(self, dt): return timedelta(minutes=-399)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'

となります。

datetime.__str__()

datetime オブジェクト d において、 str(d) は d.isoformat(' ') と等価です。

datetime.ctime()

日付を表す文字列を、例えば datetime(2002, 12, 4, 20, 30, 40).ctime() == 'Wed Dec  4 20:30:40 2002' のようにして返します。ネイティブの C 関数 ctime() (time.ctime() はこの関数を呼び出しますが、 datetime.ctime() は呼び出しません) が C 標準に準拠しているプラットフォームでは、 d.ctime() は time.ctime(time.mktime(d.timetuple())) と等価です。

datetime.strftime(format)

明示的な書式化文字列で制御された、日付を表現する文字列を返します。 strftime() のふるまいについてのセクション strftime() と strptime() の振る舞い を参照してください。

datetime オブジェクトを使う例:

>>> from datetime import datetime, date, time
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now() or datetime.utcnow()
>>> datetime.now()
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.utcnow()
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:
...     print it
...
2006    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:
...     print it
...
2006    # ISO year
47      # ISO week
2       # ISO weekday
>>> # Formatting datetime
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'

datetime を tzinfo と組み合わせて使う:

>>> from datetime import timedelta, datetime, tzinfo
>>> class GMT1(tzinfo):
...     def __init__(self):         # DST starts last Sunday in March
...         d = datetime(dt.year, 4, 1)   # ends last Sunday in October
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...     def utcoffset(self, dt):
...         return timedelta(hours=1) + self.dst(dt)
...     def dst(self, dt):
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=1)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...          return "GMT +1"
...
>>> class GMT2(tzinfo):
...     def __init__(self):
...         d = datetime(dt.year, 4, 1)
...         self.dston = d - timedelta(days=d.weekday() + 1)
...         d = datetime(dt.year, 11, 1)
...         self.dstoff = d - timedelta(days=d.weekday() + 1)
...     def utcoffset(self, dt):
...         return timedelta(hours=1) + self.dst(dt)
...     def dst(self, dt):
...         if self.dston <=  dt.replace(tzinfo=None) < self.dstoff:
...             return timedelta(hours=2)
...         else:
...             return timedelta(0)
...     def tzname(self,dt):
...         return "GMT +2"
...
>>> gmt1 = GMT1()
>>> # Daylight Saving Time
>>> dt1 = datetime(2006, 11, 21, 16, 30, tzinfo=gmt1)
>>> dt1.dst()
datetime.timedelta(0)
>>> dt1.utcoffset()
datetime.timedelta(0, 3600)
>>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=gmt1)
>>> dt2.dst()
datetime.timedelta(0, 3600)
>>> dt2.utcoffset()
datetime.timedelta(0, 7200)
>>> # Convert datetime to another time zone
>>> dt3 = dt2.astimezone(GMT2())
>>> dt3     # doctest: +ELLIPSIS
datetime.datetime(2006, 6, 14, 14, 0, tzinfo=<GMT2 object at 0x...>)
>>> dt2     # doctest: +ELLIPSIS
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=<GMT1 object at 0x...>)
>>> dt2.utctimetuple() == dt3.utctimetuple()
True

8.1.5. time オブジェクト

time オブジェクトは (ローカルの) 日中時刻を表現します。この時刻表現は特定の日の影響を受けず, tzinfo オブジェクトを介した修正の対象となります。

class datetime.time(hour[, minute[, second[, microsecond[, tzinfo]]]])

全ての引数はオプションです。 tzinfo は None または tzinfo クラスのサブクラスのインスタンスにすることができます。残りの引数は整数または長整数で、以下のような範囲に入ります:

0 <= hour < 24

0 <= minute < 60

0 <= second < 60

0 <= microsecond < 1000000.

引数がこれらの範囲外にある場合、 ValueError が送出されます。 tzinfo のデフォルト値が None である以外のデフォルト値は 0 です。

以下にクラス属性を示します:

time.min

表現できる最も古い datetime で、 time(0, 0, 0, 0) です。 The earliest representable time, time(0, 0, 0, 0).

time.max

表現できる最も新しい datetime で、 time(23, 59, 59, 999999, tzinfo=None) です。

time.resolution

等しくない datetime オブジェクト間の最小の差で、 timedelta(microseconds=1) ですが, time オブジェクト間の四則演算はサポートされていないので注意してください。

以下に (読み出し専用の) インスタンス属性を示します:

time.hour

range(24) 内の値です。

time.minute

range(60) 内の値です。

time.second

range(60) 内の値です。

time.microsecond

range(1000000) 内の値です。

time.tzinfo

time コンストラクタに tzinfo 引数として与えられたオブジェクトになり、何も渡されなかった場合には None になります。

以下にサポートされている操作を示します:

time と time の比較では、 a が時刻として b よりも前を表す場合に a は b よりも小さいと見なされます。被演算子の片方が naive でもう一方が aware の場合、 TypeError が送出されます。両方の被演算子が aware で、同じ tzinfo メンバを持つ場合、共通の tzinfo メンバは無視され、基本の datetime 間の比較が行われます。両方の被演算子が aware で異なる tzinfo メンバを持つ場合、被演算子はまず (self.utcoffset() で得られる) UTC オフセットで修正されます。型混合の比較がデフォルトのオブジェクトアドレス比較となってしまうのを抑止するために, time オブジェクトが他の型のオブジェクトと比較された場合、比較演算子が == または != でないかぎり TypeError が送出されます。後者の場合、それぞれ False または True を返します。

ハッシュ化、辞書のキーとしての利用

効率的な pickle 化

ブール演算コンテキストでは, time オブジェクトは、分に変換し, utfoffset() (None を返した場合には 0) を差し引いて変換した後の結果がゼロでない場合、かつそのときに限って真とみなされます。

以下にインスタンスメソッドを示します:

time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])

キーワード引数で指定したメンバの値を除き、同じ値をもつ time オブジェクトを返します。メンバに対する変換を行わずに aware な datetime オブジェクトから naive な time オブジェクトを生成するために、 tzinfo=None を指定することもできます。

time.isoformat()

日付と時刻を ISO 8601 形式、すなわち HH:MM:SS.mmmmmm か、 microsecond が 0 の場合には HH:MM:SS で表した文字列を返します。 utcoffset() が None を返さない場合、 UTC からのオフセットを時間と分を表した (符号付きの) 6 文字からなる 文字列が追加されます: すなわち、 HH:MM:SS.mmmmmm+HH:MM となるか、 microsecond が 0 の場合には HH:MM:SS+HH:MM となります。

time.__str__()

time オブジェクト t において、 str(t) は t.isoformat() と等価です。

time.strftime(format)

明示的な書式化文字列で制御された、日付を表現する文字列を返します。 strftime() のふるまいについてのセクション strftime() と strptime() の振る舞い を参照してください。

time.utcoffset()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.utcoffset(None) を返します。後者の式が None か、1 日以下の大きさを持つ経過時間を表す timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

time.dst()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.dst(None) を返します。後者の式が None か、 1日以下の大きさを持つ経過時間を表す timedelta オブジェクトのいずれかを返さない場合には例外を送出します。

time.tzname()

tzinfo が None の場合、 None を返し、そうでない場合には self.tzinfo.tzname(None) を返します。後者の式が None か文字列オブジェクトのいずれかを返さない場合には例外を送出します。

使用例:

>>> from datetime import time, tzinfo
>>> class GMT1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1)
...     def dst(self, dt):
...         return timedelta(0)
...     def tzname(self,dt):
...         return "Europe/Prague"
...
>>> t = time(12, 10, 30, tzinfo=GMT1())
>>> t                               # doctest: +ELLIPSIS
datetime.time(12, 10, 30, tzinfo=<GMT1 object at 0x...>)
>>> gmt = GMT1()
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'Europe/Prague'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 Europe/Prague'

8.1.6. tzinfo オブジェクト

tzinfo は抽象基底クラスです。つまり、このクラスは直接インスタンス化して利用しません。具体的なサブクラスを派生し、 (少なくとも) 利用したい datetime のメソッドが必要とする tzinfo の標準メソッドを実装してやる必要があります。 datetime モジュールでは、 tzinfo の具体的なサブクラスは何ら提供していません。

tzinfo (の具体的なサブクラス) のインスタンスは datetime および time オブジェクトのコンストラクタに渡すことができます。後者のオブジェクトでは、データメンバをローカル時刻におけるものとして見ており、 tzinfo オブジェクトはローカル時刻の UTC からのオフセット、タイムゾーンの名前、 DST オフセットを、渡された日付および時刻オブジェクトからの相対で示すためのメソッドを提供します。

pickle 化についての特殊な要求事項: tzinfo のサブクラスは引数なしで呼び出すことのできる __init__() メソッドを持たねばなりません。そうでなければ、 pickle 化することはできますがおそらく unpickle 化することはできないでしょう。これは技術的な側面からの要求であり、将来緩和されるかもしれません。

tzinfo の具体的なサブクラスでは、以下のメソッドを実装する必要があります。厳密にどのメソッドが必要なのかは、 aware な datetime オブジェクトがこのサブクラスのインスタンスをどのように使うかに依存します。不確かならば、単に全てを実装してください。

tzinfo.utcoffset(self, dt)

ローカル時間の UTC からのオフセットを、 UTC から東向きを正とした分で返します。ローカル時間が UTC の西側にある場合、この値は負になります。このメソッドは UTC からのオフセットの総計を返すように意図されているので注意してください; 例えば、 tzinfo オブジェクトがタイムゾーンと DST 修正の両方を表現する場合、 utcoffset() はそれらの合計を返さなければなりません。 UTC オフセットが未知である場合、 None を返してください。そうでない場合には、返される値は -1439 から 1439 の両端を含む値 (1440 = 24*60 ; つまり、オフセットの大きさは 1 日より短くなくてはなりません) が分で指定された timedelta オブジェクトでなければなりません。ほとんどの utcoffset() 実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:

return CONSTANT                 # fixed-offset class
return CONSTANT + self.dst(dt)  # daylight-aware class

utcoffset() が None を返さない場合、 dst() も None を返してはなりません。

utcoffset() のデフォルトの実装は NotImplementedError を送出します。

tzinfo.dst(self, dt)

夏時間 (DST) 修正を、 UTC から東向きを正とした分で返します。 DST 情報が未知の場合、 None が返されます。 DST が有効でない場合には timedelta(0) を返します。 DST が有効の場合、オフセットは timedelta オブジェクトで返します (詳細は utcoffset() を参照してください)。 DST オフセットが利用可能な場合、この値は utcoffset() が返す UTC からのオフセットには既に加算されているため、 DST を個別に取得する必要がない限り dst() を使って問い合わせる必要はないので注意してください。例えば、 datetime.timetuple() は tzinfo メンバの dst() メソッドを呼んで tm_isdst フラグがセットされているかどうか判断し、 tzinfo.fromutc() は dst() タイムゾーンを移動する際に DST による変更があるかどうかを調べます。

標準および夏時間の両方をモデル化している tzinfo サブクラスのインスタンス tz は以下の式:

tz.utcoffset(dt) - tz.dst(dt)

が、 dt.tzinfo == tz 全ての datetime オブジェクト dt について常に同じ結果を返さなければならないという点で、一貫性を持っていなければなりません。正常に実装された tzinfo のサブクラスでは、この式はタイムゾーンにおける “標準オフセット (standard offset)” を表し、特定の日や時刻の事情ではなく地理的な位置にのみ依存していなくてはなりません。 datetime.astimezone() の実装はこの事実に依存していますが、違反を検出することができません; 正しく実装するのはプログラマの責任です。 tzinfo のサブクラスでこれを保証することができない場合、 tzinfo.fromutc() の実装をオーバライドして、 astimezone() に関わらず正しく動作するようにしてもかまいません。

ほとんどの dst() 実装は、おそらく以下の二つのうちの一つに似たものになるでしょう:

def dst(self):
    # a fixed-offset class:  doesn't account for DST
    return timedelta(0)

or

def dst(self):
    # Code to set dston and dstoff to the time zone's DST
    # transition times based on the input dt.year, and expressed
    # in standard local time.  Then

    if dston <= dt.replace(tzinfo=None) < dstoff:
        return timedelta(hours=1)
    else:
        return timedelta(0)

デフォルトの dst() 実装は NotImplementedError を送出します。

tzinfo.tzname(self, dt)

datetime オブジェクト dt に対応するタイムゾーン名を文字列で返します。 datetime モジュールでは文字列名について何も定義しておらず、特に何かを意味するといった要求仕様もまったくありません。例えば、 “GMT”,”UTC”, “-500”, “-5:00”, “EDT”, “US/Eastern”, “America/New York” は全て有効な応答となります。文字列名が未知の場合には None を返してください。 tzinfo のサブクラスでは、特に, tzinfo クラスが夏時間について記述している場合のように、渡された dt の特定の値によって異なった名前を返したい場合があるため、文字列値ではなくメソッドとなっていることに注意してください。

デフォルトの tzname() 実装は NotImplementedError を送出します。

以下のメソッドは datetime や time オブジェクトにおいて、同名のメソッドが呼び出された際に応じて呼び出されます。 datetime オブジェクトは自身を引数としてメソッドに渡し、 time オブジェクトは引数として None をメソッドに渡します。従って、 tzinfo のサブクラスにおけるメソッドは引数 dt が None の場合と、 datetime の場合を受理するように用意しなければなりません。

None が渡された場合、最良の応答方法を決めるのはクラス設計者次第です。例えば、このクラスが tzinfo プロトコルと関係をもたないということを表明させたければ、 None が適切です。標準時のオフセットを見つける他の手段がない場合には、標準 UTC オフセットを返すために utcoffset(None) を使うともっと便利かもしれません。

datetime オブジェクトが datetime() メソッドの応答として返された場合、 dt.tzinfo は self と同じオブジェクトになります。ユーザが直接 tzinfo メソッドを呼び出さないかぎり、 tzinfo メソッドは dt.tzinfo と self が同じであることに依存します。その結果 tzinfo メソッドは dt がローカル時間であると解釈するので、他のタイムゾーンでのオブジェクトの振る舞いについて心配する必要がありません。

tzinfo.fromutc(self, dt)

デフォルトの datetime.astimezone() 実装で呼び出されます。 datetime.astimezone() から呼ばれた場合、 dt.tzinfo は self であり、 dt の日付および時刻データメンバは UTC 時刻を表しているものとして見えます。 fromutc() の目的は、 self のローカル時刻に等しい datetime オブジェクトを返すことにより日付と時刻データメンバを修正することにあります。

ほとんどの tzinfo サブクラスではデフォルトの fromutc() 実装を問題なく継承できます。デフォルトの実装は、固定オフセットのタイムゾーンや、標準時と夏時間の両方について記述しているタイムゾーン、そして DST 移行時刻が年によって異なる場合でさえ、扱えるくらい強力なものです。デフォルトの fromutc() 実装が全ての場合に対して正しく扱うことができないような例は、標準時の (UTCからの) オフセットが引数として渡された特定の日や時刻に依存するもので、これは政治的な理由によって起きることがあります。デフォルトの astimezone() や fromutc() の実装は、結果が標準時オフセットの変化にまたがる何時間かの中にある場合、期待通りの結果を生成しないかもしれません。

エラーの場合のためのコードを除き、デフォルトの fromutc() の実装は以下のように動作します:

def fromutc(self, dt):
    # raise ValueError error if dt.tzinfo is not self
    dtoff = dt.utcoffset()
    dtdst = dt.dst()
    # raise ValueError if dtoff is None or dtdst is None
    delta = dtoff - dtdst  # this is self's standard offset
    if delta:
        dt += delta   # convert to standard local time
        dtdst = dt.dst()
        # raise ValueError if dtdst is None
    if dtdst:
        return dt + dtdst
    else:
        return dt

以下に tzinfo クラスの使用例を示します:

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)
HOUR = timedelta(hours=1)

# A UTC class.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

# A class building tzinfo objects for fixed-offset time zones.
# Note that FixedOffset(0, "UTC") is a different way to build a
# UTC tzinfo object.

class FixedOffset(tzinfo):
    """Fixed offset in minutes east from UTC."""

    def __init__(self, offset, name):
        self.__offset = timedelta(minutes = offset)
        self.__name = name

    def utcoffset(self, dt):
        return self.__offset

    def tzname(self, dt):
        return self.__name

    def dst(self, dt):
        return ZERO

# A class capturing the platform's idea of local time.

import time as _time

STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
    DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
    DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):

    def utcoffset(self, dt):
        if self._isdst(dt):
            return DSTOFFSET
        else:
            return STDOFFSET

    def dst(self, dt):
        if self._isdst(dt):
            return DSTDIFF
        else:
            return ZERO

    def tzname(self, dt):
        return _time.tzname[self._isdst(dt)]

    def _isdst(self, dt):
        tt = (dt.year, dt.month, dt.day,
              dt.hour, dt.minute, dt.second,
              dt.weekday(), 0, -1)
        stamp = _time.mktime(tt)
        tt = _time.localtime(stamp)
        return tt.tm_isdst > 0

Local = LocalTimezone()

# A complete implementation of current DST rules for major US time zones.

def first_sunday_on_or_after(dt):
    days_to_go = 6 - dt.weekday()
    if days_to_go:
        dt += timedelta(days_to_go)
    return dt

# In the US, DST starts at 2am (standard time) on the first Sunday in April.
DSTSTART = datetime(1, 4, 1, 2)
# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
# which is the first Sunday on or after Oct 25.
DSTEND = datetime(1, 10, 25, 1)

class USTimeZone(tzinfo):

    def __init__(self, hours, reprname, stdname, dstname):
        self.stdoffset = timedelta(hours=hours)
        self.reprname = reprname
        self.stdname = stdname
        self.dstname = dstname

    def __repr__(self):
        return self.reprname

    def tzname(self, dt):
        if self.dst(dt):
            return self.dstname
        else:
            return self.stdname

    def utcoffset(self, dt):
        return self.stdoffset + self.dst(dt)

    def dst(self, dt):
        if dt is None or dt.tzinfo is None:
            # An exception may be sensible here, in one or both cases.
            # It depends on how you want to treat them.  The default
            # fromutc() implementation (called by the default astimezone()
            # implementation) passes a datetime with dt.tzinfo is self.
            return ZERO
        assert dt.tzinfo is self

        # Find first Sunday in April & the last in October.
        start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
        end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))

        # Can't compare naive to aware objects, so strip the timezone from
        # dt first.
        if start <= dt.replace(tzinfo=None) < end:
            return HOUR
        else:
            return ZERO

Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
Central  = USTimeZone(-6, "Central",  "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")

標準時間 (standard time) および夏時間 (daylight time) の両方を記述している tzinfo のサブクラスでは、回避不能の難解な問題が年に 2 度あるので注意してください。具体的な例として、東部アメリカ時刻 (US Eastern, UTC -5000) を考えます。 EDT は 3 月の第二日曜日の 1:59 (EST) 以後に開始し、11 月の最初の日曜日の 1:59 (EDT) に終了します:

  UTC   3:MM  4:MM  5:MM  6:MM  7:MM  8:MM
  EST  22:MM 23:MM  0:MM  1:MM  2:MM  3:MM
  EDT  23:MM  0:MM  1:MM  2:MM  3:MM  4:MM

start  22:MM 23:MM  0:MM  1:MM  3:MM  4:MM

  end  23:MM  0:MM  1:MM  1:MM  2:MM  3:MM

DST の開始の際 (“start” の並び) ローカルの壁時計は 1:59 から 3:00 に飛びます。この日は 2:MM の形式をとる時刻は実際には無意味となります。従って、 astimezone(Eastern) は DST が開始する日には hour == 2 となる結果を返すことはありません。 astimezone() がこのことを保証するようにするには、 tzinfo.dst() メソッドは “失われた時間” (東部時刻における 2:MM) が夏時間に存在することを考えなければなりません。

DST が終了する際 (“end” の並び) では、問題はさらに悪化します: 1 時間の間、ローカルの壁時計ではっきりと時刻をいえなくなります: それは夏時間の最後の 1 時間です。東部時刻では、その日の UTC での 5:MM に夏時間は終了します。ローカルの壁時計は 1:59 (夏時間) から 1:00 (標準時) に再び巻き戻されます。ローカルの時刻における 1:MM はあいまいになります。 astimezone() は二つの UTC 時刻を同じローカルの時刻に対応付けることでローカルの時計の振る舞いをまねます。東部時刻の例では、 5:MM および 6:MM の形式をとる UTC 時刻は両方とも、東部時刻に変換された際に 1:MM に対応づけられます。 astimezone() がこのことを保証するようにするには、 tzinfo.dst() は “繰り返された時間” が標準時に存在することを考慮しなければなりません。このことは、例えばタイムゾーンの標準のローカルな時刻に DST への切り替え時刻を表現することで簡単に設定することができます。

このようなあいまいさを許容できないアプリケーションは、ハイブリッドな tzinfo サブクラスを使って問題を回避しなければなりません; UTC や、他のオフセットが固定された tzinfo のサブクラス (EST (-5 時間の固定オフセット) のみを表すクラスや、 EDT (-4 時間の固定オフセット) のみを表すクラス) を使う限り、あいまいさは発生しません。

8.1.7. strftime() と strptime() の振る舞い

date, datetime,および time オブジェクトは全て、明示的な書式化文字列でコントロールして時刻表現文字列を生成するための strftime(format) メソッドをサポートしています。大雑把にいうと、 d.strftime(fmt) は time モジュールの time.strftime(fmt, d.timetuple()) のように動作します。ただし全てのオブジェクトが timetuple() メソッドをサポートしているわけではありません。

逆に datetime.strptime() クラスメソッドは日付や時刻に対応するフォーマット文字列から datetime オブジェクトを生成します。 datetime.strptime(date_string, format) は datetime(*(time.strptime(date_string, format)[0:6])) と等価です。

time オブジェクトでは、年、月、日の値がないため、それらの書式化コードを使うことができません。無理矢理使った場合、年は 1900 に置き換えられ、月と日は 1 に置き換えられます。

date オブジェクトでは、時、分、秒、マイクロ秒の値がないため、それらの書式化コードを使うことができません。無理矢理使った場合、これらの値は 0 に置き換えられます。

バージョン 2.6 で追加: time および、 datetime オブジェクトは、6桁まで0埋めされるマイクロ秒まで拡大された %f 書式をサポートします。

naive オブジェクトでは、書式化コード %z および %Z は空文字列に置き換えられます。

aware オブジェクトでは以下のようになります:

%z

utcoffset() は +HHMM あるいは -HHMM の形式をもった 5 文字の文字列に変換されます。HH は UTC オフセット時間を与える 2 桁の文字列で、 MM は UTC オフセット分を与える 2 桁の文字列です。例えば、 utcoffset() が timedelta(hours=-3, minutes=-30) を返した場合、 %z は文字列 '-0330' に置き換わります。

%Z

tzname() が None を返した場合、 %Z は空文字列に置き換わります。そうでない場合、 %Z は返された値に置き換わりますが、これは文字列でなければなりません。

Python はプラットフォームの C ライブラリから strftime() 関数を呼び出し、プラットフォーム間のバリエーションはよくあることなので、サポートされている書式化コードの全セットはプラットフォーム間で異なります。

以下のリストはC標準(1989年版)が要求する全ての書式化コードで、標準C実装があれば全ての環境で動作します。 1999 年版の C 標準では書式化コードが追加されているので注意してください。

strftime() が正しく動作する年の厳密な範囲はプラットフォーム間で異なります。プラットフォームに関わらず、1900 年以前の年は使うことができません。

指定子 | 意味 | 備考
%a | ロケールの短縮された曜日名を表示します |
%A | ロケールの曜日名を表示します |
%b | ロケールの短縮された月名を表示します |
%B | ロケールの月名を表示します |
%c | ロケールの日時を適切な形式で表示します |
%d | 月中の日にちを10進表記した文字列 [01,31] を表示します |
%f | マイクロ秒を10進表記した文字列 [000000,999999] を表示します (左側から0埋めされます) | (1)
%H | 時 (24時間表記) を10進表記した文字列 [00,23] を表示します |
%I | 時 (12時間表記) を10進表記した文字列 [01,12] を表示します |
%j | 年中の日にちを10進表記した文字列 [001,366] を表示します |
%m | 月を10進表記した文字列 [01,12] を表示します |
%M | 分を10進表記した文字列 [00,59] を表示します |
%p | ロケールの AM もしくは PM を表示します | (2)
%S | 秒を10進表記した文字列 [00,61] を表示します | (3)
%U | 年中の週番号 (週の始まりは日曜日とする) を10進表記した文字列 [00,53] を表示します新年の最初の日曜日に先立つ日は 0週に属するとします | (4)
%w | 曜日を10進表記した文字列 [0(日曜日),6] を表示します |
%W | 年中の週番号 (週の始まりは月曜日とする) を10進表記した文字列 [00,53] を表示します新年の最初の月曜日に先立つ日は 0週に属するとします | (4)
%x | ロケールの日付を適切な形式で表示します |
%X | ロケールの時間を適切な形式で表示します |
%y | 世紀なしの年(下2桁)を10進表記した文字列 [00,99] を表示します |
%Y | 世紀ありの年を10進表記した文字列を表示します |
%z | UTCオフセットを +HHMM もしくは -HHMM の形式で表示します (オブジェクトがnaiveであれば空文字列) | (5)
%Z | タイムゾーンの名前を表示します (オブジェクトがnaiveであれば空文字列) |
%% | 文字 '%' を表示します |

Notes:

strptime() メソッドと共に使われた場合、 %f 指定子は 1 桁から 6 桁の数字を受け付け、右側から 0 埋めされます。 %f は C 標準規格の書式セットに拡張されます。

strptime() メソッドと共に使われた場合、 %p 指定子は出力の時間フィールドのみに影響し、 %I 指定子が使われたかのように振る舞います。

範囲は 0 から 61 で正しいです; これはうるう秒と、 (極めて稀ですが) 2秒のうるう秒を考慮してのことです。

strptime() メソッドと共に使われた場合、 %U と %W 指定子は、年と曜日が指定された場合の計算でのみ使われます。

例えば、 utcoffset() が timedelta(hours=-3, minutes=-30) を返すとしたら、 %z は文字列、 '-0330' で置き換えられます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.2. calendar — 一般的なカレンダーに関する関数群

このモジュールは Unix の cal プログラムのようなカレンダー出力を行い、それに加えてカレンダーに関する有益な関数群を提供します。標準ではこれらのカレンダーは（ヨーロッパの慣例に従って）月曜日を週の始まりとし、日曜日を最後の日としています。 setfirstweekday() を用いることで、日曜日(6)や他の曜日を週の始まりに設定することができます。日付を表す引数は整数値で与えます。関連する機能として、 datetime と time モジュールも参照してください。

このモジュールで提供する関数とクラスのほとんどは datetime に依存しており、過去も未来も現代のグレゴリオ暦を利用します。この方式は Dershowitz と Reingold の書籍「Calendrical Calculations」にある proleptic Gregorian 暦に一致しており、同書では全ての計算の基礎となる暦としています。 [1]

参考

最新バージョンの calendar module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/calendar.py?view=markup]

class calendar.Calendar([firstweekday])

Calendar オブジェクトを作ります。 firstweekday は整数で週の始まりの曜日を指定するものです。 0 が月曜(デフォルト)、 6 なら日曜です。

Calendar オブジェクトは整形されるカレンダーのデータを準備するために使えるいくつかのメソッドを提供しています。しかし整形機能そのものは提供していません。それはサブクラスの仕事なのです。

バージョン 2.5 で追加.

Calendar インスタンスには以下のメソッドがあります。

calendar.iterweekdays(weekday)

曜日の数字を一週間分生成するイテレータを返します。イテレータから得られる最初の数字は firstweekday() が返す数字と同じになります。

calendar.itermonthdates(year, month)

year 年 month 月に対するイテレータを返します。このイテレータはその月の全ての日(datetime.date オブジェクトとして) およびその前後の日で週に欠けが無いようにするのに必要な日を返します。

calendar.itermonthdays2(year, month)

year 年 month 月に対する itermonthdates() と同じようなイテレータを返します。生成されるのは日付の数字と曜日を表す数字のタプルです。

calendar.itermonthdays(year, month)

year 年 month 月に対する itermonthdates() と同じようなイテレータを返します。生成されるのは日付の数字だけです。

calendar.monthdatescalendar(year, month)

year 年 month 月の週のリストを返します。週は全て七つの datetime.date オブジェクトからなるリストです。

calendar.monthdays2calendar(year, month)

year 年 month 月の週のリストを返します。週は全て七つの日付の数字と曜日を表す数字のタプルからなるリストです。

calendar.monthdayscalendar(year, month)

year 年 month 月の週のリストを返します。週は全て七つの日付の数字からなるリストです。

calendar.yeardatescalendar(year[, width])

指定された年のデータを整形に向く形で返します。返される値は月の並びのリストです。月の並びは最大で width ヶ月(デフォルトは3ヶ月)分です。各月は4ないし6週からなり、各週は1ないし7日からなります。各日は datetime.date オブジェクトです。

calendar.yeardays2calendar(year[, width])

指定された年のデータを整形に向く形で返します (yeardatescalendar() と同様です)。週のリストの中が日付の数字と曜日の数字のタプルになります。月の範囲外の部分の日付はゼロです。

calendar.yeardayscalendar(year[, width])

指定された年のデータを整形に向く形で返します (yeardatescalendar() と同様です)。週のリストの中が日付の数字になります。月の範囲外の日付はゼロです。

class calendar.TextCalendar([firstweekday])

このクラスはプレインテキストのカレンダーを生成するのに使えます。

バージョン 2.5 で追加.

TextCalendar インスタンスには以下のメソッドがあります。

formatmonth(theyear, themonth[, w[, l]])

ひと月分のカレンダーを複数行の文字列で返します。 w により日の列幅を変えることができ、それらはセンタリングされます。 l により各週の表示される行数を変えることができます。 setfirstweekday() メソッドでセットされた週の最初の曜日に依存します。

prmonth(theyear, themonth[, w[, l]])

formatmonth() で返されるひと月分のカレンダーを出力します。

formatyear(theyear[, w[, l[, c[, m]]]])

m 列からなる一年間のカレンダーを複数行の文字列で返します。任意の引数 w, l, c はそれぞれ、日付列の表示幅、各週の行数及び月と月の間のスペースの数を変更するためのものです。 setfirstweekday() メソッドでセットされた週の最初の曜日に依存します。カレンダーを出力できる最初の年はプラットフォームに依存します。

pryear(theyear[, w[, l[, c[, m]]]])

formatyear() で返される一年間のカレンダーを出力します。

class calendar.HTMLCalendar([firstweekday])

このクラスは HTML のカレンダーを生成するのに使えます。

バージョン 2.5 で追加.

HTMLCalendar インスタンスには以下のメソッドがあります。

formatmonth(theyear, themonth[, withyear])

ひと月分のカレンダーを HTML のテーブルとして返します。 withyear が真であればヘッダには年も含まれます。そうでなければ月の名前だけが使われます。

formatyear(theyear[, width])

一年分のカレンダーを HTML のテーブルとして返します。 width の値 (デフォルトでは 3 です) は何ヶ月分を一行に収めるかを指定します。

formatyearpage(theyear[, width[, css[, encoding]]])

一年分のカレンダーを一つの完全な HTML ページとして返します。 width の値(デフォルトでは 3 です) は何ヶ月分を一行に収めるかを指定します。 css は使われるカスケーディングスタイルシートの名前です。スタイルシートを使わないようにするために None を渡すこともできます。 encoding には出力に使うエンコーディングを指定します (デフォルトではシステムデフォルトのエンコーディングです)。

class calendar.LocaleTextCalendar([firstweekday[, locale]])

この TextCalendar のサブクラスではコンストラクタにロケール名を渡すことができ、メソッドの返り値で月や曜日が指定されたロケールのものになります。このロケールがエンコーディングを含む場合には、月や曜日の入った文字列はユニコードとして返されます。

バージョン 2.5 で追加.

class calendar.LocaleHTMLCalendar([firstweekday[, locale]])

この HTMLCalendar のサブクラスではコンストラクタにロケール名を渡すことができ、メソッドの返り値で月や曜日が指定されたロケールのものになります。このロケールがエンコーディングを含む場合には、月や曜日の入った文字列はユニコードとして返されます。

バージョン 2.5 で追加.

ノート

これら2つのクラスの formatweekday() と formatmonthname() メソッドは、一時的に現在の locale を指定された locale に変更します。現在の locale はプロセス全体に影響するので、これらはスレッドセーフではありません。

単純なテキストのカレンダーに関して、このモジュールには以下のような関数が提供されています。

calendar.setfirstweekday(weekday)

週の最初の曜日(0 は月曜日, 6 は日曜日)を設定します。定数 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY 及び SUNDAY は便宜上提供されています。例えば、日曜日を週の開始日に設定するときは:

import calendar
calendar.setfirstweekday(calendar.SUNDAY)

バージョン 2.0 で追加.

calendar.firstweekday()

現在設定されている週の最初の曜日を返します。

バージョン 2.0 で追加.

calendar.isleap(year)

year が閏年なら True を、そうでなければ False を返します。

calendar.leapdays(y1, y2)

範囲(y1 ... y2)指定された期間の閏年の回数を返します。ここで y1 や y2 は年を表します。

バージョン 2.0 で変更: Python 1.5.2では、この関数は世紀をまたがった範囲では動作しません。

calendar.weekday(year, month, day)

year (1970–...), month (1–12), day (1–31) で与えられた日の曜日(0 は月曜日)を返します。

calendar.weekheader(n)

短縮された曜日名を含むヘッダを返します。 n は各曜日を何文字で表すかを指定します。

calendar.monthrange(year, month)

year と month で指定された月の一日の曜日と日数を返します。

calendar.monthcalendar(year, month)

月のカレンダーを行列で返します。各行が週を表し、月の範囲外の日は0になります。それぞれの週は setfirstweekday() で設定をしていない限り月曜日から始まります。

calendar.prmonth(theyear, themonth[, w[, l]])

month() 関数によって返される月のカレンダーを出力します。

calendar.month(theyear, themonth[, w[, l]])

TextCalendar の formatmonth() メソッドを利用して、ひと月分のカレンダーを複数行の文字列で返します。

バージョン 2.0 で追加.

calendar.prcal(year[, w[, l[c]]])

calendar() 関数で返される一年間のカレンダーを出力します。

calendar.calendar(year[, w[, l[c]]])

TextCalendar の formatyear() メソッドを利用して、 3列からなる一年間のカレンダーを複数行の文字列で返します。

バージョン 2.0 で追加.

calendar.timegm(tuple)

関連はありませんが便利な関数で、 time モジュールの gmtime() 関数の戻値のような時間のタプルを受け取り、 1970年を起点とし、POSIX規格のエンコードによるUnixのタイムスタンプに相当する値を返します。実際、 time.gmtime() と timegm() は反対の動作をします。

バージョン 2.0 で追加.

calendar モジュールの以下のデータ属性を利用することができます:

calendar.day_name

現在のロケールでの曜日を表す配列です。

calendar.day_abbr

現在のロケールでの短縮された曜日を表す配列です。

calendar.month_name

現在のロケールでの月の名を表す配列です。この配列は通常の約束事に従って、 1月を数字の 1 で表しますので、長さが 13 ある代わりに month_name[0] が空文字列になります。

calendar.month_abbr

現在のロケールでの短縮された月の名を表す配列です。この配列は通常の約束事に従って、1月を数字の 1 で表しますので、長さが 13 ある代わりに month_name[0] が空文字列になります。

参考

Module datetime

time モジュールと似た機能を持った日付と時間用のオブジェクト指向インタフェース。

Module time

低レベルの時間に関連した関数群。

注記

[1]
訳注: proleptic Gregorian 暦とはグレゴリオ暦制定(1582年)以前についてもグレゴリオ暦で言い表す暦の方式のことで ISO 8601 などでも採用されています

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.3. collections — 高性能なコンテナ・データ型

バージョン 2.4 で追加.

このモジュールは、汎用の Python 組み込みコンテナ dict, list, set, および tuple に代わる、特殊なコンテナデータ型を実装しています。

namedtuple()
名前付きフィールドを持つタプルのサブクラスを作成するファクトリ関数

バージョン 2.6 で追加.

deque
両端における append や pop を高速に行えるリスト風のコンテナ

バージョン 2.4 で追加.

Counter
ハッシュ可能なオブジェクトを数え上げる辞書のサブクラス

バージョン 2.7 で追加.

OrderedDict
項目が追加された順序を記憶する辞書のサブクラス

バージョン 2.7 で追加.

defaultdict
ファクトリ関数を呼び出して存在しない値を供給する辞書のサブクラス

バージョン 2.5 で追加.

コンテナ型の作成に加えて、 collections モジュールは幾つかの ABC (abstract base classes = 抽象基底クラス) を提供しています。 ABC はクラスが特定のインタフェース持っているかどうか、たとえばハッシュ可能であるかやマッピングであるかを判定するのに利用します。

参考

Latest version of the collections module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/collections.py?view=markup]

8.3.1. Counter オブジェクト

便利で迅速な検数をサポートするカウンタツールが提供されています。例えば:

>>> # リストに現れる単語の検数
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
...     cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # Hamlet で最も多い 10 単語の発見
>>> import re
>>> words = re.findall('\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]

class collections.Counter([iterable-or-mapping])

Counter はハッシュ可能なオブジェクトをカウントする dict のサブクラスです。これは、要素を辞書のキーとして保存し、そのカウントを辞書の値として保存する、順序付けされていないコレクションです。カウントは、0 や負のカウントを含む整数値をとれます。 Counter クラスは、他の言語のバッグや多重集合のようなものです。

要素は、 iterable から数え上げられたり、他の mapping (やカウンタ) から初期化されます:

>>> c = Counter()                           # 新しい空のカウンタ
>>> c = Counter('gallahad')                 # イテラブルからの新しいカウンタ
>>> c = Counter({'red': 4, 'blue': 2})      # マッピングからの新しいカウンタ
>>> c = Counter(cats=4, dogs=8)             # キーワード引数からの新しいカウンタ

カウンタオブジェクトは辞書のインタフェースを持ちますが、存在しない要素に対して KeyError を送出する代わりに 0 を返すという違いがあります:

>>> c = Counter(['eggs', 'ham'])
>>> c['bacon']                              # 存在しない要素のカウントは 0
0

カウントを 0 に設定しても、要素はカウンタから取り除かれません。完全に取り除くには、 del を使ってください:

>>> c['sausage'] = 0                        # カウントが 0 のカウンタの項目
>>> del c['sausage']                        # del は項目を実際に取り除く

バージョン 2.7 で追加.

カウンタオブジェクトは、すべての辞書に利用できるものに加え、 3 つのメソッドをサポートしています:

elements()

それぞれの要素を、そのカウント分の回数だけ繰り返すイテレータを返します。要素は任意の順序で返されます。ある要素のカウントが 1 未満なら、 elements() はそれを無視します。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']

most_common([n])

最も多い n 要素を、カウントが多いものから少ないものまで順に並べたリストを返します。 n が指定されなければ、 most_common() はカウンタの すべての 要素を返します。等しいカウントの要素は任意に並べられます:

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

subtract([iterable-or-mapping])

要素から iterable の要素または mapping の要素が引かれます。 dict.update() に似ていますが、カウントを置き換えるのではなく引きます。入力も出力も、 0 や負になりえます。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

普通の辞書のメソッドは、以下の 2 つのメソッドがカウンタに対して異なる振る舞いをするのを除き、 Counter オブジェクトにも利用できます。

fromkeys(iterable)

このクラスメソッドは Counter オブジェクトには実装されていません。

update([iterable-or-mapping])

要素が iterable からカウントされるか、別の mapping (やカウンタ) が追加されます。 dict.update() に似ていますが、カウントを置き換えるのではなく追加します。また、 iterable には (key, value) 対のシーケンスではなく、要素のシーケンスが求められます。

Counter オブジェクトを使ったよくあるパターン:

sum(c.values())                 # すべてのカウントの合計
c.clear()                       # すべてのカウントをリセット
list(c)                         # 単一の要素として列挙
set(c)                          # 集合に変換
dict(c)                         # 普通の辞書に変換
c.items()                       # (elem, cnt) 対のリストに変換
Counter(dict(list_of_pairs))    # (elem, cnt) 対のリストから変換
c.most_common()[:-n:-1]         # 最も少ない n 要素
c += Counter()                  # 0 と負の要素を取り除く

Counter オブジェクトを組み合わせて多重集合 (1 以上のカウントをもつカウンタ) を作るために、いくつかの数学演算が提供されています。足し算と引き算は、対応する要素を足したり引いたりすることによってカウンタを組み合わせます。共通部分と合併集合は、対応するカウントの最大値と最小値を返します。それぞれの演算はカウントに符号がついた入力を受け付けますが、カウントが 0 以下である結果は出力から除かれます。

>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d                       # 2 つのカウンタを足し合わせる:  c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d                       # 引く (正のカウンタだけを残す)
Counter({'a': 2})
>>> c & d                       # 共通部分:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d                       # 合併集合:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})

ノート

カウンタはもともと、推移するカウントを正の整数で表すために設計されました。しかし、他の型や負の値を必要とするユースケースを不必要に排除することがないように配慮されています。このようなユースケースの助けになるように、この節で最低限の範囲と型の制限について記述します。

Counter クラス自体は辞書のサブクラスで、キーと値に制限はありません。値はカウントを表す数であることを意図していますが、値フィールドに任意のものを保存 できます。

most_common() メソッドが要求するのは、値が順序付け可能なことだけです。

c[key] += 1 のようなインプレース演算では、値の型に必要なのは足し算と引き算ができることだけです。よって分数、浮動小数点数、小数も使え、負の値がサポートされています。これと同じことが、負や 0 の値を入力と出力に許す update() と subtract() メソッドにも言えます。

多重集合メソッドは正の値を扱うユースケースに対してのみ設計されています。入力は負や 0 に出来ますが、正の値の出力のみが生成されます。型の制限はありませんが、値の型は足し算、引き算、比較をサポートしている必要があります。

elements() メソッドは整数のカウントを要求します。これは 0 と負のカウントを無視します。

参考

Python 2.5 に適応する Counter class [http://code.activestate.com/recipes/576611/] と Python 2.4 のための早期の Bag recipe [http://code.activestate.com/recipes/259174/]。

Smalltalk の Bag class [http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html]

Wikipedia の Multisets [http://en.wikipedia.org/wiki/Multiset] の項目。

C++ multisets [http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm] の例を交えたチュートリアル。

数学的な多重集合の演算とそのユースケースは、 Knuth, Donald. The Art of Computer Programming Volume II, Section 4.6.3, Exercise 19 を参照してください。

与えられた要素の集まりから与えられた大きさの別個の多重集合をすべて数え上げるには、 itertools.combinations_with_replacement() を参照してください。

map(Counter, combinations_with_replacement(‘ABC’, 2)) –> AA AB AC BB BC CC

8.3.2. deque オブジェクト

class collections.deque([iterable[, maxlen]])

iterable で与えられるデータから、新しい deque オブジェクトを (append() をつかって) 左から右に初期化して返します。 iterable が指定されない場合、新しい deque オブジェクトは空になります。

Deque とは、スタックとキューを一般化したものです (この名前は「デック」と発音され、これは「double-ended queue」の省略形です)。Deque はどちらの側からも append と pop が可能で、スレッドセーフでメモリ効率がよく、どちらの方向からもおよそ O(1) のパフォーマンスで実行できます。

list オブジェクトでも同様の操作を実現できますが、これは高速な固定長の操作に特化されており、内部のデータ表現形式のサイズと位置を両方変えるような pop(0) や insert(0, v) などの操作ではメモリ移動のために O(n) のコストを必要とします。

バージョン 2.4 で追加.

maxlen が指定され無かったり None だった場合、 deque は不定のサイズまで大きくなります。それ以外の場合、 deque は指定された最大長に制限されます。長さが制限された deque がいっぱいになると、新しい要素を追加するときに追加した要素数分だけ追加した逆側から要素が捨てられます。長さが制限された deque は Unix における tail フィルタと似た機能を提供します。トランザクションの tracking や最近使った要素だけを残したいデータプール (pool of data) などにも便利です。

バージョン 2.6 で変更: maxlen パラメータを追加しました。

Deque オブジェクトは以下のようなメソッドをサポートしています:

append(x)

x を deque の右側につけ加えます。

appendleft(x)

x を deque の左側につけ加えます。

clear()

deque からすべての要素を削除し、長さを 0 にします。

count(x)

x に等しい deque の要素を数え上げます。

バージョン 2.7 で追加.

extend(iterable)

イテレータ化可能な引数 iterable から得られる要素を deque の右側に追加し拡張します。

extendleft(iterable)

イテレータ化可能な引数 iterable から得られる要素を deque の左側に追加し拡張します。注意: 左から追加した結果は、イテレータ引数の順序とは逆になります。

pop()

deque の右側から要素をひとつ削除し、その要素を返します。要素がひとつも存在しない場合は IndexError を発生させます。

popleft()

deque の左側から要素をひとつ削除し、その要素を返します。要素がひとつも存在しない場合は IndexError を発生させます。

remove(value)

最初に現れる value を削除します。要素がみつからないない場合は ValueError を発生させます。

バージョン 2.5 で追加.

reverse()

deque の要素をインプレースに逆転し、 None を返します。

バージョン 2.7 で追加.

rotate(n)

deque の要素を全体で n ステップだけ右にローテートします。 n が負の値の場合は、左にローテートします。Deque をひとつ右にローテートすることは d.appendleft(d.pop()) と同じです。

deque オブジェクトは読み取り専用属性も 1 つ提供しています。

maxlen

deque の最大長で、制限されていなければ None です。

バージョン 2.7 で追加.

上記の操作のほかにも、deque は次のような操作をサポートしています: イテレータ化、pickle、 len(d), reversed(d), copy.copy(d), copy.deepcopy(d), in 演算子による包含検査、そして d[-1] などの添え字による参照。両端についてインデックスアクセスは O(1) ですが、中央部分については O(n) の遅さです。高速なランダムアクセスが必要ならリストを使ってください。

例:

>>> from collections import deque
>>> d = deque('ghi')                 # 3つの要素からなる新しい deque をつくる。
>>> for elem in d:                   # deque の要素をひとつずつたどる。
...     print elem.upper()
G
H
I

>>> d.append('j')                    # 新しい要素を右側につけたす。
>>> d.appendleft('f')                # 新しい要素を左側につけたす。
>>> d                                # deque の表現形式。
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # いちばん右側の要素を削除し返す。
'j'
>>> d.popleft()                      # いちばん左側の要素を削除し返す。
'f'
>>> list(d)                          # deque の内容をリストにする。
['g', 'h', 'i']
>>> d[0]                             # いちばん左側の要素をのぞく。
'g'
>>> d[-1]                            # いちばん右側の要素をのぞく。
'i'

>>> list(reversed(d))                # deque の内容を逆順でリストにする。
['i', 'h', 'g']
>>> 'h' in d                         # deque を検索。
True
>>> d.extend('jkl')                  # 複数の要素を一度に追加する。
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # 右ローテート
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # 左ローテート
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # 新しい deque を逆順でつくる。
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # deque を空にする。
>>> d.pop()                          # 空の deque からは pop できない。
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in -toplevel-
    d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() は入力を逆順にする。
>>> d
deque(['c', 'b', 'a'])

8.3.3. deque のレシピ

この節では deque をつかったさまざまなアプローチを紹介します。

長さが制限された deque は Unix における tail フィルタに相当する機能を提供します:

def tail(filename, n=10):
    'ファイルの最後の n 行を返す.'
    return deque(open(filename), n)

別のアプローチとして deque を右に append して左に pop して使うことで追加した要素を維持するのに使えます:

def moving_average(iterable, n=3):
    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
    # http://en.wikipedia.org/wiki/Moving_average
    it = iter(iterable)
    d = deque(itertools.islice(it, n-1))
    d.appendleft(0)
    s = sum(d)
    for elem in it:
        s += elem - d.popleft()
        d.append(elem)
        yield s / float(n)

rotate() メソッドのおかげで、 deque の一部を切り出したり削除したりできることになります。たとえば del d[n] の純粋な Python 実装では pop したい要素まで rotate() します

def delete_nth(d, n):
    d.rotate(-n)
    d.popleft()
    d.rotate(n)

deque の切り出しを実装するのにも、同様のアプローチを使います。まず対象となる要素を rotate() によって deque の左端までもってきてから、 popleft() をつかって古い要素を消します。そして、 extend() で新しい要素を追加したのち、逆のローテートでもとに戻せばよいのです。このアプローチをやや変えたものとして、Forth スタイルのスタック操作、つまり dup, drop, swap, over, pick, rot, および roll を実装するのも簡単です。

8.3.4. defaultdict オブジェクト

class collections.defaultdict([default_factory[, ...]])

新しいディクショナリ状のオブジェクトを返します。 defaultdict は組込みの dict のサブクラスです。メソッドをオーバーライドし、書き込み可能なインスタンス変数を1つ追加している以外は dict クラスと同じです。同じ部分については以下では省略されています。

1つめの引数は default_factory 属性の初期値です。デフォルトは None です。残りの引数はキーワード引数もふくめ、 dict のコンストラクタにあたえられた場合と同様に扱われます。

バージョン 2.5 で追加.

defaultdict オブジェクトは標準の dict に加えて、以下のメソッドを実装しています:

__missing__(key)

もし default_factory 属性が None であれば、このメソッドは KeyError 例外を、 key を引数として発生させます。

もし default_factory 属性が None でなければ、このメソッドは default_factory を引数なしで呼び出し、あたえられた key に対応するデフォルト値を作ります。そしてこの値を key に対応する値を辞書に登録して返ります。

もし default_factory の呼出が例外を発生させた場合には、変更せずそのまま例外を投げます。

このメソッドは dict クラスの __getitem__() メソッドで、キーが存在しなかった場合によびだされます。値を返すか例外を発生させるのどちらにしても、 __getitem__() からもそのまま値が返るか例外が発生します。

defaultdict オブジェクトは以下のインスタンス変数をサポートしています:

default_factory

この属性は __missing__() メソッドによって使われます。これは存在すればコンストラクタの第1引数によって初期化され、そうでなければ None になります。

8.3.4.1. defaultdict の使用例

list を default_factory とすることで、キー=値ペアのシーケンスをリストの辞書へ簡単にグループ化できます。:

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

それぞれのキーが最初に登場したとき、マッピングにはまだ存在しません。そのためエントリは default_factory 関数が返す空の list を使って自動的に作成されます。 list.append() 操作は新しいリストに紐付けられます。キーが再度出現下場合には、通常の参照動作が行われます(そのキーに対応するリストが返ります)。そして list.append() 操作で別の値をリストに追加します。このテクニックは dict.setdefault() を使った等価なものよりシンプルで速いです:

>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

default_factory を int にすると、 defaultdict を(他の言語の bag や multisetのように)要素の数え上げに便利に使うことができます:

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]

最初に文字が出現したときは、マッピングが存在しないので default_factory 関数が int() を呼んでデフォルトのカウント0を生成します。インクリメント操作が各文字を数え上げます。

常に0を返す int() は特殊な関数でした。定数を生成するより速くて柔軟な方法は、 0に限らず何でも定数を生成する itertools.repeat() を使うことです。

>>> def constant_factory(value):
...     return itertools.repeat(value).next
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'

default_factory を set に設定することで、 defaultdict をセットの辞書を作るために利用することができます:

>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> d.items()
[('blue', set([2, 4])), ('red', set([1, 3]))]

8.3.5. namedtuple() 名前付きフィールドを持つタプルのファクトリ関数

名前付きタプルはタプルの中の場所に意味を割り当てて、より読みやすく自己解説的なコードを書けるようにします。通常のタプルが利用されていた場所で利用でき、場所に対するインデックスの代わりに名前を使ってフィールドにアクセスできます。

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])

typename という名前の tuple の新しいサブクラスを返します。新しいサブクラスは、 tuple に似ているけれどもインデックスやイテレータだけでなく属性名によるアクセスもできるオブジェクトを作るのに使います。このサブクラスのインスタンスは、わかりやすい docstring (型名と属性名が入っています) や、 tuple の内容を name=value という形のリストで返す使いやすい __repr__() も持っています。

field_names は ['x', 'y'] のような文字列のシーケンスです。 field_names には、代わりに各属性名を空白文字 (whitespace) および/またはカンマ (,) で区切った文字列を渡すこともできます。例えば、 'x y' や 'x, y' です。

アンダースコア (_) で始まる名前を除いて、 Python の正しい識別子 (identifier) ならなんでも属性名として使うことができます。正しい識別子とはアルファベット(letters), 数字(digits), アンダースコア(_) を含みますが、数字やアンダースコアで始まる名前や、 class, for, return, global, pass, print, raise などといった keyword は使えません。

rename が真なら、不適切なフィールド名は自動的に位置引数に置き換えられます。例えば ['abc', 'def', 'ghi', 'abc'] は、予約語 def と重複しているフィールド名 abc が除去され、 ['abc', '_1', 'ghi', '_3'] に変換されます。

verbose が真なら、クラスを作る直前にクラス定義が表示されます。

名前付きタプルのインスタンスはインスタンスごとの辞書を持たないので、軽量で、普通のタプル以上のメモリを使用しません。

バージョン 2.6 で追加.

バージョン 2.7 で変更: rename のサポートを追加しました。

例:

>>> Point = namedtuple('Point', ['x', 'y'], verbose=True)
class Point(tuple):
        'Point(x, y)'

        __slots__ = ()

        _fields = ('x', 'y')

        def __new__(_cls, x, y):
            'Create a new instance of Point(x, y)'
            return _tuple.__new__(cls, (x, y))

        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new Point object from a sequence or iterable'
            result = new(cls, iterable)
            if len(result) != 2:
                raise TypeError('Expected 2 arguments, got %d' % len(result))
            return result

        def __repr__(self):
            'Return a nicely formatted representation string'
            return 'Point(x=%r, y=%r)' % self

        def _asdict(self):
            'Return a new OrderedDict which maps field names to their values'
            return OrderedDict(zip(self._fields, self))

        def _replace(_self, **kwds):
            'Return a new Point object replacing specified fields with new values'
            result = _self._make(map(kwds.pop, ('x', 'y'), _self))
            if kwds:
                raise ValueError('Got unexpected field names: %r' % kwds.keys())
            return result

        def __getnewargs__(self):
            'Return self as a plain tuple.   Used by copy and pickle.'
            return tuple(self)

        x = _property(_itemgetter(0), doc='Alias for field number 0')
        y = _property(_itemgetter(1), doc='Alias for field number 1')

>>> Point = namedtuple('Point', 'x y')
>>> p = Point(11, y=22)     # 順序による引数やキーワード引数を使ってインスタンス化
>>> p[0] + p[1]             # 通常の tuple (11, 22) と同じようにインデックスアクセス
33
>>> x, y = p                # 通常の tuple と同じようにアンパック
>>> x, y
(11, 22)
>>> p.x + p.y               # 名前でフィールドにアクセス
33
>>> p                       # name=value スタイルの読みやすい __repr__
Point(x=11, y=22)

名前付きタプルは csv や sqlite3 モジュールが返すタプルのフィールドに名前を付けるときにとても便利です:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print emp.name, emp.title

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
    print emp.name, emp.title

タプルから継承したメソッドに加えて、名前付きタプルは3つの追加メソッドと一つの属性をサポートしています。フィールド名との衝突を避けるためにメソッド名と属性名はアンダースコアで始まります。

classmethod somenamedtuple._make(iterable)

既存の sequence や Iterable から新しいインスタンスを作るクラスメソッド.

>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)

somenamedtuple._asdict()

フィールド名を対応する値にマッピングする新しい順序付き辞書 (OrderedDict) を返します:

>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])

バージョン 2.7 で変更: 通常の dict の代わりに OrderedDict を返すようになりました。

somenamedtuple._replace(kwargs)

指定されたフィールドを新しい値で置き換えた、新しい名前付きタプルを作って返します:

>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)

>>> for partnum, record in inventory.items():
        inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())

somenamedtuple._fields

フィールド名をリストにしたタプル. 内省 (introspection) したり、既存の名前付きタプルをもとに新しい名前つきタプルを作成する時に便利です。

>>> p._fields            # view the field names
('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)

文字列に格納された名前を使って名前つきタプルから値を取得するには getattr() 関数を使います:

>>> getattr(p, 'x')
11

辞書を名前付きタプルに変換するには、 ** 演算子 (double-star-operator, 引数リストのアンパック で説明しています) を使います。:

>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)

名前付きタプルは通常の Python クラスなので、継承して機能を追加したり変更するのは容易です。次の例では計算済みフィールドと固定幅の print format を追加しています:

>>> class Point(namedtuple('Point', 'x y')):
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7.):
        print p
Point: x= 3.000  y= 4.000  hypot= 5.000
Point: x=14.000  y= 0.714  hypot=14.018

このサブクラスは __slots__ に空のタプルをセットしています。これにより、インスタンス辞書の作成を抑制してメモリ使用量を低く保つのに役立ちます。

サブクラス化は新しいフィールドを追加するのには適していません。代わりに、新しい名前付きタプルを _fields 属性を元に作成してください:

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

_replace() でプロトタイプのインスタンスをカスタマイズする方法で、デフォルト値を実現できます。

>>> Account = namedtuple('Account', 'owner balance transaction_count')
>>> default_account = Account('<owner name>', 0.0, 0)
>>> johns_account = default_account._replace(owner='John')

列挙型定数は名前付きタプルでも実装できますが、クラス定義を利用した方がシンプルで効率的です:

>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))
>>> Status.open, Status.pending, Status.closed
(0, 1, 2)
>>> class Status:
        open, pending, closed = range(3)

参考

Named tuple recipe [http://code.activestate.com/recipes/500261/] は Python 2.4 で使えます。

8.3.6. OrderedDict オブジェクト

順序付き辞書 (ordered dictionary) は、ちょうど普通の辞書と同じようなものですが、項目が挿入された順序を記憶します。順序付き辞書に渡ってイテレートするとき、項目はそのキーが最初に追加された順序で返されます。

class collections.OrderedDict([items])

通常の dict メソッドをサポートする、辞書のサブクラスのインスタンスを返します。 OrderedDict は、キーが最初に追加された順序を記憶します。新しい項目が既存の項目を上書きしても、元の挿入位置は変わらないままです。項目を削除して再挿入するとそれが最後に移動します。

バージョン 2.7 で追加.

OrderedDict.popitem(last=True)

順序付き辞書の popitem() メソッドは、(key, value) 対を返して消去します。この対は last が真なら後入先出で、偽なら先入先出で返されます。

通常のマッピングのメソッドに加え、順序付き辞書は reversed() による逆順の反復もサポートしています。

OrderedDict 間の等価判定は順序に影響され、 list(od1.items())==list(od2.items()) として実装されます。 OrderedDict オブジェクトと他のマッピング (Mapping) オブジェクトの等価判定は、順序に影響されず、通常の辞書と同様です。これによって、 OrderedDict オブジェクトは通常の辞書が使われるところならどこでも代用できます。

OrderedDict コンストラクタと update() メソッドは、どちらもキーワード引数を受け付けますが、その順序は失われます。これは、Python の関数呼び出しの意味づけにおいて、キーワード引数は順序付けされていない辞書を用いて渡されるからです。

参考

Equivalent OrderedDict recipe [http://code.activestate.com/recipes/576693/] that runs on Python 2.4 or later.

8.3.6.1. OrderedDict の例とレシピ

順序付き辞書は挿入順序を記憶するので、ソートと組み合わせて使うことで、ソートされた辞書を作れます:

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

この新しい順序付き辞書は、項目が削除されてもソートされた順序を保持します。しかし、キーが追加されるとき、そのキーは最後に追加され、ソートは保持されません。

キーが 最後に 挿入された順序を記憶するような、順序付き辞書の変種を作るのも簡単です。新しい項目が既存の項目を上書きしたら、元の挿入位置は最後に移動します:

class LastUpdatedOrderedDict(OrderedDict):

    'Store items in the order the keys were last added'
    def __setitem__(self, key, value):
        if key in self:
            del self[key]
        OrderedDict.__setitem__(self, key, value)

順序付き辞書は、 Counter クラスと組み合わせてカウンタに要素が最初に現れた順序を記憶させられます:

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first encountered'

     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

8.3.7. ABCs - abstract base classes

collections モジュールは以下の ABC (抽象基底クラス) を提供します:

ABC | 継承しているクラス | 抽象メソッド | mixin メソッド
Container |  | __contains__ |
Hashable |  | __hash__ |
Iterable |  | __iter__ |
Iterator | Iterable | next | __iter__
Sized |  | __len__ |
Callable |  | __call__ |
Sequence | Sized, Iterable, Container | __getitem__ | __contains__. __iter__, __reversed__. index, count
MutableSequence | Sequence | __setitem__ __delitem__, insert, | Sequence から継承したメソッドと、 append, reverse, extend, pop, remove, __iadd__
Set | Sized, Iterable, Container |  | __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, and isdisjoint
MutableSet | Set | add, discard | Set から継承したメソッドと、 clear, pop, remove, __ior__, __iand__, __ixor__, __isub__
Mapping | Sized, Iterable, Container | __getitem__ | __contains__, keys, items, values, get, __eq__, __ne__
MutableMapping | Mapping | __setitem__ __detitem__, | Mapping から継承したメソッドと、 pop, popitem, clear, update, setdefault
MappingView | Sized |  | __len__
KeysView | MappingView, Set |  | __contains__, __iter__
ItemsView | MappingView, Set |  | __contains__, __iter__
ValuesView | MappingView |  | __contains__, __iter__

class collections.Container

class collections.Hashable

class collections.Sized

class collections.Callable

それぞれメソッド __contains__(), __hash__(), __len__(), and __call__() を提供するクラスの ABC です。

class collections.Iterable

__iter__() メソッドを提供するクラスの ABC です。 iterable の定義も参照してください。

class collections.Iterator

__iter__() および next() メソッドを提供するクラスの ABC です。 iterator の定義も参照してください。

class collections.Sequence

class collections.MutableSequence

読み込み専用と、ミュータブルな シーケンス の ABC です。

class collections.Set

class collections.MutableSet

読み込み専用と、ミュータブルな集合の ABC です。

class collections.Mapping

class collections.MutableMapping

読み込み専用と、ミュータブルな マッピング の ABC です。

class collections.MappingView

class collections.ItemsView

class collections.KeysView

class collections.ValuesView

マッピング、要素、キー、値の view の ABC です。

これらの ABC はクラスやインスタンスが特定の機能を提供しているかどうかを調べるのに使えます。例えば:

size = None
if isinstance(myvar, collections.Sized):
   size = len(myvar)

幾つかの ABC はコンテナ型 API を提供するクラスを開発するのを助ける mixin 型としても使えます。例えば、 Set API を提供するクラスを作る場合、3つの基本になる抽象メソッド __contains__(), __iter__(), __len__() だけが必要です。 ABC が残りの __and__() や isdisjoint() といったメソッドを提供します:

class ListBasedSet(collections.Set):
     ''' 速度よりもメモリ使用量を重視して、 hashable も提供しない
         set の別の実装 '''
     def __init__(self, iterable):
         self.elements = lst = []
         for value in iterable:
             if value not in lst:
                 lst.append(value)
     def __iter__(self):
         return iter(self.elements)
     def __contains__(self, value):
         return value in self.elements
     def __len__(self):
         return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2            # __and__() は ABC により自動的に提供される

Set と MutableSet を mixin型として利用するときの注意点:

幾つかの set の操作は新しい set を作るので、デフォルトの mixin メソッドは iterable から新しいインスタンスを作成する方法を必要とします。クラスのコンストラクタは ClassName(iterable) の形のシグネチャを持つと仮定されます。内部の _from_iterable() というクラスメソッドが cls(iterable) を呼び出して新しい set を作る部分でこの仮定が使われています。コンストラクタのシグネチャが異なるクラスで Set を使う場合は、 iterable 引数から新しいインスタンスを生成するように _from_iterable() をオーバーライドする必要があります。

(たぶん意味はそのままに速度を向上する目的で)比較をオーバーライドする場合、 __le__() だけを再定義すれば、その他の演算は自動的に追随します。

Set mixin型は set のハッシュ値を計算する _hash() メソッドを提供しますが、すべての set が hashable や immutable とは限らないので、 __hash__() は提供しません。 mixin を使って hashable な set を作る場合は、 Set と Hashable の両方を継承して、 __hash__ = Set._hash と定義してください。

参考

Latest version of the Python source code for the collections abstract base classes [http://svn.python.org/view/python/branches/release27-maint/Lib/_abcoll.py?view=markup]

MutableSet を使った例として OrderedSet recipe [http://code.activestate.com/recipes/576694/]

ABCs についての詳細は、 abc モジュールと PEP 3119 [http://www.python.org/dev/peps/pep-3119] を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.4. heapq — ヒープキューアルゴリズム

バージョン 2.3 で追加.

このモジュールではヒープキューアルゴリズムの一実装を提供しています。優先度キューアルゴリズムとしても知られています。

参考

Latest version of the heapq Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/heapq.py?view=markup]

ヒープとは、全ての親ノードの値が、その全ての子の値以下であるようなバイナリツリーです。この実装は、全ての k に対して、ゼロから要素を数えていった際に、 heap[k] <= heap[2*k+1] かつ heap[k] <= heap[2*k+2] となる配列を使っています。比較のために、存在しない要素は無限大として扱われます。ヒープの興味深い性質は、最小の要素が常にルート、つまり heap[0] になることです。

以下の API は教科書におけるヒープアルゴリズムとは 2 つの側面で異なっています: (a) ゼロベースのインデクス化を行っています。これにより、ノードに対するインデクスとその子ノードのインデクスの関係がやや明瞭でなくなりますが、 Python はゼロベースのインデクス化を使っているのでよりしっくりきます。 (b) われわれの pop メソッドは最大の要素ではなく最小の要素 (教科書では “min heap:最小ヒープ” と呼ばれています; 教科書では並べ替えをインプレースで行うのに適した “max heap:最大ヒープ” が一般的です)。

これらの 2 点によって、ユーザに戸惑いを与えることなく、ヒープを通常の Python リストとして見ることができます: heap[0] が最小の要素となり、 heap.sort() はヒープ不変式を保ちます!

ヒープを作成するには、 [] に初期化されたリストを使うか、 heapify() を用いて要素の入ったリストを変換します。

以下の関数が提供されています:

heapq.heappush(heap, item)

item を heap に push します。ヒープ不変式を保ちます。

heapq.heappop(heap)

pop を行い、 heap から最初の要素を返します。ヒープ不変式は保たれます。ヒープが空の場合、 IndexError が送出されます。

heapq.heappushpop(heap, item)

item を heap に push した後、pop を行って heap から最初の要素を返します。この一続きの動作を heappush() に引き続いて heappop() を別々に呼び出すよりも効率的に実行します。

バージョン 2.6 で追加.

heapq.heapify(x)

リスト x をインプレース処理し、線形時間でヒープに変換します。

heapq.heapreplace(heap, item)

heap から最小の要素を pop して返し、新たに item を push します。ヒープのサイズは変更されません。ヒープが空の場合、 IndexError が送出されます。この一息の演算は heappop() に次いで heappush() を送出するよりも効率的で、固定サイズのヒープを用いている場合にはより適しています。 pop/push の組み合わせは必ずヒープから要素を一つ返し、それを item と置き換えます。

返される値は加えられた item よりも大きくなるかもしれません。それを望まないなら、代わりに heappushpop() を使うことを考えてください。この push/pop の組み合わせは二つの値の小さい方を返し、大きい方の値をヒープに残します。

このモジュールではさらに3つのヒープに基く汎用関数を提供します。

heapq.merge(*iterables)

複数のソートされた入力をマージ(merge)して一つのソートされた出力にします (たとえば、複数のログファイルの時刻の入ったエントリーをマージします)。ソートされた値にわたる iterator を返します。

sorted(itertools.chain(*iterables)) と似ていますが、イテレータを返し、一度にはデータをメモリに読み込みまず、それぞれの入力が(最小から最大へ)ソートされていることを仮定します。

バージョン 2.6 で追加.

heapq.nlargest(n, iterable[, key])

iterable で定義されるデータセットのうち、最大値から降順に n 個の値のリストを返します。 (あたえられた場合) key は、引数を一つとる、 iterable のそれぞれの要素から比較キーを生成する関数を指定します: key=str.lower 以下のコードと同等です: sorted(iterable, key=key, reverse=True)[:n]

バージョン 2.4 で追加.

バージョン 2.5 で変更: 省略可能な key 引数を追加.

heapq.nsmallest(n, iterable[, key])

iterable で定義されるデータセットのうち、最小値から昇順に n 個の値のリストを返します。 (あたえられた場合) key は、引数を一つとる、 iterable のそれぞれの要素から比較キーを生成する関数を指定します: key=str.lower 以下のコードと同等です: sorted(iterable, key=key)[:n]

バージョン 2.4 で追加.

バージョン 2.5 で変更: 省略可能な key 引数を追加.

後ろ二つの関数は n の値が小さな場合に最適な動作をします。大きな値の時には sorted() 関数の方が効率的です。さらに、 n==1 の時には min() および max() 関数の方が効率的です。

8.4.1. 基本的な例

ヒープソート [http://ja.wikipedia.org/wiki/%E3%83%92%E3%83%BC%E3%83%97%E3%82%BD%E3%83%BC%E3%83%88] は、すべての値をヒープに push し、それから最小の値を一つづつ pop することで実装できます:

>>> def heapsort(iterable):
...     'Equivalent to sorted(iterable)'
...     h = []
...     for value in iterable:
...         heappush(h, value)
...     return [heappop(h) for i in range(len(h))]
...
>>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

ヒープの要素はタプルに出来ます。これは、追跡される主レコードとは別に (タスクの優先度のような) 比較値を指定するときに便利です:

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')

8.4.2. 優先度キュー実装の注釈

優先度つきキュー [http://ja.wikipedia.org/wiki/%E5%84%AA%E5%85%88%E5%BA%A6%E3%81%A4%E3%81%8D%E3%82%AD%E3%83%A5%E3%83%BC] は、ヒープの一般的な使い方で、実装にはいくつか困難な点があります:

ソート安定性: 優先度が等しい二つのタスクが、もともと追加された順序で返されるためにはどうしたらいいでしょうか？

将来の Python 3 では、優先度が等しくてタスクにデフォルトの比較順序がないと、タプルの比較は (priority, task) 対に分けられます。

あるタスクの優先度が変化したら、どうやってそれをヒープの新しい位置に移動させるのでしょうか？

未解決のタスクが削除される必要があるとき、どのようにそれをキューから探して削除するのでしょうか？

最初の二つの困難の解決策は、項目を優先度、項目番号、そしてタスクを含む 3 要素のリストとして保存することです。この項目番号は、同じ優先度の二つのタスクが、追加された順序で返されるようにするための同点決勝戦として働きます。そして二つの項目番号が等しくなることはありませんので、タプルの比較が二つのタスクを直接比べようとすることはありえません。

残りの困難は主に、未解決のタスクを探して、その優先度を変更したり、完全に削除することです。タスクを探すことは、キュー内の項目を指し示す辞書によってなされます。

項目を削除したり、優先度を変更することは、ヒープ構造の不変関係を壊すことになるので、もっと難しいです。ですから、可能な解決策は、その項目が無効であるものとしてマークし、必要なら変更された優先度の項目を加えることです:

pq = []                         # 優先度キューリスト
counter = itertools.count(1)    # ユニークなシーケンス番号
task_finder = {}                # タスクから項目へのマッピング
INVALID = 0                     # 項目が削除されたものとしてマークする

def add_task(priority, task, count=None):
    if count is None:
        count = next(counter)
    entry = [priority, count, task]
    task_finder[task] = entry
    heappush(pq, entry)

def get_top_priority():
    while True:
        priority, count, task = heappop(pq)
        del task_finder[task]
        if count is not INVALID:
            return task

def delete_task(task):
    entry = task_finder[task]
    entry[1] = INVALID

def reprioritize(priority, task):
    entry = task_finder[task]
    add_task(priority, task, entry[1])
    entry[1] = INVALID

8.4.3. 理論

ヒープとは、全ての k について、要素を 0 から数えたときに、 a[k] <= a[2*k+1] かつ a[k] <= a[2*k+2] となる配列です。比較のために、存在しない要素を無限大と考えます。ヒープの興味深い属性は heap[0] が常に最小の要素になることです。

上記の奇妙な不変式は、勝ち抜き戦判定の際に効率的なメモリ表現を行うためのものです。以下の番号は a[k] ではなく k とします:

                               0

              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

上の木構造では、各セル k は 2*k+1 および 2*k+2 を最大値としています。スポーツに見られるような通常の 2 つ組勝ち抜き戦では、各セルはその下にある二つのセルに対する勝者となっていて、個々のセルの勝者を追跡していくことにより、そのセルに対する全ての相手を見ることができます。しかしながら、このような勝ち抜き戦を使う計算機アプリケーションの多くでは、勝歴を追跡する必要はりません。メモリ効率をより高めるために、勝者が上位に進級した際、下のレベルから持ってきて置き換えることにすると、あるセルとその下位にある二つのセルは異なる三つの要素を含み、かつ上位のセルは二つの下位のセルに対して “勝者と” なります。

このヒープ不変式が常に守られれば、インデクス 0 は明らかに最勝者となります。最勝者の要素を除去し、”次の” 勝者を見つけるための最も単純なアルゴリズム的手法は、ある敗者要素 (ここでは上図のセル 30 とします) を 0 の場所に持っていき、この新しい 0 を濾過するようにしてツリーを下らせて値を交換してゆきます。不変関係が再構築されるまでこれを続けます。この操作は明らかに、ツリー内の全ての要素数に対して対数的な計算量となります。全ての要素について繰り返すと、 O(n log n) のソート(並べ替え)になります。

このソートの良い点は、新たに挿入する要素が、その最に取り出す 0 番目の要素よりも “良い値” でない限り、ソートを行っている最中に新たな要素を効率的に追加できるというところです。

この性質は、シミュレーション的な状況で、ツリーで全ての入力イベントを保持し、”勝者となる状況” を最小のスケジュール時刻にするような場合に特に便利です。あるイベントが他のイベント群の実行をスケジュールする際、それらは未来にスケジュールされることになるので、それらのイベント群を容易にヒープに積むことができます。すなわち、ヒープはスケジューラを実装する上で良いデータ構造であるといえます (私は MIDI シーケンサで使っているものです。 :-)

これまでスケジューラを実装するための様々なデータ構造が広範に研究されています。ヒープは十分高速で、速度もおおむね一定であり、最悪の場合でも平均的な速度とさほど変わらないため良いデータ構造といえます。しかし、最悪の場合がひどい速度になることを除き、たいていでより効率の高い他のデータ構造表現も存在します。

ヒープはまた、巨大なディスクのソートでも非常に有用です。おそらくご存知のように、巨大なソートを行うと、複数の “ラン (run)” (予めソートされた配列で、そのサイズは通常 CPU メモリの量に関係しています) が生成され、続いて統合処理 (merging) がこれらのランを判定します。この統合処理はしばしば非常に巧妙に組織されています [1] 。重要なのは、最初のソートが可能な限り長いランを生成することです。勝ち抜き戦はこれを行うための良い方法です。もし利用可能な全てのメモリを使って勝ち抜き戦を行い、要素を置換および濾過処理して現在のランに収めれば、ランダムな入力に対してメモリの二倍のサイズのランを生成することになり、大体順序づけがなされている入力に対してはもっと高い効率になります。

さらに、ディスク上の 0 番目の要素を出力して、現在の勝ち抜き戦に (最後に出力した値に “勝って” しまうために) 収められない入力を得たなら、ヒープには収まらないため、ヒープのサイズは減少します。解放されたメモリは二つ目のヒープを段階的に構築するために巧妙に再利用することができ、この二つ目のヒープは最初のヒープが崩壊していくのと同じ速度で成長します。最初のヒープが完全に消滅したら、ヒープを切り替えて新たなランを開始します。なんと巧妙で効率的なのでしょう！

一言で言うと、ヒープは知って得するメモリ構造です。私はいくつかのアプリケーションでヒープを使っていて、 ‘ヒープ’ モジュールを常備するのはいい事だと考えています。 :-)

注記

[1]
現在使われているディスクバランス化アルゴリズムは、最近はもはや巧妙というよりも目障りであり、このためにディスクに対するシーク機能が重要になっています。巨大な容量を持つテープのようにシーク不能なデバイスでは、事情は全く異なり、個々のテープ上の移動が可能な限り効率的に行われるように非常に巧妙な処理を (相当前もって) 行わねばなりません (すなわち、もっとも統合処理の “進行” に関係があります)。テープによっては逆方向に読むことさえでき、巻き戻しに時間を取られるのを避けるために使うこともできます。正直、本当に良いテープソートは見ていて素晴らしく驚異的なものです！ソートというのは常に偉大な芸術なのです！:-)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.5. bisect — 配列二分法アルゴリズム

このモジュールは、挿入の度にリストをソートすることなく、リストをソートされた順序に保つことをサポートします。大量の比較操作を伴うような、アイテムがたくさんあるリストでは、より一般的なアプローチに比べて、パフォーマンスが向上します。動作に基本的な二分法アルゴリズムを使っているので、 bisect と呼ばれています。ソースコードはこのアルゴリズムの実例として一番役に立つかもしれません (境界条件はすでに正しいです!)。

バージョン 2.1 で追加.

参考

Latest version of the bisect module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/bisect.py?view=markup]

次の関数が用意されています。

bisect.bisect_left(a, x, lo=0, hi=len(a))

ソートされた順序を保ったまま x を a に挿入できる点を探し当てます。リストの中から検索する部分集合を指定するには、パラメーターの lo と hi を使います。デフォルトでは、リスト全体が使われます。 x がすでに a に含まれている場合、挿入点は既存のどのエントリーよりも前(左)になります。戻り値は、 list.insert() の第一引数として使うのに適しています。 a はすでにソートされているものとします。

返された挿入点 i は、配列 a を二つに分け、 all(val < x for val in a[lo:i]) が左側に、 all(val >= x for val in a[i:hi]) が右側になるようにします。

bisect.bisect_right(a, x, lo=0, hi=len(a))

bisect.bisect(a, x, lo=0, hi=len(a))

bisect_left() と似ていますが、 a に含まれる x のうち、どのエントリーよりも後ろ(右)にくるような挿入点を返します。

bisect.insort_left(a, x, lo=0, hi=len(a))

x を a にソートされた順序で挿入します。これは、 a.insert(bisect.bisect_left(a, x, lo, hi), x) と等価です。 a はすでにソートされているものとします。なお、O(log n) の探索は遅い O(n) の挿入の段階に支配されます。

bisect.insort_right(a, x, lo=0, hi=len(a))

bisect.insort(a, x, lo=0, hi=len(a))

insort_left() と似ていますが、 a に含まれる x のうち、どのエントリーよりも後ろに x を挿入します。

参考

bisect を利用して、直接の探索ができ、キー関数をサポートする、完全な機能を持つコレクションクラスを組み立てる SortedCollection recipe [http://code.activestate.com/recipes/577197-sortedcollection/]。キーは、探索中に不必要な呼び出しをさせないために、予め計算しておきます。

8.5.1. ソート済みリストの探索

上記の bisect() 関数群は挿入点を探索するのには便利ですが、普通の探索タスクに使うのはトリッキーだったり不器用だったりします。以下の 5 関数は、これらをどのように標準の探索やソート済みリストに変換するかを説明します:

def index(a, x):
    'Locate the leftmost value exactly equal to x'
    i = bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    raise ValueError

def find_lt(a, x):
    'Find rightmost value less than x'
    i = bisect_left(a, x)
    if i:
        return a[i-1]
    raise ValueError

def find_le(a, x):
    'Find rightmost value less than or equal to x'
    i = bisect_right(a, x)
    if i:
        return a[i-1]
    raise ValueError

def find_gt(a, x):
    'Find leftmost value greater than x'
    i = bisect_right(a, x)
    if i != len(a):
        return a[i]
    raise ValueError

def find_ge(a, x):
    'Find leftmost item greater than or equal to x'
    i = bisect_left(a, x)
    if i != len(a):
        return a[i]
    raise ValueError

8.5.2. その他の使用例

bisect() 関数は数値テーブルの探索に役に立ちます。この例では、 bisect() を使って、(たとえば)順序のついた数値の区切り点の集合に基づいて、試験の成績の等級を表す文字を調べます。区切り点は 90 以上は ‘A’、 80 から 89 は ‘B’、などです。

>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
...     i = bisect(breakpoints, score)
...     return grades[i]
...
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']

sorted() 関数と違い、 bisect() 関数に key や reversed 引数を用意するのは、設計が非効率になるので、非合理的です。 (連続する bisect 関数の呼び出しは前回の key 参照の結果を “記憶” しません)

代わりに、事前に計算しておいたキーのリストから検索して、レコードのインデックスを見つけます。

>>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key=lambda r: r[1])
>>> keys = [r[1] for r in data]         # precomputed list of keys
>>> data[bisect_left(keys, 0)]
('black', 0)
>>> data[bisect_left(keys, 1)]
('blue', 1)
>>> data[bisect_left(keys, 5)]
('red', 5)
>>> data[bisect_left(keys, 8)]
('yellow', 8)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.6. array — 効率のよい数値アレイ

このモジュールでは、基本的な値 (文字、整数、浮動小数点数) のアレイ (array、配列) をコンパクトに表現できるオブジェクト型を定義しています。アレイはシーケンス (sequence) 型であり、中に入れるオブジェクトの型に制限があることを除けば、リストとまったく同じように振る舞います。オブジェクト生成時に一文字の 型コード を用いて型を指定します。次の型コードが定義されています:

型コード | C の型 | Python の型 | 最小サイズ (バイト単位)
'c' | char | 文字(str型) | 1
'b' | signed char | int型 | 1
'B' | unsigned char | int型 | 1
'u' | Py_UNICODE | Unicode文字(unicode型) | 2 (ノートを参照)
'h' | signed short | int型 | 2
'H' | unsigned short | int型 | 2
'i' | signed int | int型 | 2
'I' | unsigned int | long型 | 2
'l' | signed long | int型 | 4
'L' | unsigned long | long型 | 4
'f' | float | float型 | 4
'd' | double | float型 | 8

ノート

'u' 型コードは Python の Unicode 文字列に対応します。一文字幅の文字は 2 バイトで二文字幅の文字は 4 バイトです。

値の実際の表現はマシンアーキテクチャ (厳密に言うとCの実装) によって決まります。値の実際のサイズは itemsize 属性から得られます。 Python の通常の整数型では C の unsigned (long) 整数の最大範囲を表せないため、 'L' と 'I' で表現されている要素に入る値は Python では長整数として表されます。

このモジュールでは次の型を定義しています:

class array.array(typecode[, initializer])

要素のデータ型が typecode に限定される新しいアレイで、オプションの値 initializer を渡すと初期値になりますが、リスト、文字列または適当な型のイテレーション可能オブジェクトでなければなりません。

バージョン 2.4 で変更: 以前はリストか文字列しか受け付けませんでした。

リストか文字列を渡した場合、新たに作成されたアレイの fromlist() 、 fromstring() あるいは fromunicode() メソッド (以下を参照して下さい)に渡され、初期値としてアレイに追加されます。それ以外の場合には、イテレーション可能オブジェクト initializer は新たに作成されたオブジェクトの extend() メソッドに渡されます。

array.ArrayType

array の別名です。撤廃されました。

アレイオブジェクトでは、インデクス指定、スライス、連結および反復といった、通常のシーケンスの演算をサポートしています。スライス代入を使うときは、代入値は同じ型コードのアレイオブジェクトでなければなりません。それ以外のオブジェクトを指定すると TypeError を送出します。アレイオブジェクトはバッファインタフェースを実装しており、バッファオブジェクトをサポートしている場所ならどこでも利用できます。

次のデータ要素やメソッドもサポートされています:

array.typecode

アレイを作るときに使う型コード文字です。

array.itemsize

アレイの要素 1 つの内部表現に使われるバイト長です。

array.append(x)

値 x の新たな要素をアレイの末尾に追加します。

array.buffer_info()

アレイの内容を記憶するために使っているバッファの、現在のメモリアドレスと要素数の入ったタプル (address, length) を返します。バイト単位で表したメモリバッファの大きさは array.buffer_info()[1] * array.itemsize で計算できます。例えば ioctl() 操作のような、メモリアドレスを必要とする低レベルな (そして、本質的に危険な) I/Oインタフェースを使って作業する場合に、ときどき便利です。アレイ自体が存在し、長さを変えるような演算を適用しない限り、有効な値を返します。

ノート

C やC++ で書いたコードからアレイオブジェクトを使う場合 (buffer_info() の情報を使う意味のある唯一の方法です) は、アレイオブジェクトでサポートしているバッファインタフェースを使う方がより理にかなっています。このメソッドは後方互換性のために保守されており、新しいコードでの使用は避けるべきです。バッファインタフェースの説明は buffer オブジェクトと memoryview オブジェクト にあります。

array.byteswap()

アレイのすべての要素に対して「バイトスワップ」 (リトルエンディアンとビッグエンディアンの変換) を行います。このメソッドは大きさが 1、2、4 および 8 バイトの値にのみをサポートしています。他の型の値に使うと RuntimeError を送出します。異なるバイトオーダをもつ計算機で書かれたファイルからデータを読み込むときに役に立ちます。

array.count(x)

シーケンス中の x の出現回数を返します。

array.extend(iterable)

iterable から要素を取り出し、アレイの末尾に要素を追加します。 iterable が別のアレイ型である場合、二つのアレイは 全く 同じ型コードでなければなりません。それ以外の場合には TypeError を送出します。 iterable がアレイでない場合、アレイに値を追加できるような正しい型の要素からなるイテレーション可能オブジェクトでなければなりません。

バージョン 2.4 で変更: 以前は他のアレイ型しか引数に指定できませんでした。

array.fromfile(f, n)

ファイルオブジェクト f から (マシン依存のデータ形式そのままで) n 個の要素を読み出し、アレイの末尾に要素を追加します。 n 個の要素を読めなかったときは EOFError を送出しますが、それまでに読み出せた値はアレイに追加されています。 f は本当の組み込みファイルオブジェクトでなければなりません。 read() メソッドをもつ他の型では動作しません。

array.fromlist(list)

リストから要素を追加します。型に関するエラーが発生した場合にアレイが変更されないことを除き、 for x in list: a.append(x) と同じです。

array.fromstring(s)

文字列から要素を追加します。文字列は、 (ファイルから fromfile() メソッドを使って値を読み込んだときのように) マシン依存のデータ形式で表された値の配列として解釈されます。

array.fromunicode(s)

指定した Unicode 文字列のデータを使ってアレイを拡張します。アレイの型コードは 'u' でなければなりません。それ以外の場合には、 ValueError を送出します。他の型のアレイに Unicode 型のデータを追加するには、 array.fromstring(unicodestring.decode(enc)) を使ってください。

array.index(x)

アレイ中で x が出現するインデクスのうち最小の値 i を返します。

array.insert(i, x)

アレイ中の位置 i の前に値 x をもつ新しい要素を挿入します。 i の値が負の場合、アレイの末尾からの相対位置として扱います。

array.pop([i])

アレイからインデクスが i の要素を取り除いて返します。オプションの引数はデフォルトで -1 になっていて、最後の要素を取り除いて返すようになっています。

array.read(f, n)

バージョン 1.5.1 で撤廃: fromfile() メソッドを使ってください。

ファイルオブジェクト f から (マシン依存のデータ形式そのままで) n 個の要素を読み出し、アレイの末尾に要素を追加します。 n 個の要素を読めなかったときは EOFError を送出しますが、それまでに読み出せた値はアレイに追加されています。 f は本当の組み込みファイルオブジェクトでなければなりません。 read() メソッドをもつ他の型では動作しません。

array.remove(x)

アレイ中の x のうち、最初に現れたものを取り除きます。

array.reverse()

アレイの要素の順番を逆にします。

array.tofile(f)

アレイのすべての要素をファイルオブジェクト f に (マシン依存のデータ形式そのままで)書き込みます。

array.tolist()

アレイを同じ要素を持つ普通のリストに変換します。

array.tostring()

アレイをマシン依存のデータアレイに変換し、文字列表現 (tofile() メソッドによってファイルに書き込まれるものと同じバイト列) を返します。

array.tounicode()

アレイを Unicode 文字列に変換します。アレイの型コードは 'u' でなければなりません。それ以外の場合には ValueError を送出します。他の型のアレイから Unicode 文字列を得るには、 array.tostring().decode(enc) を使ってください。

array.write(f)

バージョン 1.5.1 で撤廃: tofile() メソッドを使ってください。

ファイルオブジェクト f に、全ての要素を(マシン依存のデータ形式そのままで)書き込みます。

アレイオブジェクトを表示したり文字列に変換したりすると、 array(typecode, initializer) という形式で表現されます。アレイが空の場合、 initializer の表示を省略します。アレイが空でなければ、 typecode が 'c' の場合には文字列に、それ以外の場合には数値のリストになります。関数 array() を from array import array で import している限り、変換後の文字列に eval() を用いると元のアレイオブジェクトと同じデータ型と値を持つアレイに逆変換できることが保証されています。文字列表現の例を以下に示します:

array('l')
array('c', 'hello world')
array('u', u'hello \u2641')
array('l', [1, 2, 3, 4, 5])
array('d', [1.0, 2.0, 3.14])

参考

Module struct

異なる種類のバイナリデータのパックおよびアンパック。

Module xdrlib

遠隔手続き呼び出しシステムで使われる外部データ表現仕様 (External Data Representation, XDR) のデータのパックおよびアンパック。

The Numerical Python Manual [http://numpy.sourceforge.net/numdoc/HTML/numdoc.htm]

Numeric Python 拡張モジュール (NumPy) では、別の方法でシーケンス型を定義しています。 Numerical Python に関する詳しい情報は http://numpy.sourceforge.net/ を参照してください。 (NumPy マニュアルの PDF バージョンは http://numpy.sourceforge.net/numdoc/numdoc.pdf で手に入ります。)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.7. sets — ユニークな要素の順序なしコレクション

バージョン 2.3 で追加.

バージョン 2.6 で撤廃: 組み込みの set/frozenset 型がこのモジュールを置き換えます。

sets モジュールは、ユニークな要素の順序なしコレクションを構築し、操作するためのクラスを提供します。帰属関係のテストやシーケンスから重複を取り除いたり、積集合・和集合・差集合・対称差集合のような標準的な数学操作などを含みます。

他のコレクションのように、 x in set, len(set), for x in set をサポートします。順序なしコレクションは、挿入の順序や要素位置を記録しません。従って、インデックス・スライス・他のシーケンス的な振舞いをサポートしません。

ほとんどの集合のアプリケーションは、 __hash__() を除いてすべての集合のメソッドを提供する Set クラスを使用します。ハッシュを要求する高度なアプリケーションについては、 ImmutableSet クラスが __hash__() メソッドを加えているが、集合の内容を変更するメソッドは省略されます。 Set と ImmutableSet は、何が集合(isinstance(obj, BaseSet))であるか決めるのに役立つ抽象クラス BaseSet から派生します。

集合クラスは辞書を使用して実装されます。このことから、集合の要素にするには辞書のキーと同様の要件を満たさなければなりません。具体的には、要素になるものには __eq__() と __hash__() が定義されているという条件です。その結果、集合はリストや辞書のような変更可能な要素を含むことができません。しかしそれらは、タプルや ImmutableSet のインスタンスのような不変コレクションを含むことができます。集合の集合の実装中の便宜については、内部集合が自動的に変更不可能な形式に変換されます。例えば、 Set([Set(['dog'])]) は Set([ImmutableSet(['dog'])]) へ変換されます。

class sets.Set([iterable])

新しい空の Set オブジェクトを構築します。もしオプション iterable が与えられたら、イタレータから得られた要素を備えた集合として更新します。 iterable 中の全ての要素は、変更不可能であるか、または 不変に自動変換するためのプロトコル で記述されたプロトコルを使って変更不可能なものに変換可能であるべきです。

class sets.ImmutableSet([iterable])

新しい空の ImmutableSet オブジェクトを構築します。もしオプション iterable が与えられたら、イタレータから得られた要素を備えた集合として更新します。 iterable 中の全ての要素は、変更不可能であるか、または 不変に自動変換するためのプロトコル で記述されたプロトコルを使って変更不可能なものに変換可能であるべきです。

ImmutableSet オブジェクトは __hash__() メソッドを備えているので、集合要素または辞書キーとして使用することができます。 ImmutableSet オブジェクトは要素を加えたり取り除いたりするメソッドを持っていません。したがって、コンストラクタが呼ばれたとき要素はすべて知られていなければなりません。

8.7.1. Set オブジェクト

Set と ImmutableSet のインスタンスはともに、以下の操作を備えています:

演算 | 等価な演算 | 結果
len(s) |  | 集合 s の濃度 (cardinality)
x in s |  | x が s に帰属していれば真を返す
x not in s |  | x が s に帰属していなければ真を返す
s.issubset(t) | s <= t | s のすべての要素が t に帰属していれば真を返す
s.issuperset(t) | s >= t | t のすべての要素が s に帰属していれば真を返す
s.union(t) | s | t | s と t の両方の要素からなる新しい集合
s.intersection(t) | s & t | s と t で共通する要素からなる新しい集合
s.difference(t) | s - t | s にあるが t にない要素からなる新しい集合
s.symmetric_difference(t) | s ^ t | s と t のどちらか一方に属する要素からなる集合
s.copy() |  | s の浅いコピーからなる集合

演算子を使わない書き方である union(), intersection(), difference(), および symmetric_difference() は任意のイテレート可能オブジェクトを引数として受け取るのに対し、演算子を使った書き方の方では引数は集合型でなければならないので注意してください。これはエラーの元となる Set('abc') & 'cbs' のような書き方を排除し、より可読性のある Set('abc').intersection('cbs') を選ばせるための仕様です。

バージョン 2.3.1 で変更: 以前は全ての引数が集合型でなければなりませんでした。

加えて、 Set と ImmutableSet は集合間の比較をサポートしています。二つの集合は、各々の集合のすべての要素が他方に含まれて (各々が他方の部分集合) いる場合、かつその場合に限り等価になります。ある集合は、他方の集合の真の部分集合 (proper subset、部分集合であるが非等価) である場合、かつその場合に限り、他方の集合より小さくなります。ある集合は、他方の集合の真の上位集合 (proper superset、上位集合であるが非等価) である場合、かつその場合に限り、他方の集合より大きくなります。

部分集合比較やと等値比較では、完全な順序決定関数を一般化できません。たとえば、互いに素な 2 つの集合は等しくありませんし、互いの部分集合でもないので、 a<b, a==b, a>b は すべて False を返します。したがって集合は __cmp__() メソッドを実装しません。

集合は一部の順序（部分集合の関係）を定義するだけなので、集合のリストにおいて list.sort() メソッドの出力は未定義です。

以下は ImmutableSet で利用可能であるが Set にはない操作です:

演算 | 結果
hash(s) | s のハッシュ値を返す

以下は Set で利用可能であるが ImmutableSet にはない操作です:

演算 | 等価な演算 | 結果
s.update(t) | s |= t | t を加えた要素からなる集合 s を返します
s.intersection_update(t) | s &= t | t でも見つかった要素だけを持つ集合 s を返します
s.difference_update(t) | s -= t | t にあった要素を取り除いた後の集合 s を返します
s.symmetric_difference_update(t) | s ^= t | s と t のどちらか一方に属する要素からなる集合 s を返します
s.add(x) |  | 要素 x を集合 s に加えます
s.remove(x) |  | 要素 x を集合 s から取り除きます; x がなければ KeyError を送出します
s.discard(x) |  | 要素 x が存在すれば、集合 s から取り除きます
s.pop() |  | s から要素を取り除き、それを返します; 集合が空なら KeyError を送出します
s.clear() |  | 集合 s からすべての要素を取り除きます

演算子を使わない書き方である update(), intersection_update(), difference_update(), および symmetric_difference_update() は任意のイテレート可能オブジェクトを引数として受け取るので注意してください。

バージョン 2.3.1 で変更: 以前は全ての引数が集合型でなければなりませんでした。

もう一つ注意を述べますが、このモジュールでは union_update() が update() の別名として含まれています。このメソッドは後方互換性のために残されているものです。プログラマは組み込みの set() および frozenset() でサポートされている update() を選ぶべきです。

8.7.2. 使用例

>>> from sets import Set
>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
>>> employees = engineers | programmers | managers           # union
>>> engineering_management = engineers & managers            # intersection
>>> fulltime_management = managers - engineers - programmers # difference
>>> engineers.add('Marvin')                                  # add element
>>> print engineers # doctest: +SKIP
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
>>> employees.issuperset(engineers)     # superset test
False
>>> employees.union_update(engineers)   # update from another set
>>> employees.issuperset(engineers)
True
>>> for group in [engineers, programmers, managers, employees]: # doctest: +SKIP
...     group.discard('Susan')          # unconditionally remove element
...     print group
...
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
Set(['Janice', 'Jack', 'Sam'])
Set(['Jane', 'Zack', 'Jack'])
Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack'])

8.7.3. 不変に自動変換するためのプロトコル

集合は変更不可能な要素だけを含むことできます。都合上、変更可能な Set オブジェクトは、集合要素として加えられる前に、自動的に ImmutableSet へコピーします。そのメカニズムはハッシュ可能な(hashable)要素を常に加えることですが、もしハッシュ不可能な場合は、その要素は変更不可能な等価物を返す __as_immutable__() メソッドを持っているかどうかチェックされます。

Set オブジェクトは、 ImmutableSet のインスタンスを返す __as_immutable__() メソッドを持っているので、集合の集合を構築することが可能です。

集合内のメンバーであることをチェックするために、要素をハッシュする必要がある __contains__() メソッドと remove() メソッドが、同様のメカニズムを必要としています。これらのメソッドは要素がハッシュできるかチェックします。もし出来なければ–__hash__(), __eq__(), __ne__() のための一時的なメソッドを備えたクラスによってラップされた要素を返すメソッド– __as_temporarily_immutable__() メソッドをチェックします。

代理メカニズムは、オリジナルの可変オブジェクトから分かれたコピーを組み上げる手間を助けてくれます。

Set オブジェクトは、新しいクラス _TemporarilyImmutableSet によってラップされた Set オブジェクトを返す、 __as_temporarily_immutable__() メソッドを実装します。

ハッシュ可能を与えるための2つのメカニズムは通常ユーザーに見えません。しかしながら、マルチスレッド環境下においては、 _TemporarilyImmutableSet によって一時的にラップされたものを持っているスレッドがあるときに、もう一つのスレッドが集合を更新することで、衝突を発生させることができます。言いかえれば、変更可能な集合の集合はスレッドセーフではありません。

8.7.4. 組み込み set 型との比較

組み込みの set および frozenset 型はこの sets で学んだことを生かして設計されています。主な違いは次の通りです。

Set と ImmutableSet は set と frozenset に改名されました。

BaseSet に相当するものはありません。代わりに isinstance(x, (set, frozenset)) を使って下さい。

組み込みのものに使われているハッシュアルゴリズムは、多くのデータ集合に対してずっと良い性能(少ない衝突)を実現します。

組み込みのものはより空間効率良く pickle 化できます。

組み込みのものには union_update() メソッドがありません。代わりに同じ機能の update() メソッドを使って下さい。

組み込みのものには _repr(sorted=True) メソッドがありません。代わりに組み込み関数の repr() と sorted() を使って repr(sorted(s)) として下さい。

組み込みのものは変更不可能なものに自動で変換するプロトコルがありません。この機能は多くの人が困惑を覚えるわりに、コミュニティの誰からも実際的な使用例の報告がありませんでした。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.8. sched — イベントスケジューラ

sched モジュールは一般的な目的のためのイベントスケジューラを実装するクラスを定義します:

参考

最新バージョンの sched モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/sched.py?view=markup]

class sched.scheduler(timefunc, delayfunc)

scheduler クラスはイベントをスケジュールするための一般的なインターフェースを定義します。それは”外部世界”を実際に扱うための 2つの関数を必要とします — timefunc は引数なしで呼出し可能であるべきで、そして数(それは”time”です, どんな単位でもかまいません) を返すようにします。 delayfunc は1つの引数(timefunc の出力と互換)で呼出し可能であり、その時間だけ遅延しなければいけません。各々のイベントが、マルチスレッドアプリケーションの中で他のスレッドが実行する機会の許可を実行した後に、 delayfunc は引数 0 で呼ばれるでしょう。

例:

>>> import sched, time
>>> s = sched.scheduler(time.time, time.sleep)
>>> def print_time(): print "From print_time", time.time()
...
>>> def print_some_times():
...     print time.time()
...     s.enter(5, 1, print_time, ())
...     s.enter(10, 1, print_time, ())
...     s.run()
...     print time.time()
...
>>> print_some_times()
930343690.257
From print_time 930343695.274
From print_time 930343700.273
930343700.276

マルチスレッド環境において、 scheduler クラスにはスレッドセーフのための制限があります。現在実行中のスケジューラに対して、中断中のタスクよりも前に新しいタスクを挿入することはできません。もし挿入しようとすると、メインスレッドはイベントキューが空になるまで動作しなくなります。代わりに、より推奨される方法として、 threading.Timer クラスを利用してください。

例:

>>> import time
>>> from threading import Timer
>>> def print_time():
...     print "From print_time", time.time()
...
>>> def print_some_times():
...     print time.time()
...     Timer(5, print_time, ()).start()
...     Timer(10, print_time, ()).start()
...     time.sleep(11)  # sleep while time-delay events execute
...     print time.time()
...
>>> print_some_times()
930343690.257
From print_time 930343695.274
From print_time 930343700.273
930343701.301

8.8.1. スケジューラオブジェクト

scheduler インスタンスは以下のメソッドと属性を持っています:

scheduler.enterabs(time, priority, action, argument)

新しいイベントをスケジュールします。引数 time は、コンストラクタへ渡された timefunc の戻り値と互換な数値型でなければいけません。同じ time によってスケジュールされたイベントは、それらの priority によって実行されるでしょう。

イベントを実行することは、 action(*argument) を実行することを意味します。 argument は action のためのパラメータを保持するシーケンスでなければいけません。

戻り値は、イベントのキャンセル後に使われるかもしれないイベントです (cancel() を見よ)。

scheduler.enter(delay, priority, action, argument)

時間単位以上の delay でイベントをスケジュールします。そのとき、その他の関連時間、その他の引数、効果、戻り値は、 enterabs() に対するものと同じです。

scheduler.cancel(event)

キューからイベントを消去します。もし event がキューにある現在のイベントでないならば、このメソッドは ValueError を送出します。

scheduler.empty()

もしイベントキューが空ならば、Trueを返します。

scheduler.run()

すべてのスケジュールされたイベントを実行します。この関数は次のイベントを(コンストラクタへ渡された関数 delayfunc() を使うことで)待ち、そしてそれを実行し、イベントがスケジュールされなくなるまで同じことを繰り返します。

action あるいは delayfunc は例外を投げることができます。いずれの場合も、スケジューラは一貫した状態を維持し、例外を伝播するでしょう。例外が action によって投げられる場合、イベントは run() への呼出しを未来に行なわないでしょう。

イベントのシーケンスが、次イベントの前に、利用可能時間より実行時間が長いと、スケジューラは単に遅れることになるでしょう。イベントが落ちることはありません; 呼出しコードはもはや適切でないキャンセルイベントに対して責任があります。

scheduler.queue

読み込み専用の属性で、これからのイベントが実行される順序で格納されたリストを返します。各イベントは、次の属性 time, priority, action, argument を持った名前付きタプル (named tuple) の形式になります。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.9. mutex — 排他制御

バージョン 2.6 で撤廃: mutex モジュールは Python 3.0 で削除されました。

mutex モジュールでは、ロック (lock) の獲得と解除によって排他制御を可能にするクラスを定義しています。排他制御は threading やマルチタスクを使う上で便利かもしれませんが、このクラスがそうした機能を必要として(いたり、想定して)いるわけではありません。

mutex モジュールでは以下のクラスを定義しています:

class mutex.mutex

新しい (ロックされてない) mutex を作ります。

mutex には 2 つの状態変数 — “ロック” ビット (locked bit) とキュー (queue) があります。 mutex がロックされていなければ、キューは空です。それ以外の場合、キューは空になっているか、 (function, argument) のペアが一つ以上入っています。このペアはロックを獲得しようと待機している関数 (またはメソッド) を表しています。キューが空でないときに mutex をロック解除すると、キューの先頭のエントリをキューから除去し、そのエントリのペアに基づいて function(argument) を呼び出します。これによって、先頭にあったエントリが新たなロックを獲得します。

当然のことながらマルチスレッドの制御には利用できません – というのも、 lock() が、ロックを獲得したら関数を呼び出すという変なインタフェースだからです。

8.9.1. mutex オブジェクト

mutex には以下のメソッドがあります:

mutex.test()

mutex がロックされているかどうか調べます。

mutex.testandset()

「原子的 (Atomic)」な Test-and-Set 操作です。ロックがセットされていなければ獲得して True を返します。それ以外の場合には False を返します。

mutex.lock(function, argument)

mutex がロックされていなければ function(argument) を実行します。 mutex がロックされている場合、関数とその引数をキューに置きます。キューに置かれた function(argument) がいつ実行されるかについては unlock() を参照してください。

mutex.unlock()

キューが空ならば mutex をロック解除します。そうでなければ、キューの最初の要素を実行します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.10. queue — 同期キュークラス

ノート

Queue モジュールは Python 3.0 で queue という名前に変更されました。 2to3 ツールは、自動的に import を変換します。

Queue モジュールは、多生産者-多消費者(multi-producer, multi-consumer)キューを実装します。これは、複数のスレッドの間で情報を安全に交換しなければならないときのマルチスレッドプログラミングで特に有益です。このモジュールの Queue クラスは、必要なすべてのロックセマンティクスを実装しています。これはPythonのスレッドサポートの状況に依存します。 threading モジュールを参照してください。

3種類のキューが実装されていて、キューから取り出されるエントリの順番だけが違います。 FIFOキューでは、最初に追加されたエントリが最初に取り出されます。 LIFOキューでは、最後に追加されたエントリが最初に取り出されます(スタックのように振る舞います)。優先順位付きキュー(priority queue)では、エントリは(heapq モジュールを利用して)ソートされ、最も低い値のエントリが最初に取り出されます。

参考

最新バージョンの queue モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/Queue.py?view=markup].

Queue モジュールは以下のクラスと例外を定義します:

class Queue.Queue(maxsize=0)

FIFOキューのコンストラクタです。 maxsize はキューに置くことのできる要素数の上限を設定する整数です。いったんこの大きさに達したら、挿入はキューの要素が消費されるまでブロックされます。もし maxsize が0以下であるならば、キューの大きさは無限です。

class Queue.LifoQueue(maxsize=0)

LIFOキューのコンストラクタです。 maxsize はキューに置くことのできる要素数の上限を設定する整数です。いったんこの大きさに達したら、挿入はキューの要素が消費されるまでブロックされます。もし maxsize が0以下であるならば、キューの大きさは無限です。

バージョン 2.6 で追加.

class Queue.PriorityQueue(maxsize=0)

優先順位付きキューのコンストラクタです。 maxsize はキューに置くことのできる要素数の上限を設定する整数です。いったんこの大きさに達したら、挿入はキューの要素が消費されるまでブロックされます。もし maxsize が0以下であるならば、キューの大きさは無限です。

exception Queue.Empty

空な Queue オブジェクトで、非ブロックメソッドとして get() (または get_nowait()) が呼ばれたとき、送出される例外です。

exception Queue.Full

満杯な Queue オブジェクトで、非ブロックメソッドとして put() (または put_nowait()) が呼ばれたとき、送出される例外です。

参考

collections.deque は、ロックなしで popleft() や append() といったアトミック操作が可能なキューの実装です。

8.10.1. キューオブジェクト

キューオブジェクト(Queue, LifoQueue, PriorityQueue)は、以下のpublicメソッドを提供しています。

Queue.qsize()

Queue.empty()

Queue.full()

Queue.put(item[, block[, timeout]])

item をキューに入れます。もしオプション引数 block がTrueで timeout がNone(デフォルト)ならば、フリースロットが利用可能になるまでブロックします。 timeout が正の値の場合、最大で timeout 秒間ブロックし、その時間内に空きスロットが利用可能にならなければ、例外 Full を送出します。他方(block がFalse)、直ちにフリースロットが利用できるならば、キューにアイテムを置きます。できないならば、例外 Full を送出します (この場合 timeout は無視されます)。

バージョン 2.3 で追加: timeout 引数が追加されました。

Queue.put_nowait(item)

put(item, False) と同じ意味です。

Queue.get([block[, timeout]])

キューからアイテムを取り除き、それを返します。もしオプション引数 block がTrueで timeout がNone(デフォルト)ならば、アイテムが利用可能になるまでブロックします。もし timeout が正の値の場合、最大で timeout 秒間ブロックし、その時間内でアイテムが利用可能にならなければ、例外 Empty を送出します。他方(block がFalse)、直ちにアイテムが利用できるならば、それを返します。できないならば、例外 Empty を送出します (この場合 timeout は無視されます)。

バージョン 2.3 で追加: timeout 引数が追加されました。

Queue.get_nowait()

get(False) と同じ意味です。

キューに入れられたタスクが全て消費者スレッドに処理されたかどうかを追跡するために 2つのメソッドが提供されます。

Queue.task_done()

過去にキューに入れられたタスクが完了した事を示します。キューの消費者スレッドに利用されます。タスクの取り出しに使われた、各 get() に対して、それに続く task_done() の呼び出しは、取り出したタスクに対する処理が完了した事をキューに教えます。

join() がブロックされていた場合、全itemが処理された (キューに put() された全てのitemに対して task_done() が呼び出されたことを意味します) 時に復帰します。

キューにあるよりitemの個数よりも多く呼び出された場合、 ValueError が送出されます。

バージョン 2.5 で追加.

Queue.join()

キューの中の全アイテムが処理される間でブロックします。

キューにitemが追加される度に、未完了タスクカウントが増やされます。消費者スレッドが task_done() を呼び出して、itemを受け取ってそれに対する処理が完了した事を知らせる度に、未完了タスクカウントが減らされます。未完了タスクカウントが0になったときに、join() のブロックが解除されます。

バージョン 2.5 で追加.

キューに入れたタスクが完了するのを待つ例:

def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()       # 全タスクが完了するまでブロック

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.11. weakref — 弱参照

バージョン 2.1 で追加.

weakref モジュールは、Pythonプログラマがオブジェクトへの弱参照 (weak refarence)を作成できるようにします。

以下では、用語 リファレント(referent) は弱参照が参照するオブジェクトを意味します。

オブジェクトに対する弱参照は、そのオブジェクトを生かしておく十分条件にはなりません: あるリファレントに対する参照が弱参照しか残っていない場合、ガベージコレクション (garbage collection)機構は自由にリファレントを破壊し、そのメモリを別の用途に再利用できます。弱参照の主な用途は、巨大なオブジェクトを保持するキャッシュやマップ型の実装において、キャッシュやマップ型にあるという理由だけオブジェクトを存続させたくない場合です。

例えば、巨大なバイナリ画像のオブジェクトがたくさんあり、それぞれに名前を関連付けたいとします。 Python の辞書型を使って名前を画像に対応付けたり画像を名前に対応付けたりすると、画像オブジェクトは辞書内のキーや値に使われているため存続しつづけることになります。 weakref モジュールが提供している WeakKeyDictionary や WeakValueDictionary クラスはその代用で、対応付けを構築するのに弱参照を使い、キャッシュやマップ型に存在するという理由だけでオブジェクトを存続させないようにします。例えば、もしある画像オブジェクトが WeakValueDictionary の値になっていた場合、最後に残った画像オブジェクトへの参照を弱参照マップ型が保持していれば、ガーベジコレクションはこのオブジェクトを再利用でき、画像オブジェクトに対する弱参照内の対応付けは削除されます。

WeakKeyDictionary や WeakValueDictionary は弱参照を使って実装されていて、キーや値がガベージコレクションによって回収されたことを弱参照辞書に知らせるような弱参照オブジェクトのコールバック関数を設定しています。ほとんどのプログラムが、いずれかの弱参照辞書型を使うだけで必要を満たせるはずです — 自作の弱参照辞書を直接作成する必要は普通はありません。とはいえ、高度な使い方をするために、弱参照辞書の実装に使われている低水準の機構は weakref モジュールで公開されています。

ノート

オブジェクトへの弱参照は、そのオブジェクトの __del__() メソッドが呼び出される前にクリアされます。弱参照のコールバック呼ばれるときに、そのオブジェクトがまだ生存しているためです。

すべてのオブジェクトを弱参照できるわけではありません。弱参照できるオブジェクトは、クラスインスタンス、(Cではなく) Pythonで書かれた関数、(束縛および非束縛の両方の) メソッド、 set と frozenset 型、ファイルオブジェクト、ジェネレータ(generator)、 type オブジェクト、 bsddb モジュールの DBcursor 型、ソケット型、 array 型、 deque 型、正規表現パターンオブジェクト, code オブジェクトです。

バージョン 2.4 で変更: ファイル、ソケット、 array 、および正規表現パターンのサポートを追加しました.

バージョン 2.7 で変更: thread.lock, threading.Lock, code オブジェクトのサポートを追加しました。

list や dict など、いくつかの組み込み型は弱参照を直接サポートしませんが、以下のようにサブクラス化を行えばサポートを追加できます:

class Dict(dict):
    pass

obj = Dict(red=1, green=2, blue=3)   # このオブジェクトは弱参照可能

CPython implementation detail: tuple や long など、他の組み込み型はサブクラス化しても弱参照をサポートしません。

拡張型は、簡単に弱参照をサポートできます。詳細については、 弱参照(Weak Reference)のサポートを参照してください。

class weakref.ref(object[, callback])

object への弱参照を返します。リファレントがまだ生きているならば、元のオブジェクトは参照オブジェクトの呼び出しで取り出せす。リファレントがもはや生きていないならば、参照オブジェクトを呼び出したときに None を返します。 callback に None 以外の値を与えた場合、オブジェクトをまさに後始末処理しようとするときに呼び出します。このとき弱参照オブジェクトは callback の唯一のパラメタとして渡されます。リファレントはもはや利用できません。

同じオブジェクトに対してたくさんの弱参照を作れます。それぞれの弱参照に対して登録されたコールバックは、もっとも新しく登録されたコールバックからもっとも古いものへと呼び出されます。

コールバックが発生させた例外は標準エラー出力に書き込まれますが、伝播されません。それらはオブジェクトの __del__() メソッドが発生させる例外と完全に同じ方法で処理されます。

object がハッシュ可能(hashable)ならば、弱参照はハッシュ可能です。それらは object が削除された後でもそれらのハッシュ値を保持します。 object が削除されてから初めて hash() が呼び出された場合に、その呼び出しは TypeError を発生させます。

弱参照は等価性のテストをサポートしていますが、順序をサポートしていません。参照がまだ生きているならば、 callback に関係なく二つの参照はそれらのリファレントと同じ等価関係を持ちます。リファレントのどちらか一方が削除された場合、参照オブジェクトが同一である場合に限り、その参照は等価です。

バージョン 2.4 で変更: 以前はファクトリでしたが、サブクラス化可能な型になりました。 object 型から派生しています.

weakref.proxy(object[, callback])

弱参照を使う object へのプロキシを返します。弱参照オブジェクトを明示的な参照外しをしながら利用する代わりに、多くのケースでプロキシを利用することができます。返されるオブジェクトは、 object が呼び出し可能かどうかによって、 ProxyType または CallableProxyType のどちらかの型を持ちます。プロキシオブジェクトはリファレントに関係なくハッシュ可能(hashable)ではありません。これによって、それらの基本的な変更可能という性質による多くの問題を避けています。そして、辞書のキーとしての利用を妨げます。 callback は ref() 関数の同じ名前のパラメータと同じものです。

ノート

訳注: リファレントが変更不能型であっても、プロキシはリファレントが消えるという状態の変更があるために、変更可能型です。

weakref.getweakrefcount(object)

object を参照する弱参照とプロキシの数を返します。

weakref.getweakrefs(object)

object を参照するすべての弱参照とプロキシオブジェクトのリストを返します。

class weakref.WeakKeyDictionary([dict])

キーを弱参照するマッピングクラス。キーへの強参照がなくなったときに、辞書のエントリは捨てられます。アプリケーションの他の部分が所有するオブジェクトへ属性を追加することもなく、それらのオブジェクトに追加データを関連づけるために使うことができます。これは属性へのアクセスをオーバーライドするオブジェクトに特に便利です。

ノート

警告: WeakKeyDictionary は Python 辞書型の上に作られているので、反復処理を行うときにはサイズ変更してはなりません。 WeakKeyDictionary の場合、反復処理の最中にプログラムが行った操作が、(ガベージコレクションの副作用として) 「魔法のように」辞書内の要素を消し去ってしまうため、確実なサイズ変更は困難なのです。

WeakKeyDictionary オブジェクトは、以下の追加のメソッドを持ちます。これらのメソッドは、内部の参照を直接公開します。その参照は、利用される時に生存しているとは限りません。なので、参照を利用する前に、その参照をチェックする必要があります。これにより、必要なくなったキーの参照が残っているために、ガベージコレクタがそのキーを削除できなくなる事態を避ける事ができます。

WeakKeyDictionary.iterkeyrefs()

キーへの弱参照を生成する iterator を返します。

バージョン 2.5 で追加.

WeakKeyDictionary.keyrefs()

キーへの弱参照のリストを返します。

バージョン 2.5 で追加.

class weakref.WeakValueDictionary([dict])

値を弱参照するマッピングクラス。値への強参照が存在しなくなったときに、辞書のエントリは捨てられます。

ノート

警告: WeakValueDictionary は Python 辞書型の上に作られているので、反復処理を行うときにはサイズ変更してはなりません。 WeakKeyDictionary の場合、反復処理の最中にプログラムが行った操作が、(ガベージコレクションの副作用として) 「魔法のように」辞書内の要素を消し去ってしまうため、確実なサイズ変更は困難なのです。

WeakValueDictionary オブジェクトは、以下の追加のメソッドを持ちます。これらのメソッドは、 WeakKeyDictionary クラスの iterkeyrefs() と keyrefs() メソッドと同じ目的を持っています。

WeakValueDictionary.itervaluerefs()

値への弱参照を生成するイテレータ(iterator)を返します。

バージョン 2.5 で追加.

WeakValueDictionary.valuerefs()

値への弱参照のリストを返します。

バージョン 2.5 で追加.

class weakref.WeakSet([elements])

要素への弱参照を持つ集合型。要素への強参照が無くなったときに、その要素は削除されます。

バージョン 2.7 で追加.

weakref.ReferenceType

弱参照オブジェクトのための型オブジェクト。

weakref.ProxyType

呼び出し可能でないオブジェクトのプロキシのための型オブジェクト。

weakref.CallableProxyType

呼び出し可能なオブジェクトのプロキシのための型オブジェクト。

weakref.ProxyTypes

プロキシのためのすべての型オブジェクトを含むシーケンス。これは両方のプロキシ型の名前付けに依存しないで、オブジェクトがプロキシかどうかのテストをより簡単にできます。

exception weakref.ReferenceError

プロキシオブジェクトが使われても、元のオブジェクトがガベージコレクションされてしまっているときに発生する例外。これは標準の ReferenceError 例外と同じです。

参考

PEP 0205 [http://www.python.org/dev/peps/pep-0205] - Weak References

この機能の提案と理論的根拠。初期の実装と他の言語における類似の機能についての情報へのリンクを含んでいます。

8.11.1. 弱参照オブジェクト

弱参照オブジェクトは属性あるいはメソッドを持ちません。しかし、リファレントがまだ存在するならば、呼び出すことでそのリファレントを取得できるようにします:

>>> import weakref
>>> class Object:
...     pass
...
>>> o = Object()
>>> r = weakref.ref(o)
>>> o2 = r()
>>> o is o2
True

リファレントがもはや存在しないならば、参照オブジェクトの呼び出しは None を返します:

>>> del o, o2
>>> print r()
None

弱参照オブジェクトがまだ生きているかどうかのテストは、式 ref() is not None を用いて行われます。通常、参照オブジェクトを使う必要があるアプリケーションコードはこのパターンに従います:

# rは弱参照オブジェクト
o = r()
if o is None:
    # リファレントがガーベジコレクトされた
    print "Object has been allocated; can't frobnicate."
else:
    print "Object is still live!"
    o.do_something_useful()

“生存性(liveness)”のテストを分割すると、スレッド化されたアプリケーションにおいて競合状態を作り出します。 (訳注:if r() is not None: r().do_something() では、2度目のr()がNoneを返す可能性があります) 弱参照が呼び出される前に、他のスレッドは弱参照が無効になる原因となり得ます。上で示したイディオムは、シングルスレッドのアプリケーションと同じくマルチスレッド化されたアプリケーションにおいても安全です。

サブクラス化を行えば、 ref オブジェクトの特殊なバージョンを作成できます。これは WeakValueDictionary の実装で使われており、マップ内の各エントリによるメモリのオーバヘッドを減らしています。こうした実装は、ある参照に追加情報を関連付けたい場合に便利ですし、リファレントを取り出すための呼び出し時に何らかの追加処理を行いたい場合にも使えます。

以下の例では、 ref のサブクラスを使って、あるオブジェクトに追加情報を保存し、リファレントがアクセスされたときにその値に作用をできるようにするための方法を示しています:

import weakref

class ExtendedRef(weakref.ref):
    def __init__(self, ob, callback=None, **annotations):
        super(ExtendedRef, self).__init__(ob, callback)
        self.__counter = 0
        for k, v in annotations.iteritems():
            setattr(self, k, v)

    def __call__(self):
        """Return a pair containing the referent and the number of
        times the reference has been called.
        """
        ob = super(ExtendedRef, self).__call__()
        if ob is not None:
            self.__counter += 1
            ob = (ob, self.__counter)
        return ob

8.11.2. 例

この簡単な例では、アプリケーションが以前に参照したオブジェクトを取り出すためにオブジェクトIDを利用する方法を示します。オブジェクトに生きたままであることを強制することなく、オブジェクトの IDを他のデータ構造の中で使うことができ、必要に応じてIDからオブジェクトを取り出せます。

import weakref

_id2obj_dict = weakref.WeakValueDictionary()

def remember(obj):
    oid = id(obj)
    _id2obj_dict[oid] = obj
    return oid

def id2obj(oid):
    return _id2obj_dict[oid]

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.12. UserDict — 辞書オブジェクトのためのクラスラッパー

このモジュールは最小限のマッピングインターフェイスをすでに持っているクラスのために、すべての辞書メソッドを定義しているmixin、 DictMixin を定義しています。これによって、shelveモジュールのような辞書の代わりをする必要があるクラスを書くことが非常に簡単になります。

このモジュールでは UserDict クラスを定義しています。これは辞書オブジェクトのラッパーとして動作します。これは dict (Python 2.2から利用可能な機能です)によって置き換えられています。 dict の導入以前に、 UserDict クラスは辞書風のサブクラスをオーバライドや新メソッドの定義によって作成するために使われていました。

参考

最新バージョンの UserDict Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/UserDict.py?view=markup]

UserDict モジュールは UserDict クラスと DictMixin を定義しています:

class UserDict.UserDict([initialdata])

辞書をシミュレートするクラス。インスタンスの内容は通常の辞書に保存され、 UserDict インスタンスの data 属性を通してアクセスできます。 initialdata が与えられれば、 data はその内容で初期化されます。他の目的のために使えるように、 initialdata への参照が保存されないことがあるということに注意してください。

ノート

後方互換性のために、 UserDict のインスタンスはイテレート可能ではありません。

class UserDict.IterableUserDict([initialdata])

UserDict のイテレーションをサポートするサブクラス (使用例: for key in myDict).

マッピングのメソッドと演算(節 マップ型 を参照)に加えて、 UserDict 、 IterableUserDict インスタンスは次の属性を提供します:

IterableUserDict.data

UserDict クラスの内容を保存するために使われる実際の辞書。

class UserDict.DictMixin

__getitem__() 、 __setitem__() 、 __delitem__() および keys() といった最小の辞書インタフェースを既に持っているクラスのために、全ての辞書メソッドを定義する mixin です。

このmixinはスーパークラスとして使われるべきです。上のそれぞれのメソッドを追加することで、より多くの機能がだんだん追加されます。例えば、 __delitem__() 以外の全てのメソッドを定義すると、使えないのは pop() と popitem() だけになります。

4 つの基底メソッドに加えて、 __contains__() 、 __iter__() および iteritems() を定義すれば、順次効率化を果たすことができます。

mixin はサブクラスのコンストラクタについて何も知らないので、 __init__() や copy() は定義していません。

Python 2.6 からは、 DictMixin の代わりに、 collections.MutableMapping を利用することが推奨されています。

8.13. UserList — リストオブジェクトのためのクラスラッパー

ノート

このモジュールは後方互換性のためだけに残されています。Python 2.2より前のバージョンのPythonで動作する必要のないコードを書いているのならば、組み込み list 型から直接サブクラス化することを検討してください。

このモジュールはリストオブジェクトのラッパーとして働くクラスを定義します。独自のリストに似たクラスのために役に立つ基底クラスで、これを継承し既存のメソッドをオーバーライドしたり、あるいは、新しいものを追加したりすることができます。このような方法で、リストに新しい振る舞いを追加できます。

UserList モジュールは UserList クラスを定義しています:

class UserList.UserList([list])

リストをシミュレートするクラス。インスタンスの内容は通常のリストに保存され、 UserList インスタンスの data 属性を通してアクセスできます。インスタンスの内容は最初に list のコピーに設定されますが、デフォルトでは空リスト [] です。 list は何かイテレートできるオブジェクトで、例えば、通常のPythonリストや、 UserList (またはサブクラス)のインスタンスなどを利用できます。

ノート

UserList クラスは Python 3.0 では collections モジュールに移動されました。 2to3 ツールが自動的にソースコードの import 文を修正します。

変更可能シーケンスのメソッドと演算(節 シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange を参照)に加えて、 UserList インスタンスは次の属性を提供します:

UserList.data

UserList クラスの内容を保存するために使われる実際のPythonリストオブジェクト。

サブクラス化の要件: UserList のサブクラスは引数なしか、あるいは一つの引数のどちらかとともに呼び出せるコンストラクタを提供することが期待されます。新しいシーケンスを返すリスト演算は現在の実装クラスのインスタンスを作成しようとします。そのために、データ元として使われるシーケンスオブジェクトである一つのパラメータとともにコンストラクタを呼び出せると想定しています。

派生クラスがこの要求に従いたくないならば、このクラスがサポートしているすべての特殊メソッドはオーバーライドされる必要があります。その場合に提供される必要のあるメソッドについての情報は、ソースを参考にしてください。

バージョン 2.0 で変更: Pythonバージョン1.5.2と1.6では、コンストラクタが引数なしで呼び出し可能であることと変更可能な data 属性を提供するということも要求されます。Pythonの初期のバージョンでは、派生クラスのインスタンスを作成しようとはしません。

8.14. UserString — 文字列オブジェクトのためのクラスラッパー

ノート

このモジュールの UserString クラスは後方互換性のためだけに残されています。Python 2.2より前のバージョンのPythonで動作する必要のないコードを書いているのならば、 UserString を使う代わりに組み込み str 型から直接サブクラス化することを検討してください(組み込みの MutableString と等価なものはありません)。

このモジュールは文字列オブジェクトのラッパーとして働くクラスを定義します。独自の文字列に似たクラスのために役に立つ基底クラスで、これを継承し既存のメソッドをオーバーライドしたり、あるいは、新しいものを追加したりすることができます。このような方法で、文字列に新しい振る舞いを追加できます。

これらのクラスは実際のクラスやユニコードオブジェクトに比べてとても効率が悪いということに注意した方がよいでしょう。これは特に MutableString に対して当てはまります。

UserString モジュールは次のクラスを定義しています:

class UserString.UserString([sequence])

文字列またはユニコード文字列オブジェクトをシミュレートするクラス。インスタンスの内容は通常の文字列またはユニコード文字列オブジェクトに保存され、 UserString インスタンスの data 属性を通してアクセスできます。インスタンスの内容は最初に sequence のコピーに設定されます。 sequence は通常のPython文字列またはユニコード文字列、 UserString (またはサブクラス)のインスタンス、あるいは組み込み str() 関数を使って文字列に変換できる任意のシーケンスのいずれかです。

class UserString.MutableString([sequence])

このクラスは上の UserString から派生し、 変更可能に なるように文字列を再定義します。変更可能な文字列は辞書のキーとして使うことができません。なぜなら、辞書はキーとして 変更不能な オブジェクトを要求するからです。このクラスの主な目的は、辞書のキーとして変更可能なオブジェクトを使うという試みを捕捉するために、継承と __hash__() メソッドを取り除く(オーバーライドする)必要があることを示す教育的な例を提供することです。そうしなければ、非常にエラーになりやすく、突き止めることが困難でしょう。

バージョン 2.6 で撤廃: MutableString クラスは Python 3.0 では削除されます。

文字列とユニコードオブジェクトのメソッドと演算(節 文字列メソッド を参照)に加えて、 UserString インスタンスは次の属性を提供します:

MutableString.data

UserString クラスの内容を保存するために使われる実際のPython文字列またはユニコードオブジェクト。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.15. types — 組み込み型の名前

このモジュールは標準のPythonインタプリタで使われているオブジェクトの型について、名前を定義しています(拡張モジュールで定義されている型を除く)。このモジュールは listiterator 型のようなプロセス中に例外をふくまないので、 from types import * のように使っても安全です。このモジュールの将来のバージョンで追加される名前は、 Type で終わる予定です。

関数での典型的な利用方法は、以下のように引数の型によって異なる動作をする場合です:

from types import *
def delete(mylist, item):
    if type(item) is IntType:
       del mylist[item]
    else:
       mylist.remove(item)

Python 2.2以降では、 int() や str() のようなファクトリ関数は、型の名前となりましたので、 types を使用する必要はなくなりました。上記のサンプルは、以下のように記述する事が推奨されています。

def delete(mylist, item):
    if isinstance(item, int):
       del mylist[item]
    else:
       mylist.remove(item)

このモジュールは以下の名前を定義しています。

types.NoneType

None の型です。

types.TypeType

typeオブジェクトの型です (type() などによって返されます)。組み込みの type のエイリアスになります。

types.BooleanType

bool の True と False の型です。これは組み込みの bool のエイリアスです。

バージョン 2.3 で追加.

types.IntType

整数の型です(e.g. 1)。組み込みの int のエイリアスになります。

types.LongType

長整数の型です(e.g. 1L)。組み込みの long のエイリアスになります。

types.FloatType

浮動小数点数の型です(e.g. 1.0)。組み込みの float のエイリアスになります。

types.ComplexType

複素数の型です(e.g. 1.0j)。 Pythonが複素数のサポートなしでコンパイルされていた場合には定義されません。

types.StringType

文字列の型です(e.g. 'Spam')。組み込みの str のエイリアスになります。

types.UnicodeType

Unicode文字列の型です(e.g. u'Spam')。 Pythonがユニコードのサポートなしでコンパイルされていた場合には定義されません。組み込みの Unicode のエイリアスになります。

types.TupleType

タプルの型です(e.g. (1, 2, 3, 'Spam'))。組み込みの tuple のエイリアスになります。

types.ListType

リストの型です(e.g. [0, 1, 2, 3])。組み込みの list のエイリアスになります。

types.DictType

辞書の型です(e.g. {'Bacon': 1, 'Ham': 0})。組み込みの dict のエイリアスになります。

types.DictionaryType

DictType の別名です。

types.FunctionType

types.LambdaType

ユーザー定義の関数または lambda 式によって作成された関数の型です。

types.GeneratorType

ジェネレータ(generator)関数の呼び出しによって生成されたイテレータオブジェクトの型です。

バージョン 2.2 で追加.

types.CodeType

compile() 関数などによって返されるコードオブジェクトの型です。

types.ClassType

ユーザー定義の、古いスタイルのクラスの型です。

types.InstanceType

ユーザー定義のクラスのインスタンスの型です。

types.MethodType

ユーザー定義のクラスのインスタンスのメソッドの型です。

types.UnboundMethodType

MethodType の別名です。

types.BuiltinFunctionType

types.BuiltinMethodType

len() や sys.exit() のような組み込み関数や、組み込み型のメソッドの型です。 (ここでは、”組み込み”という単語を、”Cで書かれた”という意味で使っています)

types.ModuleType

モジュールの型です。

types.FileType

sys.stdout のようなopenされたファイルオブジェクトの型です。組み込みの file のエイリアスになります。

types.XRangeType

xrange() 関数によって返されるrangeオブジェクトの型です。組み込みの xrange のエイリアスになります。

types.SliceType

slice() 関数によって返されるオブジェクトの型です。組み込みの slice のエイリアスになります。

types.EllipsisType

Ellipsis の型です。

types.TracebackType

sys.exc_traceback に含まれるようなトレースバックオブジェクトの型です。

types.FrameType

フレームオブジェクトの型です。トレースバックオブジェクト tb の tb.tb_frame などです。

types.BufferType

buffer() 関数によって作られるバッファオブジェクトの型です。

types.DictProxyType

TypeType.__dict__ のような dictへのプロキシ型です。

types.NotImplementedType

NotImplemented の型です。

types.GetSetDescriptorType

FrameType.f_locals や array.array.typecode のような、拡張モジュールにおいて PyGetSetDef によって定義されたオブジェクトの型です。この型はオブジェクト属性のディスクリプタとして利用されます。 property 型と同じ目的を持った型ですが、こちらは拡張モジュールで定義された型のためのものです。

バージョン 2.5 で追加.

types.MemberDescriptorType

datetime.timedelta.days のような、拡張モジュールにおいて PyMemberDef によって定義されたオブジェクトの型です。この型は、標準の変換関数を利用するような、Cのシンプルなデータメンバで利用されます。 property 型と同じ目的を持った型ですが、こちらは拡張モジュールで定義された型のためのものです。

CPython implementation detail: Pythonの他の実装では、この型は GetSetDescriptorType と同一かもしれません。

バージョン 2.5 で追加.

types.StringTypes

文字列型のチェックを簡単にするための StringType と UnicodeType を含むシーケンスです。 UnicodeType は実行中の版のPythonに含まれている場合にだけ含まれるので、2つの文字列型のシーケンスを使うよりこれを使う方が移植性が高くなります。例: isinstance(s, types.StringTypes).

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.16. new — ランタイム内部オブジェクトの作成

バージョン 2.6 で撤廃: new モジュールは Python 3.0 で削除されました。代わりに、 types モジュールのクラスを利用してください。

new モジュールはインタプリタオブジェクト作成関数へのインターフェイスを与えます。新しいオブジェクトを”魔法を使ったように”作り出す必要がある、通常の作成関数が使えないときに、これは主にマーシャル型関数で使われます。このモジュールはインタプリタへの低レベルインターフェイスを提供します。したがって、このモジュールを使うときには注意しなければなりません。オブジェクトが利用される時にインタプリタをクラッシュさせるような引数を与えることもできてしまいます。

new モジュールは次の関数を定義しています:

new.instance(class[, dict])

この関数は __init__() コンストラクタを呼び出さずに辞書 dict をもつ class のインスタンスを作り出します。 dict が省略されるか、 None である場合は、新しいインスタンスのために新しい空の辞書が作られます。オブジェクトがいつもと同じ状態であるという保証はないことに注意してください。

new.instancemethod(function, instance, class)

この関数は instance に束縛されたメソッドオブジェクトか、あるいは instance が None の場合に束縛されていないメソッドオブジェクトを返します。 function は呼び出し可能でなければなりません。

new.function(code, globals[, name[, argdefs[, closure]]])

与えられたコードとグローバル変数をもつ(Python)関数を返します。 name を与えるならば、文字列か None でなければならない。文字列の場合は、関数は与えられた名前をもつ。そうでなければ、関数名は code.co_name から取られる。 argdefs を与える場合はタプルでなければならず、パラメータのデフォルト値を決めるために使われます。 closure を与える場合は None または名前を code.co_freevars に束縛するセルオブジェクトのタプルである必要があります。

)が与えられていると、

new.code(argcount, nlocals, stacksize, flags, codestring, constants, names, varnames, filename, name, firstlineno, lnotab)

この関数は PyCode_New() というC関数へのインターフェイスです。

new.module(name[, doc])

この関数は name という名前の新しいモジュールオブジェクトを返します。 name は文字列でなければならない。省略可能な doc 引数はどんな型でもよい。

new.classobj(name, baseclasses, dict)

この関数は新しいクラスオブジェクトを返します。そのクラスオブジェクトは(クラスのタプルであるべき) baseclasses から派生し、名前空間 dict を持ち、 name という名前です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.17. copy — 浅いコピーおよび深いコピー操作

このモジュールでは汎用の (浅い／深い) コピー操作を提供しています。

以下にインタフェースをまとめます:

copy.copy(x)

x の浅い (shallow) コピーを返します。

copy.deepcopy(x)

x の深い (deep) コピーを返します。

exception copy.error

モジュール特有のエラーを送出します。

浅い (shallow) コピーと深い (deep) コピーの違いが関係するのは、複合オブジェクト (リストやクラスインスタンスのような他のオブジェクトを含むオブジェクト) だけです:

浅いコピー (shallow copy) は新たな複合オブジェクトを作成し、その後 (可能な限り) 元のオブジェクト中に見つかったオブジェクトに対する参照 を挿入します。

深いコピー (deep copy) は新たな複合オブジェクトを作成し、その後元のオブジェクト中に見つかったオブジェクトの コピー を挿入します。

深いコピー操作には、しばしば浅いコピー操作の時には存在しない 2 つの問題がついてまわります:

再帰的なオブジェクト (直接、間接に関わらず、自分自身に対する参照を持つ複合オブジェクト) は再帰ループを引き起こします。

深いコピーでは、 何もかも をコピーするため、例えば複数のコピー間で共有されるべき管理データ構造までも、余分にコピーしてしまいます。

deepcopy() 関数では、これらの問題を以下のようにして回避しています:

現在のコピー過程ですでにコピーされたオブジェクトからなる、 “メモ” 辞書を保持します; かつ

ユーザ定義のクラスでコピー操作やコピーされる内容の集合を上書きできるようにします。

このモジュールでは、モジュール、メソッド、スタックトレース、スタックフレーム、ファイル、ソケット、ウィンドウ、アレイ、その他これらに類似の型をコピーしません。このモジュールでは元のオブジェクトを変更せずに返すことで関数とクラスを (浅くまたは深く)「コピー」します。これは pickle モジュールでの扱われかたと同じです。

辞書型の浅いコピーは dict.copy() で、リストの浅いコピーはリスト全体を指すスライス (例えば copy_list = original_list[:]) でできます。

バージョン 2.5 で変更: 関数コピーの追加.

クラスでは、pickle 化を制御するためのインタフェースと同じインタフェースをコピーの制御に使うことができます。これらのメソッドに関する情報は pickle モジュールの記述を参照してください。 copy モジュールは pickle 用関数登録モジュール copy_reg を使いません。

クラス独自のコピー実装を定義するために、特殊メソッド __copy__() および __deepcopy__() を定義することができます。前者は浅いコピー操作を実装するために使われます; 追加の引数はありません。後者は深いコピー操作を実現するために呼び出されます; この関数には単一の引数としてメモ辞書が渡されます。 __deepcopy__() の実装で、内容のオブジェクトに対して深いコピーを生成する必要がある場合、 deepcopy() を呼び出し、最初の引数にそのオブジェクトを、メモ辞書を二つ目の引数に与えなければなりません。

参考

Module pickle

オブジェクト状態の取得と復元をサポートするために使われる特殊メソッドについて議論されています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.18. pprint — データ出力の整然化

pprint モジュールを使うと、Pythonの任意のデータ構造をインタープリタへの入力で使われる形式にして”pretty-print”できます。フォーマット化された構造の中にPythonの基本的なタイプではないオブジェクトがあるなら、表示できないかもしれません。 Pythonの定数として表現できない多くの組み込みオブジェクトと同様、ファイル、ソケット、クラスあるいはインスタンスのようなオブジェクトが含まれていた場合は出力できません。

可能であればオブジェクトをフォーマット化して1行に出力しますが、与えられた幅に合わないなら複数行に分けて出力します。無理に幅を設定したいなら、 PrettyPrinter オブジェクトを作成して明示してください。

バージョン 2.5 で変更: 辞書は出力を計算する前にキーでソートされます。 2.5以前では、辞書は1行以上必要な場合にのみソートされていましたがドキュメントには書かれていませんでした。

バージョン 2.6 で変更: set と frozenset がサポートされました。

参考

最新バージョンの pprint module Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/pprint.py?view=markup]

pprint モジュールには1つのクラスが定義されています：

class pprint.PrettyPrinter(...)

PrettyPrinter インスタンスを作ります。このコンストラクタにはいくつかのキーワードパラメータを設定できます。

stream キーワードで出力ストリームを設定できます；このストリームに対して呼び出されるメソッドはファイルプロトコルの write() メソッドだけです。もし設定されなければ、 PrettyPrinter は sys.stdout を使用します。さらに3つのパラメータで出力フォーマットをコントロールできます。そのキーワードは indent 、 depth と width です。

再帰的なレベルごとに加えるインデントの量は indent で設定できます；デフォルト値は1です。他の値にすると出力が少しおかしく見えますが、ネスト化されたところが見分け易くなります。

出力されるレベルは depth で設定できます；出力されるデータ構造が深いなら、指定以上の深いレベルのものは ... で置き換えられて表示されます。デフォルトでは、オブジェクトの深さを制限しません。

width パラメータを使うと、出力する幅を望みの文字数に設定できます；デフォルトでは80文字です。もし指定した幅にフォーマットできない場合は、できるだけ近づけます。

>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff[:])
>>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(stuff)
[   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
    'spam',
    'eggs',
    'lumberjack',
    'knights',
    'ni']
>>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
... ('parrot', ('fresh fruit',))))))))
>>> pp = pprint.PrettyPrinter(depth=6)
>>> pp.pprint(tup)
(266, (267, (307, (287, (288, (...))))))
('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))

PrettyPrinter クラスにはいくつかの派生する関数が提供されています：

pprint.pformat(object[, indent[, width[, depth]]])

object をフォーマット化して文字列として返します。 indent 、 width と、 depth は PrettyPrinter コンストラクタにフォーマット指定引数として渡されます。

バージョン 2.4 で変更: 引数 indent 、 width と、 depth が追加されました.

pprint.pprint(object[, stream[, indent[, width[, depth]]]])

object をフォーマット化して stream に出力し、最後に改行します。 stream が省略されたら、 sys.stdout に出力します。これは対話型のインタープリタ上で、求める値を print する代わりに使用できます。 indent 、 width と、 depth は PrettyPrinter コンストラクタにフォーマット指定引数として渡されます。

>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff)
>>> pprint.pprint(stuff)
[<Recursion on list with id=...>,
 'spam',
 'eggs',
 'lumberjack',
 'knights',
 'ni']

バージョン 2.4 で変更: 引数 indent 、 width と、 depth が追加されました.

pprint.isreadable(object)

object をフォーマット化して出力できる（”readable”）か、あるいは eval() を使って値を再構成できるかを返します。再帰的なオブジェクトに対しては常に False を返します。

>>> pprint.isreadable(stuff)
False

pprint.isrecursive(object)

object が再帰的な表現かどうかを返します。

さらにもう1つ、関数が定義されています：

pprint.saferepr(object)

object の文字列表現を、再帰的なデータ構造から保護した形式で返します。もし object の文字列表現が再帰的な要素を持っているなら、再帰的な参照は <Recursion on typename with id=number> で表示されます。出力は他と違ってフォーマット化されません。

>>> pprint.saferepr(stuff)
"[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"

8.18.1. PrettyPrinter オブジェクト

PrettyPrinter インスタンスには以下のメソッドがあります：

PrettyPrinter.pformat(object)

object のフォーマット化した表現を返します。これは PrettyPrinter のコンストラクタに渡されたオプションを考慮してフォーマット化されます。

PrettyPrinter.pprint(object)

object のフォーマット化した表現を指定したストリームに出力し、最後に改行します。

以下のメソッドは、対応する同じ名前の関数と同じ機能を持っています。以下のメソッドをインスタンスに対して使うと、新たに PrettyPrinter オブジェクトを作る必要がないのでちょっぴり効果的です。

PrettyPrinter.isreadable(object)

object をフォーマット化して出力できる（”readable”）か、あるいは eval() を使って値を再構成できるかを返します。これは再帰的なオブジェクトに対して False を返すことに注意して下さい。もし PrettyPrinter の depth パラメータが設定されていて、オブジェクトのレベルが設定よりも深かったら、 False を返します。

PrettyPrinter.isrecursive(object)

オブジェクトが再帰的な表現かどうかを返します。

このメソッドをフックとして、サブクラスがオブジェクトを文字列に変換する方法を修正するのが可能になっています。デフォルトの実装では、内部で saferepr() を呼び出しています。

PrettyPrinter.format(object, context, maxlevels, level)

3つの値を返します： object をフォーマット化して文字列にしたもの、その結果が読み込み可能かどうかを示すフラグ、再帰が含まれているかどうかを示すフラグ。

最初の引数は表示するオブジェクトです。 2つめの引数はオブジェクトの id() をキーとして含むディクショナリで、オブジェクトを含んでいる現在の（直接、間接に object のコンテナとして表示に影響を与える）環境です。ディクショナリ context の中でどのオブジェクトが表示されたか表示する必要があるなら、3つめの返り値は True になります。 format() メソッドの再帰呼び出しではこのディクショナリのコンテナに対してさらにエントリを加えます。 3つめの引数 maxlevels で再帰呼び出しのレベルを設定します；もし制限しないなら、 0 にします。この引数は再帰呼び出しでそのまま渡されます。 4つめの引数 level で現在のレベルを設定します；再帰呼び出しでは、現在の呼び出しより小さい値が渡されます。

バージョン 2.3 で追加.

8.18.2. pprint の例

この例は pprint() 関数とその引数の幾つかの使い方を例示しています。

>>> import pprint
>>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
... ('parrot', ('fresh fruit',))))))))
>>> stuff = ['a' * 10, tup, ['a' * 30, 'b' * 30], ['c' * 20, 'd' * 20]]
>>> pprint.pprint(stuff)
['aaaaaaaaaa',
 ('spam',
  ('eggs',
   ('lumberjack',
    ('knights', ('ni', ('dead', ('parrot', ('fresh fruit',)))))))),
 ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
 ['cccccccccccccccccccc', 'dddddddddddddddddddd']]
>>> pprint.pprint(stuff, depth=3)
['aaaaaaaaaa',
 ('spam', ('eggs', (...))),
 ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
 ['cccccccccccccccccccc', 'dddddddddddddddddddd']]
>>> pprint.pprint(stuff, width=60)
['aaaaaaaaaa',
 ('spam',
  ('eggs',
   ('lumberjack',
    ('knights',
     ('ni', ('dead', ('parrot', ('fresh fruit',)))))))),
 ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
 ['cccccccccccccccccccc', 'dddddddddddddddddddd']]

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

8. データ型 »

8.19. repr — もう一つの repr() の実装

ノート

repr モジュールは Python 3.0 では reprlib にリネームされました。 2to3 ツールはソースコード内の import 文を自動で 3.0 に適応させます。

repr モジュールは結果の文字列の大きさを制限したオブジェクト表現を作り出すための方法を提供します。これはPythonデバッガで使われていますが、他の状況でも同じように役に立つかもしれません。

参考

最新バージョンの repr module Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/repr.py?view=markup]

このモジュールはクラスとインスタンス、それに関数を提供します:

class repr.Repr

組み込みクラス repr() によく似た関数を実装するために役に立つ書式化サービスを提供します。過度に長い表現を作り出さないように、異なるオブジェクト型に対する大きさの制限が追加されます。

repr.aRepr

これは下で説明される repr() 関数を提供するために使われる Repr のインスタンスです。このオブジェクトの属性を変更すると、 repr() と Python デバッガが使うサイズ制限に影響します。

repr.repr(obj)

これは aRepr の repr() メソッドです。同じ名前の組み込み関数が返す文字列と似ていますが、最大サイズに制限のある文字列を返します。

8.19.1. Reprオブジェクト

Repr インスタンスは様々なオブジェクト型の表現にサイズ制限を与えるために使えるいくつかのメンバーと、特定のオブジェクト型を書式化するメソッドを提供します。

Repr.maxlevel

再帰的な表現を作る場合の深さ制限。デフォルトは 6 です。

Repr.maxdict

Repr.maxlist

Repr.maxtuple

Repr.maxset

Repr.maxfrozenset

Repr.maxdeque

Repr.maxarray

指定されたオブジェクト型に対するエントリ表現の数についての制限。 maxdict に対するデフォルトは 4 で、 maxarray は 5 、その他に対しては 6 です。

バージョン 2.4 で追加: maxset, maxfrozenset, set.

Repr.maxlong

長整数の表現のおける文字数の最大値。中央の数字が抜け落ちます。デフォルトは 40 です。

Repr.maxstring

文字列の表現における文字数の制限。文字列の”通常の”表現は文字の材料だということに注意してください: 表現にエスケープシーケンスが必要とされる場合は、表現が短縮されたときにこれらはマングルされます。デフォルトは 30 です。

Repr.maxother

この制限は Repr オブジェクトに利用できる特定の書式化メソッドがないオブジェクト型のサイズをコントロールするために使われます。 maxstring と同じようなやり方で適用されます。デフォルトは 20 です。

Repr.repr(obj)

インスタンスが強制する書式化を使う組み込み repr() と等価なもの。

Repr.repr1(obj, level)

repr() が使う再帰的な実装。これはどの書式化メソッドを呼び出すかを決定するために obj の型を使い、それを obj と level に渡します。再帰呼び出しにおいて level の値に対して level - 1 を与える再帰的な書式化を実行するために、型に固有のメソッドは repr1() を呼び出します。

Repr.repr_TYPE(obj, level)

型名に基づく名前をもつメソッドとして、特定の型に対する書式化メソッドは実装されます。メソッド名では、 TYPE は string.join(string.split(type(obj).__name__, '_')) に置き換えられます。これらのメソッドへのディスパッチは repr1() によって処理されます。再帰的に値の書式を整える必要がある型固有のメソッドは、 self.repr1(subobj, level - 1) を呼び出します。

8.19.2. Reprオブジェクトをサブクラス化する

更なる組み込みオブジェクト型へのサポートを追加するためや、すでにサポートされている型の扱いを変更するために、 Repr.repr1() による動的なディスパッチを使って Repr をサブクラス化することができます。この例はファイルオブジェクトのための特別なサポートを追加する方法を示しています:

import repr as reprlib
import sys

class MyRepr(reprlib.Repr):
    def repr_file(self, obj, level):
        if obj.name in ['<stdin>', '<stdout>', '<stderr>']:
            return obj.name
        else:
            return repr(obj)

aRepr = MyRepr()
print aRepr.repr(sys.stdin)          # prints '<stdin>'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール

この章で解説されるモジュールは数値と数学関連の関数とデータ型を提供します。 numbers モジュールは数値型の抽象的階層を定義します。 math と cmath はさまざまな浮動小数点数および複素数向け数学関数を含みます。速度より10進法での正確さに興味があるユーザには、 decimal モジュールが真の10進表現をサポートしています。

この章で解説されるモジュールの一覧:

9.1. numbers — 数の抽象基底クラス

9.1.1. 数値塔

9.1.2. 型実装者のための注意事項

9.1.2.1. さらに数のABCを追加する

9.1.2.2. 算術演算の実装

9.2. math — 数学関数

9.2.1. 数論および数表現にまつわる関数です

9.2.2. 指数および対数関数

9.2.3. 三角関数

9.2.4. 角度に関する関数

9.2.5. 双曲線関数

9.2.6. 特殊な関数

9.2.7. 定数

9.3. cmath — 複素数のための数学関数

9.3.1. 極座標変換

9.3.2. 指数関数と対数関数

9.3.3. 三角関数

9.3.4. 双曲線関数

9.3.5. 類別関数

9.3.6. 定数

9.4. decimal — 10進固定及び浮動小数点数の算術演算

9.4.1. Quick-start Tutorial

9.4.2. Decimal オブジェクト

9.4.2.1. 論理引数

9.4.3. Context オブジェクト

9.4.4. シグナル

9.4.5. 浮動小数点数に関する注意

9.4.5.1. 精度を上げて丸め誤差を抑制する

9.4.5.2. 特殊値

9.4.6. スレッドを使った処理

9.4.7. レシピ

9.4.8. Decimal FAQ

9.5. fractions — 有理数

9.6. random — 擬似乱数を生成する

9.7. itertools — 効率的なループ実行のためのイテレータ生成関数

9.7.1. Itertool関数

9.7.2. レシピ

9.8. functools — 高階関数と呼び出し可能オブジェクトの操作

9.8.1. partial オブジェクト

9.9. operator — 関数形式の標準演算子

9.9.1. 演算子から関数への対応表

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.1. numbers — 数の抽象基底クラス

バージョン 2.6 で追加.

numbers モジュール (PEP 3141 [http://www.python.org/dev/peps/pep-3141]) は数の抽象基底クラスの、順により多くの演算を定義していく階層を定義します。このモジュールで定義される型はどれもインスタンス化できません。

class numbers.Number

数の階層の根。引数 x が、種類は何であれ、数であるということだけチェックしたい場合、 isinstance(x, Number) が使えます。

9.1.1. 数値塔

class numbers.Complex

この型のサブクラスは複素数を表し、組み込みの complex 型を受け付ける演算を含みます。それらは: complex および bool への変換、 real, imag, +, -, *, /, abs(), conjugate(), ==, != です。 - と != 以外の全てのものは抽象メソッドや抽象プロパティです。

real

抽象プロパティ。この複素数の実数部分を取り出します。

imag

抽象プロパティ。この複素数の虚数部分を取り出します。

conjugate()

抽象プロパティ。複素共役を返します。たとえば、 (1+3j).conjugate() == (1-3j) です。

class numbers.Real

Complex の上に、 Real は実数で意味を成す演算を加えます。

簡潔に言うとそれらは: float への変換, math.trunc(), round(), math.floor(), math.ceil(), divmod(), //, %, <, <=, > および >= です。

Real はまた complex(), real, imag および conjugate() のデフォルトを提供します。

class numbers.Rational

Real をサブタイプ化し numerator と denominator のプロパティを加えたものです。これら分子分母は最小の値でなければなりません。この他に float() のデフォルトも提供します。

numerator

抽象プロパティ。

denominator

抽象プロパティ。

class numbers.Integral

Rational をサブタイプ化し int への変換が加わります。 float(), numerator および denominator のデフォルトと、ビット列演算: <<, >>, &, ^, |, ~ を提供します。

9.1.2. 型実装者のための注意事項

実装する人は等しい数が等しく扱われるように同じハッシュを与えるように気を付けねばなりません。これは二つの異なった実数の拡張があるような場合にはややこしいことになるかもしれません。たとえば、 fractions.Fraction は hash() を以下のように実装しています:

def __hash__(self):
    if self.denominator == 1:
        # Get integers right.
        return hash(self.numerator)
    # Expensive check, but definitely correct.
    if self == float(self):
        return hash(float(self))
    else:
        # Use tuple's hash to avoid a high collision rate on
        # simple fractions.
        return hash((self.numerator, self.denominator))

9.1.2.1. さらに数のABCを追加する

もちろん、他にも数に対する ABC が有り得ますし、そういったものを付け加える可能性を閉ざしてしまうとすれば貧相な階層でしかありません。たとえば MyFoo を Complex と Real の間に付け加えるには:

class MyFoo(Complex): ...
MyFoo.register(Real)

9.1.2.2. 算術演算の実装

私たちは、混在型(mixed-mode)演算について作者が両方の引数の型について知っているような実装を呼び出すか、両方を最も近い組み込み型に変換してそこで演算するか、どちらかを行うように算術演算を実装したいのです。 Integral のサブタイプに対して、このことは __add__() と __radd__() が次のように定義されるべきであることを意味します:

class MyIntegral(Integral):

    def __add__(self, other):
        if isinstance(other, MyIntegral):
            return do_my_adding_stuff(self, other)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(self, other)
        else:
            return NotImplemented

    def __radd__(self, other):
        if isinstance(other, MyIntegral):
            return do_my_adding_stuff(other, self)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(other, self)
        elif isinstance(other, Integral):
            return int(other) + int(self)
        elif isinstance(other, Real):
            return float(other) + float(self)
        elif isinstance(other, Complex):
            return complex(other) + complex(self)
        else:
            return NotImplemented

ここには5つの異なる Complex のサブクラス間の混在型の演算があります。上のコードの中で MyIntegral と OtherTypeIKnowAbout に触れない部分を “ボイラープレート” と呼ぶことにしましょう。 a を Complex のサブタイプである A のインスタンス (a : A <: Complex)、同様に b : B <: Complex として、 a + b を考えます:

A が b を受け付ける __add__() を定義している場合、何も問題はありません。

A でボイラープレート部分に落ち込み、その結果 __add__() が値を返すならば、 B に良く考えられた __radd__() が定義されている可能性を見逃してしまいますので、ボイラープレートは __add__() から NotImplemented を返すのが良いでしょう。(若しくは、 A はまったく __add__() を実装すべきではなかったかもしれません。)

そうすると、 B の __radd__() にチャンスが巡ってきます。ここで a が受け付けられるならば、結果は上々です。

ここでボイラープレートに落ち込むならば、もう他に試すべきメソッドはありませんので、デフォルト実装の出番です。

もし B <: A ならば、Python は A.__add__ の前に B.__radd__ を試します。これで良い理由は、 A についての知識を持って実装しており、 Complex に委ねる前にこれらのインスタンスを扱えるはずだからです。

もし A <: Complex かつ B <: Real で他に共有された知識が無いならば、適切な共通の演算は組み込みの complex を使ったものになり、どちらの __radd__() ともそこに着地するでしょうから、 a+b == b+a です。

ほとんどの演算はどのような型についても非常に良く似ていますので、与えられた演算子について順結合(forward)および逆結合(reverse)のメソッドを生成する支援関数を定義することは役に立ちます。たとえば、 fractions.Fraction では次のようなものを利用しています:

def _operator_fallbacks(monomorphic_operator, fallback_operator):
    def forward(a, b):
        if isinstance(b, (int, long, Fraction)):
            return monomorphic_operator(a, b)
        elif isinstance(b, float):
            return fallback_operator(float(a), b)
        elif isinstance(b, complex):
            return fallback_operator(complex(a), b)
        else:
            return NotImplemented
    forward.__name__ = '__' + fallback_operator.__name__ + '__'
    forward.__doc__ = monomorphic_operator.__doc__

    def reverse(b, a):
        if isinstance(a, Rational):
            # Includes ints.
            return monomorphic_operator(a, b)
        elif isinstance(a, numbers.Real):
            return fallback_operator(float(a), float(b))
        elif isinstance(a, numbers.Complex):
            return fallback_operator(complex(a), complex(b))
        else:
            return NotImplemented
    reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
    reverse.__doc__ = monomorphic_operator.__doc__

    return forward, reverse

def _add(a, b):
    """a + b"""
    return Fraction(a.numerator * b.denominator +
                    b.numerator * a.denominator,
                    a.denominator * b.denominator)

__add__, __radd__ = _operator_fallbacks(_add, operator.add)

# ...

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.2. math — 数学関数

このモジュールはいつでも利用できます。標準 C で定義されている数学関数にアクセスすることができます。

これらの関数で複素数を使うことはできません。複素数に対応する必要があるならば、 cmath モジュールにある同じ名前の関数を使ってください。ほとんどのユーザーは複素数を理解するのに必要なだけの数学を勉強したくないので、複素数に対応した関数と対応していない関数の区別がされています。これらの関数では複素数が利用できないため、引数に複素数を渡されると、複素数の結果が返るのではなく例外が発生します。その結果、どういった理由で例外が送出されたかに早い段階で気づく事ができます。 [1]

このモジュールでは次の関数を提供しています。明示的な注記のない限り、戻り値は全て浮動小数点数になります。

9.2.1. 数論および数表現にまつわる関数です

math.ceil(x)

x の天井値 (ceil)、すなわち x 以上の最も小さい整数を float 型で返します。

math.copysign(x, y)

x に y の符号を付けて返します。符号付きのゼロをサポートしているプラットフォームでは、 copysign(1.0, -0.0) は -1.0 を返します。

バージョン 2.6 で追加.

math.fabs(x)

x の絶対値を返します。

math.factorial(x)

x の階乗を返します。 x が整数値でなかったり負であったりするときは、 ValueError を送出します。

バージョン 2.6 で追加.

math.floor(x)

x の床値 (floor)、すなわち x 以下の最も大きい整数を float型で返します。

math.fmod(x, y)

プラットフォームの C ライブラリで定義されている fmod(x, y) を返します。 Python の x % y という式は必ずしも同じ結果を返さないということに注意してください。 C 標準の要求では、 fmod() は除算の結果が x と同じ符号になり、大きさが abs(y) より小さくなるような整数 n については fmod(x, y) が厳密に (数学的に、つまり限りなく高い精度で) x - n*y と等価であるよう求めています。 Python の x % y は、 y と同じ符号の結果を返し、浮動小数点の引数に対して厳密な解を出せないことがあります。例えば、 fmod(-1e-100, 1e100) は -1e-100 ですが、 Python の -1e-100 % 1e100 は 1e100-1e-100 になり、浮動小数点型で厳密に表現できず、ややこしいことに 1e100 に丸められます。このため、一般には浮動小数点の場合には関数 fmod() 、整数の場合には x % y を使う方がよいでしょう。

math.frexp(x)

x の仮数と指数を (m, e) のペアとして返します。 m はfloat型で、 e は厳密に x == m * 2**e であるような整数型です。 x がゼロの場合は、 (0.0, 0) を返し、それ以外の場合は、 0.5 <= abs(m) < 1 を返します。これは浮動小数点型の内部表現を可搬性を保ったまま “分解 (pick apart)” するためです。

math.fsum(iterable)

iterable 中の値の浮動小数点数の正確な和を返します。複数の部分和を追跡することで桁落ちを防ぎます:

>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
0.9999999999999999
>>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
1.0

アルゴリズムの正確性は IEEE-754 演算の保証と丸めモードが偶数丸め (half-even) である典型的な場合に依存します。 Windows以外の幾つかのビルドでは、依存するCライブラリが、拡張精度の加算と時々時々合計の中間値を double 型へ丸めを行ってしまい、最下位ビットの消失が発生します。

より詳しい議論と代替となる二つのアプローチについては、 ASPN cookbook recipes for accurate floating point summation [http://code.activestate.com/recipes/393090/] をご覧下さい。

バージョン 2.6 で追加.

math.isinf(x)

浮動小数点数 x が正または負の無限大であるかチェックします。

バージョン 2.6 で追加.

math.isnan(x)

浮動小数点数 x が NaN (not a number) であるかチェックします。 NaN についての詳しい情報は、 IEEE 754 標準を参照してください。

バージョン 2.6 で追加.

math.ldexp(x, i)

x * (2**i) を返します。

math.modf(x)

x の小数部分と整数部分を返します。両方の結果は x の符号を受け継ぎます。整数部はfloat型で返されます。

math.trunc(x)

x の Integral (たいてい長整数)へ切り捨てられた Real 値を返します。 __trunc__ メソッドを利用します。

バージョン 2.6 で追加.

frexp() と modf() は C のものとは異なった呼び出し/返しパターンを持っていることに注意してください。引数を1つだけ受け取り、1組のペアになった値を返すので、2つ目の戻り値を ‘出力用の引数’ 経由で返したりはしません (Python には出力用の引数はありません)。

ceil() 、 floor() 、および modf() 関数については、非常に大きな浮動小数点数が 全て 整数そのものになるということに注意してください。通常、Python の浮動小数点型は 53 ビット以上の精度をもたない (プラットフォームにおける C double 型と同じ) ので、結果的に abs(x) >= 2**52 であるような浮動小数点型 x は小数部分を持たなくなるのです。

9.2.2. 指数および対数関数

math.exp(x)

e**x を返します。

math.expm1(x)

e**x - 1 を返します。 x が小さい float の場合は、 exp(x) - 1 の減算は桁落ちを発生させるかもしれません。 expm1() 関数はこの計算を完全な精度で実行します。

>>> from math import exp, expm1
>>> exp(1e-5) - 1  # gives result accurate to 11 places
1.0000050000069649e-05
>>> expm1(1e-5)    # result accurate to full precision
1.0000050000166668e-05

バージョン 2.7 で追加.

math.log(x[, base])

引数が1つの場合、 x の (e を底とする)自然対数を返します。

引数が2つの場合、 log(x)/log(base) として求められる base を底とした x の対数を返します。

バージョン 2.3 で変更: base 引数が追加されました。

math.log1p(x)

1+x の自然対数(つまり底 e の対数)を返します。結果はゼロに近い x に対して正確になるような方法で計算されます。

バージョン 2.6 で追加.

math.log10(x)

x の10を底とした対数(常用対数)を返します。この関数は通常、 log(x, 10) よりも高精度です。

math.pow(x, y)

x の y 乗を返します。例外的な場合については、 C99 標準の付録 ‘F’ に可能な限り従います。特に、 pow(1.0, x) と pow(x, 0.0) は、たとえ x が零や NaN でも、常に 1.0 を返します。もし x と y の両方が有限の値で、 x が負、 y が整数でない場合、 pow(x, y) は未定義で、 ValueError を送出します。

バージョン 2.6 で変更: 以前は 1**nan や nan**0 の結果は未定義でした。

math.sqrt(x)

x の平方根を返します。

9.2.3. 三角関数

math.acos(x)

x の逆余弦を返します。

math.asin(x)

x の逆正弦を返します。

math.atan(x)

x の逆正接を返します。

math.atan2(y, x)

y / x の逆正接をラジアンで返します。戻り値は -pi から pi の間になります。この角度は、極座標平面において原点から (x, y) へのベクトルが X 軸の正の方向となす角です。 atan2() のポイントは、入力 x, y の両方の符号が既知であるために、位相角の正しい象限を計算できることにあります。例えば、 atan(1) と atan2(1, 1) はいずれも pi/4 ですが、 atan2(-1, -1) は -3*pi/4 になります。

math.cos(x)

x の余弦を返します。

math.hypot(x, y)

ユークリッド距離(sqrt(x*x + y*y))を返します。

math.sin(x)

x の正弦を返します。

math.tan(x)

x の正接を返します。

9.2.4. 角度に関する関数

math.degrees(x)

角 x をラジアンから度に変換します。

math.radians(x)

角 x を度からラジアンに変換します。

9.2.5. 双曲線関数

math.acosh(x)

x の逆双曲線余弦を返します。

バージョン 2.6 で追加.

math.asinh(x)

x の逆双曲線正弦を返します。

バージョン 2.6 で追加.

math.atanh(x)

x の逆双曲線正接を返します。

バージョン 2.6 で追加.

math.cosh(x)

x の双曲線余弦を返します。

math.sinh(x)

x の双曲線正弦を返します。

math.tanh(x)

x の双曲線正接を返します。

9.2.6. 特殊な関数

math.erf(x)

x の誤差関数を返します。

バージョン 2.7 で追加.

math.erfc(x)

x の相補誤差関数を返します。

バージョン 2.7 で追加.

math.gamma(x)

x のガンマ関数を返します。

バージョン 2.7 で追加.

math.lgamma(x)

x のガンマ関数の絶対値の自然対数を返します。

バージョン 2.7 で追加.

9.2.7. 定数

math.pi

利用可能な精度の、数学定数 π = 3.141592... (円周率)

math.e

利用可能な精度の、数学定数 e = 2.718281... (自然対数の底)

CPython implementation detail: math モジュールは、ほとんどが実行プラットフォームにおける C 言語の数学ライブラリ関数に対する薄いラッパでできています。例外的な場合での挙動は、適切である限り C99 標準の Annex F に従います。現在の実装では、(C99 Annex F でゼロ除算か不正な演算やゼロ除算を通知することが推奨されている) sqrt(-1.0) や log(0.0) といった不正な操作に対して ValueError を発生させ、(例えば exp(1000.0) のような) 演算結果がオーバーフローする場合には OverflowError を発生させます。上記の関数群は、1つ以上の引数が NaN であった場合を除いて、 NaN を返しません。引数に NaN が与えられた場合は、殆どの関数は NaN を返しますが、 (C99 Annex F に従って) 別の動作をする場合があります。例えば、 pow(float('nan'), 0.0) や hypot(float('nan'), float('inf')) といった場合です。

Python は signaling NaN と quiet NaN を区別せず、 signaling NaN に対する挙動は未定義とされていることに注意してください。典型的な挙動は、全ての NaN を quiet NaN として扱うことです。

バージョン 2.6 で変更.

参考

Module cmath

これらの多くの関数の複素数版。

注記

[1]
訳注：例外が発生せずに結果が返ると、計算結果がおかしくなった原因が複素数を渡したためだということに気づくのが遅れる可能性があります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.3. cmath — 複素数のための数学関数

このモジュールは常に利用できます。提供しているのは複素数を扱う数学関数へのアクセス手段です。このモジュール中の関数は整数、浮動小数点数または複素数を引数にとります。また、 __complex__() または __float__() どちらかのメソッドを提供している Python オブジェクトも受け付けます。これらのメソッドはそのオブジェクトを複素数または浮動小数点数に変換するのにそれぞれ使われ、呼び出された関数はそうして変換された結果を利用します。

ノート

ハードウェア及びシステムレベルでの符号付きゼロのサポートがあるプラットフォームでは、分枝切断 (branch cut) の関わる関数において切断された両側の分枝で連続になります。ゼロの符号でどちらの分枝であるかを区別するのです。符号付きゼロがサポートされないプラットフォームでは連続性は以下の仕様で述べるようになります。

9.3.1. 極座標変換

Python の複素数 z は内部的には 直交座標 もしくは カーテシアン座標 と呼ばれる座標を使って格納されています。この座標はその複素数の 実部 z.real と 虚部 z.imag で決まります。言い換えると

z == z.real + z.imag*1j

ということです。

極座標 は複素数を表現する別の方法です。極座標では、複素数 z は半径 r と位相角 phi で定義されます。半径 r は z から原点までの距離です。位相 phi は x 軸の正の部分から原点と z を結んだ線分までの角度を反時計回りにラジアンで測った値です。

次の関数はネイティブの直交座標を極座標に変換したりその逆を行うのに使えます。

cmath.phase(x)

x の位相 (x の 偏角 とも呼びます) を浮動小数点数で返します。 phase(x) は math.atan2(x.imag, x.real) と同等です。返り値は [-π, π] の範囲にあり、この演算の分枝切断は負の実軸に沿って延びていて、上から連続です。 (現在のほとんどのシステムはそうですが) 符号付きゼロをサポートしているシステムでは、返り値の符号は x.imag がゼロであってもその符号と等しくなります:

>>> phase(complex(-1.0, 0.0))
3.1415926535897931
>>> phase(complex(-1.0, -0.0))
-3.1415926535897931

バージョン 2.6 で追加.

ノート

複素数 x の半径 (絶対値) は組み込みの abs() 関数でも計算することができます。この演算を行う cmath モジュールの関数はありません。

cmath.polar(x)

x の極座標表現を返します。 x の半径 r と x の位相 phi の組 (r, phi) を返します。 polar(x) は (abs(x), phase(x)) に等しいです。

バージョン 2.6 で追加.

cmath.rect(r, phi)

極座標 r, phi を持つ複素数 x を返します。値は r * (math.cos(phi) + math.sin(phi)*1j) に等しいです。

バージョン 2.6 で追加.

9.3.2. 指数関数と対数関数

cmath.exp(x)

指数 e**x を返します。

cmath.log(x[, base])

base を底とする x の対数を返します。もし base が指定されていない場合には、 x の自然対数を返します。分枝切断を一つもち、 0 から負の実数軸に沿って -∞ へと延びており、上から連続しています。

バージョン 2.4 で変更: base 引数が追加されました。

cmath.log10(x)

x の底を 10 とする対数を返します。 log() と同じ分枝切断を持ちます。

cmath.sqrt(x)

x の平方根を返します。 log() と同じ分枝切断を持ちます。

9.3.3. 三角関数

cmath.acos(x)

x の逆余弦を返します。この関数には二つの分枝切断(branch cut)があります: 一つは 1 から右側に実数軸に沿って∞へと延びていて、下から連続しています。もう一つは -1 から左側に実数軸に沿って -∞へと延びていて、上から連続しています。

cmath.asin(x)

x の逆正弦を返します。 acos() と同じ分枝切断を持ちます。

cmath.atan(x)

x の逆正接を返します。二つの分枝切断があります: 一つは 1j から虚数軸に沿って ∞j へと延びており、右から連続です。もう一つは -1j から虚数軸に沿って -∞j へと延びており、左から連続です。

バージョン 2.6 で変更: 上側の分割での連続な方向が逆転しました。

cmath.cos(x)

x の余弦を返します。

cmath.sin(x)

x の正弦を返します。

cmath.tan(x)

x の正接を返します。

9.3.4. 双曲線関数

cmath.acosh(x)

x の逆双曲線余弦を返します。分枝切断が一つあり、1 の左側に実数軸に沿って -∞へと延びていて、上から連続しています。

cmath.asinh(x)

x の逆双曲線正弦を返します。二つの分枝切断があります：一つは 1j から虚数軸に沿って ∞j へと延びており、右から連続です。もう一つは -1j から虚数軸に沿って -∞j へと延びており、左から連続です。

バージョン 2.6 で変更: 分枝切断が C99 標準で推奨されたものに合わせて動かされました。

cmath.atanh(x)

x の逆双曲線正接を返します。二つの分枝切断があります: 一つは 1 から実数軸に沿って ∞ へと延びており、下から連続です。もう一つは -1 から実数軸に沿って -∞ へと延びており、上から連続です。

バージョン 2.6 で変更: 右側の分割での連続な方向が逆転しました。

cmath.cosh(x)

x の双曲線余弦を返します。

cmath.sinh(x)

x の双曲線正弦を返します。

cmath.tanh(x)

x の双曲線正接を返します。

9.3.5. 類別関数

cmath.isinf(x)

x の実数部または虚数部が正または負の無限大であれば True を返します。

バージョン 2.6 で追加.

cmath.isnan(x)

x の実数部または虚数部が非数 (NaN) であれば True を返します。

バージョン 2.6 で追加.

9.3.6. 定数

cmath.pi

定数 π (円周率)で、浮動小数点数です。

cmath.e

定数 e (自然対数の底)で、浮動小数点数です。

math と同じような関数が選ばれていますが、全く同じではないので注意してください。機能を二つのモジュールに分けているのは、複素数に興味がなかったり、もしかすると複素数とは何かすら知らないようなユーザがいるからです。そういった人たちはむしろ、 math.sqrt(-1) が複素数を返すよりも例外を送出してほしいと考えます。また、 cmath で定義されている関数は、たとえ結果が実数で表現可能な場合 (虚数部がゼロの複素数) でも、常に複素数を返すので注意してください。

分枝切断(branch cut)に関する注釈: 分枝切断をもつ曲線上では、与えられた関数は連続でありえなくなります。これらは多くの複素関数における必然的な特性です。複素関数を計算する必要がある場合、これらの分枝に関して理解しているものと仮定しています。悟りに至るために何らかの(到底基礎的とはいえない)複素数に関する書をひもといてください。数値計算を目的とした分枝切断の正しい選択方法についての情報としては、以下がよい参考文献となります:

参考

Kahan, W: Branch cuts for complex elementary functions; or, Much ado about nothings’s sign bit. In Iserles, A., and Powell, M. (eds.), The state of the art in numerical analysis. Clarendon Press (1987) pp165-211.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.4. decimal — 10進固定及び浮動小数点数の算術演算

バージョン 2.4 で追加.

decimal モジュールは10進の浮動小数点算術をサポートします。 decimal には、 float データ型に比べて、以下のような利点があります:

Decimal は「人々を念頭にデザインされた浮動小数点を元にしており、必然的に最も重要な指針があります – コンピュータは人々が学校で習った算術と同じように動作する算術を提供しなければならない」 – 10進数演算仕様より

10進数を正確に表現できます。 1.1 や 2.2 のような数は、2 進数の浮動小数点型では正しく表現できません。エンドユーザは普通、 2 進数における 1.1 + 2.2 の近似値が 3.3000000000000003 だからといって、そのように表示してほしいとは考えないものです。

値の正確さは算術にも及びます。10進の浮動小数点による計算では、 0.1 + 0.1 + 0.1 - 0.3 は厳密にゼロに等しくなります。 2 進浮動小数点では 5.5511151231257827e-017 になってしまいます。ゼロに近い値とはいえ、この誤差は数値間の等価性テストの信頼性を阻害します。また、誤差が蓄積されることもあります。こうした理由から、数値間の等価性を厳しく保たねばならないようなアプリケーションを考えるなら、10進数による数値表現が望ましいということになります。

decimal モジュールでは、有効桁数の表記が取り入れられており、例えば 1.30 + 1.20 は 2.50 になります。すなわち、末尾のゼロは有効数字を示すために残されます。こうした仕様は通貨計算を行うアプリケーションでは慣例です。乗算の場合、「教科書的な」アプローチでは、乗算の被演算子すべての桁数を使います。例えば、 1.3 * 1.2 は 1.56 になり、 1.30 * 1.20 は 1.5600 になります。

ハードウェアによる 2 進浮動小数点表現と違い、 decimal モジュールでは計算精度をユーザが変更できます(デフォルトでは 28 桁です)。この桁数はほとんどの問題解決に十分な大きさです:

>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')

2進と10進の浮動小数点は、いずれも広く公開されている標準仕様のもとに実装されています。組み込みの浮動小数点型では、標準仕様で提唱されている機能のほんのささやかな部分を利用できるにすぎませんが、 decimal では標準仕様が要求している全ての機能を利用できます。必要に応じて、プログラマは値の丸めやシグナル処理を完全に制御できます。この中には全ての不正確な操作を例外でブロックして正確な算術を遵守させるオプションもあります。

decimal モジュールは「偏見なく、正確な丸めなしの十進算術(固定小数点算術と呼ばれることもある)と丸めありの浮動小数点数算術」(10進数演算仕様より引用)をサポートするようにデザインされました。

このモジュールは、10進数型、算術コンテキスト (context for arithmetic)、そしてシグナル (signal) という三つの概念を中心に設計されています、

10進数型は変更不可能な型です。この型には符号部、仮数部、そして指数部があります。有効桁数を残すために、仮数部の末尾にあるゼロの切り詰めは行われません。 decimal では、 Infinity, -Infinity, および NaN といった特殊な値も定義されています。標準仕様では -0 と +0 も区別しています。

算術コンテキストとは、精度や値丸めの規則、指数部の制限を決めている環境です。この環境では、演算結果を表すためのフラグや、演算上発生した特定のシグナルを例外として扱うかどうかを決めるトラップイネーブラも定義しています。丸め規則には ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, および ROUND_05UP があります。

シグナルとは、演算の過程で生じる例外的条件です。個々のシグナルは、アプリケーションそれぞれの要求に従って、無視されたり、単なる情報とみなされたり、例外として扱われたりします。 decimal モジュールには、 Clamped, InvalidOperation, DivisionByZero, Inexact, Rounded, Subnormal, Overflow, および Underflow といったシグナルがあります。

各シグナルには、フラグとトラップイネーブラがあります。演算上何らかのシグナルに遭遇すると、フラグは 1 にセットされてゆきます。このとき、もしトラップイネーブラが 1 にセットされていれば、例外を送出します。フラグの値は膠着型 (sticky) なので、演算によるフラグの変化をモニタしたければ、予めフラグをリセットしておかねばなりません。

参考

IBM による汎用10進演算仕様、 The General Decimal Arithmetic Specification [http://speleotrove.com/decimal/] 。

IEEE 標準化仕様 854-1987, IEEE 854 に関する非公式のテキスト [http://754r.ucbtest.org/standards/854.pdf] 。

9.4.1. Quick-start Tutorial

普通、 decimal を使うときには、モジュールを import し、現在の演算コンテキストを getcontext() で調べ、必要に応じて精度や丸めを設定し、演算エラーのトラップを有効にします:

>>> from decimal import *
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
        capitals=1, flags=[], traps=[Overflow, DivisionByZero,
        InvalidOperation])

>>> getcontext().prec = 7       # 新たな精度を設定

Decimal のインスタンスは、整数、文字列、浮動小数点数、またはタプルから構成できます。整数や浮動小数点数からの構成は、整数や浮動小数点数の値を正確に変換します。 Decimal は “数値ではない (Not a Number)” を表す NaN や正負の Infinity (無限大)、 -0 といった特殊な値も表現できます。

>>> getcontext().prec = 28
>>> Decimal(10)
Decimal('10')
>>> Decimal('3.14')
Decimal('3.14')
>>> Decimal(3.14)
Decimal('3.140000000000000124344978758017532527446746826171875')
>>> Decimal((0, (3, 1, 4), -2))
Decimal('3.14')
>>> Decimal(str(2.0 ** 0.5))
Decimal('1.41421356237')
>>> Decimal(2) ** Decimal('0.5')
Decimal('1.414213562373095048801688724')
>>> Decimal('NaN')
Decimal('NaN')
>>> Decimal('-Infinity')
Decimal('-Infinity')

新たな Decimal 型数値の有効桁数は入力した数の桁数だけで決まります。演算コンテキストにおける精度や値丸めの設定が影響するのは算術操作の中だけです。

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

Decimal 型数値はほとんどの場面で Python の他の機能とうまくやりとりできます。 Decimal 浮動小数点小劇場 (flying circus) を示しましょう:

>>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())
>>> max(data)
Decimal('9.25')
>>> min(data)
Decimal('0.03')
>>> sorted(data)
[Decimal('0.03'), Decimal('1.00'), Decimal('1.34'), Decimal('1.87'),
 Decimal('2.35'), Decimal('3.45'), Decimal('9.25')]
>>> sum(data)
Decimal('19.29')
>>> a,b,c = data[:3]
>>> str(a)
'1.34'
>>> float(a)
1.34
>>> round(a, 1)     # round() は値をまず二進の浮動小数点数に変換します
1.3
>>> int(a)
1
>>> a * 5
Decimal('6.70')
>>> a * b
Decimal('2.5058')
>>> c % a
Decimal('0.77')

いくつかの数学的関数も Decimal には用意されています:

>>> getcontext().prec = 28
>>> Decimal(2).sqrt()
Decimal('1.414213562373095048801688724')
>>> Decimal(1).exp()
Decimal('2.718281828459045235360287471')
>>> Decimal('10').ln()
Decimal('2.302585092994045684017991455')
>>> Decimal('10').log10()
Decimal('1')

quantize() メソッドは位を固定して数値を丸めます。このメソッドは、計算結果を固定の桁数で丸めることがよくある、通貨を扱うアプリケーションで便利です:

>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('1.'), rounding=ROUND_UP)
Decimal('8')

前述のように、 getcontext() 関数を使うと現在の演算コンテキストにアクセスでき、設定を変更できます。ほとんどのアプリケーションはこのアプローチで十分です。

より高度な作業を行う場合、 Context() コンストラクタを使って別の演算コンテキストを作っておくと便利なことがあります。別の演算コンテキストをアクティブにしたければ、 setcontext() を使います。

Decimal モジュールでは、標準仕様に従って、すぐ利用できる二つの標準コンテキスト、 BasicContext および ExtendedContext を提供しています。後者はほとんどのトラップが有効になっており、とりわけデバッグの際に便利です:

>>> myothercontext = Context(prec=60, rounding=ROUND_HALF_DOWN)
>>> setcontext(myothercontext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857142857142857142857142857')

>>> ExtendedContext
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
        capitals=1, flags=[], traps=[])
>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(7)
Decimal('0.142857143')
>>> Decimal(42) / Decimal(0)
Decimal('Infinity')

>>> setcontext(BasicContext)
>>> Decimal(42) / Decimal(0)
Traceback (most recent call last):
  File "<pyshell#143>", line 1, in -toplevel-
    Decimal(42) / Decimal(0)
DivisionByZero: x / 0

演算コンテキストには、演算中に遭遇した例外的状況をモニタするためのシグナルフラグがあります。フラグが一度セットされると、明示的にクリアするまで残り続けます。そのため、フラグのモニタを行いたいような演算の前には clear_flags() メソッドでフラグをクリアしておくのがベストです。 :

>>> setcontext(ExtendedContext)
>>> getcontext().clear_flags()
>>> Decimal(355) / Decimal(113)
Decimal('3.14159292')
>>> getcontext()
Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
        capitals=1, flags=[Rounded, Inexact], traps=[])

flags エントリから、 Pi の有理数による近似値が丸められた (コンテキスト内で決められた精度を超えた桁数が捨てられた) ことと、計算結果が厳密でない (無視された桁の値に非ゼロのものがあった) ことがわかります。

コンテキストの traps フィールドに入っている辞書を使うと、個々のトラップをセットできます:

>>> setcontext(ExtendedContext)
>>> Decimal(1) / Decimal(0)
Decimal('Infinity')
>>> getcontext().traps[DivisionByZero] = 1
>>> Decimal(1) / Decimal(0)
Traceback (most recent call last):
  File "<pyshell#112>", line 1, in -toplevel-
    Decimal(1) / Decimal(0)
DivisionByZero: x / 0

ほとんどのプログラムでは、開始時に一度だけ現在の演算コンテキストを修正します。また、多くのアプリケーションでは、データから Decimal への変換はループ内で一度だけキャストして行います。コンテキストを設定し、 Decimal オブジェクトを生成できたら、ほとんどのプログラムは他の Python 数値型と全く変わらないかのように Decimal を操作できます。

9.4.2. Decimal オブジェクト

class decimal.Decimal([value[, context]])

value に基づいて新たな Decimal オブジェクトを構築します。

value は整数、文字列、タプル、 float および他の Decimal オブジェクトにできます。 value を指定しない場合、 Decimal("0") を返します。 value が文字列の場合、先頭と末尾の空白を取り除いた後には以下の 10進数文字列の文法に従わねばなりません:

sign           ::=  '+' | '-'
digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
indicator      ::=  'e' | 'E'
digits         ::=  digit [digit]...
decimal-part   ::=  digits '.' [digits] | ['.'] digits
exponent-part  ::=  indicator [sign] digits
infinity       ::=  'Infinity' | 'Inf'
nan            ::=  'NaN' [digits] | 'sNaN' [digits]
numeric-value  ::=  decimal-part [exponent-part] | infinity
numeric-string ::=  [sign] numeric-value | [sign] nan

value をユニコード文字列にした場合、他のユニコード数字も上の digit の場所に使うことができます。つまり各書記体系における(アラビア-インド系やデーヴァナーガリーなど)の数字や、全角数字０(u'\uff10')から９(u'\uff19')までなどです。

value を tuple にする場合、タプルは三つの要素を持ち、それぞれ符号 (正なら 0 、負なら 1)、仮数部を表す数字のタプル、そして指数を表す整数でなければなりません。例えば、 Decimal((0, (1, 4, 1, 4), -3)) は Decimal('1.414') を返します。

value を float にする場合、2進浮動小数点数値が損失なく正確に等価な Decimal に変換されます。この変換はしばしば 53 桁以上の精度を要求します。例えば、 Decimal(float('1.1')) は Decimal('1.100000000000000088817841970012523233890533447265625') に変換されます。

context に指定した精度 (precision) は、オブジェクトが記憶する桁数には影響しません。桁数は value に指定した桁数だけから決定されます。例えば、演算コンテキストに指定された精度が 3 桁しかなくても、Decimal('3.00000') は 5 つのゼロを全て記憶します。

context 引数の目的は、 value が正しくない形式の文字列であった場合に行う処理を決めることにあります; 演算コンテキストが InvalidOperation をトラップするようになっていれば、例外を送出します。それ以外の場合には、コンストラクタは値が NaN の Decimal を返します。

一度生成すると、 Decimal オブジェクトは変更不能 (immutable) になります。

バージョン 2.6 で変更: 文字列から Decimal インスタンスを生成する際に先頭と末尾の空白が許されることになりました。

バージョン 2.7 で変更: このコンストラクタの引数は、 float インスタンスにもできるようになりました。

10進浮動小数点オブジェクトは、 float や int のような他の組み込み型と多くの点で似ています。通常の数学演算や特殊メソッドを適用できます。また、 Decimal オブジェクトはコピーでき、pickle 化でき、print で出力でき、辞書のキーにでき、集合の要素にでき、比較、保存、他の型 (float や long) への型強制を行えます。

Decimal オブジェクトは一般に、算術演算で浮動小数点数と組み合わせることができません。例えば、 Decimal に float を足そうとすると、 TypeError が送出されます。ただしこの規則には例外があります。 float インスタンス x と Decimal インスタンス y を比較する比較演算子です。この例外がなかったとすると、 Decimal と float インスタンスの比較は、リファレンスマニュアルの式 (expression) 節で記述されている、異なる型のオブジェクトを比較するときの一般の規則に従うことになり、紛らわしい結果につながります。

バージョン 2.7 で変更: float インスタンス x と Decimal インスタンス y の比較は、 x と y の値に基づく結果を返すようになりました。以前のバージョンでは、どんな float インスタンス x とどんな Decimal インスタンス y に対しても、 x < y は同じ(任意の) 結果を返していました。

こうした標準的な数値型の特性の他に、10進浮動小数点オブジェクトには様々な特殊メソッドがあります:

adjusted()

仮数部の先頭の一桁だけが残るように右側の数字を追い出す桁シフトを行い、その結果の指数部を返します: Decimal('321e+5').adjusted() なら 7 です。最上桁の小数点からの相対位置を調べる際に使います。

as_tuple()

数値を表現するための名前付きタプル(named tuple): (sign, digittuple, exponent) を返します。

バージョン 2.6 で変更: 名前付きタプルを使用するようになりました。

canonical()

引数の標準的(canonical)エンコーディングを返します。現在のところ、 Deciaml インスタンスのエンコーディングは常に標準的なので、この操作は引数に手を加えずに返します。

バージョン 2.6 で追加.

compare(other[, context])

二つの Decimal インスタンスを比較します。この演算は通常の比較メソッド __cmp__() と同じように振る舞いますが、整数でなく Decimal インスタンスを返すところと、両方の引数が NaN だったときに結果としても NaN を返すところが異なります。:

a or b is a NaN ==> Decimal("NaN")
a < b           ==> Decimal("-1")
a == b          ==> Decimal("0")
a > b           ==> Decimal("1")

compare_signal(other[, context])

この演算は compare() とほとんど同じですが、全ての NaN がシグナルを送るところが異なります。すなわち、どちらの比較対象も発信 (signaling) NaN でないならば無言(quiet) NaN である比較対象があたかも発信 NaN であるかのように扱われます。

バージョン 2.6 で追加.

compare_total(other)

二つの対象を数値によらず抽象表現によって比較します。 compare() に似ていますが、結果は Decimal に全順序を与えます。この順序づけによると、数値的に等しくても異なった表現を持つ二つの Decimal インスタンスの比較は等しくなりません:

>>> Decimal('12.0').compare_total(Decimal('12'))
Decimal('-1')

無言 NaN と発信 NaN もこの全順序に位置付けられます。この関数の結果は、もし比較対象が同じ表現を持つならば Decimal('0') であり、一つめの比較対象が二つめより下位にあれば Decimal('-1') 、上位にあれば Decimal('1') です。全順序の詳細については仕様を参照してください。

バージョン 2.6 で追加.

compare_total_mag(other)

二つの対象を compare_total() のように数値によらず抽象表現によって比較しますが、両者の符号を無視します。 x.compare_total_mag(y) は x.copy_abs().compare_total(y.copy_abs()) と等価です。

バージョン 2.6 で追加.

conjugate()

self を返すだけです。このメソッドは十進演算仕様に適合するためだけのものです。

バージョン 2.6 で追加.

copy_abs()

引数の絶対値を返します。この演算はコンテキストに影響されず、静かです。すなわち、フラグは変更されず、丸めは行われません。

バージョン 2.6 で追加.

copy_negate()

引数の符号を変えて返します。この演算はコンテキストに影響されず、静かです。すなわち、フラグは変更されず、丸めは行われません。

バージョン 2.6 で追加.

copy_sign(other)

最初の演算対象のコピーに二つめと同じ符号を付けて返します。たとえば:

>>> Decimal('2.3').copy_sign(Decimal('-1.5'))
Decimal('-2.3')

この演算はコンテキストに影響されず、静かです。すなわち、フラグは変更されず、丸めは行われません。

バージョン 2.6 で追加.

exp([context])

与えられた数での(自然)指数関数 e**x の値を返します。結果は ROUND_HALF_EVEN 丸めモードで正しく丸められます。

>>> Decimal(1).exp()
Decimal('2.718281828459045235360287471')
>>> Decimal(321).exp()
Decimal('2.561702493119680037517373933E+139')

バージョン 2.6 で追加.

from_float(f)

浮動小数点数を正確に小数に変換するクラスメソッドです。

なお、 Decimal.from_float(0.1) は Decimal(‘0.1’) と同じではありません。 0.1 は二進浮動小数点数で正確に表せないので、その値は表現できる最も近い値、 0x1.999999999999ap-4 として記憶されます。浮動小数点数での等価な値は 0.1000000000000000055511151231257827021181583404541015625 です。

ノート

Python 2.7 以降では、 Decimal インスタンスは float から直接構成することも出来ます。

>>> Decimal.from_float(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> Decimal.from_float(float('nan'))
Decimal('NaN')
>>> Decimal.from_float(float('inf'))
Decimal('Infinity')
>>> Decimal.from_float(float('-inf'))
Decimal('-Infinity')

バージョン 2.7 で追加.

fma(other, third[, context])

融合積和(fused multiply-add)です。self*other+third を途中結果の積 self*other で丸めを行わずに計算して返します。

>>> Decimal(2).fma(3, 5)
Decimal('11')

バージョン 2.6 で追加.

is_canonical()

引数が標準的(canonical)ならば True を返し、そうでなければ False を返します。現在のところ、 Decimal のインスタンスは常に標準的なのでこのメソッドの結果はいつでも True です。

バージョン 2.6 で追加.

is_finite()

引数が有限の数値ならば True を、無限大か NaN ならば False を返します。

バージョン 2.6 で追加.

is_infinite()

引数が正または負の無限大ならば True を、そうでなければ False を返します。

バージョン 2.6 で追加.

is_nan()

引数が(無言か発信かは問わず) NaN であれば True を、そうでなければ False を返します。

バージョン 2.6 で追加.

is_normal()

引数が 正規(normal) のゼロでない有限数値で調整された指数が Emin 以上ならば True を返します。引数がゼロ、非正規(subnormal)、無限大または NaN であれば False を返します。ここでの 正規 という用語は標準的な(canonical)値を作り出すために使われる normalize() メソッドにおける意味合いとは異なりますので注意して下さい。

バージョン 2.6 で追加.

is_qnan()

引数が無言 NaN であれば True を、そうでなければ False を返します。

バージョン 2.6 で追加.

is_signed()

引数に負の符号がついていれば True を、そうでなければ False を返します。注意すべきはゼロや NaN なども符号を持ち得ることです。

バージョン 2.6 で追加.

is_snan()

引数が発信 NaN であれば True を、そうでなければ False を返します。

バージョン 2.6 で追加.

is_subnormal()

引数が非正規数(subnormal)であれば True を、そうでなければ False を返します。非正規な数値とは、ゼロでなく、有限で、調整された指数が Emin 未満のものを指します。

バージョン 2.6 で追加.

is_zero()

引数が(正または負の)ゼロであれば True を、そうでなければ False を返します。

バージョン 2.6 で追加.

ln([context])

演算対象の自然対数(底 e の対数)を返します。結果は ROUND_HALF_EVEN 丸めモードで正しく丸められます。

バージョン 2.6 で追加.

log10([context])

演算対象の常用対数(底 10 の対数)を返します。結果は ROUND_HALF_EVEN 丸めモードで正しく丸められます。

バージョン 2.6 で追加.

logb([context])

非零の数値については、 Decimal インスタンスとして調整された指数を返します。演算対象がゼロだった場合、 Decimal('-Infinity') が返され DivisionByZero フラグが送出されます。演算対象が無限大だった場合、 Decimal('Infinity') が返されます。

バージョン 2.6 で追加.

logical_and(other[, context])

logical_and() は二つの 論理引数 (論理引数参照)を取る論理演算です。結果は二つの引数の数字ごとの and です。

バージョン 2.6 で追加.

logical_invert([context])

logical_invert() は論理演算です。結果は引数の数字ごとの反転です。

バージョン 2.6 で追加.

logical_or(other[, context])

logical_or() は二つの 論理引数 (論理引数参照)を取る論理演算です。結果は二つの引数の数字ごとの or です。

バージョン 2.6 で追加.

logical_xor(other[, context])

logical_xor() は二つの 論理引数 (論理引数参照)を取る論理演算です。結果は二つの引数の数字ごとの排他的論理和です。

バージョン 2.6 で追加.

max(other[, context])

max(self, other) と同じですが、値を返す前に現在のコンテキストに即した丸め規則を適用します。また、 NaN に対して、(コンテキストの設定と、発信か無言どちらのタイプであるかに応じて) シグナルを発行するか無視します。

max_mag(other[, context])

max() メソッドに似ていますが、比較は絶対値で行われます。

バージョン 2.6 で追加.

min(other[, context])

min(self, other) と同じですが、値を返す前に現在のコンテキストに即した丸め規則を適用します。また、 NaN に対して、(コンテキストの設定と、発信か無言どちらのタイプであるかに応じて) シグナルを発行するか無視します。

min_mag(other[, context])

min() メソッドに似ていますが、比較は絶対値で行われます。

バージョン 2.6 で追加.

next_minus([context])

与えられたコンテキスト(またはコンテキストが渡されなければ現スレッドのコンテキスト)において表現可能な、操作対象より小さい最大の数を返します。

バージョン 2.6 で追加.

next_plus([context])

与えられたコンテキスト(またはコンテキストが渡されなければ現スレッドのコンテキスト)において表現可能な、操作対象より大きい最小の数を返します。

バージョン 2.6 で追加.

next_toward(other[, context])

二つの比較対象が等しくなければ、一つめの対象に最も近く二つめの対象へ近付く方向の数を返します。もし両者が数値的に等しければ、二つめの対象の符号を採った一つめの対象のコピーを返します。

バージョン 2.6 で追加.

normalize([context])

数値を正規化 (normalize) して、右端に連続しているゼロを除去し、 Decimal('0') と同じ結果はすべて Decimal('0e0') に変換します。同じクラスの値から基準表現を生成する際に用います。たとえば、 Decimal('32.100') と Decimal('0.321000e+2') の正規化は、いずれも同じ値 Decimal('32.1') になります。

number_class([context])

操作対象の クラス を表す文字列を返します。返されるのは以下の10種類のいずれかです。

"-Infinity", 負の無限大であることを示します。

"-Normal", 負の通常数であることを示します。

"-Subnormal", 負の非正規数であることを示します。

"-Zero", 負のゼロであることを示します。

"+Zero", 正のゼロであることを示します。

"+Subnormal", 正の非正規数であることを示します。

"+Normal", 正の通常数であることを示します。

"+Infinity", 正の無限大であることを示します。

"NaN", 無言(quiet) NaN (Not a Number) であることを示します。

"sNaN", 発信(signaling) NaN であることを示します。

バージョン 2.6 で追加.

quantize(exp[, rounding[, context[, watchexp]]])

二つめの操作対象と同じ指数を持つように丸めを行った、一つめの操作対象と等しい値を返します。

>>> Decimal('1.41421356').quantize(Decimal('1.000'))
Decimal('1.414')

他の操作と違い、打ち切り(quantize)操作後の係数の長さが精度を越えた場合には、 InvalidOperation がシグナルされます。これによりエラー条件がない限り打ち切られた指数が常に右側の引数と同じになることが保証されます。

同様に、他の操作と違い、 quantize は Underflow を、たとえ結果が非正規になったり不正確になったとしても、シグナルしません。

二つ目の演算対象の指数が一つ目のそれよりも大きければ丸めが必要かもしれません。この場合、丸めモードは以下のように決められます。 rounding 引数が与えられていればそれが使われます。そうでなければ context 引数で決まります。どちらの引数も渡されなければ現在のスレッドのコンテキストの丸めモードが使われます。

watchexp が (default) に設定されている場合、処理結果の指数が Emax よりも大きい場合や Etiny よりも小さい場合にエラーを返します。

radix()

Decimal(10) つまり Decimal クラスがその全ての算術を実行する基数を返します。仕様との互換性のために取り入れられています。

バージョン 2.6 で追加.

remainder_near(other[, context])

モジュロを計算し、正負のモジュロのうちゼロに近い値を返します。たとえば、 Decimal(10).remainder_near(6) は Decimal('4') よりもゼロに近い値 Decimal('-2') を返します。

ゼロからの差が同じ場合には、 self と同じ符号を持った方を返します。

rotate(other[, context])

一つめの演算対象の数字を二つめので指定された量だけ巡回(rotate)した結果を返します。二つめの演算対象は -precision から precision までの範囲の整数でなければなりません。この二つめの演算対象の絶対値が何桁ずらすかを決めます。そしてもし正の数ならば巡回の方向は左に、そうでなければ右になります。一つめの演算対象の仮数部は必要ならば精度いっぱいまでゼロで埋められます。符号と指数は変えられません。

バージョン 2.6 で追加.

same_quantum(other[, context])

self と other が同じ指数を持っているか、あるいは双方とも NaN である場合に真を返します。

scaleb(other[, context])

二つめの演算対象で調整された指数の一つめの演算対象を返します。同じことですが、一つめの演算対象を 10**other 倍したものを返します。二つめの演算対象は整数でなければなりません。

バージョン 2.6 で追加.

shift(other[, context])

一つめの演算対象の数字を二つめので指定された量だけシフトした結果を返します。二つめの演算対象は -precision から precision までの範囲の整数でなければなりません。この二つめの演算対象の絶対値が何桁ずらすかを決めます。そしてもし正の数ならばシフトの方向は左に、そうでなければ右になります。一つめの演算対象の係数は必要ならば精度いっぱいまでゼロで埋められます。符号と指数は変えられません。

バージョン 2.6 で追加.

sqrt([context])

平方根を精度いっぱいまで求めます。

to_eng_string([context])

数値を工学で用いられる形式 (工学表記; enginnering notation) の文字列に変換します。

工学表記では指数は 3 の倍数になります。従って、最大で 3 桁までの数字が基数の小数部に現れます。たとえば、 Decimal('123E+1') は Decimal('1.23E+3') に変換されます。

to_integral([rounding[, context]])

Inexact や Rounded といったシグナルを出さずに最近傍の整数に値を丸めます。 rounding が指定されていれば適用されます; それ以外の場合、値丸めの方法は context の設定か現在のコンテキストの設定になります。

to_integral_exact([rounding[, context]])

最近傍の整数に値を丸め、丸めが起こった場合には Inexact または Rounded のシグナルを適切に出します。丸めモードは以下のように決められます。 rounding 引数が与えられていればそれが使われます。そうでなければ context 引数で決まります。どちらの引数も渡されなければ現在のスレッドのコンテキストの丸めモードが使われます。

バージョン 2.6 で追加.

to_integral_value([rounding[, context]])

Inexact や Rounded といったシグナルを出さずに最近傍の整数に値を丸めます。 rounding が指定されていれば適用されます; それ以外の場合、値丸めの方法は context の設定か現在のコンテキストの設定になります。

バージョン 2.6 で変更: to_integral から to_integral_value に改名されました。古い名前も互換性のために残されています。

9.4.2.1. 論理引数

logical_and(), logical_invert(), logical_or(), および logical_xor() メソッドはその引数が 論理引数 であると想定しています。論理引数 とは Decimal インスタンスで指数と符号は共にゼロであり、各桁の数字が 0 か 1 であるものです。

9.4.3. Context オブジェクト

コンテキスト (context) とは、算術演算における環境設定です。コンテキストは計算精度を決定し、値丸めの方法を設定し、シグナルのどれが例外になるかを決め、指数の範囲を制限しています。

多重スレッドで処理を行う場合には各スレッドごとに現在のコンテキストがあり、 getcontext() や setcontext() といった関数でアクセスしたり設定変更できます:

decimal.getcontext()

アクティブなスレッドの現在のコンテキストを返します。

decimal.setcontext(c)

アクティブなスレッドのコンテキストを c に設定します。

Python 2.5 から、 with 文と localcontext() 関数を使って実行するコンテキストを一時的に変更することもできるようになりました。

decimal.localcontext([c])

with 文の入口でアクティブなスレッドのコンテキストを c のコピーに設定し、with 文を抜ける時に元のコンテキストに復旧する、コンテキストマネージャを返します。コンテキストが指定されなければ、現在のコンテキストのコピーが使われます。

バージョン 2.5 で追加.

たとえば、以下のコードでは精度を42桁に設定し、計算を実行し、そして元のコンテキストに復帰します。

from decimal import localcontext

with localcontext() as ctx:
    ctx.prec = 42   # 高精度の計算を実行
    s = calculate_something()
s = +s  # 最終的な結果をデフォルトの精度に丸める

新たなコンテキストは、以下で説明する Context コンストラクタを使って生成できます。その他にも、 decimal モジュールでは作成済みのコンテキストを提供しています:

class decimal.BasicContext

汎用10進演算仕様で定義されている標準コンテキストの一つです。精度は 9 桁に設定されています。丸め規則は ROUND_HALF_UP です。すべての演算結果フラグはクリアされています。 Inexact, Rounded, Subnormal を除く全ての演算エラートラップが有効 (例外として扱う) になっています。

多くのトラップが有効になっているので、デバッグの際に便利なコンテキストです。

class decimal.ExtendedContext

汎用10進演算仕様で定義されている標準コンテキストの一つです。精度は 9 桁に設定されています。丸め規則は ROUND_HALF_EVEN です。すべての演算結果フラグはクリアされています。トラップは全て無効(演算中に一切例外を送出しない) になっています。

トラップが無効になっているので、エラーの伴う演算結果を NaN や Infinity にし、例外を送出しないようにしたいアプリケーションに向いたコンテキストです。このコンテキストを使うと、他の場合にはプログラムが停止してしまうような状況があっても実行を完了させられます。

class decimal.DefaultContext

Context コンストラクタが新たなコンテキストを作成するさいに雛形にするコンテキストです。このコンテキストのフィールド (精度の設定など) を変更すると、 Context コンストラクタが生成する新たなコンテキストに影響を及ぼします。

このコンテキストは、主に多重スレッド環境で便利です。スレッドを開始する前に何らかのフィールドを変更しておくと、システム全体のデフォルト設定に効果を及ぼせます。スレッドを開始した後にフィールドを変更すると競合条件を抑制するためにスレッドを同期化せねばならないので推奨しません。

単一スレッドの環境では、このコンテキストを使わないよう薦めます。下で述べるように明示的にコンテキストを作成してください。

デフォルトの値は精度 28 桁、丸め規則 ROUND_HALF_EVEN で、トラップ Overflow, InvalidOperation, および DivisionByZero が有効になっています。

上に挙げた三つのコンテキストに加え、 Context コンストラクタを使って新たなコンテキストを生成できます。

class decimal.Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1)

新たなコンテキストを生成します。あるフィールドが定義されていないか None であれば、 DefaultContext からデフォルト値をコピーします。 flags フィールドが設定されていいか None の場合には、全てのフラグがクリアされます。

prec フィールドは正の整数で、コンテキストにおける算術演算の計算精度を設定します。

rounding は、

ROUND_CEILING (Infinity 寄りの値にする),

ROUND_DOWN (ゼロ寄りの値にする),

ROUND_FLOOR (-Infinity 寄りの値にする),

ROUND_HALF_DOWN (最近値のうちゼロ寄りの値にする),

ROUND_HALF_EVEN (最近値のうち偶数値を優先する),

ROUND_HALF_UP (最近値のうちゼロから遠い値にする),

ROUND_UP (ゼロから遠い値にする), または

ROUND_05UP (ゼロに向かって丸めた後の最小の桁が 0 か 5

ならばゼロから遠い値にし、そうでなければゼロにする)

のいずれかです。

traps および flags フィールドには、セットしたいシグナルを列挙します。一般的に、新たなコンテキストを作成するときにはトラップだけを設定し、フラグはクリアしておきます。

Emin および Emax フィールドには、指数範囲の外側限界値を整数で指定します。

capitals フィールドは 0 または 1 (デフォルト) にします。 1 に設定すると、指数記号を大文字 E で出力します。それ以外の場合には Decimal('6.02e+23') のように e を使います。

バージョン 2.6 で変更: ROUND_05UP 丸めモードが追加されました。

Context クラスでは、いくつかの汎用のメソッドの他、現在のコンテキストで算術演算を直接行うためのメソッドを数多く定義しています。加えて、 Decimal の各メソッドについて(adjusted() および as_tuple() メソッドを例外として)対応する Context のメソッドが存在します。たとえば、 Context インスタンス C と Decimal インスタンス x に対して、 C.exp(x) は x.exp(context=C) と等価です。それぞれの Context メソッドは、Decimal インスタンスが受け付けられるところならどこでも、Python の整数 (int または long のインスタンス) を受け付けます。

clear_flags()

フラグを全て 0 にリセットします。

copy()

コンテキストの複製を返します。

copy_decimal(num)

Decimal インスタンス num のコピーを返します。

create_decimal(num)

self をコンテキストとする新たな Decimal インスタンスを num から生成します。 Decimal コンストラクタと違い、数値を変換する際にコンテキストの精度、値丸め方法、フラグ、トラップを適用します。

定数値はしばしばアプリケーションの要求よりも高い精度を持っているため、このメソッドが役に立ちます。また、値丸めを即座に行うため、例えば以下のように、入力値に値丸めを行わないために合計値にゼロの加算を追加するだけで結果が変わってしまうといった、現在の精度よりも細かい値の影響が紛れ込む問題を防げるという恩恵もあります。以下の例は、丸められていない入力を使うということは和にゼロを加えると結果が変わり得るという見本です :

>>> getcontext().prec = 3
>>> Decimal('3.4445') + Decimal('1.0023')
Decimal('4.45')
>>> Decimal('3.4445') + Decimal(0) + Decimal('1.0023')
Decimal('4.44')

このメソッドは IBM 仕様の to-number 演算を実装したものです。引数が文字列の場合、前や後ろに余計な空白を付けることは許されません。

create_decimal_from_float(f)

浮動小数点数 f から新しい Decimal インスタンスを生成しますが、 self をコンテキストとして丸めます。 Decimal.from_float() クラスメソッドとは違い、変換にコンテキストの精度、丸めメソッド、フラグ、そしてトラップが適用されます。

>>> context = Context(prec=5, rounding=ROUND_DOWN)
>>> context.create_decimal_from_float(math.pi)
Decimal('3.1415')
>>> context = Context(prec=5, traps=[Inexact])
>>> context.create_decimal_from_float(math.pi)
Traceback (most recent call last):
    ...
Inexact: None

バージョン 2.7 で追加.

Etiny()

Emin - prec + 1 に等しい値を返します。演算結果の劣化が起こる桁の最小値です。アンダーフローが起きた場合、指数は Etiny に設定されます。

Etop()

Emax - prec + 1 に等しい値を返します。

Decimal を使った処理を行う場合、通常は Decimal インスタンスを生成して、算術演算を適用するというアプローチをとります。演算はアクティブなスレッドにおける現在のコンテキストの下で行われます。もう一つのアプローチは、コンテキストのメソッドを使った特定のコンテキスト下での計算です。コンテキストのメソッドは Decimal クラスのメソッドに似ているので、ここでは簡単な説明にとどめます。

abs(x)

x の絶対値を返します。

add(x, y)

x と y の和を返します。

canonical(x)

同じ Decimal オブジェクト x を返します。

compare(x, y)

二つの値を数値として比較します。

compare_signal(x, y)

二つの演算対象の値を数値として比較します。

compare_total(x, y)

二つの演算対象を抽象的な表現を使って比較します。

compare_total_mag(x, y)

二つの演算対象を抽象的な表現を使い符号を無視して比較します。

copy_abs(x)

x のコピーの符号を 0 にセットして返します。

copy_negate(x)

x のコピーの符号を反転して返します。

copy_sign(x, y)

y から x に符号をコピーします。

divide(x, y)

x を y で除算した値を返します。

divide_int(x, y)

x を y で除算した値を整数に切り捨てて返します。

divmod(x, y)

二つの数値間の除算を行い、結果の整数部を返します。

exp(x)

e ** x を返します。

fma(x, y, z)

x を y 倍したものに z を加えて返します。

is_canonical(x)

x が標準的(canonical)ならば True を返します。そうでなければ False です。

is_finite(x)

x が有限ならば True を返します。そうでなければ False です。

is_infinite(x)

x が無限ならば True を返します。そうでなければ False です。

is_nan(x)

x が NaN か sNaN であれば True を返します。そうでなければ False です。

is_normal(x)

x が通常の数ならば True を返します。そうでなければ False です。

is_qnan(x)

x が無言 NaN であれば True を返します。そうでなければ False です。

is_signed(x)

x が負の数であれば True を返します。そうでなければ False です。

is_snan(x)

x が発信 NaN であれば True を返します。そうでなければ False です。

is_subnormal(x)

x が非正規数であれば True を返します。そうでなければ False です。

is_zero(x)

x がゼロであれば True を返します。そうでなければ False です。

ln(x)

x の自然対数(底 e の対数)を返します。

log10(x)

x の底 10 の対数を返します。

logb(x)

演算対象の MSD の大きさの指数部を返します。

logical_and(x, y)

それぞれの桁に論理演算 and を当てはめます。

logical_invert(x)

x の全ての桁を反転させます。

logical_or(x, y)

それぞれの桁に論理演算 or を当てはめます。

logical_xor(x, y)

それぞれの桁に論理演算 xor を当てはめます。

max(x, y)

二つの値を数値として比較し、大きいほうを返します。

max_mag(x, y)

値を符号を無視して数値として比較します。

min(x, y)

二つの値を数値として比較し、小さいほうを返します。

min_mag(x, y)

値を符号を無視して数値として比較します。

minus(x)

Python における単項マイナス演算子に対応する演算です。

multiply(x, y)

x と y の積を返します。

next_minus(x)

x より小さい最大の表現可能な数を返します。

next_plus(x)

x より大きい最小の表現可能な数を返します。

next_toward(x, y)

x に y の方向に向かって最も近い数を返します。

normalize(x)

x をもっとも単純な形にします。

number_class(x)

x のクラスを指し示すものを返します。

plus(x)

Python における単項のプラス演算子に対応する演算です。コンテキストにおける精度や値丸めを適用するので、等値 (identity) 演算とは 違います 。

power(x, y[, modulo])

x の y 乗を計算します。 modulo が指定されていればモジュロを取ります。

二引数であれば x**y を計算します。 x が負であれば y は整でなければなりません。結果は y が整であって結果が有限になり ‘precision’ 桁で正確に表現できるのでなければ不正確になります。その結果は現スレッドのコンテキストの丸めモードを使って正しく丸められます。

三引数であれば (x**y) % modulo を計算します。この形式の場合、以下の制限が引数に掛かります:

全ての引数は整

y は非負でなければならない

x と y の少なくともどちらかはゼロでない

modulo は非零で大きくても ‘precision’ 桁

Context.power(x, y, modulo) で得られる値は (x**y) % modulo を精度無制限で計算して得られるものと同じ値ですが、より効率的に計算されます。結果の指数は x, y, modulo の指数に関係なくゼロです。この計算は常に正確です。

バージョン 2.6 で変更: x**y 形式で y が非整数で構わないことになった。三引数バージョンに対するより厳格な要求。

quantize(x, y)

x に値丸めを適用し、指数を y にした値を返します。

radix()

単に 10 を返します。何せ十進ですから :)

remainder(x, y)

整数除算の剰余を返します。

剰余がゼロでない場合、符号は割られる数の符号と同じになります。

remainder_near(x, y)

x - y * n を返します。ここで n は x / y の正確な値に一番近い整数です (この結果が 0 ならばその符号は x の符号と同じです)。

rotate(x, y)

x の y 回巡回したコピーを返します。

same_quantum(x, y)

self と other が同じ指数を持っているか、あるいは双方とも NaN である場合に真を返します。

scaleb(x, y)

一つめの演算対象の指数部に二つめの値を加えたものを返します。

shift(x, y)

x を y 回シフトしたコピーを返します。

sqrt(x)

x の平方根を精度いっぱいまで求めます。

subtract(x, y)

x と y の間の差を返します。

to_eng_string()

工学表記で文字列に変換します。

to_integral(x)

最近傍の整数に値を丸めます。

to_sci_string(x)

数値を科学表記で文字列に変換します。

9.4.4. シグナル

シグナルは、計算中に生じた様々なエラー条件を表現します。各々のシグナルは一つのコンテキストフラグと一つのトラップイネーブラに対応しています。

コンテキストフラグは、該当するエラー条件に遭遇するたびにセットされます。演算後にフラグを調べれば、演算に関する情報 (例えば計算が厳密だったかどうか) がわかります。フラグを調べたら、次の計算を始める前にフラグを全てクリアするようにしてください。

あるコンテキストのトラップイネーブラがあるシグナルに対してセットされている場合、該当するエラー条件が生じると Python の例外を送出します。例えば、 DivisionByZero が設定されていると、エラー条件が生じた際に DivisionByZero 例外を送出します。

class decimal.Clamped

値の表現上の制限に沿わせるために指数部が変更されたことを通知します。

通常、クランプ (clamp) は、指数部がコンテキストにおける指数桁の制限値 Emin および Emax を越えた場合に発生します。可能な場合には、係数部にゼロを加えた表現に合わせて指数部を減らします。

class decimal.DecimalException

他のシグナルの基底クラスで、 ArithmeticError のサブクラスです。

class decimal.DivisionByZero

有限値をゼロで除算したときのシグナルです。

除算やモジュロ除算、数を負の値で累乗した場合に起きることがあります。このシグナルをトラップしない場合、演算結果は Infinity または -Infinity になり、その符号は演算に使った入力に基づいて決まります。

class decimal.Inexact

値の丸めによって演算結果から厳密さが失われたことを通知します。

このシグナルは値丸め操作中にゼロでない桁を無視した際に生じます。演算結果は値丸め後の値です。シグナルのフラグやトラップは、演算結果の厳密さが失われたことを検出するために使えるだけです。

class decimal.InvalidOperation

無効な演算が実行されたことを通知します。

ユーザが有意な演算結果にならないような操作を要求したことを示します。このシグナルをトラップしない場合、 NaN を返します。このシグナルの発生原因として考えられるのは、以下のような状況です:

Infinity - Infinity
0 * Infinity
Infinity / Infinity
x % 0
Infinity % x
x._rescale( non-integer )
sqrt(-x) and x > 0
0 ** 0
x ** (non-integer)
x ** Infinity

class decimal.Overflow

数値オーバフローを示すシグナルです。

このシグナルは、値丸めを行った後の指数部が Emax より大きいことを示します。シグナルをトラップしない場合、演算結果は値丸めのモードにより、表現可能な最大の数値になるように内側へ引き込んで丸めを行った値か、 Infinity になるように外側に丸めた値のいずれかになります。いずれの場合も、 Inexact および Rounded が同時にシグナルされます。

class decimal.Rounded

情報が全く失われていない場合も含み、値丸めが起きたときのシグナルです。

このシグナルは、値丸めによって桁がなくなると常に発生します。なくなった桁がゼロ (例えば 5.00 を丸めて 5.0 になった場合) であってもです。このシグナルをトラップしなければ、演算結果をそのまま返します。このシグナルは有効桁数の減少を検出する際に使います。

class decimal.Subnormal

値丸めを行う前に指数部が Emin より小さかったことを示すシグナルです。

演算結果が微小である場合 (指数が小さすぎる場合) に発生します。このシグナルをトラップしなければ、演算結果をそのまま返します。

class decimal.Underflow

演算結果が値丸めによってゼロになった場合に生じる数値アンダフローです。

演算結果が微小なため、値丸めによってゼロになった場合に発生します。 Inexact および Subnormal シグナルも同時に発生します。

これらのシグナルの階層構造をまとめると、以下の表のようになります:

exceptions.ArithmeticError(exceptions.StandardError)
    DecimalException
        Clamped
        DivisionByZero(DecimalException, exceptions.ZeroDivisionError)
        Inexact
            Overflow(Inexact, Rounded)
            Underflow(Inexact, Rounded, Subnormal)
        InvalidOperation
        Rounded
        Subnormal

9.4.5. 浮動小数点数に関する注意

9.4.5.1. 精度を上げて丸め誤差を抑制する

10進浮動小数点数を使うと、10進数表現による誤差を抑制できます (0.1 を正確に表現できるようになります); しかし、ゼロでない桁が一定の精度を越えている場合には、演算によっては依然として値丸めによる誤差を引き起こします。 Knuth は、十分でない計算精度の下で値丸めを伴う浮動小数点演算を行った結果、加算の結合則や分配則における恒等性が崩れてしまう例を二つ示しています:

# Examples from Seminumerical Algorithms, Section 4.2.2.
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 8

>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal('9.5111111')
>>> u + (v + w)
Decimal('10')

>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal('0.01')
>>> u * (v+w)
Decimal('0.0060000')

decimal モジュールでは、最下桁を失わないように十分に計算精度を広げることで、上で問題にしたような恒等性をとりもどせます:

>>> getcontext().prec = 20
>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal('9.51111111')
>>> u + (v + w)
Decimal('9.51111111')
>>>
>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal('0.0060000')
>>> u * (v+w)
Decimal('0.0060000')

9.4.5.2. 特殊値

decimal モジュールの数体系では、 NaN, sNaN, -Infinity, Infinity, および二つのゼロ、 +0 と -0 といった特殊な値を提供しています。

無限大 (Infinity) は Decimal('Infinity') で直接構築できます。また、 DivisionByZero をトラップせずにゼロで除算を行った場合にも出てきます。同様に、 Overflow シグナルをトラップしなければ、表現可能な最大の数値の制限を越えた値を丸めたときに出てきます。

無限大には符号があり (アフィン: affine であり)、算術演算に使用でき、非常に巨大で不確定の(indeterminate)値として扱われます。例えば、無限大に何らかの定数を加算すると、演算結果は別の無限大になります。

演算によっては結果が不確定になるものがあり、 NaN を返します。ただし、 InvalidOperation シグナルをトラップするようになっていれば例外を送出します。

例えば、 0/0 は NaN を返します。 NaN は「非数値 (not a number)」を表します。このような NaN は暗黙のうちに生成され、一度生成されるとそれを他の計算にも流れてゆき、関係する個々の演算全てが個別の NaN を返すようになります。この挙動は、たまに入力値が欠けるような状況で一連の計算を行う際に便利です — 特定の計算に対しては無効な結果を示すフラグを立てつつ計算を進められるからです。

一方、 NaN の変種である sNaN は関係する全ての演算で演算後にシグナルを送出します。 sNaN は、無効な演算結果に対して特別な処理を行うために計算を停止する必要がある場合に便利です。

Python の比較演算は NaN が関わってくると少し驚くようなことがあります。等価性のテストの一方の対象が無言または発信 NaN である場合いつでも False を返し(たとえ Decimal('NaN')==Decimal('NaN') でも)、一方で不等価をテストするといつでも True を返します。二つの Decimal を <, <=, > または >= を使って比較する試みは一方が NaN である場合には InvalidOperation シグナルを誘発し、このシグナルをトラップしなければ結果は False に終わります。汎用10進演算仕様は直接の比較の振る舞いについて定めていないことに注意しておきましょう。ここでの NaN が関係する比較ルールは IEEE 854 標準から持ってきました (section 5.7 の Table 3 を見て下さい)。厳格に標準遵守を貫くなら、 compare() および compare-signal() メソッドを代わりに使いましょう。

アンダフローの起きた計算は、符号付きのゼロ (signed zero) を返すことがあります。符号は、より高い精度で計算を行った結果の符号と同じになります。符号付きゼロの大きさはやはりゼロなので、正のゼロと負のゼロは等しいとみなされ、符号は単なる参考にすぎません。

二つの符号付きゼロが区別されているのに等価であることに加えて、異なる精度におけるゼロの表現はまちまちなのに、値は等価とみなされるということがあります。これに慣れるには多少時間がかかります。正規化浮動小数点表現に目が慣れてしまうと、以下の計算でゼロに等しい値が返っているとは即座に分かりません:

>>> 1 / Decimal('Infinity')
Decimal('0E-1000000026')

9.4.6. スレッドを使った処理

関数 getcontext() は、スレッド毎に別々の Context オブジェクトにアクセスします。別のスレッドコンテキストを持つということは、複数のスレッドが互いに影響を及ぼさずに (getcontext.prec=10 のような) 変更を適用できるということです。

同様に、setcontext() 関数は自動的に引数のコンテキストを現在のスレッドのコンテキストに設定します。

getcontext() を呼び出す前に setcontext() が呼び出されていなければ、現在のスレッドで使うための新たなコンテキストを生成するために getcontext() が自動的に呼び出されます。

新たなコンテキストは、DefaultContext と呼ばれる雛形からコピーされます。アプリケーションを通じて全てのスレッドに同じ値を使うようにデフォルトを設定したければ、DefaultContext オブジェクトを直接変更します。 getcontext() を呼び出すスレッド間で競合条件が生じないようにするため、DefaultContext への変更はいかなるスレッドを開始するよりも 前に 行わねばなりません。以下に例を示します:

# スレッドを立ち上げる前にアプリケーションにわたるデフォルトを設定
DefaultContext.prec = 12
DefaultContext.rounding = ROUND_DOWN
DefaultContext.traps = ExtendedContext.traps.copy()
DefaultContext.traps[InvalidOperation] = 1
setcontext(DefaultContext)

# その後でスレッドを開始
t1.start()
t2.start()
t3.start()
 . . .

9.4.7. レシピ

Decimal クラスの利用を実演している例をいくつか示します。これらはユーティリティ関数としても利用できます:

def moneyfmt(value, places=2, curr='', sep=',', dp='.',
             pos='', neg='-', trailneg=''):
    """Decimal を通貨表現の文字列に変換します。

    places:  小数点以下の値を表すのに必要な桁数
    curr:    符号の前に置く通貨記号 (オプションで、空でもかまいません)
    sep:     桁のグループ化に使う記号、オプションです (コンマ、ピリオド、
             スペース、または空)
    dp:      小数点 (コンマまたはピリオド)
             小数部がゼロの場合には空にできます。
    pos:     正数の符号オプション: '+', 空白または空文字列
    neg:     負数の符号オプション: '-', '(', 空白または空文字列
    trailneg:後置マイナス符号オプション:  '-', ')', 空白または空文字列

    >>> d = Decimal('-1234567.8901')
    >>> moneyfmt(d, curr='$')
    '-$1,234,567.89'
    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
    '1.234.568-'
    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
    '($1,234,567.89)'
    >>> moneyfmt(Decimal(123456789), sep=' ')
    '123 456 789.00'
    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
    '<0.02>'

    """
    q = Decimal(10) ** -places      # 2 places --> '0.01'
    sign, digits, exp = value.quantize(q).as_tuple()
    result = []
    digits = map(str, digits)
    build, next = result.append, digits.pop
    if sign:
        build(trailneg)
    for i in range(places):
        build(next() if digits else '0')
    build(dp)
    if not digits:
        build('0')
    i = 0
    while digits:
        build(next())
        i += 1
        if i == 3 and digits:
            i = 0
            build(sep)
    build(curr)
    build(neg if sign else pos)
    return ''.join(reversed(result))

def pi():
    """現在の精度まで円周率を計算します。

    >>> print pi()
    3.141592653589793238462643383

    """
    getcontext().prec += 2  # 中間ステップのための余分の数字
    three = Decimal(3)      # 普通の float に対する "three=3.0" の代わり
    lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
    while s != lasts:
        lasts = s
        n, na = n+na, na+8
        d, da = d+da, da+32
        t = (t * n) / d
        s += t
    getcontext().prec -= 2
    return +s               # 単項のプラスで新しい精度に変換します

def exp(x):
    """e の x 乗を返します。結果の型は入力の型と同じです。

    >>> print exp(Decimal(1))
    2.718281828459045235360287471
    >>> print exp(Decimal(2))
    7.389056098930650227230427461
    >>> print exp(2.0)
    7.38905609893
    >>> print exp(2+0j)
    (7.38905609893+0j)

    """
    getcontext().prec += 2
    i, lasts, s, fact, num = 0, 0, 1, 1, 1
    while s != lasts:
        lasts = s
        i += 1
        fact *= i
        num *= x
        s += num / fact
    getcontext().prec -= 2
    return +s

def cos(x):
    """x ラジアンの余弦を返します。

    >>> print cos(Decimal('0.5'))
    0.8775825618903727161162815826
    >>> print cos(0.5)
    0.87758256189
    >>> print cos(0.5+0j)
    (0.87758256189+0j)

    """
    getcontext().prec += 2
    i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
    while s != lasts:
        lasts = s
        i += 2
        fact *= i * (i-1)
        num *= x * x
        sign *= -1
        s += num / fact * sign
    getcontext().prec -= 2
    return +s

def sin(x):
    """x ラジアンの正弦を返します。

    >>> print sin(Decimal('0.5'))
    0.4794255386042030002732879352
    >>> print sin(0.5)
    0.479425538604
    >>> print sin(0.5+0j)
    (0.479425538604+0j)

    """
    getcontext().prec += 2
    i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
    while s != lasts:
        lasts = s
        i += 2
        fact *= i * (i-1)
        num *= x * x
        sign *= -1
        s += num / fact * sign
    getcontext().prec -= 2
    return +s

9.4.8. Decimal FAQ

Q. decimal.Decimal('1234.5') などと打ち込むのは煩わしいのですが、対話式インタプリタを使う際にタイプ量を少なくする方法はありませんか?

A. コンストラクタを1文字に縮める人もいるようです。 :

>>> D = decimal.Decimal
>>> D('1.23') + D('3.45')
Decimal('4.68')

Q. 小数点以下2桁の固定小数点数のアプリケーションの中で、いくつかの入力が余計な桁を保持しているのでこれを丸めなければなりません。その他のものに余計な桁はなくそのまま使えます。どのメソッドを使うのがいいでしょうか?

A. quantize() メソッドで固定した桁に丸められます。 Inexact トラップを設定しておけば、確認にも有用です。 :

>>> TWOPLACES = Decimal(10) ** -2       # Decimal('0.01') と同じ

>>> # 小数点以下2桁に丸める
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')

>>> # 小数点以下2桁を越える桁を保持していないことの確認
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')

>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
   ...
Inexact: None

Q. 正当な2桁の入力が得られたとして、その正当性をアプリケーション実行中も変わらず保ち続けるにはどうすればいいでしょうか?

A. 加減算あるいは整数との乗算のような演算は自動的に固定小数点を守ります。その他の除算や整数以外の乗算などは小数点以下の桁を変えてしまいますので実行後は quantize() ステップが必要です。:

>>> a = Decimal('102.72')           # Initial fixed-point values
>>> b = Decimal('3.17')
>>> a + b                           # Addition preserves fixed-point
Decimal('105.89')
>>> a - b
Decimal('99.55')
>>> a * 42                          # So does integer multiplication
Decimal('4314.24')
>>> (a * b).quantize(TWOPLACES)     # Must quantize non-integer multiplication
Decimal('325.62')
>>> (b / a).quantize(TWOPLACES)     # And quantize division
Decimal('0.03')

固定小数点のアプリケーションを開発する際は、 quantize() の段階を扱う関数を定義しておくと便利です :

>>> def mul(x, y, fp=TWOPLACES):
...     return (x * y).quantize(fp)
>>> def div(x, y, fp=TWOPLACES):
...     return (x / y).quantize(fp)

>>> mul(a, b)                       # 自動的に固定点を保つ
Decimal('325.62')
>>> div(b, a)
Decimal('0.03')

Q. 一つの値に対して多くの表現方法があります。 200 と 200.000 と 2E2 と 02E+4 は全て同じ値で違った精度の数です。これらをただ一つの正規化された値に変換することはできますか?

A. normalize() メソッドは全ての等しい値をただ一つの表現に直します。 :

>>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split())
>>> [v.normalize() for v in values]
[Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')]

Q. ある種の10進数値はいつも指数表記で表示されます。指数表記以外の表示にする方法はありますか?

A. 値によっては、指数表記だけが有効桁数を表せる表記法なのです。たとえば、 5.0E+3 を 5000 と表してしまうと、値は変わりませんが元々の2桁という有効数字が反映されません。

もしアプリケーションが有効数字の追跡を等閑視するならば、指数部や末尾のゼロを取り除き、有効数字を忘れ、しかし値を変えずにおくことは容易です:

def remove_exponent(d):
    '''Remove exponent and trailing zeros.

    >>> remove_exponent(Decimal('5E+3'))
    Decimal('5000')

    '''
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

Q. 普通の float を Decimal に変換できますか?

A. はい。どんな 2 進浮動小数点数も Decimal として正確に表現できます。ただし、正確な変換は直感的に考えたよりも多い桁になることがあります。

>>> Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')

Q. 複雑な計算の中で、精度不足や丸めの異常で間違った結果になっていないことをどうやって保証すれば良いでしょうか?

A. decimal モジュールでは検算は容易です。一番良い方法は、大きめの精度や様々な丸めモードで再計算してみることです。大きく異なった結果が出てきたら、精度不足や丸めの問題や悪条件の入力、または数値計算的に不安定なアルゴリズムを示唆しています。

Q. コンテキストの精度は計算結果には適用されていますが入力には適用されていないようです。様々に異なる精度の入力値を混ぜて計算する時に注意すべきことはありますか?

A. はい。原則として入力値は正確であると見做しておりそれらの値を使った計算も同様です。結果だけが丸められます。入力の強みは “what you type is what you get” (打ち込んだ値が得られる値)という点にあります。入力が丸められないということを忘れていると結果が奇妙に見えるというのは弱点です。 :

>>> getcontext().prec = 3
>>> Decimal('3.104') + Decimal('2.104')
Decimal('5.21')
>>> Decimal('3.104') + Decimal('0.000') + Decimal('2.104')
Decimal('5.20')

解決策は精度を上げるかまたは単項のプラス演算子を使って入力の丸めを強制することです。 :

>>> getcontext().prec = 3
>>> +Decimal('1.23456789')      # 単項のプラスで丸めを引き起こします
Decimal('1.23')

もしくは、入力を Context.create_decimal() を使って生成時に丸めてしまうこともできます。 :

>>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678')
Decimal('1.2345')

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.5. fractions — 有理数

バージョン 2.6 で追加.

fractions モジュールは有理数計算のサポートを提供します。

Fraction インスタンスは一対の整数、他の有理数または文字列から組み立てられます。

class fractions.Fraction(numerator=0, denominator=1)

class fractions.Fraction(other_fraction)

class fractions.Fraction(float)

class fractions.Fraction(decimal)

class fractions.Fraction(string)

最初のバージョンは numerator と denominator が numbers.Rational のインスタンスであることを要求し、 numerator/denominator の値を持つ新しい Fraction インスタンスを返します。 denominator が 0 ならば、 ZeroDivisionError を送出します。二番目のバージョンは other_fraction が numbers.Rational のインスタンスであることを要求し、同じ値を持つ新しい Fraction インスタンスを返します。その次の二つのバージョンは、 float と decimal.Decimal インスタンスを受け付け、それとちょうど同じ値を持つ Fraction インスタンスを返します。なお、二進浮動小数点数にお決まりの問題 (浮動小数点演算、その問題と制限 参照) のため、 Fraction(1.1) の引数は 11/10 と正確に等しいとは言えないので、 Fraction(1.1) は予期した通りの Fraction(11, 10) を返 しません 。最後のバージョンは、文字列またはユニコードのインスタンスを渡されると思っています。一つめの形式の通常の形式は:

[sign] numerator ['/' denominator]

で、ここにオプションの sign は ‘+’ か ‘-‘ のどちらかであり、numerator および denominator (もしあるならば) は十進数の数字の並びです。さらに、 float コンストラクタで受け付けられる、有限の値を表す文字列は、必ず Fraction コンストラクタでも受け付けられます。どちらの形式でも入力される文字列は前後に空白があって構いません。例を見ましょう:

>>> from fractions import Fraction
>>> Fraction(16, -10)
Fraction(-8, 5)
>>> Fraction(123)
Fraction(123, 1)
>>> Fraction()
Fraction(0, 1)
>>> Fraction('3/7')
Fraction(3, 7)
[40794 refs]
>>> Fraction(' -3/7 ')
Fraction(-3, 7)
>>> Fraction('1.414213 \t\n')
Fraction(1414213, 1000000)
>>> Fraction('-.125')
Fraction(-1, 8)
>>> Fraction('7e-6')
Fraction(7, 1000000)
>>> Fraction(2.25)
Fraction(9, 4)
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
>>> from decimal import Decimal
>>> Fraction(Decimal('1.1'))
Fraction(11, 10)

Fraction クラスは抽象基底クラス numbers.Rational を継承し、その全てのメソッドと演算を実装します。 Fraction インスタンスはハッシュ可能で、したがって不変(immutable)であるものとして扱います。加えて、 Fraction には以下のメソッドがあります:

バージョン 2.7 で変更: Fraction コンストラクタは、今では float や decimal.Decimal インスタンスを受けつけます。

from_float(flt)

このクラスメソッドは float である flt の正確な値を表す Fraction を構築します。気を付けてください Fraction.from_float(0.3) と Fraction(3, 10) の値は同じではありません。

ノート

From Python 2.7 以降では、 float から直接 Fraction インスタンスを構成することも出来ます。

from_decimal(dec)

このクラスメソッドは decimal.Decimal である dec の正確な値を表す Fraction を構築します。

ノート

From Python 2.7 以降では、 decimal.Decimal から直接 Fraction インスタンスを構成することも出来ます。

limit_denominator(max_denominator=1000000)

高々 max_denominator を分母に持つ self に最も近い Fraction を見付けて返します。このメソッドは与えられた浮動小数点数の有理数近似を見つけるのに役立ちます:

>>> from fractions import Fraction
>>> Fraction('3.1415926535897932').limit_denominator(1000)
Fraction(355, 113)

あるいは float で表された有理数を元に戻すのにも使えます:

>>> from math import pi, cos
>>> Fraction(cos(pi/3))
Fraction(4503599627370497, 9007199254740992)
>>> Fraction(cos(pi/3)).limit_denominator()
Fraction(1, 2)
>>> Fraction(1.1).limit_denominator()
Fraction(11, 10)

fractions.gcd(a, b)

整数 a と b の最大公約数を返します。 a も b もゼロでないとすると、 gcd(a, b) の絶対値は a と b の両方を割り切る最も大きな整数です。 gcd(a, b) は b がゼロでなければ b と同じ符号になります。そうでなければ a の符号を取ります。 gcd(0, 0) は 0 を返します。

参考

numbers モジュール

数値の塔を作り上げる抽象基底クラス。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.6. random — 擬似乱数を生成する

このモジュールでは様々な分布をもつ擬似乱数生成器を実装しています。

参考

最新バージョンの random モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/random.py?view=markup]

整数用では、ある値域内の数の選択を一様にします。シーケンス用には、シーケンスからのランダムな要素の一様な選択、リストの要素の順列をランダムに置き換える関数、順列を入れ替えずにランダムに取り出す関数があります。

実数用としては、一様分布、正規分布 (ガウス分布)、対数正規分布、負の指数分布、ガンマおよびベータ分布を計算する関数があります。角度分布の生成用には、von Mises 分布が利用可能です。

ほとんど全てのモジュール関数は基礎となる関数 random() に依存します。この関数は半開区間 [0.0, 1.0) の値域を持つ一様な浮動小数点数を生成します。Python は中心となる乱数生成器として Mersenne Twister を使います。これは 53 ビットの浮動小数点を生成し、周期が 2**19937-1、本体は C で実装されていて、高速でスレッドセーフです。Mersenne Twister は、現存する中で、最も大規模にテストされた乱数生成器のひとつです。しかし、完全に決定論的であるため、この乱数生成器は全ての目的に合致しているわけではなく、暗号化の目的には全く向いていません。

このモジュールで提供されている関数は、実際には random.Random クラスの隠蔽されたインスタンスのメソッドにバインドされています。内部状態を共有しない生成器を取得するため、自分で Random のインスタンスを生成することができます。異なる Random のインスタンスを各スレッド毎に生成し、 jumpahead() メソッドを使うことで各々のスレッドにおいて生成された乱数列ができるだけ重複しないようにすれば、マルチスレッドプログラムを作成する上で特に便利になります。

自分で考案した基本乱数生成器を使いたいなら、クラス Random をサブクラス化することもできます: この場合、メソッド random() 、 seed() 、 getstate() 、 setstate() 、および jumpahead() をオーバライドしてください。オプションとして、新しいジェネレータは getrandbits() メソッドを提供できます — これにより randrange() メソッドが任意に大きな範囲から選択を行えるようになります。

バージョン 2.4 で追加: getrandbits() メソッド.

サブクラス化の例として、 random モジュールは WichmannHill クラスを提供します。このクラスは Python だけで書かれた代替生成器を実装しています。このクラスは、乱数生成器に Wichmann-Hill 法を使っていた古いバージョンの Python から得られた結果を再現するための、後方互換の手段になります。ただし、この Wichmann-Hill 生成器はもはや推奨することができないということに注意してください。現在の水準では生成される周期が短すぎ、また厳密な乱数性試験に合格しないことが知られています。こうした欠点を修正した最近の改良についてはページの最後に挙げた参考文献を参照してください。

バージョン 2.3 で変更: MersenneTwister が Wichmann-Hill の代わりにデフォルト生成器になりました。

random モジュールは SystemRandom クラスも提供していますが、このクラスは OS が提供している乱数発生源を利用して乱数を生成するシステム関数 os.urandom() を使うものです。

保守関数:

random.seed([x])

基本乱数生成器を初期化します。オプション引数 x はハッシュ可能(hashable)な任意のオブジェクトをとり得ます。 x が省略されるか None の場合、現在のシステム時間が使われます; 現在のシステム時間はモジュールが最初にインポートされた時に乱数生成器を初期化するためにも使われます。

乱数の発生源をオペレーティングシステムが提供している場合、システム時刻の代わりにその発生源が使われます（詳細については os.urandom() 関数を参照）。

バージョン 2.4 で変更: 以前は、オペレーティングシステムのリソースは使われませんでした。

random.getstate()

乱数生成器の現在の内部状態を記憶したオブジェクトを返します。このオブジェクトを setstate() に渡して内部状態を復帰することができます。

バージョン 2.1 で追加.

バージョン 2.6 で変更: Python 2.6 が作り出す状態オブジェクトは以前のバージョンには読み込めません。

random.setstate(state)

state は予め getstate() を呼び出して得ておかなくてはなりません。 setstate() は setstate() が呼び出された時の乱数生成器の内部状態を復帰します。

バージョン 2.1 で追加.

random.jumpahead(n)

内部状態を、現在の状態から、非常に離れているであろう状態に変更します。 n は非負の整数です。これはマルチスレッドのプログラムが複数の Random クラスのインスタンスと結合されている場合に非常に便利です: setstate() や seed() は全てのインスタンスを同じ内部状態にするのに使うことができ、その後 jumpahead() を使って各インスタンスの内部状態を引き離すことができます。

バージョン 2.1 で追加.

バージョン 2.3 で変更: n ステップ先の特定の状態になるのではなく、 jumpahead(n) は何ステップも離れているであろう別の状態にする。

random.getrandbits(k)

k ビット分の乱数ビットを納めた Python の long 整数を返します。このメソッドは MersenneTwister 生成器で提供されており、その他の乱数生成器でもオプションのAPIとして提供されているかもしれません。このメソッドが使えるとき、 randrange() メソッドは大きな範囲を扱えるようになります。

バージョン 2.4 で追加.

整数用の関数:

random.randrange([start], stop[, step])

range(start, stop, step) の要素からランダムに選ばれた要素を返します。この関数は choice(range(start, stop, step)) と等価ですが、実際には range オブジェクトを生成しません。

バージョン 1.5.2 で追加.

random.randint(a, b)

a <= N <= b であるようなランダムな整数 N を返します。

シーケンス用の関数:

random.choice(seq)

空でないシーケンス seq からランダムに要素を返します。 seq が空のときは、 IndexError が送出されます。

random.shuffle(x[, random])

シーケンス x を直接変更によって混ぜます。オプションの引数 random は、値域が [0.0, 1.0) のランダムな浮動小数点数を返すような引数を持たない関数です; 標準では、この関数は random() です。

かなり小さい len(x) であっても、 x の順列はほとんどの乱数生成器の周期よりも大きくなるので注意してください; このことは長いシーケンスに対してはほとんどの順列は生成されないことを意味します。

random.sample(population, k)

母集団のシーケンスから選ばれた長さ k の一意な要素からなるリストを返します。値の置換を行わないランダムサンプリングに用いられます。

バージョン 2.3 で追加.

母集団自体を変更せずに、母集団内の要素を含む新たなリストを返します。返されたリストは選択された順に並んでいるので、このリストの部分スライスもランダムなサンプルになります。これにより、くじの当選者を1等賞と2等賞（の部分スライス）に分けるといったことも可能です。母集団の要素はハッシュ可能 (hashable) でなくても、ユニークでなくても、かまいません。母集団が繰り返しを含む場合、返されたリストの各要素はサンプルから選択可能な要素になります。整数の並びからサンプルを選ぶには、引数に xrange() オブジェクトを使いましょう。特に、巨大な母集団からサンプルを取るとき、速度と空間効率が上がります。 sample(xrange(10000000), 60)

以下の関数は特殊な実数値分布を生成します。関数パラメタは対応する分布の公式において、数学的な慣行に従って使われている変数から取られた名前がつけられています; これらの公式のほとんどは多くの統計学のテキストに載っています。

random.random()

値域 [0.0, 1.0) の次のランダムな浮動小数点数を返します。

random.uniform(a, b)

a <= b であれば a <= N <= b であるようなランダムな浮動小数点数 N を返し、 b < a であれば b <= N <= a になります。

端点 b が値の範囲に含まれるかどうかは、等式 a + (b-a) * random() における浮動小数点の丸めに依存します。

random.triangular(low, high, mode)

low <= N < high でありこれら境界値の間に指定された最頻値 mode を持つようなランダムな浮動小数点数 N を返します。境界 low と high のデフォルトは 0 と 1 です。最頻値 mode のデフォルトは両境界値の中点になり、対称な分布を与えます。

バージョン 2.6 で追加.

random.betavariate(alpha, beta)

ベータ分布です。引数の満たすべき条件は alpha > 0 および beta > 0 です。 0 から 1 の値を返します。

random.expovariate(lambd)

指数分布です。 lambd は平均にしたい値で 1.0 を割ったものです。 (このパラメタは “lambda” と呼ぶべきなのですが、Python の予約語なので使えません。) 返される値の範囲は 0 から正の無限大です。

random.gammavariate(alpha, beta)

ガンマ分布です。 (ガンマ関数 ではありません ！) 引数の満たすべき条件は alpha > 0 および beta > 0 です。

random.gauss(mu, sigma)

ガウス分布です。 mu は平均であり、 sigma は標準偏差です。この関数は後で定義する関数 normalvariate() より少しだけ高速です。

random.lognormvariate(mu, sigma)

対数正規分布です。この分布を自然対数を用いた分布にした場合、平均 mu で標準偏差 sigma の正規分布になるでしょう。 mu は任意の値を取ることができ、 sigma はゼロより大きくなければなりません。

random.normalvariate(mu, sigma)

正規分布です、 mu は平均で、 sigma は標準偏差です。

random.vonmisesvariate(mu, kappa)

mu は平均の角度で、0 から 2*pi までのラジアンで表されます。 kappa は濃度パラメタで、ゼロまたはそれ以上でなければなりません。 kappa がゼロに等しい場合、この分布は範囲 0 から 2*pi の一様でランダムな角度の分布に退化します。

random.paretovariate(alpha)

パレート分布です。 alpha は形状パラメタです。

random.weibullvariate(alpha, beta)

ワイブル分布です。 alpha はスケールパラメタで、 beta は形状パラメタです。

代替の乱数生成器:

class random.WichmannHill([seed])

乱数生成器として Wichmann-Hill アルゴリズムを実装するクラスです。 Random クラスと同じメソッド全てと、下で説明する whseed() メソッドを持ちます。このクラスは、Python だけで実装されているので、スレッドセーフではなく、呼び出しと呼び出しの間にロックが必要です。また、周期が 6,953,607,871,644 と短く、独立した2つの乱数列が重複しないように注意が必要です。

random.whseed([x])

これは obsolete で、バージョン 2.1 以前の Python と、ビット・レベルの互換性のために提供されてます。詳細は seed() を参照してください。 whseed() は、引数に与えた整数が異なっても、内部状態が異なることを保障しません。取り得る内部状態の個数が 2**24 以下になる場合もあります。

class random.SystemRandom([seed])

オペレーティングシステムの提供する発生源によって乱数を生成する os.urandom() 関数を使うクラスです。すべてのシステムで使えるメソッドではありません。ソフトウェアの状態に依存してはいけませんし、一連の操作は再現不能です。それに応じて、 seed() と jumpahead() メソッドは何の影響も及ぼさず、無視されます。 getstate() と setstate() メソッドが呼び出されると、例外 NotImplementedError が送出されます。

バージョン 2.4 で追加.

基本使用例:

>>> random.random()        # Random float x, 0.0 <= x < 1.0
0.37444887175646646
>>> random.uniform(1, 10)  # Random float x, 1.0 <= x < 10.0
1.1800146073117523
>>> random.randint(1, 10)  # Integer from 1 to 10, endpoints included
7
>>> random.randrange(0, 101, 2)  # Even integer from 0 to 100
26
>>> random.choice('abcdefghij')  # Choose a random element
'c'

>>> items = [1, 2, 3, 4, 5, 6, 7]
>>> random.shuffle(items)
>>> items
[7, 3, 2, 5, 6, 4, 1]

>>> random.sample([1, 2, 3, 4, 5],  3)  # Choose 3 elements
[4, 1, 5]

参考

M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator”, ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998.

Wichmann, B. A. & Hill, I. D., “Algorithm AS 183: An efficient and portable pseudo-random number generator”, Applied Statistics 31 (1982) 188-190.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.7. itertools — 効率的なループ実行のためのイテレータ生成関数

バージョン 2.3 で追加.

このモジュールではイテレータ(iterator)を構築する部品を実装しています。プログラム言語 APL, Haskell, SML からアイデアを得ていますが、 Python に適した形に修正されています。

このモジュールは、高速でメモリ効率に優れ、単独でも組合せても使用することのできるツールを標準化したものです。同時に、このツール群は “イテレータの代数” を構成していて、 pure Python で簡潔かつ効率的なツールを作れるようにしています。

例えば、SML の作表ツール tabulate(f) は f(0), f(1), ... のシーケンスを作成します。同じことを Python では imap() と count() を組合せて imap(f, count()) という形で実現できます。

これらのツールと、対をなすビルトインの組合せは、 operator モジュールにある高速な関数を使うことでうまく実現できます。例えば、乗算演算子を二つのベクタにmapすることで効率的なドット積ができます: sum(imap(operator.mul, vector1, vector2))

無限イテレータ:

イテレータ | 引数 | 結果 | 例
count() | start, [step] | start, start+step, start+2*step, ... | count(10) --> 10 11 12 13 14 ...
cycle() | p | p0, p1, ... plast, p0, p1, ... | cycle('ABCD') --> A B C D A B C D ...
repeat() | elem [,n] | elem, elem, elem, ... 無限もしくは n 回 | repeat(10, 3) --> 10 10 10

一番短い入力シーケンスで止まるイテレータ:

イテレータ | 引数 | 結果 | 例
chain() | p, q, ... | p0, p1, ... plast, q0, q1, ... | chain('ABC', 'DEF') --> A B C D E F
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), ... | compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
dropwhile() | pred, seq | seq[n], seq[n+1], pred が偽の場所から始まる | dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
groupby() | iterable[, keyfunc] | keyfunc(v) の値でグループ化したサブイテレータ |
ifilter() | pred, seq | pred(elem) が真になるseqの要素 | ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
ifilterfalse() | pred, seq | pred(elem) が偽になるseqの要素 | ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
islice() | seq, [start,] stop [, step] | seq[start:stop:step] | islice('ABCDEFG', 2, None) --> C D E F G
imap() | func, p, q, ... | func(p0, q0), func(p1, q1), ... | imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
starmap() | func, seq | func(*seq[0]), func(*seq[1]), ... | starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
tee() | it, n | it1, it2 , ... itn 一つのイテレータを n 個に分ける |
takewhile() | pred, seq | seq[0], seq[1], pred が偽になるまで | takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
izip() | p, q, ... | (p[0], q[0]), (p[1], q[1]), ... | izip('ABCD', 'xy') --> Ax By
izip_longest() | p, q, ... | (p[0], q[0]), (p[1], q[1]), ... | izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-

組合せジェネレータ:

イテレータ | 引数 | 結果
product() | p, q, ... [repeat=1] | デカルト積、ネストしたforループと等価
permutations() | p[, r] | 長さrのタプル列, 繰り返しを許さない順列
combinations() | p, r | 長さrのタプル列, 繰り返しを許さない組合せ
combinations_with_replacement() | p, r | 長さrのタプル列, 繰り返しを許した組合せ
product('ABCD', repeat=2) |  | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2) |  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2) |  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) |  | AA AB AC AD BB BC BD CC CD DD

9.7.1. Itertool関数

以下の関数は全て、イテレータを作成して返します。無限長のストリームのイテレータを返す関数もあり、この場合にはストリームを中断するような関数かループ処理から使用しなければなりません。

itertools.chain(*iterables)

先頭の iterable の全要素を返し、次に2番目の iterable の全要素…と全 iterable の要素を返すイテレータを作成します。連続したシーケンスを、一つのシーケンスとして扱う場合に使用します。この関数は以下のスクリプトと同等です：

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

classmethod chain.from_iterable(iterable)

もう一つの chain() のためのコンストラクタです。遅延評価される唯一のイテラブル引数から連鎖した入力を受け取ります。この関数は以下のコードと等価です：

@classmethod
def from_iterable(iterables):
    # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

バージョン 2.6 で追加.

itertools.combinations(iterable, r)

入力 iterable の要素からなる長さ r の部分列を返します。

組合せ(combination)は辞書式順序で出力されます。したがって、入力 iterable がソートされていれば、組合せのタプルは整列された形で生成されます。

各要素は場所に基づいて一意に取り扱われ、値には依りません。入力された要素がバラバラならば、各組合せの中に重複した値は現れません。

この関数は以下のコードと等価です：

def combinations(iterable, r):
    # combinations('ABCD', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

combination() のコードは permutations() のシーケンスから (入力プールでの位置に応じた順序で) 要素がソートされていないものをフィルターしたようにも表現できます:

def combinations(iterable, r):
    pool = tuple(iterable)
    n = len(pool)
    for indices in permutations(range(n), r):
        if sorted(indices) == list(indices):
            yield tuple(pool[i] for i in indices)

返される要素の数は、 0 <= r <= n の場合は、 n! / r! / (n-r)! で、 r > n の場合は 0 です。

バージョン 2.6 で追加.

itertools.combinations_with_replacement(iterable, r)

入力 iterable から、それぞれの要素が複数回現れることを許して、長さ r の要素の部分列を返します。

組合せは、辞書的に並べられた順序で出力されます。ですから、入力 iterable がソートされていれば、組合せのタプルはソートされた順に生成されます。

要素は、値ではなく位置に基づいて一意に扱われます。ですから、入力の要素が一意であれば、生成された組合せも一意になります。

以下と等価です:

def combinations_with_replacement(iterable, r):
    # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
    pool = tuple(iterable)
    n = len(pool)
    if not n and r:
        return
    indices = [0] * r
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != n - 1:
                break
        else:
            return
        indices[i:] = [indices[i] + 1] * (r - i)
        yield tuple(pool[i] for i in indices)

combinations_with_replacement() のコードは、 product() の部分列から、要素が (入力プールの位置に従って) ソートされた順になっていない項目をフィルタリングしたものとしても表せます:

def combinations_with_replacement(iterable, r):
    pool = tuple(iterable)
    n = len(pool)
    for indices in product(range(n), repeat=r):
        if sorted(indices) == list(indices):
            yield tuple(pool[i] for i in indices)

返される要素の数は、 n > 0 のとき (n+r-1)! / r! / (n-1)! です。

バージョン 2.7 で追加.

itertools.compress(data, selectors)

data の要素から、 selectors の対応する要素が True と評価されるものだけを返す、フィルタリングしたイテレータを作ります。 data と selectors のどちらかが尽きたときに止まります。以下と等価です:

def compress(data, selectors):
    # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
    return (d for d, s in izip(data, selectors) if s)

バージョン 2.7 で追加.

itertools.count(start=0, step=1)

n で始まる、等間隔の値を返すイテレータを作成します。 imap() で連続したデータの生成によく使われます。また、 izip() にシーケンス番号を追加するのにも使われます。この関数は以下のスクリプトと同等です:

def count(start=0, step=1):
    # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
    n = start
    while True:
        yield n
        n += step

浮動小数点数で数えるときは、 (start + step * i for i in count()) のように、掛け算を使ったコードに置き換えたほうが正確にできることがあります。

バージョン 2.7 で変更: step 引数を追加し、非整数の引数を取れるようになりました。

itertools.cycle(iterable)

iterable から要素を取得し、同時にそのコピーを保存するイテレータを作成します。 iterable の全要素を返すと、セーブされたコピーから要素を返し、これを無限に繰り返します。この関数は以下のスクリプトと同等です：

def cycle(iterable):
    # cycle('ABCD') --> A B C D A B C D A B C D ...
    saved = []
    for element in iterable:
        yield element
        saved.append(element)
    while saved:
        for element in saved:
              yield element

cycle() は大きなメモリ領域を使用します。使用するメモリ量は iterable の大きさに依存します。

itertools.dropwhile(predicate, iterable)

predicate が真である限りは要素を無視し、その後は全ての要素を返すイテレータを作成します。このイテレータは、predicate が最初に偽になるまで 全く 要素を返さないため、要素を返し始めるまでに長い時間がかかる場合があります。この関数は以下のスクリプトと同等です：

def dropwhile(predicate, iterable):
    # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
    iterable = iter(iterable)
    for x in iterable:
        if not predicate(x):
            yield x
            break
    for x in iterable:
        yield x

itertools.groupby(iterable[, key])

同じキーをもつような要素からなる iterable 中のグループに対して、キーとグループを返すようなイテレータを作成します。 key は各要素に対するキー値を計算する関数です。キーを指定しない場合や None にした場合、 key 関数のデフォルトは恒等関数になり要素をそのまま返します。通常、 iterable は同じキー関数で並べ替え済みである必要があります。

groupby() の操作は Unix の uniq フィルターと似ています。 key 関数の値が変わるたびに休止または新しいグループを生成します (このために通常同じ key 関数でソートしておく必要があるのです)。この動作は SQL の入力順に関係なく共通の要素を集約する GROUP BY とは違ます。

返されるグループはそれ自体がイテレータで、 groupby() と iterable を共有しています。もととなる iterable を共有しているため、 groupby() オブジェクトの要素取り出しを先に進めると、それ以前の要素であるグループは見えなくなってしまいます。従って、データが後で必要な場合にはリストの形で保存しておく必要があります：

groups = []
uniquekeys = []
data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
    groups.append(list(g))      # Store group iterator as a list
    uniquekeys.append(k)

groupby() は以下のコードと等価です：

class groupby(object):
    # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
    # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
    def __init__(self, iterable, key=None):
        if key is None:
            key = lambda x: x
        self.keyfunc = key
        self.it = iter(iterable)
        self.tgtkey = self.currkey = self.currvalue = object()
    def __iter__(self):
        return self
    def next(self):
        while self.currkey == self.tgtkey:
            self.currvalue = next(self.it)    # Exit on StopIteration
            self.currkey = self.keyfunc(self.currvalue)
        self.tgtkey = self.currkey
        return (self.currkey, self._grouper(self.tgtkey))
    def _grouper(self, tgtkey):
        while self.currkey == tgtkey:
            yield self.currvalue
            self.currvalue = next(self.it)    # Exit on StopIteration
            self.currkey = self.keyfunc(self.currvalue)

バージョン 2.4 で追加.

itertools.ifilter(predicate, iterable)

predicate が True となる要素だけを返すイテレータを作成します。 predicate が None の場合、値が真であるアイテムだけを返します。この関数は以下のスクリプトと同等です：

def ifilter(predicate, iterable):
    # ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9
    if predicate is None:
        predicate = bool
    for x in iterable:
        if predicate(x):
            yield x

itertools.ifilterfalse(predicate, iterable)

predicateが False となる要素だけを返すイテレータを作成します。 predicate が None の場合、値が偽であるアイテムだけを返します。この関数は以下のスクリプトと同等です：

def ifilterfalse(predicate, iterable):
    # ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
    if predicate is None:
        predicate = bool
    for x in iterable:
        if not predicate(x):
            yield x

itertools.imap(function, *iterables)

iterables の要素を引数として funtion を呼び出すイテレータを作成します。 function が None の場合、引数のタプルを返します。 map() と似ていますが、最短の iterable の末尾まで到達した後は None を補って処理を続行するのではなく、終了します。これは、 map() に無限長のイテレータを指定するのは多くの場合誤りですが (全出力が評価されてしまうため)、 imap() の場合には一般的で役に立つ方法であるためです。この関数は以下のスクリプトと同等です：

def imap(function, *iterables):
    # imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000
    iterables = map(iter, iterables)
    while True:
        args = [next(it) for it in iterables]
        if function is None:
            yield tuple(args)
        else:
            yield function(*args)

itertools.islice(iterable[, start], stop[, step])

iterable から要素を選択して返すイテレータを作成します。 start が0以外であれば、iterable の先頭要素は start に達するまでスキップします。以降、 step が1以下なら連続した要素を返し、 1以上なら指定された値分の要素をスキップします。 stop が None であれば、無限に、もしくは iterable の全要素を返すまで値を返します。 None 以外ならイテレータは指定された要素位置で停止します。通常のスライスと異なり、 start 、 stop 、 step に負の値を指定する事はできません。シーケンス化されたデータから関連するデータを取得する場合（複数行からなるレポートで、三行ごとに名前が指定されている場合など）に使用します。この関数は以下のスクリプトと同等です：

def islice(iterable, *args):
    # islice('ABCDEFG', 2) --> A B
    # islice('ABCDEFG', 2, 4) --> C D
    # islice('ABCDEFG', 2, None) --> C D E F G
    # islice('ABCDEFG', 0, None, 2) --> A C E G
    s = slice(*args)
    it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
    nexti = next(it)
    for i, element in enumerate(iterable):
        if i == nexti:
            yield element
            nexti = next(it)

start が None ならば、繰返しは0から始まります。 step が None ならば、ステップは1となります。

バージョン 2.5 で変更: start と step はデフォルト値として None を受け付けます。

itertools.izip(*iterables)

各 iterable の要素をまとめるイテレータを作成します。 zip() に似ていますが、リストではなくイテレータを返します。複数のイテレート可能オブジェクトに対して、同じ繰り返し処理を同時に行う場合に使用します。この関数は以下のスクリプトと同等です：

def izip(*iterables):
    # izip('ABCD', 'xy') --> Ax By
    iterables = map(iter, iterables)
    while iterables:
        yield tuple(map(next, iterables))

バージョン 2.4 で変更: イテレート可能オブジェクトを指定しない場合、 TypeError 例外を送出する代わりに長さゼロのイテレータを返します。

イテレート可能オブジェクトの左から右への評価順序は保証されます。このことによって、データ列を長さnのグループにまとめる常套句 izip(*[iter(s)]*n) が実現可能になります。

izip() を長さが不揃いな入力に使うのは、残され使われなかった長い方のイテレート可能オブジェクトの値を気にしない時だけにするべきです。こういった値が重要ならば izip_longest() を代わりに使ってください。

itertools.izip_longest(*iterables[, fillvalue])

各 iterable の要素をまとめるイテレータを作成します。イテレート可能オブジェクトの長さが不揃いならば、足りない値は fillvalue で埋められます。最も長いイテレート可能オブジェクトが尽きるまで繰り返されます。この関数は以下のコードと等価です：

def izip_longest(*args, **kwds):
    # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
    fillvalue = kwds.get('fillvalue')
    def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
        yield counter()         # yields the fillvalue, or raises IndexError
    fillers = repeat(fillvalue)
    iters = [chain(it, sentinel(), fillers) for it in args]
    try:
        for tup in izip(*iters):
            yield tup
    except IndexError:
        pass

もしイテラブルの内一つでも潜在的に無限列であれば、 izip_longest() 関数の呼出しを呼び出し回数を制限する何か (たとえば islice() や takewhile()) で包むべきです。 fillvalue が指定されない場合のデフォルトは None です。

バージョン 2.6 で追加.

itertools.permutations(iterable[, r])

iterable の要素からなる長さ r の置換(permutation)を次々と返します。

r が指定されないかまたは None であるならば、 r のデフォルトは iterable の長さとなり全ての可能な最長の置換が生成されます。

置換は辞書式にソートされた順序で吐き出されます。したがって入力の iterable がソートされていたならば、置換のタプルはソートされた状態で出力されます。

要素は位置に基づいて一意的に扱われ、値に基づいてではありません。したがって入力された要素が全て異なっているならば、それぞれの置換に重複した要素が現れないことになります。

以下と等価です：

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = range(n)
    cycles = range(n, n-r, -1)
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

permutations() のコードは product() の列から重複のあるもの (それらは入力プールの同じ位置から取られたものです) を除外するようにフィルタを掛けたものとしても表現できます：

def permutations(iterable, r=None):
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    for indices in product(range(n), repeat=r):
        if len(set(indices)) == r:
            yield tuple(pool[i] for i in indices)

返される要素の数は、 0 <= r <= n の場合 n! / (n-r)! で、 r > n の場合は 0 です。

バージョン 2.6 で追加.

itertools.product(*iterables[, repeat])

入力イテラブルの直積(Cartesian product)です。

ジェネレータ式の入れ子 for ループと等価になります。たとえば product(A, B) は ((x,y) for x in A for y in B) と同じものを返します。

入れ子ループは走行距離計と同じように右端の要素がイテレーションごとに更新されていきます。このパターンは辞書式順序を作り出し、入力のイテレート可能オブジェクトたちがソートされていれば、直積タプルもソートされた順に吐き出されます。

イテラブル自身との直積を計算するためには、オプションの repeat キーワード引数に繰り返し回数を指定します。たとえば product(A, repeat=4) は product(A, A, A, A) と同じ意味です。

この関数は以下のコードと等価ですが、実際の実装ではメモリ中に中間結果を作りません：

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

バージョン 2.6 で追加.

itertools.repeat(object[, times])

繰り返し object を返すイテレータを作成します。 times を指定しない場合、無限に値を返し続けます。 imap() で常に同じオブジェクトを関数の引数として指定する場合に使用します。また、 izip() で作成するタプルの定数部分を指定する場合にも使用することもできます。この関数は以下のスクリプトと同等です：

def repeat(object, times=None):
    # repeat(10, 3) --> 10 10 10
    if times is None:
        while True:
            yield object
    else:
        for i in xrange(times):
            yield object

itertools.starmap(function, iterable)

iterables の要素を引数として funtion を呼び出すイテレータを作成します。 function の引数が単一の iterable にタプルとして格納されている場合(“zip済み”)、 imap() の代わりに使用します。 imap() と starmap() ではfunctionの呼び出し方法が異なり、 imap() は function(a,b) 、 starmap() では function(*c) のように呼び出します。この関数は以下のスクリプトと同等です：

def starmap(function, iterable):
    # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
    for args in iterable:
        yield function(*args)

バージョン 2.6 で変更: 以前のバージョンでは、 starmap() は関数の引数がタプルであることが必要でした。このバージョンからどんなイテレート可能オブジェクトでも良くなりました。

itertools.takewhile(predicate, iterable)

predicate が真である限り iterable から要素を返すイテレータを作成します。この関数は以下のスクリプトと同等です：

def takewhile(predicate, iterable):
    # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
    for x in iterable:
        x = iterable.next()
        if predicate(x):
            yield x
        else:
            break

itertools.tee(iterable[, n=2])

一つの iterable から n 個の独立したイテレータを生成して返します。以下のコードと等価になります：

def tee(iterable, n=2):
    it = iter(iterable)
    deques = [collections.deque() for i in range(n)]
    def gen(mydeque):
        while True:
            if not mydeque:             # when the local deque is empty
                newval = next(it)       # fetch a new value and
                for d in deques:        # load it to all the deques
                    d.append(newval)
            yield mydeque.popleft()
    return tuple(gen(d) for d in deques)

一度 tee() でイテレータを分割すると、もとの iterable を他で使ってはいけません。さもなければ、 tee() オブジェクトの知らない間に iterable が先の要素に進んでしまうことになります。

tee() はかなり大きなメモリ領域を使用するかもしれません (使用するメモリ量はiterableの大きさに依存します)。一般には、一つのイテレータが他のイテレータよりも先にほとんどまたは全ての要素を消費するような場合には、 tee() よりも list() を使った方が高速です。

バージョン 2.4 で追加.

9.7.2. レシピ

この節では、既存の itertools を素材としてツールセットを拡張するためのレシピを示します。

iterable 全体を一度にメモリ上に置くよりも、要素を一つづつ処理する方がメモリ効率上の有利さを保てます。関数形式のままツールをリンクしてゆくと、コードのサイズを減らし、一時変数を減らす助けになります。インタプリタのオーバヘッドをもたらす for ループやジェネレータ(generator) を使わずに、 “ベクトル化された” ビルディングブロックを使うと、高速な処理を実現できます。

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(islice(iterable, n))

def tabulate(function, start=0):
    "Return function(0), function(1), ..."
    return imap(function, count(start))

def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)

def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return sum(imap(pred, iterable))

def padnone(iterable):
    """Returns the sequence elements and then returns None indefinitely.

    Useful for emulating the behavior of the built-in map() function.
    """
    return chain(iterable, repeat(None))

def ncycles(iterable, n):
    "Returns the sequence elements n times"
    return chain.from_iterable(repeat(tuple(iterable), n))

def dotproduct(vec1, vec2):
    return sum(imap(operator.mul, vec1, vec2))

def flatten(listOfLists):
    "Flatten one level of nesting"
    return chain.from_iterable(listOfLists)

def repeatfunc(func, times=None, *args):
    """Repeat calls to func with specified arguments.

    Example:  repeatfunc(random.random)
    """
    if times is None:
        return starmap(func, repeat(args))
    return starmap(func, repeat(args, times))

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    # Recipe credited to George Sakkis
    pending = len(iterables)
    nexts = cycle(iter(it).next for it in iterables)
    while pending:
        try:
            for next in nexts:
                yield next()
        except StopIteration:
            pending -= 1
            nexts = cycle(islice(nexts, pending))

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

def unique_justseen(iterable, key=None):
    "List unique elements, preserving order. Remember only the element just seen."
    # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
    # unique_justseen('ABBCcAD', str.lower) --> A B C A D
    return imap(next, imap(itemgetter(1), groupby(iterable, key)))

def iter_except(func, exception, first=None):
    """ Call a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like __builtin__.iter(func, sentinel) but uses an exception instead
    of a sentinel to end the loop.

    Examples:
        bsddbiter = iter_except(db.next, bsddb.error, db.first)
        heapiter = iter_except(functools.partial(heappop, h), IndexError)
        dictiter = iter_except(d.popitem, KeyError)
        dequeiter = iter_except(d.popleft, IndexError)
        queueiter = iter_except(q.get_nowait, Queue.Empty)
        setiter = iter_except(s.pop, KeyError)

    """
    try:
        if first is not None:
            yield first()
        while 1:
            yield func()
    except exception:
        pass

def random_product(*args, **kwds):
    "Random selection from itertools.product(*args, **kwds)"
    pools = map(tuple, args) * kwds.get('repeat', 1)
    return tuple(random.choice(pool) for pool in pools)

def random_permutation(iterable, r=None):
    "Random selection from itertools.permutations(iterable, r)"
    pool = tuple(iterable)
    r = len(pool) if r is None else r
    return tuple(random.sample(pool, r))

def random_combination(iterable, r):
    "Random selection from itertools.combinations(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.sample(xrange(n), r))
    return tuple(pool[i] for i in indices)

def random_combination_with_replacement(iterable, r):
    "Random selection from itertools.combinations_with_replacement(iterable, r)"
    pool = tuple(iterable)
    n = len(pool)
    indices = sorted(random.randrange(n) for i in xrange(r))
    return tuple(pool[i] for i in indices)

上記のレシピはデフォルト値を指定してグローバルな名前検索をローカル変数の検索に変えることで、より効率を上げることができます。例えば、 dotproduct のレシピを書き換えるとすればこんな具合です:

def dotproduct(vec1, vec2, sum=sum, imap=imap, mul=operator.mul):
    return sum(imap(mul, vec1, vec2))

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.8. functools — 高階関数と呼び出し可能オブジェクトの操作

バージョン 2.5 で追加.

functools モジュールは高階関数、つまり関数に対する関数、あるいは他の関数を返す関数、のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。

参考

最新バージョンの functools の Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/functools.py?view=markup]

モジュール functools では以下の関数を定義します。

functools.cmp_to_key(func)

古いスタイルの比較関数を key 関数に変換します。 key 関数を受け取る関数 (sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby() など) と共に使用します。この関数は、主に比較関数をサポートしていない Python 3.x への移行のためのツールとして用意されています。

比較関数は2つの引数を受け取り、それらを比較し、”より小さい” (less-than)の場合は負の値を、同値の場合には 0 を、 “より大きい” (greater-than) 場合には正の値を返します。 key 関数は1つの引数を受け取り、ある順序で並べた時の位置に相当する値を返します。

例:

sorted(iterable, key=cmp_to_key(locale.strcoll))  # ロケールに準拠したソート順

バージョン 2.7 で追加.

functools.total_ordering(cls)

1つ以上のリッチ順序比較メソッドを定義したクラスを受け取り、残りを実装するクラスデコレータ。このデコレータは全てのリッチ順序比較演算をサポートするための労力を軽減します。

引数のクラスは、 __lt__(), __le__(), __gt__(), __ge__() の中からどれか1つと、 __eq__() メソッドを定義する必要があります。

例:

@total_ordering
class Student:
    def __eq__(self, other):
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))

バージョン 2.7 で追加.

functools.reduce(function, iterable[, initializer])

これは reduce() 関数と同じものです。このモジュールからも使えるようにしたのは Python 3 と前方互換なコードを書けるようにするためです。

バージョン 2.6 で追加.

functools.partial(func[, *args][, **keywords])

新しい partial オブジェクトを返します。このオブジェクトは呼び出されると位置引数 args とキーワード引数 keywords 付きで呼び出された func のように振る舞います。呼び出しに際してさらなる引数が渡された場合、それらは args に付け加えられます。追加のキーワード引数が渡された場合には、それらで keywords を拡張または上書きします。大雑把にいうと、次のコードと等価です。

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

関数 partial() は、関数の引数と/かキーワードの一部を「凍結」した部分適用として使われ、簡素化された引数形式をもった新たなオブジェクトを作り出します。例えば、 partial() を使って base 引数のデフォルトが 2 である int() 関数のように振る舞う呼び出し可能オブジェクトを作ることができます。 :

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18

functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

wrapper 関数を wrapped 関数に見えるようにアップデートします。オプション引数はタプルで、元の関数のどの属性が wrapper 関数の一致する属性に直接書き込まれる(assigned)か、また wrapper 関数のどの属性が元の関数の対応する属性でアップデートされる(updated)か、を指定します。これらの引数のデフォルト値はモジュール定数 WRAPPER_ASSIGNMENTS (wrapper 関数に __name__ 、 __module__ そしてドキュメンテーション文字列 __doc__ を書き込みます) と WRAPPER_UPDATES (wrapper 関数のインスタンス辞書をアップデートします) です。

この関数は主に関数を包んで wrapper を返すデコレータ関数(decorator) の中で使われるよう意図されています。もし wrapper 関数がアップデートされないとすると、返される関数のメタデータは元の関数の定義ではなく wrapper 関数の定義を反映してしまい、これは典型的に役立たずです。

functools.wraps(wrapped[, assigned][, updated])

これはラッパ関数を定義するときに partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) を関数デコレータとして呼び出す便宜関数です。 :

>>> from functools import wraps
>>> def my_decorator(f):
...     @wraps(f)
...     def wrapper(*args, **kwds):
...         print 'Calling decorated function'
...         return f(*args, **kwds)
...     return wrapper
...
>>> @my_decorator
... def example():
...     """Docstring"""
...     print 'Called example function'
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'

このデコレータ・ファクトリーを使わなければ、上の例中の関数の名前は 'wrapper' となり、元々の example() のドキュメンテーション文字列は失われたところです。

9.8.1. partial オブジェクト

partial オブジェクトは、 partial() 関数によって作られる呼び出し可能オブジェクトです。オブジェクトには読み取り専用の属性が三つあります。

partial.func

呼び出し可能オブジェクトまたは関数です。 partial の呼び出しは新しい引数とキーワードと共に func に転送されます。

partial.args

最左の位置引数で、 partial オブジェクトの呼び出し時にその呼び出しの際の位置引数の前に追加されます。

partial.keywords

partial オブジェクトの呼び出し時に渡されるキーワード引数です。

partial オブジェクトは function オブジェクトのように呼び出し可能で、弱参照可能で、属性を持つことができます。重要な相違点もあります。例えば、 __name__ と __doc__ 両属性は自動では作られません。また、クラス中で定義された partial オブジェクトはスタティックメソッドのように振る舞い、インスタンスの属性問い合わせの中で束縛メソッドに変換されません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

9. 数値と数学モジュール »

9.9. operator — 関数形式の標準演算子

operator モジュールは、Python 固有の各演算子に対応している C 言語で実装された関数セットを提供します。例えば、 operator.add(x, y) は式 x+y と等価です。関数名は特殊なクラスメソッドとして扱われます; 便宜上、先頭と末尾の __ を取り除いたものも提供されています。

これらの関数はそれぞれ、オブジェクトの比較、論理演算、数学演算、シーケンス操作、および抽象型テストに分類されます。

オブジェクト比較関数は全てのオブジェクトで有効で、関数の名前はサポートする大小比較演算子からとられています:

operator.lt(a, b)

operator.le(a, b)

operator.eq(a, b)

operator.ne(a, b)

operator.ge(a, b)

operator.gt(a, b)

operator.__lt__(a, b)

operator.__le__(a, b)

operator.__eq__(a, b)

operator.__ne__(a, b)

operator.__ge__(a, b)

operator.__gt__(a, b)

これらは a および b の大小比較を行います。特に、 lt(a, b) は a < b 、 le(a, b) は a <= b 、 eq(a, b) は a == b 、 ne(a, b) は a != b 、 gt(a, b) は a > b 、そして ge(a, b) は a >= b と等価です。組み込み関数 cmp() と違って、これらの関数はどのような値を返してもよく、ブール代数値として解釈できてもできなくてもかまいません。大小比較の詳細については 比較 (comparison) を参照してください。

バージョン 2.2 で追加.

論理演算もまた全てのオブジェクトに対して適用することができ、真値テスト、同一性テストおよびブール演算をサポートします:

operator.not_(obj)

operator.__not__(obj)

not obj の結果を返します。(オブジェクトのインスタンスには __not__() メソッドは適用されないので注意してください; この操作を定義しているのはインタプリタコアだけです。結果は __nonzero__() および __len__() メソッドによって影響されます。)

operator.truth(obj)

obj が真の場合 True を返し、そうでない場合 False を返します。この関数は bool のコンストラクタ呼び出しと同等です。

operator.is_(a, b)

a is b を返します。オブジェクトの同一性をテストします。

operator.is_not(a, b)

a is not b を返します。オブジェクトの同一性をテストします。

演算子で最も多いのは数学演算およびビット単位の演算です:

operator.abs(obj)

operator.__abs__(obj)

obj の絶対値を返します。

operator.add(a, b)

operator.__add__(a, b)

数値 a および b について a + b を返します。

operator.and_(a, b)

operator.__and__(a, b)

a と b の論理積を返します。

operator.div(a, b)

operator.__div__(a, b)

__future__.division が有効でない場合には a / b を返します。 “古い(classic)” 除算としても知られています。

operator.floordiv(a, b)

operator.__floordiv__(a, b)

a // b を返します。

バージョン 2.2 で追加.

operator.index(a)

operator.__index__(a)

整数に変換された a を返します。 a.__index__() と同等です。

バージョン 2.5 で追加.

operator.inv(obj)

operator.invert(obj)

operator.__inv__(obj)

operator.__invert__(obj)

obj のビット単位反転を返します。 ~obj と同じです。

バージョン 2.0 で追加: 名前 invert() および __invert__() が追加されました。

operator.lshift(a, b)

operator.__lshift__(a, b)

a の b ビット左シフトを返します。

operator.mod(a, b)

operator.__mod__(a, b)

a % b を返します。

operator.mul(a, b)

operator.__mul__(a, b)

数値 a および b について a * b を返します。

operator.neg(obj)

operator.__neg__(obj)

obj の符号反転 (-obj) を返します。

operator.or_(a, b)

operator.__or__(a, b)

a と b の論理和を返します。

operator.pos(obj)

operator.__pos__(obj)

obj の符号非反転 (+obj) を返します。

operator.pow(a, b)

operator.__pow__(a, b)

数値 a および b について a ** b を返します。

バージョン 2.3 で追加.

operator.rshift(a, b)

operator.__rshift__(a, b)

a の b ビット右シフトを返します。

operator.sub(a, b)

operator.__sub__(a, b)

a - b を返します。

operator.truediv(a, b)

operator.__truediv__(a, b)

__future__.division が有効な場合 a / b を返します。 “真の”除算としても知られています。

バージョン 2.2 で追加.

operator.xor(a, b)

operator.__xor__(a, b)

a および b の排他的論理和を返します。

シーケンスを扱う演算子（いくつかの演算子は map 型も扱います）には以下のようなものがあります:

operator.concat(a, b)

operator.__concat__(a, b)

シーケンス a および b について a + b を返します。

operator.contains(a, b)

operator.__contains__(a, b)

b in a を調べた結果を返します。演算対象が左右反転しているので注意してください。

バージョン 2.0 で追加: 関数名 __contains__() が追加されました。

operator.countOf(a, b)

a の中に b が出現する回数を返します。

operator.delitem(a, b)

operator.__delitem__(a, b)

a でインデクスが b の要素を削除します。

operator.delslice(a, b, c)

operator.__delslice__(a, b, c)

a でインデクスが b から c-1 のスライス要素を削除します。

バージョン 2.6 で撤廃: この関数は Python 3.x で削除されます。 delitem() をスライスインデクスで使って下さい。

operator.getitem(a, b)

operator.__getitem__(a, b)

a でインデクスが b の要素を返します。

operator.getslice(a, b, c)

operator.__getslice__(a, b, c)

a でインデクスが b から c-1 のスライス要素を返します。

バージョン 2.6 で撤廃: この関数は Python 3.x で削除されます。 getitem() をスライスインデクスで使って下さい。

operator.indexOf(a, b)

a で最初に b が出現する場所のインデクスを返します。

operator.repeat(a, b)

operator.__repeat__(a, b)

バージョン 2.7 で撤廃: 代わりに __mul__() を使って下さい。

シーケンス a と整数 b について a * b を返します。

operator.sequenceIncludes(...)

バージョン 2.0 で撤廃: contains() を使ってください。

contains() の別名です。

operator.setitem(a, b, c)

operator.__setitem__(a, b, c)

a でインデクスが b の要素の値を c に設定します。

operator.setslice(a, b, c, v)

operator.__setslice__(a, b, c, v)

a でインデクスが b から c-1 のスライス要素の値をシーケンス v に設定します。

バージョン 2.6 で撤廃: この関数は Python 3.x で削除されます。 setitem() をスライスインデクスで使って下さい。

operator の関数を使う例を挙げます:

>>> # Elementwise multiplication
>>> map(mul, [0, 1, 2, 3], [10, 20, 30, 40])
[0, 20, 60, 120]

>>> # Dot product
>>> sum(map(mul, [0, 1, 2, 3], [10, 20, 30, 40]))
200

多くの演算に「その場」バージョンがあります。以下の関数はそうした演算子の通常の文法に比べてより素朴な呼び出し方を提供します。たとえば、文(statement) x += y は x = operator.iadd(x, y) と等価です。別の言い方をすると、 z = operator.iadd(x, y) は複合文 z = x; z += y と等価です。

operator.iadd(a, b)

operator.__iadd__(a, b)

a = iadd(a, b) は a += b と等価です。

バージョン 2.5 で追加.

operator.iand(a, b)

operator.__iand__(a, b)

a = iand(a, b) は a &= b と等価です。

バージョン 2.5 で追加.

operator.iconcat(a, b)

operator.__iconcat__(a, b)

a = iconcat(a, b) は二つのシーケンス a と b に対し a += b と等価です。

バージョン 2.5 で追加.

operator.idiv(a, b)

operator.__idiv__(a, b)

a = idiv(a, b) は __future__.division が有効でないときに a /= b と等価です。

バージョン 2.5 で追加.

operator.ifloordiv(a, b)

operator.__ifloordiv__(a, b)

a = ifloordiv(a, b) は a //= b と等価です。

バージョン 2.5 で追加.

operator.ilshift(a, b)

operator.__ilshift__(a, b)

a = ilshift(a, b) は a < <= b と等価です。

バージョン 2.5 で追加.

operator.imod(a, b)

operator.__imod__(a, b)

a = imod(a, b) は a %= b と等価です。

バージョン 2.5 で追加.

operator.imul(a, b)

operator.__imul__(a, b)

a = imul(a, b) は a *= b と等価です。

バージョン 2.5 で追加.

operator.ior(a, b)

operator.__ior__(a, b)

a = ior(a, b) は a |= b と等価です。

バージョン 2.5 で追加.

operator.ipow(a, b)

operator.__ipow__(a, b)

a = ipow(a, b) は a **= b と等価です。

バージョン 2.5 で追加.

operator.irepeat(a, b)

operator.__irepeat__(a, b)

バージョン 2.7 で撤廃: 代わりに __imul__() を使って下さい。

a = irepeat(a, b) は a がシーケンスで b が整数であるとき a *= b と等価です。

バージョン 2.5 で追加.

operator.irshift(a, b)

operator.__irshift__(a, b)

a = irshift(a, b) は a >>= b と等価です。

バージョン 2.5 で追加.

operator.isub(a, b)

operator.__isub__(a, b)

a = isub(a, b) は a -= b と等価です。

バージョン 2.5 で追加.

operator.itruediv(a, b)

operator.__itruediv__(a, b)

a = itruediv(a, b) は __future__.division が有効なときに a /= b と等価です。

バージョン 2.5 で追加.

operator.ixor(a, b)

operator.__ixor__(a, b)

a = ixor(a, b) は a ^= b と等価です。

バージョン 2.5 で追加.

operator モジュールでは、オブジェクトの型を調べるための述語演算子も定義しています。しかしながらこれらはいつでも信頼できるというわけではありません。代わりに抽象基底クラスをテストするのが望ましい方法です (詳しくは collections や numbers を参照して下さい)。

operator.isCallable(obj)

バージョン 2.0 で撤廃: isinstance(x, collections.Callable)() を使ってください。

オブジェクト obj を関数のように呼び出すことができる場合真を返し、それ以外の場合偽を返します。関数、バインドおよび非バインドメソッド、クラスオブジェクト、および __call__() メソッドをサポートするインスタンスオブジェクトは真を返します。

operator.isMappingType(obj)

バージョン 2.7 で撤廃: 代わりに isinstance(x, collections.Mapping) を使って下さい。

オブジェクト obj がマップ型インタフェースをサポートする場合に真を返します。辞書および __getitem__() メソッドが定義された全てのインスタンスオブジェクトに対しては、この値は真になります。

operator.isNumberType(obj)

バージョン 2.7 で撤廃: 代わりに isinstance(x, numbers.Number) を使って下さい。

オブジェクト obj が数値を表現している場合に真を返します。 C で実装された全ての数値型対して、この値は真になります。

operator.isSequenceType(obj)

バージョン 2.7 で撤廃: 代わりに isinstance(x, collections.Sequence) を使って下さい。

obj がシーケンス型プロトコルをサポートする場合に真を返します。シーケンス型メソッドを C で定義している全てのオブジェクトおよび __getitem__() メソッドが定義された全てのインスタンスオブジェクトに対して、この値は真になります。

operator モジュールはアトリビュートとアイテムの汎用的な検索のための道具も定義しています。 map(), sorted(), itertools.groupby(), や関数を引数に取るその他の関数に対して高速にフィールドを抽出する際に引数として使うと便利です。

operator.attrgetter(attr[, args...])

演算対象から attr を取得する呼び出し可能なオブジェクトを返します。二つ以上のアトリビュートを要求された場合には、アトリビュートのタプルを返します。 f = attrgetter('name') とした後で、 f(b) を呼び出すと b.name を返します。 f = attrgetter('name', 'date') とした後で、 f(b) を呼び出すと (b.name, b.date) を返します。以下と等価です:

def attrgetter(*items):
    if len(items) == 1:
        attr = items[0]
        def g(obj):
            return resolve_attr(obj, attr)
    else:
        def g(obj):
            return tuple(resolve_att(obj, attr) for attr in items)
    return g

def resolve_attr(obj, attr):
    for name in attr.split("."):
        obj = getattr(obj, name)
    return obj

アトリビュート名にドットを含んでも構いません。 f = attrgetter('date.month') とした後で、 f(b) を呼び出すと b.date.month を返します。

バージョン 2.4 で追加.

バージョン 2.5 で変更: 複数のアトリビュートがサポートされました。

バージョン 2.6 で変更: ドット付きアトリビュートがサポートされました。

operator.itemgetter(item[, args...])

演算対象からその __getitem__() メソッドを使って item を取得する呼び出し可能なオブジェクトを返します。二つ以上のアイテムを要求された場合には、アイテムのタプルを返します。以下のコードと等価です:

def itemgetter(*items):
    if len(items) == 1:
        item = items[0]
        def g(obj):
            return obj[item]
    else:
        def g(obj):
            return tuple(obj[item] for item in items)
    return g

アイテムは演算対象の __getitem__() メソッドが受け付けるどんな型でも構いません。辞書ならば任意のハッシュ可能な値を受け付けますし、リスト、タプル、文字列などはインデクスかスライスを受け付けます:

>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1,3,5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2,None))('ABCDEFG')
'CDEFG'

バージョン 2.4 で追加.

バージョン 2.5 で変更: 複数のアトリビュートがサポートされました.

itemgetter() を使って特定のフィールドをタプルから取り出す例:

>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
>>> map(getcount, inventory)
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]

operator.methodcaller(name[, args...])

引数の name メソッドを呼び出す呼び出し可能オブジェクトを返します。追加の引数および/またはキーワード引数が与えられると、これらもそのメソッドに引き渡されます。 f = methodcaller('name') とした後で、 f(b) を呼び出すと b.name() を返します。 f = methodcaller('name', 'foo', bar=1) とした後で、 f(b) を呼び出すと b.name('foo', bar=1) を返します。以下と等価です:

def methodcaller(name, *args, **kwargs):
    def caller(obj):
        return getattr(obj, name)(*args, **kwargs)
    return caller

9.9.1. 演算子から関数への対応表

下のテーブルでは、個々の抽象的な操作が、どのように Python 構文上の各演算子や operator モジュールの関数に対応しているかを示しています。

操作 | 構文 | 関数
加算 | a + b | add(a, b)
結合 | seq1 + seq2 | concat(seq1, seq2)
包含テスト | obj in seq | contains(seq, obj)
除算 | a / b | div(a, b) (__future__.division が無効な場合)
除算 | a / b | truediv(a, b) (__future__.division が有効な場合)
除算 | a // b | floordiv(a, b)
論理積 | a & b | and_(a, b)
排他的論理和 | a ^ b | xor(a, b)
ビット反転 | ~ a | invert(a)
論理和 | a | b | or_(a, b)
べき乗 | a ** b | pow(a, b)
インデクス指定の代入 | obj[k] = v | setitem(obj, k, v)
インデクス指定の削除 | del obj[k] | delitem(obj, k)
インデクス指定 | obj[k] | getitem(obj, k)
左シフト | a << b | lshift(a, b)
剰余 | a % b | mod(a, b)
乗算 | a * b | mul(a, b)
(算術)否 | - a | neg(a)
(論理)否 | not a | not_(a)
符号反転 | + a | pos(a)
右シフト | a >> b | rshift(a, b)
シーケンスの反復 | seq * i | repeat(seq, i)
スライス指定の代入 | seq[i:j] = values | setslice(seq, i, j, values)
スライス指定の削除 | del seq[i:j] | delslice(seq, i, j)
スライス指定 | seq[i:j] | getslice(seq, i, j)
文字列書式化 | s % obj | mod(s, obj)
減算 | a - b | sub(a, b)
真値テスト | obj | truth(obj)
順序付け | a < b | lt(a, b)
順序付け | a <= b | le(a, b)
等価性 | a == b | eq(a, b)
不等性 | a != b | ne(a, b)
順序付け | a >= b | ge(a, b)
順序付け | a > b | gt(a, b)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス

この章で説明されるモジュールはディスクのファイルやディレクトリを扱います。たとえば、ファイルの属性を読むためのモジュール、ファイルパスを移植可能な方式で操作する、テンポラリファイルを作成するためのモジュールです。この章の完全な一覧は:

10.1. os.path — 共通のパス名操作

10.2. fileinput — 複数の入力ストリームをまたいだ行の繰り返し処理をサポートする。

10.3. stat — stat() の返す内容を解釈する

10.4. statvfs — os.statvfs() で使われる定数群

10.5. filecmp — ファイルおよびディレクトリの比較

10.5.1. dircmp クラス

10.6. tempfile — 一時的なファイルやディレクトリの生成

10.7. glob — Unix 形式のパス名のパターン展開

10.8. fnmatch — Unix ファイル名のパターンマッチ

10.9. linecache — テキストラインにランダムアクセスする

10.10. shutil — 高レベルなファイル操作

10.10.1. ディレクトリとファイルの操作

10.10.1.1. copytree の例

10.10.2. アーカイブの操作

10.10.2.1. アーカイブ化の例

10.11. dircache — キャッシュされたディレクトリ一覧の生成

10.12. macpath — Mac OS 9 のパス操作関数

参考

Section ファイルオブジェクト

Python組み込みのファイルオブジェクト。

Module os

オペレーティングシステムのインタフェース、組み込みのファイルオブジェクトより低レベルでのファイル操作を含む。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.1. os.path — 共通のパス名操作

このモジュールには、パス名を操作する便利な関数が定義されています。ファイルの読み書きに関しては、 open() 、ファイルシステムへのアクセスに関しては、 os モジュールを参照下さい。

ノート

これらの関数の多くは Windows の一律命名規則 (UNCパス名) を正しくサポートしていません。 splitunc() と ismount() は正しく UNC パス名を操作できます。

ノート

OSによって異なるパスの決まりがあるので、標準ライブラリにはこのモジュールの幾つかのバージョンが含まれています。 os.path モジュールは常に現在 Pythonが動作しているOSに適したパスモジュールで、ローカルのパスを扱うのに適しています。各々のモジュールをインポートして 常に 一つのフォーマットを利用することも可能です。これらは全て同じインタフェースを持っています。:

posixpath for UNIX-style paths

ntpath for Windows paths

macpath for old-style MacOS paths

os2emxpath for OS/2 EMX paths

os.path.abspath(path)

path の標準化された絶対パスを返します。たいていのプラットフォームでは、 normpath(join(os.getcwd(), path)) と同じ結果になります。

バージョン 1.5.2 で追加.

os.path.basename(path)

パス名 path の末尾のファイル名を返します。これは split(path) で返されるペアの2番目の要素です。この関数が返す値は Unix の basename とは異なります; Unix の basename は '/foo/bar/' に対して 'bar' を返しますが、 basename() は空文字列 ('') を返します。

os.path.commonprefix(list)

パスの list の中の共通する最長のプレフィックスを (パス名の1文字1 文字を判断して) 返します。もし list が空なら、空文字列 ('') を返します。これは一度に1文字を扱うため、不正なパスを返すことがあるかもしれませんので注意して下さい。

os.path.dirname(path)

パス path のディレクトリ名を返します。これは split(path) で返されるペアの最初の要素です。

os.path.exists(path)

path が存在するなら、 True を返します。壊れたシンボリックリンクについては False を返します。いくつかのプラットフォームでは、たとえ path が物理的に存在していたとしても、リクエストされたファイルに対する os.stat() の実行が許可されなければこの関数が False を返すことがあります。

os.path.lexists(path)

path が存在するパスなら True を返す。壊れたシンボリックリンクについては True を返します。 os.lstat() がない環境では exists() と同じです。

バージョン 2.4 で追加.

os.path.expanduser(path)

Unix 、および、 Windows では、与えられた引数の先頭のパス要素 ~ 、または ~user を、 user のホームディレクトリのパスに置き換えて返します。

Unix では、先頭の ~ は、環境変数 HOME が設定されているならその値に置き換えられます。そうでなければ、現在のユーザのホームディレクトリをビルトインモジュール pwd を使ってパスワードディレクトリから探して置き換えます。先頭の ~user については、直接パスワードディレクトリから探します。

Windows では ~ だけがサポートされ、環境変数 HOME または HOMEDRIVE と HOMEPATH の組み合わせで置き換えられます。

もし置き換えに失敗したり、引数のパスがチルダで始まっていなかったら、パスをそのまま返します。

os.path.expandvars(path)

引数のパスの環境変数を展開して返します。引数の中の $name または ${name} のような形式の文字列は環境変数、 name に置き換えられます。不正な変数名や存在しない変数名の場合には変換されず、そのまま返します。

Windows では、 $name や ${name} の形式に加えて、 %name% の形式もサポートされています。

os.path.getatime(path)

path に最後にアクセスした時刻を、エポック (time モジュールを参照下さい) からの経過時間を示す秒数で返します。ファイルが存在しなかったりアクセスできない場合は os.error を送出します。

バージョン 2.3 で変更: os.stat_float_times() が True を返す場合、戻り値は浮動小数点値となります。

バージョン 1.5.2 で追加.

os.path.getmtime(path)

path の最終更新時刻を、エポック (time モジュールを参照下さい) からの経過時間を示す秒数で返します。ファイルが存在しなかったりアクセスできない場合は os.error を送出します。

バージョン 2.3 で変更: os.stat_float_times() が True を返す場合、戻り値は浮動小数点値となります。

バージョン 1.5.2 で追加.

os.path.getctime(path)

システムによって、ファイルの最終変更時刻 (Unix のようなシステム) や作成時刻 (Windows のようなシステム) をシステムの ctime で返します。戻り値はエポック (time モジュールを参照下さい) からの経過秒数を示す数値です。ファイルが存在しなかったりアクセスできない場合は os.error を送出します。

バージョン 2.3 で追加.

os.path.getsize(path)

ファイル path のサイズをバイト数で返します。ファイルが存在しなかったりアクセスできない場合は os.error を送出します。

バージョン 1.5.2 で追加.

os.path.isabs(path)

path が絶対パスなら、 True を返します。すなわち、 Unix ではスラッシュで始まり、 Windows ではドライブレターに続く (バック) スラッシュで始まる場合です。

os.path.isfile(path)

path が存在する正しいファイルなら、 True を返します。シンボリックリンクの場合にはその実体をチェックするので、同じパスに対して islink() と isfile() の両方が True を返すことがあります。

os.path.isdir(path)

path が存在するなら、 True を返します。シンボリックリンクの場合にはその実体をチェックするので、同じパスに対して islink() と isdir() の両方が True を返すことがあります。

os.path.islink(path)

path がシンボリックリンクなら、 True を返します。シンボリックリンクがサポートされていないプラットフォームでは、常に False を返します。

os.path.ismount(path)

パス名 path がマウントポイント mount point (ファイルシステムの中で異なるファイルシステムがマウントされているところ) なら、 True を返します: この関数は path の親ディレクトリである path/.. が path と異なるデバイス上にあるか、あるいは path/.. と path が同じデバイス上の同じ i-node を指しているかをチェックします — これによって全ての Unix と POSIX 標準でマウントポイントが検出できます。

os.path.join(path1[, path2[, ...]])

1 つあるいはそれ以上のパスの要素をうまく結合します。付け加える要素に絶対パスがあれば、それより前の要素は (Windows ではドライブ名があればそれも含めて) 全て破棄され、以降の要素を結合します。戻り値は path1 と省略可能な path2 以降を結合したもので、 path2 が空文字列でないなら、ディレクトリの区切り文字 (os.sep) が各要素の間に挿入されます。 Windows では各ドライブに対してカレントディレクトリがあるので、 os.path.join("c:", "foo") によって、 c:\foo ではなく、ドライブ C: 上のカレントディレクトリからの相対パス (c:foo) が返されます。

os.path.normcase(path)

パス名の大文字、小文字をシステムの標準にします。 Unix と Mac OS X ではそのまま返します。大文字、小文字を区別しないファイルシステムではパス名を小文字に変換します。 Windows では、スラッシュをバックスラッシュに変換します。

os.path.normpath(path)

パス名を標準化します。余分な区切り文字や上位レベル参照を削除し、 A//B 、 A/B/ 、 A/./B 、 A/foo/../B が全て A/B になるようにします。大文字、小文字は標準化しません (それには normcase() を使って下さい) 。 Windows では、スラッシュをバックスラッシュに変換します。パスがシンボリックリンクを含んでいるかによって意味が変わることに注意してください。

os.path.realpath(path)

パスの中のシンボリックリンク (もしそれが当該オペレーティングシステムでサポートされていれば)を取り除いて、標準化したパスを返します。

バージョン 2.2 で追加.

os.path.relpath(path[, start])

カレントディレクトリ、または、オプション引数の start から、 path への相対ファイルパスを返します。

start のデフォルト値は os.curdir です。

利用可能: Windows 、 Unix

バージョン 2.6 で追加.

os.path.samefile(path1, path2)

2つの引数であるパス名が同じファイルあるいはディレクトリを指していれば (同じデバイスナンバーと i-node ナンバーで示されていれば) 、 True を返します。どちらかのパス名で os.stat() の呼び出しに失敗した場合には、例外が発生します。

利用可能: Unix

os.path.sameopenfile(fp1, fp2)

ファイルディスクリプタ fp1 と fp2 が同じファイルを指していたら、 True を返します。利用可能: Unix

os.path.samestat(stat1, stat2)

stat タプル stat1 と stat2 が同じファイルを指していたら、 True を返します。これらのタプルは fstat() 、 lstat() や stat() で返されたものでかまいません。この関数は、 samefile() と sameopenfile() で使われるのと同様なものを背後に実装しています。

利用可能: Unix

os.path.split(path)

パス名 path を (head, tail) のペアに分割します。 tail はパスの構成要素の末尾で、 head はそれより前の部分です。 tail はスラッシュを含みません; もし path の最後にスラッシュがあれば、 tail は空文字列になります。もし path にスラッシュがなければ、 head は空文字列になります。 path が空文字列なら、 head と tail のどちらも空文字列になります。 head の末尾のスラッシュは、 head がルートディレクトリ (1つ以上のスラッシュのみ) でない限り、取り除かれます。 join(head, tail) の結果は常に path と同じ場所を示すパスになりますが、文字列としては異なるかもしれません。

os.path.splitdrive(path)

パス名 path を (drive, tail) のペアに分割します。 drive はドライブ名か、空文字列です。ドライブ名を使用しないシステムでは、 drive は常に空文字列です。全ての場合に drive + tail は path と等しくなります。

バージョン 1.3 で追加.

os.path.splitext(path)

パス名 path を (root, ext) のペアにします。 root + ext == path になります。 ext は空文字列か1つのピリオドで始まり、多くても1つのピリオドを含みます。ベースネームを導出するピリオドは無視されます。 ; splitext('.cshrc') は、 ('.cshrc', '') を返します。

バージョン 2.6 で変更: 以前のバージョンでは、最初の文字がピリオドであった場合、空の root を生成していました。

os.path.splitunc(path)

パス名 path をペア (unc, rest) に分割します。ここで unc は (r'\\host\mount' のような) UNC マウントポイント、そして rest は (r'\path\file.ext' のような) パスの残りの部分です。ドライブ名を含むパスでは常に unc が空文字列になります。

利用可能: Windows

os.path.walk(path, visit, arg)

path をルートとする各ディレクトリに対して (もし path がディレクトリなら path も含みます) 、 (arg, dirname, names) を引数として関数 visit を呼び出します。引数 dirname は訪れたディレクトリを示し、引数 names はそのディレクトリ内のファイルのリスト (os.listdir(dirname) で得られる) です。関数 visit によって names を変更して、 dirname 以下の対象となるディレクトリのセットを変更することもできます。例えば、あるディレクトリツリーだけ関数を適用しないなど。 (names で参照されるオブジェクトは、 del あるいはスライスを使って正しく変更しなければなりません。)

ノート

ディレクトリへのシンボリックリンクはサブディレクトリとして扱われないので、 walk() による操作対象とはされません。ディレクトリへのシンボリックリンクを操作対象とするには、 os.path.islink(file) と os.path.isdir(file) で識別して、 walk() で必要な操作を実行しなければなりません。

ノート

この関数は廃止予定で、 3.0 では削除されました。 os.walk() が残っています。

os.path.supports_unicode_filenames

任意のユニコード文字列を (ファイルシステムの制限内で) ファイルネームに使うことが可能なら、真を返します。

バージョン 2.3 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.2. fileinput — 複数の入力ストリームをまたいだ行の繰り返し処理をサポートする。

このモジュールは標準入力やファイルの並びにまたがるループを素早く書くためのヘルパークラスと関数を提供しています。

典型的な使い方は以下の通りです。

import fileinput
for line in fileinput.input():
    process(line)

このプログラムは sys.argv[1:] に含まれる全てのファイルをまたいで繰り返します。もし該当するものがなければ、 sys.stdin がデフォルトとして扱われます。ファイル名として '-' が与えられた場合も、 sys.stdin に置き換えられます。別のファイル名リストを使いたい時には、 input() の最初の引数にリストを与えます。単一ファイル名の文字列も受け付けます。

全てのファイルはデフォルトでテキストモードでオープンされます。しかし、 input() や FileInput() をコールする際に mode パラメータを指定すれば、これをオーバーライドすることができます。オープン中あるいは読み込み中にI/Oエラーが発生した場合には、 IOError が発生します。

sys.stdin が2回以上使われた場合は、2回目以降は行を返しません。ただしインタラクティブに利用している時や明示的にリセット (sys.stdin.seek(0)) を使う)を行った場合はその限りではありません。

空のファイルは開いた後すぐ閉じられます。空のファイルはファイル名リストの最後にある場合にしか外部に影響を与えません。

ファイルの各行は、各種改行文字まで含めて返されます。ファイルの最後が改行文字で終っていない場合には、改行文字で終わらない行が返されます。

ファイルのオープン方法を制御するためのオープン時フックは、 fileinput.input() あるいは FileInput() の openhook パラメータで設定します。このフックは、ふたつの引数 filename と mode をとる関数でなければなりません。そしてその関数の返り値はオープンしたファイルオブジェクトとなります。このモジュールには、便利なフックが既に用意されています。

参考

最新バージョンの fileinput Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/fileinput.py?view=markup]

以下の関数がこのモジュールの基本的なインタフェースです。

fileinput.input([files[, inplace[, backup[, mode[, openhook]]]]])

FileInput クラスのインスタンスを作ります。生成されたインスタンスは、このモジュールの関数群が利用するグローバルな状態として利用されます。この関数への引数は FileInput クラスのコンストラクタへ渡されます。

バージョン 2.5 で変更: パラメータ mode および openhook が追加されました.

以下の関数は fileinput.input() 関数によって作られたグローバルな状態を利用します。アクティブな状態が無い場合には、 RuntimeError が発生します。

fileinput.filename()

現在読み込み中のファイル名を返します。一行目が読み込まれる前は None を返します。

fileinput.fileno()

現在のファイルの “ファイルデスクリプタ” を整数値で返します。ファイルがオープンされていない場合 (最初の行の前、ファイルとファイルの間) は -1 を返します。

バージョン 2.5 で追加.

fileinput.lineno()

最後に読み込まれた行の、累積した行番号を返します。1行目が読み込まれる前は 0 を返します。最後のファイルの最終行が読み込まれた後には、その行の行番号を返します。

fileinput.filelineno()

現在のファイル中での行番号を返します。1行目が読み込まれる前は 0 を返します。最後のファイルの最終行が読み込まれた後には、その行のファイル中での行番号を返します。

fileinput.isfirstline()

最後に読み込まれた行がファイルの1行目ならTrue、そうでなければFalseを返します。

fileinput.isstdin()

最後に読み込まれた行が sys.stdin から読まれていればTrue、そうでなければFalseを返します。

fileinput.nextfile()

現在のファイルを閉じます。次の繰り返しでは(存在すれば)次のファイルの最初の行が読み込まれます。閉じたファイルの読み込まれなかった行は、累積の行数にカウントされません。ファイル名は次のファイルの最初の行が読み込まれるまで変更されません。最初の行の読み込みが行われるまでは、この関数は呼び出されても何もしませんので、最初のファイルをスキップするために利用することはできません。最後のファイルの最終行が読み込まれた後にも、この関数は呼び出されても何もしません。

fileinput.close()

シーケンスを閉じます。

このモジュールのシーケンスの振舞いを実装しているクラスのサブクラスを作ることもできます。

class fileinput.FileInput([files[, inplace[, backup[, mode[, openhook]]]]])

FileInput クラスはモジュールの関数に対応するメソッド filename() 、 fileno() 、 lineno() 、 filelineno() 、 isfirstline() 、 isstdin() 、 nextfile() および close() を実装しています。それに加えて、次の入力行を返す readline() メソッドと、シーケンスの振舞いの実装をしている __getitem__() メソッドがあります。シーケンスはシーケンシャルに読み込むことしかできません。つまりランダムアクセスと readline() を混在させることはできません。

mode を使用すると、 open() に渡すファイルモードを指定することができます。これは 'r' 、 'rU' 、 'U' および 'rb' のうちのいずれかとなります。

openhook を指定する場合は、ふたつの引数 filename と mode をとる関数でなければなりません。この関数の返り値は、オープンしたファイルオブジェクトとなります。 inplace と openhook を同時に使うことはできません。

バージョン 2.5 で変更: パラメータ mode および openhook が追加されました.

インプレース(in-place)フィルタオプション: キーワード引数 inplace=1 が input() か FileInput クラスのコンストラクタに渡された場合には、入力ファイルはバックアップファイルに移動され、標準出力が入力ファイルに設定されます(バックアップファイルと同じ名前のファイルが既に存在していた場合には、警告無しに置き替えられます)。これによって入力ファイルをその場で書き替えるフィルタを書くことができます。キーワード引数 backup (通常は backup='.<拡張子>' という形で利用します)が与えられていた場合、バックアップファイルの拡張子として利用され、バックアップファイルは削除されずに残ります。デフォルトでは、拡張子は '.bak' になっていて、出力先のファイルが閉じられればバックアップファイルも消されます。インプレースフィルタ機能は、標準入力を読み込んでいる間は無効にされます。

ノート

現在の実装はMS-DOSの8+3ファイルシステムでは動作しません。

このモジュールには、次のふたつのオープン時フックが用意されています。

fileinput.hook_compressed(filename, mode)

gzipやbzip2で圧縮された(拡張子が '.gz' や '.bz2' の) ファイルを、 gzip モジュールや bz2 モジュールを使って透過的にオープンします。ファイルの拡張子が '.gz' や '.bz2' でない場合は、通常通りファイルをオープンします (つまり、 open() をコールする際に伸長を行いません)。

使用例: fi = fileinput.FileInput(openhook=fileinput.hook_compressed)

バージョン 2.5 で追加.

fileinput.hook_encoded(encoding)

各ファイルを codecs.open() でオープンするフックを返します。指定した encoding でファイルを読み込みます。

使用例: fi = fileinput.FileInput(openhook=fileinput.hook_encoded("iso-8859-1"))

ノート

このフックでは、指定した encoding によっては FileInput がUnicode文字列を返す可能性があります。

バージョン 2.5 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.3. stat — stat() の返す内容を解釈する

stat モジュールでは、 os.stat() 、 os.lstat() および os.fstat() (存在すれば) の返す内容を解釈するための定数や関数を定義しています。 stat() 、 fstat() 、および lstat() の関数呼び出しについての完全な記述はシステムのドキュメントを参照してください。

stat モジュールでは、特殊なファイル型を判別するための以下の関数を定義しています:

stat.S_ISDIR(mode)

ファイルのモードがディレクトリの場合にゼロでない値を返します。

stat.S_ISCHR(mode)

ファイルのモードがキャラクタ型の特殊デバイスファイルの場合にゼロでない値を返します。

stat.S_ISBLK(mode)

ファイルのモードがブロック型の特殊デバイスファイルの場合にゼロでない値を返します。

stat.S_ISREG(mode)

ファイルのモードが通常ファイルの場合にゼロでない値を返します。

stat.S_ISFIFO(mode)

ファイルのモードが FIFO (名前つきパイプ) の場合にゼロでない値を返します。

stat.S_ISLNK(mode)

ファイルのモードがシンボリックリンクの場合にゼロでない値を返します。

stat.S_ISSOCK(mode)

ファイルのモードがソケットの場合にゼロでない値を返します。

より一般的なファイルのモードを操作するための二つの関数が定義されています:

stat.S_IMODE(mode)

os.chmod() で設定することのできる一部のファイルモード — すなわち、ファイルの許可ビット (permission bits) に加え、 (サポートされているシステムでは) スティッキービット (sticky bit)、実行グループ ID 設定 (set-group-id) および実行ユーザ ID 設定 (set-user-id) ビット — を返します。

stat.S_IFMT(mode)

ファイルの形式を記述しているファイルモードの一部 (上記の S_IS*() 関数で使われます) を返します。

通常、ファイルの形式を調べる場合には os.path.is*() 関数を使うことになります; ここで挙げた関数は同じファイルに対して複数のテストを同時に行いたいが、 stat() システムコールを何度も呼び出してオーバヘッドが生じるのを避けたい場合に便利です。これらはまた、ブロック型およびキャラクタ型デバイスに対するテストのように、 os.path で扱うことのできないファイルの情報を調べる際にも便利です。

例:

import os, sys
from stat import *

def walktree(top, callback):
    '''recursively descend the directory tree rooted at top,
       calling the callback function for each regular file'''

    for f in os.listdir(top):
        pathname = os.path.join(top, f)
        mode = os.stat(pathname)[ST_MODE]
        if S_ISDIR(mode):
            # It's a directory, recurse into it
            walktree(pathname, callback)
        elif S_ISREG(mode):
            # It's a file, call the callback function
            callback(pathname)
        else:
            # Unknown file type, print a message
            print 'Skipping %s' % pathname

def visitfile(file):
    print 'visiting', file

if __name__ == '__main__':
    walktree(sys.argv[1], visitfile)

以下の全ての変数は、 os.stat() 、 os.fstat() 、または os.lstat() が返す 10 要素のタプルにおけるインデクスを単にシンボル定数化したものです。

stat.ST_MODE

Iノードの保護モード。

stat.ST_INO

Iノード番号。

stat.ST_DEV

Iノードが存在するデバイス。

stat.ST_NLINK

該当する Iノードへのリンク数。

stat.ST_UID

ファイルの所持者のユーザ ID。

stat.ST_GID

ファイルの所持者のグループ ID。

stat.ST_SIZE

通常ファイルではバイトサイズ; いくつかの特殊ファイルでは処理待ちのデータ量。

stat.ST_ATIME

最後にアクセスした時刻。

stat.ST_MTIME

最後に変更された時刻。

stat.ST_CTIME

オペレーティングシステムから返される”ctime”。あるOS(Unixなど)では最後にメタデータが更新された時間となり、別のOS(Windowsなど)では作成時間となります(詳細については各プラットフォームのドキュメントを参照してください)。

“ファイルサイズ” の解釈はファイルの型によって異なります。通常のファイルの場合、サイズはファイルの大きさをバイトで表したものです。ほとんどの Unix 系 (特に Linux) における FIFO やソケットの場合、”サイズ” は os.stat() 、 os.fstat() 、あるいは os.lstat() を呼び出した時点で読み出し待ちであったデータのバイト数になります; この値は時に有用で、特に上記の特殊なファイルを非ブロックモードで開いた後にポーリングを行いたいといった場合に便利です。他のキャラクタ型およびブロック型デバイスにおけるサイズフィールドの意味はさらに異なっていて、背後のシステムコールの実装によります。

以下の変数は、 ST_MODE フィールドで使用されるフラグを定義しています。

最初に挙げる、以下のフラグを使うよりは、上記の関数を使うほうがポータブルです:

stat.S_IFMT

ファイルタイプのビットフィールド用のビットマスク

stat.S_IFSOCK

ソケット

stat.S_IFLNK

シンボリックリンク

stat.S_IFREG

通常のファイル

stat.S_IFBLK

ブロックデバイス

stat.S_IFDIR

ディレクトリ

stat.S_IFCHR

キャラクターデバイス

stat.S_IFIFO

FIFO.

以下のフラグは、 os.chmod() の mode 引数に使うこともできます:

stat.S_ISUID

UID ビットを設定する

stat.S_ISGID

グループIDビットを設定する。このビットには幾つかの特殊ケースがあります。ディレクトリに対して設定されていた場合、 BSD のセマンティクスが利用される事を示しています。すなわち、そこに作成されるファイルは、作成したプロセスの有効グループID (effective group ID) ではなくそのディレクトリのグループIDを継承し、そこに作成されるディレクトリにも S_ISGID ビットが設定されます。グループ実行ビット (S_IXGRP) が設定されていないファイルに対してこのビットが設定されていた場合、強制ファイル/レコードロックを意味します。 (S_ENFMT も参照してください。)

stat.S_ISVTX

スティッキービット。このビットがディレクトリに対して設定されているとき、そのディレクトリ内のファイルは、そのファイルのオーナー、あるいはそのディレクトリのオーナーか特権プロセスのみが、リネームや削除をすることが出来ることを意味しています。

stat.S_IRWXU

ファイルオーナーの権限に対するマスク

stat.S_IRUSR

オーナーがリード権限を持っている

stat.S_IWUSR

オーナーがライト権限を持っている

stat.S_IXUSR

オーナーが実行権限を持っている

stat.S_IRWXG

グループの権限に対するマスク

stat.S_IRGRP

グループがリード権限を持っている

stat.S_IWGRP

グループがライト権限を持っている

stat.S_IXGRP

グループが実行権限を持っている

stat.S_IRWXO

その他 (グループ外) の権限に対するマスク

stat.S_IROTH

その他はリード権限を持っている

stat.S_IWOTH

その他はライト権限を持っている

stat.S_IXOTH

その他は実行権限を持っている

stat.S_ENFMT

System V ファイルロック強制。このフラグは S_ISGID と共有されています。グループ実行ビット (S_IXGRP) が設定されていないファイルでは、ファイル/レコードのロックが強制されます。

stat.S_IREAD

S_IRUSR の、 Unix V7 のシノニム

stat.S_IWRITE

S_IWUSR の、 Unix V7 のシノニム

stat.S_IEXEC

S_IXUSR の、 Unix V7 のシノニム

以下のフラグを os.chflags() の flags 引数として利用できます:

stat.UF_NODUMP

ファイルをダンプしない

stat.UF_IMMUTABLE

ファイルは変更されない

stat.UF_APPEND

ファイルは追記しかされない。

stat.UF_OPAQUE

ユニオンファイルシステムのスタックを通したとき、このディレクトリは不透明です。

stat.UF_NOUNLINK

ファイルはリネームや削除されない。

stat.SF_ARCHIVED

ファイルはアーカイブされているかもしれません。

stat.SF_IMMUTABLE

ファイルは変更されないかもしれません。

stat.SF_APPEND

ファイルは追記しかされないかもしれません。

stat.SF_NOUNLINK

ファイルはリネームされたり削除されたりしないかもしれません。

stat.SF_SNAPSHOT

このファイルはスナップショットファイルです。

詳しい情報は *BSD か Mac OS システムの man page chflags(2) を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.4. statvfs — os.statvfs() で使われる定数群

バージョン 2.6 で撤廃: statvfs モジュールは Python 3.0 で削除されます。

statvfs モジュールでは、 os.statvfs() の返す値を解釈するための定数を定義しています。 os.statvfs() は “マジックナンバ” を記憶せずにタプルを生成して返します。このモジュールで定義されている各定数は os.statvfs() が返すタプルにおいて、特定の情報が収められている各エントリへの インデクスです。

statvfs.F_BSIZE

選択されているファイルシステムのブロックサイズです。

statvfs.F_FRSIZE

ファイルシステムの基本ブロックサイズです。

statvfs.F_BLOCKS

ブロック数の総計です。

statvfs.F_BFREE

空きブロック数の総計です。

statvfs.F_BAVAIL

非スーパユーザが利用できる空きブロック数です。

statvfs.F_FILES

ファイルノード数の総計です。

statvfs.F_FFREE

空きファイルノード数の総計です。

statvfs.F_FAVAIL

非スーパユーザが利用できる空きノード数です。

statvfs.F_FLAG

フラグで、システム依存です: statvfs() マニュアルページを参照してください。

statvfs.F_NAMEMAX

ファイル名の最大長です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.5. filecmp — ファイルおよびディレクトリの比較

filecmp モジュールでは、ファイルおよびディレクトリを比較するため、様々な時間／正確性のトレードオフに関するオプションを備えた関数を定義しています。ファイルの比較については、 differ モジュールも参照してください。

参考

最新バージョンの filecmp Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/filecmp.py?view=markup]

filecmp モジュールでは以下の関数を定義しています:

filecmp.cmp(f1, f2[, shallow])

名前が f1 および f2 のファイルを比較し、二つのファイルが同じらしければ True を返し、そうでなければ false を返します。

shallow が与えられておりかつ偽でなければ、 os.stat() の返すシグネチャが一致するファイルは同じであると見なされます。

この関数で比較されたファイルは os.stat() シグネチャが変更されるまで再び比較されることはありません。 use_statcache を真にすると、キャッシュ無効化機構を失敗させます — そのため、 statcache のキャッシュから古いファイル stat 値が使われます。

可搬性と効率のために、個の関数は外部プログラムを一切呼び出さないので注意してください。

filecmp.cmpfiles(dir1, dir2, common[, shallow])

dir1 と dir2 ディレクトリの中の、 common で指定されたファイルを比較します。

ファイル名からなる3つのリスト: match, mismatch, errors を返します。 match には双方のディレクトリで一致したファイルのリストが含まれ、 mismatch にはそうでないファイル名のリストが入ります。そして errors は比較されなかったファイルが列挙されます。 errors になるのは、片方あるいは両方のディレクトリに存在しなかった、ユーザーにそのファイルを読む権限がなかった、その他何らかの理由で比較を完了することができなかった場合です。

引数 shallow はその意味も標準の設定も filecmp.cmp() と同じです。

例えば、 cmpfiles('a', 'b', ['c', 'd/e']) は a/c を b/c と、 a/d/e を b/d/e と、それぞれ比較します。 'c' と 'd/e' はそれぞれ、返される3つのリストのいずれかに登録されます。

例:

>>> import filecmp
>>> filecmp.cmp('undoc.rst', 'undoc.rst')
True
>>> filecmp.cmp('undoc.rst', 'index.rst')
False

10.5.1. dircmp クラス

dircmp のインスタンスは以下のコンストラクタで生成されます:

class filecmp.dircmp(a, b[, ignore[, hide]])

ディレクトリ a および b を比較するための新しいディレクトリ比較オブジェクトを生成します。 ignore は比較の際に無視するファイル名のリストで、標準の設定では ['RCS', 'CVS', 'tags'] です。 hide は表示しない名前のリストで、標準の設定では [os.curdir, os.pardir] です。

dircmp クラスは以下のメソッドを提供しています:

report()

a および b の間の比較結果を (sys.stdout に) 出力します。

report_partial_closure()

a および b およびそれらの直下にある共通のサブディレクトリ間での比較結果を出力します。

report_full_closure()

a および b およびそれらの共通のサブディレクトリ間での比較結果を (再帰的に比較して) 出力します。

dircmp は、比較しているディレクトリツリーに関する様々な種類の情報を取得するために使えるような、多くの興味深い属性を提供しています。

__getattr__() フックを経由すると、全ての属性をのろのろと計算するため、速度上のペナルティを受けないのは計算処理の軽い属性を使ったときだけなので注意してください。

left_list

a にあるファイルおよびサブディレクトリです。 hide および ignore でフィルタされています。

right_list

b にあるファイルおよびサブディレクトリです。 hide および ignore でフィルタされています。

common

a および b の両方にあるファイルおよびサブディレクトリです。

left_only

a だけにあるファイルおよびサブディレクトリです。

right_only

b だけにあるファイルおよびサブディレクトリです。

common_dirs

a および b の両方にあるサブディレクトリです。

common_files

a および b の両方にあるファイルです。

common_funny

a および b の両方にあり、ディレクトリ間でタイプが異なるか、 os.stat() がエラーを報告するような名前です。

same_files

a および b 両方にあり、一致するファイルです。

diff_files

a および b 両方にあるが、一致しないファイルです。

funny_files

a および b 両方にあるが、比較されなかったファイルです。

subdirs

common_dirs のファイル名を dircmp オブジェクトに対応付けた辞書です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.6. tempfile — 一時的なファイルやディレクトリの生成

このモジュールを使うと、一時的なファイルやディレクトリを生成できます。このモジュールはサポートされている全てのプラットフォームで利用可能です。

バージョン 2.3 の Python では、このモジュールに対してセキュリティを高める為の見直しが行われました。現在では新たに 3 つの関数、 NamedTemporaryFile() 、 mkstemp() 、および mkdtemp() が提供されており、安全でない mktemp() を使いつづける必要をなくしました。このモジュールで生成される一時ファイルはもはやプロセス番号を含みません; その代わり、6 桁のランダムな文字からなる文字列が使われます。

また、ユーザから呼び出し可能な関数は全て、一時ファイルの場所や名前を直接操作できるようにするための追加の引数をとるようになりました。もはや変数 tempdir および template を使う必要はありません。以前のバージョンとの互換性を維持するために、引数の順番は多少変です; 明確さのためにキーワード引数を使うことをお勧めします。

このモジュールではユーザから呼び出し可能な以下の関数を定義しています:

tempfile.TemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]])

一時的な記憶領域として使うことができるファイルライク(file-like)オブジェクトを返します。ファイルは mkstemp() を使って生成されます。このファイルは閉じられると (オブジェクトがガーベジコレクションされた際に、暗黙のうちに閉じられる場合を含みます) すぐに消去されます。Unix環境では、ファイルが生成されるとすぐにそのファイルのディレクトリエントリは除去されてしまいます。一方、他のプラットフォームではこの機能はサポートされていません; 従って、コードを書くときには、この関数で作成した一時ファイルをファイルシステム上で見ることができる、あるいはできないということをあてにすべきではありません。

生成されたファイルを一旦閉じなくてもファイルを読み書きできるようにするために、 mode パラメタは標準で 'w+b' に設定されています。ファイルに記録するデータが何であるかに関わらず全てのプラットフォームで一貫性のある動作をさせるために、バイナリモードが使われています。 bufsize の値は標準で -1 で、これはオペレーティングシステムにおける標準の値を使うことを意味しています。

dir 、 prefix および suffix パラメタは mkstemp() に渡されます。

返されるオブジェクトは、POSIXプラットフォームでは本物のfileオブジェクトです。それ以外のプラットフォームではファイルライクオブジェクトが返され、 file 属性に本物のfileオブジェクトがあります。このファイルライクオブジェクトは、通常のファイルと同じように with 文で利用することができます。

tempfile.NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])

この関数はファイルがファイルシステム上で見ることができるよう保証されている点を除き、 TemporaryFile() と全く同じに働きます。 (Unixでは、ディレクトリエントリはunlinkされません) ファイル名はファイルオブジェクトの name メンバから取得することができます。このファイル名を使って一時ファイルをもう一度開くとことができるかどうかは、プラットフォームによって異なります。 (Unixでは可能でしたが、Windows NT以降では開く事ができません。) delete がtrue(デフォルト)の場合、ファイルは閉じられるとすぐに削除されます。

返されるオブジェクトは、常にファイルライクオブジェクトです。このオブジェクトの file 属性が本物のfileオブジェクトになります。このファイルライクオブジェクトは、通常のファイルと同じように with 文を利用することができます。

バージョン 2.3 で追加.

バージョン 2.6 で追加: delete 引数

tempfile.SpooledTemporaryFile([max_size=0[, mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None]]]]]])

この関数は、ファイルサイズが max_size を超えるか、 fileno() メソッドが呼ばれるまでの間メモリ上で処理される以外は、 TemporaryFile() と同じです。 max_size を超えるか fileno() が呼ばれたとき、一時ファイルの内容がディスクに書き込まれ、その後の処理は TemporaryFile() で行われます。

この関数が返すファイルは、追加で1つのメソッド rollover() を持っています。このメソッドが呼ばれると、(サイズに関係なく)メモリからディスクへのロールオーバーが実行されます。

返されるオブジェクトはファイルライクオブジェクトで、その _file 属性は、 rollover() が呼ばれたかどうかによって、 StringIO オブジェクトか、本物のファイルオブジェクトになります。このファイルライクオブジェクトは、通常のファイルオブジェクトと同じように、 with 文で利用することができます。

バージョン 2.6 で追加.

tempfile.mkstemp([suffix=''[, prefix='tmp'[, dir=None[, text=False]]]])

可能な限り最も安全な手段で一時ファイルを生成します。使用するプラットフォームで os.open() の O_EXCL フラグが正しく実装されている限り、ファイルの生成で競合条件が起こることはありません。このファイルは、ファイルを生成したユーザのユーザ ID からのみ読み書き可能です。使用するプラットフォームにおいて、ファイルを実行可能かどうかを示す許可ビットが使われている場合、ファイルは誰からも実行不可なように設定されます。このファイルのファイル記述子は子プロセスに継承されません。

TemporaryFile() と違って、 mkstemp() で生成されたファイルが用済みになったときにファイルを消去するのはユーザの責任です。

suffix が指定された場合、ファイル名は指定されたsuffixで終わります。そうでない場合にはsuffixは付けられません。 mkstemp() はファイル名とsuffixの間にドットを追加しません; 必要なら、 suffix の先頭につけてください。

prefix が指定された場合、ファイル名は指定されたプレフィクス(接頭文字列) で始まります; そうでない場合、標準のプレフィクスが使われます。

dir が指定された場合、一時ファイルは指定されたディレクトリ下に作成されます; そうでない場合、標準のディレクトリが使われます。デフォルトのディレクトリは、プラットフォームごとに異なるリストから選ばれます。しかし、アプリケーションのユーザーは TMPDIR, TEMP, TMP 環境変数を設定することで、その場所を設定することができます。そのため、生成されたファイル名について、クォート無しで os.popen() を使って外部コマンドに渡せるかどうかなどの保証はありません。

text が指定された場合、ファイルをバイナリモード (標準の設定) かテキストモードで開くかを示します。使用するプラットフォームによってはこの値を設定しても変化はありません。

mkstemp() は開かれたファイルを扱うための OS レベルの値とファイルの絶対パス名が順番に並んだタプルを返します。

バージョン 2.3 で追加.

tempfile.mkdtemp([suffix[, prefix[, dir]]])

可能な限り安全な方法で一時ディレクトリを作成します。ディレクトリの生成で競合条件は発生しません。ディレクトリを作成したユーザ ID だけが、このディレクトリに対して内容を読み出したり、書き込んだり、検索したりすることができます。

mkdtemp() によって作られたディレクトリとその内容が用済みになった時、にそれを消去するのはユーザの責任です。

prefix 、 suffix 、および dir 引数は mkstemp() のものと同じです。

mkdtemp() は新たに生成されたディレクトリの絶対パス名を返します。

バージョン 2.3 で追加.

tempfile.mkdtemp([suffix=''[, prefix='tmp'[, dir=None]]])

可能な限り最もセキュアな方法で、一時ディレクトリを作成します。ディレクトリの作成時に、競合状態はありません。作成されたディレクトリは、作成したユーザーIDのみで、読み込み可能で、書き込み可能で、検索可能です。

mkdtemp() 関数のユーザーは、作成された一時ディレクトリとその中身を削除する責任があります。

prefix, suffix, dir 引数は mkstemp() 関数と同じです。

mkdtemp() は生成したディレクトリの絶対パスを返します。

バージョン 2.3 で追加.

tempfile.mktemp([suffix=''[, prefix='tmp'[, dir=None]]])

バージョン 2.3 で撤廃: 代わりに mkstemp() を使って下さい.

一時ファイルの絶対パス名を返します。このパス名は少なくともこの関数が呼び出された時点ではファイルシステム中に存在しなかったパス名です。 prefix 、 prefix 、 suffix 、および dir 引数は mkstemp() のものと同じです。

警告

この関数を使うとプログラムのセキュリティホールになる可能性があります。この関数が返したファイル名を返した後、あなたがそのファイル名を使って次に何かをしようとする段階に至る前に、誰か他の人間があなたにパンチをくらわせてしまうかもしれません。 mktemp() の利用は、 NamedTemporaryFile() に delete=False 引数を渡すことで、簡単に置き換えることができます。

>>> f = NamedTemporaryFile(delete=False)
>>> f
<open file '<fdopen>', mode 'w+b' at 0x384698>
>>> f.name
'/var/folders/5q/5qTPn6xq2RaWqk+1Ytw3-U+++TI/-Tmp-/tmpG7V1Y0'
>>> f.write("Hello World!\n")
>>> f.close()
>>> os.unlink(f.name)
>>> os.path.exists(f.name)
False

このモジュールでは、一時的なファイル名の作成方法を指定する 2 つのグローバル変数を使います。これらの変数は上記のいずれかの関数を最初に呼び出した際に初期化されます。関数呼び出しをおこなうユーザはこれらの値を変更することができますが、これはお勧めできません; その代わりに関数に適切な引数を指定してください。

tempfile.tempdir

この値が None 以外に設定された場合、このモジュールで定義されている関数全ての dir 引数に対する標準の設定値となります。

tempdir が設定されていないか None の場合、上記のいずれかの関数を呼び出した際は常に、Python は標準的なディレクトリ候補のリストを検索し、関数を呼び出しているユーザの権限でファイルを作成できる最初のディレクトリ候補を tempdir に設定します。リストは以下のようになっています:

環境変数 TMPDIR で与えられているディレクトリ名。

環境変数 TEMP で与えられているディレクトリ名。

環境変数 TMP で与えられているディレクトリ名。

プラットフォーム依存の場所:

RiscOS では環境変数 Wimp$ScrapDir で与えられているディレクトリ名。

Windows ではディレクトリ C:\TEMP 、 C:\TMP 、 \TEMP 、および

\TMP の順。

その他の全てのプラットフォームでは、 /tmp 、 /var/tmp 、および /usr/tmp の順。

最後の手段として、現在の作業ディレクトリ。

tempfile.gettempdir()

現在選択されている、テンポラリファイルを作成するためのディレクトリを返します。 tempdir が None でない場合、単にその内容を返します; そうでない場合には上で記述されている検索が実行され、その結果が返されます。

バージョン 2.3 で追加.

tempfile.template

バージョン 2.0 で撤廃: 代わりに gettempprefix() を使ってください。

この値に None 以外の値を設定した場合、 mktemp() が返すファイル名のディレクトリ部を含まない先頭部分 (プレフィクス) を定義します。ファイル名を一意にするために、 6 つのランダムな文字および数字がこのプレフィクスの後に追加されます。デフォルトのプレフィックスは tmp です。

このモジュールの古いバージョンでは、 os.fork() を呼び出した後に template を None に設定することが必要でした; この仕様はバージョン 1.5.2 からは必要なくなりました。

tempfile.gettempprefix()

一時ファイルを生成する際に使われるファイル名の先頭部分を返します。この先頭部分にはディレクトリ部は含まれません。変数 template を直接読み出すよりもこの関数を使うことを勧めます。

バージョン 1.5.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.7. glob — Unix 形式のパス名のパターン展開

glob モジュールはUnix シェルで使われているルールに従って指定されたパターンにマッチするすべてのパス名を見つけ出します。チルダ展開は使えませんが、 * 、 ? と [] で表される文字範囲には正しくマッチします。これは os.listdir() 関数と fnmatch.fnmatch() 関数を一緒に使って実行されていて、実際に subshell を呼び出しているわけではありません。(チルダ展開とシェル変数展開を利用したければ、 os.path.expanduser() と os.path.expandvars() を使ってください。)

参考

最新バージョンの glob モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/glob.py?view=markup]

glob.glob(pathname)

pathname (パスの指定を含んだ文字列でなければいけません。)にマッチする空の可能性のあるパス名のリストを返します。

pathname は( /usr/src/Python-1.5/Makefile のように)絶対パスでもいいし、(../../Tools/*/*.gif のように)相対パスでもよくて、シェル形式のワイルドカードを含んでいてもかまいません。結果には(シェルと同じく)壊れたシンボリックリンクも含まれます。

glob.iglob(pathname)

実際には一度に全てを格納せずに、 glob() と同じ値を順に生成するイテレータを返します。

バージョン 2.5 で追加.

たとえば、次の三つのファイルだけがあるディレクトリを考えてください: 1.gif 、 2.txt 、 card.gif 。 glob() は次のような結果になります。パスに接頭するどの部分が保たれているかに注意してください。

>>> import glob
>>> glob.glob('./[0-9].*')
['./1.gif', './2.txt']
>>> glob.glob('*.gif')
['1.gif', 'card.gif']
>>> glob.glob('?.gif')
['1.gif']

参考

Module fnmatch

シェル形式の(パスではない)ファイル名展開

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.8. fnmatch — Unix ファイル名のパターンマッチ

このモジュールは Unix のシェル形式のワイルドカードへの対応を提供しますが、(re モジュールでドキュメント化されている) 正規表現と同じでは ありません 。シェル形式のワイルドカードで使われる特別な文字は、

Pattern | Meaning
* | すべてにマッチします
? | 任意の一文字にマッチします
[seq] | seq にある任意の文字にマッチします
[!seq] | seq にない任意の文字にマッチします

ファイル名のセパレーター(Unixでは '/')はこのモジュールに固有なものでは ない ことに注意してください。パス名展開については、 glob モジュールを参照してください (glob はパス名の部分にマッチさせるのに fnmatch() を使っています)。同様に、ピリオドで始まるファイル名はこのモジュールに固有ではなくて、 * と ? のパターンでマッチします。

参考

最新バージョンの fnmatch の Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/fnmatch.py?view=markup]

fnmatch.fnmatch(filename, pattern)

filenameの文字列がpatternの文字列にマッチするかテストして、 True 、 False のいずれかを返します。オペレーティングシステムが大文字、小文字を区別しない場合、比較を行う前に、両方のパラメタを全て大文字、または全て小文字に揃えます。オペレーティングシステムが標準でどうなっているかに関係なく、大小文字を区別して比較する場合には、 fnmatchcase() が使えます。

次の例では、カレントディレクトリにある、拡張子が .txt である全てのファイルを表示しています。

import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '*.txt'):
        print file

fnmatch.fnmatchcase(filename, pattern)

filename が pattern にマッチするかテストして、 True 、 False を返します。比較は大文字、小文字を区別します。

fnmatch.filter(names, pattern)

pattern にマッチする names のリストの部分集合を返します。 [n for n in names if fnmatch(n, pattern)] と同じですが、もっと効率よく実装しています。

バージョン 2.2 で追加.

fnmatch.translate(pattern)

シェルスタイルの pattern を、正規表現に変換して返します。

メタ文字をクォートする方法が無いことに気を付けてください。

例:

>>> import fnmatch, re
>>>
>>> regex = fnmatch.translate('*.txt')
>>> regex
'.*\\.txt$'
>>> reobj = re.compile(regex)
>>> reobj.match('foobar.txt')
<_sre.SRE_Match object at 0x...>

参考

Module glob

Unix シェル形式のパス展開。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.9. linecache — テキストラインにランダムアクセスする

linecache モジュールは、キャッシュ (一つのファイルから何行も読んでおくのが一般的です) を使って、内部で最適化を図りつつ、任意のファイルの任意の行を取得するのを可能にします。 traceback モジュールは、整形されたトレースバックにソースコードを含めるためにこのモジュールを利用しています。

参考

最新バージョンの linecache module Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/linecache.py?view=markup]

linecache モジュールでは次の関数が定義されています:

linecache.getline(filename, lineno[, module_globals])

filename という名前のファイルから lineno 行目を取得します。この関数は決して例外を発生させません — エラーの際には '' を返します。 (行末の改行文字は、見つかった行に含まれます。)

filename という名前のファイルが見つからなかった場合、モジュールの、つまり、 sys.path でそのファイルを探します。 zipfileやその他のファイルシステムでないimport元に対応するためまず modules_globals の PEP 302 [http://www.python.org/dev/peps/pep-0302] __loader__ をチェックし、そのあと sys.path を探索します。

バージョン 2.5 で追加: パラメータ module_globals の追加.

linecache.clearcache()

キャッシュをクリアします。それまでに getline() を使って読み込んだファイルの行が必要でなくなったら、この関数を使ってください。

linecache.checkcache([filename])

キャッシュが有効かチェックします。キャッシュしたファイルにディスク上で変更があったかもしれなくて、更新が必要なときにこの関数を使ってください。もし filename がなければ、全てのキャッシュエントリをチェックします。

サンプル:

>>> import linecache
>>> linecache.getline('/etc/passwd', 4)
'sys:x:3:3:sys:/dev:/bin/sh\n'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.10. shutil — 高レベルなファイル操作

shutil モジュールはファイルやファイルの収集に関する多くの高レベルな操作方法を提供します。特にファイルのコピーや削除のための関数が用意されています。個別のファイルに対する操作については、 os モジュールを参照してください。

参考

Latest version of the shutil module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/shutil.py?view=markup]

警告

高レベルなファイルコピー関数(copy(), copy2())でも、全てのファイルのメタデータをコピーできるわけではありません。

POSIXプラットフォームでは、これはACLやファイルのオーナー、グループが失われることを意味しています。 Mac OSでは、リソースフォーク(resource fork)やその他のメタデータが利用されません。これは、リソースが失われ、ファイルタイプや生成者コード(creator code)が正しくなくなることを意味しています。 Windowsでは、ファイルオーナー、ACL、代替データストリームがコピーされません。

10.10.1. ディレクトリとファイルの操作

shutil.copyfileobj(fsrc, fdst[, length])

ファイル形式のオブジェクト fsrc の内容を fdst へコピーします。整数値 length はバッファサイズを表します。特に負の length はチャンク内のソースデータを繰り返し操作することなくコピーします。つまり標準ではデータは制御不能なメモリ消費を避けるためにチャンク内に読み込まれます。 fsrc オブジェクトのファイルポジションが0でない場合、現在のポジションから後ろの部分だけがコピーされることに注意してください。

shutil.copyfile(src, dst)

src で指定されたファイルの内容を dst で指定されたファイルへとコピーします。(メタデータはコピーされません) dst は完全なターゲットファイル名である必要があります。コピー先にディレクトリ名を使用したい場合は、 copy() を参照してください。もし、 src と dst が同じファイルであれば、 Error 例外が発生します。

コピー先は書き込み可能である必要があります。そうでなければ IOError を発生します。もし dst が存在したら、置き換えられます。キャラクタやブロックデバイス、パイプ等の特別なファイルはこの関数ではコピーできません。 src と dst にはパス名を文字列で与えられます。

shutil.copymode(src, dst)

src から dst へパーミッションをコピーします。ファイル内容や所有者、グループは影響を受けません。 src と dst には文字列としてパス名を与えられます。

shutil.copystat(src, dst)

src から dst へ、パーミッション、最終アクセス時間、最終更新時間、フラグをコピーします。ファイル内容や所有者、グループは影響を受けません。 src と dst には文字列としてパス名を与えられます。

shutil.copy(src, dst)

ファイル src をファイルまたはディレクトリ dist へコピーします。もし、 dst がディレクトリであればファイル名は src と同じものが指定されたディレクトリ内に作成（または上書き）されます。パーミッションはコピーされます。 src と dst には文字列としてパス名を与えられます。

shutil.copy2(src, dst)

copy() と類似していますが、メタデータも同様にコピーされます。実際のところ、この関数は copy() の後に copystat() しています。 Unix コマンドの cp -p と同様の働きをします。

shutil.ignore_patterns(*patterns)

このファクトリ関数は、 copytree() 関数の ignore 引数に渡すための呼び出し可能オブジェクトを作成します。 glob形式の patterns にマッチするファイルやディレクトリが無視されます。下の例を参照してください。

バージョン 2.6 で追加.

shutil.copytree(src, dst[, symlinks])

src を起点としたディレクトリツリーをコピーします。 dst で指定されたターゲットディレクトリは、既存のもので無い必要があります。存在しない親ディレクトリも含めて作成されます。パーミッションと時刻は copystat() 関数でコピーされます。個々のファイルは copy2() によってコピーされます。

symlinks が真であれば、元のディレクトリ内のシンボリックリンクはコピー先のディレクトリ内へシンボリックリンクとしてコピーされます。偽が与えられたり省略された場合は元のディレクトリ内のリンクの対象となっているファイルがコピー先のディレクトリ内へコピーされます。

ignore 引数を利用する場合、その呼び出し可能オブジェクトは、引数として、 copytree() が走査するディレクトリと、 os.listdir() が返すそのディレクトリの内容を受け取ります。 copytree() は再帰的に呼び出されるので、 ignore はコピーされる各ディレクトリ毎に呼び出されます。 ignore の戻り値は、ファイルやディレクトリに対するカレントディレクトリからの相対パスのシーケンスである必要があります。 (例えば、第二引数のサブセット) 返された名前は、無視され、コピーされません。 ignore_patterns() を使って、glob形式のパターンからこの引数のための呼び出し可能オブジェクトを作成することができます。

エラーが発生したときはエラー理由のリストを持った Error を起こします。

この関数は、究極の道具としてではなく、ソースコードが利用例になっていると捉えるべきでしょう。

バージョン 2.3 で変更: コピー中にエラーが発生した場合、メッセージを出力するのではなく Error を起こす。

バージョン 2.5 で変更: dst を作成する際に中間のディレクトリ作成が必要な場合、エラーを起こすのではなく作成する。ディレクトリのパーミッションと時刻を copystat() を利用してコピーする。

バージョン 2.6 で変更: 何がコピーされるかを制御するための ignore 引数

shutil.rmtree(path[, ignore_errors[, onerror]])

ディレクトリツリー全体を削除します。 path はディレクトリを指している必要があります。（ディレクトリに対するシンボリックリンクではいけません）もし ignore_errors が真であれば削除に失敗したことによるエラーは無視されます。偽が与えられたり省略された場合はこれらのエラーは onerror で与えられたハンドラを呼び出して処理され、onerror が省略された場合は例外を引き起こします。

onerror が与えられた場合、それは3つのパラメータ function, path および excinfo を受け入れて呼び出し可能のものでなくてはなりません。最初のパラメータ function は例外を引き起こした関数で os.listdir(), os.remove(), os.rmdir() のいずれかでしょう。 2番目のパラメータ path は function へ渡されたパス名です。 3番目のパラメータ excinfo は sys.exc_info() で返されるような例外情報になるでしょう。 onerror が引き起こす例外はキャッチできません。

バージョン 2.6 で変更: path を明示的にチェックして、シンボリックリンクだった場合は OSError を返すようになりました。

shutil.move(src, dst)

再帰的にファイルやディレクトリを別の場所へ移動します。

もし移動先が現在のファイルシステム上であれば単純に名前を変更します。そうでない場合は(copy2() で)コピーを行い、その後コピー元は削除されます。

バージョン 2.3 で追加.

exception shutil.Error

この例外は複数ファイルの操作を行っているときに生じる例外をまとめたものです。 copytree() に対しては例外の引数は3つのタプル(srcname, dstname, exception)からなるリストです。

バージョン 2.3 で追加.

10.10.1.1. copytree の例

以下は前述の copytree() 関数のドキュメント文字列を省略した実装例です。本モジュールで提供される他の関数の使い方を示しています。

def copytree(src, dst, symlinks=False, ignore=None):
    names = os.listdir(src)
    if ignore is not None:
        ignored_names = ignore(src, names)
    else:
        ignored_names = set()

    os.makedirs(dst)
    errors = []
    for name in names:
        if name in ignored_names:
            continue
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks, ignore)
            else:
                copy2(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error), why:
            errors.append((srcname, dstname, str(why)))
        # catch the Error from the recursive copytree so that we can
        # continue with other files
        except Error, err:
            errors.extend(err.args[0])
    try:
        copystat(src, dst)
    except WindowsError:
        # can't copy file access times on Windows
        pass
    except OSError, why:
        errors.extend((src, dst, str(why)))
    if errors:
        raise Error(errors)

ignore_patterns() ヘルパ関数を利用する、もう1つの例です。

from shutil import copytree, ignore_patterns

copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

この例では、 .pyc ファイルと、 tmp で始まる全てのファイルやディレクトリを除いて、全てをコピーします。

ignore 引数にロギングさせる別の例です。

from shutil import copytree
import logging

def _logpath(path, names):
    logging.info('Working in %s' % path)
    return []   # nothing will be ignored

copytree(source, destination, ignore=_logpath)

10.10.2. アーカイブの操作

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

アーカイブファイル (zip や tar など) を作成し、その名前を返します。

base_name は作成するファイルの名前で、パスを含み、フォーマット特有の拡張子はすべて除きます。 format はアーカイブフォーマットで、 “zip”, “tar”, “bztar” または “gztar” のいずれかです。

root_dir は、アーカイブのルートディレクトリとなるディレクトリです。すなわち、一般的には、アーカイブを作成する前に root_dir をカレントディレクトリにします。

base_dir は、アーカイブを開始するディレクトリです。すなわち、 base_dir は、アーカイブのすべてのファイルとディレクトリに共通する接頭辞になります。

root_dir と base_dir のどちらも、デフォルトはカレントディレクトリです。

owner と group は、tar アーカイブを作成するときに使われます。デフォルトでは、カレントのオーナとグループを使います。

バージョン 2.7 で追加.

shutil.get_archive_formats()

アーカイブ化をサポートしているフォーマットのリストを返します。返されるシーケンスのそれぞれの要素は、タプル (name, description) です。

デフォルトでは、 shutil はこれらのフォーマットを提供しています:

gztar: gzip された tar ファイル

bztar: bzip2 された tar ファイル

tar: 圧縮されていない tar ファイル

zip: ZIP ファイル

register_archive_format() を使って、新しいフォーマットを登録したり、既存のフォーマットに独自のアーカイバを提供したりできます。

バージョン 2.7 で追加.

shutil.register_archive_format(name, function[, extra_args[, description]])

フォーマット name のアーカイバを登録します。 function は、アーカイバを呼び出すのに使われる呼び出し可能オブジェクトです。

extra_args は、与えられるなら (name, value) のシーケンスで、アーカイバ呼び出し可能オブジェクトが使われるときの追加キーワード引数に使われます。

description は、アーカイバのリストを返す get_archive_formats() で使われます。デフォルトでは、空のリストです。

バージョン 2.7 で追加.

shutil.unregister_archive_format(name)

アーカイブフォーマット name を、サポートされているフォーマットのリストから取り除きます。

バージョン 2.7 で追加.

10.10.2.1. アーカイブ化の例

この例では、ユーザの .ssh ディレクトリにあるすべてのファイルを含む、 gzip された tar ファイルアーカイブを作成します:

>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'

結果のアーカイブは、以下のものを含みます:

$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff       0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff     609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff      65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff     668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff     609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff    1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff     397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff   37192 2010-02-06 18:23:10 ./known_hosts

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.11. dircache — キャッシュされたディレクトリ一覧の生成

バージョン 2.6 で撤廃: dircache モジュールは Python 3.0 で削除されました。

durcache モジュールはキャッシュされた情報を使ってディレクトリ一覧を読み出すための関数を定義しています。キャッシュはディレクトリの mtime に応じて無効化されます。さらに、一覧中のディレクトリにスラッシュ (‘/’) を追加することでディレクトリであると分かるようにするための関数も定義しています。

dircache モジュールは以下の関数を定義しています:

dircache.reset()

ディレクトリキャッシュをリセットします。

dircache.listdir(path)

os.listdir() によって得た path のディレクトリ一覧を返します。 path を変えない限り、以降の listdir() を呼び出してもディレクトリ構造を読み込みなおすことはしないので注意してください。

返されるリストは読み出し専用であると見なされるので注意してください (おそらく将来のバージョンではタプルを返すように変更されるはず ? です)。

dircache.opendir(path)

listdir() と同じです。以前のバージョンとの互換性のために定義されています。

dircache.annotate(head, list)

list を head の相対パスからなるリストとして、各パスがディレクトリを指す場合には '/' をパス名の後ろに追加したものに置き換えます。

>>> import dircache
>>> a = dircache.listdir('/')
>>> a = a[:] # Copy the return value so we can change 'a'
>>> a
['bin', 'boot', 'cdrom', 'dev', 'etc', 'floppy', 'home', 'initrd', 'lib', 'lost+
found', 'mnt', 'proc', 'root', 'sbin', 'tmp', 'usr', 'var', 'vmlinuz']
>>> dircache.annotate('/', a)
>>> a
['bin/', 'boot/', 'cdrom/', 'dev/', 'etc/', 'floppy/', 'home/', 'initrd/', 'lib/
', 'lost+found/', 'mnt/', 'proc/', 'root/', 'sbin/', 'tmp/', 'usr/', 'var/', 'vm
linuz']

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

10. ファイルとディレクトリへのアクセス »

10.12. macpath — Mac OS 9 のパス操作関数

このモジュールは os.path モジュールの Macintosh 9 (およびそれ以前) 用の実装です。これを使用すると、古い形式の Macintosh のパス名を Mac OS X (あるいはその他の任意のプラットフォーム) 上で扱うことができます。

次の関数がこのモジュールで利用できます。 normcase() 、 normpath() 、 isabs() 、 join() 、 split() 、 isdir() 、 isfile() 、 walk() 、 exists() 。 os.path で利用できる他の関数については、ダミーの関数として相当する物が利用できます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化

この章で解説されるモジュール群は Python データをディスクに永続的な形式で保存します。モジュール pickle とモジュール marshal は多くの Python データ型をバイト列に変換し、バイト列から再生成します。様々な DBM 関連モジュールはハッシュを基にした、文字列から他の文字列へのマップを保存するファイルフォーマット群をサポートします。モジュール bsddb はディスクベースの文字列から文字列へのマッピングを、ハッシュ、B-Tree、レコードを基にしたフォーマットで提供します。

この章で説明されるモジュールは:

11.1. pickle — Python オブジェクトの整列化

11.1.1. 他の Python モジュールとの関係

11.1.2. データストリームの形式

11.1.3. 使用法

11.1.4. 何を pickle 化したり unpickle 化できるのか?

11.1.5. pickle 化プロトコル

11.1.5.1. 通常のクラスインスタンスの pickle 化および unpickle 化

11.1.5.2. 拡張型の pickle 化および unpickle 化

11.1.5.3. 外部オブジェクトの pickle 化および unpickle 化

11.1.6. Unpickler をサブクラス化する

11.1.7. 例

11.2. cPickle — より高速な pickle

11.3. copy_reg — pickle サポート関数を登録する

11.4. shelve — Python オブジェクトの永続化

11.4.1. 制限事項

11.4.2. 使用例

11.5. marshal — 内部使用向けの Python オブジェクト整列化

11.6. anydbm — DBM 形式のデータベースへの汎用アクセスインタフェース

11.7. whichdb — どのDBMモジュールがデータベースを作ったかを推測する

11.8. dbm — UNIX dbmのシンプルなインタフェース

11.9. gdbm — GNU による dbm の再実装

11.10. dbhash — BSD データベースライブラリへの DBM 形式のインタフェース

11.10.1. データベースオブジェクト

11.11. bsddb — Berkeley DB ライブラリへのインタフェース

11.11.1. ハッシュ、BTree、およびレコードオブジェクト

11.12. dumbdbm — 可搬性のある DBM 実装

11.12.1. Dumbdbm オブジェクト

11.13. sqlite3 — SQLite データベースに対する DB-API 2.0 インタフェース

11.13.1. モジュールの関数と定数

11.13.2. Connection オブジェクト

11.13.3. カーソルオブジェクト

11.13.4. Row オブジェクト

11.13.5. SQLite と Python の型

11.13.5.1. 入門編

11.13.5.2. 追加された Python の型を SQLite データベースに格納するために適合関数を使う

11.13.5.2.1. オブジェクト自身で適合するようにする

11.13.5.2.2. 適合関数を登録する

11.13.5.3. SQLite の値を好きな Python 型に変換する

11.13.5.4. デフォルトの適合関数と変換関数

11.13.6. トランザクション制御

11.13.7. sqlite3 の効率的な使い方

11.13.7.1. ショートカットメソッドを使う

11.13.7.2. 位置ではなく名前でカラムにアクセスする

11.13.7.3. コネクションをコンテキストマネージャーとして利用する

11.13.8. 既知の問題

11.13.8.1. マルチスレッド

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.1. pickle — Python オブジェクトの整列化

pickle モジュールでは、Python オブジェクトデータ構造を直列化 (serialize) したり非直列化 (de-serialize)するための基礎的ですが強力なアルゴリズムを実装しています。 “Pickle 化 (Pickling)” は Python のオブジェクト階層をバイトストリームに変換する過程を指します。”非 Pickle 化 (unpickling)” はその逆の操作で、バイトストリームをオブジェクト階層に戻すように変換します。Pickle 化 (及び非 Pickle 化) は、別名 “直列化 (serialization)” や “整列化 (marshalling)” [1] 、 “平坦化 (flattening)” として知られていますが、ここでは混乱を避けるため、用語として “Pickle 化” および “非Pickle 化” を使います。

このドキュメントでは pickle モジュールおよび cPickle モジュールの両方について記述します。

警告

pickle モジュールはエラーや不正に生成されたデータに対するセキュリティを考慮していません。信頼できない、あるいは認証されていないソースから受信したデータを unpickle してはいけません。

11.1.1. 他の Python モジュールとの関係

pickle モジュールには cPickle と呼ばれる最適化のなされた親類モジュールがあります。名前が示すように、 cPickle は C で書かれており、このため pickle より 1000 倍くらいまで高速になる可能性があります。しかしながら cPickle では Pickler() および Unpickler() クラスのサブクラス化をサポートしていません。これは cPickle では、これらは関数であってクラスではないからです。ほとんどのアプリケーションではこの機能は不要であり、 cPickle の持つ高いパフォーマンスの恩恵を受けることができます。その他の点では、二つのモジュールにおけるインタフェースはほとんど同じです; このマニュアルでは共通のインタフェースを記述しており、必要に応じてモジュール間の相違について指摘します。以下の議論では、 pickle と cPickle の総称として “pickle” という用語を使うことにします。

これら二つのモジュールが生成するデータストリームは相互交換できることが保証されています。

Python には marshal と呼ばれるより原始的な直列化モジュールがありますが、一般的に Python オブジェクトを直列化する方法としては pickle を選ぶべきです。 marshal は基本的に .pyc ファイルをサポートするために存在しています。

pickle モジュールはいくつかの点で marshal と明確に異なります:

pickle モジュールでは、同じオブジェクトが再度直列化されることのないよう、すでに直列化されたオブジェクトについて追跡情報を保持します。 marshal はこれを行いません。

この機能は再帰的オブジェクトと共有オブジェクトの両方に重要な関わりをもっています。再帰的オブジェクトとは自分自身に対する参照を持っているオブジェクトです。再帰的オブジェクトは marshal で扱うことができず、実際、再帰的オブジェクトを marshal 化しようとすると Python インタプリタをクラッシュさせてしまいます。共有オブジェクトは、直列化しようとするオブジェクト階層の異なる複数の場所で同じオブジェクトに対する参照が存在する場合に生じます。共有オブジェクトを共有のままにしておくことは、変更可能なオブジェクトの場合には非常に重要です。

marshal はユーザ定義クラスやそのインスタンスを直列化するために使うことができません。 pickle はクラスインスタンスを透過的に保存したり復元したりすることができますが、クラス定義をインポートすることが可能で、かつオブジェクトが保存された際と同じモジュールで定義されていなければなりません。

marshal の直列化フォーマットは Python の異なるバージョンで可搬性があることを保証していません。 marshal の本来の仕事は .pyc ファイルのサポートなので、Python を実装する人々には、必要に応じて直列化フォーマットを以前のバージョンと互換性のないものに変更する権限が残されています。 pickle 直列化フォーマットには、全ての Python リリース間で以前のバージョンとの互換性が保証されています。

直列化は永続化 (persisitence) よりも原始的な概念です; pickle はファイルオブジェクトを読み書きしますが、永続化されたオブジェクトの名前付け問題や、(より複雑な) オブジェクトに対する競合アクセスの問題を扱いません。 pickle モジュールは複雑なオブジェクトをバイトストリームに変換することができ、バイトストリームを変換前と同じ内部構造をオブジェクトに変換することができます。このバイトストリームの最も明白な用途はファイルへの書き込みですが、その他にもネットワークを介して送信したり、データベースに記録したりすることができます。モジュール shelve はオブジェクトを DBM 形式のデータベースファイル上で pickle 化したり unpickle 化したりするための単純なインタフェースを提供しています。

11.1.2. データストリームの形式

pickle が使うデータ形式は Python 特有です。そうすることで、XDR のような外部の標準が持つ制限 (例えば XDR ではポインタの共有を表現できません) を課せられることがないという利点があります; しかしこれは Python で書かれていないプログラムが pickle 化された Python オブジェクトを再構築できない可能性があることを意味します。

標準では、 pickle データ形式では印字可能な ASCII 表現を使います。これはバイナリ表現よりも少しかさばるデータになります。印字可能な ASCII の利用 (とその他の pickle 表現形式が持つ特徴) の大きな利点は、デバッグやリカバリを目的とした場合に、 pickle 化されたファイルを標準的なテキストエディタで読めるということです。

現在、pickle化に使われるプロトコルは、以下の 3 種類です。

バージョン 0 のプロトコルは、最初の ASCII プロトコルで、以前のバージョンのPython と後方互換です。

バージョン 1 のプロトコルは、古いバイナリ形式で、以前のバージョンの Python と後方互換です。

バージョン 2 のプロトコルは、Python 2.3 で導入されました。 new-style class を、より効率よく piclke 化します。

詳細は PEP 307 [http://www.python.org/dev/peps/pep-0307] を参照してください。

protocol を指定しない場合、プロトコル 0 が使われます。 protocol に負値か HIGHEST_PROTOCOL を指定すると、有効なプロトコルの内、もっとも高いバージョンのものが使われます。

バージョン 2.3 で変更: protocol パラメータが導入されました。

protocol version >= 1 を指定することで、少しだけ効率の高いバイナリ形式を選ぶことができます。

11.1.3. 使用法

オブジェクト階層を直列化するには、まず pickler を生成し、続いてpickler の dump() メソッドを呼び出します。データストリームから非直列化するには、まず unpickler を生成し、続いて unpicklerの load() メソッドを呼び出します。 pickle モジュールでは以下の定数を提供しています:

pickle.HIGHEST_PROTOCOL

有効なプロトコルのうち、最も大きいバージョン。この値は、 protocol として渡せます。

バージョン 2.3 で追加.

ノート

protocols >= 1 で作られた pickle ファイルは、常にバイナリモードでオープンするようにしてください。古い ASCII ベースの pickle プロトコル 0 では、矛盾しない限りにおいてテキストモードとバイナリモードのいずれも利用することができます。

プロトコル 0 で書かれたバイナリの pickle ファイルは、行ターミネータとして単独の改行(LF)を含んでいて、ですのでこの形式をサポートしない、 Notepad や他のエディタで見たときに「おかしく」見えるかもしれません。

この pickle 化の手続きを便利にするために、 pickle モジュールでは以下の関数を提供しています:

pickle.dump(obj, file[, protocol])

すでに開かれているファイルオブジェクト file に、 obj を pickle 化したものを表現する文字列を書き込みます。 Pickler(file, protocol).dump(obj) と同じです。

protocol を指定しない場合、プロトコル 0 が使われます。 protocol

に負値か HIGHEST_PROTOCOL を指定すると、有効なプロトコルの内、もっとも高いバージョンのものが使われます。

バージョン 2.3 で変更: protocol パラメータが導入されました。

file は、単一の文字列引数を受理する write() メソッドを持た

なければなりません。従って、 file としては、書き込みのために開かれたファイルオブジェクト、 StringIO オブジェクト、その他前述のインタフェースに適合する他のカスタムオブジェクトをとることができます。

pickle.load(file)

すでに開かれているファイルオブジェクト file から文字列を読み出し、読み出された文字列を pickle 化されたデータ列として解釈して、もとのオブジェクト階層を再構築して返します。 Unpickler(file).load() と同じです。

file は、整数引数をとる read() メソッドと、引数の必要ない readline() メソッドを持たなければなりません。これらのメソッドは両方とも文字列を返さなければなりません。従って、 file としては、読み出しのために開かれたファイルオブジェクト、 StringIO オブジェクト、その他前述のインタフェースに適合する他のカスタムオブジェクトをとることができます。

この関数はデータ列の書き込まれているモードがバイナリかそうでないかを自動的に判断します。

pickle.dumps(obj[, protocol])

obj の pickle 化された表現を、ファイルに書き込む代わりに文字列で返します。

protocol を指定しない場合、プロトコル 0 が使われます。 protocol に負値か HIGHEST_PROTOCOL を指定すると、有効なプロトコルの内、もっとも高いバージョンのものが使われます。

バージョン 2.3 で変更: protocol パラメータが追加されました。

pickle.loads(string)

pickle 化されたオブジェクト階層を文字列から読み出します。文字列中で pickle 化されたオブジェクト表現よりも後に続く文字列は無視されます。

pickle モジュールでは、以下の 3 つの例外も定義しています:

exception pickle.PickleError

下で定義されている他の例外で共通の基底クラスです。 Exception を継承しています。

exception pickle.PicklingError

この例外は unpickle 不可能なオブジェクトが dump() メソッドに渡された場合に送出されます。

exception pickle.UnpicklingError

この例外は、オブジェクトを unpickle 化する際に問題が発生した場合に送出されます。 unpickle 化中には AttributeError 、 EOFError 、 ImportError 、および IndexError といった他の例外 (これだけとは限りません) も発生する可能性があるので注意してください。

pickle モジュールでは、2 つの呼び出し可能オブジェクト [2] として、 Pickler および Unpickler を提供しています:

class pickle.Pickler(file[, protocol])

pickle 化されたオブジェクトのデータ列を書き込むためのファイル類似のオブジェクトを引数にとります。

protocol を指定しない場合、プロトコル 0 が使われます。 protocol に負値か HIGHEST_PROTOCOL を指定すると、有効なプロトコルの内、もっとも高いバージョンのものが使われます。

バージョン 2.3 で変更: protocol パラメータが導入されました。

file は単一の文字列引数を受理する write() メソッドを持たなければなりません。従って、 file としては、書き込みのために開かれたファイルオブジェクト、 StringIO オブジェクト、その他前述のインタフェースに適合する他のカスタムオブジェクトをとることができます。

Pickler オブジェクトでは、一つ (または二つ) の public なメソッドを定義しています:

dump(obj)

コンストラクタで与えられた、すでに開かれているファイルオブジェクトに obj の pickle 化された表現を書き込みます。コンストラクタに渡された protocol 引数の値に応じて、バイナリおよびASCII 形式が使われます。

clear_memo()

picller の “メモ” を消去します。メモとは、共有オブジェクトまたは再帰的なオブジェクトが値ではなく参照で記憶されるようにするために、 pickler がこれまでどのオブジェクトに遭遇してきたかを記憶するデータ構造です。このメソッドは pickler を再利用する際に便利です。

ノート

Python 2.3 以前では、 clear_memo() は cPickle で生成された pickler でのみ利用可能でした。 pickle モジュールでは、pickler は memo と呼ばれる Python 辞書型のインスタンス変数を持ちます。従って、 pickler モジュールにおける pickler のメモを消去は、以下のようにしてできます:

mypickler.memo.clear()

以前のバージョンの Python での動作をサポートする必要のないコードでは、単に clear_memo() を使ってください。

同じ Pickler のインスタンスに対し、 dump() メソッドを複数回呼び出すことは可能です。この呼び出しは、対応する Unpickler インスタンスで同じ回数だけ load() を呼び出す操作に対応します。同じオブジェクトが dump() を複数回呼び出して pickle 化された場合、 load() は全て同じオブジェクトに対して参照を行います [3] 。

Unpickler オブジェクトは以下のように定義されています:

class pickle.Unpickler(file)

pickle データ列を読み出すためのファイル類似のオブジェクトを引数に取ります。このクラスはデータ列がバイナリモードかどうかを自動的に判別します。従って、 Pickler のファクトリメソッドのようなフラグを必要としません。

file は、整数引数を取る read() メソッド、および引数を持たない readline() メソッドの、 2 つのメソッドを持ちます。両方のメソッドとも文字列を返します。従って、 file としては、読み出しのために開かれたファイルオブジェクト、 StringIO オブジェクト、その他前述のインタフェースに適合する他のカスタムオブジェクトをとることができます。

Unpickler オブジェクトは 1 つ (または 2 つ) の public なメソッドを持っています:

load()

コンストラクタで渡されたファイルオブジェクトからオブジェクトの pickle 化表現を読み出し、中に収められている再構築されたオブジェクト階層を返します。

このメソッドは自動的にデータストリームがバイナリモードで書き出されているかどうかを判別します。

noload()

load() に似ていますが、実際には何もオブジェクトを生成しないという点が違います。この関数は第一に pickle 化データ列中で参照されている、”永続化 id” と呼ばれている値を検索する上で便利です。詳細は以下の pickle 化プロトコル を参照してください。

注意: noload() メソッドは現在 cPickle モジュールで生成された Unpickler オブジェクトのみで利用可能です。 pickle モジュールの Unpickler には、 noload() メソッドがありません。

11.1.4. 何を pickle 化したり unpickle 化できるのか?

以下の型は pickle 化できます:

None 、 True 、および False

整数、長整数、浮動小数点数、複素数

通常文字列および Unicode 文字列

pickle 化可能なオブジェクトからなるタプル、リスト、集合および辞書

モジュールのトップレベルで定義されている関数

モジュールのトップレベルで定義されている組込み関数

モジュールのトップレベルで定義されているクラス

__dict__ または __setstate__() を pickle 化できる上記クラスのインスタンス (詳細は pickle 化プロトコル 節を参照してください)

pickle 化できないオブジェクトを pickle 化しようとすると、 PicklingError 例外が送出されます; この例外が起きた場合、背後のファイルには未知の長さのバイト列が書き込まれてしまいます。極端に再帰的なデータ構造を pickle 化しようとした場合には再帰の深さ制限を越えてしまうかもしれず、この場合には RuntimeError が送出されます。この制限は、 sys.setrecursionlimit() で慎重に上げていくことは可能です。

(組み込みおよびユーザ定義の) 関数は、値ではなく “完全記述された” 参照名として pickle 化されるので注意してください。これは、関数の定義されているモジュールの名前と一緒と併せ、関数名だけが pickle 化されることを意味します。関数のコードや関数の属性は何も pickle化されません。従って、定義しているモジュールは unpickle 化環境で import 可能でなければならず、そのモジュールには指定されたオブジェクトが含まれていなければなりません。そうでない場合、例外が送出されます [4] 。

クラスも同様に名前参照で pickle 化されるので、unpickle 化環境には同じ制限が課せられます。クラス中のコードやデータは何も pickle 化されないので、以下の例ではクラス属性 attr が unpickle 化環境で復元されないことに注意してください

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)

pickle 化可能な関数やクラスがモジュールのトップレベルで定義されていなければならないのはこれらの制限のためです。

同様に、クラスのインスタンスが pickle 化された際、そのクラスのコードおよびデータはオブジェクトと一緒に pickle 化されることはありません。インスタンスのデータのみが pickle 化されます。この仕様は、クラス内のバグを修正したりメソッドを追加した後でも、そのクラスの以前のバージョンで作られたオブジェクトを読み出せるように意図的に行われています。あるクラスの多くのバージョンで使われるような長命なオブジェクトを作ろうと計画しているなら、そのクラスの __setstate__() メソッドによって適切な変換が行われるようにオブジェクトのバージョン番号を入れておくとよいかもしれません。

11.1.5. pickle 化プロトコル

この節では pickler/unpickler と直列化対象のオブジェクトとの間のインタフェースを定義する “pickle 化プロトコル”について記述します。このプロトコルは自分のオブジェクトがどのように直列化されたり非直列化されたりするかを定義し、カスタマイズし、制御するための標準的な方法を提供します。この節での記述は、unpickle 化環境を不信な pickle 化データに対して安全にするために使う特殊なカスタマイズ化についてはカバーしていません; 詳細は Unpickler をサブクラス化する を参照してください。

11.1.5.1. 通常のクラスインスタンスの pickle 化および unpickle 化

object.__getinitargs__()

pickle 化されたクラスインスタンスが unpickle 化されたとき、 __init__() メソッドは通常呼び出され ません 。 unpickle 化の際に __init__() が呼び出される方が望ましい場合、旧スタイルクラスではメソッド __getinitargs__() を定義することができます。このメソッドはクラスコンストラクタ (例えば __init__()) に渡されるべき タプルを 返さなければなりません。 __getinitargs__() メソッドは pickle 時に呼び出されます; この関数が返すタプルはインスタンスの pickle 化データに組み込まれます。

object.__getnewargs__()

新スタイルクラスでは、プロトコル 2 で呼び出される __getnewargs__() を定義する事ができます。インスタンス生成時に内部的な不変条件が成立する必要があったり、（タプルや文字列のように）型の __new__() メソッドに指定する引数によってメモリの割り当てを変更する必要がある場合には __getnewargs__() を定義してください。新スタイルクラス C のインスタンスは、次のように生成されます。:

obj = C.__new__(C, \*args)

ここで args は元のオブジェクトの __getnewargs__() メソッドを呼び出した時の戻り値となります。 __getnewargs__() を定義していない場合、 args は空のタプルとなります。

object.__getstate__()

クラスは、インスタンスの pickle 化方法にさらに影響を与えることができます; クラスが __getstate__() メソッドを定義している場合、このメソッドが呼び出され、返された状態値はインスタンスの内容として、インスタンスの辞書の代わりに pickle 化されます。 __getstate__() メソッドが定義されていない場合、インスタンスの __dict__ の内容が pickle 化されます。

object.__setstate__(state)

unpickle 化では、クラスが __setstate__() も定義していた場合、 unpickle 化された状態値とともに呼び出されます。 [5] __setstate__() メソッドが定義されていない場合、pickle 化された状態は辞書型でなければならず、その要素は新たなインスタンスの辞書に代入されます。クラスが __getstate__() と __setstate__() の両方を定義している場合、状態値オブジェクトは辞書である必要はなく、これらのメソッドは期待通りの動作を行います。 [6]

ノート

新しいスタイルのクラスにおいて __getstate__() が負値を返す場合、 __setstate__() メソッドは呼ばれません。

ノート

unpickleするとき、 __getattr__(), __getattribute__(), __setattr__() といったメソッドがインスタンスに対して呼ばれます。これらのメソッドが何か内部の不変条件に依存しているのであれば、その型は __getinitargs__() か __getnewargs__() のどちらかを実装してその不変条件を満たせるようにするべきです。それ以外の場合、 __new__() も __init__() も呼ばれません。

11.1.5.2. 拡張型の pickle 化および unpickle 化

object.__reduce__()

Pickler が全く未知の型の — 拡張型のような — オブジェクトに遭遇した場合、pickle 化方法のヒントとして 2 個所を探します。第一は __reduce__() メソッドを実装しているかどうかです。もし実装されていれば、pickle 化時に __reduce__() メソッドが引数なしで呼び出されます。メソッドはこの呼び出しに対して文字列またはタプルのどちらかを返さねばなりません。

文字列を返す場合、その文字列は通常通りに pickle 化されるグローバル変数の名前を指しています。 __reduce__() の返す文字列は、モジュールにからみてオブジェクトのローカルな名前でなければなりません; pickle モジュールはモジュールの名前空間を検索して、オブジェクトの属するモジュールを決定します。

タプルを返す場合、タプルの要素数は 2 から 5 でなければなりません。オプションの要素は省略したり None を指定したりできます。各要素の意味づけは以下の通りです:

オブジェクトの初期バージョンを生成するために呼び出される呼び出し可能オブジェクトです。この呼び出し可能オブジェクトへの引数はタプルの次の要素で与えられます。それ以降の要素では pickle 化されたデータを完全に再構築するために使われる付加的な状態情報が与えられます。

逆 pickle 化の環境下では、このオブジェクトはクラスか、 “安全なコンストラクタ (safe constructor, 下記参照)” として登録されていたり属性 __safe_for_unpickling__ の値が真であるような呼び出し可能オブジェクトでなければなりません。そうでない場合、逆 pickle 化を行う環境で UnpicklingError が送出されます。通常通り、 callable は名前だけで pickle 化されるので注意してください。

呼び出し可能なオブジェクトのための引数からなるタプル

バージョン 2.5 で変更: 以前は、この引数には None もあり得ました。

オプションとして、 通常のクラスインスタンスの pickle 化および unpickle 化 節で記述されているようにオブジェクトの __setstate__() メソッドに渡される、オブジェクトの状態。オブジェクトが __setstate__() メソッドを持たない場合、上記のように、この値は辞書でなくてはならず、オブジェクトの __dict__ に追加されます。

オプションとして、リスト中の連続する要素を返すイテレータ (シーケンスではありません)。このリストの要素は pickle 化され、 obj.append(item) または obj.extend(list_of_items) のいずれかを使って追加されます。主にリストのサブクラスで用いられていますが、他のクラスでも、適切なシグネチャの append() や extend() を備えている限り利用できます。 (append() と extend() のいずれを使うかは、どのバージョンの pickle プロトコルを使っているか、そして追加する要素の数で決まります。従って両方のメソッドをサポートしていなければなりません。)

オプションとして、辞書中の連続する要素を返すイテレータ (シーケンスではありません)。このリストの要素は (key, value) という形式でなければなりません。要素は pickle 化され、 obj[key] = value を使ってオブジェクトに格納されます。主に辞書のサブクラスで用いられていますが、他のクラスでも、 __setitem__() を備えている限り利用できます。

object.__reduce_ex__(protocol)

__reduce__() を実装する場合、プロトコルのバージョンを知っておくと便利なことがあります。これは __reduce__() の代わりに __reduce_ex__() を使って実現できます。 __reduce_ex__() が定義されている場合、 __reduce__() よりも優先して呼び出されます (以前のバージョンとの互換性のために __reduce__() を残しておいてもかまいません)。 __reduce_ex__() はプロトコルのバージョンを表す整数の引数を一つ伴って呼び出されます。

object クラスでは __reduce__() と __reduce_ex__() の両方を定義しています。とはいえ、サブクラスで __reduce__() をオーバライドしており、 __reduce_ex__() をオーバライドしていない場合には、 __reduce_ex__() の実装がそれを検出して __reduce__() を呼び出すようになっています。

pickle 化するオブジェクト上で __reduce__() メソッドを実装する代わりに、 copy_reg モジュールを使って呼び出し可能オブジェクトを登録する方法もあります。このモジュールはプログラムに “縮小化関数 (reduction function)” とユーザ定義型のためのコンストラクタを登録する方法を提供します。縮小化関数は、単一の引数として pickle 化するオブジェクトをとることを除き、上で述べた __reduce__() メソッドと同じ意味とインタフェースを持ちます。

登録されたコンストラクタは上で述べたような unpickle 化については “安全なコンストラクタ” であると考えられます。

11.1.5.3. 外部オブジェクトの pickle 化および unpickle 化

オブジェクトの永続化を便利にするために、 pickle は pickle 化されたデータ列上にないオブジェクトに対して参照を行うという概念をサポートしています。これらのオブジェクトは “永続化 id (persistent id)” で参照されており、この id は単に印字可能なASCII 文字からなる任意の文字列です。これらの名前の解決方法は pickle モジュールでは定義されていません;

オブジェクトはこの名前解決を pickler および unpickler 上のユーザ定義関数にゆだねます [7] 。外部永続化 id の解決を定義するには、pickler オブジェクトの persistent_id 属性と、 unpickler オブジェクトの persistent_load 属性を設定する必要があります。

外部永続化 id を持つオブジェクトを pickle 化するには、pickler は自作の persistent_id() メソッドを持たなければなりません。このメソッドは一つの引数をとり、 None とオブジェクトの永続化 id のうちどちらかを返さなければなりません。 None が返された場合、 pickler は単にオブジェクトを通常のように pickle 化するだけです。永続化 id 文字列が返された場合、 piclkler はその文字列に対して、、unpickler がこの文字列を永続化 id として認識できるように、マーカと共にpickle 化します。

外部オブジェクトを unpickle 化するには、unpickler は自作の persistent_load() 関数を持たなければなりません。この関数は永続化 id 文字列を引数にとり、参照されているオブジェクトを返します。

多分 より理解できるようになるようなちょっとした例を以下に示します:

import pickle
from cStringIO import StringIO

src = StringIO()
p = pickle.Pickler(src)

def persistent_id(obj):
    if hasattr(obj, 'x'):
        return 'the value %d' % obj.x
    else:
        return None

p.persistent_id = persistent_id

class Integer:
    def __init__(self, x):
        self.x = x
    def __str__(self):
        return 'My name is integer %d' % self.x

i = Integer(7)
print i
p.dump(i)

datastream = src.getvalue()
print repr(datastream)
dst = StringIO(datastream)

up = pickle.Unpickler(dst)

class FancyInteger(Integer):
    def __str__(self):
        return 'I am the integer %d' % self.x

def persistent_load(persid):
    if persid.startswith('the value '):
        value = int(persid.split()[2])
        return FancyInteger(value)
    else:
        raise pickle.UnpicklingError, 'Invalid persistent id'

up.persistent_load = persistent_load

j = up.load()
print j

cPickle モジュール内では、 unpickler の persistent_load 属性は Pythonリスト型として設定することができます。この場合、 unpickler が永続化 id に遭遇しても、永続化 id 文字列は単にリストに追加されるだけです。この仕様は、pickle データ中の全てのオブジェクトを実際にインスタンス化しなくても、 pickle データ列中でオブジェクトに対する参照を “嗅ぎ回る” ことができるようにするために存在しています [8] 。リストに persistent_load を設定するやり方は、よく Unpickler クラスの noload() メソッドと共に使われます。

11.1.6. Unpickler をサブクラス化する

デフォルトでは、逆 pickle 化は pickle 化されたデータ中に見つかったクラスを import することになります。自前の unpickler をカスタマイズすることで、何が unpickle 化されて、どのメソッドが呼び出されるかを厳密に制御することはできます。しかし不運なことに、厳密になにを行うべきかは pickle と cPickle のどちらを使うかで異なります [9] 。

pickle モジュールでは、 Unpickler からサブクラスを派生し、 load_global() メソッドを上書きする必要があります。 load_global() は pickle データ列から最初の 2 行を読まなければならず、ここで最初の行はそのクラスを含むモジュールの名前、2 行目はそのインスタンスのクラス名になるはずです。次にこのメソッドは、例えばモジュールをインポートして属性を掘り起こすなどしてクラスを探し、発見されたものを unpickler のスタックに置きます。その後、このクラスは空のクラスの __class__ 属性に代入する方法で、クラスの __init__() を使わずにインスタンスを魔法のように生成します。あなたの作業は (もしその作業を受け入れるなら)、unpickler のスタックの上に push された load_global() を、unpickle しても安全だと考えられる何らかのクラスの既知の安全なバージョンにすることです。あるいは全てのインスタンスに対して unpickling を許可したくないならエラーを送出してください。このからくりがハックのように思えるなら、あなたは間違っていません。このからくりを動かすには、ソースコードを参照してください。

cPickle では事情は多少すっきりしていますが、十分というわけではありません。何を unpickle 化するかを制御するには、 unpickler の find_global 属性を関数か None に設定します。属性が None の場合、インスタンスを unpickle しようとする試みは全て UnpicklingError を送出します。属性が関数の場合、この関数はモジュール名またはクラス名を受理し、対応するクラスオブジェクトを返さなくてはなりません。このクラスが行わなくてはならないのは、クラスの探索、必要な import のやり直しです。そしてそのクラスのインスタンスが unpickle 化されるのを防ぐためにエラーを送出することもできます。

以上の話から言えることは、アプリケーションが unpickle 化する文字列の発信元については非常に高い注意をはらわなくてはならないということです。

11.1.7. 例

いちばん単純には、 dump() と load() を使用してください。自己参照リストが正しく pickle 化およびリストアされることに注目してください。

import pickle

data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()

以下の例は pickle 化された結果のデータを読み込みます。 pickle を含むデータを読み込む場合、ファイルはバイナリモードでオープンしなければいけません。これは ASCII 形式とバイナリ形式のどちらが使われているかは分からないからです。

import pprint, pickle

pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()

より大きな例で、クラスを pickle 化する挙動を変更するやり方を示します。 TextReader クラスはテキストファイルを開き、 readline() メソッドが呼ばれるたびに行番号と行の内容を返します。 TextReader インスタンスが pickle 化された場合、ファイルオブジェクト 以外の 全ての属性が保存されます。インスタンスが unpickle 化された際、ファイルは再度開かれ、以前のファイル位置から読み出しを再開します。上記の動作を実装するために、 __setstat__() および __getstate__() メソッドが使われています。

#!/usr/local/bin/python

class TextReader:
    """Print and number lines in a text file."""
    def __init__(self, file):
        self.file = file
        self.fh = open(file)
        self.lineno = 0

    def readline(self):
        self.lineno = self.lineno + 1
        line = self.fh.readline()
        if not line:
            return None
        if line.endswith("\n"):
            line = line[:-1]
        return "%d: %s" % (self.lineno, line)

    def __getstate__(self):
        odict = self.__dict__.copy() # copy the dict since we change it
        del odict['fh']              # remove filehandle entry
        return odict

    def __setstate__(self, dict):
        fh = open(dict['file'])      # reopen file
        count = dict['lineno']       # read from file...
        while count:                 # until line count is restored
            fh.readline()
            count = count - 1
        self.__dict__.update(dict)   # update attributes
        self.fh = fh                 # save the file object

使用例は以下のようになるでしょう:

>>> import TextReader
>>> obj = TextReader.TextReader("TextReader.py")
>>> obj.readline()
'1: #!/usr/local/bin/python'
>>> obj.readline()
'2: '
>>> obj.readline()
'3: class TextReader:'
>>> import pickle
>>> pickle.dump(obj, open('save.p', 'wb'))

pickle が Python プロセス間でうまく働くことを見たいなら、先に進む前に他の Python セッションを開始してください。以下の振る舞いは同じプロセスでも新たなプロセスでも起こります。

>>> import pickle
>>> reader = pickle.load(open('save.p', 'rb'))
>>> reader.readline()
'4:     """Print and number lines in a text file."""'

参考

Module copy_reg

拡張型を登録するための Pickle インタフェース構成機構。

Module shelve

オブジェクトのインデクス付きデータベース; pickle を使います。

Module copy

オブジェクトの浅いコピーおよび深いコピー。

Module marshal

高いパフォーマンスを持つ組み込み型整列化機構。

11.2. cPickle — より高速な pickle

cPickle モジュールは Python オブジェクトの直列化および非直列化をサポートし、 pickle モジュールとほとんど同じインタフェースと機能を提供します。いくつか相違点がありますが、最も重要な違いはパフォーマンスとサブクラス化が可能かどうかです。

第一に、 cPickle は C で実装されているため、 pickle よりも最大で 1000 倍高速です。第二に、 cPickle モジュール内では、呼び出し可能オブジェクト Pickler() および Unpickler() は関数で、クラスではありません。つまり、pickle 化や unpickle 化を行うカスタムのサブクラスを派生することができないということです。多くのアプリケーションではこの機能は不要なので、 cPickle モジュールによる大きなパフォーマンス向上の恩恵を受けられるはずです。 pickle と cPickle で作られた pickle データ列は同じなので、既存の pickle データに対して pickle と cPickle を互換に使用することができます。 [10]

cPickle と pickle の API 間には他にも些細な相違がありますが、ほとんどのアプリケーションで互換性があります。より詳細なドキュメンテーションは pickle のドキュメントにあり、そこでドキュメント化されている相違点について挙げています。

注記

[1]
marshal モジュールと間違えないように注意してください。

[2]
pickle では、これらの呼び出し可能オブジェクトはクラスであり、サブクラス化してその動作をカスタマイズすることができます。しかし、 cPickle モジュールでは、これらの呼び出し可能オブジェクトはファクトリ関数であり、サブクラス化することができません。サブクラスを作成する共通の理由の一つは、どのオブジェクトを実際に unpickle するかを制御することです。詳細については Unpickler をサブクラス化するを参照してください。

[3]
警告: これは、複数のオブジェクトを pickle 化する際に、オブジェクトやそれらの一部に対する変更を妨げないようにするための仕様です。あるオブジェクトに変更を加えて、その後同じ Pickler を使って再度 pickle 化しようとしても、そのオブジェクトは pickle 化しなおされません — そのオブジェクトに対する参照が pickle 化され、 Unpickler は変更された値ではなく、元の値を返します。これには 2 つの問題点 : (1) 変更の検出、そして (2) 最小限の変更を整列化すること、があります。ガーベジコレクションもまた問題になります。

[4]
送出される例外は ImportError や AttributeError になるはずですが、他の例外も起こりえます。

[5]
これらのメソッドはクラスインスタンスのコピーを実装する際にも用いられます。

[6]
このプロトコルはまた、 copy で定義されている浅いコピーや深いコピー操作でも用いられます。

[7]
ユーザ定義関数に関連付けを行うための実際のメカニズムは、 pickle および cPickle では少し異なります。 pickle のユーザは、サブクラス化を行い、 persistend_id() および persistent_load() メソッドを上書きすることで同じ効果を得ることができます。

[8]
Guide と Jim が居間に座り込んでピクルス (pickles) を嗅いでいる光景を想像してください。

[9]
注意してください: ここで記述されている機構は内部の属性とメソッドを使っており、これらはPython の将来のバージョンで変更される対象になっています。われわれは将来、この挙動を制御するための、 pickle および cPickle の両方で動作する、共通のインタフェースを提供するつもりです。

[10]
pickle データ形式は実際には小規模なスタック指向のプログラム言語であり、またあるオブジェクトをエンコードする際に多少の自由度があるため、二つのモジュールが同じ入力オブジェクトに対して異なるデータ列を生成することもあります。しかし、常に互いに他のデータ列を読み出せることが保証されています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.3. copy_reg — pickle サポート関数を登録する

ノート

copy_reg モジュールはPython 3.0で copyreg に変更されました。 2to3 ツールが自動的にソースコードの import を変換します。

copy_reg モジュールは pickle と cPickle モジュールに対するサポートを提供します。その上、 copy モジュールは将来これをつかう可能性が高いです。クラスでないオブジェクトコンストラクタについての設定情報を提供します。このようなコンストラクタはファクトリ関数か、またはクラスインスタンスでしょう。

copy_reg.constructor(object)

object を有効なコンストラクタであると宣言します。 object が呼び出し可能でなければ(そして、それゆえコンストラクタとして有効でないならば)、 TypeError を発生します。

copy_reg.pickle(type, function[, constructor])

function が型 type のオブジェクトに対する”リダクション”関数として使うことを宣言します。 type は”標準的な”クラスオブジェクトであってはいけません。(標準的なクラスは異なった扱われ方をします。詳細は、 pickle モジュールのドキュメンテーションを参照してください。) function は文字列または二ないし三つの要素を含むタプルです。

オプションの constructor パラメータが与えられた場合は、pickle化時に function が返した引数のタプルとともによびだされたときにオブジェクトを再構築するために使われ得る呼び出し可能オブジェクトです。 object がクラスであるか、または constructor が呼び出し可能でない場合に、 TypeError を発生します。

function と constructor の求められるインターフェイスについての詳細は、 pickle モジュールを参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.4. shelve — Python オブジェクトの永続化

“シェルフ (shelf, 棚)” は辞書に似た永続性を持つオブジェクトです。 “dbm” データベースとの違いは、シェルフの値 (キーではありません！) は実質上どんな Python オブジェクトにも — pickle モジュールが扱えるなら何でも — できるということです。これにはほとんどのクラスインスタンス、再帰的なデータ型、沢山の共有されたサブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。

参考

最新バージョンの shelve モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/shelve.py?view=markup]

shelve.open(filename[, flag='c'[, protocol=None[, writeback=False]]])

永続的な辞書を開きます。指定された filename は、根底にあるデータベースの基本ファイル名となります。副作用として、 filename には拡張子がつけられる場合があり、ひとつ以上のファイルが生成される可能性もあります。デフォルトでは、根底にあるデータベースファイルは読み書き可能なように開かれます。オプションの flag パラメタは anydbm.open() における flag パラメタと同様に解釈されます。

デフォルトでは、値を整列化する際にはバージョン 0 の pickle 化が用いられます。pickle 化プロトコルのバージョンは protocol パラメタで指定することができます。

バージョン 2.3 で変更: protocol パラメタが追加されました。

Python の意味論から、シェルフには永続的な辞書の可変エントリに対する変更を知る術がありません。デフォルトでは、変更されたオブジェクトはシェルフに代入されたときだけ 書き込まれます (使用例 参照)。オプションの writeback パラメタが True に設定されていれば、アクセスされたすべてのエントリはメモリ上にキャッシュされ、 sync() および close() を呼び出した際に書き戻されます。この機能は永続的な辞書上の可変の要素に対する変更を容易にしますが、多数のエントリがアクセスされた場合、膨大な量のメモリがキャッシュのために消費され、アクセスされた全てのエントリを書き戻す (アクセスされたエントリが可変であるか、あるいは実際に変更されたかを決定する方法は存在しないのです) ために、ファイルを閉じる操作を非常に低速にしてしまいます。

警告

Because the shelve module is backed by pickle, it is insecure to load a shelf from an untrusted source. Like with pickle, loading a shelf can execute arbitrary code.

shelve モジュールは裏で pickle を使っているので、信頼できないソースから shelf を読み込むのは危険です。 pickle と同じく、 shelf の読み込みでも任意のコードを実行できるからです。

シェルフオブジェクトは辞書がサポートする全てのメソッドをサポートしています。これにより、辞書ベースのスクリプトから永続的な記憶媒体を必要とするスクリプトに容易に移行できるようになります。

追加でサポートされるメソッドが二つあります:

Shelf.sync()

シェルフが writeback を True にセットして開かれている場合に、キャッシュ中の全てのエントリを書き戻します。また容易にできるならば、キャッシュを空にしてディスク上の永続的な辞書を同期します。このメソッドはシェルフを close() によって閉じるとき自動的に呼び出されます。

Shelf.close()

永続的な 辞書 オブジェクトを同期して閉じます。既に閉じられているシェルフに対して呼び出すと ValueError に終わります。

参考

通常の辞書に近い速度をもち、いろいろなストレージフォーマットに対応した、永続化辞書のレシピ [http://code.activestate.com/recipes/576642/]

11.4.1. 制限事項

どのデータベースパッケージが使われるか (例えば dbm 、 gdbm 、 bsddb) は、どのインタフェースが利用可能かに依存します。従って、データベースを dbm を使って直接開く方法は安全ではありません。データベースはまた、 dbm が使われた場合 (不幸なことに) その制約に縛られます — これはデータベースに記録されたオブジェクト (の pickle 化された表現) はかなり小さくなければならず、キー衝突が生じた場合に、稀にデータベースを更新することができなくなるということを意味します。

shelve モジュールは、シェルフに置かれたオブジェクトの 並列した 読み出し/書き込みアクセスをサポートしません (複数の同時読み出しアクセスは安全です)。あるプログラムが書き込みために開かれたシェルフを持っているとき、他のプログラムはそのシェルフを読み書きのために開いてはいけません。この問題を解決するために Unix のファイルロック機構を使うことができますが、この機構は Unix のバージョン間で異なり、使われているデータベースの実装について知識が必要となります。

class shelve.Shelf(dict[, protocol=None[, writeback=False]])

UserDict.DictMixin のサブクラスで、pickle 化された値を dict オブジェクトに保存します。

デフォルトでは、値を整列化する際にはバージョン 0 の pickle 化が用いられます。pickle 化プロトコルのバージョンは protocol パラメタで指定することができます。pickle 化プロトコルについては pickle のドキュメントを参照してください。

バージョン 2.3 で変更: protocol パラメタが追加されました。

writeback パラメタが True に設定されていれば、アクセスされたすべてのエントリはメモリ上にキャッシュされ、ファイルを閉じる際に書き戻されます; この機能により、可変のエントリに対して自然な操作が可能になりますが、さらに多くのメモリを消費し、辞書をファイルと同期して閉じる際に長い時間がかかるようになります。

class shelve.BsdDbShelf(dict[, protocol=None[, writeback=False]])

Shelf のサブクラスで、 first(), next(), previous(), last(), set_location() メソッドを公開しています。これらのメソッドは bsddb モジュールでは利用可能ですが、他のデータベースモジュールでは利用できません。コンストラクタに渡された dict オブジェクトは上記のメソッドをサポートしていなくてはなりません。通常は、 bsddb.hashopen(), bsddb.btopen() または bsddb.rnopen() のいずれかを呼び出して得られるオブジェクトが条件を満たしています。オプションの protocol および writeback パラメタは Shelf クラスにおけるパラメタと同様に解釈されます。

class shelve.DbfilenameShelf(filename[, flag='c'[, protocol=None[, writeback=False]]])

Shelf のサブクラスで、辞書様オブジェクトの代わりに filename を受理します。根底にあるファイルは anydbm.open() を使って開かれます。デフォルトでは、ファイルは読み書き可能な状態で開かれます。オプションの flag パラメタは open() 関数におけるパラメタと同様に解釈されます。オプションの protocol および writeback パラメタは Shelf クラスにおけるパラメタと同様に解釈されます。

11.4.2. 使用例

インタフェースは以下のコードに集約されています (key は文字列で、 data は任意のオブジェクトです):

import shelve

d = shelve.open(filename) # open -- file may get suffix added by low-level
                          # library

d[key] = data   # store data at key (overwrites old data if
                # using an existing key)
data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
                # such key)
del d[key]      # delete data stored at key (raises KeyError
                # if no such key)
flag = d.has_key(key)   # true if the key exists
klist = d.keys() # a list of all existing keys (slow!)

# as d was opened WITHOUT writeback=True, beware:
d['xx'] = range(4)  # this works as expected, but...
d['xx'].append(5)   # *this doesn't!* -- d['xx'] is STILL range(4)!

# having opened d without writeback=True, you need to code carefully:
temp = d['xx']      # extracts the copy
temp.append(5)      # mutates the copy
d['xx'] = temp      # stores the copy right back, to persist it

# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.

d.close()       # close it

参考

Module anydbm

dbm スタイルのデータベースに対する汎用インタフェース。

Module bsddb

BSD db データベースインタフェース。

Module dbhash

bsddb をラップする薄いレイヤで、他のデータベースモジュールのように関数 open() を提供しています。

Module dbm

標準の Unix データベースインタフェース。

Module dumbdbm

dbm インタフェースの移植性のある実装。

Module gdbm

dbm インタフェースに基づいた GNU データベースインタフェース。

Module pickle

shelve によって使われるオブジェクト整列化機構。

Module cPickle

pickle の高速版。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.5. marshal — 内部使用向けの Python オブジェクト整列化

このモジュールには Python 値をバイナリ形式で読み書きできるような関数が含まれています。このバイナリ形式は Python 特有のものですが、マシンアーキテクチャ非依存のものです (つまり、Python の値を PC 上でファイルに書き込み、Sun に転送し、そこで読み戻すことができます)。バイナリ形式の詳細は意図的にドキュメント化されていません; この形式は (稀にしかないことですが) Python のバージョン間で変更される可能性があるからです。 [1]

このモジュールは汎用の “永続化 (persistence)” モジュールではありません。汎用的な永続化や、RPC 呼び出しを通じた Python オブジェクトの転送については、モジュール pickle および shelve を参照してください。 marshal モジュールは主に、 “擬似コンパイルされた (pseudo-compiled)” コードの .pyc ファイルへの読み書きをサポートするために存在します。したがって、 Python のメンテナは、必要が生じれば marshal 形式を後方互換性のないものに変更する権利を有しています。 Python オブジェクトを直列化 (シリアライズ) および非直列化 (デシリアライズ) したい場合には、 pickle モジュールを使ってください。 pickle は速度は同等で、バージョン間の互換性が保証されていて、 marshal より広範囲のオブジェクトをサポートしています。

警告

marshal モジュールは、誤ったデータや悪意を持って作成されたデータに対する安全性を考慮していません。信頼できない、もしくは認証されていない出所からのデータを非整列化してはなりません。

すべての Python オブジェクト型がサポートされているわけではありません; 一般的には、 Python の特定の実行に依存しないオブジェクトだけがこのモジュールで読み書きできます。以下の型: 真偽値、整数、長整数、浮動小数点数、複素数、文字列、 Unicode オブジェクト、タプル、リスト、 set 、 frozenset 、辞書、コードオブジェクト、がサポートされています。ただし、タプル、リスト、 set 、 frozenset 、辞書は、それらに含まれた値がサポートされている型である限りサポートされると解釈しなければなりません; また、再帰的なリストおよび辞書は書き込んではなりません (無限ループを引き起こします)。シングルトンである None、 Ellipsis、 StopIteration も整列化可能です。

警告

(DEC Alpha のように) C言語の long int が 32 ビットよりも長いビット長を持つ場合、 32 ビットよりも長い Python 整数を作成することが可能です。そのような整数が整列化された後、 C 言語の long int のビット長が 32 ビットしかないマシン上で読み戻された場合、通常整数の代わりに Python 長整数が返されます。型は異なりますが、数値は同じです。 (この動作は Python 2.2 で新たに追加されたものです。それ以前のバージョンでは、値のうち最小桁から 32 ビット以外の情報は失われ、警告メッセージが出力されていました。)

文字列を操作する関数と同様に、ファイルの読み書きを行う関数が提供されています。

このモジュールでは以下の関数を定義しています:

marshal.dump(value, file[, version])

開かれたファイルに値を書き込みます。値はサポートされている型でなくてはなりません。ファイルは sys.stdout か、 open() や posix.popen() が返すようなファイルオブジェクトでなくてはなりません。またファイルはバイナリモード ('wb' または 'w+b') で開かれていなければなりません。

値 (または値に含まれるオブジェクト) がサポートされていない型の場合、 ValueError 例外が送出されます — しかし、同時にごみのデータがファイルに書き込まれます。このオブジェクトは load() で適切に読み出されることはありません。

バージョン 2.4 で追加: version 引数は dump が利用するデータフォーマットを表します (下記参照)。

marshal.load(file)

開かれたファイルから値を一つ読んで返します。 (異なるバージョンの Python の互換性のない marshal フォーマットだったなどの理由で) 有効な値が読み出せなかった場合、 EOFError、 ValueError、または TypeError を送出します。 file はバイナリモード ('rb' または 'r+b') で開かれたファイルオブジェクトでなければなりません.

ノート

サポートされていない型を含むオブジェクトが dump() で整列化されている場合、 load() は整列化不能な値を None で置き換えます。

marshal.dumps(value[, version])

dump(value, file) でファイルに書き込まれるような文字列を返します。値はサポートされている型でなければなりません。値がサポートされていない型のオブジェクト (またはサポートされていない型のオブジェクトを含むようなオブジェクト) の場合、 ValueError 例外が送出されます。

バージョン 2.4 で追加: version 引数は dumps が利用するデータフォーマットを表します (下記参照)。

marshal.loads(string)

データ文字列を値に変換します。有効な値が見つからなかった場合、 EOFError、 ValueError、または TypeError が送出されます。文字列中の余分な文字は無視されます。

これに加えて、以下の定数が定義されています:

marshal.version

このモジュールが利用するバージョンを表します。バージョン0 は歴史的なフォーマットです。バージョン1 は文字列の再利用をします (Python 2.4で追加されました)。バージョン2 は浮動小数点数にバイナリフォーマットを使用します (Python 2.5で追加されました)。現在のバージョンは2です。

バージョン 2.4 で追加.

注記

[1]
このモジュールの名前は (特に) Modula-3 の設計者の間で使われていた用語の一つに由来しています。彼らはデータを自己充足的な形式で輸送する操作に “整列化 (marshalling)” という用語を使いました。厳密に言えば、”整列させる (to marshal)” とは、あるデータを (例えば RPC バッファのように) 内部表現形式から外部表現形式に変換することを意味し、”非整列化 (unmarshalling)” とはその逆を意味します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.6. anydbm — DBM 形式のデータベースへの汎用アクセスインタフェース

ノート

anydbm モジュールはPython 3.0では dbm に名前が変更されました。 2to3 ツールが自動的に import を変換します。

anydbm は種々の DBM データベース — (bsddb を使う) dbhash 、 gdbm 、および dbm — への汎用インタフェースです。これらのモジュールがどれもインストールされていない場合、 dumbdbm モジュールの低速で単純な DBM 実装が使われます。

anydbm.open(filename[, flag[, mode]])

データベースファイル filename を開き、対応するオブジェクトを返します。

データベースファイルがすでに存在する場合、 whichdb モジュールを使ってファイルタイプが判定され、適切なモジュールが使われます; 既存のデータベースファイルが存在しなかった場合、上に挙げたモジュール中で最初にインポートすることができたものが使われます。

オプションの flag は以下の値のいずれかです:

値 | 意味
'r' | 既存のデータベースを読み込み専用で開く (デフォルト)
'w' | 既存のデータベースを読み書き用に開く
'c' | データベースを読み書き用に開く。ただし存在しない場合には新たに作成する
'n' | 常に新たに読み書き用の新規のデータベースを作成する

この引数が指定されない場合、標準の値は 'r' になります。

オプションの mode 引数は、新たにデータベースを作成しなければならない場合に使われる Unix のファイルモードです。標準の値は 8 進数の 0666 です (この値は現在有効な umask で修飾されます)。

exception anydbm.error

サポートされているモジュールのどれかによって送出されうる例外が収められるタプルで、先頭の要素は同じ名前の例外 anydbm.error になっています — anydbm.error が送出された場合、後者が使われます。

open() によって返されたオブジェクトは辞書とほとんど同じ同じ機能をサポートします; キーとそれに対応付けられた値を記憶し、引き出し、削除することができ、 has_key() および keys() メソッドを使うことができます。キーおよび値は常に文字列です。

以下の例ではホスト名と対応するタイトルがいくつか登録し、データベースの内容を表示します:

import anydbm

# データベースを開く、必要なら作成する
db = anydbm.open('cache', 'c')

# いくつかの値を設定する
db['www.python.org'] = 'Python Website'
db['www.cnn.com'] = 'Cable News Network'

# 内容についてループ。
# .keys(), .values() のような他の辞書メソッドもつかえます。
for k, v in db.iteritems():
    print k, '\t', v

# 文字列でないキーまたは値は例外を
# おこします（ほとんどのばあい TypeErrorです)。
db['www.yahoo.com'] = 4

# 終了したらcloseします。
db.close()

参考

Module dbhash

BSD db データベースインタフェース。

Module dbm

標準の Unix データベースインタフェース。

Module dumbdbm

dbm インタフェースの移植性のある実装。

Module gdbm

dbm インタフェースに基づいた GNU データベースインタフェース。

Module shelve

Python dbm インタフェース上に構築された汎用オブジェクト永続化機構。

Module whichdb

既存のデータベースがどの形式のデータベースか判定するユーティリティモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.7. whichdb — どのDBMモジュールがデータベースを作ったかを推測する

ノート

whichdb モジュールが持っている1つの関数は、Python 3.0では dbm モジュールに移動されました。 2to3 ツールは自動的に import を修正します。

このモジュールに含まれる唯一の関数はあることを推測します。つまり、与えられたファイルを開くためには、利用可能なデータベースモジュール(dbm, gdbm, dbhash)のどれを用いるべきかということです。

whichdb.whichdb(filename)

ファイルが読めないか存在しないために開くことが出来ない場合は None 、ファイルの形式を推測できない場合は空の文字列('')、推測できる場合は必要なモジュール名('dbm', 'gdbm' など)を含む文字列を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.8. dbm — UNIX dbmのシンプルなインタフェース

ノート

dbm モジュールは、Python 3.0では dbm.ndbm に変更されました。 2to3 ツールは、自動的に import を修正します。

dbm モジュールはUnixの”(n)dbm”ライブラリのインタフェースを提供します。 dbmオブジェクトは、キーと値が必ず文字列である以外は辞書オブジェクトのようなふるまいをします。 print文などでdbmインスタンスを出力してもキーと値は出力されません。また、 items() と values() メソッドはサポートされません。

このモジュールは、BSD DB、GNU GDBM互換インタフェースを持ったクラシックなndbmインタフェースを使うことができます。 Unix上のビルド時に configure スクリプトで適切なヘッダファイルが割り当られます。

以下はこのモジュールの定義:

exception dbm.error

I/Oエラーのようなdbm特有のエラーが起ったときに上げられる値です。また、正しくないキーが与えられた場合に通常のマッピングエラーのような KeyError が発生します。

dbm.library

ndbm が使用している実装ライブラリ名です。

dbm.open(filename[, flag[, mode]])

dbmデータベースを開いてdbmオブジェクトを返します。引数 filename はデータベースのファイル名を指定します。 (拡張子 .dir や .pag は付けません。また、BSD DBは拡張子 .db がついたファイルが一つ作成されます。)

オプション引数 flag は次のような値を指定します:

Value | Meaning
'r' | 存在するデータベースを読取り専用で開きます。(デフォルト)
'w' | 存在するデータベースを読み書き可能な状態で開きます。
'c' | データベースを読み書き可能な状態で開きます。また、データベースが存在しない場合は新たに作成します。
'n' | 常に空のデータベースが作成され、読み書き可能な状態で開きます。

オプション引数 mode はデータベース作成時に使用される Unixのファイルモードを指定します。デフォルトでは8進数の 0666 です。(この値はumaskによってマスクされます)

参考

Module anydbm

dbm スタイルの一般的なインタフェース

Module gdbm

GNU GDBMライブラリの類似したインタフェース

Module whichdb

存在しているデータベースの形式を決めるためのユーティリティモジュール

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.9. gdbm — GNU による dbm の再実装

ノート

gdbm モジュールはPython 3.0で dbm.gnu にリネームされました。 2to3 ツールがimportを自動的に修正します。

このモジュールは dbm モジュールによく似ていますが、 gdbm を使っていくつかの追加機能を提供しています。 gdbm と dbm では生成されるファイル形式に互換性がないので注意してください。

gdbm モジュールでは GNU DBM ライブラリへのインタフェースを提供します。 gdbm オブジェクトはキーと値が常に文字列であることを除き、マップ型 (辞書型) と同じように動作します。 gdbm オブジェクトに対して print を適用してもキーや値を印字することはなく、 items() 及び values() メソッドはサポートされていません。

このモジュールでは以下の定数および関数を定義しています:

exception gdbm.error

I/O エラーのような gdbm 特有のエラーで送出されます。誤ったキーの指定のように、一般的なマップ型のエラーに対しては KeyError が送出されます。

gdbm.open(filename[, flag[, mode]])

gdbm データベースを開いて gdbm オブジェクトを返します。 filename 引数はデータベースファイルの名前です。

オプションの flag は、

値 | 意味
'r' | 既存のデータベースを読み込み専用で開きます(デフォルト)
'w' | 既存のデータベースを読み書き用に開きます
'c' | データベースを読み書き用に開きます。まだ存在しない場合は作成します。
'n' | 常に新しい、空のデータベースを、読み書き用に開きます。

以下の追加の文字を flag に追加して、データベースの開きかたを制御することができます。

値 | 意味
'f' | データベースを高速モードで開きます。書き込みが同期されません。
's' | 同期モード。データベースへの変更がすぐにファイルに書き込まれます。
'u' | データベースをロックしません。

全てのバージョンの gdbm で全てのフラグが有効とは限りません。モジュール定数 open_flags はサポートされているフラグ文字からなる文字列です。無効なフラグが指定された場合、例外 error が送出されます。

オプションの mode 引数は、新たにデータベースを作成しなければならない場合に使われる Unix のファイルモードです。標準の値は 8 進数の 0666 です。

辞書型形式のメソッドに加えて、 gdbm オブジェクトには以下のメソッドがあります:

gdbm.firstkey()

このメソッドと next() メソッドを使って、データベースの全てのキーにわたってループ処理を行うことができます。探索は gdbm の内部ハッシュ値の順番に行われ、キーの値に順に並んでいるとは限りません。このメソッドは最初のキーを返します。

gdbm.nextkey(key)

データベースの順方向探索において、 key よりも後に来るキーを返します。以下のコードはデータベース db について、キー全てを含むリストをメモリ上に生成することなく全てのキーを出力します:

k = db.firstkey()
while k != None:
    print k
    k = db.nextkey(k)

gdbm.reorganize()

大量の削除を実行した後、 gdbm ファイルの占めるスペースを削減したい場合、このルーチンはデータベースを再組織化します。この再組織化を使う以外に gdbm はデータベースファイルの大きさを短くすることはありません; そうでない場合、削除された部分のファイルスペースは保持され、新たな (キー、値の) ペアが追加される際に再利用されます。

gdbm.sync()

データベースが高速モードで開かれていた場合、このメソッドはディスクにまだ書き込まれていないデータを全て書き込ませます。

参考

Module anydbm

dbm 形式のデータベースへの汎用インタフェース。

Module whichdb

既存のデータベースがどの形式のデータベースか判定するユーティリティモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.10. dbhash — BSD データベースライブラリへの DBM 形式のインタフェース

バージョン 2.6 で撤廃: dbhash モジュールは Python 3.0 では削除されます。

dbhash モジュールでは BSD db ライブラリを使ってデータベースを開くための関数を提供します。このモジュールは、 DBM 形式のデータベースへのアクセスを提供する他の Python データベースモジュールのインタフェースをそのまま反映しています。 dbhash を使うには bsddb モジュールが必要です。

このモジュールでは一つの例外と一つの関数を提供しています:

exception dbhash.error

KeyError 以外のデータベースのエラーで送出されます。 bsddb.error と同じ意味です。

dbhash.open(path[, flag[, mode]])

データベース db を開き、データベースオブジェクトを返します。引数 path はデータベースファイルの名前です。

flag 引数は、次のいずれかの値になります。

値 | 意味
'r' | 既存のデータベースを、読み込み専用で開きます。 (デフォルト)
'w' | 既存のデータベースを、読み書き用に開きます。
'c' | データベースを読み書き用に開きます。存在しない場合は作成します。
'n' | 常に新しい空のデータベースを、読み書き用に開きます。

BSD db ライブラリがロックをサポートしているプラットフォームでは、 flag に 'l' を追加して、ロックを利用することを指定できます。

オプションの mode 引数は、新たにデータベースを作成しなければならないときにデータベースファイルに設定すべき Unix ファイル権限ビットを表すために使われます; この値はプロセスの現在の umask 値でマスクされます。

参考

Module anydbm

dbm 形式のデータベースへの汎用インタフェース。

Module bsddb

BSD db ライブラリへの低レベルインタフェース。

Module whichdb

既存のデータベースがどの形式のデータベースか判定するユーティリティモジュール。

11.10.1. データベースオブジェクト

open() によって返されるデータベースオブジェクトは、全ての DBM 形式データベースやマップ型オブジェクトで共通のメソッドを提供します。それら標準のメソッドに加えて、以下のメソッドが利用可能です。

dbhash.first()

このメソッドと next() メソッドを使って、データベースの全てのキー/値のペアにわたってループ処理を行えます。探索はデータベースの内部ハッシュ値の順番に行われ、キーの値に順に並んでいるとは限りません。このメソッドは最初のキーを返します。

dbhash.last()

データベース探索における最後のキー/値を返します。逆順探索を開始する際に使うことができます; previous() を参照してください。

dbhash.next()

データベースの順方向探索において、次のよりも後に来るキー/値のペアを返します。以下のコードはデータベース db について、キー全てを含むリストをメモリ上に生成することなく全てのキーを出力します。

print db.first()
for i in xrange(1, len(db)):
    print db.next()

dbhash.previous()

データベースの逆方向探索において、手前に来るキー/値のペアを返します。 last() と併せて、逆方向の探索に用いられます。

dbhash.sync()

このメソッドはディスクにまだ書き込まれていないデータを全て書き込ませます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.11. bsddb — Berkeley DB ライブラリへのインタフェース

バージョン 2.6 で撤廃: bsddb モジュールは、 Python 3.0 では削除されるので、非推奨です。

bsddb モジュールは Berkeley DB ライブラリへのインタフェースを提供します。ユーザは適当な open() 呼び出しを使うことで、ハッシュ、B-Tree、またはレコードに基づくデータベースファイルを生成することができます。bsddb オブジェクトは辞書と大体同じように振る舞います。しかし、キー及び値は文字列でなければならないので、他のオブジェクトをキーとして使ったり、他の種のオブジェクトを記録したい場合、それらのデータを何らかの方法で直列化しなければなりません。これには通常 marshal.dumps() や pickle.dumps() が使われます。

bsddb モジュールは、バージョン 4.0 から 4.7 までの間の Berkeley DB ライブラリを必要とします。

参考

http://www.jcea.es/programacion/pybsddb.htm

Berkeley DBインターフェース bsddb.db のドキュメントがあります。インターフェースは、Berkeley DB 4.x でSleepycatが提供しているオブジェクト指向インターフェースとほぼ同じインターフェースとなっています。

http://www.oracle.com/database/berkeley-db/

The Berkeley DB library.

より新しい DB である DBEnv や DBSequence オブジェクトのインターフェースも bsddb.db モジュールで使用できます。これは、上の URL で説明されている Berkeley DB C API によりマッチしています。 bsddb.db API が提供する追加機能には、チューニングやトランザクション、ログ出力、マルチプロセス環境でのデータベースへの同時アクセスなどがあります。

以下では、従来のbsddbモジュールと互換性のある、古いインターフェースを解説しています。Python 2.5 以降、このインターフェースはマルチスレッドに対応しています。マルチスレッドを使用する場合は bsddb.db API を推奨します。こちらのほうがスレッドをよりうまく制御できるからです。

bsddb モジュールでは、適切な形式の Berkeley DB ファイルにアクセスするオブジェクトを生成する以下の関数を定義しています。各関数の最初の二つの引数は同じです。可搬性のために、ほとんどのインスタンスでは最初の二つの引数だけが使われているはずです。

bsddb.hashopen(filename[, flag[, mode[, pgsize[, ffactor[, nelem[, cachesize[, lorder[, hflags]]]]]]]])

filename と名づけられたハッシュ形式のファイルを開きます。 filename に None を指定することで、ディスクに保存するつもりがないファイルを生成することもできます。オプションの flag には、ファイルを開くためのモードを指定します。このモードは 'r' (読み出し専用), 'w' (読み書き可能)、 'c' (読み書き可能 - 必要ならファイルを生成…これがデフォルトです) または 'n' (読み書き可能 - ファイル長を 0 に切り詰め)、にすることができます。他の引数はほとんど使われることはなく、下位レベルの dbopen() 関数に渡されるだけです。他の引数の使い方およびその解釈については Berkeley DB のドキュメントを読んで下さい。

bsddb.btopen(filename[, flag[, mode[, btflags[, cachesize[, maxkeypage[, minkeypage[, pgsize[, lorder]]]]]]]])

filename と名づけられた B-Tree 形式のファイルを開きます。 filename に None を指定することで、ディスクに保存するつもりがないファイルを生成することもできます。オプションの flag には、ファイルを開くためのモードを指定します。このモードは 'r' (読み出し専用)、 'w' (読み書き可能)、 'c' (読み書き可能 - 必要ならファイルを生成…これがデフォルトです)、または 'n' (読み書き可能 - ファイル長を 0 に切り詰め)、にすることができます。他の引数はほとんど使われることはなく、下位レベルの dbopen() 関数に渡されるだけです。他の引数の使い方およびその解釈については Berkeley DB のドキュメントを読んで下さい。

bsddb.rnopen(filename[, flag[, mode[, rnflags[, cachesize[, pgsize[, lorder[, rlen[, delim[, source[, pad]]]]]]]]]])

filename と名づけられた DB レコード形式のファイルを開きます、 filename に None を指定することで、ディスクに保存するつもりがないファイルを生成することもできます、オプションの flag には、ファイルを開くためのモードを指定します、このモードは 'r' (読み出し専用), 'w' (読み書き可能)、 'c' (読み書き可能 - 必要ならファイルを生成…これがデフォルトです)、または 'n' (読み書き可能 - ファイル長を 0 に切り詰め)、にすることができます。他の引数はほとんど使われることはなく、下位レベルの dbopen() 関数に渡されるだけです、他の引数の使い方およびその解釈については Berkeley DB のドキュメントを読んで下さい。

ノート

2.3以降の Unix 版Pythonには、 bsddb185 モジュールが存在する場合があります。このモジュールは古いBerkeley DB 1.85データベースライブラリを持つシステムをサポートするため だけ に存在しています。新規に開発するコードでは、 bsddb185 を直接使用しないで下さい。このモジュールは Python 3.0 で削除されます。(必要であれば、PyPIにあるかもしれません)

参考

Module dbhash

bsddb への DBM 形式のインタフェース

11.11.1. ハッシュ、BTree、およびレコードオブジェクト

インスタンス化したハッシュ、B-Tree, およびレコードオブジェクトは辞書型と同じメソッドをサポートするようになります。加えて、以下に列挙したメソッドもサポートします。

バージョン 2.3.1 で変更: 辞書型メソッドを追加しました.

bsddbobject.close()

データベースの背後にあるファイルを閉じます。オブジェクトはアクセスできなくなります。これらのオブジェクトには oepn() メソッドがないため、再度ファイルを開くためには、新たな bsddb モジュールを開く関数を呼び出さなくてはなりません。

bsddbobject.keys()

DB ファイルに収められているキーからなるリストを返します。リスト内のキーの順番は決まっておらず、あてにはなりません。特に、異なるファイル形式の DB 間では返されるリストの順番が異なります。

bsddbobject.has_key(key)

引数 key が DB ファイルにキーとして含まれている場合 1 を返します。

bsddbobject.set_location(key)

カーソルを key で示される要素に移動し、キー及び値からなるタプルを返します。(bopen() を使って開かれる) B-Tree データベースでは、 key が実際にはデータベース内に存在しなかった場合、カーソルは並び順が key の次に来るような要素を指し、その場所のキー及び値が返されます。他のデータベースでは、データベース中に key が見つからなかった場合 KeyError が送出されます。

bsddbobject.first()

カーソルを DB ファイルの最初の要素に設定し、その要素を返します。 B-Tree データベースの場合を除き、ファイル中のキーの順番は決まっていません。データベースが空の場合、このメソッドは bsddb.error を発生させます。

bsddbobject.next()

カーソルを DB ファイルの次の要素に設定し、その要素を返します。 B-Tree データベースの場合を除き、ファイル中のキーの順番は決まっていません。

bsddbobject.previous()

カーソルを DB ファイルの直前の要素に設定し、その要素を返します。 B-Tree データベースの場合を除き、ファイル中のキーの順番は決まっていません。 (hashopen() で開かれるような) ハッシュ表データベースではサポートされていません。

bsddbobject.last()

カーソルを DB ファイルの最後の要素に設定し、その要素を返します。ファイル中のキーの順番は決まっていません。 (hashopen() で開かれるような) ハッシュ表データベースではサポートされていません。データベースが空の場合、このメソッドは bsddb.error を発生させます。

bsddbobject.sync()

ディスク上のファイルをデータベースに同期させます。

以下はプログラム例です:

>>> import bsddb
>>> db = bsddb.btopen('/tmp/spam.db', 'c')
>>> for i in range(10): db['%d'%i] = '%d'% (i*i)
...
>>> db['3']
'9'
>>> db.keys()
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> db.first()
('0', '0')
>>> db.next()
('1', '1')
>>> db.last()
('9', '81')
>>> db.set_location('2')
('2', '4')
>>> db.previous()
('1', '1')
>>> for k, v in db.iteritems():
...     print k, v
0 0
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
>>> '8' in db
True
>>> db.sync()
0

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.12. dumbdbm — 可搬性のある DBM 実装

ノート

dumbdbm モジュールは、 Python 3.0 では dbm.dumb にリネームされます。 2to3 ツールが自動的にimportを修正します。

ノート

dumbdbm モジュールは、 anydbm が安定なモジュールを他に見つけることができなかった際の最後の手段とされています。 dumbdbm モジュールは速度を重視して書かれているわけではなく、他のデータベースモジュールのように重い使い方をするためのものではありません。

dumbdbm モジュールは永続性辞書に類似したインタフェースを提供し、全て Python で書かれています。 gdbm や bsddb といったモジュールと異なり、外部ライブラリは必要ありません。他の永続性マップ型のように、キーおよび値は常に文字列でなければなりません。

このモジュールでは以下の内容を定義してします:

exception dumbdbm.error

I/O エラーのような dumbdbm 特有のエラーの際に送出されます。不正なキーを指定したときのような、一般的な対応付けエラーの際には KeyError が送出されます。

dumbdbm.open(filename[, flag[, mode]])

dumbdbm データベースを開き、 dubmdbm オブジェクトを返します。 filename 引数はデータベースファイル名の雛型 (特定の拡張子をもたないもの) です。dumbdbm データベースが生成される際、 .dat および .dir の拡張子を持ったファイルが生成されます。

オプションの flag 引数は現状では無視されます; データベースは常に更新のために開かれ、存在しない場合には新たに作成されます。

オプションの mode 引数は Unix におけるファイルのモードで、データベースを作成する際に使われます。デフォルトでは 8 進コードの 0666 になっています (umask によって修正を受けます)。

バージョン 2.2 で変更: mode 引数は以前のバージョンでは無視されます.

参考

Module anydbm

dbm 形式のデータベースに対する汎用インタフェース。

Module dbm

DBM/NDBM ライブラリに対する同様のインタフェース。

Module gdbm

GNU GDBM ライブラリに対する同様のインタフェース。

Module shelve

非文字列データを記録する永続化モジュール。

Module whichdb

既存のデータベースの形式を判定するために使われるユーティリティモジュール。

11.12.1. Dumbdbm オブジェクト

UserDict.DictMixin クラスで提供されているメソッドに加え、 dumbdbm オブジェクトでは以下のメソッドを提供しています。

dumbdbm.sync()

ディスク上の辞書とデータファイルを同期します。このメソッドは Shelve オブジェクトの sync() メソッドから呼び出されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

11. データの永続化 »

11.13. sqlite3 — SQLite データベースに対する DB-API 2.0 インタフェース

バージョン 2.5 で追加.

SQLite は、別にサーバプロセスは必要とせずデータベースのアクセスに SQL 問い合わせ言語の非標準的な一種を使える軽量なディスク上のデータベースを提供する C ライブラリです。ある種のアプリケーションは内部データ保存に SQLite を使えます。また、SQLite を使ってアプリケーションのプロトタイプを作りその後そのコードを PostgreSQL や Oracle のような大規模データベースに移植するということも可能です。

sqlite3 は Gerhard Häring によって書かれ、 PEP 249 [http://www.python.org/dev/peps/pep-0249] に記述された DB-API 2.0 仕様に準拠した SQL インタフェースを提供するものです。

このモジュールを使うには、最初にデータベースを表す Connection オブジェクトを作ります。ここではデータはファイル /tmp/example に格納されているものとします。

conn = sqlite3.connect('/tmp/example')

特別な名前である :memory: を使うと RAM 上にデータベースを作ることもできます。

Connection があれば、 Cursor オブジェクトを作りその execute() メソッドを呼んで SQL コマンドを実行することができます。

c = conn.cursor()

# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')

# Insert a row of data
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")

# Save (commit) the changes
conn.commit()

# We can also close the cursor if we are done with it
c.close()

たいてい、SQL 操作は Python 変数の値を使う必要があります。この時、クエリーを Python の文字列操作を使って構築することは、安全とは言えないので、すべきではありません。そのようなことをするとプログラムが SQL インジェクション攻撃に対し脆弱になりかねません。

代わりに、DB-API のパラメータ割り当てを使います。 ? を変数の値を使いたいところに埋めておきます。その上で、値のタプルをカーソルの execute() メソッドの第2引数として引き渡します。(他のデータベースモジュールでは変数の場所を示すのに %s や :1 などの異なった表記を用いることがあります。) 例を示します。

# Never do this -- insecure!
symbol = 'IBM'
c.execute("... where symbol = '%s'" % symbol)

# Do this instead
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)

# Larger example
for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
         ]:
    c.execute('insert into stocks values (?,?,?,?,?)', t)

SELECT 文を実行した後データを取得する方法は3つありどれを使っても構いません。一つはカーソルをイテレータ(iterator)として扱う、一つはカーソルの fetchone() メソッドを呼んで一致した内の一行を取得する、もう一つは fetchall() メソッドを呼んで一致した全ての行のリストとして受け取る、という3つです。

以下の例ではイテレータの形を使います。

>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
...    print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.14)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>

参考

http://code.google.com/p/pysqlite/

pysqlite のウェブページ – sqlite3 は「pysqlite」という名の下、外部で開発されています。

http://www.sqlite.org

SQLite のウェブページ。ここの文書ではサポートされる SQL 方言の文法と使えるデータ型を説明しています

PEP 249 [http://www.python.org/dev/peps/pep-0249] - Database API Specification 2.0

Marc-Andre Lemburg により書かれた PEP

http://www.python.jp/doc/contrib/peps/pep-0249.txt

訳注: PEP 249 の日本語訳があります

11.13.1. モジュールの関数と定数

sqlite3.PARSE_DECLTYPES

この定数は connect() 関数の detect_types パラメータとして使われます。

この定数を設定すると sqlite3 モジュールは戻り値のカラムの宣言された型を読み取るようになります。意味を持つのは宣言の最初の単語です。すなわち、”integer primary key” においては “integer” が読み取られます。また、 “number(10)” では、 “number” が読み取られます。そして、そのカラムに対して、変換関数の辞書を探してその型に対して登録された関数を使うようにします。

sqlite3.PARSE_COLNAMES

この定数は connect() 関数の detect_types パラメータとして使われます。

この定数を設定すると SQLite のインタフェースは戻り値のそれぞれのカラムの名前を読み取るようになります。文字列の中の [mytype] といった形の部分を探し、’mytype’ がそのカラムの名前であると判断します。そして ‘mytype’ のエントリを変換関数辞書の中から見つけ、見つかった変換関数を値を返す際に用います。 Cursor.description で見つかるカラム名はその最初の単語だけです。すなわち、もし 'as "x [datetime]"' のようなものを SQL の中で使っていたとすると、読み取るのはカラム名の中の最初の空白までの全てですので、カラム名として使われるのは単純に “x” ということになります。

sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements])

ファイル database の SQLite データベースへの接続を開きます。 ":memory:" という名前を使うことでディスクの代わりに RAM 上のデータベースへの接続を開くこともできます。

データベースが複数の接続からアクセスされている状況で、その内の一つがデータベースに変更を加えたとき、SQLite データベースはそのトランザクションがコミットされるまでロックされます。 timeout パラメータで、例外を送出するまで接続がロックが解除されるのをどれだけ待つかを決めます。デフォルトは 5.0 (5秒) です。

isolation_level パラメータについては、 Connection オブジェクトの、 Connection.isolation_level 属性を参照してください。

SQLite がネイティブにサポートするのは TEXT, INTEGER, FLOAT, BLOB および NULL 型だけです。もし他の型を使いたければ、その型のためのサポートを自分で追加しなければなりません。 detect_types パラメータを、モジュールレベルの register_converter() 関数で登録した自作の 変換関数 と一緒に使えば、簡単にできます。

パラメータ detect_types のデフォルトは 0 (つまりオフ、型検知無し)です。型検知を有効にするためには、 PARSE_DECLTYPES と PARSE_COLNAMES の適当な組み合わせをこのパラメータにセットします。

デフォルトでは、 sqlite3 モジュールは connect の呼び出しの際にモジュールの Connection クラスを使います。しかし、 Connection クラスを継承したクラスを factory パラメータに渡して connect() にそのクラスを使わせることもできます。詳しくはこのマニュアルの SQLite と Python の型 節を参考にしてください。

sqlite3 モジュールは SQL 解析のオーバーヘッドを避けるために内部で文キャッシュを使っています。接続に対してキャッシュされる文の数を自分で指定したいならば、 cached_statements パラメータに設定してください。現在の実装ではデフォルトでキャッシュされる SQL 文の数を 100 にしています。

sqlite3.register_converter(typename, callable)

データベースから得られるバイト列を希望する Python の型に変換する呼び出し可能オブジェクト (callable) を登録します。その呼び出し可能オブジェクトは型が typename である全てのデータベース上の値に対して呼び出されます。型検知がどのように働くかについては connect() 関数の detect_types パラメータの説明も参照してください。注意が必要なのは typename はクエリの中の型名と大文字小文字も一致しなければならないということです。

sqlite3.register_adapter(type, callable)

自分が使いたい Python の型 type を SQLite がサポートしている型に変換する呼び出し可能オブジェクト (callable) を登録します。その呼び出し可能オブジェクト callable はただ一つの引数に Python の値を受け取り、int, long, float, (UTF-8 でエンコードされた) str, unicode または buffer のいずれかの型の値を返さなければなりません

sqlite3.complete_statement(sql)

もし文字列 sql がセミコロンで終端された一つ以上の完全な SQL 文を含んでいれば、 True を返します。判定は SQL 文として文法的に正しいかではなく、閉じられていない文字列リテラルが無いことおよびセミコロンで終端されていることだけで行なわれます。

この関数は以下の例にあるような SQLite のシェルを作る際に使われます。

# A minimal SQLite shell for experiments

import sqlite3

con = sqlite3.connect(":memory:")
con.isolation_level = None
cur = con.cursor()

buffer = ""

print "Enter your SQL commands to execute in sqlite3."
print "Enter a blank line to exit."

while True:
    line = raw_input()
    if line == "":
        break
    buffer += line
    if sqlite3.complete_statement(buffer):
        try:
            buffer = buffer.strip()
            cur.execute(buffer)

            if buffer.lstrip().upper().startswith("SELECT"):
                print cur.fetchall()
        except sqlite3.Error, e:
            print "An error occurred:", e.args[0]
        buffer = ""

con.close()

sqlite3.enable_callback_tracebacks(flag)

デフォルトでは、ユーザ定義の関数、集計関数、変換関数、認可コールバックなどはトレースバックを出力しません。デバッグの際にはこの関数を flag に True を指定して呼び出します。そうした後は先に述べたような関数のトレースバックが sys.stderr に出力されます。元に戻すには False を使います。

11.13.2. Connection オブジェクト

class sqlite3.Connection

SQLite データベースコネクション。以下の属性やメソッドを持ちます。

Connection.isolation_level

現在の分離レベルを取得または設定します。 None で自動コミットモードまたは “DEFERRED”, “IMMEDIATE”, “EXLUSIVE” のどれかです。より詳しい説明は トランザクション制御 節を参照してください。

Connection.cursor([cursorClass])

cursor メソッドはオプション引数 cursorClass を受け付けます。これを指定するならば、指定されたクラスは sqlite3.Cursor を継承したカーソルクラスでなければなりません。

Connection.commit()

このメソッドは現在のトランザクションをコミットします。このメソッドを呼ばないと、前回 commit() を呼び出してから行ったすべての変更は、他のデータベースコネクションから見ることができません。もし、データベースに書き込んだはずのデータが見えなくて悩んでいる場合は、このメソッドの呼び出しを忘れていないかチェックしてください。

Connection.rollback()

このメソッドは最後に行った commit() 後の全ての変更をロールバックします。

Connection.close()

このメソッドはデータベースコネクションを閉じます。このメソッドが自動的に commit() を呼び出さないことに注意してください。 commit() をせずにコネクションを閉じると、変更が消えてしまいます。

Connection.execute(sql[, parameters])

このメソッドは非標準のショートカットで、cursor メソッドを呼び出して中間的なカーソルオブジェクトを作り、そのカーソルの execute メソッドを与えられたパラメータと共に呼び出します。

Connection.executemany(sql[, parameters])

このメソッドは非標準のショートカットで、cursor メソッドを呼び出して中間的なカーソルオブジェクトを作り、そのカーソルの executemany メソッドを与えられたパラメータと共に呼び出します。

Connection.executescript(sql_script)

このメソッドは非標準のショートカットで、cursor メソッドを呼び出して中間的なカーソルオブジェクトを作り、そのカーソルの executescript メソッドを与えられたパラメータと共に呼び出します。

Connection.create_function(name, num_params, func)

後から SQL 文中で name という名前の関数として使えるユーザ定義関数を作成します。 num_params は関数が受け付ける引数の数、 func は SQL 関数として使われる Python の呼び出し可能オブジェクトです。

関数は SQLite でサポートされている任意の型を返すことができます。具体的には unicode, str, int, long, float, buffer および None です。

例:

import sqlite3
import md5

def md5sum(t):
    return md5.md5(t).hexdigest()

con = sqlite3.connect(":memory:")
con.create_function("md5", 1, md5sum)
cur = con.cursor()
cur.execute("select md5(?)", ("foo",))
print cur.fetchone()[0]

Connection.create_aggregate(name, num_params, aggregate_class)

ユーザ定義の集計関数を作成します。

集計クラスにはパラメータ num_params で指定される個数の引数を取る step メソッドおよび最終的な集計結果を返す finalize メソッドを実装しなければなりません。

finalize メソッドは SQLite でサポートされている任意の型を返すことができます。具体的には unicode, str, int, long, float, buffer および None です。

例:

import sqlite3

class MySum:
    def __init__(self):
        self.count = 0

    def step(self, value):
        self.count += value

    def finalize(self):
        return self.count

con = sqlite3.connect(":memory:")
con.create_aggregate("mysum", 1, MySum)
cur = con.cursor()
cur.execute("create table test(i)")
cur.execute("insert into test(i) values (1)")
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print cur.fetchone()[0]

Connection.create_collation(name, callable)

name と callable で指定される照合順序を作成します。呼び出し可能オブジェクトには二つの文字列が渡されます。一つめのものが二つめのものより低く順序付けられるならば -1 を返し、等しければ 0 を返し、一つめのものが二つめのものより高く順序付けられるならば 1 を返すようにしなければなりません。この関数はソート(SQL での ORDER BY)をコントロールするもので、比較を行なうことは他の SQL 操作には影響を与えないことに注意しましょう。

また、呼び出し可能オブジェクトに渡される引数は Python のバイト文字列として渡されますが、それは通常 UTF-8 で符号化されたものになります。

以下の例は「間違った方法で」ソートする自作の照合順序です:

import sqlite3

def collate_reverse(string1, string2):
    return -cmp(string1, string2)

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)

cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
    print row
con.close()

照合順序を取り除くには create_collation を callable として None を渡して呼び出します:

con.create_collation("reverse", None)

Connection.interrupt()

このメソッドを別スレッドから呼び出して接続上で現在実行中であろうクエリを中断させられます。クエリが中断されると呼び出し元は例外を受け取ります。

Connection.set_authorizer(authorizer_callback)

このルーチンはコールバックを登録します。コールバックはデータベースのテーブルのカラムにアクセスしようとするたびに呼び出されます。コールバックはアクセスが許可されるならば SQLITE_OK を、SQL 文全体がエラーとともに中断されるべきならば SQLITE_DENY を、カラムが NULL 値として扱われるべきなら SQLITE_IGNORE を返さなければなりません。これらの定数は sqlite3 モジュールに用意されています。

コールバックの第一引数はどの種類の操作が許可されるかを決めます。第二第三引数には第一引数に依存して本当に使われる引数か None かが渡されます。第四引数はもし適用されるならばデータベースの名前(“main”, “temp”, etc.)です。第五引数はアクセスを試みる要因となった最も内側のトリガまたはビューの名前、またはアクセスの試みが入力された SQL コードに直接起因するものならば None です。

第一引数に与えることができる値や、その第一引数によって決まる第二第三引数の意味については、SQLite の文書を参考にしてください。必要な定数は全て sqlite3 モジュールに用意されています。

Connection.set_progress_handler(handler, n)

バージョン 2.6 で追加.

このメソッドはコールバックを登録します。コールバックは SQLite 仮想マシン上の n 個の命令を実行するごとに呼び出されます。これは、GUI 更新などのために、長時間かかる処理中に SQLite からの呼び出しが欲しい場合に便利です。

以前登録した progress handler をクリアしたい場合は、このメソッドを、 handler 引数に None を渡して呼び出してください。

Connection.enable_load_extension(enabled)

バージョン 2.7 で追加.

このメソッドは SQLite エンジンが共有ライブラリから SQLite 拡張を読み込むのを許可したり、禁止したりします。 SQLite 拡張は新しい関数や集計関数や仮想テーブルの実装を定義できます。 1つの有名な拡張は SQLite によって頒布されている全テキスト検索拡張です。

import sqlite3

con = sqlite3.connect(":memory:")

# enable extension loading
con.enable_load_extension(True)

# Load the fulltext search extension
con.execute("select load_extension('./fts3.so')")

# alternatively you can load the extension using an API call:
# con.load_extension("./fts3.so")

# disable extension laoding again
con.enable_load_extension(False)

# example from SQLite wiki
con.execute("create virtual table recipe using fts3(name, ingredients)")
con.executescript("""
    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
    """)
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
    print row

Connection.load_extension(path)

バージョン 2.7 で追加.

このメソッドは共有ライブラリから SQLite 拡張を読み込みます。このメソッドを使う前に enable_load_extension() で拡張の読み込みを許可しておかなくてはなりません。

Connection.row_factory

この属性を、カーソルとタプルの形での元の行のデータを受け取り最終的な行を表すオブジェクトを返す呼び出し可能オブジェクトに、変更することができます。これによって、より進んだ結果の返し方を実装することができます。例えば、カラムの名前で各データにアクセスできるようなオブジェクトを返したりできます。

例:

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

タプルを返すのでは物足りず、名前に基づいたカラムへのアクセスが行ないたい場合は、高度に最適化された sqlite3.Row 型を row_factory にセットすることを考えてはいかがでしょうか。 Row クラスでは添字でも大文字小文字を無視した名前でもカラムにアクセスでき、しかもほとんどメモリーを浪費しません。おそらく、辞書を使うような独自実装のアプローチよりも、もしかすると db の行に基づいた解法よりも良いものかもしれません。

Connection.text_factory

この属性を使って TEXT データ型をどのオブジェクトで返すかを制御できます。デフォルトではこの属性は unicode に設定されており、 sqlite3 モジュールは TEXT を Unicode オブジェクトで返します。もしバイト列で返したいならば、 str に設定してください。

効率の問題を考えて、非ASCIIデータに限って Unicode オブジェクトを返し、その他の場合にはバイト列を返す方法もあります。これを有効にしたければ、この属性を sqlite3.OptimizedUnicode に設定してください。

バイト列を受け取って望みの型のオブジェクトを返すような呼び出し可能オブジェクトを何でも設定して構いません。

以下の説明用のコード例を参照してください:

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()

# Create the table
con.execute("create table person(lastname, firstname)")

AUSTRIA = u"\xd6sterreich"

# by default, rows are returned as Unicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert row[0] == AUSTRIA

# but we can make pysqlite always return bytestrings ...
con.text_factory = str
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == str
# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
# database ...
assert row[0] == AUSTRIA.encode("utf-8")

# we can also implement a custom text_factory ...
# here we implement one that will ignore Unicode characters that cannot be
# decoded from UTF-8
con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),))
row = cur.fetchone()
assert type(row[0]) == unicode

# pysqlite offers a builtin optimized text_factory that will return bytestring
# objects, if the data is in ASCII only, and otherwise return unicode objects
con.text_factory = sqlite3.OptimizedUnicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == unicode

cur.execute("select ?", ("Germany",))
row = cur.fetchone()
assert type(row[0]) == str

Connection.total_changes

データベース接続が開始されて以来の行の変更・挿入・削除がなされた行の総数を返します。

Connection.iterdump

データベースをSQL testフォーマットでダンプするためのイテレータを返します。 in-memory データベースの内容を、後でリストアするための保存する場合に便利です。この関数は sqlite3 シェルの中の .dump コマンドと同じ機能を持っています。

バージョン 2.6 で追加.

例:

# existing_db.db ファイルを dump.sql ファイルにダンプする
import sqlite3, os

con = sqlite3.connect('existing_db.db')
with open('dump.sql', 'w') as f:
    for line in con.iterdump():
        f.write('%s\n' % line)

11.13.3. カーソルオブジェクト

class sqlite3.Cursor

Cursor インスタンスは以下の属性やメソッドを持ちます。

Cursor.execute(sql[, parameters])

SQL 文を実行します。SQL 文はパラメータ化できます(すなわち SQL リテラルの代わりの場所確保文字 (placeholder) を入れておけます)。 sqlite3 モジュールは2種類の場所確保記法をサポートします。一つは疑問符(qmark スタイル)、もう一つは名前(named スタイル)です。

まず最初の例は qmark スタイルのパラメータを使った書き方を示します:

import sqlite3

con = sqlite3.connect("mydb")

cur = con.cursor()

who = "Yeltsin"
age = 72

cur.execute("select name_last, age from people where name_last=? and age=?", (who, age))
print cur.fetchone()

次の例は named スタイルの使い方です:

import sqlite3

con = sqlite3.connect("mydb")

cur = con.cursor()

who = "Yeltsin"
age = 72

cur.execute("select name_last, age from people where name_last=:who and age=:age",
    {"who": who, "age": age})
print cur.fetchone()

execute() は一つの SQL 文しか実行しません。二つ以上の文を実行しようとすると、Warning を発生させます。複数の SQL 文を一つの呼び出しで実行したい場合は executescript() を使ってください。

Cursor.executemany(sql, seq_of_parameters)

SQL 文 sql を seq_of_parameters シーケンス(またはマッピング)に含まれる全てのパラメータに対して実行します。 sqlite3 モジュールでは、シーケンスの代わりにパラメータの組を作り出すイテレータ使うことが許されています。

import sqlite3

class IterChars:
    def __init__(self):
        self.count = ord('a')

    def __iter__(self):
        return self

    def next(self):
        if self.count > ord('z'):
            raise StopIteration
        self.count += 1
        return (chr(self.count - 1),) # this is a 1-tuple

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)

cur.execute("select c from characters")
print cur.fetchall()

もう少し短いジェネレータ(generator)を使った例です:

import sqlite3

def char_generator():
    import string
    for c in string.letters[:26]:
        yield (c,)

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

cur.executemany("insert into characters(c) values (?)", char_generator())

cur.execute("select c from characters")
print cur.fetchall()

Cursor.executescript(sql_script)

これは非標準の便宜メソッドで、一度に複数の SQL 文を実行することができます。メソッドは最初に COMMIT 文を発行し、次いで引数として渡された SQLスクリプトを実行します。

sql_script はバイト文字列または Unicode 文字列です。

例:

import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
    create table person(
        firstname,
        lastname,
        age
    );

    create table book(
        title,
        author,
        published
    );

    insert into book(title, author, published)
    values (
        'Dirk Gently''s Holistic Detective Agency',
        'Douglas Adams',
        1987
    );
    """)

Cursor.fetchone()

クエリ結果から次の row をフェッチして、1つのシーケンスを返します。これ以上データがない場合は None を返します。

Cursor.fetchmany([size=cursor.arraysize])

クエリ結果から次の幾つかの row をフェッチして、リストを返します。これ以上データがない場合は空のリストを返します。

一回の呼び出しで返される row の数は、 size 引数で指定できます。この引数が与えられない場合、 cursor の arraysize 属性が利用されます。このメソッドは可能な限り指定された size の数の row を fetch しようとするべきです。もし、指定された数の row が利用可能でない場合、それより少ない数の row が返されます。

size 引数とパフォーマンスの関係についての注意です。パフォーマンスを最適化するためには、大抵、 arraysize 属性を利用するのがベストです。 size 引数を利用したのであれば、次の fetchmany() の呼び出しでも同じ数を利用するのがベストです。

Cursor.fetchall()

全ての(残りの)クエリ結果の row をフェッチして、リストを返します。 cursor の arraysize 属性がこの操作のパフォーマンスに影響することに気をつけてください。これ以上の row がない場合は、空のリストが返されます。

Cursor.rowcount

一応 sqlite3 モジュールの Cursor クラスはこの属性を実装していますが、データベースエンジン自身の「影響を受けた行」/「選択された行」の決定方法は少し風変わりです。

DELETE 文では、条件を付けずに DELETE FROM table とすると SQLite は rowcount を 0 と報告します。

executemany() では、変更数が rowcount に合計されます。

Python DB API 仕様で求められているように、 rowcount 属性は「現在のカーソルがまだ executeXXX() を実行していない場合や、データベースインタフェースから最後に行った操作の結果行数を決定できない場合には、この属性は -1 となります。」

SELECT 文でも、全ての行を取得し終えるまで全部で何行になったか決められないので rowcount はいつでも -1 です。

Cursor.lastrowid

この読み込み専用の属性は、最後に変更した row の rowid を提供します。この属性は、 execute() メソッドを利用して INSERT 文を実行したときのみ設定されます。 INSERT 以外の操作や、 executemany() メソッドを利用した場合は、 lastrowid は None に設定されます。

Cursor.description

この読み込み専用の属性は、最後のクエリの結果のカラム名を提供します。 Python DB API との互換性を維持するために、各カラムに対して 7つのタプルを返しますが、タプルの後ろ6つの要素は全て None です。

この属性は SELECT 文にマッチする row が1つもなかった場合でもセットされます。

11.13.4. Row オブジェクト

class sqlite3.Row

Row インスタンスは、 Connection オブジェクトの row_factory として高度に最適化されています。タプルによく似た機能を持つ row を作成します。

カラム名とインデックスによる要素へのアクセス, イテレーション, repr(), 同値テスト, len() をサポートしています。

もし、2つの Row オブジェクトが完全に同じカラムと値を持っていた場合、それらは同値になります。

バージョン 2.6 で変更: .. Added iteration and equality (hashability).

イテレーションと同値性、ハッシュ可能

keys()

このメソッドはカラム名のタプルを返します。クエリ直後から、これは Cursor.description の各タプルの最初のメンバになります。

バージョン 2.6 で追加.

Rowの例のために、まずサンプルのテーブルを初期化します。

conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")
conn.commit()
c.close()

そして、 Row を使ってみます。

>>> conn.row_factory = sqlite3.Row
>>> c = conn.cursor()
>>> c.execute('select * from stocks')
<sqlite3.Cursor object at 0x7f4e7dd8fa80>
>>> r = c.fetchone()
>>> type(r)
<type 'sqlite3.Row'>
>>> r
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14)
>>> len(r)
5
>>> r[2]
u'RHAT'
>>> r.keys()
['date', 'trans', 'symbol', 'qty', 'price']
>>> r['qty']
100.0
>>> for member in r: print member
...
2006-01-05
BUY
RHAT
100.0
35.14

11.13.5. SQLite と Python の型

11.13.5.1. 入門編

SQLite が最初からサポートしているのは次の型です。

NULL, INTEGER, REAL, TEXT, BLOB

したがって、次の Python の型は問題なく SQLite に送り込めます:

Python の型 | SQLite の型
None | NULL
int | INTEGER
long | INTEGER
float | REAL
str (UTF8-encoded) | TEXT
unicode | TEXT
buffer | BLOB

SQLite の型から Python の型へのデフォルトでの変換は以下の通りです:

SQLite の型 | Python の型
NULL | None
INTEGER | int または long, (サイズによる)
REAL | float
TEXT | text_factory に依存する。デフォルトでは unicode
BLOB | buffer

sqlite3 モジュールの型システムは二つの方法で拡張できます。一つはオブジェクト適合(adaptation)を通じて追加された Python の型を SQLite に格納することです。もう一つは変換関数(converter)を通じて sqlite3 モジュールに SQLite の型を違った Python の型に変換させることです。

11.13.5.2. 追加された Python の型を SQLite データベースに格納するために適合関数を使う

既に述べたように、SQLite が最初からサポートする型は限られたものだけです。それ以外の Python の型を SQLite で使うには、その型を sqlite3 モジュールがサポートしている型の一つに 適合 させなくてはなりません。サポートしている型というのは、NoneType, int, long, float, str, unicode, buffer です。

sqlite3 モジュールは PEP 246 [http://www.python.org/dev/peps/pep-0246] に述べられているような Python オブジェクト適合を用います。使われるプロトコルは PrepareProtocol です。

sqlite3 モジュールで望みの Python の型をサポートされている型の一つに適合させる方法は二つあります。

11.13.5.2.1. オブジェクト自身で適合するようにする

自分でクラスを書いているならばこの方法が良いでしょう。次のようなクラスがあるとします:

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

さてこの点を SQLite の一つのカラムに収めたいと考えたとしましょう。最初にしなければならないのはサポートされている型の中から点を表現するのに使えるものを選ぶことです。ここでは単純に文字列を使うことにして、座標を区切るのにはセミコロンを使いましょう。次に必要なのはクラスに変換された値を返す __conform__(self, protocol) メソッドを追加することです。引数 protocol は PrepareProtocol になります。

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __conform__(self, protocol):
        if protocol is sqlite3.PrepareProtocol:
            return "%f;%f" % (self.x, self.y)

con = sqlite3.connect(":memory:")
cur = con.cursor()

p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]

11.13.5.2.2. 適合関数を登録する

もう一つの可能性は型を文字列表現に変換する関数を作り register_adapter() でその関数を登録することです。

ノート

適合させる型/クラスは新スタイルクラス(new-style class)でなければなりません。すなわち、 object を基底クラスの一つとしていなければなりません。

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

def adapt_point(point):
    return "%f;%f" % (point.x, point.y)

sqlite3.register_adapter(Point, adapt_point)

con = sqlite3.connect(":memory:")
cur = con.cursor()

p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]

sqlite3 モジュールには二つの Python 標準型 datetime.date と datetime.datetime に対するデフォルト適合関数があります。いま datetime.datetime オブジェクトを ISO 表現でなく Unix タイムスタンプとして格納したいとしましょう。

import sqlite3
import datetime, time

def adapt_datetime(ts):
    return time.mktime(ts.timetuple())

sqlite3.register_adapter(datetime.datetime, adapt_datetime)

con = sqlite3.connect(":memory:")
cur = con.cursor()

now = datetime.datetime.now()
cur.execute("select ?", (now,))
print cur.fetchone()[0]

11.13.5.3. SQLite の値を好きな Python 型に変換する

適合関数を書くことで好きな Python 型を SQLite に送り込めるようになりました。しかし、本当に使い物になるようにするには Python から SQLite さらに Python へという往還(roundtrip)の変換ができる必要があります。

そこで変換関数(converter)です。

Point クラスの例に戻りましょう。x, y 座標をセミコロンで区切った文字列として SQLite に格納したのでした。

まず、文字列を引数として取り Point オブジェクトをそれから構築する変換関数を定義します。

ノート

変換関数は SQLite に送り込んだデータ型に関係なく 常に 文字列を渡されます。

def convert_point(s):
    x, y = map(float, s.split(";"))
    return Point(x, y)

次に sqlite3 モジュールにデータベースから取得したものが本当に点であることを教えなければなりません。二つの方法があります:

宣言された型を通じて暗黙的に

カラム名を通じて明示的に

どちらの方法も モジュールの関数と定数 節の中で説明されています。それぞれ PARSE_DECLTYPES 定数と PARSE_COLNAMES 定数の項目です。

以下の例で両方のアプローチを紹介します。

import sqlite3

class Point(object):
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __repr__(self):
        return "(%f;%f)" % (self.x, self.y)

def adapt_point(point):
    return "%f;%f" % (point.x, point.y)

def convert_point(s):
    x, y = map(float, s.split(";"))
    return Point(x, y)

# Register the adapter
sqlite3.register_adapter(Point, adapt_point)

# Register the converter
sqlite3.register_converter("point", convert_point)

p = Point(4.0, -3.2)

#########################
# 1) Using declared types
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute("create table test(p point)")

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("select p from test")
print "with declared types:", cur.fetchone()[0]
cur.close()
con.close()

#######################
# 1) Using column names
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(p)")

cur.execute("insert into test(p) values (?)", (p,))
cur.execute('select p as "p [point]" from test')
print "with column names:", cur.fetchone()[0]
cur.close()
con.close()

11.13.5.4. デフォルトの適合関数と変換関数

datetime モジュールの date 型および datetime 型のためのデフォルト適合関数があります。これらの型は ISO 日付 / ISO タイムスタンプとして SQLite に送られます。

デフォルトの変換関数は datetime.date 用が “date” という名前で、 datetime.datetime 用が “timestamp” という名前で登録されています。

これにより、多くの場合特別な細工無しに Python の日付 / タイムスタンプを使えます。適合関数の書式は実験的な SQLite の date/time 関数とも互換性があります。

以下の例でこのことを確かめます。

import sqlite3
import datetime

con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(d date, ts timestamp)")

today = datetime.date.today()
now = datetime.datetime.now()

cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
cur.execute("select d, ts from test")
row = cur.fetchone()
print today, "=>", row[0], type(row[0])
print now, "=>", row[1], type(row[1])

cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
row = cur.fetchone()
print "current_date", row[0], type(row[0])
print "current_timestamp", row[1], type(row[1])

11.13.6. トランザクション制御

デフォルトでは、 sqlite3 モジュールはデータ変更言語(DML)文(すなわち INSERT/UPDATE/DELETE/REPLACE)の前に暗黙のうちにトランザクションを開始し、非DML、非クエリ文(すなわち SELECT や上記のいずれでもないもの。)の前にトランザクションをコミットします。

ですから、もしトランザクション中に CREATE TABLE ..., VACUUM, PRAGMA といったコマンドを発行すると、 sqlite3 モジュールはそのコマンドの実行前に暗黙のうちにコミットします。このようにする理由は二つあります。第一にこうしたコマンドのうちの幾つかはトランザクション中ではうまく動きません。第二に sqlite3 はトランザクションの状態(トランザクションが掛かっているかどうか) を追跡する必要があるからです。

sqlite3 が暗黙のうちに実行する BEGIN 文の種類(またはそういうものを使わないこと)を connect() 呼び出しの isolation_level パラメータを通じて、または接続の isolation_level プロパティを通じて、制御することができます。

もし 自動コミットモード が使いたければ、 isolation_level は None にしてください。

そうでなければデフォルトのまま BEGIN 文を使い続けるか、 SQLite がサポートする分離レベル “DEFERRED”, “IMMEDIATE” または “EXCLUSIVE” を設定してください。

11.13.7. sqlite3 の効率的な使い方

11.13.7.1. ショートカットメソッドを使う

Connection オブジェクトの非標準的なメソッド execute(), executemany(), executescript() を使うことで、 (しばしば余計な) Cursor オブジェクトをわざわざ作り出さずに済むので、コードをより簡潔に書くことができます。 Cursor オブジェクトは暗黙裡に生成されショートカットメソッドの戻り値として受け取ることができます。この方法を使えば、 SELECT 文を実行してその結果について反復することが、 Connection オブジェクトに対する呼び出し一つで行なえます。

import sqlite3

persons = [
    ("Hugo", "Boss"),
    ("Calvin", "Klein")
    ]

con = sqlite3.connect(":memory:")

# Create the table
con.execute("create table person(firstname, lastname)")

# Fill the table
con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)

# Print the table contents
for row in con.execute("select firstname, lastname from person"):
    print row

# Using a dummy WHERE clause to not let SQLite take the shortcut table deletes.
print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows"

11.13.7.2. 位置ではなく名前でカラムにアクセスする

sqlite3 モジュールの有用な機能の一つに、行生成関数として使われるための sqlite3.Row クラスがあります。

このクラスでラップされた行は、位置インデクス(タプルのような)でも大文字小文字を区別しない名前でもアクセスできます:

import sqlite3

con = sqlite3.connect("mydb")
con.row_factory = sqlite3.Row

cur = con.cursor()
cur.execute("select name_last, age from people")
for row in cur:
    assert row[0] == row["name_last"]
    assert row["name_last"] == row["nAmE_lAsT"]
    assert row[1] == row["age"]
    assert row[1] == row["AgE"]

11.13.7.3. コネクションをコンテキストマネージャーとして利用する

バージョン 2.6 で追加.

Connection オブジェクトはコンテキストマネージャーとして利用して、トランザクションを自動的にコミットしたりロールバックすることができます。例外が発生したときにトランザクションはロールバックされ、それ以外の場合、トランザクションはコミットされます。

import sqlite3

con = sqlite3.connect(":memory:")
con.execute("create table person (id integer primary key, firstname varchar unique)")

# Successful, con.commit() is called automatically afterwards
with con:
    con.execute("insert into person(firstname) values (?)", ("Joe",))

# con.rollback() is called after the with block finishes with an exception, the
# exception is still raised and must be catched
try:
    with con:
        con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
    print "couldn't add Joe twice"

11.13.8. 既知の問題

11.13.8.1. マルチスレッド

古いバージョンの SQLite はスレッド間でのコネクションの共有に問題がありました。その理由は、Python のモジュールではスレッド間のコネクションとカーソルの共有ができないためです。依然としてそのようなことをしようとすると、実行時に例外を受け取るでしょう。

唯一の例外は interrupt() メソッドで、これだけが異なるスレッドから呼び出せます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ

この章で説明されるモジュールは zlib, gzip, bzip2 アルゴリズムによるデータの圧縮と、 ZIP, tar フォーマットのアーカイブ作成をサポートします。

12.1. zlib — gzip 互換の圧縮

12.2. gzip — gzip ファイルのサポート

12.2.1. 使い方の例

12.3. bz2 — bzip2 互換の圧縮ライブラリ

12.3.1. ファイルの圧縮/解凍

12.3.2. 逐次的な圧縮/解凍

12.3.3. 一括圧縮/解凍

12.4. zipfile — ZIP アーカイブの処理

12.4.1. ZipFile オブジェクト

12.4.2. PyZipFile オブジェクト

12.4.3. ZipInfo オブジェクト

12.5. tarfile — tar アーカイブファイルを読み書きする

12.5.1. TarFile オブジェクト

12.5.2. TarInfo オブジェクト

12.5.3. 例

12.5.4. サポートされる tar のフォーマット

12.5.5. Unicode に関する問題

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ »

12.1. zlib — gzip 互換の圧縮

このモジュールでは、データ圧縮を必要とするアプリケーションが zlib ライブラリを使って圧縮および解凍を行えるようにします。 zlib ライブラリ自体の Webページは http://www.zlib.net です。 Pythonモジュールと zlib ライブラリの1.1.3より前のバージョンには互換性のない部分があることが知られています。1.1.3にはセキュリティホールが存在しますので、1.1.4以降のバージョンを利用することをお勧めします。

zlib の関数にはたくさんのオプションがあり、しばしば特定の順番で使う必要があります。このドキュメントでは順番のことについて全てを説明し尽くそうとはしていません。信頼できる情報が必要ならば http://www.zlib.net/manual.html にある zlib のマニュアルを参照するようにしてください。

.gz ファイルの読み書きのためには、 gzip モジュールを参照してください。その他のアーカイブフォーマットについては、 bz2, zipfile, tarfile モジュールを参照してください。

このモジュールで利用可能な例外と関数を以下に示します:

exception zlib.error

圧縮および解凍時のエラーによって送出される例外。

zlib.adler32(data[, value])

data のAdler-32 チェックサムを計算します。（Adler-32 チェックサムは、おおむね CRC32 と同等の信頼性を持ちながらはるかに高速に計算することができます。） value が与えられていれば、 value はチェックサム計算の初期値として使われます。それ以外の場合には固定のデフォルト値が使われます。この機能によって、複数の入力を結合したデータ全体にわたり、通しのチェックサムを計算することができます。このアルゴリズムは暗号論的には強力とはいえないので、認証やデジタル署名などに用いるべきではありません。このアルゴリズムはチェックサムアルゴリズムとして用いるために設計されたものなので、汎用的なハッシュアルゴリズムには向きません。

この関数は常に整数オブジェクトを返します。

ノート

全てのPythonのバージョンとプラットフォームで共通な数値を生成するには、 adler32(data) & 0xffffffff を利用してください。もしチェックサムをパックされたバイナリフォーマットのためにしか利用しないのであれば、符号が関係なくなり、32bitのバイナリ値としては戻り値は正しいので、この処理は必要ありません。

バージョン 2.6 で変更: 戻り値の範囲は、プラットフォームに関係なく [-2**31, 2**31-1] になりました。古いバージョンでは、この値は幾つかのプラットフォームでは符号付き、別のプラットフォームでは符号なしになっていました。

バージョン 3.0 で変更: 戻り値の範囲は、プラットフォームに関係なく [0, 2**32-1] です。

zlib.compress(string[, level])

string で与えられた文字列を圧縮し、圧縮されたデータを含む文字列を返します。 level は 1 から 9 までの整数をとる値で、圧縮のレベルを制御します。 1 は最も高速で最小限の圧縮を行います。 9 はもっとも低速になりますが最大限の圧縮を行います。デフォルトの値は 6 です。圧縮時に何らかのエラーが発生した場合、 error 例外を送出します。

zlib.compressobj([level])

一度にメモリ上に置くことができないようなデータストリームを圧縮するための圧縮オブジェクトを返します。 level は 1 から 9 までの整数で、圧縮レベルを制御します。 1 はもっとも高速で最小限の圧縮を、 9 はもっとも低速になりますが最大限の圧縮を行います。デフォルトの値は 6 です。

zlib.crc32(data[, value])

data の CRC (Cyclic Redundancy Check, 巡回符号方式) チェックサムを計算します。 value が与えられていれば、チェックサム計算の初期値として使われます。与えられていなければデフォルトの初期値が使われます。 value を与えることで、複数の入力を結合したデータ全体にわたり、通しのチェックサムを計算することができます。このアルゴリズムは暗号論的には強力ではなく、認証やデジタル署名に用いるべきではありません。アルゴリズムはチェックサムアルゴリズムとして設計されているので、汎用のハッシュアルゴリズムには向きません。

この関数は常に整数オブジェクトを返します。

ノート

全てのPythonのバージョンとプラットフォームで共通な数値を生成するには、 crc32(data) & 0xffffffff を利用してください。もしチェックサムをパックされたバイナリフォーマットのためにしか利用しないのであれば、符号が関係なくなり、32bitのバイナリ値としては戻り値は正しいので、この処理は必要ありません。

バージョン 2.6 で変更: 戻り値の範囲は、プラットフォームに関係なく [-2**31, 2**31-1] になりました。古いバージョンでは、この値は幾つかのプラットフォームでは符号付き、別のプラットフォームでは符号なしになっていました。

バージョン 3.0 で変更: 戻り値の範囲は、プラットフォームに関係なく [0, 2**32-1] です。

zlib.decompress(string[, wbits[, bufsize]])

string 内のデータを解凍して、解凍されたデータを含む文字列を返します。 wbits パラメータはウィンドウバッファの大きさを制御します。より詳しい説明は後で行います。 bufsize が与えられていれば、出力バッファの初期サイズとして使われます。解凍処理に何らかのエラーが生じた場合、 error 例外を送出します。

wbits の絶対値は、データを圧縮する際に用いられるヒストリバッファのサイズ (ウィンドウサイズ) に対し、 2 を底とする対数をとったものです。最近のほとんどのバージョンの zlib ライブラリを使っているなら、 wbits の絶対値は 8 から 15 とするべきです。より大きな値はより良好な圧縮につながりますが、より多くのメモリを必要とします。ストリームを解凍するとき、 wbits は元のストリームを圧縮するために使用したサイズより小さくしてはいけません。小さすぎる値を使用すると例外が発生します。そのため、デフォルトの値は 15 です。 wbits の値が負の場合、標準的な gzip ヘッダを出力しません。

bufsize は解凍されたデータを保持するためのバッファサイズの初期値です。バッファの空きは必要に応じて必要なだけ増加するので、必ずしも正確な値を指定する必要はありません。この値のチューニングでできることは、 malloc() が呼ばれる回数を数回減らすことぐらいです。デフォルトのサイズは 16384 です。

zlib.decompressobj([wbits])

メモリ上に一度に展開できないようなデータストリームを解凍するために用いられる解凍オブジェクトを返します。 wbits パラメータはウィンドウバッファのサイズを制御します。

圧縮オブジェクトは以下のメソッドをサポートします:

Compress.compress(string)

string を圧縮し、圧縮されたデータを含む文字列を返します。この文字列は少なくとも string の一部分のデータに対する圧縮データを含みます。このデータは以前に呼んだ compress() が返した出力と結合することができます。入力の一部は以後の処理のために内部バッファに保存されることもあります。

Compress.flush([mode])

未処理の入力データが処理され、この未処理部分を圧縮したデータを含む文字列が返されます。 mode は定数 Z_SYNC_FLUSH 、 Z_FULL_FLUSH 、または Z_FINISH のいずれかをとり、デフォルト値は Z_FINISH です。 Z_SYNC_FLUSH および Z_FULL_FLUSH ではこれ以後にもデータ文字列を圧縮できるモードです。一方、 Z_FINISH は圧縮ストリームを閉じ、これ以後のデータの圧縮を禁止します。 mode に Z_FINISH を設定して flush() メソッドを呼び出した後は、 compress() メソッドを再び呼ぶべきではありません。唯一の現実的な操作はこのオブジェクトを削除することだけです。

Compress.copy()

圧縮オブジェクトのコピーを返します。これを使うと先頭部分が共通している複数のデータを効率的に圧縮することができます。

バージョン 2.5 で追加.

解凍オブジェクトは以下のメソッドと 2 つの属性をサポートします:

Decompress.unused_data

圧縮データの末尾より後のバイト列が入った文字列です。すなわち、この値は圧縮データの入っているバイト列の最後の文字が利用可能になるまでは "" のままとなります。入力文字列全てが圧縮データを含んでいた場合、この属性は "" 、すなわち空文字列になります。

圧縮データ文字列がどこで終了しているかを決定する唯一の方法は、実際にそれを解凍することです。つまり、大きなファイルの一部分に圧縮データが含まれているときに、その末端を調べるためには、データをファイルから読み出し、空でない文字列を後ろに続けて、 unused_data が空文字列でなくなるまで、解凍オブジェクトの decompress() メソッドに入力しつづけるしかありません。

Decompress.unconsumed_tail

解凍されたデータを収めるバッファの長さ制限を超えたために、最も最近の decompress() 呼び出しで処理しきれなかったデータを含む文字列です。このデータはまだ zlib 側からは見えていないので、正しい解凍出力を得るには以降の decompress() メソッド呼び出しに (場合によっては後続のデータが追加された) データを差し戻さなければなりません。

Decompress.decompress(string[, max_length])

string を解凍し、少なくとも string の一部分に対応する解凍されたデータを含む文字列を返します。このデータは以前に decompress() メソッドを呼んだ時に返された出力と結合することができます。入力データの一部分が以後の処理のために内部バッファに保存されることもあります。

オプションパラメータ max_length が与えられると、返される解凍データの長さが max_length 以下に制限されます。このことは入力した圧縮データの全てが処理されるとは限らないことを意味し、処理されなかったデータは unconsumed_tail 属性に保存されます。解凍処理を継続したいならば、この保存されたデータを以降の decompress() 呼び出しに渡さなくてはなりません。 max_length が与えられなかった場合、全ての入力が解凍され、 unconsumed_tail 属性は空文字列になります。

Decompress.flush([length])

未処理の入力データを全て処理し、最終的に圧縮されなかった残りの出力文字列を返します。 flush() を呼んだ後、 decompress() を再度呼ぶべきではありません。このときできる唯一の現実的な操作はオブジェクトの削除だけです。

オプション引数 length は出力バッファの初期サイズを決めます。

Decompress.copy()

解凍オブジェクトのコピーを返します。これを使うとデータストリームの途中にある解凍オブジェクトの状態を保存でき、未来のある時点で行なわれるストリームのランダムなシークをスピードアップするのに利用できます。

バージョン 2.5 で追加.

参考

Module gzip

Reading and writing gzip -format files.

http://www.zlib.net

zlib ライブラリホームページ

http://www.zlib.net/manual.html

zlib ライブラリの多くの関数の意味と使い方を解説したマニュアル

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ »

12.2. gzip — gzip ファイルのサポート

このモジュールは、ファイルをGNUの gzip, gunzip のように圧縮、伸長するシンプルなインタフェースを提供しています。

データ圧縮は zlib モジュールで提供されています。

gzip モジュールは、Pythonのファイルオブジェクトに似た GzipFile クラスを提供しています。 GzipFile クラスは gzip フォーマットのファイルを読み書きします。自動的にデータを圧縮・伸張するので、外からは通常のファイルオブジェクトのように見えます。

compress や pack 等によって作られる、 gzip や gunzip が伸長できる他のファイルフォーマットについては、このモジュールは対応していないので注意してください。

他のアーカイブフォーマットについては、 bz2, zipfile, tarfile モジュールを参照してください。

このモジュールでは以下の項目を定義しています:

class gzip.GzipFile([filename[, mode[, compresslevel[, fileobj[, mtime]]]]])

GzipFile クラスのコンストラクタです。 GzipFile オブジェクトは readinto() と truncate() メソッドを除くほとんどのファイルオブジェクトのメソッドをシミュレートします。少なくとも fileobj および filename は有効な値でなければなりません。

クラスの新しいインスタンスは、 fileobj に基づいて作成されます。 fileobj は通常のファイル、 StringIO オブジェクト、そしてその他ファイルをシミュレートできるオブジェクトでかまいません。値はデフォルトでは None で、ファイルオブジェクトを生成するために filename を開きます。

gzip ファイルヘッダ中には、ファイルが解凍されたときの元のファイル名を収めることができますが、 fileobj が None でない場合、引数 filename がファイル名として認識できる文字列であれば、 filename はファイルヘッダに収めるためだけに使われます。そうでない場合（この値はデフォルトでは空文字列です）、元のファイル名はヘッダに収められません。

mode 引数は、ファイルを読み出すのか、書き込むのかによって、 'r', 'rb', 'a', 'ab', 'w', そして 'wb' のいずれかになります。 fileobj のファイルモードが認識可能な場合、 mode はデフォルトで fileobj のモードと同じになります。そうでない場合、デフォルトのモードは 'rb' です。 ‘b’ フラグがついていなくても、ファイルがバイナリモードで開かれることを保証するために ‘b’ フラグが追加されます。これはプラットフォーム間での移植性のためです。

compresslevel 引数は 1 から 9 までの整数で、圧縮のレベルを制御します。 1 は最も高速で最小限の圧縮しか行いません。 9 は最も低速ですが、最大限の圧縮を行います。デフォルトの値は 9 です。

mtime 引数はオプションで、圧縮時にストリームに書かれる数値型のタイムスタンプです。 gzip で圧縮された全てのストリームはタイムスタンプを必要とします。省略された場合や None が渡された場合は、現在の時刻が利用されます。このモジュールは伸長時にはタイムスタンプを無視しますが、 gunzip などのいくつかのプログラムはタイムスタンプを利用します。タイムスタンプのフォーマットは time.time() の戻り値や、 os.stat() の戻り値となるオブジェクトの st_mtime メンバと同じです。

圧縮したデータの後ろにさらに何か追記したい場合もあるので、 GzipFile オブジェクトの close() メソッド呼び出しは fileobj をクローズしません。この機能によって、書き込みのためにオープンした StringIO オブジェクトを fileobj として渡し、(GzipFile を close() した後に) StringIO オブジェクトの getvalue() メソッドを使って書き込んだデータの入っているメモリバッファを取得することができます。

GzipFile はイテレーションと with 文をサポートします。

バージョン 2.7 で変更: with 構文のサポートが追加されました。

バージョン 2.7 で変更: zero-pad されたファイルのサポートが追加されました。

gzip.open(filename[, mode[, compresslevel]])

GzipFile(filename, mode, compresslevel) の短縮形です。引数 filename は必須です。デフォルトで mode は 'rb' に、 compresslevel は 9 に設定されています。

12.2.1. 使い方の例

圧縮されたファイルを読み込む例:

import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()

GZIP圧縮されたファイルを作成する例:

import gzip
content = "Lots of content here"
f = gzip.open('/home/joe/file.txt.gz', 'wb')
f.write(content)
f.close()

既存のファイルをGZIP圧縮する例:

import gzip
f_in = open('/home/joe/file.txt', 'rb')
f_out = gzip.open('/home/joe/file.txt.gz', 'wb')
f_out.writelines(f_in)
f_out.close()
f_in.close()

参考

Module zlib

gzip ファイル形式のサポートを行うために必要な基本ライブラリモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ »

12.3. bz2 — bzip2 互換の圧縮ライブラリ

バージョン 2.3 で追加.

このモジュールでは bz2 圧縮ライブラリのためのわかりやすいインタフェースを提供します。モジュールでは完全なファイルインタフェース、データを一括して圧縮/解凍する関数、データを逐次的に圧縮/解凍するための型を実装しています。

その他のアーカイブフォーマットに関しては、 gzip, zipfile, tarfile モジュールを参照してください。

bz2 モジュールが提供している機能を以下にまとめます。

BZ2File クラスは、 readline(), readlines(), writelines(), seek() 等を含む、完全なファイルインタフェースを実装します。

BZ2File クラスは seek() をエミュレーションでサポートします。

BZ2File クラスは広範囲の改行文字バリエーション(universal newline) をサポートします。

BZ2File クラスは、ファイルオブジェクトの先読みアルゴリズムを元にして実装されている、最適化された行単位のイテレーション機能を提供します。

BZ2Compressor および BZ2Decompressor クラスでは逐次的圧縮（解凍）をサポートしています。

compress() および decompress() 関数は、一括圧縮/解凍機能を提供しています。

個別のロックメカニズムによってスレッド安全性を持っています。

12.3.1. ファイルの圧縮/解凍

BZ2File クラスは圧縮ファイルの操作機能を提供しています。

class bz2.BZ2File(filename[, mode[, buffering[, compresslevel]]])

bz2 ファイルを開きます。 mode は 'r' (デフォルト)または 'w' で、それぞれ読み込みと書き込みに対応します。書き込み用に開いた場合、ファイルが存在しないなら新しく作成し、そうでない場合ファイルを切り詰ます。 buffering パラメタを与えた場合、 0 はバッファリングなしを表し、それよりも大きい値はバッファサイズになります。デフォルトでは 0 です。圧縮レベル (compresslevel) を与える場合、値は 1 から 9 までの整数値でなければなりません。デフォルトの値は 9 です。ファイルを読み込む際に、広範囲の改行文字バリエーション(universal newline)をサポートさせたい場合は 'U' を mode に追加します。このモードで開かれた入力ファイルの行末はどれも、Pythonからは '\n' として見えます。また、開かれているファイルオブジェクトは newlines 属性を持ち、 None (まだ改行文字を読み込んでいない時), '\r', '\n', '\r\n' またはそれまでに読み込んだ全ての改行文字バリエーションを含むタプルになります。広範囲の改行文字サポートが利用できるのは読み込みだけです。 BZ2File が生成するインスタンスは通常のファイルインスタンスと同様のイテレーション操作をサポートしています。

BZ2File は with 構文をサポートしています。

バージョン 2.7 で変更: with 構文のサポートが追加されました。

close()

ファイルを閉じます。オブジェクトのデータ属性 closed を真にします。閉じたファイルはそれ以後入出力操作の対象にできません。 close() 自体の呼び出しはエラーを引き起こすことなく何度も実行できます。

read([size])

最大で size バイトの解凍されたデータを読み出し、文字列として返します。 size 引数を負の値にした場合や省略した場合、EOF まで読み出します。

readline([size])

ファイルから次の 1 行を読み出し、改行文字も含めて文字列を返します。負でない size 値は、返される文字列の最大バイト長を制限します (その場合不完全な行を返すこともあります)。 EOF の時には空文字列を返します。

readlines([size])

ファイルから読み取った各行の文字列からなるリストを返します。オプション引数 size を与えた場合、文字列リストの合計バイト数の大まかな上限の指定になります。

xreadlines()

前のバージョンとの互換性のために用意されています。 BZ2File オブジェクトはかつて xreadlines モジュールで提供されていたパフォーマンス最適化を含んでいます。

バージョン 2.3 で撤廃: このメソッドは file オブジェクトの同名のメソッドとの互換性のために用意されていますが、現在は推奨されないメソッドです。代りに for line in file を使ってください。

seek(offset[, whence])

ファイルの読み書き位置を移動します。引数 offset はバイト数で指定したオフセット値です。オプション引数 whence はデフォルトで os.SEEK_SET もしくは 0 (ファイルの先頭からのオフセットで、offset >= 0 になるはず) です。他にとり得る値は 1 (現在のファイル位置からの相対位置で、正負どちらの値もとり得る)、および 2 (ファイルの終末端からの相対位置で、通常は負の値になるが、多くのプラットフォームではファイルの終末端を越えて seek できる) です。

bz2 ファイルの seek はエミュレーションであり、パラメタの設定によっては処理が非常に低速になるかもしれないので注意してください。

tell()

現在のファイル位置を整数（long 整数になるかもしれません）で返します。

write(data)

ファイルに文字列 data を書き込みます。バッファリングのため、ディスク上のファイルに書き込まれたデータを反映させるには close() が必要になるかもしれないので注意してください。

writelines(sequence_of_strings)

複数の文字列からなるシーケンスをファイルに書き込みます。それぞれの文字列を書き込む際に改行文字を追加することはありません。シーケンスはイテレーション処理で文字列を取り出せる任意のオブジェクトにできます。この操作はそれぞれの文字列を write() を呼んで書き込むのと同じ操作です。

12.3.2. 逐次的な圧縮/解凍

逐次的な圧縮および解凍は BZ2Compressor および BZ2Decompressor クラスを用いて行います。

class bz2.BZ2Compressor([compresslevel])

新しい圧縮オブジェクトを作成します。このオブジェクトはデータを逐次的に圧縮できます。一括してデータを圧縮したいのなら、代わりに compress() 関数を使ってください。 compresslevel パラメタを与える場合、この値は 1 と 9 の間の整数でなければなりません。デフォルトの値は 9 です。

compress(data)

圧縮オブジェクトに追加のデータを入力します。圧縮データのチャンクを生成できた場合にはチャンクを返します。圧縮データの入力を終えた後は圧縮処理を終えるために flush() を呼んでください。内部バッファに残っている未処理のデータを返します。

flush()

圧縮処理を終え、内部バッファに残されているデータを返します。このメソッドの呼び出し以降は同じ圧縮オブジェクトを使ってはなりません。

class bz2.BZ2Decompressor

新しい解凍オブジェクトを生成します。このオブジェクトは逐次的にデータを解凍できます。一括してデータを解凍したいのなら、代わりに decompress() 関数を使ってください。

decompress(data)

解凍オブジェクトに追加のデータを入力します。可能な限り、解凍データのチャンクを生成できた場合にはチャンクを返します。ストリームの末端に到達した後に解凍処理を行おうとした場合には、例外 EOFError を送出します。ストリームの終末端の後ろに何らかのデータがあった場合、解凍処理はこのデータを無視し、オブジェクトの unused_data 属性に収めます。

12.3.3. 一括圧縮/解凍

一括での圧縮および解凍を行うための関数、 compress() および decompress() が提供されています。

bz2.compress(data[, compresslevel])

data を一括して圧縮します。データを逐次的に圧縮したいなら、代わりに BZ2Compressor を使ってください。もし compresslevel パラメタを与えるなら、この値は 1 から 9 の間の値をとらなくてはなりません。デフォルトの値は 9 です。

bz2.decompress(data)

data を一括して解凍します。データを逐次的に解凍したいなら、代わりに BZ2Decompressor を使ってください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ »

12.4. zipfile — ZIP アーカイブの処理

バージョン 1.6 で追加.

ZIP は一般によく知られているアーカイブ（書庫化）および圧縮の標準ファイルフォーマットです。このモジュールでは ZIP 形式のファイルの作成、読み書き、追記、書庫内のファイル一覧の作成を行うためのツールを提供します。より高度な使い方でこのモジュールを利用したいなら、 PKZIP Application Note [http://www.pkware.com/documents/casestudies/APPNOTE.TXT]. に定義されている ZIP ファイルフォーマットを理解することが必要になるでしょう。

このモジュールは現在のところ、マルチディスク ZIP ファイルを扱うことはできません ZIP64 拡張を利用する ZIP ファイル (サイズが 4GB を超えるような ZIP ファイル) は扱えます。このモジュールは暗号化されたアーカイブの復号をサポートしますが、現在のところ、暗号化ファイルを作成することはできません。 C言語ではなく、Pythonで実装されているため、復号は非常に遅いです。

他のアーカイブ形式については、 bz2 、 gzip 、および、 tarfile モジュールを参照下さい。

このモジュールでは、以下の項目が定義されています:

exception zipfile.BadZipfile

不備のある ZIP ファイル操作の際に送出されるエラー (旧名称: zipfile.error)

exception zipfile.LargeZipFile

ZIP ファイルが ZIP64 の機能を必要とするとき、その機能が有効にされていないと送出されるエラー

class zipfile.ZipFile

ZIP ファイルの読み書きのためのクラスです。コンストラクタの詳細については、 ZipFile オブジェクト 節) を参照してください。

class zipfile.PyZipFile

Python ライブラリを含む ZIP アーカイブを生成するためのクラスです。

class zipfile.ZipInfo([filename[, date_time]])

アーカイブ中のメンバに関する情報を提供するために用いられるクラスです。このクラスのインスタンスは ZipFile オブジェクトの getinfo() および infolist() メソッドによって返されます。 zipfile モジュールを利用するほとんどのユーザはこのオブジェクトを自ら生成する必要はなく、モジュールが生成して返すオブジェクトを利用するだけでしょう。 filename はアーカイブメンバの完全な名前で、 date_time はファイルの最終更新時刻を記述する、6つのフィールドからなるタプルでなくてはなりません。各フィールドについては ZipInfo オブジェクト 節を参照してください。

zipfile.is_zipfile(filename)

filename が正しいマジックナンバをもつ ZIP ファイルのときに True を返し、そうでない場合 False を返します。 filename にはファイルやファイルライクオブジェクトを渡すこともできます。

バージョン 2.7 で変更: ファイルやファイルライクオブジェクトをサポート

zipfile.ZIP_STORED

アーカイブメンバが圧縮されていないことを表す数値定数です。

zipfile.ZIP_DEFLATED

通常の ZIP 圧縮手法を表す数値定数。ZIP 圧縮は zlib モジュールを必要とします。現在のところ他の圧縮手法はサポートされていません。

参考

PKZIP Application Note [http://www.pkware.com/documents/casestudies/APPNOTE.TXT]

ZIP ファイル形式およびアルゴリズムを作成した Phil Katz によるドキュメント。

Info-ZIP Home Page [http://www.info-zip.org/]

Info-ZIP プロジェクトによる ZIP アーカイブプログラム及びプログラム開発ライブラリに関する情報。

12.4.1. ZipFile オブジェクト

class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

ZIP ファイルを開きます。 file はファイルへのパス名 (文字列) またはファイルのように振舞うオブジェクトのどちらでもかまいません。 mode パラメタは、既存のファイルを読むためには 'r' 、既存のファイルを切り詰めたり新しいファイルに書き込むためには 'w' 、追記を行うためには 'a' でなくてはなりません。 mode が 'a' で file が既存の ZIP ファイルを参照している場合、追加するファイルは既存のファイル中の ZIP アーカイブに追加されます。 file が ZIP を参照していない場合、新しい ZIP アーカイブが生成され、既存のファイルの末尾に追加されます。このことは、ある ZIP ファイルを他のファイル(例えば python.exe)に追加することを意味しています。

バージョン 2.6 で変更: mode が 'a' でファイルが存在しない場合、ファイルが作られるようになりました。

compression はアーカイブを書き出すときの ZIP 圧縮法で、 ZIP_STORED または ZIP_DEFLATED でなくてはなりません。不正な値を指定すると RuntimeError が送出されます。また、 ZIP_DEFLATED 定数が指定されているのに zlib を利用することができない場合も、 RuntimeError が送出されます。デフォルト値は ZIP_STORED です。 allowZip64 が True ならば 2GB より大きな ZIP ファイルの作成時に ZIP64 拡張を使用します。これが False (デフォルト) ならば、 zipfile モジュールは ZIP64 拡張が必要になる場面で例外を送出します。 ZIP64 拡張はデフォルトでは無効にされていますが、これは Unix の zip および unzip (InfoZIP ユーティリティ) コマンドがこの拡張をサポートしていないからです。

バージョン 2.7.1 で変更: ファイルが 'a' か 'w' モードで作成されて、アーカイブに1ファイルも追加しないまま close() した場合に、空のアーカイブとして正しいZIPの構造がそのファイルに書かれるようになりました。

ZipFile はコンテキストマネージャーにもなっているので、 with 文をサポートしています。次の例では、 myzip は with 文のブロックが終了したときに、 (たとえ例外が発生したとしても) close されます。

with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')

バージョン 2.7 で追加: ZipFile にコンテキストマネージャーの機能を追加しました。

ZipFile.close()

アーカイブファイルを閉じます。 close() はプログラムを終了する前に必ず呼び出さなければなりません。さもないとアーカイブ上の重要なレコードが書き込まれません。

ZipFile.getinfo(name)

アーカイブメンバ name に関する情報を持つ ZipInfo オブジェクトを返します。アーカイブに含まれないファイル名に対して getinfo() を呼び出すと、 KeyError が送出されます。

ZipFile.infolist()

アーカイブに含まれる各メンバの ZipInfo オブジェクトからなるリストを返します。既存のアーカイブファイルを開いている場合、リストの順番は実際の ZIP ファイル中のメンバの順番と同じになります。

ZipFile.namelist()

アーカイブメンバの名前のリストを返します。

ZipFile.open(name[, mode[, pwd]])

アーカイブからメンバーを file-like オブジェクト (ZipExtFile) として展開します。 name はアーカイブに含まれるファイル名、もしくは、 ZipInfo オブジェクトです。 mode パラメーターを指定するならば、以下のうちのどれかである必要があります: 'r' (デフォルト)、 'U' 、 'rU' 'U' か 'rU' を選ぶと、読み出し専用オブジェクトにおいて universal newline support が有効化されます。 pwd は、暗号化ファイルで使われるパスワードです。閉じられた ZIP ファイルに対して open() を呼び出すと、 RuntimeError が送出されます。

ノート

file-like オブジェクトは読み出し専用で、以下のメソッドを提供します: read(), readline(), readlines(), __iter__(), next()

ノート

file-like オブジェクトをコンストラクターの第一引数として、 ZipFile が作成された場合、 ZipFile のファイルポインターを使った open() メソッドにより、オブジェクトが返されます。この場合、 open() で返されたオブジェクトに対し、 ZipFile オブジェクトに対する追加の操作をしてはいけません。もし、 ZipFile が文字列 (ファイル名) をコンストラクターに対する第一引数として作成されたなら、 open() は、 ZipExtFile に含まれる、ZipFile と独立して操作することができる、ファイルオブジェクトを新規に作成します。

ノート

open(), read(), および、 extract() の各メソッドはファイル名、もしくは、 ZipInfo オブジェクトを引数にとれます。これは、名前が重複するメンバーを持つ ZIP ファイルを読み出すときに役に立つでしょう。

バージョン 2.6 で追加.

ZipFile.extract(member[, path[, pwd]])

メンバーをアーカイブからカレントワーキングディレクトリに展開します。 member は、展開するファイルのフルネーム、もしくは、 ZipInfo オブジェクトでなければなりません。ファイル情報は、可能な限り正確に展開されます。 path は展開先のディレクトリを指定します。 member はファイル名、もしくは、 ZipInfo オブジェクトです。 pwd は暗号化ファイルに使われるパスワードです。

バージョン 2.6 で追加.

ZipFile.extractall([path[, members[, pwd]]])

すべてのメンバーをアーカイブからカレントワーキングディレクトリに展開します。 path は、展開先のディレクトリを指定します。 members は、オプションで、 namelist() で返されるリストの部分集合でなければなりません。 pwd は、暗号化ファイルに使われるパスワードです。

警告

信頼できないソースからきた Zip ファイルを、事前に中身をチェックせずに展開してはいけません。ファイルを path の外側に作成することができるからです。例えば、 "/" で始まる絶対パスを持ったメンバーや、 2 つのドット ".." を持つファイル名などの場合です。

バージョン 2.6 で追加.

ZipFile.printdir()

アーカイブの目次を sys.stdout に出力します。

ZipFile.setpassword(pwd)

pwd を展開する圧縮ファイルのデフォルトパスワードとして指定します。

バージョン 2.6 で追加.

ZipFile.read(name[, pwd])

アーカイブ中のファイル名 name の内容をバイト列にして返します。 name はアーカイブに含まれるファイル、もしくは、 ZipInfo オブジェクトの名前です。アーカイブは読み込みまたは追記モードで開かれていなくてはなりません。 pwd は暗号化されたファイルのパスワードで、指定された場合、 setpassword() で指定されたデフォルトのパスワードを上書きします。閉じられた ZipFile に対し read() を呼び出すと、 RuntimeError が送出されます。

バージョン 2.6 で変更: pwd が追加され、 name に ZipInfo オブジェクトを指定できるようになりました。

ZipFile.testzip()

アーカイブ中の全てのファイルを読み、CRC チェックサムとヘッダが正常か調べます。最初に見つかった不正なファイルの名前を返します。不正なファイルがなければ None を返します。閉じた ZipFile に対して testzip() メソッドを呼び出すと、 RuntimeError が送出されます。

ZipFile.write(filename[, arcname[, compress_type]])

filename に指定したファイル名を持つファイルを、アーカイブ名を arcname (デフォルトでは filename と同じですがドライブレターと先頭にあるパスセパレータは取り除かれます) にしてアーカイブに収録します。 compress_type を指定した場合、コンストラクタを使って新たなアーカイブエントリを生成した際に使った compression パラメタを上書きします。アーカイブのモードは 'w' または 'a' でなくてはなりません。モードが 'r' で作成された ZipFile に対し write() メソッドを呼び出すと、 RuntimeError が送出されます。閉じた ZipFile に対し write() メソッドを呼び出すと、 RuntimeError が送出されます。

ノート

ZIP ファイル中のファイル名に関する公式なエンコーディング方式はありません。もしユニコードのファイル名が付けられているならば、それを write() に渡す前に望ましいエンコーディングでバイト列に変換しなければなりません。 WinZip は全てのファイル名を DOS Latin としても知られる CP437 で解釈します。

ノート

アーカイブ名はアーカイブルートに対する相対的なものでなければなりません。言い換えると、アーカイブ名はパスセパレータで始まってはいけません。

ノート

もし、 arcname (arcname が与えられない場合は、 filename) が null byte を含むなら、アーカイブ中のファイルのファイル名は、 null byte までで、切り詰められます。

ZipFile.writestr(zinfo_or_arcname, bytes[, compress_type])

文字列 bytes をアーカイブに書き込みます。 zinfo_or_arcname はアーカイブ中で指定するファイル名か、または ZipInfo インスタンスを指定します。 zinfo_or_arcname に ZipInfo インスタンスを指定する場合、 zinfo インスタンスには少なくともファイル名、日付および時刻を指定しなければなりません。ファイル名を指定した場合、日付と時刻には現在の日付と時間が設定されます。アーカイブはモード 'w' または 'a' で開かれていなければなりません。閉じた ZipFile に対し writestr() メソッドを呼び出すと RuntimeError が送出されます。

compressed_type が指定された場合、その値はコンストラクタに与えられた compression の値か、 zinfo_or_arcname が ZipInfo のインスタンスだったときはその値をオーバーライドします。

ノート

ZipInfo インスタンスを、引数 zinfo_or_arcname として与えた場合、与えられた ZipInfo インスタンスのメンバーである、 compress_type で指定された圧縮方法が使われます。デフォルトでは、 ZipInfo コンストラクターが、このメンバーを ZIP_STORED に設定します。

バージョン 2.7 で変更: compression_type 引数

以下のデータ属性も利用することができます。

ZipFile.debug

使用するデバッグ出力レベル。この属性は 0 (デフォルト、何も出力しない) から 3 (最も多くデバッグ情報を出力する) までの値に設定することができます。デバッグ情報は sys.stdout に出力されます。

ZipFile.comment

ZIP ファイルの付けられたコメントです。モードが ‘a’、または、’w’で作成された ZipFile インスタンスにコメントを付ける場合、コメント 65535 byte 以下の文字列でなければなりません。コメントがそれより長い場合、アーカイブでは、 ZipFile.close() メソッドが呼び出された時点で切り詰められます。

12.4.2. PyZipFile オブジェクト

PyZipFile コンストラクタは ZipFile コンストラクタと同じパラメタを必要とします。インスタンスは ZipFile のメソッドの他に、追加のメソッドを一つ持ちます。

PyZipFile.writepy(pathname[, basename])

*.py ファイルを探し、 *.py ファイルに対応するファイルをアーカイブに追加します。対応するファイルとは、もしあれば *.pyo であり、そうでなければ *.pyc で、必要に応じて *.py からコンパイルします。もし pathname がファイルなら、ファイル名は .py で終わっていなければなりません。また、(*.py に対応する *.py[co]) ファイルはアーカイブのトップレベルに (パス情報なしで) 追加されます。もし pathname が .py で終わらないファイル名なら RuntimeError を送出します。もし pathname がディレクトリで、ディレクトリがパッケージディレクトリでないなら、全ての *.py[co] ファイルはトップレベルに追加されます。もしディレクトリがパッケージディレクトリなら、全ての *.py[co] ファイルはパッケージ名の名前をもつファイルパスの下に追加されます。サブディレクトリがパッケージディレクトリなら、それらは再帰的に追加されます basename はクラス内部での呼び出しに使用するためのものです。 writepy() メソッドは以下のようなファイル名を持ったアーカイブを生成します。

string.pyc                    # トップレベル名
test/__init__.pyc             # パッケージディレクトリ
test/test_support.pyc         # test.test_suport モジュール
test/bogus/__init__.pyc       # サブパッケージディレクトリ
test/bogus/myfile.pyc         # test.bogus.myfile サブモジュール

12.4.3. ZipInfo オブジェクト

ZipFile オブジェクトの getinfo() および infolist() メソッドは ZipInfo クラスのインスタンスを返します。それぞれのインスタンスオブジェクトは ZIP アーカイブの一個のメンバについての情報を保持しています。

インスタンスは以下の属性を持ちます:

ZipInfo.filename

アーカイブ中のファイルの名前。

ZipInfo.date_time

アーカイブメンバの最終更新日時。この属性は6つの値からなるタプルです。:

Index | Value
0 | 西暦年
1 | 月 (1 から始まる)
2 | 日 (1 から始まる)
3 | 時 (0 から始まる)
4 | 分 (0 から始まる)
5 | 秒 (0 から始まる)

ZipInfo.compress_type

アーカイブメンバの圧縮形式。

ZipInfo.comment

各アーカイブメンバに対するコメント。

ZipInfo.extra

拡張フィールドデータ。この文字列データに含まれているデータの内部構成については、 PKZIP Application Note [http://www.pkware.com/documents/casestudies/APPNOTE.TXT] でコメントされています。

ZipInfo.create_system

ZIP アーカイブを作成したシステムを記述する文字列。

ZipInfo.create_version

このアーカイブを作成した PKZIP のバージョン。

ZipInfo.extract_version

このアーカイブを展開する際に必要な PKZIP のバージョン。

ZipInfo.reserved

予約領域。ゼロでなくてはなりません。

ZipInfo.flag_bits

ZIP フラグビット列。

ZipInfo.volume

ファイルヘッダのボリュームナンバ。

ZipInfo.internal_attr

内部属性。

ZipInfo.external_attr

外部ファイル属性。

ZipInfo.header_offset

ファイルヘッダへのバイト数で表したオフセット。

ZipInfo.CRC

圧縮前のファイルの CRC-32 チェックサム。

ZipInfo.compress_size

圧縮後のデータのサイズ。

ZipInfo.file_size

圧縮前のファイルのサイズ。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

12. データ圧縮とアーカイブ »

12.5. tarfile — tar アーカイブファイルを読み書きする

バージョン 2.3 で追加.

tarfile モジュールは、gzipやbz2圧縮されたものも含めて、tarアーカイブの読み書きができます。 (.zip ファイルの読み書きは zipfile モジュールで可能です。)

いくつかの事実と外観：

gzip と bz2 で圧縮されたアーカイブを読み書きします。

POSIX.1-1988 (ustar) フォーマットの読み書きをサポートしています。

longname, longlink 拡張を含めた、GNU tarフォーマットの読み書きをサポートしています。 sparse 拡張は読み込みのみサポートしています。

POSIX.1-2001 (pax) フォーマットの読み書きをサポートしています。

バージョン 2.6 で追加.

ディレクトリ、普通のファイル、ハードリンク、シンボリックリンク、fifo、キャラクタデバイスおよびブロックデバイスを処理します。また、タイムスタンプ、アクセス許可およびオーナーのようなファイル情報の取得および保存が可能です。

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

パス名 name の TarFile オブジェクトを返します。 TarFile オブジェクトと、利用出来るキーワード引数に関する詳細な情報については、 TarFile オブジェクト 節を参照してください。

mode は 'filemode[:compression]' の形式をとる文字列でなければなりません。デフォルトの値は 'r' です。以下に mode のとりうる組み合わせ全てを示します。

mode | 動作
'r' または 'r:*' | 圧縮方法に関して透過的に、読み込み用にオープンします(推奨)。
'r:' | 非圧縮で読み込み用に排他的にオープンします。
'r:gz' | gzip 圧縮で読み込み用にオープンします。
'r:bz2' | bzip2 圧縮で読み込み用にオープンします。
'a' または 'a:' | 非圧縮で追加用にオープンします。ファイルが存在しない場合は新たに作成されます。
'w' または 'w:' | 非圧縮で書き込み用にオープンします。
'w:gz' | gzip 圧縮で書き込み用にオープンします。
'w:bz2' | bzip2 圧縮で書き込み用にオープンします。

'a:gz' あるいは 'a:bz2' は可能ではないことに注意して下さい。もし mode が、ある(圧縮した)ファイルを読み込み用にオープンするのに適していないなら、 ReadError が発生します。これを防ぐには mode 'r' を使って下さい。もし圧縮メソッドがサポートされていなければ、 CompressionError が発生します。

もし fileobj が指定されていれば、それは name でオープンされたファイルオブジェクトの代替として使うことができます。そのファイルオブジェクトの位置が0にあることを前提に動作します。

特別な目的のために、 mode の2番目の形式: 'ファイルモード|[圧縮]' があります。この形式を使うと、 tarfile.open() が返すのはデータをブロックからなるストリームとして扱う TarFile オブジェクトになります。この場合、ファイルに対してランダムな seek を行えなくなります。 fileobj を指定する場合、 read() および write() メソッドを持つ任意のオブジェクトにできます。 bufsize にはブロックサイズを指定します。デフォルトは 20 * 512 バイトです。 sys.stdin 、ソケットファイルオブジェクト、テープデバイスと組み合わせる場合にはこの形式を使ってください。ただし、このような TarFile オブジェクトにはランダムアクセスを行えないという制限があります。例 節を参照してください。現在可能なモードは：

モード | 動作
'r|*' | tar ブロックの ストリーム を 圧縮方法に関して透過的に読み込み用にオープンします。
'r|' | 非圧縮 tar ブロックの ストリーム を読み込み用にオープンします。
'r|gz' | gzip 圧縮の ストリーム を読み込み用にオープンします。
'r|bz2' | bzip2 圧縮の ストリーム を読み込み用にオープンします。
'w|' | 非圧縮の ストリーム を書き込み用にオープンします。
'w|gz' | gzip 圧縮の ストリーム を書き込み用にオープンします。
'w|bz2' | bzip2 圧縮の ストリーム を書き込み用にオープンします。

class tarfile.TarFile

tar アーカイブを読んだり、書いたりするためのクラスです。このクラスを直接使わず、代わりに tarfile.open() を使ってください。 TarFile オブジェクト を参照してください。

tarfile.is_tarfile(name)

もし name が tar アーカイブファイルであり、 tarfile モジュールで読み出せる場合に True を返します。

class tarfile.TarFileCompat(filename, mode='r', compression=TAR_PLAIN)

zipfile 風なインターフェースを持つ tar アーカイブへの制限されたアクセスのためのクラスです。詳細は zipfile のドキュメントを参照してください。 compression は、以下の定数のどれかでなければなりません：

TAR_PLAIN

非圧縮 tar アーカイブのための定数。

TAR_GZIPPED

gzip 圧縮 tar アーカイブのための定数。

バージョン 2.6 で撤廃: TarFileCompat クラスは、 Python 3.0 で削除されるので、非推奨になりました。

exception tarfile.TarError

すべての tarfile 例外のための基本クラスです。

exception tarfile.ReadError

tar アーカイブがオープンされた時、 tarfile モジュールで操作できないか、あるいは何か無効であるとき発生します。

exception tarfile.CompressionError

圧縮方法がサポートされていないか、あるいはデータを正しくデコードできない時に発生します。

exception tarfile.StreamError

ストリーム風の TarFile オブジェクトで典型的な制限のために発生します。

exception tarfile.ExtractError

TarFile.extract() を使った時に 致命的でない エラーに対して発生します。ただし TarFile.errorlevel== 2 の場合に限ります。

exception tarfile.HeaderError

TarInfo.frombuf() メソッドが、バッファが不正だったときに送出します。

バージョン 2.6 で追加.

以下の各定数は、 tarfile モジュールが作成できるtarアーカイブフォーマットを定義しています。詳細は、 サポートされる tar のフォーマット を参照してください。

tarfile.USTAR_FORMAT

POSIX.1-1988 (ustar) フォーマット

tarfile.GNU_FORMAT

GNU tar フォーマット

tarfile.PAX_FORMAT

POSIX.1-2001 (pax) フォーマット

tarfile.DEFAULT_FORMAT

アーカイブを作成する際のデフォルトのフォーマット。現在は GNU_FORMAT

以下のモジュールレベル変数が利用できます。

tarfile.ENCODING

デフォルト文字エンコーディング。 sys.getfilesystemencoding() か sys.getdefaultencoding() のどちらかの値。

参考

Module zipfile

zipfile 標準モジュールのドキュメント。

GNU tar マニュアル, 基本 Tar 形式 [http://www.gnu.org/software/tar/manual/html_node/Standard.html]

GNU tar 拡張機能を含む、 tar アーカイブファイルのためのドキュメント。

12.5.1. TarFile オブジェクト

TarFile オブジェクトは、tar アーカイブへのインターフェースを提供します。 tar アーカイブは一連のブロックです。アーカイブメンバー(保存されたファイル)は、ヘッダーブロックとそれに続くデータブロックから構成されています。ある tar アーカイブにファイルを何回も保存することができます。各アーカイブメンバーは、 TarInfo オブジェクトによって表わされます、詳細については TarInfo オブジェクト を参照してください。

TarFile オブジェクトは with 文によりコンテキストマネージャーとして利用できます。 with ブロックが終了したときにオブジェクトは close されます。例外が発生した時、内部で利用されているファイルオブジェクトのみが close され、開かれたアーカイブは終了されないことに注意してください。例 セクションにあるユースケースを参照してください。

バージョン 2.7 で追加: コンテキストマネージャープロトコルがサポートされました。

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors=None, pax_headers=None, debug=0, errorlevel=0)

以下の全ての引数はオプションで、インスタンス属性としてもアクセスすることができます。

name はアーカイブのパス名。 fileobj が渡された場合は省略可能。その場合、ファイルオブジェクトの name 属性があれば、それを利用します。

mode は、既存のアーカイブファールから読み込むための 'r', 既存のアーカイブファイルに追記するための 'a', 既存のファイルがあれば上書きして新しいファイルを作成する 'w' のいずれかです。

もし fileobj が与えられていれば、それを使ってデータを読み書きします。もしそれが決定できれば、 mode は fileobj のモードで上書きされます。 fileobj は位置0から利用されます。

ノート

TarFile をクローズする時に、 fileobj はクローズされません。

format はアーカイブのフォーマットを制御します。モジュールレベルで定義されている、 USTAR_FORMAT, GNU_FORMAT, PAX_FORMAT のいずれかである必要があります。

バージョン 2.6 で追加.

tarinfo 引数を利用して、デフォルトの TarInfo クラスを別のクラスで置き換えられます。

バージョン 2.6 で追加.

dereference が False だった場合、シンボリックリンクやハードリンクがアーカイブに追加されます。 True だった場合、リンクのターゲットとなるファイルの内容がアーカイブに追加されます。シンボリックリンクをサポートしていないシステムでは効果がありません。

ignore_zeros が False だった場合、空ブロックをアーカイブの終端だと扱います。 True だった場合、空の(無効な)ブロックをスキップして、可能な限り多くのメンバを取得しようとします。このオプションは、連結(concatenate)されたり、壊れたアーカイブファイルを扱うときにのみ、意味があります。

debug は 0 (デバッグメッセージ無し)から 3 (全デバッグメッセージ) まで設定できます。このメッセージは sys.stderr に書き込まれます。

errorlevel が 0 の場合、 TarFile.extract() 使用時に全てのエラーが無視されます。エラーが無視された場合でも、 debug が有効であれば、エラーメッセージは出力されます。 1 の場合、全ての 致命的な(fatal) エラーは OSError か IOError を送出します。 2 の場合、全ての 致命的でない(non-fatal) エラーも TarError 例外として送出されます。

encoding と errors 引数は、文字列と unicode オブジェクトとの間の相互変換方法を指定します。デフォルトの設定で、ほとんどのユーザーでうまく動作するでしょう。詳しい情報は、 Unicode に関する問題 節を参照してください。

バージョン 2.6 で追加.

pax_headers 引数は、オプションの、 unicode 文字列の辞書で、 format が PAX_FORMAT だった場合に pax グローバルヘッダに追加されます。

バージョン 2.6 で追加.

TarFile.open(...)

代替コンストラクタです。モジュールレベルでの tarfile.open() 関数は、実際はこのクラスメソッドへのショートカットです。

TarFile.getmember(name)

メンバー name に対する TarInfo オブジェクトを返します。もし name がアーカイブに見つからなければ、 KeyError が発生します。

ノート

アーカイブ内にメンバーが複数ある場合は、最後に出現するものが最新のバージョンとみなされます。

TarFile.getmembers()

TarInfo アーカイブのメンバーをオブジェクトのリストとして返します。このリストはアーカイブ内のメンバーと同じ順番です。

TarFile.getnames()

メンバーをその名前のリストとして返します。これは getmembers() で返されるリストと同じ順番です。

TarFile.list(verbose=True)

目次を sys.stdout に表示します。もし verbose が False であれば、メンバー名のみ表示します。 True であれば、 "ls -l" に似た出力を生成します。

TarFile.next()

TarFile が読み込み用にオープンされている時、アーカイブの次のメンバーを TarInfo オブジェクトとして返します。もしそれ以上利用可能なものがなければ、 None を返します。

TarFile.extractall(path=".", members=None)

全てのメンバーをアーカイブから現在の作業ディレクトリーまたは path に抽出します。オプションの members が与えられるときには、 getmembers() で返されるリストの一部でなければなりません。所有者、変更時刻、パーミッションのようなディレクトリー情報は全てのメンバーが抽出された後にセットされます。これは二つの問題を回避するためです。一つはディレクトリーの変更時刻はその中にファイルが作成されるたびにリセットされるということ。もう一つは、ディレクトリーに書き込み許可がなければその中のファイル抽出は失敗してしまうということです。

警告

内容を信頼できないtarアーカイブを、事前の内部チェック前に展開してはいけません。ファイルが path の外側に作られる可能性があります。例えば、 "/" で始まる絶対パスのファイル名や、2重ドット ".." で始まるパスのファイル名です。

バージョン 2.5 で追加.

TarFile.extract(member, path="")

メンバーをアーカイブから現在の作業ディレクトリに、その完全名を使って抽出します。ファイル情報はできるだけ正確に抽出されます。 member は、ファイル名でも TarInfo オブジェクトでも構いません。 path を使って、異なるディレクトリを指定することができます。

ノート

extract() メソッドは幾つかの展開に関する問題を扱いません。殆どの場合、 extractall() メソッドの利用を考慮するべきです。

警告

extractall() の警告(warning)を参照

TarFile.extractfile(member)

アーカイブからメンバーをオブジェクトとして抽出します。 member は、ファイル名あるいは TarInfo オブジェクトです。もし member が普通のファイルであれば、ファイル風のオブジェクトを返します。もし member がリンクであれば、ファイル風のオブジェクトをリンクのターゲットから構成します。もし member が上のどれでもなければ、 None が返されます。

ノート

ファイル風のオブジェクトは読み出し専用です。このオブジェクトは read(), readline(), readlines(), seek(), tell(), close(). の各メソッドを提供し、行に対するイテレーションをサポートします。

TarFile.add(name, arcname=None, recursive=True, exclude=None, filter=None)

ファイル name をアーカイブに追加します。 name は、任意のファイルタイプ (ディレクトリ、fifo、シンボリックリンク等)です。もし arcname が与えられていれば、それはアーカイブ内のファイルの代替名を指定します。デフォルトではディレクトリは再帰的に追加されます。これは、 recursive を False に設定することで避けることができます。 exclude を指定する場合、それは1つのファイル名を引数にとってブール値を返す関数である必要があります。この関数の戻り値が True の場合、そのファイルが除外されます。 False の場合、そのファイルは追加されます。 filter を指定する場合、それは TarInfo オブジェクトを引数として受け取り、操作した TarInfo オブジェクトを返す関数でなければなりません。代わりに None を返した場合、 TarInfo オブジェクトはアーカイブから除外されます。例 にある例を参照してください。

バージョン 2.6 で変更: exclude 引数が追加されました。

バージョン 2.7 で変更: filter 引数が追加されました。

バージョン 2.7 で撤廃: exclude 引数は廃止予定です。代わりに filter 引数を利用してください。将来 exclude 引数が削除されたときに互換性を保つため、 filter は位置引数ではなくてキーワード引数として利用するべきです。

TarFile.addfile(tarinfo, fileobj=None)

TarInfo オブジェクト tarinfo をアーカイブに追加します。もし fileobj が与えられていれば、 tarinfo.size バイトがそれから読まれ、アーカイブに追加されます。 gettarinfo() を使って TarInfo オブジェクトを作成することができます。

ノート

Windows プラットフォームでは、 fileobj は、ファイルサイズに関する問題を避けるために、常に、モード 'rb' でオープンされるべきです。

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

ファイル name あるいはファイルオブジェクト fileobj のどちらかに対して (そのファイル記述子に os.fstat() を使って) TarInfo オブジェクトを作成します。 TarInfo の属性のいくつかは、 addfile() を使って追加する前に修正することができます。もし arcname が与えられていれば、アーカイブ内のファイルの代替名を指定します。

TarFile.close()

TarFile をクローズします。書き出しモードでは、完了ゼロブロックが 2つ、アーカイブに追加されます。

TarFile.posix

この値を True にすることは、 format を USTAR_FORMAT にすることと同じです。この値を False にすることは、 format を GNU_FORMAT にすることと同じです。

バージョン 2.4 で変更: posix のデフォルト値が False になりました.

バージョン 2.6 で撤廃: 代わりに format 属性を利用してください。

TarFile.pax_headers

pax グローバルヘッダに含まれる key-value ペアの辞書

バージョン 2.6 で追加.

12.5.2. TarInfo オブジェクト

TarInfo オブジェクトは TarFile の一つのメンバーを表します。ファイルに必要な(ファイルタイプ、ファイルサイズ、時刻、パーミッション、所有者等のような)すべての属性を保存する他に、そのタイプを決定するのに役に立ついくつかのメソッドを提供します。これにはファイルのデータそのものは 含まれません 。

TarInfo オブジェクトは TarFile のメソッド getmember() 、 getmembers() および gettarinfo() によって返されます。

class tarfile.TarInfo(name="")

TarInfo オブジェクトを作成します。

TarInfo.frombuf(buf)

TarInfo オブジェクトを文字列バッファ buf から作成して返します。

バージョン 2.6 で追加: バッファが不正な場合は、 HeaderError を送出します。

TarInfo.fromtarfile(tarfile)

TarFile オブジェクトの tarfile から、次のメンバを読み込んで、それを TarInfo オブジェクトとして返します。

バージョン 2.6 で追加.

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='strict')

TarInfo オブジェクトから文字列バッファを作成します。引数についての情報は、 TarFile クラスのコンストラクタを参照してください。

バージョン 2.6 で変更: 引数が追加されました。

TarInfo オブジェクトには以下の public なデータ属性があります：

TarInfo.name

アーカイブメンバーの名前。

TarInfo.size

バイト単位でのサイズ。

TarInfo.mtime

最終更新時刻。

TarInfo.mode

許可ビット。

TarInfo.type

ファイルタイプです。 type は普通、以下の定数: REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE のいずれかです。 TarInfo オブジェクトのタイプをもっと簡単に決定するには、下記の is_*() メソッドを使って下さい。

TarInfo.linkname

ターゲットファイル名の名前で、これはタイプ LNKTYPE と SYMTYPE の TarInfo オブジェクトにだけ存在します。

TarInfo.uid

ファイルメンバを保存した元のユーザのユーザ ID です。

TarInfo.gid

ファイルメンバを保存した元のユーザのグループ ID です。

TarInfo.uname

ファイルメンバを保存した元のユーザのユーザ名です。

TarInfo.gname

ファイルメンバを保存した元のユーザのグループ名です。

TarInfo.pax_headers

pax 拡張ヘッダに関連付けられた、 key-value ペアの辞書。

バージョン 2.6 で追加.

TarInfo オブジェクトは便利な照会用のメソッドもいくつか提供しています:

TarInfo.isfile()

Tarinfo オブジェクトが普通のファイルの場合に、 True を返します。

TarInfo.isreg()

isfile() と同じです。

TarInfo.isdir()

ディレクトリの場合に True を返します。

TarInfo.issym()

シンボリックリンクの場合に True を返します。

TarInfo.islnk()

ハードリンクの場合に True を返します。

TarInfo.ischr()

キャラクタデバイスの場合に True を返します。

TarInfo.isblk()

ブロックデバイスの場合に True を返します。

TarInfo.isfifo()

FIFO の場合に True を返します。

TarInfo.isdev()

キャラクタデバイス、ブロックデバイスあるいは FIFOのいずれかの場合に True を返します。

12.5.3. 例

tar アーカイブから現在のディレクトリーに全て抽出する方法

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()

tarアーカイブの一部を、リストの代わりにジェネレータ関数を利用して、 TarFile.extractall() で展開する方法

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

非圧縮 tar アーカイブをファイル名のリストから作成する方法

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

with 文を利用した同じ例:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

gzip 圧縮 tar アーカイブを作成してメンバー情報のいくつかを表示する方法

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
    print tarinfo.name, " は大きさが ", tarinfo.size, "バイトで ",
    if tarinfo.isreg():
        print "普通のファイルです。"
    elif tarinfo.isdir():
        print "ディレクトリです。"
    else:
        print "ファイル・ディレクトリ以外のものです。"
tar.close()

TarFile.add() 関数の filter 引数を利用してユーザー情報をリセットしながらアーカイブを作成する例:

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

12.5.4. サポートされる tar のフォーマット

tarfile モジュールは、3つの tar フォーマットを作成することができます。

POSIX.1-1988 ustar format (USTAR_FORMAT). ファイル名の長さは256文字までで、リンク名の長さは100文字までです。最大のファイルサイズは8GBです。このフォーマットは古くて制限が多いですが、広くサポートされています。

GNU tar format (GNU_FORMAT). 長いファイル名とリンク名、8GBを超えるファイルやスパース(sparse)ファイルをサポートしています。これは GNU/Linux システムにおいて、デ・ファクト・スタンダードになっています。 tarfile モジュールは長いファイル名を完全にサポートしています。スパースファイルは読み込みのみサポートしています。

The POSIX.1-2001 pax format (PAX_FORMAT). 一番柔軟性があり、ほぼ制限が無いフォーマットです。長いファイル名やリンク名、大きいファイルをサポートし、パス名をポータブルな方法で保存します。しかし、現在のところ、全ての tar の実装が pax フォーマットを正しく扱えるわけではありません。

pax フォーマットは既存の ustar フォーマットの拡張です。 ustar では保存できない情報を追加のヘッダを利用して保存します。 pax には2種類のヘッダがあります。 1つ目は拡張ヘッダで、その次のファイルヘッダに影響します。 2つ目はグローバルヘッダで、アーカイブ全体に対して有効で、それ以降の全てのファイルに影響します。全ての pax ヘッダの内容は、ポータブル性のために UTF-8 で保存されます。

他にも、読み込みのみサポートしている tar フォーマットが幾つかあります。

ancient V7 format. これは Unix 7th Edition から存在する、最初の tar フォーマットです。通常のファイルとディレクトリのみ保存します。名前は100文字を超えてはならず、ユーザー/グループ名に関する情報は保存されません。幾つかのアーカイブは、フィールドがASCIIでない文字を含む場合に、ヘッダのチェックサムの計算を誤っています。

The SunOS tar extended format. POSIX.1-2001 pax フォーマットの亜流ですが、互換性がありません。

12.5.5. Unicode に関する問題

tarフォーマットはもともと、テープドライブにファイルシステムのバックアップを取る目的で設計されました。現在、tarアーカイブはファイルを配布する場合に一般的に用いられ、ネットワークごしに送受信されます。オリジナルのフォーマットの抱える1つの問題(ほか多くのフォーマットも同じですが)は、文字エンコーディングが異なる環境を考慮していないことです。例えば、通常の UTF-8 の環境で作成されたアーカイブは、非ASCII文字を含んでいた場合 Latin-1 のシステムでは正しく読み込むことができません。非ASCII文字を含む名前(ファイル名、リンク名、ユーザー/グループ名)が破壊されます。不幸なことに、アーカイブのエンコーディングを自動検出する方法はありません。

pax フォーマットはこの問題を解決するように設計されました。このフォーマットは、非ASCII文字の名前を UTF-8 で保存します。 pax アーカイブを読み込むときに、この UTF-8 の名前がローカルのファイルシステムのエンコーディングに変換されます。

unicode 変換の動作は、 TarFile クラスの encoding と errors キーワード引数によって制御されます。

encoding のデフォルト値はローカルの文字エンコーディングです。これは sys.getfilesystemencoding() と sys.getdefaultencoding() から取得されます。読み込みモードでは、 encoding は pax フォーマット内の unicode の名前をローカルの文字エンコーディングに変換するために利用されます。書き込みモードでは、 encoding の扱いは選択されたアーカイブフォーマットに依存します。 PAX_FORMAT の場合、入力された非ASCII文字を含む文字は UTF-8 文字列として保存する前に一旦デコードする必要があるので、そこで encoding が利用されます。それ以外のフォーマットでは、 encoding は、入力された名前に unicode が含まれない限りは利用されません。unicodeが含まれている場合、アーカイブに保存する前に encoding でエンコードされます。

errors 引数は、 encoding を利用して変換できない文字の扱いを指定します。利用可能な値は、 Codec 基底クラス 節でリストアップされています。読み込みモードでは、追加の値として 'utf-8' を選択することができ、エラーが発生したときは UTF-8 を利用することができます。(これがデフォルトです) 書き込みモードでは、 errors のデフォルト値は 'strict' になっていて、名前が気づかないうちに変化することが無いようにしています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット

この章で説明されるモジュールは様々な(マークアップやでないものやEメールの) ファイルフォーマットを構文解析します。

13.1. csv — CSV ファイルの読み書き

13.1.1. モジュールの内容

13.1.2. Dialect クラスと書式化パラメタ

13.1.3. reader オブジェクト

13.1.4. writer オブジェクト

13.1.5. 使用例

13.2. ConfigParser — 設定ファイルの構文解析器

13.2.1. RawConfigParser オブジェクト

13.2.2. ConfigParser オブジェクト

13.2.3. SafeConfigParser オブジェクト

13.2.4. 例

13.3. robotparser — robots.txt のためのパーザ

13.4. netrc — netrc ファイルの処理

13.4.1. netrc オブジェクト

13.5. xdrlib — XDR データのエンコードおよびデコード

13.5.1. Packer オブジェクト

13.5.2. Unpacker オブジェクト

13.5.3. 例外

13.6. plistlib — Mac OS X .plist ファイルの生成と解析

13.6.1. 例

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.1. csv — CSV ファイルの読み書き

バージョン 2.3 で追加.

CSV (Comma Separated Values、カンマ区切り値列) と呼ばれる形式は、スプレッドシートやデータベース間でのデータのインポートやエクスポートにおける最も一般的な形式です。”CSV 標準” は存在しないため、 CSV 形式はデータを読み書きする多くのアプリケーション上の操作に応じて定義されているにすぎません。標準がないということは、異なるアプリケーションによって生成されたり取り込まれたりするデータ間では、しばしば微妙な違いが発生するということを意味します。こうした違いのために、複数のデータ源から得られた CSV ファイルを処理する作業が鬱陶しいものになることがあります。とはいえ、デリミタ (delimiter) やクオート文字の相違はあっても、全体的な形式は十分似通っているため、こうしたデータを効率的に操作し、データの読み書きにおける細々としたことをプログラマから隠蔽するような単一のモジュールを書くことは可能です。

csv モジュールでは、CSV 形式で書かれたテーブル状のデータを読み書きするためのクラスを実装しています。このモジュールを使うことで、プログラマは Excel で使われている CSV 形式に関して詳しい知識をもっていなくても、 “このデータを Excel で推奨されている形式で書いてください” とか、 “データを Excel で作成されたこのファイルから読み出してください” と言うことができます。プログラマはまた、他のアプリケーションが解釈できる CSV 形式を記述したり、独自の特殊な目的をもった CSV 形式を定義することができます。

csv モジュールの reader および writer オブジェクトはシーケンス型を読み書きします。プログラマは DictReader や DictWriter クラスを使うことで、データを辞書形式で読み書きすることもできます。

ノート

このバージョンの csv モジュールは Unicode 入力をサポートしていません。また、現在のところ、 ASCII NUL 文字に関連したいくつかの問題があります。従って、安全を期すには、全ての入力を UTF-8 または印字可能な ASCII にしなければなりません。これについては 使用例 節の例を参照してください。これらの制限は将来取り去られることになっています。

参考

PEP 305 [http://www.python.org/dev/peps/pep-0305] - CSV File API

Python へのこのモジュールの追加を提案している Python 改良案 (PEP: Python Enhancement Proposal)

13.1.1. モジュールの内容

csv モジュールでは以下の関数を定義しています:

csv.reader(csvfile[, dialect='excel'][, fmtparam])

与えられた csvfile 内の行を反復処理するような reader オブジェクトを返します。 csvfile はイテレータ(iterator)プロトコルをサポートし、 next() メソッドが呼ばれた際に常に文字列を返すような任意のオブジェクトにすることができます — ファイルオブジェクトでもリストでも構いません。 csvfile がファイルオブジェクトの場合、ファイルオブジェクトの形式に違いがあるようなプラットフォームでは ‘b’ フラグを付けて開かなければなりません。オプションとして dialect パラメタを与えることができ、特定の CSV 表現形式 (dialect) 特有のパラメタの集合を定義するために使われます。 dialect パラメタは Dialect クラスのサブクラスのインスタンスか、 list_dialects() 関数が返す文字列の一つにすることができます。別のオプションである fmtparam キーワード引数は、現在の表現形式における個々の書式パラメタを上書きするために与えることができます。表現形式および書式化パラメタの詳細については、 Dialect クラスと書式化パラメタ 節を参照してください。

csv ファイルから読み込まれた各行は、文字列のリストとして返されます。データ型の変換が自動的に行われることはありません。

短い利用例:

>>> import csv
>>> spamReader = csv.reader(open('eggs.csv', 'rb'), delimiter=' ', quotechar='|')
>>> for row in spamReader:
...     print ', '.join(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

バージョン 2.5 で変更: パーサが複数行に亘るクオートされたフィールドに関して厳格になりました。以前は、クオートされたフィールドの中で終端の改行文字無しに行が終わった場合、返されるフィールドには改行が挿入されていましたが、この振る舞いはフィールドの中に復帰文字を含むようなファイルを読むときに問題を起こしていました。そこでフィールドに改行文字を挿入せずに返すように改められました。この結果、フィールドに埋め込まれた改行文字が重要ならば、入力は改行文字を保存するような仕方で複数行に分割されなければなりません。 .

csv.writer(csvfile[, dialect='excel'][, fmtparam])

ユーザが与えたデータをデリミタで区切られた文字列に変換し、与えられたファイルオブジェクトに書き込むための writer オブジェクトを返します。 csvfile は write() メソッドを持つ任意のオブジェクトです。 csvfile がファイルオブジェクトの場合、 ‘b’ フラグが意味を持つプラットフォームでは ‘b’ フラグを付けて開かなければなりません。オプションとして dialect 引数を与えることができ、利用するCSV表現形式(dialect)を指定することができます。 dialect パラメタは Dialect クラスのサブクラスのインスタンスか、 list_dialects() 関数が返す文字列の1つにすることができます。別のオプション引数である fmtparam キーワード引数は、現在の表現形式における個々の書式パラメタを上書きするために与えることができます。 dialect と書式パラメタについての詳細は、 Dialect クラスと書式化パラメタ 節を参照してください。 DB API を実装するモジュールとのインタフェースを可能な限り容易にするために、 None は空文字列として書き込まれます。この処理は可逆な変換ではありませんが、SQL で NULL データ値を CSV にダンプする処理を、 cursor.fetch* 呼び出しによって返されたデータを前処理することなく簡単に行うことができます。他の非文字列データは、書き出される前に str() を使って文字列に変換されます。

短い利用例:

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'wb'), delimiter=' ',
...                         quotechar='|', quoting=csv.QUOTE_MINIMAL)
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

csv.register_dialect(name[, dialect][, fmtparam])

dialect を name と関連付けます。 name は文字列か Unicode オブジェクトでなければなりません。表現形式(dialect)は Dialect のサブクラスを渡すか、またはキーワード引数 fmtparam 、もしくは両方で指定できますが、キーワード引数の方が優先されます。表現形式と書式化パラメタについての詳細は、 Dialect クラスと書式化パラメタ 節を参照してください。

csv.unregister_dialect(name)

name に関連づけられた表現形式を表現形式レジストリから削除します。 name が表現形式名でない場合には Error を送出します。

csv.get_dialect(name)

name に関連づけられた表現形式を返します。 name が表現形式名でない場合には Error を送出します。

バージョン 2.5 で変更.

csv.list_dialects()

登録されている全ての表現形式を返します。

csv.field_size_limit([new_limit])

パーサが許容する現在の最大フィールドサイズを返します。 new_limit が渡されたときは、その値が新しい上限になります。

バージョン 2.5 で追加.

csv モジュールでは以下のクラスを定義しています:

class csv.DictReader(csvfile[, fieldnames=None[, restkey=None[, restval=None[, dialect='excel'[, *args, **kwds]]]]])

省略可能な fieldnames パラメタで与えられたキーを読み出された情報に対応付ける他は正規の reader のように動作するオブジェクトを生成します。 fieldnames パラメタが無い場合には、 csvfile の最初の行の値がフィールド名として利用されます。読み出された行が fieldnames のシーケンスよりも多くのフィールドを持っていた場合、残りのフィールドデータは restkey の値をキーとするシーケンスに追加されます。読み出された行が fieldnames のシーケンスよりも少ないフィールドしか持たない場合、残りのキーはオプションの restval パラメタに指定された値を取ります。その他の省略可能またはキーワード形式のパラメタはベースになっている reader のインスタンスに渡されます。

class csv.DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]])

辞書を出力行に対応付ける他は正規の writer のように動作するオブジェクトを生成します。 fieldnames パラメタには、辞書中の writerow() メソッドに渡される値がどの順番で csvfile に書き出されるかを指定します。オプションの restval パラメタは、 fieldnames 内のキーが辞書中にない場合に書き出される値を指定します。 writerow() メソッドに渡された辞書に、 fieldnames 内には存在しないキーが入っている場合、オプションの extraaction パラメタでどのような動作を行うかを指定します。この値が 'raise' に設定されている場合 ValueError が送出されます。 'ignore' に設定されている場合、辞書の余分の値は無視されます。その他のパラメタはベースになっている writer のインスタンスに渡されます。

DictReader クラスとは違い、 DictWriter の fieldnames パラメータは省略可能ではありません。Pythonの dict オブジェクトは整列されていないので、列が csvfile に書かれるべき順序を推定するための十分な情報はありません。

class csv.Dialect

Dialect クラスはコンテナクラスで、基本的な用途としては、その属性を特定の reader や writer インスタンスのパラメタを定義するために用います。

class csv.excel

excel クラスは Excel で生成される CSV ファイルの通常のプロパティを定義します。これは 'excel' という名前の dialect として登録されています。

class csv.excel_tab

excel クラスは Excel で生成されるタブ分割ファイルの通常のプロパティを定義します。これは 'excel-tab' という名前の dialect として登録されています。

class csv.Sniffer([sample=16384])

Sniffer クラスは CSV ファイルの書式を推理するために用いられるクラスです。

Sniffer クラスではメソッドを二つ提供しています:

sniff(sample[, delimiters=None])

与えられた sample を解析し、発見されたパラメタを反映した Dialect サブクラスを返します。オプションの delimiters パラメタを与えた場合、有効なデリミタ文字を含んでいるはずの文字列として解釈されます。

has_header(sample)

(CSV 形式と仮定される) サンプルテキストを解析して、最初の行がカラムヘッダの羅列のように推察される場合 True を返します。

Sniffer の利用例:

csvfile = open("example.csv", "rb")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
# ... process CSV file contents here ...

csv モジュールでは以下の定数を定義しています:

csv.QUOTE_ALL

writer オブジェクトに対し、全てのフィールドをクオートするように指示します。

csv.QUOTE_MINIMAL

writer オブジェクトに対し、 delimiter 、 quotechar または lineterminator に含まれる任意の文字のような特別な文字を含むフィールドだけをクオートするように指示します。

csv.QUOTE_NONNUMERIC

writer オブジェクトに対し、全ての非数値フィールドをクオートするように指示します。

reader に対しては、クオートされていない全てのフィールドを float 型に変換するよう指示します。

csv.QUOTE_NONE

writer オブジェクトに対し、フィールドを決してクオートしないように指示します。現在の delimiter が出力データ中に現れた場合、現在設定されている escapechar 文字が前に付けられます。 escapechar がセットされていない場合、エスケープが必要な文字に遭遇した writer は Error を送出します。

reader に対しては、クオート文字の特別扱いをしないように指示します。

csv モジュールでは以下の例外を定義しています:

exception csv.Error

全ての関数において、エラーが検出された際に送出される例外です。

13.1.2. Dialect クラスと書式化パラメタ

レコードに対する入出力形式の指定をより簡単にするために、特定の書式化パラメタは表現形式 (dialect) にまとめてグループ化されます。表現形式は Dialect クラスのサブクラスで、様々なクラス特有のメソッドと、 validate() メソッドを一つ持っています。 reader または writer オブジェクトを生成するとき、プログラマは文字列または Dialect クラスのサブクラスを表現形式パラメタとして渡さなければなりません。さらに、 dialect パラメタの代りに、プログラマは上で定義されている属性と同じ名前を持つ個々の書式化パラメタを Dialect クラスに指定することができます。

Dialect は以下の属性をサポートしています:

Dialect.delimiter

フィールド間を分割するのに用いられる 1 文字からなる文字列です。デフォルトでは ',' です。

Dialect.doublequote

フィールド内に現れた quotechar のインスタンスで、クオートではないその文字自身でなければならない文字をどのようにクオートするかを制御します。 True の場合、この文字は二重化されます。 False の場合、 escapechar は quotechar の前に置かれます。デフォルトでは True です。

出力においては、 doublequote が False で escapechar がセットされていない場合、フィールド内に quotechar が現れると Error が送出されます。

Dialect.escapechar

writer が、 quoting が QUOTE_NONE に設定されている場合に delimiter をエスケープするため、および、 doublequote が False の場合に quotechar をエスケープするために用いられる、 1 文字からなる文字列です。読み込み時には escapechar はそれに引き続く文字の特別な意味を取り除きます。デフォルトでは None で、エスケープを行ないません。

Dialect.lineterminator

writer が作り出す各行を終端する際に用いられる文字列です。デフォルトでは '\r\n' です。

ノート

reader は '\r' または '\n' のどちらかを行末と認識するようにハードコードされており、 lineterminator を無視します。この振る舞いは将来変更されるかもしれません。

Dialect.quotechar

delimiter や quotechar といった特殊文字を含むか、改行文字を含むフィールドをクオートする際に用いられる 1 文字からなる文字列です。デフォルトでは '"' です。

Dialect.quoting

クオートがいつ writer によって生成されるか、また reader によって認識されるかを制御します。 QUOTE_* 定数のいずれか (モジュールの内容 節参照) をとることができ、デフォルトでは QUOTE_MINIMAL です。

Dialect.skipinitialspace

True の場合、 delimiter の直後に続く空白は無視されます。デフォルトでは False です。

13.1.3. reader オブジェクト

reader オブジェクト(DictReader インスタンス、および reader() 関数によって返されたオブジェクト) は、以下の public なメソッドを持っています:

csvreader.next()

reader の反復可能なオブジェクトから、現在の表現形式に基づいて次の行を解析して返します。

reader オブジェクトには以下の公開属性があります:

csvreader.dialect

パーサで使われる表現形式の読み取り専用の記述です。

csvreader.line_num

ソースイテレータから読んだ行数です。この数は返されるレコードの数とは、レコードが複数行に亘ることがあるので、一致しません。

バージョン 2.5 で追加.

DictReader オブジェクトは、以下のpublicな属性を持っています:

csvreader.fieldnames

オブジェクトを生成するときに渡されなかった場合、この属性は最初のアクセス時か、ファイルから最初のレコードを読み出したときに初期化されます。

バージョン 2.6 で変更.

13.1.4. writer オブジェクト

Writer オブジェクト(DictWriter インスタンス、および writer() 関数によって返されたオブジェクト) は、以下の public なメソッドを持っています:

Writer オブジェクト(writer() で生成される DictWriter クラスのインスタンス）は、以下の公開メソッドを持っています。 row には、 Writer オブジェクトの場合には文字列か数値のシーケンスを指定し、 DictWriter オブジェクトの場合はフィールド名をキーとして対応する文字列か数値を格納した辞書オブジェクトを指定します(数値は str() で変換されます)。複素数を出力する場合、値をかっこで囲んで出力します。このため、CSV ファイルを読み込むアプリケーションで（そのアプリケーションが複素数をサポートしていたとしても）問題が発生する場合があります。

csvwriter.writerow(row)

row パラメタを現在の表現形式に基づいて書式化し、 writer のファイルオブジェクトに書き込みます。

csvwriter.writerows(rows)

rows パラメタ(上記 row のリスト)全てを現在の表現形式に基づいて書式化し、 writer のファイルオブジェクトに書き込みます。

writer オブジェクトには以下の公開属性があります:

csvwriter.dialect

writer で使われる表現形式の読み取り専用の記述です。

DictWriter のオブジェクトは以下の public メソッドを持っています。

DictWriter.writeheader()

(コンストラクタで指定された)フィールド名の行を出力します。

バージョン 2.7 で追加.

13.1.5. 使用例

最も簡単な CSV ファイル読み込みの例です:

import csv
with open('some.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        print row

別の書式での読み込み:

import csv
with open('passwd', 'rb') as f:
    reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
    for row in reader:
        print row

上に対して、単純な書き込みのプログラム例は以下のようになります。

import csv
with open('some.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerows(someiterable)

新しい表現形式の登録:

import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
with open('passwd', 'rb') as f:
    reader = csv.reader(f, 'unixpwd')

もう少し手の込んだ reader の使い方 — エラーを捉えてレポートします。

import csv, sys
filename = 'some.csv'
with open(filename, 'rb') as f:
    reader = csv.reader(f)
    try:
        for row in reader:
            print row
    except csv.Error, e:
        sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))

このモジュールは文字列の解析は直接サポートしませんが、簡単にできます。

import csv
for row in csv.reader(['one,two,three']):
    print row

csv モジュールは直接は Unicode の読み書きをサポートしませんが、 ASCII NUL 文字に関わる問題のために8ビットクリーンに書き込みます。ですから、NUL を使う UTF-16 のようなエンコーディングを避ける限りエンコード・デコードを行なう関数やクラスを書くことができます。 UTF-8 がお勧めです。

以下の unicode_csv_reader() は Unicode の CSV データ (Unicode 文字列のリスト)を扱うための csv.reader をラップするジェネレータ(generator)です。 utf_8_encoder() は一度に 1 文字列(または行) ずつ Unicode 文字列を UTF-8 としてエンコードするジェネレータです。エンコードされた文字列は CSV reader により分解され、 unicode_csv_reader() が UTF-8 エンコードの分解された文字列をデコードして Unicode に戻します。

import csv

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
    # csv.py doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # decode UTF-8 back to Unicode, cell by cell:
        yield [unicode(cell, 'utf-8') for cell in row]

def utf_8_encoder(unicode_csv_data):
    for line in unicode_csv_data:
        yield line.encode('utf-8')

その他のエンコーディングには以下の UnicodeReader クラスと UnicodeWriter クラスが使えます。二つのクラスは encoding パラメータをコンストラクタで取り、本物の reader や writer に渡されるデータが UTF-8 でエンコードされていることを保証します。

import csv, codecs, cStringIO

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

    def __iter__(self):
        return self

    def next(self):
        return self.reader.next().encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        f = UTF8Recoder(f, encoding)
        self.reader = csv.reader(f, dialect=dialect, **kwds)

    def next(self):
        row = self.reader.next()
        return [unicode(s, "utf-8") for s in row]

    def __iter__(self):
        return self

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.2. ConfigParser — 設定ファイルの構文解析器

ノート

ConfigParser モジュールは Python 3.0 で configparser に改名されました。 2to3 ツールが自動的にソース内の import を修正します。

このモジュールでは、 ConfigParser クラスを定義しています。 ConfigParser クラスは、Microsoft Windows の INI ファイルに見られるような構造をもつ、基礎的な設定ファイルを実装しています。このモジュールを使って、エンドユーザーが簡単にカスタマイズできるような Python プログラムを書くことができます。

ノート

このライブラリでは、Windowsのレジストリ用に拡張された INI 文法はサポート していません 。

参考

モジュール shlex

アプリケーション用の設定ファイルフォーマットとして使える、 Unix シェルライクなミニ言語の作成を支援します。

モジュール json

jsom モジュールは、同じ目的に利用できる JavaScript の文法のサブセットを実装しています。

設定ファイルは 1 つ以上のセクションからなり、セクションは [section] ヘッダとそれに続く RFC 822 [http://tools.ietf.org/html/rfc822.html] 形式の name: value エントリからなっています。(section 3.1.1 “LONG HEADER FIELDS” を参照) name=value という形式も使えます。値の先頭にある空白文字は削除されるので注意してください。オプションの値には、同じセクションか DEFAULT セクションにある値を参照するような書式化文字列を含めることができます。初期化時や検索時に別のデフォルト値を与えることもできます。 '#' か ';' ではじまる行は無視され、コメントを書くために利用できます。

設定ファイルは、特定の文字 (# と ;) で始まるコメントを含んでいることがあります。コメントはある行の中に単独で書かれる場合もありますし、値やセクション名のある行に書かれる場合もあります。後者がコメントとして認識されるためには、その前に空白文字が入っている必要があります。 (後方互換性のために、 # ではなく ; で一行コメントを書いてください。)

最も高機能なクラス SafeConfigParser は置換機能をサポートします。これは同じセクション内の値や DEFAULT という特別なセクションの値を参照するフォーマット文字列を使うことができるという意味です。さらに初期化のときにデフォルトの値を追加することもできます。

例:

[My Section]
foodir: %(dir)s/whatever
dir=frob
long: this value continues
   in the next line

この場合 %(dir)s は変数 dir (この場合は frob)に展開されます。参照の展開は必要に応じて実行されます。

デフォルト値は ConfigParser のコンストラクタに辞書として渡すことで設定できます。追加の(他の値をオーバーライドする)デフォルト値は get() メソッドに渡すことができます。

セクションは通常、組み込みの辞書型に格納されます。 ConfigParser コンストラクタの引数として、代替の辞書型を渡すことができます。例えば、キーをソートするような辞書型が渡された場合、iniファイルに書き戻すときにセクションはソートされます。

class ConfigParser.RawConfigParser([defaults[, dict_type[, allow_no_value]]])

基本的な設定オブジェクトです。 defaults が与えられた場合、オブジェクトに固有のデフォルト値がその値で初期化されます。 dict_type が与えられた場合、それが、セクションのリストの格納、セクション内のオプションの格納、デフォルト値のために利用されます。

allow_no_value (デフォルト: False) が真の時、値のないオプションが許可されます。この場合の値は None になります。

このクラスは値の置換をサポートしません。

全てのオプション名が optionxform() メソッドに渡されます。このメソッドのデフォルトの実装では、オプション名を小文字に変換します。

バージョン 2.3 で追加.

バージョン 2.6 で変更: dict_type が追加されました。

バージョン 2.7 で変更: デフォルトの dict_type は collections.OrderedDict です。 allow_no_value が追加されました。

class ConfigParser.ConfigParser([defaults[, dict_type[, allow_no_value]]])

RawConfigParser の派生クラスで値の置換を実装しており、 get() メソッドと items() メソッドに省略可能な引数を追加しています。 defaults に含まれる値は %()s による値の置換に適当なものである必要があります。 __name__ は組み込みのデフォルト値で、セクション名が含まれるので defaults で設定してもオーバーライドされます。

置換で使われるすべてのオプション名は、ほかのオプション名への参照と同様に optionxform() メソッドを介して渡されます。 optionxform() のデフォルト実装を使うと、値 foo %(bar)s および foo %(BAR)s は同一になります。

バージョン 2.3 で追加.

バージョン 2.6 で変更: dict_type が追加されました。

バージョン 2.7 で変更: デフォルトの dict_type は collections.OrderedDict です。 allow_no_value が追加されました。

class ConfigParser.SafeConfigParser([defaults[, dict_type[, allow_no_value]]])

ConfigParser の派生クラスでより安全な値の置換を実装しています。この実装はより予測可能性が高くなっています。新規に書くアプリケーションでは、古いバージョンのPythonと互換性を持たせる必要がない限り、このバージョンを利用することが望ましいです。

バージョン 2.3 で追加.

バージョン 2.6 で変更: dict_type が追加されました。

バージョン 2.7 で変更: デフォルトの dict_type は collections.OrderedDict です。 allow_no_value が追加されました。

exception ConfigParser.Error

他の全ての configparser の例外の基底クラスです。

exception ConfigParser.NoSectionError

指定したセクションが見つからなかった時に起きる例外です。

exception ConfigParser.DuplicateSectionError

すでに存在するセクション名に対して add_section() が呼び出された際に起きる例外です。

exception ConfigParser.NoOptionError

指定したオプションが指定したセクションに存在しなかった時に起きる例外です。

exception ConfigParser.InterpolationError

文字列の置換中に問題が起きた時に発生する例外の基底クラスです。

exception ConfigParser.InterpolationDepthError

InterpolationError の派生クラスで、文字列の置換回数が MAX_INTERPOLATION_DEPTH を越えたために完了しなかった場合に発生する例外です。

exception ConfigParser.InterpolationMissingOptionError

InterpolationError の派生クラスで、値が参照しているオプションが見つからない場合に発生する例外です。

exception ConfigParser.InterpolationSyntaxError

InterpolationError の派生クラスで、指定された構文で値を置換することができなかった場合に発生する例外です。

バージョン 2.3 で追加.

exception ConfigParser.MissingSectionHeaderError

セクションヘッダを持たないファイルを構文解析しようとした時に起きる例外です。

exception ConfigParser.ParsingError

ファイルの構文解析中にエラーが起きた場合に発生する例外です。

ConfigParser.MAX_INTERPOLATION_DEPTH

raw が偽だった場合の get() による再帰的な文字列置換の繰り返しの最大値です。 ConfigParser クラスだけに関係します。

参考

Module shlex

Unix のシェルに似た、アプリケーションの設定ファイル用フォーマットとして使えるもう一つの小型言語です。

13.2.1. RawConfigParser オブジェクト

RawConfigParser クラスのインスタンスは以下のメソッドを持ちます:

RawConfigParser.defaults()

インスタンス全体で使われるデフォルト値の辞書を返します。

RawConfigParser.sections()

利用可能なセクションのリストを返します。 DEFAULT はこのリストに含まれません。

RawConfigParser.add_section(section)

section という名前のセクションをインスタンスに追加します。同名のセクションが存在した場合、 DuplicateSectionError が発生します。 DEFAULT (もしくは大文字小文字が違うもの)が渡された場合、 ValueError が発生します。

RawConfigParser.has_section(section)

指定したセクションがコンフィグレーションファイルに存在するかを返します。 DEFAULT セクションは存在するとみなされません。

RawConfigParser.options(section)

section で指定したセクションで利用できるオプションのリストを返します。

RawConfigParser.has_option(section, option)

与えられたセクションが存在してかつオプションが与えられていれば True を返し、そうでなければ False を返します。

バージョン 1.6 で追加.

RawConfigParser.read(filenames)

ファイル名のリストを読んで解析をこころみ、うまく解析できたファイル名のリストを返します。もし filenames が文字列かユニコード文字列なら、1つのファイル名として扱われます。 filenames で指定されたファイルが開けない場合、そのファイルは無視されます。この挙動は設定ファイルが置かれる可能性のある場所(例えば、カレントディレクトリ、ホームディレクトリ、システム全体の設定を行うディレクトリ)を設定して、そこに存在する設定ファイルを読むことを想定して設計されています。設定ファイルが存在しなかった場合、 ConfigParser のインスタンスは空のデータセットを持ちます。初期値の設定ファイルを先に読み込んでおく必要があるアプリケーションでは、 readfp() を read() の前に呼び出すことでそのような動作を実現できます:

import ConfigParser, os

config = ConfigParser.ConfigParser()
config.readfp(open('defaults.cfg'))
config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')])

バージョン 2.4 で変更: うまく解析できたファイル名のリストを返す.

RawConfigParser.readfp(fp[, filename])

fp で与えられるファイルかファイルのようなオブジェクトを読み込んで構文解析します(readline() メソッドだけを使います)。もし filename が省略されて fp が name 属性を持っていれば filename の代わりに使われます。ファイル名の初期値は <???> です。

RawConfigParser.get(section, option)

section の option 変数を取得します。

RawConfigParser.getint(section, option)

section の option を整数として評価する関数です。

RawConfigParser.getfloat(section, option)

section の option を浮動小数点数として評価する関数です。

RawConfigParser.getboolean(section, option)

指定した section の option 値をブール値に型強制する便宜メソッドです。 option として受理できる値は、真 (True) としては "1" 、 "yes" 、 "true" 、 "on" 、偽 (False) としては "0" 、 "no" 、 "false" 、 "off" です。これらの文字列値に対しては大文字小文字の区別をしません。その他の値の場合には ValueError を送出します。

RawConfigParser.items(section)

与えられた section のそれぞれのオプションについて (name, value) ペアのリストを返します。

RawConfigParser.set(section, option, value)

与えられたセクションが存在していれば、オプションを指定された値に設定します。セクションが存在しなければ NoSectionError を発生させます。 RawConfigParser (あるいは raw パラメータをセットした ConfigParser) を文字列型でない値の 内部的な 格納場所として使うことは可能ですが、すべての機能 (置換やファイルへの出力を含む) がサポートされるのは文字列を値として使った場合だけです。

バージョン 1.6 で追加.

RawConfigParser.write(fileobject)

設定を文字列表現に変換してファイルオブジェクトに書き出します。この文字列表現は read() で読み込むことができます。

バージョン 1.6 で追加.

RawConfigParser.remove_option(section, option)

指定された section から指定された option を削除します。セクションが存在しなければ、 NoSectionError を起こします。存在するオプションを削除した時は True を、そうでない時は False を返します。

バージョン 1.6 で追加.

RawConfigParser.remove_section(section)

指定された section を設定から削除します。もし指定されたセクションが存在すれば True 、そうでなければ False を返します。

RawConfigParser.optionxform(option)

入力ファイル中に見つかったオプション名か、クライアントコードから渡されたオプション名 option を、内部で利用する形式に変換します。デフォルトでは option を全て小文字に変換した名前が返されます。サブルクラスではこの関数をオーバーライドすることでこの振舞いを替えることができます。

振舞いを替えるために ConfigParser を継承して新たにクラスを作る必要はありません、あるインスタンスのメソッドを文字列を引数に取る関数で置き換えることもできます。たとえば、このメソッドを str() に設定することで大小文字の差を区別するように変更することができます:

cfgparser = ConfigParser()
...
cfgparser.optionxform = str

設定ファイルを読み込むときには、 optionxform() が呼ばれる前にオプション名の前後の空白文字が取り除かれることに注意してください。

13.2.2. ConfigParser オブジェクト

ConfigParser クラスは RawConfigParser のインターフェースをいくつかのメソッドについて拡張し、省略可能な引数を追加しています。

ConfigParser.get(section, option[, raw[, vars]])

section の option 変数を取得します。このメソッドに渡される vars は辞書でなくてはいけません。 (もし渡されているならば) vars 、 section 、 defaults の順に option が探されます。

raw が真でない時には、全ての '%' 置換は展開されてから返されます。置換後の値はオプションと同じ順序で探されます

ConfigParser.items(section[, raw[, vars]])

指定した section 内の各オプションに対して、 (name, value) のペアからなるリストを返します。省略可能な引数は get() メソッドと同じ意味を持ちます。

バージョン 2.3 で追加.

13.2.3. SafeConfigParser オブジェクト

SafeConfigParser は ConfigParser と同様の拡張インターフェイスをもっていますが、以下のような機能が追加されています:

SafeConfigParser.set(section, option, value)

もし与えられたセクションが存在している場合は、指定された値を与えられたオプションに設定します。そうでない場合は NoSectionError を発生させます。 value は文字列 (str または unicode) でなければならず、そうでない場合には TypeError が発生します。

バージョン 2.4 で追加.

13.2.4. 例

configurationファイルを書き出す例:

import ConfigParser

config = ConfigParser.RawConfigParser()

# When adding sections or items, add them in the reverse order of
# how you want them to be displayed in the actual file.
# In addition, please note that using RawConfigParser's and the raw
# mode of ConfigParser's respective set functions, you can assign
# non-string values to keys internally, but will receive an error
# when attempting to write to a file or when you get it in non-raw
# mode. SafeConfigParser does not allow such assignments to take place.
config.add_section('Section1')
config.set('Section1', 'int', '15')
config.set('Section1', 'bool', 'true')
config.set('Section1', 'float', '3.1415')
config.set('Section1', 'baz', 'fun')
config.set('Section1', 'bar', 'Python')
config.set('Section1', 'foo', '%(bar)s is %(baz)s!')

# Writing our configuration file to 'example.cfg'
with open('example.cfg', 'wb') as configfile:
    config.write(configfile)

configurationファイルを読み込む例:

import ConfigParser

config = ConfigParser.RawConfigParser()
config.read('example.cfg')

# getfloat() raises an exception if the value is not a float
# getint() and getboolean() also do this for their respective types
float = config.getfloat('Section1', 'float')
int = config.getint('Section1', 'int')
print float + int

# Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
# This is because we are using a RawConfigParser().
if config.getboolean('Section1', 'bool'):
    print config.get('Section1', 'foo')

置換機能を利用するには、 ConfigParser か SafeConfigParser クラスを利用します:

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('example.cfg')

# Set the third, optional argument of get to 1 if you wish to use raw mode.
print config.get('Section1', 'foo', 0) # -> "Python is fun!"
print config.get('Section1', 'foo', 1) # -> "%(bar)s is %(baz)s!"

# The optional fourth argument is a dict with members that will take
# precedence in interpolation.
print config.get('Section1', 'foo', 0, {'bar': 'Documentation',
                                        'baz': 'evil'})

3種類全てのConfigParserクラスで、デフォルト値を利用できます。別にオプションが指定されていなかった場合、このデフォルト値は置換機能でも利用されます:

import ConfigParser

# New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
config = ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'})
config.read('example.cfg')

print config.get('Section1', 'foo') # -> "Python is fun!"
config.remove_option('Section1', 'bar')
config.remove_option('Section1', 'baz')
print config.get('Section1', 'foo') # -> "Life is hard!"

opt_move 関数は、オプションをセクション間で移動することができます:

def opt_move(config, section1, section2, option):
    try:
        config.set(section2, option, config.get(section1, option, 1))
    except ConfigParser.NoSectionError:
        # Create non-existent section
        config.add_section(section2)
        opt_move(config, section1, section2, option)
    else:
        config.remove_option(section1, option)

いくつかの設定ファイルでは、値のない設定項目がある以外は ConfigParser の文法と同じ文法になっています。コンストラクタの allow_no_value 引数で、そのような値を許可することができます。

>>> import ConfigParser
>>> import io

>>> sample_config = """
... [mysqld]
... user = mysql
... pid-file = /var/run/mysqld/mysqld.pid
... skip-external-locking
... old_passwords = 1
... skip-bdb
... skip-innodb
... """
>>> config = ConfigParser.RawConfigParser(allow_no_value=True)
>>> config.readfp(io.BytesIO(sample_config))

>>> # Settings with values are treated as before:
>>> config.get("mysqld", "user")
'mysql'

>>> # Settings without values provide None:
>>> config.get("mysqld", "skip-bdb")

>>> # Settings which aren't specified still raise an error:
>>> config.get("mysqld", "does-not-exist")
Traceback (most recent call last):
  ...
ConfigParser.NoOptionError: No option 'does-not-exist' in section: 'mysqld'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.3. robotparser — robots.txt のためのパーザ

ノート

robotparser モジュールは、 Python 3.0 では urllib.robotparser にリネームされました。 2to3 ツールが自動的にソースコードの import を修正します。

このモジュールでは単一のクラス、 RobotFileParser を提供します。このクラスは、特定のユーザエージェントが robots.txt ファイルを公開している Web サイトのある URL を取得可能かどうかの質問に答えます。 robots.txt ファイルの構造に関する詳細は http://www.robotstxt.org/orig.html を参照してください。

class robotparser.RobotFileParser

このクラスでは単一の robots.txt ファイルを読み出し、解釈し、ファイルの内容に関する質問の回答を得るためのメソッドを定義しています。

set_url(url)

robots.txt ファイルを参照するための URL を設定します。

read()

robots.txt URL を読み出し、パーザに入力します。

parse(lines)

引数 lines の内容を解釈します。

can_fetch(useragent, url)

解釈された robots.txt ファイル中に記載された規則に従ったとき、 useragent が url を取得してもよい場合には True を返します。

mtime()

robots.txt ファイルを最後に取得した時刻を返します。この値は、定期的に新たな robots.txt をチェックする必要がある、長時間動作する Web スパイダープログラムを実装する際に便利です。

modified()

robots.txt ファイルを最後に取得した時刻を現在の時刻に設定します。

以下にRobotFileParser クラスの利用例を示します。

>>> import robotparser
>>> rp = robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.4. netrc — netrc ファイルの処理

バージョン 1.5.2 で追加.

netrc クラスは、Unix ftp プログラムや他の FTP クライアントで用いられる netrc ファイル形式を解析し、カプセル化 (encapsulate) します。

class netrc.netrc([file])

netrc のインスタンスやサブクラスのインスタンスは netrc ファイルのデータをカプセル化します。初期化の際の引数が存在する場合、解析対象となるファイルの指定になります。引数がない場合、ユーザのホームディレクトリ下にある .netrc が読み出されます。解析エラーが発生した場合、ファイル名、行番号、解析を中断したトークンに関する情報の入った NetrcParseError を送出します。

exception netrc.NetrcParseError

ソースファイルのテキスト中で文法エラーに遭遇した場合に netrc クラスによって送出される例外です。この例外のインスタンスは 3 つのインスタンス変数を持っています: msg はテキストによるエラーの説明で、 filename はソースファイルの名前、そして lineno はエラーが発見された行番号です。

13.4.1. netrc オブジェクト

netrc インスタンスは以下のメソッドを持っています:

netrc.authenticators(host)

host の認証情報として、三要素のタプル (login, account, password) を返します。与えられた host に対するエントリが netrc ファイルにない場合、 ‘default’ エントリに関連付けられたタプルが返されます。 host に対応するエントリがなく、default エントリもない場合、 None を返します。

netrc.__repr__()

クラスの持っているデータを netrc ファイルの書式に従った文字列で出力します。(コメントは無視され、エントリが並べ替えられる可能性があります。)

netrc のインスタンスは以下の公開されたインスタンス変数を持っています:

netrc.hosts

ホスト名を (login, account, password) からなるタプルに対応づけている辞書です。’default’ エントリがある場合、その名前の擬似ホスト名として表現されます。

netrc.macros

マクロ名を文字列のリストに対応付けている辞書です。

ノート

利用可能なパスワードの文字セットは、ASCIIのサブセットのみです。2.3より前のバージョンでは厳しく制限されていましたが、2.3以降ではASCIIの記号を使用することができます。しかし、空白文字と印刷不可文字を使用することはできません。この制限は .netrcファイルの解析方法によるものであり、将来解除されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.5. xdrlib — XDR データのエンコードおよびデコード

xdrlib モジュールは外部データ表現標準 (External Data Representation Standard) のサポートを実現します。この標準は 1987 年に Sun Microsystems, Inc. によって書かれ、 RFC 1014 [http://tools.ietf.org/html/rfc1014.html] で定義されています。このモジュールでは RFC で記述されているほとんどのデータ型をサポートしています。

xdrlib モジュールでは 2 つのクラスが定義されています。一つは変数を XDR 表現にパックするためのクラスで、もう一方は XDR 表現からアンパックするためのものです。2 つの例外クラスが同様にして定義されています。

class xdrlib.Packer

Packer はデータを XDR 表現にパックするためのクラスです。 Packer クラスのインスタンス生成は引数なしで行われます。

class xdrlib.Unpacker(data)

Unpacker は Packer と対をなしていて、文字列バッファから XDR をアンパックするためのクラスです。入力バッファ data を引数に与えてインスタンスを生成します。

参考

RFC 1014 [http://tools.ietf.org/html/rfc1014.html] - XDR: External Data Representation Standard

この RFC が、かつてこのモジュールが最初に書かれた当時に XDR 標準であったデータのエンコード方法を定義していました。現在は RFC 1832 [http://tools.ietf.org/html/rfc1832.html] に更新されているようです。

RFC 1832 [http://tools.ietf.org/html/rfc1832.html] - XDR: External Data Representation Standard

こちらが新しい方のRFCで、XDR の改訂版が定義されています。

13.5.1. Packer オブジェクト

Packer インスタンスには以下のメソッドがあります:

Packer.get_buffer()

現在のパック処理用バッファを文字列で返します。

Packer.reset()

パック処理用バッファをリセットして、空文字にします。

一般的には、適切な pack_type() メソッドを使えば、一般に用いられているほとんどの XDR データをパックすることができます。各々のメソッドは一つの引数をとり、パックしたい値を与えます。単純なデータ型をパックするメソッドとして、以下のメソッド: pack_uint() 、 pack_int() 、 pack_enum() 、 pack_bool() 、 pack_uhyper() そして pack_hyper() がサポートされています。

Packer.pack_float(value)

単精度 (single-precision) の浮動小数点数 value をパックします。

Packer.pack_double(value)

倍精度 (double-precision) の浮動小数点数 value をパックします。

以下のメソッドは文字列、バイト列、不透明データ (opaque data) のパック処理をサポートします:

Packer.pack_fstring(n, s)

固定長の文字列、 s をパックします。 n は文字列の長さですが、この値自体はデータバッファにはパック されません 。 4 バイトのアラインメントを保証するために、文字列は必要に応じて null バイト列でパディングされます。

Packer.pack_fopaque(n, data)

pack_fstring() と同じく、固定長の不透明データストリームをパックします。

Packer.pack_string(s)

可変長の文字列 s をパックします。文字列の長さが最初に符号なし整数でパックされ、続いて pack_fstring() を使って文字列データがパックされます。

Packer.pack_opaque(data)

pack_string() と同じく、可変長の不透明データ文字列をパックします。

Packer.pack_bytes(bytes)

pack_string() と同じく、可変長のバイトストリームをパックします。

以下のメソッドはアレイやリストのパック処理をサポートします:

Packer.pack_list(list, pack_item)

一様な項目からなる list をパックします。このメソッドはサイズ不定、すなわち、全てのリスト内容を網羅するまでサイズが分からないリストに対して有用です。リストのすべての項目に対し、最初に符号無し整数 1 がパックされ、続いてリスト中のデータがパックされます。 pack_item は個々の項目をパックするために呼び出される関数です。リストの末端に到達すると、符号無し整数 0 がパックされます。

例えば、整数のリストをパックするには、コードは以下のようになるはずです:

import xdrlib
p = xdrlib.Packer()
p.pack_list([1, 2, 3], p.pack_int)

Packer.pack_farray(n, array, pack_item)

一様な項目からなる固定長のリスト (array) をパックします。 n はリストの長さです。この値はデータバッファにパック されませんが、 len(array) が n と等しくない場合、例外 ValueError が送出されます。上と同様に、 pack_item は個々の要素をパック処理するための関数です。

Packer.pack_array(list, pack_item)

一様の項目からなる可変長の list をパックします。まず、リストの長さが符号無し整数でパックされ、つづいて各要素が上の pack_farray() と同じやり方でパックされます。

13.5.2. Unpacker オブジェクト

Unpacker クラスは以下のメソッドを提供します:

Unpacker.reset(data)

文字列バッファを data でリセットします。

Unpacker.get_position()

データバッファ中の現在のアンパック処理位置を返します。

Unpacker.set_position(position)

データバッファ中のアンパック処理位置を position に設定します。 get_position() および set_position() は注意して使わなければなりません。

Unpacker.get_buffer()

現在のアンパック処理用データバッファを文字列で返します。

Unpacker.done()

アンパック処理を終了させます。全てのデータがまだアンパックされていなければ、例外 Error が送出されます。

上のメソッドに加えて、 Packer でパック処理できるデータ型はいずれも Unpacker でアンパック処理できます。アンパック処理メソッドは unpack_type() の形式をとり、引数をとりません。これらのメソッドはアンパックされたデータオブジェクトを返します。

Unpacker.unpack_float()

単精度の浮動小数点数をアンパックします。

Unpacker.unpack_double()

unpack_float() と同様に、倍精度の浮動小数点数をアンパックします。

上のメソッドに加えて、文字列、バイト列、不透明データをアンパックする以下のメソッドが提供されています:

Unpacker.unpack_fstring(n)

固定長の文字列をアンパックして返します。 n は予想される文字列の長さです。4 バイトのアラインメントを保証するために null バイトによるパディングが行われているものと仮定して処理を行います。

Unpacker.unpack_fopaque(n)

unpack_fstring() と同様に、固定長の不透明データストリームをアンパックして返します。

Unpacker.unpack_string()

可変長の文字列をアンパックして返します。最初に文字列の長さが符号無し整数としてアンパックされ、次に unpack_fstring() を使って文字列データがアンパックされます。

Unpacker.unpack_opaque()

unpack_string() と同様に、可変長の不透明データ文字列をアンパックして返します。

Unpacker.unpack_bytes()

unpack_string() と同様に、可変長のバイトストリームをアンパックして返します。

以下メソッドはアレイおよびリストのアンパック処理をサポートします。

Unpacker.unpack_list(unpack_item)

一様な項目からなるリストをアンパック処理してかえします。リストは一度に 1 要素づつアンパック処理されます、まず符号無し整数によるフラグがアンパックされます。もしフラグが 1 なら、要素はアンパックされ、返り値のリストに追加されます。フラグが 0 であれば、リストの終端を示します。 unpack_item は個々の項目をアンパック処理するために呼び出される関数です。

Unpacker.unpack_farray(n, unpack_item)

一様な項目からなる固定長のアレイをアンパックして（リストとして）返します。 n はバッファ内に存在すると期待されるリストの要素数です。上と同様に、 unpack_item は各要素をアンパックするために使われる関数です。

Unpacker.unpack_array(unpack_item)

一様な項目からなる可変長の list をアンパックして返します。まず、リストの長さが符号無し整数としてアンパックされ、続いて各要素が上の unpack_farray() のようにしてアンパック処理されます。

13.5.3. 例外

このモジュールでの例外はクラスインスタンスとしてコードされています:

exception xdrlib.Error

ベースとなる例外クラスです。 Error public なデータメンバとして msg を持ち、エラーの詳細が収められています。

exception xdrlib.ConversionError

Error から派生したクラスです。インスタンス変数は塚されていません。

これらの例外を補足する方法を以下の例に示します:

import xdrlib
p = xdrlib.Packer()
try:
    p.pack_double(8.01)
except xdrlib.ConversionError, instance:
    print 'packing the double failed:', instance.msg

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

13. ファイルフォーマット »

13.6. plistlib — Mac OS X .plist ファイルの生成と解析

バージョン 2.6 で変更: このモジュールは以前は Mac 専用ライブラリだけにありましたが、全てのプラットフォームで使えるようにしました。

このモジュールは主に Mac OS X で使われる「プロパティーリスト」 XML ファイルを読み書きするインターフェイスを提供します。

プロパティーリスト (.plist) ファイル形式は基本的型のオブジェクト、たとえば辞書やリスト、数、文字列など、に対する単純な XML による保存形式です。たいてい、トップレベルのオブジェクトは辞書です。

値は文字列、整数、浮動小数点数、ブール型、タプル、リスト、辞書 (ただし文字列だけがキーになれます)、 Data または datetime.datetime のオブジェクトです。文字列の値は(辞書のキーも含めて)ユニコード文字列であって構いません – それらは UTF-8 で書き出されます。

<data> plist 型は Data クラスを通じてサポートされます。これは Python の文字列に対する薄いラッパです。文字列に制御文字を含めなければならない場合は Data を使って下さい。

参考

PList manual page [http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html]

このファイル形式の Apple の文書。

このモジュールは以下の関数を定義しています:

plistlib.readPlist(pathOrFile)

plist ファイルを読み込みます。 pathOrFile はファイル名でも(読み込み可能な)ファイルオブジェクトでも構いません。展開されたルートオブジェクト(たいていは辞書です)を返します。

XML データは xml.parsers.expat にある Expat パーサを使って解析されます – 間違いのある XML に対して送られる可能性のある例外についてはそちらの文書を参照して下さい。未知の要素は plist 解析器から単純に無視されます。

plistlib.writePlist(rootObject, pathOrFile)

rootObject を plist ファイルに書き込みます。 pathOrFile はファイル名でも(書き込み可能な)ファイルオブジェクトでも構いません。

TypeError が、オブジェクトがサポート外の型のものであったりサポート外の型のオブジェクトを含むコンテナだった場合に、送出されます。

plistlib.readPlistFromString(data)

文字列から plist を読み取ります。ルートオブジェクトを返します。

plistlib.writePlistToString(rootObject)

rootObject を plist 形式の文字列として返します。

plistlib.readPlistFromResource(path[, restype='plst'[, resid=0]])

path のリソースフォークの中の restype タイプのリソースから plist を読み込みます。使用可能: Mac OS X。

警告

3.x では、この関数は削除されています。

plistlib.writePlistToResource(rootObject, path[, restype='plst'[, resid=0]])

rootObject を path のリソースフォークの中に restype タイプのリソースとして書き込みます。使用可能: Mac OS X。

警告

3.x では、この関数は削除されてます。

以下のクラスが使用可能です。

class plistlib.Data(data)

文字列 data を包むラッパオブジェクトを返します。 plist 中に入れられる <data> 型を表すものとして plist への/からの変換関数で使われます。

これには data という一つの属性があり、そこに収められた Python 文字列を取り出すのに使えます。

13.6.1. 例

plist を作ります:

pl = dict(
    aString="Doodah",
    aList=["A", "B", 12, 32.1, [1, 2, 3]],
    aFloat = 0.1,
    anInt = 728,
    aDict=dict(
        anotherString="<hello & hi there!>",
        aUnicodeValue=u'M\xe4ssig, Ma\xdf',
        aTrueValue=True,
        aFalseValue=False,
    ),
    someData = Data("<binary gunk>"),
    someMoreData = Data("<lots of binary gunk>" * 10),
    aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
)
# unicode keys are possible, but a little awkward to use:
pl[u'\xc5benraa'] = "That was a unicode key."
writePlist(pl, fileName)

plist を解析します:

pl = readPlist(pathOrFile)
print pl["aKey"]

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

14. 暗号関連のサービス

この章で記述されているモジュールでは、暗号の本質に関わる様々なアルゴリズムを実装しています。これらは必要に応じてインストールすることで使えます。概要を以下に示します:

14.1. hashlib — セキュアハッシュおよびメッセージダイジェスト

14.2. hmac — メッセージ認証のための鍵付きハッシュ化

14.3. md5 — MD5 メッセージダイジェストアルゴリズム

14.4. sha — SHA-1 メッセージダイジェストアルゴリズム

あなたがハードコアなサイファーパンクなら、 A.M. Kuchling の書いた暗号化モジュールに興味を持つかもしれません。このパッケージは AES をはじめとする様々な暗号化アルゴリズムのモジュールを含みます。これらのモジュールは Python と一緒には配布されず、別に入手できます。詳細は URL http://www.amk.ca/python/code/crypto.html を見てください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

14. 暗号関連のサービス »

14.1. hashlib — セキュアハッシュおよびメッセージダイジェスト

バージョン 2.5 で追加.

このモジュールは、セキュアハッシュやメッセージダイジェスト用のさまざまなアルゴリズムを実装したものです。FIPSのセキュアなハッシュアルゴリズムである SHA1、SHA224、SHA256、SHA384およびSHA512 (FIPS 180-2 で定義されているもの) だけでなくRSAのMD5アルゴリズム (Internet RFC 1321 [http://tools.ietf.org/html/rfc1321.html] で定義されています)も実装しています。「セキュアなハッシュ」と「メッセージダイジェスト」はどちらも同じ意味です。古くからあるアルゴリズムは「メッセージダイジェスト」と呼ばれていますが、最近は「セキュアハッシュ」という用語が用いられています。

ノート

adler32 や crc32 ハッシュ関数が使いたければ、 zlib モジュールにあります。

警告

中には、ハッシュの衝突の脆弱性をかかえているアルゴリズムもあります。最後のFAQをごらんください。

hash のそれぞれの型の名前をとったコンストラクタメソッドがひとつずつあります。返されるハッシュオブジェクトは、どれも同じシンプルなインターフェイスを持っています。たとえば sha1() を使用するとSHA1ハッシュオブジェクトが作成されます。このオブジェクトの update() メソッドに、任意の文字列を渡すことができます。それまでに渡した文字列の digest を知りたければ、 digest() メソッドあるいは hexdigest() メソッドを使用します。

このモジュールで常に使用できるハッシュアルゴリズムのコンストラクタは md5() 、 sha1() 、 sha224() 、 sha256() 、 sha384() および sha512() です。それ以外のアルゴリズムが使用できるかどうかは、Python が使用している OpenSSL ライブラリに依存します。

たとえば、 'Nobody inspects the spammish repetition' という文字列のダイジェストを取得するには次のようにします。 :

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
64

もっと簡潔に書くと、このようになります。 :

>>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'

汎用的なコンストラクタ new() も用意されています。このコンストラクタの最初のパラメータとして、使いたいアルゴリズムの名前を指定します。アルゴリズム名として指定できるのは、先ほど説明したアルゴリズムかOpenSSLライブラリが提供するアルゴリズムとなります。しかし、アルゴリズム名のコンストラクタのほうが new() よりずっと高速なので、そちらを使うことをお勧めします。

new() にOpenSSLのアルゴリズムを指定する例です。 :

>>> h = hashlib.new('ripemd160')
>>> h.update("Nobody inspects the spammish repetition")
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'

このモジュールは以下の定数属性を提供しています。

hashlib.algorithms

このモジュールによってサポートされていることが保証されるハッシュアルゴリズムの名前が入ったたぷる。

バージョン 2.7 で追加.

コンストラクタが返すハッシュオブジェクトには、次のような定数属性が用意されています。

hash.digest_size

生成されたハッシュのバイト数。

hash.block_size

内部で使われるハッシュアルゴリズムのブロックのバイト数。

ハッシュオブジェクトには次のようなメソッドがあります。

hash.update(arg)

ハッシュオブジェクトを文字列 arg で更新します。繰り返してコールするのは、すべての引数を連結して1回だけコールするのと同じ意味になります。つまり、 m.update(a); m.update(b) と m.update(a+b) は同じ意味だということです。

バージョン 2.7 で変更.

hash.digest()

これまでに update() メソッドに渡した文字列のダイジェストを返します。これは digest_size バイトの文字列であり、非ASCII文字やnull バイトを含むこともあります。

hash.hexdigest()

digest() と似ていますが、返される文字列は倍の長さとなり、16進形式となります。これは、電子メールなどの非バイナリ環境で値を交換する場合に便利です。

hash.copy()

ハッシュオブジェクトのコピー (“クローン”) を返します。これは、共通部分を持つ複数の文字列のダイジェストを効率的に計算するために使用します。

参考

Module hmac

ハッシュを用いてメッセージ認証コードを生成するモジュールです。

Module base64

バイナリハッシュを非バイナリ環境用にエンコードするもうひとつの方法です。

http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf

FIPS 180-2 のセキュアハッシュアルゴリズムについての説明。

http://www.cryptography.com/cnews/hash.html

Hash Collision FAQ。既知の問題を持つアルゴリズムとその使用上の注意点に関する情報があります。

http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms

どのアルゴリズムにどんな既知の問題があって、それが実際に利用する際にどう影響するかについての Wikipedia の記事

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

14. 暗号関連のサービス »

14.2. hmac — メッセージ認証のための鍵付きハッシュ化

バージョン 2.2 で追加.

このモジュールでは RFC 2104 [http://tools.ietf.org/html/rfc2104.html] で記述されている HMAC アルゴリズムを実装しています。

hmac.new(key[, msg[, digestmod]])

新たな hmac オブジェクトを返します。 msg が存在すれば、メソッド呼び出し update(msg) を行います。 digestmod は HMAC オブジェクトが使うダイジェストコンストラクタあるいはモジュールです。標準では hashlib.md5() コンストラクタになっています。

HMAC オブジェクトは以下のメソッドを持っています:

hmac.update(msg)

hmac オブジェクトを文字列 msg で更新します。このメソッドの呼出の繰り返しは、それらの引数を全て結合した引数で単一の呼び出しをした際と同じになります。すなわち m.update(a); m.update(b) は m.update(a + b) と等価です。

hmac.digest()

これまで update() メソッドに渡された文字列のダイジェスト値を返します。これは digest_size バイトの文字列で、 NUL バイトを含む非 ASCII 文字が含まれることがあります。

hmac.hexdigest()

digest() と似ていますが、返される文字列は倍の長さとなり、16進形式となります。これは、電子メールなどの非バイナリ環境で値を交換する場合に便利です。

hmac.copy()

hmac オブジェクトのコピー (“クローン”) を返します。このコピーは最初の部分文字列が共通になっている文字列のダイジェスト値を効率よく計算するために使うことができます。

参考

Module hashlib

セキュアハッシュ関数を提供する Python モジュールです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

14. 暗号関連のサービス »

14.3. md5 — MD5 メッセージダイジェストアルゴリズム

バージョン 2.5 で撤廃: 代わりにモジュール hashlib を使ってください。

このモジュールは RSA 社の MD5 メッセージダイジェスト アルゴリズムへのインタフェースを実装しています。 (Internet RFC 1321 [http://tools.ietf.org/html/rfc1321.html] も参照してください)。利用方法は極めて単純です。まず md5 オブジェクトを new() を使って生成します。後は update() メソッドを使って、生成されたオブジェクトに任意の文字列データを入力します。オブジェクトに入力された文字列データ全体の digest (“fingerprint” として知られる強力な 128-bit チェックサム) は digest() を使っていつでも調べることができます。

例えば、文字列 'Nobody inspects the spammish repetition' のダイジェストを得るためには以下のようにします:

>>> import md5
>>> m = md5.new()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'

もっと詰めて書くと以下のようになります:

>>> md5.new("Nobody inspects the spammish repetition").digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'

以下の値はモジュールの中で定数として与えられており、 new() で返される md5 オブジェクトの属性としても与えられます:

md5.digest_size

返されるダイジェスト値のバイト数で表した長さ。常に 16 です。

md5 クラスオブジェクトは以下のメソッドをサポートします:

md5.new([arg])

新たな md5 オブジェクトを返します。もし arg が存在するなら、 update(arg) を呼び出します。

md5.md5([arg])

下位互換性のために、 new() の別名として提供されています。

md5 オブジェクトは以下のメソッドをサポートします:

md5.update(arg)

文字列 arg を入力として md5 オブジェクトを更新します。このメソッドを繰り返して呼び出す操作は、それぞれの呼び出し時の引数 arg を結合したデータを引数として一回の呼び出す操作と同等になります: つまり、 m.update(a); m.update(b) は m.update(a+b) と同等です。

md5.digest()

これまで update() で与えてきた文字列入力のダイジェストを返します。返り値は 16 バイトの文字列で、null バイトを含む非 ASCII 文字が入っているかもしれません。

md5.hexdigest()

digest() に似ていますが、ダイジェストは長さ 32 の文字列になり、16 進表記文字しか含みません。この文字列は電子メールやその他のバイナリを受け付けない環境でダイジェストを安全にやりとりするために使うことができます。

md5.copy()

md5 オブジェクトのコピー (“クローン”) を返します。冒頭の部分文字列が共通な複数の文字列のダイジェストを効率よく計算する際に使うことができます。

参考

Module sha

Secure Hash Algorithm (SHA) を実装した類似のモジュール。 SHA アルゴリズムはより安全なハッシュアルゴリズムだと考えられています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

14. 暗号関連のサービス »

14.4. sha — SHA-1 メッセージダイジェストアルゴリズム

バージョン 2.5 で撤廃: かわりにモジュール hashlib を使ってください。

このモジュールは、SHA-1 として知られている、 NIST のセキュアハッシュアルゴリズムへのインターフェースを実装しています。 SHA-1 はオリジナルの SHA ハッシュアルゴリズムを改善したバージョンです。 md5 モジュールと同じように使用します。 sha オブジェクトを生成するために new() を使い、 update() メソッドを使って、このオブジェクトに任意の文字列を入力し、それまでに入力した文字列全体の digest をいつでも調べることができます。 SHA-1 のダイジェストは MD5 の 128 bit とは異なり、160 bit です。

sha.new([string])

新たな sha オブジェクトを返します。もし string が存在するなら、 update(string) を呼び出します。

以下の値はモジュールの中で定数として与えられており、 new() で返される sha オブジェクトの属性としても与えられます:

sha.blocksize

ハッシュ関数に入力されるブロックのサイズ。このサイズは常に 1 です。このサイズは、任意の文字列をハッシュできるようにするために使われます。

sha.digest_size

返されるダイジェスト値をバイト数で表した長さ。常に 20 です。

sha オブジェクトには md5 オブジェクトと同じメソッドがあります。

sha.update(arg)

文字列 arg を入力として sha オブジェクトを更新します。このメソッドを繰り返し呼び出す(操作は、それぞれの呼び出し時の引数を結合したデータを引数として一回の呼び出す操作と同等になります。つまり、 m.update(a); m.update(b) は m.update(a+b) と同等です。

sha.digest()

これまで update() メソッドで与えてきた文字列のダイジェストを返します。戻り値は 20 バイトの文字列で、nullバイトを含む非 ASCII 文字が入っているかもしれません。

sha.hexdigest()

digits() と似ていますが、ダイジェストは長さ40の文字列になり、16進表記数字しか含みません。電子メールやその他のバイナリを受け付けない環境で安全に値をやりとりするために使うことができます。

sha.copy()

sha オブジェクトのコピー(“クローン”)を返します。冒頭の部分文字列が共通な複数の文字列のダイジェストを効率よく計算する際に使うことができます。

参考

セキュアハッシュスタンダード [http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf]

セキュアハッシュアルゴリズムは NIST のドキュメント FIPS PUB 180-2 で定義されています。 セキュアハッシュスタンダード [http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf], 2002年8月出版。

暗号ツールキット (セキュアハッシュ) [http://csrc.nist.gov/CryptoToolkit/tkhash.html]

NISTからはられているセキュアハッシュに関するさまざまな情報へのリンク

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス

本章に記述されたモジュールは、ファイルの取り扱いや時間計測のような (ほぼ)すべてのオペレーティングシステムで利用可能な機能にインタフェースを提供します。これらのインタフェースは、Unix もしくは C のインタフェースを基に作られますが、ほとんどの他のシステムで同様に利用可能です。概要を以下に記述します。

15.1. os — 雑多なオペレーティングシステムインタフェース

15.1.1. プロセスのパラメタ

15.1.2. ファイルオブジェクトの生成

15.1.3. ファイル記述子の操作

15.1.3.1. open() フラグ定数

15.1.4. ファイルとディレクトリ

15.1.5. プロセス管理

15.1.6. 雑多なシステム情報

15.1.7. 雑多な関数

15.2. io — ストリームを扱うコアツール

15.2.1. モジュールインタフェース

15.2.2. I/O 基底クラス

15.2.3. 生ファイルI/O

15.2.4. バッファ付きストリーム

15.2.5. テキスト I/O

15.2.6. 進んだ話題

15.2.6.1. パフォーマンス

15.2.6.1.1. バイナリ I/O

15.2.6.1.2. テキスト I/O

15.2.6.2. マルチスレッディング

15.2.6.3. リエントラント性

15.3. time — 時刻データへのアクセスと変換

15.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー

15.4.1. 例

15.4.1.1. パーサーを作る

15.4.1.2. 引数を追加する

15.4.1.3. 引数をパースする

15.4.2. ArgumentParser オブジェクト

15.4.2.1. description

15.4.2.2. epilog

15.4.2.3. add_help

15.4.2.4. prefix_chars

15.4.2.5. fromfile_prefix_chars

15.4.2.6. argument_default

15.4.2.7. parents

15.4.2.8. formatter_class

15.4.2.9. conflict_handler

15.4.2.10. prog

15.4.2.11. usage

15.4.3. add_argument() メソッド

15.4.3.1. name or flags

15.4.3.2. action

15.4.3.3. nargs

15.4.3.4. const

15.4.3.5. default

15.4.3.6. type

15.4.3.7. choices

15.4.3.8. required

15.4.3.9. help

15.4.3.10. metavar

15.4.3.11. dest

15.4.4. parse_args() メソッド

15.4.4.1. オプション値の文法

15.4.4.2. 不正な引数

15.4.4.3. "-" を含む引数

15.4.4.4. 引数の短縮形

15.4.4.5. sys.argv 以外

15.4.4.6. Namespace オブジェクト

15.4.5. その他のユーティリティ

15.4.5.1. サブコマンド

15.4.5.2. FileType オブジェクト

15.4.5.3. 引数グループ

15.4.5.4. 相互排他

15.4.5.5. パーサーのデフォルト値

15.4.5.6. ヘルプの表示

15.4.5.7. 部分解析

15.4.5.8. ファイル解析のカスタマイズ

15.4.5.9. 終了メソッド

15.4.6. optparse からのアップグレード

15.5. optparse — コマンドラインオプション解析器

15.5.1. 背景

15.5.1.1. 用語集

15.5.1.2. オプションとは何か

15.5.1.3. 固定引数とは何か

15.5.2. チュートリアル

15.5.2.1. オプション・アクションを理解する

15.5.2.2. store アクション

15.5.2.3. ブール値 (フラグ) オプションの処理

15.5.2.4. その他のアクション

15.5.2.5. デフォルト値

15.5.2.6. ヘルプの生成

15.5.2.6.1. オプションをグループ化する

15.5.2.7. バージョン番号の出力

15.5.2.8. optparse のエラー処理法

15.5.2.9. 全てをつなぎ合わせる

15.5.3. リファレンスガイド

15.5.3.1. parserを作る

15.5.3.2. パーザへのオプション追加

15.5.3.3. オプションの定義

15.5.3.4. オプション属性

15.5.3.5. 標準的なオプション・アクション

15.5.3.6. 標準のオプション型

15.5.3.7. 引数の解析

15.5.3.8. オプション解析器への問い合わせと操作

15.5.3.9. オプション間の衝突

15.5.3.10. クリーンアップ

15.5.3.11. その他のメソッド

15.5.4. オプション処理コールバック

15.5.4.1. callbackオプションの定義

15.5.4.2. コールバック関数はどのように呼び出されるか

15.5.4.3. コールバック中で例外を送出する

15.5.4.4. コールバックの例 1: ありふれたコールバック

15.5.4.5. コールバックの例 2: オプションの順番をチェックする

15.5.4.6. コールバックの例 3: オプションの順番をチェックする (汎用的)

15.5.4.7. コールバックの例 4: 任意の条件をチェックする

15.5.4.8. コールバックの例5: 固定引数

15.5.4.9. コールバックの例6: 可変個の引数

15.5.5. optparse の拡張

15.5.5.1. 新しい型の追加

15.5.5.2. 新しいアクションの追加

15.6. getopt — C言語スタイルのコマンドラインオプションパーサ

15.7. logging — Python 用ロギング機能

15.7.1. ロガーオブジェクト

15.7.2. ハンドラオブジェクト

15.7.3. フォーマッタオブジェクト

15.7.4. フィルタオブジェクト

15.7.5. LogRecord オブジェクト

15.7.6. LogRecord 属性

15.7.7. LoggerAdapter オブジェクト

15.7.8. スレッドセーフ性

15.7.9. モジュールレベル関数

15.7.10. warnings モジュールとの統合

15.8. logging.config — ロギングの環境設定

15.8.1. 環境設定のための関数

15.8.2. 環境設定辞書スキーマ

15.8.2.1. 辞書スキーマの詳細

15.8.2.2. 増分設定

15.8.2.3. オブジェクトの接続

15.8.2.4. ユーザ定義オブジェクト

15.8.2.5. 外部オブジェクトへのアクセス

15.8.2.6. 内部オブジェクトへのアクセス

15.8.3. 環境設定ファイルの書式

15.9. logging.handlers — ロギングハンドラ

15.9.1. StreamHandler

15.9.2. FileHandler

15.9.3. NullHandler

15.9.4. WatchedFileHandler

15.9.5. RotatingFileHandler

15.9.6. TimedRotatingFileHandler

15.9.7. SocketHandler

15.9.8. DatagramHandler

15.9.9. SysLogHandler

15.9.10. NTEventLogHandler

15.9.11. SMTPHandler

15.9.12. MemoryHandler

15.9.13. HTTPHandler

15.10. getpass — 可搬性のあるパスワード入力機構

15.11. curses — 文字セル表示のための端末操作

15.11.1. 関数

15.11.2. Window オブジェクト

15.11.3. 定数

15.12. curses.textpad — curses プログラムのためのテキスト入力ウィジェット

15.12.1. Textbox オブジェクト

15.13. curses.wrapper — curses プログラムのための端末ハンドラ

15.14. curses.ascii — ASCII 文字に関するユーティリティ

15.15. curses.panel — curses のためのパネルスタック拡張

15.15.1. 関数

15.15.2. Panel オブジェクト

15.16. platform — 実行中プラットフォームの固有情報を参照する

15.16.1. クロスプラットフォーム

15.16.2. Java プラットフォーム

15.16.3. Windows プラットフォーム

15.16.3.1. Win95/98 固有

15.16.4. Mac OS プラットフォーム

15.16.5. Unix プラットフォーム

15.17. errno — 標準の errno システムシンボル

15.18. ctypes — Pythonのための外部関数ライブラリ

15.18.1. ctypesチュートリアル

15.18.1.1. 動的リンクライブラリをロードする

15.18.1.2. ロードしたdllから関数にアクセスする

15.18.1.3. 関数を呼び出す

15.18.1.4. 基本のデータ型

15.18.1.5. 続・関数を呼び出す

15.18.1.6. 自作のデータ型とともに関数を呼び出す

15.18.1.7. 要求される引数の型を指定する (関数プロトタイプ)

15.18.1.8. 戻り値の型

15.18.1.9. ポインタを渡す(または、パラメータの参照渡し)

15.18.1.10. 構造体と共用体

15.18.1.11. 構造体/共用体アライメントとバイトオーダー

15.18.1.12. 構造体と共用体におけるビットフィールド

15.18.1.13. 配列

15.18.1.14. ポインタ

15.18.1.15. 型変換

15.18.1.16. 不完全型

15.18.1.17. コールバック関数

15.18.1.18. dllからエクスポートされている値へアクセスする

15.18.1.19. 予期しないこと

15.18.1.20. 可変サイズのデータ型

15.18.2. ctypesリファレンス

15.18.2.1. 共有ライブラリを見つける

15.18.2.2. 共有ライブラリをロードする

15.18.2.3. 外部関数

15.18.2.4. 関数プロトタイプ

15.18.2.5. ユーティリティ関数

15.18.2.6. データ型

15.18.2.7. 基本データ型

15.18.2.8. 標準データ型

15.18.2.9. 配列とポインタ

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.1. os — 雑多なオペレーティングシステムインタフェース

このモジュールは、OS依存の機能をポータブルな方法で利用する方法を提供します。単純なファイルの読み書きについては、 open() を参照してください。パス操作については、 os.path モジュールを参照してください。コマンドラインに与えられた全てのファイルから行を読み込んでいくには、 fileinput モジュールを参照してください。一時ファイルや一時ディレクトリの作成については、 tempfile モジュールを参照してください。高レベルなファイルとディレクトリの操作については、 shutil モジュールを参照してください。

利用可能性に関する注意:

Pythonの、全てのOS依存モジュールの設計方針は、可能な限り同一のインタフェースで同一の機能を利用できるようにする、というものです。例えば、 os.stat(path) は path に関する stat 情報を、 (POSIXを元にした)同じフォーマットで返します。

特定のオペレーティングシステム固有の拡張も os を介して利用することができますが、これらの利用はもちろん、可搬性を脅かします！

「利用できる環境: Unix」の意味はこの関数が Unix システムにあることが多いということです。このことは特定の OS における存在を主張するものではありません。

特に記述がない場合、「利用できる環境: Unix」と書かれている関数は、 Unix をコアにしている Mac OS X でも利用することができます。

ノート

このモジュール内のすべての関数は、間違った、あるいはアクセス出来ないファイル名やファイルパス、その他型が合っていてもOSが受理しない引数に対して、 OSError を送出します。

exception os.error

組み込みの OSError 例外に対するエイリアス

os.name

import されているオペレーティング・システム依存モジュールの名前です。現在次の名前が登録されています: 'posix', 'nt', 'os2', 'ce', 'java', 'riscos'.

15.1.1. プロセスのパラメタ

これらの関数とデータ要素は、現在のプロセスおよびユーザに対する情報提供および操作のための機能を提供しています。

os.environ

環境変数の値を表すマップ型オブジェクトです。例えば、 environ['HOME'] は( いくつかのプラットフォーム上での) あなたのホームディレクトリへのパスです。これは C の getenv("HOME") と等価です。

このマップ型の内容は、 os モジュールの最初の import の時点、通常は Python の起動時に site.py が処理される中で取り込まれます。それ以後に変更された環境変数は os.environ を直接変更しない限り反映されません。

プラットフォーム上で putenv() がサポートされている場合、このマップ型オブジェクトは環境変数に対するクエリと同様に変更するために使うこともできます。 putenv() はマップ型オブジェクトが修正される時に、自動的に呼ばれることになります。

ノート

putenv() を直接呼び出しても os.environ の内容は変わらないので、 os.environ を直接変更する方がベターです。

ノート

FreeBSD と Mac OS X を含むいつくかのプラットフォームでは、 environ の値を変更するとメモリリークの原因になる場合があります。システムの putenv() に関するドキュメントを参照してください。

putenv() が提供されていない場合、このマッピングオブジェクトに変更を加えたコピーを適切なプロセス生成機能に渡して、子プロセスが修正された環境変数を利用するようにできます。

プラットフォームが unsetenv() 関数をサポートしているならば、このマッピングからアイテムを取り除いて(delete)環境変数を消すことができます。 unsetenv() は os.environ からアイテムが取り除かれた時に自動的に呼ばれます。 pop() か clear() が呼ばれた時も同様です。

バージョン 2.6 で変更.

os.chdir(path)

os.fchdir(fd)

os.getcwd()

これらの関数は、 ファイルとディレクトリ 節で説明されています。

os.ctermid()

プロセスの制御端末に対応するファイル名を返します。

利用できる環境: Unix

os.getegid()

現在のプロセスの実効(effective)グループ id を返します。この id は現在のプロセスで実行されているファイルの “set id” ビットに対応します。

利用できる環境: Unix

os.geteuid()

現在のプロセスの実効(effective)ユーザ id を返します。

利用できる環境: Unix

os.getgid()

現在のプロセスの実際のグループ id を返します。

利用できる環境: Unix

os.getgroups()

現在のプロセスに関連づけられた従属グループ id のリストを返します。

利用できる環境: Unix

os.initgroups(username, gid)

システムの initgroups() を呼んで、指定された username がメンバーであるグループと gid でしていされたグループでグループアクセスリストを初期化する。

利用できる環境: Unix

バージョン 2.7 で追加.

os.getlogin()

現在のプロセスの制御端末にログインしているユーザ名を返します。ほとんどの場合、ユーザが誰かを知りたいときには環境変数 LOGNAME を、現在の実効ユーザ id のユーザ名を知りたいときには pwd.getpwuid(os.getuid())[0] を使うほうが便利です。

利用できる環境: Unix

os.getpgid(pid)

プロセス id pid のプロセスのプロセス・グループ id を返します。もし pid が 0 ならば、現在のプロセスのプロセス・グループ id を返します。

利用できる環境: Unix

バージョン 2.3 で追加.

os.getpgrp()

現在のプロセス・グループの id を返します。

利用できる環境: Unix

os.getpid()

現在のプロセス id を返します。

利用できる環境: Unix、 Windows

os.getppid()

親プロセスの id を返します。

利用できる環境: Unix

os.getresuid()

現在のプロセスの real, effective, saved user id を示す、 (ruid, euid, suid) のタプルを返します。

利用できる環境: Unix

バージョン 2.7 で追加.

os.getresgid()

現在のプロセスの real, effective, saved group id を示す、 (ruid, euid, suid) のタプルを返します。

利用できる環境: Unix

バージョン 2.7 で追加.

os.getuid()

現在のプロセスのユーザ id を返します。

利用できる環境: Unix

os.getenv(varname[, value])

環境変数 varname が存在する場合にはその値を返し、存在しない場合には value を返します。 value のデフォルト値は None です。

利用できる環境: 主な Unix 互換環境、Windows

os.putenv(varname, value)

varname と名づけられた環境変数の値を文字列 value に設定します。このような環境変数への変更は、 os.system(), popen() , fork() および execv() により起動された子プロセスに影響します。

利用できる環境: 主な Unix 互換環境、Windows

ノート

FreeBSD と Mac OS X を含むいつくかのプラットフォームでは、 environ の値を変更するとメモリリークの原因になる場合があります。システムの putenv に関するドキュメントを参照してください。

putenv() がサポートされている場合、 os.environ の要素に対する代入を行うと自動的に putenv() を呼び出します; しかし、 putenv() の呼び出しは os.environ を更新しないので、実際には os.environ の要素に代入する方が望ましい操作です。

os.setegid(egid)

現在のプロセスに実効グループ id をセットします。

利用できる環境: Unix

os.seteuid(euid)

現在のプロセスに実効ユーザ id をセットします。

利用できる環境: Unix

os.setgid(gid)

現在のプロセスにグループ id をセットします。

利用できる環境: Unix

os.setgroups(groups)

現在のグループに関連付けられた従属グループ id のリストを groups に設定します。 groups はシーケンス型でなくてはならず、各要素はグループを特定する整数でなくてはなりません。この操作は通常、スーパユーザしか利用できません。

利用できる環境: Unix

バージョン 2.2 で追加.

os.setpgrp()

システムコール setpgrp() または setpgrp(0, 0)() のどちらかのバージョンのうち、 (実装されていれば) 実装されている方を呼び出します。機能については Unix マニュアルを参照してください。

利用できる環境: Unix

os.setpgid(pid, pgrp)

システムコール setpgid() を呼び出して、 pid の id をもつプロセスのプロセスグループ id を pgrp に設定します。

利用できる環境: Unix

os.setregid(rgid, egid)

現在のプロセスの real, effective group id を設定します。

利用できる環境: Unix

os.setresgid(rgid, egid, sgid)

現在のプロセスの real, effective, saved group id を設定します。

利用できる環境: Unix

バージョン 2.7 で追加.

os.setresuid(ruid, euid, suid)

Set the current process’s real, effective, and saved user ids.

利用できる環境: Unix

バージョン 2.7 で追加.

os.setreuid(ruid, euid)

現在のプロセスに対して実際のユーザ id および実効ユーザ id を設定します。

利用できる環境: Unix

os.getsid(pid)

システムコール getsid() を呼び出します。機能については Unix マニュアルを参照してください。

利用できる環境: Unix

バージョン 2.4 で追加.

os.setsid()

システムコール setsid() を呼び出します。機能については Unix マニュアルを参照してください。

利用できる環境: Unix

os.setuid(uid)

現在のプロセスのユーザ id を設定します。

利用できる環境: Unix

os.strerror(code)

エラーコード code に対応するエラーメッセージを返します。不明なエラーコードに対して strerror() が NULL を返す環境では、その場合に ValueError を送出します。

利用できる環境: Unix, Windows

os.umask(mask)

現在の数値 umask を設定し、以前の umask 値を返します。

利用できる環境: Unix, Windows

os.uname()

現在のオペレーティングシステムを特定する情報の入った 5 要素のタプルを返します。このタプルには 5 つの文字列: (sysname, nodename, release, version, machine) が入っています。システムによっては、ノード名を 8 文字、または先頭の要素だけに切り詰めます; ホスト名を取得する方法としては、 socket.gethostname() を使う方がよいでしょう、あるいは socket.gethostbyaddr(socket.gethostname()) でもかまいません。

利用できる環境: Unix互換環境

os.unsetenv(varname)

varname という名前の環境変数を取り消します。このような環境の変化は os.system(), popen() または fork() と execv() で開始されるサブプロセスに影響を与えます。

利用できる環境: ほとんどの Unix 互換環境、Windows

unsetenv() がサポートされている時には os.environ のアイテムの削除が対応する unsetenv() の呼び出しに自動的に翻訳されます。しかし、 unsetenv() の呼び出しは os.environ を更新しませんので、むしろ os.environ のアイテムを削除する方が好ましい方法です。

15.1.2. ファイルオブジェクトの生成

以下の関数は新しいファイルオブジェクトを作成します。(open() も参照してください)

os.fdopen(fd[, mode[, bufsize]])

ファイル記述子 fd に接続している、開かれたファイルオブジェクトを返します。引数 mode および bufsize は、組み込み関数 open() における対応する引数と同じ意味を持ちます。

利用できる環境: Unix, Windows

バージョン 2.3 で変更: 引数 mode は、指定されるならば、 'r', 'w', 'a' のいずれかの文字で始まらなければなりません。そうでなければ ValueError が送出されます.

バージョン 2.5 で変更: Unixでは、引数 mode が 'a' で始まる時には O_APPEND フラグがファイル記述子に設定されます。 (ほとんどのプラットフォームで fdopen() 実装が既に行なっていることです).

os.popen(command[, mode[, bufsize]])

command への、または command からのパイプ入出力を開きます。戻り値はパイプに接続されている開かれたファイルオブジェクトで、 mode が 'r' (標準の設定です) または 'w' かによって読み出しまたは書き込みを行うことができます。引数 bufsize は、組み込み関数 open() における対応する引数と同じ意味を持ちます。 command の終了ステータス (wait() で指定された書式でコード化されています) は、 close() メソッドの戻り値として取得することができます。例外は終了ステータスがゼロ (すなわちエラーなしで終了) の場合で、このときには None を返します。

利用できる環境: Unix, Windows

バージョン 2.6 で撤廃: この関数は撤廃されました。代わりに subprocess モジュールを利用してください。特に、 古い関数を subprocess モジュールで置き換える 節をチェックしてください。

バージョン 2.0 で変更: この関数は、Pythonの初期のバージョンでは、 Windows環境下で信頼できない動作をしていました。これはWindowsに付属して提供されるライブラリの _popen() 関数を利用したことによるものです。新しいバージョンの Python では、 Windows 付属のライブラリにある壊れた実装を利用しません。

os.tmpfile()

更新モード(w+b)で開かれた新しいファイルオブジェクトを返します。このファイルはディレクトリエントリ登録に関連付けられておらず、このファイルに対するファイル記述子がなくなると自動的に削除されます。

利用できる環境: Unix, Windows

幾つかの少し異なった方法で子プロセスを作成するために、幾つかの popen*() 関数が提供されています。

バージョン 2.6 で撤廃: 全ての popen*() 関数は撤廃されました。代わりに subprocess モジュールを利用してください。

popen*() の変種はどれも、 bufsize が指定されている場合には I/O パイプのバッファサイズを表します。 mode を指定する場合には、文字列 'b' または 't' でなければなりません; これは、Windows でファイルをバイナリモードで開くかテキストモードで開くかを決めるために必要です。 mode の標準の設定値は 't' です。

また Unix ではこれらの変種はいずれも cmd をシーケンスにできます。その場合、引数はシェルの介在なしに直接 (os.spawnv() のように) 渡されます。 cmd が文字列の場合、引数は( os.system() のように) シェルに渡されます。

以下のメソッドは子プロセスから終了ステータスを取得できるようにはしていません。入出力ストリームを制御し、かつ終了コードの取得も行える唯一の方法は、 subprocess モジュールを利用する事です。以下のメソッドはUnixでのみ利用可能です。

これらの関数の利用に関係して起きうるデッドロック状態についての議論は、フロー制御の問題 節を参照してください。

os.popen2(cmd[, mode[, bufsize]])

cmd を子プロセスとして実行します。ファイル・オブジェクト (child_stdin, child_stdout) を返します。

バージョン 2.6 で撤廃: この関数は撤廃されました。 subprocess モジュールを利用してください。特に、 古い関数を subprocess モジュールで置き換える 節を参照してください。

利用できる環境: Unix, Windows

バージョン 2.0 で追加.

os.popen3(cmd[, mode[, bufsize]])

cmd を子プロセスとして実行します。ファイルオブジェクト (child_stdin, child_stdout, child_stderr) を返します。

バージョン 2.6 で撤廃: この関数は撤廃されました。 subprocess モジュールを利用してください。特に、 古い関数を subprocess モジュールで置き換える 節を参照してください。

利用できる環境: Unix, Windows

バージョン 2.0 で追加.

os.popen4(cmd[, mode[, bufsize]])

cmd を子プロセスとして実行します。ファイルオブジェクト (child_stdin, child_stdout_and_stderr) を返します。

バージョン 2.6 で撤廃: この関数は撤廃されました。 subprocess モジュールを利用してください。特に、 古い関数を subprocess モジュールで置き換える 節を参照してください。

利用できる環境: Unix, Windows

バージョン 2.0 で追加.

(child_stdin, child_stdout, および child_stderr は子プロセスの視点で名付けられているので注意してください。すなわち、 child_stdin とは子プロセスの標準入力を意味します。)

この機能は popen2 モジュール内の同じ名前の関数を使っても実現できますが、これらの関数の戻り値は異なる順序を持っています。

15.1.3. ファイル記述子の操作

これらの関数は、ファイル記述子を使って参照されている I/Oストリームを操作します。

ファイル記述子とは現在のプロセスから開かれたファイルに対応する小さな整数です。例えば、標準入力のファイル記述子はいつでも 0 で、標準出力は 1、標準エラーは 2 です。その他にさらにプロセスから開かれたファイルには 3、4、5、などが割り振られます。「ファイル記述子」という名前は少し誤解を与えるものかもしれませんが、 Unixプラットフォームにおいて、ソケットやパイプもファイル記述子によって参照されます。

ファイルオブジェクトに紐付けられたファイル記述子は fileno() メソッドによって取得可能です。ただし、ファイル記述子を直接使うとファイルオブジェクトのメソッドは経由しませんので、内部でバッファするかどうかといったファイルオブジェクトの都合は無視されます。

os.close(fd)

ファイルディスクリプタ fd を閉じます。

利用できる環境: Unix、 Windows

ノート

注:この関数は低レベルの I/O のためのもので、 os.open() や pipe() が返すファイル記述子に対して適用しなければなりません。組み込み関数 open() や popen(), fdopen() の返す “ファイルオブジェクト” を閉じるには、オブジェクトの close() メソッドを使ってください。

os.closerange(fd_low, fd_high)

fd_low (を含む) から fd_high (含まない) までの全てのディスクリプタを、エラーを無視しながら閉じます。次のコードと等価です:

for fd in xrange(fd_low, fd_high):
    try:
        os.close(fd)
    except OSError:
        pass

利用できる環境: Unix, Windows

バージョン 2.6 で追加.

os.dup(fd)

ファイル記述子 fd の複製を返します。

利用できる環境: Unix, Windows

os.dup2(fd, fd2)

ファイル記述子を fd から fd2 に複製し、必要なら後者の記述子を前もって閉じておきます。

利用できる環境: Unix, Windows

os.fchmod(fd, mode)

fd で指定されたファイルのモードを mode に変更します。 mode に指定できる値については、 chmod() のドキュメントを参照してください。

利用できる環境: Unix

バージョン 2.6 で追加.

os.fchown(fd, uid, gid)

fd で指定されたファイルの owner id と group id を、 uid と gid に変更します。どちらかの id を変更しない場合は、 -1 を渡してください。

利用できる環境: Unix

バージョン 2.6 で追加.

os.fdatasync(fd)

ファイル記述子 fd を持つファイルのディスクへの書き込みを強制します。メタデータの更新は強制しません。

利用できる環境: Unix

os.fpathconf(fd, name)

開いているファイルに関連したシステム設定情報 (system configuration information) を返します。 name には取得したい設定名を指定します; これは定義済みのシステム固有値名の文字列で、多くの標準 (POSIX.1、 Unix 95、 Unix 98 その他) で定義されています。プラットフォームによっては別の名前も定義しています。ホストオペレーティングシステムの関知する名前は pathconf_names 辞書で与えられています。このマップオブジェクトに入っていない設定変数については、 name に整数を渡してもかまいません。

もし name が文字列でかつ不明である場合、 ValueError を送出します。 name の指定値がホストシステムでサポートされておらず、 pathconf_names にも入っていない場合、 errno.EINVAL をエラー番号として OSError を送出します。

利用できる環境: Unix

os.fstat(fd)

stat() のようにファイル記述子 fd の状態を返します。

利用できる環境: Unix, Windows

os.fstatvfs(fd)

statvfs() のように、ファイル記述子 fd に関連づけられたファイルが入っているファイルシステムに関する情報を返します。

利用できる環境: Unix

os.fsync(fd)

ファイル記述子 fd を持つファイルのディスクへの書き込みを強制します。 Unix では、ネイティブの fsync() 関数を、Windows では MS _commit() 関数を呼び出します。

Python のファイルオブジェクト f を使う場合、 f の内部バッファを確実にディスクに書き込むために、まず f.flush() を実行し、それから os.fsync(f.fileno()) してください。

利用できる環境: Unix, Windows (2.2.3 以降)

os.ftruncate(fd, length)

ファイル記述子 fd に対応するファイルを、サイズが最大で length バイトになるように切り詰めます。

利用できる環境: Unix

os.isatty(fd)

ファイル記述子 fd が開いていて、tty(のような)装置に接続されている場合、 1 を返します。そうでない場合は 0 を返します。

利用できる環境: Unix

os.lseek(fd, pos, how)

ファイル記述子 fd の現在の位置を pos に設定します。 pos の意味は how で修飾されます: ファイルの先頭からの相対には SEEK_SET か 0 を設定します; 現在の位置からの相対には SEEK_CUR か 1 を設定します; ファイルの末尾からの相対には SEEK_END か 2 を設定します。

利用できる環境: Unix, Windows

os.SEEK_SET

os.SEEK_CUR

os.SEEK_END

lseek() 関数に渡すパラメータ。値は順に 0, 1, 2 です。

利用できる環境: Unix, Windows

バージョン 2.5 で追加.

os.open(file, flags[, mode])

ファイル file を開き、 flag に従って様々なフラグを設定し、可能なら mode に従ってファイルモードを設定します。 mode の標準の設定値は 0777 (8進表現) で、先に現在の umask を使ってマスクを掛けます。新たに開かれたファイルのファイル記述子を返します。

フラグとファイルモードの値についての詳細は C ランタイムのドキュメントを参照してください; (O_RDONLY や O_WRONLY のような) フラグ定数はこのモジュールでも定義されています (以下を参照してください)。特に、Windows ではバイナリファイルを開くときに O_BINARY を加える必要があります。

利用できる環境: Unix, Windows

ノート

この関数は低レベルの I/O のためのものです。通常の利用では、 read() や write() (やその他多くの) メソッドを持つ「ファイルオブジェクト」を返す、組み込み関数 open() を使ってください。ファイル記述子を「ファイルオブジェクト」でラップするには fdopen() を使ってください。

os.openpty()

新しい擬似端末のペアを開きます。ファイル記述子のペア (master, slave) を返し、それぞれ pty および tty を表します。 (少しだけ) より可搬性のあるアプローチとしては、 pty モジュールを使ってください。

利用できる環境: いくつかの Unix 系システム

os.pipe()

パイプを作成します。ファイル記述子のペア (r, w) を返し、それぞれ読み出し、書き込み用に使うことができます。

利用できる環境: Unix, Windows

os.read(fd, n)

ファイル記述子 fd から最大で n バイト読み出します。読み出されたバイト列の入った文字列を返します。 fd が参照しているファイルの終端に達した場合、空の文字列が返されます。

利用できる環境: Unix, Windows

ノート

この関数は低レベルの I/O のためのもので、 os.open() や pipe() が返すファイル記述子に対して適用しなければなりません。組み込み関数 open() や popen(), fdopen() の返す “ファイルオブジェクト”、あるいは sys.stdin から読み出すには、オブジェクトの read() か readline() メソッドを使ってください。

os.tcgetpgrp(fd)

fd (open() が返す開かれたファイル記述子) で与えられる端末に関連付けられたプロセスグループを返します。

利用できる環境: Unix

os.tcsetpgrp(fd, pg)

fd (open() が返す開かれたファイル記述子) で与えられる端末に関連付けられたプロセスグループを pg に設定します。

利用できる環境: Unix

os.ttyname(fd)

ファイル記述子 fd に関連付けられている端末デバイスを特定する文字列を返します。 fd が端末に関連付けられていない場合、例外が送出されます。

利用できる環境: Unix

os.write(fd, str)

ファイル記述子 fd に文字列 str を書き込みます。実際に書き込まれたバイト数を返します。

利用できる環境: Unix, Windows

ノート

この関数は低レベルの I/O のためのもので、 os.open() や pipe() が返すファイル記述子に対して適用しなければなりません。組み込み関数 open() や popen(), fdopen() の返す “ファイルオブジェクト”、あるいは sys.stdout, sys.stderr に書き込むには、オブジェクトの write() メソッドを使ってください。

15.1.3.1. open() フラグ定数

以下の定数は open() 関数の flags 引数に利用します。これらの定数は、ビット単位OR | で組み合わせることができます。幾つかの定数は、全てのプラットフォームで使えるわけではありません。利用可能かどうかや使い方については、 Unix では open(2), Windows では MSDN [http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx] を参照してください。

os.O_RDONLY

os.O_WRONLY

os.O_RDWR

os.O_APPEND

os.O_CREAT

os.O_EXCL

os.O_TRUNC

利用できる環境: Unix, Windows

os.O_DSYNC

os.O_RSYNC

os.O_SYNC

os.O_NDELAY

os.O_NONBLOCK

os.O_NOCTTY

os.O_SHLOCK

os.O_EXLOCK

利用できる環境: Unix

os.O_BINARY

os.O_NOINHERIT

os.O_SHORT_LIVED

os.O_TEMPORARY

os.O_RANDOM

os.O_SEQUENTIAL

os.O_TEXT

利用できる環境: Windows

os.O_ASYNC

os.O_DIRECT

os.O_DIRECTORY

os.O_NOFOLLOW

os.O_NOATIME

これらの定数は GNU 拡張で、Cライブラリで定義されていない場合は利用できません。

15.1.4. ファイルとディレクトリ

os.access(path, mode)

実 uid/gid を使って path に対するアクセスが可能か調べます。ほとんどのオペレーティングシステムは実効 uid/gid を使うため、このルーチンは suid/sgid 環境において、プログラムを起動したユーザが path に対するアクセス権をもっているかを調べるために使われます。 path が存在するかどうかを調べるには mode を F_OK にします。ファイル操作許可 (permission) を調べるために R_OK, W_OK, X_OK から一つまたはそれ以上のフラグと OR をとることもできます。アクセスが許可されている場合 True を、そうでない場合 False を返します。詳細は access(2) のマニュアルページを参照してください。

利用できる環境: Unix, Windows

ノート

access() を使ってユーザーが例えばファイルを開く権限を持っているか open() を使って実際にそうする前に調べることはセキュリティ・ホールを作り出してしまいます。というのは、調べる時点と開く時点の時間差を利用してそのユーザーがファイルを操作してしまうかもしれないからです。 EAFP テクニックを利用する方が好ましいです。例えば:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()
return "some default data"

このコードは次のように書いたほうが良いです:

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCESS:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

ノート

I/O 操作は access() が成功を思わせるときにも失敗することがありえます。特にネットワーク・ファイルシステムにおける操作が通常の POSIX 許可ビット・モデルをはみ出す意味論を備える場合にはそのようなことが起こりえます。

os.F_OK

access() の mode に渡すための値で、 path が存在するかどうかを調べます。

os.R_OK

access() の mode に渡すための値で、 path が読み出し可能かどうかを調べます。

os.W_OK

access() の mode に渡すための値で、 path が書き込み可能かどうかを調べます。

os.X_OK

access() の mode に渡すための値で、 path が実行可能かどうかを調べます。

os.chdir(path)

現在の作業ディレクトリ (current working directory) を path に設定します。

利用できる環境: Unix, Windows

os.getcwd()

現在の作業ディレクトリを表現する文字列を返します。

利用できる環境: Unix, Windows

os.getcwdu()

現在の作業ディレクトリを表現するユニコードオブジェクトを返します。

利用できる環境: Unix、 Windows

バージョン 2.3 で追加.

os.chflags(path, flags)

path のフラグを flags に変更する。 flags は、以下の値を(bitwise ORで)組み合わせたものです。 (stat モジュールを参照してください):

stat.UF_NODUMP

stat.UF_IMMUTABLE

stat.UF_APPEND

stat.UF_OPAQUE

stat.UF_NOUNLINK

stat.SF_ARCHIVED

stat.SF_IMMUTABLE

stat.SF_APPEND

stat.SF_NOUNLINK

stat.SF_SNAPSHOT

利用できる環境: Unix

バージョン 2.6 で追加.

os.chroot(path)

現在のプロセスに対してルートディレクトリを path に変更します。

利用できる環境: Unix

バージョン 2.2 で追加.

os.chmod(path, mode)

path のモードを数値 mode に変更します。 mode は、(stat モジュールで定義されている) 以下の値のいずれかまたはビット単位の OR で組み合わせた値を取り得ます:

stat.S_ISUID

stat.S_ISGID

stat.S_ENFMT

stat.S_ISVTX

stat.S_IREAD

stat.S_IWRITE

stat.S_IEXEC

stat.S_IRWXU

stat.S_IRUSR

stat.S_IWUSR

stat.S_IXUSR

stat.S_IRWXG

stat.S_IRGRP

stat.S_IWGRP

stat.S_IXGRP

stat.S_IRWXO

stat.S_IROTH

stat.S_IWOTH

stat.S_IXOTH

利用できる環境: Unix、 Windows

ノート

Windows でも chmod() はサポートされていますが、ファイルの読み込み専用フラグを (定数 S_IWRITE と S_IREAD, または対応する整数値を通して) 設定できるだけです。他のビットは全て無視されます。

os.chown(path, uid, gid)

path の所有者 (owner) id とグループ id を、数値 uid および gid に変更します。いずれかの id を変更せずにおくには、その値として -1 をセットします。

利用できる環境: Unix

os.lchflags(path, flags)

path のフラグを数値 flags に設定します。 chflags() に似ていますが、シンボリックリンクをたどりません。

利用できる環境: Unix

バージョン 2.6 で追加.

os.lchown(path, uid, gid)

path の所有者 (owner) id とグループ id を、数値 uid および gid に変更します。この関数はシンボリックリンクをたどりません。

利用できる環境: Unix

バージョン 2.3 で追加.

os.link(source, link_name)

source を指しているハードリンク link_name を作成します。

利用できる環境: Unix

os.listdir(path)

path で指定されたディレクトリ内のエントリ名が入ったリストを返します。リスト内の順番は不定です。特殊エントリ '.' および '..' は、それらがディレクトリに入っていてもリストには含められません。

利用できる環境: Unix、 Windows

バージョン 2.3 で変更: Windows NT/2k/XP と Unixでは、 path が Unicode オブジェクトの場合、 Unicode オブジェクトのリストが返されます。デコード不可能なファイル名は依然として string オブジェクトになります。

os.lstat(path)

与えられた path に対して、 lstat() システムコールと同じ動作をします。 stat() に似ていますが、シンボリックリンクをたどりません。シンボリックリンクのない環境では stat() の別名です。

os.mkfifo(path[, mode])

数値で指定されたモード mode を持つ FIFO (名前付きパイプ) を path に作成します。 mode の標準の値は 0666 (8進) です。現在の umask 値が前もって mode からマスクされます。

利用できる環境: Unix

FIFO は通常のファイルのようにアクセスできるパイプです。 FIFO は (例えば os.unlink() を使って) 削除されるまで存在しつづけます。一般的に、FIFO は “クライアント” と “サーバ” 形式のプロセス間でランデブーを行うために使われます: このとき、サーバは FIFO を読み出し用に開き、クライアントは書き込み用に開きます。 mkfifo() は FIFO を開かない — 単にランデブーポイントを作成するだけ — なので注意してください。

os.mknod(filename[, mode=0600, device])

filename という名前で、ファイルシステム・ノード (ファイル、デバイス特殊ファイル、または、名前つきパイプ) を作ります。 mode は、作ろうとするノードの使用権限とタイプを、 stat.S_IFREG, stat.S_IFCHR, stat.S_IFBLK, stat.S_IFIFO (これらの定数は stat で使用可能) のいずれかと（ビット OR で）組み合わせて指定します。 S_IFCHR と S_IFBLK を指定すると、 device は新しく作られたデバイス特殊ファイルを (おそらく os.makedev() を使って) 定義し、指定しなかった場合には無視します。

バージョン 2.3 で追加.

os.major(device)

生のデバイス番号から、デバイスのメジャー番号を取り出します。 (たいてい stat の st_dev フィールドか st_rdev フィールドです)

バージョン 2.3 で追加.

os.minor(device)

生のデバイス番号から、デバイスのマイナー番号を取り出します。 (たいてい stat の st_dev フィールドか st_rdev フィールドです)

バージョン 2.3 で追加.

os.makedev(major, minor)

major と minor から、新しく生のデバイス番号を作ります。

バージョン 2.3 で追加.

os.mkdir(path[, mode])

数値で指定されたモード mode をもつディレクトリ path を作成します。 mode の標準の値は 0777 (8進)です。システムによっては、 mode は無視されます。利用の際には、現在の umask 値が前もってマスクされます。指定されたディレクトリがすでに存在する場合は OSError 例外を発生させます。

一時ディレクトリを作成することもできます: tempfile モジュールの tempfile.mkdtemp() 関数を参照してください。

利用できる環境: Unix, Windows

os.makedirs(path[, mode])

再帰的なディレクトリ作成関数です。 mkdir() に似ていますが、末端 (leaf) となるディレクトリを作成するために必要な中間の全てのディレクトリを作成します。末端ディレクトリがすでに存在する場合や、作成ができなかった場合には error 例外を送出します。 mode の標準の値は 0777 (8進)です。システムによっては、 mode は無視されます。利用の際には、現在の umask 値が前もってマスクされます。

ノート

makedirs() は作り出すパス要素が os.pardir を含むと混乱することになります。

バージョン 1.5.2 で追加.

バージョン 2.3 で変更: この関数は UNC パスを正しく扱えるようになりました.

os.pathconf(path, name)

指定されたファイルに関係するシステム設定情報を返します。 name には取得したい設定名を指定します; これは定義済みのシステム固有値名の文字列で、多くの標準 (POSIX.1、 Unix 95、 Unix 98 その他) で定義されています。プラットフォームによっては別の名前も定義しています。ホストオペレーティングシステムの関知する名前は pathconf_names 辞書で与えられています。このマップ型オブジェクトに入っていない設定変数については、 name に整数を渡してもかまいません。

もし name が文字列でかつ不明である場合、 ValueError を送出します。 name の指定値がホストシステムでサポートされておらず、 pathconf_names にも入っていない場合、 errno.EINVAL をエラー番号として OSError を送出します。

利用できる環境: Unix

os.pathconf_names

pathconf() および fpathconf() が受理するシステム設定名を、ホストオペレーティングシステムで定義されている整数値に対応付けている辞書です。この辞書はシステムでどの設定名が定義されているかを決定するために利用できます。

利用できる環境: Unix

os.readlink(path)

シンボリックリンクが指しているパスを表す文字列を返します。返される値は絶対パスにも、相対パスにもなり得ます; 相対パスの場合、 os.path.join(os.path.dirname(path), result) を使って絶対パスに変換することができます。

バージョン 2.6 で変更.

利用できる環境: Unix

os.remove(path)

ファイル path を削除(消去)します。 path がディレクトリの場合、 OSError が送出されます; ディレクトリの削除については rmdir() を参照してください。この関数は下で述べられている unlink() 関数と同一です。 Windows では、使用中のファイルを削除しようと試みると例外を送出します; Unixでは、ディレクトリエントリは削除されますが、記憶装置上にアロケーションされたファイル領域は元のファイルが使われなくなるまで残されます。

利用できる環境: Unix, Windows

os.removedirs(path)

再帰的なディレクトリ削除関数です。 rmdir() と同じように動作しますが、末端ディレクトリがうまく削除できるかぎり、 removedirs() は path に現れる親ディレクトリをエラーが送出されるまで (このエラーは通常、指定したディレクトリの親ディレクトリが空でないことを意味するだけなので無視されます) 順に削除することを試みます。例えば、 os.removedirs('foo/bar/baz') では最初にディレクトリ 'foo/bar/baz' を削除し、次に 'foo/bar' さらに 'foo' をそれらが空ならば削除します。末端のディレクトリが削除できなかった場合には OSError が送出されます。

バージョン 1.5.2 で追加.

os.rename(src, dst)

ファイルまたはディレクトリ src を dst に名前変更します。 dst がディレクトリの場合、 OSError が送出されます。 Unixでは、 dst が存在し、かつファイルの場合、ユーザの権限があるかぎり暗黙のうちに元のファイルが置き換えられます。この操作はいくつかの Unix 系システムにおいて、 src と dst が異なるファイルシステム上にあると失敗することがあります。ファイル名の変更が成功する場合、この操作は原子的 (atomic) 操作となります (これは POSIX 要求仕様です)。 Windows では、 dst が既に存在する場合には、たとえファイルの場合でも OSError が送出されます; これは dst が既に存在するファイル名の場合、名前変更の原子的操作を実装する手段がないからです。

利用できる環境: Unix, Windows

os.renames(old, new)

再帰的にディレクトリやファイル名を変更する関数です。 rename() のように動作しますが、新たなパス名を持つファイルを配置するために必要な途中のディレクトリ構造をまず作成しようと試みます。名前変更の後、元のファイル名のパス要素は removedirs() を使って右側から順に枝刈りされてゆきます。

バージョン 1.5.2 で追加.

ノート

この関数はコピー元の末端のディレクトリまたはファイルを削除する権限がない場合には失敗します。

os.rmdir(path)

ディレクトリ path を削除します。ディレクトリが空の場合にだけ正常に動作します。そうでなければ OSError が送出されます。ディレクトリ・ツリー全体を削除するのには shutil.rmtree() が使えます。

利用できる環境: Unix, Windows

os.stat(path)

与えられた path に対して stat() システムコール相当の処理を実行します。 (この関数はシンボリックリンクをたどります。シンボリックリンクに対して stat したい場合は lstat() を利用してください)

戻り値はオブジェクトで、その属性は stat 構造体に従います:

st_mode - 保護 bits,

st_ino - inode 番号,

st_dev - デバイス,

st_nlink - ハードリンク数,

st_uid - オーナーの uid,

st_gid - オーナーの group id,

st_size - ファイルのサイズ(単位: byte),

st_atime - 最近にアクセスされた時間,

st_mtime - 最近に内容を変更した時間,

st_ctime - プラットフォーム依存; Unix では最近のメタデータ変更時間、 Windows ではファイルが生成された時間

バージョン 2.3 で変更: もし stat_float_times() が True を返す場合、時間値は浮動小数点で秒を計ります。ファイルシステムがサポートしていれば、秒の小数点以下の桁も含めて返されます。 Mac OS では、時間は常に浮動小数点です。詳細な説明は stat_float_times() を参照してください。

(Linux のような) いくつかの Unix システムでは、以下の属性が利用できるかもしれません:

st_blocks - ファイル用にアロケーションされているブロック数,

st_blksize - ファイルシステムのブロックサイズ,

st_rdev - i ノードデバイスの場合、デバイスの形式,

st_flags - ファイルに対するユーザー定義のフラグ

他の (FreeBSD のような) Unix システムでは、以下の属性が利用できる場合があります (ただし root がそれらを使うことにした場合以外は値が入っていないでしょう):

st_gen - ファイル生成番号,

st_birthtime - ファイル生成時刻

Mac OS システムでは、以下の属性も利用可能なときがあります:

st_rsize,

st_creator,

st_type,

RISCOS システムでは、以下の属性も利用できます:

st_ftype (file type),

st_attrs (attributes),

st_obtype (object type)

ノート

st_atime, st_mtime, および st_ctime メンバの厳密な意味や精度はオペレーティングシステムやファイルシステムによって変わります。例えば、FAT や FAT32 ファイルシステムを使っている Windows システムでは、 st_atime の精度は 1 日に過ぎません。詳しくはお使いのオペレーティングシステムのドキュメントを参照してください。

os.stat_float_times([newvalue])

stat_result がタイムスタンプに浮動小数点オブジェクトを使うかどうかを決定します。 newvalue が True の場合、以後の stat() 呼び出しは浮動小数点を返し、 False の場合には以後整数を返します。 newvalue が省略された場合、現在の設定どおりの戻り値になります。

古いバージョンの Python と互換性を保つため、 stat_result にタプルとしてアクセスすると、常に整数が返されます。

バージョン 2.5 で変更: Python はデフォルトで浮動小数点数を返すようになりました。浮動小数点数のタイムスタンプではうまく動かないアプリケーションはこの機能を利用して昔ながらの振る舞いを取り戻すことができます。

タイムスタンプの精度 (すなわち最小の小数部分) はシステム依存です。システムによっては秒単位の精度しかサポートしません。そういったシステムでは小数部分は常に 0 です。

この設定の変更は、プログラムの起動時に、 __main__ モジュールの中でのみ行うことを推奨します。ライブラリは決して、この設定を変更するべきではありません。浮動小数点型のタイムスタンプを処理すると、不正確な動作をするようなライブラリを使う場合、ライブラリが修正されるまで、浮動小数点型を返す機能を停止させておくべきです。

os.statvfs(path)

与えられた path に対して statvfs() システムコールを実行します。戻り値はオブジェクトで、その属性は与えられたパスが収められているファイルシステムについて記述したものです。各属性は statvfs 構造体のメンバ: f_bsize, f_frsize, f_blocks, f_bfree, f_bavail, f_files, f_ffree, f_favail, f_flag, f_namemax,に対応します。

後方互換性のために、戻り値は上の順にそれぞれ対応する属性値が並んだタプルとしてアクセスすることもできます。標準モジュール statvfs では、シーケンスとしてアクセスする場合に、 statvfs 構造体から情報を引き出す上便利な関数や定数を定義しています; これは属性として各フィールドにアクセスできないバージョンの Python で動作する必要のあるコードを書く際に便利です。

利用できる環境: Unix

バージョン 2.2 で変更: 返されたオブジェクトの属性としてのアクセス機能を追加しました.

os.symlink(source, link_name)

source を指しているシンボリックリンクを link_name に作成します。

利用できる環境: Unix

os.tempnam([dir[, prefix]])

一時ファイル (temporary file) を生成する上でファイル名として相応しい一意なパス名を返します。この値は一時的なディレクトリエントリを表す絶対パスで、 dir ディレクトリの下か、 dir が省略されたり None の場合には一時ファイルを置くための共通のディレクトリの下になります。 prefix が与えられており、かつ None でない場合、ファイル名の先頭につけられる短い接頭辞になります。アプリケーションは tempnam() が返したパス名を使って正しくファイルを生成し、生成したファイルを管理する責任があります; 一時ファイルの自動消去機能は提供されていません。

警告

tempnam() を使うと、symlink 攻撃に対して脆弱になります; 代りに tmpfile() (ファイルオブジェクトの生成) を使うよう検討してください。

利用できる環境: Unix、 Windows

os.tmpnam()

一時ファイル (temporary file) を生成する上でファイル名として相応しい一意なパス名を返します。この値は一時ファイルを置くための共通のディレクトリ下の一時的なディレクトリエントリを表す絶対パスです。アプリケーションは tmpnam() が返したパス名を使って正しくファイルを生成し、生成したファイルを管理する責任があります; 一時ファイルの自動消去機能は提供されていません。

警告

tmpnam() を使うと、symlink 攻撃に対して脆弱になります; 代りに tmpfile() (ファイルオブジェクトの生成) を使うよう検討してください。

利用できる環境: Unix, Windowsこの関数はおそらく Windows では使うべきではないでしょう; Micorosoft の tmpnam() 実装では、常に現在のドライブのルートディレクトリ下のファイル名を生成しますが、これは一般的にはテンポラリファイルを置く場所としてはひどい場所です (アクセス権限によっては、この名前をつかってファイルを開くことすらできないかもしれません)。

os.TMP_MAX

tmpnam() がテンポラリ名を再利用し始めるまでに生成できる一意な名前の最大数です。

os.unlink(path)

ファイル path を削除します。 remove() と同じです; unlink() の名前は伝統的な Unix の関数名です。

利用できる環境: Unix, Windows

os.utime(path, times)

path で指定されたファイルに最終アクセス時刻および最終修正時刻を設定します。 times が None の場合、ファイルの最終アクセス時刻および最終更新時刻は現在の時刻になります。 (この動作は、その path に対してUnixの touch プログラムを実行するのに似ています)

そうでない場合、 times は2要素のタプルで、 (atime, mtime) の形式をとらなくてはなりません。これらはそれぞれアクセス時刻および修正時刻を設定するために使われます。

path にディレクトリを指定できるかどうかは、オペレーティングシステムがディレクトリをファイルの一種として実装しているかどうかに依存します (例えば、 Windows はそうではありません)。ここで設定した時刻の値は、オペレーティングシステムがアクセス時刻や更新時刻を記録する際の精度によっては、後で stat() 呼び出したときの値と同じにならないかも知れないので注意してください。 stat() も参照してください。

バージョン 2.0 で変更: times として None をサポートするようにしました.

利用できる環境: Unix, Windows

os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

ディレクトリツリー以下のファイル名を、ツリーをトップダウンもしくはボトムアップに走査することで生成します。ディレクトリ top を根に持つディレクトリツリーに含まれる、各ディレクトリ(top 自身を含む) から、タプル (dirpath, dirnames, filenames) を生成します。

dirpath は文字列で、ディレクトリへのパスです。 dirnames は dirpath 内のサブディレクトリ名のリスト ('.' と '..' は除く）です。 filenames は dirpath 内の非ディレクトリ・ファイル名のリストです。このリスト内の名前には、ファイル名までのパスが含まれないことに、注意してください。 dirpath 内のファイルやディレクトリへの (top からたどった) フルパスを得るには、 os.path.join(dirpath, name) してください。

オプション引数 topdown が True であるか、指定されなかった場合、各ディレクトリからタプルを生成した後で、サブディレクトリからタプルを生成します。 (ディレクトリはトップダウンで生成)。 topdown が False の場合、ディレクトリに対応するタプルは、そのディレクトリ以下の全てのサブディレクトリに対応するタプルの後で (ボトムアップで) 生成されます

topdown が True のとき、呼び出し側は dirnames リストを、インプレースで (たとえば、 del やスライスを使った代入で) 変更でき、 walk() は dirnames に残っているサブディレクトリ内のみを再帰します。これにより、検索を省略したり、特定の訪問順序を強制したり、呼び出し側が walk() を再開する前に、呼び出し側が作った、または名前を変更したディレクトリを、 walk() に知らせたりすることができます。 topdown が False のときに dirnames を変更しても効果はありません。ボトムアップモードでは dirpath 自身が生成される前に dirnames 内のディレクトリの情報が生成されるからです。

デフォルトでは、 os.listdir() 呼び出しから送出されたエラーは無視されます。オプションの引数 onerror を指定するなら、この値は関数でなければなりません; この関数は単一の引数として、 OSError インスタンスを伴って呼び出されます。この関数ではエラーを報告して歩行を続けたり、例外を送出して歩行を中断したりできます。ファイル名は例外オブジェクトの filename 属性として取得できることに注意してください。

デフォルトでは、 walk() はディレクトリへのシンボリックリンクをたどりません。 followlinks に True を設定すると、ディレクトリへのシンボリックリンクをサポートしているシステムでは、シンボリックリンクの指しているディレクトリを走査します。

バージョン 2.6 で追加: followlinks 引数

ノート

followlinks を True に設定すると、シンボリックリンクが親ディレクトリを指していた場合に、無限ループになることに気をつけてください。 walk() は、すでにたどったディレクトリを管理したりはしません。

ノート

相対パスを渡した場合、 walk() の回復の間でカレント作業ディレクトリを変更しないでください。 walk() はカレントディレクトリを変更しませんし、呼び出し側もカレントディレクトリを変更しないと仮定しています。

以下の例では、最初のディレクトリ以下にある各ディレクトリに含まれる、非ディレクトリファイルのバイト数を表示します。ただし、CVS サブディレクトリより下を見に行きません。

import os
from os.path import join, getsize
for root, dirs, files in os.walk('python/Lib/email'):
    print root, "consumes",
    print sum(getsize(join(root, name)) for name in files),
    print "bytes in", len(files), "non-directory files"
    if 'CVS' in dirs:
        dirs.remove('CVS')  # don't visit CVS directories

次の例では、ツリーをボトムアップで歩行することが不可欠になります; rmdir() はディレクトリが空になる前に削除させないからです:

# Delete everything reachable from the directory named in "top",
# assuming there are no symbolic links.
# CAUTION:  This is dangerous!  For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        os.rmdir(os.path.join(root, name))

バージョン 2.3 で追加.

15.1.5. プロセス管理

プロセスを生成したり管理するために、以下の関数を利用することができます。

様々な exec*() 関数が、プロセス内にロードされた新たなプログラムに与えるための引数からなるリストをとります。どの場合でも、新たなプログラムに渡されるリストの最初の引数は、ユーザがコマンドラインで入力する引数ではなく、プログラム自身の名前になります。 C プログラマにとっては、これはプログラムの main() に渡される argv[0] になります。例えば、 os.execv('/bin/echo', ['foo', 'bar']) は、標準出力に bar を出力します; foo は無視されたかのように見えることでしょう。

os.abort()

SIGABRT シグナルを現在のプロセスに対して生成します。 Unixでは、標準設定の動作はコアダンプの生成です; Windows では、プロセスは即座に終了コード 3 を返します。 signal.signal() を使って SIGABRT に対するシグナルハンドラを設定しているプログラムは異なる挙動を示すので注意してください。利用できる環境: Unix、 Windows

os.execl(path, arg0, arg1, ...)

os.execle(path, arg0, arg1, ..., env)

os.execlp(file, arg0, arg1, ...)

os.execlpe(file, arg0, arg1, ..., env)

os.execv(path, args)

os.execve(path, args, env)

os.execvp(file, args)

os.execvpe(file, args, env)

これらの関数はすべて、現在のプロセスを置き換える形で新たなプログラムを実行します; 現在のプロセスは戻り値を返しません。 Unixでは、新たに実行される実行コードは現在のプロセス内にロードされ、呼び出し側と同じプロセス ID を持つことになります。エラーは OSError 例外として報告されます。

現在のプロセスは瞬時に置き換えられます。開かれているファイルオブジェクトやディスクリプタはフラッシュされません。そのため、バッファ内にデータが残っているかもしれない場合、 exec*() 関数を実行する前に sys.stdout.flush() か os.fsync() を利用してバッファをフラッシュしておく必要があります。

“l” および “v” のついた exec*() 関数は、コマンドライン引数をどのように渡すかが異なります。 “l” 型は、コードを書くときにパラメタ数が決まっている場合に、おそらくもっとも簡単に利用できます。個々のパラメタは単に execl*() 関数の追加パラメタとなります。 “v” 型は、パラメタの数が可変の時に便利で、リストかタプルの引数が args パラメタとして渡されます。どちらの場合も、子プロセスに渡す引数は動作させようとしているコマンドの名前から始めるべきですが、これは強制ではありません。

末尾近くに “p” をもつ型 (execlp(), execlpe(), execvp(),および execvpe()) は、プログラム file を探すために環境変数 PATH を利用します。環境変数が (次の段で述べる exec*e() 型関数で) 置き換えられる場合、環境変数は PATH を決定する上の情報源として使われます。その他の型、 execl(), execle(), execv(),および execve() では、実行コードを探すために PATH を使いません。 path には適切に設定された絶対パスまたは相対パスが入っていなくてはなりません。

execle(), execlpe(), execve(),および execvpe() (全て末尾に “e” がついていることに注意してください) では、 env パラメタは新たなプロセスで利用される環境変数を定義するためのマップ型でなくてはなりません(現在のプロセスの環境変数の代わりに利用されます); execl(), execlp(), execv(),および execvp() では、全て新たなプロセスは現在のプロセスの環境を引き継ぎます。

利用できる環境: Unix, Windows

os._exit(n)

終了ステータス n でプロセスを終了します。このときクリーンアップハンドラの呼び出しや、標準入出力バッファのフラッシュなどは行いません。

利用できる環境: Unix, Windows

ノート

システムを終了する標準的な方法は sys.exit(n) です。 _exit() は通常、 fork() された後の子プロセスでのみ使われます。

以下の終了コードは必須ではありませんが _exit() と共に使うことができます。一般に、メールサーバの外部コマンド配送プログラムのような、 Python で書かれたシステムプログラムに使います。

ノート

いくらかの違いがあって、これらの全てが全ての Unix プラットフォームで使えるわけではありません。以下の定数は基礎にあるプラットフォームで定義されていれば定義されます。

os.EX_OK

エラーが起きなかったことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_USAGE

誤った個数の引数が渡されたときなど、コマンドが間違って使われたことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_DATAERR

入力データが間違っていたことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_NOINPUT

入力ファイルが存在しなかった、または、読み込み不可だったことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_NOUSER

指定されたユーザが存在しなかったことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_NOHOST

指定されたホストが存在しなかったことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_UNAVAILABLE

要求されたサービスが利用できないことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_SOFTWARE

内部ソフトウェアエラーが検出されたことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_OSERR

fork できない、pipe の作成ができないなど、オペレーティング・システム・エラーが検出されたことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_OSFILE

システムファイルが存在しなかった、開けなかった、あるいはその他のエラーが起きたことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_CANTCREAT

ユーザには作成できない出力ファイルを指定したことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_IOERR

ファイルの I/O を行っている途中にエラーが発生したときの終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_TEMPFAIL

一時的な失敗が発生したことを表す終了コード。これは、再試行可能な操作の途中に、ネットワークに接続できないというような、実際にはエラーではないかも知れないことを意味します。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_PROTOCOL

プロトコル交換が不正、不適切、または理解不能なことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_NOPERM

操作を行うために十分な許可がなかった（ファイルシステムの問題を除く）ことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_CONFIG

設定エラーが起こったことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.EX_NOTFOUND

“an entry was not found” のようなことを表す終了コード。

利用できる環境: Unix

バージョン 2.3 で追加.

os.fork()

子プロセスを fork します。子プロセスでは 0 が返り、親プロセスでは子プロセスの id が返ります。エラーが発生した場合は、 OSError 例外を送出します。

FreeBSD <= 6.3, Cygwin, OS/2 EMX を含む幾つかのプラットフォームにおいて、 fork() をスレッド内から利用した場合に既知の問題があることに注意してください。

利用できる環境: Unix

os.forkpty()

子プロセスを fork します。このとき新しい擬似端末 (psheudo-terminal) を子プロセスの制御端末として使います。親プロセスでは (pid, fd) からなるペアが返り、 fd は擬似端末のマスタ側 (master end) のファイル記述子となります。可搬性のあるアプローチを取るためには、 pty モジュールを利用してください。エラーが発生した場合は、 OSError 例外を送出します。

利用できる環境: いくつかの Unix系。

os.kill(pid, sig)

プロセス pid にシグナル sig を送ります。ホストプラットフォームで利用可能なシグナルを特定する定数は signal モジュールで定義されています。

Windows: signal.CTRL_C_EVENT と signal.CTRL_BREAK_EVENT は、同じコンソールウィンドウを共有しているコンソールプロセス(例: 子プロセス) にだけ送ることができる特別なシグナルです。その他の値を sig に与えると、そのプロセスが無条件に TerminateProcess API によって kill され、終了コードが sig に設定されます。 Windows の kill() は kill するプロセスのハンドルも受け取ります。

バージョン 2.7 で追加: Windows サポート

os.killpg(pgid, sig)

プロセスグループ pgid にシグナル sig を送ります。

利用できる環境: Unix

バージョン 2.3 で追加.

os.nice(increment)

プロセスの “nice 値” に increment を加えます。新たな nice 値を返します。

利用できる環境: Unix

os.plock(op)

プログラムのセグメント (program segment) をメモリ内でロックします。 op (<sys/lock.h> で定義されています) にはどのセグメントをロックするかを指定します。

利用できる環境: Unix

os.popen(...)

os.popen2(...)

os.popen3(...)

os.popen4(...)

子プロセスを起動し、子プロセスとの通信のために開かれたパイプを返します。これらの関数は ファイルオブジェクトの生成 節で記述されています。

os.spawnl(mode, path, ...)

os.spawnle(mode, path, ..., env)

os.spawnlp(mode, file, ...)

os.spawnlpe(mode, file, ..., env)

os.spawnv(mode, path, args)

os.spawnve(mode, path, args, env)

os.spawnvp(mode, file, args)

os.spawnvpe(mode, file, args, env)

新たなプロセス内でプログラム path を実行します。

(subprocess モジュールが、新しいプロセスを実行して結果を取得するための、より強力な機能を提供しています。この関数の代わりに、 subprocess モジュールを利用することが推奨されています。 subprocess モジュールのドキュメントの、古い関数を subprocess モジュールで置き換えるというセクションを読んでください。)

mode が P_NOWAIT の場合、この関数は新たなプロセスのプロセス ID となります。; mode が P_WAIT の場合、子プロセスが正常に終了するとその終了コードが返ります。そうでない場合にはプロセスを kill したシグナル signal に対して -signal が返ります。 Windows では、プロセス ID は実際にはプロセスハンドル値になります。

“l” および “v” のついた spawn*() 関数は、コマンドライン引数をどのように渡すかが異なります。 “l” 型は、コードを書くときにパラメタ数が決まっている場合に、おそらくもっとも簡単に利用できます。個々のパラメタは単に spawnl*() 関数の追加パラメタとなります。 “v” 型は、パラメタの数が可変の時に便利で、リストかタプルの引数が args パラメタとして渡されます。どちらの場合も、子プロセスに渡す引数は動作させようとしているコマンドの名前から始まらなくてはなりません。

末尾近くに “p” をもつ型 (spawnlp(), spawnlpe(), spawnvp(), spawnvpe()) は、プログラム file を探すために環境変数 PATH を利用します。環境変数が (次の段で述べる spawn*e() 型関数で) 置き換えられる場合、環境変数は PATH を決定する上の情報源として使われます。その他の型、 spawnl(), spawnle(), spawnv(),および spawnve() では、実行コードを探すために PATH を使いません。 path には適切に設定された絶対パスまたは相対パスが入っていなくてはなりません。

spawnle(), spawnlpe(), spawnve(),および spawnvpe() (全て末尾に “e” がついていることに注意してください) では、 env パラメタは新たなプロセスで利用される環境変数を定義するためのマップ型でなくてはなりません; spawnl(), spawnlp(), spawnv(), および spawnvp() では、全て新たなプロセスは現在のプロセスの環境を引き継ぎます。 env 辞書のキーと値は全て文字列である必要があります。不正なキーや値を与えると関数が失敗し、 127 を返します。

例えば、以下の spawnlp() および spawnvpe() 呼び出し:

import os
os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', '/dev/null')

L = ['cp', 'index.html', '/dev/null']
os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)

は等価です。

利用できる環境: Unix, Windows

spawnlp(), spawnlpe(), spawnvp() および spawnvpe() は Windows では利用できません。

バージョン 1.6 で追加.

os.P_NOWAIT

os.P_NOWAITO

spawn*() 関数ファミリに対する mode パラメタとして取れる値です。この値のいずれかを mode として与えた場合、 spawn*() 関数は新たなプロセスが生成されるとすぐに、プロセスの ID を戻り値として返ります。

利用できる環境: Unix, Windows

バージョン 1.6 で追加.

os.P_WAIT

spawn*() 関数ファミリに対する mode パラメタとして取れる値です。この値を mode として与えた場合、 spawn*() 関数は新たなプロセスを起動して完了するまで返らず、プロセスがうまく終了した場合には終了コードを、シグナルによってプロセスが kill された場合には -signal を返します。

利用できる環境: Unix, Windows

バージョン 1.6 で追加.

os.P_DETACH

os.P_OVERLAY

spawn*() 関数ファミリに対する mode パラメタとして取れる値です。これらの値は上の値よりもやや可搬性において劣っています。 P_DETACH は P_NOWAIT に似ていますが、新たなプロセスは呼び出しプロセスのコンソールから切り離され (detach) ます。 P_OVERLAY が使われた場合、現在のプロセスは置き換えられます; 従って spawn*() は返りません。

利用できる環境: Windows

バージョン 1.6 で追加.

os.startfile(path[, operation])

ファイルを関連付けられたアプリケーションを使って「スタート」します。

operation が指定されないかまたは 'open' であるとき、この動作は、 Windows の Explorer 上でのファイルをダブルクリックや、コマンドプロンプト (interactive command shell) 上でのファイル名を start 命令の引数としての実行と同様です: ファイルは拡張子が関連付けされているアプリケーション (が存在する場合) を使って開かれます。

他の operation が与えられる場合、それはファイルに対して何がなされるべきかを表す “command verb” (コマンドを表す動詞) でなければなりません。 Microsoft が文書化している動詞は、 'print' と 'edit' (ファイルに対して) および 'explore' と 'find' (ディレクトリに対して) です。

startfile() は関連付けされたアプリケーションが起動すると同時に返ります。アプリケーションが閉じるまで待機させるためのオプションはなく、アプリケーションの終了状態を取得する方法もありません。 path 引数は現在のディレクトリからの相対で表します。絶対パスを利用したいなら、最初の文字はスラッシュ ('/') ではないので注意してください; もし最初の文字がスラッシュなら、システムの背後にある Win32 ShellExecute() 関数は動作しません。 os.path.normpath() 関数を使って、Win32 用に正しくコード化されたパスになるようにしてください。

利用できる環境: Windows

バージョン 2.0 で追加.

バージョン 2.5 で追加: operation パラメータ.

os.system(command)

サブシェル内でコマンド (文字列) を実行します。この関数は標準 C 関数 system() を使って実装されており、 system() と同じ制限があります。 sys.stdin などに対する変更を行っても、実行されるコマンドの環境には反映されません。

Unixでは、戻り値はプロセスの終了ステータスで、 wait() で定義されている書式にコード化されています。 POSIX は system() 関数の戻り値の意味について定義していないので、 Python の system() における戻り値はシステム依存となることに注意してください。

Windows では、戻り値は command を実行した後にシステムシェルから返される値で、Windows の環境変数 COMSPEC となります: command.com ベースのシステム (Windows 95, 98 および ME) では、この値は常に 0 です; cmd.exe ベースのシステム (Windows NT, 2000 および XP) では、この値は実行したコマンドの終了ステータスです; ネイティブでないシェルを使っているシステムについては、使っているシェルのドキュメントを参照してください。

subprocess モジュールが、新しいプロセスを実行して結果を取得するための、より強力な機能を提供しています。この関数の代わりに、 subprocess モジュールを利用することが推奨されています。 subprocess モジュールのドキュメントの、古い関数を subprocess モジュールで置き換えるというセクションのレシピを参考にして下さい。

利用できる環境: Unix, Windows

os.times()

(プロセッサまたはその他の) 積算時間を秒で表す浮動小数点数からなる、 5 要素のタプルを返します。タプルの要素は、ユーザ時間 (user time)、システム時間 (system time)、子プロセスのユーザ時間、子プロセスのシステム時間、そして過去のある固定時点からの経過時間で、この順に並んでいます。 Unix マニュアルページ times(2) または対応する Windows プラットフォーム API ドキュメントを参照してください。 Windows では、最初の２つの要素だけが埋められ、残りは0になります。

利用できる環境: Unix, Windows

os.wait()

子プロセスの実行完了を待機し、子プロセスの pid と終了コードインジケータ — 16 ビットの数で、下位バイトがプロセスを kill したシグナル番号、上位バイトが終了ステータス (シグナル番号がゼロの場合) — の入ったタプルを返します; コアダンプファイルが生成された場合、下位バイトの最上桁ビットが立てられます。

利用できる環境: Unix

os.waitpid(pid, options)

Unix の場合: プロセス id pid で与えられた子プロセスの完了を待機し、子プロセスのプロセス id と(wait() と同様にコード化された) 終了ステータスインジケータからなるタプルを返します。この関数の動作は options によって影響されます。通常の操作では 0 にします。

pid が 0 よりも大きい場合、 waitpid() は特定のプロセスのステータス情報を要求します。 pid が 0 の場合、現在のプロセスグループ内の任意の子プロセスの状態に対する要求です。 pid が -1 の場合、現在のプロセスの任意の子プロセスに対する要求です。 pid が -1 よりも小さい場合、プロセスグループ -pid (すなわち pid の絶対値) 内の任意のプロセスに対する要求です。

システムコールが -1 を返したとき、 OSError を errno と共に送出します。

Windowsでは、プロセスハンドル pid を指定してプロセスの終了を待って、 pid と、終了ステータスを8bit左シフトした値のタプルを返します。 (シフトは、この関数をクロスプラットフォームで利用しやすくするために行われます) 0 以下の pid はWindowsでは特別な意味を持っておらず、例外を発生させます。 options の値は効果がありません。 pid は、子プロセスで無くても、プロセスIDを知っているどんなプロセスでも参照することが可能です。 spawn() 関数を P_NOWAIT と共に呼び出した場合、適切なプロセスハンドルが返されます。

os.wait3([options])

waitpid() に似ていますが、プロセス id を引数に取らず、子プロセス id、終了ステータスインジケータ、リソース使用情報の3要素からなるタプルを返します。リソース使用情報の詳しい情報は resource.getrusage() を参照してください。 options は waitpid() および wait4() と同様です。

利用できる環境: Unix

バージョン 2.5 で追加.

os.wait4(pid, options)

waitpid() に似ていますが、子プロセス id、終了ステータスインジケータ、リソース使用情報の3要素からなるタプルを返します。リソース使用情報の詳しい情報は resource.getrusage() を参照してください。 wait4() の引数は waitpid() に与えられるものと同じです。

利用できる環境: Unix

バージョン 2.5 で追加.

os.WNOHANG

子プロセス状態がすぐに取得できなかった場合に直ちに終了するようにするための waitpid() のオプションです。この場合、関数は (0, 0) を返します。

利用できる環境: Unix

os.WCONTINUED

このオプションによって子プロセスは前回状態が報告された後にジョブ制御による停止状態から実行を継続された場合に報告されるようになります。

利用できる環境: ある種の Unix システム。

バージョン 2.3 で追加.

os.WUNTRACED

このオプションによって子プロセスは停止されていながら停止されてから状態が報告されていない場合に報告されるようになります。

利用できる環境: Unix

バージョン 2.3 で追加.

以下の関数は system(), wait(), あるいは waitpid() が返すプロセス状態コードを引数にとります。これらの関数はプロセスの配置を決めるために利用することができます。

os.WCOREDUMP(status)

プロセスに対してコアダンプが生成されていた場合には True を、それ以外の場合は False を返します。

利用できる環境: Unix

バージョン 2.3 で追加.

os.WIFCONTINUED(status)

プロセスがジョブ制御による停止状態から実行を継続された (continue) 場合に True を、それ以外の場合は False を返します。

利用できる環境: Unix

バージョン 2.3 で追加.

os.WIFSTOPPED(status)

プロセスが停止された (stop) 場合に True を、それ以外の場合は False を返します。

利用できる環境: Unix

os.WIFSIGNALED(status)

プロセスがシグナルによって終了した (exit) 場合に True を、それ以外の場合は False を返します。

利用できる環境: Unix

os.WIFEXITED(status)

プロセスが exit(2) システムコールで終了した場合に True を、それ以外の場合は False を返します。

利用できる環境: Unix

os.WEXITSTATUS(status)

WIFEXITED(status) が真の場合、 exit(2) システムコールに渡された整数パラメタを返します。そうでない場合、返される値には意味がありません。

利用できる環境: Unix

os.WSTOPSIG(status)

プロセスを停止させたシグナル番号を返します。

利用できる環境: Unix

os.WTERMSIG(status)

プロセスを終了させたシグナル番号を返します。

利用できる環境: Unix

15.1.6. 雑多なシステム情報

os.confstr(name)

文字列形式によるシステム設定値 (system configuration value)を返します。 name には取得したい設定名を指定します; この値は定義済みのシステム値名を表す文字列にすることができます; 名前は多くの標準 (POSIX.1、 Unix 95、 Unix 98 その他) で定義されています。ホストオペレーティングシステムの関知する名前は confstr_names 辞書のキーとして与えられています。このマップ型オブジェクトに入っていない設定変数については、 name に整数を渡してもかまいません。

name に指定された設定値が定義されていない場合、 None を返します。

もし name が文字列でかつ不明である場合、 ValueError を送出します。 name の指定値がホストシステムでサポートされておらず、 confstr_names にも入っていない場合、 errno.EINVAL をエラー番号として OSError を送出します。

利用できる環境: Unix

os.confstr_names

confstr() が受理する名前を、ホストオペレーティングシステムで定義されている整数値に対応付けている辞書です。この辞書はシステムでどの設定名が定義されているかを決定するために利用できます。

利用できる環境: Unix

os.getloadavg()

過去 1 分、5 分、15分間で、システムで走っているキューの平均プロセス数を返します。平均負荷が得られない場合には OSError を送出します。

利用できる環境: Unix

バージョン 2.3 で追加.

os.sysconf(name)

整数値のシステム設定値を返します。 name で指定された設定値が定義されていない場合、 -1 が返されます。 name に関するコメントとしては、 confstr() で述べた内容が同様に当てはまります; 既知の設定名についての情報を与える辞書は sysconf_names で与えられています。

利用できる環境: Unix

os.sysconf_names

sysconf() が受理する名前を、ホストオペレーティングシステムで定義されている整数値に対応付けている辞書です。この辞書はシステムでどの設定名が定義されているかを決定するために利用できます。

利用できる環境: Unix

以下のデータ値はパス名編集操作をサポートするために利用されます。これらの値は全てのプラットフォームで定義されています。

パス名に対する高レベルの操作は os.path モジュールで定義されています。

os.curdir

現在のディレクトリ参照するためにオペレーティングシステムで使われる文字列定数です。 POSIX と Windows では '.' になります。 os.path からも利用できます。

os.pardir

親ディレクトリを参照するためにオペレーティングシステムで使われる文字列定数です。 POSIX と Windows では '..' になります。 os.path からも利用できます。

os.sep

パス名を要素に分割するためにオペレーティングシステムで利用されている文字です。例えば POSIX では '/' で、Windowsでは '\\' です。しかし、このことを知っているだけではパス名を解析したり、パス名同士を結合したりするには不十分です — こうした操作には os.path.split() や os.path.join() を使ってください — が、たまに便利なこともあります。 os.path からも利用できます。

os.altsep

文字パス名を要素に分割する際にオペレーティングシステムで利用されるもう一つの文字で、分割文字が一つしかない場合には None になります。この値は sep がバックスラッシュとなっている DOS や Windows システムでは '/' に設定されています。 os.path からも利用できます。

os.extsep

ベースのファイル名と拡張子を分ける文字。たとえば、 os.py だったら '.' です。 os.path からも利用できます。

バージョン 2.2 で追加.

os.pathsep

(PATH のような) サーチパス内の要素を分割するためにオペレーティングシステムが慣習的に用いる文字で、POSIX における ':' や DOS および Windows における ';' に相当します。 os.path からも利用できます。

os.defpath

exec*p*() や spawn*p*() において、環境変数辞書内に 'PATH' キーがない場合に使われる標準設定のサーチパスです。 os.path からも利用できます。

os.linesep

現在のプラットフォーム上で行を分割 (あるいは終端) するために用いられている文字列です。この値は例えば POSIX での '\n' や Mac OS での '\r' のように、単一の文字にもなりますし、例えば Windows での '\r\n' のように複数の文字列にもなります。テキストモードで開いたファイルに書き込むときには、 os.linesep を利用しないでください。全てのプラットフォームで、単一の '\n' を使ってください。

os.devnull

ヌルデバイス (null device) のファイルパスです。例えばPOSIX では '/dev/null' で、 Windows では 'nul' です。この値は os.path からも利用できます。

バージョン 2.4 で追加.

15.1.7. 雑多な関数

os.urandom(n)

暗号に関する用途に適した n バイトからなるランダムな文字列を返します。

この関数は OS 固有の乱数発生源からランダムなバイト列を生成して返します。この関数の返すデータは暗号を用いたアプリケーションで十分利用できる程度に予測不能ですが、実際のクオリティは OS の実装によって異なります。 Unix系のシステムでは /dev/urandom への問い合わせを行い、 Windows では CryptGenRandom() を使います。乱数発生源が見つからない場合、 NotImplementedError を送出します。

バージョン 2.4 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.2. io — ストリームを扱うコアツール

バージョン 2.6 で追加.

io モジュールはストリーム処理を行う Python インタフェースを提供します。 Python 2.x では、これは組み込みの file オブジェクトの代わりとして提案されていますが、Python 3.x では、これがファイルやストリームのデフォルトインタフェースです。

ノート

このモジュールはもともと、Python 3.x のために設計されたものなので、このドキュメントの中で使われるすべての “bytes” は (bytes がエイリアスとなる) str 型のことで、すべての “text” は unicode 型のことです。さらに、 io API では、この 2 つの型は入れ替えられません。

I/O 階層の最上位には抽象基底クラスの IOBase があります。 IOBase ではストリームに対して基本的なインタフェースを定義しています。しかしながら、ストリームに対する読み込みと書き込みが分離されていないことに注意してください。実装においては与えられた操作をサポートしない場合は IOError を送出することが許されています。

IOBase の拡張は、単純なストリームに対する生のバイト列の読み書きを扱う RawIOBase です。 FileIO は、 RawIOBase を継承してマシンのファイルシステム中のファイルへのインタフェースを提供します。

BufferedIOBase では生のバイトストリーム (RawIOBase) 上にバッファ処理を追加します。そのサブクラスの BufferedWriter, BufferedReader, BufferedRWPair では、それぞれ読み込み専用、書き込み専用、読み書き可能なストリームをバッファします。 BufferedRandom ではランダムアクセスストリームに対してバッファされたインタフェースを提供します。 BytesIO はインメモリバイトへのシンプルなストリームです。

もう一つの IOBase のサブクラスである TextIOBase は、テキストを表すバイトストリームを扱い、 unicode エンコードやデコードといった処理を行います。 TextIOWrapper はその拡張で、バッファ付き生ストリーム (BufferedIOBase) へのバッファされたテキストインタフェースです。最後に StringIO は Unicode テキストに対するインメモリストリームです。

引数名は規約に含まれていません。そして open() の引数だけがキーワード引数として用いられることが意図されています。

15.2.1. モジュールインタフェース

io.DEFAULT_BUFFER_SIZE

モジュールのバッファ I/O クラスで使用されるデフォルトのバッファサイズを指定する整数値です。 open() は可能であればファイル全体のサイズ (os.stat() で取得されます) を使用します。

io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)

file を開き、対応するストリームを返します。ファイルが開けなかった場合、 IOError が発生します。

file は開きたいファイルの (絶対、またはカレントワーキングディレクトリに対する相対) パス名を示す文字列か、開きたいファイルがラップされているファイル記述子です。 (ファイル記述子が与えられた場合、 closefd が False に設定されていない限り、返された I/O オブジェクトが閉じられたときにそのファイル識別子も閉じられます)

mode はオプションの文字列です。これによってファイルをどのようなモードで開くか明示することができます。デフォルトは 'r' でテキストモードで読み取り専用で開くことを指します。他にも 'w' は書き込み専用 (もしファイルが存在していた場合は上書きになります) となり、 'a' では追記モードとなります。 ('a' は いくつかの Unixシステムでは すべての 書き込みがシーク位置に関係なくファイルの末尾に追記されることを意味します) テキストモードでは、もし encoding が指定されていなかった場合、エンコーディングはプラットフォーム依存となります。 (生のバイトデータの読み込みと書き込みはバイナリモードを用いて、 encoding は未指定のままとします) 指定可能なモードは次の表の通りです。

文字 | 意味
'r' | 読み込み専用で開く (デフォルト)
'w' | 書き込み専用で開く。ファイルは最初に切り詰められる。
'a' | 書き込み専用で開く。ファイルが存在する場合は末尾に追記する。
'b' | バイナリモード
't' | テキストモード (デフォルト)
'+' | ファイルを更新用に開く (読み込み／書き込み)
'U' | ユニバーサルニューラインモード (後方互換性のためのモードで、新規コードでは使用すべきではありません)

デフォルトモードは 'rt' です (テキストを読み込み専用で開きます)。バイナリのランダムアクセスでは 'w+b' はファイルを開き、ファイルを 0 バイトに切り詰めます。一方で 'r+b' でファイルを開くとサイズの切り詰めは行われません。

Python ではバイナリモードで開かれたファイルとテキストモードで開かれたファイルは区別されます。オペレーティングシステムが区別しない場合でもこの区別は適用されます。バイナリモードで開かれたファイル (つまり mode 引数に 'b' が含まれるとき) では、中身を bytes オブジェクトとして返し、一切のデコードを行いません。テキストモード (デフォルトか mode 引数に 't' が含まれている場合) では、ファイルの内容は unicode 文字列として返され、バイト列はプラットフォーム依存のエンコーディングか、 encoding が指定された場合は指定されたエンコーディングを使ってデコードされます。

オプションの buffering はバッファ用の設定を行う整数値です。 0 を設定することでバッファがオフになります (バイナリモードでのみ有効です)。 1 の場合は 1 行ごとのバッファリングを行い (テキストモードでのみ利用可能です)、 1 より大きい場合は固定サイズチャンクバッファのサイズを表します。 buffering 引数が与えられなければ、デフォルトのバッファリングポリシーは以下のように働きます:

バイナリファイルは固定サイズのチャンクでバッファリングされます。バッファサイズは、背後のデバイスの「ブロックサイズ」を決定するヒューリスティックを用いて選択され、それが不可能な場合は代わりに DEFAULT_BUFFER_SIZE が使われます。多くのシステムでは、典型的なバッファサイズは 4096 か 8192 バイト長になるでしょう。

「対話的な」テキストファイル (isatty() が True を返すファイル) は行バッファリングを使用します。その他のテキストファイルは、上で説明されたバイナリファイルのためのポリシーを使用します。

encoding はファイルをエンコードあるいはデコードするために使われるエンコーディング名です。このオプションはテキストモードでのみ使用されるべきです。デフォルトエンコーディングはプラットフォーム依存 (locale.getpreferredencoding() が返すもの) ですが、Pythonでサポートされているエンコーディングはどれでも使えます。詳しくは codecs モジュール内のサポートしているエンコーディングのリストを参照してください。

errors はエンコードやデコードの際のエラーをどのように扱うかを指定する文字列で、バイナリモードでは使えません。 'strict' を指定すると、エンコードエラーがあった場合 ValueError 例外が発生します (デフォルトである None は同様の処理を行います)。 'ignore' を指定した場合はエラーを無視します。 'replace' を指定した場合は正常に変換されなかった文字の代わりにマーカ (例えば '?' のような文字) を挿入します。書き込みの際には 'xmlcharrefreplace' (適切なXML文字参照に置き換える) か 'backslashreplace' (バックスラッシュによるエスケープシーケンスに置き換える) のどちらかが使用できます。 codecs.register_error() に登録されている他のエラー処理名も指定できます。

newline ではユニバーサルニューラインの挙動を制御しています (テキストモードのみ有効です)。 None、 ''、 '\n'、 '\r'、 '\r\n' が指定できます。以下のように動作します：

入力時、 newline が None の場合はユニバーサルニューラインモードが有効になります。入力行の行末は '\n' 、 '\r' 、 '\r\n' のいずれかで、それらは呼び出し元に戻される前に '\n' に変換されます。もし '' だった場合はユニバーサルニューラインモードは有効になりますが、行末は変換されずに呼び出し元に戻されます。他の適切な値が指定された場合は、入力行は与えられた文字列で分断され、行末は変換されずに呼び出し元に戻されます。

出力時、 newline が None の場合は、すべての '\n' 文字はシステムのデフォルト行区切り文字 os.linesep に変換されます。もし newline が '' の場合、変換は起こりません。もし newline に他の適切な値が指定された場合は、 '\n' 文字は与えられた文字に変換されます。

もし closefd が False で、ファイル名ではなくてファイル記述子が与えられていた場合、処理中のファイル記述子はファイルが閉じられた後も開いたままとなります。もしファイル名が与えられていた場合は、 closefd は関係ありません。しかし True でなければなりません。(デフォルト値)

open() によって返されるファイルオブジェクトの型はモードに依存します。 open() がテキストモードでファイルを開くために使われた場合 ('w'、 'r'、 'wt'、 'rt' など) TextIOBase のサブクラス (具体的には TextIOWrapper) が返されます。バッファリングをしてバイナリモードでファイルを開く場合、 BufferedIOBase のサブクラスが返されます。具体的なクラスは多様です。もし読み取り専用のバイナリモードだった場合は BufferedReader が返されます。書き込み専用のバイナリモードだった場合は BufferedWriter が返されます。読み書き可能なバイナリモードの場合は BufferedRandom が返されます。バッファリングが無効な場合、raw ストリーム、 RawIOBase のサブクラス、 FileIO が返されます。

unicode 文字列や bytes 文字列をファイルとして読み書きすることも可能です。 unicode 文字列では StringIO を使えばテキストモードで開いたファイルのように扱えます。 bytes では BytesIO を使えばバイナリモードで開いたファイルのように扱えます。

exception io.BlockingIOError

非ブロッキングストリームでブロック処理が起きた場合に発生するエラーです。 IOError を継承しています。

IOError で持っている属性以外に BlockingIOError では次の属性を持っています。

characters_written

ブロック前にストリームに書き込まれる文字数を保持する整数値です。

exception io.UnsupportedOperation

IOError と ValueError を継承した例外で、ストリームに未サポートの操作が行われた場合に発生します。

15.2.2. I/O 基底クラス

class io.IOBase

すべての I/O クラスの抽象基底クラスです。バイトストリームへの操作を行います。パブリックなコンストラクタはありません。

このクラスでは、継承先のクラスが選択的にオーバライドできるように多くの空の抽象実装が提供されます。デフォルトの実装では、読み込み、書き込み、シークができないファイルを表現します。

IOBase では read(), readinto(), write() が宣言されていませんが、これはシグナチャが変化するためで、実装やクライアントはこれらのメソッドをインタフェースの一部として考えるべきです。また、実装はサポートしていない操作を呼び出されたときは IOError を発生させるかもしれません。

ファイルへの読み書きに用いられるバイナリデータに使われる基本型は (str としても知られている) bytes です。 bytearray も利用可能で、いくつかのケース (たとえば readinto) では必須です。テキスト I/O クラスは unicode データを扱います。

閉じられたストリームに対するメソッド呼び出しは (問い合わせであっても) 未定義です。この場合、実装は IOError を発生させることがあります。

IOBase (とそのサブクラス) はイテレータプロトコルをサポートします。すなわち IOBase オブジェクトはストリーム内の行を yield を使ってイテレートすることができます。行は、ストリームが (bytes を与える) バイナリストリームか (unicode 文字列を与える) テキストストリームかに依って、少し違う定義がされています。下の readline() を参照してください。

IOBase はコンテキストマネージャでもあります。そのため with 構文をサポートします。次の例では、 with 構文が終わった後で—たとえ例外が発生した場合でも、 file は閉じられます。

with io.open('spam.txt', 'w') as file:
    file.write(u'Spam and eggs!')

IOBase は以下のデータ属性とメソッドを提供します:

close()

このストリームをフラッシュして閉じます。このメソッドはファイルが既に閉じられていた場合は特に何の効果もありません。いったんファイルが閉じられると、すべてのファイルに対する操作 (例えば読み込みや書き込み) で ValueError が発生します。

利便性のために、このメソッドを複数回呼ぶことは許可されています。しかし、効果があるのは最初の1回だけです。

closed

ストリームが閉じられていた場合 True になります。

fileno()

ストリームが保持しているファイル記述子 (整数値) が存在する場合はそれを返します。もし IO オブジェクトがファイル記述子を使っていない場合は IOError が発生します。

flush()

適用可能であればストリームの書き込みバッファをフラッシュします。読み込み専用や非ブロッキングストリームでは何もしません。

isatty()

ストリームが対話的であれば (つまりターミナルや tty デバイスにつながっている場合) True を返します。

readable()

ストリームが読み込める場合 True を返します。 False の場合は read() は IOError を発生させます。

readline(limit=-1)

ストリームから 1 行読み込んで返します。もし limit が指定された場合、最大で limit バイトが読み込まれます。

バイナリファイルでは行末文字は常に b'\n' となります。テキストファイルでは、認識される行末文字を選択するために open() に対する newlines 引数が使われます。

readlines(hint=-1)

ストリームから行のリストを読み込んで返します。 hint を指定することで、読み込む行数を制御できます。もし読み込んだすべての行のサイズ (バイト数、もしくは文字数) が hint の値を超えた場合、読み込みをそこで終了します。

seek(offset, whence=SEEK_SET)

ストリーム位置を指定された offset バイトに変更します。 offset は whence で指定された位置からの相対位置として解釈されます。 whence に指定できる値は：

SEEK_SET または 0 – ストリームの先頭 (デフォルト)。 offset は 0 もしくは正の値でなければなりません。

SEEK_CUR または 1 – 現在のストリーム位置。 offset は負の値も可能です。

SEEK_END または 2 – ストリームの末尾。 offset は通常負の値です。

新しい絶対位置を返します。

バージョン 2.7 で追加: SEEK_* 定数

seekable()

もしストリームがランダムアクセスをサポートしていた場合 True を返します。 False の場合は seek()、 tell()、 truncate() は IOError を発生させます。

tell()

現在のストリーム位置を返します。

truncate(size=None)

指定された size バイト (または size が指定されなければ現在の位置) にストリームをリサイズします。現在のストリーム位置は変更されません。このリサイズは、現在のファイルサイズを拡大または縮小させることができます。拡大の場合には、新しいファイル領域の内容はプラットホームに依存します (ほとんどのシステムでは、追加のバイトが 0 で埋められます。 Windowsでは不定です)。新しいファイルサイズが返されます。

writable()

ストリームが書き込みをサポートしている場合 True を返します。 False の場合は write()、 truncate() は IOError を返します。

writelines(lines)

ストリームに複数行書き込みます。行区切り文字は付与されないので、通常書き込む各行の行末には行区切り文字があります。

class io.RawIOBase

生のバイナリ I/O への基底クラスです。 IOBase を継承しています。パブリックコンストラクタはありません。

生のバイナリ I/O は典型的に、下にある OS デバイスや API への、低レベルなアクセスを提供し、高レベルな基本要素へとカプセル化しようとはしません (これはこのページで後述する Buffered I/O や Text I/O に任せます)。

IOBase の属性やメソッドに加えて、 RawIOBase は次のメソッドを提供します：

read(n=-1)

オブジェクトを n バイトまで読み込み、それを返します。簡単のため、 n が指定されていないか -1 なら、 readall() が呼び出されます。そうでなければ、システムコール呼び出しが一度だけ行われます。既に EOF に達していたら空のバイトオブジェクトが返されます。オペレーティングシステムコールが返したものがが n バイトより少なければ、 n バイトより少なく返されることがあります。

0 バイトが返って、 n が 0 でなければ、それはファイルの終端を表します。オブジェクトがノンブロッキングモードで、 1 バイトも読み込めなければ、 None が返されます。

readall()

EOF までストリームからすべてのバイトを読み込みます。必要な場合はストリームに対して複数の呼び出しをします。

readinto(b)

bytearray b に最大 len(b) バイト分読み込み、読み込んだバイト数を返します。オブジェクトがノンブロッキングモードで、 1 バイトも読み込めなければ、 None が返されます。

write(b)

与えられた bytes または bytearray オブジェクト b を生ストリームに書き込み、書き込んだバイト数を返します。これは、根底の生ストリームの性質や、特にノンブロッキングである場合に、 len(b) より小さくなり得ます。生ストリームがブロックされないように設定されていて、 1 バイトも読み込めるように書きこまれなければ、 None が返されます。

class io.BufferedIOBase

何らかのバッファリングをサポートするバイナリストリームの基底クラスです。 IOBase を継承します。パブリックなコンストラクタはありません。

RawIOBase との主な違いは、メソッド read(), readinto() および write() メソッドは (それぞれ) 要求されただけの入力を読み込もうとしたり、システムコールを、必要なら複数回、する費用として全ての与えられた出力消費しようとすることです。

加えて、元になる生ストリームが非ブロッキングモードでかつ準備ができていない場合に、これらのメソッドは、 BlockingIOError を送出するかもしれません。対応する RawIOBase バージョンと違って、 None を返すことはありません。

さらに、 read() メソッドは、 readinto() に従うデフォルト実装を持ちません。

通常の BufferedIOBase 実装は RawIOBase 実装を継承せずに、 BufferedWriter と BufferedReader がするようにこれをラップすべきです。

BufferedIOBase は IOBase からのメンバに加えて、以下のメソッドを提供もしくはオーバーライドします:

raw

BufferedIOBase が扱う根底の生ストリーム (RawIOBase インスタンス) を返します。これは BufferedIOBase API には含まれず、よって実装に含まれないことがあります。

detach()

根底の生ストリームをバッファから分離して返します。

生ストリームが取り外された後、バッファは使用不能状態になります。

バッファには、 BytesIO など、このメソッドで返される単体のストリームという概念を持たないものがあります。これらは UnsupportedOperation を送出します。

バージョン 2.7 で追加.

read(n=-1)

最大で n バイト読み込み、返します。引数が省略されるか、 None か、または負の値であった場合、データは EOF に到達するまで読み込まれます。ストリームが既に EOF に到達していた場合は空の bytes オブジェクトが返されます。

引数が正で、元になる生ストリームが対話的でなければ、必要なバイト数を満たすように複数回の生 read が発行されるかもしれません (先に EOF に到達しない限りは)。対話的な場合は、最大で一回の raw read しか発行されず、短い結果でも EOF に達したことを意味しません。

元になる生ストリームがノンブロッキングモードで、呼び出された時点でデータを持っていなければ、 BlockingIOError が送出されます。

read1(n=-1)

根底の生ストリームの read() メソッドを高々 1 回呼び出し、最大で n バイト読み込み、返します。これは、 BufferedIOBase オブジェクトの上に独自のバッファリングを実装するときに便利です。

readinto(b)

bytearray b に最大 len(b) バイト読み込み、何バイト読んだかを返します。

read() と同様、元になる生ストリームが ‘対話的’ でない限り、複数回の read が発行されるかもしれません。

元になる生ストリームが呼び出された時点でデータを持っていなければ、 BlockingIOError が送出されます。

write(b)

与えられた bytes または bytearray オブジェクト b を書き込み、書き込んだバイト数を返します (これは決して len(b) よりも小さくなることはありません。なぜなら、もし書き込みに失敗した場合は IOError が発生するからです)。実際の実装に依って、これらのバイトは根底のストリームに読めるように書きこまれたり、パフォーマンスとレイテンシの理由でバッファに保持されたりします。

ノンブロッキングモードであるとき、バッファが満杯で根底の生ストリームが書き込み時点でさらなるデータを受け付けられない場合 BlockingIOError が送出されます。

15.2.3. 生ファイルI/O

class io.FileIO(name, mode='r', closefd=True)

FileIO はバイトデータを含む OS レベルのファイルを表します。 RawIOBase インタフェースを (したがって IOBase インタフェースも) 実装しています。

name はこの 2 つのいずれかに出来ます:

開くファイルのパスを表す文字列

結果の FileIO オブジェクトがアクセスを与える、既存の OS レベルファイルディスクリプタの数を表す整数

mode はそれぞれ読み込み (デフォルト)、書き込み、追記を表す 'r'、 'w'、 'a' にすることができます。ファイルは書き込みまたは追記モードで開かれたときに存在しなければ作成されます。書き込みモードでは存在したファイル内容は消されます。読み込みと書き込みを同時に行いたければ '+' をモードに加えて下さい。

このクラスの read() (正の引数で呼び出されたとき), readinto() および write() メソッドは、単にシステムコールを一度呼び出します。

IOBase および RawIOBase から継承した属性とメソッドに加えて、 FileIO は以下のデータ属性とメソッドを提供しています:

mode

コンストラクタに渡されたモードです。

name

ファイル名。コンストラクタに名前が渡されなかったときはファイル記述子になります。

15.2.4. バッファ付きストリーム

バッファ付き I/O ストリームは、I/O デバイスに生 I/O より高レベルなインタフェースを提供します。

class io.BytesIO([initial_bytes])

インメモリの bytes バッファを利用したストリームの実装。 BufferedIOBase を継承します。

引数 initial_bytes は省略可能な bytes の初期値です。

BytesIO は BufferedIOBase または IOBase からのメソッドに加えて、以下のメソッドを提供もしくはオーバーライドします:

getvalue()

バッファの全内容を保持した bytes を返します。

read1()

BytesIO においては、このメソッドは read() と同じです。

class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)

読み込み可能でシーケンシャルな RawIOBase オブジェクトへの、高レベルなアクセスを提供するバッファです。 BufferedIOBase を継承します。このオブジェクトからデータを読み込むとき、根底の生ストリームからより大きい量のデータが要求されることがあり、内部バッファに保存されます。バッファされたデータは、続く読み込み時に直接返されます。

このコンストラクタは与えられた raw ストリームと buffer_size に対し BufferedReader を生成します。 buffer_size が省略された場合、代わりに DEFAULT_BUFFER_SIZE が使われます。

BufferedReader は BufferedIOBase または IOBase からのメソッドに加えて、以下のメソッドを提供もしくはオーバーライドします:

peek([n])

バイト列をストリームから位置を変更せずに読んで返します。これを果たすために生ストリームに対して行われる read は高々一度だけです。返されるバイト数は、要求されたより少なくまたは多くなるかもしれません。

read([n])

n バイトを読み込んで返します。 n が与えられないかまたは負の値ならば、EOF まで、または非ブロッキングモード中で read 呼び出しがブロックされるまでを返します。

read1(n)

生ストリームに対しただ一度の呼び出しで最大 n バイトを読み込んで返します。少なくとも 1 バイトがバッファされていれば、バッファされているバイト列だけが返されます。それ以外の場合にはちょうど一回生ストリームに read 呼び出しが行われます。

class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)

書き込み可能でシーケンシャルな RawIOBase オブジェクトへの、高レベルなアクセスを提供するバッファです。 BufferedIOBase を継承します。このオブジェクトに書き込むとき、データは通常内部バッファに保持されます。このバッファは、以下のような種々の状況で根底の RawIOBase オブジェクトに書きこまれます:

未解決のデータに対してバッファが足りなくなったとき

flush() が呼び出されたとき

seek() が (BufferedRandom オブジェクトに対して) 呼び出されたとき;

BufferedWriter オブジェクトが閉じられたり破棄されたりしたとき

このコンストラクタは与えられた書き込み可能な raw ストリームに対し BufferedWriter を生成します。 buffer_size が省略された場合、 DEFAULT_BUFFER_SIZE がデフォルトになります。

第三引数 max_buffer_size が提供されていますが、使われず、非推奨です。

BufferedWriter は BufferedIOBase または IOBase からのメソッドに加えて、以下のメソッドを提供もしくはオーバーライドします:

flush()

バッファに保持されたバイト列を生ストリームに流し込みます。生ストリームがブロックした場合 BlockingIOError が送出されます。

write(b)

bytes または bytearray オブジェクト b を書き込み、書き込んだバイト数を返します。ノンブロッキング時、バッファが書き込まれるべきなのに生ストリームがブロックした場合 BlockingIOError が送出されます。

class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE)

書き込み可能と書き込み可能の二つのシーケンシャルな RawIOBase オブジェクトへの、くみあわさった高レベルなアクセスを提供する、バッファ付き I/O オブジェクトです。これは、単方向のコミニュケーションチャネルの対 (パイプなど) に便利です。 BufferedIOBase を継承しています。

reader と writer はそれぞれ読み込み可能、書き込み可能な RawIOBase オブジェクトです。 buffer_size が省略された場合 DEFAULT_BUFFER_SIZE がデフォルトになります。

第四引数 max_buffer_size が提供されていますが、使われず、非推奨です。

BufferedRWPair は、 UnsupportedOperation を送出する detach() を除く、 BufferedIOBase の全てのメソッドを実装します。

class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)

ランダムアクセスストリームへのバッファ付きインタフェース。 BufferedReader および BufferedWriter を継承し、さらに seek() および tell() をサポートしています。

このコンストラクタは第一引数として与えられるシーク可能な生ストリームに対し、リーダーおよびライターを作成します。 buffer_size が省略された場合、 DEFAULT_BUFFER_SIZE がデフォルトになります。

第三引数 max_buffer_size が提供されていますが、使われず、非推奨です。

BufferedRandom は BufferedReader や BufferedWriter にできることは何でもできます。

15.2.5. テキスト I/O

class io.TextIOBase

テキストストリームの基底クラスです。このクラスはストリーム I/O への Unicode 文字と行に基づいたインタフェースを提供します。 Python の unicode 文字列は変更不可能なので、 readinto() メソッドは存在しません。 IOBase を継承します。パブリックなコンストラクタはありません。

IOBase から継承した属性とメソッドに加えて、 TextIOBase は以下のデータ属性とメソッドを提供しています:

encoding

エンコーディング名で、ストリームのバイト列を文字列にデコードするとき、また文字列をバイト列にエンコードするときに使われます。

errors

このエンコーダやデコーダのエラー設定です。

newlines

文字列、文字列のタプル、または None で、改行がどのように読み換えられるかを指定します。実装や内部コンストラクタのフラグに依って、これは利用できないことがあります。

buffer

TextIOBase が扱う根底のバイナリバッファ (BufferedIOBase インスタンス) です。これは TextIOBase API には含まれず、よって実装に含まれないことがあります。

detach()

根底のバイナリバッファを TextIOBase から分離して返します。

根底のバッファが取り外された後、 TextIOBase は使用不能状態になります。

TextIOBase 実装には、 StringIO など、根底のバッファという概念を持たないものがあります。これらを呼び出すと UnsupportedOperation を送出します。

バージョン 2.7 で追加.

read(n)

最大 n 文字をストリームから読み込み、一つの unicode にして返します。 n が負の値または None ならば、 EOF まで読みます。

readline()

改行または EOF まで読み込み、一つの unicode を返します。ストリームが既に EOF に到達している場合、空文字列が返されます。

write(s)

unicode 文字列 s をストリームに書き込み、書き込まれた文字数を返します。

class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False)

BufferedIOBase バイナリストリーム上のバッファ付きテキストストリーム。 TextIOBase を継承します。

encoding にはストリームをデコードしたりそれを使ってエンコードしたりするエンコーディング名を渡します。デフォルトは locale.getpreferredencoding() です。

errors はオプションの文字列で、エンコードやデコードの際のエラーをどのように扱うかを指定します。エンコードエラーがあったら ValueError 例外を送出させるには 'strict' を渡します(デフォルトの None でも同じです)。エラーを無視させるには 'ignore' です。 (注意しなければならないのは、エンコーディングエラーを無視するとデータ喪失につながる可能性があるということです。) 'replace' は正常に変換されなかった文字の代わりにマーカ (たとえば '?') を挿入させます。書き込み時には 'xmlcharrefreplace' (適切な XML 文字参照に置き換え) や 'backslashreplace' (バックスラッシュによるエスケープシーケンスに置き換え) も使えます。他にも codecs.register_error() で登録されたエラー処理名が有効です。

newline は None、 ''、 '\n'、 '\r'、 '\r\n' のいずれかです。行末の扱いを制御します。 None では、ユニバーサルニューラインが有効になります。これが有効になると、入力時、行末の '\n'、 '\r'、 '\r\n' は '\n' に変換されて呼び出し側に返されます。逆に出力時は '\n' がシステムのデフォルト行区切り文字 (os.linesep) に変換されます。 newline が他の適切な値の場合には、ファイル読み込みの際にその改行で改行されるようになり、変換は行われません。出力時には '\n' が newline に変換されます。

line_buffering が True の場合、 write への呼び出しが改行文字を含んでいれば flush() がそれに伴って呼び出されます。

TextIOBase およびその親クラスの属性に加えて、 TextIOWrapper は以下の属性を提供しています:

line_buffering

行バッファリングが有効かどうか。

class io.StringIO(initial_value=u'', newline=None)

Unicode テキストのためのインメモリストリーム。 TextIOWrapper を継承します。

このバッファの初期値は (デフォルトでは空の Unicode 文字列で)、 initial_value を与えることで設定できます。

TextIOWrapper およびその親クラスから継承したメソッドに加えて StringIO は以下のメソッドを提供しています:

getvalue()

StringIO オブジェクトの close() のバッファの全内容を保持した unicode を返します。

使用例:

import io

output = io.StringIO()
output.write(u'First line.\n')
output.write(u'Second line.\n')

# Retrieve file contents -- this will be
# u'First line.\nSecond line.\n'
contents = output.getvalue()

# Close object and discard memory buffer --
# .getvalue() will now raise an exception.
output.close()

class io.IncrementalNewlineDecoder

ユニバーサルニューラインモード向けに改行をデコードする補助コーデック。 codecs.IncrementalDecoder を継承します。

15.2.6. 進んだ話題

ここで、上述の I/O 実装に関係するいくつかの進んだ話題について議論します。

15.2.6.1. パフォーマンス

15.2.6.1.1. バイナリ I/O

バッファ付き I/O は、ユーザが 1 バイトだけ要求したときでさえ、データを大きな塊でのみ読み書きします。これにより、オペレーティングシステムのバッファ無し I/O ルーチンを呼び出して実行する非効率性をすべて隠しています。その成果は、OS と処理される I/O の種類に本当にとても大きく依存します (例えば、Linux のような 現行の OS では、バッファ無しディスク I/O がバッファ付き I/O と同じくらい早いことがあります)。しかし、最低でも、バッファ付き I/O は予測できるパフォーマンスを提供します。ですから、ほとんどいつも、バッファ無し I/O より、バッファ付きの I/O を使うほうが望ましいです。

15.2.6.1.2. テキスト I/O

(ファイルなどの) バイナリストレージ上のテキスト I/O は、同じストレージ上のバイナリ I/O より非常に遅いです。なぜならこれは、文字コーデックを使った Unicode からバイナリデータへの変換を暗示しているからです。これは大量のテキストデータ (例えば非常に大きなログファイル) を扱うときに顕著に成り得ます。同様に、 TextIOWrapper.tell() や TextIOWrapper.seek() はどちらも、使われている復元アルゴリズムのために遅くなります。

しかし StringIO は、ネイティブなインメモリ Unicode コンテナで、 BytesIO と同程度の速度を示します。

15.2.6.2. マルチスレッディング

(Unix における read(2) のような) オペレーティングシステムコールの、それがラッピングしているものがスレッドセーフであるような範囲内では、 FileIO オブジェクトもまた、スレッドセーフです。

バイナリバッファ付きオブジェクト (BufferedReader, BufferedWriter, BufferedRandom および BufferedRWPair のインスタンス) は、その内部構造をロックを使って保護します。このため、これらを複数のスレッドから同時に呼び出しても安全です。

TextIOWrapper オブジェクトはスレッドセーフではありません。

15.2.6.3. リエントラント性

バイナリバッファ付きオブジェクト (BufferedReader, BufferedWriter, BufferedRandom および BufferedRWPair のインスタンス) は、リエントラントではありません。リエントラントな呼び出しは普通の状況では起こりませんが、 I/O を signal ハンドラで行なっているときに起こりえます。バッファ化されたオブジェクトに、すでに 同じスレッドから アクセスされているのにもかかわらず、再び入ろうとすると RuntimeError が送出されます。

open() 関数は TextIOWrapper 内部のバッファ付きオブジェクトをラップするため、テキストファイルにも暗黙に拡張されます。これは、標準ストリームを含むので、組み込み関数 print() にも同様に影響します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.3. time — 時刻データへのアクセスと変換

このモジュールでは、時刻に関するさまざまな関数を提供します。関連した機能について、 datetime, calendar モジュールも参照してください。

このモジュールは常に利用可能ですが、全ての関数が全てのプラットフォームで利用可能なわけではありません。このモジュールで定義されているほとんどの関数は、プラットフォーム上の同名の C ライブラリ関数を呼び出します。これらの関数に対する意味付けはプラットフォーム間で異なるため、プラットフォーム提供のドキュメントを読んでおくと便利でしょう。

まずいくつかの用語の説明と慣習について整理します。

エポック (epoch) は、時刻の計測がはじまった時点のことです。その年の 1 月 1 日の午前 0 時に “エポックからの経過時間” が 0 になるように設定されます。Unixではエポックは 1970 年です。エポックがどうなっているかを知るには、 gmtime(0) の値を見るとよいでしょう。

このモジュールの中の関数は、エポック以前あるいは遠い未来の日付や時刻を扱うことができません。将来カットオフ（関数が正しく日付や時刻を扱えなくなる）が起きる時点は、C ライブラリによって決まります。 Unixではカットオフは通常 2038 です。

2000年問題 (Y2K): Python はプラットフォームの C ライブラリに依存しています。C ライブラリは日付および時刻をエポックからの経過秒で表現するので、一般的に 2000 年問題を持ちません。時刻を表現する struct_time （下記を参照してください）を入力として受け取る関数は一般的に 4 桁表記の西暦年を要求します。以前のバージョンとの互換性のために、モジュール変数 accept2dyear がゼロでない整数の場合、 2 桁の西暦年をサポートします。この変数の初期値は環境変数 PYTHONY2K が空文字列のとき 1 に設定されます。空文字列でない文字列が設定されている場合、 0 に設定されます。こうして、 PYTHONY2K を空文字列でない文字列に設定することで、西暦年の入力がすべて 4 桁の西暦年でなければならないようにすることができます。 2桁の西暦年が入力された場合には、POSIX または X/Open 標準に従って変換されます: 69-99 の西暦年は 1969-1999 となり、0–68 の西暦年は 2000–2068 になります。100-1899 は常に不正な値になります。この仕様は Python 1.5.2(a2) から新たに追加された機能であることに注意してください; それ以前のバージョン、すなわち Python 1.5.1 および 1.5.2a1 では、1900 以下の年に対して 1900 を足します。

UTC は協定世界時 (Coordinated Universal Time) のことです (以前はグリニッジ標準時 または GMTとして知られていました)。 UTC の頭文字の並びは誤りではなく、英仏の妥協によるものです。

DST は夏時間 (Daylight Saving Time) のことで、一年のうち部分的に 1 時間タイムゾーンを修正することです。DST のルールは不可思議で (局所的な法律で定められています)、年ごとに変わることもあります。 C ライブラリはローカルルールを記したテーブルを持っており (柔軟に対応するため、たいていはシステムファイルから読み込まれます)、この点に関しては唯一の真実の知識の源です。

多くの現時刻を返す関数 (real-time functions) の精度は、値や引数を表現するのに使う単位から想像されるよりも低いかも知れません。例えば、ほとんどの Unix システムで、クロックの一刹那 (ticks) の精度は 1 秒の 50 から 100 分の 1 に過ぎません。

反対に、 time() および sleep() は Unix の同等の関数よりましな精度を持っています: 時刻は浮動小数点で表され、 time() は可能なかぎり最も正確な時刻を (Unix の gettimeofday() があればそれを使って) 返します。また sleep() にはゼロでない端数を与えることができます (Unix の select() があれば、それを使って実装しています)。

gmtime(), localtime(), strptime() が返す時刻値、および asctime(), mktime(), strftime() に与える時刻値はどちらも 9 つの整数からなるシーケンスです。 gmtime(), localtime(), strptime() の戻り値は属性名でアクセスすることもできます。

これらのオブジェクトについての解説は struct_time を参照してください。

バージョン 2.2 で変更: 時刻値の配列はタプルから struct_time に変更され、それぞれのフィールドに属性名がつけられました。

時間の表現を変換するためには、以下の関数を利用してください。

From

To

Use

epochからの秒数

struct_time in UTC

gmtime()

epochからの秒数

struct_time in local time

localtime()

struct_time in UTC

epochからの秒数

calendar.timegm()

struct_time in local time

epochからの秒数

mktime()

このモジュールでは以下の関数とデータ型を定義します:

time.accept2dyear

2 桁の西暦年を使えるかを指定するブール型の値です。標準では真ですが、環境変数 PYTHONY2K が空文字列でない値に設定されている場合には偽になります。実行時に変更することもできます。

time.altzone

ローカルの夏時間タイムゾーンにおける UTC からの時刻オフセットで、西に行くほど増加する秒で表した値です (ほとんどの西ヨーロッパでは負になり、アメリカでは正、イギリスではゼロになります) 。 daylight がゼロでないときのみ使用してください。

time.asctime([t])

gmtime() や localtime() が返す時刻を表現するタプル又は struct_time を、 'Sun Jun 20 23:21:05 1993' といった書式の 24 文字の文字列に変換します。 t が与えられていない場合には、 localtime() が返す現在の時刻が使われます。 asctime() はロケール情報を使いません。

ノート

同名の C の関数と違って、末尾には改行文字はありません。

バージョン 2.1 で変更: tuple を省略できるようになりました。

time.clock()

Unixでは、現在のプロセッサ時間秒を浮動小数点数で返します。時刻の精度および “プロセッサ時間 (processor time)” の定義そのものは同じ名前の C 関数に依存します。いずれにせよ、この関数は Python のベンチマークや計時アルゴリズムに使われています。

Windows では、最初にこの関数が呼び出されてからの経過時間を wall-clock 秒で返します。この関数は Win32 関数 QueryPerformanceCounter() に基づいていて、その精度は通常 1 マイクロ秒以下です。

time.ctime([secs])

エポックからの経過秒数で表現された時刻を、ローカルの時刻を表現する文字列に変換します。 secs を指定しない、または None を指定した場合、 time() が返す値を現在の時刻として使います。 ctime(secs) は asctime(localtime(secs)) と同じです。 ctime() はロケール情報を使いません。

バージョン 2.1 で変更: secs を省略できるようになりました.

バージョン 2.4 で変更: secs が None の場合に現在時刻を使うようになりました.

time.daylight

DST タイムゾーンが定義されている場合ゼロでない値になります。

time.gmtime([secs])

エポックからの経過時間で表現された時刻を、UTC における struct_time に変換します。このとき dst フラグは常にゼロとして扱われます。 secs を指定しない、または None を指定した場合、 time() が返す値を現在の時刻として使います。秒の端数は無視されます。 struct_time のレイアウトについては上を参照してください。

バージョン 2.1 で変更: secs を省略できるようになりました.

バージョン 2.4 で変更: secs が None の場合に現在時刻を使うようになりました.

time.localtime([secs])

gmtime() に似ていますが、ローカルタイムに変換します。 secs を指定しない、または None を指定した場合、 time() が返す値を現在の時刻として使います。現在の時刻に DST が適用される場合、 dst フラグは 1 に設定されます。

バージョン 2.1 で変更: secs を省略できるようになりました。

バージョン 2.4 で変更: secs が None の場合に現在時刻を使うようになりました.

time.mktime(t)

localtime() の逆を行う関数です。引数は struct_time か完全な 9 つの要素全てに値の入ったタプル (dst フラグも必要です; 現在の時刻に DST が適用されるか不明の場合には -1 を使ってください) で、 UTC ではなく ローカルの時刻を指定します。 time() との互換性のために浮動小数点数の値を返します。入力の値が正しい時刻で表現できない場合、例外 OverflowError または ValueError が送出されます (どちらが送出されるかは Python およびその下にある C ライブラリのどちらにとって無効な値が入力されたかで決まります) 。この関数で生成できる最も昔の時刻値はプラットフォームに依存します。

time.sleep(secs)

与えられた秒数の間実行を停止します。より精度の高い実行停止時間を指定するために、引数は浮動小数点にしてもかまいません。何らかのシステムシグナルがキャッチされた場合、それに続いてシグナル処理ルーチンが実行され、 sleep() を停止してしまいます。従って実際の実行停止時間は要求した時間よりも短くなるかもしれません。また、システムが他の処理をスケジューリングするために、実行停止時間が要求した時間よりも多少長い時間になることもあります。

time.strftime(format[, t])

gmtime() や localtime() が返す時刻値タプル又は struct_time を、 format で指定した文字列形式に変換します。 t が与えられていない場合、 localtime() が返す現在の時刻が使われます。 format は文字列でなくてはなりません。 t のいずれかのフィールドが許容範囲外の数値であった場合、 ValueError を送出します。

バージョン 2.1 で変更: t を省略できるようになりました。

バージョン 2.4 で変更: t のフィールド値が許容範囲外の値の場合に ValueError を送出するようになりました.

バージョン 2.5 で変更: 0 は時刻値タプルのどこでも使用可能になりました。もし不正な値の場合には正常な値に修正されます。

format 文字列には以下の指示語 (directive) を埋め込むことができます。これらはフィールド長や精度のオプションを付けずに表され、 strftime() の結果の対応する文字列と入れ替えられます:

Directive | Meaning | Notes
%a | ロケールにおける省略形の曜日名。 |
%A | ロケールにおける省略なしの曜日名。 |
%b | ロケールにおける省略形の月名。 |
%B | ロケールにおける省略なしの月名。 |
%c | ロケールにおける適切な日付および時刻表現。 |
%d | 月の始めから何日目かを表す 10 進数 [01,31]。 |
%H | (24 時間計での) 時を表す 10 進数 [00,23]。 |
%I | (12 時間計での) 時を表す 10 進数 [01,12]。 |
%j | 年の初めから何日目かを表す 10 進数 [001,366]。 |
%m | 月を表す 10 進数 [01,12]。 |
%M | 分を表す 10 進数 [00,59]。 |
%p | ロケールにおける AM または PM に対応する文字列。 | (1)
%S | 秒を表す 10 進数 [00,61]。 | (2)
%U | 年の初めから何週目か (日曜を週の始まりとします)を表す 10 進数 [00,53]。年が明けてから最初の日曜日までの全ての曜日は 0 週目に属すると見なされます。 | (3)
%w | 曜日を表す 10 進数 [0(日曜日),6]。 |
%W | 年の初めから何週目か (日曜を週の始まりとします)を表す 10 進数 [00,53]。年が明けてから最初の月曜日までの全ての曜日は 0 週目に属すると見なされます。 | (3)
%x | ロケールにおける適切な日付の表現。 |
%X | ロケールにおける適切な時刻の表現。 |
%y | 上 2 桁なしの西暦年を表す 10 進数 [00,99]。 |
%Y | 上 2 桁付きの西暦年を表す 10 進数。 |
%Z | タイムゾーンの名前 (タイムゾーンがない場合には空文字列)。 |
%% | 文字 '%' 自体の表現。 |

注意:

strptime() 関数で使う場合、 %p ディレクティブが出力結果の時刻フィールドに影響を及ぼすのは、時刻を解釈するために %I を使ったときのみです。

値の幅は間違いなく 0 to 61 です; これはうるう秒と、（ごく稀ですが）2 重のうるう秒のためのものです。

strptime() 関数で使う場合、 %U および %W を計算に使うのは曜日と年を指定したときだけです。

以下に RFC 2822 [http://tools.ietf.org/html/rfc2822.html] インターネット電子メール標準で定義されている日付表現と互換の書式の例を示します。 [1]

>>> from time import gmtime, strftime
>>> strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
'Thu, 28 Jun 2001 14:17:15 +0000'

いくつかのプラットフォームではさらにいくつかの指示語がサポートされていますが、標準 ANSI C で意味のある値はここで列挙したものだけです。

いくつかのプラットフォームでは、フィールドの幅や精度を指定するオプションが以下のように指示語の先頭の文字 '%' の直後に付けられるようになっていました; この機能も移植性はありません。フィールドの幅は通常 2 ですが、 %j は例外で 3 です。

time.strptime(string[, format])

時刻を表現する文字列をフォーマットに従って解釈します。返される値は gmtime() や localtime() が返すような struct_time です。

format パラメタは strftime() で使うものと同じ指示語を使います; このパラメタの値はデフォルトでは "%a %b %d %H:%M:%S %Y" で、 ctime() が返すフォーマットに一致します。 string が format に従って解釈できなかった場合、例外 ValueError が送出されます。解析しようとする string が解析後に余分なデータを持っていた場合、 ValueError が送出されます。欠落したデータについて、適切な値を推測できない場合はデフォルトの値で埋められ、その値は (1900, 1, 1, 0, 0, 0, 0, 1, -1) です。

例:

>>> import time
>>> time.strptime("30 Nov 00", "%d %b %y")   # doctest: +NORMALIZE_WHITESPACE
time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0,
                 tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)

%Z 指示語へのサポートは tzname に収められている値と daylight が真かどうかで決められます。このため、常に既知の (かつ夏時間でないと考えられている) UTC や GMT を認識する時以外はプラットフォーム固有の動作になります。

ドキュメント内で説明されているディレクティブだけがサポートされています。 strftime() はプラットフォームによって実装されているので、説明されていないディレクティブも利用できるかもしれません。しかし、 strptime() はプラットフォーム非依存なので、サポートされているディレクティブ以外は利用できないかもしれません。

class time.struct_time

gmtime(), localtime() および strptime() が返す時刻値シーケンスのタイプです。これは名前付きタプル(named tuple)のインタフェースをもったオブジェクトです。値はインデックスでも属性名でもアクセス可能です。以下の値があります。

Index | Attribute | Values
0 | tm_year | (例えば 1993)
1 | tm_mon | [1,12] の間の数
2 | tm_mday | [1,31] の間の数
3 | tm_hour | [0,23] の間の数
4 | tm_min | [0,59] の間の数
5 | tm_sec | [0,61] の間の数 strftime() の説明にある (1) を読んで下さい
6 | tm_wday | [0,6] の間の数、月曜が 0 になります
7 | tm_yday | [1,366] の間の数
8 | tm_isdst | 0, 1 または -1; 以下を参照してください

バージョン 2.2 で追加.

C の構造体と違って、月の値が 0-11 でなく 1-12 であることに注意してください。西暦年の値は上の 2000年問題 (Y2K) で述べたように扱われます。夏時間フラグを -1 にして mktime() に渡すと、たいていは正確な夏時間の状態を実現します。

struct_time を引数とする関数に正しくない長さの struct_time や要素の型が正しくない struct_time を与えた場合には、 TypeError が送出されます。

time.time()

時刻を浮動小数点数で返します。単位は UTC におけるエポックからの秒数です。時刻は常に浮動小数点で返されますが、全てのシステムが 1 秒より高い精度で時刻を提供するとは限らないので注意してください。この関数が返す値は通常減少していくことはありませんが、この関数を 2 回呼び出し、呼び出しの間にシステムクロックの時刻を巻き戻して設定した場合には、以前の呼び出しよりも低い値が返ることもあります。

time.timezone

(DST でない) ローカルタイムゾーンの UTC からの時刻オフセットで、西に行くほど増加する秒で表した値です (ほとんどの西ヨーロッパでは負になり、アメリカでは正、イギリスではゼロになります) 。

time.tzname

二つの文字列からなるタプルです。最初の要素は DST でないローカルのタイムゾーン名です。ふたつめの要素は DST のタイムゾーンです。 DST のタイムゾーンが定義されていない場合。二つ目の文字列を使うべきではありません。

time.tzset()

ライブラリで使われている時刻変換規則をリセットします。どのように行われるかは、環境変数 TZ で指定されます。

バージョン 2.3 で追加.

利用できるシステム: Unix。

ノート

多くの場合、環境変数 TZ を変更すると、 tzset() を呼ばない限り localtime() のような関数の出力に影響を及ぼすため、値が信頼できなくなってしまいます。

TZ 環境変数には空白文字を含めてはなりません。

環境変数 TZ の標準的な書式は以下です (分かりやすいように空白を入れています):

std offset [dst [offset [,start[/time], end[/time]]]]

各値は以下のようになっています:

std と dst

三文字またはそれ以上の英数字で、タイムゾーンの略称を与えます。この値は time.tzname になります。

offset

オフセットは形式: ± hh[:mm[:ss]] をとります。この表現は、UTC 時刻にするためにローカルな時間に加算する必要のある時間値を示します。’-‘ が先頭につく場合、そのタイムゾーンは本子午線 (Prime Meridian) より東側にあります; それ以外の場合は本子午線の西側です。オフセットが dst の後ろに続かない場合、夏時間は標準時より一時間先行しているものと仮定します。

start[/time], end[/time]

いつ DST に移動し、DST から戻ってくるかを示します。開始および終了日時の形式は以下のいずれかです:

Jn

ユリウス日 (Julian day) n (1 <= n <= 365) を表します。うるう日は計算に含められないため、2 月 28 日は常に 59 で、 3 月 1 日は 60 になります。

n

ゼロから始まるユリウス日 (0 <= n <= 365) です。うるう日は計算に含められるため、2 月 29 日を参照することができます。

Mm.n.d

m 月の第 n 週における d 番目の日 (0 <= d <= 6, 1 <= n <= 5, 1 <= m <= 12) を表します。週 5 は月における最終週の d 番目の日を表し、第 4 週か第 5 週のどちらかになります。週 1 は日 d が最初に現れる日を指します。日 0 は日曜日です。

time は offset とほぼ同じで、先頭に符号 (‘-‘ や ‘+’) を付けてはいけないところだけが違います。時刻が指定されていなければ、デフォルトの値 02:00:00 になります。

>>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'02:07:36 05/08/03 EDT'
>>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'16:08:12 05/08/03 AEST'

多くの Unix システム (*BSD, Linux, Solaris, および Darwin を含む) では、システムの zoneinfo (tzfile(5)) データベースを使ったほうが、タイムゾーンごとの規則を指定する上で便利です。これを行うには、必要なタイムゾーンデータファイルへのパスをシステムの ‘zoneinfo’ タイムゾーンデータベースからの相対で表した値を環境変数 TZ に設定します。システムの ‘zoneinfo’ は通常 /usr/share/zoneinfo にあります。例えば、 'US/Eastern' 、 'Australia/Melbourne' 、 'Egypt' ないし 'Europe/Amsterdam' と指定します。

>>> os.environ['TZ'] = 'US/Eastern'
>>> time.tzset()
>>> time.tzname
('EST', 'EDT')
>>> os.environ['TZ'] = 'Egypt'
>>> time.tzset()
>>> time.tzname
('EET', 'EEST')

参考

Module datetime

日付と時刻に対する、よりオブジェクト指向のインタフェースです。

Module locale

国際化サービス。ロケールの設定は time モジュールのいくつかの関数が返す値に影響をおよぼすことがあります。

Module calendar

一般的なカレンダー関連の関数。 timegm() はこのモジュールの gmtime() の逆の操作を行います。

注記

[1]
現在では %Z の利用は推奨されていません。しかしここで実現したい時間及び分オフセットへの展開を行ってくれる %Z エスケープは全ての ANSI C ライブラリでサポートされているわけではありません。また、オリジナルの 1982 年に提出された RFC 822 [http://tools.ietf.org/html/rfc822.html] 標準は西暦年の表現を 2 桁と要求しています(%Y でなく%y )。しかし実際には 2000 年になるだいぶ以前から 4 桁の西暦年表現に移行しています。4 桁の西暦年表現は RFC 2822 [http://tools.ietf.org/html/rfc2822.html] において義務付けられ、伴って RFC 822 [http://tools.ietf.org/html/rfc822.html] での取り決めは撤廃されました。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー

バージョン 2.7 で追加.

argparse モジュールはユーザーフレンドリーなコマンドラインインタフェースの作成を簡単にします。プログラムがどんな引数を必要としているのかを定義すると、 argparse が sys.argv からそのオプションをパースする部分の面倒を見ます。 argparse モジュールは自動的にヘルプと使用方法メッセージを生成し、ユーザーが不正な引数をプログラムに指定したときにエラーを発生させます。

15.4.1. 例

次のコードは、整数のリストを受け取って合計か最大値を返す Python プログラムです:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                   const=sum, default=max,
                   help='sum the integers (default: find the max)')

args = parser.parse_args()
print args.accumulate(args.integers)

上の Python コードが prog.py という名前のファイルに保存されたと仮定します。コマンドラインから実行して、便利なヘルプメッセージを提供することができます。

$ prog.py -h
usage: prog.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
 N           an integer for the accumulator

optional arguments:
 -h, --help  show this help message and exit
 --sum       sum the integers (default: find the max)

妥当な引数を与えて実行された場合、このプログラムはコマンドライン引数の整数列の合計か最大値を表示します:

$ prog.py 1 2 3 4
4

$ prog.py 1 2 3 4 --sum
10

不正な引数が与えられた場合、エラーを発生させます:

$ prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

以降のセクションでは、この例をひと通り解説して行きます。

15.4.1.1. パーサーを作る

argparse を使う最初のステップは、 ArgumentParser オブジェクトを生成することです:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

ArgumentParser オブジェクトはコマンドラインを解析して Python データ型にするために必要な全ての情報を保持します。

15.4.1.2. 引数を追加する

ArgumentParser にプログラム引数の情報を与えるために、 add_argument() メソッドを呼び出します。一般的に、このメソッドの呼び出しは ArgumentParser に、コマンドラインの文字列を受け取ってそれをオブジェクトにする方法を教えます。この情報は保存され、 parse_args() が呼び出されたときに利用されます。例えば:

>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
...                     help='an integer for the accumulator')
>>> parser.add_argument('--sum', dest='accumulate', action='store_const',
...                     const=sum, default=max,
...                     help='sum the integers (default: find the max)')

あとで、 parse_args() を呼び出すと、 integers と accumulate という2つの属性を持ったオブジェクトを返します。 integers 属性は1つ以上の整数のリストで、 accumulate 属性はコマンドラインから --sum が指定された場合は sum() 関数、それ以外の場合は max() 関数になります。

15.4.1.3. 引数をパースする

ArgumentParser は引数を parse_args() メソッドでパースします。このメソッドはコマンドラインを調べ、各引数を正しい型に変換して、適切なアクションを実行します。ほとんどの場合、これはシンプルな namespace オブジェクトをコマンドラインの解析結果から構築することを意味します:

>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])

スクリプトでは、 parse_args() は典型的には引数なしで呼び出され、 ArgumentParser は自動的に sys.argv からコマンドライン引数を取得します。

15.4.2. ArgumentParser オブジェクト

class argparse.ArgumentParser([description][, epilog][, prog][, usage][, add_help][, argument_default][, parents][, prefix_chars][, conflict_handler][, formatter_class])

新しい ArgumentParser オブジェクトを生成します。各引数についてはあとで詳しく説明しますが、簡単に言うと:

description - 引数のヘルプの前に表示されるテキスト

epilog - 引数のヘルプの後で表示されるテキスト

add_help - -h/–help オプションをパーサーに追加する (デフォルト: True)

argument_default - 引数にグローバルのデフォルト値を設定する (デフォルト: None)

parents - ArgumentParser オブジェクトのリストで、このオブジェクトの引数が追加される

prefix_chars - オプションの引数の prefix になる文字集合 (デフォルト: ‘-‘)

fromfile_prefix_chars - 追加の引数を読み込むファイルの prefix になる文字集合 (デフォルト: None)

formatter_class - ヘルプ出力をカスタマイズするためのクラス

conflict_handler - 衝突するオプションを解決する方法を定義する。通常は利用する必要はありません。

prog - プログラム名 (デフォルト: sys.argv[0])

usage - プログラムの利用方法を解説する文字列 (デフォルト: 生成される)

以下のセクションでは各オプションの利用方法を解説します。

15.4.2.1. description

多くの場合、 ArgumentParser のコンストラクタを呼び出すときに description= キーワード引数が利用されます。この引数はプログラムが何をしてどう動くのかについての短い説明です。ヘルプメッセージで、この description はコマンドラインの利用法と引数のヘルプメッセージの間に表示されます:

>>> parser = argparse.ArgumentParser(description='A foo that bars')
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

optional arguments:
 -h, --help  show this help message and exit

デフォルトでは、 description は行ラップされるので、与えられたスペースにマッチします。この挙動を変更するには、 formatter_class 引数を参照してください。

15.4.2.2. epilog

いくつかのプログラムは、プログラムについての追加の説明を引数の解説の後に表示します。このテキストは ArgumentParser の epilog= 引数に指定することができます:

>>> parser = argparse.ArgumentParser(
...     description='A foo that bars',
...     epilog="And that's how you'd foo a bar")
>>> parser.print_help()
usage: argparse.py [-h]

A foo that bars

optional arguments:
 -h, --help  show this help message and exit

And that's how you'd foo a bar

description 引数と同じく、 epilog= テキストもデフォルトで行ラップされ、 ArgumentParser の formatter_class 引数で動作を調整することができます。

15.4.2.3. add_help

デフォルトでは、 ArgumentParser オブジェクトはシンプルにパーサーのヘルプメッセージを表示するオプションを自動的に追加します。例えば、以下のコードを含む myprogram.py ファイルについて考えてください:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

コマンドラインに -h か --help が指定された場合、 ArgumentParser の help が表示されます:

$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help

必要に応じて、この help オプションを無効にする場合があります。これは ArgumentParser の add_help= 引数に False を渡すことで可能です:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
>>> parser.print_help()
usage: PROG [--foo FOO]

optional arguments:
 --foo FOO  foo help

ヘルプオプションは通常 -h/--help です。例外は prefix_chars= が指定されてその中に '-' が無かった場合で、その場合は -h と --help は有効なオプションではありません。この場合、 prefix_chars の最初の文字がヘルプオプションの prefix として利用されます:

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
>>> parser.print_help()
usage: PROG [+h]

optional arguments:
  +h, ++help  show this help message and exit

15.4.2.4. prefix_chars

ほとんどのコマンドラインオプションは、 -f/--foo のように prefix に '-' を使います。 +f や /foo のような、他の、あるいは追加の prefix 文字をサポートしなければならない場合、 ArgumentParser のコンストラクタの prefix_chars= 引数を指定します:

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
>>> parser.add_argument('+f')
>>> parser.add_argument('++bar')
>>> parser.parse_args('+f X ++bar Y'.split())
Namespace(bar='Y', f='X')

prefix_chars= 引数のデフォルトは '-' です。 '-' を含まない文字集合を指定すると、 -f/--foo オプションが許可されなくなります。

15.4.2.5. fromfile_prefix_chars

ときどき、例えば非常に長い引数リストを扱う場合に、その引数リストを毎回コマンドラインにタイプする代わりにファイルに置いておきたい場合があります。 ArgumentParser のコンストラクタに fromfile_prefix_chars= 引数が指定された場合、指定された文字のいずれかで始まる引数はファイルとして扱われ、そのファイルに含まれる引数リストに置換されます。例えば:

>>> with open('args.txt', 'w') as fp:
...    fp.write('-f\nbar')
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')

ファイルから読み込まれる引数は、デフォルトでは1行に1つ(ただし、 convert_arg_line_to_args() も参照してください)で、コマンドライン上でファイルを参照する引数があった場所にその引数があったものとして扱われます。なので、上の例では、 ['-f', 'foo', '@args.txt'] は ['-f', 'foo', '-f', 'bar'] と等価になります。

fromfile_prefix_chars= 引数のデフォルト値は None で、引数がファイル参照だとして扱われることが無いことを意味しています。

15.4.2.6. argument_default

一般的には、引数のデフォルト値は add_argument() メソッドにデフォルト値を渡すか、 set_defaults() メソッドに name-value ペアを渡すことで指定します。しかしまれに、1つのパーサー全体に適用されるデフォルト引数が便利なことがあります。これをするには、 ArgumentParser に argument_default= キーワード引数を渡します。例えば、全体で parse_args() メソッド呼び出しの属性の生成を抑制するには、 argument_default=SUPPRESS を指定します:

>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar', nargs='?')
>>> parser.parse_args(['--foo', '1', 'BAR'])
Namespace(bar='BAR', foo='1')
>>> parser.parse_args([])
Namespace()

15.4.2.7. parents

ときどき、いくつかのパーサーが共通の引数セットを共有することがあります。それらの引数を繰り返し定義する代わりに、全ての共通引数を持った parser を ArgumentParser の parents= 引数に渡すことができます。 parents= 引数は ArgumentParser オブジェクトのリストを受け取り、全ての位置アクションとオプションのアクションをそれらから集め、そのアクションを構築中の ArgumentParser オブジェクトに追加します:

>>> parent_parser = argparse.ArgumentParser(add_help=False)
>>> parent_parser.add_argument('--parent', type=int)

>>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> foo_parser.add_argument('foo')
>>> foo_parser.parse_args(['--parent', '2', 'XXX'])
Namespace(foo='XXX', parent=2)

>>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> bar_parser.add_argument('--bar')
>>> bar_parser.parse_args(['--bar', 'YYY'])
Namespace(bar='YYY', parent=None)

一番親になるパーサーに add_help=False を指定していることに注目してください。こうしないと、 ArgumentParser は2つの -h/--help オプションを与えられる (1つは親から、もうひとつは子から) ことになり、エラーを発生させます。

ノート

parents= に渡す前にパーサーを完全に初期化する必要があります。子パーサーを作成してから親パーサーを変更した場合、その変更は子パーサーに反映されません。

15.4.2.8. formatter_class

ArgumentParser オブジェクトは代わりのフォーマットクラスを指定することでヘルプのフォーマットをカスタマイズすることができます。現在、3つのフォーマットクラスがあります:

class argparse.RawDescriptionHelpFormatter

class argparse.RawTextHelpFormatter

class argparse.ArgumentDefaultsHelpFormatter

最初の2つは説明のテキストがどう表示されるかについてより制御できるようになっており、残りの1つは引数のデフォルト値についての情報を自動的に追加します。

デフォルトでは、 ArgumentParser オブジェクトはコマンドラインのヘルプメッセージ中で description と epilog を行ラップします:

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     description='''this description
...         was indented weird
...             but that is okay''',
...     epilog='''
...             likewise for this epilog whose whitespace will
...         be cleaned up and whose words will be wrapped
...         across a couple lines''')
>>> parser.print_help()
usage: PROG [-h]

this description was indented weird but that is okay

optional arguments:
 -h, --help  show this help message and exit

likewise for this epilog whose whitespace will be cleaned up and whose words
will be wrapped across a couple lines

formatter_class= に RawDescriptionHelpFormatter を渡すと、 description と epilog がすでに正しくフォーマット済みで、行ラップしてはいけないことを指定できます:

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.RawDescriptionHelpFormatter,
...     description=textwrap.dedent('''\
...         Please do not mess up this text!
...         --------------------------------
...             I have indented it
...             exactly the way
...             I want it
...         '''))
>>> parser.print_help()
usage: PROG [-h]

Please do not mess up this text!
--------------------------------
   I have indented it
   exactly the way
   I want it

optional arguments:
 -h, --help  show this help message and exit

RawTextHelpFormatter は引数の説明を含めて全ての種類のヘルプテキストで空白を維持します。

残りの利用できるフォーマットクラスである ArgumentDefaultsHelpFormatter は、各引数のデフォルト値に関する情報を追加します:

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
>>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
>>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
>>> parser.print_help()
usage: PROG [-h] [--foo FOO] [bar [bar ...]]

positional arguments:
 bar         BAR! (default: [1, 2, 3])

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   FOO! (default: 42)

15.4.2.9. conflict_handler

ArgumentParser オブジェクトは同じオプション文字列に対して複数のアクションを許可していません。デフォルトでは、 ArgumentParser オブジェクトは、すでに利用されているオプション文字列を使って新しい引数をつくろうとしたときに例外を発生させます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
Traceback (most recent call last):
 ..
ArgumentError: argument --foo: conflicting option string(s): --foo

ときどき (例えば、 parents を利用する場合など), 古い引数を同じオプション文字列で上書きするほうが便利な場合があります。この動作をするには、 ArgumentParser の conflict_handler= 引数に 'resolve' を渡します:

>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
>>> parser.add_argument('-f', '--foo', help='old foo help')
>>> parser.add_argument('--foo', help='new foo help')
>>> parser.print_help()
usage: PROG [-h] [-f FOO] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 -f FOO      old foo help
 --foo FOO   new foo help

ArgumentParser オブジェクトは、全てのオプション文字列がオーバーライドサれた場合にだけアクションを削除することに注目してください。上の例では、 --foo オプション文字列だけがオーバーライドされているので、古い -f/--foo アクションは -f アクションとして残っています。

15.4.2.10. prog

デフォルトでは、 ArgumentParser オブジェクトはヘルプメッセージ中に表示するプログラム名を sys.argv[0] から取得します。このデフォルトの動作は、プログラムがコマンドライン上でどう起動されたにヘルプメッセージをマッチさせるので、か多くの場合に正しい挙動です。例えば、 myprogram.py という名前のファイルに次のコードがあるとします:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help')
args = parser.parse_args()

このプログラムのヘルプは、プログラム名として (プログラムがどこから起動されたのかに関わらず) myprogram.py を表示します:

$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help
$ cd ..
$ python subdir\myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help

このデフォルトの動作を変更するには、 ArgumentParser の prog= 引数に他の値を指定します:

>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.print_help()
usage: myprogram [-h]

optional arguments:
 -h, --help  show this help message and exit

プログラム名は、 sys.argv[0] から取られた場合でも prog= 引数で与えられた場合でも、ヘルプメッセージ中では %(prog)s フォーマット指定で利用することができます。

>>> parser = argparse.ArgumentParser(prog='myprogram')
>>> parser.add_argument('--foo', help='foo of the %(prog)s program')
>>> parser.print_help()
usage: myprogram [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo of the myprogram program

15.4.2.11. usage

デフォルトでは、 ArgumentParser は使用法メッセージを、もっている引数から生成します:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [-h] [--foo [FOO]] bar [bar ...]

positional arguments:
 bar          bar help

optional arguments:
 -h, --help   show this help message and exit
 --foo [FOO]  foo help

デフォルトのメッセージは usage= キーワード引数でオーバーライドできます:

>>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
>>> parser.add_argument('--foo', nargs='?', help='foo help')
>>> parser.add_argument('bar', nargs='+', help='bar help')
>>> parser.print_help()
usage: PROG [options]

positional arguments:
 bar          bar help

optional arguments:
 -h, --help   show this help message and exit
 --foo [FOO]  foo help

%(prog)s フォーマット指定子を、使用法メッセージ中でプログラム名として利用できます。

15.4.3. add_argument() メソッド

ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

1つのコマンドライン引数がどう解析されるかを定義します。各引数についての解説は以下で行いますが、簡潔には:

name or flags - 名前か、オプション文字列のリスト (例: foo か -f, --foo)

action - コマンドラインにこの引数があった時のアクション

nargs - 消費するべきコマンドライン引数の数

const - いくつかの action と nargs の組み合わせで利用される定数

default - コマンドラインに引数がなかった場合に生成される値

type - コマンドライン引数が変換されるべき型

choices - 引数として許される値のコンテナ

required - コマンドラインオプションが省略可能かどうか(オプション引数のみ)

help - 引数が何なのかを示す簡潔な説明

metavar - 使用法メッセージの中で使われる引数の名前

dest - parse_args() が返すオブジェクトに追加される属性名

以下のセクションではこれらの使い方を説明します。

15.4.3.1. name or flags

add_argument() メソッドは、指定されているのが -f や --foo のようなオプション引数なのか、ファイル名リストなどの位置引数なのかを知る必要があります。そのため、 add_argument() の第1引数は、フラグのリストか、シンプルな引数名のどちらかになります。例えば、オプション引数は次のようにして作ります:

>>> parser.add_argument('-f', '--foo')

一方、位置引数は次のようにして作ります:

>>> parser.add_argument('bar')

parse_args() が呼ばれた時、オプション引数は - prefix により識別され、それ以外の引数は位置引数として扱われます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args(['BAR'])
Namespace(bar='BAR', foo=None)
>>> parser.parse_args(['BAR', '--foo', 'FOO'])
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
PROG: error: too few arguments

15.4.3.2. action

ArgumentParser オブジェクトはコマンドライン引数にアクションを割り当てます。このアクションは、割り当てられたコマンドライン引数に関してどんな処理でもできますが、ほとんどのアクションは単に parse_args() が返すオブジェクトに属性を追加するだけです。 action キーワード引数は、コマンドライン引数がどう処理されるかを指定します。サポートされているアクションは:

'store' - これは単に引数の値を格納します。これはデフォルトのアクションです。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')

'store_const' - このアクションは const キーワード引数で指定された値を格納します。 (const キーワード引数のデフォルト値はあまり役に立たない None であることに注意) 'store_const' アクションは、何かの種類のフラグを指定するオプション引数によく使われます。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args('--foo'.split())
Namespace(foo=42)

'store_true', 'store_false' - これらのアクションはそれぞれ True と False を格納します。これらは 'store_const' の特別版になります。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(bar=False, foo=True)

'append' - このアクションはリストを格納して、各引数の値をそのリストに追加します。このアクションは複数回指定することができるオプションに便利です。利用例:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])

'append_const' - このアクションはリストを格納して、 const キーワード引数に与えられた値をそのリストに追加します。(const キーワード引数のデフォルト値はあまり役に立たない None であることに注意) 'append_const' アクションは、定数を同じリストに複数回格納する場合に便利です。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<type 'str'>, <type 'int'>])

'version' - このアクションは add_argument() の呼び出しに version= キーワード引数を期待します。指定されたときはバージョン情報を表示して終了します。

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0

Action API を実装したオブジェクトを渡すことで、任意のアクションを指定することもできます。独自のアクションを作る一番手軽な方法は argparse.Action を継承して、適切な __call__ メソッドを実装することです。 __call__ メソッドは 4つの引数を受け取らなければなりません:

parser - このアクションを持っている ArgumentParser オブジェクト

namespace - parse_args() が返す namespace オブジェクト。ほとんどのアクションはこのオブジェクトに属性を追加します。

values - 型変換が適用された後の、関連付けられたコマンドライン引数。 (型変換は add_argument() メソッドの type キーワード引数で指定されます)

option_string - このアクションを実行したオプション文字列。 option_string 引数はオプションで、アクションが位置引数に関連付けられた場合は渡されません。

カスタムアクションの例です:

>>> class FooAction(argparse.Action):
...     def __call__(self, parser, namespace, values, option_string=None):
...         print '%r %r %r' % (namespace, values, option_string)
...         setattr(namespace, self.dest, values)
...
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action=FooAction)
>>> parser.add_argument('bar', action=FooAction)
>>> args = parser.parse_args('1 --foo 2'.split())
Namespace(bar=None, foo=None) '1' None
Namespace(bar='1', foo=None) '2' '--foo'
>>> args
Namespace(bar='1', foo='2')

15.4.3.3. nargs

ArgumentParser オブジェクトは通常1つのコマンドライン引数を1つのアクションに渡します。 nargs キーワード引数は1つのアクションにそれ以外の数のコマンドライン引数を割り当てます。指定できる値は:

N (整数). N 個の引数がコマンドラインから集められ、リストに格納されます。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
>>> parser.add_argument('bar', nargs=1)
>>> parser.parse_args('c --foo a b'.split())
Namespace(bar=['c'], foo=['a', 'b'])

nargs=1 は1要素のリストを作ることに注意してください。これはデフォルトの、要素がそのまま属性になる動作とは異なります。

'?'. 可能なら1つの引数がコマンドラインから取られ、1つのアイテムを作ります。コマンドライン引数が存在しない場合、 default の値が生成されます。オプション引数の場合、さらにオプション引数がしていされ、その後にコマンドライン引数が無いというケースもありえます。この場合は const の値が生成されます。この動作の例です:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
>>> parser.add_argument('bar', nargs='?', default='d')
>>> parser.parse_args('XX --foo YY'.split())
Namespace(bar='XX', foo='YY')
>>> parser.parse_args('XX --foo'.split())
Namespace(bar='XX', foo='c')
>>> parser.parse_args(''.split())
Namespace(bar='d', foo='d')

nargs='?' のよくある利用例の1つは、入出力ファイルの指定オプションです:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
...                     default=sys.stdin)
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
...                     default=sys.stdout)
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>,
          outfile=<open file 'output.txt', mode 'w' at 0x...>)
>>> parser.parse_args([])
Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>,
          outfile=<open file '<stdout>', mode 'w' at 0x...>)

'*'. 全てのコマンドライン引数がリストに集められます。複数の位置引数が nargs='*' を持つことにあまり意味はありませんが、複数のオプション引数が nargs='*' を持つことはありえます。例えば:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
>>> parser.add_argument('--bar', nargs='*')
>>> parser.add_argument('baz', nargs='*')
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])

'+'. '*' と同じように、全てのコマンドライン引数をリストに集めます。加えて、最低でも1つのコマンドライン引数が存在しない場合にエラーメッセージを生成します。例えば:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
>>> parser.parse_args('a b'.split())
Namespace(foo=['a', 'b'])
>>> parser.parse_args(''.split())
usage: PROG [-h] foo [foo ...]
PROG: error: too few arguments

nargs キーワード引数が指定されない場合、消費される引数の数は action によって決定されます。通常これは、1つのコマンドライン引数は1つのアイテムになる(リストにはならない)ことを意味します。

15.4.3.4. const

add_argument() の const 引数は、コマンドライン引数から読み込まれないけれども ArgumentParser のいくつかのアクションで必要とされる値のために使われます。この引数の2つのよくあるユースケースは:

add_argument() が action='store_const' か action='append_const' で呼び出された時、これらのアクションは const の値を parse_args() が返すオブジェクトの属性に追加します。サンプルは action の解説を参照してください。

add_argument() がオプション文字列 (-f や --foo) と nargs='?' で呼び出された場合。この場合0個か1つのコマンドライン引数を取るオプション引数が作られます。オプション引数にコマンドライン引数が続かなかった場合、 const の値が代わりに利用されます。サンプルは nargs の解説を参照してください。

const キーワード引数のデフォルト値は None です。

15.4.3.5. default

全てのオプション引数といくつかの位置引数はコマンドライン上で省略されることがあります。 add_argument() の default キーワード引数(デフォルト: None)は、コマンドライン引数が存在しなかった場合に利用する値を指定します。オプション引数では、オプション文字列がコマンドライン上に存在しなかったときに default の値が利用されます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args('--foo 2'.split())
Namespace(foo='2')
>>> parser.parse_args(''.split())
Namespace(foo=42)

位置引数では、 nargs ='?' か '*' で、コマンドライン引数が存在しなかったときに default 値が利用されます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args('a'.split())
Namespace(foo='a')
>>> parser.parse_args(''.split())
Namespace(foo=42)

default=argparse.SUPPRESS を渡すと、コマンドライン引数が存在しないときに属性の追加をしなくなります:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')

15.4.3.6. type

デフォルトでは、 ArgumentParser オブジェクトはコマンドライン引数を単なる文字列として読み込みます。しかし、コマンドラインの文字列は float, int, file など別の型として扱うべき事がよくあります。 add_argument() の type キーワード引数により型チェックと型変換を行うことができます。たくさんのよく使われるビルトイン型を type 引数の値として直接指定することができます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.add_argument('bar', type=file)
>>> parser.parse_args('2 temp.txt'.split())
Namespace(bar=<open file 'temp.txt', mode 'r' at 0x...>, foo=2)

いろいろな種類のファイルを簡単に扱うために、 argparse モジュールは mode= と bufsize= 引数を取る FileType ファクトリを提供しています。例えば、書き込み可能なファイルを作るために FileType('w') を利用できます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
Namespace(bar=<open file 'out.txt', mode 'w' at 0x...>)

type= には1つの文字列を引数に受け取って型変換結果を返すような任意の callable を渡すことができます:

>>> def perfect_square(string):
...     value = int(string)
...     sqrt = math.sqrt(value)
...     if sqrt != int(sqrt):
...         msg = "%r is not a perfect square" % string
...         raise argparse.ArgumentTypeError(msg)
...     return value
...
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=perfect_square)
>>> parser.parse_args('9'.split())
Namespace(foo=9)
>>> parser.parse_args('7'.split())
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square

さらに、 choices キーワード引数を使って、値の範囲をチェックすることもできます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=int, choices=xrange(5, 10))
>>> parser.parse_args('7'.split())
Namespace(foo=7)
>>> parser.parse_args('11'.split())
usage: PROG [-h] {5,6,7,8,9}
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)

詳細は choices セクションを参照してください。

15.4.3.7. choices

コマンドライン引数をいくつかの選択肢のなかから選ばせたい場合があります。これは add_argument() に choices キーワード引数を渡すことで可能です。コマンドラインを解析する時、引数の値がチェックされ、その値が選択肢の中に含まれていない場合はエラーメッセージを表示します:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', choices='abc')
>>> parser.parse_args('c'.split())
Namespace(foo='c')
>>> parser.parse_args('X'.split())
usage: PROG [-h] {a,b,c}
PROG: error: argument foo: invalid choice: 'X' (choose from 'a', 'b', 'c')

choices コンテナに含まれているかどうかのチェックは、 type による型変換が実行された後であることに注意してください。なので、 choices に格納するオブジェクトの型は指定された type にマッチしている必要があります:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=complex, choices=[1, 1j])
>>> parser.parse_args('1j'.split())
Namespace(foo=1j)
>>> parser.parse_args('-- -4'.split())
usage: PROG [-h] {1,1j}
PROG: error: argument foo: invalid choice: (-4+0j) (choose from 1, 1j)

in 演算をサポートしている任意のオブジェクトを choices に渡すことができます。なので、 dict, set, その他カスタムコンテナなどは全てサポートしています。

15.4.3.8. required

通常、 argparse モジュールは -f や --bar といったフラグはオプション(optional) 引数だと仮定し、コマンドライン上になくても良いものとして扱います。オプションを 要求(required) するには、 add_argument() の required= キーワード引数に True を指定します:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: argparse.py [-h] [--foo FOO]
argparse.py: error: option --foo is required

上の例のように、オプションが required と指定されると、 parse_args() はそのオプションがコマンドラインに存在しないときにエラーを表示します。

ノート

ユーザーは option は 自由に選択できる(optional) だと期待するので、 required option は一般的には悪いもので、できる限り避けるべきです。

15.4.3.9. help

help の値はその引数の簡潔な説明を含む文字列です。ユーザーが(コマンドライン上で -h か --help を指定するなどして) ヘルプを要求したとき、この help の説明が各引数に表示されます:

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true',
...         help='foo the bars before frobbling')
>>> parser.add_argument('bar', nargs='+',
...         help='one of the bars to be frobbled')
>>> parser.parse_args('-h'.split())
usage: frobble [-h] [--foo] bar [bar ...]

positional arguments:
 bar     one of the bars to be frobbled

optional arguments:
 -h, --help  show this help message and exit
 --foo   foo the bars before frobbling

help 文字列には、プログラム名や引数の default などを繰り返し記述するのを避けるためのフォーマット指定子を含めることができます。利用できる指定子には、プログラム名 %(prog)s と、 %(default)s や %(type)s など add_argument() のキーワード引数の多くが含まれます:

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42,
...         help='the bar to %(prog)s (default: %(default)s)')
>>> parser.print_help()
usage: frobble [-h] [bar]

positional arguments:
 bar     the bar to frobble (default: 42)

optional arguments:
 -h, --help  show this help message and exit

15.4.3.10. metavar

ArgumentParser がヘルプメッセージを出力する時、各引数に対してなんらかの参照方法が必要です。デフォルトでは、 ArgumentParser オブジェクトは各オブジェクトの “名前” として dest を利用します。デフォルトでは、位置引数には dest の値をそのまま利用し、オプション引数については dest の値を大文字に変換して利用します。なので、1つの dest='bar' である位置引数は bar として参照されます。 1つのオプション引数 --foo が1つのコマンドライン引数を要求するときは、その引数は FOO として参照されます。例です:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo FOO] bar

positional arguments:
 bar

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO

代わりの名前を、 metavar として指定できます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo YYY] XXX

positional arguments:
 XXX

optional arguments:
 -h, --help  show this help message and exit
 --foo YYY

metavar は 表示される 名前だけを変更することに注意してください。 parse_args() の返すオブジェクトの属性名は dest の値のままです。

nargs を指定した場合、 metavar が複数回利用されるかもしれません。 metavar にタプルを渡すと、各引数に対して異なる名前を指定できます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', nargs=2)
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> parser.print_help()
usage: PROG [-h] [-x X X] [--foo bar baz]

optional arguments:
 -h, --help     show this help message and exit
 -x X X
 --foo bar baz

15.4.3.11. dest

ほとんどの ArgumentParser のアクションは parse_args() が返すオブジェクトに対する属性として値を追加します。この属性の名前は add_argument() の dest キーワード引数によって決定されます。位置引数のアクションについては、 dest は通常 add_argument() の第一引数として渡します:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args('XXX'.split())
Namespace(bar='XXX')

オプション引数のアクションについては、 dest の値は通常オプション文字列から生成されます。 ArgumentParser は最初の長いオプション文字列を選択し、先頭の '--' を除去することで dest の値を生成します。長いオプション文字列が指定されていない場合、最初の短いオプション文字列から先頭の '-' 文字を除去することで dest を生成します。先頭以外の全ての '-' 文字は、妥当な属性名になるように '_' 文字へ変換されます。次の例はこの動作を示しています:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')

dest にカスタムの属性名を与えることも可能です:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

15.4.4. parse_args() メソッド

ArgumentParser.parse_args(args=None, namespace=None)

引数の文字列をオブジェクトに変換し、 namespace オブジェクトの属性に代入します。結果の namespace オブジェクトを返します。

事前の add_argument() メソッドの呼び出しが、どのオブジェクトが生成されてどう代入されるかを決定します。詳細は add_argument() のドキュメントを参照してください。

デフォルトでは、引数文字列は sys.argv から取られ、新しい空の Namespace オブジェクトが属性のために作られます。

15.4.4.1. オプション値の文法

parse_args() メソッドはオプションの値(があれば) を指定する複数の方法をサポートしています。一番シンプルな方法は、オプションとその値は2つの別々の引数として渡されます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('--foo')
>>> parser.parse_args('-x X'.split())
Namespace(foo=None, x='X')
>>> parser.parse_args('--foo FOO'.split())
Namespace(foo='FOO', x=None)

長いオプション (1文字よりも長い名前を持ったオプション) では、オプションとその値は = で区切られた1つのコマンドライン引数として渡すこともできます:

>>> parser.parse_args('--foo=FOO'.split())
Namespace(foo='FOO', x=None)

短いオプション (1文字のオプション) では、オプションとその値は連結して渡すことができます:

>>> parser.parse_args('-xX'.split())
Namespace(foo=None, x='X')

複数の短いオプションは、最後の1つ(か、0個)のオプションだけが値を要求する場合には、1つの - prefix だけで連結することができます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', action='store_true')
>>> parser.add_argument('-y', action='store_true')
>>> parser.add_argument('-z')
>>> parser.parse_args('-xyzZ'.split())
Namespace(x=True, y=True, z='Z')

15.4.4.2. 不正な引数

parse_args() は、コマンドラインの解析中に、曖昧なオプション、不正な型、不正なオプション、位置引数の数の不一致などのエラーを検証します。それらのエラーが発生した場合、エラーメッセージと使用法メッセージを表示して終了します:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', nargs='?')

>>> # invalid type
>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'

>>> # invalid option
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: no such option: --bar

>>> # wrong number of arguments
>>> parser.parse_args(['spam', 'badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: extra arguments found: badger

15.4.4.3. "-" を含む引数

parse_args() メソッドは、ユーザーが明らかなミスをした場合はエラーを表示しますが、いくつか本質的に曖昧な場面があります。例えば、コマンドライン引数 '-1' は、オプションの指定かもしれませんし位置引数かもしれません。 parse_args() メソッドはこれを次のように扱います: 負の数として解釈でき、パーサーに負の数のように解釈できるオプションが存在しない場合にのみ、 '-' で始まる位置引数になりえます:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
>>> parser.add_argument('foo', nargs='?')

>>> # no negative number options, so -1 is a positional argument
>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')

>>> # no negative number options, so -1 and -5 are positional arguments
>>> parser.parse_args(['-x', '-1', '-5'])
Namespace(foo='-5', x='-1')

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-1', dest='one')
>>> parser.add_argument('foo', nargs='?')

>>> # negative number options present, so -1 is an option
>>> parser.parse_args(['-1', 'X'])
Namespace(foo=None, one='X')

>>> # negative number options present, so -2 is an option
>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: no such option: -2

>>> # negative number options present, so both -1s are options
>>> parser.parse_args(['-1', '-1'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: argument -1: expected one argument

'-' で始まる位置引数があって、それが負の数として解釈できない場合、ダミーの引数 '--' を挿入して、 parse_args() にそれ以降の全てが位置引数だと教えることができます:

>>> parser.parse_args(['--', '-f'])
Namespace(foo='-f', one=None)

15.4.4.4. 引数の短縮形

parse_args() メソッドは、長いオプションを、曖昧さが無い範囲で短縮することを許可しています:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
>>> parser.add_argument('-badger')
>>> parser.parse_args('-bac MMM'.split())
Namespace(bacon='MMM', badger=None)
>>> parser.parse_args('-bad WOOD'.split())
Namespace(bacon=None, badger='WOOD')
>>> parser.parse_args('-ba BA'.split())
usage: PROG [-h] [-bacon BACON] [-badger BADGER]
PROG: error: ambiguous option: -ba could match -badger, -bacon

引数が複数のオプションになり得る場合はエラーになります。

15.4.4.5. sys.argv 以外

ArgumentParser が sys.argv 以外の引数をパースできると役に立つ場合があります。その場合は文字列のリストを parse_args() に渡します。これはインタラクティブプロンプトからテストするときに便利です:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...     'integers', metavar='int', type=int, choices=xrange(10),
...  nargs='+', help='an integer in the range 0..9')
>>> parser.add_argument(
...     '--sum', dest='accumulate', action='store_const', const=sum,
...   default=max, help='sum the integers (default: find the max)')
>>> parser.parse_args(['1', '2', '3', '4'])
Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
>>> parser.parse_args('1 2 3 4 --sum'.split())
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

15.4.4.6. Namespace オブジェクト

デフォルトでは、 parse_args() は Namespace の新しいオブジェクトに必要な属性を設定して返します。このクラスはシンプルに設計されており、単に読みやすい文字列表現を持った object のサブクラスです。もし属性を辞書のように扱える方が良ければ、 vars() を使う標準的な Python のイディオムを利用することができます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

ArgumentParser が、新しい Namespace オブジェクトではなく、既存のオブジェクトに属性を設定する方が良い場合があります。これは namespace= キーワード引数を指定することで可能です:

>>> class C(object):
...     pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'

15.4.5. その他のユーティリティ

15.4.5.1. サブコマンド

ArgumentParser.add_subparsers()

多くのプログラムは、その機能をサブコマンドへと分割します。例えば svn プログラムは svn checkout, svn update, svn commit などのサブコマンドを利用できます。機能をサブコマンドに分割するのは、プログラムがいくつかの異なった機能を持っていて、それぞれが異なるコマンドライン引数を必要とする場合には良いアイデアです。 ArgumentParser は add_subparsers() メソッドによりサブコマンドをサポートしています。 add_subparsers() メソッドは通常引数なしに呼び出され、特殊なアクションオブジェクトを返します。このオブジェクトには1つのメソッド add_parser() があり、コマンド名と ArgumentParser コンストラクタの任意の引数を受け取り、通常の方法で操作できる ArgumentParser オブジェクトを返します。

いくつかの使用例:

>>> # create the top-level parser
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', action='store_true', help='foo help')
>>> subparsers = parser.add_subparsers(help='sub-command help')
>>>
>>> # create the parser for the "a" command
>>> parser_a = subparsers.add_parser('a', help='a help')
>>> parser_a.add_argument('bar', type=int, help='bar help')
>>>
>>> # create the parser for the "b" command
>>> parser_b = subparsers.add_parser('b', help='b help')
>>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
>>>
>>> # parse some arg lists
>>> parser.parse_args(['a', '12'])
Namespace(bar=12, foo=False)
>>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
Namespace(baz='Z', foo=True)

parse_args() が返すオブジェクトにはメインパーサーとコマンドラインで選択されたサブパーサーによる属性だけが設定されており、選択されなかったサブコマンドのパーサーの属性が設定されていないことに注意してください。なので、上の例では、 "a" コマンドが指定されたときは foo, bar 属性だけが存在し、 "b" コマンドが指定されたときは foo, baz 属性だけが存在しています。

同じように、サブパーサーにヘルプメッセージが要求された場合は、そのパーサーに対するヘルプだけが表示されます。ヘルプメッセージには親パーサーや兄弟パーサーのヘルプメッセージを表示しません。 (ただし、各サブパーサーコマンドのヘルプメッセージは、上の例にもあるように add_parser() の help= 引数によって指定できます)

>>> parser.parse_args(['--help'])
usage: PROG [-h] [--foo] {a,b} ...

positional arguments:
  {a,b}   sub-command help
a     a help
b     b help

optional arguments:
  -h, --help  show this help message and exit
  --foo   foo help

>>> parser.parse_args(['a', '--help'])
usage: PROG a [-h] bar

positional arguments:
  bar     bar help

optional arguments:
  -h, --help  show this help message and exit

>>> parser.parse_args(['b', '--help'])
usage: PROG b [-h] [--baz {X,Y,Z}]

optional arguments:
  -h, --help     show this help message and exit
  --baz {X,Y,Z}  baz help

add_subparsers() メソッドは title と description キーワード引数もサポートしています。どちらかが存在する場合、サブパーサーのコマンドはヘルプ出力でそれぞれのグループの中に表示されます。例えば:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',
...                                    description='valid subcommands',
...                                    help='additional help')
>>> subparsers.add_parser('foo')
>>> subparsers.add_parser('bar')
>>> parser.parse_args(['-h'])
usage:  [-h] {foo,bar} ...

optional arguments:
  -h, --help  show this help message and exit

subcommands:
  valid subcommands

  {foo,bar}   additional help

サブコマンドを扱う1つの便利な方法は add_subparsers() メソッドと set_defaults() を組み合わせて、各サブパーサーにどの Python 関数を実行するかを教えることです。例えば:

>>> # sub-command functions
>>> def foo(args):
...     print args.x * args.y
...
>>> def bar(args):
...     print '((%s))' % args.z
...
>>> # create the top-level parser
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>>
>>> # create the parser for the "foo" command
>>> parser_foo = subparsers.add_parser('foo')
>>> parser_foo.add_argument('-x', type=int, default=1)
>>> parser_foo.add_argument('y', type=float)
>>> parser_foo.set_defaults(func=foo)
>>>
>>> # create the parser for the "bar" command
>>> parser_bar = subparsers.add_parser('bar')
>>> parser_bar.add_argument('z')
>>> parser_bar.set_defaults(func=bar)
>>>
>>> # parse the args and call whatever function was selected
>>> args = parser.parse_args('foo 1 -x 2'.split())
>>> args.func(args)
2.0
>>>
>>> # parse the args and call whatever function was selected
>>> args = parser.parse_args('bar XYZYX'.split())
>>> args.func(args)
((XYZYX))

こうすると、 parse_args() が引数の解析が終わってから適切な関数を呼び出すようになります。このように関数をアクションに関連付けるのは大抵サブパーサーごとに異なるアクションを扱う最も簡単な方法です。ただし、実行されたサブパーサーの名前を確認する必要がある場合は、 add_subparsers() を呼び出すときに dest キーワードを指定することができます:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(dest='subparser_name')
>>> subparser1 = subparsers.add_parser('1')
>>> subparser1.add_argument('-x')
>>> subparser2 = subparsers.add_parser('2')
>>> subparser2.add_argument('y')
>>> parser.parse_args(['2', 'frobble'])
Namespace(subparser_name='2', y='frobble')

15.4.5.2. FileType オブジェクト

class argparse.FileType(mode='r', bufsize=None)

FileType ファクトリは ArgumentParser.add_argument() の type 引数に渡すことができるオブジェクトを生成します。 type が FileType オブジェクトである引数はコマンドライン引数を、指定されたモードとバッファサイズでファイルとして開きます:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
>>> parser.parse_args(['--output', 'out'])
Namespace(output=<open file 'out', mode 'wb' at 0x...>)

FileType オブジェクトは擬似引数 '-' を識別し、読み込み用の FileType であれば sys.stdin を、書き込み用の FileType であれば sys.stdout に変換します:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>)

15.4.5.3. 引数グループ

ArgumentParser.add_argument_group(title=None, description=None)

デフォルトでは、 ArgumentParser はヘルプメッセージを表示するときに、コマンドライン引数を “positional arguments”(位置引数) と “optional arguments”(オプション引数) にグループ化します。このデフォルトの動作よりも良い引数のグループ化方法がある場合、 add_argument_group() メソッドで適切なグループを作成できます:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group = parser.add_argument_group('group')
>>> group.add_argument('--foo', help='foo help')
>>> group.add_argument('bar', help='bar help')
>>> parser.print_help()
usage: PROG [--foo FOO] bar

group:
  bar    bar help
  --foo FOO  foo help

add_argument_group() メソッドは、通常の ArgumentParser と同じような add_argument() メソッドを持つ引数グループオブジェクトを返します。引数がグループに追加された時、パーサーはその引数を通常の引数のように扱いますが、ヘルプメッセージではその引数を分離されたグループの中に表示します。 add_argument_group() メソッドには、この表示をカスタマイズするための title と description 引数があります:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> group1 = parser.add_argument_group('group1', 'group1 description')
>>> group1.add_argument('foo', help='foo help')
>>> group2 = parser.add_argument_group('group2', 'group2 description')
>>> group2.add_argument('--bar', help='bar help')
>>> parser.print_help()
usage: PROG [--bar BAR] foo

group1:
  group1 description

  foo    foo help

group2:
  group2 description

  --bar BAR  bar help

ユーザー定義グループ以外の全ての引数は通常の “positional arguments” と “optional arguments” セクションに表示されます。

15.4.5.4. 相互排他

argparse.add_mutually_exclusive_group(required=False)

相互排他グループを作ります。 argparse は相互排他グループの中でただ1つの引数のみが存在することを確認します:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group()
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args(['--foo'])
Namespace(bar=True, foo=True)
>>> parser.parse_args(['--bar'])
Namespace(bar=False, foo=False)
>>> parser.parse_args(['--foo', '--bar'])
usage: PROG [-h] [--foo | --bar]
PROG: error: argument --bar: not allowed with argument --foo

add_mutually_exclusive_group() メソッドは、その相互排他引数のどれか 1つを選ぶことが要求されることを示す required 引数を取ります:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group(required=True)
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args([])
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required

現在のところ、相互排他引数グループは add_argument_group() の title と description 引数をサポートしていません。

15.4.5.5. パーサーのデフォルト値

ArgumentParser.set_defaults(**kwargs)

ほとんどの場合、 parse_args() が返すオブジェクトの属性はコマンドライン引数の内容と引数のアクションによってのみ決定されます。 set_defaults() を使うと与えられたコマンドライン引数の内容によらず追加の属性を決定することが可能です:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.set_defaults(bar=42, baz='badger')
>>> parser.parse_args(['736'])
Namespace(bar=42, baz='badger', foo=736)

パーサーレベルのデフォルト値は常に引数レベルのデフォルト値をオーバーライドします:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='bar')
>>> parser.set_defaults(foo='spam')
>>> parser.parse_args([])
Namespace(foo='spam')

パーサーレベルの default は、複数のパーサーを扱うときに特に便利です。このタイプの例については add_subparsers() メソッドを参照してください。

ArgumentParser.get_default(dest)

add_argument() か set_defaults() によって指定された、 namespace の属性のデフォルト値を取得します:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='badger')
>>> parser.get_default('foo')
'badger'

15.4.5.6. ヘルプの表示

ほとんどの典型的なアプリケーションでは、 parse_args() が使用法やエラーメッセージのフォーマットと表示について面倒を見ます。しかし、いくつかのフォーマットメソッドが利用できます:

ArgumentParser.print_usage(file=None)

ArgumentParser がコマンドラインからどう実行されるべきかの短い説明を表示します。 file が None の時は、 sys.stdout に出力されます。

ArgumentParser.print_help(file=None)

プログラムの使用法と ArgumentParser に登録された引数についての情報を含むヘルプメッセージを表示します。 file が None の時は、 sys.stdout に出力されます。

これらのメソッドの、表示する代わりにシンプルに文字列を返すバージョンもあります:

ArgumentParser.format_usage()

ArgumentParser がコマンドラインからどう実行されるべきかの短い説明を格納した文字列を返します。

ArgumentParser.format_help()

プログラムの使用法と ArgumentParser に登録された引数についての情報を含むヘルプメッセージを格納した文字列を返します。

15.4.5.7. 部分解析

ArgumentParser.parse_known_args(args=None, namespace=None)

ときどき、スクリプトがコマンドライン引数のいくつかだけを解析し、残りの引数は別のスクリプトやプログラムに渡すことがあります。こういった場合、 parse_known_args() メソッドが便利です。これは parse_args() と同じように動作しますが、余分な引数が存在してもエラーを生成しません。代わりに、評価された namespace オブジェクトと、残りの引数文字列のリストからなる2要素タプルを返します。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('bar')
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])

15.4.5.8. ファイル解析のカスタマイズ

ArgumentParser.convert_arg_line_to_args(arg_line)

ファイルから引数を読み込む場合(ArgumentParser コンストラクタの fromfile_prefix_chars キーワード引数を参照)、1行につき1つの引数を読み込みます。 convert_arg_line_to_args() をオーバーライドしてこの動作をカスタマイズすることができます。

このメソッドは、引数ファイルから読まれた文字列である1つの引数 arg_line を受け取ります。そしてその文字列を解析した結果の引数のリストを返します。このメソッドはファイルから1行読みこむごとに、順番に呼ばれます。

このメソッドをオーバーライドする便利な例として、スペース区切りのワードを 1つの引数として扱います:

def convert_arg_line_to_args(self, arg_line):
    for arg in arg_line.split():
        if not arg.strip():
            continue
        yield arg

15.4.5.9. 終了メソッド

ArgumentParser.exit(status=0, message=None)

このメソッドは、 message が指定されていればそれを表示した後、指定された終了ステータス status でプログラムを終了します。

ArgumentParser.error(message)

このメソッドは message を含む使用法メッセージを標準出力に表示して、終了ステータス 2 でプログラムを終了します。

15.4.6. optparse からのアップグレード

もともと、 argparse モジュールを optparse モジュールとの互換性を保って開発しようという試みがありました。しかし、特に新しい nargs= 指定子とより良い使用法メッセージのために必要な変更のために、 optparse を透過的に拡張することは難しかったのです。 optparse のほとんどすべてがコピーペーストされたりモンキーパッチを当てられたりしたとき、もはや後方互換性を保とうとすることは現実的ではありませんでした。

optparse から argparse への現実的なアップグレード・パス:

全ての optparse.OptionParser.add_option() の呼び出しを、 ArgumentParser.add_argument() の呼び出しに置き換える。

options, args = parser.parse_args() を args = parser.parse_args() に置き換え、位置引数については追加で ArgumentParser.add_argument() を呼び出す。

コールバック・アクションと callback_* キーワード引数を type や action 引数に置き換える。

type キーワード引数に渡していた文字列の名前を、それに応じたオブジェクト (例: int, float, complex, ...) に置き換える。

optparse.Values を Namespace に置き換え、 optparse.OptionError と optparse.OptionValueError を ArgumentError に置き換える。

%default や %prog などの暗黙の引数を含む文字列を、 %(default)s や %(prog)s などの、通常の Python で辞書を使う場合のフォーマット文字列に置き換える。

OptionParser のコンストラクタの version 引数を、 parser.add_argument('--version', action='version', version='<the version>') に置き換える。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.5. optparse — コマンドラインオプション解析器

バージョン 2.7 で撤廃: optparse モジュールは廃止予定で、今後開発はされません。今後の開発は argparse モジュールに対して行われます。

バージョン 2.3 で追加.

optparse モジュールは、昔からある getopt よりも簡便で、柔軟性に富み、かつ強力なコマンドライン解析ライブラリです。 optparse では、より宣言的なスタイルのコマンドライン解析手法、すなわち OptionParser のインスタンスを作成してオプションを追加してゆき、そのインスタンスでコマンドラインを解析するという手法をとっています。 optparse を使うと、GNU/POSIX 構文でオプションを指定できるだけでなく、使用法やヘルプメッセージの生成も行えます。

optparse を使った簡単なスクリプトの例を以下に示します。

from optparse import OptionParser

[...]
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
                  help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose", default=True,
                  help="don't print status messages to stdout")

(options, args) = parser.parse_args()

このようにわずかな行数のコードによって、スクリプトのユーザはコマンドライン上で例えば以下のような「よくある使い方」を実行できるようになります。

<yourscript> --file=outfile -q

コマンドライン解析の中で、 optparse はユーザの指定したコマンドライン引数値に応じて parse_args() の返す options の属性値を設定してゆきます。 parse_args() がコマンドライン解析から処理を戻したとき、 options.filename は "outfile" に、 options.verbose は False になっているはずです。 optparse は長い形式と短い形式の両方のオプション表記をサポートしており、短い形式は結合して指定できます。また、様々な形でオプションに引数値を関連付けられます。従って、以下のコマンドラインは全て上の例と同じ意味になります。

<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile

さらに、ユーザが

<yourscript> -h
<yourscript> --help

のいずれかを実行すると、 optparse はスクリプトのオプションについて簡単にまとめた内容を出力します。

Usage: <yourscript> [options]

Options:
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  write report to FILE
  -q, --quiet           don't print status messages to stdout

yourscript の中身は実行時に決まります (通常は sys.argv[0] になります)。

15.5.1. 背景

optparse は、素直で慣習に則ったコマンドラインインタフェースを備えたプログラムの作成を援助する目的で設計されました。その結果、Unix で慣習的に使われているコマンドラインの構文や機能だけをサポートするに留まっています。こうした慣習に詳しくなければ、よく知っておくためにもこの節を読んでおきましょう。

15.5.1.1. 用語集

引数 (argument)

コマンドラインでユーザが入力するテキストの塊で、シェルが execl() や execv() に引き渡すものです。Python では、引数は sys.argv[1:] の要素となります。(sys.argv[0] は実行しようとしているプログラムの名前です。引数解析に関しては、この要素はあまり重要ではありません。) Unix シェルでは、「語 (word)」という用語も使います。

場合によっては sys.argv[1:] 以外の引数リストを代入する方が望ましいことがあるので、「引数」は「 sys.argv[1:] または sys.argv[1:] の代替として提供される別のリストの要素」と読むべきでしょう。

オプション (option)

追加的な情報を与えるための引数で、プログラムの実行に対する教示やカスタマイズを行います。オプションには多様な文法が存在します。伝統的な Unix における書法はハイフン (“-”) の後ろに一文字が続くもので、例えば -x や -F です。また、伝統的な Unix における書法では、複数のオプションを一つの引数にまとめられます。例えば -x -F は -xF と等価です。 GNU プロジェクトでは -- の後ろにハイフンで区切りの語を指定する方法、例えば --file や --dry-run も提供しています。 optparse は、これら二種類のオプション書法だけをサポートしています。

他に見られる他のオプション書法には以下のようなものがあります:

ハイフンの後ろに数個の文字が続くもので、例えば -pf (このオプションは複数のオプションを一つにまとめたものとは 違います)

ハイフンの後ろに語が続くもので、例えば -file (これは技術的には上の書式と同じですが、通常同じプログラム上で一緒に使うことはありません)

プラス記号の後ろに一文字、数個の文字、または語を続けたもので、例えば +f, +rgb

スラッシュ記号の後ろに一文字、数個の文字、または語を続けたもので、例えば /f, /file

上記のオプション書法は optparse ではサポートしておらず、今後もサポートする予定はありません。これは故意によるものです: 最初の三つはどの環境の標準でもなく、最後の一つは VMS や MS-DOS, そして Windows を対象にしているときにしか意味をなさないからです。

オプション引数 (option argument)

あるオプションの後ろに続く引数で、そのオプションに密接な関連をもち、オプションと同時に引数リストから取り出されます。 optparse では、オプション引数は以下のように別々の引数にできます。

-f foo
--file foo

また、一つの引数中にも入れられます。

-ffoo
--file=foo

通常、オプションは引数をとることもとらないこともあります。あるオプションは引数をとることがなく、またあるオプションは常に引数をとります。多くの人々が「オプションのオプション引数」機能を欲しています。これは、あるオプションが引数が指定されている場合には引数をとり、そうでない場合には引数をもたないようにするという機能です。この機能は引数解析をあいまいにするため、議論の的となっています: 例えば、もし -a がオプション引数をとり、 -b がまったく別のオプションだとしたら、 -ab をどうやって解析すればいいのでしょうか？こうした曖昧さが存在するため、 optparse は今のところこの機能をサポートしていません。

固定引数 (positional argument)

他のオプションが解析される、すなわち他のオプションとその引数が解析されて引数リストから除去された後に引数リストに置かれているものです。

必須のオプション (required option)

コマンドラインで与えなければならないオプションです; 「必須なオプション (required option)」という語は、英語では矛盾した言葉です。 optparse では必須オプションの実装を妨げてはいませんが、とりたてて実装上役立つこともしていません。

例えば、下記のような架空のコマンドラインを考えてみましょう:

prog -v --report /tmp/report.txt foo bar

-v と --report はどちらもオプションです。 --report オプションが引数をとるとすれば、 /tmp/report.txt はオプションの引数です。 foo と bar は固定引数になります。

15.5.1.2. オプションとは何か

オプションはプログラムの実行を調整したり、カスタマイズしたりするための補助的な情報を与えるために使います。もっとはっきりいうと、オプションはあくまでもオプション (省略可能)であるということです。本来、プログラムはともかくもオプションなしでうまく実行できてしかるべきです。(Unix やGNU ツールセットのプログラムをランダムにピックアップしてみてください。オプションを全く指定しなくてもちゃんと動くでしょう？例外は find, tar, dd くらいです—これらの例外は、オプション文法が標準的でなく、インタフェースが混乱を招くと酷評されてきた変種のはみ出しものなのです)

多くの人が自分のプログラムに「必須のオプション」を持たせたいと考えます。しかしよく考えてください。必須なら、それは オプション(省略可能) ではないのです！プログラムを正しく動作させるのに絶対的に必要な情報があるとすれば、そこには固定引数を割り当てるべきなのです。

良くできたコマンドラインインタフェース設計として、ファイルのコピーに使われる cp ユーティリティのことを考えてみましょう。ファイルのコピーでは、コピー先を指定せずにファイルをコピーするのは無意味な操作ですし、少なくとも一つのコピー元が必要です。従って、 cp は引数無しで実行すると失敗します。とはいえ、 cp はオプションを全く必要としない柔軟で便利なコマンドライン文法を備えています:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

まだあります。ほとんどの cp の実装では、ファイルモードや変更時刻を変えずにコピーする、シンボリックリンクの追跡を行わない、すでにあるファイルを上書きする前にユーザに尋ねる、など、ファイルをコピーする方法をいじるための一連のオプションを実装しています。しかし、こうしたオプションは、一つのファイルを別の場所にコピーする、または複数のファイルを別のディレクトリにコピーするという、 cp の中心的な処理を乱すことはないのです。

15.5.1.3. 固定引数とは何か

固定引数とは、プログラムを動作させる上で絶対的に必要な情報となる引数です。

よいユーザインタフェースとは、可能な限り少ない固定引数をもつものです。プログラムを正しく動作させるために 17 個もの別個の情報が必要だとしたら、その 方法 はさして問題にはなりません —ユーザはプログラムを正しく動作させられないうちに諦め、立ち去ってしまうからです。ユーザインタフェースがコマンドラインでも、設定ファイルでも、GUI やその他の何であっても同じです: 多くの要求をユーザに押し付ければ、ほとんどのユーザはただ音をあげてしまうだけなのです。

要するに、ユーザが絶対に提供しなければならない情報だけに制限する — そして可能な限りよく練られたデフォルト設定を使うよう試みてください。もちろん、プログラムには適度な柔軟性を持たせたいとも望むはずですが、それこそがオプションの果たす役割です。繰り返しますが、設定ファイルのエントリであろうが、 GUI でできた「環境設定」ダイアログ上のウィジェットであろうが、コマンドラインオプションであろうが関係ありません — より多くのオプションを実装すればプログラムはより柔軟性を持ちますが、実装はより難解になるのです。高すぎる柔軟性はユーザを閉口させ、コードの維持をより難しくするのです。

15.5.2. チュートリアル

optparse はとても柔軟で強力でありながら、ほとんどの場合には簡単に利用できます。この節では、 optparse ベースのプログラムで広く使われているコードパターンについて述べます。

まず、 OptionParser クラスを import しておかねばなりません。次に、プログラムの冒頭で OptionParser インスタンスを生成しておきます:

from optparse import OptionParser
[...]
parser = OptionParser()

これでオプションを定義できるようになりました。基本的な構文は以下の通りです:

parser.add_option(opt_str, ...,
                  attr=value, ...)

各オプションには、 -f や --file のような一つまたは複数のオプション文字列と、パーザがコマンドライン上のオプションを見つけた際に、何を準備し、何を行うべきかを optparse に教えるためのオプション属性 (option attribute)がいくつか入ります。

通常、各オプションには短いオプション文字列と長いオプション文字列があります。例えば:

parser.add_option("-f", "--file", ...)

といった具合です。

オプション文字列は、(ゼロ文字の場合も含め)いくらでも短く、またいくらでも長くできます。ただしオプション文字列は少なくとも一つなければなりません。

add_option() に渡されたオプション文字列は、実際にはこの関数で定義したオプションに対するラベルになります。簡単のため、以後ではコマンドライン上で オプションを見つける という表現をしばしば使いますが、これは実際には optparse がコマンドライン上の オプション文字列 を見つけ、対応づけされているオプションを捜し出す、という処理に相当します。

オプションを全て定義したら、 optparse にコマンドラインを解析するように指示します:

(options, args) = parser.parse_args()

(お望みなら、 parse_args() に自作の引数リストを渡してもかまいません。とはいえ、実際にはそうした必要はほとんどないでしょう: optionparser はデフォルトで sys.argv[1:] を使うからです。)

parse_args() は二つの値を返します:

全てのオプションに対する値の入ったオブジェクト options — 例えば、 --file が単一の文字列引数をとる場合、 options.file はユーザが指定したファイル名になります。オプションを指定しなかった場合には None になります。

オプションの解析後に残った固定引数からなるリスト args 。

このチュートリアルの節では、最も重要な四つのオプション属性: action, type, dest (destination), help についてしか触れません。このうち最も重要なのは action です。

15.5.2.1. オプション・アクションを理解する

アクション(action)は optparse がコマンドライン上にあるオプションを見つけたときに何をすべきかを指示します。 optparse には押し着せのアクションのセットがハードコードされています。新たなアクションの追加は上級者向けの話題であり、 optparse の拡張 で触れます。ほとんどのアクションは、値を何らかの変数に記憶するよう optparse に指示します — 例えば、文字列をコマンドラインから取り出して、 options の属性の中に入れる、といった具合にです。

オプション・アクションを指定しない場合、 optparse のデフォルトの動作は store になります。

15.5.2.2. store アクション

もっとも良く使われるアクションは store です。このアクションは次の引数 (あるいは現在の引数の残りの部分) を取り出し、正しい型の値か確かめ、指定した保存先に保存するよう optparse に指示します。

例えば:

parser.add_option("-f", "--file",
                  action="store", type="string", dest="filename")

のように指定しておき、偽のコマンドラインを作成して optparse に解析させてみましょう:

args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)

オプション文字列 -f を見つけると、 optparse は次の引数である foo.txt を消費し、その値を options.filename に保存します。従って、この parse_args() 呼び出し後には options.filename は "foo.txt" になっています。

オプションの型として、 optparse は他にも int や float をサポートしています。

整数の引数を想定したオプションの例を示します:

parser.add_option("-n", type="int", dest="num")

このオプションには長い形式のオプション文字列がないため、設定に問題がないということに注意してください。また、デフォルトのアクションは store なので、ここでは action を明示的に指定していません。

架空のコマンドラインをもう一つ解析してみましょう。今度は、オプション引数をオプションの右側にぴったりくっつけて一緒くたにします: -n42 (一つの引数のみ) は -n 42 (二つの引数からなる) と等価になるので、

(options, args) = parser.parse_args(["-n42"])
print options.num

は 42 を出力します。

型を指定しない場合、 optparse は引数を string であると仮定します。デフォルトのアクションが store であることも併せて考えると、最初の例はもっと短くなります:

parser.add_option("-f", "--file", dest="filename")

保存先 (destination) を指定しない場合、 optparse はデフォルト値としてオプション文字列から気のきいた名前を設定します: 最初に指定した長い形式のオプション文字列が --foo-bar であれば、デフォルトの保存先は foo_bar になります。長い形式のオプション文字列がなければ、 optparse は最初に指定した短い形式のオプション文字列を探します: 例えば、 -f に対する保存先は f になります。

optparse では、 long や complex といった組み込み型も取り入れています。型の追加は optparse の拡張 で触れています。

15.5.2.3. ブール値 (フラグ) オプションの処理

フラグオプション—特定のオプションに対して真または偽の値の値を設定するオプション— はよく使われます。 optparse では、二つのアクション、 store_true および store_false をサポートしています。例えば、 verbose というフラグを -v で有効にして、 -q で無効にしたいとします:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")

ここでは二つのオプションに同じ保存先を指定していますが、全く問題ありません (下記のように、デフォルト値の設定を少し注意深く行わねばならないだけです)

-v をコマンドライン上に見つけると、 optparse は options.verbose を True に設定します。 -q を見つければ、 options.verbose は False にセットされます。

15.5.2.4. その他のアクション

この他にも、 optparse は以下のようなアクションをサポートしています:

"store_const"

定数値を保存します。

"append"

オプションの引数を指定のリストに追加します。

"count"

指定のカウンタを 1 増やします。

"callback"

指定の関数を呼び出します。

これらのアクションについては、 リファレンスガイド 節の「リファレンスガイド」およびオプション処理コールバック 節で触れます。

15.5.2.5. デフォルト値

上記の例は全て、何らかのコマンドラインオプションが見つかった時に何らかの変数 (保存先: destination) に値を設定していました。では、該当するオプションが見つからなかった場合には何が起きるのでしょうか？デフォルトは全く与えていないため、これらの値は全て None になります。たいていはこれで十分ですが、もっときちんと制御したい場合もあります。 optparse では各保存先に対してデフォルト値を指定し、コマンドラインの解析前にデフォルト値が設定されるようにできます。

まず、 verbose/quiet の例について考えてみましょう。 optparse に対して、 -q がない限り verbose を True に設定させたいなら、以下のようにします:

parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")

デフォルトの値は特定のオプションではなく 保存先 に対して適用されます。また、これら二つのオプションはたまたま同じ保存先を持っているにすぎないため、上のコードは下のコードと全く等価になります:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)

下のような場合を考えてみましょう:

parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)

やはり verbose のデフォルト値は True になります; 特定の目的変数に対するデフォルト値として有効なのは、最後に指定した値だからです。

デフォルト値をすっきりと指定するには、 OptionParser の set_defaults() メソッドを使います。このメソッドは parse_args() を呼び出す前ならいつでも使えます:

parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()

前の例と同様、あるオプションの値の保存先に対するデフォルトの値は最後に指定した値になります。コードを読みやすくするため、デフォルト値を設定するときには両方のやり方を混ぜるのではなく、片方だけを使うようにしましょう。

15.5.2.6. ヘルプの生成

optparse にはヘルプと使い方の説明 (usage text) を生成する機能があり、ユーザに優しいコマンドラインインタフェースを作成する上で役立ちます。やらなければならないのは、各オプションに対する help の値と、必要ならプログラム全体の使用法を説明する短いメッセージを与えることだけです。

ユーザフレンドリな (ドキュメント付きの) オプションを追加した OptionParser を以下に示します:

usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
                  action="store_true", dest="verbose", default=True,
                  help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose",
                  help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
                  metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
                  default="intermediate",
                  help="interaction mode: novice, intermediate, "
                       "or expert [default: %default]")

optparse がコマンドライン上で -h や --help を見つけた場合や、 parser.print_help() を呼び出した場合、この OptionParser は以下のようなメッセージを標準出力に出力します。

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

(help オプションでヘルプを出力した場合、 optparse は出力後にプログラムを終了します。)

optparse ができるだけうまくメッセージを生成するよう手助けするには、他にもまだまだやるべきことがあります:

スクリプト自体の利用法を表すメッセージを定義します:

usage = "usage: %prog [options] arg1 arg2"

optparse は %prog を現在のプログラム名、すなわち os.path.basename(sys.argv[0]) と置き換えます。この文字列は詳細なオプションヘルプの前に展開され出力されます。

usage の文字列を指定しない場合、 optparse は型どおりとはいえ気の利いたデフォルト値、 "Usage: %prog [options]" を使います。固定引数をとらないスクリプトの場合はこれで十分でしょう。

全てのオプションにヘルプ文字列を定義します。行の折り返しは気にしなくてかまいません — optparse は行の折り返しに気を配り、見栄えのよいヘルプ出力を生成します。

オプションが値をとるということは自動的に生成されるヘルプメッセージの中で分かります。例えば、”mode” option の場合には:

-m MODE, --mode=MODE

のようになります。

ここで “MODE” はメタ変数 (meta-variable) と呼ばれます: メタ変数は、ユーザが -m/--mode に対して指定するはずの引数を表します。デフォルトでは、 optparse は保存先の変数名を大文字だけにしたものをメタ変数に使います。これは時として期待通りの結果になりません — 例えば、上の例の --filename オプションでは明示的に metavar="FILE" を設定しており、その結果自動生成されたオプション説明テキストは:

-f FILE, --filename=FILE

のようになります。

この機能の重要さは、単に表示スペースを節約するといった理由にとどまりません: 上の例では、手作業で書いたヘルプテキストの中でメタ変数として FILE を使っています。その結果、ユーザに対してやや堅苦しい表現の書法 -f FILE と、より平易に意味付けを説明した “write output to FILE” との間に対応があるというヒントを与えています。これは、エンドユーザにとってより明解で便利なヘルプテキストを作成する単純でありながら効果的な手法なのです。

バージョン 2.4 で追加: デフォルト値を持つオプションのヘルプ文字列には %default を入れられます — optparse は %default をデフォルト値の str() で置き換えます。該当するオプションにデフォルト値がない場合 (あるいはデフォルト値が None である場合) %default の展開結果は none になります。

15.5.2.6.1. オプションをグループ化する

たくさんのオプションを扱う場合、オプションをグループ分けするとヘルプ出力が見やすくなります。 OptionParser は、複数のオプションをまとめたオプショングループを複数持つことができます。

オプションのグループは、 OptionGroup を使って作成します:

class optparse.OptionGroup(parser, title, description=None)

parser は、このグループが属する OptionParser のインスタンスです

title はグループのタイトルです

description はオプションで、グループの長い説明です

OptionGroup は (OptionParser のように) OptionContainer を継承していて、オプションをグループに追加するために add_option() メソッドを利用できます。

全てのオプションを定義したら、 OptionParser の add_option_group() メソッドを使ってグループを定義済みのパーサーに追加します。

前のセクションで定義したパーサーに、続けて OptionGroup を追加します:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

この結果のヘルプ出力は次のようになります。

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

さらにサンプルを拡張して、複数のグループを使うようにしてみます:

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
                 help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
                 help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)

出力結果は次のようになります:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert
                        [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

  Debug Options:
    -d, --debug         Print debug information
    -s, --sql           Print all SQL statements executed
    -e                  Print every action done

もう1つの、特にオプショングループをプログラムから操作するときに利用できるメソッドがあります:

OptionParser.get_option_group(opt_str)

opt_str と同じ title か long description を持っている OptionGroup があれば返します。

15.5.2.7. バージョン番号の出力

optparse では、使用法メッセージと同様にプログラムのバージョン文字列を出力できます。 OptionParser の version 引数に文字列を渡します:

parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

%prog は usage と同じような展開を受けます。その他にも version には何でも好きな内容を入れられます。 version を指定した場合、 optparse は自動的に --version オプションをパーザに渡します。コマンドライン中に --version が見つかると、 optparse は version 文字列を展開して (%prog を置き換えて) 標準出力に出力し、プログラムを終了します。

例えば、 /usr/bin/foo という名前のスクリプトなら:

$ /usr/bin/foo --version
foo 1.0

のようになります。

以下の2つのメソッドを、 version 文字列を表示するために利用できます。

OptionParser.print_version(file=None)

現在のプログラムのバージョン (self.version) を file (デフォルト: stdout) へ表示します。 print_usage() と同じく、 self.version の中の全ての %prog が現在のプログラム名に置き換えられます。 self.version が空文字列だだったり未定義だったときは何もしません。

OptionParser.get_version()

print_version() と同じですが、バージョン文字列を表示する代わりに返します。

15.5.2.8. optparse のエラー処理法

optparse を使う場合に気を付けねばならないエラーには、大きく分けてプログラマ側のエラーとユーザ側のエラーという二つの種類があります。プログラマ側のエラーの多くは、例えば不正なオプション文字列や定義されていないオプション属性の指定、あるいはオプション属性を指定し忘れるといった、誤った OptionParser.add_option() 呼び出しによるものです。こうした誤りは通常通りに処理されます。すなわち、例外(optparse.OptionError や TypeError) を送出して、プログラムをクラッシュさせます。

もっと重要なのはユーザ側のエラーの処理です。というのも、ユーザの操作エラーというものはコードの安定性に関係なく起こるからです。 optparse は、誤ったオプション引数の指定 (整数を引数にとるオプション -n に対して -n 4x と指定してしまうなど) や、引数を指定し忘れた場合 (-n が何らかの引数をとるオプションであるのに、 -n が引数の末尾に来ている場合) といった、ユーザによるエラーを自動的に検出します。また、アプリケーション側で定義されたエラー条件が起きた場合、 OptionParser.error() を呼び出してエラーを通知できます:

(options, args) = parser.parse_args()
[...]
if options.a and options.b:
    parser.error("options -a and -b are mutually exclusive")

いずれの場合にも optparse はエラーを同じやり方で処理します。すなわち、プログラムの使用法メッセージとエラーメッセージを標準エラー出力に出力して、終了ステータス 2 でプログラムを終了させます。

上に挙げた最初の例、すなわち整数を引数にとるオプションにユーザが 4x を指定した場合を考えてみましょう:

$ /usr/bin/foo -n 4x
Usage: foo [options]

foo: error: option -n: invalid integer value: '4x'

値を全く指定しない場合には、以下のようになります:

$ /usr/bin/foo -n
Usage: foo [options]

foo: error: -n option requires an argument

optparse は、常にエラーを引き起こしたオプションについて説明の入ったエラーメッセージを生成するよう気を配ります; 従って、 OptionParser.error() をアプリケーションコードから呼び出す場合にも、同じようなメッセージになるようにしてください。

optparse のデフォルトのエラー処理動作が気に入らないのなら、 OptionParser をサブクラス化して、 exit() かつ/または error() をオーバライドする必要があります。

15.5.2.9. 全てをつなぎ合わせる

optparse を使ったスクリプトは、通常以下のようになります:

from optparse import OptionParser
[...]
def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename",
                      help="read data from FILENAME")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose")
    [...]
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")
    if options.verbose:
        print "reading %s..." % options.filename
    [...]

if __name__ == "__main__":
    main()

15.5.3. リファレンスガイド

15.5.3.1. parserを作る

optparse を使う最初の一歩は OptionParser インスタンスを作ることです。

class optparse.OptionParser(...)

OptionParser のコンストラクタの引数はどれも必須ではありませんが、いくつものキーワード引数がオプションとして使えます。これらはキーワード引数として渡さなければなりません。すなわち、引数が宣言されている順番に頼ってはいけません。

usage (デフォルト: "%prog [options]")

プログラムが間違った方法で実行されるかまたはヘルプオプションを付けて実行された場合に表示される使用法です。 optparse は使用法の文字列を表示する際に %prog を os.path.basename(sys.argv[0]) (または prog キーワード引数が指定されていればその値) に展開します。使用法メッセージを抑制するためには特別な optparse.SUPPRESS_USAGE という値を指定します。

option_list (デフォルト: [])

パーザに追加する Option オブジェクトのリストです。 option_list の中のオプションは standard_option_list (OptionParser のサブクラスでセットされる可能性のあるクラス属性) の後に追加されますが、バージョンやヘルプのオプションよりは前になります。このオプションの使用は推奨されません。パーザを作成した後で、 add_option() を使って追加してください。

option_class (デフォルト: optparse.Option)

add_option() でパーザにオプションを追加するときに使用されるクラス。

version (デフォルト: None)

ユーザがバージョンオプションを与えたときに表示されるバージョン文字列です。 version に真の値を与えると、 optparse は自動的に単独のオプション文字列 --version とともにバージョンオプションを追加します。部分文字列 %prog は usage と同様に展開されます。

conflict_handler (デフォルト: "error")

オプション文字列が衝突するようなオプションがパーザに追加されたときにどうするかを指定します。オプション間の衝突 節を参照して下さい。

description (デフォルト: None)

プログラムの概要を表す一段落のテキストです。 optparse はユーザがヘルプを要求したときにこの概要を現在のターミナルの幅に合わせて整形し直して表示します (usage の後、オプションリストの前に表示されます)。

formatter (デフォルト: 新しい IndentedHelpFormatter)

ヘルプテキストを表示する際に使われる optparse.HelpFormatter のインスタンスです。 optparse はこの目的のためにすぐ使えるクラスを二つ提供しています。 IndentedHelpFormatter と TitledHelpFormatter がそれです。

add_help_option (デフォルト: True)

もし真ならば、 optparse はパーザにヘルプオプションを (オプション文字列 -h と --help とともに)追加します。

prog

usage や version の中の %prog を展開するときに os.path.basename(sys.argv[0]) の代わりに使われる文字列です。

epilog (default: None)

オプションのヘルプの後に表示されるヘルプテキスト.

15.5.3.2. パーザへのオプション追加

パーザにオプションを加えていくにはいくつか方法があります。推奨するのは チュートリアル 節で示したような meth:OptionParser.add_option() を使う方法です。 add_option() は以下の二つのうちいずれかの方法で呼び出せます。

(make_option() などが返す) Option インスタンスを渡します。

make_option() に (すなわち Option のコンストラクタに) 固定引数とキーワード引数の組み合わせを渡して、 Option インスタンスを生成させます。

もう一つの方法は、あらかじめ作成しておいた Option インスタンスからなるリストを、以下のようにして OptionParser のコンストラクタに渡すというものです:

option_list = [
    make_option("-f", "--filename",
                action="store", type="string", dest="filename"),
    make_option("-q", "--quiet",
                action="store_false", dest="verbose"),
    ]
parser = OptionParser(option_list=option_list)

(make_option() は Option インスタンスを生成するファクトリ関数です; 現在のところ、この関数は Option のコンストラクタの別名にすぎません。 optparse の将来のバージョンでは、 Option を複数のクラスに分割し、 make_option() は適切なクラスを選んでインスタンスを生成するようになる予定です。従って、 Option を直接インスタンス化しないでください。)

15.5.3.3. オプションの定義

各々の Option インスタンス、は -f や --file といった同義のコマンドラインオプションからなる集合を表現しています。一つの Option には任意の数のオプションを短い形式でも長い形式でも指定できます。ただし、少なくとも一つは指定せねばなりません。

正しい方法で Option インスタンスを生成するには、 OptionParser の add_option() を使います。

OptionParser.add_option(opt_str[, ...], attr=value, ...)

短い形式のオプション文字列を一つだけ持つようなオプションを生成するには次のようにします。

parser.add_option("-f", attr=value, ...)

また、長い形式のオプション文字列を一つだけ持つようなオプションの定義は次のようになります。

parser.add_option("--foo", attr=value, ...)

キーワード引数は新しい Option オブジェクトの属性を定義します。オプションの属性のうちでもっとも重要なのは action です。この属性は、他のどの属性と関連があるか、そしてどの属性が必要かに大きく作用します。関係のないオプション属性を指定したり、必要な属性を指定し忘れたりすると、 optparse は誤りを解説した OptionError 例外を送出します。

コマンドライン上にあるオプションが見つかったときの optparse の振舞いを決定しているのは アクション(action) です。 optparse でハードコードされている標準的なアクションには以下のようなものがあります:

"store"

オプションの引数を保存します (デフォルトの動作です)

"store_const"

定数を保存します

"store_true"

真 (True) を保存します

"store_false"

偽 (False) を保存します

"append"

オプションの引数をリストに追加します

"append_const"

定数をリストに追加します

"count"

カウンタを一つ増やします

"callback"

指定された関数を呼び出します

"help"

全てのオプションとそのドキュメントの入った使用法メッセージを出力します。

(アクションを指定しない場合、デフォルトは "store" になります。このアクションでは、 type および dest オプション属性を指定できます。標準的なオプション・アクション を参照してください。)

すでにお分かりのように、ほとんどのアクションはどこかに値を保存したり、値を更新したりします。この目的のために、 optparse は常に特別なオブジェクトを作り出し、それは通常 options と呼ばれます (optparse.Values のインスタンスになっています)。オプションの引数 (や、その他の様々な値) は、 dest (保存先: destination) オプション属性に従って、 options の属性として保存されます。

例えば、

parser.parse_args()

を呼び出した場合、 optparse はまず options オブジェクトを生成します:

options = Values()

パーザ中で以下のようなオプション

parser.add_option("-f", "--file", action="store", type="string", dest="filename")

が定義されていて、パーズしたコマンドラインに以下のいずれかが入っていた場合:

-ffoo
-f foo
--file=foo
--file foo

optparse はこのオプションを見つけて、

options.filename = "foo"

と同等の処理を行います。

type および dest オプション属性は action と同じくらい重要ですが、 全てのオプションで意味をなすのは action だけなのです。

15.5.3.4. オプション属性

以下のオプション属性は parser.add_option() へのキーワード引数として渡すことができます。特定のオプションに無関係なオプション属性を渡した場合、または必須のオプションを渡しそこなった場合、 optparse は OptionError を送出します。

Option.action

(デフォルト: "store")

このオプションがコマンドラインにあった場合に optparse に何をさせるかを決めます。取りうるオプションについてはこちら を参照してください。

Option.type

(デフォルト: "string")

このオプションに与えられる引数の型 (たとえば "string" や "int") です。取りうるオプションについてはこちら を参照してください。

Option.dest

(デフォルト: オプション文字列を使う)

このオプションのアクションがある値をどこかに書いたり書き換えたりを意味する場合、これは optparse にその書く場所を教えます。詳しく言えば dest には optparse がコマンドラインを解析しながら組み立てる options オブジェクトの属性の名前を指定します。

Option.default

コマンドラインに指定がなかったときにこのオプションの対象に使われる値です。 OptionParser.set_defaults() も参照してください。

Option.nargs

(デフォルト: 1)

このオプションがあったときに幾つの type 型の引数が消費されるべきかを指定します。 1 より大きい場合、 optparse は dest に値のタプルを格納します。

Option.const

定数を格納する動作のための、その定数です。

Option.choices

"choice" 型オプションに対してユーザが選べる選択肢となる文字列のリストです。

Option.callback

アクションが "callback" であるオプションに対し、このオプションがあったときに呼ばれる呼び出し可能オブジェクトです。呼び出し時に渡される引数の詳細については、 オプション処理コールバック を参照してください。

Option.callback_args

Option.callback_kwargs

callback に渡される標準的な4つのコールバック引数の後ろに追加する、位置指定引数とキーワード引数。

Option.help

ユーザが help オプション(--help のような)を指定したときに表示される、使用可能な全オプションのリストの中のこのオプションに関する説明文です。説明文を提供しておかなければ、オプションは説明文なしで表示されます。オプションを隠すには特殊な値 optparse.SUPPRESS_HELP を使います。

Option.metavar

(デフォルト: オプション文字列から)

説明文を表示する際にオプションの引数の身代わりになるものです。例は チュートリアル 節を参照してください。

15.5.3.5. 標準的なオプション・アクション

様々なオプション・アクションにはどれも互いに少しづつ異なった条件と作用があります。ほとんどのアクションに関連するオプション属性がいくつかあり、値を指定して optparse の挙動を操作できます。いくつかのアクションには必須の属性があり、必ず値を指定せねばなりません。

"store" [関連: type, dest, nargs, choices]

オプションの後には必ず引数が続きます。引数は type に従って値に変換されて dest に保存されます。 nargs > 1 の場合、複数の引数をコマンドラインから取り出します。引数は全て type に従って変換され、 dest にタプルとして保存されます。 標準のオプション型 節を参照してください。

choices を(文字列のリストかタプルで) 指定した場合、型のデフォルト値は "choice" になります。

type を指定しない場合、デフォルトの値は "string" です。

dest を指定しない場合、 optparse は保存先を最初の長い形式のオプション文字列から導出します (例えば、 --foo-bar は foo_bar になります)。長い形式のオプション文字列がない場合、 optparse は最初の短い形式のオプションから保存先の変数名を導出します (-f は f になります)。

例えば:

parser.add_option("-f")
parser.add_option("-p", type="float", nargs=3, dest="point")

とすると、以下のようなコマンドライン:

-f foo.txt -p 1 -3.5 4 -fbar.txt

を解析した場合、 optparse は

options.f = "foo.txt"
options.point = (1.0, -3.5, 4.0)
options.f = "bar.txt"

のように設定を行います。

"store_const" [関連: const; 関連: dest]

値 cost を dest に保存します。

例えば:

parser.add_option("-q", "--quiet",
                  action="store_const", const=0, dest="verbose")
parser.add_option("-v", "--verbose",
                  action="store_const", const=1, dest="verbose")
parser.add_option("--noisy",
                  action="store_const", const=2, dest="verbose")

とします。 --noisy が見つかると、 optparse は

options.verbose = 2

のように設定を行います。

"store_true" [関連: dest]

"store_const" の特殊なケースで、真 (True) を dest に保存します。

"store_false" [関連:dest]

"store_true" と似ていて、偽 (False) を保存します。

例:

parser.add_option("--clobber", action="store_true", dest="clobber")
parser.add_option("--no-clobber", action="store_false", dest="clobber")

"append" [関連: type, dest, nargs, choices]

このオプションの後ろには必ず引数が続きます。引数は dest のリストに追加されます。 dest のデフォルト値を指定しなかった場合、 optparse がこのオプションを最初にみつけた時点で空のリストを自動的に生成します。 nargs > 1 の場合、複数の引数をコマンドラインから取り出し、長さ nargs のタプルを生成して dest に追加します。

type および dest のデフォルト値は "store" アクションと同じです。

例:

parser.add_option("-t", "--tracks", action="append", type="int")

-t3 がコマンドライン上で見つかると、 optparse は:

options.tracks = []
options.tracks.append(int("3"))

と同等の処理を行います。

その後、 --tracks=4 が見つかると:

options.tracks.append(int("4"))

を実行します。

"append_const" [関連: const; 関連: dest]

"store_const" と同様ですが、 const の値は dest に追加(append)されます。 "append" の場合と同じように dest のデフォルトは None ですがこのオプションを最初にみつけた時点で空のリストを自動的に生成します。

"count" [関連: dest]

dest に保存されている整数値をインクリメントします。 dest は (デフォルトの値を指定しない限り) 最初にインクリメントを行う前にゼロに設定されます。

例:

parser.add_option("-v", action="count", dest="verbosity")

コマンドライン上で最初に -v が見つかると、 optparse は:

options.verbosity = 0
options.verbosity += 1

と同等の処理を行います。

以後、 -v が見つかるたびに、

options.verbosity += 1

を実行します。

"callback" [必須: callback; 関連: type, nargs, callback_args, callback_kwargs]

callback に指定された関数を次のように呼び出します。

func(option, opt_str, value, parser, *args, **kwargs)

詳細は、 オプション処理コールバック 節を参照してください。

"help"

現在のオプションパーザ内の全てのオプションに対する完全なヘルプメッセージを出力します。ヘルプメッセージは OptionParser のコンストラクタに渡した usage 文字列と、各オプションに渡した help 文字列から生成します。

オプションに help 文字列が指定されていなくても、オプションはヘルプメッセージ中に列挙されます。オプションを完全に表示させないようにするには、特殊な値 optparse.SUPPRESS_HELP を使ってください。

optparse は全ての OptionParser に自動的に help オプションを追加するので、通常自分で生成する必要はありません。

例:

from optparse import OptionParser, SUPPRESS_HELP

# 通常、 help オプションは自動的に追加されますが、
# add_help_option 引数を使って抑制することができます。
parser = OptionParser(add_help_option=False)

parser.add_option("-h", "--help", action="help")
parser.add_option("-v", action="store_true", dest="verbose",
                  help="Be moderately verbose")
parser.add_option("--file", dest="filename",
                  help="Input file to read data from")
parser.add_option("--secret", help=SUPPRESS_HELP)

optparse がコマンドライン上に -h または --help を見つけると、以下のようなヘルプメッセージを標準出力に出力します (sys.argv[0] は "foo.py" だとします)。

Usage: foo.py [options]

Options:
  -h, --help        Show this help message and exit
  -v                Be moderately verbose
  --file=FILENAME   Input file to read data from

ヘルプメッセージの出力後、 optparse は sys.exit(0) でプロセスを終了します。

"version"

OptionParser に指定されているバージョン番号を標準出力に出力して終了します。バージョン番号は、実際には OptionParser の print_version() メソッドで書式化されてから出力されます。通常、 OptionParser のコンストラクタに version 引数が指定されたときのみ関係のあるアクションです。 help オプションと同様、 optparse はこのオプションを必要に応じて自動的に追加するので、 version オプションを作成することはほとんどないでしょう。

15.5.3.6. 標準のオプション型

optparse には、 "string", "int", "long", "choice", "float", "complex" の 6 種類のビルトインのオプション型があります。新たなオプションの型を追加したければ、 optparse の拡張節を参照してください。

文字列オプションの引数はチェックや変換を一切受けません: コマンドライン上のテキストは保存先にそのまま保存されます (またはコールバックに渡されます)。

整数引数 ("int" 型や "long" 型) は次のように読み取られます。

数が 0x から始まるならば、16進数として読み取られます

数が 0 から始まるならば、8進数として読み取られます

数が 0b から始まるならば、2進数として読み取られます

それ以外の場合、数は10進数として読み取られます

変換は適切な底(2, 8, 10, 16 のどれか)とともに int() または long() を呼び出すことで行なわれます。この変換が失敗した場合 optparse の処理も失敗に終わりますが、より役に立つエラーメッセージを出力します。

"float" および "complex" のオプション引数は直接 float() や complex() で変換されます。エラーは同様の扱いです。

"choice" オプションは "string" オプションのサブタイプです。 choice オプションの属性 (文字列からなるシーケンス) には、利用できるオプション引数のセットを指定します。 optparse.check_choice() はユーザの指定したオプション引数とマスタリストを比較して、無効な文字列が指定された場合には OptionValueError を送出します。

15.5.3.7. 引数の解析

OptionParser を作成してオプションを追加していく上で大事なポイントは、 parse_args() メソッドの呼び出しです。

(options, args) = parser.parse_args(args=None, values=None)

ここで入力パラメータは

args

処理する引数のリスト (デフォルト: sys.argv[1:])

values

オプション引数を格納する optparse.Values のオブジェクト (デフォルト: 新しい Values のインスタンス) – 既存のオブジェクトを指定した場合、オプションのデフォルトは初期化されません。

であり、戻り値は

options

values に渡されたものと同じオブジェクト、または optparse によって生成された optparse.Values インスタンス

args

全てのオプションの処理が終わった後で残った位置引数

です。

一番普通の使い方は一切キーワード引数を使わないというものです。 values を指定した場合、それは繰り返される setattr() の呼び出し (大雑把に言うと保存される各オプション引数につき一回ずつ) で更新されていき、 parse_args() で返されます。

parse_args() が引数リストでエラーに遭遇した場合、 OptionParser の error() メソッドを適切なエンドユーザ向けのエラーメッセージとともに呼び出します。この呼び出しにより、最終的に終了ステータス 2 (伝統的な Unix におけるコマンドラインエラーの終了ステータス) でプロセスを終了させることになります。

15.5.3.8. オプション解析器への問い合わせと操作

オプションパーザのデフォルトの振る舞いは、ある程度カスタマイズすることができます。また、オプションパーザの中を調べることもできます。 OptionParser は幾つかのヘルパーメソッドを提供しています。

OptionParser.disable_interspersed_args()

オプションで無い最初の引数を見つけた時点でパースを止めるように設定します。例えば、 -a と -b が両方とも引数を取らないシンプルなオプションだったとすると、 optparse は通常次の構文を受け付け、

prog -a arg1 -b arg2

それを次と同じように扱います。

prog -a -b arg1 arg2

この機能を無効にしたいときは、 disable_interspersed_args() メソッドを呼び出してください。古典的な Unix システムのように、最初のオプションでない引数を見つけたときにオプションの解析を止めるようになります。

別のコマンドを実行するコマンドをプロセッサを作成する際、別のコマンドのオプションと自身のオプションが混ざるのを防ぐために利用することができます。例えば、各コマンドがそれぞれ異なるオプションのセットを持つ場合などに有効です。

OptionParser.enable_interspersed_args()

オプションで無い最初の引数を見つけてもパースを止めないように設定します。オプションとコマンド引数の順序が混ざっても良いようになります。これはデフォルトの動作です。

OptionParser.get_option(opt_str)

オプション文字列 opt_str に対する Option インスタンスを返します。該当するオプションがなければ None を返します。

OptionParser.has_option(opt_str)

OptionParser に(-q や --verbose のような) オプション opt_str がある場合、真を返します。

OptionParser.remove_option(opt_str)

OptionParser に opt_str に対応するオプションがある場合、そのオプションを削除します。該当するオプションに他のオプション文字列が指定されていた場合、それらのオプション文字列は全て無効になります。 opt_str がこの OptionParser オブジェクトのどのオプションにも属さない場合、 ValueError を送出します。

15.5.3.9. オプション間の衝突

注意が足りないと、衝突するオプションを定義してしまうことがあります。

parser.add_option("-n", "--dry-run", ...)
[...]
parser.add_option("-n", "--noisy", ...)

(とりわけ、 OptionParser から標準的なオプションを備えた自前のサブクラスを定義してしまった場合にはよく起きます。)

ユーザがオプションを追加するたびに、 optparse は既存のオプションとの衝突がないかチェックします。何らかの衝突が見付かると、現在設定されている衝突処理メカニズムを呼び出します。衝突処理メカニズムはコンストラクタ中で呼び出せます:

parser = OptionParser(..., conflict_handler=handler)

個別にも呼び出せます:

parser.set_conflict_handler(handler)

衝突時の処理をおこなうハンドラ(handler)には、以下のものが利用できます:

"error" (デフォルトの設定)

オプション間の衝突をプログラム上のエラーとみなし、 OptionConflictError を送出します。

"resolve"

オプション間の衝突をインテリジェントに解決します (下記参照)。

一例として、衝突をインテリジェントに解決する OptionParser を定義し、衝突を起こすようなオプションを追加してみましょう:

parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")

この時点で、 optparse はすでに追加済のオプションがオプション文字列 -n を使っていることを検出します。 conflict_handler が "resolve" なので、 optparse は既に追加済のオプションリストの方から -n を除去して問題を解決します。従って、 -n の除去されたオプションは --dry-run だけでしか有効にできなくなります。ユーザがヘルプ文字列を要求した場合、問題解決の結果を反映したメッセージが出力されます:

Options:
  --dry-run     do no harm
  [...]
  -n, --noisy   be noisy

これまでに追加したオプション文字列を跡形もなく削り去り、ユーザがそのオプションをコマンドラインから起動する手段をなくせます。この場合、 optparse はオプションを完全に除去してしまうので、こうしたオプションはヘルプテキストやその他のどこにも表示されなくなります。例えば、現在の OptionParser の場合、以下の操作:

parser.add_option("--dry-run", ..., help="new dry-run option")

を行った時点で、最初の -n/--dry-run オプションはもはやアクセスできなくなります。このため、 optparse はオプションを消去してしまい、ヘルプテキスト:

Options:
  [...]
  -n, --noisy   be noisy
  --dry-run     new dry-run option

だけが残ります。

15.5.3.10. クリーンアップ

OptionParser インスタンスはいくつかの循環参照を抱えています。このことは Python のガーベジコレクタにとって問題になるわけではありませんが、使い終わった OptionParser に対して destroy() を呼び出すことでこの循環参照を意図的に断ち切るという方法を選ぶこともできます。この方法は特に長時間実行するアプリケーションで OptionParser から大きなオブジェクトグラフが到達可能になっているような場合に有用です。

15.5.3.11. その他のメソッド

OptionParser にはその他にも幾つかの公開されたメソッドがあります:

OptionParser.set_usage(usage)

上で説明したコンストラクタの usage キーワード引数での規則に従った使用法の文字列をセットします。 None を渡すとデフォルトの使用法文字列が使われるようになり、 optparse.SUPPRESS_USAGE によって使用法メッセージを抑制できます。

OptionParser.print_usage(file=None)

現在のプログラムの使用法メッセージ (self.usage) を file (デフォルト: stdout) に表示します。 self.usage 内にある全ての %prog という文字列は現在のプログラム名に置換されます。 self.usage が空もしくは未定義の時は何もしません。

OptionParser.get_usage()

print_usage() と同じですが、使用法メッセージを表示する代わりに文字列として返します。

OptionParser.set_defaults(dest=value, ...)

幾つかの保存先に対してデフォルト値をまとめてセットします。 set_defaults() を使うのは複数のオプションにデフォルト値をセットする好ましいやり方です。複数のオプションが同じ保存先を共有することがあり得るからです。たとえば幾つかの “mode” オプションが全て同じ保存先をセットするものだったとすると、どのオプションもデフォルトをセットすることができ、しかし最後に指定したものだけが有効になります。

parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced",
                  default="novice")    # overridden below
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice",
                  default="advanced")  # overrides above setting

こうした混乱を避けるために set_defaults() を使います。

parser.set_defaults(mode="advanced")
parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced")
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice")

15.5.4. オプション処理コールバック

optparse の組み込みのアクションや型が望みにかなったものでない場合、二つの選択肢があります: 一つは optparse の拡張、もう一つは callback オプションの定義です。 optparse の拡張は汎用性に富んでいますが、単純なケースに対していささか大げさでもあります。大体は簡単なコールバックで事足りるでしょう。

callback オプションの定義は二つのステップからなります:

"callback" アクションを使ってオプション自体を定義する。

コールバックを書く。コールバックは少なくとも後で説明する 4 つの引数をとる関数 (またはメソッド) でなければなりません。

15.5.4.1. callbackオプションの定義

callback オプションを最も簡単に定義するには、 OptionParser.add_option() メソッドを使います。 action の他に指定しなければならない属性は callback すなわちコールバックする関数自体です:

parser.add_option("-c", action="callback", callback=my_callback)

callback は関数 (または呼び出し可能オブジェクト)なので、callback オプションを定義する時にはあらかじめ my_callback() を定義しておかねばなりません。この単純なケースでは、 optparse は -c が何らかの引数をとるかどうか判別できず、通常は c が引数を伴わないことを意味します — 知りたいことはただ単に -c がコマンドライン上に現れたどうかだけです。とはいえ、場合によっては、自分のコールバック関数に任意の個数のコマンドライン引数を消費させたいこともあるでしょう。これがコールバック関数をトリッキーなものにしています; これについてはこの節の後の方で説明します。

optparse は常に四つの引数をコールバックに渡し、その他には Optioncallback_args および callback_kwargs で指定した追加引数しか渡しません。従って、最小のコールバック関数シグネチャは:

def my_callback(option, opt, value, parser):

のようになります。

コールバックの四つの引数については後で説明します。

callback オプションを定義する場合には、他にもいくつかオプション属性を指定できます:

type

他で使われているのと同じ意味です: store や append アクションの時と同じく、この属性は optparse に引数を一つ消費して type で指定した型に変換させます。 optparse は変換後の値をどこかに保存する代わりにコールバック関数に渡します。

nargs

これも他で使われているのと同じ意味です: このオプションが指定されていて、かつ nargs > 1 である場合、 optparse は nargs 個の引数を消費します。このとき各引数は type 型に変換できねばなりません。変換後の値はタプルとしてコールバックに渡されます。

callback_args

その他の位置指定引数からなるタプルで、コールバックに渡されます。

callback_kwargs

その他のキーワード引数からなる辞書で、コールバックに渡されます。

15.5.4.2. コールバック関数はどのように呼び出されるか

コールバックは全て以下の形式で呼び出されます:

func(option, opt_str, value, parser, *args, **kwargs)

ここで、

option

コールバックを呼び出している Option のインスタンスです。

opt_str

は、コールバック呼び出しのきっかけとなったコマンドライン上のオプション文字列です。 (長い形式のオプションに対する省略形が使われている場合、 opt は完全な、正式な形のオプション文字列となります — 例えば、ユーザが --foobar の短縮形として --foo をコマンドラインに入力した時には、 opt_str は "--foobar" となります。)

value

オプションの引数で、コマンドライン上に見つかったものです。 optparse は、 type が設定されている場合、単一の引数しかとりません。 value の型はオプションの型として指定された型になります。このオプションに対する type が None である(引数なしの) 場合、 value は None になります。 nargs > 1 であれば、 value は適切な型をもつ値のタプルになります。

parser

現在のオプション解析の全てを駆動している OptionParser インスタンスです。この変数が有用なのは、この値を介してインスタンス属性としていくつかの興味深いデータにアクセスできるからです:

parser.largs

現在放置されている引数、すなわち、すでに消費されたものの、オプションでもオプション引数でもない引数からなるリストです。 parser.largs は自由に変更でき、たとえば引数を追加したりできます (このリストは args 、すなわち parse_args() の二つ目の戻り値になります)

parser.rargs

現在残っている引数、すなわち、 opt_str および value があれば除き、それ以外の引数が残っているリストです。 parser.rargs は自由に変更でき、例えばさらに引数を消費したりできます。

parser.values

オプションの値がデフォルトで保存されるオブジェクト (optparse.OptionValues のインスタンス) です。この値を使うと、コールバック関数がオプションの値を記憶するために、他の optparse と同じ機構を使えるようにするため、グローバル変数や閉包 (closure) を台無しにしないので便利です。コマンドライン上にすでに現れているオプションの値にもアクセスできます。

args

callback_args オプション属性で与えられた任意の固定引数からなるタプルです。

kwargs

callback_kwargs オプション属性で与えられた任意のキーワード引数からなるタプルです。

15.5.4.3. コールバック中で例外を送出する

オプション自体か、あるいはその引数に問題がある場合、コールバック関数は OptionValueError を送出せねばなりません。 optparse はこの例外をとらえてプログラムを終了させ、ユーザが指定しておいたエラーメッセージを標準エラー出力に出力します。エラーメッセージは明確、簡潔かつ正確で、どのオプションに誤りがあるかを示さねばなりません。さもなければ、ユーザは自分の操作のどこに問題があるかを解決するのに苦労することになります。

15.5.4.4. コールバックの例 1: ありふれたコールバック

引数をとらず、発見したオプションを単に記録するだけのコールバックオプションの例を以下に示します:

def record_foo_seen(option, opt_str, value, parser):
    parser.values.saw_foo = True

parser.add_option("--foo", action="callback", callback=record_foo_seen)

もちろん、 "store_true" アクションを使っても実現できます。

15.5.4.5. コールバックの例 2: オプションの順番をチェックする

もう少し面白みのある例を示します: この例では、 -b を発見して、その後で -a がコマンドライン中に現れた場合にはエラーになります。

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use -a after -b")
    parser.values.a = 1
[...]
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")

15.5.4.6. コールバックの例 3: オプションの順番をチェックする (汎用的)

このコールバック (フラグを立てるが、 -b が既に指定されていればエラーになる) を同様の複数のオプションに対して再利用したければ、もう少し作業する必要があります: エラーメッセージとセットされるフラグを一般化しなければなりません。

def check_order(option, opt_str, value, parser):
    if parser.values.b:
        raise OptionValueError("can't use %s after -b" % opt_str)
    setattr(parser.values, option.dest, 1)
[...]
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')

15.5.4.7. コールバックの例 4: 任意の条件をチェックする

もちろん、単に定義済みのオプションの値を調べるだけにとどまらず、コールバックには任意の条件を入れられます。例えば、満月でなければ呼び出してはならないオプションがあるとしましょう。やらなければならないことはこれだけです:

def check_moon(option, opt_str, value, parser):
    if is_moon_full():
        raise OptionValueError("%s option invalid when moon is full"
                               % opt_str)
    setattr(parser.values, option.dest, 1)
[...]
parser.add_option("--foo",
                  action="callback", callback=check_moon, dest="foo")

(is_moon_full() の定義は読者への課題としましょう。

15.5.4.8. コールバックの例5: 固定引数

決まった数の引数をとるようなコールパックオプションを定義するなら、問題はやや興味深くなってきます。引数をとるようコールバックに指定するのは、 "store" や "append" オプションの定義に似ています。 type を定義していれば、そのオプションは引数を受け取ったときに該当する型に変換できねばなりません。さらに nargs を指定すれば、オプションは nargs 個の引数を受け取ります。

標準の "store" アクションをエミュレートする例を以下に示します:

def store_value(option, opt_str, value, parser):
    setattr(parser.values, option.dest, value)
[...]
parser.add_option("--foo",
                  action="callback", callback=store_value,
                  type="int", nargs=3, dest="foo")

optparse は 3 個の引数を受け取り、それらを整数に変換するところまで面倒をみてくれます。ユーザは単にそれを保存するだけです。 (他の処理もできます; いうまでもなく、この例にはコールバックは必要ありません)

15.5.4.9. コールバックの例6: 可変個の引数

あるオプションに可変個の引数を持たせたいと考えているなら、問題はいささか手強くなってきます。この場合、 optparse では該当する組み込みのオプション解析機能を提供していないので、自分でコールバックを書かねばなりません。さらに、 optparse が普段処理している、伝統的な Unix コマンドライン解析における難題を自分で解決せねばなりません。とりわけ、コールバック関数では引数が裸の -- や - の場合における慣習的な処理規則:

either -- or - can be option arguments

裸の -- (何らかのオプションの引数でない場合): コマンドライン処理を停止し、 -- を無視します。

裸の - (何らかのオプションの引数でない場合): コマンドライン処理を停止しますが、 - は残します (parser.largs に追加します)。

を実装せねばなりません。

オプションが可変個の引数をとるようにさせたいなら、いくつかの巧妙で厄介な問題に配慮しなければなりません。どういう実装をとるかは、アプリケーションでどのようなトレードオフを考慮するかによります (このため、 optparse では可変個の引数に関する問題を直接的に取り扱わないのです)。

とはいえ、可変個の引数をもつオプションに対するスタブ (stub、仲介インタフェース) を以下に示しておきます:

 def vararg_callback(option, opt_str, value, parser):
     assert value is None
     value = []

     def floatable(str):
         try:
             float(str)
             return True
         except ValueError:
             return False

     for arg in parser.rargs:
         # stop on --foo like options
         if arg[:2] == "--" and len(arg) > 2:
             break
         # stop on -a, but not on -3 or -3.0
         if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
             break
         value.append(arg)

     del parser.rargs[:len(value)]
     setattr(parser.values, option.dest, value)

[...]
parser.add_option("-c", "--callback", dest="vararg_attr",
                  action="callback", callback=vararg_callback)

15.5.5. optparse の拡張

optparse がコマンドラインオプションをどのように解釈するかを決める二つの重要な要素はそれぞれのオプションのアクションと型なので、拡張の方向は新しいアクションと型を追加することになると思います。

15.5.5.1. 新しい型の追加

新しい型を追加するためには、 optparse の Option クラスのサブクラスを自身で定義する必要があります。このクラスには optparse における型を定義する一対の属性があります。それは TYPES と TYPE_CHECKER です。

Option.TYPES

TYPES は型名のタプルです。新しく作るサブクラスでは、タプル TYPES を単純に標準のものを利用して新しく定義すると良いでしょう。

Option.TYPE_CHECKER

TYPE_CHECKER は辞書で型名を型チェック関数に対応付けるものです。型チェック関数は以下のようなシグネチャを持ちます。

def check_mytype(option, opt, value)

ここで option は Option のインスタンスであり、 opt はオプション文字列(たとえば -f)で、 value は望みの型としてチェックされ変換されるべくコマンドラインで与えられる文字列です。 check_mytype() は想定されている型 mytype のオブジェクトを返さなければなりません。型チェック関数から返される値は OptionParser.parse_args() で返されるOptionValues インスタンスに収められるか、またはコールバックに value パラメータとして渡されます。

型チェック関数は何か問題に遭遇したら OptionValueError を送出しなければなりません。 OptionValueError は文字列一つを引数に取り、それはそのまま OptionParser の error() メソッドに渡され、そこでプログラム名と文字列 "error:" が前置されてプロセスが終了する前に stderr に出力されます。

馬鹿馬鹿しい例ですが、Python スタイルの複素数を解析する "complex" オプション型を作ってみせることにします。(optparse 1.3 が複素数のサポートを組み込んでしまったため以前にも増して馬鹿らしくなりましたが、気にしないでください。)

最初に必要な import 文を書きます。

from copy import copy
from optparse import Option, OptionValueError

まずは型チェック関数を定義しなければなりません。これは後で(これから定義する Option のサブクラスの TYPE_CHECKER クラス属性の中で) 参照されることになります。

def check_complex(option, opt, value):
    try:
        return complex(value)
    except ValueError:
        raise OptionValueError(
            "option %s: invalid complex value: %r" % (opt, value))

最後に Option のサブクラスです。

class MyOption (Option):
    TYPES = Option.TYPES + ("complex",)
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["complex"] = check_complex

(もしここで Option.TYPE_CHECKER に copy() を適用しなければ、 optparse の Option クラスの TYPE_CHECKER 属性をいじってしまうことになります。 Python の常として、良いマナーと常識以外にそうすることを止めるものはありません。)

これだけです! もう新しいオプション型を使うスクリプトを他の optparse に基づいたスクリプトとまるで同じように書くことができます。ただし、 OptionParser に Option でなく MyOption を使うように指示しなければなければなりません。

parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")

別のやり方として、オプションリストを構築して OptionParser に渡すという方法もあります。 add_option() を上でやったように使わないならば、OptionParser にどのクラスを使うのか教える必要はありません。

option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)

15.5.5.2. 新しいアクションの追加

新しいアクションの追加はもう少しトリッキーです。というのも optparse が使っている二つのアクションの分類を理解する必要があるからです。

“store” アクション

optparse が値を現在の OptionValues の属性に格納することになるアクションです。この種類のオプションは Option のコンストラクタに dest 属性を与えることが要求されます。

“typed” アクション

コマンドラインから引数を受け取り、それがある型であることが期待されているアクションです。もう少しはっきり言えば、その型に変換される文字列を受け取るものです。この種類のオプションは Option のコンストラクタに type 属性を与えることが要求されます。

この分類には重複する部分があります。デフォルトの “store” アクションには "store", "store_const", "append", "count" などがありますが、デフォルトの “typed” オプションは "store", "append", "callback" の三つです。

アクションを追加する際に、以下の Option のクラス属性(全て文字列のリストです) の中の少なくとも一つに付け加えることでそのアクションを分類する必要があります。

Option.ACTIONS

全てのアクションは ACTIONS にリストされていなければなりません

Option.STORE_ACTIONS

“store” アクションはここにもリストされます

Option.TYPED_ACTIONS

“typed” アクションはここにもリストされます

Option.ALWAYS_TYPED_ACTIONS

型を取るアクション (つまりそのオプションが値を取る) はここにもリストされます。このことの唯一の効果は optparse が、型の指定が無くアクションが ALWAYS_TYPED_ACTIONS のリストにあるオプションに、デフォルト型 "string" を割り当てるということだけです。

実際に新しいアクションを実装するには、Option の take_action() メソッドをオーバライドしてそのアクションを認識する場合分けを追加しなければなりません。

例えば、 "extend" アクションというのを追加してみましょう。このアクションは標準的な "append" アクションと似ていますが、コマンドラインから一つだけ値を読み取って既存のリストに追加するのではなく、複数の値をコンマ区切りの文字列として読み取ってそれらで既存のリストを拡張します。すなわち、もし --names が "string" 型の "extend" オプションだとすると、次のコマンドライン

--names=foo,bar --names blah --names ding,dong

の結果は次のリストになります。

["foo", "bar", "blah", "ding", "dong"]

再び Option のサブクラスを定義します。

class MyOption(Option):

    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = value.split(",")
            values.ensure_value(dest, []).extend(lvalue)
        else:
            Option.take_action(
                self, action, dest, opt, value, values, parser)

注意すべきは次のようなところです。

"extend" はコマンドラインの値を予期していると同時にその値をどこかに格納しますので、 STORE_ACTIONS と TYPED_ACTIONS の両方に入ります。

optparse が extend アクションに "string" 型を割り当てるように "extend" アクションは ALWAYS_TYPED_ACTIONS にも入れてあります。

MyOption.take_action() にはこの新しいアクション一つの扱いだけを実装してあり、他の標準的な optparse のアクションについては Option.take_action() に制御を戻すようにしてあります。

values は optparse_parser.Values クラスのインスタンスであり、非常に有用な ensure_value() メソッドを提供しています。 ensure_value() は本質的に安全弁付きの getattr() です。次のように呼び出します。

values.ensure_value(attr, value)

values に attr 属性が無いか None だった場合に、 ensure_value() は最初に value をセットし、それから value を返します。この振る舞いは "extend", "append", "count" のように、データを変数に集積し、またその変数がある型 (最初の二つはリスト、最後のは整数) であると期待されるアクションを作るのにとても使い易いものです。 ensure_value() を使えば、作ったアクションを使うスクリプトはオプションに保存先にデフォルト値をセットすることに煩わされずに済みます。デフォルトを None にしておけば ensure_value() がそれが必要になったときに適当な値を返してくれます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.6. getopt — C言語スタイルのコマンドラインオプションパーサ

ノート

getopt モジュールは、 C言語の getopt() 関数に慣れ親しんだ人のためにデザインされたAPIを持つコマンドラインパーサです。 C言語の getopt() に慣れ親しんでいない人や、コードを少なくしたい場合、より良いヘルプメッセージとエラーメッセージが欲しい場合は、代わりに argparse モジュールの利用を検討してください。

このモジュールは sys.argv に入っているコマンドラインオプションの構文解析を支援します。 ‘-‘ や ‘--‘ の特別扱いも含めて、 Unixの getopt() と同じ記法をサポートしています。 3番目の引数(省略可能)を設定することで、 GNUのソフトウェアでサポートされているような長形式のオプションも利用することができます。

より便利で、柔軟性があり、強力な代替として、 optparse モジュールがあります。

このモジュールは2つの関数と1つの例外を提供しています:

getopt.getopt(args, options[, long_options])

コマンドラインオプションとパラメータのリストを構文解析します。 args は構文解析の対象になる引数リストです。これは先頭のプログラム名を除いたもので、通常 sys.argv[1:] で与えられます。 options はスクリプトで認識させたいオプション文字と、引数が必要な場合にはコロン(':')をつけます。つまりUnixの getopt() と同じフォーマットになります。

ノート

GNUの getopt() とは違って、オプションでない引数の後は全てオプションではないと判断されます。これは GNUでない、Unixシステムの挙動に近いものです。

long_options は長形式のオプションの名前を示す文字列のリストです。名前には、先頭の '--' は含めません。引数が必要な場合には名前の最後に等号('=')を入れます。オプション引数はサポートしていません。長形式のオプションだけを受けつけるためには、 options は空文字列である必要があります。長形式のオプションは、該当するオプションを一意に決定できる長さまで入力されていれば認識されます。たとえば、 long_options が ['foo', 'frob'] の場合、 --fo は --foo にマッチしますが、 --f では一意に決定できないので、 GetoptError が発生します。

返り値は2つの要素から成っています: 最初は (option, value) のタプルのリスト、 2つ目はオプションリストを取り除いたあとに残ったプログラムの引数リストです (args の末尾部分のスライスになります)。それぞれの引数と値のタプルの最初の要素は、短形式の時はハイフン 1つで始まる文字列 (例: '-x')、長形式の時はハイフン2つで始まる文字列(例: '--long-option') となり、引数が2番目の要素になります。引数をとらない場合には空文字列が入ります。オプションは見つかった順に並んでいて、複数回同じオプションを指定することができます。長形式と短形式のオプションは混在させることができます。

getopt.gnu_getopt(args, options[, long_options])

この関数はデフォルトでGNUスタイルのスキャンモードを使う以外は getopt() と同じように動作します。つまり、オプションとオプションでない引数とを混在させることができます。 getopt() 関数はオプションでない引数を見つけると解析をやめてしまいます。

オプション文字列の最初の文字を '+' にするか、環境変数 POSIXLY_CORRECT を設定することで、オプションでない引数を見つけると解析をやめるように振舞いを変えることができます。

バージョン 2.3 で追加.

exception getopt.GetoptError

引数リストの中に認識できないオプションがあった場合か、引数が必要なオプションに引数が与えられなかった場合に発生します。例外の引数は原因を示す文字列です。長形式のオプションについては、不要な引数が与えられた場合にもこの例外が発生します。 msg 属性と opt 属性で、エラーメッセージと関連するオプションを取得できます。特に関係するオプションが無い場合には opt は空文字列となります。

バージョン 1.6 で変更: GetoptError は error の別名として導入されました。

exception getopt.error

GetoptError へのエイリアスです。後方互換性のために残されています。

Unixスタイルのオプションを使った例です:

>>> import getopt
>>> args = '-a -b -cfoo -d bar a1 a2'.split()
>>> args
['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'abc:d:')
>>> optlist
[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
>>> args
['a1', 'a2']

長形式のオプションを使っても同様です:

>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
>>> args = s.split()
>>> args
['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'x', [
...     'condition=', 'output-file=', 'testing'])
>>> optlist
[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
>>> args
['a1', 'a2']

スクリプト中での典型的な使い方は以下のようになります:

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError, err:
        # ヘルプメッセージを出力して終了
        print str(err) # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    # ...

if __name__ == "__main__":
    main()

argparse モジュールを使えば、より良いヘルプメッセージとエラーメッセージを持った同じコマンドラインインタフェースをより少ないコードで実現できます。

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    args = parser.parse_args()
    # ... do something with args.output ...
    # ... do something with args.verbose ..

参考

Module argparse

別のコマンドラインオプションと引数の解析ライブラリ.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.7. logging — Python 用ロギング機能

Important

このページには、リファレンス情報だけが含まれています。チュートリアルは、以下のページを参照してください

基本チュートリアル

上級チュートリアル

ロギングクックブック

バージョン 2.3 で追加.

このモジュールは、アプリケーションやライブラリのための柔軟なエラーログ記録 (logging) システムを実装するための関数やクラスを定義しています。

標準ライブラリモジュールとしてログ記録 API が提供される利点は、すべての Python モジュールがログ記録に参加できることであり、これによってあなたが書くアプリケーションのログにサードパーティーのモジュールが出力するメッセージを含ませることができます。

このモジュールは、多くの機能性と柔軟性を提供します。ロギングに慣れていないなら、つかむのに一番いいのはチュートリアルを読むことです (右のリンクを参照してください)。

モジュールで定義されている基本的なクラスと関数を、以下に列挙します。

ロガーは、アプリケーションコードが直接使うインタフェースを公開します。

ハンドラは、(ロガーによって生成された) ログ記録を適切な送信先に送ります。

フィルタは、どのログ記録を出力するかを決定する、きめ細かい機能を提供します。

フォーマッタは、ログ記録が最終的に出力されるレイアウトを指定します。

15.7.1. ロガーオブジェクト

ロガーには以下のような属性とメソッドがあります。ロガーを直接インスタンス化することはできず、常にモジュール関数 logging.getLogger(name) を介してインスタンス化することに注意してください。

class logging.Logger

Logger.propagate

この評価が true であれば、ロギングメッセージはこのロガーによって、またこの子ロガーによって、上位の (親) ロガーのハンドラに渡されます。メッセージは、親ロガーのハンドラに直接渡されます - 問題の親ロガーのレベルもフィルタも考慮されません。

この値の評価結果が false になる場合、ロギングメッセージは上位の (親の) ロガーのハンドラに渡されません。

コンストラクタはこの属性を 1 に設定します。

Logger.setLevel(lvl)

このロガーの閾値を lvl に設定します。ログ記録しようとするメッセージで、 lvl よりも深刻でないものは無視されます。ロガーが生成された際、レベルは NOTSET (これによりすべてのメッセージについて、ロガーがルートロガーであれば処理される、そうでなくてロガーが非ルートロガーの場合には親ロガーに委譲させる) に設定されます。ルートロガーは WARNING レベルで生成されることに注意してください。

「親ロガーに委譲」という用語の意味は、もしロガーのレベルが NOTEST ならば、祖先ロガーの系列の中を NOTEST 以外のレベルの祖先を見つけるかルートに到達するまで辿っていく、ということです。

もし NOTEST 以外のレベルの祖先が見つかったなら、その祖先のレベルが探索を開始したロガーの実効レベルとして扱われ、ログイベントがどのように処理されるかを決めるのに使われます。

ルートに到達した場合、ルートのレベルが NOTEST ならばすべてのメッセージは処理されます。そうでなければルートのレベルが実効レベルとして使われます。

Logger.isEnabledFor(lvl)

深刻度が lvl のメッセージが、このロガーで処理されることになっているかどうかを示します。このメソッドはまず、 logging.disable(lvl) で設定されるモジュールレベルの深刻度レベルを調べ、次にロガーの実効レベルを getEffectiveLevel() で調べます。

Logger.getEffectiveLevel()

このロガーの実効レベルを示します。 NOTSET 以外の値が setLevel() で設定されていた場合、その値が返されます。そうでない場合、 NOTSET 以外の値が見つかるまでロガーの階層をルートロガーの方向に追跡します。見つかった場合、その値が返されます。

Logger.getChild(suffix)

このロガーの子であるロガーを、接頭辞によって決定し、返します。従って、 logging.getLogger('abc').getChild('def.ghi') は、 logging.getLogger('abc.def.ghi') によって返されるのと同じロガーを返すことになります。コレは簡便なメソッドで、親ロガーがリテラルでなく __name__ などを使って名付けられているときに便利です。

バージョン 2.7 で追加.

Logger.debug(msg, *args, **kwargs)

レベル DEBUG のメッセージをこのロガーで記録します。 msg はメッセージの書式化文字列で、 args は msg に文字列書式化演算子を使って取り込むための引数です。 (これは、書式化文字列の中でキーワードを使い、引数として単一の辞書を渡すことができる、ということを意味します。)

キーワード引数 kwargs からは 2 つのキーワードが調べられます。一つ目は exc_info で、この値の評価値が false でない場合、例外情報をログメッセージに追加します。 (sys.exc_info() の返す形式の) 例外情報を表すタプルが与えられていれば、それをメッセージに使います。それ以外の場合には、 sys.exc_info() を呼び出して例外情報を取得します。

もう一つのキーワード引数は extra で、当該ログイベント用に作られる LogRecoed の __dict__ にユーザー定義属性を加えるのに使われる辞書を渡すために用いられます。これらの属性は好きなように使えます。たとえば、ログメッセージの一部にすることもできます。以下の例を見てください:

FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' }
logger = logging.getLogger('tcpserver')
logger.warning('Protocol problem: %s', 'connection reset', extra=d)

出力はこのようになります:

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

extra で渡される辞書のキーはロギングシステムで使われているものと衝突しないようにしなければなりません。 (どのキーがロギングシステムで使われているかについての詳細は Formatter のドキュメントを参照してください。)

これらの属性をログメッセージに使うことにしたなら、少し注意が必要です。上の例では、 ‘clientip’ と ‘user’ が LogRecord の属性辞書に含まれていることを期待した書式化文字列で Formatter がセットアップされています。もしこれらが欠けていると、書式化例外が発生してしまうためメッセージはログに残りません。したがってこの場合、常にこれらのキーを含む extra 辞書を渡す必要があります。

このようなことは煩わしいかもしれませんが、この機能は限定された場面で使われるように意図しているものなのです。たとえば同じコードがいくつものコンテキストで実行されるマルチスレッドのサーバで、興味のある条件が現れるのがそのコンテキストに依存している (上の例で言えば、リモートのクライアント IP アドレスや認証されたユーザ名など)、というような場合です。そういった場面では、それ用の Formatter が特定の Handler と共に使われるというのはよくあることです。

Logger.info(msg, *args, **kwargs)

レベル INFO のメッセージをこのロガーで記録します。引数は debug() と同じように解釈されます。

Logger.warning(msg, *args, **kwargs)

レベル WARNING のメッセージをこのロガーで記録します。引数は debug() と同じように解釈されます。

Logger.error(msg, *args, **kwargs)

レベル ERROR のメッセージをこのロガーで記録します。引数は debug() と同じように解釈されます。

Logger.critical(msg, *args, **kwargs)

レベル CRITICAL のメッセージをこのロガーで記録します。引数は debug() と同じように解釈されます。

Logger.log(lvl, msg, *args, **kwargs)

整数で表したレベル lvl のメッセージをこのロガーで記録します。その他の引数は debug() と同じように解釈されます。

Logger.exception(msg, *args)

レベル ERROR のメッセージをこのロガーで記録します。引数は debug() と同じように解釈されます。例外情報がログメッセージに追加されます。このメソッドは例外ハンドラからのみ呼び出されるべきです。

Logger.addFilter(filt)

指定されたフィルタ filt をこのロガーに追加します。

Logger.removeFilter(filt)

指定されたフィルタ filt をこのロガーから取り除きます。

Logger.filter(record)

このロガーのフィルタをレコード (record) に適用し、レコードがフィルタを透過して処理されることになる場合には true を返します。

Logger.addHandler(hdlr)

指定されたハンドラ hdlr をこのロガーに追加します。

Logger.removeHandler(hdlr)

指定されたハンドラ hdlr をこのロガーから取り除きます。

Logger.findCaller()

呼び出し元のソースファイル名と行番号を調べます。ファイル名と行番号と関数名を 3 要素のタプルで返します。

バージョン 2.4 で変更: 関数名も加えられました。以前のバージョンではファイル名と行番号を 2 要素のタプルで返していました。

Logger.handle(record)

レコードを、このロガーおよびその上位ロガー (ただし propagate の値が false になったところまで) に関連付けられているすべてのハンドラに渡して処理します。このメソッドは、ローカルで生成されたレコードだけでなく、ソケットから受信した unpickle されたレコードに対しても同様に用いられます。 filter() によって、ロガーレベルでのフィルタが適用されます。

Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None)

このメソッドは、特殊な LogRecord インスタンスを生成するためにサブクラスでオーバライドできるファクトリメソッドです。

バージョン 2.5 で変更: func と extra が追加されました。

15.7.2. ハンドラオブジェクト

ハンドラ (Handler) は以下の属性とメソッドを持ちます。 Handler は直接インスタンス化されることはありません; このクラスはより便利なサブクラスの基底クラスとして働きます。しかしながら、サブクラスにおける __init__() メソッドでは、 Handler.__init__() を呼び出す必要があります。

Handler.__init__(level=NOTSET)

レベルを設定して、 Handler インスタンスを初期化します。空のリストを使ってフィルタを設定し、 I/O 機構へのアクセスを直列化するために (createLock() を使って) ロックを生成します。

Handler.createLock()

スレッドセーフでない背後の I/O 機能に対するアクセスを直列化するために用いられるスレッドロック (thread lock) を初期化します。

Handler.acquire()

createLock() で生成されたスレッドロックを獲得します。

Handler.release()

acquire() で獲得したスレッドロックを解放します。

Handler.setLevel(lvl)

このハンドラに対する閾値を lvl に設定します。ログ記録しようとするメッセージで、 lvl よりも深刻でないものは無視されます。ハンドラが生成された際、レベルは NOTSET (すべてのメッセージが処理される) に設定されます。

Handler.setFormatter(form)

このハンドラのフォーマッタを form に設定します。

Handler.addFilter(filt)

指定されたフィルタ filt をこのハンドラに追加します。

Handler.removeFilter(filt)

指定されたフィルタ filt をこのハンドラから除去します。

Handler.filter(record)

このハンドラのフィルタをレコードに適用し、レコードがフィルタを透過して処理されることになる場合には true 値を返します。

Handler.flush()

すべてのログ出力がフラッシュされるようにします。このクラスのバージョンではなにも行わず、サブクラスで実装するためのものです。

Handler.close()

ハンドラで使われているすべてのリソースの後始末を行います。このバージョンでは何も出力せず、 shutdown() が呼ばれたときに閉じられたハンドラを内部リストから削除します。サブクラスではオーバライドされた close() メソッドからこのメソッドが必ず呼ばれるようにしてください。

Handler.handle(record)

ハンドラに追加されたフィルタの条件に応じて、指定されたログレコードを出力します。このメソッドは I/O スレッドロックの獲得/解放を伴う実際のログ出力をラップします。

Handler.handleError(record)

このメソッドは emit() の呼び出し中に例外に遭遇した際にハンドラから呼び出されます。デフォルトではこのメソッドは何も行いません。すなわち、例外は暗黙のまま無視されます。ほとんどの場合、これがロギングシステムの望ましい動作です - というのは、ほとんどのユーザはロギングシステム自体のエラーは気にせず、むしろアプリケーションのエラーに興味があるからです。しかしながら、望むならこのメソッドを自作のハンドラと置き換えることもできます。 record には、例外発生時に処理されていたレコードが入ります。

Handler.format(record)

レコードに対する書式化を行います - フォーマッタが設定されていれば、それを使います。そうでない場合、モジュールにデフォルト指定されたフォーマッタを使います。

Handler.emit(record)

指定されたログ記録レコードを実際にログ記録する際のすべての処理を行います。このメソッドはサブクラスで実装されることを意図しており、そのためこのクラスのバージョンは NotImplementedError を送出します。

標準として含まれているハンドラについては、 logging.handlers を参照してください。

15.7.3. フォーマッタオブジェクト

フォーマッタ (Formatter) は以下の属性とメソッドを持っています。 Formatter は LogRecord を (通常は) 人間か外部のシステムで解釈できる文字列に変換する役割を担っています。基底クラスの Formatter では書式化文字列を指定することができます。何も指定されなかった場合、 '%(message)s' の値が使われます。

Formatter は LogRecord 属性の知識を利用できるような書式化文字列を用いて初期化することができます。例えば、上で言及したデフォルト値では、ユーザによるメッセージと引数はあらかじめ書式化されて、 LogRecord の message 属性に入っていることを利用しています。この書式化文字列は、 Python 標準の % を使った変換文字列で構成されます。文字列整形に関する詳細は 文字列フォーマット操作 を参照してください。

LogRecord の便利なマッピングキーは、 LogRecord 属性の節で与えられます。

class logging.Formatter(fmt=None, datefmt=None)

Formatter クラスの新たなインスタンスを返します。インスタンスは全体としてのメッセージに対する書式化文字列と、メッセージの日付/時刻部分のための書式化文字列を伴って初期化されます。 fmt が指定されない場合、 '%(message)s' が使われます。 datefmt が指定されない場合、 ISO8601 日付書式が使われます。

format(record)

レコードの属性辞書が、文字列を書式化する演算で被演算子として使われます。書式化された結果の文字列を返します。辞書を書式化する前に、二つの準備段階を経ます。レコードの message 属性が msg % args を使って処理されます。書式化された文字列が '(asctime)' を含むなら、 formatTime() が呼び出され、イベントの発生時刻を書式化します。例外情報が存在する場合、 formatException() を使って書式化され、メッセージに追加されます。ここで注意していただきたいのは、書式化された例外情報は exc_text にキャッシュされるという点です。これが有用なのは例外情報がピックル化されて回線上を送ることができるからですが、しかし二つ以上の Formatter サブクラスで例外情報の書式化をカスタマイズしている場合には注意が必要になります。この場合、フォーマッタが書式化を終えるごとにキャッシュをクリアして、次のフォーマッタがキャッシュされた値を使わずに新鮮な状態で再計算するようにしなければならないことになります。

formatTime(record, datefmt=None)

このメソッドは、フォーマッタが書式化された時間を利用したい際に、 format() から呼び出されます。このメソッドは特定の要求を提供するためにフォーマッタで上書きすることができますが、基本的な振る舞いは以下のようになります: datefmt (文字列) が指定された場合、レコードが生成された時刻を書式化するために time.strftime() で使われます。そうでない場合、 ISO8601 書式が使われます。結果の文字列が返されます。

この関数は、ユーザが設定できる関数を使って、生成時刻をタプルに変換します。デフォルトでは、 time.localtime() が使われます。これを特定のフォーマッタインスタンスに対して変更するには、 converter 属性を time.localtime() や time.gmtime() と同じシグネチャを持つ関数に設定してください。これをすべてのフォーマッタに対して変更するには、例えばすべてのロギング時刻を GMT で表されるようにするには、 Formatter クラスの converter 属性を設定してください。

formatException(exc_info)

指定された例外情報 (sys.exc_info() が返すような標準例外のタプル) を文字列として書式化します。デフォルトの実装は単に traceback.print_exception() を使います。結果の文字列が返されます。

15.7.4. フィルタオブジェクト

フィルタ (Filter) は、 ハンドラ や ロガー によって使われ、レベルによって提供されるのよりも洗練されたフィルタリングを実現します。基底のフィルタクラスは、ロガー階層構造内の特定地点の配下にあるイベントだけを許可します。例えば、’A.B’ で初期化されたフィルタは、ロガー ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’ 等によって記録されたイベントは許可しますが、 ‘A.BB’, ‘B.A.B’ などは許可しません。空の文字列で初期化された場合、すべてのイベントを通過させます。

class logging.Filter(name='')

Filter クラスのインスタンスを返します。 name が指定されていれば、 name はロガーの名前を表します。指定されたロガーとその子ロガーのイベントがフィルタを通過できるようになります。 name が指定されなければ、すべてのイベントを通過させます。

filter(record)

指定されたレコードがログされているか？されていなければゼロを、されていればゼロでない値を返します。適切と判断されれば、このメソッドによってレコードはその場で修正されることがあります。

なお、ハンドラに取り付けられたフィルタは、ハンドラからイベントが放出されるたびに参照されますが、ロガーに取り付けられたフィルタは、イベントがハンドラに (debug(), info() などを使って) 記録されるたびに参照されます。これにより、子孫のロガーで生成されたイベントは、ロガーのフィルタ設定には、そのフィルタが子孫のロガーにも適用されるのでない限り、フィルタされなくなります。

実際には、 Filter をサブクラス化する必要はありません。同じ意味の filter メソッドを持つ、すべてのインスタンスを通せます。

フィルタは本来、レコードをレベルよりも洗練された基準に基づいてフィルタするために使われますが、それが取り付けられたハンドラやロガーによって処理されるレコードをすべて監視します。これは、特定のロガーやハンドラに処理されたレコードの数を数えたり、処理されている LogRecord の属性を追加、変更、削除したりするときに便利です。もちろん、LogRecord を変更するには注意が必要ですが、これにより、ログにコンテキスト情報を注入できます (Filter を使ったコンテキスト情報の伝達 を参照してください)。

15.7.5. LogRecord オブジェクト

LogRecord インスタンスは、何かをログ記録するたびに Logger によって生成されます。また、 makeLogRecord() を通して (例えば、ワイヤを通して受け取られた pickle 化されたイベントから) 手動で生成することも出来ます。

class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None)

ロギングされているイベントに適切なすべての情報を含みます。

一時情報が msg と args に渡され、それらは msg % args を使って組み合わされ、レコードの message 属性を生成します。

パラメタ:

name – この LogRecord で表されるイベントをロギングするのに使われるロガーの名前です。

level – このロギングイベントの数値のレベル (DEBUG, INFO などのいずれか) です。なお、これは LogRecord の 2 つの属性に変換されます。数値 levelno と、対応するレベル名 levelname です。

pathname – ロギングを呼び出したソースファイルの完全なパス名です。

lineno – ロギングを呼び出したソースファイルの行番号です。

msg – イベント記述メッセージで、これは変数データのプレースホルダを持つフォーマット文字列になり得ます。

args – msg 引数と組み合わせてイベント記述を得るための変数データです。

exc_info – 現在の例外情報を含む例外タプルか、利用できる例外情報がないなら None です。

func – ロギングの呼び出しを行った関数またはメソッドの名前です。

バージョン 2.5 で変更: func が追加されました。

getMessage()

ユーザが供給した引数をメッセージに交ぜた後、この LogRecord インスタンスへのメッセージを返します。ユーザがロギングの呼び出しに与えた引数が文字列でなければ、その引数に str() が呼ばれ、文字列に変換されます。これにより、 __str__ メソッドが実際のフォーマット文字列を返せるようなユーザ定義のクラスをメッセージとして使えます。

15.7.6. LogRecord 属性

LogRecord には幾つかの属性があり、そのほとんどはコンストラクタのパラメタから得られます。(なお、LogRecord コンストラクタのパラメタと LogRecord 属性が常に厳密に対応するわけではありません。) これらの属性は、レコードからのデータをフォーマット文字列に統合するのに使えます。以下のテーブルに、属性名、意味、そして % 形式フォーマット文字列における対応するプレースホルダを (アルファベット順に) 列挙します。

属性名 | フォーマット | 説明
args | このフォーマットを自分で使う必要はないでしょう。 | msg に組み合わせて message を生成するための引数のタプル。
asctime | %(asctime)s | LogRecord が生成された時刻を人間が読める書式で表したもの。デフォルトでは “2003-07-08 16:49:45,896” 形式 (コンマ以降の数字は時刻のミリ秒部分) です。
created | %(created)f | LogRecord が生成された時刻 (time.time() によって返される形式で)。
exc_info | このフォーマットを自分で使う必要はないでしょう。 | (sys.exc_info 風の) 例外タプルか、例外が起こっていなければ None 。
filename | %(filename)s | pathname のファイル名部分。
funcName | %(funcName)s | ロギングの呼び出しを含む関数の名前。
levelname | %(levelname)s | メッセージのための文字のロギングレベル ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')。
levelno | %(levelno)s | メッセージのための数値のロギングレベル (DEBUG, INFO, WARNING, ERROR, CRITICAL)。
lineno | %(lineno)d | ロギングの呼び出しが発せられたソース行番号 (利用できる場合のみ)。
module | %(module)s | モジュール (filename の名前部分)。
msecs | %(msecs)d | LogRecord が生成された時刻のミリ秒部分。
message | %(message)s | msg % args として求められた、ログメッセージ。 Formatter.format() が呼び出されたときに設定されます。
msg | このフォーマットを自分で使う必要はないでしょう。 | 元のロギングの呼び出しで渡されたフォーマット文字列。 args と合わせて、 message 、または任意のオブジェクトを生成します (任意のオブジェクトをメッセージに使用する 参照)。
name | %(name)s | ロギングに使われたロガーの名前。
pathname | %(pathname)s | ロギングの呼び出しが発せられたファイルの完全なパス名 (利用できる場合のみ)。
process | %(process)d | プロセス ID (利用可能な場合のみ)。
processName | %(processName)s | プロセス名 (利用可能な場合のみ)。
relativeCreated | %(relativeCreated)d | logging モジュール が読み込まれた時刻に対する、LogRecord が生成された時刻を、ミリ秒で表したもの。
thread | %(thread)d | スレッド ID (利用可能な場合のみ)。
threadName | %(threadName)s | スレッド名 (利用可能な場合のみ)。

バージョン 2.5 で変更: funcName が追加されました。

15.7.7. LoggerAdapter オブジェクト

LoggerAdapter インスタンスは文脈情報をログ記録呼び出しに渡すのを簡単にするために使われます。使い方の例は 文脈情報をログ記録出力に付加する を参照してください。

バージョン 2.6 で追加.

class logging.LoggerAdapter(logger, extra)

内部で使う Logger インスタンスと辞書風 (dict-like) オブジェクトで初期化した LoggerAdapter のインスタンスを返します。

process(msg, kwargs)

文脈情報を挿入するために、ログ記録呼び出しに渡されたメッセージおよび/またはキーワード引数に変更を加えます。ここでの実装は extra としてコンストラクタに渡されたオブジェクトを取り、 ‘extra’ キーを使って kwargs に加えます。返り値は (msg, kwargs) というタプルで、 (変更されているはずの) 渡された引数を含みます。

上のメソッドに加えて、 LoggerAdapter は Logger にあるすべてのログ記録メソッド、すなわち debug(), info(), warning(), error(), exception(), critical(), log(), isEnabledFor(), getEffectiveLevel(), setLevel(), hasHandlers() をサポートします。これらのメソッドは対応する Logger のメソッドと同じ引数を取りますので、二つの型を取り替えて使うことができます。

バージョン 2.7 で変更: isEnabledFor() メソッドが LoggerAdapter に追加されました。このメソッドは、下にあるロガーに委譲します。

15.7.8. スレッドセーフ性

logging モジュールは、クライアントで特殊な作業を必要としない限りスレッドセーフになっています。このスレッドセーフ性はスレッドロックによって達成されています; モジュールの共有データへのアクセスを直列化するためのロックが一つ存在し、各ハンドラでも背後にある I/O へのアクセスを直列化するためにロックを生成します。

signal モジュールを使用して非同期シグナルハンドラを実装している場合、そのようなハンドラからはログ記録を使用できないかもしれません。これは、 threading モジュールにおけるロック実装が常にリエントラントではなく、そのようなシグナルハンドラから呼び出すことができないからです。

15.7.9. モジュールレベル関数

上で述べたクラスに加えて、いくつかのモジュールレベルの関数が存在します。

logging.getLogger([name])

指定された名前のロガーを返します。名前が指定されていない場合、ロガー階層のルート (root) にあるロガーを返します。 name を指定する場合には、通常は “a”, “a.b”, “a.b.c.d” といったドット区切りの階層的な名前にします。名前の付け方はログ機能を使う開発者次第です。

与えられた名前に対して、この関数はどの呼び出しでも同じロガーインスタンスを返します。したがって、ロガーインスタンスをアプリケーションの各部でやりとりする必要はありません。

logging.getLoggerClass()

標準の Logger クラスか、最後に setLoggerClass() に渡したクラスを返します。この関数は、新たなクラス定義の中で呼び出して、カスタマイズした Logger クラスのインストールが既に他のコードで適用したカスタマイズを取り消さないことを保証するために使われることがあります。例えば以下のようにします:

class MyLogger(logging.getLoggerClass()):
    # ... override behaviour here

logging.debug(msg[, *args[, **kwargs]])

レベル DEBUG のメッセージをルートロガーで記録します。 msg はメッセージの書式化文字列で、 args は msg に文字列書式化演算子を使って取り込むための引数です。 (これは、書式化文字列の中でキーワードを使い、引数として単一の辞書を渡すことができる、ということを意味します。)

キーワード引数 kwargs からは 2 つのキーワードが調べられます。一つ目は exc_info で、この値の評価値が false でない場合、例外情報をログメッセージに追加します。 (sys.exc_info() の返す形式の) 例外情報を表すタプルが与えられていれば、それをメッセージに使います。それ以外の場合には、 sys.exc_info() を呼び出して例外情報を取得します。

もう一つのキーワード引数は extra で、当該ログイベント用に作られる LogRecoed の __dict__ にユーザー定義属性を加えるのに使われる辞書を渡すために用いられます。これらの属性は好きなように使えます。たとえば、ログメッセージの一部にすることもできます。以下の例を見てください:

FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)

出力はこのようになります:

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

extra で渡される辞書のキーはロギングシステムで使われているものと衝突しないようにしなければなりません。 (どのキーがロギングシステムで使われているかについての詳細は Formatter のドキュメントを参照してください。)

これらの属性をログメッセージに使うことにしたなら、少し注意が必要です。上の例では、 ‘clientip’ と ‘user’ が LogRecord の属性辞書に含まれていることを期待した書式化文字列で Formatter がセットアップされています。もしこれらが欠けていると、書式化例外が発生してしまうためメッセージはログに残りません。したがってこの場合、常にこれらのキーを含む extra 辞書を渡す必要があります。

このようなことは煩わしいかもしれませんが、この機能は限定された場面で使われるように意図しているものなのです。たとえば同じコードがいくつものコンテキストで実行されるマルチスレッドのサーバで、興味のある条件が現れるのがそのコンテキストに依存している (上の例で言えば、リモートのクライアント IP アドレスや認証されたユーザ名など)、というような場合です。そういった場面では、それ用の Formatter が特定の Handler と共に使われるというのはよくあることです。

バージョン 2.5 で変更: extra が追加されました。

logging.info(msg[, *args[, **kwargs]])

レベル INFO のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。

logging.warning(msg[, *args[, **kwargs]])

レベル WARNING のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。

logging.error(msg[, *args[, **kwargs]])

レベル ERROR のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。

logging.critical(msg[, *args[, **kwargs]])

レベル CRITICAL のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。

logging.exception(msg[, *args])

レベル ERROR のメッセージをルートロガーで記録します。引数は debug() と同じように解釈されます。例外情報がログメッセージに追加されます。このメソッドは例外ハンドラからのみ呼び出されます。

logging.log(level, msg[, *args[, **kwargs]])

レベル level のメッセージをルートロガーで記録します。その他の引数は debug() と同じように解釈されます。

注意事項: Python の 2.7.1 や 3.2 以前のバージョンでは、上述のルートロガーに委譲するモジュールレベル関数は、スレッドが開始される 前に ハンドラがルートロガーに加えられるのでない限り、スレッド内で使 わない べきです。これらの便利な関数は、 basicConfig() を呼び出して、少なくとも 1 つのハンドラが利用できることを保証します。以前のバージョンの Python では、これは (珍しい状況下で) ハンドラがルートロガーに複数回加えられ、それにより同じイベントに複数のメッセージが現れることにつながります。

logging.disable(lvl)

すべてのロガーに対して、ロガー自体のレベルに優先するような上書きレベル lvl を与えます。アプリケーション全体にわたって一時的にログ出力を抑制する必要が生じた場合にはこの関数が有効です。その効果は、深刻度 lvl 以下のすべてのログ呼び出しを無効にすることです。そのためこの関数を値 INFO を伴って呼び出した場合、すべての INFO と DEBUG イベントは捨てられ、ロガーの実効レベルに従って優先度 WARNING 以上のものは処理されるでしょう。

logging.addLevelName(lvl, levelName)

内部的な辞書の中でレベル lvl をテキスト levelName に関連付けます。これは例えば Formatter でメッセージを書式化する際のように、数字のレベルをテキスト表現に対応付ける際に用いられます。この関数は自作のレベルを定義するために使うこともできます。使われるレベルに対する唯一の制限は、レベルは正の整数でなくてはならず、メッセージの深刻度が上がるに従ってレベルの数も上がらなくてはならないということです。

ノート: 独自のレベルを定義することを考えているなら、 カスタムレベルの節をご覧ください。

logging.getLevelName(lvl)

ログ記録レベル lvl のテキスト表現を返します。レベルが定義済みのレベル CRITICAL, ERROR, WARNING, INFO, DEBUG のいずれかである場合、対応する文字列が返されます。 addLevelName() を使ってレベルに名前を関連付けていた場合、 lvl に関連付けられた名前が返されます。定義済みのレベルに対応する数値を指定した場合、レベルに対応した文字列表現を返します。そうでない場合、文字列 “Level %s” % lvl を返します。

logging.makeLogRecord(attrdict)

属性が attrdict で定義された、新しい LogRecord インスタンスを生成して返します。この関数は、 pickle された LogRecord 属性の辞書をソケットを介して送信し、受信端で LogRecord インスタンスとして再構成する場合に便利です。

logging.basicConfig([**kwargs])

デフォルトの Formatter を持つ StreamHandler を生成してルートロガーに追加し、ロギングシステムの基本的な環境設定を行います。関数 debug(), info(), warning(), error(), critical() は、ルートロガーにハンドラが定義されていない場合に自動的に basicConfig() を呼び出します。

この関数はルートロガーに設定されたハンドラがあれば何もしません。

バージョン 2.4 で変更: 以前は basicConfig() はキーワード引数を取りませんでした。

注意事項: この関数は、他のスレッドが開始する前に、メインスレッドから呼ばれるべきです。Python の 2.7.1 や 3.2 以前のバージョンでは、この関数が複数のスレッドから呼び出されると、(珍しい状況下で) これは (珍しい状況下で) ハンドラがルートロガーに複数回加えられ、ログにメッセージが重複して現れるなど、予期せぬ結果につながります。

以下のキーワード引数がサポートされます。

Format | 説明
filename | StreamHandler ではなく指定された名前で FileHandler が作られます
filemode | filename が指定されているとき、ファイルモードを指定します (filemode が指定されない場合デフォルトは ‘a’ です)
format | 指定された書式化文字列をハンドラで使います
datefmt | 指定された日付/時刻の書式を使います
level | ルートロガーのレベルを指定されたものにします
stream | 指定されたストリームを StreamHandler の初期化に使います。この引数は ‘filename’ と同時には使えないことに注意してください。両方が指定されたときには ‘stream’ は無視されます

logging.shutdown()

ロギングシステムに対して、バッファのフラッシュを行い、すべてのハンドラを閉じることで順次シャットダウンを行うように告知します。この関数はアプリケーションの終了時に呼ばれるべきであり、また呼び出し以降はそれ以上ロギングシステムを使ってはなりません。

logging.setLoggerClass(klass)

ロギングシステムに対して、ロガーをインスタンス化する際にクラス klass を使うように指示します。指定するクラスは引数として名前だけをとるようなメソッド __init__() を定義していなければならず、 __init__() では Logger.__init__() を呼び出さなければなりません。典型的な利用法として、この関数は自作のロガーを必要とするようなアプリケーションにおいて、他のロガーがインスタンス化される前にインスタンス化されます。

15.7.10. warnings モジュールとの統合

captureWarnings() 関数をつかって、 logging を warnings モジュールと統合できます。

logging.captureWarnings(capture)

この関数は、 logging による警告の補足を、有効にまたは無効にします。

capture が True なら、 warnings モジュールに発せられた警告は、ロギングシステムにリダイレクトされるようになります。具体的には、警告が warnings.formatwarning() でフォーマット化され、結果の文字列が ‘py.warnings’ という名のロガーに、 WARNING の重大度でロギングされるようになります。

capture が False なら、警告のロギングシステムに対するリダイレクトは止められ、警告は元の (すなわち、 captureWarnings(True) が呼び出される前に有効だった) 送信先にリダイレクトされるようになります。

参考

Module logging.config

logging モジュールの環境設定 API です。

Module logging.handlers

logging モジュールに含まれる、便利なハンドラです。

PEP 282 [http://www.python.org/dev/peps/pep-0282] - A Logging System

この機能を Python 標準ライブラリに含めることを述べた提案です。

Original Python logging package [http://www.red-dove.com/python_logging.html]

これは、 logging パッケージのオリジナルのソースです。このサイトから利用できるバージョンのパッケージは、 logging パッケージを標準ライブラリに含まない、 Python 1.5.2, 2.1.x および 2.2.x で使うのに適しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.8. logging.config — ロギングの環境設定

Important

このページには、リファレンス情報だけが含まれています。チュートリアルは、以下のページを参照してください

基本チュートリアル

上級チュートリアル

ロギングクックブック

この節は、 logging モジュールを設定するための API を解説します。

15.8.1. 環境設定のための関数

以下の関数は logging モジュールの環境設定をします。これらの関数は、 logging.config にあります。これらの関数の使用はオプションです — logging モジュールはこれらの関数を使うか、 (logging 自体で定義されている) 主要な API を呼び出し、 logging か logging.handlers で宣言されているハンドラを定義することで設定できます。

logging.config.dictConfig(config)

辞書からロギング環境設定を取得します。この辞書の内容は、以下の環境設定辞書スキーマ で記述されています。

環境設定中にエラーに遭遇すると、この関数は適宜メッセージを記述しつつ ValueError, TypeError, AttributeError または ImportError を送出します。例外を送出する条件を (不完全かもしれませんが) 以下に列挙します:

文字列でなかったり、実際のロギングレベルと関係ない文字列であったりする level

ブール値でない propagate の値

対応する行き先を持たない id

インクリメンタルな呼び出しの中で見つかった存在しないハンドラ id

無効なロガー名

内部や外部のオブジェクトに関わる不可能性

解析は DictConfigurator クラスによって行われます。このクラスのコンストラクタは環境設定に使われる辞書に渡され、このクラスは configure() メソッドを持ちます。 logging.config モジュールは、呼び出し可能属性 dictConfigClass を持ち、これはまず DictConfigurator に設定されます。 dictConfigClass の値は適切な独自の実装で置き換えられます。

dictConfig() は dictConfigClass を、指定された辞書を渡して呼び出し、それから返されたオブジェクトの configure() メソッドを呼び出して、環境設定を作用させます:

def dictConfig(config):
    dictConfigClass(config).configure()

例えば、 DictConfigurator のサブクラスは、自身の __init__() で DictConfigurator.__init__() を呼び出し、それから続く configure() の呼び出しに使えるカスタムの接頭辞を設定できます。 dictConfigClass は、この新しいサブクラスに束縛され、そして dictConfig() はちょうどデフォルトの、カスタマイズされていない状態のように呼び出せます。

バージョン 2.7 で追加.

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)

ログ記録の環境設定をファイル名 fname の configparser 形式ファイルから読み出します。この関数はアプリケーションから何度も呼び出すことができ、これによって、 (設定を選択し、選択された設定を読み出す機構をデベロッパが提供していれば) 複数の準備済みの設定からエンドユーザが選択するようにできます。

パラメタ:

defaults – ConfigParser に渡すためのデフォルト値はこの引数で指定できます。

disable_existing_loggers – False に指定されると、この呼び出しがなされたときに存在するロガーはそのままにしておかれます。後方互換性を保って古い動作を行えるように、デフォルトは True です。この動作は、すべての既存のロガーを、ロギング環境設定でそれ自身かその祖先を明示的に指名されない限り、無効にします。

バージョン 2.6 で変更: disable_existing_loggers キーワード引数が追加されました。以前は、既存のロガーは 必ず 無効にされていました。

logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT)

指定されたポートでソケットサーバを開始し、新たな設定を待ち受けます。ポートが指定されなければ、モジュールのデフォルトの DEFAULT_LOGGING_CONFIG_PORT が使われます。ログ記録の環境設定は fileConfig() で処理できるようなファイルとして送信されます。 Thread インスタンスを返し、サーバを開始するために start() を呼び、適切な状況で join() を呼び出すことができます。サーバを停止するには stopListening() を呼んでください。

ソケットに設定を送るには、まず設定ファイルを読み、それを struct.pack('>L', n) を使って長さ 4 バイトのバイナリにパックしたものを前に付けたバイト列としてソケットに送ります。

logging.config.stopListening()

listen() を呼び出して作成された、待ち受け中のサーバを停止します。通常 listen() の戻り値に対して join() が呼ばれる前に呼び出します。

15.8.2. 環境設定辞書スキーマ

ロギング設定を記述するには、生成するさまざまなオブジェクトと、それらのつながりを列挙しなければなりません。例えば、 ‘console’ という名前のハンドラを生成し、’startup’ という名前のロガーがメッセージを ‘console’ ハンドラに送るというようなことを記述します。これらのオブジェクトは、 logging モジュールによって提供されるものに限らず、独自のフォーマッタやハンドラクラスを書くことも出来ます。このクラスへのパラメタは、 sys.stderr のような外部オブジェクトを必要とすることもあります。これらのオブジェクトとつながりを記述する構文は、以下の オブジェクトの接続 で定義されています。

15.8.2.1. 辞書スキーマの詳細

dictConfig() に渡される辞書は、以下のキーを含んでいなければなりません:

version - スキーマのバージョンを表す整数値に設定されます。現在有効な値は 1 だけですが、このキーがあることで、このスキーマは後方互換性を保ちながら発展できます。

その他すべてのキーは省略可能ですが、与えられたなら以下に記述するように解釈されます。以下のすべての場合において、 ‘環境設定辞書’ と記載されている所では、その辞書に特殊な '()' キーがあるかを調べることで、カスタムのインスタント化が必要であるか判断されます。その場合は、以下の ユーザ定義オブジェクト で記述されている機構がインスタンス生成に使われます。そうでなければ、インスタンス化するべきものを決定するのにコンテキストが使われます。

formatters - 対応する値は辞書で、そのそれぞれのキーがフォーマッタ id になり、それぞれの値が対応する Formatter インスタンスをどのように環境設定するかを記述する辞書になります。

環境設定辞書は、(デフォルトが None の) キー format と datefmt を検索され、それらが logging.Formatter インスタンスを構成するのに使われます。

filters - 対応する値は辞書で、そのそれぞれのキーがフィルタ id になり、それぞれの値が対応する Filter インスタンスをどのように環境設定するかを記述する辞書になります。

環境設定辞書は、(デフォルトが空文字列の) キー name を検索され、それらが logging.Formatter インスタンスを構成するのに使われます。

handlers - 対応する値は辞書で、そのそれぞれのキーがハンドラ id になり、それぞれの値が対応する Handler インスタンスをどのように環境設定するかを記述する辞書になります。

環境設定辞書は、以下のキーを検索されます。

class (必須)。これはハンドラクラスの完全に修飾された名前です。

level (任意)。ハンドラのレベルです。

formatter (任意)。このハンドラへのフォーマッタの id です。

filters (任意)。このハンドラへのフィルタの id のリストです。

その他の すべての キーは、ハンドラのコンストラクタにキーワード引数として渡されます。例えば、以下のコード片が与えられたら:

handlers:
  console:
    class : logging.StreamHandler
    formatter: brief
    level   : INFO
    filters: [allow_foo]
    stream  : ext://sys.stdout
  file:
    class : logging.handlers.RotatingFileHandler
    formatter: precise
    filename: logconfig.log
    maxBytes: 1024
    backupCount: 3

id が console であるハンドラが、 sys.stdout を根底のストリームにして、 logging.StreamHandler としてインスタンス化されます。id が file であるハンドラが、 filename='logconfig.log', maxBytes=1024, backupCount=3 をキーワード引数にして、 logging.handlers.RotatingFileHandler としてインスタンス化されます。

loggers - 対応する値は辞書で、そのそれぞれのキーがロガー名になり、それぞれの値が対応する Logger インスタンスをどのように環境設定するかを記述する辞書になります。

環境設定辞書は、以下のキーを検索されます。

level (任意)。ロガーのレベルです。

propagate (任意)。ロガーの伝播の設定です。

filters (任意)。このロガーへのフィルタの id のリストです。

filters (任意)。このロガーへのハンドラの id のリストです。

指定されたロガーは、指定されたレベル、伝播、ハンドラに従って環境設定されます。

root - これは、ルートロガーへの設定になります。この環境設定の進行は、 propagate 設定が適用されないことを除き、他のロガーと同じです。

incremental - この環境設定が既存の環境設定に対する増分として解釈されるかどうかです。この値のデフォルトは False で、指定された環境設定は、既存の fileConfig() API によって使われているのと同じ意味上で、既存の環境設定を置き換えます。

指定された値が True なら、環境設定は増分設定 の節で記述されているように進行します。

disable_existing_loggers - 既存のロガーをすべて無効にするべきかどうかです。この設定は、 fileConfig() における同じ名前のパラメタと同じです。設定されていなければ、このパラメタのデフォルトは True です。この値は、 incremental が True なら無視されます。

15.8.2.2. 増分設定

増分設定に完全な柔軟性を提供するのは難しいです。例えば、フィルタやフォーマッタのようなオブジェクトは匿名なので、一旦環境設定がなされると、設定を拡張するときにそのような匿名オブジェクトを参照することができません。

さらに、一旦環境設定がなされた後、実行時にロガー、ハンドラ、フィルタ、フォーマッタのオブジェクトグラフを任意に変えなければならない例もありません。ロガーとハンドラの冗長性は、レベル (または、ロガーの場合には、伝播フラグ) を設定することによってのみ制御できます。安全な方法でオブジェクトグラフを任意に変えることは、マルチスレッド環境で問題となります。不可能ではないですが、その効用は実装に加えられる複雑さに見合いません。

従って、環境設定辞書の incremental キーが与えられ、これが True であるとき、システムは formatters と filters の項目を完全に無視し、 handlers の項目の level 設定と、 loggers と root の項目の level と propagate 設定のみを処理します。

環境設定辞書の値を使うことで、設定は pickle 化された辞書としてソケットリスナにワイヤを通して送ることができます。従って、時間のかかるアプリケーションのロギングの冗長性は、アプリケーションを止めて再起動する必要がない時間に変えることができます。

15.8.2.3. オブジェクトの接続

このスキーマは、ロギングオブジェクトの一揃い - ロガー、ハンドラ、フォーマッタ、フィルタ - について記述します。これらは、オブジェクトグラフ上でお互い接続されます。従って、このスキーマは、オブジェクト間の接続を表現しなければなりません。例えば、環境設定で、特定のロガーが特定のハンドラに取り付けられたとします。この議論では、ロガーとハンドラが、これら 2 つの接続のそれぞれ送信元と送信先であるといえます。もちろん、この設定オブジェクト中では、これはハンドラへの参照を保持しているロガーで表されます。設定辞書中で、これは次のようになされます。まず、送信先オブジェクトを曖昧さなく指定する id を与えます。そして、その id を送信元オブジェクトの環境設定で使い、送信元とその id をもつ送信先が接続されていることを示します。

ですから、例えば、以下の YAML のコード片を例にとると:

formatters:
  brief:
    # configuration for formatter with id 'brief' goes here
  precise:
    # configuration for formatter with id 'precise' goes here
handlers:
  h1: #This is an id
   # configuration of handler with id 'h1' goes here
   formatter: brief
  h2: #This is another id
   # configuration of handler with id 'h2' goes here
   formatter: precise
loggers:
  foo.bar.baz:
    # other configuration for logger 'foo.bar.baz'
    handlers: [h1, h2]

(注釈: YAML がここで使われているのは、辞書の等価な Python 形式よりもこちらのほうが少し読みやすいからです。)

ロガーの id は、プログラム上でロガーへの参照を得るために使われるロガー名で、たとえば foo.bar.baz です。フォーマッタとフィルタの id は、 (上の brief, precise のような) 任意の文字列値にできます。これらは一時的なもので、環境設定辞書の処理にのみ意味があり、オブジェクト間の接続を決定するのに使われます。また、これらは設定の呼び出しが完了したとき、どこにも残りません。

上記のコード片は、 foo.bar.baz というの名ロガーに、ハンドラ id h1 と h2 で表される 2 つのハンドラを接続することを示します。 h1 のフォーマッタは id brief で記述されるもので、 h2 のフォーマッタは id precise で記述されるものです。

15.8.2.4. ユーザ定義オブジェクト

このスキーマは、ハンドラ、フィルタ、フォーマッタのための、ユーザ定義オブジェクトをサポートします。 (ロガーは、異なるインスタンスに対して異なる型を持つ必要はないので、この環境設定スキーマは、ユーザ定義ロガークラスをサポートしていません。)

設定されるオブジェクトは、それらの設定を詳述する辞書によって記述されます。場所によっては、あるオブジェクトがどのようにインスタンス化されるかというコンテキストを、ロギングシステムが推測できます。しかし、ユーザ定義オブジェクトがインスタンス化されるとき、システムはどのようにこれを行うかを知りません。ユーザ定義オブジェクトのインスタンス化を完全に柔軟なものにするため、ユーザは ‘ファクトリ’ - 設定辞書を引数として呼ばれ、インスタンス化されたオブジェクトを返す呼び出し可能オブジェクト - を提供する必要があります。これは特殊キー '()' で利用できる、ファクトリへの絶対インポートパスによって合図されます。ここに具体的な例を挙げます:

formatters:
  brief:
    format: '%(message)s'
  default:
    format: '%(asctime)s %(levelname)-8s %(name)-15s %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
  custom:
      (): my.package.customFormatterFactory
      bar: baz
      spam: 99.9
      answer: 42

上記の YAML コード片は 3 つのフォーマッタを定義します。 1 つ目は、id が brief で、指定されたフォーマット文字列をもつ、標準 logging.Formatter インスタンスです。 2 つ目は、id が default で、長いフォーマットを持ち、時間フォーマットも定義していて、結果はその 2 つのフォーマット文字列で初期化された logging.Formatter になります。Python ソース形式で見ると、 brief と default フォーマッタは、それぞれ設定の部分辞書:

{
  'format' : '%(message)s'
}

と:

{
  'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
  'datefmt' : '%Y-%m-%d %H:%M:%S'
}

を持ち、これらの辞書が特殊キー '()' を持たないので、インスタンス化はコンテキストから推測され、結果として標準の logging.Formatter インスタンスが生成されます。id が custom である、3 つ目のフォーマッタの設定をする部分辞書は:

{
  '()' : 'my.package.customFormatterFactory',
  'bar' : 'baz',
  'spam' : 99.9,
  'answer' : 42
}

で、ユーザ定義のインスタンス化が望まれることを示す特殊キー '()' を含みます。この場合、指定された呼び出し可能ファクトリオブジェクトが使われます。これが実際の呼び出し可能オブジェクトであれば、それが直接使われます - そうではなく、(この例でのように) 文字列を指定したなら、実際の呼び出し可能オブジェクトは、通常のインポート機構を使って検索されます。その呼び出し可能オブジェクトは、環境設定の部分辞書の、 残りの 要素をキーワード引数として呼ばれます。上記の例では、id が custom のフォーマッタは、以下の呼び出しによって返されるものとみなされます:

my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)

キー '()' が特殊キーとして使われるのは、キーワードパラメタ名として不正で、呼び出しに使われるキーワード引数と衝突し得ないからです。 '()' はまた、対応する値が呼び出し可能オブジェクトであると覚えやすくします。

15.8.2.5. 外部オブジェクトへのアクセス

環境設定が、例えば sys.stderr のような、設定の外部のオブジェクトへの参照を必要とすることがあります。設定辞書が Python コードで構成されていれば話は簡単ですが、これがテキストファイル (JSON, YAML 等) を通して提供されていると問題となります。テキストファイルでは、 sys.stderr をリテラル文字列 'sys.stderr' と区別する標準の方法がありません。この区別を容易にするため、環境設定システムは、文字列中の特定の特殊接頭辞を見つけ、それらを特殊に扱います。例えば、リテラル文字列 'ext://sys.stderr' が設定中の値として与えられたら、この ext:// は剥ぎ取られ、この値の残りが普通のインポート機構で処理されます。

このような接頭辞の処理は、プロトコルの処理と同じようになされます。どちらの機構も、正規表現 ^(?P<prefix>[a-z]+)://(?P<suffix>.*)$ にマッチする接頭辞を検索し、それによって prefix が認識されたなら、接頭辞に応じたやり方で suffix が処理され、その処理の結果によって文字列値が置き換えられます。接頭辞が認識されなければ、その文字列値はそのまま残されます。

15.8.2.6. 内部オブジェクトへのアクセス

外部オブジェクトと同様、環境設定内部のオブジェクトへのアクセスを必要とすることもあります。これは、その各オブジェクトを司る環境設定システムによって暗黙に行われます。例えば、ロガーやハンドラの level に対する文字列値 'DEBUG' は、自動的に値 logging.DEBUG に変換されますし、 handlers, filters および formatter の項目は、オブジェクト id を取って、適切な送信先オブジェクトを決定します。

しかし、ユーザ定義モジュールには、 logging モジュールには分からないような、より一般的な機構が必要です。例えば、 logging.handlers.MemoryHandler があって、委譲する先の別のハンドラである target 引数を取るとします。システムはこのクラスをすでに知っていますから、設定中で、与えられた target は関連するターゲットハンドラのオブジェクト id でさえあればよく、システムはその id からハンドラを決定します。しかし、ユーザが my.package.MyHandler を定義して、それが alternate ハンドラを持つなら、設定システムは alternate がハンドラを参照していることを知りません。これを知らせるのに、一般的な解析システムで、ユーザはこのように指定できます:

handlers:
  file:
    # configuration of file handler goes here

  custom:
    (): my.package.MyHandler
    alternate: cfg://handlers.file

リテラル文字列 'cfg://handlers.file' は、 ext:// 接頭辞が付いた文字列と同じように分析されますが、インポート名前空間ではなく、環境設定自体が検索されます。この機構は str.format でできるのと同じようにドットやインデクスのアクセスができます。従って、環境設定において以下のコード片が与えられれば:

handlers:
  email:
    class: logging.handlers.SMTPHandler
    mailhost: localhost
    fromaddr: my_app@domain.tld
    toaddrs:
      - support_team@domain.tld
      - dev_team@domain.tld
    subject: Houston, we have a problem.

文字列 'cfg://handlers' は、キー handlers をもつ辞書であると分析され、文字列 'cfg://handlers.email' は、 handlers 辞書内の、 email キーをもつ辞書であると分析されます。文字列 'cfg://handlers.email.toaddrs[1] は、 'dev_team@domain.tld' と分析され、 'cfg://handlers.email.toaddrs[0]' は値 'support_team@domain.tld' と分析されます。 subject の値には、 'cfg://handlers.email.subject' または等価な 'cfg://handlers.email[subject]' でアクセスできます。後者が必要なのは、キーがスペースや非アルファベット文字を含むときのみです。インデクス値が十進数時のみで成り立っているなら、まず対応する整数値を使ってアクセスが試みられ、必要なら文字列値で代替します。

文字列 cfg://handlers.myhandler.mykey.123 が与えられると、これは config_dict['handlers']['myhandler']['mykey']['123'] と分析されます。文字列が cfg://handlers.myhandler.mykey[123] と指定されたら、システムは config_dict['handlers']['myhandler']['mykey'][123] から値を引き出そうとし、失敗したら config_dict['handlers']['myhandler']['mykey']['123'] で代替します。

15.8.3. 環境設定ファイルの書式

fileConfig() が解釈できる環境設定ファイルの形式は、 ConfigParser の機能に基づいています。ファイルには、 [loggers], [handlers], [formatters] といったセクションが入っていなければならず、各セクションではファイル中で定義されている各タイプのエンティティを名前で指定しています。こうしたエンティティの各々について、そのエンティティをどう設定するかを示した個別のセクションがあります。すなわち、 log01 という名前の [loggers] セクションにあるロガーに対しては、対応する詳細設定がセクション [logger_log01] に収められています。同様に、 hand01 という名前の [handlers] セクションにあるハンドラは [handler_hand01] と呼ばれるセクションに設定をもつことになり、 [formatters] セクションにある form01 は [formatter_form01] というセクションで設定が指定されています。ルートロガーの設定は [logger_root] と呼ばれるセクションで指定されていなければなりません。

ファイルにおけるこれらのセクションの例を以下に示します:

[loggers]
keys=root,log02,log03,log04,log05,log06,log07

[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09

[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09

ルートロガーでは、レベルとハンドラのリストを指定しなければなりません。ルートロガーのセクションの例を以下に示します:

[logger_root]
level=NOTSET
handlers=hand01

level エントリは DEBUG, INFO, WARNING, ERROR, CRITICAL のうちの一つか、 NOTSET になります。ルートロガーの場合にのみ、 NOTSET はすべてのメッセージがログ記録されることを意味します。レベル値は logging パッケージの名前空間のコンテキストにおいて eval() されます。

handlers エントリはコンマで区切られたハンドラ名からなるリストで、 [handlers] セクションになくてはなりません。また、これらの各ハンドラの名前に対応するセクションが設定ファイルに存在しなければなりません。

ルートロガー以外のロガーでは、いくつか追加の情報が必要になります。これは以下の例のように表されます:

[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser

level および handlers エントリはルートロガーのエントリと同様に解釈されますが、非ルートロガーのレベルが NOTSET に指定された場合、ロギングシステムはロガー階層のより上位のロガーにロガーの実効レベルを問い合わせるところが違います。 propagate エントリは、メッセージをロガー階層におけるこのロガーの上位のハンドラに伝播させることを示す 1 に設定されるか、メッセージを階層の上位に伝播 しない ことを示す 0 に設定されます。 qualname エントリはロガーのチャネル名を階層的に表したもの、すなわちアプリケーションがこのロガーを取得する際に使う名前になります。

ハンドラの環境設定を指定しているセクションは以下の例のようになります:

[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)

class エントリはハンドラのクラス (logging パッケージの名前空間において eval() で決定されます) を示します。 level はロガーの場合と同じように解釈され、 NOTSET は “すべてを記録する (log everything)” と解釈されます。

バージョン 2.6 で変更: ハンドラクラスのドット区切りモジュールおよびクラス名としての解決のサポートが追加された。

formatter エントリはこのハンドラのフォーマッタに対するキー名を表します。空文字列の場合、デフォルトのフォーマッタ (logging._defaultFormatter) が使われます。名前が指定されている場合、その名前は [formatters] セクションになくてはならず、対応するセクションが設定ファイル中になければなりません。

args エントリは、 logging パッケージの名前空間のコンテキストで eval() される際、ハンドラクラスのコンストラクタに対する引数からなるリストになります。典型的なエントリがどうやって作成されるかについては、対応するハンドラのコンストラクタか、以下の例を参照してください:

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
args=('python.log', 'w')

[handler_hand03]
class=handlers.SocketHandler
level=INFO
formatter=form03
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)

[handler_hand04]
class=handlers.DatagramHandler
level=WARN
formatter=form04
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)

[handler_hand05]
class=handlers.SysLogHandler
level=ERROR
formatter=form05
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)

[handler_hand06]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=form06
args=('Python Application', '', 'Application')

[handler_hand07]
class=handlers.SMTPHandler
level=WARN
formatter=form07
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')

[handler_hand08]
class=handlers.MemoryHandler
level=NOTSET
formatter=form08
target=
args=(10, ERROR)

[handler_hand09]
class=handlers.HTTPHandler
level=NOTSET
formatter=form09
args=('localhost:9022', '/log', 'GET')

フォーマッタの環境設定を指定しているセクションは以下のような形式です:

[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter

format エントリは全体を書式化する文字列で、 datefmt エントリは strftime() 互換の日付/時刻書式化文字列です。空文字列の場合、パッケージによって ISO8601 形式の日付/時刻に置き換えられ、日付書式化文字列 "%Y-%m-%d %H:%M:%S" を指定した場合とほとんど同じになります。 ISO8601 形式ではミリ秒も指定しており、上の書式化文字列の結果にカンマで区切って追加されます。 ISO8601 形式の時刻の例は 2003-01-23 00:29:50,411 です。

class エントリはオプションです。 class はフォーマッタのクラス名 (ドット区切りのモジュールとクラス名として) を示します。このオプションは Formatter のサブクラスをインスタンス化するのに有用です。 Formatter のサブクラスは例外トレースバックを展開された形式または圧縮された形式で表現することができます。

参考

モジュール logging

logging モジュールの API リファレンス。

Module logging.handlers

logging モジュールに含まれる便利なハンドラ。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.9. logging.handlers — ロギングハンドラ

Important

このページには、リファレンス情報だけが含まれています。チュートリアルは、以下のページを参照してください

基本チュートリアル

上級チュートリアル

ロギングクックブック

このパッケージでは、以下の便利なハンドラが提供されています。なお、これらのハンドラのうち、3 つ (StreamHandler, FileHandler および NullHandler) は、実際には logging モジュール自身で定義されていますが、他のハンドラと一緒にここでドキュメント化します。

15.9.1. StreamHandler

logging コアパッケージに含まれる StreamHandler クラスは、ログ出力を sys.stdout, sys.stderr あるいは何らかのファイル風 (file-like) オブジェクト (あるいは、より正確に言えば write() および flush() メソッドをサポートする何らかのオブジェクト) といったストリームに送信します。

class logging.StreamHandler(stream=None)

StreamHandler クラスの新たなインスタンスを返します。 stream が指定された場合、インスタンスはログ出力先として指定されたストリームを使います; そうでない場合、 sys.stderr が使われます。

emit(record)

フォーマッタが指定されていれば、フォーマッタを使ってレコードを書式化します。次に、レコードがストリームに書き込まれ、末端に改行がつけられます。例外情報が存在する場合、 traceback.print_exception() を使って書式化され、ストリームの末尾につけられます。

flush()

ストリームの flush() メソッドを呼び出してバッファをフラッシュします。 close() メソッドは Handler から継承しているため何も出力を行わないので、 flush() 呼び出しを明示的に行う必要があるかもしれません。

15.9.2. FileHandler

logging コアパッケージに含まれる FileHandler クラスは、ログ出力をディスク上のファイルに送信します。このクラスは出力機能を StreamHandler から継承しています。

class logging.FileHandler(filename, mode='a', encoding=None, delay=False)

FileHandler クラスの新たなインスタンスを返します。指定されたファイルが開かれ、ログ記録のためのストリームとして使われます。 mode が指定されなかった場合、 'a' が使われます。 encoding が None でない場合、その値はファイルを開くときのエンコーディングとして使われます。 delay が true ならば、ファイルを開くのは最初の emit() 呼び出しまで遅らせられます。デフォルトでは、ファイルは無制限に大きくなりつづけます。

バージョン 2.6 で変更: delay が追加されました。

close()

ファイルを閉じます。

emit(record)

record をファイルに出力します。

15.9.3. NullHandler

バージョン 2.7 で追加.

logging コアパッケージに含まれる NullHandler クラスは、いかなるフォーマット化も出力も行いません。これは本質的には、ライブラリ開発者に使われる ‘no-op’ ハンドラです。

class logging.NullHandler

NullHandler クラスの新しいインスタンスを返します。

emit(record)

このメソッドは何もしません。

handle(record)

このメソッドは何もしません。

createLock()

アクセスが特殊化される必要がある I/O が下にないので、このメソッドはロックに対して None を返します。

NullHandler の使い方の詳しい情報は、 ライブラリのためのロギングの設定 を参照してください。

15.9.4. WatchedFileHandler

バージョン 2.6 で追加.

logging.handlers モジュールに含まれる WatchedFileHandler クラスは、ログ記録先のファイルを監視する FileHandler の一種です。ファイルが変更された場合、ファイルを閉じてからファイル名を使って開き直します。

ファイルはログファイルをローテーションさせる newsyslog や logrotate のようなプログラムを使うことで変更されることがあります。このハンドラは、 Unix/Linux で使われることを意図していますが、ファイルが最後にログを出力してから変わったかどうかを監視します。 (ファイルはデバイスや inode が変わることで変わったと判断します。) ファイルが変わったら古いファイルのストリームは閉じて、現在のファイルを新しいストリームを取得するために開きます。

このハンドラを Windows で使うことは適切ではありません。というのも Windows では開いているログファイルを移動したり削除したりできないからです - logging はファイルを排他的ロックを掛けて開きます - そのためこうしたハンドラは必要ないのです。さらに、 Windows では ST_INO がサポートされていません (stat() はこの値として常に 0 を返します)。

class logging.handlers.WatchedFileHandler(filename[, mode[, encoding[, delay]]])

WatchedFileHandler クラスの新たなインスタンスを返します。指定されたファイルが開かれ、ログ記録のためのストリームとして使われます。 mode が指定されなかった場合、 'a' が使われます。 encoding が None でない場合、その値はファイルを開くときのエンコーディングとして使われます。 delay が true ならば、ファイルを開くのは最初の emit() 呼び出しまで遅らせられます。デフォルトでは、ファイルは無制限に大きくなりつづけます。

emit(record)

レコードをファイルに出力しますが、その前にファイルが変更されていないかチェックします。もし変更されていれば、レコードをファイルに出力する前に、既存のストリームはフラッシュして閉じられ、ファイルが再度開かれます。

15.9.5. RotatingFileHandler

logging.handlers モジュールに含まれる RotatingFileHandler クラスは、ディスク上のログファイルに対するローテーション処理をサポートします。

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)

RotatingFileHandler クラスの新たなインスタンスを返します。指定されたファイルが開かれ、ログ記録のためのストリームとして使われます。 mode が指定されなかった場合、 'a' が使われます。 encoding が None でない場合、その値はファイルを開くときのエンコーディングとして使われます。 delay が true ならば、ファイルを開くのは最初の emit() 呼び出しまで遅らせられます。デフォルトでは、ファイルは無制限に大きくなりつづけます。

maxBytes および backupCount 値を指定することで、あらかじめ決められたサイズでファイルをロールオーバ (rollover) させることができます。指定サイズを超えそうになると、ファイルは閉じられ、暗黙のうちに新たなファイルが開かれます。ロールオーバは現在のログファイルの長さが maxBytes に近くなると常に起きます。 backupCount が非ゼロの場合、システムは古いログファイルをファイル名に ”.1”, ”.2” といった拡張子を追加して保存します。例えば、 backupCount が 5 で、基本のファイル名が app.log なら、 app.log, app.log.1, app.log.2 ... と続き、 app.log.5 までを得ることになります。ログの書き込み対象になるファイルは常に app.log です。このファイルが満杯になると、ファイルは閉じられ、 app.log.1 に名前が変更されます。 app.log.1, app.log.2 などが存在する場合、それらのファイルはそれぞれ app.log.2, app.log.3 といった具合に名前が変更されます。

バージョン 2.6 で変更: delay が追加されました。

doRollover()

上述のような方法でロールオーバを行います。

emit(record)

上述のようなロールオーバを行いながら、レコードをファイルに出力します。

15.9.6. TimedRotatingFileHandler

logging.handlers モジュールに含まれる TimedRotatingFileHandler クラスは、特定の時間間隔でのログローテーションをサポートしています。

class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False)

TimedRotatingFileHandler クラスの新たなインスタンスを返します。 filename に指定したファイルを開き、ログ出力先のストリームとして使います。ログファイルのローテーション時には、ファイル名に拡張子 (suffix) をつけます。ログファイルのローテーションは when および interval の積に基づいて行います。

when は interval の単位を指定するために使います。使える値は下表の通りです。大小文字の区別は行いません:

値 | interval の単位
'S' | 秒
'M' | 分
'H' | 時間
'D' | 日
'W' | 曜日 (0=Monday)
'midnight' | 深夜

古いログファイルを保存する際にロギングシステムは拡張子を付けます。拡張子は日付と時間に基づいて、 strftime の %Y-%m-%d_%H-%M-%S 形式かその前方の一部を、ロールオーバ間隔に依存した形で使います。

最初に次のロールオーバー時間を計算するとき (ハンドラが生成されるとき)、次のローテーションがいつ起こるかを計算するために、既存のログファイルの最終変更時刻または現在の時間が使用されます。

utc 引数が true の場合時刻は UTC になり、それ以外では現地時間が使われます。

backupCount がゼロでない場合、保存されるファイル数は高々 backupCount 個で、それ以上のファイルがロールオーバされる時に作られるならば、一番古いものが削除されます。削除のロジックは interval で決まるファイルを削除するので、 interval を変えると古いファイルが残ったままになることもあります。

delay が true なら、ファイルを開くのは emit() の最初の呼び出しまで延期されます。

バージョン 2.6 で変更: delay が追加されました。

バージョン 2.7 で変更: utc が追加されました。

doRollover()

上述の方法でロールオーバを行います。

emit(record)

Outputs the record to the file, catering for rollover as described above. 上で説明した方法でロールオーバを行いながら、レコードをファイルに出力します。

15.9.7. SocketHandler

logging.handlers モジュールに含まれる SocketHandler クラスは、ログ出力をネットワークソケットに送信します。基底クラスでは TCP ソケットを用います。

class logging.handlers.SocketHandler(host, port)

アドレスが host および port で与えられた遠隔のマシンと通信するようにした SocketHandler クラスのインスタンスを生成して返します。

close()

ソケットを閉じます。

emit()

レコードの属性辞書を pickle して、バイナリ形式でソケットに書き込みます。ソケット操作でエラーが生じた場合、暗黙のうちにパケットは捨てられます。事前に接続が失われていた場合、接続を再度確立します。受信端でレコードを unpickle して LogRecord にするには、 makeLogRecord() 関数を使ってください。

handleError()

emit() の処理中に発生したエラーを処理します。よくある原因は接続の消失です。次のイベント発生時に再試行できるようにソケットを閉じます。

makeSocket()

サブクラスで必要なソケット形式を詳細に定義できるようにするためのファクトリメソッドです。デフォルトの実装では、 TCP ソケット (socket.SOCK_STREAM) を生成します。

makePickle(record)

レコードの属性辞書を pickle してから先頭に長さ情報を付けてバイナリ形式にして、ソケットを介して送信できるようにして返します。

pickle が完全に安全というわけではないことに注意してください。セキュリティに関して心配なら、より安全なメカニズムを実装するためにこのメソッドをオーバーライドすると良いでしょう。例えば、 HMAC を使って pickle に署名して、受け取る側ではそれを検証することができます。あるいはまた、受け取る側でグローバルなオブジェクトの unpickle を無効にすることができます。

send(packet)

pickle された文字列 packet をソケットに送信します。この関数はネットワークがビジーの時に発生する部分的送信に対応しています。

createSocket()

ソケットの生成を試みます。失敗時には、指数的な減速アルゴリズムを使います。最初の失敗時には、ハンドラは送ろうとしていたメッセージを落とします。続くメッセージが同じインスタンスで扱われたとき、幾らかの時間が経過するまで接続を試みません。デフォルトのパラメタは、最初の遅延時間が 1 秒で、その遅延時間の後でそれでも接続が確保できないなら、遅延時間は 2 倍づつになり、最大で 30 秒になります。

この働きは、以下のハンドラ属性で制御されます:

retryStart (最初の遅延時間、デフォルトは 1.0 秒)。

retryFactor (乗数、デフォルトは 2.0)。

retryMax (最大遅延時間、デフォルトは 30.0 秒)。

これは、リモートリスナがハンドラが使われた 後に 起動すると、 (ハンドラは遅延が経過するまで接続を試みようとさえせず、遅延時間中に黙ってメッセージを落とすだけなので) メッセージが失われてしまうこともあるということです。

15.9.8. DatagramHandler

logging.handlers モジュールに含まれる DatagramHandler クラスは、 SocketHandler を継承しており、 UDP ソケットを介したログ記録メッセージの送信をサポートしています。

class logging.handlers.DatagramHandler(host, port)

アドレスが host および port で与えられた遠隔のマシンと通信するようにした DatagramHandler クラスのインスタンスを生成して返します。

emit()

レコードの属性辞書を pickle して、バイナリ形式でソケットに書き込みます。ソケット操作でエラーが生じた場合、暗黙のうちにパケットは捨てられます。事前に接続が失われていた場合、接続を再度確立します。受信端でレコードを unpickle して LogRecord にするには、 makeLogRecord() 関数を使ってください。

makeSocket()

ここで SocketHandler のファクトリメソッドをオーバライドして、 UDP ソケット (socket.SOCK_DGRAM) を生成しています。

send(s)

pickle された文字列をソケットに送信します。

15.9.9. SysLogHandler

logging.handlers モジュールに含まれる SysLogHandler クラスは、ログ記録メッセージを遠隔またはローカルの Unix syslog に送信する機能をサポートしています。

class logging.handlers.SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)

遠隔の Unix マシンと通信するための、 SysLogHandler クラスの新たなインスタンスを返します。マシンのアドレスは (host, port) のタプル形式をとる address で与えられます。 address が指定されない場合、 ('localhost', 514) が使われます。アドレスは UDP ソケットを使って開かれます。 (host, port) のタプル形式の代わりに文字列で “/dev/log” のように与えることもできます。この場合、 Unix ドメインソケットが syslog にメッセージを送るのに使われます。 facility が指定されない場合、 LOG_USER が使われます。開かれるソケットの型は、 socktype 引数に依り、デフォルトは socket.SOCK_DGRAM で、UDP ソケットを開きます。 (rsyslog のような新しい syslog デーモンと使うために) TCP ソケットを開くには、 socket.SOCK_STREAM の値を指定してください。

なお、あなたのサーバが UDP ポート 514 を聴取していないなら、 SysLogHandler が働かないことがあります。その場合は、あなたがドメインソケットに使うべきアドレスが何か調べてください - これはシステム依存です。例えば、Linux システムでは通常 ‘/dev/log’ ですが、 OS/X では ‘/var/run/syslog’ です。あなたのプラットフォームを調べ、適切なアドレスを使うことが必要になります (あなたのアプリケーションがいくつかのプラットフォームで動く必要があるなら、これを実行時に確かめなければならないかもしれません)。 Windows では、UDP オプションを使う必要性がかなり高いです。

バージョン 2.7 で変更: socktype が追加されました。

close()

遠隔ホストへのソケットを閉じます。

emit(record)

レコードは書式化された後、 syslog サーバに送信されます。例外情報が存在しても、サーバには 送信されません 。

encodePriority(facility, priority)

ファシリティおよび優先度を整数に符号化します。値は文字列でも整数でも渡すことができます。文字列が渡された場合、内部の対応付け辞書が使われ、整数に変換されます。

シンボリックな LOG_ 値は SysLogHandler で定義されています。これは sys/syslog.h ヘッダーファイルで定義された値を反映しています。

優先度

名前 (文字列) | シンボル値
alert | LOG_ALERT
crit or critical | LOG_CRIT
debug | LOG_DEBUG
emerg or panic | LOG_EMERG
err or error | LOG_ERR
info | LOG_INFO
notice | LOG_NOTICE
warn or warning | LOG_WARNING

ファシリティ

名前 (文字列) | シンボル値
auth | LOG_AUTH
authpriv | LOG_AUTHPRIV
cron | LOG_CRON
daemon | LOG_DAEMON
ftp | LOG_FTP
kern | LOG_KERN
lpr | LOG_LPR
mail | LOG_MAIL
news | LOG_NEWS
syslog | LOG_SYSLOG
user | LOG_USER
uucp | LOG_UUCP
local0 | LOG_LOCAL0
local1 | LOG_LOCAL1
local2 | LOG_LOCAL2
local3 | LOG_LOCAL3
local4 | LOG_LOCAL4
local5 | LOG_LOCAL5
local6 | LOG_LOCAL6
local7 | LOG_LOCAL7

mapPriority(levelname)

ログレベル名を syslog 優先度名に対応付けます。カスタムレベルを使用している場合や、デフォルトアルゴリズムがニーズに適していない場合には、このメソッドをオーバーライドする必要があるかもしれません。デフォルトアルゴリズムは、 DEBUG, INFO, WARNING, ERROR, CRITICAL を等価な syslog 名に、他のすべてのレベル名を “warning” に対応付けます。

15.9.10. NTEventLogHandler

logging.handlers モジュールに含まれる NTEventLogHandler クラスは、ログ記録メッセージをローカルな Windows NT, Windows 2000, または Windows XP のイベントログに送信する機能をサポートします。この機能を使えるようにするには、 Mark Hammond による Python 用 Win32 拡張パッケージをインストールする必要があります。

class logging.handlers.NTEventLogHandler(appname, dllname=None, logtype='Application')

NTEventLogHandler クラスの新たなインスタンスを返します。 appname はイベントログに表示する際のアプリケーション名を定義するために使われます。この名前を使って適切なレジストリエントリが生成されます。 dllname はログに保存するメッセージ定義の入った .dll または .exe ファイルへの完全修飾パス名を与えなければなりません (指定されない場合、 win32service.pyd が使われます - このライブラリは Win32 拡張とともにインストールされ、いくつかのプレースホルダとなるメッセージ定義を含んでいます)。これらのプレースホルダを利用すると、メッセージの発信源全体がログに記録されるため、イベントログは巨大になるので注意してください。 logtype は Application, System, Security のいずれかで、デフォルトは Application です。

close()

現時点では、イベントログエントリの発信源としてのアプリケーション名をレジストリから除去することはできます。しかしこれを行うと、イベントログビューアで意図した通りにログが見えなくなるでしょう - これはイベントログが .dll 名を取得するためにレジストリにアクセスできなければならないからです。現在のバージョンではこの操作を行いません。

emit(record)

メッセージ ID、イベントカテゴリ、イベント型を決定し、メッセージを NT イベントログに記録します。

getEventCategory(record)

レコードに対するイベントカテゴリを返します。自作のカテゴリを指定したい場合、このメソッドをオーバライドしてください。このクラスのバージョンのメソッドは 0 を返します。

getEventType(record)

レコードのイベント型を返します。自作の型を指定したい場合、このメソッドをオーバライドしてください。このクラスのバージョンのメソッドは、ハンドラの typemap 属性を使って対応付けを行います。この属性は __init__() で初期化され、 DEBUG, INFO, WARNING, ERROR, CRITICAL が入っています。自作のレベルを使っているのなら、このメソッドをオーバライドするか、ハンドラの typemap 属性に適切な辞書を配置する必要があるでしょう。

getMessageID(record)

レコードのメッセージ ID を返します。自作のメッセージを使っているのなら、ロガーに渡される msg を書式化文字列ではなく ID にします。その上で、辞書参照を行ってメッセージ ID を得ます。このクラスのバージョンでは 1 を返します。この値は win32service.pyd における基本メッセージ ID です。

15.9.11. SMTPHandler

logging.handlers モジュールに含まれる SMTPHandler クラスは、 SMTP を介したログ記録メッセージの送信機能をサポートします。

class logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None)

新たな SMTPHandler クラスのインスタンスを返します。インスタンスは email の from および to アドレス行、および subject 行とともに初期化されます。 toaddrs は文字列からなるリストでなければなりません。非標準の SMTP ポートを指定するには、 mailhost 引数に (host, port) のタプル形式を指定します。文字列を使った場合、標準の SMTP ポートが使われます。もし SMTP サーバが認証を必要とするならば、 (username, password) のタプル形式を credentials 引数に指定することができます。 secure が真であれば、ハンドラは email の伝達に TLS を使おうと試みます。

バージョン 2.6 で変更: credentials が追加されました。

バージョン 2.7 で変更: secure が追加されました。

emit(record)

レコードを書式化し、指定されたアドレスに送信します。

getSubject(record)

レコードに応じたサブジェクト行を指定したいなら、このメソッドをオーバライドしてください。

15.9.12. MemoryHandler

logging.handlers モジュールに含まれる MemoryHandler は、ログ記録するレコードをメモリ上にバッファリングし、定期的にその内容をターゲット (target) となるハンドラにフラッシュする機能をサポートしています。フラッシュ処理はバッファが一杯になるか、ある深刻度かそれ以上のレベルを持つイベントが観測された際に行われます。

MemoryHandler はより一般的な抽象クラス、 BufferingHandler のサブクラスです。この抽象クラスでは、ログ記録するレコードをメモリ上にバッファリングします。各レコードがバッファに追加される毎に、 shouldFlush() を呼び出してバッファをフラッシュすべきかどうか調べます。フラッシュする必要がある場合、 flush() が必要にして十分な処理を行うものと想定しています。

class logging.handlers.BufferingHandler(capacity)

指定した許容量のバッファでハンドラを初期化します。

emit(record)

レコードをバッファに追加します。 shouldFlush() が true を返す場合、バッファを処理するために flush() を呼び出します。

flush()

このメソッドをオーバライドして、自作のフラッシュ動作を実装することができます。このクラスのバージョンのメソッドでは、単にバッファの内容を削除して空にします。

shouldFlush(record)

バッファが許容量に達している場合に true を返します。このメソッドは自作のフラッシュ処理方針を実装するためにオーバライドすることができます。

class logging.handlers.MemoryHandler(capacity, flushLevel=ERROR, target=None)

MemoryHandler クラスの新たなインスタンスを返します。インスタンスはサイズ capacity のバッファとともに初期化されます。 flushLevel が指定されていない場合、 ERROR が使われます。 target が指定されていない場合、ハンドラが何らかの意味のある処理を行う前に setTarget() でターゲットを指定する必要があります。

close()

flush() を呼び出し、ターゲットを None に設定してバッファを消去します。

flush()

MemoryHandler の場合、フラッシュ処理は単に、バッファされたレコードをターゲットがあれば送信することを意味します。これと異なる動作を行いたい場合、オーバライドしてください。

setTarget(target)

ターゲットハンドラをこのハンドラに設定します。

shouldFlush(record)

バッファが一杯になっているか、 flushLevel またはそれ以上のレコードでないかを調べます。

15.9.13. HTTPHandler

logging.handlers モジュールに含まれる HTTPHandler クラスは、ログ記録メッセージを GET または POST セマンティクスを使って Web サーバに送信する機能をサポートしています。

class logging.handlers.HTTPHandler(host, url, method='GET')

HTTPHandler クラスの新たなインスタンスを返します。 host は特別なポートを使うことが必要な場合には、 host:port の形式で使うこともできます。 method が指定されなかった場合 GET が使われます。

emit(record)

レコードを URL エンコードされた辞書形式で Web サーバに送信します。

参考

Module logging

logging モジュールの API リファレンスです。

Module logging.config

logging モジュールの環境設定 API です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.10. getpass — 可搬性のあるパスワード入力機構

getpassモジュールは二つの関数を提供します:

getpass.getpass([prompt[, stream]])

エコーなしでユーザーにパスワードを入力させるプロンプト。ユーザーは prompt の文字列をプロンプトに使え、デフォルトは 'Password:' です。 Unixではプロンプトはファイルに似たオブジェクト stream へ出力されます。 stream のデフォルトは、制御端末(/dev/tty)か、それが利用できない場合は sys.stderr です。 (この引数は Windowsでは無視されます。)

もしエコー無しの入力が利用できない場合は、 getpass() は stream に警告メッセージを出力し、 sys.stdin から読み込み、 GetPassWarning 警告を発生させます。

利用できるシステム: Macintosh, Unix, Windows

バージョン 2.5 で変更: パラメータ stream の追加.

バージョン 2.6 で変更.

ノート

IDLE から getpass を呼び出した場合、入力はIDLEのウィンドウではなく、 IDLE を起動したターミナルから行われます。

exception getpass.GetPassWarning

UserWarning のサブクラスで、入力がエコーされてしまった場合に発生します。

getpass.getuser()

ユーザーの “ログイン名”を返します。　有効性:Unix、Windows

この関数は環境変数 LOGNAME USER LNAME USERNAME の順序でチェックして、最初の空ではない文字列が設定された値を返します。もし、なにも設定されていない場合はpwdモジュールが提供するシステム上のパスワードデータベースから返します。それ以外は、例外が上がります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.11. curses — 文字セル表示のための端末操作

バージョン 1.6 で変更: ncurses ライブラリのサポートを追加し、パッケージに変換しました.

curses モジュールは、可搬性のある端末操作を行うためのデファクトスタンダードである、curses ライブラリへのインタフェースを提供します。

Unix 環境では curses は非常に広く用いられていますが、DOS、OS2、そしておそらく他のシステムのバージョンも利用することができます。この拡張モジュールは Linux および BSD 系の Unixで動作するオープンソースの curses ライブラリである ncurses の API に合致するように設計されています。

ノート

version 5.4 から、ncurses ライブラリは nl_langinfo 関数を利用して非ASCIIデータをどう解釈するかを決定するようになりました。これは、アプリケーションは locale.setlocale() 関数を呼び出して、 Unicode文字列をシステムの利用可能なエンコーディングのどれかでエンコードする必要があることを意味します。この例では、システムのデフォルトエンコーディングを利用しています。

import locale
locale.setlocale(locale.LC_ALL, '')
code = locale.getpreferredencoding()

この後、 str.encode() を呼び出すときに code を利用します。

参考

Module curses.ascii

ロケール設定に関わらず ASCII 文字を扱うためのユーティリティ。

Module curses.panel

curses ウィンドウにデプス機能を追加するパネルスタック拡張。

Module curses.textpad

Emacs ライクなキーバインディングをサポートする編集可能な curses 用テキストウィジェット。

Module curses.wrapper

アプリケーションの起動時および終了時に適切な端末のセットアップとリセットを確実に行うための関数。

Python で Curses プログラミング

Andrew Kuchling および Eric Raymond によって書かれた、curses を Python で使うためのチュートリアルです。

Python ソースコードの Demo/curses/ ディレクトリには、このモジュールで提供されている curses バインディングを使ったプログラム例がいくつか収められています。

15.11.1. 関数

curses モジュールでは以下の例外を定義しています:

exception curses.error

curses ライブラリ関数がエラーを返した際に送出される例外です。

ノート

関数やメソッドにおけるオプションの引数 x および y がある場合、標準の値は常に現在のカーソルになります。オプションの attr がある場合、標準の値は A_NORMAL です。

curses では以下の関数を定義しています:

curses.baudrate()

端末の出力速度をビット／秒で返します。ソフトウェア端末エミュレータの場合、これは固定の高い値を持つことになります。この関数は歴史的な理由で入れられています; かつては、この関数は時間遅延を生成するための出力ループを書くために用いられたり、行速度に応じてインタフェースを切り替えたりするために用いられたりしていました。

curses.beep()

注意を促す短い音を鳴らします。

curses.can_change_color()

端末に表示される色をプログラマが変更できるか否かによって、真または偽を返します。

curses.cbreak()

cbreak モードに入ります。cbreak モード (“rare” モードと呼ばれることもあります) では、通常の tty 行バッファリングはオフにされ、文字を一文字一文字読むことができます。ただし、raw モードとは異なり、特殊文字 (割り込み:interrupt、終了:quit、一時停止:suspend、およびフロー制御) については、tty ドライバおよび呼び出し側のプログラムに対する通常の効果をもっています。まず raw() を呼び出し、次いで cbreak() を呼び出すと、端末を cbreak モードにします。

curses.color_content(color_number)

色 color_number の赤、緑、および青 (RGB) 要素の強度を返します。 color_number は 0 から COLORS の間でなければなりません。与えられた色の R、G、B、の値からなる三要素のタプルが返されます。この値は 0 (その成分はない) から 1000 (その成分の最大強度) の範囲をとります。

curses.color_pair(color_number)

指定された色の表示テキストにおける属性値を返します。属性値は A_STANDOUT, A_REVERSE 、およびその他の A_* 属性と組み合わせられています。 pair_number() はこの関数の逆です。

curses.curs_set(visibility)

カーソルの状態を設定します。 visibility は 0、1、または 2 に設定され、それぞれ不可視、通常、または非常に可視、を意味します。要求された可視属性を端末がサポートしている場合、以前のカーソル状態が返されます; そうでなければ例外が送出されます。多くの端末では、 “可視 (通常)” モードは下線カーソルで、”非常に可視” モードはブロックカーソルです。

curses.def_prog_mode()

現在の端末属性を、稼動中のプログラムが curses を使う際のモードである “プログラム” モードとして保存します。(このモードの反対は、プログラムが curses を使わない “シェル” モードです。) その後 reset_prog_mode() を呼ぶとこのモードを復旧します。

curses.def_shell_mode()

現在の端末属性を、稼動中のプログラムが curses を使っていないときのモードである “シェル” モードとして保存します。(このモードの反対は、プログラムが curses 機能を利用している “プログラム” モードです。) その後 reset_shell_mode() を呼ぶとこのモードを復旧します。

curses.delay_output(ms)

出力に ms ミリ秒の一時停止を入れます。

curses.doupdate()

物理スクリーン (physical screen) を更新します。curses ライブラリは、現在の物理スクリーンの内容と、次の状態として要求されている仮想スクリーンをそれぞれ表す、2 つのデータ構造を保持しています。 doupdate() は更新を適用し、物理スクリーンを仮想スクリーンに一致させます。

仮想スクリーンは addstr() のような書き込み操作をウィンドウに行った後に noutrefresh() を呼び出して更新することができます。通常の refresh() 呼び出しは、単に noutrefresh() を呼んだ後に doupdate() を呼ぶだけです; 複数のウィンドウを更新しなければならない場合、全てのウィンドウに対して noutrefresh() を呼び出した後、一度だけ doupdate() を呼ぶことで、パフォーマンスを向上させることができ、おそらくスクリーンのちらつきも押さえることができます。

curses.echo()

echo モードに入ります。 echo モードでは、各文字入力はスクリーン上に入力された通りにエコーバックされます。

curses.endwin()

ライブラリの非初期化を行い、端末を通常の状態に戻します。

curses.erasechar()

ユーザの現在の消去文字 (erase character) 設定を返します。 Unix オペレーティングシステムでは、この値は curses プログラムが制御している端末の属性であり、curses ライブラリ自体では設定されません。

curses.filter()

filter() ルーチンを使う場合、 initscr() を呼ぶ前に呼び出さなくてはなりません。この手順のもたらす効果は以下の通りです: まず二つの関数の呼び出しの間は、LINES は 1 に設定されます; clear、cup、cud、cud1、cuu1、cuu、vpa は無効化されます; home 文字列は cr の値に設定されます。これにより、カーソルは現在の行に制限されるので、スクリーンの更新も同様に制限されます。この関数は、スクリーンの他の部分に影響を及ぼさずに文字単位の行編集を行う場合に利用できます。

curses.flash()

スクリーンをフラッシュ(flash) します。すなわち、画面を色反転 (reverse-video) にして、短時間でもとにもどします。人によっては、 beep() で生成される可聴な注意音よりも、このような “可視ベル(visible bell)” を好みます。

curses.flushinp()

全ての入力バッファをフラッシュします。この関数は、ユーザによってすでに入力されているが、まだプログラムによって処理されていない全ての先行入力文字 (typeahead) を捨て去ります。

curses.getmouse()

getch() が KEY_MOUSE を返してマウスイベントを通知した後、この関数を呼んで待ち行列 (queue) 上に置かれているマウスイベントを取得しなければなりません。イベントは (id, x, y, z, bstate) の 5 要素のタプルで表現されています。 id は複数のデバイスを区別するための ID 値で、 x, y, z はイベントの座標値です (現在 z は使われていません)。 bstate は整数値で、その各ビットはイベントのタイプを示す値に設定されています。この値は以下に示す定数のうち一つまたはそれ以上のビット単位 OR になっています。以下の定数の n は 1 から 4 のボタン番号を示します: BUTTONn_PRESSED, BUTTONn_RELEASED, BUTTONn_CLICKED, BUTTONn_DOUBLE_CLICKED, BUTTONn_TRIPLE_CLICKED, BUTTON_SHIFT, BUTTON_CTRL, BUTTON_ALT.

curses.getsyx()

仮想スクリーンにおける現在のカーソル位置を y および x の順で返します。 leaveok が真に設定されていれば、 -1、-1 が返されます。

curses.getwin(file)

以前の putwin() 呼び出しでファイルに保存されている、ウィンドウ関連データを読み出します。次に、このルーチンはそのデータを使って新たなウィンドウを生成し初期化して、その新規ウィンドウオブジェクトを返します。

curses.has_colors()

端末が色表示を行える場合には真を返します。そうでない場合には偽を返します。

curses.has_ic()

端末が文字の挿入／削除機能を持つ場合に真を返します。この関数は、最近の端末エミュレータがどれもこの機能を持っているのと同じく、歴史的な理由だけのために含められています。

curses.has_il()

端末が行の挿入／削除機能を持つか、領域単位のスクロールによって機能をシミュレートできる場合に真を返します。この関数は、最近の端末エミュレータがどれもこの機能を持っているのと同じく、歴史的な理由だけのために含められています。

curses.has_key(ch)

キー値 ch をとり、現在の端末タイプがその値のキーを認識できる場合に真を返します。

curses.halfdelay(tenths)

半遅延モード、すなわち cbreak モードに似た、ユーザが打鍵した文字がすぐにプログラムで利用できるようになるモードで使われます。しかしながら、何も入力されなかった場合、 tenths 十秒後に例外が送出されます。 tenths の値は 1 から 255 の間でなければなりません。半遅延モードから抜けるには nocbreak() を使います。

curses.init_color(color_number, r, g, b)

色の定義を変更します。変更したい色番号と、その後に 3 つ組みの RGB 値 (赤、緑、青の成分の大きさ) をとります。 color_number の値は 0 から COLORS の間でなければなりません。 r, g, b の値は 0 から 1000 の間でなければなりません。 init_color() を使うと、スクリーン上でカラーが使用されている部分は全て新しい設定に即時変更されます。この関数はほとんどの端末で何も行いません; can_change_color() が 1 を返す場合にのみ動作します。

curses.init_pair(pair_number, fg, bg)

色ペアの定義を変更します。3 つの引数: 変更したい色ペア、前景色の色番号、背景色の色番号、をとります。 pair_number は 1 から COLOR_PAIRS -1 の間でなければなりません (0 色ペアは黒色背景に白色前景となるように設定されており、変更することができません) 。 fg および bg 引数は 0 と COLORS の間でなければなりません。色ペアが以前に初期化されていれば、スクリーンを更新して、指定された色ペアの部分を新たな設定に変更します。

curses.initscr()

ライブラリを初期化します。スクリーン全体をあらわす WindowObject を返します。

ノート

端末のオープン時にエラーが発生した場合、curses ライブラリによってインタープリタが終了される場合があります。

curses.isendwin()

endwin() がすでに呼び出されている (すなわち、curses ライブラリが非初期化されてしまっている) 場合に真を返します。

curses.keyname(k)

k に番号付けされているキーの名前を返します。印字可能な ASCII 文字を生成するキーの名前はそのキーの文字自体になります。コントロールキーと組み合わせたキーの名前は、キャレットの後に対応する ASCII 文字が続く 2 文字の文字列になります。Alt キーと組み合わせたキー (128-255) の名前は、先頭に ‘M-‘ が付き、その後に対応する ASCII 文字が続く文字列になります。

curses.killchar()

ユーザの現在の行削除文字を返します。 Unix オペレーティングシステムでは、この値は curses プログラムが制御している端末の属性であり、curses ライブラリ自体では設定されません。

curses.longname()

現在の端末について記述している terminfo の長形式 name フィールドが入った文字列を返します。verbose 形式記述の最大長は 128 文字です。この値は initscr() 呼び出しの後でのみ定義されています。

curses.meta(yes)

yes が 1 の場合、8 ビット文字を入力として許します。 yes が 0 の場合、 7 ビット文字だけを許します。

curses.mouseinterval(interval)

ボタンが押されてから離されるまでの時間をマウスクリック一回として認識する最大の時間間隔を設定します。以前の内部設定値を返します。標準の値は 200 ミリ秒、または 5 分の 1 秒です。

curses.mousemask(mousemask)

報告すべきマウスイベントを設定し、 (availmask, oldmask) の組からなるタプルを返します。 availmask はどの指定されたマウスイベントのどれが報告されるかを示します; どのイベント指定も完全に失敗した場合には 0 が返ります。 oldmask は与えられたウィンドウの以前のマウスイベントマスクです。この関数が呼ばれない限り、マウスイベントは何も報告されません。

curses.napms(ms)

ms ミリ秒スリープします。

curses.newpad(nlines, ncols)

与えられた行とカラム数を持つパッド (pad) データ構造を生成し、そのポインタを返します。パッドはウィンドウオブジェクトとして返されます。

パッドはウィンドウと同じようなものですが、スクリーンのサイズによる制限をうけず、スクリーンの特定の部分に関連付けられていなくてもかまいません。大きなウィンドウが必要であり、スクリーンにはそのウィンドウの一部しか一度に表示しない場合に使えます。 (スクロールや入力エコーなどによる) パッドに対する再描画は起こりません。パッドに対する refresh() および noutrefresh() メソッドは、パッド中の表示する部分と表示するために利用するスクリーン上の位置を指定する 6 つの引数が必要です。これらの引数は pminrow、 pmincol、 sminrow、 smincol、 smaxrow、smaxcol です; p で始まる引数はパッド中の表示領域の左上位置で、s で始まる引数はパッド領域を表示するスクリーン上のクリップ矩形を指定します。

curses.newwin([nlines, ncols], begin_y, begin_x)

左上の角が (begin_y, begin_x) で、高さ／幅が nlines / ncols の新規ウィンドウを返します。

標準では、ウィンドウは指定された位置からスクリーンの右下まで広がります。

curses.nl()

newlime モードに入ります。このモードはリターンキーを入力中の改行として変換し、出力時に改行文字を復帰 (return) と改行 (line-feed) に変換します。newline モードは初期化時にはオンになっています。

curses.nocbreak()

cbreak モードから離れます。行バッファリングを行う通常の “cooked” モードに戻ります。

curses.noecho()

echo モードから離れます。入力のエコーバックはオフにされます。

curses.nonl()

newline モードから離れます。入力時のリターンキーから改行への変換、および出力時の改行から復帰／改行への低レベル変換を無効化します (ただし、 addch('\n') の振る舞いは変更せず、仮想スクリーン上では常に復帰と改行に等しくなります)。変換をオフにすることで、 curses は水平方向の動きを少しだけ高速化できることがあります; また、入力中のリターンキーの検出ができるようになります。

curses.noqiflush()

noquiflush ルーチンを使うと、通常行われている INTR、QUIT、および SUSP 文字による入力および出力キューのフラッシュが行われなくなります。シグナルハンドラが終了した際、割り込みが発生しなかったかのように出力を続たい場合、ハンドラ中で noqiflush() を呼び出すことができます。

curses.noraw()

raw モードから離れます。行バッファリングを行う通常の “cooked” モードに戻ります。

curses.pair_content(pair_number)

要求された色ペア中の色を含む (fg, bg) からなるタプルを返します。 pair_number は 1 から COLOR_PAIRS - 1 の間でなければなりません。

curses.pair_number(attr)

attr に対する色ペアセットの番号を返します。 color_pair() はこの関数の逆に相当します。

curses.putp(string)

tputs(str, 1, putchar) と等価です; 現在の端末における、指定された terminfo 機能の値を出力します。putp の出力は常に標準出力に送られるので注意して下さい。

curses.qiflush([flag])

flag が偽なら、 noqiflush() を呼ぶのとと同じ効果です。 flag が真か、引数が与えられていない場合、制御文字が読み出された最にキューはフラッシュされます。

curses.raw()

raw モードに入ります。raw モードでは、通常の行バッファリングと割り込み (interrupt)、終了 (quit)、一時停止 (suspend)、およびフロー制御キーはオフになります; 文字は curses 入力関数に一文字づつ渡されます。

curses.reset_prog_mode()

端末を “program” モードに復旧し、予め def_prog_mode() で保存した内容に戻します。

curses.reset_shell_mode()

端末を “shell” モードに復旧し、予め def_shell_mode() で保存した内容に戻します。

curses.setsyx(y, x)

仮想スクリーンカーソルを y, x に設定します。 y および x が共に -1 の場合、leaveok が設定されます。

curses.setupterm([termstr, fd])

端末を初期化します。 termstr は文字列で、端末の名前を与えます; 省略された場合、TERM 環境変数の値が使われます。 fd は初期化シーケンスが送られる先のファイル記述子です; fd を与えない場合、 sys.stdout のファイル記述子が使われます。

curses.start_color()

プログラマがカラーを利用したい場合で、かつ他の何らかのカラー操作ルーチンを呼び出す前に呼び出さなくてはなりません。この関数は initscr() を呼んだ直後に呼ぶようにしておくとよいでしょう。

start_color() は 8 つの基本色 (黒、赤、緑、黄、青、マゼンタ、シアン、および白) と、色数の最大値と端末がサポートする色ペアの最大数が入っている、 curses モジュールにおける二つのグローバル変数、 COLORS および COLOR_PAIRS を初期化します。この関数はまた、色設定を端末のスイッチが入れられたときの状態に戻します。

curses.termattrs()

端末がサポートする全てのビデオ属性を論理和した値を返します。この情報は、curses プログラムがスクリーンの見え方を完全に制御する必要がある場合に便利です。

curses.termname()

14 文字以下になるように切り詰められた環境変数 TERM の値を返します。

curses.tigetflag(capname)

terminfo 機能名 capname に対応する機能値をブール値で返します。 capname がブール値で表される機能値でない場合 -1 が返され、機能がキャンセルされているか、端末記述上に見つからない場合には 0 を返します。

curses.tigetnum(capname)

terminfo 機能名 capname に対応する機能値を数値で返します。 capname が数値で表される機能値でない場合 -2 が返され、機能がキャンセルされているか、端末記述上に見つからない場合には -1 を返します。

curses.tigetstr(capname)

terminfo 機能名 capname に対応する機能値を文字列値で返します。 capname が文字列値で表される機能値でない場合や、機能がキャンセルされているか、端末記述上に見つからない場合には None を返します。

curses.tparm(str[, ...])

str を与えられたパラメタを使って文字列にインスタンス化します。 str は terminfo データベースから得られたパラメタを持つ文字列でなければなりません。例えば、 tparm(tigetstr("cup"), 5, 3) は '\033[6;4H' のようになります。厳密には端末の形式によって異なる結果となります。

curses.typeahead(fd)

先読みチェックに使うためのファイル記述子 fd を指定します。 fd が -1 の場合、先読みチェックは行われません。

curses ライブラリはスクリーンを更新する間、先読み文字列を定期的に検索することで “行はみ出し最適化 (line-breakout optimization)” を行います。入力が得られ、かつ入力は端末からのものである場合、現在行おうとしている更新は refresh や doupdate を再度呼び出すまで先送りにします。この関数は異なるファイル記述子で先読みチェックを行うように指定することができます。

curses.unctrl(ch)

ch の印字可能な表現を文字列で返します。制御文字は例えば ^C のようにキャレットに続く文字として表示されます。印字可能文字はそのままです。

curses.ungetch(ch)

ch をプッシュして、 getch() を次に呼び出したときに返されるようにします。

ノート

getch() を呼び出すまでは ch は一つしかプッシュできません。

curses.ungetmouse(id, x, y, z, bstate)

与えられた状態データが関連付けられた KEY_MOUSE イベントを入力キューにプッシュします。

curses.use_env(flag)

この関数を使う場合、 initscr() または newterm を呼ぶ前に呼び出さなくてはなりません。 flag が偽の場合、環境変数 LINES および COLUMNS の値 (これらは標準の設定で使われます) の値が設定されていたり、curses がウィンドウ内で動作して (この場合 LINES や COLUMNS が設定されていないとウィンドウのサイズを使います) いても、terminfo データベースに指定された lines および columns の値を使います。

curses.use_default_colors()

この機能をサポートしている端末上で、色の値としてデフォルト値を使う設定をします。あなたのアプリケーションで透過性とサポートするためにこの関数を使ってください。デフォルトの色は色番号-1に割り当てられます。

この関数を呼んだ後、たとえば init_pair(x, curses.COLOR_RED, -1) は色ペア x を赤い前景色とデフォルトの背景色に初期化します。

15.11.2. Window オブジェクト

上記の initscr() や newwin() が返すウィンドウは、以下のメソッドを持ちます:

window.addch([y, x], ch[, attr])

ノート

ここで 文字 は Python 文字 (長さ 1 の文字列) C における文字 (ASCII コード) を意味します。(この注釈は文字について触れているドキュメントではどこでも当てはまります。) 組み込みの ord() は文字列をコードの集まりにする際に便利です。

(y, x) にある文字 ch を属性 attr で描画します。このときその場所に以前描画された文字は上書きされます。標準の設定では、文字の位置および属性はウィンドウオブジェクトにおける現在の設定になります。

window.addnstr([y, x], str, n[, attr])

文字列 str から最大で n 文字を (y, x) に属性 attr で描画します。以前ディスプレイにあった内容はすべて上書きされます。

window.addstr([y, x], str[, attr])

(y, x) に文字列 str を属性 attr で描画します。以前ディスプレイにあった内容はすべて上書きされます。

window.attroff(attr)

現在のウィンドウに書き込まれた全ての内容に対し “バックグラウンド” に設定された属性 attr を除去します。

window.attron(attr)

現在のウィンドウに書き込まれた全ての内容に対し “バックグラウンド” に属性 attr を追加します。

window.attrset(attr)

“バックグラウンド” の属性セットを attr に設定します。初期値は 0 (属性なし) です。

window.bkgd(ch[, attr])

ウィンドウ上の背景プロパティを、 attr を属性とする文字 ch に設定します。変更はそのウィンドウ中の全ての文字に以下のようにして適用されます:

ウィンドウ中の全ての文字の属性が新たな背景属性に変更されます。

以前の背景文字が出現すると、常に新たな背景文字に変更されます。

window.bkgdset(ch[, attr])

ウィンドウの背景を設定します。ウィンドウの背景は、文字と何らかの属性の組み合わせから成り立ちます。背景情報の属性の部分は、ウィンドウ上に描画されている空白でない全ての文字と組み合わされ (OR され) ます。空白文字には文字部分と属性部分の両方が組み合わされます。背景は文字のプロパティとなり、スクロールや行／文字の挿入／削除操作の際には文字と一緒に移動します。

window.border([ls[, rs[, ts[, bs[, tl[, tr[, bl[, br]]]]]]]])

ウィンドウの縁に境界線を描画します。各引数には境界の特定部分を表現するために使われる文字を指定します; 詳細は以下のテーブルを参照してください。文字は整数または 1 文字からなる文字列で指定されます。

ノート

どの引数も、 0 を指定した場合標準設定の文字が使われるようになります。キーワード引数は使うことが できません 。標準の設定はテーブル中に示されています:

引数 | 記述 | 標準の設定値
ls | 左側 | ACS_VLINE
rs | 右側 | ACS_VLINE
ts | 上側 | ACS_HLINE
bs | 下側 | ACS_HLINE
tl | 左上の角 | ACS_ULCORNER
tr | 右上の角 | ACS_URCORNER
bl | 左下の角 | ACS_LLCORNER
br | 右下の角 | ACS_LRCORNER

window.box([vertch, horch])

border() と同様ですが、 ls および rs は共に vertch で、 ts および bs は共に horch です。この関数では、角に使われる文字は常に標準設定の値です。

window.chgat([y, x, ] [num,] attr)

現在のカーソルのポジションか、引数が指定された場合は (y, x) から、 num 文字の属性を設定します。 num が指定されない、または num = -1 の場合は、属性はその行の終わりまでのすべての文字に適用されます。この関数はカーソルを移動しません。変更された行に対して touchline() メソッドが呼び出されるので、その行の内容は次のwindow refreshの時に再描画されます。

window.clear()

erase() に似ていますが、次に refresh() が呼び出された際に全てのウィンドウを再描画するようにします。

window.clearok(yes)

yes が 1 ならば、次の refresh() はウィンドウを完全に消去します。

window.clrtobot()

カーソルの位置からウィンドウの端までを消去します: カーソル以降の全ての行が削除されるため、 clrtoeol() が実行されたのとおなじになります。

window.clrtoeol()

カーソル位置から行末までを消去します。

window.cursyncup()

ウィンドウの全ての親ウィンドウについて、現在のカーソル位置を反映するよう更新します。

window.delch([y, x])

(y, x) にある文字を削除します。 Delete any character at (y, x).

window.deleteln()

カーソルの下にある行を削除します。後続の行はすべて 1 行上に移動します。

window.derwin([nlines, ncols], begin_y, begin_x)

“derive window (ウィンドウを派生する)” の短縮形です。 derwin() は subwin() と同じですが、 begin_y および begin+x はスクリーン全体の原点ではなく、ウィンドウの原点からの相対位置です。派生したウィンドウオブジェクトが返されます。

window.echochar(ch[, attr])

文字 ch に属性 attr を付与し、即座に refresh() をウィンドウに対して呼び出します。

window.enclose(y, x)

与えられた文字セル座標をスクリーン原点から相対的なものとし、ウィンドウの中に含まれるかを調べて、真または偽を返します。スクリーン上のウィンドウの一部がマウスイベントの発生場所を含むかどうかを調べる上で便利です。

window.erase()

ウィンドウをクリアします。

window.getbegyx()

左上の角の座標をあらわすタプル (y, x) を返します。

window.getch([y, x])

文字を取得します。返される整数は ASCII の範囲の値となる わけではない ので注意してください。ファンクションキー、キーパッド上のキー等は 256 よりも大きな数字を返します。無遅延 (no-delay) モードでは、入力がない場合 -1 が返されます。それ以外の場合は、 getch() はキー入力を待ちます。

window.getkey([y, x])

文字を取得し、 getch() のように整数を返す代わりに文字列を返します。ファンクションキー、キーバットキーなどはキー名の入った複数バイトからなる文字列を返します。無遅延モードでは、入力がない場合例外が送出されます。

window.getmaxyx()

ウィンドウの高さおよび幅を表すタプル (y, x) を返します。

window.getparyx()

親ウィンドウ中におけるウィンドウの開始位置を x と y の二つの整数で返します。ウィンドウに親ウィンドウがない場合 -1,-1 を返します。

window.getstr([y, x])

原始的な文字編集機能つきで、ユーザの入力文字列を読み取ります。

window.getyx()

ウィンドウの左上角からの相対で表した現在のカーソル位置をタプル (y, x) で返します。

window.hline([y, x], ch, n)

(y, x) から始まり、 n の長さを持つ、文字 ch で作られる水平線を表示します。

window.idcok(flag)

flag が偽の場合、curses は端末のハードウェアによる文字挿入／削除機能を使おうとしなくなります; flag が真ならば、文字挿入／削除は有効にされます。curses が最初に初期化された際には文字挿入／削除は標準の設定で有効になっています。

window.idlok(yes)

yes が 1 であれば、 curses はハードウェアの行編集機能を利用しようと試みます。行挿入／削除は無効化されます。

window.immedok(flag)

flag が真ならば、ウィンドウイメージ内における何らかの変更があるとウィンドウを更新するようになります; すなわち、 refresh() を自分で呼ばなくても良くなります。とはいえ、wrefresh を繰り返し呼び出すことになるため、この操作はかなりパフォーマンスを低下させます。標準の設定では無効になっています。

window.inch([y, x])

ウィンドウの指定の位置の文字を返します。下位 8 ビットが常に文字となり、それより上のビットは属性を表します。

window.insch([y, x], ch[, attr])

(y, x) に文字 ch を属性 attr で描画し、行の x からの内容を 1 文字分右にずらします。

window.insdelln(nlines)

nlines 行を指定されたウィンドウの現在の行の上に挿入します。その下にある nlines 行は失われます。負の nlines を指定すると、カーソルのある行以降の nlines を削除し、削除された行の後ろに続く内容が上に来ます。その下にある nlines は消去されます。現在のカーソル位置はそのままです。

window.insertln()

カーソルの下に空行を 1 行入れます。それ以降の行は 1 行づつ下に移動します。

window.insnstr([y, x], str, n[, attr])

文字列をカーソルの下にある文字の前に (一行に収まるだけ) 最大 n 文字挿入します。 n がゼロまたは負の値の場合、文字列全体が挿入されます。カーソルの右にある全ての文字は右に移動し、行の左端にある文字は失われます。カーソル位置は (y, x が指定されていた場合はそこに移動しますが、その後は) 変化しません。

window.insstr([y, x], str[, attr])

キャラクタ文字列を (行に収まるだけ) カーソルより前に挿入します。カーソルの右側にある文字は全て右にシフトし、行の右端の文字は失われます。カーソル位置は (y, x が指定されていた場合はそこに移動しますが、その後は) 変化しません。

window.instr([y, x] [, n])

現在のカーソル位置、または y, x が指定されている場合にはその場所から始まるキャラクタ文字列をウィンドウから抽出して返します。属性は文字から剥ぎ取られます。 n が指定された場合、 instr() は (末尾の NUL 文字を除いて) 最大で n 文字までの長さからなる文字列を返します。

window.is_linetouched(line)

指定した行が、最後に refresh() を呼んだ時から変更されている場合に真を返します; そうでない場合には偽を返します。 line が現在のウィンドウ上の有効な行でない場合、 curses.error 例外を送出します。

window.is_wintouched()

指定したウィンドウが、最後に refresh() を呼んだ時から変更されている場合に真を返します; そうでない場合には偽を返します。

window.keypad(yes)

yes が 1 の場合、ある種のキー (キーパッドやファンクションキー) によって生成されたエスケープシーケンスは curses で解釈されます。 yes が 0 の場合、エスケープシーケンスは入力ストリームにそのままの状態で残されます。

window.leaveok(yes)

yes が 1 の場合、カーソルは “カーソル位置” に移動せず現在の場所にとどめます。これにより、カーソルの移動を減らせる可能性があります。この場合、カーソルは不可視にされます。

yes が 0 の場合、カーソルは更新の際に常に “カーソル位置” に移動します。

window.move(new_y, new_x)

カーソルを (new_y, new_x) に移動します。

window.mvderwin(y, x)

ウィンドウを親ウィンドウの中で移動します。ウィンドウのスクリーン相対となるパラメタ群は変化しません。このルーチンは親ウィンドウの一部をスクリーン上の同じ物理位置に表示する際に用いられます。

window.mvwin(new_y, new_x)

ウィンドウの左上角が (new_y, new_x) になるように移動します。

window.nodelay(yes)

yes が 1 の場合、 getch() は非ブロックで動作します。

window.notimeout(yes)

yes が 1 の場合、エスケープシーケンスはタイムアウトしなくなります。

yes が 0 の場合、数ミリ秒間の間エスケープシーケンスは解釈されず、入力ストリーム中にそのままの状態で残されます。

window.noutrefresh()

更新をマークはしますが待機します。この関数はウィンドウのデータ構造を表現したい内容を反映するように更新しますが、物理スクリーン上に反映させるための強制更新を行いません。更新を行うためには doupdate() を呼び出します。

window.overlay(destwin[, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])

ウィンドウを destwin の上に重ね書き (overlay) します。ウィンドウは同じサイズである必要はなく、重なっている領域だけが複写されます。この複写は非破壊的 (non-destructive) です。これは現在の背景文字が destwin の内容を上書きしないことを意味します。

複写領域をきめ細かく制御するために、 overlay() の第二形式を使うことができます。 sminrow および smincol は元のウィンドウの左上の座標で、他の変数は destwin 内の矩形を表します。

window.overwrite(destwin[, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol])

destwin の上にウィンドウの内容を上書き (overwrite) します。ウィンドウは同じサイズである必要はなく、重なっている領域だけが複写されます。この複写は破壊的 (destructive) です。これは現在の背景文字が destwin の内容を上書きすることを意味します。

複写領域をきめ細かく制御するために、 overlay() の第二形式を使うことができます。 sminrow および smincol は元のウィンドウの左上の座標で、他の変数は destwin 内の矩形を表します。

window.putwin(file)

ウィンドウに関連付けられている全てのデータを与えられたファイルオブジェクトに書き込みます。この情報は後に getwin() 関数を使って取得することができます。

window.redrawln(beg, num)

beg 行から始まる num スクリーン行の表示内容が壊れており、次の refresh() 呼び出しで完全に再描画されなければならないことを通知します。

window.redrawwin()

ウィンドウ全体を更新 (touch) し、次の refresh() 呼び出しで完全に再描画されるようにします。

window.refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])

ディスプレイを即時更新し (現実のウィンドウとこれまでの描画／削除メソッドの内容との同期をとり) ます。

6 つのオプション引数はウィンドウが newpad() で生成された場合にのみ指定することができます。追加の引数はパッドやスクリーンのどの部分が含まれるのかを示すために必要です。 pminrow および pmincol にはパッドが表示されている矩形の左上角を指定します。 sminrow, smincol, smaxrow, および smaxcol には、スクリーン上に表示される矩形の縁を指定します。パッド内に表示される矩形の右下角はスクリーン座標から計算されるので、矩形は同じサイズでなければなりません。矩形は両方とも、それぞれのウィンドウ構造内に完全に含まれていなければなりません。 pminrow, pmincol, sminrow, または smincol に負の値を指定すると、ゼロを指定したものとして扱われます。

window.scroll([lines=1])

スクリーンまたはスクロール領域を上に lines 行スクロールします。

window.scrollok(flag)

ウィンドウのカーソルが、最下行で改行を行ったり最後の文字を入力したりした結果、ウィンドウやスクロール領域の縁からはみ出して移動した際の動作を制御します。 flag が偽の場合、カーソルは最下行にそのままにしておかれます。 flag が真の場合、ウィンドウは 1 行上にスクロールします。端末の物理スクロール効果を得るためには idlok() も呼び出す必要があるので注意してください。

window.setscrreg(top, bottom)

スクロール領域を top から bottom に設定します。スクロール動作は全てこの領域で行われます。

window.standend()

A_STANDOUT 属性をオフにします。端末によっては、この操作で全ての属性をオフにする副作用が発生します。

window.standout()

A_STANDOUT 属性をオンにします。

window.subpad([nlines, ncols], begin_y, begin_x)

左上の角が (begin_y, begin_x) にあり、幅／高さがそれぞれ ncols / nlines であるようなサブウィンドウを返します。

window.subwin([nlines, ncols], begin_y, begin_x)

左上の角が (begin_y, begin_x) にあり、幅／高さがそれぞれ ncols / nlines であるようなサブウィンドウを返します。

標準の設定では、サブウィンドウは指定された場所からウィンドウの右下角まで広がります。

window.syncdown()

このウィンドウの上位のウィンドウのいずれかで更新(touch)された各場所をこのウィンドウ内でも更新します。このルーチンは refresh() から呼び出されるので、手動で呼び出す必要はほとんどないはずです。

window.syncok(flag)

flag を真にして呼び出すと、ウィンドウが変更された際は常に syncup() を自動的に呼ぶようになります。

window.syncup()

ウィンドウ内で更新 (touch) した場所を、上位の全てのウィンドウ内でも更新します。

window.timeout(delay)

ウィンドウのブロックまたは非ブロック読み込み動作を設定します。 delay が負の場合、ブロック読み出しが使われ、入力を無期限で待ち受けます。 delay がゼロの場合、非ブロック読み出しが使われ、入力待ちの文字がない場合 getch() は -1 を返します。 delay が正の値であれば、 getch() は delay ミリ秒間ブロックし、ブロック後の時点で入力がない場合には -1 を返します。

window.touchline(start, count[, changed])

start から始まる count 行が変更されたかのように振舞わせます。もし changed が与えられた場合、その引数は指定された行が変更された(changed=1)か、変更されていないか(changed=0)を指定します。

window.touchwin()

描画を最適化するために、全てのウィンドウが変更されたかのように振舞わせます。

window.untouchwin()

ウィンドウ内の全ての行を、最後に refresh() を呼んだ際から変更されていないものとしてマークします。

window.vline([y, x], ch, n)

(y, x) から始まり、 n の長さを持つ、文字 ch で作られる垂直線を表示します。

15.11.3. 定数

curses モジュールでは以下のデータメンバを定義しています:

curses.ERR

getch() のような整数を返す curses ルーチンのいくつかは、失敗した際に ERR を返します。

curses.OK

napms() のような整数を返す curses ルーチンのいくつかは、成功した際に OK を返します。

curses.version

モジュールの現在のバージョンを表現する文字列です。 __version__ でも取得できます。

以下に文字セルの属性を指定するために利用可能ないくつかの定数を示します:

属性 | 意味
A_ALTCHARSET | 代用文字 (alternate character) モード。
A_BLINK | 点滅モード。
A_BOLD | 太字モード。
A_DIM | 低輝度モード。
A_NORMAL | 通常の属性。
A_REVERSE | 背景色と前景色を入れ替える。
A_STANDOUT | 強調モード。
A_UNDERLINE | 下線モード。

キーは KEY_ で始まる名前をもつ整数定数です。利用可能なキーキャップはシステムに依存します。

キー定数 | キー
KEY_MIN | 最小のキー値
KEY_BREAK | ブレーク (Break, 信頼できません)
KEY_DOWN | 下向き矢印 (Down-arrow)
KEY_UP | 上向き矢印 (Up-arrow)
KEY_LEFT | 左向き矢印 (Left-arrow)
KEY_RIGHT | 右向き矢印 (Right-arrow)
KEY_HOME | ホームキー (Home, または上左矢印)
KEY_BACKSPACE | バックスペース (Backspace, 信頼できません)
KEY_F0 | ファンクションキー 64 個までサポートされています。
KEY_Fn | ファンクションキー n の値
KEY_DL | 行削除 (Delete line)
KEY_IL | 行挿入 (Insert line)
KEY_DC | 文字削除 (Delete char)
KEY_IC | 文字挿入、または文字挿入モードへ入る
KEY_EIC | 文字挿入モードから抜ける
KEY_CLEAR | 画面消去
KEY_EOS | 画面の末端まで消去
KEY_EOL | 行末端まで消去
KEY_SF | 前に 1 行スクロール
KEY_SR | 後ろ (逆方向) に 1 行スクロール
KEY_NPAGE | 次のページ (Page Next)
KEY_PPAGE | 前のページ (Page Prev)
KEY_STAB | タブ設定
KEY_CTAB | タブリセット
KEY_CATAB | 全てのタブをリセット
KEY_ENTER | 入力または送信 (信頼できません)
KEY_SRESET | ソフトウェア (部分的) リセット (信頼できません)
KEY_RESET | リセットまたはハードリセット (信頼できません)
KEY_PRINT | 印刷 (Print)
KEY_LL | 下ホーム (Home down) または最下行 (左下)
KEY_A1 | キーパッドの左上キー
KEY_A3 | キーパッドの右上キー
KEY_B2 | キーパッドの中央キー
KEY_C1 | キーパッドの左下キー
KEY_C3 | キーパッドの右下キー
KEY_BTAB | Back tab
KEY_BEG | 開始 (Beg)
KEY_CANCEL | キャンセル (Cancel)
KEY_CLOSE | 閉じる (Close)
KEY_COMMAND | コマンド (Cmd)
KEY_COPY | コピー (Copy)
KEY_CREATE | 生成 (Create)
KEY_END | 終了 (End)
KEY_EXIT | 終了 (Exit)
KEY_FIND | 検索 (Find)
KEY_HELP | ヘルプ (Help)
KEY_MARK | マーク (Mark)
KEY_MESSAGE | メッセージ (Message)
KEY_MOVE | 移動 (Move)
KEY_NEXT | 次へ (Next)
KEY_OPEN | 開く (Open)
KEY_OPTIONS | オプション (Options)
KEY_PREVIOUS | 前へ (Prev)
KEY_REDO | やり直し (Redo)
KEY_REFERENCE | 参照 (Ref)
KEY_REFRESH | 更新 (Refresh)
KEY_REPLACE | 置換 (Replace)
KEY_RESTART | 再起動 (Restart)
KEY_RESUME | 再開 (Resume)
KEY_SAVE | 保存 (Save)
KEY_SBEG | シフト付き開始 Beg
KEY_SCANCEL | シフト付きキャンセル Cancel
KEY_SCOMMAND | シフト付き Command
KEY_SCOPY | シフト付き Copy
KEY_SCREATE | シフト付き Create
KEY_SDC | シフト付き Delete char
KEY_SDL | シフト付き Delete line
KEY_SELECT | 選択 (Select)
KEY_SEND | シフト付き End
KEY_SEOL | シフト付き Clear line
KEY_SEXIT | シフト付き Dxit
KEY_SFIND | シフト付き Find
KEY_SHELP | シフト付き Help
KEY_SHOME | シフト付き Home
KEY_SIC | シフト付き Input
KEY_SLEFT | シフト付き Left arrow
KEY_SMESSAGE | シフト付き Message
KEY_SMOVE | シフト付き Move
KEY_SNEXT | シフト付き Next
KEY_SOPTIONS | シフト付き Options
KEY_SPREVIOUS | シフト付き Prev
KEY_SPRINT | シフト付き Print
KEY_SREDO | シフト付き Redo
KEY_SREPLACE | シフト付き Replace
KEY_SRIGHT | シフト付き Right arrow
KEY_SRSUME | シフト付き Resume
KEY_SSAVE | シフト付き Save
KEY_SSUSPEND | シフト付き Suspend
KEY_SUNDO | シフト付き Undo
KEY_SUSPEND | 一時停止 (Suspend)
KEY_UNDO | 元に戻す (Undo)
KEY_MOUSE | マウスイベント通知
KEY_RESIZE | 端末リサイズイベント
KEY_MAX | 最大キー値

VT100 や、X 端末エミュレータのようなソフトウェアエミュレーションでは、通常少なくとも 4 つのファンクションキー (KEY_F1, KEY_F2, KEY_F3, KEY_F4) が利用可能で、矢印キーは KEY_UP, KEY_DOWN, KEY_LEFT および KEY_RIGHT が対応付けられています。計算機に PC キーボードが付属している場合、矢印キーと 12 個のファンクションキー (古い PC キーボードには 10 個しかファンクションキーがないかもしれません) が利用できると考えてよいでしょう; また、以下のキーパッド対応付けは標準的なものです:

キーキャップ | 定数
Insert | KEY_IC
Delete | KEY_DC
Home | KEY_HOME
End | KEY_END
Page Up | KEY_NPAGE
Page Down | KEY_PPAGE

代用文字 (alternative character) セットを以下の表に列挙します。これらは VT100 端末から継承したものであり、X 端末のようなソフトウェアエミュレーション上で一般に利用可能なものです。グラフィックが利用できない場合、curses は印字可能 ASCII文字による粗雑な近似出力を行います。

ノート

これらは initscr() が呼び出された後でしか利用できません。

ACS コード | 意味
ACS_BBSS | 右上角の別名
ACS_BLOCK | 黒四角ブロック
ACS_BOARD | 白四角ブロック
ACS_BSBS | 水平線の別名
ACS_BSSB | 左上角の別名
ACS_BSSS | 上向き T 字罫線の別名
ACS_BTEE | 下向き T 字罫線
ACS_BULLET | 黒丸(bullet)
ACS_CKBOARD | チェッカーボードパタン (点描)
ACS_DARROW | 下向き矢印
ACS_DEGREE | 度
ACS_DIAMOND | ダイアモンド
ACS_GEQUAL | より大きいか等しい
ACS_HLINE | 水平線
ACS_LANTERN | ランタン(lantern) シンボル
ACS_LARROW | left arrow
ACS_LEQUAL | より小さいか等しい
ACS_LLCORNER | 左下角
ACS_LRCORNER | 右下角
ACS_LTEE | left tee
ACS_NEQUAL | 等号否定
ACS_PI | パイ記号
ACS_PLMINUS | プラスマイナス記号
ACS_PLUS | 大プラス記号
ACS_RARROW | 右向き矢印
ACS_RTEE | 右向き T 字罫線
ACS_S1 | scan line 1
ACS_S3 | scan line 3
ACS_S7 | scan line 7
ACS_S9 | scan line 9
ACS_SBBS | 右下角の別名
ACS_SBSB | 垂直線の別名
ACS_SBSS | 右向き T 字罫線の別名
ACS_SSBB | 左下角の別名
ACS_SSBS | 下向き T 字罫線の別名
ACS_SSSB | 左向き T 字罫線の別名
ACS_SSSS | 交差罫線または大プラス記号の別名
ACS_STERLING | ポンドスターリング記号
ACS_TTEE | 上向き T 字罫線
ACS_UARROW | 上向き矢印
ACS_ULCORNER | 左上角
ACS_URCORNER | 右上角
ACS_VLINE | 垂直線

以下のテーブルは定義済みの色を列挙したものです:

定数 | 色
COLOR_BLACK | 黒
COLOR_BLUE | 青
COLOR_CYAN | シアン (薄く緑がかった青)
COLOR_GREEN | 緑
COLOR_MAGENTA | マゼンタ (紫がかった赤)
COLOR_RED | 赤
COLOR_WHITE | 白
COLOR_YELLOW | 黄色

15.12. curses.textpad — curses プログラムのためのテキスト入力ウィジェット

バージョン 1.6 で追加.

curses.textpad モジュールでは、curses ウィンドウ内での基本的なテキスト編集を処理し、Emacs に似た (すなわち Netscape Navigator, BBedit 6.x, FrameMaker, その他諸々のプログラムとも似た) キーバインドをサポートしている Textbox クラスを提供します。このモジュールではまた、テキストボックスを枠で囲むなどの目的のために有用な、矩形描画関数を提供しています。

curses.textpad モジュールでは以下の関数を定義しています:

curses.textpad.rectangle(win, uly, ulx, lry, lrx)

矩形を描画します。最初の引数はウィンドウオブジェクトでなければなりません; 残りの引数はそのウィンドウからの相対座標になります。 2 番目および 3 番目の引数は描画すべき矩形の左上角の y および x 座標です; 4 番目および 5 番目の引数は右下角の y および x 座標です。矩形は、 VT100/IBM PC におけるフォーム文字を利用できる端末(xterm やその他のほとんどのソフトウェア端末エミュレータを含む) ではそれを使って描画されます。そうでなければ ASCII 文字のダッシュ、垂直バー、およびプラス記号で描画されます。

15.12.1. Textbox オブジェクト

以下のような Textbox オブジェクトをインスタンス生成することができます:

class curses.textpad.Textbox(win)

テキストボックスウィジェットオブジェクトを返します。 win 引数は、テキストボックスを入れるための WindowObject でなければなりません。テキストボックスの編集カーソルは、最初はテキストボックスが入っているウィンドウの左上角に配置され、その座標は (0, 0) です。インスタンスの stripspaces フラグの初期値はオンに設定されます。

Textbox オブジェクトは以下のメソッドを持ちます:

edit([validator])

普段使うことになるエントリポイントです。終了キーストロークの一つが入力されるまで編集キーストロークを受け付けます。 validator を与える場合、関数でなければなりません。 validator はキーストロークが入力されるたびにそのキーストロークが引数となって呼び出されます; 返された値に対して、コマンドキーストロークとして解釈が行われます。このメソッドはウィンドウの内容を文字列として返します; ウィンドウ内の空白が含められるかどうかは stripspaces メンバで決められます。

do_command(ch)

単一のコマンドキーストロークを処理します。以下にサポートされている特殊キーストロークを示します:

キーストローク | 動作
Control-A | ウィンドウの左端に移動します。
Control-B | カーソルを左へ移動し、必要なら前の行に折り返します。
Control-D | カーソル下の文字を削除します。
Control-E | 右端 (stripspaces がオフのとき) または行末 (stripspaces がオンのとき) に移動します。
Control-F | カーソルを右に移動し、必要なら次の行に折り返します。
Control-G | ウィンドウを終了し、その内容を返します。
Control-H | 逆方向に文字を削除します。(バックスペース)
Control-J | ウィンドウが 1 行であれば終了し、そうでなければ新しい行を挿入します。
Control-K | 行が空白行ならその行全体を削除し、そうでなければカーソル以降行末までを消去します。
Control-L | スクリーンを更新します。
Control-N | カーソルを下に移動します; 1 行下に移動します。
Control-O | カーソルの場所に空行を 1 行挿入します。
Control-P | カーソルを上に移動します; 1 行上に移動します。

移動操作は、カーソルがウィンドウの縁にあって移動ができない場合には何も行いません。場合によっては、以下のような同義のキーストロークがサポートされています:

定数 | キーストローク
KEY_LEFT | Control-B
KEY_RIGHT | Control-F
KEY_UP | Control-P
KEY_DOWN | Control-N
KEY_BACKSPACE | Control-h

他のキーストロークは、与えられた文字を挿入し、(行折り返し付きで) 右に移動するコマンドとして扱われます。

gather()

このメソッドはウィンドウの内容を文字列として返します; ウィンドウ内の空白が含められるかどうかは stripspaces メンバ変数で決められます。

stripspaces

このデータメンバはウィンドウ内の空白領域の解釈方法を制御するためのフラグです。フラグがオンに設定されている場合、各行の末端にある空白領域は無視されます; すなわち、末端空白領域にカーソルが入ると、その場所の代わりに行の末尾にカーソルが移動します。また、末端の空白領域はウィンドウの内容を取得する際に剥ぎ取られます。

15.13. curses.wrapper — curses プログラムのための端末ハンドラ

バージョン 1.6 で追加.

このモジュールでは関数 wrapper() 一つを提供しています。これは curses 使用アプリケーションの残りの部分となるもう一つの関数です。アプリケーションが例外を送出した場合、 wrapper() は例外を再送出してトレースバックを生成する前に端末を正常な状態に復元します。

curses.wrapper.wrapper(func, ...)

curses を初期化し、別の関数 func を呼び出、エラーが発生した場合には通常のキーボード／スクリーン動作に戻すラッパ関数です。呼び出し可能オブジェクト func は主ウィンドウの ‘stdscr’ に対する最初の引数として渡されます。その他の引数は wrapper() に渡されます。

フック関数を呼び出す前に、 wrapper() は cbreak モードをオン、エコーをオフにし、端末キーパッドを有効にします。端末がカラーをサポートしている場合にはカラーを初期化します。 (通常終了も例外による終了も) 終了時には cooked モードに復元し、エコーをオンにし、端末キーパッドを無効化します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.14. curses.ascii — ASCII 文字に関するユーティリティ

バージョン 1.6 で追加.

curses.ascii モジュールでは、 ASCII 文字を指す名前定数と、様々な ASCII 文字区分についてある文字が帰属するかどうかを調べる関数を提供します。このモジュールで提供されている定数は以下の制御文字の名前です:

Name | Meaning
NUL | 空
SOH | ヘディング開始、コンソール割り込み
STX | テキスト開始
ETX | テキスト終了
EOT | テキスト伝送終了
ENQ | 問い合わせ、 ACK フロー制御時に使用
ACK | 肯定応答
BEL | ベル
BS | 一文字後退
TAB | タブ
HT | TAB の別名: “水平タブ”
LF | 改行
NL | LF の別名: “改行”
VT | 垂直タブ
FF | 改頁
CR | 復帰
SO | シフトアウト、他の文字セットの開始
SI | シフトイン、標準の文字セットに復帰
DLE | データリンクでのエスケープ
DC1 | 装置制御 1、フロー制御のための XON
DC2 | 装置制御 2、ブロックモードフロー制御
DC3 | 装置制御 3、フロー制御のための XOFF
DC4 | 装置制御 4
NAK | 否定応答
SYN | 同期信号
ETB | ブロック転送終了
CAN | キャンセル
EM | 媒体終端
SUB | 代入文字
ESC | エスケープ文字
FS | ファイル区切り文字
GS | グループ区切り文字
RS | レコード区切り文字、ブロックモード終了子
US | 単位区切り文字
SP | 空白文字
DEL | 削除

これらの大部分は、最近は実際に定数の意味通りに使われることがほとんどないので注意してください。これらのニーモニック符号はデジタル計算機より前のテレプリンタにおける慣習から付けられたものです。

このモジュールでは、標準 C ライブラリの関数を雛型とする以下の関数をサポートしています:

curses.ascii.isalnum(c)

ASCII 英数文字かどうかを調べます; isalpha(c) or isdigit(c) と等価です。

curses.ascii.isalpha(c)

ASCII アルファベット文字かどうかを調べます; isupper(c) or islower(c) と等価です。

curses.ascii.isascii(c)

文字が 7 ビット ASCII 文字に合致するかどうかを調べます。

curses.ascii.isblank(c)

ASCII 余白文字かどうかを調べます。

curses.ascii.iscntrl(c)

ASCII 制御文字 (0x00 から 0x1f の範囲) かどうかを調べます。

curses.ascii.isdigit(c)

ASCII 10 進数字、すなわち '0' から '9' までの文字かどうかを調べます。 c in string.digits と等価です。

curses.ascii.isgraph(c)

空白以外の ASCII 印字可能文字かどうかを調べます。

curses.ascii.islower(c)

ASCII 小文字かどうかを調べます。

curses.ascii.isprint(c)

空白文字を含め、 ASCII 印字可能文字かどうかを調べます。

curses.ascii.ispunct(c)

空白または英数字以外の ASCII 印字可能文字かどうかを調べます。

curses.ascii.isspace(c)

ASCII 余白文字、すなわち空白、改行、復帰、改頁、水平タブ、垂直タブかどうかを調べます。

curses.ascii.isupper(c)

ASCII 大文字かどうかを調べます。

curses.ascii.isxdigit(c)

ASCII 16 進数字かどうかを調べます。 c in string.hexdigits と等価です。

curses.ascii.isctrl(c)

ASCII 制御文字 (0 から 31 までの値) かどうかを調べます。

curses.ascii.ismeta(c)

非 ASCII 文字 (0x80 またはそれ以上の値) かどうかを調べます。

これらの関数は数字も文字列も使えます; 引数を文字列にした場合、組み込み関数 ord() を使って変換されます。

これらの関数は全て、関数に渡した文字列の最初の文字から得られたビット値を調べるので注意してください; 関数はホスト計算機で使われている文字列エンコーディングについて何ら関知しません。文字列エンコーディングについて関知する (そして国際化に関するプロパティを正しく扱う) 関数については、モジュール string を参照してください。

以下の 2 つの関数は、引数として 1 文字の文字列または整数で表したバイト値のどちらでもとり得ます; これらの関数は引数と同じ型で値を返します。

curses.ascii.ascii(c)

ASCII 値を返します。 c の下位 7 ビットに対応します。

curses.ascii.ctrl(c)

与えた文字に対応する制御文字を返します (0x1f とビット単位で論理積を取ります) 。

curses.ascii.alt(c)

与えた文字に対応する 8 ビット文字を返します (0x80 とビット単位で論理和を取ります) 。

以下の関数は 1 文字からなる文字列値または整数値を引数に取り、文字列を返します。

curses.ascii.unctrl(c)

ASCII 文字 c の文字列表現を返します。もし c が印字可能文字であれば、返される文字列は c そのものになります。もし c が制御文字 (0x00-0x1f) であれば、キャレット ('^') と、その後ろに続く c に対応した大文字からなる文字列になります。 c が ASCII 削除文字 (0x7f) であれば、文字列は '^?' になります。 c のメタビット (0x80) がセットされていれば、メタビットは取り去られ、前述のルールが適用され、 '!' が前につけられます。

curses.ascii.controlnames

0 (NUL) から 0x1f (US) までの 32 の ASCII 制御文字と、空白文字 SP のニーモニック符号名からなる 33 要素の文字列によるシーケンスです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.15. curses.panel — curses のためのパネルスタック拡張

パネルは深さ (depth) の機能が追加されたウィンドウです。これにより、ウィンドウをお互いに重ね合わせることができ、各ウィンドウの可視部分だけが表示されます。パネルはスタック中に追加したり、スタック内で上下移動させたり、スタックから除去することができます。

15.15.1. 関数

curses.panel では以下の関数を定義しています:

curses.panel.bottom_panel()

パネルスタックの最下層のパネルを返します。

curses.panel.new_panel(win)

与えられたウィンドウ win に関連付けられたパネルオブジェクトを返します。返されたパネルオブジェクトを参照しておく必要があることに注意してください。もし参照しなければ、パネルオブジェクトはガベージコレクションされてパネルスタックから削除されます。

curses.panel.top_panel()

パネルスタックの最上層のパネルを返します。

curses.panel.update_panels()

仮想スクリーンをパネルスタック変更後の状態に更新します。この関数では curses.doupdate() を呼ばないので、ユーザは自分で呼び出す必要があります。

15.15.2. Panel オブジェクト

上記の new_panel() が返す Panel オブジェクトはスタック順の概念を持つウィンドウです。ウィンドウはパネルに関連付けられており、表示する内容を決定している一方、パネルのメソッドはパネルスタック中のウィンドウの深さ管理を担います。

Panel オブジェクトは以下のメソッドを持っています:

Panel.above()

現在のパネルの上にあるパネルを返します。

Panel.below()

現在のパネルの下にあるパネルを返します。

Panel.bottom()

パネルをスタックの最下層にプッシュします。

Panel.hidden()

パネルが隠れている (不可視である) 場合に真を返し、そうでない場合偽を返します。

Panel.hide()

パネルを隠します。この操作ではオブジェクトは消去されず、スクリーン上のウィンドウを不可視にするだけです。

Panel.move(y, x)

パネルをスクリーン座標 (y, x) に移動します。

Panel.replace(win)

パネルに関連付けられたウィンドウを win に変更します。

Panel.set_userptr(obj)

パネルのユーザポインタを obj に設定します。このメソッドは任意のデータをパネルに関連付けるために使われ、任意の Python オブジェクトにすることができます。

Panel.show()

(隠れているはずの) パネルを表示します。

Panel.top()

パネルをスタックの最上層にプッシュします。

Panel.userptr()

パネルのユーザポインタを返します。任意の Python オブジェクトです。

Panel.window()

パネルに関連付けられているウィンドウオブジェクトを返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.16. platform — 実行中プラットフォームの固有情報を参照する

バージョン 2.3 で追加.

ノート

プラットフォーム毎にアルファベット順に並べています。Linuxについては Unixセクションを参照してください。

15.16.1. クロスプラットフォーム

platform.architecture(executable=sys.executable, bits='', linkage='')

executable で指定した実行可能ファイル（省略時はPythonインタープリタのバイナリ）の各種アーキテクチャ情報を調べます。

戻り値はタプル (bits, linkage) で、アーキテクチャのビット数と実行可能ファイルのリンク形式を示します。どちらの値も文字列で返ります。

値が不明な場合は、パラメータで指定した値が返ります。 bits を '' と指定した場合、ビット数として sizeof(pointer)() が返ります。（Pythonのバージョンが1.5.2以下の場合は、サポートされているポインタサイズとして sizeof(long)() を使用します。）

この関数は、システムの file コマンドを使用します。 file はほとんどのUnixプラットフォームと一部の非Unixプラットフォームで利用可能ですが、 file コマンドが利用できず、かつ executable が Pythonインタープリタでない場合には適切なデフォルト値が返ります。

ノート

Mac OS X (とひょっとすると他のプラットフォーム) では、実行可能ファイルは複数のアーキテクチャを含んだユニバーサル形式かもしれません。

現在のインタプリタが “64-bit” であるかどうかを調べるには、 sys.maxsize の方が信頼できます。

is_64bits = sys.maxsize > 2**32

platform.machine()

'i386' のような、機種を返します。不明な場合は空文字列を返します。

platform.node()

コンピュータのネットワーク名を返します。ネットワーク名は完全修飾名とは限りません。不明な場合は空文字列を返します。

platform.platform(aliased=0, terse=0)

実行中プラットフォームを識別する文字列を返します。この文字列には、有益な情報をできるだけ多く付加しています。

戻り値は機械で処理しやすい形式ではなく、 人間にとって読みやすい 形式となっています。異なったプラットフォームでは異なった戻り値となるようになっています。

aliased が真なら、システムの名称として一般的な名称ではなく、別名を使用して結果を返します。たとえば、SunOS は Solaris となります。この機能は system_alias() で実装されています。

terse が真なら、プラットフォームを特定するために最低限必要な情報だけを返します。

platform.processor()

'amdk6' のような、（現実の）プロセッサ名を返します。

不明な場合は空文字列を返します。NetBSDのようにこの情報を提供しない、または machine() と同じ値しか返さないプラットフォームも多く存在しますので、注意してください。

platform.python_build()

Pythonのビルド番号と日付を、 (buildno, builddate) のタプルで返します。

platform.python_compiler()

Pythonをコンパイルする際に使用したコンパイラを示す文字列を返します。

platform.python_branch()

Python実装のバージョン管理システム上のブランチを特定する文字列を返します。

バージョン 2.6 で追加.

platform.python_implementation()

Python実装を指定する文字列を返します。戻り値は: ‘CPython’, ‘IronPython’, ‘Jython’, ‘PyPy’ のいずれかです。

バージョン 2.6 で追加.

platform.python_revision()

Python実装のバージョン管理システム上のリビジョンを特定する文字列を返します。

バージョン 2.6 で追加.

platform.python_version()

Pythonのバージョンを、 'major.minor.patchlevel' 形式の文字列で返します。

sys.version と異なり、patchlevel（デフォルトでは0)も必ず含まれています。

platform.python_version_tuple()

Pythonのバージョンを、文字列のタプル (major, minor, patchlevel) で返します。

sys.version と異なり、patchlevel（デフォルトでは 0)も必ず含まれています。

platform.release()

'2.2.0' や 'NT' のような、システムのリリース情報を返します。不明な場合は空文字列を返します。

platform.system()

'Linux', 'Windows', 'Java' のような、システム/OS 名を返します。不明な場合は空文字列を返します。

platform.system_alias(system, release, version)

マーケティング目的で使われる一般的な別名に変換して (system, release, version) を返します。混乱を避けるために、情報を並べなおす場合があります。

platform.version()

'#3 on degas' のような、システムのリリース情報を返します。不明な場合は空文字列を返します。

platform.uname()

非常に可搬性の高い uname インターフェースで、実行中プラットフォームを示す情報を、文字列のタプル (system, node, release, version, machine, processor) で返します。

os.uname() と異なり、複数のプロセッサ名が候補としてタプルに追加される場合があります。

不明な項目は '' となります。

15.16.2. Java プラットフォーム

platform.java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', ''))

Jython用のバージョンインターフェースです。

タプル (release, vendor, vminfo, osinfo) を返します。 vminfo はタプル (vm_name, vm_release, vm_vendor) 、 osinfo はタプル (os_name, os_version, os_arch) です。不明な項目は引数で指定した値(デフォルトは '') となります。

15.16.3. Windows プラットフォーム

platform.win32_ver(release='', version='', csd='', ptype='')

Windowsのレジストリからバージョン情報を取得し、バージョン番号/CSDレベル/OSタイプ（シングルプロセッサ又はマルチプロセッサ）をタプル (version, csd, ptype) で返します。

参考： ptype はシングルプロセッサのNT上では 'Uniprocessor Free' 、マルチプロセッサでは 'Multiprocessor Free' となります。 ‘Free’ がついている場合はデバッグ用のコードが含まれていないことを示し、 ‘Checked’ がついていれば引数や範囲のチェックなどのデバッグ用コードが含まれていることを示します。

ノート

この関数は、Mark Hammondの win32all がインストールされた環境で良く動作しますが、Python 2.3 以上なら一応動作します。(Python 2.6からサポートされました) もちろん、この関数が使えるのはWin32互換プラットフォームのみです。

15.16.3.1. Win95/98 固有

platform.popen(cmd, mode='r', bufsize=None)

可搬性の高い popen() インターフェースで、可能なら win32pipe.popen() を使用します。 win32pipe.popen() はWindows NTでは利用可能ですが、Windows 9xではハングしてしまいます。

15.16.4. Mac OS プラットフォーム

platform.mac_ver(release='', versioninfo=('', '', ''), machine='')

Mac OSのバージョン情報を、タプル (release, versioninfo, machine) で返します。 versioninfo は、タプル (version, dev_stage, non_release_version) です。

不明な項目は '' となります。タプルの要素は全て文字列です。

この関数で使用している gestalt() API については、 http://www.rgaros.nl/gestalt/ を参照してください。

15.16.5. Unix プラットフォーム

platform.dist(distname='', version='', id='', supported_dists=('SuSE', 'debian', 'redhat', 'mandrake', ...))

この関数は、現在 linux_distribution() が提供している機能の古いバージョンです。新しいコードを書くときは、 linux_distribution() を利用してください。

linux_distribution() との違いは、 dist() は常に supported_dists 引数から取った短い名前を返す事です。

platform.linux_distribution(distname='', version='', id='', supported_dists=('SuSE', 'debian', 'redhat', 'mandrake', ...), full_distribution_name=1)

OSディストリビューション名の取得を試みます。

supported_dists は、検索するLinuxディストリビューションを定義するために利用します。デフォルトでは、リリースファイル名で定義されている、現在サポートされているLinuxディストリビューションのリストです。

full_distribution_name が True (デフォルト)の場合、 OSから読み込まれた完全なディストリビューション名が返されます。それ以外の場合、 supported_dists で利用された短い名前が返されます。

戻り値はタプル (distname, version, id) で、不明な項目は引数で指定した値となります。

バージョン 2.6 で追加.

platform.libc_ver(executable=sys.executable, lib='', version='', chunksize=2048)

executableで指定したファイル（省略時はPythonインタープリタ）がリンクしているlibcバージョンの取得を試みます。戻り値は文字列のタプル (lib, version) で、不明な項目は引数で指定した値となります。

この関数は、実行形式に追加されるシンボルの細かな違いによって、libcのバージョンを特定します。この違いは gcc でコンパイルされた実行可能ファイルでのみ有効だと思われます。

chunksize にはファイルから情報を取得するために読み込むバイト数を指定します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.17. errno — 標準の errno システムシンボル

このモジュールから標準の errno システムシンボルを取得することができます。個々のシンボルの値は errno に対応する整数値です。これらのシンボルの名前は、 linux/include/errno.h から借用されており、かなり網羅的なはずです。

errno.errorcode

errno 値を背後のシステムにおける文字列表現に対応付ける辞書です。例えば、 errno.errorcode[errno.EPERM] は 'EPERM' に対応付けられます。

数値のエラーコードをエラーメッセージに変換するには、 os.strerror() を使ってください。

以下のリストの内、現在のプラットフォームで使われていないシンボルはモジュール上で定義されていません。定義されているシンボルだけを挙げたリストは errno.errorcode.keys() として取得することができます。取得できるシンボルには以下のようなものがあります:

errno.EPERM

許可されていない操作です (Operation not permitted)

errno.ENOENT

ファイルまたはディレクトリがありません (No such file or directory)

errno.ESRCH

指定したプロセスが存在しません (No such process)

errno.EINTR

割り込みシステムコールです (Interrupted system call)

errno.EIO

I/O エラーです (I/O error)

errno.ENXIO

そのようなデバイスまたはアドレスはありません (No such device or address)

errno.E2BIG

引数リストが長すぎます (Arg list too long)

errno.ENOEXEC

実行形式にエラーがあります (Exec format error)

errno.EBADF

ファイル番号が間違っています (Bad file number)

errno.ECHILD

子プロセスがありません (No child processes)

errno.EAGAIN

再試行してください (Try again)

errno.ENOMEM

空きメモリがありません (Out of memory)

errno.EACCES

許可がありません (Permission denied)

errno.EFAULT

不正なアドレスです (Bad address)

errno.ENOTBLK

ブロックデバイスが必要です (Block device required)

errno.EBUSY

そのデバイスまたは資源は使用中です (Device or resource busy)

errno.EEXIST

ファイルがすでに存在します (File exists)

errno.EXDEV

デバイス間のリンクです (Cross-device link)

errno.ENODEV

そのようなデバイスはありません (No such device)

errno.ENOTDIR

ディレクトリではありません (Not a directory)

errno.EISDIR

ディレクトリです (Is a directory)

errno.EINVAL

無効な引数です (Invalid argument)

errno.ENFILE

ファイルテーブルがオーバフローしています (File table overflow)

errno.EMFILE

開かれたファイルが多すぎます (Too many open files)

errno.ENOTTY

タイプライタではありません (Not a typewriter)

errno.ETXTBSY

テキストファイルが使用中です (Text file busy)

errno.EFBIG

ファイルが大きすぎます (File too large)

errno.ENOSPC

デバイス上に空きがありません (No space left on device)

errno.ESPIPE

不正なシークです (Illegal seek)

errno.EROFS

読み出し専用ファイルシステムです (Read-only file system)

errno.EMLINK

リンクが多すぎます (Too many links)

errno.EPIPE

パイプが壊れました (Broken pipe)

errno.EDOM

数学引数が関数の定義域を越えています (Math argument out of domain of func)

errno.ERANGE

表現できない数学演算結果になりました (Math result not representable)

errno.EDEADLK

リソースのデッドロックが起きます (Resource deadlock would occur)

errno.ENAMETOOLONG

ファイル名が長すぎます (File name too long)

errno.ENOLCK

レコードロッキングが利用できません (No record locks available)

errno.ENOSYS

実装されていない機能です (Function not implemented)

errno.ENOTEMPTY

ディレクトリが空ではありません (Directory not empty)

errno.ELOOP

これ以上シンボリックリンクを追跡できません (Too many symbolic links encountered)

errno.EWOULDBLOCK

操作がブロックします (Operation would block)

errno.ENOMSG

指定された型のメッセージはありません (No message of desired type)

errno.EIDRM

識別子が除去されました (Identifier removed)

errno.ECHRNG

チャネル番号が範囲を超えました (Channel number out of range)

errno.EL2NSYNC

レベル 2 で同期がとれていません (Level 2 not synchronized)

errno.EL3HLT

レベル 3 で終了しました (Level 3 halted)

errno.EL3RST

レベル 3 でリセットしました (Level 3 reset)

errno.ELNRNG

リンク番号が範囲を超えています (Link number out of range)

errno.EUNATCH

プロトコルドライバが接続されていません (Protocol driver not attached)

errno.ENOCSI

CSI 構造体がありません (No CSI structure available)

errno.EL2HLT

レベル 2 で終了しました (Level 2 halted)

errno.EBADE

無効な変換です (Invalid exchange)

errno.EBADR

無効な要求記述子です (Invalid request descriptor)

errno.EXFULL

変換テーブルが一杯です (Exchange full)

errno.ENOANO

陰極がありません (No anode)

errno.EBADRQC

無効なリクエストコードです (Invalid request code)

errno.EBADSLT

無効なスロットです (Invalid slot)

errno.EDEADLOCK

ファイルロックにおけるデッドロックエラーです (File locking deadlock error)

errno.EBFONT

フォントファイル形式が間違っています (Bad font file format)

errno.ENOSTR

ストリーム型でないデバイスです (Device not a stream)

errno.ENODATA

利用可能なデータがありません (No data available)

errno.ETIME

時間切れです (Timer expired)

errno.ENOSR

streams リソースを使い切りました (Out of streams resources)

errno.ENONET

計算機はネットワーク上にありません (Machine is not on the network)

errno.ENOPKG

パッケージがインストールされていません (Package not installed)

errno.EREMOTE

対象物は遠隔にあります (Object is remote)

errno.ENOLINK

リンクが切られました (Link has been severed)

errno.EADV

Advertise エラーです (Advertise error)

errno.ESRMNT

Srmount エラーです (Srmount error)

errno.ECOMM

送信時の通信エラーです (Communication error on send)

errno.EPROTO

プロトコルエラーです (Protocol error)

errno.EMULTIHOP

多重ホップを試みました (Multihop attempted)

errno.EDOTDOT

RFS 特有のエラーです (RFS specific error)

errno.EBADMSG

データメッセージではありません (Not a data message)

errno.EOVERFLOW

定義されたデータ型にとって大きすぎる値です (Value too large for defined data type)

errno.ENOTUNIQ

名前がネットワーク上で一意でありません (Name not unique on network)

errno.EBADFD

ファイル記述子の状態が不正です (File descriptor in bad state)

errno.EREMCHG

遠隔のアドレスが変更されました (Remote address changed)

errno.ELIBACC

必要な共有ライブラリにアクセスできません (Can not access a needed shared library)

errno.ELIBBAD

壊れた共有ライブラリにアクセスしています (Accessing a corrupted shared library)

errno.ELIBSCN

a.out の .lib セクションが壊れています (.lib section in a.out corrupted)

errno.ELIBMAX

リンクを試みる共有ライブラリが多すぎます (Attempting to link in too many shared libraries)

errno.ELIBEXEC

共有ライブラリを直接実行することができません (Cannot exec a shared library directly)

errno.EILSEQ

不正なバイト列です (Illegal byte sequence)

errno.ERESTART

割り込みシステムコールを復帰しなければなりません (Interrupted system call should be restarted)

errno.ESTRPIPE

ストリームパイプのエラーです (Streams pipe error)

errno.EUSERS

ユーザが多すぎます (Too many users)

errno.ENOTSOCK

非ソケットに対するソケット操作です (Socket operation on non-socket)

errno.EDESTADDRREQ

目的アドレスが必要です (Destination address required)

errno.EMSGSIZE

メッセージが長すぎます (Message too long)

errno.EPROTOTYPE

ソケットに対して不正なプロトコル型です (Protocol wrong type for socket)

errno.ENOPROTOOPT

利用できないプロトコルです (Protocol not available)

errno.EPROTONOSUPPORT

サポートされていないプロトコルです (Protocol not supported)

errno.ESOCKTNOSUPPORT

サポートされていないソケット型です (Socket type not supported)

errno.EOPNOTSUPP

通信端点に対してサポートされていない操作です (Operation not supported on transport endpoint)

errno.EPFNOSUPPORT

サポートされていないプロトコルファミリです (Protocol family not supported)

errno.EAFNOSUPPORT

プロトコルでサポートされていないアドレスファミリです (Address family not supported by protocol)

errno.EADDRINUSE

アドレスは使用中です (Address already in use)

errno.EADDRNOTAVAIL

要求されたアドレスを割り当てできません (Cannot assign requested address)

errno.ENETDOWN

ネットワークがダウンしています (Network is down)

errno.ENETUNREACH

ネットワークに到達できません (Network is unreachable)

errno.ENETRESET

リセットによってネットワーク接続が切られました (Network dropped connection because of reset)

errno.ECONNABORTED

ソフトウェアによって接続が終了されました (Software caused connection abort)

errno.ECONNRESET

接続がピアによってリセットされました (Connection reset by peer)

errno.ENOBUFS

バッファに空きがありません (No buffer space available)

errno.EISCONN

通信端点がすでに接続されています (Transport endpoint is already connected)

errno.ENOTCONN

通信端点が接続されていません (Transport endpoint is not connected)

errno.ESHUTDOWN

通信端点のシャットダウン後は送信できません (Cannot send after transport endpoint shutdown)

errno.ETOOMANYREFS

参照が多すぎます: 接続できません (Too many references: cannot splice)

errno.ETIMEDOUT

接続がタイムアウトしました (Connection timed out)

errno.ECONNREFUSED

接続を拒否されました (Connection refused)

errno.EHOSTDOWN

ホストはシステムダウンしています (Host is down)

errno.EHOSTUNREACH

ホストへの経路がありません (No route to host)

errno.EALREADY

すでに処理中です (Operation already in progress)

errno.EINPROGRESS

現在処理中です (Operation now in progress)

errno.ESTALE

無効な NFS ファイルハンドルです (Stale NFS file handle)

errno.EUCLEAN

(Structure needs cleaning)

errno.ENOTNAM

XENIX 名前付きファイルではありません (Not a XENIX named type file)

errno.ENAVAIL

XENIX セマフォは利用できません (No XENIX semaphores available)

errno.EISNAM

名前付きファイルです (Is a named type file)

errno.EREMOTEIO

遠隔側の I/O エラーです (Remote I/O error)

errno.EDQUOT

ディスククオータを超えました (Quota exceeded)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

15. 汎用オペレーティングシステムサービス »

15.18. ctypes — Pythonのための外部関数ライブラリ

バージョン 2.5 で追加.

ctypes は Python のための外部関数ライブラリです。このライブラリは C と互換性のあるデータ型を提供し、動的リンク/共有ライブラリ内の関数呼び出しを可能にします。動的リンク/共有ライブラリを純粋な Python でラップするために使うことができます。

15.18.1. ctypesチュートリアル

注意: このチュートリアルのコードサンプルは動作確認のために doctest を使います。コードサンプルの中には Linux、 Windows、あるいは Mac OS X 上で異なる動作をするものがあるため、サンプルのコメントに doctest 命令を入れてあります。

注意: いくつかのコードサンプルで ctypes の c_int 型を参照しています。 32 ビットシステムにおいてこの型は c_long 型のエイリアスです。そのため、 c_int 型を想定しているときに c_long が表示されたとしても、混乱しないようにしてください — 実際には同じ型なのです。

15.18.1.1. 動的リンクライブラリをロードする

動的リンクライブラリをロードするために、 ctypes は cdll をエクスポートします。 Windows では windll と oledll オブジェクトをエクスポートします。

これらのオブジェクトの属性としてライブラリにアクセスすることでライブラリをロードします。 cdll は標準 cdecl 呼び出し規約を用いて関数をエクスポートしているライブラリをロードします。それに対して、 windll ライブラリは stdcall 呼び出し規約を用いる関数を呼び出します。 oledll も stdcall 呼び出し規約を使いますが、関数が Windows HRESULT エラーコードを返すことを想定しています。このエラーコードは関数呼び出しが失敗したとき、 WindowsError 例外を自動的に送出させるために使われます。

Windows用の例ですが、 msvcrt はほとんどの標準 C 関数が含まれている MS 標準 C ライブラリであり、 cdecl 呼び出し規約を使うことに注意してください:

>>> from ctypes import *
>>> print windll.kernel32 # doctest: +WINDOWS
<WinDLL 'kernel32', handle ... at ...>
>>> print cdll.msvcrt # doctest: +WINDOWS
<CDLL 'msvcrt', handle ... at ...>
>>> libc = cdll.msvcrt # doctest: +WINDOWS
>>>

Windows では通常の .dll ファイル拡張子を自動的に追加します。

Linux ではライブラリをロードするために拡張子を 含む ファイル名を指定する必要があるので、ロードしたライブラリに対する属性アクセスはできません。 dll ローダーの LoadLibrary() メソッドを使うか、コンストラクタを呼び出して CDLL のインスタンスを作ることでライブラリをロードするかのどちらかを行わなければなりません:

>>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
<CDLL 'libc.so.6', handle ... at ...>
>>> libc = CDLL("libc.so.6")     # doctest: +LINUX
>>> libc                         # doctest: +LINUX
<CDLL 'libc.so.6', handle ... at ...>
>>>

15.18.1.2. ロードしたdllから関数にアクセスする

dll オブジェクトの属性として関数にアクセスします:

>>> from ctypes import *
>>> libc.printf
<_FuncPtr object at 0x...>
>>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
<_FuncPtr object at 0x...>
>>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "ctypes.py", line 239, in __getattr__
    func = _StdcallFuncPtr(name, self)
AttributeError: function 'MyOwnFunction' not found
>>>

kernel32 や user32 のような win32 システム dll は、多くの場合関数の UNICODE バージョンに加えて ANSI バージョンもエクスポートすることに注意してください。 UNICODE バージョンは後ろに W が付いた名前でエクスポートされ、 ANSI バージョンは A が付いた名前でエクスポートされます。与えられたモジュールの モジュールハンドル を返す win32 GetModuleHandle 関数は次のような C プロトタイプを持ちます。 UNICODE バージョンが定義されているかどうかにより GetModuleHandle としてどちらか一つを公開するためにマクロが使われます:

/* ANSI version */
HMODULE GetModuleHandleA(LPCSTR lpModuleName);
/* UNICODE version */
HMODULE GetModuleHandleW(LPCWSTR lpModuleName);

windll は魔法を使ってどちらか一つを選ぶようなことはしません。 GetModuleHandleA もしくは GetModuleHandleW を明示的に指定して必要とするバージョンにアクセスし、文字列かユニコード文字列を使ってそれぞれ呼び出さなければなりません。

時には、 dll が関数を "??2@YAPAXI@Z" のような Python 識別子として有効でない名前でエクスポートすることがあります。このような場合に関数を取り出すには、 getattr() を使わなければなりません。:

>>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS
<_FuncPtr object at 0x...>
>>>

Windows では、名前ではなく序数によって関数をエクスポートする dll もあります。こうした関数には序数を使って dll オブジェクトにインデックス指定することでアクセスします:

>>> cdll.kernel32[1] # doctest: +WINDOWS
<_FuncPtr object at 0x...>
>>> cdll.kernel32[0] # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "ctypes.py", line 310, in __getitem__
    func = _StdcallFuncPtr(name, self)
AttributeError: function ordinal 0 not found
>>>

15.18.1.3. 関数を呼び出す

これらの関数は他の Python 呼び出し可能オブジェクトと同じように呼び出すことができます。この例では time() 関数 (Unixエポックからのシステム時間を秒単位で返す) と、 GetModuleHandleA() 関数 (win32モジュールハンドルを返す) を使います。

この例は両方の関数を NULL ポインタとともに呼び出します (None を NULL ポインタとして使う必要があります):

>>> print libc.time(None) # doctest: +SKIP
1150640792
>>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS
0x1d000000
>>>

ctypes は引数の数を間違えたり、あるいは呼び出し規約を間違えた関数呼び出しからあなたを守ろうとします。残念ながら、これは Windows でしか機能しません。関数が返った後にスタックを調べることでこれを行います。したがって、エラーは発生しますが、その関数は呼び出された 後です:

>>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>

同じ例外が cdecl 呼び出し規約を使って stdcall 関数を呼び出したときに送出されますし、逆の場合も同様です。:

>>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf("spam") # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>

正しい呼び出し規約を知るためには、呼び出したい関数についての C ヘッダファイルもしくはドキュメントを見なければなりません。

Windows では、関数が無効な引数とともに呼び出された場合の一般保護例外によるクラッシュを防ぐために、 ctypes は win32 構造化例外処理を使います:

>>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
WindowsError: exception: access violation reading 0x00000020
>>>

しかし、 ctypes を使って Python をクラッシュさせる方法は十分なほどあるので、よく注意すべきです。

None 、整数、長整数、バイト文字列およびユニコード文字列だけが、こうした関数呼び出しにおいてパラメータとして直接使えるネイティブの Python オブジェクトです。 None は C の NULL ポインタとして渡され、バイト文字列とユニコード文字列はそのデータを含むメモリブロックへのポインタ (char * または wchar_t *) として渡されます。 Python 整数と Python 長整数はプラットホームのデフォルトの C int 型として渡され、その値は C int 型に合うようにマスクされます。

他のパラメータ型をもつ関数呼び出しに移る前に、 ctypes データ型についてさらに学ぶ必要があります。

15.18.1.4. 基本のデータ型

ctypes はたくさんの C と互換性のあるデータ型を定義しています :

ctypes の型 | C の型 | Python の型
c_bool | _Bool | bool (1)
c_char | char | 1文字の文字列
c_wchar | wchar_t | 1文字のユニコード文字列
c_byte | char | 整数/長整数
c_ubyte | unsigned char | 整数/長整数
c_short | short | 整数/長整数
c_ushort | unsigned short | 整数/長整数
c_int | int | 整数/長整数
c_uint | unsigned int | 整数/長整数
c_long | long | 整数/長整数
c_ulong | unsigned long | 整数/長整数
c_longlong | __int64 または long long | 整数/長整数
c_ulonglong | unsigned __int64 または unsigned long long | 整数/長整数
c_float | float | 浮動小数点数
c_double | double | 浮動小数点数
c_longdouble | longdouble | 浮動小数点数
c_char_p | char * (NUL 終端) | 文字列または None
c_wchar_p | wchar_t * (NUL 終端) | ユニコードまたは None
c_void_p | void * | 整数/長整数または None

コンストラクタは任意のオブジェクトをその真偽値として受け取ります。

これら全ての型はその型を呼び出すことによって作成でき、オプションとして型と値が合っている初期化子を指定することができます:

>>> c_int()
c_long(0)
>>> c_char_p("Hello, World")
c_char_p('Hello, World')
>>> c_ushort(-3)
c_ushort(65533)
>>>

これらの型は変更可能であり、値を後で変更することもできます:

>>> i = c_int(42)
>>> print i
c_long(42)
>>> print i.value
42
>>> i.value = -99
>>> print i.value
-99
>>>

新しい値をポインタ型 c_char_p, c_wchar_p および c_void_p のインスタンスへ代入すると、変わるのは指しているメモリ位置 であって、メモリブロックの 内容ではありません (これは当然で、なぜなら、 Python 文字列は変更不可能だからです):

>>> s = "Hello, World"
>>> c_s = c_char_p(s)
>>> print c_s
c_char_p('Hello, World')
>>> c_s.value = "Hi, there"
>>> print c_s
c_char_p('Hi, there')
>>> print s                 # 最初の文字列は変更されていない
Hello, World
>>>

しかし、変更可能なメモリを指すポインタであることを想定している関数へそれらを渡さないように注意すべきです。もし変更可能なメモリブロックが必要なら、 ctypes には create_string_buffer() 関数があり、いろいろな方法で作成することできます。現在のメモリブロックの内容は raw プロパティを使ってアクセス (あるいは変更) することができます。もし現在のメモリブロックに NUL 終端文字列としてアクセスしたいなら、 value プロパティを使ってください:

>>> from ctypes import *
>>> p = create_string_buffer(3)      # 3バイトのバッファを作成、NULで初期化される
>>> print sizeof(p), repr(p.raw)
3 '\x00\x00\x00'
>>> p = create_string_buffer("Hello")      # NUL終端文字列を含むバッファを作成
>>> print sizeof(p), repr(p.raw)
6 'Hello\x00'
>>> print repr(p.value)
'Hello'
>>> p = create_string_buffer("Hello", 10)  # 10バイトのバッファを作成
>>> print sizeof(p), repr(p.raw)
10 'Hello\x00\x00\x00\x00\x00'
>>> p.value = "Hi"
>>> print sizeof(p), repr(p.raw)
10 'Hi\x00lo\x00\x00\x00\x00\x00'
>>>

create_string_buffer() 関数は初期の ctypes リリースにあった c_string() 関数だけでなく、 (エイリアスとしてはまだ利用できる) c_buffer() 関数をも置き換えるものです。 C の型 wchar_t のユニコード文字を含む変更可能なメモリブロックを作成するには、 create_unicode_buffer() 関数を使ってください。

15.18.1.5. 続・関数を呼び出す

printf は sys.stdout では なく 、本物の標準出力チャンネルへプリントすることに注意してください。したがって、これらの例はコンソールプロンプトでのみ動作し、 IDLE や PythonWin では動作しません。:

>>> printf = libc.printf
>>> printf("Hello, %s\n", "World!")
Hello, World!
14
>>> printf("Hello, %S\n", u"World!")
Hello, World!
14
>>> printf("%d bottles of beer\n", 42)
42 bottles of beer
19
>>> printf("%f bottles of beer\n", 42.5)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
>>>

前に述べたように、必要な C のデータ型へ変換できるようにするためには、整数、文字列およびユニコード文字列を除くすべての Python 型を対応する ctypes 型でラップしなければなりません。:

>>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
An int 1234, a double 3.140000
31
>>>

15.18.1.6. 自作のデータ型とともに関数を呼び出す

自作のクラスのインスタンスを関数引数として使えるように、 ctypes 引数変換をカスタマイズすることもできます。 ctypes は _as_parameter_ 属性を探し出し、関数引数として使います。もちろん、整数、文字列もしくはユニコードの中の一つでなければなりません。:

>>> class Bottles(object):
...     def __init__(self, number):
...         self._as_parameter_ = number
...
>>> bottles = Bottles(42)
>>> printf("%d bottles of beer\n", bottles)
42 bottles of beer
19
>>>

インスタンスのデータを _as_parameter_ インスタンス変数の中に入れたくない場合には、そのデータを利用できるようにする property() を定義することができます。

15.18.1.7. 要求される引数の型を指定する (関数プロトタイプ)

argtypes 属性を設定することによって、 DLL からエクスポートされている関数に要求される引数の型を指定することができます。

argtypes は C データ型のシーケンスでなければなりません (この場合 printf 関数はおそらく良い例ではありません。なぜなら、引数の数が可変であり、フォーマット文字列に依存した異なる型のパラメータを取るからです。一方では、この機能の実験にはとても便利です)。:

>>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
>>> printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)
String 'Hi', Int 10, Double 2.200000
37
>>>

(C の関数のプロトタイプのように) 書式を指定すると互換性のない引数型になるのを防ぎ、引数を有効な型へ変換しようとします。:

>>> printf("%d %d %d", 1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: wrong type
>>> printf("%s %d %f\n", "X", 2, 3)
X 2 3.000000
13
>>>

関数呼び出しへ渡す自作のクラスを定義した場合には、 argtypes シーケンスの中で使えるようにするために、そのクラスに from_param() クラスメソッドを実装しなければなりません。 from_param() クラスメソッドは関数呼び出しへ渡された Python オブジェクトを受け取り、型チェックもしくはこのオブジェクトが受け入れ可能であると確かめるために必要なことはすべて行ってから、オブジェクト自身、 _as_parameter_ 属性、あるいは、この場合に C 関数引数として渡したい何かの値を返さなければなりません。繰り返しになりますが、その返される結果は整数、文字列、ユニコード、 ctypes インスタンス、あるいは _as_parameter_ 属性をもつオブジェクトであるべきです。

15.18.1.8. 戻り値の型

デフォルトでは、関数は C int を返すと仮定されます。他の戻り値の型を指定するには、関数オブジェクトの restype 属性に設定します。

さらに高度な例として、 strchr 関数を使います。この関数は文字列ポインタと char を受け取り、文字列へのポインタを返します。:

>>> strchr = libc.strchr
>>> strchr("abcdef", ord("d")) # doctest: +SKIP
8059983
>>> strchr.restype = c_char_p # c_char_pは文字列へのポインタ
>>> strchr("abcdef", ord("d"))
'def'
>>> print strchr("abcdef", ord("x"))
None
>>>

上の ord("x") 呼び出しを避けたいなら、 argtypes 属性を設定することができます。二番目の引数が一文字の Python 文字列から C の char へ変換されます。:

>>> strchr.restype = c_char_p
>>> strchr.argtypes = [c_char_p, c_char]
>>> strchr("abcdef", "d")
'def'
>>> strchr("abcdef", "def")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ArgumentError: argument 2: exceptions.TypeError: one character string expected
>>> print strchr("abcdef", "x")
None
>>> strchr("abcdef", "d")
'def'
>>>

外部関数が整数を返す場合は、 restype 属性として呼び出し可能な Python オブジェクト (例えば、関数またはクラス) を使うこともできます。呼び出し可能オブジェクトは C 関数が返す 整数 とともに呼び出され、この呼び出しの結果は関数呼び出しの結果として使われるでしょう。これはエラーの戻り値をチェックして自動的に例外を送出させるために役に立ちます。:

>>> GetModuleHandle = windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
>>> def ValidHandle(value):
...     if value == 0:
...         raise WinError()
...     return value
...
>>>
>>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
>>> GetModuleHandle(None) # doctest: +WINDOWS
486539264
>>> GetModuleHandle("something silly") # doctest: +WINDOWS
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in ValidHandle
WindowsError: [Errno 126] The specified module could not be found.
>>>

WinError はエラーコードの文字列表現を得るために Windows の FormatMessage() api を呼び出し、例外を 返す 関数です。 WinError はオプションでエラーコードパラメータを取ります。このパラメータが使われない場合は、エラーコードを取り出すために GetLastError() を呼び出します。

errcheck 属性によってもっと強力なエラーチェック機構を利用できることに注意してください。詳細はリファレンスマニュアルを参照してください。

15.18.1.9. ポインタを渡す(または、パラメータの参照渡し)

時には、 C api 関数がパラメータのデータ型として ポインタ を想定していることがあります。おそらくパラメータと同一の場所に書き込むためか、もしくはそのデータが大きすぎて値渡しできない場合です。これは パラメータの参照渡し としても知られています。

ctypes は byref() 関数をエクスポートしており、パラメータを参照渡しするために使用します。 pointer() 関数を使っても同じ効果が得られます。しかし、 pointer() は本当のポインタオブジェクトを構築するためより多くの処理を行うことから、 Python 側でポインタオブジェクト自体を必要としないならば byref() を使う方がより高速です。:

>>> i = c_int()
>>> f = c_float()
>>> s = create_string_buffer('\000' * 32)
>>> print i.value, f.value, repr(s.value)
0 0.0 ''
>>> libc.sscanf("1 3.14 Hello", "%d %f %s",
...             byref(i), byref(f), s)
3
>>> print i.value, f.value, repr(s.value)
1 3.1400001049 'Hello'
>>>

15.18.1.10. 構造体と共用体

構造体と共用体は ctypes モジュールに定義されている Structure および Union ベースクラスからの派生クラスでなければなりません。それぞれのサブクラスは _fields_ 属性を定義する必要があります。 _fields_ は フィールド名 と フィールド型を持つ 2要素タプル のリストでなければなりません。

フィールド型は c_int か他の ctypes 型 (構造体、共用体、配列、ポインタ) から派生した ctypes 型である必要があります。

x と y という名前の二つの整数からなる簡単な POINT 構造体の例です。コンストラクタで構造体の初期化する方法の説明にもなっています。:

>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = [("x", c_int),
...                 ("y", c_int)]
...
>>> point = POINT(10, 20)
>>> print point.x, point.y
10 20
>>> point = POINT(y=5)
>>> print point.x, point.y
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: too many initializers
>>>

また、さらに複雑な構造体を構成することができます。 Structure はそれ自体がフィールド型に構造体を使うことで他の構造体を内部に持つことができます。

upperleft と lowerright という名前の二つの POINT を持つ RECT 構造体です。:

>>> class RECT(Structure):
...     _fields_ = [("upperleft", POINT),
...                 ("lowerright", POINT)]
...
>>> rc = RECT(point)
>>> print rc.upperleft.x, rc.upperleft.y
0 5
>>> print rc.lowerright.x, rc.lowerright.y
0 0
>>>

入れ子になった構造体はいくつかの方法を用いてコンストラクタで初期化することができます。:

>>> r = RECT(POINT(1, 2), POINT(3, 4))
>>> r = RECT((1, 2), (3, 4))

フィールド descriptor (記述子)は クラス から取り出せます。デバッグするときに役に立つ情報を得ることができます:

>>> print POINT.x
<Field type=c_long, ofs=0, size=4>
>>> print POINT.y
<Field type=c_long, ofs=4, size=4>
>>>

15.18.1.11. 構造体/共用体アライメントとバイトオーダー

デフォルトでは、 Structure と Union のフィールドは C コンパイラが行うのと同じ方法でアライメントされています。サブクラスを定義するときに _pack_ クラス属性を指定することでこの動作を変えることは可能です。このクラス属性には正の整数を設定する必要があり、フィールドの最大アライメントを指定します。これは MSVC で #pragma pack(n) が行っていること同じです。

ctypes は Structure と Union に対してネイティブのバイトオーダーを使います。ネイティブではないバイトオーダーの構造体を作成するには、 BigEndianStructure, LittleEndianStructure, BigEndianUnion および LittleEndianUnion ベースクラスの中の一つを使います。これらのクラスにポインタフィールドを持たせることはできません。

15.18.1.12. 構造体と共用体におけるビットフィールド

ビットフィールドを含む構造体と共用体を作ることができます。ビットフィールドは整数フィールドに対してのみ作ることができ、ビット幅は _fields_ タプルの第三要素で指定します。:

>>> class Int(Structure):
...     _fields_ = [("first_16", c_int, 16),
...                 ("second_16", c_int, 16)]
...
>>> print Int.first_16
<Field type=c_long, ofs=0:0, bits=16>
>>> print Int.second_16
<Field type=c_long, ofs=0:16, bits=16>
>>>

15.18.1.13. 配列

Array はシーケンスであり、決まった数の同じ型のインスタンスを持ちます。

推奨されている配列の作成方法はデータ型に正の整数を掛けることです。:

TenPointsArrayType = POINT * 10

ややわざとらしいデータ型の例になりますが、他のものに混ざって 4 個の POINT がある構造体です。:

>>> from ctypes import *
>>> class POINT(Structure):
...    _fields_ = ("x", c_int), ("y", c_int)
...
>>> class MyStruct(Structure):
...    _fields_ = [("a", c_int),
...                ("b", c_float),
...                ("point_array", POINT * 4)]
>>>
>>> print len(MyStruct().point_array)
4
>>>

インスタンスはクラスを呼び出す通常の方法で作成します。:

arr = TenPointsArrayType()
for pt in arr:
    print pt.x, pt.y

上記のコードは 0 0 という行が並んだものを表示します。配列の要素がゼロで初期化されているためです。

正しい型の初期化子を指定することもできます。:

>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,
...
1 2 3 4 5 6 7 8 9 10
>>>

15.18.1.14. ポインタ

ポインタのインスタンスは ctypes 型に対して pointer() 関数を呼び出して作成します。:

>>> from ctypes import *
>>> i = c_int(42)
>>> pi = pointer(i)
>>>

ポインタインスタンスはポインタが指すオブジェクト (上の例では i ) を返す contents 属性を持ちます。:

>>> pi.contents
c_long(42)
>>>

ctypes は OOR (original object return 、元のオブジェクトを返すこと) ではないことに注意してください。属性を取り出す度に、新しい同等のオブジェクトを作成しているのです。:

>>> pi.contents is i
False
>>> pi.contents is pi.contents
False
>>>

別の c_int インスタンスがポインタの contents 属性に代入されると、これが記憶されているメモリ位置を指すポインタに変化します。:

>>> i = c_int(99)
>>> pi.contents = i
>>> pi.contents
c_long(99)
>>>

ポインタインスタンスは整数でインデックス指定することもできます。:

>>> pi[0]
99
>>>

整数インデックスへ代入するとポインタが指す値が変更されます。:

>>> print i
c_long(99)
>>> pi[0] = 22
>>> print i
c_long(22)
>>>

0 ではないインデックスを使うこともできますが、 C の場合と同じように自分が何をしているかを理解している必要があります。任意のメモリ位置にアクセスもしくは変更できるのです。一般的にこの機能を使うのは、 C 関数からポインタを受け取り、そのポインタが単一の要素ではなく実際に配列を指していると 分かっている 場合だけです。

舞台裏では、 pointer() 関数は単にポインタインスタンスを作成するという以上のことを行っています。はじめにポインタ 型 を作成する必要があります。これは任意の ctypes 型を受け取る POINTER() 関数を使って行われ、新しい型を返します。:

>>> PI = POINTER(c_int)
>>> PI
<class 'ctypes.LP_c_long'>
>>> PI(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: expected c_long instead of int
>>> PI(c_int(42))
<ctypes.LP_c_long object at 0x...>
>>>

ポインタ型を引数なしで呼び出すと NULL ポインタを作成します。 NULL ポインタは False ブール値を持っています。:

>>> null_ptr = POINTER(c_int)()
>>> print bool(null_ptr)
False
>>>

ctypes はポインタの指す値を取り出すときに NULL かどうかを調べます(しかし、 NULL でない不正なポインタの指す値の取り出す行為は Python をクラッシュさせるでしょう)。:

>>> null_ptr[0]
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

>>> null_ptr[0] = 1234
Traceback (most recent call last):
    ....
ValueError: NULL pointer access
>>>

15.18.1.15. 型変換

たいていの場合、 ctypes は厳密な型チェックを行います。これが意味するのは、関数の argtypes リスト内に、もしくは、構造体定義におけるメンバーフィールドの型として POINTER(c_int) がある場合、厳密に同じ型のインスタンスだけを受け取るということです。このルールには ctypes が他のオブジェクトを受け取る場合に例外がいくつかあります。例えば、ポインタ型の代わりに互換性のある配列インスタンスを渡すことができます。このように、 POINTER(c_int) に対して、 ctypes は c_int の配列を受け取ります。:

>>> class Bar(Structure):
...     _fields_ = [("count", c_int), ("values", POINTER(c_int))]
...
>>> bar = Bar()
>>> bar.values = (c_int * 3)(1, 2, 3)
>>> bar.count = 3
>>> for i in range(bar.count):
...     print bar.values[i]
...
1
2
3
>>>

POINTER型フィールドを NULL に設定するために、 None を代入してもかまいません。:

>>> bar.values = None
>>>

時には、非互換な型のインスタンスであることもあります。 C では、ある型を他の型へキャストすることができます。 ctypes は同じやり方で使える cast() 関数を提供しています。上で定義した Bar 構造体は POINTER(c_int) ポインタまたは c_int 配列を values フィールドに対して受け取り、他の型のインスタンスは受け取りません:

>>> bar.values = (c_byte * 4)()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
>>>

このような場合には、 cast() 関数が便利です。

cast() 関数は ctypes インスタンスを異なる ctypes データ型を指すポインタへキャストするために使えます。 cast() は二つのパラメータ、ある種のポインタかそのポインタへ変換できる ctypes オブジェクトと、 ctypes ポインタ型を取ります。そして、第二引数のインスタンスを返します。このインスタンスは第一引数と同じメモリブロックを参照しています:

>>> a = (c_byte * 4)()
>>> cast(a, POINTER(c_int))
<ctypes.LP_c_long object at ...>
>>>

したがって、 cast() を Bar 構造体の values フィールドへ代入するために使うことができます:

>>> bar = Bar()
>>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
>>> print bar.values[0]
0
>>>

15.18.1.16. 不完全型

不完全型 はメンバーがまだ指定されていない構造体、共用体もしくは配列です。 C では、前方宣言により指定され、後で定義されます。:

struct cell; /* 前方宣言 */

struct {
    char *name;
    struct cell *next;
} cell;

ctypes コードへの直接的な変換ではこうなるでしょう。しかし、動作しません:

>>> class cell(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("next", POINTER(cell))]
...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in cell
NameError: name 'cell' is not defined
>>>

なぜなら、新しい class cell はクラス文自体の中では利用できないからです。 ctypes では、 cell クラスを定義して、 _fields_ 属性をクラス文の後で設定することができます。:

>>> from ctypes import *
>>> class cell(Structure):
...     pass
...
>>> cell._fields_ = [("name", c_char_p),
...                  ("next", POINTER(cell))]
>>>

試してみましょう。 cell のインスタンスを二つ作り、互いに参照し合うようにします。最後に、つながったポインタを何度かたどります。:

>>> c1 = cell()
>>> c1.name = "foo"
>>> c2 = cell()
>>> c2.name = "bar"
>>> c1.next = pointer(c2)
>>> c2.next = pointer(c1)
>>> p = c1
>>> for i in range(8):
...     print p.name,
...     p = p.next[0]
...
foo bar foo bar foo bar foo bar
>>>

15.18.1.17. コールバック関数

ctypes は C の呼び出し可能な関数ポインタを Python 呼び出し可能オブジェクトから作成できるようにします。これらは コールバック関数 と呼ばれることがあります。

最初に、コールバック関数のためのクラスを作る必要があります。そのクラスには呼び出し規約、戻り値の型およびこの関数が受け取る引数の数と型についての情報があります。

CFUNCTYPE ファクトリ関数は通常の cdecl 呼び出し規約を用いてコールバック関数のための型を作成します。 Windows では、 WINFUNCTYPE ファクトリ関数が stdcall 呼び出し規約を用いてコールバック関数の型を作成します。

これらのファクトリ関数はともに最初の引数に戻り値の型、残りの引数としてコールバック関数が想定する引数の型を渡して呼び出されます。

標準 C ライブラリの qsort() 関数を使う例を示します。これはコールバック関数の助けをかりて要素をソートするために使われます。 qsort() は整数の配列をソートするために使われます。:

>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
>>> qsort = libc.qsort
>>> qsort.restype = None
>>>

qsort() はソートするデータを指すポインタ、データ配列の要素の数、要素の一つの大きさ、およびコールバック関数である比較関数へのポインタを引数に渡して呼び出さなければなりません。そして、コールバック関数は要素を指す二つのポインタを渡されて呼び出され、一番目が二番目より小さいなら負の数を、等しいならゼロを、それ以外なら正の数を返さなければなりません。

コールバック関数は整数へのポインタを受け取り、整数を返す必要があります。まず、コールバック関数のための type を作成します。:

>>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
>>>

コールバック関数のはじめての実装なので、受け取った引数を単純に表示して、 0 を返します (漸進型開発 (incremental development)です ;-):

>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a, b
...     return 0
...
>>>

C の呼び出し可能なコールバック関数を作成します。:

>>> cmp_func = CMPFUNC(py_cmp_func)
>>>

そうすると、準備完了です。:

>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
>>>

ポインタの中身にアクセスする方法がわかっているので、コールバック関数を再定義しましょう。:

>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a[0], b[0]
...     return 0
...
>>> cmp_func = CMPFUNC(py_cmp_func)
>>>

Windowsでの実行結果です。:

>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
py_cmp_func 7 1
py_cmp_func 33 1
py_cmp_func 99 1
py_cmp_func 5 1
py_cmp_func 7 5
py_cmp_func 33 5
py_cmp_func 99 5
py_cmp_func 7 99
py_cmp_func 33 99
py_cmp_func 7 33
>>>

linuxではソート関数がはるかに効率的に動作しており、実施する比較の数が少ないように見えるのが不思議です。:

>>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 5 7
py_cmp_func 1 7
>>>

ええ、ほぼ完成です! 最終段階は、実際に二つの要素を比較して実用的な結果を返すことです。:

>>> def py_cmp_func(a, b):
...     print "py_cmp_func", a[0], b[0]
...     return a[0] - b[0]
...
>>>

Windowsでの最終的な実行結果です。:

>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +WINDOWS
py_cmp_func 33 7
py_cmp_func 99 33
py_cmp_func 5 99
py_cmp_func 1 99
py_cmp_func 33 7
py_cmp_func 1 33
py_cmp_func 5 33
py_cmp_func 5 7
py_cmp_func 1 7
py_cmp_func 5 1
>>>

Linuxでは:

>>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX
py_cmp_func 5 1
py_cmp_func 33 99
py_cmp_func 7 33
py_cmp_func 1 7
py_cmp_func 5 7
>>>

Windows の qsort() 関数は linux バージョンより多く比較する必要があることがわかり、非常におもしろいですね!

簡単に確認できるように、今では配列はソートされています。:

>>> for i in ia: print i,
...
1 5 7 33 99
>>>

コールバック関数についての重要な注意事項:

C コードから使われる限り、 CFUNCTYPE オブジェクトへの参照を確実に保持してください。 ctypes は保持しません。もしあなたがやらなければ、オブジェクトはゴミ集めされてしまい、コールバックしたときにあなたのプログラムをクラッシュさせるかもしれません。

15.18.1.18. dllからエクスポートされている値へアクセスする

共有ライブラリの一部は関数だけでなく変数もエクスポートしています。 Python ライブラリにある例としては Py_OptimizeFlag 、起動時の -O または -OO フラグに依存して、 0 , 1 または 2 が設定される整数があります。

ctypes は型の in_dll() クラスメソッドを使ってこのように値にアクセスできます。 pythonapi はPython C api へアクセスできるようにするための予め定義されたシンボルです。:

>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
>>> print opt_flag
c_long(0)
>>>

インタープリタが -O を指定されて動き始めた場合、サンプルは c_long(1) を表示するでしょうし、 -OO が指定されたならば c_long(2) を表示するでしょう。

ポインタの使い方を説明する拡張例では、 Python がエクスポートする PyImport_FrozenModules ポインタにアクセスします。

Python ドキュメントから引用すると: このポインタは “struct _frozen” のレコードからなり、終端の要素のメンバが NULL かゼロになっているような配列を指すよう初期化されます。フリーズされたモジュールを import するとき、このテーブルを検索します。サードパーティ製のコードからこのポインタに仕掛けを講じて、動的に生成されたフリーズ化モジュールの集合を提供するようにできます。

これで、このポインタを操作することが役に立つことを証明できるでしょう。例の大きさを制限するために、このテーブルを ctypes を使って読む方法だけを示します。:

>>> from ctypes import *
>>>
>>> class struct_frozen(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("code", POINTER(c_ubyte)),
...                 ("size", c_int)]
...
>>>

私たちは struct _frozen データ型を定義済みなので、このテーブルを指すポインタを得ることができます。:

>>> FrozenTable = POINTER(struct_frozen)
>>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
>>>

table が struct_frozen レコードの配列への pointer なので、その配列に対して反復処理を行えます。しかし、ループが確実に終了するようにする必要があります。なぜなら、ポインタに大きさの情報がないからです。遅かれ早かれ、アクセス違反か何かでクラッシュすることになるでしょう。 NULL エントリに達したときはループを抜ける方が良いです。:

>>> for item in table:
...    print item.name, item.size
...    if item.name is None:
...        break
...
__hello__ 104
__phello__ -104
__phello__.spam 104
None 0
>>>

標準 Python はフローズンモジュールとフローズンパッケージ (負のサイズのメンバーで表されています) を持っているという事実はあまり知られておらず、テストにだけ使われています。例えば、 import __hello__ を試してみてください。

15.18.1.19. 予期しないこと

ctypes には別のことを期待しているのに実際に起きることは違うという場合があります。

次に示す例について考えてみてください。:

>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = ("x", c_int), ("y", c_int)
...
>>> class RECT(Structure):
...     _fields_ = ("a", POINT), ("b", POINT)
...
>>> p1 = POINT(1, 2)
>>> p2 = POINT(3, 4)
>>> rc = RECT(p1, p2)
>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
1 2 3 4
>>> # now swap the two points
>>> rc.a, rc.b = rc.b, rc.a
>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
3 4 3 4
>>>

うーん、最後の文に 3 4 1 2 と表示されることを期待していたはずです。何が起きたのでしょうか? 上の行の rc.a, rc.b = rc.b, rc.a の各段階はこのようになります。:

>>> temp0, temp1 = rc.b, rc.a
>>> rc.a = temp0
>>> rc.b = temp1
>>>

temp0 と temp1 は前記の rc オブジェクトの内部バッファでまだ使われているオブジェクトです。したがって、 rc.a = temp0 を実行すると temp0 のバッファ内容が rc のバッファへコピーされます。さらに、これは temp1 の内容を変更します。そのため、最後の代入 rc.b = temp1 は、期待する結果にはならないのです。

Structure 、 Union および Array のサブオブジェクトを取り出しても、そのサブオブジェクトが コピー されるわけではなく、ルートオブジェクトの内部バッファにアクセスするラッパーオブジェクトを取り出すことを覚えておいてください。

期待とは違う振る舞いをする別の例はこれです。:

>>> s = c_char_p()
>>> s.value = "abc def ghi"
>>> s.value
'abc def ghi'
>>> s.value is s.value
False
>>>

なぜ False と表示されるのでしょうか? ctypes インスタンスはメモリと、メモリの内容にアクセスするいくつかの descriptor (記述子)を含むオブジェクトです。メモリブロックに Python オブジェクトを保存してもオブジェクト自身が保存される訳ではなく、オブジェクトの contents が保存されます。その contents に再アクセスすると新しい Python オブジェクトがその度に作られます。

15.18.1.20. 可変サイズのデータ型

ctypes は可変サイズの配列と構造体をサポートしています。

resize() 関数は既存の ctypes オブジェクトのメモリバッファのサイズを変更したい場合に使えます。この関数は第一引数にオブジェクト、第二引数に要求されたサイズをバイト単位で指定します。メモリブロックはオブジェクト型で指定される通常のメモリブロックより小さくすることはできません。これをやろうとすると、 ValueError が送出されます。:

>>> short_array = (c_short * 4)()
>>> print sizeof(short_array)
8
>>> resize(short_array, 4)
Traceback (most recent call last):
    ...
ValueError: minimum size is 8
>>> resize(short_array, 32)
>>> sizeof(short_array)
32
>>> sizeof(type(short_array))
8
>>>

これはこれで上手くいっていますが、この配列の追加した要素へどうやってアクセスするのでしょうか? この型は要素の数が 4 個であるとまだ認識しているので、他の要素にアクセスするとエラーになります。:

>>> short_array[:]
[0, 0, 0, 0]
>>> short_array[7]
Traceback (most recent call last):
    ...
IndexError: invalid index
>>>

ctypes で可変サイズのデータ型を使うもう一つの方法は、必要なサイズが分かった後に Python の動的性質を使って一つ一つデータ型を(再)定義することです。

15.18.2. ctypesリファレンス

15.18.2.1. 共有ライブラリを見つける

コンパイルされる言語でプログラミングしている場合、共有ライブラリはプログラムをコンパイル/リンクしているときと、そのプログラムが動作しているときにアクセスされます。

ctypes ライブラリローダーはプログラムが動作しているときのように振る舞い、ランタイムローダーを直接呼び出すのに対し、 find_library() 関数の目的はコンパイラが行うのと似た方法でライブラリを探し出すことです。 (複数のバージョンの共有ライブラリがあるプラットホームでは、一番最近に見つかったものがロードされます)。

ctypes.util モジュールはロードするライブラリを決めるのに役立つ関数を提供します。

ctypes.util.find_library(name)

ライブラリを見つけてパス名を返そうと試みます。 name は lib のような接頭辞、 .so, .dylib のような接尾辞、あるいは、バージョン番号が何も付いていないライブラリの名前です (これは posix リンカのオプション -l に使われている形式です)。もしライブラリが見つからなければ、 None を返します。

厳密な機能はシステムに依存します。

Linux では、 find_library() はライブラリファイルを見つけるために外部プログラム (/sbin/ldconfig, gcc および objdump) を実行しようとします。ライブラリファイルのファイル名を返します。いくつか例があります。:

>>> from ctypes.util import find_library
>>> find_library("m")
'libm.so.6'
>>> find_library("c")
'libc.so.6'
>>> find_library("bz2")
'libbz2.so.1.0'
>>>

OS X では、 find_library() はライブラリの位置を探すために、予め定義された複数の命名方法とパスを試し、成功すればフルパスを返します。:

>>> from ctypes.util import find_library
>>> find_library("c")
'/usr/lib/libc.dylib'
>>> find_library("m")
'/usr/lib/libm.dylib'
>>> find_library("bz2")
'/usr/lib/libbz2.dylib'
>>> find_library("AGL")
'/System/Library/Frameworks/AGL.framework/AGL'
>>>

Windows では、 find_library() はシステムの探索パスに沿って探し、フルパスを返します。しかし、予め定義された命名方法がないため、 find_library("c") のような呼び出しは失敗し、 None を返します。

もし ctypes を使って共有ライブラリをラップするなら、実行時にライブラリを探すために find_library() を使う代わりに、開発時に共有ライブラリ名を決めて、ラッパーモジュールにハードコードした方が良い かもしれません 。

15.18.2.2. 共有ライブラリをロードする

共有ライブラリを Python プロセスへロードする方法はいくつかあります。一つの方法は下記のクラスの一つをインスタンス化することです。:

class ctypes.CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は標準 C 呼び出し規約を使用し、 int を返すと仮定されます。

class ctypes.OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

Windows用: このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は stdcall 呼び出し規約を使用し、 windows 固有の HRESULT コードを返すと仮定されます。 HRESULT 値には関数呼び出しが失敗したのか成功したのかを特定する情報とともに、補足のエラーコードが含まれます。戻り値が失敗を知らせたならば、 WindowsError が自動的に送出されます。

class ctypes.WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)

Windows用: このクラスのインスタンスはロードされた共有ライブラリをあらわします。これらのライブラリの関数は stdcall 呼び出し規約を使用し、デフォルトでは int を返すと仮定されます。

Windows CE では標準呼び出し規約だけが使われます。便宜上、このプラットホームでは、 WinDLL と OleDLL が標準呼び出し規約を使用します。

これらのライブラリがエクスポートするどの関数でも呼び出す前に Python GIL (global interpreter lock) は解放され、後でまた獲得されます。

class ctypes.PyDLL(name, mode=DEFAULT_MODE, handle=None)

Python GIL が関数呼び出しの間解放 されず 、関数実行の後に Python エラーフラグがチェックされるということを除けば、このクラスのインスタンスは CDLL インスタンスのように振る舞います。エラーフラグがセットされた場合、 Python 例外が送出されます。

要するに、これは Python C api 関数を直接呼び出すのに便利だというだけです。

これらすべてのクラスは少なくとも一つの引数、すなわちロードする共有ライブラリのパスを渡して呼び出すことでインスタンス化されます。すでにロード済みの共有ライブラリへのハンドルがあるなら、 handle 名前付き引数として渡すことができます。土台となっているプラットホームの dlopen または LoadLibrary 関数がプロセスへライブラリをロードするために使われ、そのライブラリに対するハンドルを得ます。

mode パラメータはライブラリがどうやってロードされたかを特定するために使うことができます。詳細は、 dlopen(3) マニュアルページを参考にしてください。 Windows では mode は無視されます。

use_errno 変数が True に設定されたとき、システムの errno エラーナンバーに安全にアクセスする ctypes の仕組みが有効化されます。 ctypes はシステムの errno 変数のスレッド限定のコピーを管理します。もし、 use_errno=True の状態で作られた外部関数を呼び出したなら、関数呼び出し前の errno 変数は ctypes のプライベートコピーと置き換えられ、同じことが関数呼び出しの直後にも発生します。

ctypes.get_errno() 関数は ctypes のプライベートコピーの値を返します。そして、 ctypes.set_errno() 関数は ctypes のプライベートコピーを置き換え、以前の値を返します。

use_last_error パラメータは、 True に設定されたとき、 GetLastError() と SetLastError() Windows API によって管理される Windows エラーコードに対するのと同じ仕組みが有効化されます。 ctypes.get_last_error() と ctypes.set_last_error() は Windows エラーコードの ctypes プライベートコピーを変更したり要求したりするのに使われます。

バージョン 2.6 で追加: use_last_error と use_errno オプション変数が追加されました。

ctypes.RTLD_GLOBAL

mode パラメータとして使うフラグ。このフラグが利用できないプラットホームでは、整数のゼロと定義されています。

ctypes.RTLD_LOCAL

mode パラメータとして使うフラグ。これが利用できないプラットホーム

では、 RTLD_GLOBAL と同様です。

ctypes.DEFAULT_MODE

共有ライブラリをロードするために使われるデフォルトモード。 OSX 10.3 では RTLD_GLOBAL であり、そうでなければ RTLD_LOCAL と同じです。

これらのクラスのインスタンスには公開メソッドがありません。けれども、 __getattr__() と __getitem__() は特別なはたらきをします。その共有ライブラリがエクスポートする関数に添字を使って属性としてアクセスできるのです。 __getattr__() と __getitem__() のどちらもが結果をキャッシュし、そのため常に同じオブジェクトを返すことに注意してください。

次に述べる公開属性が利用できます。それらの名前はエクスポートされた関数名に衝突しないように下線で始まります。:

PyDLL._handle

ライブラリへのアクセスに用いられるシステムハンドル。

PyDLL._name

コンストラクタに渡されたライブラリの名前。

共有ライブラリは ( LibraryLoader クラスのインスタンスである ) 前もって作られたオブジェクトの一つを使うことによってロードすることもできます。それらの LoadLibrary() メソッドを呼び出すか、ローダーインスタンスの属性としてライブラリを取り出すかのどちらかによりロードします。

class ctypes.LibraryLoader(dlltype)

共有ライブラリをロードするクラス。 dlltype は CDLL 、 PyDLL 、 WinDLL もしくは OleDLL 型の一つであるべきです。

__getattr__() は特別なはたらきをします: ライブラリローダーインスタンスの属性として共有ライブラリにアクセスするとそれがロードされるということを可能にします。結果はキャッシュされます。そのため、繰り返し属性アクセスを行うといつも同じライブラリが返されます。

LoadLibrary(name)

共有ライブラリをプロセスへロードし、それを返します。このメソッドはライブラリの新しいインスタンスを常に返します。

これらの前もって作られたライブラリローダーを利用することができます。:

ctypes.cdll

CDLL インスタンスを作ります。

ctypes.windll

Windows用: WinDLL インスタンスを作ります。

ctypes.oledll

Windows用: OleDLL インスタンスを作ります。

ctypes.pydll

PyDLL インスタンスを作ります。

C Python api に直接アクセするために、すぐに使用できる Python 共有ライブラリオブジェクトが用意されています。:

ctypes.pythonapi

属性として Python C api 関数を公開する PyDLL のインスタンス。これらすべての関数は C int を返すと仮定されますが、もちろん常に正しいとは限りません。そのため、これらの関数を使うためには正しい restype 属性を代入しなければなりません。

15.18.2.3. 外部関数

前節で説明した通り、外部関数はロードされた共有ライブラリの属性としてアクセスできます。デフォルトではこの方法で作成された関数オブジェクトはどんな数の引数でも受け取り、引数としてどんな ctypes データのインスタンスをも受け取り、そして、ライブラリローダーが指定したデフォルトの結果の値の型を返します。関数オブジェクトはプライベートクラスのインスタンスです。:

class ctypes._FuncPtr

C の呼び出し可能外部関数のためのベースクラス。

外部関数のインスタンスも C 互換データ型です。それらは C の関数ポインタを表しています。

この振る舞いは外部関数オブジェクトの特別な属性に代入することによって、カスタマイズすることができます。

restype

外部関数の結果の型を指定するために ctypes 型を代入する。何も返さない関数を表す void に対しては None を使います。

ctypes 型ではない呼び出し可能な Python オブジェクトを代入することは可能です。このような場合、関数が C int を返すと仮定され、呼び出し可能オブジェクトはこの整数を引数に呼び出されます。さらに処理を行ったり、エラーチェックをしたりできるようにするためです。これの使用は推奨されません。より柔軟な後処理やエラーチェックのためには restype として ctypes 型を使い、 errcheck 属性へ呼び出し可能オブジェクトを代入してください。

argtypes

関数が受け取る引数の型を指定するために ctypes 型のタプルを代入します。 stdcall 呼び出し規約をつかう関数はこのタプルの長さと同じ数の引数で呼び出されます。その上、 C 呼び出し規約をつかう関数は追加の不特定の引数も取ります。

外部関数が呼ばれたとき、それぞれの実引数は argtypes タプルの要素の from_param() クラスメソッドへ渡されます。このメソッドは実引数を外部関数が受け取るオブジェクトに合わせて変えられるようにします。例えば、 argtypes タプルの c_char_p 要素は、 ctypes 変換規則にしたがって引数として渡されたユニコード文字列をバイト文字列へ変換するでしょう。

新: ctypes 型でない要素を argtypes に入れることができますが、個々の要素は引数として使える値 ( 整数、文字列、 ctypes インスタンス ) を返す from_param() メソッドを持っていなければなりません。これにより関数パラメータとしてカスタムオブジェクトを適合するように変更できるアダプタが定義可能となります。

errcheck

Python 関数または他の呼び出し可能オブジェクトをこの属性に代入します。呼び出し可能オブジェクトは三つ以上の引数とともに呼び出されます。

callable(result, func, arguments)

result は外部関数が返すもので、 restype 属性で指定されます。

func は外部関数オブジェクト自身で、これにより複数の関数の処理結果をチェックまたは後処理するために、同じ呼び出し可能オブジェクトを再利用できるようになります。

arguments は関数呼び出しに最初に渡されたパラメータが入ったタプルです。これにより使われた引数に基づた特別な振る舞いをさせることができるようになります。

この関数が返すオブジェクトは外部関数呼び出しから返された値でしょう。しかし、戻り値をチェックして、外部関数呼び出しが失敗しているなら例外を送出させることもできます。

exception ctypes.ArgumentError

この例外は外部関数呼び出しが渡された引数を変換できなかったときに送出されます。

15.18.2.4. 関数プロトタイプ

外部関数は関数プロトタイプをインスタンス化することによって作成されます。関数プロトタイプは C の関数プロトタイプと似ています。実装を定義せずに、関数 ( 戻り値、引数の型、呼び出し規約 ) を記述します。ファクトリ関数は関数に要求する戻り値の型と引数の型とともに呼び出されます。

ctypes.CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)

返された関数プロトタイプは標準 C 呼び出し規約をつかう関数を作成します。関数は呼び出されている間 GIL を解放します。 use_errno が True に設定されれば、呼び出しの前後で System 変数 errno の ctypesプライベートコピーは本当の errno の値と交換されます。 use_last_error も Windows エラーコードに対するのと同様です。

バージョン 2.6 で変更: オプションの use_errno と use_last_error 変数が追加されました。

ctypes.WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)

Windows 用: 返された関数プロトタイプは stdcall 呼び出し規約をつかう関数を作成します。ただし、 WINFUNCTYPE() が CFUNCTYPE() と同じである Windows CE を除きます。関数は呼び出されている間 GIL を解放します。 use_errno と use_last_error は前述と同じ意味を持ちます。

ctypes.PYFUNCTYPE(restype, *argtypes)

返された関数プロトタイプは Python 呼び出し規約をつかう関数を作成します。関数は呼び出されている間 GIL を解放 しません 。

ファクトリ関数によって作られた関数プロトタイプは呼び出しのパラメータの型と数に依存した別の方法でインスタンス化することができます。 :

prototype(address)

指定されたアドレス(整数でなくてはなりません)の外部関数を返します。

prototype(callable)

Python の callable から C の呼び出し可能関数(コールバック関数) を作成します。

prototype(func_spec[, paramflags])

共有ライブラリがエクスポートしている外部関数を返します。 func_spec は 2 要素タプル (name_or_ordinal, library) でなければなりません。第一要素はエクスポートされた関数の名前である文字列、またはエクスポートされた関数の序数である小さい整数です。第二要素は共有ライブラリインスタンスです。

prototype(vtbl_index, name[, paramflags[, iid]])

COM メソッドを呼び出す外部関数を返します。 vtbl_index は仮想関数テーブルのインデックスで、非負の小さい整数です。 name は COM メソッドの名前です。 iid はオプションのインターフェイス識別子へのポインタで、拡張されたエラー情報の提供のために使われます。

COM メソッドは特殊な呼び出し規約を用います。このメソッドは argtypes タプルに指定されたパラメータに加えて、第一引数として COM インターフェイスへのポインタを必要とします。

オプションの paramflags パラメータは上述した機能より多機能な外部関数ラッパーを作成します。

paramflags は argtypes と同じ長さのタプルでなければなりません。

このタプルの個々の要素はパラメータについてのより詳細な情報を持ち、 1 、 2 もしくは 3 要素を含むタプルでなければなりません。

第一要素はパラメータについてのフラグの組み合わせを含んだ整数です。

1

入力パラメータを関数に指定します。

2

出力パラメータ。外部関数が値を書き込みます。

4

デフォルトで整数ゼロになる入力パラメータ。

オプションの第二要素はパラメータ名の文字列です。これが指定された場合は、外部関数を名前付きパラメータで呼び出すことができます。

オプションの第三要素はこのパラメータのデフォルト値です。

この例では、デフォルトパラメータと名前付き引数をサポートするために Windows MessageBoxA 関数をラップする方法を示します。 windowsヘッダファイルの C の宣言はこれです。:

WINUSERAPI int WINAPI
MessageBoxA(
    HWND hWnd ,
    LPCSTR lpText,
    LPCSTR lpCaption,
    UINT uType);

ctypes を使ってラップします。:

>>> from ctypes import c_int, WINFUNCTYPE, windll
>>> from ctypes.wintypes import HWND, LPCSTR, UINT
>>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
>>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
>>> MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
>>>

今は MessageBox 外部関数をこのような方法で呼び出すことができます。:

>>> MessageBox()
>>> MessageBox(text="Spam, spam, spam")
>>> MessageBox(flags=2, text="foo bar")
>>>

二番目の例は出力パラメータについて説明します。 win32 の GetWindowRect 関数は、指定されたウィンドウの大きさを呼び出し側が与える RECT 構造体へコピーすることで取り出します。 C の宣言はこうです。:

WINUSERAPI BOOL WINAPI
GetWindowRect(
     HWND hWnd,
     LPRECT lpRect);

ctypes を使ってラップします。:

>>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
>>> from ctypes.wintypes import BOOL, HWND, RECT
>>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
>>> paramflags = (1, "hwnd"), (2, "lprect")
>>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
>>>

もし単一の値もしくは一つより多い場合には出力パラメータ値が入ったタプルがあるならば、出力パラメータを持つ関数は自動的に出力パラメータ値を返すでしょう。そのため、今は GetWindowRect 関数は呼び出されたときに RECT インスタンスを返します。

さらに出力処理やエラーチェックを行うために、出力パラメータを errcheck プロトコルと組み合わせることができます。 win32 GetWindowRect api 関数は成功したか失敗したかを知らせるために BOOL を返します。そのため、この関数はエラーチェックを行って、 api 呼び出しが失敗した場合に例外を送出させることができます。:

>>> def errcheck(result, func, args):
...     if not result:
...         raise WinError()
...     return args
...
>>> GetWindowRect.errcheck = errcheck
>>>

errcheck 関数が変更なしに受け取った引数タプルを返したならば、 ctypes は出力パラメータに対して通常の処理を続けます。 RECT インスタンスの代わりに window 座標のタプルを返してほしいなら、関数のフィールドを取り出し、代わりにそれらを返すことができます。通常処理はもはや行われないでしょう。:

>>> def errcheck(result, func, args):
...     if not result:
...         raise WinError()
...     rc = args[1]
...     return rc.left, rc.top, rc.bottom, rc.right
...
>>> GetWindowRect.errcheck = errcheck
>>>

15.18.2.5. ユーティリティ関数

ctypes.addressof(obj)

メモリバッファのアドレスを示す整数を返します。 obj は ctypes 型のインスタンスでなければなりません。

ctypes.alignment(obj_or_type)

ctypes 型のアライメントの必要条件を返します。 obj_or_type は ctypes 型またはインスタンスでなければなりません。

ctypes.byref(obj[, offset])

obj (ctypes 型のインスタンスでなければならない) への軽量ポインタを返します。 offset はデフォルトでは 0 で、内部ポインターへ加算される整数です。

byref(obj, offset) は、 C コードとしては、以下のようにみなされます。:

(((char *)&obj) + offset)

返されるオブジェクトは外部関数呼び出しのパラメータとしてのみ使用できます。 pointer(obj) と似たふるまいをしますが、作成が非常に速く行えます。

バージョン 2.6 で追加: offset オプション引数が追加されました。

ctypes.cast(obj, type)

この関数は C のキャスト演算子に似ています。 obj と同じメモリブロックを指している type の新しいインスタンスを返します。 type はポインタ型でなければならず、 obj はポインタとして解釈できるオブジェクトでなければなりません。

ctypes.create_string_buffer(init_or_size[, size])

この関数は変更可能な文字バッファを作成します。返されるオブジェクトは c_char の ctypes 配列です。

init_or_size は配列のサイズを指定する整数もしくは配列要素を初期化するために使われる文字列である必要があります。

第一引数として文字列が指定された場合は、バッファが文字列の長さより一要素分大きく作られます。配列の最後の要素が NUL 終端文字であるためです。文字列の長さを使うべきでない場合は、配列のサイズを指定するために整数を第二引数として渡すことができます。

第一引数がユニコード文字列ならば、 ctypes 変換規則にしたがい 8 ビット文字列へ変換されます。

ctypes.create_unicode_buffer(init_or_size[, size])

この関数は変更可能なユニコード文字バッファを作成します。返されるオブジェクトは c_wchar の ctypes 配列です。

init_or_size は配列のサイズを指定する整数もしくは配列要素を初期化するために使われるユニコード文字列です。

第一引数としてユニコード文字列が指定された場合は、バッファが文字列の長さより一要素分大きく作られます。配列の最後の要素が NUL 終端文字であるためです。文字列の長さを使うべきでない場合は、配列のサイズを指定するために整数を第二引数として渡すことができます。

第一引数が 8 ビット文字列ならば、 ctypes 変換規則にしたがいユニコード文字列へ変換されます。

ctypes.DllCanUnloadNow()

Windows用: この関数は ctypes をつかってインプロセス COM サーバーを実装できるようにするためのフックです。 _ctypes 拡張 dll がエクスポートしている DllCanUnloadNow 関数から呼び出されます。

ctypes.DllGetClassObject()

Windows用: この関数は ctypes をつかってインプロセス COM サーバーを実装できるようにするためのフックです。 _ctypes 拡張 dll がエクスポートしている DllGetClassObject 関数から呼び出されます。

ctypes.util.find_library(name)

ライブラリを検索し、パス名を返します。 name は lib のような接頭辞、 .so や .dylib のような接尾辞、そして、バージョンナンバーを除くライブラリ名です (これは posix のリンカーオプション -l で使われる書式です) 。もしライブラリが見つからなければ、 None を返します。

実際の機能はシステムに依存します。

バージョン 2.6 で変更: Windows限定: find_library("m") もしくは find_library("c") は find_msvcrt() の呼び出し結果を返します。

ctypes.util.find_msvcrt()

Windows用: Python と拡張モジュールで使われる VC ランタイプライブラリのファイル名を返します。もしライブラリ名が同定できなければ、 None を返します。

もし、例えば拡張モジュールにより割り付けられたメモリを free(void *) で解放する必要があるなら、メモリ割り付けを行ったのと同じライブラリの関数を使うことが重要です。

バージョン 2.6 で追加.

ctypes.FormatError([code])

Windows用: エラーコード code の説明文を返します。エラーコードが指定されない場合は、 Windows api 関数 GetLastError を呼び出して、もっとも新しいエラーコードが使われます。

ctypes.GetLastError()

Windows用: 呼び出し側のスレッド内で Windows によって設定された最新のエラーコードを返します。この関数はWindowsの GetLastError() 関数を直接実行します。 ctypesのプライベートなエラーコードのコピーを返したりはしません。

ctypes.get_errno()

システムの errno 変数の、スレッドローカルなプライベートコピーを返します。

バージョン 2.6 で追加.

ctypes.get_last_error()

Windowsのみ: システムの LastError 変数の、スレッドローカルなプライベートコピーを返します。

バージョン 2.6 で追加.

ctypes.memmove(dst, src, count)

標準 C の memmove ライブラリ関数と同じものです。: count バイトを src から dst へコピーします。 dst と src はポインタへ変換可能な整数または ctypes インスタンスでなければなりません。

ctypes.memset(dst, c, count)

標準 C の memset ライブラリ関数と同じものです。: アドレス dst のメモリブロックを値 c を count バイト分書き込みます。 dst はアドレスを指定する整数または ctypes インスタンスである必要があります。

ctypes.POINTER(type)

このファクトリ関数は新しい ctypes ポインタ型を作成して返します。ポインタ型はキャッシュされ、内部で再利用されます。したがって、この関数を繰り返し呼び出してもコストは小さいです。 type は ctypes 型でなければなりません。

ctypes.pointer(obj)

この関数は obj を指す新しいポインタインスタンスを作成します。戻り値は POINTER(type(obj)) 型のオブジェクトです。

注意: 外部関数呼び出しへオブジェクトへのポインタを渡したいだけなら、はるかに高速な byref(obj) を使うべきです。

ctypes.resize(obj, size)

この関数は obj の内部メモリバッファのサイズを変更します。 obj は ctypes 型のインスタンスでなければなりません。バッファを sizeof(type(obj)) で与えられるオブジェクト型の本来のサイズより小さくすることはできませんが、バッファを拡大することはできます。

ctypes.set_conversion_mode(encoding, errors)

この関数は 8 ビット文字列とユニコード文字列の間で変換するときに使われる規則を設定します。 encoding は 'utf-8' や 'mbcs' のようなエンコーディングを指定する文字列でなければなりません。 errors はエンコーディング/デコーディングエラーについてのエラー処理を指定する文字列でなければなりません。指定可能な値の例としては、 "strict", "replace", "ignore" があります。

set_conversion_mode() は以前の変換規則を含む 2 要素タプルを返します。 windows では初期の変換規則は ('mbcs', 'ignore') であり、他のシステムでは ('ascii', 'strict') です。

ctypes.set_errno(value)

システム変数 errno の、呼び出し元スレッドでの ctypes のプライベートコピーの現在値を value に設定し、前の値を返します。

バージョン 2.6 で追加.

ctypes.set_last_error(value)

Windows用: システム変数 LastError の、呼び出し元スレッドでの ctypes のプライベートコピーの現在値を value に設定し、前の値を返します。

バージョン 2.6 で追加.

ctypes.sizeof(obj_or_type)

ctypes 型もしくはインスタンスのメモリバッファのサイズをバイト単位で返します。 C の sizeof() 関数と同じ動作です。

ctypes.string_at(address[, size])

この関数はメモリアドレス address から始まる文字列を返します。 size が指定された場合はサイズとして使われます。指定されなければ、文字列がゼロ終端されていると仮定します。

ctypes.WinError(code=None, descr=None)

Windows用: この関数は ctypes の中でもおそらく最悪な名前がつけられたものです。 WindowsError のインスタンスを作成します。 code が指定されないならば、エラーコードを決めるために GetLastError が呼び出されます。 descr が指定されないならば、 FormatError() がエラーの説明文を得るために呼び出されます。

ctypes.wstring_at(address[, size])

この関数はユニコード文字列としてメモリアドレス address から始まるワイドキャラクタ文字列を返します。 size が指定されたならば、文字列の文字数として使われます。指定されなければ、文字列がゼロ終端されていると仮定します。

15.18.2.6. データ型

class ctypes._CData

この非公開クラスはすべての ctypes データ型の共通のベースクラスです。他のことはさておき、すべての ctypes 型インスタンスは C 互換データを保持するメモリブロックを内部に持ちます。このメモリブロックのアドレスは addressof() ヘルパー関数が返します。別のインスタンス変数が _objects として公開されます。これはメモリブロックがポインタを含む場合に存続し続ける必要のある他の Python オブジェクトを含んでいます。

ctypes データ型の共通メソッド、すべてのクラスメソッドが存在します (正確には、メタクラスのメソッドです):

from_buffer(source[, offset])

このメソッドは source オブジェクトのバッファを共有する ctypes のインスタンスを返します。 source オブジェクトは書き込み可能バッファインターフェースをサポートしている必要があります。オプションの offset 引数では source バッファのオフセットをバイト単位で指定します。デフォルトではゼロです。もし source バッファが十分に大きくなければ、 ValueError が送出されます。

バージョン 2.6 で追加.

from_buffer_copy(source[, offset])

このメソッドは source オブジェクトの読み出し可能バッファをコピーすることで、ctypes のインスタンスを生成します。オプションの offset 引数では source バッファのオフセットをバイト単位で指定します。デフォルトではゼロです。もし source バッファが十分に大きくなければ、 ValueError が送出されます。

バージョン 2.6 で追加.

from_address(address)

このメソッドは address で指定されたメモリを使って ctypes 型のインスタンスを返します。 address は整数でなければなりません。

from_param(obj)

このメソッドは obj を ctypes 型に適合させます。外部関数の argtypes タプルに、その型があるとき、外部関数呼び出しで実際に使われるオブジェクトと共に呼び出されます。

すべての ctypes のデータ型は、それが型のインスタンスであれば、 obj を返すこのクラスメソッドのデフォルトの実装を持ちます。いくつかの型は、別のオブジェクトも受け付けます。

in_dll(library, name)

このメソッドは、共有ライブラリによってエクスポートされた ctypes 型のインスタンスを返します。 name はエクスポートされたデータの名前で、 library はロードされた共有ライブラリです。

ctypes データ型共通のインスタンス変数:

_b_base_

ctypes 型データのインスタンスは、それ自身のメモリブロックを持たず、基底オブジェクトのメモリブロックの一部を共有することがあります。 _b_base_ 読み出し専用属性は、メモリブロックを保持する ctypes の基底オブジェクトです。

_b_needsfree_

この読み出し専用の変数は、 ctypes データインスタンスが、それ自身に割り当てられたメモリブロックを持つとき true になります。それ以外の場合は false になります。

_objects

このメンバは None 、または、メモリブロックの内容が正しく保つために、生存させておかなくてはならない Python オブジェクトを持つディクショナリです。このオブジェクトはデバッグでのみ使われます。決してディクショナリの内容を変更しないで下さい。

15.18.2.7. 基本データ型

class ctypes._SimpleCData

この非公開クラスはすべての基本 ctypes データ型のベースクラスです。ここでこのクラスに触れたのは、基本 ctypes データ型の共通属性を含んでいるからです。 _SimpleCData は _CData のサブクラスですので、そのメソッドと属性を継承しています。

バージョン 2.6 で変更: ポインタと、ポインタを含まない ctypes データ型が pickle 化できるようになりました。

インスタンスは一つだけ属性を持ちます:

value

この属性は、インスタンスの実際の値を持ちます。整数型とポインタ型に対しては整数型、文字型に対しては一文字の文字列、文字へのポインタに対しては Python の文字列もしくはユニコード文字列となります。

value 属性が ctypes インスタンスより参照されたとき、大抵の場合はそれぞれに対し新しいオブジェクトを返します。 ctypes はオリジナルのオブジェクトを返す実装にはなって おらず 新しいオブジェクトを構築します。同じことが他の ctypes オブジェクトインスタンスに対しても言えます。

基本データ型は、外部関数呼び出しの結果として返されたときや、例えば構造体のフィールドメンバーや配列要素を取り出すときに、ネイティブの Python 型へ透過的に変換されます。言い換えると、外部関数が c_char_p の restype を持つ場合は、 c_char_p インスタンスではなく 常に Python 文字列を受け取ることでしょう。

基本データ型のサブクラスはこの振る舞いを継承 しません 。したがって、外部関数の restype が c_void_p のサブクラスならば、関数呼び出しからこのサブクラスのインスタンスを受け取ります。もちろん、 value 属性にアクセスしてポインタの値を得ることができます。

これらが基本データ型です:

class ctypes.c_byte

C の signed char データ型を表し、小整数として値を解釈します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_char

C char データ型を表し、単一の文字として値を解釈します。コンストラクタはオプションの文字列初期化子を受け取り、その文字列の長さちょうど一文字である必要があります。

class ctypes.c_char_p

C char * データ型を表し、ゼロ終端文字列へのポインタでなければなりません。バイナリデータを指す可能性のある一般的なポインタに対しては POINTER(c_char) を使わなければなりません。コンストラクタは整数のアドレスもしくは文字列を受け取ります。

class ctypes.c_double

C double データ型を表します。コンストラクタはオプションの浮動小数点数初期化子を受け取ります。

class ctypes.c_longdouble

C long double データ型を表します。コンストラクタはオプションで浮動小数点数初期化子を受け取ります。 sizeof(long double) == sizeof(double) であるプラットホームでは c_double の別名です。

バージョン 2.6 で追加.

class ctypes.c_float

C float データ型を表します。コンストラクタはオプションの浮動小数点数初期化子を受け取ります。

class ctypes.c_int

C signed int データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。 sizeof(int) == sizeof(long) であるプラットホームでは、 c_long の別名です。

class ctypes.c_int8

C 8-bit signed int データ型を表します。たいていは、 c_byte の別名です。

class ctypes.c_int16

C 16-bit signed int データ型を表します。たいていは、 c_short の別名です。

class ctypes.c_int32

C 32-bit signed int データ型を表します。たいていは、 c_int の別名です。

class ctypes.c_int64

C 64-bit signed int データ型を表します。たいていは、 c_longlong の別名です。

class ctypes.c_long

C signed long データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_longlong

C signed long long データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_short

C signed short データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_size_t

C size_t データ型を表します。

class ctypes.c_ssize_t

C ssize_t データ型を表します。

バージョン 2.7 で追加.

class ctypes.c_ubyte

C unsigned char データ型を表します。その値は小整数として解釈されます。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_uint

C unsigned int データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。 sizeof(int) == sizeof(long) であるプラットホームでは、 c_ulong の別名です。

class ctypes.c_uint8

C 8-bit unsigned int データ型を表します。たいていは、 c_ubyte の別名です。

class ctypes.c_uint16

C 16-bit unsigned int データ型を表します。たいていは、 c_ushort の別名です。

class ctypes.c_uint32

C 32-bit unsigned int データ型を表します。たいていは、 c_uint の別名です。

class ctypes.c_uint64

C 64-bit unsigned int データ型を表します。たいていは、 c_ulonglong の別名です。

class ctypes.c_ulong

C unsigned long データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_ulonglong

C unsigned long long データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_ushort

C unsigned short データ型を表します。コンストラクタはオプションの整数初期化子を受け取ります。オーバーフローのチェックは行われません。

class ctypes.c_void_p

C void * データ型を表します。値は整数として表されます。コンストラクタはオプションの整数初期化子を受け取ります。

class ctypes.c_wchar

C wchar_t データ型を表し、値はユニコード文字列の単一の文字として解釈されます。コンストラクタはオプションの文字列初期化子を受け取り、その文字列の長さはちょうど一文字である必要があります。

class ctypes.c_wchar_p

C wchar_t * データ型を表し、ゼロ終端ワイド文字列へのポインタでなければなりません。コンストラクタは整数のアドレスもしくは文字列を受け取ります。

class ctypes.c_bool

C bool データ型 (より正確には、C99 の _Bool) を表します。その値は True または False であり、コンストラクタはどんなオブジェクト ( 真値を持ちます ) でも受け取ります。

バージョン 2.6 で追加.

class ctypes.HRESULT

Windows用: HRESULT 値を表し、関数またはメソッド呼び出しに対する成功またはエラーの情報を含んでいます。

class ctypes.py_object

C PyObject * データ型を表します。引数なしでこれを呼び出すと NULL PyObject * ポインタを作成します。

ctypes.wintypes モジュールは他の Windows 固有のデータ型を提供します。例えば、 HWND, WPARAM, DWORD です。 MSG や RECT のような有用な構造体も定義されています。

15.18.2.8. 標準データ型

class ctypes.Union(*args, **kw)

ネイティブのバイトオーダーでの共用体のための抽象ベースクラス。

class ctypes.BigEndianStructure(*args, **kw)

ビックエンディアン バイトオーダーでの構造体のための抽象ベースクラス。

class ctypes.LittleEndianStructure(*args, **kw)

リトルエンディアン バイトオーダーでの構造体のための抽象ベースクラス。

ネイティブではないバイトオーダーを持つ構造体にポインタ型フィールドあるいはポインタ型フィールドを含む他のどんなデータ型をも入れることはできません。

class ctypes.Structure(*args, **kw)

ネイティブ のバイトオーダーでの構造体のための抽象ベースクラス。

具象構造体型と具象共用体型はこれらの型の一つをサブクラス化することで作らなければなりません。少なくとも、 _fields_ クラス変数を定義する必要があります。 ctypes は、属性に直接アクセスしてフィールドを読み書きできるようにする記述子 ( descriptor ) を作成するでしょう。これらは、

ctypes._fields_

構造体のフィールドを定義するシーケンス。要素は2要素タプルか3要素タプルでなければなりません。第一要素はフィールドの名前です。第二要素はフィールドの型を指定します。それはどんな ctypes データ型でも構いません。

c_int のような整数型のために、オプションの第三要素を与えることができます。フィールドのビット幅を定義する正の小整数である必要があります。

一つの構造体と共用体の中で、フィールド名はただ一つである必要があります。これはチェックされません。名前が繰り返しでてきたときにアクセスできるのは一つのフィールドだけです。

Structure サブクラスを定義するクラス文の 後で 、 _fields_ クラス変数を定義することができます。これにより自身を直接または間接的に参照するデータ型を作成できるようになります。:

class List(Structure):
    pass
List._fields_ = [("pnext", POINTER(List)),
                 ...
                ]

しかし、 _fields_ クラス変数はその型が最初に使われる ( インスタンスが作成される、それに対して sizeof() が呼び出されるなど ) より前に定義されていなければなりません。その後 _fields_ クラス変数へ代入すると AttributeError が送出されます。

構造体および共用体サブクラスは位置引数と名前付き引数の両方を受け取ります。位置引数は _fields_ 定義中に現れたのと同じ順番でフィールドを初期化するために使われ、名前付き引数は対応する名前を使ってフィールドを初期化するために使われます。

構造体型のサブクラスを定義することができ、もしあるならサブクラス内で定義された _fields_ に加えて、ベースクラスのフィールドも継承します。

ctypes._pack_

インスタンスの構造体フィールドのアライメントを上書きできるようにするオブションの小整数。 _pack_ は _fields_ が代入されたときすでに定義されていなければなりません。そうでなければ、何ら影響はありません。

ctypes._anonymous_

無名 (匿名) フィールドの名前が並べあげられたオプションのシーケンス。 _fields_ が代入されたとき、 _anonymous_ がすでに定義されていなければなりません。そうでなければ、何ら影響はありません。

この変数に並べあげられたフィールドは構造体型もしくは共用体型フィールドである必要があります。構造体フィールドまたは共用体フィールドを作る必要なく、入れ子になったフィールドに直接アクセスできるようにするために、 ctypes は構造体型の中に記述子を作成します。

型の例です(Windows):

class _U(Union):
    _fields_ = [("lptdesc", POINTER(TYPEDESC)),
                ("lpadesc", POINTER(ARRAYDESC)),
                ("hreftype", HREFTYPE)]

class TYPEDESC(Structure):
    _anonymous_ = ("u",)
    _fields_ = [("u", _U),
                ("vt", VARTYPE)]

TYPEDESC 構造体はCOMデータ型を表現しており、 vt フィールドは共用体フィールドのどれが有効であるかを指定します。 u フィールドは匿名フィールドとして定義されているため、 TYPEDESC インスタンスから取り除かれてそのメンバーへ直接アクセスできます。 td.lptdesc と td.u.lptdesc は同等ですが、前者がより高速です。なぜなら一時的な共用体インスタンスを作る必要がないためです。:

td = TYPEDESC()
td.vt = VT_PTR
td.lptdesc = POINTER(some_type)
td.u.lptdesc = POINTER(some_type)

構造体のサブ-サブクラスを定義することができ、ベースクラスのフィールドを継承します。サブクラス定義に別の _fields_ 変数がある場合は、この中で指定されたフィールドはベースクラスのフィールドへ追加されます。

構造体と共用体のコンストラクタは位置引数とキーワード引数の両方を受け取ります。位置引数は _fields_ の中に現れたのと同じ順番でメンバーフィールドを初期化するために使われます。コンストラクタのキーワード引数は属性代入として解釈され、そのため、同じ名前をもつ _fields_ を初期化するか、 _fields_ に存在しない名前に対しては新しい属性を作ります。

15.18.2.9. 配列とポインタ

未作成 - チュートリアルの節 ポインタ と配列 を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス

この章で説明するモジュールでは、特定のオペレーティングシステムでだけ利用できるオペレーティングシステム機能へのインタフェースを提供します。このインタフェースは、おおむね Unix や C のインタフェースにならってモデル化してありますが、他のシステム上（WindowsやNTなど）でも利用できることがあります。次に概要を示します。

16.1. select — I/O 処理の完了を待機する

16.1.1. エッジおよびレベルトリガポーリング (epoll) オブジェクト

16.1.2. ポーリングオブジェクト

16.1.3. kqueue オブジェクト

16.1.4. kevent オブジェクト

16.2. threading — 高水準のスレッドインタフェース

16.2.1. Thread オブジェクト

16.2.2. Lock オブジェクト

16.2.3. RLock オブジェクト

16.2.4. Condition オブジェクト

16.2.5. Semaphore オブジェクト

16.2.5.1. Semaphore の例

16.2.6. Event オブジェクト

16.2.7. Timer オブジェクト

16.2.8. with 文でのロック・条件変数・セマフォの使い方

16.2.9. スレッド化されたコード中でのImport

16.3. thread — マルチスレッドのコントロール

16.4. dummy_threading — threading の代替モジュール

16.5. dummy_thread — thread の代替モジュール

16.6. multiprocessing — プロセスベースの “並列処理” インタフェース

16.6.1. はじめに

16.6.1.1. Process クラス

16.6.1.2. プロセス間でのオブジェクト交換

16.6.1.3. プロセス間の同期

16.6.1.4. プロセス間での状態の共有

16.6.1.5. ワーカープロセスのプールを使用

16.6.2. リファレンス

16.6.2.1. Process クラスと例外

16.6.2.2. パイプ (Pipe) とキュー (Queue)

16.6.2.3. その他の関数(Miscellaneous)

16.6.2.4. Connection オブジェクト

16.6.2.5. 同期プリミティブ

16.6.2.6. 共有 ctypes オブジェクト

16.6.2.6.1. multiprocessing.sharedctypes モジュール

16.6.2.7. Managers

16.6.2.7.1. Namespace オブジェクト

16.6.2.7.2. カスタマイズされたマネージャ

16.6.2.7.3. リモートマネージャを使用する

16.6.2.8. Proxy オブジェクト

16.6.2.8.1. クリーンアップ

16.6.2.9. プロセスプール

16.6.2.10. Listeners and Clients

16.6.2.10.1. アドレスフォーマット

16.6.2.11. 認証キー

16.6.2.12. ロギング

16.6.2.13. multiprocessing.dummy モジュール

16.6.3. プログラミングガイドライン

16.6.3.1. 全てのプラットホーム

16.6.3.2. Windows

16.6.4. 例

16.7. mmap — メモリマップファイル

16.8. readline — GNU readline のインタフェース

16.8.1. 例

16.9. rlcompleter — GNU readline向け補完関数

16.9.1. Completerオブジェクト

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.1. select — I/O 処理の完了を待機する

このモジュールでは、ほとんどのオペレーティングシステムで利用可能な select() および poll() 関数、 Linux 2.5+ で利用可能な epoll() 、多くのBSDで利用可能な kqueue() 関数に対するアクセスを提供しています。 Windows 上ではソケットに対してしか動作しないので注意してください; その他のオペレーティングシステムでは、他のファイル形式でも (特に Unixではパイプにも) 動作します。通常のファイルに対して適用し、最後にファイルを読み出した時から内容が増えているかを決定するために使うことはできません。

このモジュールでは以下の内容を定義しています:

exception select.error

エラーが発生したときに送出される例外です。エラーに付属する値は、 errno からとったエラーコードを表す数値とそのエラーコードに対応する文字列からなるペアで、C 関数の perror() が出力するものと同様です。

select.epoll([sizehint=-1])

(Linux 2.5.44 以降でのみサポート) エッジポーリング(edge polling)オブジェクトを返します。このオブジェクトは、 I/O イベントのエッジトリガもしくはレベルトリガインタフェースとして使うことができます。エッジポーリングオブジェクトが提供しているメソッドについては、 エッジおよびレベルトリガポーリング (epoll) オブジェクト 節を参照してください。

バージョン 2.6 で追加.

select.poll()

(全てのオペレーティングシステムでサポートされているわけではありません) ポーリングオブジェクトを返します。このオブジェクトはファイル記述子を登録したり登録解除したりすることができ、ファイル記述子に対する I/O イベント発生をポーリングすることができます; ポーリングオブジェクトが提供しているメソッドについては ポーリングオブジェクト 節を参照してください。

select.kqueue()

(BSD でのみサポート) カーネルキュー(kernel queue)オブジェクトを返します。カーネルキューオブジェクトが提供しているメソッドについては、 kqueue オブジェクト 節を参照してください。

バージョン 2.6 で追加.

select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)

(BSD でのみサポート) カーネルイベント(kernel event)オブジェクトを返します。カーネルイベントオブジェクトが提供しているメソッドについては、 kevent オブジェクト 節を参照してください。

バージョン 2.6 で追加.

select.select(rlist, wlist, xlist[, timeout])

Unix の select() システムコールに対する直接的なインタフェースです。最初の 3 つの引数は ‘待機可能オブジェクト’ からなるシーケンスです: 待機可能オブジェクトとは、ファイル記述子を表す整数値か、引数なしで整数を返すメソッド fileno() を持つオブジェクトです。

rlist: 読み込み可能になるまで待つ

wlist: 書き込み可能になるまで待つ

xlist: “例外状態 (exceptional condition)” になるまで待つ (“例外状態” については、システムのマニュアルページを参照してください)

引数に空のシーケンスを指定してもかまいませんが、3 つの引数全てを空のシーケンスにしてもよいかどうかはプラットフォームに依存します (Unix では動作し、Windows では動作しないことが知られています)。オプションの timeout 引数にはタイムアウトまでの秒数を浮動小数点数で指定します。 timeout 引数が省略された場合、関数は少なくとも一つのファイル記述子が何らかの準備完了状態になるまでブロックします。 timeout に 0 を指定した場合は、ポーリングを行いブロックしないことを示します。

戻り値は準備完了状態のオブジェクトからなる 3 つのリストです: したがってこのリストはそれぞれ関数の最初の 3 つの引数のサブセットになります。ファイル記述子のいずれも準備完了にならないままタイムアウトした場合、3 つの空のリストが返されます。

シーケンスの中に含めることのできるオブジェクトは Python ファイルオブジェクト (例えば sys.stdin や、 open() または os.popen() が返すオブジェクト)、 socket.socket() が返すソケットオブジェクトです。ラッパー (wrapper) クラスを自分で定義することもできます。この場合、適切な (単なる乱数ではなく本当のファイル記述子を返す) fileno() メソッドを持つ必要があります。

ノート

select() は Windows のファイルオブジェクトを受理しませんが、ソケットは受理します。 Windows では、背後の select() 関数は WinSock ライブラリで提供されており、 WinSock によって生成されたものではないファイル記述子を扱うことができないのです。

select.PIPE_BUF

select() や poll() などのインタフェースにより書き込み可能になったと報告されたファイルは、 PIPE_BUF バイトまではブロックしないで書き込みできることが保証されます。この値は POSIX では最低でも 512 であることが保証されています。

利用可能な環境: Unix

バージョン 2.7 で追加.

16.1.1. エッジおよびレベルトリガポーリング (epoll) オブジェクト

http://linux.die.net/man/4/epoll

eventmask

定数 | 意味
EPOLLIN | 読み込み可能
EPOLLOUT | 書き込み可能
EPOLLPRI | 緊急の読み出しデータ
EPOLLERR | 設定された fd にエラー状態が発生した
EPOLLHUP | 設定された fd がハングアップした
EPOLLET | エッジトリガ動作に設定する。デフォルトではレベルトリガ動作
EPOLLONESHOT | 1ショット動作に設定する。1回イベントが取り出されたら、その fd が内部で無効になる。
EPOLLRDNORM | EPOLLIN と同じ
EPOLLRDBAND | priority data band を読み込める
EPOLLWRNORM | EPOLLOUT と同じ
EPOLLWRBAND | priority data に書き込みできる
EPOLLMSG | 無視される

epoll.close()

epoll オブジェクトの制御用ファイル記述子を閉じる。

epoll.fileno()

制御用ファイル記述子の番号を返す。

epoll.fromfd(fd)

fd から epoll オブジェクトを作成する。

epoll.register(fd[, eventmask])

epoll オブジェクトにファイル記述子 fd を登録する。

ノート

ポーリングオブジェクト の register とは異なり、登録済みのファイル記述子を登録しようとすると IOError が発生します。

epoll.modify(fd, eventmask)

ファイル記述子 fd の登録を変更する。

epoll.unregister(fd)

epoll オブジェクトから登録されたファイル記述子 fd を削除する。

epoll.poll([timeout=-1[, maxevents=-1]])

イベントを待つ。 timeout はタイムアウト時間で、単位は秒(float型) です。

16.1.2. ポーリングオブジェクト

poll() システムコールはほとんどの Unix システムでサポートされており、非常に多数のクライアントに同時にサービスを提供するようなネットワークサーバが高いスケーラビリティを持てるようにしています。 poll() は対象のファイル記述子を列挙するだけでよいため、良くスケールします。一方、 select() はビット対応表を構築し、対象ファイルの記述子に対応するビットを立て、その後全ての対応表の全てのビットを線形探索します。 select() は O(最大のファイル記述子番号) なのに対し、 poll() は O(対象とするファイル記述子の数) で済みます。

poll.register(fd[, eventmask])

ファイル記述子をポーリングオブジェクトに登録します。これ以降の poll() メソッド呼び出しでは、そのファイル記述子に処理待ち中の I/O イベントがあるかどうかを監視します。 fd は整数か、整数値を返す fileno() メソッドを持つオブジェクトを取ります。ファイルオブジェクトも fileno() を実装しているので、引数として使うことができます。

eventmask はオプションのビットマスクで、どの種類の I/O イベントを監視したいかを記述します。この値は以下の表で述べる定数 POLLIN 、 POLLPRI 、および POLLOUT の組み合わせにすることができます。ビットマスクを指定しない場合、標準の値が使われ、 3 種類のイベント全てに対して監視が行われます。

定数 | 意味
POLLIN | 読み出し可能なデータが存在する
POLLPRI | 緊急の読み出し可能なデータが存在する
POLLOUT | 書き出しの準備ができている: 書き出し処理がブロックしない
POLLERR | 何らかのエラー状態
POLLHUP | ハングアップ
POLLNVAL | 無効な要求: 記述子が開かれていない

登録済みのファイル記述子を登録してもエラーにはならず、一度だけ登録した場合と同じ効果になります。

poll.modify(fd, eventmask)

登録されているファイル記述子 fd を変更する。これは、 register(fd, eventmask) と同じ効果を持ちます。登録されていないファイル記述子に対してこのメソッドを呼び出すと、 errno ENOENT で IOError 例外が発生します。

バージョン 2.6 で追加.

poll.unregister(fd)

ポーリングオブジェクトによって追跡中のファイル記述子を登録解除します。 register() メソッドと同様に、 fd は整数か、整数値を返す fileno() メソッドを持つオブジェクトを取ります。

登録されていないファイル記述子を登録解除しようとすると KeyError 例外が送出されます。

poll.poll([timeout])

登録されたファイル記述子に対してポーリングを行い、報告すべき I/O イベントまたはエラーの発生したファイル記述子毎に 2 要素のタプル (fd, event) からなるリストを返します。リストは空になることもあります。 fd はファイル記述子で、 event は該当するファイル記述子について報告されたイベントを表すビットマスクです — 例えば POLLIN は入力待ちを示し、 POLLOUT はファイル記述子に対する書き込みが可能を示す、などです。空のリストは呼び出しがタイムアウトしたか、報告すべきイベントがどのファイル記述子でも発生しなかったことを示します。 timeout が与えられた場合、処理を戻すまで待機する時間の長さをミリ秒単位で指定します。 timeout が省略されたり、負の値であったり、あるいは None の場合、そのポーリングオブジェクトが監視している何らかのイベントが発生するまでブロックします。

16.1.3. kqueue オブジェクト

kqueue.close()

kqueue オブジェクトの制御用ファイル記述子を閉じる。

kqueue.fileno()

制御用ファイル記述子の番号を返す。

kqueue.fromfd(fd)

与えられたファイル記述子から、kqueue オブジェクトを作成する。

kqueue.control(changelist, max_events[, timeout=None]) → eventlist

kevent に対する低レベルのインタフェース

changelist は kevent オブジェクトの iterable または None

max_events は 0 または正の整数

timeout はタイムアウト秒数 (float を利用可能)

16.1.4. kevent オブジェクト

http://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2

kevent.ident

イベントを特定するための値。この値は、フィルタにもよりますが、大抵の場合はファイル記述子です。コンストラクタでは、 ident として、整数値か fileno() メソッドを持ったオブジェクトを渡せます。 kevent は内部で整数値を保存します。

kevent.filter

カーネルフィルタの名前。

定数 | 意味
KQ_FILTER_READ | 記述子を受け取り、読み込めるデータが存在する時に戻る
KQ_FILTER_WRITE | 記述子を受け取り、書き込み可能な時に戻る
KQ_FILTER_AIO | AIO リクエスト
KQ_FILTER_VNODE | fflag で監視されたイベントが1つ以上発生したときに戻る
KQ_FILTER_PROC | プロセスID上のイベントを監視する
KQ_FILTER_NETDEV | ネットワークデバイス上のイベントを監視する (Mac OS X では利用不可)
KQ_FILTER_SIGNAL | 監視しているシグナルがプロセスに届いたときに戻る
KQ_FILTER_TIMER | 任意のタイマを設定する

kevent.flags

フィルタアクション。

定数 | 意味
KQ_EV_ADD | イベントを追加または修正する
KQ_EV_DELETE | キューからイベントを取り除く
KQ_EV_ENABLE | control() がイベントを返すのを許可する
KQ_EV_DISABLE | イベントを無効にする
KQ_EV_ONESHOT | イベントを最初の発生後無効にする
KQ_EV_CLEAR | イベントを受け取った後で状態をリセットする
KQ_EV_SYSFLAGS | 内部イベント
KQ_EV_FLAG1 | 内部イベント
KQ_EV_EOF | フィルタ依存のEOF状態
KQ_EV_ERROR | 戻り値を参照

kevent.fflags

フィルタ依存のフラグ。

KQ_FILTER_READ と KQ_FILTER_WRITE フィルタのフラグ:

定数 | 意味
KQ_NOTE_LOWAT | ソケットバッファの最低基準値

KQ_FILTER_VNODE フィルタのフラグ:

定数 | 意味
KQ_NOTE_DELETE | unlink() が呼ばれた
KQ_NOTE_WRITE | 書き込みが発生した
KQ_NOTE_EXTEND | ファイルのサイズが拡張された
KQ_NOTE_ATTRIB | 属性が変更された
KQ_NOTE_LINK | リンクカウントが変更された
KQ_NOTE_RENAME | ファイル名が変更された
KQ_NOTE_REVOKE | ファイルアクセスが破棄された

KQ_FILTER_PROC フィルタフラグ:

定数 | 意味
KQ_NOTE_EXIT | プロセスが終了した
KQ_NOTE_FORK | プロセスが fork() を呼び出した
KQ_NOTE_EXEC | プロセスが新しいプロセスを実行した
KQ_NOTE_PCTRLMASK | 内部フィルタフラグ
KQ_NOTE_PDATAMASK | 内部フィルタフラグ
KQ_NOTE_TRACK | fork() の呼び出しを超えてプロセスを監視する
KQ_NOTE_CHILD | NOTE_TRACK に対して子プロセスに渡される
KQ_NOTE_TRACKERR | 子プロセスにアタッチできなかった

KQ_FILTER_NETDEV フィルタフラグ (Mac OS X では利用不可):

定数 | 意味
KQ_NOTE_LINKUP | リンクアップしている
KQ_NOTE_LINKDOWN | リンクダウンしている
KQ_NOTE_LINKINV | リンク状態が不正

kevent.data

フィルタ固有のデータ。

kevent.udata

ユーザー定義値。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.2. threading — 高水準のスレッドインタフェース

このモジュールでは、高水準のスレッドインタフェースをより低水準な thread モジュールの上に構築しています。 mutex と Queue モジュールのドキュメントも参照下さい。

また、 thread がないために threading を使えないような状況向けに dummy_threading を提供しています。

ノート

Python 2.6 からこのモジュールは Java のスレッディング API の影響を受けた camelCase のプロパティを置き換える PEP 8 [http://www.python.org/dev/peps/pep-0008] に準拠したエイリアスを提供します。この更新された API は multiprocessing モジュールのものと互換です。しかしながら、 camelCase の名称の廃止の予定は決まっておらず、 Python 2.x と 3.x の両方でサポートされ続けます。

ノート

Python 2.5 から, 幾つかの Thread のメソッドは間違った呼び出しに対して AssertionError の代わりに RuntimeError を返します。

CPython implementation detail: CPython は Global Interpreter Lock のため、ある時点で Python コードを実行できるスレッドは1つに限られます。 (いくつかのパフォーマンスが強く求められるライブラリはこの制限を克服しています) アプリケーションにより良くマルチコアのマシンの計算能力を利用させたい場合は、 multiprocessing モジュールの利用をお勧めします。ただし、I/Oバウンドなタスクを並行して複数走らせたい場合においては、マルチスレッドは正しい選択肢です。

参考

最新バージョンの threading module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/threading.py?view=markup]

このモジュールでは以下のような関数とオブジェクトを定義しています:

threading.active_count()

threading.activeCount()

生存中の Thread オブジェクトの数を返します。この数は enumerate() の返すリストの長さと同じです。

threading.Condition()

新しい条件変数 (condition variable) オブジェクトを返すファクトリ関数です。条件変数を使うと、ある複数のスレッドを別のスレッドの通知があるまで待機させられます。

Condition オブジェクト を参照してください。

threading.current_thread()

threading.currentThread()

関数を呼び出している処理のスレッドに対応する Thread オブジェクトを返します。関数を呼び出している処理のスレッドが threading モジュールで生成したものでない場合、限定的な機能しかもたないダミースレッドオブジェクトを返します。

threading.enumerate()

現在、生存中の Thread オブジェクト全てのリストを返します。リストには、デーモンスレッド (daemonic thread)、 current_thread() の生成するダミースレッドオブジェクト、そして主スレッドが入ります。終了したスレッドとまだ開始していないスレッドは入りません。

threading.Event()

新たなイベントオブジェクトを返すファクトリ関数です。イベントは set() メソッドを使うと True に、 clear() メソッドを使うと False にセットされるようなフラグを管理します。 wait() メソッドは、全てのフラグが真になるまでブロックするようになっています。

Event オブジェクト を参照してください。

class threading.local

スレッドローカルデータ (thread-local data) を表現するためのクラスです。スレッドローカルデータとは、値が各スレッド固有になるようなデータです。スレッドローカルデータを管理するには、 local (または local のサブクラス) のインスタンスを作成して、その属性に値を代入します

mydata = threading.local()
mydata.x = 1

インスタンスの値はスレッドごとに違った値になります。

詳細と例題については、 _threading_local モジュールのドキュメンテーション文字列を参照してください。

バージョン 2.4 で追加.

threading.Lock()

新しいプリミティブロック (primitive lock) オブジェクトを返すファクトリ関数です。スレッドが一度プリミティブロックを獲得すると、それ以後のロック獲得の試みはロックが解放されるまでブロックします。どのスレッドでもロックを解放できます。

Lock オブジェクト を参照してください。

threading.RLock()

新しい再入可能ロックオブジェクトを返すファクトリ関数です。再入可能ロックはそれを獲得したスレッドによって解放されなければなりません。いったんスレッドが再入可能ロックを獲得すると、同じスレッドはブロックされずにもう一度それを獲得できます ; そのスレッドは獲得した回数だけ解放しなければいけません。

RLock オブジェクト を参照してください。

threading.Semaphore([value])

新しいセマフォ (semaphore) オブジェクトを返すファクトリ関数です。セマフォは、 release() を呼び出した数から acquire() を呼び出した数を引き、初期値を足した値を表すカウンタを管理します。 acquire() メソッドは、カウンタの値を負にせずに処理を戻せるまで必要ならば処理をブロックします。 value を指定しない場合、デフォルトの値は 1 になります。

Semaphore オブジェクト を参照してください。

threading.BoundedSemaphore([value])

新しい有限セマフォ (bounded semaphore) オブジェクトを返すファクトリ関数です。有限セマフォは、現在の値が初期値を超過しないようチェックを行います。超過を起こした場合、 ValueError を送出します。たいていの場合、セマフォは限られた容量のリソースを保護するために使われるものです。従って、あまりにも頻繁なセマフォの解放はバグが生じているしるしです。 value を指定しない場合、デフォルトの値は 1 になります。

class threading.Thread

処理中のスレッドを表すクラスです。このクラスは制限のある範囲内で安全にサブクラス化できます。

Thread オブジェクト を参照してください。

class threading.Timer

指定時間経過後に関数を実行するスレッドです。

Timer オブジェクト を参照してください。

threading.settrace(func)

threading モジュールを使って開始した全てのスレッドにトレース関数を設定します。 func は各スレッドの run() を呼び出す前にスレッドの sys.settrace() に渡されます。

バージョン 2.3 で追加.

threading.setprofile(func)

threading モジュールを使って開始した全てのスレッドにプロファイル関数を設定します。 func は各スレッドの run() を呼び出す前にスレッドの sys.settrace() に渡されます。

バージョン 2.3 で追加.

threading.stack_size([size])

新しいスレッドが作られる際に使われるスレッドのスタックサイズを返します。オプションの size 引数は次に作られるスレッドに対するスタックサイズを指定するものですが、 0 (プラットフォームまたは設定されたデフォルト) または少なくとも 32,768 (32kB) であるような正の整数でなければなりません。もしスタックサイズの変更がサポートされていなければ ThreadError が送出されます。また指定されたスタックサイズが条件を満たしていなければ ValueError が送出されスタックサイズは変更されないままになります。 32kB は今のところインタプリタ自体に十分なスタックスペースを保証するための値としてサポートされる最小のスタックサイズです。プラットフォームによってはスタックサイズの値に固有の制限が課されることもあります。たとえば 32kB より大きな最小スタックサイズを要求されたり、システムメモリサイズの倍数の割り当てを要求されるなどです - より詳しい情報はプラットフォームごとの文書で確認してください (4kB ページは一般的ですので、情報が見当たらないときには 4096 の倍数を指定しておくといいかもしれません)。利用可能 : Windows, POSIX スレッドのあるシステム。

バージョン 2.5 で追加.

オブジェクトの詳細なインターフェースを以下に説明します。

このモジュールのおおまかな設計は Java のスレッドモデルに基づいています。とはいえ、 Java がロックと条件変数を全てのオブジェクトの基本的な挙動にしているのに対し、 Python ではこれらを別個のオブジェクトに分けています。 Python の Thread クラスがサポートしているのは Java の Thread クラスの挙動のサブセットにすぎません; 現状では、優先度 (priority)やスレッドグループがなく、スレッドの破壊 (destroy)、中断 (stop)、一時停止 (suspend)、復帰 (resume)、割り込み (interrupt) は行えません。 Java の Thread クラスにおける静的メソッドに対応する機能が実装されている場合にはモジュールレベルの関数になっています。

以下に説明するメソッドは全て原子的 (atomic) に実行されます。

16.2.1. Thread オブジェクト

このクラスは個別のスレッド中で実行される活動 (activity) を表現します。活動を決める方法は 2 つあり、一つは呼出し可能オブジェクトをコンストラクタへ渡す方法、もう一つはサブクラスで run() メソッドをオーバライドする方法です。 (コンストラクタを除く) その他のメソッドは一切サブクラスでオーバライドしてはなりません。言い換えるならば、このクラスの __init__() と run() メソッド だけ をオーバライドしてくださいということです。

ひとたびスレッドオブジェクトを生成すると、スレッドの start() メソッドを呼び出して活動を開始せねばなりません。 start() メソッドはそれぞれのスレッドの run() メソッドを起動します。

スレッドの活動が始まると、スレッドは ‘生存中 (alive)’ とみなされます。スレッドは通常 run() メソッドが終了するまで生存中となります。もしくは、捕捉されない例外が送出されるまでです。 is_alive() メソッドはスレッドが生存中であるかどうか調べます。

他のスレッドはスレッドの join() メソッドを呼び出せます。このメソッドは、 join() を呼び出されたスレッドが終了するまで、メソッドの呼び出し手となるスレッドをブロックします。

スレッドには名前があります。名前はコンストラクタに渡したり、または、 name 属性を通して読み出したり、変更したりできます。

スレッドには “デーモンスレッド (daemon thread)” であるというフラグを立てられます。このフラグには、残っているスレッドがデーモンスレッドだけになった時に Python プログラム全体を終了させるという意味があります。フラグの初期値はスレッドを生成する側のスレッドから継承します。フラグの値は daemon 属性を通して設定できます。

スレッドには “主スレッド (main thread)” オブジェクトがあります。主スレッドは Python プログラムを最初に制御していたスレッドです。主スレッドはデーモンスレッドではありません。

“ダミースレッド (dumm thread)” オブジェクトを作成できる場合があります。ダミースレッドは、 “外来スレッド (alien thread)” に相当するスレッドオブジェクトです。ダミースレッドは、C コードから直接生成されたスレッドのような、 threading モジュールの外で開始された処理スレッドです。ダミースレッドオブジェクトには限られた機能しかなく、常に生存中、かつデーモンスレッドであるとみなされ、 join() できません。また、外来スレッドの終了を検出するのは不可能なので、ダミースレッドは削除できません。

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

コンストラクタは常にキーワード引数を使って呼び出さねばなりません。各引数は以下の通りです:

group は None にせねばなりません。将来 ThreadGroup クラスが実装されたときの拡張用に予約されている引数です。

target は run() メソッドによって起動される呼出し可能オブジェクトです。デフォルトでは何も呼び出さないことを示す None になっています。

name はスレッドの名前です。デフォルトでは、 N を小さな 10 進数として、 “Thread- N” という形式の一意な名前を生成します。

args は target を呼び出すときの引数タプルです。デフォルトは () です。

kwargs は target を呼び出すときのキーワード引数の辞書です。デフォルトは {} です。

サブクラスでコンストラクタをオーバライドした場合、必ずスレッドが何かを始める前に基底クラスのコンストラクタ (Thread.__init__()) を呼び出しておかなくてはなりません。

start()

スレッドの活動を開始します。

このメソッドは、スレッドオブジェクトあたり一度しか呼び出してはなりません。 start() は、オブジェクトの run() メソッドが個別の処理スレッド中で呼び出されるように調整します。

同じスレッドオブジェクトに対し、このメソッドを2回以上呼び出した場合、 RuntimeError を送出します。

run()

スレッドの活動をもたらすメソッドです。

このメソッドはサブクラスでオーバライドできます。標準の run() メソッドでは、オブジェクトのコンストラクタの target 引数に呼び出し可能オブジェクトを指定した場合、 args および kwargs の引数列およびキーワード引数とともに呼び出します。

join([timeout])

スレッドが終了するまで待機します。このメソッドは、 join() を呼び出されたスレッドが、正常終了あるいは処理されない例外によって終了するか、オプションのタイムアウトが発生するまで、メソッドの呼び出し手となるスレッドをブロックします。

timeout 引数を指定して、 None 以外の値にする場合、タイムアウトを秒 (または端数秒) を表す浮動小数点数でなければなりません。 join() はいつでも None を返すので、 isAlive() を呼び出してタイムアウトしたかどうかを確認しなければなりません。もしスレッドがまだ生存中であれば、 join() はタイムアウトしています。

timeout が指定されないかまたは None であるときは、この操作はスレッドが終了するまでブロックします。

一つのスレッドに対して何度でも join() できます。

実行中のスレッドに対し、 join() を呼び出そうとすると、デッドロックを引き起こすため、 RuntimeError が送出されます。スレッドが開始される前に join() を呼び出そうとしても、同じ例外が送出されます。

getName()

setNmae()

name に対応する、旧式の API です。

name

識別のためにのみ用いられる文字列です。名前には機能上の意味づけ (semantics) はありません。複数のスレッドに同じ名前をつけてもかまいません。名前の初期値はコンストラクタで設定されます。

ident

‘スレッド識別子’ 、または、スレッドが開始されていなければ None です。非ゼロの整数です。 thread.get_ident() 関数を参照下さい。スレッド識別子は、スレッドが終了した後、新たなスレッドが生成された場合、再利用され得ます。スレッド識別子は、スレッドが終了した後でも利用できます。

バージョン 2.6 で追加.

is_alive()

isAlive()

スレッドが生存中かどうかを返します。

このメソッドは run() メソッドが起動した直後からその run() メソッドが終了するまでの間 True を返します。モジュール関数、 enumerate() は、全ての生存中のスレッドのリストを返します。

isDaemon()

setDaemon()

daemon に対応する、旧式の API です。

daemon

スレッドのデーモンフラグです。このフラグは start() の呼び出し前に設定されなければなりません。さもなくば、 RuntimeError が送出されます。

初期値は生成側のスレッドから継承されます。

デーモンでない生存中のスレッドが全てなくなると、 Python プログラム全体が終了します。

16.2.2. Lock オブジェクト

プリミティブロックとは、ロックが生じた際に特定のスレッドによって所有されない同期プリミティブです。 Python では現在のところ拡張モジュール thread で直接実装されている最も低水準の同期プリミティブを使えます。

プリミティブロックは2つの状態、 “ロック” または “アンロック” があります。このロックはアンロック状態で作成されます。ロックには基本となる二つのメソッド、 acquire() と release() があります。ロックの状態がアンロックである場合、 acquire() は状態をロックに変更して即座に処理を戻します。状態がロックの場合、 acquire() は他のスレッドが release() を呼出してロックの状態をアンロックに変更するまでブロックします。その後、状態をロックに再度設定してから処理を戻します。 release() メソッドを呼び出すのはロック状態のときでなければなりません; このメソッドはロックの状態をアンロックに変更し、即座に処理を戻します。アンロックの状態のロックを解放しようとすると RuntimeError が送出されます。

複数のスレッドにおいて acquire() がアンロック状態への遷移を待っているためにブロックが起きている時に release() を呼び出してロックの状態をアンロックにすると、一つのスレッドだけが処理を進行できます。どのスレッドが処理を進行できるのかは定義されておらず、実装によって異なるかもしれません。

全てのメソッドは原子的に実行されます。

Lock.acquire([blocking])

ブロックあり、またはブロックなしでロックを獲得します。

引数なしで呼び出した場合、ロックの状態がアンロックになるまでブロックし、その後状態をロックにセットして真値を返します。

引数 blocking の値を真にして呼び出した場合、引数なしで呼び出したときと同じことを行ない、Trueを返します。

引数 blocking の値を偽にして呼び出すとブロックしません。引数なしで呼び出した場合にブロックするような状況であった場合には直ちに偽を返します。それ以外の場合には、引数なしで呼び出したときと同じ処理を行い真を返します。

Lock.release()

ロックを解放します。

ロックの状態がロックのとき、状態をアンロックにリセットして処理を戻します。他のスレッドがロックがアンロック状態になるのを待ってブロックしている場合、ただ一つのスレッドだけが処理を継続できるようにします。

ロックがアンロック状態のとき、このメソッドを呼び出してはなりません。

戻り値はありません。

16.2.3. RLock オブジェクト

再入可能ロック (reentrant lock) とは、同じスレッドが複数回獲得できるような同期プリミティブです。再入可能ロックの内部では、プリミティブロックの使うロック／アンロック状態に加え、 “所有スレッド (owning thread)” と “再帰レベル (recursion level)” という概念を用いています。ロック状態では何らかのスレッドがロックを所有しており、アンロック状態ではいかなるスレッドもロックを所有していません。

スレッドがこのロックの状態をロックにするには、ロックの acquire() メソッドを呼び出します。このメソッドは、スレッドがロックを所有すると処理を戻します。ロックの状態をアンロックにするには release() メソッドを呼び出します。 acquire() / release() からなるペアの呼び出しはネストできます; 最後に呼び出した release() (最も外側の呼び出しペア) だけが、ロックの状態をアンロックにリセットし、 acquire() でブロック中の別のスレッドの処理を進行させられます。

RLock.acquire([blocking=1])

ブロックあり、またはブロックなしでロックを獲得します。

引数なしで呼び出した場合: スレッドが既にロックを所有している場合、再帰レベルをインクリメントして即座に処理を戻します。それ以外の場合、他のスレッドがロックを所有していれば、そのロックの状態がアンロックになるまでブロックします。その後、ロックの状態がアンロックになる (いかなるスレッドもロックを所有しない状態になる) と、ロックの所有権を獲得し、再帰レベルを 1 にセットして処理を戻します。ロックの状態がアンロックになるのを待っているスレッドが複数ある場合、その中の一つだけがロックの所有権を獲得できます。この場合、戻り値はありません。

blocking 引数の値を真にした場合、引数なしで呼び出した場合と同じ処理を行って真を返します。

blocking 引数の値を偽にした場合、ブロックしません。引数なしで呼び出した場合にブロックするような状況であった場合には直ちに偽を返します。それ以外の場合には、引数なしで呼び出したときと同じ処理を行い真を返します。

RLock.release()

再帰レベルをデクリメントしてロックを解放します。デクリメント後に再帰レベルがゼロになった場合、ロックの状態をアンロック (いかなるスレッドにも所有されていない状態) にリセットし、ロックの状態がアンロックになるのを待ってブロックしているスレッドがある場合にはその中のただ一つだけが処理を進行できるようにします。デクリメント後も再帰レベルがゼロでない場合、ロックの状態はロックのままで、呼び出し手のスレッドに所有されたままになります。

呼び出し手のスレッドがロックを所有しているときにのみこのメソッドを呼び出してください。ロックの状態がアンロックの時にこのメソッドを呼び出すと、 RuntimeError が送出されます。

戻り値はありません。

16.2.4. Condition オブジェクト

条件変数 (condition variable) は常にある種のロックに関連付けられています; 条件変数に関連付けるロックは明示的に引き渡したり、デフォルトで生成させたりできます。 (複数の条件変数で同じロックを共有するような場合には、引渡しによる関連付けが便利です。)

条件変数には、 acquire() メソッドおよび release() があり、関連付けされているロックの対応するメソッドを呼び出すようになっています。また、 wait(), notify(), notifyAll() といったメソッドがあります。これら三つのメソッドを呼び出せるのは、呼び出し手のスレッドがロックを獲得している時だけです。そうでない場合は RuntimeError が送出されます。

wait() メソッドは現在のスレッドのロックを解放し、他のスレッドが同じ条件変数に対して notify() または notifyAll() を呼び出して現在のスレッドを起こすまでブロックします。一度起こされると、再度ロックを獲得して処理を戻します。 wait() にはタイムアウトも設定できます。

notify() メソッドは条件変数待ちのスレッドを1つ起こします。 notifyAll() メソッドは条件変数待ちの全てのスレッドを起こします。

注意: notify() と notifyAll() はロックを解放しません; 従って、スレッドが起こされたとき、 wait() の呼び出しは即座に処理を戻すわけではなく、 notify() または notifyAll() を呼び出したスレッドが最終的にロックの所有権を放棄したときに初めて処理を返すのです。

豆知識: 条件変数を使う典型的なプログラミングスタイルでは、何らかの共有された状態変数へのアクセスを同期させるためにロックを使います; 状態変数が特定の状態に変化したことを知りたいスレッドは、自分の望む状態になるまで繰り返し wait() を呼び出します。その一方で、状態変更を行うスレッドは、前者のスレッドが待ち望んでいる状態であるかもしれないような状態へ変更を行ったときに notify() や notifyAll() を呼び出します。例えば、以下のコードは無制限のバッファ容量のときの一般的な生産者-消費者問題です:

# Consume one item
cv.acquire()
while not an_item_is_available():
    cv.wait()
get_an_available_item()
cv.release()

# Produce one item
cv.acquire()
make_an_item_available()
cv.notify()
cv.release()

notify() と notifyAll() のどちらを使うかは、その状態の変化に興味を持っている待ちスレッドが一つだけなのか、あるいは複数なのかで考えます。例えば、典型的な生産者-消費者問題では、バッファに 1 つの要素を加えた場合には消費者スレッドを 1 つしか起こさなくてかまいません。

class threading.Condition([lock])

lock を指定して、 None の値にする場合、 Lock または RLock オブジェクトでなければなりません。この場合、 lock は根底にあるロックオブジェクトとして使われます。それ以外の場合には新しい RLock オブジェクトを生成して使います。

acquire(*args)

根底にあるロックを獲得します。このメソッドは根底にあるロックの対応するメソッドを呼び出します。そのメソッドの戻り値を返します。

release()

根底にあるロックを解放します。このメソッドは根底にあるロックの対応するメソッドを呼び出します。戻り値はありません。

wait([timeout])

通知 (notify) を受けるか、タイムアウトするまで待機します。呼び出し手のスレッドがロックを獲得していないときにこのメソッドを呼び出すと RuntimeError が送出されます。

このメソッドは根底にあるロックを解放し、他のスレッドが同じ条件変数に対して notify() または notifyAll() を呼び出して現在のスレッドを起こすか、オプションのタイムアウトが発生するまでブロックします。一度スレッドが起こされると、再度ロックを獲得して処理を戻します。

timeout 引数を指定して、 None 以外の値にする場合、タイムアウトを秒 (または端数秒) を表す浮動小数点数でなければなりません。

根底にあるロックが RLock である場合、 release() メソッドではロックは解放されません。というのも、ロックが再帰的に複数回獲得されている場合には、 release() によって実際にアンロックが行われないかもしれないからです。その代わり、ロックが再帰的に複数回獲得されていても確実にアンロックを行える RLock クラスの内部インタフェースを使います。その後ロックを再獲得する時に、もう一つの内部インタフェースを使ってロックの再帰レベルを復帰します。

notify()

この条件変数を待っているスレッドがあれば、そのスレッドを起こします。呼び出し手のスレッドがロックを獲得していないときにこのメソッドを呼び出すと RuntimeError が送出されます。

何らかの待機中スレッドがある場合、そのスレッドの一つを起こします。待機中のスレッドがなければ何もしません。

現在の実装では、待機中のメソッドをただ一つだけ起こします。とはいえ、この挙動に依存するのは安全ではありません。将来、実装の最適化によって、複数のスレッドを起こすようになるかもしれないからです。

注意: 起こされたスレッドは実際にロックを再獲得できるまで wait() 呼出しから戻りません。 notify() はロックを解放しないので、 notify() 呼び出し手は明示的にロックを解放せねばなりません。

notify_all()

notifyAll()

この条件を待っているすべてのスレッドを起こします。このメソッドは notify() のように動作しますが、 1 つではなくすべての待ちスレッドを起こします。呼び出し手のスレッドがロックを獲得していない場合、 RuntimeError が送出されます。

16.2.5. Semaphore オブジェクト

セマフォ (semaphore) は、計算機科学史上最も古い同期プリミティブの一つで、草創期のオランダ計算機科学者 Edsger W. Dijkstra によって発明されました (彼は acquire() と release() の代わりに P() と V() を使いました)。

セマフォは acquire() でデクリメントされ release() でインクリメントされるような内部カウンタを管理します。カウンタは決してゼロより小さくはなりません; acquire() は、カウンタがゼロになっている場合、他のスレッドが release() を呼び出すまでブロックします。

class threading.Semaphore([value])

オプションの引数には、内部カウンタの初期値を指定します。デフォルトは 1 です。与えられた value が 0 より小さい場合、 ValueError が送出されます。

acquire([blocking])

セマフォを獲得します。

引数なしで呼び出した場合: acqure() 処理に入ったときに内部カウンタがゼロより大きければ、カウンタを 1 デクリメントして即座に処理を戻します。 acqure() 処理に入ったときに内部カウンタがゼロの場合、他のスレッドが release() を呼び出してカウンタをゼロより大きくするまでブロックします。この処理は、適切なインターロック (interlock) を介して行い、複数の acquire() 呼び出しがブロックされた場合、 release() が正確に一つだけを起こせるようにします。この実装はランダムに一つ選択するだけでもよいので、ブロックされたスレッドがどの起こされる順番に依存してはなりません。この場合、戻り値はありません。

blocking 引数の値を真にした場合、引数なしで呼び出した場合と同じ処理を行って真を返します。

blocking 引数の値を偽にした場合、ブロックしません。引数なしで呼び出した場合にブロックするような状況であった場合には直ちに偽を返します。それ以外の場合には、引数なしで呼び出したときと同じ処理を行い真を返します。

release()

内部カウンタを 1 インクリメントして、セマフォを解放します。 release() 処理に入ったときにカウンタがゼロであり、カウンタの値がゼロより大きくなるのを待っている別のスレッドがあった場合、そのスレッドを起こします。

16.2.5.1. Semaphore の例

セマフォはしばしば、容量に限りのある資源、例えばデータベースサーバなどを保護するために使われます。リソースが固定の状況では、常に有限セマフォを使わねばなりません。主スレッドは、作業スレッドを立ち上げる前にセマフォを初期化します:

maxconnections = 5
...
pool_sema = BoundedSemaphore(value=maxconnections)

作業スレッドは、ひとたび立ち上がると、サーバへ接続する必要が生じたときにセマフォの acquire() および release() メソッドを呼び出します:

pool_sema.acquire()
conn = connectdb()
... use connection ...
conn.close()
pool_sema.release()

有限セマフォを使うと、セマフォを獲得回数以上に解放してしまうというプログラム上の間違いを見逃しにくくします。

16.2.6. Event オブジェクト

イベントは、あるスレッドがイベントを発信し、他のスレッドはそれを待つという、スレッド間で通信を行うための最も単純なメカニズムの一つです。

イベントオブジェクトは内部フラグを管理します。このフラグは set() メソッドで値を真に、 clear() メソッドで値を偽にリセットします。 wait() メソッドはフラグがTrueになるまでブロックします。

class threading.Event

内部フラグの初期値は偽です。

is_set()

isSet()

内部フラグの値が真である場合にのみ真を返します。

バージョン 2.6 で変更: 新たに is_set() 構文が使えるようになりました。

set()

内部フラグの値を真にセットします。フラグの値が真になるのを待っている全てのスレッドを起こします。一旦フラグが真になると、スレッドが wait() を呼び出しても全くブロックしなくなります。

clear()

内部フラグの値を偽にリセットします。以降は、 set() を呼び出して再び内部フラグの値を真にセットするまで、 wait() を呼出したスレッドはブロックするようになります。

wait([timeout])

内部フラグの値が真になるまでブロックします。 wait() 処理に入った時点で内部フラグの値が真であれば、直ちに処理を戻します。そうでない場合、他のスレッドが set() を呼び出してフラグの値を真にセットするか、オプションのタイムアウトが発生するまでブロックします。

timeout 引数を指定して、 None 以外の値にする場合、タイムアウトを秒 (または端数秒) を表す浮動小数点数でなければなりません。

このメソッドは終了時の内部フラグを返します。 timeout が指定されて、操作がタイムアウトしたとき以外は、 True を返すはずです。

バージョン 2.7 で変更: 以前は、このメソッドは常に None を返していました。

16.2.7. Timer オブジェクト

このクラスは、一定時間経過後に実行される活動、すなわちタイマ活動を表現します。 Timer は Thread のサブクラスであり、自作のスレッドを構築した一例でもあります。

タイマは start() メソッドを呼び出すとスレッドとして作動し始めします。 (活動を開始する前に) cancel() メソッドを呼び出すと、タイマを停止できます。タイマが活動を実行するまでの待ち時間は、ユーザが指定した待ち時間と必ずしも厳密には一致しません。

例:

def hello():
    print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed

class threading.Timer(interval, function, args=[], kwargs={})

interval 秒後に function を引数 args 、キーワード引数 kwargs つきで実行するようなタイマを生成します。

cancel()

タイマをストップして、その動作の実行をキャンセルします。このメソッドはタイマがまだ活動待ち状態にある場合にのみ動作します。

16.2.8. with 文でのロック・条件変数・セマフォの使い方

このモジュールのオブジェクトで acquire() と release() 両メソッドを具えているものは全て with 文のコンテキストマネージャとして使うことができます。 acquire() メソッドが with 文のブロックに入るときに呼び出され、ブロック脱出時には release() メソッドが呼ばれます。

現在のところ、 Lock 、 RLock 、 Condition 、 Semaphore 、 BoundedSemaphore を with 文のコンテキストマネージャとして使うことができます。以下の例を見てください。

import threading

some_rlock = threading.RLock()

with some_rlock:
    print "some_rlock is locked while this executes"

16.2.9. スレッド化されたコード中でのImport

スレッドセーフなimportのためには、継承の制限に起因する、ふたつの重要な制約があります。

ひとつ目は、主とするモジュール以外では、importが新しいスレッドを生成しないようになっていなければなりません。そして、そのスレッドを待たなければなりません。この制約を守らない場合、生成されたスレッドが直接的、または、間接的にモジュールをimportしようとした際に、デッドロックを引き起こす可能性があります。

ふたつ目は、全てのimportが、インタープリターが自身を終了させる前に完了しなければなりません。これは、最も簡単な方法としては、threadingモジュールを通して生成される非デーモンからのみimportを実行することで達成できます。デーモンスレッド、および、直接、threadモジュールから生成されたスレッドは、インタープリター終了後にimportを実行しないようにする、別の同期の仕組みを必要とします。この制約を守らない場合、 intermittent (間歇) 例外を引き起こし、インタープリターのシャットダウン中にクラッシュする可能性があります。 (後から実行されるimportは、すでにアクセス可能でなくなった領域にアクセスしようとするためです)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.3. thread — マルチスレッドのコントロール

ノート

Python 3.0 では thread モジュールは _thread に改名されました。 2to3 ツールは、 3.0 コードへの変換時に、自動的に import 宣言を適合させます。しかしながら、上位の threading モジュールを使うことを検討して下さい。

このモジュールはマルチスレッド (別名 軽量プロセス (light-weight processes)または タスク (tasks)) に用いられる低レベルプリミティブを提供します — グローバルデータ空間を共有するマルチスレッドを制御します。同期のための単純なロック (別名 mutexes またはバイナリセマフォ (binary semaphores))が提供されています。 threading モジュールは、このモジュール上で、より使い易く高級なスレッディングの API　を提供します。

このモジュールはオプションです。 Windows, Linux, SGI IRIX, Solaris 2.x、そして同じようなPOSIXスレッド (別名 “pthread” ) 実装のシステム上でサポートされます。 thread を使用することのできないシステムでは、 dummy_thread が用意されています。 dummy_thread はこのモジュールと同じインターフェースを持ち、置き換えて使用することができます。

定数と関数は以下のように定義されています:

exception thread.error

スレッド特有の例外です。

thread.LockType

これはロックオブジェクトのタイプです。

thread.start_new_thread(function, args[, kwargs])

新しいスレッドを開始して、そのIDを返します。スレッドは引数リスト args (タプルでなければなりません)の関数 function を実行します。オプション引数 kwargs はキーワード引数の辞書を指定します。関数が戻るとき、スレッドは黙って終了します。関数が未定義の例外でターミネートしたとき、スタックトレースが表示され、そしてスレッドが終了します (しかし他のスレッドは走り続けます)。

thread.interrupt_main()

メインスレッドで KeyboardInterrupt を送出します。サブスレッドはこの関数を使ってメインスレッドに割り込みをかけることができます。

バージョン 2.3 で追加.

thread.exit()

SystemExit を送出します。それが捕えられないときは、黙ってスレッドを終了させます。

thread.exit_prog(status)

全てのスレッドを終了させ、整数の引き数 status をプログラム全体の終了コードとして返します。 ** 警告:** このスレッド、および、他のスレッドの finally 節の、未実行のプログラムは実行されません。

thread.allocate_lock()

新しいロックオブジェクトを返します。ロックのメソッドはこの後に記述されます。ロックは初期状態としてアンロック状態です。

thread.get_ident()

現在のスレッドの ‘スレッドID’ を返します。非ゼロの整数です。この値は直接の意味を持っていません; 例えばスレッド特有のデータの辞書に索引をつけるためのような、マジッククッキーとして意図されています。スレッドが終了し、他のスレッドが作られたとき、スレッド ID は再利用されるかもしれません。

thread.stack_size([size])

新しいスレッドが作られる際に使われるスレッドのスタックサイズを返します。オプションの size 引数は次に作られるスレッドに対するスタックサイズを指定するものですが、 0 (プラットフォームまたは設定されたデフォルト) または少なくとも 32,768 (32kB) であるような正の整数でなければなりません。もしスタックサイズの変更がサポートされていなければ ThreadError が送出されます。また指定されたスタックサイズが条件を満たしていなければ ValueError が送出されスタックサイズは変更されないままになります。 32kB は今のところインタプリタ自体に十分なスタックスペースを保証するための値としてサポートされる最小のスタックサイズです。プラットフォームによってはスタックサイズの値に固有の制限が課されることもあります。たとえば 32kB より大きな最小スタックサイズを要求されたり、システムメモリサイズの倍数の割り当てを要求されるなどです - より詳しい情報はプラットフォームごとの文書で確認してください (4kB ページは一般的ですので、情報が見当たらないときには 4096 の倍数を指定しておくといいかもしれません)。利用可能: Windows, POSIX スレッドのあるシステム。

バージョン 2.5 で追加.

ロックオブジェクトは次のようなメソッドを持っています:

lock.acquire([waitflag])

オプションの引数なしで使用すると、このメソッドは他のスレッドがロックしているかどうかにかかわらずロックを獲得します。ただし、他のスレッドがすでにロックしている場合には解除されるまで待ってからロックを獲得します (同時にロックを獲得できるスレッドはひとつだけであり、これこそがロックの存在理由です)。整数の引数 waitflag を指定すると、その値によって動作が変わります。引数が 0 のときは、待たずにすぐ獲得できる場合にだけロックを獲得します。 0 以外の値を与えると、先の例と同様、ロックの状態にかかわらず獲得をおこないます。なお、ロックを獲得すると True 、できなかったときには False を返します。

lock.release()

ロックを解放します。そのロックは既に獲得されたものでなければなりませんが、しかし同じスレッドによって獲得されたものである必要はありません。

lock.locked()

ロックの状態を返します: 同じスレッドによって獲得されたものなら True 、違うのなら False を返します。

これらのメソッドに加えて、ロックオブジェクトは with 文を通じて以下の例のように使うこともできます。

import thread

a_lock = thread.allocate_lock()

with a_lock:
    print "a_lock is locked while this executes"

警告:

スレッドは割り込みと奇妙な相互作用をします: KeyboardInterrupt 例外は任意のスレッドによって受け取られます。 ( signal モジュールが利用可能なとき、割り込みは常にメインスレッドへ行きます。)

sys.exit() を呼び出す、あるいは SystemExit 例外を送出することは、 thread.exit() を呼び出すことと同じです。

I/O待ちをブロックするかもしれない全ての組込み関数が、他のスレッドの走行を許すわけではありません。 (ほとんどの一般的なもの ( time.sleep(), file.read(), select.select()) は期待通りに働きます。)

ロックの acquire() メソッドに割り込むことはできません — KeyboardInterrupt 例外は、ロックが獲得された後に発生します。

メインスレッドが終了したとき、他のスレッドが生き残るかどうかは、システムに依存します。ネイティブスレッド実装を使う SGI, IRIX では生き残ります。その他の多くのシステムでは、 try ... finally 節や、オブジェクトデストラクタを実行せずに終了されます。

メインスレッドが終了したとき、それの通常のクリーンアップは行なわれず、 (try ... finally 節が尊重されることは除きます)、標準 I/O ファイルはフラッシュされません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.4. dummy_threading — threading の代替モジュール

このモジュールは threading モジュールのインターフェースをそっくりまねるものです。 threading モジュールがサポートされていないプラットフォームで import することを意図して作られたものです。

使用例:

try:
    import threading as _threading
except ImportError:
    import dummy_threading as _threading

生成するスレッドが他のブロックしたスレッドを待ち、デッドロック発生の可能性がある場合には、このモジュールを使わないようにしてください。ブロッキング I/O を使っている場合によく起きます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.5. dummy_thread — thread の代替モジュール

ノート

dummy_thread モジュールは、Python 3.0では _dummy_thread に変更されました。 2to3 ツールは自動的にソースコードの import を修正します。しかし、代わりに高レベルの dummy_threading モジュールの利用を検討するべきです。

このモジュールは thread モジュールのインターフェースをそっくりまねるものです。 thread モジュールがサポートされていないプラットフォームで import することを意図して作られたものです。

使用例:

try:
    import thread as _thread
except ImportError:
    import dummy_thread as _thread

生成するスレッドが、他のブロックしたスレッドを待ち、デッドロック発生の可能性がある場合には、このモジュールを使わないようにしてください。ブロッキング I/O を使っている場合によく起きます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.6. multiprocessing — プロセスベースの “並列処理” インタフェース

バージョン 2.6 で追加.

16.6.1. はじめに

multiprocessing はPythonの標準ライブラリのパッケージで threading とよく似た API を使ってプロセスを生成することができます。 multiprocessing パッケージを使用すると、ローカルとリモート両方の並列制御を行うことができます。また、このパッケージはスレッドの代わりにサブプロセスを使用することにより、グローバルインタプリタロック ( Global Interpreter Lock ) の問題を避ける工夫が行われています。このような特徴があるため multiprocessing モジュールを使うことで、マルチプロセッサマシンの性能を最大限に活用することができるでしょう。なお、このモジュールは Unix と Windows で動作します。

警告

このパッケージに含まれる機能には、ホストとなるオペレーティングシステム上で動作している共有セマフォ (shared semaphore) を使用しているものがあります。これが使用できない場合には、 multiprocessing.synchronize モジュールが無効になり、このモジュールのインポート時に ImportError が発生します。詳細は issue 3770 [http://bugs.python.org/issue3770] を参照してください。

ノート

このパッケージに含まれる機能を使用するためには、子プロセスから __main__ モジュールを呼び出せる必要があります。このことについては プログラミングガイドライン で触れていますが、ここであらためて強調しておきます。何故かというと、いくつかのサンプルコード、例えば multiprocessing.Pool のサンプルはインタラクティブシェル上では動作しないからです。以下に例を示します。

>>> from multiprocessing import Pool
>>> p = Pool(5)
>>> def f(x):
...     return x*x
...
>>> p.map(f, [1,2,3])
Process PoolWorker-1:
Process PoolWorker-2:
Process PoolWorker-3:
Traceback (most recent call last):
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'

(このサンプルを試すと、3つのトレースバック全てがほぼランダムに交互に重なって表示されます。そうなったら、なんとかしてマスタープロセスを止めましょう。)

16.6.1.1. Process クラス

multiprocessing モジュールでは、プロセスは以下の手順によって生成されます。はじめに Process のオブジェクトを作成し、続いて start() メソッドを呼び出します。この Process クラスは threading.Thread クラスと同様の API を持っています。まずは、簡単な例をもとにマルチプロセスを使用したプログラムについてみていきましょう。

from multiprocessing import Process

def f(name):
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

実行された個々のプロセス ID を表示するために拡張したサンプルコードを以下に例を示します。

from multiprocessing import Process
import os

def info(title):
    print title
    print 'module name:', __name__
    print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    info('function f')
    print 'hello', name

if __name__ == '__main__':
    info('main line')
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

(Windows 環境で) if __name__ == '__main__' という文が必要な理由については、プログラミングガイドライン を参照してください。

16.6.1.2. プロセス間でのオブジェクト交換

multiprocessing モジュールでは、プロセス間通信の手段が2つ用意されています。それぞれ以下に詳細を示します。

キュー (Queue)

Queue クラスは Queue.Queue クラスとほとんど同じように使うことができます。以下に例を示します。

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # "[42, None, 'hello']" を表示
    p.join()

キューはスレッドセーフであり、プロセスセーフです。

パイプ (Pipe)

Pipe() 関数は接続用オブジェクトのペアを返します。デフォルトでは、このオブジェクトを介して、親子間でパイプを使った双方向通信をおこなうことができます。以下に例を示します。

from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, 'hello'])
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print parent_conn.recv()   # "[42, None, 'hello']" を表示
    p.join()

2つのコネクション用オブジェクトが Pipe() 関数から返され、親側の入出力、子側の入出力といったように、それぞれパイプの両端となります。 (他プロセスと通信する方法として) 各接続用オブジェクトには、 send() メソッドと recv() メソッドがあります。データを破壊してしまうような使い方に注意する必要があります。それは、2つのプロセス (もしくはスレッド) が同時に 同じ パイプに対して、読み書きをおこなった場合に起こります。もちろん、異なったパイプを使用していれば、同時に読み書きをおこなってもデータが破壊されてしまう危険性はありません。

16.6.1.3. プロセス間の同期

multiprocessing は threading モジュールと同じプロセス間同期の仕組みを備えています。以下の例では、ロックを使用して、一度に1つのプロセスしか標準出力に書き込まないようにしています。

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    print 'hello world', i
    l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

ロックを使用しないで標準出力に書き込んだ場合は、各プロセスからの出力がごちゃまぜになってしまいます。

16.6.1.4. プロセス間での状態の共有

これまでの話の流れで触れたとおり、並列プログラミングをする時には、出来る限り状態を共有しないというのが定石です。複数のプロセッサを使用するときは特にそうでしょう。

しかし、どうしてもプロセス間のデータ共有が必要な場合のために multiprocessing モジュールにはその方法が用意されています。

共有メモリ (Shared memory)

データを共有メモリ上に保持するために Value クラス、もしくは Array クラスを使用することができます。以下のサンプルコードを使って、この機能についてみていきましょう。

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]

このサンプルコードを実行すると以下のように表示されます。

3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

num と arr を生成するときに使用されている 'd' と 'i' の引数は array モジュールにより使用される種別の型コードです。ここで使用されている 'd' は倍精度浮動小数、 'i' は符号付整数を表します。これらの共有オブジェクトは、プロセスセーフでありスレッドセーフです。

共有メモリを使用して、さらに柔軟なプログラミングを行うには multiprocessing.sharedctypes モジュールを使用します。このモジュールは共有メモリから割り当てられた任意の ctypes オブジェクトの生成をサポートします。

サーバプロセス (Server process)

Manager() 関数により生成されたマネージャオブジェクトはサーバプロセスを管理します。マネージャオブジェクトは Python のオブジェクトを保持して、他のプロセスがプロキシ経由でその Python オブジェクトを操作することができます。

Manager() 関数が返すマネージャは list 、 dict 、 Namespace 、 Lock 、 RLock 、 Semaphore 、 BoundedSemaphore 、 Condition 、 Event 、 Queue 、 Value 、 Array をサポートします。以下にサンプルコードを示します。

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    manager = Manager()

    d = manager.dict()
    l = manager.list(range(10))

    p = Process(target=f, args=(d, l))
    p.start()
    p.join()

    print d
    print l

このサンプルコードを実行すると以下のように表示されます。

{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

サーバプロセスのマネージャオブジェクトは共有メモリのオブジェクトよりも柔軟であるといえます。それは、どのような型のオブジェクトでも使えるからです。また、1つのマネージャオブジェクトはネットワーク経由で他のコンピュータ上のプロセスによって共有することもできます。しかし、共有メモリより動作が遅いという欠点があります。

16.6.1.5. ワーカープロセスのプールを使用

Pool クラスは、ワーカープロセスをプールする機能を備えています。このクラスには、いくつかの方法で開放されたワーカープロセスへタスクを割り当てるメソッドがあります。

以下に例を示します。

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # 4つのワーカープロセスで開始
    result = pool.apply_async(f, [10])    # 非同期で "f(10)" を評価
    print result.get(timeout=1)           # あなたのコンピュータが *かなり* 遅くない限りは "100" を表示
    print pool.map(f, range(10))          # "[0, 1, 4,..., 81]" を表示

16.6.2. リファレンス

multiprocessing パッケージは threading モジュールの API とほとんど同じです。

16.6.2.1. Process クラスと例外

class multiprocessing.Process([group[, target[, name[, args[, kwargs]]]]])

Process オブジェクトは各プロセスの振る舞いを表します。 Process クラスは threading.Thread クラスの全てのメソッドと同じインタフェースを提供します。

コンストラクタは必ずキーワード引数で呼び出すべきです。引数 group には必ず None を渡してください。この引数は threading.Thread クラスとの互換性のためだけに残されています。引数 target には、呼び出し可能オブジェクト (Collable Object) を渡します。このオブジェクトは run() メソッドから呼び出されます。この引数はデフォルトで None となっており、何も呼び出されません。引数 name にはプロセス名を渡します。デフォルトでは、自動でユニークな名前が割り当てられます。命名規則は、 ‘Process-N₁:N₂:...:Nk‘ となります。ここで N₁,N₂,...,Nk は整数の数列で、作成した プロセス数に対応します。引数 args は target で指定された呼び出し可能オブジェクトへの引数を渡します。同じく、引数 kwargs はキーワード引数を渡します。デフォルトでは、 target には引数が渡されないようになっています。

サブクラスがコンストラクタをオーバーライドする場合は、そのプロセスに対する処理を行う前に基底クラスのコンストラクタ (Process.__init__()) を実行しなければなりません。

run()

プロセスが実行する処理を表すメソッドです。

このメソッドはサブクラスでオーバーライドすることができます。標準の run() メソッドは呼び出し可能オブジェクトを呼び出します。この呼び出されるオブジェクトはコンストラクタの target 引数として渡されます。もしコンストラクタに args もしくは kwargs 引数が渡されていれば、呼び出すオブジェクトにこれらの引数を渡します。

start()

プロセスの処理を開始するためのメソッドです。

このメソッドをプロセスごとに呼び出す必要があります。各プロセスの run() メソッドを呼び出す準備が完了します。

join([timeout])

join() されたプロセスが terminate を呼び出すまで、もしくはオプションで指定したタイムアウトが発生するまで呼び出し側のスレッドをブロックします。

timeout が None ならタイムアウトは設定されません。

1つのプロセスは何回も join することができます。

プロセスは自分自身を join することはできません。それはデッドロックを引き起こすからです。プロセスが start される前に join しようとするとエラーが発生します。

name

プロセス名です。

この名前は文字列で、プロセスの識別にのみ使用されます。特別な命名規則はありません。複数のプロセスが同じ名前を持つ場合もあります。また、この名前はコンストラクタにより初期化されます。

is_alive()

プロセスが実行中かを判別します。

おおまかに言って、プロセスオブジェクトは start() メソッドを呼び出してから子プロセス終了までの期間が実行中となります。

daemon

デーモンプロセスであるかどうかのフラグであり、ブール値を設定します。この属性は start() が呼び出される前に設定する必要があります。

初期値は作成するプロセスから継承します。

プロセスが終了するとき、その子プロセスのデーモンプロセス全てを終了させようとします。

デーモンプロセスは子プロセスを作成できないことに注意してください。もしそうでなければ、そのデーモンの親プロセスが終了したときに子プロセスが孤児になってしまう場合があるからです。加えて Unix デーモンまたはサービスで ない 場合には、非デーモンプロセスが終了したとき、普通のプロセスとして (join されずに) 終了します。

Threading.Thread クラスのAPIに加えて Process クラスのオブジェクトには以下の属性およびメソッドがあります。

pid

プロセスIDを返します。プロセスの生成前は None が設定されています。

exitcode

子プロセスの終了コードです。子プロセスがまだ終了していない場合は None が返されます。負の値 -N は子プロセスがシグナル N で終了したことを表します。

authkey

プロセスの認証キーです (バイト文字列です)。

multiprocessing モジュールがメインプロセスにより初期化される場合には、 os.random() 関数を使用してランダムな値が設定されます。

Process クラスのオブジェクトの作成時にその親プロセスから認証キーを継承します。もしくは authkey に別のバイト文字列を設定することもできます。

詳細は 認証キー を参照してください。

terminate()

プロセスを終了します。Unix 環境では SIGTERM シグナルを、 Windows 環境では TerminateProcess() を使用して終了させます。終了ハンドラや finally 節などは、実行されないことに注意してください。

このメソッドにより終了するプロセスの子孫プロセスは、終了 しません 。そういった子孫プロセスは単純に孤児になります。

警告

このメソッドの使用時に、関連付けられたプロセスがパイプやキューを使用している場合には、使用中のパイプやキューが破損して他のプロセスから使用できなくなる可能性があります。同様に、プロセスがロックやセマフォなどを取得している場合には、このプロセスが終了してしまうと他のプロセスのデッドロックの原因になるでしょう。

プロセスオブジェクトが作成したプロセスのみが start(), join(), is_alive() と exit_code のメソッドを呼び出すべきです。

以下の例では Process のメソッドの使い方を示しています。

>>> import multiprocessing, time, signal
>>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
>>> print p, p.is_alive()
<Process(Process-1, initial)> False
>>> p.start()
>>> print p, p.is_alive()
<Process(Process-1, started)> True
>>> p.terminate()
>>> time.sleep(0.1)
>>> print p, p.is_alive()
<Process(Process-1, stopped[SIGTERM])> False
>>> p.exitcode == -signal.SIGTERM
True

exception multiprocessing.BufferTooShort

この例外は Connection.recv_bytes_into() によって発生し、バッファオブジェクトが小さすぎてメッセージが読み込めないことを示します。

e が BufferTooShort のインスタンスとすると、 e.args[0] はバイト文字列でそのメッセージを取得できます。

16.6.2.2. パイプ (Pipe) とキュー (Queue)

マルチプロセス環境では、一般的にメッセージパッシングをプロセス間通信のために使用し、ロックのような同期プリミティブの使用しないようにします。

メッセージのやりとりのために Pipe() (2つのプロセス間の通信用)、もしくはキュー (複数プロセスがメッセージを生成、消費する通信用) を使用することができます。

Queue と JoinableQueue は複数プロセスから生成/消費を行う FIFO キューです。これらのキューは標準ライブラリの Queue.Queue を模倣しています。 Queue には Python 2.5 の Queue.Queue クラスで導入された task_done() と join() メソッドがないことが違う点です。

もし JoinableQueue を使用するなら、キューから削除される各タスクのために JoinableQueue.task_done() を呼び出さなければ なりません 。もしくは、ある例外を発生させてオーバーフローする可能性がある未終了タスクを数えるためにセマフォが使用されます。

管理オブジェクトを使用することで共有キューを作成できることも覚えておいてください。詳細は Managers を参照してください。

ノート

multiprocessing は通常の Queue.Empty と、タイムアウトのシグナルを送るために Queue.Full 例外を使用します。それらは Queue からインポートする必要があるので multiprocessing の名前空間では利用できません。

警告

Queue を利用しようとしている最中にプロセスを Process.terminate() や os.kill() で終了させる場合、キューにあるデータは破損し易くなります。終了した後で他のプロセスがキューを利用しようとすると、例外を発生させる可能性があります。

警告

上述したように、もし子プロセスがキューへ要素を追加するなら (そして JoinableQueue.cancel_join_thread() を使用しない) そのプロセスはバッファされた全ての要素がパイプへフラッシュされるまで終了しません。

これは、そのプロセスを join しようとする場合、キューに追加された全ての要素が消費されるのを確認しない限り、デッドロックを発生させる可能性があることを意味します。似たような現象で、子プロセスが非デーモンプロセスの場合、親プロセスは終了時に非デーモンの全ての子プロセスを join しようとしてハングアップする可能性があります。

Manager を使用して作成されたキューではこの問題はありません。詳細は プログラミングガイドライン を参照してください。

プロセス間通信におけるキューの使用方法は 例 を参照してください。

multiprocessing.Pipe([duplex])

パイプの終端を表す Connection オブジェクトのタプル (conn1, conn2) を返します。

duplex が True (デフォルト) なら、双方向性パイプです。 duplex が False なら、パイプは一方向性です。 conn1 はメッセージの受信専用に conn2 はメッセージの送信専用として使用されます。

class multiprocessing.Queue([maxsize])

パイプや2～3個のロック/セマフォを使用して実装されたプロセス共有キューを返します。あるプロセスが最初に要素をキューへ追加するとき、バッファからパイプの中へオブジェクトを転送する供給スレッドが開始されます。

標準ライブラリの Queue モジュールからの通常の Queue.Empty や Queue.Full 例外はタイムアウトのシグナルを送るために発生します。

Queue は task_done() や join() を除く Queue.Queue の全てのメソッドを実装します。

qsize()

おおよそのキューのサイズを返します。マルチスレッディング/マルチプロセスの特性上、この数値は信用できません。

これは sem_getvalue() が実装されていない Mac OS X のような Unix プラットホーム上で NotImplementedError を発生させる可能性があることを覚えておいてください。

empty()

キューが空っぽなら True を、そうでなければ False を返します。マルチスレッディング/マルチプロセスの特性上、これは信用できません。

full()

キューがいっぱいなら True を、そうでなければ False を返します。マルチスレッディング/マルチプロセスの特性上、これは信用できません。

put(item[, block[, timeout]])

キューの中へ要素を追加します。オプションの引数 block が True (デフォルト) 且つ timeout が None (デフォルト) なら、空きスロットが利用可能になるまで必要であればブロックします。 timeout が正の数なら、最大 timeout 秒ブロックして、その時間内に空きスロットが利用できなかったら Queue.Full 例外を発生させます。それ以外 ( block が False ) で、空きスロットがすぐに利用可能な場合はキューに要素を追加します。そうでなければ Queue.Full 例外が発生します(その場合 timeout は無視されます)。

put_nowait(item)

put(item, False) と等価です。

get([block[, timeout]])

キューから要素を取り出して削除します。オプションの引数 block が True (デフォルト) 且つ timeout が None (デフォルト) なら、要素が取り出せるまで必要であればブロックします。 timeout が正の数なら、最大 timeout 秒ブロックして、その時間内に要素が取り出せなかったら Queue.Empty 例外を発生させます。それ以外 ( block が False ) で、要素がすぐに取り出せる場合は要素を返します。そうでなければ Queue.Empty 例外が発生します(その場合 timeout は無視されます)。

get_nowait()

get_no_wait()

get(False) と等価です。

multiprocessing.Queue は Queue.Queue にはない追加メソッドがあります。これらのメソッドは通常、ほとんどのコードに必要ありません。

close()

カレントプロセスからこのキューへそれ以上データが追加されないことを表します。バックグラウンドスレッドはパイプへバッファされた全てのデータをフラッシュするとすぐに終了します。これはキューがガベージコレクトされるときに自動的に呼び出されます。

join_thread()

バックグラウンドスレッドを join します。このメソッドは close() が呼び出された後でのみ使用されます。バッファされた全てのデータがパイプへフラッシュされるのを保証した上で、バックグラウンドスレッドが終了するまでブロックします。

デフォルトでは、あるプロセスがキューを作成していない場合、終了時にキューのバックグラウンドスレッドを join しようとします。そのプロセスは join_thread() が何もしないように cancel_join_thread() を呼び出すことができます。

cancel_join_thread()

join_thread() がブロッキングするのを防ぎます。特にこれはバックグラウンドスレッドがそのプロセスの終了時に自動的に join されるのを防ぎます。詳細は join_thread() を参照してください。

class multiprocessing.JoinableQueue([maxsize])

JoinableQueue は Queue のサブクラスであり、 task_done() や join() メソッドが追加されているキューです。

task_done()

以前にキューへ追加されたタスクが完了したことを表します。キュー消費スレッドによって使用されます。タスクをフェッチするために使用されるそれぞれの get() では、次に task_done() を呼び出してタスクの処理が完了したことをキューへ伝えます。

もし join() がブロッキング状態なら、全ての要素が処理されたときに復帰します( task_done() 呼び出しが全ての要素からキュー内へ put() されたと受け取ったことを意味します)。

キューにある要素より多く呼び出された場合 ValueError が発生します。

join()

キューにある全ての要素が取り出されて処理されるまでブロッキングします。

キューに要素が追加されると未終了タスク数が増えます。キューの要素が取り出されて全て処理が完了したことを表す task_done() を消費スレッドが呼び出すと数が減ります。未終了タスク数がゼロになると join() はブロッキングを解除します。

16.6.2.3. その他の関数(Miscellaneous)

multiprocessing.active_children()

カレントプロセスのアクティブな子プロセスの全てのリストを返します。

これを呼び出すと “join” して既に終了しているプロセスには副作用があります。

multiprocessing.cpu_count()

システムの CPU 数を返します。もしかしたら NotImplementedError が発生するかもしれません。

multiprocessing.current_process()

カレントプロセスに対応する Process オブジェクトを返します。

threading.current_thread() とよく似た関数です。

multiprocessing.freeze_support()

multiprocessing を使用するプログラムが固まったときにウィンドウを実行状態にすることをサポートします。 ( py2exe , PyInstaller や cx_Freeze でテストされています。)

メインモジュールの if __name__ == '__main__' の後でこの関数を連続的に呼び出す必要があります。以下に例を示します。

from multiprocessing import Process, freeze_support

def f():
    print 'hello world!'

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

もし freeze_support() の行がない場合、固まった実行状態で実行しようとして RuntimeError を発生させます。

そのモジュールが Python インタプリタによって普通に実行されるなら freeze_support() は何の影響もありません。

multiprocessing.set_executable()

子プロセスを開始するときに使用する Python インタプリタのパスを設定します。 (デフォルトでは sys.executable が使用されます)。コードに組み込むときは、おそらく次のようにする必要があります。

  setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe'))

子プロセスを生成する前に行います。 (Windows 専用)

ノート

multiprocessing には threading.active_count(), threading.enumerate(), threading.settrace(), threading.setprofile(), threading.Timer や threading.local のような関数はありません。

16.6.2.4. Connection オブジェクト

Connection オブジェクトは pickle でシリアライズ可能なオブジェクトか文字列を送ったり、受け取ったりします。そういったオブジェクトはメッセージ指向の接続ソケットと考えられます。

Connection オブジェクトは通常は Pipe() を使用して作成されます。詳細は Listeners and Clients も参照してください。

class multiprocessing.Connection

send(obj)

コネクションの向こう側へ recv() を使用して読み込むオブジェクトを送ります。

オブジェクトは pickle でシリアライズ可能でなければなりません。 pickle が極端に大きすぎる (OS にも依りますが、およそ 32 MB+) と、 ValueError 例外が送出されることがあります。

recv()

コネクションの向こう側から send() を使用して送られたオブジェクトを返します。何も受け取らずにコネクションの向こう側でクローズされた場合 EOFError が発生します。

fileno()

コネクションが使用するハンドラか、ファイルディスクリプタを返します。

close()

コネクションをクローズします。

コネクションがガベージコレクトされるときに自動的に呼び出されます。

poll([timeout])

読み込み可能なデータがあるかどうかを返します。

timeout が指定されていなければすぐに返します。 timeout に数値を指定すると、最大指定した秒数をブロッキングします。 timeout に None を指定するとタイムアウトせずにずっとブロッキングします。

send_bytes(buffer[, offset[, size]])

バッファインタフェースをサポートするオブジェクトから完全なメッセージとしてバイトデータを送ります。

offset が指定されると buffer のその位置からデータが読み込まれます。 size が指定されると大量データがバッファから読み込まれます。

recv_bytes([maxlength])

文字列のようにコネクションの向こう側から送られたバイトデータの完全なメッセージを返します。何も受け取らずにコネクションの向こう側でクローズされた場合 EOFError が発生します。

maxlength を指定して、且つ maxlength よりメッセージが長い場合、 IOError を発生させて、それ以上はコネクションから読み込めなくなります。

recv_bytes_into(buffer[, offset])

コネクションの向こう側から送られたバイトデータを buffer に読み込み、メッセージのバイト数を返します。何も受け取らずにコネクションの向こう側でクローズされた場合 EOFError が発生します。

buffer は書き込み可能なバッファインタフェースを備えたオブジェクトでなければなりません。 offset が与えられたら、その位置からバッファへメッセージが書き込まれます。オフセットは buffer バイトよりも小さい正の数でなければなりません。

バッファがあまりに小さいと BufferTooShort 例外が発生します。 e が例外インスタンスとすると完全なメッセージは e.args[0] で確認できます。

例:

>>> from multiprocessing import Pipe
>>> a, b = Pipe()
>>> a.send([1, 'hello', None])
>>> b.recv()
[1, 'hello', None]
>>> b.send_bytes('thank you')
>>> a.recv_bytes()
'thank you'
>>> import array
>>> arr1 = array.array('i', range(5))
>>> arr2 = array.array('i', [0] * 10)
>>> a.send_bytes(arr1)
>>> count = b.recv_bytes_into(arr2)
>>> assert count == len(arr1) * arr1.itemsize
>>> arr2
array('i', [0, 1, 2, 3, 4, 0, 0, 0, 0, 0])

警告

Connection.recv() メソッドは受信したデータを自動的に unpickle 化します。それはメッセージを送ったプロセスが信頼できる場合を除いてセキュリティリスクになります。

そのため Pipe() を使用してコネクションオブジェクトを生成する場合を除いて、何らかの認証処理を実行した後で recv() や send() メソッドのみを使用すべきです。詳細は 認証キー を参照してください。

警告

もしプロセスがパイプの読み込み又は書き込み中に kill されると、メッセージの境界が正しいかどうか分からないので、そのパイプのデータは破壊されたようになります。

16.6.2.5. 同期プリミティブ

一般的に同期プリミティブはマルチスレッドプログラムのようにマルチプロセスプログラムでは必要ありません。詳細は threading モジュールのドキュメントを参照してください。

マネージャオブジェクトを使用して同期プリミティブを作成できることも覚えておいてください。詳細は Managers を参照してください。

class multiprocessing.BoundedSemaphore([value])

束縛されたセマフォオブジェクト: threading.BoundedSemaphore のクローンです。

(Mac OS X では sem_getvalue() が実装されていないので Semaphore と区別がつきません。)

class multiprocessing.Condition([lock])

状態変数: threading.Condition のクローンです。

lock を指定するなら multiprocessing の Lock か RLock オブジェクトにすべきです。

class multiprocessing.Event

threading.Event のクローンです。このメソッドは、終了時の内部セマフォの状態を返すので、タイムアウトが与えられ、実際にオペレーションがタイムアウトしたのでなければ、必ず True を返します。

バージョン 2.7 で変更: 以前は、このメソッドは必ず None を返していました。

class multiprocessing.Lock

非再帰的なロックオブジェクト: threading.Lock のクローンです。

class multiprocessing.RLock

再帰的なロックオブジェクト: threading.RLock のクローンです。

class multiprocessing.Semaphore([value])

セマフォオブジェクト: threading.Semaphore のクローンです。

ノート

BoundedSemaphore, Lock, RLock と Semaphore の acquire() メソッドは threading ではサポートされていないタイムアウトパラメータを取ります。その引数はキーワード引数で受け取れる acquire(block=True, timeout=None) です。 block が True 且つ timeout が None ではないなら、タイムアウトが秒単位で設定されます。 block が False なら timeout は無視されます。

Mac OS X では sem_timedwait がサポートされていないので、 acquire() タイムアウトを与えて呼ぶと、擬似的なスリーピングループ関数を実行することになります。

ノート

メインスレッドが BoundedSemaphore.acquire(), Lock.acquire(), RLock.acquire(), Semaphore.acquire(), Condition.acquire() 又は Condition.wait() を呼び出してブロッキング状態のときに Ctrl-C で生成される SIGINT シグナルを受け取ると、その呼び出しはすぐに中断されて KeyboardInterrupt が発生します。

これは同等のブロッキング呼び出しが実行中のときに SIGINT が無視される threading の振る舞いとは違っています。

16.6.2.6. 共有 ctypes オブジェクト

子プロセスにより継承される共有メモリを使用する共有オブジェクトを作成することができます。

multiprocessing.Value(typecode_or_type, *args[, lock])

共有メモリから割り当てられた ctypes オブジェクトを返します。デフォルトでは、返り値は実際のオブジェクトの同期ラッパーです。

typecode_or_type は返されるオブジェクトの型を決めます。それは ctypes の型か array モジュールで使用されるような1文字の型コードかのどちらか一方です。 *args は型のコンストラクタへ渡されます。

lock が True (デフォルト) なら、値へ同期アクセスするために新たなロックオブジェクトが作成されます。 lock が Lock か RLock なら値への同期アクセスに使用されます。 lock が False なら、返されたオブジェクトへのアクセスはロックにより自動的に保護されません。そのため、必ずしも “プロセスセーフ” ではありません。

lock はキーワード引数でのみ指定することに注意してください。

multiprocessing.Array(typecode_or_type, size_or_initializer, *, lock=True)

共有メモリから割り当てられた ctypes 配列を返します。デフォルトでは、返り値は実際の配列の同期ラッパーです。

typecode_or_type は返される配列の要素の型を決めます。それは ctypes の型か array モジュールで使用されるような1文字の型コードかのどちらか一方です。 size_or_initializer が整数なら、配列の長さを決定し、その配列はゼロで初期化されます。別の使用方法として size_or_initializer は配列の初期化に使用されるシーケンスになり、そのシーケンス長が配列の長さを決定します。

lock が True (デフォルト) なら、値へ同期アクセスするために新たなロックオブジェクトが作成されます。 lock が Lock か RLock なら値への同期アクセスに使用されます。 lock が False なら、返されたオブジェクトへのアクセスはロックにより自動的に保護されません。そのため、必ずしも “プロセスセーフ” ではありません。

lock はキーワード引数でのみ指定することに注意してください。

ctypes.c_char の配列は文字列を格納して取り出せる value と raw 属性を持っていることを覚えておいてください。

16.6.2.6.1. multiprocessing.sharedctypes モジュール

multiprocessing.sharedctypes モジュールは子プロセスに継承される共有メモリの ctypes オブジェクトを割り当てる関数を提供します。

ノート

共有メモリのポインタを格納することは可能ではありますが、特定プロセスのアドレス空間の位置を参照するということを覚えておいてください。しかし、そのポインタは別のプロセスのコンテキストにおいて無効になる確率が高いです。そして、別のプロセスからそのポインタを逆参照しようとするとクラッシュを引き起こす可能性があります。

multiprocessing.sharedctypes.RawArray(typecode_or_type, size_or_initializer)

共有メモリから割り当てられた ctypes 配列を返します。

typecode_or_type は返される配列の要素の型を決めます。それは ctypes の型か array モジュールで使用されるような1文字の型コードかのどちらか一方です。 size_or_initializer が整数なら、配列の長さを決定し、その配列はゼロで初期化されます。別の使用方法として size_or_initializer は配列の初期化に使用されるシーケンスになり、そのシーケンス長が配列の長さを決定します。

要素を取得したり設定したりすることは潜在的に非アトミックであることに注意してください。ロックを使用して自動的に同期されたアクセスを保証するには Array() を使用してください。

multiprocessing.sharedctypes.RawValue(typecode_or_type, *args)

共有メモリから割り当てられた ctypes オブジェクトを返します。

typecode_or_type は返される型を決めます。それは ctypes の型か array モジュールで使用されるような1文字の型コードかのどちらか一方です。 *args は型のコンストラクタへ渡されます。

値を取得したり設定したりすることは潜在的に非アトミックであることに注意してください。ロックを使用して自動的に同期されたアクセスを保証するには Value() を使用してください。

ctypes.c_char の配列は文字列を格納して取り出せる value と raw 属性を持っていることを覚えておいてください。詳細は ctypes を参照してください。

multiprocessing.sharedctypes.Array(typecode_or_type, size_or_initializer, *args[, lock])

lock の値に依存する点を除けば RawArray() と同様です。プロセスセーフな同期ラッパーが raw ctypes 配列の代わりに返されるでしょう。

lock が True (デフォルト) なら、値へ同期アクセスするために新たなロックオブジェクトが作成されます。 lock が Lock か RLock なら値への同期アクセスに使用されます。 lock が False なら、返されたオブジェクトへのアクセスはロックにより自動的に保護されません。そのため、必ずしも “プロセスセーフ” ではありません。

lock はキーワード引数でのみ指定することに注意してください。

multiprocessing.sharedctypes.Value(typecode_or_type, *args[, lock])

lock の値に依存する点を除けば RawValue() と同様です。プロセスセーフな同期ラッパーが ctypes オブジェクトの代わりに返されるでしょう。

lock が True (デフォルト) なら、値へ同期アクセスするために新たなロックオブジェクトが作成されます。 lock が Lock か RLock なら値への同期アクセスに使用されます。 lock が False なら、返されたオブジェクトへのアクセスはロックにより自動的に保護されません。そのため、必ずしも “プロセスセーフ” ではありません。

lock はキーワード引数でのみ指定することに注意してください。

multiprocessing.sharedctypes.copy(obj)

共有メモリから割り当てられた ctypes オブジェクト obj をコピーしたオブジェクトを返します。

multiprocessing.sharedctypes.synchronized(obj[, lock])

同期アクセスに lock を使用する ctypes オブジェクトのためにプロセスセーフなラッパーオブジェクトを返します。 lock が None (デフォルト) なら、 multiprocessing.RLock オブジェクトが自動的に作成されます。

同期ラッパーがラップするオブジェクトに加えて2つのメソッドがあります。 get_obj() はラップされたオブジェクトを返します。 get_lock() は同期のために使用されるロックオブジェクトを返します。

ラッパー経由で ctypes オブジェクトにアクセスすることは raw ctypes オブジェクトへアクセスするよりずっと遅くなることに注意してください。

次の表は通常の ctypes 構文で共有メモリから共有 ctypes オブジェクトを作成するための構文を比較します。 ( MyStruct テーブル内には ctypes.Structure のサブクラスがあります。)

ctypes | type を使用する sharedctypes | typecode を使用する sharedctypes
c_double(2.4) | RawValue(c_double, 2.4) | RawValue(‘d’, 2.4)
MyStruct(4, 6) | RawValue(MyStruct, 4, 6) |
(c_short * 7)() | RawArray(c_short, 7) | RawArray(‘h’, 7)
(c_int * 3)(9, 2, 8) | RawArray(c_int, (9, 2, 8)) | RawArray(‘i’, (9, 2, 8))

以下に子プロセスが多くの ctypes オブジェクトを変更する例を紹介します。

from multiprocessing import Process, Lock
from multiprocessing.sharedctypes import Value, Array
from ctypes import Structure, c_double

class Point(Structure):
    _fields_ = [('x', c_double), ('y', c_double)]

def modify(n, x, s, A):
    n.value **= 2
    x.value **= 2
    s.value = s.value.upper()
    for a in A:
        a.x **= 2
        a.y **= 2

if __name__ == '__main__':
    lock = Lock()

    n = Value('i', 7)
    x = Value(c_double, 1.0/3.0, lock=False)
    s = Array('c', 'hello world', lock=lock)
    A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock)

    p = Process(target=modify, args=(n, x, s, A))
    p.start()
    p.join()

    print n.value
    print x.value
    print s.value
    print [(a.x, a.y) for a in A]

結果は以下のように表示されます。

49
0.1111111111111111
HELLO WORLD
[(3.515625, 39.0625), (33.0625, 4.0), (5.640625, 90.25)]

16.6.2.7. Managers

Manager は別のプロセス間で共有されるデータの作成方法を提供します。マネージャオブジェクトは 共有オブジェクト を管理するサーバプロセスを制御します。他のプロセスはプロキシ経由で共有オブジェクトへアクセスすることができます。

multiprocessing.Manager()

プロセス間で共有オブジェクトのために使用される SyncManager オブジェクトを返します。返されたマネージャオブジェクトは生成される子プロセスに対応して、共有オブジェクトを作成するメソッドを持ち、応答プロキシを返します。

マネージャプロセスは親プロセスが終了するか、ガベージコレクトされると停止します。マネージャクラスは multiprocessing.managers モジュールで定義されています。

class multiprocessing.managers.BaseManager([address[, authkey]])

BaseManager オブジェクトを作成します。

作成後、マネージャオブジェクトが開始されたマネージャプロセスの参照を保証するために start() か get_server().serve_forever() を呼び出します。

address はマネージャプロセスが新たなコネクションを待ち受けるアドレスです。 address が None の場合、任意のアドレスが設定されます。

authkey はサーバプロセスへ接続しようとするコネクションの正当性を検証するために使用される認証キーです。 authkey が None の場合 current_process().authkey が使用されます。 authkey を使用する場合は文字列でなければなりません。

start([initializer[, initargs]])

マネージャを開始するためにサブプロセスを開始します。 initializer が None でなければ、サブプロセスは開始時に initializer(*initargs) を呼び出します。

get_server()

マネージャの制御下にある実際のサーバに相当する Server オブジェクトを返します。 Server オブジェクトは serve_forever() メソッドをサポートします。

>>> from multiprocessing.managers import BaseManager
>>> manager = BaseManager(address=('', 50000), authkey='abc'))
>>> server = manager.get_server()
>>> server.serve_forever()

Server はさらに address 属性も持っています。

connect()

ローカルからリモートのマネージャオブジェクトへ接続します。

>>> from multiprocessing.managers import BaseManager
>>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc))>>>
m.connect()

shutdown()

マネージャが使用するプロセスを停止します。これはサーバプロセスを開始するために start() が使用された場合のみ有効です。

これは複数回呼び出すことができます。

register(typeid[, callable[, proxytype[, exposed[, method_to_typeid[, create_method]]]]])

マネージャクラスで呼び出し可能オブジェクト(callable)や型を登録するために使用されるクラスメソッドです。

typeid は特に共有オブジェクトの型を識別するために使用される “型識別子” です。これは文字列でなければなりません。

callable はこの型識別子のオブジェクトを作成するために使用される呼び出し可能オブジェクトです。マネージャインスタンスが from_address() クラスメソッドを使用して作成されるか、 create_method 引数が False の場合は None でも構いません。

proxytype はこの typeid で共有オブジェクトのプロキシを作成するために使用される BaseProxy のサブクラスです。 None の場合、プロキシクラスは自動的に作成されます。

exposed は BaseProxy._callMethod() を使用してアクセスされるこの typeid のプロキシになるメソッド名のシーケンスを指定するために使用されます。 ( exposed が None の場合 proxytype._exposed_ が存在すれば、それが代わりに使用されます。) exposed リストが指定されない場合は、共有オブジェクトの全ての “パブリックメソッド” にアクセスされます。 (ここで言う “パブリックメソッド” は __call__() メソッドを持ち、 '_' で始まらない名前の属性を意味します。)

method_to_typeid はプロキシが返す exposed メソッドの型を指定するために使用されるマッピングです。それは typeid 文字列に対してメソッド名をマップします。 ( method_to_typeid が None の場合 proxytype._method_to_typeid_ が存在すれば、それが代わりに使用されます。) メソッド名がこのマッピングのキーではないか、マッピングが None の場合、そのメソッドによって返されるオブジェクトが値によってコピーされます。

create_method は、新たな共有オブジェクトを作成するためにサーバプロセスへ伝えるのに使用されるメソッドを typeid の名前で作成し、そのためのプロキシを返すかを決定します。デフォルトでは True です。

BaseManager インスタンスも読み取り専用属性を1つ持っています。

address

マネージャが使用するアドレスです。

class multiprocessing.managers.SyncManager

プロセス間の同期のために使用される BaseManager のサブクラスです。 multiprocessing.Manager() はこの型のオブジェクトを返します。

また共有リストやディクショナリの作成もサポートします。

BoundedSemaphore([value])

共有 threading.BoundedSemaphore オブジェクトを作成して、そのプロキシを返します。

Condition([lock])

共有 threading.Condition オブジェクトを作成して、そのプロキシを返します。

lock が提供される場合 threading.Lock か threading.RLock オブジェクトのためのプロキシになります。

Event()

共有 threading.Event オブジェクトを作成して、そのプロキシを返します。

Lock()

共有 threading.Lock オブジェクトを作成して、そのプロキシを返します。

Namespace()

共有 Namespace オブジェクトを作成して、そのプロキシを返します。

Queue([maxsize])

共有 Queue.Queue オブジェクトを作成して、そのプロキシを返します。

RLock()

共有 threading.RLock オブジェクトを作成して、そのプロキシを返します。

Semaphore([value])

共有 threading.Semaphore オブジェクトを作成して、そのプロキシを返します。

Array(typecode, sequence)

配列を作成して、そのプロキシを返します。

Value(typecode, value)

書き込み可能な value 属性を作成して、そのプロキシを返します。

dict()

dict(mapping)

dict(sequence)

共有 dict オブジェクトを作成して、そのプロキシを返します。

list()

list(sequence)

共有 list オブジェクトを作成して、そのプロキシを返します。

ノート

プロキシには、ミュータブルな値や、辞書とリストのプロキシの要素が、いつ変えられたのかを知る方法がないため、これらの値や要素の変化はマネージャを通して伝播しません。要素などを変化させるために、コンテナプロキシに変化されたオブジェクトを再代入できます。

# create a list proxy and append a mutable object (a dictionary) lproxy = manager.list() lproxy.append({}) # now mutate the dictionary d = lproxy[0] d[‘a’] = 1 d[‘b’] = 2 # at this point, the changes to d are not yet synced, but by # reassigning the dictionary, the proxy is notified of the change lproxy[0] = d

16.6.2.7.1. Namespace オブジェクト

Namespace オブジェクトはプライベートなメソッドを持っていますが、書き込み属性を持ちます。そのオブジェクト表現はその属性の値を表示します。

しかし、Namespace オブジェクトのためにプロキシを使用するとき '_' が先頭に付く属性はプロキシの属性になり、参照対象の属性にはなりません。

>>> manager = multiprocessing.Manager()
>>> Global = manager.Namespace()
>>> Global.x = 10
>>> Global.y = 'hello'
>>> Global._z = 12.3    # これはプロキシの属性です
>>> print Global
Namespace(x=10, y='hello')

16.6.2.7.2. カスタマイズされたマネージャ

独自のマネージャを作成するために BaseManager のサブクラスを作成して、マネージャクラスで呼び出し可能なオブジェクトか新たな型を登録するために register() クラスメソッドを使用します。

from multiprocessing.managers import BaseManager

class MathsClass(object):
    def add(self, x, y):
        return x + y
    def mul(self, x, y):
        return x * y

class MyManager(BaseManager):
    pass

MyManager.register('Maths', MathsClass)

if __name__ == '__main__':
    manager = MyManager()
    manager.start()
    maths = manager.Maths()
    print maths.add(4, 3)         # 7 を表示
    print maths.mul(7, 8)         # 56 を表示

16.6.2.7.3. リモートマネージャを使用する

あるマシン上でマネージャサーバを実行して、他のマシンからそのサーバを使用するクライアントを持つことができます(ファイアウォールを通過できることが前提)。

次のコマンドを実行することでリモートクライアントからアクセスを受け付ける1つの共有キューのためにサーバを作成します。

>>> from multiprocessing.managers import BaseManager
>>> import Queue
>>> queue = Queue.Queue()
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue', callable=lambda:queue)
>>> m = QueueManager(address=('', 50000), authkey='abracadabra')
>>> s = m.get_server()
>>> s.serve_forever()

あるクライアントからサーバへのアクセスは次のようになります。

>>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue')
>>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra')
>>> m.connect()
>>> queue = m.get_queue()
>>> queue.put('hello')

別のクライアントもそれを使用することができます。

>>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass
>>> QueueManager.register('get_queue')
>>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra')
>>> m.connect()
>>> queue = m.get_queue()
>>> queue.get()
'hello'

ローカルプロセスもそのキューへアクセスすることができます。クライアント上で上述のコードを使用してアクセスします。

>>> from multiprocessing import Process, Queue
>>> from multiprocessing.managers import BaseManager
>>> class Worker(Process):
...     def __init__(self, q):
...         self.q = q
...         super(Worker, self).__init__()
...     def run(self):
...         self.q.put('local hello')
...
>>> queue = Queue()
>>> w = Worker(queue)
>>> w.start()
>>> class QueueManager(BaseManager): pass
...
>>> QueueManager.register('get_queue', callable=lambda: queue)
>>> m = QueueManager(address=('', 50000), authkey='abracadabra')
>>> s = m.get_server()
>>> s.serve_forever()

16.6.2.8. Proxy オブジェクト

プロキシは別のプロセスで(おそらく)有効な共有オブジェクトを 参照する オブジェクトです。共有オブジェクトはプロキシの 参照対象 になると言うことができます。複数のプロキシオブジェクトが同じ参照対象を持つ可能性もあります。

プロキシオブジェクトはその参照対象が持つ対応メソッドを実行するメソッドを持ちます。 (そうは言っても、参照対象の全てのメソッドが必ずしもプロキシ経由で利用可能ではありません) プロキシは通常その参照対象ができることと同じ方法で使用されます。

>>> from multiprocessing import Manager
>>> manager = Manager()
>>> l = manager.list([i*i for i in range(10)])
>>> print l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> print repr(l)
<ListProxy object, typeid 'list' at 0x...>
>>> l[4]
16
>>> l[2:5]
[4, 9, 16]

プロキシに str() を適用すると参照対象のオブジェクト表現を返すのに対して、 repr() を適用するとプロキシのオブジェクト表現を返すことに注意してください。

プロキシオブジェクトの重要な機能はプロセス間で受け渡し可能な pickle 化ができることです。しかし、プロキシが対応するマネージャプロセスに対して送信される場合、そのプロキシを unpickle するとその参照対象を生成することを覚えておいてください。例えば、これはある共有オブジェクトに別の共有オブジェクトが含められることを意味します。

>>> a = manager.list()
>>> b = manager.list()
>>> a.append(b)         # a の参照対象に b の参照対象を含める
>>> print a, b
[[]] []
>>> b.append('hello')
>>> print a, b
[['hello']] ['hello']

ノート

multiprocessing のプロキシ型は値による比較に対して何もサポートしません。そのため、インスタンスでは、

>>> manager.list([1,2,3]) == [1,2,3]
False

比較を行いたいときは参照対象のコピーを使用してください。

class multiprocessing.managers.BaseProxy

プロキシオブジェクトは BaseProxy のサブクラスのインスタンスです。

_callmethod(methodname[, args[, kwds]])

プロキシの参照対象のメソッドの実行結果を返します。

proxy がプロキシで、プロキシ内の参照対象が obj なら、

proxy._callmethod(methodname, args, kwds)

は、

getattr(obj, methodname)(*args, **kwds)

マネージャプロセス内のこの式を評価します。

返される値はその呼び出し結果のコピーか、新たな共有オブジェクトに対するプロキシになります。詳細は BaseManager.register() の method_to_typeid 引数のドキュメントを参照してください。

例外がその呼び出しによって発生する場合 _callmethod() によって再発生させます。もし他の例外がマネージャプロセスで発生するなら、 RemoteError 例外に変換されて _callmethod() によって発生させます。

特に methodname が 公開 されていない場合は例外が発生することに注意してください。

_callmethod() の使用例になります。

>>> l = manager.list(range(10))
>>> l._callmethod('__len__')
10
>>> l._callmethod('__getslice__', (2, 7))   # `l[2:7]` と等価
[2, 3, 4, 5, 6]
>>> l._callmethod('__getitem__', (20,))     # `l[20]` と等価
Traceback (most recent call last):
...
IndexError: list index out of range

_getvalue()

参照対象のコピーを返します。

参照対象が unpickle 化できるなら例外を発生します。

__repr__()

プロキシオブジェクトのオブジェクト表現を返します。

__str__()

参照対象のオブジェクト表現を返します。

16.6.2.8.1. クリーンアップ

プロキシオブジェクトは弱参照(weakref)コールバックを使用します。プロキシオブジェクトがガベージコレクトされるときにその参照対象が所有するマネージャからその登録を取り消せるようにするためです。

共有オブジェクトはプロキシが参照しなくなったときにマネージャプロセスから削除されます。

16.6.2.9. プロセスプール

Pool クラスでタスクを実行するプロセスのプールを作成することができます。

class multiprocessing.Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])

プロセスプールオブジェクトはジョブが実行されるようにワーカープロセスのプールを制御します。タイムアウトやコールバックで非同期の実行をサポートして、並列 map 実装を持ちます。

processes は使用するワーカープロセスの数です。 processes が None の場合 cpu_count() が返す数を使用します。 initializer が None の場合、各ワーカープロセスが開始時に initializer(*initargs) を呼び出します。

バージョン 2.7 で追加: maxtasksperchild は、使われないリソースの開放のためにワーカープロセスが退出して、新しいワーカープロセスで置き換えられるまでに完了できるタスクの数です。デフォルトの maxtasksperchild は None で、ワーカープロセスがプールと同じだけ残ることを意味します。

ノート

Pool 中のワーカープロセスは典型的に、プールのワークキューの存続期間とちょうど同じだけ残ります。(Apache, mod_wsgi, 等のような) 他のシステムによく見られるパターンは、ワーカーが設定された量だけのワークを完了させるまでプールに置いたら退出させ、新しいプロセスが産まれて古いプロセスを置き換えるものです。 Pool の maxtasksperchild 引数は、この能力をエンドユーザに開放します。

apply(func[, args[, kwds]])

apply() 組み込み関数と同じです。その結果を返せるようになるまでブロックします。これらのブロックが与えられる場合、 apply_async() の方がうまく並列実行を処理します。さらに関数はプールの中の一つのワーカーにのみ渡されます。

apply_async(func[, args[, kwds[, callback]]])

apply() メソッドの一種で結果オブジェクトを返します。

callback が指定された場合、1つの引数を受け取って呼び出されます。その結果を返せるようになったときに callback が結果オブジェクトに対して (その呼び出しが失敗しない限り)適用されます。その結果を扱う別スレッドはブロックされるので callback はすぐに終了します。

map(func, iterable[, chunksize])

並列な map() 組み込み関数と同じです( iterable な引数を1つだけサポートします)。その結果を返せるようになるまでブロックします。

このメソッドは独立したタスクのようにプロセスプールに対して実行するチャンク数に分割します。チャンク(概算)サイズは chunksize に正の整数を指定することで行います。

map_async(func, iterable[, chunksize[, callback]])

map() メソッドの一種で結果オブジェクトを返します。

callback が指定された場合、1つの引数を受け取って呼び出されます。その結果を返せるようになったときに callback が結果オブジェクトに対して (その呼び出しが失敗しない限り)適用されます。その結果を扱う別スレッドはブロックされるので callback はすぐに終了します。

imap(func, iterable[, chunksize])

itertools.imap() と同じです。

chunksize 引数は map() メソッドで使用されるものと同じです。引数 iterable がとても大きいなら chunksize に大きな値を指定して使用する方がデフォルト値の 1 を使用するよりもジョブの完了が かなり 速くなります。

また chunksize が 1 の場合 imap() メソッドが返すイテレータの next() メソッドはオプションで timeout パラメータを持ちます。 next(timeout) は、その結果が timeout 秒以内に返されないときに multiprocessing.TimeoutError を発生させます。

imap_unordered(func, iterable[, chunksize])

イテレータが返す結果の順番が任意の順番で良いと見なされることを除けば imap() と同じです。 (ワーカープロセスが1つしかない場合のみ “正しい” 順番になることが保証されます。)

close()

これ以上プールでタスクが実行されないようにします。全てのタスクが完了した後でワーカープロセスが終了します。

terminate()

実行中の処理を完了させずにワーカープロセスをすぐに停止します。プールオブジェクトがガベージコレクトされるときに terminate() が呼び出されます。

join()

ワーカープロセスが終了するのを待ちます。 join() を使用する前に close() か terminate() を呼び出さなければなりません。

class multiprocessing.pool.AsyncResult

Pool.apply_async() や Pool.map_async() で返される結果のクラスです。

get([timeout])

結果を受け取ったときに返します。 timeout が None ではなくて、その結果が timeout 秒以内に受け取れない場合 multiprocessing.TimeoutError が発生します。リモートの呼び出しが例外を発生させる場合、その例外は get() が再発生させます。

wait([timeout])

その結果が有効になるか timeout 秒経つまで待ちます。

ready()

その呼び出しが完了しているかどうかを返します。

successful()

その呼び出しが例外を発生させることなく完了したかどうかを返します。その結果が返せる状態でない場合 AssertionError が発生します。

次の例はプールの使用例を紹介します。

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # 4つのワーカープロセスで開始

    result = pool.apply_async(f, (10,))   # 非同期で "f(10)" を評価
    print result.get(timeout=1)           # あなたのコンピュータが *かなり* 遅くない限りは "100" を表示

    print pool.map(f, range(10))          # "[0, 1, 4,..., 81]" を表示

    it = pool.imap(f, range(10))
    print it.next()                       # "0" を表示
    print it.next()                       # "1" を表示
    print it.next(timeout=1)              # あなたのコンピュータが *かなり* 遅くない限りは "4" を表示

    import time
    result = pool.apply_async(time.sleep, (10,))
    print result.get(timeout=1)           # TimeoutError を発生

16.6.2.10. Listeners and Clients

通常、プロセス間でメッセージを渡すにはキューを使用するか Pipe() が返す Connection オブジェクトを使用します。

しかし multiprocessing.connection モジュールはさらに柔軟な仕組みがあります。基本的にはソケットもしくは Windows の名前付きパイプを扱う高レベルのメッセージ指向 API を提供して hmac モジュールを使用して ダイジェスト認証 もサポートします。

multiprocessing.connection.deliver_challenge(connection, authkey)

ランダム生成したメッセージをコネクションの相手側へ送信して応答を待ちます。

その応答がキーとして authkey を使用するメッセージのダイジェストと一致する場合、コネクションの相手側へ歓迎メッセージを送信します。そうでなければ AuthenticationError を発生させます。

multiprocessing.connection.answerChallenge(connection, authkey)

メッセージを受信して、そのキーとして authkey を使用するメッセージのダイジェストを計算し、ダイジェストを送り返します。

歓迎メッセージを受け取れない場合 AuthenticationError が発生します。

multiprocessing.connection.Client(address[, family[, authenticate[, authkey]]])

address で渡したアドレスを使用するリスナーに対してコネクションを確立しようとして Connection を返します。

コネクション種別は family 引数で決定しますが、一般的には address のフォーマットから推測できるので、これは指定されません。 ( アドレスフォーマット を参照してください)

authenticate が True か authkey が文字列の場合、ダイジェスト認証が使用されます。認証に使用されるキーは authkey 、又は authkey が None の場合は current_process().authkey のどちらかです。認証が失敗した場合 AuthenticationError が発生します。認証キー を参照してください。

class multiprocessing.connection.Listener([address[, family[, backlog[, authenticate[, authkey]]]]])

コネクションを ‘待ち受ける’ 束縛されたソケットか Windows の名前付きパイプのラッパです。

address はリスナーオブジェクトの束縛されたソケットか名前付きパイプが使用するアドレスです。

ノート

‘0.0.0.0’ のアドレスを使用する場合、Windows 上の終点へ接続することができません。終点へ接続したい場合は ‘127.0.0.1’ を使用すべきです。

family は使用するソケット(名前付きパイプ)の種別です。これは 'AF_INET' (TCP ソケット), 'AF_UNIX' (Unix ドメインソケット) 又は 'AF_PIPE' (Windows 名前付きパイプ) という文字列のどれか1つになります。これらのうち 'AF_INET' のみが利用可能であることが保証されています。 family が None の場合 address のフォーマットから推測されたものが使用されます。 address も None の場合はデフォルトが選択されます。詳細は アドレスフォーマット を参照してください。 family が 'AF_UNIX' で address が None の場合 tempfile.mkstemp() を使用して作成されたプライベートな一時ディレクトリにソケットが作成されます。

リスナーオブジェクトがソケットを使用する場合、ソケットに束縛されるときに backlog (デフォルトでは1つ) がソケットの listen() メソッドに対して渡されます。

authenticate が True (デフォルトでは False ) か authkey が None ではない場合、ダイジェスト認証が使用されます。

authkey が文字列の場合、認証キーとして使用されます。そうでない場合は None でなければいけません。

authkey が None 且つ authenticate が True の場合 current_process().authkey が認証キーとして使用されます。 authkey が None 且つ authentication が False の場合、認証は行われません。もし認証が失敗した場合 AuthenticationError が発生します。詳細 認証キー を参照してください。

accept()

リスナーオブジェクトの名前付きパイプか束縛されたソケット上でコネクションを受け付けて Connection オブジェクトを返します。認証が失敗した場合 AuthenticationError が発生します。

close()

リスナーオブジェクトの名前付きパイプか束縛されたソケットをクローズします。これはリスナーがガベージコレクトされるときに自動的に呼ばれます。そうは言っても、明示的に close() を呼び出す方が望ましいです。

リスナーオブジェクトは次の読み取り専用属性を持っています。

address

リスナーオブジェクトが使用中のアドレスです。

last_accepted

最後にコネクションを受け付けたアドレスです。有効なアドレスがない場合は None になります。

このモジュールは2つの例外を定義します。

exception multiprocessing.connection.AuthenticationError

認証エラーが起こったときに例外が発生します。

例

次のサーバコードは認証キーとして 'secret password' を使用するリスナーを作成します。このサーバはコネクションを待ってクライアントへデータを送信します。

from multiprocessing.connection import Listener
from array import array

address = ('localhost', 6000)     # family is deduced to be 'AF_INET'
listener = Listener(address, authkey='secret password')

conn = listener.accept()
print 'connection accepted from', listener.last_accepted

conn.send([2.25, None, 'junk', float])

conn.send_bytes('hello')

conn.send_bytes(array('i', [42, 1729]))

conn.close()
listener.close()

次のコードはサーバへ接続して、サーバからデータを受信します。

from multiprocessing.connection import Client
from array import array

address = ('localhost', 6000)
conn = Client(address, authkey='secret password')

print conn.recv()                 # => [2.25, None, 'junk', float]

print conn.recv_bytes()            # => 'hello'

arr = array('i', [0, 0, 0, 0, 0])
print conn.recv_bytes_into(arr)     # => 8
print arr                         # => array('i', [42, 1729, 0, 0, 0])

conn.close()

16.6.2.10.1. アドレスフォーマット

'AF_INET' アドレスは (hostname, port) のタプルになります。 hostname は文字列で port は整数です。

'AF_UNIX' アドレスはファイルシステム上のファイル名の文字列です。

'AF_PIPE' アドレスは r'\\.\pipe\PipeName' の文字列です。 ServerName というリモートコンピュータ上の名前付きパイプに接続するために Client() を使用するには、代わりに r'\\ServerName\pipe\PipeName' のアドレスを使用すべきです。

デフォルトでは、2つのバックスラッシュで始まる文字列は 'AF_UNIX' よりも 'AF_PIPE' として推測されることに注意してください。

16.6.2.11. 認証キー

Connection.recv() を使用するとき、データは自動的に unpickle されて受信します。信頼できない接続元からのデータを unpickle することはセキュリティリスクがあります。そのため Listener や Client() はダイジェスト認証を提供するために hmac モジュールを使用します。

認証キーはパスワードとして見なされる文字列です。コネクションが確立すると、双方の終点で正しい接続先であることを証明するために知っているお互いの認証キーを要求します。 (双方の終点が同じキーを使用して通信しようとしても、コネクション上でそのキーを送信することは できません 。)

認証が要求されて認証キーが指定されている場合 current_process().authkey の返す値が使用されます。 (詳細は Process を参照してください。) この値はカレントプロセスを作成する Process オブジェクトによって自動的に継承されます。これは(デフォルトでは)複数プロセスのプログラムの全プロセスが相互にコネクションを確立するときに使用される1つの認証キーを共有することを意味します。

適当な認証キーを os.urandom() を使用して生成することもできます。

16.6.2.12. ロギング

ロギングのために幾つかの機能が利用可能です。しかし logging パッケージは、 (ハンドラ種別に依存して)違うプロセスからのメッセージがごちゃ混ぜになるので、プロセスの共有ロックを使用しないことに注意してください。

multiprocessing.get_logger()

multiprocessing が使用するロガーを返します。必要に応じて新たなロガーを作成します。

最初に作成するとき、ロガーはレベルに logging.NOTSET が設定されていてデフォルトハンドラがありません。このロガーへ送られるメッセージはデフォルトではルートロガーへ伝播されません。

Windows 上では子プロセスが親プロセスのロガーレベルを継承しないことに注意してください。さらにその他のロガーのカスタマイズ内容も全て継承されません。

multiprocessing.log_to_stderr()

この関数は get_logger() に対する呼び出しを実行しますが、 get_logger によって作成されるロガーを返すことに加えて、 '[%(levelname)s/%(processName)s] %(message)s' のフォーマットを使用して sys.stderr へ出力を送るハンドラを追加します。

以下にロギングを有効にした例を紹介します。

>>> import multiprocessing, logging
>>> logger = multiprocessing.log_to_stderr()
>>> logger.setLevel(logging.INFO)
>>> logger.warning('doomed')
[WARNING/MainProcess] doomed
>>> m = multiprocessing.Manager()
[INFO/SyncManager-...] child process calling self.run()
[INFO/SyncManager-...] created temp directory /.../pymp-...
[INFO/SyncManager-...] manager serving at '/.../listener-...'
>>> del m
[INFO/MainProcess] sending shutdown message to manager
[INFO/SyncManager-...] manager exiting with exitcode 0

これらの2つのロギング関数があることに加えて、 multiprocessing モジュールも2つの追加ロギングレベル属性を提供します。それは SUBWARNING と SUBDEBUG です。次の表は通常のレベル階層にうまく適合していることを表します。

Level | Numeric value
SUBWARNING | 25
SUBDEBUG | 5

完全なロギングレベルの表については logging モジュールを参照してください。

こういった追加のロギングレベルは主に multiprocessing モジュールの信頼できるデバッグメッセージのために使用されます。以下に上述の例に SUBDEBUG を有効にしたものを紹介します。

>>> import multiprocessing, logging
>>> logger = multiprocessing.log_to_stderr()
>>> logger.setLevel(multiprocessing.SUBDEBUG)
>>> logger.warning('doomed')
[WARNING/MainProcess] doomed
>>> m = multiprocessing.Manager()
[INFO/SyncManager-...] child process calling self.run()
[INFO/SyncManager-...] created temp directory /.../pymp-...
[INFO/SyncManager-...] manager serving at '/.../pymp-.../listener-...'
>>> del m
[SUBDEBUG/MainProcess] finalizer calling ...
[INFO/MainProcess] sending shutdown message to manager
[DEBUG/SyncManager-1] manager received shutdown message
[SUBDEBUG/SyncManager-...] calling <Finalize object, callback=unlink, ...
[SUBDEBUG/SyncManager-...] finalizer calling <built-in function unlink> ...
[SUBDEBUG/SyncManager-...] calling <Finalize object, dead>
[SUBDEBUG/SyncManager-...] finalizer calling <function rmtree at 0x5aa730> ...
[INFO/SyncManager-...] manager exiting with exitcode 0

16.6.2.13. multiprocessing.dummy モジュール

multiprocessing.dummy は multiprocessing の API を複製しますが threading モジュールのラッパーでしかありません。

16.6.3. プログラミングガイドライン

multiprocessing を使用するときに守るべき確かなガイドラインとイディオムです。

16.6.3.1. 全てのプラットホーム

共有状態を避ける

できるだけプロセス間で巨大なデータを移動することは避けるようにすべきです。

threading モジュールのプリミティブな低レベルの同期を使用するよりも、キューかパイプをプロセス間通信に使用することがおそらく最善の方法です。

pickle 機能

プロキシのメソッドへの引数は pickle 化できることを保証します。

プロキシのスレッドセーフ

プロキシオブジェクトをロックで保護しない限り1つ以上のスレッドから使用してはいけません。

(違うプロセスで 同じ プロキシを使用することは問題ではありません。)

ゾンビプロセスを join する

Unix 上ではプロセスが終了したときに join しないと、そのプロセスはゾンビになります。新たなプロセスが開始する(又は active_children() が呼ばれる)ときに、 join されていない全ての完了プロセスが join されるので、あまり多くにはならないでしょう。また、終了したプロセスの Process.is_alive() はそのプロセスを join します。そうは言っても、自分で開始した全てのプロセスを明示的に join することはおそらく良いプラクティスです。

pickle/unpickle より継承する方が良い

Windows 上では multiprocessing の多くの型を子プロセスが使用するために pickle 化する必要があります。しかし、パイプやキューを使用する他のプロセスへ共有オブジェクトを送ることは一般的に避けるべきです。その代わり、どこかに作成された共有リソースへアクセスが必要なプロセスは他のプロセスから継承できるようにそのプログラムを修正すべきです。

プロセスを強制終了させることを避ける

あるプロセスを停止するために Process.terminate() メソッドを使用すると、そのプロセスが現在使用されている(ロック、セマフォ、パイプやキューのような)共有リソースを破壊したり他のプロセスから利用できない状態を引き起こし易いです。

そのため、共有リソースを使用しないプロセスでのみ Process.terminate() を使用するように考慮することがおそらく最善の方法です。

キューを使用するプロセスを join する

キューに要素を追加するプロセスは、全てのバッファされた要素が “feeder” スレッドによって下位層のパイプに対してフィードされるまで終了を待つということを覚えておいてください。 (子プロセスはこの動作を避けるためにキューの Queue.cancel_join_thread() メソッドを呼ぶことができます。)

これはキューを使用するときに、キューに追加された全ての要素が最終的にそのプロセスが join される前に削除されていることを確認する必要があることを意味します。そうしないと、そのキューに要素が追加したプロセスの終了を保証できません。デーモンではないプロセスは自動的に join されることも覚えておいてください。

次の例はデッドロックを引き起こします。

from multiprocessing import Process, Queue

def f(q):
    q.put('X' * 1000000)

if __name__ == '__main__':
    queue = Queue()
    p = Process(target=f, args=(queue,))
    p.start()
    p.join()                    # これはデッドロックします
    obj = queue.get()

修正するには最後の2行を入れ替えます(または単純に p.join() の行を削除します)。

明示的に子プロセスへリソースを渡す

Unix 上では子プロセスはグローバルなリソースを使用する親プロセスが作成した共有リソースを使用することができます。しかし、引数としてそのオブジェクトを子プロセスのコンストラクタへ渡す方が良いです。

(潜在的に) Windows 互換なコードを作成することは別として、さらにこれは子プロセスが生き続ける限り、そのオブジェクトは親プロセスでガベージコレクトされないことも保証します。これは親プロセスでそのオブジェクトがガベージコレクトされるときにリソースが開放される場合に重要になるでしょう。

そのため、例えば、

from multiprocessing import Process, Lock

def f():
    ... do something using "lock" ...

if __name__ == '__main__':
   lock = Lock()
   for i in range(10):
        Process(target=f).start()

次のように書き直すべきです。

from multiprocessing import Process, Lock

def f(l):
    ... do something using "l" ...

if __name__ == '__main__':
   lock = Lock()
   for i in range(10):
        Process(target=f, args=(lock,)).start()

sys.stdin をファイル形式のオブジェクトへ置き換えることに注意してください

muliprocessing は元々 muliprocessing.Process.__bootstrap() の中で無条件に

os.close(sys.stdin.fileno())

を呼び出していました — これはプロセス間で問題が起こしてしまいます。そこで、これは以下のように変更されました。

sys.stdin.close()
sys.stdin = open(os.devnull)

これによってプロセス間同士が衝突して bad file descripter エラーを起こすという基本的な問題は解決しました、しかし、アプリケーションの出力バッファーを sys.stdin() からファイル形式のオブジェクトに置き換えるという潜在的危険を持ち込みます。複数のプロセスがファイル形式オブジェクトの close() を呼び出した場合、オブジェクトに同じデータが何度もフラッシュされ、衝突が起きる危険があります。

もし、ファイル形式オブジェクトを書いて、独自のキャッシュ実装する場合、キャッシュする時に常に pid を記録しておく、 pid が変わったらキュッシュを捨てることでフォークセーフにできます。例:

@property
def cache(self):
    pid = os.getpid()
    if pid != self._pid:
        self._pid = pid
        self._cache = []
    return self._cache

より詳しい情報は issue 5155 [http://bugs.python.org/issue5155] 、 issue 5351 [http://bugs.python.org/issue5351] 、 issue 5331 [http://bugs.python.org/issue5331] を見てください。

16.6.3.2. Windows

Windows では os.fork() がないので幾つか追加制限があります。

さらなる pickle 機能

Process.__init__() へ渡す全ての引数は pickle 化できることを保証します。これは特に束縛、又は非束縛メソッドが Windows 上の target 引数として直接的に使用できないことを意味します。その代わり、まさに関数を定義してください。

また Process をサブクラス化する場合、そのインスタンスが Process.start() メソッドが呼ばれたときに pickle 化できることを保証します。

グローバル変数

子プロセスで実行されるコードがグローバル変数にアクセスしようとする場合、子プロセスが見るその値は Process.start() が呼ばれたときの親プロセスのその値と同じではない可能性があります。

しかし、単にモジュールレベルの定数であるグローバル変数なら問題にはなりません。

メインモジュールの安全なインポート

新たに Python インタプリタによって、意図しない副作用(新たなプロセスを開始する等) を起こさずにメインモジュールを安全にインポートできることを保証します。

例えば Windows で次のモジュールを実行しようとすると RuntimeError で失敗します。

from multiprocessing import Process

def foo():
    print 'hello'

p = Process(target=foo)
p.start()

代わりに、次のように if __name__ == '__main__': を使用してプログラムの “エントリポイント” を保護すべきです。

from multiprocessing import Process, freeze_support

def foo():
    print 'hello'

if __name__ == '__main__':
    freeze_support()
    p = Process(target=foo)
    p.start()

( freeze_support() 行はプログラムが固まらずに実行されるなら通常は取り除かれます。)

これは新たに生成された Python インタプリタがそのモジュールを安全にインポートして、モジュールの foo() 関数を実行します。

プール又はマネージャがメインモジュールで作成される場合に似たような制限が適用されます。

16.6.4. 例

カスタマイズされたマネージャやプロキシの作成方法と使用方法を紹介します。

#
# This module shows how to use arbitrary callables with a subclass of
# `BaseManager`.
#

from multiprocessing import freeze_support
from multiprocessing.managers import BaseManager, BaseProxy
import operator

##

class Foo(object):
    def f(self):
        print 'you called Foo.f()'
    def g(self):
        print 'you called Foo.g()'
    def _h(self):
        print 'you called Foo._h()'

# A simple generator function
def baz():
    for i in xrange(10):
        yield i*i

# Proxy type for generator objects
class GeneratorProxy(BaseProxy):
    _exposed_ = ('next', '__next__')
    def __iter__(self):
        return self
    def next(self):
        return self._callmethod('next')
    def __next__(self):
        return self._callmethod('__next__')

# Function to return the operator module
def get_operator_module():
    return operator

##

class MyManager(BaseManager):
    pass

# register the Foo class; make `f()` and `g()` accessible via proxy
MyManager.register('Foo1', Foo)

# register the Foo class; make `g()` and `_h()` accessible via proxy
MyManager.register('Foo2', Foo, exposed=('g', '_h'))

# register the generator function baz; use `GeneratorProxy` to make proxies
MyManager.register('baz', baz, proxytype=GeneratorProxy)

# register get_operator_module(); make public functions accessible via proxy
MyManager.register('operator', get_operator_module)

##

def test():
    manager = MyManager()
    manager.start()

    print '-' * 20

    f1 = manager.Foo1()
    f1.f()
    f1.g()
    assert not hasattr(f1, '_h')
    assert sorted(f1._exposed_) == sorted(['f', 'g'])

    print '-' * 20

    f2 = manager.Foo2()
    f2.g()
    f2._h()
    assert not hasattr(f2, 'f')
    assert sorted(f2._exposed_) == sorted(['g', '_h'])

    print '-' * 20

    it = manager.baz()
    for i in it:
        print '<%d>' % i,
    print

    print '-' * 20

    op = manager.operator()
    print 'op.add(23, 45) =', op.add(23, 45)
    print 'op.pow(2, 94) =', op.pow(2, 94)
    print 'op.getslice(range(10), 2, 6) =', op.getslice(range(10), 2, 6)
    print 'op.repeat(range(5), 3) =', op.repeat(range(5), 3)
    print 'op._exposed_ =', op._exposed_

##

if __name__ == '__main__':
    freeze_support()
    test()

Pool の使用例を紹介します。

#
# A test of `multiprocessing.Pool` class
#

import multiprocessing
import time
import random
import sys

#
# Functions used by test code
#

def calculate(func, args):
    result = func(*args)
    return '%s says that %s%s = %s' % (
        multiprocessing.current_process().name,
        func.__name__, args, result
        )

def calculatestar(args):
    return calculate(*args)

def mul(a, b):
    time.sleep(0.5*random.random())
    return a * b

def plus(a, b):
    time.sleep(0.5*random.random())
    return a + b

def f(x):
    return 1.0 / (x-5.0)

def pow3(x):
    return x**3

def noop(x):
    pass

#
# Test code
#

def test():
    print 'cpu_count() = %d\n' % multiprocessing.cpu_count()

    #
    # Create pool
    #

    PROCESSES = 4
    print 'Creating pool with %d processes\n' % PROCESSES
    pool = multiprocessing.Pool(PROCESSES)
    print 'pool = %s' % pool
    print

    #
    # Tests
    #

    TASKS = [(mul, (i, 7)) for i in range(10)] + \
            [(plus, (i, 8)) for i in range(10)]

    results = [pool.apply_async(calculate, t) for t in TASKS]
    imap_it = pool.imap(calculatestar, TASKS)
    imap_unordered_it = pool.imap_unordered(calculatestar, TASKS)

    print 'Ordered results using pool.apply_async():'
    for r in results:
        print '\t', r.get()
    print

    print 'Ordered results using pool.imap():'
    for x in imap_it:
        print '\t', x
    print

    print 'Unordered results using pool.imap_unordered():'
    for x in imap_unordered_it:
        print '\t', x
    print

    print 'Ordered results using pool.map() --- will block till complete:'
    for x in pool.map(calculatestar, TASKS):
        print '\t', x
    print

    #
    # Simple benchmarks
    #

    N = 100000
    print 'def pow3(x): return x**3'

    t = time.time()
    A = map(pow3, xrange(N))
    print '\tmap(pow3, xrange(%d)):\n\t\t%s seconds' % \
          (N, time.time() - t)

    t = time.time()
    B = pool.map(pow3, xrange(N))
    print '\tpool.map(pow3, xrange(%d)):\n\t\t%s seconds' % \
          (N, time.time() - t)

    t = time.time()
    C = list(pool.imap(pow3, xrange(N), chunksize=N//8))
    print '\tlist(pool.imap(pow3, xrange(%d), chunksize=%d)):\n\t\t%s' \
          ' seconds' % (N, N//8, time.time() - t)

    assert A == B == C, (len(A), len(B), len(C))
    print

    L = [None] * 1000000
    print 'def noop(x): pass'
    print 'L = [None] * 1000000'

    t = time.time()
    A = map(noop, L)
    print '\tmap(noop, L):\n\t\t%s seconds' % \
          (time.time() - t)

    t = time.time()
    B = pool.map(noop, L)
    print '\tpool.map(noop, L):\n\t\t%s seconds' % \
          (time.time() - t)

    t = time.time()
    C = list(pool.imap(noop, L, chunksize=len(L)//8))
    print '\tlist(pool.imap(noop, L, chunksize=%d)):\n\t\t%s seconds' % \
          (len(L)//8, time.time() - t)

    assert A == B == C, (len(A), len(B), len(C))
    print

    del A, B, C, L

    #
    # Test error handling
    #

    print 'Testing error handling:'

    try:
        print pool.apply(f, (5,))
    except ZeroDivisionError:
        print '\tGot ZeroDivisionError as expected from pool.apply()'
    else:
        raise AssertionError, 'expected ZeroDivisionError'

    try:
        print pool.map(f, range(10))
    except ZeroDivisionError:
        print '\tGot ZeroDivisionError as expected from pool.map()'
    else:
        raise AssertionError, 'expected ZeroDivisionError'

    try:
        print list(pool.imap(f, range(10)))
    except ZeroDivisionError:
        print '\tGot ZeroDivisionError as expected from list(pool.imap())'
    else:
        raise AssertionError, 'expected ZeroDivisionError'

    it = pool.imap(f, range(10))
    for i in range(10):
        try:
            x = it.next()
        except ZeroDivisionError:
            if i == 5:
                pass
        except StopIteration:
            break
        else:
            if i == 5:
                raise AssertionError, 'expected ZeroDivisionError'

    assert i == 9
    print '\tGot ZeroDivisionError as expected from IMapIterator.next()'
    print

    #
    # Testing timeouts
    #

    print 'Testing ApplyResult.get() with timeout:',
    res = pool.apply_async(calculate, TASKS[0])
    while 1:
        sys.stdout.flush()
        try:
            sys.stdout.write('\n\t%s' % res.get(0.02))
            break
        except multiprocessing.TimeoutError:
            sys.stdout.write('.')
    print
    print

    print 'Testing IMapIterator.next() with timeout:',
    it = pool.imap(calculatestar, TASKS)
    while 1:
        sys.stdout.flush()
        try:
            sys.stdout.write('\n\t%s' % it.next(0.02))
        except StopIteration:
            break
        except multiprocessing.TimeoutError:
            sys.stdout.write('.')
    print
    print

    #
    # Testing callback
    #

    print 'Testing callback:'

    A = []
    B = [56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

    r = pool.apply_async(mul, (7, 8), callback=A.append)
    r.wait()

    r = pool.map_async(pow3, range(10), callback=A.extend)
    r.wait()

    if A == B:
        print '\tcallbacks succeeded\n'
    else:
        print '\t*** callbacks failed\n\t\t%s != %s\n' % (A, B)

    #
    # Check there are no outstanding tasks
    #

    assert not pool._cache, 'cache = %r' % pool._cache

    #
    # Check close() methods
    #

    print 'Testing close():'

    for worker in pool._pool:
        assert worker.is_alive()

    result = pool.apply_async(time.sleep, [0.5])
    pool.close()
    pool.join()

    assert result.get() is None

    for worker in pool._pool:
        assert not worker.is_alive()

    print '\tclose() succeeded\n'

    #
    # Check terminate() method
    #

    print 'Testing terminate():'

    pool = multiprocessing.Pool(2)
    DELTA = 0.1
    ignore = pool.apply(pow3, [2])
    results = [pool.apply_async(time.sleep, [DELTA]) for i in range(100)]
    pool.terminate()
    pool.join()

    for worker in pool._pool:
        assert not worker.is_alive()

    print '\tterminate() succeeded\n'

    #
    # Check garbage collection
    #

    print 'Testing garbage collection:'

    pool = multiprocessing.Pool(2)
    DELTA = 0.1
    processes = pool._pool
    ignore = pool.apply(pow3, [2])
    results = [pool.apply_async(time.sleep, [DELTA]) for i in range(100)]

    results = pool = None

    time.sleep(DELTA * 2)

    for worker in processes:
        assert not worker.is_alive()

    print '\tgarbage collection succeeded\n'

if __name__ == '__main__':
    multiprocessing.freeze_support()

    assert len(sys.argv) in (1, 2)

    if len(sys.argv) == 1 or sys.argv[1] == 'processes':
        print ' Using processes '.center(79, '-')
    elif sys.argv[1] == 'threads':
        print ' Using threads '.center(79, '-')
        import multiprocessing.dummy as multiprocessing
    else:
        print 'Usage:\n\t%s [processes | threads]' % sys.argv[0]
        raise SystemExit(2)

    test()

ロック、コンディションやキューのような同期の例を紹介します。

#
# A test file for the `multiprocessing` package
#

import time, sys, random
from Queue import Empty

import multiprocessing               # may get overwritten

#### TEST_VALUE

def value_func(running, mutex):
    random.seed()
    time.sleep(random.random()*4)

    mutex.acquire()
    print '\n\t\t\t' + str(multiprocessing.current_process()) + ' has finished'
    running.value -= 1
    mutex.release()

def test_value():
    TASKS = 10
    running = multiprocessing.Value('i', TASKS)
    mutex = multiprocessing.Lock()

    for i in range(TASKS):
        p = multiprocessing.Process(target=value_func, args=(running, mutex))
        p.start()

    while running.value > 0:
        time.sleep(0.08)
        mutex.acquire()
        print running.value,
        sys.stdout.flush()
        mutex.release()

    print
    print 'No more running processes'

#### TEST_QUEUE

def queue_func(queue):
    for i in range(30):
        time.sleep(0.5 * random.random())
        queue.put(i*i)
    queue.put('STOP')

def test_queue():
    q = multiprocessing.Queue()

    p = multiprocessing.Process(target=queue_func, args=(q,))
    p.start()

    o = None
    while o != 'STOP':
        try:
            o = q.get(timeout=0.3)
            print o,
            sys.stdout.flush()
        except Empty:
            print 'TIMEOUT'

    print

#### TEST_CONDITION

def condition_func(cond):
    cond.acquire()
    print '\t' + str(cond)
    time.sleep(2)
    print '\tchild is notifying'
    print '\t' + str(cond)
    cond.notify()
    cond.release()

def test_condition():
    cond = multiprocessing.Condition()

    p = multiprocessing.Process(target=condition_func, args=(cond,))
    print cond

    cond.acquire()
    print cond
    cond.acquire()
    print cond

    p.start()

    print 'main is waiting'
    cond.wait()
    print 'main has woken up'

    print cond
    cond.release()
    print cond
    cond.release()

    p.join()
    print cond

#### TEST_SEMAPHORE

def semaphore_func(sema, mutex, running):
    sema.acquire()

    mutex.acquire()
    running.value += 1
    print running.value, 'tasks are running'
    mutex.release()

    random.seed()
    time.sleep(random.random()*2)

    mutex.acquire()
    running.value -= 1
    print '%s has finished' % multiprocessing.current_process()
    mutex.release()

    sema.release()

def test_semaphore():
    sema = multiprocessing.Semaphore(3)
    mutex = multiprocessing.RLock()
    running = multiprocessing.Value('i', 0)

    processes = [
        multiprocessing.Process(target=semaphore_func,
                                args=(sema, mutex, running))
        for i in range(10)
        ]

    for p in processes:
        p.start()

    for p in processes:
        p.join()

#### TEST_JOIN_TIMEOUT

def join_timeout_func():
    print '\tchild sleeping'
    time.sleep(5.5)
    print '\n\tchild terminating'

def test_join_timeout():
    p = multiprocessing.Process(target=join_timeout_func)
    p.start()

    print 'waiting for process to finish'

    while 1:
        p.join(timeout=1)
        if not p.is_alive():
            break
        print '.',
        sys.stdout.flush()

#### TEST_EVENT

def event_func(event):
    print '\t%r is waiting' % multiprocessing.current_process()
    event.wait()
    print '\t%r has woken up' % multiprocessing.current_process()

def test_event():
    event = multiprocessing.Event()

    processes = [multiprocessing.Process(target=event_func, args=(event,))
                 for i in range(5)]

    for p in processes:
        p.start()

    print 'main is sleeping'
    time.sleep(2)

    print 'main is setting event'
    event.set()

    for p in processes:
        p.join()

#### TEST_SHAREDVALUES

def sharedvalues_func(values, arrays, shared_values, shared_arrays):
    for i in range(len(values)):
        v = values[i][1]
        sv = shared_values[i].value
        assert v == sv

    for i in range(len(values)):
        a = arrays[i][1]
        sa = list(shared_arrays[i][:])
        assert a == sa

    print 'Tests passed'

def test_sharedvalues():
    values = [
        ('i', 10),
        ('h', -2),
        ('d', 1.25)
        ]
    arrays = [
        ('i', range(100)),
        ('d', [0.25 * i for i in range(100)]),
        ('H', range(1000))
        ]

    shared_values = [multiprocessing.Value(id, v) for id, v in values]
    shared_arrays = [multiprocessing.Array(id, a) for id, a in arrays]

    p = multiprocessing.Process(
        target=sharedvalues_func,
        args=(values, arrays, shared_values, shared_arrays)
        )
    p.start()
    p.join()

    assert p.exitcode == 0

####

def test(namespace=multiprocessing):
    global multiprocessing

    multiprocessing = namespace

    for func in [ test_value, test_queue, test_condition,
                  test_semaphore, test_join_timeout, test_event,
                  test_sharedvalues ]:

        print '\n\t######## %s\n' % func.__name__
        func()

    ignore = multiprocessing.active_children()      # cleanup any old processes
    if hasattr(multiprocessing, '_debug_info'):
        info = multiprocessing._debug_info()
        if info:
            print info
            raise ValueError, 'there should be no positive refcounts left'

if __name__ == '__main__':
    multiprocessing.freeze_support()

    assert len(sys.argv) in (1, 2)

    if len(sys.argv) == 1 or sys.argv[1] == 'processes':
        print ' Using processes '.center(79, '-')
        namespace = multiprocessing
    elif sys.argv[1] == 'manager':
        print ' Using processes and a manager '.center(79, '-')
        namespace = multiprocessing.Manager()
        namespace.Process = multiprocessing.Process
        namespace.current_process = multiprocessing.current_process
        namespace.active_children = multiprocessing.active_children
    elif sys.argv[1] == 'threads':
        print ' Using threads '.center(79, '-')
        import multiprocessing.dummy as namespace
    else:
        print 'Usage:\n\t%s [processes | manager | threads]' % sys.argv[0]
        raise SystemExit, 2

    test(namespace)

ワーカープロセスのコレクションに対するタスクをフィードするキューの使用方法とその結果をまとめる方法の例をを紹介します。

#
# Simple example which uses a pool of workers to carry out some tasks.
#
# Notice that the results will probably not come out of the output
# queue in the same in the same order as the corresponding tasks were
# put on the input queue.  If it is important to get the results back
# in the original order then consider using `Pool.map()` or
# `Pool.imap()` (which will save on the amount of code needed anyway).
#

import time
import random

from multiprocessing import Process, Queue, current_process, freeze_support

#
# Function run by worker processes
#

def worker(input, output):
    for func, args in iter(input.get, 'STOP'):
        result = calculate(func, args)
        output.put(result)

#
# Function used to calculate result
#

def calculate(func, args):
    result = func(*args)
    return '%s says that %s%s = %s' % \
        (current_process().name, func.__name__, args, result)

#
# Functions referenced by tasks
#

def mul(a, b):
    time.sleep(0.5*random.random())
    return a * b

def plus(a, b):
    time.sleep(0.5*random.random())
    return a + b

#
#
#

def test():
    NUMBER_OF_PROCESSES = 4
    TASKS1 = [(mul, (i, 7)) for i in range(20)]
    TASKS2 = [(plus, (i, 8)) for i in range(10)]

    # Create queues
    task_queue = Queue()
    done_queue = Queue()

    # Submit tasks
    for task in TASKS1:
        task_queue.put(task)

    # Start worker processes
    for i in range(NUMBER_OF_PROCESSES):
        Process(target=worker, args=(task_queue, done_queue)).start()

    # Get and print results
    print 'Unordered results:'
    for i in range(len(TASKS1)):
        print '\t', done_queue.get()

    # Add more tasks using `put()`
    for task in TASKS2:
        task_queue.put(task)

    # Get and print some more results
    for i in range(len(TASKS2)):
        print '\t', done_queue.get()

    # Tell child processes to stop
    for i in range(NUMBER_OF_PROCESSES):
        task_queue.put('STOP')

if __name__ == '__main__':
    freeze_support()
    test()

ワーカープロセスのプールが1つのソケットを共有してそれぞれの SimpleHTTPServer.HttpServer インスタンスを実行する方法の例を紹介します。

#
# Example where a pool of http servers share a single listening socket
#
# On Windows this module depends on the ability to pickle a socket
# object so that the worker processes can inherit a copy of the server
# object.  (We import `multiprocessing.reduction` to enable this pickling.)
#
# Not sure if we should synchronize access to `socket.accept()` method by
# using a process-shared lock -- does not seem to be necessary.
#

import os
import sys

from multiprocessing import Process, current_process, freeze_support
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

if sys.platform == 'win32':
    import multiprocessing.reduction    # make sockets pickable/inheritable

def note(format, *args):
    sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args))

class RequestHandler(SimpleHTTPRequestHandler):
    # we override log_message() to show which process is handling the request
    def log_message(self, format, *args):
        note(format, *args)

def serve_forever(server):
    note('starting server')
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass

def runpool(address, number_of_processes):
    # create a single server object -- children will each inherit a copy
    server = HTTPServer(address, RequestHandler)

    # create child processes to act as workers
    for i in range(number_of_processes-1):
        Process(target=serve_forever, args=(server,)).start()

    # main process also acts as a worker
    serve_forever(server)

def test():
    DIR = os.path.join(os.path.dirname(__file__), '..')
    ADDRESS = ('localhost', 8000)
    NUMBER_OF_PROCESSES = 4

    print 'Serving at http://%s:%d using %d worker processes' % \
          (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES)
    print 'To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32']

    os.chdir(DIR)
    runpool(ADDRESS, NUMBER_OF_PROCESSES)

if __name__ == '__main__':
    freeze_support()
    test()

multiprocessing と threading を比較した簡単なベンチマークです。

#
# Simple benchmarks for the multiprocessing package
#

import time, sys, multiprocessing, threading, Queue, gc

if sys.platform == 'win32':
    _timer = time.clock
else:
    _timer = time.time

delta = 1

#### TEST_QUEUESPEED

def queuespeed_func(q, c, iterations):
    a = '0' * 256
    c.acquire()
    c.notify()
    c.release()

    for i in xrange(iterations):
        q.put(a)

    q.put('STOP')

def test_queuespeed(Process, q, c):
    elapsed = 0
    iterations = 1

    while elapsed < delta:
        iterations *= 2

        p = Process(target=queuespeed_func, args=(q, c, iterations))
        c.acquire()
        p.start()
        c.wait()
        c.release()

        result = None
        t = _timer()

        while result != 'STOP':
            result = q.get()

        elapsed = _timer() - t

        p.join()

    print iterations, 'objects passed through the queue in', elapsed, 'seconds'
    print 'average number/sec:', iterations/elapsed

#### TEST_PIPESPEED

def pipe_func(c, cond, iterations):
    a = '0' * 256
    cond.acquire()
    cond.notify()
    cond.release()

    for i in xrange(iterations):
        c.send(a)

    c.send('STOP')

def test_pipespeed():
    c, d = multiprocessing.Pipe()
    cond = multiprocessing.Condition()
    elapsed = 0
    iterations = 1

    while elapsed < delta:
        iterations *= 2

        p = multiprocessing.Process(target=pipe_func,
                                    args=(d, cond, iterations))
        cond.acquire()
        p.start()
        cond.wait()
        cond.release()

        result = None
        t = _timer()

        while result != 'STOP':
            result = c.recv()

        elapsed = _timer() - t
        p.join()

    print iterations, 'objects passed through connection in',elapsed,'seconds'
    print 'average number/sec:', iterations/elapsed

#### TEST_SEQSPEED

def test_seqspeed(seq):
    elapsed = 0
    iterations = 1

    while elapsed < delta:
        iterations *= 2

        t = _timer()

        for i in xrange(iterations):
            a = seq[5]

        elapsed = _timer()-t

    print iterations, 'iterations in', elapsed, 'seconds'
    print 'average number/sec:', iterations/elapsed

#### TEST_LOCK

def test_lockspeed(l):
    elapsed = 0
    iterations = 1

    while elapsed < delta:
        iterations *= 2

        t = _timer()

        for i in xrange(iterations):
            l.acquire()
            l.release()

        elapsed = _timer()-t

    print iterations, 'iterations in', elapsed, 'seconds'
    print 'average number/sec:', iterations/elapsed

#### TEST_CONDITION

def conditionspeed_func(c, N):
    c.acquire()
    c.notify()

    for i in xrange(N):
        c.wait()
        c.notify()

    c.release()

def test_conditionspeed(Process, c):
    elapsed = 0
    iterations = 1

    while elapsed < delta:
        iterations *= 2

        c.acquire()
        p = Process(target=conditionspeed_func, args=(c, iterations))
        p.start()

        c.wait()

        t = _timer()

        for i in xrange(iterations):
            c.notify()
            c.wait()

        elapsed = _timer()-t

        c.release()
        p.join()

    print iterations * 2, 'waits in', elapsed, 'seconds'
    print 'average number/sec:', iterations * 2 / elapsed

####

def test():
    manager = multiprocessing.Manager()

    gc.disable()

    print '\n\t######## testing Queue.Queue\n'
    test_queuespeed(threading.Thread, Queue.Queue(),
                    threading.Condition())
    print '\n\t######## testing multiprocessing.Queue\n'
    test_queuespeed(multiprocessing.Process, multiprocessing.Queue(),
                    multiprocessing.Condition())
    print '\n\t######## testing Queue managed by server process\n'
    test_queuespeed(multiprocessing.Process, manager.Queue(),
                    manager.Condition())
    print '\n\t######## testing multiprocessing.Pipe\n'
    test_pipespeed()

    print

    print '\n\t######## testing list\n'
    test_seqspeed(range(10))
    print '\n\t######## testing list managed by server process\n'
    test_seqspeed(manager.list(range(10)))
    print '\n\t######## testing Array("i", ..., lock=False)\n'
    test_seqspeed(multiprocessing.Array('i', range(10), lock=False))
    print '\n\t######## testing Array("i", ..., lock=True)\n'
    test_seqspeed(multiprocessing.Array('i', range(10), lock=True))

    print

    print '\n\t######## testing threading.Lock\n'
    test_lockspeed(threading.Lock())
    print '\n\t######## testing threading.RLock\n'
    test_lockspeed(threading.RLock())
    print '\n\t######## testing multiprocessing.Lock\n'
    test_lockspeed(multiprocessing.Lock())
    print '\n\t######## testing multiprocessing.RLock\n'
    test_lockspeed(multiprocessing.RLock())
    print '\n\t######## testing lock managed by server process\n'
    test_lockspeed(manager.Lock())
    print '\n\t######## testing rlock managed by server process\n'
    test_lockspeed(manager.RLock())

    print

    print '\n\t######## testing threading.Condition\n'
    test_conditionspeed(threading.Thread, threading.Condition())
    print '\n\t######## testing multiprocessing.Condition\n'
    test_conditionspeed(multiprocessing.Process, multiprocessing.Condition())
    print '\n\t######## testing condition managed by a server process\n'
    test_conditionspeed(multiprocessing.Process, manager.Condition())

    gc.enable()

if __name__ == '__main__':
    multiprocessing.freeze_support()
    test()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.7. mmap — メモリマップファイル

メモリにマップされたファイルオブジェクトは、文字列とファイルオブジェクトの両方のように振舞います。しかし通常の文字列オブジェクトとは異なり、これらは可変です。文字列が期待されるほとんどの場所で mmap オブジェクトを利用できます。例えば、メモリマップファイルを探索するために re モジュールを使うことができます。それらは可変なので、 obj[index] = 'a' のように文字を変換できますし、スライスを使うことで obj[i1:i2] = '...' のように部分文字列を変換することができます。現在のファイル位置をデータの始めとする読込みや書込み、ファイルの異なる位置へ seek() することもできます。

メモリマップファイルは Unix 上と Windows 上とでは異なる mmap コンストラクタによって作られます。いずれの場合も、開いたファイルのファイル記述子を、更新のために提供しなければなりません。すでに存在する Python ファイルオブジェクトをマップしたい場合は、 fileno パラメータに渡す値を手に入れるために、 fileno() メソッドを使用して下さい。そうでなければ、ファイル記述子を直接返す os.open() 関数 (呼び出すときにはまだファイルが閉じている必要があります) を使って、ファイルを開くことができます。

Unix バージョンと Windows バージョンのどちらのコンストラクタについても、オプションのキーワード・パラメータとして access を指定することになるかもしれません。 access は3つの値の内の1つを受け入れます。 ACCESS_READ は読み込み専用、 ACCESS_WRITE は書き込み可能、 ACCESS_COPY はコピーした上での書き込みです。 access は Unix と Windows の両方で使用することができます。 access が指定されない場合、 Windows の mmap は書き込み可能マップを返します。 3つのアクセス型すべてに対する初期メモリ値は、指定されたファイルから得られます。 ACCESS_READ 型のメモリマップに対して書き込むと TypeError 例外を送出します。 ACCESS_WRITE 型のメモリマップへの書き込みはメモリと元のファイルの両方に影響を与えます。 ACCESS_COPY 型のメモリマップへの書き込みはメモリに影響を与えますが、元のファイルを更新することはありません。

バージョン 2.5 で変更: 無名メモリ(anonymous memory)にマップするためには fileno として -1 を渡し、length を与えてください。

バージョン 2.6 で変更: mmap.mmap はこれまで mmap オブジェクトを生成するファクトリ関数でした。これからは mmap.mmap がクラスそのものになります。

class mmap.mmap(fileno, length[, tagname[, access[, offset]]])

(Windows バージョン) ファイルハンドル fileno によって指定されたファイルから length バイトをマップして、 mmap オブジェクトを生成します。 length が現在のファイルサイズより大きな場合、ファイルサイズは length を含む大きさにまで拡張されます。 length が 0 の場合、マップの最大の長さは現在のファイルサイズになります。ただし、ファイル自体が空のときは Windows が例外を送出します (Windows では空のマップを作成することができません)。

tagname は、 None 以外で指定された場合、マップのタグ名を与える文字列となります。 Windows は同じファイルに対する様々なマップを持つことを可能にします。既存のタグの名前を指定すればそのタグがオープンされ、そうでなければこの名前の新しいタグが作成されます。もしこのパラメータを省略したり None を与えたりしたならば、マップは名前なしで作成されます。タグ・パラメータの使用の回避は、あなたのコードを Unix と Windows の間で移植可能にしておくのを助けてくれるでしょう。

offset は非負整数のオフセットとして指定できます。 mmap の参照はファイルの先頭からのオフセットに相対的になります。 offset のデフォルトは 0 です。 offset は ALLOCATIONGRANULARITY の倍数でなければなりません。

class mmap.mmap(fileno, length[, flags[, prot[, access[, offset]]]])

(Unix バージョン) ファイル記述子 fileno によって指定されたファイルから length バイトをマップし、 mmap オブジェクトを返します。 length が 0 の場合、マップの最大長は mmap が呼び出された時点のファイルサイズになります。

flags はマップの種類を指定します。 MAP_PRIVATE はプライベートな copy-on-write(書込み時コピー)のマップを作成します。従って、mmap オブジェクトの内容への変更はこのプロセス内にのみ有効です。 MAP_SHARED はファイルの同じ領域をマップする他のすべてのプロセスと共有されたマップを作成します。デフォルトは MAP_SHARED です。

prot が指定された場合、希望のメモリ保護を与えます。 2つの最も有用な値は、 PROT_READ と PROT_WRITE です。これは、読込み可能または書込み可能を指定するものです。 prot のデフォルトは PROT_READ | PROT_WRITE です。

access はオプションのキーワード・パラメータとして、 flags と prot の代わりに指定してもかまいません。 flags, prot と access の両方を指定することは間違っています。このパラメーターを使用法についての情報は、先に述べた access の記述を参照してください。

offset は非負整数のオフセットとして指定できます。 mmap の参照はファイルの先頭からのオフセットに相対的になります。 offset のデフォルトは 0 です。 offset は PAGESIZE または ALLOCATIONGRANULARITY の倍数でなければなりません。

Mac OS X と OpenVMS において、作成された memory mapping の正当性を確実にするために fileno で指定されたファイルディスクリプタは内部で自動的に物理的なストレージ (physical backing store) と同期されます。

以下の例は mmap の簡単な使い方です:

import mmap

# write a simple example file
with open("hello.txt", "wb") as f:
    f.write("Hello Python!\n")

with open("hello.txt", "r+b") as f:
    # memory-map the file, size 0 means whole file
    map = mmap.mmap(f.fileno(), 0)
    # read content via standard file methods
    print map.readline()  # prints "Hello Python!"
    # read content via slice notation
    print map[:5]  # prints "Hello"
    # update content using slice notation;
    # note that new content must have same size
    map[6:] = " world!\n"
    # ... and read again using standard file methods
    map.seek(0)
    print map.readline()  # prints "Hello  world!"
    # close the map
    map.close()

次の例では無名マップを作り親プロセスと子プロセスの間でデータのやりとりをしてみせます:

import mmap
import os

map = mmap.mmap(-1, 13)
map.write("Hello world!")

pid = os.fork()

if pid == 0: # In a child process
    map.seek(0)
    print map.readline()

    map.close()

メモリマップファイルオブジェクトは以下のメソッドをサポートしています:

mmap.close()

ファイルを閉じます。この呼出しの後にオブジェクトの他のメソッドの呼出すことは、例外の送出を引き起こすでしょう。

mmap.find(string[, start[, end]])

オブジェクト内の [start, end] の範囲に含まれている部分文字列 string が見つかった場所の最も小さいインデックスを返します。オプションの引数 start と end はスライスに使われるときのように解釈されます。失敗したときには -1 を返します。

mmap.flush([offset, size])

ファイルのメモリコピー内での変更をディスクへフラッシュします。この呼出しを使わなかった場合、オブジェクトが破壊される前に変更が書き込まれる保証はありません。もし offset と size が指定された場合、与えられたバイトの範囲の変更だけがディスクにフラッシュされます。指定されない場合、マップ全体がフラッシュされます。

(Windows バージョン) ゼロ以外の値が返されたら成功を、ゼロは失敗を意味します。

(Unix バージョン) ゼロの値が返されたら成功を意味します。呼び出しが失敗すると例外が送出されます。

mmap.move(dest, src, count)

オフセット src から始まる count バイトをインデックス dest の位置へコピーします。もし mmap が ACCESS_READ で作成されていた場合、 TypeError 例外を発生させます。

mmap.read(num)

現在のファイル位置から最大で num バイト分の文字列を返します。ファイル位置は返したバイトの分だけ後ろの位置へ更新されます。

mmap.read_byte()

現在のファイル位置から長さ1の文字列を返します。ファイル位置は1だけ進みます。

mmap.readline()

現在のファイル位置から次の改行までの、1行を返します。

mmap.resize(newsize)

マップと元ファイル(がもしあれば)のサイズを変更します。もし mmap が ACCESS_READ または ACCESS_COPY で作成されたならば、マップサイズの変更は TypeError 例外を発生させます。

mmap.rfind(string[, start[, end]])

オブジェクト内の [start, end] の範囲に含まれている部分文字列 string が見つかった場所の最も大きいインデックスを返します。オプションの引数 start と end はスライスに使われるときのように解釈されます。失敗したときには -1 を返します。

mmap.seek(pos[, whence])

ファイルの現在位置をセットします。 whence 引数はオプションであり、デフォルトは os.SEEK_SET つまり 0 (絶対位置)です。その他の値として、 os.SEEK_CUR つまり 1 (現在位置からの相対位置)と os.SEEK_END つまり 2 (ファイルの終わりからの相対位置)があります。

mmap.size()

ファイルの長さを返します。メモリマップ領域のサイズより大きいかもしれません。

mmap.tell()

ファイル・ポインタの現在位置を返します。

mmap.write(string)

メモリ内のファイル・ポインタの現在位置に string のバイト列を書き込みます。ファイル位置はバイト列が書き込まれた後の位置へ更新されます。もし mmap が ACCESS_READ で作成されていた場合、書き込み時に TypeError 例外を発生させるでしょう。

mmap.write_byte(byte)

メモリ内のファイル・ポインタの現在位置に単一文字の文字列 byte を書き込みます。ファイル位置は 1 だけ進みます。もし mmap が ACCESS_READ で作成されていた場合、書き込み時に TypeError 例外を発生させるでしょう。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.8. readline — GNU readline のインタフェース

readline モジュールでは、補完をしやすくしたり、ヒストリファイルを Python インタプリタから読み書きできるようにするためのいくつかの関数を定義しています。このモジュールは直接使うことも rlcompleter モジュールを介して使うこともできます。このモジュールで利用される設定はインタプリタの対話プロンプトの振舞い、組み込みの raw_input() と input() 関数の振舞いに影響します。

readline モジュールでは以下の関数を定義しています:

readline.parse_and_bind(string)

readline 初期化ファイルの行を一行解釈して実行します。

readline.get_line_buffer()

行編集バッファの現在の内容を返します。

readline.insert_text(string)

コマンドラインにテキストを挿入します。

readline.read_init_file([filename])

readline 初期化ファイルを解釈します。標準のファイル名設定は最後に使われたファイル名です。

readline.read_history_file([filename])

readline ヒストリファイルを読み出します。標準のファイル名設定は ~/.history です。

readline.write_history_file([filename])

readline ヒストリファイルを保存します。標準のファイル名設定は ~/.history です。

readline.clear_history()

現在のヒストリをクリアします。 (注意:インストールされている GNU readline がサポートしていない場合、この関数は利用できません)

バージョン 2.4 で追加.

readline.get_history_length()

ヒストリファイルに必要な長さを返します。負の値はヒストリファイルのサイズに制限がないことを示します。

readline.set_history_length(length)

ヒストリファイルに必要な長さを設定します。この値は write_history_file() がヒストリを保存する際にファイルを切り詰めるために使います。負の値はヒストリファイルのサイズを制限しないことを示します。

readline.get_current_history_length()

現在のヒストリ行数を返します(この値は get_history_length() で取得する異なります。 get_history_length() はヒストリファイルに書き出される最大行数を返します)。

バージョン 2.3 で追加.

readline.get_history_item(index)

現在のヒストリから、 index 番目の項目を返します。

バージョン 2.3 で追加.

readline.remove_history_item(pos)

ヒストリから指定した位置にあるヒストリを削除します。

バージョン 2.4 で追加.

readline.replace_history_item(pos, line)

指定した位置にあるヒストリを、指定した line で置き換えます。

バージョン 2.4 で追加.

readline.redisplay()

画面の表示を、現在のヒストリ内容によって更新します。

バージョン 2.3 で追加.

readline.set_startup_hook([function])

startup_hook 関数を設定または除去します。 function が指定されていれば、新たな startup_hook 関数として用いられます; 省略されるか None になっていれば、現在インストールされているフック関数は除去されます。 startup_hook 関数は readline が最初のプロンプトを出力する直前に引数なしで呼び出されます。

readline.set_pre_input_hook([function])

pre_input_hook 関数を設定または除去します。 function が指定されていれば、新たな pre_input_hook 関数として用いられます; 省略されるか None になっていれば、現在インストールされているフック関数は除去されます。 pre_input_hook 関数は readline が最初のプロンプトを出力した後で、かつ readline が入力された文字を読み込み始める直前に引数なしで呼び出されます。

readline.set_completer([function])

completer 関数を設定または除去します。 function が指定されていれば、新たな completer 関数として用いられます; 省略されるか None になっていれば、現在インストールされている completer 関数は除去されます。 completer 関数は function(text, state) の形式で、関数が文字列でない値を返すまで state を 0, 1, 2, ..., にして呼び出します。この関数は text から始まる文字列の補完結果として可能性のあるものを返さなくてはなりません。

readline.get_completer()

completer 関数を取得します。completer 関数が設定されていなければ None を返します。

バージョン 2.3 で追加.

readline.get_completion_type()

実行中の補完のタイプを取得します。

バージョン 2.6 で追加.

readline.get_begidx()

readline タブ補完スコープの先頭のインデクスを取得します。

readline.get_endidx()

readline タブ補完スコープの末尾のインデクスを取得します。

readline.set_completer_delims(string)

タブ補完のための readline 単語区切り文字を設定します。

readline.get_completer_delims()

タブ補完のための readline 単語区切り文字を取得します。

readline.set_completion_display_matches_hook([function])

補完表示関数を設定あるいは解除します。 function が指定された場合、それが新しい補完表示関数として利用されます。省略されたり、 None が渡された場合、既に設定されていた補完表示関数が解除されます。補完表示関数は、マッチの表示が必要になるたびに、 function(substitution, [matches], longest_match_length) という形で呼び出されます。

バージョン 2.6 で追加.

readline.add_history(line)

1 行をヒストリバッファに追加し、最後に打ち込まれた行のようにします。

参考

Module rlcompleter

対話的プロンプトで Python 識別子を補完する機能。

16.8.1. 例

以下の例では、ユーザのホームディレクトリにある .pyhist という名前のヒストリファイルを自動的に読み書きするために、 readline モジュールによるヒストリの読み書き関数をどのように使うかを例示しています。以下のソースコードは通常、対話セッションの中で PYTHONSTARTUP ファイルから読み込まれ自動的に実行されることになります。

import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".pyhist")
try:
    readline.read_history_file(histfile)
except IOError:
    pass
import atexit
atexit.register(readline.write_history_file, histfile)
del os, histfile

次の例では code.InteractiveConsole クラスを拡張し、ヒストリの保存・復旧をサポートします。

import code
import readline
import atexit
import os

class HistoryConsole(code.InteractiveConsole):
    def __init__(self, locals=None, filename="<console>",
                 histfile=os.path.expanduser("~/.console-history")):
        code.InteractiveConsole.__init__(self, locals, filename)
        self.init_history(histfile)

    def init_history(self, histfile):
        readline.parse_and_bind("tab: complete")
        if hasattr(readline, "read_history_file"):
            try:
                readline.read_history_file(histfile)
            except IOError:
                pass
            atexit.register(self.save_history, histfile)

    def save_history(self, histfile):
        readline.write_history_file(histfile)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

16. オプションのオペレーティングシステムサービス »

16.9. rlcompleter — GNU readline向け補完関数

rlcompleter モジュールではPythonの識別子やキーワードを定義した readline モジュール向けの補完関数を定義しています。

このモジュールが Unixプラットフォームでimportされ、 readline が利用できるときには、 Completer クラスのインスタンスが自動的に作成され、 complete() メソッドが readline 補完に設定されます。

使用例:

>>> import rlcompleter
>>> import readline
>>> readline.parse_and_bind("tab: complete")
>>> readline. <TAB PRESSED>
readline.__doc__          readline.get_line_buffer(  readline.read_init_file(
readline.__file__         readline.insert_text(      readline.set_completer(
readline.__name__         readline.parse_and_bind(
>>> readline.

rlcompleter モジュールは Pythonの対話モードで利用する為にデザインされています。ユーザは以下の命令を初期化ファイル (環境変数 PYTHONSTARTUP によって定義されます)に書き込むことで、 Tab キーによる補完を利用できます:

try:
    import readline
except ImportError:
    print "Module readline not available."
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")

readline のないプラットフォームでも、このモジュールで定義される Completer クラスは独自の目的に使えます。

16.9.1. Completerオブジェクト

Completerオブジェクトは以下のメソッドを持っています:

Completer.complete(text, state)

text の state 番目の補完候補を返します。

もし text がピリオド('.')を含まない場合、 __main__ 、 __builtin__ で定義されている名前か、キーワード ( keyword モジュールで定義されている) から補完されます。

ピリオドを含む名前の場合、副作用を出さずに名前を最後まで評価しようとします(関数を明示的に呼び出しはしませんが、 __getattr__() を呼んでしまうことはあります)そして、 dir() 関数でマッチする語を見つけます。式を評価中に発生した全ての例外は補足して無視され、 None を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク

この章で解説されるモジュールは他のプロセスと通信するメカニズムを提供します。

いくつかのモジュール、たとえば signal や subprocess は同じマシン上での2つのプロセス間でだけ動作します。他のモジュールはネットワークプロトコルをサポートし、2つかそれ以上のプロセスがマシンをまたいで通信するために利用できます。

この章で解説されるモジュールの一覧は:

17.1. subprocess — サブプロセス管理

17.1.1. subprocess モジュールを使う

17.1.1.1. 便利な関数

17.1.1.2. 例外

17.1.1.3. セキュリティ

17.1.2. Popen オブジェクト

17.1.3. Windows Popen ヘルパ

17.1.3.1. 定数

17.1.4. 古い関数を subprocess モジュールで置き換える

17.1.4.1. /bin/sh シェルのバッククォートを置き換える

17.1.4.2. シェルのパイプラインを置き換える

17.1.4.3. os.system() を置き換える

17.1.4.4. os.spawn 関数群を置き換える

17.1.4.5. os.popen(), os.popen2(), os.popen3() を置き換える

17.1.4.6. popen2 モジュールの関数群を置き換える

17.1.5. 注釈

17.1.5.1. Windows における引数シーケンスから文字列への変換

17.2. socket — 低レベルネットワークインターフェース

17.2.1. socket オブジェクト

17.2.2. 例

17.3. ssl — ソケットオブジェクトに対する TLS/SSL ラッパー

17.3.1. 関数、定数、例外

17.3.2. SSLSocket オブジェクト

17.3.3. 証明書

17.3.4. 例

17.3.4.1. SSLサポートをテストする

17.3.4.2. クライアントサイドの処理

17.3.4.3. サーバーサイドの処理

17.4. signal — 非同期イベントにハンドラを設定する

17.4.1. 例

17.5. popen2 — アクセス可能な I/O ストリームを持つ子プロセス生成

17.5.1. Popen3 および Popen4 オブジェクト

17.5.2. フロー制御の問題

17.6. asyncore — 非同期ソケットハンドラ

17.6.1. asyncoreの例：簡単なHTTPクライアント

17.6.2. 基本的な echo サーバーの例

17.7. asynchat — 非同期ソケットコマンド/レスポンスハンドラ

17.7.1. asynchat - 補助クラス

17.7.2. asynchat 使用例

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.1. subprocess — サブプロセス管理

バージョン 2.4 で追加.

subprocess モジュールは、新しくプロセスを開始したり、それらの標準入出力/エラー出力に対してパイプで接続したり、それらの終了ステータスを取得したりします。このモジュールは以下のような古いいくつかのモジュールを置き換えることを目的としています:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

これらのモジュールや関数の代わりに、 subprocess モジュールをどのように使うかについては以下の節で説明します。

参考

PEP 324 [http://www.python.org/dev/peps/pep-0324] – PEP proposing the subprocess module

17.1.1. subprocess モジュールを使う

このモジュールでは Popen と呼ばれるクラスを定義しています:

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

各引数の説明は以下のとおりです:

args は文字列か、あるいはプログラムへの引数のシーケンスです。実行するプログラムは通常 args シーケンスあるいは文字列の最初の要素ですが、 executable 引数を使うことにより明示的に指定することもできます。 executable が与えられると、その引数シーケンスの最初の要素は、多くのプログラムではコマンド名として扱われます。ただ、コマンド名は実際に実行される名前とは違う場合があります。 Unix では、コマンド名は ps のようなユーティリティプログラムに表示されます。

Unix で shell=False の場合 (デフォルト): この場合、 Popen クラスは子プログラムを実行するのに os.execvp() を使います。 文字列が引数として与えられた場合、実行されるプログラムの名前かパスとして使われます；ただし、プログラムは引数無しの場合のみ動作します。

ノート

args を正しくトークン化するには、 shlex.split() が便利です。このメソッドは特に複雑な状況で活躍します。

>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "ech '$MONEY"]
>>> p = subprocess.Popen(args) # Success!

シェルの中で (-input 、 eggs.txt のように) スペースで区切られたオプションと引数はリストの別の要素として区切られていること、シェルの中で (上にあるようなスペースを含むファイル名や echo コマンドのように) クォーティングかバックスラッシュエスケープが必要なものは単一のリスト要素にされていることに注目してください。

Unix で shell=True の場合: args が文字列の場合、シェルを介して実行されるコマンドライン文字列を指定します。文字列は厳密にシェルプロンプトで打つ形式と一致しなければなりません。例えば、文字列の中にスペースを含むファイル名がある場合、はクォーティングかバックスラッシュエスケープが必要です。 args が文字列の場合には最初の要素はコマンド名を表わす文字列としてそして残りの要素は続く引数としてシェルに渡されます。これは、以下の Popen と等価ということです。

Popen(['/bin/sh', '-c', args[0], args[1], ...])

警告

信頼されていないソースからの衛生化されていない入力を組み込んだシェルコマンドを実行すると、任意のコマンドを実行されることになるセキュリティ上の重大な欠陥 シェルインジェクション(en) [http://en.wikipedia.org/wiki/Shell_injection#Shell_injection] に対して脆弱になります。この理由から、コマンド文字列が外部入力から構成される場合、 shell=True は 絶対に使うべきではありません:

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False は、この脆弱性に悩まされません。上述のノートは、 shell=False を使ったコードを動かすのに役立つでしょう。

Windows の場合: Popen クラスは子プログラムを実行するのに文字列の扱える CreateProcess() を使います。 args がシーケンスの場合、これは Windows における引数シーケンスから文字列への変換 で解説する方法に従って、文字列に変換されます。

bufsize は、もしこれが与えられた場合、ビルトインの open() 関数の該当する引数と同じ意味をもちます: 0 はバッファされないことを意味し、 1 は行ごとにバッファされることを、それ以外の正の値は (ほぼ) その大きさのバッファが使われることを意味します。負の bufsize はシステムのデフォルト値が使われることを意味し、通常これはバッファがすべて有効となります。 bufsize のデフォルト値は 0 (バッファされない) です。

ノート

パフォーマンス上の問題がある場合、 bufsize を -1 か十分大きな正の値 (例えば 4096) に設定し、バッファを有効にすることを勧めます。

executable 引数には実行するプログラムを指定します。これはほとんど必要ありません: ふつう、実行するプログラムは args 引数で指定されるからです。 shell=True の場合、 executable 引数は使用するシェルを指定します。 Unix では、デフォルトのシェルは /bin/sh です。Windows では、デフォルトのシェルは COMSPEC 環境変数で指定されます。 Windows で shell=True を有効にする必要があるのは dir や copy などのシェル組み込みのコマンドを使いたい場合だけです。バッチファイルを実行するときも、コンソールベースで起動するときも、 shell=True にする必要はありません。

stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力のファイルハンドルをそれぞれ指定します。とりうる値は PIPE 、既存のファイル記述子 (正の整数)、既存のファイルオブジェクト、そして None です。 PIPE を指定すると新しいパイプが子プロセスに向けて作られます。 None を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。加えて、 stderr を STDOUT にすると、アプリケーションの stderr からの出力は stdout と同じファイルハンドルに出力されます。

preexec_fn に callable オブジェクトが指定されている場合、このオブジェクトは子プロセスが起動されてから、プログラムが exec される直前に呼ばれます。(Unixのみ) もしくは、Windowsで close_fds が真の場合、すべてのファイルハンドルは子プロセスに引き継がれません。 Windowsの場合、 close_fds を真にしながら、 stdin, stdout, stderr を利用して標準ハンドルをリダイレクトすることはできません。

close_fds が真の場合、子プロセスが実行される前に 0 、 1 および 2 をのぞくすべてのファイル記述子が閉じられます。(Unixのみ)

shell が True の場合、指定されたコマンドはシェルを介して実行されます。

cwd が None 以外の場合、子プロセスのカレントディレクトリが実行される前に cwd に変更されます。このディレクトリは実行ファイルを探す段階では考慮されませんので、プログラムのパスを cwd に対する相対パスで指定することはできない、ということに注意してください。

env が None 以外の場合、これは新しいプロセスでの環境変数を定義します。デフォルトでは、子プロセスは現在のプロセスの環境変数を引き継ぎます。

ノート

env を特定の値として与える場合、プログラムを実行するのに必要な変数全てを与えなければなりません。 Windows で side-by-side assembly [http://en.wikipedia.org/wiki/Side-by-Side_Assembly] を実行するためには、 env は正しい SystemRoot を 含まなければいけません 。

universal_newlines が True の場合、 stdout および stderr のファイルオブジェクトはテキストファイルとして open されますが、行の終端は Unix形式の行末 '\n' か、古い Macintosh 形式の行末 '\r' か、あるいは Windows 形式の行末 '\r\n' のいずれも許されます。これらすべての外部表現は Python プログラムには '\n' として認識されます。

ノート

この機能は Python に universal newline がサポートされている場合 (デフォルト) にのみ有効です。また、 stdout, stdin および stderr のファイルオブジェクトの newlines 属性は communicate() メソッドでは更新されません。

startupinfo は、根底の CreateProcess 関数に渡される STARTUPINFO オブジェクトになります。 creationflags は、与えられるなら、 CREATE_NEW_CONSOLE または CREATE_NEW_PROCESS_GROUP にできます。(Windows のみ)

subprocess.PIPE

Popen の stdin, stdout, stderr 引数に渡して、標準ストリームに対するパイプを開くことを指定するための特別な値.

subprocess.STDOUT

Popen の stderr 引数に渡して、標準エラーが標準出力と同じハンドルに出力されるように指定するための特別な値.

17.1.1.1. 便利な関数

このモジュールは以下の二つのショートカット関数も定義しています:

subprocess.call(*popenargs, **kwargs)

コマンドを指定された引数で実行し、そのコマンドが完了するのを待って、 returncode 属性を返します。

この引数は Popen コンストラクタの引数と同じです。使用例:

>>> retcode = call(["ls", "-l"])

警告

Popen.wait() のように、これは以下の場合にデッドロックになります。 stdout=PIPE および/または stderr=PIPE を使って、子プロセスが十分な出力を生成したのに、出力先が、OS パイプバッファがそれ以上のデータを受け付けるのを待っているような場合です。

subprocess.check_call(*popenargs, **kwargs)

コマンドを引数付きで実行します。コマンドが完了するのを待ちます。終了コードがゼロならば終わりますが、そうでなければ CalledProcessError 例外を送出します。 CalledProcessError オブジェクトにはリターンコードが returncode 属性として収められています。

引数は Popen コンストラクタと一緒です。使用例:

>>> subprocess.check_call(["ls", "-l"])
0

バージョン 2.5 で追加.

警告

call() の警告を参照してください。

subprocess.check_output(*popenargs, **kwargs)

引数でコマンドを実行し、その出力をバイト文字列として返します。

終了コードが非 0 なら、 CalledProcessError を送出します。 CalledProcessError オブジェクトは、戻りコードを returncode 属性に、出力を output 属性に保持します。

引数は、 Popen コンストラクタのものと同じです。例:

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

stdout 引数は内部で使われるため、許可されません。結果の標準エラーを捕捉するには、 stderr=subprocess.STDOUT を使ってください:

>>> subprocess.check_output(
...     ["/bin/sh", "-c", "ls non_existent_file; exit 0"],
...     stderr=subprocess.STDOUT)
'ls: non_existent_file: No such file or directory\n'

バージョン 2.7 で追加.

17.1.1.2. 例外

子プロセス内で raise した例外は、新しいプログラムが実行される前であれば、親プロセスでも raise されます。さらに、この例外オブジェクトには child_traceback という属性が追加されており、これには子プロセスの視点からの traceback 情報が格納されています。

もっとも一般的に起こる例外は OSError です。これは、たとえば存在しないファイルを実行しようとしたときなどに発生します。アプリケーションは OSError 例外にはあらかじめ準備しておく必要があります。

不適当な引数で Popen が呼ばれた場合は、 ValueError が発生します。

check_call() はもし呼び出されたプロセスがゼロでないリターンコードを返したならば CalledProcessError を送出します。

17.1.1.3. セキュリティ

ほかの popen 関数とは異なり、この実装は決して暗黙のうちに /bin/sh を実行しません。これはシェルのメタ文字をふくむすべての文字が安全に子プロセスに渡されるということを意味しています。

17.1.2. Popen オブジェクト

Popen クラスのインスタンスには、以下のようなメソッドがあります:

Popen.poll()

子プロセスが終了しているかどうかを検査します。 returncode 属性を設定し、返します。

Popen.wait()

子プロセスが終了するまで待ちます。 returncode 属性を設定し、返します。

警告

これは、子プロセスが十分な出力を生成したのに、出力先が、 OS パイプバッファがそれ以上のデータを受け付けるのを待っているような場合に、デッドロックになります。これを避けるために、 communicate() を利用してください。

Popen.communicate(input=None)

プロセスと通信します: end-of-file に到達するまでデータを stdin に送信し、stdout および stderr からデータを受信します。プロセスが終了するまで待ちます。オプション引数 input には子プロセスに送られる文字列か、あるいはデータを送らない場合は None を指定します。

communicate() はタプル (stdoutdata, stderrdata) を返します。

子プロセスの標準入力にデータを送りたい場合は、 Popen オブジェクトを stdin=PIPE と指定して作成しなければなりません。同じく、戻り値のタプルから None ではない値を取得するためには、 stdout=PIPE かつ/または stderr=PIPE を指定しなければなりません。

ノート

受信したデータはメモリ中にバッファされます。そのため、返されるデータが大きいかあるいは制限がないような場合はこのメソッドを使うべきではありません。

Popen.send_signal(signal)

signal シグナルを子プロセスに送ります。

ノート

Windows では、 SIGTERM は terminate() のエイリアスです。 CTRL_C_EVENT と CTRL_BREAK_EVENT を、 CREATE_NEW_PROCESS_GROUP を含む creationflags で始まった、プロセスに送れます。

バージョン 2.6 で追加.

Popen.terminate()

子プロセスを止めます。 Posix OSでは、このメソッドは SIGTERM シグナルを子プロセスに送ります。 Windows では、 Win32 API の TerminateProcess() 関数を利用して子プロセスを止めます。

バージョン 2.6 で追加.

Popen.kill()

子プロセスを殺します。 Posix OS では SIGKILL シグナルを子プロセスに送ります。 Windows では、 kill() は terminate() のエイリアスです。

バージョン 2.6 で追加.

以下の属性も利用できます:

警告

stdin.write(), stdout.read(), stderr.read() を利用すると、別のパイプのOSパイプバッファがいっぱいになってデッドロックする恐れがあります。これを避けるためには communicate() を利用してください。

Popen.stdin

stdin 引数が PIPE の場合、この属性には子プロセスの入力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.stdout

stdout 引数が PIPE の場合、この属性には子プロセスの出力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.stderr

stderr 引数が PIPE の場合、この属性には子プロセスのエラー出力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.pid

子プロセスのプロセス ID が入ります。

shell 引数を True にセットした場合は、生成されたシェルのプロセス ID になります。

Popen.returncode

poll() か wait() (か、間接的に communicate() )から設定された、子プロセスの終了ステータスが入ります。 None はまだその子プロセスが終了していないことを示します。

負の値 -N は子プロセスがシグナル N により中止させられたことを示します (Unix のみ)。

17.1.3. Windows Popen ヘルパ

STARTUPINFO クラスと以下の定数は、Windows でいつでも利用できます。

class subprocess.STARTUPINFO

Popen の生成に使われる Windows STARTUPINFO [http://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx] 構造の部分的なサポートです。

dwFlags

特定の STARTUPINFO のメンバが、プロセスがウィンドウを生成するときに使われるかを決定するビットフィールドです:

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW

hStdInput

dwFlags が STARTF_USESTDHANDLES を指定すれば、このメンバがプロセスの標準入力処理です。 STARTF_USESTDHANDLES が指定されなければ、標準入力のデフォルトはキーボードバッファです。

hStdOutput

dwFlags が STARTF_USESTDHANDLES を指定すれば、このメンバがプロセスの標準出力処理です。そうでなければ、このメンバは無視され、標準出力のデフォルトはコンソールウィンドウのバッファです。

hStdError

dwFlags が STARTF_USESTDHANDLES を指定すれば、このメンバがプロセスの標準エラー処理です。そうでなければ、このメンバは無視され、標準エラーのデフォルトはコンソールウィンドウのバッファです。

wShowWindow

dwFlags が STARTF_USESHOWWINDOW を指定すれば、このメンバは ShowWindow [http://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx] 関数の nCmdShow パラメタで指定された値なら、 SW_SHOWDEFAULT 以外の任意のものにできます。しかし、このメンバは無視されます。

この属性には SW_HIDE が提供されています。これは、 Popen が shell=True として呼び出されたときに使われます。

17.1.3.1. 定数

subprocess モジュールは、以下の定数を公開します。

subprocess.STD_INPUT_HANDLE

標準入力デバイスです。この初期値は、コンソール入力バッファ、 CONIN$ です。

subprocess.STD_OUTPUT_HANDLE

標準出力デバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.STD_ERROR_HANDLE

標準エラーデバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.SW_HIDE

ウィンドウを隠します。別のウィンドウが活性化します。

subprocess.STARTF_USESTDHANDLES

追加情報を保持する、 STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput, および STARTUPINFO.hStdError メンバを指定します。

subprocess.STARTF_USESHOWWINDOW

追加情報を保持する、 STARTUPINFO.wShowWindow メンバを指定します。

subprocess.CREATE_NEW_CONSOLE

新しいプロセスが、親プロセスのコンソールを継承する (デフォルト) のではなく、新しいコンソールを持ちます。

Popen が shell=True として生成されたとき、このフラグは必ず設定されます。

subprocess.CREATE_NEW_PROCESS_GROUP

新しいプロセスグループが生成されることを指定する Popen creationflags パラメタです。このフラグは、サブプロセスで os.kill() を使うのに必要です。

CREATE_NEW_CONSOLE が指定されていたら、このフラグは無視されます。

17.1.4. 古い関数を subprocess モジュールで置き換える

以下、この節では、”a ==> b” と書かれているものは a の代替として b が使えるということを表します。

ノート

この節で紹介されている関数はすべて、実行するプログラムが見つからないときは (いくぶん) 静かに終了します。このモジュールは OSError 例外を発生させます。

以下の例では、 subprocess モジュールは “from subprocess import *” でインポートされたと仮定しています。

17.1.4.1. /bin/sh シェルのバッククォートを置き換える

output=`mycmd myarg`
==>
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]

17.1.4.2. シェルのパイプラインを置き換える

output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

p2 を開始した後の p1.stdout.close() の呼び出しは、p1 が p2 の前に存在した場合に、p1 が SIGPIPE を受け取るために重要です。

17.1.4.3. os.system() を置き換える

sts = os.system("mycmd" + " myarg")
==>
p = Popen("mycmd" + " myarg", shell=True)
sts = os.waitpid(p.pid, 0)[1]

注意:

このプログラムは普通シェル経由で呼び出す必要はありません。

終了状態を見るよりも returncode 属性を見るほうが簡単です。

より現実的な例ではこうなるでしょう:

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print >>sys.stderr, "子プロセスがシグナルによって中止されました", -retcode
    else:
        print >>sys.stderr, "子プロセスが終了コードを返しました", retcode
except OSError, e:
    print >>sys.stderr, "実行に失敗しました:", e

17.1.4.4. os.spawn 関数群を置き換える

P_NOWAIT の例:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT の例:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

シーケンスを使った例:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

環境変数を使った例:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

17.1.4.5. os.popen(), os.popen2(), os.popen3() を置き換える

pipe = os.popen("cmd", 'r', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout

pipe = os.popen("cmd", 'w', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin

(child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)

(child_stdin,
 child_stdout,
 child_stderr) = os.popen3("cmd", mode, bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)

(child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode,
                                                   bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

Unix では、 os.popen2、os.popen3、os.popen4 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく直接渡されます。この使い方は以下のように置き換えられます。

(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
                                        bufsize)
==>
p = Popen(["/bin/ls", "-l"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE)
(child_stdin, child_stdout) = (p.stdin, p.stdout)

終了コードハンドリングは以下のように解釈します。

pipe = os.popen("cmd", 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print "There were some errors"
==>
process = Popen("cmd", 'w', shell=True, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print "There were some errors"

17.1.4.6. popen2 モジュールの関数群を置き換える

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen(["somestring"], shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

Unix では、 popen2 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく、直接渡されます。この使い方は、以下のように置き換えられます。

(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize,
                                            mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 および popen2.Popen4 は基本的には subprocess.Popen と同様です。ただし、違う点は:

Popen は実行できなかった場合に例外を発生させます。

capturestderr 引数は stderr 引数に代わりました。

stdin=PIPE および stdout=PIPE を指定する必要があります。

popen2 はデフォルトですべてのファイル記述子を閉じますが、 Popen では明示的に close_fds=True を指定する必要があります。

17.1.5. 注釈

17.1.5.1. Windows における引数シーケンスから文字列への変換

Windows では、 args シーケンスは以下の (MS C ランタイムで使われる規則に対応する) 規則を使って解析できる文字列に変換されます:

引数は、スペースかタブのどちらかの空白で分けられます。

ダブルクオーテーションマークで囲まれた文字列は、空白が含まれていたとしても 1 つの引数として解釈されます。クオートされた文字列は引数に埋め込めます。

バックスラッシュに続くダブルクオーテーションマークは、文字通りのダブルクオーテーションマークと解釈されます。

バックスラッシュは、ダブルクオーテーションが続かない限り、文字通りに解釈されます。

複数のバックスラッシュにダブルクオーテーションマークが続くなら、バックスラッシュ 2 つで 1 つのバックスラッシュ文字と解釈されます。バックスラッシュの数が奇数なら、最後のバックスラッシュは規則 3 に従って続くダブルクオーテーションマークをエスケープします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.2. socket — 低レベルネットワークインターフェース

このモジュールは、PythonでBSD ソケット(socket) インターフェースを利用するために使用します。最近のUnixシステム、Windows, Max OS X, BeOS, OS/2など、多くのプラットフォームで利用可能です。

ノート

いくつかの振る舞いはプラットフォームに依存します。オペレーティングシステムのソケットAPIを呼び出しているためです。

C言語によるソケットプログラミングの基礎については、以下の資料を参照してください。 An Introductory 4.3BSD Interprocess Communication Tutorial (Stuart Sechrest), An Advanced 4.3BSD Interprocess Communication Tutorial (Samuel J. Leffler他), UNIX Programmer’s Manual, Supplementary Documents 1(PS1:7章 PS1:8章)。ソケットの詳細については、各プラットフォームのソケット関連システムコールに関するドキュメント(Unix ではマニュアルページ、WindowsではWinSock(またはWinSock2)仕様書)も参照してください。 IPv6対応のAPIについては、 RFC 3493 [http://tools.ietf.org/html/rfc3493.html] “Basic Socket Interface Extensions for IPv6” を参照してください。

Pythonインターフェースは、Unixのソケット用システムコールとライブラリを、そのままPythonのオブジェクト指向スタイルに変換したものです。各種ソケット関連のシステムコールは、 socket() 関数で生成するソケットオブジェクト のメソッドとして実装されています。メソッドのパラメータはCのインターフェースよりも多少高水準で、例えば read() や write() メソッドではファイルオブジェクトと同様、受信時のバッファ確保や送信時の出力サイズなどは自動的に処理されます。

ソケットのアドレスは以下のように指定します:単一の文字列は、 AF_UNIX アドレスファミリを示します。 (host, port) のペアは AF_INET アドレスファミリを示し、 host は 'daring.cwi.nl' のようなインターネットドメイン形式または '100.50.200.5' のようなIPv4アドレスを文字列で、 port はポート番号を整数で指定します。 AF_INET6 アドレスファミリは (host, port, flowinfo, scopeid) の長さ4のタプルで示し、 flowinfo と scopeid にはそれぞれCの struct sockaddr_in6 における sin6_flowinfo と sin6_scope_id の値を指定します。後方互換性のため、 socket モジュールのメソッドでは sin6_flowinfo と sin6_scope_id を省略する事ができますが、 scopeid を省略するとスコープを持ったIPv6アドレスの処理で問題が発生する場合があります。現在サポートされているアドレスファミリは以上です。ソケットオブジェクトで利用する事のできるアドレス形式は、ソケットオブジェクトの作成時に指定したアドレスファミリで決まります。

IPv4アドレスのホストアドレスが空文字列の場合、 INADDR_ANY として処理されます。また、 '<broadcast>' の場合は INADDR_BROADCAST として処理されます。 IPv6では後方互換性のためこの機能は用意されていませんので、IPv6をサポートするPythonプログラムでは利用しないで下さい。

IPv4/v6ソケットの host 部にホスト名を指定すると、処理結果が一定ではない場合があります。これはPythonはDNSから取得したアドレスのうち最初のアドレスを使用するので、 DNSの処理やホストの設定によって異なるIPv4/6アドレスを取得する場合があるためです。常に同じ結果が必要であれば、 host に数値のアドレスを指定してください。

バージョン 2.5 で追加: AF_NETLINK ソケットが pid, groups のペアで表現されます.

バージョン 2.6 で追加: Linuxのみ、 AF_TIPC アドレスファミリを使って TIPC を利用することができます。 TIPCはオープンで、IPベースではないクラスターコンピューター環境向けのネットワークプロトコルです。アドレスはタプルで表現され、その中身はアドレスタイプに依存します。一般的なタプルの形は (addr_type, v1, v2, v3 [, scope]) で、

addr_type は TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, TIPC_ADDR_ID のうちのどれかです。

scope は TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, TIPC_NODE_SCOPE のうちのどれかです。

addr_type が TIPC_ADDR_NAME の場合、 v1 はサーバータイプ、 v2 はポートID (the port identifier)、そして v3 は 0 であるべきです。

addr_type が TIPC_ADDR_NAMESEQ の場合、 v1 はサーバータイプ、 v2 はポート番号下位(lower port number)、 v3 はポート番号上位(upper port number) です。

addr_type が TIPC_ADDR_ID の場合、 v1 はノード、 v2 は参照、 v3 は0であるべきです。

エラー時には例外が発生します。引数型のエラーやメモリ不足の場合には通常の例外が発生し、ソケットやアドレス関連のエラーの場合は socket.error が発生します。

setblocking() メソッドで、非ブロッキングモードを使用することができます。また、より汎用的に settimeout() メソッドでタイムアウトを指定する事ができます。

socket モジュールでは、以下の定数と関数を提供しています。

exception socket.error

この例外は、ソケット関連のエラーが発生した場合に送出されます。例外の値は障害の内容を示す文字列か、または os.error と同様な (errno, string) のペアとなります。オペレーティングシステムで定義されているエラーコードについては errno を参照してください。

バージョン 2.6 で変更: socket.error は IOError の子クラスになりました。

exception socket.herror

この例外は、C APIの gethostbyname_ex() や gethostbyaddr() などで、 h_errno のようなアドレス関連のエラーが発生した場合に送出されます。

例外の値は (h_errno, string) のペアで、ライブラリの呼び出し結果を返します。 string はC関数 hstrerror() で取得した、 h_errno の意味を示す文字列です。

exception socket.gaierror

この例外は getaddrinfo() と getnameinfo() でアドレス関連のエラーが発生した場合に送出されます。

例外の値は (error, string) のペアで、ライブラリの呼び出し結果を返します。 string はC関数 gai_strerror() で取得した、 h_errno の意味を示す文字列です。 error の値は、このモジュールで定義される EAI_* 定数の何れかとなります。

exception socket.timeout

この例外は、あらかじめ settimeout() を呼び出してタイムアウトを有効にしてあるソケットでタイムアウトが生じた際に送出されます。例外に付属する値は文字列で、その内容は現状では常に “timed out” となります。

バージョン 2.3 で追加.

socket.AF_UNIX

socket.AF_INET

socket.AF_INET6

アドレス（およびプロトコル）ファミリを示す定数で、 socket() の最初の引数に指定することができます。 AF_UNIX ファミリをサポートしないプラットフォームでは、 AF_UNIX は未定義となります。

socket.SOCK_STREAM

socket.SOCK_DGRAM

socket.SOCK_RAW

socket.SOCK_RDM

socket.SOCK_SEQPACKET

ソケットタイプを示す定数で、 socket() の2番目の引数に指定することができます。(ほとんどの場合、 SOCK_STREAM と SOCK_DGRAM 以外は必要ありません。)

SO_*

socket.SOMAXCONN

MSG_*

SOL_*

IPPROTO_*

IPPORT_*

INADDR_*

IP_*

IPV6_*

EAI_*

AI_*

NI_*

TCP_*

Unixのソケット・IPプロトコルのドキュメントで定義されている各種定数。ソケットオブジェクトの setsockopt() や getsockopt() で使用します。ほとんどのシンボルはUnixのヘッダファイルに従っています。一部のシンボルには、デフォルト値を定義してあります。

SIO_*

RCVALL_*

WindowsのWSAIoctl()のための定数です。この定数はソケットオブジェクトの ioctl() メソッドに引数として渡されます。

バージョン 2.6 で追加.

TIPC_*

TIPC関連の定数で、CのソケットAPIが公開しているものにマッチします。詳しい情報はTIPCのドキュメントを参照してください。

バージョン 2.6 で追加.

socket.has_ipv6

現在のプラットフォームでIPv6がサポートされているか否かを示す真偽値。

バージョン 2.3 で追加.

socket.create_connection(address[, timeout[, source_address]])

便利関数。 address ((host, port) の形のタプル) に接続してソケットオブジェクトを返します。オプションの timeout 引数を指定すると、接続を試みる前にソケットオブジェクトのタイムアウトを設定します。

source_address は接続する前にバインドするソースアドレスを指定するオプション引数で、指定する場合は (host, port) の2要素タプルでなければなりません。 host や port が ‘’ か 0 だった場合は、OSのデフォルトの動作になります。

バージョン 2.6 で追加.

バージョン 2.7 で変更: source_address が追加されました.

socket.getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0)

host / port 引数の指すアドレス情報を、そのサービスに接続されたソケットを作成するために必要な全ての引数が入った 5 要素のタプルに変換します。 host はドメイン名、IPv4/v6アドレスの文字列、または None です。 port は 'http' のようなサービス名文字列、ポート番号を表す数値、または None です。 host と port に None を指定すると C APIに NULL を渡せます。

オプションの family 、 socktype 、 proto 引数を指定すると、返されるアドレスのリストを絞り込むことができます。これらの引数の値として 0 を渡すと絞る込まない結果を返します。 flags 引数には AI_* 定数のうち 1 つ以上が指定でき、結果の取り方を変えることができます。例えば、 AI_NUMERICHOST を指定するとドメイン名解決を行わないようにし、 host がドメイン名だった場合には例外を送出します。

この関数は以下の構造をとる 5 要素のタプルのリストを返します:

(family, socktype, proto, canonname, sockaddr)

このタプルにある family, socktype, proto は、 socket() 関数を呼び出す際に指定する値と同じ整数です。 AI_CANONNAME を含んだ flags を指定した場合、 canonname は host の規準名(canonical name)を示す文字列です; そうでない場合は canonname は空文字列です。 sockaddr は、ソケットアドレスを family に依存した形式で表すタプルで、 ( AF_INET の場合は 2 要素のタプル (address, port) 、 AF_INET6 の場合は 4 要素のタプル (address, port, flow info, scope id) ) socket.connect() に渡すためのものです。

次の例では www.python.org の 80 番ポートポートへの TCP 接続を得るためのアドレス情報を取得しようとしています。 (結果は IPv6 をサポートしているかどうかで変わります):

>>> socket.getaddrinfo("www.python.org", 80, 0, 0, socket.SOL_TCP)
[(2, 1, 6, '', ('82.94.164.162', 80)),
 (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))]

バージョン 2.2 で追加.

socket.getfqdn([name])

name の完全修飾ドメイン名を返します。 name が空または省略された場合、ローカルホストを指定したとみなします。完全修飾ドメイン名の取得にはまず gethostbyaddr() でチェックし、次に可能であればエイリアスを調べ、名前にピリオドを含む最初の名前を値として返します。完全修飾ドメイン名を取得できない場合、 gethostname() で返されるホスト名を返します。

バージョン 2.0 で追加.

socket.gethostbyname(hostname)

ホスト名を '100.50.200.5' のようなIPv4形式のアドレスに変換します。ホスト名としてIPv4アドレスを指定した場合、その値は変換せずにそのまま返ります。 gethostbyname() APIへのより完全なインターフェースが必要であれば、 gethostbyname_ex() を参照してください。 gethostbyname() は、IPv6名前解決をサポートしていません。IPv4/ v6のデュアルスタックをサポートする場合は getaddrinfo() を使用します。

socket.gethostbyname_ex(hostname)

ホスト名から、IPv4形式の各種アドレス情報を取得します。戻り値は (hostname, aliaslist, ipaddrlist) のタプルで、 hostname は ip_address で指定したホストの正式名、 aliaslist は同じアドレスの別名のリスト(空の場合もある)、 ipaddrlist は同じホスト上の同一インターフェースのIPv4アドレスのリスト(ほとんどの場合は単一のアドレスのみ) を示します。 gethostbyname() は、IPv6名前解決をサポートしていません。IPv4/v6のデュアルスタックをサポートする場合は getaddrinfo() を使用します。

socket.gethostname()

Pythonインタープリタを現在実行中のマシンのホスト名を示す文字列を取得します。

実行中マシンのIPアドレスが必要であれば、 gethostbyname(gethostname()) を使用してください。この処理は実行中ホストのアドレス-ホスト名変換が可能であることを前提としていますが、常に変換可能であるとは限りません。

注意: gethostname() は完全修飾ドメイン名を返すとは限りません。完全修飾ドメイン名が必要であれば、 gethostbyaddr(gethostname()) としてください(下記参照)。

socket.gethostbyaddr(ip_address)

(hostname, aliaslist, ipaddrlist) のタプルを返し、 hostname は ip_address で指定したホストの正式名、 aliaslist は同じアドレスの別名のリスト(空の場合もある)、 ipaddrlist は同じホスト上の同一インターフェースのIPv4アドレスのリスト(ほとんどの場合は単一のアドレスのみ)を示します。完全修飾ドメイン名が必要であれば、 getfqdn() を使用してください。 gethostbyaddr() は、IPv4/IPv6の両方をサポートしています。

socket.getnameinfo(sockaddr, flags)

ソケットアドレス sockaddr から、 (host, port) のタプルを取得します。 flags の設定に従い、 host は完全修飾ドメイン名または数値形式アドレスとなります。同様に、 port は文字列のポート名または数値のポート番号となります。

バージョン 2.2 で追加.

socket.getprotobyname(protocolname)

'icmp' のようなインターネットプロトコル名を、 socket() の第三引数として指定する事ができる定数に変換します。これは主にソケットを” raw”モード(SOCK_RAW)でオープンする場合には必要ですが、通常のソケットモードでは第三引数に0を指定するか省略すれば正しいプロトコルが自動的に選択されます。

socket.getservbyname(servicename[, protocolname])

インターネットサービス名とプロトコルから、そのサービスのポート番号を取得します。省略可能なプロトコル名として、 'tcp' か 'udp' のどちらかを指定することができます。指定がなければどちらのプロトコルにもマッチします。

socket.getservbyport(port[, protocolname])

インターネットポート番号とプロトコル名から、サービス名を取得します。省略可能なプロトコル名として、 'tcp' か 'udp' のどちらかを指定することができます。指定がなければどちらのプロトコルにもマッチします。

socket.socket([family[, type[, proto]]])

アドレスファミリ、ソケットタイプ、プロトコル番号を指定してソケットを作成します。アドレスファミリには AF_INET (デフォルト値)・ AF_INET6 ・ AF_UNIX を指定することができます。ソケットタイプには SOCK_STREAM (デフォルト値)・ SOCK_DGRAM ・または他の SOCK_ 定数の何れかを指定します。プロトコル番号は通常省略するか、または0を指定します。

socket.socketpair([family[, type[, proto]]])

指定されたアドレスファミリ、ソケットタイプ、プロトコル番号から、接続されたソケットのペアを作成します。 アドレスファミリ、ソケットタイプ、プロトコル番号は socket() 関数と同様に指定します。デフォルトのアドレスファミリは、プラットフォームで定義されていれば AF_UNIX 、そうでなければ AF_INET が使われます。

利用可能: Unix.

バージョン 2.4 で追加.

socket.fromfd(fd, family, type[, proto])

ファイルディスクリプタ (ファイルオブジェクトの fileno() で返る整数) fd を複製して、ソケットオブジェクトを構築します。アドレスファミリとプロトコル番号は socket() と同様に指定します。ファイルディスクリプタはソケットを指していなければなりませんが、実際にソケットであるかどうかのチェックは行っていません。このため、ソケット以外のファイルディスクリプタを指定するとその後の処理が失敗する場合があります。この関数が必要な事はあまりありませんが、Unixのinetデーモンのようにソケットを標準入力や標準出力として使用するプログラムで使われます。この関数で使用するソケットは、ブロッキングモードと想定しています。利用可能:Unix

socket.ntohl(x)

32ビットの正の整数のバイトオーダを、ネットワークバイトオーダからホストバイトオーダに変換します。ホストバイトオーダとネットワークバイトオーダが一致するマシンでは、この関数は何もしません。それ以外の場合は4バイトのスワップを行います。

socket.ntohs(x)

16ビットの正の整数のバイトオーダを、ネットワークバイトオーダからホストバイトオーダに変換します。ホストバイトオーダとネットワークバイトオーダが一致するマシンでは、この関数は何もしません。それ以外の場合は2バイトのスワップを行います。

socket.htonl(x)

32ビットの正の整数のバイトオーダを、ホストバイトオーダからネットワークバイトオーダに変換します。ホストバイトオーダとネットワークバイトオーダが一致するマシンでは、この関数は何もしません。それ以外の場合は4バイトのスワップを行います。

socket.htons(x)

16ビットの正の整数のバイトオーダを、ホストバイトオーダからネットワークバイトオーダに変換します。ホストバイトオーダとネットワークバイトオーダが一致するマシンでは、この関数は何もしません。それ以外の場合は2バイトのスワップを行います。

socket.inet_aton(ip_string)

ドット記法によるIPv4アドレス('123.45.67.89' など)を32ビットにパックしたバイナリ形式に変換し、長さ4の文字列として返します。この関数が返す値は、標準Cライブラリの struct in_addr 型を使用する関数に渡す事ができます。

inet_aton() はドットが 3 個以下の文字列も受け取ります; 詳細については Unix のマニュアル inet(3) を参照してください。

IPv4アドレス文字列が不正であれば、 socket.error が発生します。このチェックは、この関数で使用しているCの実装 inet_aton() で行われます。

inet_aton() は、IPv6をサポートしません。IPv4/v6のデュアルスタックをサポートする場合は inet_pton() を使用します。

socket.inet_ntoa(packed_ip)

32ビットにパックしたバイナリ形式のIPv4アドレスを、ドット記法による文字列 ('123.45.67.89' など)に変換します。この関数が返す値は、標準Cライブラリの struct in_addr 型を使用する関数に渡す事ができます。

この関数に渡す文字列の長さが4バイト以外であれば、 socket.error が発生します。 inet_ntoa() は、IPv6をサポートしません。IPv4/v6のデュアルスタックをサポートする場合は inet_pton() を使用します。

socket.inet_pton(address_family, ip_string)

IPアドレスを、アドレスファミリ固有の文字列からパックしたバイナリ形式に変換します。 inet_pton() は、 struct in_addr 型 (inet_aton() と同様)や struct in6_addr を使用するライブラリやネットワークプロトコルを呼び出す際に使用することができます。

現在サポートされている address_family は、 AF_INET と AF_INET6 です。 ip_string に不正なIPアドレス文字列を指定すると、 socket.error が発生します。有効な ip_string は、 address_family と inet_pton() の実装によって異なります。

利用可能: Unix (サポートしていないプラットフォームもあります)

バージョン 2.3 で追加.

socket.inet_ntop(address_family, packed_ip)

パックしたIPアドレス(数文字の文字列)を、 '7.10.0.5' や '5aef:2b::8' などの標準的な、アドレスファミリ固有の文字列形式に変換します。 inet_ntop() は(inet_ntoa() と同様に) struct in_addr 型や struct in6_addr 型のオブジェクトを返すライブラリやネットワークプロトコル等で使用することができます。

現在サポートされている address_family は、 AF_INET と AF_INET6 です。 packed_ip の長さが指定したアドレスファミリで適切な長さでなければ、 ValueError が発生します。 inet_ntop() でエラーとなると、 socket.error が発生します。

利用可能: Unix (サポートしていないプラットフォームもあります)

バージョン 2.3 で追加.

socket.getdefaulttimeout()

新規に生成されたソケットオブジェクトの、デフォルトのタイムアウト値を浮動小数点形式の秒数で返します。タイプアウトを使用しない場合には None を返します。最初にsocketモジュールがインポートされた時の初期値は None です。

バージョン 2.3 で追加.

socket.setdefaulttimeout(timeout)

新規に生成されたソケットオブジェクトの、デフォルトのタイムアウト値を浮動小数点形式の秒数で指定します。タイムアウトを使用しない場合には None を指定します。最初にsocketモジュールがインポートされた時の初期値は None です。

バージョン 2.3 で追加.

socket.SocketType

ソケットオブジェクトの型を示す型オブジェクト。 type(socket(...)) と同じです。

参考

Module SocketServer

ネットワークサーバの開発を省力化するためのクラス群。

Module ssl

ソケットオブジェクトに対する TLS/SSL ラッパー.

17.2.1. socket オブジェクト

ソケットオブジェクトは以下のメソッドを持ちます。 makefile() 以外のメソッドは、Unixのソケット用システムコールに対応しています。

socket.accept()

接続を受け付けます。ソケットはアドレスにbind済みで、listen中である必要があります。戻り値は (conn, address) のペアで、 conn は接続を通じてデータの送受信を行うための 新しい ソケットオブジェクト、 address は接続先でソケットにbindしているアドレスを示します。

socket.bind(address)

ソケットを address にbindします。bind済みのソケットを再バインドする事はできません。 address のフォーマットはアドレスファミリによって異なります(前述)。

ノート

本来、このメソッドは単一のタプルのみを引数として受け付けますが、以前は AF_INET アドレスを示す二つの値を指定する事ができました。これは本来の仕様ではなく、Python 2.0以降では使用することはできません。

socket.close()

ソケットをクローズします。以降、このソケットでは全ての操作が失敗します。リモート端点ではキューに溜まったデータがフラッシュされた後はそれ以上のデータを受信しません。ソケットはガベージコレクション時に自動的にクローズされます。

ノート

close() は接続に関連付けられたリソースを開放しますが、接続をすぐに切断するとは限りません。接続を即座に切断したい場合は、 close() の前に shutdown() を呼び出してください。

socket.connect(address)

address で示されるリモートソケットに接続します。 address のフォーマットはアドレスファミリによって異なります(前述)。

ノート

本来、このメソッドは単一のタプルのみを引数として受け付けますが、以前は AF_INET アドレスを示す二つの値を指定する事ができました。これは本来の仕様ではなく、Python 2.0以降では使用することはできません。

socket.connect_ex(address)

connect(address) と同様ですが、C言語の connect() 関数の呼び出しでエラーが発生した場合には例外を送出せずにエラーを戻り値として返します。(これ以外の、”host not found,”等のエラーの場合には例外が発生します。)処理が正常に終了した場合には 0 を返し、エラー時には errno の値を返します。この関数は、非同期接続をサポートする場合などに使用することができます。

ノート

本来、このメソッドは単一のタプルのみを引数として受け付けますが、以前は AF_INET アドレスを示す二つの値を指定する事ができました。これは本来の仕様ではなく、Python 2.0以降では使用することはできません。

socket.fileno()

ソケットのファイルディスクリプタを整数型で返します。ファイルディスクリプタは、 select.select() などで使用します。

Windowsではこのメソッドで返された小整数をファイルディスクリプタを扱う箇所(os.fdopen() など)で利用できません。 Unix にはこの制限はありません。

socket.getpeername()

ソケットが接続しているリモートアドレスを返します。この関数は、リモート IPv4/v6ソケットのポート番号を調べる場合などに使用します。 address のフォーマットはアドレスファミリによって異なります(前述)。この関数をサポートしていないシステムも存在します。

socket.getsockname()

ソケット自身のアドレスを返します。この関数は、IPv4/v6ソケットのポート番号を調べる場合などに使用します。 address のフォーマットはアドレスファミリによって異なります(前述)。

socket.getsockopt(level, optname[, buflen])

ソケットに指定されたオプションを返します(Unixのマニュアルページ getsockopt(2) を参照)。 SO_* 等のシンボルは、このモジュールで定義しています。 buflen を省略した場合、取得するオブションは整数とみなし、整数型の値を戻り値とします。 buflen を指定した場合、長さ buflen のバッファでオプションを受け取り、このバッファを文字列として返します。このバッファは、呼び出し元プログラムで struct モジュール等を利用して内容を読み取ることができます。

socket.ioctl(control, option)

Platform :
Windows

ioctl() メソッドは WSAIoctl システムインタフェースへの制限されたインタフェースです。詳しい情報については、 Win32 documentation [http://msdn.microsoft.com/en-us/library/ms741621%28VS.85%29.aspx] を参照してください。

他のプラットフォームでは一般的な fcntl.fcntl() と fcntl.ioctl() が使われるでしょう; これらの関数は第 1 引数としてソケットオブジェクトを取ります。

バージョン 2.6 で追加.

socket.listen(backlog)

ソケットをListenし、接続を待ちます。引数 backlog には接続キューの最大の長さ(0以上)を指定します。 backlog の最大数はシステムに依存します (通常は5)。最小値は必ず 0 です。

socket.makefile([mode[, bufsize]])

ソケットに関連付けられた ファイルオブジェクト を返します (ファイルオブジェクトについては ファイルオブジェクト を参照)。ファイルオブジェクトはソケットを dup() したファイルディスクリプタを使用しており、ソケットオブジェクトとファイルオブジェクトは別々にクローズしたりガベージコレクションで破棄したりする事ができます。ソケットはブロッキングモードでなければなりません(タイムアウトを設定することもできません)。オプション引数の mode と bufsize には、 file() 組み込み関数と同じ値を指定します。

ノート

Windows では、 makefile() によって作成される file-like オブジェクトは、 subprocess.Popen() などのファイルディスクリプタのある file オブジェクトを期待している場所で利用することはできません。

socket.recv(bufsize[, flags])

ソケットからデータを受信し、文字列として返します。受信する最大バイト数は、 bufsize で指定します。 flags のデフォルト値は0です。値の意味についてはUnixマニュアルページの recv(2) を参照してください。

ノート

ハードウェアおよびネットワークの現実に最大限マッチするように、 bufsize の値は比較的小さい2の累乗、たとえば 4096、にすべきです。

socket.recvfrom(bufsize[, flags])

ソケットからデータを受信し、結果をタプル (string, address) として返します。 string は受信データの文字列で、 address は送信元のアドレスを示します。オプション引数 flags については、 Unix のマニュアルページ recv(2) を参照してください。デフォルトは0です。 (address のフォーマットはアドレスファミリによって異なります(前述))

socket.recvfrom_into(buffer[, nbytes[, flags]])

ソケットからデータを受信し、そのデータを新しい文字列として返す代わりに buffer に書きます。戻り値は (nbytes, address) のペアで、 nbytes は受信したデータのバイト数を、 address はデータを送信したソケットのアドレスです。オプション引数 flags (デフォルト:0) の意味については、 Unix マニュアルページ recv(2) を参照してください。

(address のフォーマットは前述のとおりアドレスファミリーに依存します。)

バージョン 2.5 で追加.

socket.recv_into(buffer[, nbytes[, flags]])

nbytes バイトまでのデータをソケットから受信して、そのデータを新しい文字列にするのではなく buffer に保存します。 nbytes が指定されない(あるいは0が指定された)場合、 buffer の利用可能なサイズまで受信します。受信したバイト数を返り値として返します。オプション引数 flags (デフォルト:0) の意味については、 Unix マニュアルページ recv(2) を参照してください。

バージョン 2.5 で追加.

socket.send(string[, flags])

ソケットにデータを送信します。ソケットはリモートソケットに接続済みでなければなりません。オプション引数 flags の意味は、上記 recv() と同じです。戻り値として、送信したバイト数を返します。アプリケーションでは、必ず戻り値をチェックし、全てのデータが送られた事を確認する必要があります。データの一部だけが送信された場合、アプリケーションで残りのデータを再送信してください。

socket.sendall(string[, flags])

ソケットにデータを送信します。ソケットはリモートソケットに接続済みでなければなりません。オプション引数 flags の意味は、上記 recv() と同じです。 send() と異なり、このメソッドは string の全データを送信するか、エラーが発生するまで処理を継続します。正常終了の場合は None を返し、エラー発生時には例外が発生します。エラー発生時、送信されたバイト数を調べる事はできません。

socket.sendto(string[, flags], address)

ソケットにデータを送信します。このメソッドでは接続先を address で指定するので、接続済みではいけません。オプション引数 flags の意味は、上記 recv() と同じです。戻り値として、送信したバイト数を返します。 address のフォーマットはアドレスファミリによって異なります(前述)。

socket.setblocking(flag)

ソケットのブロッキング・非ブロッキングモードを指定します。 flag が0 の場合は非ブロッキングモード、0以外の場合はブロッキングモードとなります。全てのソケットは、初期状態ではブロッキングモードです。非ブロッキングモードでは、 recv() メソッド呼び出し時に読み込みデータが無かったり send() メソッド呼び出し時にデータを処理する事ができないような場合に error 例外が発生します。しかし、ブロッキングモードでは呼び出しは処理が行われるまでブロックされます。 s.setblocking(0) は s.settimeout(0.0) と、 s.setblocking(1) は s.settimeout(None) とそれぞれ同じ意味を持ちます。

socket.settimeout(value)

ソケットのブロッキング処理のタイムアウト値を指定します。 value には、正の浮動小数点で秒数を指定するか、もしくは None を指定します。浮動小数点値を指定した場合、操作が完了する前に value で指定した秒数が経過すると timeout が発生します。タイムアウト値に None を指定すると、ソケットのタイムアウトを無効にします。 s.settimeout(0.0) は s.setblocking(0) と、 s.settimeout(None) は s.setblocking(1) とそれぞれ同じ意味を持ちます。

バージョン 2.3 で追加.

socket.gettimeout()

ソケットに指定されたタイムアウト値を取得します。タイムアウト値が設定されている場合には浮動小数点型で秒数が、設定されていなければ None が返ります。この値は、最後に呼び出された setblocking() または settimeout() によって設定されます。

バージョン 2.3 で追加.

ソケットのブロッキングとタイムアウトについて: ソケットオブジェクトのモードは、ブロッキング・非ブロッキング・タイムアウトの何れかとなります。初期状態では常にブロッキングモードです。ブロッキングモードでは、処理が完了するまで、もしくはシステムが (接続タイムアウトなどの) エラーを返すまでブロックされます。非ブロッキングモードでは、処理を行う事ができなければ(不幸にもシステムによって異なる値の)エラーとなります。タイムアウトモードでは、ソケットに指定したタイムアウトまで、もしくはシステムがエラーを返すまでに完了しなければ処理は失敗となります。 setblocking() メソッドは、 settimeout() の省略形式です。

内部的には、タイムアウトモードではソケットを非ブロッキングモードに設定します。ブロッキングとタイムアウトの設定は、ソケットと同じネットワーク端点へ接続するファイルディスクリプタにも反映されます。この結果、 makefile() で作成したファイルオブジェクトはブロッキングモードでのみ使用することができます。これは非ブロッキングモードとタイムアウトモードでは、即座に完了しないファイル操作はエラーとなるためです。

註: connect() はタイムアウト設定に従います。一般的に、 settimeout() を connect() の前に呼ぶかタイムアウト値を create_connection() に渡すことをおすすめします。システムのネットワークスタックは Python のソケットタイムアウトの設定を無視して、自身のコネクションタイムアウトエラーを返すこともあります。

socket.setsockopt(level, optname, value)

ソケットのオプションを設定します(Unixのマニュアルページ setsockopt(2) を参照)。 SO_* 等のシンボルは、このモジュールで定義しています。 value には、整数または文字列をバッファとして指定する事ができます。文字列を指定する場合、文字列には適切なビットを設定するようにします。(struct モジュールを利用すれば、Cの構造体を文字列にエンコードする事ができます。)

socket.shutdown(how)

接続の片方向、または両方向を切断します。 how が SHUT_RD の場合、以降は受信を行えません。 how が SHUT_WR の場合、以降は送信を行えません。 how が SHUT_RDWR の場合、以降は送受信を行えません。プラットフォームによっては、接続の片方向をシャットダウンすると相手側も閉じられます。(例えば、 Mac OS X では、 shutdown(SHUT_WR) をすると、接続の相手側はもう read ができなくなります)

read() メソッドと write() メソッドは存在しませんので注意してください。代わりに flags を省略した recv() と send() を使うことができます。

ソケットオブジェクトには以下の socket コンストラクタに渡された値に対応した(読み出し専用)属性があります。

socket.family

ソケットファミリー。

バージョン 2.5 で追加.

socket.type

ソケットタイプ。

バージョン 2.5 で追加.

socket.proto

ソケットプロトコル。

バージョン 2.5 で追加.

17.2.2. 例

以下はTCP/IPプロトコルの簡単なサンプルとして、受信したデータをクライアントにそのまま返送するサーバ(接続可能なクライアントは一件のみ)と、サーバに接続するクライアントの例を示します。サーバでは、 socket() ・ bind() ・ listen() ・ accept() を実行し(複数のクライアントからの接続を受け付ける場合、 accept() を複数回呼び出します)、クライアントでは socket() と connect() だけを呼び出しています。サーバでは send() / recv() メソッドはlisten中のソケットで実行するのではなく、 accept() で取得したソケットに対して実行している点にも注意してください。

次のクライアントとサーバは、IPv4のみをサポートしています。

# Echo server program
import socket

HOST = None                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

次のサンプルは上記のサンプルとほとんど同じですが、IPv4とIPv6の両方をサポートしています。サーバでは、IPv4/v6の両方ではなく、利用可能な最初のアドレスファミリだけをlistenしています。ほとんどのIPv6対応システムではIPv6が先に現れるため、サーバはIPv4には応答しません。クライアントでは名前解決の結果として取得したアドレスに順次接続を試み、最初に接続に成功したソケットにデータを送信しています。

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
       s = socket.socket(af, socktype, proto)
    except socket.error, msg:
       s = None
       continue
    try:
       s.bind(sa)
       s.listen(1)
    except socket.error, msg:
       s.close()
       s = None
       continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()

# Echo client program
import socket
import sys

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
       s = socket.socket(af, socktype, proto)
    except socket.error, msg:
       s = None
       continue
    try:
       s.connect(sa)
    except socket.error, msg:
       s.close()
       s = None
       continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.send('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

最後の例は、Windowsで raw socket を利用して非常にシンプルなネットワークスニファーを書きます。このサンプルを実行するには、インタフェースを操作するための管理者権限が必要です。

import socket

# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# receive a package
print s.recvfrom(65565)

# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.3. ssl — ソケットオブジェクトに対する TLS/SSL ラッパー

バージョン 2.6 で追加.

このモジュールは Transport Layer Security (よく “Secure Sockets Layer” という名前で知られています) 暗号化と、クライアントサイド、サーバーサイド両方のネットワークソケットのためのピア認証の仕組みを提供しています。このモジュールはOpenSSLライブラリを利用しています。 OpenSSLは、全てのモダンなUnixシステム、Windows、Mac OS X、その他幾つかの OpenSSLがインストールされているプラットフォームで利用できます。

ノート

OSのソケットAPIに対して実装されているので、幾つかの挙動はプラットフォーム依存になるかもしれません。インストールされているOpenSSLのバージョンの違いも挙動の違いの原因になるかもしれません。

このセクションでは、 ssl モジュールのオブジェクトと関数の解説します。 TLS, SSL, certificates に関するより一般的な情報は、末尾にある “See Also” のセクションを参照してください。

このモジュールは1つのクラス、 ssl.SSLSocket を提供します。このクラスは socket.socket クラスを継承していて、ソケットで通信されるデータをSSLで暗号化・復号するソケットに似たラッパーになります。また、このクラスは追加で、 read() と write() メソッド、接続の相手側からの証明書を取得する getpeercert() メソッド、セキュア接続で使うための暗号方式を取得する cipher() メソッドをサポートしています。

17.3.1. 関数、定数、例外

exception ssl.SSLError

下層のSSL実装からのエラーを伝えるための例外です。このエラーは、低レベルなネットワークの上に載っている、高レベルな暗号化と認証レイヤーでの問題を通知します。このエラーは socket.error のサブタイプで、 socket.error は IOError のサブタイプです。

ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None)

socket.socket のインスタンス sock を受け取り、 socket.socket のサブタイプである ssl.SSLSocket のインスタンスを返します。 ssl.SSLSocket は低レイヤのソケットをSSLコンテキストでラップします。クライアントサイドソケットにおいて、コンテキストの生成は遅延されます。つまり、低レイヤのソケットがまだ接続されていない場合、コンテキストの生成はそのソケットの connect() メソッドが呼ばれた後に行われます。サーバーサイドソケットの場合、そのソケットに接続先が居なければそれは listen 用ソケットだと判断されます。 accept() メソッドで生成されるクライアント接続に対してのサーバーサイド SSLラップは自動的に行われます。そのクライアント接続に対して wrap_socket() を実行すると SSLError が発生します。

オプションの keyfile と certfile 引数は、接続のこちら側を識別するために利用される証明書を含むファイルを指定します。証明書がどのように certfile に格納されるかについてのより詳しい情報は、 証明書を参照してください。

多くの場合、証明書と同じファイルに秘密鍵も格納されています。この場合、 certfile 引数だけが必要とされます。秘密鍵が証明書と別のファイルに格納されている場合、両方の引数を指定しなければなりません。秘密鍵が certfile に格納されている場合、秘密鍵は証明書チェインの最初の証明書よりも先にないといけません。

-----BEGIN RSA PRIVATE KEY-----
... (private key in base64 encoding) ...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

server_side 引数は真偽値で、このソケットがサーバーサイドとクライアントサイドのどちらの動作をするのかを指定します。

cert_reqs 引数は、接続の相手側からの証明書を必要とするかどうかと、それを検証(validate)するかどうかを指定します。これは次の3つの定数のどれかで無ければなりません: CERT_NONE (証明書は無視されます), CERT_OPTIONAL (必要としないが、提供された場合は検証する), CERT_REQUIRED (証明書を必要とし、検証する)。もしこの引数が CERT_NONE 以外だった場合、 ca_certs 引数はCA証明書ファイルを指定していなければなりません。

ca_certs ファイルは、接続の相手側から渡された証明書を検証するために使う、一連のCA証明書を結合したものを含んでいます。このファイル内にどう証明書を並べるかについての詳しい情報は 証明書を参照してください。

ssl_version 引数は、使用するSSLプロトコルのバージョンを指定します。通常、サーバー側が特定のプロトコルバージョンを選び、クライアント側はサーバーの選んだプロトコルを受け入れなければなりません。ほとんどのバージョンは他のバージョンと互換性がありません。もしこの引数が指定されなかった場合、クライアントサイドでは、デフォルトの SSLバージョンは SSLv3 になります。サーバーサイドでは SSLv23 です。これらのバージョンは、できるだけの互換性を確保するように選ばれています。

次のテーブルは、どのクライアント側のバージョンがどのサーバー側のバージョンに接続できるかを示しています。

client / server | SSLv2 | SSLv3 | SSLv23 | TLSv1
SSLv2 | yes | no | yes | no
SSLv3 | yes | yes | yes | no
SSLv23 | yes | no | yes | no
TLSv1 | no | no | yes | yes

ノート

どの接続が成功するかは、 OpenSSL のバージョンに依存して大きく変わります。例えば、いくつか古めのバージョンの OpenSSL (OS X 10.4 の 0.9.7l など) では、 SSLv2 クライアントは SSLv23 サーバーに接続できませんでした。また、 OpenSSL 1.0.0 の初期では、 SSLv23 クライアントは明示的に SSLv2 cipher を有効にしない限りは SSLv2 接続を試みずませんでした。このバージョンで SSLv2 を有効にするには、 ciphers 引数に "ALL" か "SSLv2" を指定することができます。

ciphers 引数はこの SSL オブジェクトで利用可能な cipher を指定します。これは、 OpenSSL cipher list format [http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT] にある文字列のどれかでなければなりません。

do_handshake_on_connect 引数は、 socket.connect() の後に自動的に SSLハンドシェイクを行うか、それともアプリケーションが明示的に SSLSocket.do_handshake() メソッドを実行するかを指定します。 SSLSocket.do_handshake() を明示的に呼びだすことで、ハンドシェイクによるソケットI/Oのブロッキング動作を制御できます。

suppress_ragged_eofs 引数は、 SSLSocket.read() メソッドが、接続先から予期しないEOFを受け取った時に通知する方法を指定します。 True (デフォルト) の場合、下位のソケットレイヤーから予期せぬEOFエラーが来た場合、通常のEOFを返します。 False の場合、呼び出し元に例外を投げて通知します。

バージョン 2.7 で変更: 新しいオプション引数 ciphers

ssl.RAND_status()

SSL 擬似乱数生成器が十分なランダム性(randomness)を受け取っている時に真を、それ以外の場合は偽を返します。 ssl.RAND_egd() と ssl.RAND_add() を使って擬似乱数生成機にランダム性を加えることができます。

ssl.RAND_egd(path)

もしエントロピー収集デーモン(EGD=entropy-gathering daemon)が動いていて、 path がEGDへのソケットのパスだった場合、この関数はそのソケットから 256バイトのランダム性を読み込み、SSL擬似乱数生成器にそれを渡すことで、生成される暗号鍵のセキュリティを向上させることができます。これは、より良いランダム性のソースが無いシステムでのみ必要です。

エントロピー収集デーモンについては、 http://egd.sourceforge.net/ や http://prngd.sourceforge.net/ を参照してください。

ssl.RAND_add(bytes, entropy)

与えられた bytes をSSL擬似乱数生成器に混ぜます。 entropy 引数(float値)は、その文字列に含まれるエントロピーの下限(lower bound)です。 (なので、いつでも 0.0 を使うことができます。) エントロピーのソースについてのより詳しい情報は、 RFC 1750 [http://tools.ietf.org/html/rfc1750.html] を参照してください。

ssl.cert_time_to_seconds(timestring)

証明書内の “notBefore” や “notAfter” で使われている日時の文字列表現 timestring から、通常のエポック秒を含むfloat値にして返します。

例です。

>>> import ssl
>>> ssl.cert_time_to_seconds("May  9 00:00:00 2007 GMT")
1178694000.0
>>> import time
>>> time.ctime(ssl.cert_time_to_seconds("May  9 00:00:00 2007 GMT"))
'Wed May  9 00:00:00 2007'
>>>

ssl.get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None)

SSLで保護されたサーバーのアドレス addr を (hostname, port-number) の形で受け取り、そのサーバーから証明書を取得し、それを PEMエンコードされた文字列として返します。 ssl_version が指定された場合は、サーバーに接続を試みるときにそのバージョンのSSLプロトコルを利用します。 ca_certs が指定された場合、それは wrap_socket() の同名の引数と同じフォーマットで、ルート証明書のリストを含むファイルでなければなりません。この関数はサーバー証明書をルート証明書リストに対して認証し、認証が失敗した場合にこの関数も失敗します。

ssl.DER_cert_to_PEM_cert(DER_cert_bytes)

DERエンコードされたバイト列として与えられた証明書から、 PEMエンコードされたバージョンの同じ証明書を返します。

ssl.PEM_cert_to_DER_cert(PEM_cert_string)

PEM 形式のASCII文字列として与えられた証明書から、同じ証明書をDERエンコードしたバイト列を返します。

ssl.CERT_NONE

ソケット接続先からの証明書やその認証を必要としないときに、 sslobject() の cert_reqs 引数に指定する値。

ssl.CERT_OPTIONAL

ソケット接続先からの証明書を必要としないが、もし証明書があればそれを認証する場合に sslobject() の cert_reqs 引数に指定する値。この設定を利用するときは、 ca_certs 引数に有効な証明書認証ファイルが渡される必要があることに注意してください。

ssl.CERT_REQUIRED

ソケット接続先からの証明書とその認証が必要なときに sslobject() の cert_reqs 引数に指定する値。この設定を利用するときは、 ca_certs 引数に有効な証明書認証ファイルが渡される必要があることに注意してください。

ssl.PROTOCOL_SSLv2

チャンネル暗号化プロトコルに SSL バージョン2を選択する。

このプロトコルは、 OpenSSL が OPENSSL_NO_SSL2 フラグが有効な状態でコンパイルされている場合には利用できません。

警告

SSL version 2 は非セキュアです。このプロトコルは強く非推奨です。

ssl.PROTOCOL_SSLv23

チャンネル暗号化プロトコルとしてSSLバージョン2か3を選択します。これはサーバー側が相手側への最大限の互換性を確保するための設定です。しかし、この設定では非常に低い品質の暗号化が選ばれる可能性があります。

ssl.PROTOCOL_SSLv3

チャンネル暗号化プロトコルとしてSSLバージョン3をを選択します。クライアントにとって、これは最大限に互換性の高いSSLの種類です。

ssl.PROTOCOL_TLSv1

チャンネル暗号化プロトコルとしてTLSバージョン1を選択します。これは最も現代的で、接続の両サイドが利用できる場合は、たぶん最も安全な選択肢です。

ssl.OPENSSL_VERSION

インタプリタによってロードされた OpenSSL ライブラリのバージョン文字列:

>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8k 25 Mar 2009'

バージョン 2.7 で追加.

ssl.OPENSSL_VERSION_INFO

OpenSSL ライブラリのバージョン情報を表す5つの整数のタプル:

>>> ssl.OPENSSL_VERSION_INFO
(0, 9, 8, 11, 15)

バージョン 2.7 で追加.

ssl.OPENSSL_VERSION_NUMBER

1つの整数の形式の、 OpenSSL ライブラリの生のバージョン番号:

>>> ssl.OPENSSL_VERSION_NUMBER
9470143L
>>> hex(ssl.OPENSSL_VERSION_NUMBER)
'0x9080bfL'

バージョン 2.7 で追加.

17.3.2. SSLSocket オブジェクト

SSLSocket.read([nbytes=1024])

nbytes 以下のバイト列を SSL暗号化されたチャンネルから受信してそれを返します。

SSLSocket.write(data)

data をSSLチャンネルを使って暗号化した上で接続の相手側へ送ります。書き込めたバイト数を返します。

SSLSocket.getpeercert(binary_form=False)

接続先に証明書が無い場合、 None を返します。

binary_form が False で接続先から証明書を取得した場合、このメソッドは dict のインスタンスを返します。証明書が認証されていない場合、辞書は空です。証明書が認証されていた場合、 subject (証明書が発行された principal), notafter (その証明書がそれ以降信頼できなくなる時間) が格納された辞書を返します。証明書は既に認証されているので、 notBefore と issuer フィールドは返されません。証明書が Subject Alternative Name 拡張(RFC 3280 [http://tools.ietf.org/html/rfc3280.html] を参照)のインスタンスを格納していた場合、 subjectAltName キーも辞書に含まれます。

“subject” フィールドは、証明書の principal に格納されているRDN (relative distinguishued name)のシーケンスを格納したタプルで、各RDNは name-value ペアのシーケンスです。

{'notAfter': 'Feb 16 16:54:50 2013 GMT',
 'subject': ((('countryName', u'US'),),
             (('stateOrProvinceName', u'Delaware'),),
             (('localityName', u'Wilmington'),),
             (('organizationName', u'Python Software Foundation'),),
             (('organizationalUnitName', u'SSL'),),
             (('commonName', u'somemachine.python.org'),))}

binary_form 引数が True だった場合、証明書が渡されていればこのメソッドはDERエンコードされた証明書全体をバイト列として返し、接続先が証明書を提示しなかった場合は None を返します。この戻り値は認証とは独立しています。認証が要求されていた場合 (CERT_OPTIONAL か CERT_REQUIRED) その証明書は認証されますが、 CERT_NONE が接続時に利用された場合、証明書があったとしても、それは認証されません。

SSLSocket.cipher()

利用されている暗号の名前、その暗号の利用を定義しているSSLプロトコルのバージョン、利用されている鍵のbit長の3つの値を含むタプルを返します。もし接続が確立されていない場合、 None を返します。

SSLSocket.do_handshake()

TLS/SSL ハンドシェイクを実施します。ノンブロッキングソケットで利用された場合、ハンドシェイクが完了するまでは SSLError の arg[0] に SSL_ERROR_WANT_READ か SSL_ERROR_WANT_WRITE が設定された例外が発生し、このメソッドを繰り返し実行しなければなりません。例えば、ブロッキングソケットを真似する場合は次のようになります。

while True:
    try:
        s.do_handshake()
        break
    except ssl.SSLError, err:
        if err.args[0] == ssl.SSL_ERROR_WANT_READ:
            select.select([s], [], [])
        elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
            select.select([], [s], [])
        else:
            raise

SSLSocket.unwrap()

SSLシャットダウンハンドシェイクを実行します。これは下位レイヤーのソケットからTLSレイヤーを取り除き、下位レイヤーのソケットオブジェクトを返します。これは暗号化されたオペレーションから暗号化されていない接続に移行するときに利用されます。以降の通信には、このメソッドが返したソケットインスタンスを利用するべきです。元のソケットインスタンスは unwrap 後に正しく機能しないかもしれません。

17.3.3. 証明書

証明書を大まかに説明すると、公開鍵/秘密鍵システムの一種です。このシステムでは、各 principal (これはマシン、人、組織などです) は、ユニークな2つの暗号鍵を割り当てられます。1つは公開され、 公開鍵(public key) と呼ばれます。もう一方は秘密にされ、 秘密鍵(private key) と呼ばれます。 2つの鍵は関連しており、片方の鍵で暗号化したメッセージは、もう片方の鍵 のみで復号できます。

証明書は2つの principal の情報を含んでいます。証明書は subject 名とその公開鍵を含んでいます。また、もう一つの principal である 発行者(issuer) からの、 subject が本人であることと、その公開鍵が正しいことの宣言(statement)を含んでいます。発行者からの宣言は、その発行者の秘密鍵で署名されています。発行者の秘密鍵は発行者しか知りませんが、誰もがその発行者の公開鍵を利用して宣言を復号し、証明書内の別の情報と比較することで認証することができます。証明書はまた、その証明書が有効である期限に関する情報も含んでいます。この期限は “notBefore” と “notAfter” と呼ばれる2つのフィールドで表現されています。

Python において証明書を利用する場合、クライアントもサーバーも自分を証明するために証明書を利用することができます。ネットワーク接続の相手側に証明書の提示を要求する事ができ、そのクライアントやサーバーが認証を必要とするならその証明書を認証することができます。認証が失敗した場合、接続は例外を発生させます。認証は下位層のOpenSSLフレームワークが自動的に行います。アプリケーションは認証機構について意識する必要はありません。しかし、アプリケーションは認証プロセスのために幾つかの証明書を提供する必要があるかもしれません。

Python は証明書を格納したファイルを利用します。そのファイルは “PEM” (RFC 1422 [http://tools.ietf.org/html/rfc1422.html] 参照) フォーマットという、ヘッダー行とフッター行の間にbase-64エンコードされた形をとっている必要があります。

-----BEGIN CERTIFICATE-----
... (certificate in base64 PEM encoding) ...
-----END CERTIFICATE-----

Pythonが利用する証明書を格納したファイルは、ときには 証明書チェイン(certificate chain) と呼ばれる証明書のシーケンスを格納します。このチェインは、まずクライアントやサーバー自体の principal の証明書で始まらなければなりません。それ以降に続く証明書は、手前の証明書の発行者(issuer)の証明書になり、最後にsubject と発行者が同じ 自己署名(self-signed) 証明書で終わります。この最後の証明書は ルート証明書(root certificate と呼ばれます。これらの証明書チェインは1つの証明書ファイルに結合されなければなりません。例えば、3つの証明書からなる証明書チェインがあるとします。私たちのサーバーの証明書から、私たちのサーバーに署名した認証局の証明書、そして認証局の証明書を発行した機関のルート証明書です。

-----BEGIN CERTIFICATE-----
... (certificate for your server)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the certificate for the CA)...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (the root certificate for the CA's issuer)...
-----END CERTIFICATE-----

もし相手から送られてきた証明書の認証をしたい場合、信頼している各発行者の証明書チェインが入った “CA certs” ファイルを提供する必要があります。繰り返しますが、このファイルは単純に、各チェインを結合しただけのものです。認証のために、Pythonはそのファイルの中の最初にマッチしたチェインを利用します。

幾つかの “standard” ルート証明書が、幾つかの認証機関から入手できます: CACert.org [http://www.cacert.org/index.php?id=3], Thawte [http://www.thawte.com/roots/], Verisign [http://www.verisign.com/support/roots.html], Positive SSL [http://www.PositiveSSL.com/ssl-certificate-support/cert_installation/UTN-USERFirst-Hardware.crt] (python.org が利用しています), Equifax and GeoTrust [http://www.geotrust.com/resources/root_certificates/index.asp].

一般的に、 SSL3 か TLS1 を利用している場合、”CA certs” ファイルに全てのチェインを保存する必要はありません。接続先はそれ自身の証明書からルート証明書までの証明書チェインを送ってくるはずで、”CA certs” にはルート証明書だけあれば充分なはずです。証明書チェインを組み立てる方法についてのより詳しい情報は、 RFC 4158 [http://tools.ietf.org/html/rfc4158.html] を参照してください。

SSL暗号化接続サービスを提供するサーバーを建てる場合、適切な証明書を取得するには、認証局から買うなどの幾つかの方法があります。また、自己署名証明書を作るケースもあります。 OpenSSLを使って自己署名証明書を作るには、次のようにします。

% openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
Generating a 1024 bit RSA private key
.......++++++
.............................++++++
writing new private key to 'cert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:MyState
Locality Name (eg, city) []:Some City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc.
Organizational Unit Name (eg, section) []:My Group
Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com
Email Address []:ops@myserver.mygroup.myorganization.com
%

自己署名証明書の欠点は、それ自身がルート証明書であり、他の人はその証明書を持っていない (そして信頼しない)ことです。

17.3.4. 例

17.3.4.1. SSLサポートをテストする

インストールされているPythonがSSLをサポートしているかどうかをテストするために、ユーザーコードは次のイディオムを利用することができます。

try:
    import ssl
except ImportError:
    pass
else:
    ... # do something that requires SSL support

17.3.4.2. クライアントサイドの処理

次の例では、SSLサーバーに接続し、サーバーのアドレスと証明書を表示し、数バイト送信し、レスポンスの一部を読み込みます。

import socket, ssl, pprint

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# サーバーからの証明書を要求する
ssl_sock = ssl.wrap_socket(s,
                           ca_certs="/etc/ca_certs_file",
                           cert_reqs=ssl.CERT_REQUIRED)

ssl_sock.connect(('www.verisign.com', 443))

print repr(ssl_sock.getpeername())
print ssl_sock.cipher()
print pprint.pformat(ssl_sock.getpeercert())

# シンプルなHTTPリクエストを送信する。 -- 実際のコードではhttplibを利用してください。
ssl_sock.write("""GET / HTTP/1.0\r
Host: www.verisign.com\r\n\r\n""")

# 1チャンクのデータを読む。
# サーバーから返されたデータの全てを読み込むとは限らない。
data = ssl_sock.read()

# SSLSocketを閉じると下位レイヤーのソケットも閉じられることに注目してください。
ssl_sock.close()

2007年9月時点で、このプログラムによって表示される証明書は次のようになります。

{'notAfter': 'May  8 23:59:59 2009 GMT',
 'subject': ((('serialNumber', u'2497886'),),
             (('1.3.6.1.4.1.311.60.2.1.3', u'US'),),
             (('1.3.6.1.4.1.311.60.2.1.2', u'Delaware'),),
             (('countryName', u'US'),),
             (('postalCode', u'94043'),),
             (('stateOrProvinceName', u'California'),),
             (('localityName', u'Mountain View'),),
             (('streetAddress', u'487 East Middlefield Road'),),
             (('organizationName', u'VeriSign, Inc.'),),
             (('organizationalUnitName',
               u'Production Security Services'),),
             (('organizationalUnitName',
               u'Terms of use at www.verisign.com/rpa (c)06'),),
             (('commonName', u'www.verisign.com'),))}

これは不完全な形の subject フィールドです。

17.3.4.3. サーバーサイドの処理

サーバーサイドの処理では、通常、サーバー証明書と秘密鍵がそれぞれファイルに格納された形で必要です。ソケットを開き、ポートにバインドし、そのソケットの listen() を呼び、クライアントからの接続を待ちます。

import socket, ssl

bindsocket = socket.socket()
bindsocket.bind(('myaddr.mydomain.com', 10023))
bindsocket.listen(5)

誰かが接続してきた場合、 accept() を呼んで新しいソケットを作成し、 wrap_socket() を利用してサーバーサイドSSLコンテキストを生成します。

while True:
    newsocket, fromaddr = bindsocket.accept()
    connstream = ssl.wrap_socket(newsocket,
                                 server_side=True,
                                 certfile="mycertfile",
                                 keyfile="mykeyfile",
                                 ssl_version=ssl.PROTOCOL_TLSv1)
    try:
        deal_with_client(connstream)
    finally:
        connstream.shutdown(socket.SHUT_RDWR)
        connstream.close()

そして、 connstream からデータを読み、クライアントと切断する(あるいはクライアントが切断してくる)まで何か処理をします。

def deal_with_client(connstream):
    data = connstream.read()
    # null data means the client is finished with us
    while data:
        if not do_something(connstream, data):
            # we'll assume do_something returns False
            # when we're finished with client
            break
        data = connstream.read()
    # finished with client

そして新しいクライアント接続のために listen に戻ります。

参考

Class socket.socket

下位レイヤーの socket クラスのドキュメント

TLS (Transport Layer Security) and SSL (Secure Socket Layer) [http://www3.rad.com/networks/applications/secure/tls.htm]

Debby Koren

RFC 1422: Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management [http://www.ietf.org/rfc/rfc1422]

Steve Kent

RFC 1750: Randomness Recommendations for Security [http://www.ietf.org/rfc/rfc1750]

D. Eastlake et. al.

RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile [http://www.ietf.org/rfc/rfc3280]

Housley et. al.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.4. signal — 非同期イベントにハンドラを設定する

このモジュールでは Python でシグナルハンドラを使うための機構を提供します。シグナルとハンドラを扱う上で一般的なルールがいくつかあります:

特定のシグナルに対するハンドラが一度設定されると、明示的にリセットしないかぎり設定されたままになります (Python は背後の実装系に関係なく BSD 形式のインタフェースをエミュレートします)。例外は SIGCHLD のハンドラで、この場合は背後の実装系の仕様に従います。

クリティカルセクションから一時的にシグナルを”ブロック”することはできません。この機能をサポートしない Unix 系システムも存在するためです。

Python のシグナルハンドラは Python のユーザが望む限り非同期で呼び出されますが、呼び出されるのは Python インタプリタの “原子的な (atomic)” 命令実行単位の間です。したがって、 (巨大なサイズのテキストに対する正規表現の一致検索のような) 純粋に C 言語のレベルで実現されている時間のかかる処理中に到着したシグナルは、不定期間遅延する可能性があります。

シグナルが I/O 操作中に到着すると、シグナルハンドラが処理を返した後に I/O 操作が例外を送出する可能性があります。これは背後にある Unix システムが割り込みシステムコールにどういう意味付けをしているかに依存します。

C 言語のシグナルハンドラは常に処理を返すので、 SIGFPE や SIGSEGV のような同期エラーの捕捉はほとんど意味がありません。

Python は標準でごく少数のシグナルハンドラをインストールしています: SIGPIPE は無視されます (したがって、パイプやソケットに対する書き込みで生じたエラーは通常の Python 例外として報告されます) SIGINT は KeyboardInterrupt 例外に変換されます。これらはどれも上書きすることができます。

シグナルとスレッドの両方を同じプログラムで使用する場合にはいくつか注意が必要です。シグナルとスレッドを同時に利用する上で基本的に注意すべきことは、 signal() 命令は常に主スレッド (main thread) の処理中で実行するということです。どのスレッドも alarm()、 getsignal()、 pause()、 setitimer()、 getitimer() を実行することができます。しかし、主スレッドだけが新たなシグナルハンドラを設定することができ、したがってシグナルを受け取ることができるのは主スレッドだけです (これは、背後のスレッド実装が個々のスレッドに対するシグナル送信をサポートしているかに関わらず、 Python signal モジュールが強制している仕様です)。したがって、シグナルをスレッド間通信の手段として使うことはできません。代わりにロック機構を使ってください。

以下に signal モジュールで定義されている変数を示します:

signal.SIG_DFL

二つある標準シグナル処理オプションのうちの一つです; 単純にシグナルに対する標準の関数を実行します。例えば、ほとんどのシステムでは、 SIGQUIT に対する標準の動作はコアダンプと終了で、 SIGCHLD に対する標準の動作は単にシグナルの無視です。

signal.SIG_IGN

もう一つの標準シグナル処理オプションで、受け取ったシグナルを単に無視します。

SIG*

全てのシグナル番号はシンボル定義されています。例えば、ハングアップシグナルは signal.SIGHUP で定義されています; 変数名は C 言語のプログラムで使われているのと同じ名前で、 <signal.h> にあります。 ‘signal()‘ に関する Unix マニュアルページでは、システムで定義されているシグナルを列挙しています (あるシステムではリストは signal(2) に、別のシステムでは signal(7) に列挙されています)。全てのシステムで同じシグナル名のセットを定義しているわけではないので注意してください; このモジュールでは、システムで定義されているシグナル名だけを定義しています。

signal.CTRL_C_EVENT

CTRL+C キーストロークに該当するシグナル。このシグナルは os.kill() でだけ利用できます。

利用可能な環境: Windows

バージョン 2.7 で追加.

signal.CTRL_BREAK_EVENT

CTRL+BREAK キーストロークに該当するシグナル。このシグナルは os.kill() でだけ利用できます。

利用可能な環境: Windows

バージョン 2.7 で追加.

signal.NSIG

最も大きいシグナル番号に 1 を足した値です。

signal.ITIMER_REAL

実時間でデクリメントするインターバルタイマーです。タイマーが発火したときに SIGALRM を送ります。

signal.ITIMER_VIRTUAL

プロセスの実行時間だけデクリメントするインターバルタイマーです。タイマーが発火したときに SIGVTALRM を送ります。

signal.ITIMER_PROF

プロセスの実行中と、システムがそのプロセスのために実行している時間だけデクリメントするインターバルタイマーです。 ITIMER_VIRTUAL と組み合わせて、このタイマーはよくアプリケーションがユーザー空間とカーネル空間で消費した時間のプロファイリングに利用されます。タイマーが発火したときに SIGPROF を送ります。

signal モジュールは1つの例外を定義しています:

exception signal.ItimerError

背後の setitimer() または getitimer() 実装からエラーを通知するために送出されます。無効なインタバルタイマーや負の時間が setitimer() に渡された場合、このエラーを予期してください。このエラーは IOError の特殊型です。

signal モジュールでは以下の関数を定義しています:

signal.alarm(time)

time がゼロでない値の場合、この関数は time 秒後頃に SIGALRM をプロセスに送るように要求します。それ以前にスケジュールしたアラームはキャンセルされます (常に一つのアラームしかスケジュールできません)。この場合、戻り値は以前に設定されたアラームシグナルが通知されるまであと何秒だったかを示す値です。 time がゼロの場合、アラームは一切スケジュールされず、現在スケジュールされているアラームがキャンセルされます。戻り値がゼロの場合、現在アラームがスケジュールされていないことを示します。(Unix マニュアルページ alarm(2) を参照してください)。利用できる環境: Unix。

signal.getsignal(signalnum)

シグナル signalnum に対する現在のシグナルハンドラを返します。戻り値は呼び出し可能な Python オブジェクトか、 signal.SIG_IGN、 signal.SIG_DFL、および None といった特殊な値のいずれかです。ここで signal.SIG_IGN は以前そのシグナルが無視されていたことを示し、 signal.SIG_DFL は以前そのシグナルの標準の処理方法が使われていたことを示し、 None はシグナルハンドラがまだ Python によってインストールされていないことを示します。

signal.pause()

シグナルを受け取るまでプロセスを一時停止します; その後、適切なハンドラが呼び出されます。戻り値はありません。Windows では利用できません。(Unix マニュアルページ signal(2) を参照してください。)

signal.setitimer(which, seconds[, interval])

which で指定されたタイマー (signal.ITIMER_REAL, signal.ITIMER_VIRTUAL, signal.ITIMER_PROF のどれか) を、 seconds 秒後と (alarm() と異なり、floatを指定できます)、それから interval 秒間隔で起動するように設定します。 seconds に0を指定すると、そのタイマーをクリアすることができます。

インターバルタイマーが起動したとき、シグナルがプロセスに送られます。送られるシグナルは利用されたタイマーの種類に依存します。 signal.ITIMER_REAL の場合は SIGALRM が、 signal.ITIMER_VIRTUAL の場合は SIGVTALRM が、 signal.ITIMER_PROF の場合は SIGPROF が送られます。

以前の値が (delay, interval) のタプルとして返されます。

無効なインターバルタイマーを渡すと ItimerError 例外が発生します。利用できる環境: Unix

バージョン 2.6 で追加.

signal.getitimer(which)

which で指定されたインターバルタイマーの現在の値を返します。利用できる環境: Unix

バージョン 2.6 で追加.

signal.set_wakeup_fd(fd)

wakeup fd を fd に設定します。シグナルを受信したときに、 '\0' バイトがそのfdに書き込まれます。これは、pollやselectをしているライブラリを起こして、シグナルの処理をさせるのに利用できます。

戻り値は古い wakeup fd です。 fd はノンブロッキングでなければなりません。起こされたライブラリは、次の poll や select を実行する前にこの fd からすべてのバイトを取り除かなければなりません。

スレッドが有効な場合、この関数はメインスレッドからしか実行できません。それ以外のスレッドからこの関数を実行しようとすると ValueError 例外が発生します。

バージョン 2.6 で追加.

signal.siginterrupt(signalnum, flag)

システムコールのリスタートの動作を変更します。 flag が False の場合、 signalnum シグナルに中断されたシステムコールは再実行されます。それ以外の場合、システムコールは中断されます。戻り値はありません。利用できる環境: Unix (詳しい情報についてはマニュアルページ siginterrupt(3) を参照してください)

signal() を使ってシグナルハンドラを設定したときに、暗黙のうちに flag に true を指定して siginterrupt() が実行されるため、中断に対するリスタートの動作がリセットされることに注意してください。

バージョン 2.6 で追加.

signal.signal(signalnum, handler)

シグナル signalnum に対するハンドラを関数 handler にします。 handler は二つの引数 (下記参照) を取る呼び出し可能な Python オブジェクトか、 signal.SIG_IGN あるいは signal.SIG_DFL といった特殊な値にすることができます。以前に使われていたシグナルハンドラが返されます (上記の getsignal() の記述を参照してください)。 (Unix マニュアルページ signal(2) を参照してください。)

複数スレッドの使用が有効な場合、この関数は主スレッドからのみ呼び出すことができます; 主スレッド以外のスレッドで呼び出そうとすると、例外 ValueError が発生します。

handler は二つの引数とともに呼び出されます: シグナル番号、および現在のスタックフレーム (None またはフレームオブジェクト; フレームオブジェクトについての記述は 標準型の階層における説明 か、 inspect モジュールの属性の説明を参照してください)。

Windows では、 signal() は SIGABRT, SIGFPE, const:SIGILL, SIGINT, SIGSEGV, SIGTERM でのみ利用できます。それ以外の場合は ValueError を発生させます。

17.4.1. 例

以下は最小限のプログラム例です。この例では alarm() を使ってファイルを開く処理を待つのに費やす時間を制限します; 例えば、電源の入っていないシリアルデバイスを開こうとすると、通常 os.open() は未定義の期間ハングアップしてしまいますが、この方法はそうした場合に便利です。ここではファイルを開くまで 5 秒間のアラームを設定することで解決しています; ファイルを開く処理が長くかかりすぎると、アラームシグナルが送信され、ハンドラが例外を送出するようになっています。

import signal, os

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.5. popen2 — アクセス可能な I/O ストリームを持つ子プロセス生成

バージョン 2.6 で撤廃: このモジュールは時代遅れです。 subprocess モジュールを利用してください。特に 古い関数を subprocess モジュールで置き換える 節を参照してください。

このモジュールにより、Unix および Windows でプロセスを起動し、その入力／出力／エラー出力パイプに接続し、そのリターンコードを取得することができます。

subprocess モジュールが、新しいプロセスを起動してその結果を受け取るためのより強力な仕組みを持っています。 popen2 モジュールよりも subprocess モジュールを利用することが推奨されます。

このモジュールで提供されている第一のインタフェースは 3 つのファクトリ関数です。これらの関数のいずれも、 bufsize を指定した場合、 I/O パイプのバッファサイズを決定します。 mode を指定する場合、文字列 'b' または 't' でなければなりません; Windows では、ファイルオブジェクトをバイナリあるいはテキストモードのどちらで開くかを決めなければなりません。 mode の標準の値は 't' です。

Unixでは cmd はシーケンスでもよく、その場合には (os.spawnv() のように)引数はプログラムシェルを経由せず直接渡されます。 cmd が文字列の場合、(os.system() のように)シェルに渡されます。

子プロセスからのリターンコードを取得するには、 Popen3 および Popen4 クラスの poll() あるいは wait() メソッドを使うしかありません; これらの機能は Unixでしか利用できません。この情報は popen2() 、 popen3() 、および popen4() 関数、あるいは os モジュールにおける同等の関数の使用によっては得ることができません。 (os モジュールの関数から返されるタプルは popen2 モジュールの関数から返されるものとは違う順序です。)

popen2.popen2(cmd[, bufsize[, mode]])

cmd をサブプロセスとして実行します。ファイルオブジェクト (child_stdout, child_stdin) を返します。

popen2.popen3(cmd[, bufsize[, mode]])

cmd をサブプロセスとして実行します。ファイルオブジェクト (child_stdout, child_stdin, child_stderr) を返します。

popen2.popen4(cmd[, bufsize[, mode]])

cmd をサブプロセスとして実行します。ファイルオブジェクト (child_stdout_and_stderr, child_stdin).

バージョン 2.0 で追加.

Unixでは、ファクトリ関数によって返されるオブジェクトを定義しているクラスも利用することができます。これらのオブジェクトは Windows 実装で使われていないため、そのプラットフォーム上で使うことはできません。

class popen2.Popen3(cmd[, capturestderr[, bufsize]])

このクラスは子プロセスを表現します。通常、 Popen3 インスタンスは上で述べた popen2() および popen3() ファクトリ関数を使って生成されます。

Popen3 オブジェクトを生成するためにいずれかのヘルパー関数を使っていないのなら、 cmd パラメタは子プロセスで実行するシェルコマンドになります。 capturestderr フラグが真であれば、このオブジェクトが子プロセスの標準エラー出力を捕獲しなければならないことを意味します。標準の値は偽です。 bufsize パラメタが存在する場合、子プロセスへの／からの I/O バッファのサイズを指定します。

class popen2.Popen4(cmd[, bufsize])

Popen3 に似ていますが、標準エラー出力を標準出力と同じファイルオブジェクトで捕獲します。このオブジェクトは通常 popen4() で生成されます。

バージョン 2.0 で追加.

17.5.1. Popen3 および Popen4 オブジェクト

Popen3 および Popen4 クラスのインスタンスは以下のメソッドを持ちます:

Popen3.poll()

子プロセスがまだ終了していない際には -1 を、そうでない場合にはステータスコード (wait() を参照) を返します。

Popen3.wait()

子プロセスの状態コード出力を待機して返します。状態コードでは子プロセスのリターンコードと、プロセスが exit() によって終了したか、あるいはシグナルによって死んだかについての情報を符号化しています。状態コードの解釈を助けるための関数は os モジュールで定義されています; プロセス管理 節の W*() 関数ファミリを参照してください。

以下の属性も利用可能です:

Popen3.fromchild

子プロセスからの出力を提供するファイルオブジェクトです。 Poepn4 インスタンスの場合、この値は標準出力と標準エラー出力の両方を提供するオブジェクトになります。

Popen3.tochild

子プロセスへの入力を提供するファイルオブジェクトです。

Popen3.childerr

コンストラクタに capturestderr を渡した際には子プロセスからの標準エラー出力を提供するファイルオブジェクトで、そうでない場合 None になります。 Popen4 インスタンスでは、この値は常に None になります。

Popen3.pid

子プロセスのプロセス番号です。

17.5.2. フロー制御の問題

何らかの形式でプロセス間通信を利用している際には常に、制御フローについて注意深く考える必要があります。これはこのモジュール (あるいは os モジュールにおける等価な機能) で生成されるファイルオブジェクトの場合にもあてはまります。

親プロセスが子プロセスの標準出力を読み出している一方で、子プロセスが大量のデータを標準エラー出力に書き込んでいる場合、この子プロセスから出力を読み出そうとするとデッドロックが発生します。同様の状況は読み書きの他の組み合わせでも生じます。本質的な要因は、一方のプロセスが別のプロセスでブロック型の読み出しをしている際に、 _PC_PIPE_BUF バイトを超えるデータがブロック型の入出力を行うプロセスによって書き込まれることにあります。

こうした状況を扱うには幾つかのやりかたがあります。

多くの場合、もっとも単純なアプリケーションに対する変更は、親プロセスで以下のようなモデル:

import popen2

r, w, e = popen2.popen3('python slave.py')
e.readlines()
r.readlines()
r.close()
e.close()
w.close()

に従うようにし、子プロセスで以下:

import os
import sys

# note that each of these print statements
# writes a single long string

print >>sys.stderr, 400 * 'this is a test\n'
os.close(sys.stderr.fileno())
print >>sys.stdout, 400 * 'this is another test\n'

のようなコードにすることでしょう。

とりわけ、 sys.stderr は全てのデータを書き込んた後に閉じられなければならないということに注意してください。さもなければ、 readlines() は返ってきません。また、 sys.stderr.close() が stderr を閉じないように os.close() を使わなければならないことにも注意してください。 (そうでなく、 sys.stderr に関連付けると、暗黙のうちに閉じられてしまうので、それ以降のエラーが出力されません)。

より一般的なアプローチをサポートする必要があるアプリケーションでは、パイプ経由の I/O を select() ループでまとめるか、個々の popen*() 関数や Popen* クラスが提供する各々のファイルに対して、個別のスレッドを使って読み出しを行います。

参考

Module subprocess

子プロセスの起動と管理のためのモジュール

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.6. asyncore — 非同期ソケットハンドラ

このモジュールは、非同期ソケットサービスのクライアント・サーバを開発するための基盤として使われます。

CPUが一つしかない場合、プログラムが”二つのことを同時に”実行する方法は二つしかありません。もっとも簡単で一般的なのはマルチスレッドを利用する方法ですが、これとはまったく異なるテクニックで、一つのスレッドだけでマルチスレッドと同じような効果を得られるテクニックがあります。このテクニックはI/O処理が中心である場合にのみ有効で、CPU負荷の高いプログラムでは効果が無く、この場合にはプリエンプティブなスケジューリングが可能なスレッドが有効でしょう。しかし、多くの場合、ネットワークサーバではCPU負荷よりはIO負荷が問題となります。

もしOSのI/Oライブラリがシステムコール select() をサポートしている場合（ほとんどの場合はサポートされている）、I/O処理は”バックグラウンド”で実行し、その間に他の処理を実行すれば、複数の通信チャネルを同時にこなすことができます。一見、この戦略は奇妙で複雑に思えるかもしれませんが、いろいろな面でマルチスレッドよりも理解しやすく、制御も容易です。 asyncore は多くの複雑な問題を解決済みなので、洗練され、パフォーマンスにも優れたネットワークサーバとクライアントを簡単に開発することができます。とくに、 asynchat のような、対話型のアプリケーションやプロトコルには非常に有効でしょう。

基本的には、この二つのモジュールを使う場合は一つ以上のネットワーク チャネル を asyncore.dispatcher クラス、または asynchat.async_chat のインスタンスとして作成します。作成されたチャネルはグローバルマップに登録され、 loop() 関数で参照されます。 loop() には、専用の マップ を渡す事も可能です。

チャネルを生成後、 loop() を呼び出すとチャネル処理が開始し、最後のチャネル（非同期処理中にマップに追加されたチャネルを含む）が閉じるまで継続します。

asyncore.loop([timeout[, use_poll[, map[, count]]]])

ポーリングループを開始し、count回が過ぎるか、全てのオープン済みチャネルがクローズされた場合のみ終了します。全ての引数はオプションです。引数 count のデフォルト値はNoneで、ループは全てのチャネルがクローズされた場合のみ終了します。引数 timeout は select() または poll() の引数timeoutとして渡され、秒単位で指定します。デフォルト値は30秒です。引数 use_poll が真のとき、 select() ではなく poll() が使われます。デフォルト値は False です。

引数 map には、監視するチャネルをアイテムとして格納した辞書を指定します。チャネルがクローズされた時に map からそのチャネルが削除されます。 map が省略された場合、グローバルなマップが使用されます。チャネル (asyncore.dispatcher, asynchat.async_chat とそのサブクラス) は自由に混ぜて map に入れることができます。

class asyncore.dispatcher

dispatcher クラスは、低レベルソケットオブジェクトの薄いラッパーです。便宜上、非同期ループから呼び出されるイベント処理メソッドを追加していますが、これ以外の点では、non-blockingなソケットと同様です。

非同期ループ内で低レベルイベントが発生した場合、発生のタイミングやコネクションの状態から特定の高レベルイベントへと置き換えることができます。例えばソケットを他のホストに接続する場合、最初の書き込み可能イベントが発生すれば接続が完了した事が分かります(この時点で、ソケットへの書き込みは成功すると考えられる)。このように判定できる高レベルイベントを以下に示します：

イベント | 解説
handle_connect() | 最初にreadもしくはwriteイベントが発生した時
handle_close() | 読み込み可能なデータなしでreadイベントが発生した時
handle_accept() | listen中のソケットでreadイベントが発生した時

非同期処理中、マップに登録されたチャネルの readable() メソッドと writable() メソッドが呼び出され、 select() か poll() でread/writeイベントを検出するリストに登録するか否かを判定します。

このようにして、チャネルでは低レベルなソケットイベントの種類より多くの種類のイベントを検出する事ができます。以下にあげるイベントは、サブクラスでオーバライドすることが可能です：

handle_read()

非同期ループで、チャネルのソケットの read() メソッドの呼び出しが成功した時に呼び出されます。

handle_write()

非同期ループで、書き込み可能ソケットが実際に書き込み可能になった時に呼び出される。このメソッドは、パフォーマンスの向上のためバッファリングを行う場合などに利用できます。例：

def handle_write(self):
    sent = self.send(self.buffer)
    self.buffer = self.buffer[sent:]

handle_expt()

out of band (OOB)データが検出された時に呼び出されます。 OOBはあまりサポートされておらず、また滅多に使われないので、 handle_expt() が呼び出されることはほとんどありません。

handle_connect()

ソケットの接続が確立した時に呼び出されます。 “welcome”バナーの送信、プロトコルネゴシエーションの初期化などを行います。

handle_close()

ソケットが閉じた時に呼び出されます。

handle_error()

捕捉されない例外が発生した時に呼び出されます。デフォルトでは、短縮したトレースバック情報が出力されます。

handle_accept()

listen中のチャネルがリモートホストからの connect() で接続され、接続が確立した時に呼び出されます。

readable()

非同期ループ中に呼び出され、readイベントの監視リストに加えるか否かを決定します。デフォルトのメソッドでは True を返し、readイベントの発生を監視します。

writable()

非同期ループ中に呼び出され、writeイベントの監視リストに加えるか否かを決定します。デフォルトのメソッドでは True を返し、writeイベントの発生を監視します。

さらに、チャネルにはソケットのメソッドとほぼ同じメソッドがあり、チャネルはソケットのメソッドの多くを委譲・拡張しており、ソケットとほぼ同じメソッドを持っています。

create_socket(family, type)

引数も含め、通常のソケット生成と同じ。 socket モジュールを参照のこと。

connect(address)

通常のソケットオブジェクトと同様、 address には一番目の値が接続先ホスト、2番目の値がポート番号であるタプルを指定します。

send(data)

リモート側の端点に data を送出します。

recv(buffer_size)

リモート側の端点より、最大 buffer_size バイトのデータを読み込みます。長さ0の文字列が返ってきた場合、チャネルはリモートから切断された事を示します。

listen(backlog)

ソケットへの接続を待つ。引数 backlog は、キューイングできるコネクションの最大数を指定します(1以上)。最大数はシステムに依存でします（通常は5)

bind(address)

ソケットを address にバインドします。ソケットはバインド済みであってはなりません。 (address の形式は、アドレスファミリに依存します。 socket モジュールを参照のこと。) ソケットを再利用可能にする (SO_REUSEADDR オプションを設定する) には、 dispatcher オブジェクトの set_reuse_addr() メソッドを呼び出してください。

accept()

接続を受け入れます。ソケットはアドレスにバインド済みであり、 listen() で接続待ち状態でなければなりません。戻り値は None か (conn, address) のペアで、 conn はデータの送受信を行う 新しい ソケットオブジェクト、 address は接続先ソケットがバインドされているアドレスです。 None が返された場合、接続が起こらなかったことを意味します。その場合、サーバーはこのイベントを無視して後続の接続を待ち続けるべきです。

close()

ソケットをクローズします。以降の全ての操作は失敗します。リモート端点では、キューに溜まったデータ以外、これ以降のデータ受信は行えません。ソケットはガベージコレクト時に自動的にクローズされます。

class asyncore.dispatcher_with_send

dispatcher のサブクラスで、シンプルなバッファされた出力を持ちます。シンプルなクライアントプログラムに適しています。もっと高レベルな場合には asynchat.async_chat を利用してください。

class asyncore.file_dispatcher

file_dispatcher はファイルディスクリプタかファイルオブジェクトとオプションとして map を引数にとって、 poll() か loop() 関数で利用できるようにラップします。与えられたファイルオブジェクトなどが fileno() メソッドを持っているとき、そのメソッドが呼び出されて戻り値が file_wrapper のコンストラクタに渡されます。利用できるプラットフォーム: UNIX

class asyncore.file_wrapper

file_wrapper は整数のファイルディスクリプタを受け取って os.dup() を呼び出してハンドルを複製するので、元のハンドルは file_wrapper と独立してclose されます。このクラスは file_dispatcher クラスが使うために必要なソケットをエミュレートするメソッドを実装しています。利用できるプラットフォーム: UNIX

17.6.1. asyncoreの例：簡単なHTTPクライアント

基本的なサンプルとして、以下に非常に単純なHTTPクライアントを示します。このHTTPクライアントは dispatcher クラスでソケットを利用しています。

import asyncore, socket

class HTTPClient(asyncore.dispatcher):

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect( (host, 80) )
        self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]

client = HTTPClient('www.python.org', '/')
asyncore.loop()

17.6.2. 基本的な echo サーバーの例

この例の基本的な echoサーバーは、 dispatcher を利用して接続を受けつけ、接続をハンドラーにディスパッチします。

import asyncore
import socket

class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)

class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accept(self):
        pair = self.accept()
        if pair is None:
            pass
        else:
            sock, addr = pair
            print 'Incoming connection from %s' % repr(addr)
            handler = EchoHandler(sock)

server = EchoServer('localhost', 8080)
asyncore.loop()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

17. プロセス間通信とネットワーク »

17.7. asynchat — 非同期ソケットコマンド/レスポンスハンドラ

asynchat を使うと、 asyncore を基盤とした非同期なサーバ・クライアントをより簡単に開発する事ができます。 asynchat では、プロトコルの要素が任意の文字列で終了するか、または可変長の文字列であるようなプロトコルを容易に制御できるようになっています。 asynchat は、抽象クラス async_chat を定義しており、 async_chat を継承して collect_incoming_data() メソッドと found_terminator() メソッドを実装すれば使うことができます。 async_chat と asyncore は同じ非同期ループを使用しており、 asyncore.dispatcher も asynchat.async_chat も同じチャネルマップに登録する事ができます。通常、 asyncore.dispatcher はサーバチャネルとして使用し、リクエストの受け付け時に asynchat.async_chat オブジェクトを生成します。

class asynchat.async_chat

このクラスは、 asyncore.dispatcher から継承した抽象クラスです。使用する際には async_chat のサブクラスを作成し、 collect_incoming_data() と found_terminator() を定義しなければなりません。 asyncore.dispatcher のメソッドを使用する事もできますが、メッセージ/レスポンス処理を中心に行う場合には使えないメソッドもあります。

asyncore.dispatcher と同様に、 async_chat も select() 呼出し後のソケットの状態からイベントを生成します。ポーリングループ開始後、イベント処理フレームワークが自動的に async_chat のメソッドを呼び出しますので、プログラマが処理を記述する必要はありません。

パフォーマンスの向上やメモリの節約のために、2つのクラス属性を調整することができます。

ac_in_buffer_size

非同期入力バッファサイズ (デフォルト値: 4096)

ac_out_buffer_size

非同期出力バッファサイズ (デフォルト値: 4096)

asyncore.dispatcher と違い、 async_chat では producer の first-in-first- outキュー(fifo)を作成する事ができます。producerは more() メソッドを必ず持ち、このメソッドでチャネル上に送出するデータを返します。producerが枯渇状態 (i.e. これ以上のデータを持たない状態)にある場合、 more() は空文字列を返します。この時、 async_chat は枯渇状態にあるproducerをfifoから除去し、次のproducerが存在すればそのproducerを使用します。fifoにproducerが存在しない場合、 handle_write() は何もしません。リモート端点からの入力の終了や重要な中断点を検出する場合は、 set_terminator() に記述します。

async_chat のサブクラスでは、入力メソッド collect_incoming_data() と found_terminator() を定義し、チャネルが非同期に受信するデータを処理します。これらのメソッドについては後ろで解説します。

async_chat.close_when_done()

producer fifoのトップに None をプッシュします。このproducerがポップされると、チャネルがクローズします。

async_chat.collect_incoming_data(data)

チャネルが受信した不定長のデータを data に指定して呼び出されます。このメソッドは必ずオーバライドする必要があり、デフォルトの実装では、 NotImplementedError 例外を送出します。

async_chat.discard_buffers()

非常用のメソッドで、全ての入出力バッファとproducer fifoを廃棄します。

async_chat.found_terminator()

入力データストリームが、 set_terminator() で指定した終了条件と一致した場合に呼び出されます。このメソッドは必ずオーバライドする必要があり、デフォルトの実装では、 NotImplementedError 例外を送出します。入力データを参照する必要がある場合でも引数としては与えられないため、入力バッファをインスタンス属性として参照しなければなりません。

async_chat.get_terminator()

現在のチャネルの終了条件を返します。

async_chat.push(data)

チャネルの fifo にデータをプッシュして転送します。データをチャネルに書き出すために必要なのはこれだけですが、データの暗号化やチャンク化などを行う場合には独自の producer を使用する事もできます。

async_chat.push_with_producer(producer)

指定したproducerオブジェクトをチャネルのfifoに追加します。これより前にpushされたproducerが全て枯渇した後、チャネルはこのproducer から more() メソッドでデータを取得し、リモート端点に送信します。

async_chat.set_terminator(term)

チャネルで検出する終了条件を設定します。 term は入力プロトコルデータの処理方式によって以下の3つの型の何れかを指定します。

term | 説明
string | 入力ストリーム中でstringが検出された時、 found_terminator() を呼び出します。
integer | 指定された文字数が読み込まれた時、 found_terminator() を呼び出します。
None | 永久にデータを読み込みます。

終了条件が成立しても、その後に続くデータは、 found_terminator() の呼出し後に再びチャネルを読み込めば取得する事ができます。

17.7.1. asynchat - 補助クラス

class asynchat.fifo([list=None])

アプリケーションからプッシュされ、まだチャネルに書き出されていないデータを保持するための fifo 。 fifo は必要になるまでデータと producer を保持するために使われるリストです。引数 list には、チャネルに出力する producer またはデータを指定する事ができます。

is_empty()

fifoが空のとき(のみ)に True を返します。

first()

fifoに push() されたアイテムのうち、最も古いアイテムを返します。

push(data)

データ(文字列またはproducerオブジェクト)をproducer fifoに追加します。

pop()

fifoが空でなければ、 (True, first()) を返し、ポップされたアイテムを削除します。 fifoが空であれば (False, None) を返します。

17.7.2. asynchat 使用例

以下のサンプルは、 async_chat でHTTPリクエストを読み込む処理の一部です。Webサーバは、クライアントからの接続毎に http_request_handler オブジェクトを作成します。最初はチャネルの終了条件に空行を指定してHTTPヘッダの末尾までを検出し、その後ヘッダ読み込み済みを示すフラグを立てています。

ヘッダ読み込んだ後、リクエストの種類がPOSTであればデータが入力ストリームに流れるため、 Content-Length: ヘッダの値を数値として終了条件に指定し、適切な長さのデータをチャネルから読み込みます。

必要な入力データを全て入手したら、チャネルの終了条件に None を指定して残りのデータを無視するようにしています。この後、 handle_request() が呼び出されます。

class http_request_handler(asynchat.async_chat):

    def __init__(self, sock, addr, sessions, log):
        asynchat.async_chat.__init__(self, sock=sock)
        self.addr = addr
        self.sessions = sessions
        self.ibuffer = []
        self.obuffer = ""
        self.set_terminator("\r\n\r\n")
        self.reading_headers = True
        self.handling = False
        self.cgi_data = None
        self.log = log

    def collect_incoming_data(self, data):
        """Buffer the data"""
        self.ibuffer.append(data)

    def found_terminator(self):
        if self.reading_headers:
            self.reading_headers = False
            self.parse_headers("".join(self.ibuffer))
            self.ibuffer = []
            if self.op.upper() == "POST":
                clen = self.headers.getheader("content-length")
                self.set_terminator(int(clen))
            else:
                self.handling = True
                self.set_terminator(None)
                self.handle_request()
        elif not self.handling:
            self.set_terminator(None) # browsers sometimes over-send
            self.cgi_data = parse(self.headers, "".join(self.ibuffer))
            self.handling = True
            self.ibuffer = []
            self.handle_request()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作

この章ではインターネット上で一般的に利用されているデータ形式の操作をサポートするモジュール群について記述します．

18.1. email — 電子メールと MIME 処理のためのパッケージ

18.1.1. email: 電子メールメッセージの表現

18.1.2. email: 電子メールメッセージを解析(パース)する

18.1.2.1. FeedParser API

18.1.2.2. Parser クラス API

18.1.2.3. 追加事項

18.1.3. email: MIME 文書を生成する

18.1.4. email: 電子メールおよび MIME オブジェクトをゼロから作成する

18.1.5. email: 国際化されたヘッダ

18.1.6. email: 文字セットの表現

18.1.7. email: エンコーダ

18.1.8. email: 例外及び障害クラス

18.1.9. email: 雑用ユーティリティ

18.1.10. email: イテレータ

18.1.11. email: 使用例

18.1.12. パッケージの履歴

18.1.13. mimelib との違い

18.2. json — JSON エンコーダおよびデコーダ

18.2.1. 基本的な使い方

18.2.2. エンコーダおよびデコーダ

18.3. mailcap — mailcap ファイルの操作

18.4. mailbox — 様々な形式のメールボックス操作

18.4.1. Mailbox オブジェクト

18.4.1.1. Maildir

18.4.1.2. mbox

18.4.1.3. MH

18.4.1.4. Babyl

18.4.1.5. MMDF

18.4.2. Message objects

18.4.2.1. MaildirMessage

18.4.2.2. mboxMessage

18.4.2.3. MHMessage

18.4.2.4. BabylMessage

18.4.2.5. MMDFMessage

18.4.3. 例外

18.4.4. 撤廃されたクラスとメソッド

18.4.5. 例

18.5. mhlib — MH のメールボックスへのアクセス機構

18.5.1. MH オブジェクト

18.5.2. Folder オブジェクト

18.5.3. Message オブジェクト

18.6. mimetools — MIME メッセージを解析するためのツール

18.6.1. Message オブジェクトの追加メソッド

18.7. mimetypes — ファイル名を MIME 型へマップする

18.7.1. Mime型オブジェクト

18.8. MimeWriter — 汎用 MIME ファイルライター

18.8.1. MimeWriter オブジェクト

18.9. mimify — 電子メールメッセージの MIME 処理

18.10. multifile — 個別の部分を含んだファイル群のサポート

18.10.1. MultiFile オブジェクト

18.10.2. MultiFile の例

18.11. rfc822 — RFC 2822 準拠のメールヘッダ読み出し

18.11.1. Message オブジェクト

18.11.2. AddressList オブジェクト

18.12. base64 — RFC 3548: Base16, Base32, Base64 データの符号化

18.13. binhex — binhex4 形式ファイルのエンコードおよびデコード

18.13.1. 注記

18.14. binascii — バイナリデータと ASCIIデータとの間での変換

18.15. quopri — MIME quoted-printable 形式データのエンコードおよびデコード

18.16. uu — uuencode形式のエンコードとデコード

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ

バージョン 2.2 で追加.

email パッケージは電子メールのメッセージを管理するライブラリです。これには MIME やそれ以外の RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ベースのメッセージ文書もふくまれます。このパッケージはいくつかの古い標準パッケージ、 rfc822, mimetools, multifile などにふくまれていた機能のほとんどを持ち、くわえて標準ではなかった mimecntl などの機能もふくんでいます。このパッケージは、とくに電子メールのメッセージを SMTP (RFC 2821 [http://tools.ietf.org/html/rfc2821.html])、 NNTP、その他のサーバに送信するために作られているというわけでは ありません 。それは smtplib, nntplib モジュールなどの機能です。 email パッケージは RFC 2822 [http://tools.ietf.org/html/rfc2822.html] に加えて、 RFC 2045 [http://tools.ietf.org/html/rfc2045.html], RFC 2046 [http://tools.ietf.org/html/rfc2046.html], RFC 2047 [http://tools.ietf.org/html/rfc2047.html] および RFC 2231 [http://tools.ietf.org/html/rfc2231.html] など MIME 関連の RFC をサポートしており、できるかぎり RFC に準拠することをめざしています。

email パッケージの一番の特徴は、電子メールの内部表現であるオブジェクトモデル と、電子メールメッセージの解析および生成とを分離していることです。 email パッケージを使うアプリケーションは基本的にはオブジェクトを処理することができます。メッセージに子オブジェクトを追加したり、メッセージから子オブジェクトを削除したり、内容を完全に並べかえたり、といったことができます。フラットなテキスト文書からオブジェクトモデルへの変換、またそこからフラットな文書へと戻す変換はそれぞれ別々の解析器 (パーサ) と生成器 (ジェネレータ) が担当しています。また、一般的な MIME オブジェクトタイプのいくつかについては手軽なサブクラスが存在しており、メッセージフィールド値を抽出したり解析したり、 RFC 準拠の日付を生成したりなどのよくおこわれるタスクについてはいくつかの雑用ユーティリティもついています。

以下の節では email パッケージの機能を説明します。説明の順序は多くのアプリケーションで一般的な使用順序にもとづいています。まず、電子メールメッセージをファイルあるいはその他のソースからフラットなテキスト文書として読み込み、つぎにそのテキストを解析して電子メールのオブジェクト構造を作成し、その構造を操作して、最後にオブジェクトツリーをフラットなテキストに戻す、という順序になっています。

このオブジェクト構造は、まったくのゼロから作りだしたものであってもいっこうにかまいません。この場合も上と似たような作業順序になるでしょう。

またここには email パッケージが提供するすべてのクラスおよびモジュールに関する説明と、 email パッケージを使っていくうえで遭遇するかもしれない例外クラス、いくつかの補助ユーティリティ、そして少々のサンプルも含まれています。古い mimelib や前バージョンの email パッケージのユーザのために、現行バージョンとの違いと移植についての節も設けてあります。

18.1.1. email: 電子メールメッセージの表現

18.1.2. email: 電子メールメッセージを解析(パース)する

18.1.2.1. FeedParser API

18.1.2.2. Parser クラス API

18.1.2.3. 追加事項

18.1.3. email: MIME 文書を生成する

18.1.4. email: 電子メールおよび MIME オブジェクトをゼロから作成する

18.1.5. email: 国際化されたヘッダ

18.1.6. email: 文字セットの表現

18.1.7. email: エンコーダ

18.1.8. email: 例外及び障害クラス

18.1.9. email: 雑用ユーティリティ

18.1.10. email: イテレータ

18.1.11. email: 使用例

参考

Module smtplib

SMTP プロトコルクライアント

Module nntplib

NNTP プロトコルクライアント

18.1.12. パッケージの履歴

このテーブルは email パッケージのリリース履歴を表しています。それぞれのバージョンと、それが同梱された Python のバージョンとの関連が示されています。このドキュメントでの、追加/変更されたバージョンの表記は email パッケージのバージョンではなく 、Pythonのバージョンです。このテーブルは Python の各バージョン間の email パッケージの互換性も示しています。

email バージョン | 配布 | 互換
1.x | Python 2.2.0 to Python 2.2.1 | もうサポートされません
2.5 | Python 2.2.2+ and Python 2.3 | Python 2.1 から 2.5
3.0 | Python 2.4 | Python 2.3 から 2.5
4.0 | Python 2.5 | Python 2.3 から 2.5

以下は email バージョン4と3の間のおもな差分です。

全モジュールが PEP 8 [http://www.python.org/dev/peps/pep-0008] 標準にあわせてリネームされました。たとえば、version 3 でのモジュール email.Message は version 4 では email.message になりました。

新しいサブパッケージ email.mime が追加され、 version 3 の email.MIME* は、 email.mime のサブパッケージにまとめられました。たとえば、version 3 での email.MIMEText は、 email.mime.text になりました。

Python 2.6までは version 3 の名前も有効です。

email.mime.application モジュールが追加されました。これは MIMEApplication クラスを含んでいます。

version 3 で推奨されないとされた機能は削除されました。これらは Generator.__call__(), Message.get_type(), Message.get_main_type(), Message.get_subtype() を含みます。

RFC 2331 [http://tools.ietf.org/html/rfc2331.html] サポートの修正が追加されました。これは Message.get_param() などの関数の返り値を変更します。いくつかの環境では、3つ組のタプルで返されていた値が1つの文字列で返されます (とくに、全ての拡張パラメータセグメントがエンコードされていなかった場合、予測されていた language や charset の指定がないと、返り値は単純な文字列になります)。過去の版では % デコードがエンコードされているセグメントおよびエンコードされていないセグメントに対して行われましたが、エンコードされたセグメントのみで行われるようになりました。

email バージョン 3 とバージョン 2 との違いは以下のようなものです:

FeedParser クラスが新しく導入され、 Parser クラスは FeedParser を使って実装されるようになりました。このパーザは non-strict なものであり、解析はベストエフォート方式でおこなわれ解析中に例外を発生させることはありません。解析中に発見された問題はそのメッセージの defect (障害) 属性に保存されます。

バージョン 2 で DeprecationWarning を発生していた API はすべて撤去されました。以下のものが含まれています: MIMEText コンストラクタに渡す引数 _encoder 、 Message.add_payload() メソッド、 Utils.dump_address_pair() 関数、そして Utils.decode() と Utils.encode() です。

新しく以下の関数が DeprecationWarning を発生するようになりました: Generator.__call__(), Message.get_type(), Message.get_main_type(), Message.get_subtype(), そして Parser クラスに対する strict 引数です。これらは email の将来のバージョンで撤去される予定です。

Python 2.3 以前はサポートされなくなりました。

email バージョン 2 とバージョン 1 との違いは以下のようなものです:

email.Header モジュールおよび email.Charset モジュールが追加されています。

Message インスタンスの Pickle 形式が変わりました。が、これは正式に定義されたことは一度もないので (そしてこれからも)、この変更は互換性の欠如とはみなされていません。ですがもしお使いのアプリケーションが Message インスタンスを pickle あるいは unpickle しているなら、現在 email バージョン 2 ではプライベート変数 _charset および _default_type を含むようになったということに注意してください。

Message クラス中のいくつかのメソッドは推奨されなくなったか、あるいは呼び出し形式が変更になっています。また、多くの新しいメソッドが追加されています。詳しくは Message クラスの文書を参照してください。これらの変更は完全に下位互換になっているはずです。

message/rfc822 形式のコンテナは、見た目上のオブジェクト構造が変わりました。 email バージョン 1 ではこの content type はスカラー形式のペイロードとして表現されていました。つまり、コンテナメッセージの is_multipart() は false を返し、 get_payload() はリストオブジェクトではなく単一の Message インスタンスを直接返すようになっていたのです。

この構造はパッケージ中のほかの部分と整合がとれていなかったため、 message/rfc822 形式のオブジェクト表現形式が変更されました。 email バージョン 2 では、コンテナは is_multipart() に True を返し ます。また get_payload() はひとつの Message インスタンスを要素とするリストを返すようになりました。

注意: ここは下位互換が完全には成りたたなくなっている部分のひとつです。けれどもあらかじめ get_payload() が返すタイプをチェックするようになっていれば問題にはなりません。ただ message/rfc822 形式のコンテナを Message インスタンスにじかに set_payload() しないようにさえすればよいのです。

Parser コンストラクタに strict 引数が追加され、 parse() および parsestr() メソッドには headersonly 引数がつきました。 strict フラグはまた email.message_from_file() と email.message_from_string() にも追加されています。

Generator.__call__() はもはや推奨されなくなりました。かわりに Generator.flatten() を使ってください。また、 Generator クラスには clone() メソッドが追加されています。

email.generator モジュールに DecodedGenerator クラスが加わりました。

中間的な基底クラスである MIMENonMultipart および MIMEMultipart がクラス階層の中に追加され、ほとんどの MIME 関係の派生クラスがこれを介するようになっています。

MIMEText コンストラクタの _encoder 引数は推奨されなくなりました。いまやエンコーダは _charset 引数にもとづいて暗黙のうちに決定されます。

email.utils モジュールにおける以下の関数は推奨されなくなりました: dump_address_pairs(), decode(), および encode() 。また、このモジュールには以下の関数が追加されています: make_msgid(), decode_rfc2231(), encode_rfc2231() そして decode_params() 。

Public ではない関数 email.iterators._structure() が追加されました。

18.1.13. mimelib との違い

email パッケージはもともと mimelib [http://mimelib.sf.net/] と呼ばれる個別のライブラリからつくられたものです。その後変更が加えられ、メソッド名がより一貫したものになり、いくつかのメソッドやモジュールが加えられたりはずされたりしました。いくつかのメソッドでは、その意味も変更されています。しかしほとんどの部分において、 mimelib パッケージで使うことのできた機能は、ときどきその方法が変わってはいるものの email パッケージでも使用可能です。 mimelib パッケージと email パッケージの間の下位互換性はあまり優先はされませんでした。

以下では mimelib パッケージと email パッケージにおける違いを簡単に説明し、それに沿ってアプリケーションを移植するさいの指針を述べています。

おそらく 2つのパッケージのもっとも明らかな違いは、パッケージ名が email に変更されたことでしょう。さらにトップレベルのパッケージが以下のように変更されました:

messageFromString() は message_from_string() に名前が変更されました。

messageFromFile() は message_from_file() に名前が変更されました。

Message クラスでは、以下のような違いがあります:

asString() メソッドは as_string() に名前が変更されました。

ismultipart() メソッドは is_multipart() に名前が変更されました。

get_payload() メソッドはオプション引数として decode をとるようになりました。

getall() メソッドは get_all() に名前が変更されました。

addheader() メソッドは add_header() に名前が変更されました。

gettype() メソッドは get_type() に名前が変更されました。

getmaintype() メソッドは get_main_type() に名前が変更されました。

getsubtype() メソッドは get_subtype() に名前が変更されました。

getparams() メソッドは get_params() に名前が変更されました。また、従来の getparams() は文字列のリストを返していましたが、 get_params() は 2-タプルのリストを返すようになっています。これはそのパラメータのキーと値の組が、 '=' 記号によって分離されたものです。

getparam() メソッドは get_param().

getcharsets() メソッドは get_charsets() に名前が変更されました。

getfilename() メソッドは get_filename() に名前が変更されました。

getboundary() メソッドは get_boundary() に名前が変更されました。

setboundary() メソッドは set_boundary() に名前が変更されました。

getdecodedpayload() メソッドは廃止されました。これと同様の機能は get_payload() メソッドの decode フラグに 1 を渡すことで実現できます。

getpayloadastext() メソッドは廃止されました。これと同様の機能は email.Generator モジュールの DecodedGenerator クラスによって提供されます。

getbodyastext() メソッドは廃止されました。これと同様の機能は email.iterators モジュールにある typed_subpart_iterator() を使ってイテレータを作ることにより実現できます。

Parser クラスは、その public なインターフェイスは変わっていませんが、これはより一層かしこくなって message/delivery-status 形式のメッセージを認識するようになりました。これは配送状態通知 [1] において、各ヘッダブロックを表す独立した Message パートを含むひとつの Message インスタンスとして表現されます。

Generator クラスは、その public なインターフェイスは変わっていませんが、 email.generator モジュールに新しいクラスが加わりました。 DecodedGenerator と呼ばれるこのクラスは以前 Message.getpayloadastext() メソッドで使われていた機能のほとんどを提供します。

また、以下のモジュールおよびクラスが変更されています:

MIMEBase クラスのコンストラクタ引数 _major と _minor は、それぞれ _maintype と _subtype に変更されています。

Image クラスおよびモジュールは MIMEImage に名前が変更されました。 _minor 引数も _subtype に名前が変更されています。

Text クラスおよびモジュールは MIMEText に名前が変更されました。 _minor 引数も _subtype に名前が変更されています。

MessageRFC822 クラスおよびモジュールは MIMEMessage に名前が変更されました。注意: 従来バージョンの mimelib では、このクラスおよびモジュールは RFC822 という名前でしたが、これは大文字小文字を区別しないファイルシステムでは Python の標準ライブラリモジュール rfc822 と名前がかち合ってしまっていました。

また、 MIMEMessage クラスはいまや message main type をもつあらゆる種類の MIME メッセージを表現できるようになりました。これはオプション引数として、MIME subtype を指定する _subtype 引数をとることができるようになっています。デフォルトでは、 _subtype は rfc822 になります。

mimelib では、 address および date モジュールでいくつかのユーティリティ関数が提供されていました。これらの関数はすべて email.utils モジュールの中に移されています。

MsgReader クラスおよびモジュールは廃止されました。これにもっとも近い機能は email.iterators モジュール中の body_line_iterator() 関数によって提供されています。

注記

[1]
配送状態通知 (Delivery Status Notifications, DSN) は RFC 1894 [http://tools.ietf.org/html/rfc1894.html] によって定義されています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.1. email: 電子メールメッセージの表現

Message クラスは、 email パッケージの中心となるクラスです。これは email オブジェクトモデルの基底クラスになっています。 Message はヘッダフィールドを検索したりメッセージ本体にアクセスするための核となる機能を提供します。

概念的には、(email.message モジュールからインポートされる) Message オブジェクトには ヘッダ と ペイロード が格納されています。ヘッダは、 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 形式のフィールド名およびフィールド値がコロンで区切られたものです。コロンはフィールド名またはフィールド値のどちらにも含まれません。

ヘッダは大文字小文字を区別した形式で保存されますが、ヘッダ名が一致するかどうかの検査は大文字小文字を区別せずにおこなうことができます。 Unix-From ヘッダまたは From_ ヘッダとして知られるエンベロープヘッダがひとつ存在することもあります。ペイロードは、単純なメッセージオブジェクトの場合は単なる文字列ですが、 MIME コンテナ文書 (multipart/* または message/rfc822 など) の場合は Message オブジェクトのリストになっています。

Message オブジェクトは、メッセージヘッダにアクセスするためのマップ (辞書) 形式のインタフェイスと、ヘッダおよびペイロードの両方にアクセスするための明示的なインタフェイスを提供します。これにはメッセージオブジェクトツリーからフラットなテキスト文書を生成したり、一般的に使われるヘッダのパラメータにアクセスしたり、またオブジェクトツリーを再帰的にたどったりするための便利なメソッドを含みます。

Message クラスのメソッドは以下のとおりです:

class email.message.Message

コンストラクタは引数をとりません。

as_string([unixfrom])

メッセージ全体をフラットな文字列として返します。オプション unixfrom が True の場合、返される文字列にはエンベロープヘッダも含まれます。 unixfrom のデフォルトは False です。もし、文字列への変換を完全に行うためにデフォルト値を埋める必要がある場合、メッセージのフラット化は Message の変更を引き起こす可能性があります (例えば、MIME の境界が生成される、変更される等)。

このメソッドは手軽に利用する事ができますが、必ずしも期待通りにメッセージをフォーマットするとは限りません。たとえば、これはデフォルトでは From で始まる行を変更してしまいます。以下の例のように Generator のインスタンスを生成して flatten() メソッドを直接呼び出せばより柔軟な処理を行う事ができます。

from cStringIO import StringIO
from email.generator import Generator
fp = StringIO()
g = Generator(fp, mangle_from_=False, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

__str__()

as_string(unixfrom=True)() と同じです。

is_multipart()

メッセージのペイロードが子 Message オブジェクトからなるリストであれば True を返し、そうでなければ False を返します。 is_multipart() が False を返した場合は、ペイロードは文字列オブジェクトである必要があります。

set_unixfrom(unixfrom)

メッセージのエンベロープヘッダを unixfrom に設定します。これは文字列である必要があります。

get_unixfrom()

メッセージのエンベロープヘッダを返します。エンベロープヘッダが設定されていない場合は None が返されます。

attach(payload)

与えられた payload を現在のペイロードに追加します。この時点でのペイロードは None か、あるいは Message オブジェクトのリストである必要があります。このメソッドの実行後、ペイロードは必ず Message オブジェクトのリストになります。ペイロードにスカラーオブジェクト (文字列など) を格納したい場合は、かわりに set_payload() を使ってください。

get_payload([i[, decode]])

現在のペイロードへの参照を返します。これは is_multipart() が True の場合 Message オブジェクトのリストになり、 is_multipart() が False の場合は文字列になります。ペイロードがリストの場合、リストを変更することはそのメッセージのペイロードを変更することになります。

オプション引数の i がある場合、 is_multipart() が True ならば get_payload() はペイロード中で 0 から数えて i 番目の要素を返します。 i が 0 より小さい場合、あるいはペイロードの個数以上の場合は IndexError が発生します。ペイロードが文字列 (つまり is_multipart() が False) にもかかわらず i が与えられたときは TypeError が発生します。

オプションの decode はそのペイロードが Content-Transfer-Encoding ヘッダに従ってデコードされるべきかどうかを指示するフラグです。この値が True でメッセージが multipart ではない場合、ペイロードはこのヘッダの値が quoted-printable または base64 のときにかぎりデコードされます。これ以外のエンコーディングが使われている場合、 Content-Transfer-Encoding ヘッダがない場合、あるいは曖昧なbase64データが含まれる場合は、ペイロードはそのまま (デコードされずに) 返されます。もしメッセージが multipart で decode フラグが True の場合は None が返されます。 decode のデフォルト値は False です。

set_payload(payload[, charset])

メッセージ全体のオブジェクトのペイロードを payload に設定します。ペイロードの形式をととのえるのは呼び出し側の責任です。オプションの charset はメッセージのデフォルト文字セットを設定します。詳しくは set_charset() を参照してください。

バージョン 2.2.2 で変更: charset 引数の追加.

set_charset(charset)

ペイロードの文字セットを charset に変更します。ここには Charset インスタンス (email.charset 参照)、文字セット名をあらわす文字列、あるいは None のいずれかが指定できます。文字列を指定した場合、これは Charset インスタンスに変換されます。 charset が None の場合、 charset パラメータは Content-Type ヘッダから除去されます (それ以外にメッセージの変形は行われません)。これ以外のものを文字セットとして指定した場合、 TypeError が発生します。

MIME-Version ヘッダが存在しなければ、追加されます。 Content-Type ヘッダが存在しなければ、 text/plain を値として追加されます。 Content-Type が存在していてもいなくても、 charset パラメタは charset.output_charset に設定されます。 charset.input_charset と charset.output_charset が異なるなら、ペイロードは output_charset に再エンコードされます。 Content-Transfer-Encoding ヘッダが存在しなければ、ペイロードは、必要なら指定された Charset を使って transfer エンコードされ、適切な値のヘッダが追加されます。 Content-Transfer-Encoding ヘッダがすでに存在すれば、ペイロードはすでにその Content-Transfer-Encoding によって正しくエンコードされたものと見なされ、変形されません。

ここでいうメッセージとは、unicode 文字列か charset.input_charset でエンコードされたペイロードを持つ text/* 形式のものを仮定しています。これは、もし必要とあらばプレーンテキスト形式を変換するさいに charset.output_charset のトランスファーエンコードに変換されます。MIME ヘッダ (MIME-Version, Content-Type, Content-Transfer-Encoding) は必要に応じて追加されます。

バージョン 2.2.2 で追加.

get_charset()

そのメッセージ中のペイロードの Charset インスタンスを返します。

バージョン 2.2.2 で追加.

以下のメソッドは、メッセージの RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダにアクセスするためのマップ (辞書) 形式のインタフェイスを実装したものです。これらのメソッドと、通常のマップ (辞書) 型はまったく同じ意味をもつわけではないことに注意してください。たとえば辞書型では、同じキーが複数あることは許されていませんが、ここでは同じメッセージヘッダが複数ある場合があります。また、辞書型では keys() で返されるキーの順序は保証されていませんが、 Message オブジェクト内のヘッダはつねに元のメッセージ中に現れた順序、あるいはそのあとに追加された順序で返されます。削除され、その後ふたたび追加されたヘッダはリストの一番最後に現れます。

こういった意味のちがいは意図的なもので、最大の利便性をもつようにつくられています。

注意: どんな場合も、メッセージ中のエンベロープヘッダはこのマップ形式のインタフェイスには含まれません。

__len__()

複製されたものもふくめてヘッダ数の合計を返します。

__contains__(name)

メッセージオブジェクトが name という名前のフィールドを持っていれば true を返します。この検査では名前の大文字小文字は区別されません。 name は最後にコロンをふくんでいてはいけません。このメソッドは以下のように in 演算子で使われます:

if 'message-id' in myMessage:
    print 'Message-ID:', myMessage['message-id']

__getitem__(name)

指定された名前のヘッダフィールドの値を返します。 name は最後にコロンをふくんでいてはいけません。そのヘッダがない場合は None が返され、 KeyError 例外は発生しません。

注意: 指定された名前のフィールドがメッセージのヘッダに2回以上現れている場合、どちらの値が返されるかは未定義です。ヘッダに存在するフィールドの値をすべて取り出したい場合は get_all() メソッドを使ってください。

__setitem__(name, val)

メッセージヘッダに name という名前の val という値をもつフィールドをあらたに追加します。このフィールドは現在メッセージに存在するフィールドのいちばん後に追加されます。

注意: このメソッドでは、すでに同一の名前で存在するフィールドは上書き されません 。もしメッセージが名前 name をもつフィールドをひとつしか持たないようにしたければ、最初にそれを除去してください。たとえば:

del msg['subject']
msg['subject'] = 'PythonPythonPython!'

__delitem__(name)

メッセージのヘッダから、 name という名前をもつフィールドをすべて除去します。たとえこの名前をもつヘッダが存在していなくても例外は発生しません。

has_key(name)

メッセージが name という名前をもつヘッダフィールドを持っていれば真を、そうでなければ偽を返します。

keys()

メッセージ中にあるすべてのヘッダのフィールド名のリストを返します。

values()

メッセージ中にあるすべてのフィールドの値のリストを返します。

items()

メッセージ中にあるすべてのヘッダのフィールド名とその値を 2-タプルのリストとして返します。

get(name[, failobj])

指定された名前をもつフィールドの値を返します。これは指定された名前がないときにオプション引数の failobj (デフォルトでは None) を返すことをのぞけば、 __getitem__() と同じです。

さらに、役に立つメソッドをいくつか紹介します:

get_all(name[, failobj])

name の名前をもつフィールドのすべての値からなるリストを返します。該当する名前のヘッダがメッセージ中に含まれていない場合は failobj (デフォルトでは None) が返されます。

add_header(_name, _value, **_params)

拡張ヘッダ設定。このメソッドは __setitem__() と似ていますが、追加のヘッダ・パラメータをキーワード引数で指定できるところが違っています。 _name に追加するヘッダフィールドを、 _value にそのヘッダの最初の 値を渡します。

キーワード引数辞書 _params の各項目ごとに、そのキーがパラメータ名として扱われ、キー名にふくまれるアンダースコアはハイフンに置換されます (なぜならハイフンは通常の Python 識別子としては使えないからです)。ふつう、パラメータの値が None 以外のときは、 key="value" の形で追加されます。パラメータの値が None のときはキーのみが追加されます。値が非 ASCII 文字を含むなら、それは (CHARSET, LANGUAGE, VALUE) の形式の 3 タプルでなくてはなりません。ここで CHARSET はその値をエンコードするのに使われる文字セットを指名する文字列で、 LANGUAGE は通常 None か空文字列にでき (その他の可能性は RFC 2231 [http://tools.ietf.org/html/rfc2231.html] を参照してください)、 VALUE は非 ASCII コードポイントを含む文字列値です。

例を示しましょう:

msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

こうするとヘッダには以下のように追加されます。

Content-Disposition: attachment; filename="bud.gif"

非 ASCII 文字を使った例:

msg.add_header('Content-Disposition', 'attachment',
               filename=('iso-8859-1', '', 'Fußballer.ppt'))

は、以下のようになります:

Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"

replace_header(_name, _value)

ヘッダの置換。 _name と一致するヘッダで最初に見つかったものを置き換えます。このときヘッダの順序とフィールド名の大文字小文字は保存されます。一致するヘッダがない場合、 KeyError が発生します。

バージョン 2.2.2 で追加.

get_content_type()

そのメッセージの content-type を返します。返された文字列は強制的に小文字で maintype/subtype の形式に変換されます。メッセージ中に Content-Type ヘッダがない場合、デフォルトの content-type は get_default_type() が返す値によって与えられます。 RFC 2045 [http://tools.ietf.org/html/rfc2045.html] によればメッセージはつねにデフォルトの content-type をもっているので、 get_content_type() はつねになんらかの値を返すはずです。

RFC 2045 [http://tools.ietf.org/html/rfc2045.html] はメッセージのデフォルト content-type を、それが multipart/digest コンテナに現れているとき以外は text/plain に規定しています。あるメッセージが multipart/digest コンテナ中にある場合、その content-type は message/rfc822 になります。もし Content-Type ヘッダが適切でない content-type 書式だった場合、 RFC 2045 [http://tools.ietf.org/html/rfc2045.html] はそれのデフォルトを text/plain として扱うよう定めています。

バージョン 2.2.2 で追加.

get_content_maintype()

そのメッセージの主 content-type を返します。これは get_content_type() によって返される文字列の maintype 部分です。

バージョン 2.2.2 で追加.

get_content_subtype()

そのメッセージの副 content-type (sub content-type、subtype) を返します。これは get_content_type() によって返される文字列の subtype 部分です。

バージョン 2.2.2 で追加.

get_default_type()

デフォルトの content-type を返します。ほどんどのメッセージではデフォルトの content-type は text/plain ですが、メッセージが multipart/digest コンテナに含まれているときだけ例外的に message/rfc822 になります。

バージョン 2.2.2 で追加.

set_default_type(ctype)

デフォルトの content-type を設定します。 ctype は text/plain あるいは message/rfc822 である必要がありますが、強制ではありません。デフォルトの content-type はヘッダの Content-Type には格納されません。

バージョン 2.2.2 で追加.

get_params([failobj[, header[, unquote]]])

メッセージの Content-Type パラメータをリストとして返します。返されるリストはキー/値の組からなる2要素タプルが連なったものであり、これらは '=' 記号で分離されています。 '=' の左側はキーになり、右側は値になります。パラメータ中に '=' がなかった場合、値の部分は空文字列になり、そうでなければその値は get_param() で説明されている形式になります。また、オプション引数 unquote が True (デフォルト) である場合、この値は unquote されます。

オプション引数 failobj は、 Content-Type ヘッダが存在しなかった場合に返すオブジェクトです。オプション引数 header には Content-Type のかわりに検索すべきヘッダを指定します。

バージョン 2.2.2 で変更: unquote が追加されました.

get_param(param[, failobj[, header[, unquote]]])

メッセージの Content-Type ヘッダ中のパラメータ param を文字列として返します。そのメッセージ中に Content-Type ヘッダが存在しなかった場合、 failobj (デフォルトは None) が返されます。

オプション引数 header が与えられた場合、 Content-Type のかわりにそのヘッダが使用されます。

パラメータのキー比較は常に大文字小文字を区別しません。返り値は文字列か 3 要素のタプルで、タプルになるのはパラメータが RFC 2231 [http://tools.ietf.org/html/rfc2231.html] エンコードされている場合です。3 要素タプルの場合、各要素の値は (CHARSET, LANGUAGE, VALUE) の形式になっています。 CHARSET と LAGUAGE は None になることがあり、その場合 VALUE は us-ascii 文字セットでエンコードされているとみなさねばならないので注意してください。普段は LANGUAGE を無視できます。

この関数を使うアプリケーションが、パラメータが RFC 2231 [http://tools.ietf.org/html/rfc2231.html] 形式でエンコードされているかどうかを気にしないのであれば、 email.utils.collapse_rfc2231_value() に get_param() の返り値を渡して呼び出すことで、このパラメータをひとつにまとめることができます。この値がタプルならばこの関数は適切にデコードされた Unicode 文字列を返し、そうでない場合は unquote された元の文字列を返します。たとえば:

rawparam = msg.get_param('foo')
param = email.utils.collapse_rfc2231_value(rawparam)

いずれの場合もパラメータの値は (文字列であれ3要素タプルの VALUE 項目であれ) つねに unquote されます。ただし、 unquote が False に指定されている場合は unquote されません。

バージョン 2.2.2 で変更: unquote 引数の追加、3要素タプルが返り値になる可能性あり。

set_param(param, value[, header[, requote[, charset[, language]]]])

Content-Type ヘッダ中のパラメータを設定します。指定されたパラメータがヘッダ中にすでに存在する場合、その値は value に置き換えられます。 Content-Type ヘッダがまだこのメッセージ中に存在していない場合、 RFC 2045 [http://tools.ietf.org/html/rfc2045.html] にしたがいこの値には text/plain が設定され、新しいパラメータ値が末尾に追加されます。

オプション引数 header が与えられた場合、 Content-Type のかわりにそのヘッダが使用されます。オプション引数 unquote が False でない限り、この値は unquote されます (デフォルトは True)。

オプション引数 charset が与えられると、そのパラメータは RFC 2231 [http://tools.ietf.org/html/rfc2231.html] に従ってエンコードされます。オプション引数 language は RFC 2231 の言語を指定しますが、デフォルトではこれは空文字列となります。 charset と language はどちらも文字列である必要があります。

バージョン 2.2.2 で追加.

del_param(param[, header[, requote]])

指定されたパラメータを Content-Type ヘッダ中から完全にとりのぞきます。ヘッダはそのパラメータと値がない状態に書き換えられます。 requote が False でない限り (デフォルトでは True です)、すべての値は必要に応じて quote されます。オプション変数 header が与えられた場合、 Content-Type のかわりにそのヘッダが使用されます。

バージョン 2.2.2 で追加.

set_type(type[, header][, requote])

Content-Type ヘッダの maintype と subtype を設定します。 type は maintype/subtype という形の文字列でなければなりません。それ以外の場合は ValueError が発生します。

このメソッドは Content-Type ヘッダを置き換えますが、すべてのパラメータはそのままにします。 requote が False の場合、これはすでに存在するヘッダを quote せず放置しますが、そうでない場合は自動的に quote します (デフォルト動作)。

オプション変数 header が与えられた場合、 Content-Type のかわりにそのヘッダが使用されます。 Content-Type ヘッダが設定される場合には、 MIME-Version ヘッダも同時に付加されます。

バージョン 2.2.2 で追加.

get_filename([failobj])

そのメッセージ中の Content-Disposition ヘッダにある、 filename パラメータの値を返します。目的のヘッダに filename パラメータがない場合には Content-Type ヘッダにある name パラメータを探します。それも無い場合またはヘッダが無い場合には failobj が返されます。返される文字列はつねに email.utils.unquote() によって unquote されます。

get_boundary([failobj])

そのメッセージ中の Content-Type ヘッダにある、 boundary パラメータの値を返します。目的のヘッダが欠けていたり、 boundary パラメータがない場合には failobj が返されます。返される文字列はつねに email.utils.unquote() によって unquote されます。

set_boundary(boundary)

メッセージ中の Content-Type ヘッダにある、 boundary パラメータに値を設定します。 set_boundary() は必要に応じて boundary を quote します。そのメッセージが Content-Type ヘッダを含んでいない場合、 HeaderParseError が発生します。

注意: このメソッドを使うのは、古い Content-Type ヘッダを削除して新しい boundary をもったヘッダを add_header() で足すのとは少し違います。 set_boundary() は一連のヘッダ中での Content-Type ヘッダの位置を保つからです。しかし、これは元の Content-Type ヘッダ中に存在していた連続する行の順番までは 保ちません 。

get_content_charset([failobj])

そのメッセージ中の Content-Type ヘッダにある、 charset パラメータの値を返します。値はすべて小文字に変換されます。メッセージ中に Content-Type がなかったり、このヘッダ中に boundary パラメータがない場合には failobj が返されます。

注意: これは get_charset() メソッドとは異なります。こちらのほうは文字列のかわりに、そのメッセージボディのデフォルトエンコーディングの Charset インスタンスを返します。

バージョン 2.2.2 で追加.

get_charsets([failobj])

メッセージ中に含まれる文字セットの名前をすべてリストにして返します。そのメッセージが multipart である場合、返されるリストの各要素がそれぞれの subpart のペイロードに対応します。それ以外の場合、これは長さ 1 のリストを返します。

リスト中の各要素は文字列であり、これは対応する subpart 中のそれぞれの Content-Type ヘッダにある charset の値です。しかし、その subpart が Content-Type をもってないか、 charset がないか、あるいは MIME maintype が text でないいずれかの場合には、リストの要素として failobj が返されます。

walk()

walk() メソッドは多目的のジェネレータで、これはあるメッセージオブジェクトツリー中のすべての part および subpart をわたり歩くのに使えます。順序は深さ優先です。おそらく典型的な用法は、 walk() を for ループ中でのイテレータとして使うことでしょう。ループを一回まわるごとに、次の subpart が返されるのです。

以下の例は、 multipart メッセージのすべての part において、その MIME タイプを表示していくものです。

>>> for part in msg.walk():
...     print part.get_content_type()
multipart/report
text/plain
message/delivery-status
text/plain
text/plain
message/rfc822

バージョン 2.5 で変更: 以前の非推奨メソッド get_type() 、 get_main_type() 、 get_subtype() は削除されました。

Message オブジェクトはオプションとして 2つのインスタンス属性をとることができます。これはある MIME メッセージからプレーンテキストを生成するのに使うことができます。

preamble

MIME ドキュメントの形式では、ヘッダ直後にくる空行と最初の multipart 境界をあらわす文字列のあいだにいくらかのテキスト (訳注: preamble, 序文) を埋めこむことを許しています。このテキストは標準的な MIME の範疇からはみ出しているので、 MIME 形式を認識するメールソフトからこれらは通常まったく見えません。しかしメッセージのテキストを生で見る場合、あるいはメッセージを MIME 対応していないメールソフトで見る場合、このテキストは目に見えることになります。

preamble 属性は MIME ドキュメントに加えるこの最初の MIME 範囲外テキストを含んでいます。 Parser があるテキストをヘッダ以降に発見したが、それはまだ最初の MIME 境界文字列が現れる前だった場合、パーザはそのテキストをメッセージの preamble 属性に格納します。 Generator がある MIME メッセージからプレーンテキスト形式を生成するとき、これはそのテキストをヘッダと最初の MIME 境界の間に挿入します。詳細は email.parser および email.Generator を参照してください。

注意: そのメッセージに preamble がない場合、 preamble 属性には None が格納されます。

epilogue

epilogue 属性はメッセージの最後の MIME 境界文字列からメッセージ末尾までのテキストを含むもので、それ以外は preamble 属性と同じです。

バージョン 2.5 で変更: Generator でファイル終端に改行を出力するため、 epilogue に空文字列を設定する必要はなくなりました。

defects

defects 属性はメッセージを解析する途中で検出されたすべての問題点 (defect、障害) のリストを保持しています。解析中に発見されうる障害についてのより詳細な説明は email.errors を参照してください。

バージョン 2.4 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.2. email: 電子メールメッセージを解析(パース)する

メッセージオブジェクト構造体をつくるには 2つの方法があります。ひとつはまったくのスクラッチから Message を生成して、これを attach() と set_payload() 呼び出しを介してつなげていく方法で、もうひとつは電子メールメッセージのフラットなテキスト表現を解析 (parse、パーズ) する方法です。

email パッケージでは、MIME 文書をふくむ、ほとんどの電子メールの文書構造に対応できる標準的なパーザ (解析器) を提供しています。このパーザに文字列あるいはファイルオブジェクトを渡せば、パーザはそのオブジェクト構造の基底となる (root の) Message インスタンスを返します。簡単な非MIMEメッセージであれば、この基底オブジェクトのペイロードはたんにメッセージのテキストを格納する文字列になるでしょう。 MIMEメッセージであれば、基底オブジェクトはその is_multipart() メソッドに対して True を返します。そして、その各 subpart に get_payload() メソッドおよび walk() メソッドを介してアクセスすることができます。

実際には 2つのパーザインターフェイスが使用可能です。ひとつは旧式の Parser API であり、もうひとつはインクリメンタルな FeedParser API です。旧式の Parser API はメッセージ全体のテキストが文字列としてすでにメモリ上にあるか、それがローカルなファイルシステム上に存在しているときには問題ありません。 FeedParser はメッセージを読み込むときに、そのストリームが入力待ちのためにブロックされるような場合 (ソケットから email メッセージを読み込む時など) に、より有効です。 FeedParser はインクリメンタルにメッセージを読み込み、解析します。パーザを close したときには根っこ (root) のオブジェクトのみが返されます [1] 。

このパーザは、ある制限された方法で拡張できます。また、もちろん自分でご自分のパーザを完全に無から実装することもできます。 email パッケージについているパーザと Message クラスの間に隠された秘密の関係はなにもありませんので、ご自分で実装されたパーザも、それが必要とするやりかたでメッセージオブジェクトツリーを作成することができます。

18.1.2.1. FeedParser API

バージョン 2.4 で追加.

email.feedparser モジュールからインポートされる FeedParser は email メッセージをインクリメンタルに解析するのに向いた API を提供します。これは email メッセージのテキストを (ソケットなどの) 読み込みがブロックされる可能性のある情報源から入力するときに必要となります。もちろん FeedParser は文字列またはファイルにすべて格納されている email メッセージを解析するのにも使うことができますが、このような場合には旧式の Parser API のほうが便利かもしれません。これら 2つのパーザ API の意味論と得られる結果は同一です。

FeedParser API は簡単です。まずインスタンスをつくり、それにテキストを (それ以上テキストが必要なくなるまで) 流しこみます。その後パーザを close すると根っこ (root) のメッセージオブジェクトが返されます。標準に従ったメッセージを解析する場合、 FeedParser は非常に正確であり、標準に従っていないメッセージでもちゃんと動きます。そのさい、これはメッセージがどのように壊れていると認識されたかについての情報を残します。これはメッセージオブジェクトの defects 属性にリストとして現れ、メッセージ中に発見された問題が記録されます。パーザが検出できる障害 (defect) については email.errors モジュールを参照してください。

以下は FeedParser の API です:

class email.parser.FeedParser([_factory])

FeedParser インスタンスを作成します。オプション引数 _factory には引数なしの callable を指定し、これはつねに新しいメッセージオブジェクトの作成が必要になったときに呼び出されます。デフォルトでは、これは email.message.Message クラスになっています。

feed(data)

FeedParser にデータを供給します。 data は 1行または複数行からなる文字列を渡します。渡される行は完結していなくてもよく、その場合 FeedParser は部分的な行を適切につなぎ合わせます。文字列中の各行は標準的な 3種類の行末文字 (復帰 CR、改行 LF、または CR+LF) どれかの組み合わせでよく、これらが混在してもかまいません。

close()

FeedParser を close し、それまでに渡されたすべてのデータの解析を完了させ根っこ (root) のメッセージオブジェクトを返します。 FeedParser を close したあとにさらにデータを feed した場合の挙動は未定義です。

18.1.2.2. Parser クラス API

email.parser モジュールからインポートされる Parser クラスは、メッセージを表すテキストが文字列またはファイルの形で完全に使用可能なときメッセージを解析するのに使われる API を提供します。 email.Parser モジュールはまた、 HeaderParser と呼ばれる2番目のクラスも提供しています。これはメッセージのヘッダのみを処理したい場合に使うことができ、ずっと高速な処理がおこなえます。なぜならこれはメッセージ本体を解析しようとはしないからです。かわりに、そのペイロードにはメッセージ本体の生の文字列が格納されます。 HeaderParser クラスは Parser クラスと同じ API をもっています。

class email.parser.Parser([_class])

Parser クラスのコンストラクタです。オプション引数 _class をとることができます。これは呼び出し可能なオブジェクト (関数やクラス) でなければならず、メッセージ内コンポーネント (sub-message object) が作成されるときは常にそのファクトリクラスとして使用されます。デフォルトではこれは Message になっています (email.message 参照)。このファクトリクラスは引数なしで呼び出されます。

オプション引数 strict は無視されます。

バージョン 2.4 で撤廃: Parser は Python 2.4 で新しく導入された FeedParser の後方互換性のための API ラッパで、 すべての 解析が事実上 non-strict です。 Parser コンストラクタに strict フラグを渡す必要はありません。

バージョン 2.2.2 で変更: strict フラグが追加されました.

バージョン 2.4 で変更: strict フラグは推奨されなくなりました.

それ以外の Parser メソッドは以下のとおりです:

parse(fp[, headersonly])

ファイルなどストリーム形式 [2] のオブジェクト fp からすべてのデータを読み込み、得られたテキストを解析して基底 (root) メッセージオブジェクト構造を返します。 fp はストリーム形式のオブジェクトで readline() および read() 両方のメソッドをサポートしている必要があります。

fp に格納されているテキスト文字列は、一連の RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 形式のヘッダおよびヘッダ継続行 (header continuation lines) によって構成されている必要があります。オプションとして、最初にエンペローブヘッダが来ることもできます。ヘッダ部分はデータの終端か、ひとつの空行によって終了したとみなされます。ヘッダ部分に続くデータはメッセージ本体となります (MIME エンコードされた subpart を含んでいるかもしれません)。

オプション引数 headersonly はヘッダ部分を解析しただけで終了するか否かを指定します。デフォルトの値は False で、これはそのファイルの内容すべてを解析することを意味しています。

バージョン 2.2.2 で変更: headersonly フラグが追加されました.

parsestr(text[, headersonly])

parse() メソッドに似ていますが、ファイルなどのストリーム形式のかわりに文字列を引数としてとるところが違います。文字列に対してこのメソッドを呼ぶことは、 text を StringIO インスタンスとして作成して parse() を適用するのと同じです。

オプション引数 headersonly は parse() メソッドと同じです。

バージョン 2.2.2 で変更: headersonly フラグが追加されました.

ファイルや文字列からメッセージオブジェクト構造を作成するのはかなりよくおこなわれる作業なので、便宜上次のような 2つの関数が提供されています。これらは email パッケージのトップレベルの名前空間で使用できます。

email.message_from_string(s[, _class[, strict]])

文字列からメッセージオブジェクト構造を作成し返します。これは Parser().parsestr(s) とまったく同じです。オプション引数 _class および strict は Parser クラスのコンストラクタと同様に解釈されます。

バージョン 2.2.2 で変更: strict フラグが追加されました.

email.message_from_file(fp[, _class[, strict]])

Open されたファイルオブジェクトからメッセージオブジェクト構造を作成し返します。これは Parser().parse(fp) とまったく同じです。オプション引数 _class および strict は Parser クラスのコンストラクタと同様に解釈されます。

バージョン 2.2.2 で変更: strict フラグが追加されました.

対話的な Python プロンプトでこの関数を使用するとすれば、このようになります:

>>> import email
>>> msg = email.message_from_string(myString)

18.1.2.3. 追加事項

以下はテキスト解析の際に適用されるいくつかの規約です:

ほとんどの非 multipart 形式のメッセージは単一の文字列ペイロードをもつ単一のメッセージオブジェクトとして解析されます。このオブジェクトは is_multipart() に対して False を返します。このオブジェクトに対する get_payload() メソッドは文字列オブジェクトを返します。

multipart 形式のメッセージはすべてメッセージ内コンポーネント (sub-message object) のリストとして解析されます。外側のコンテナメッセージオブジェクトは is_multipart() に対して True を返し、このオブジェクトに対する get_payload() メソッドは Message subpart のリストを返します。

message/* の Content-Type をもつほとんどのメッセージ (例: message/delivery-status や message/rfc822 など) もコンテナメッセージオブジェクトとして解析されますが、ペイロードのリストの長さは 1 になります。このオブジェクトは is_multipart() メソッドに対して True を返し、リスト内にあるひとつだけの要素がメッセージ内のコンポーネントオブジェクトになります。

いくつかの標準的でないメッセージは、 multipart の使い方に統一がとれていない場合があります。このようなメッセージは Content-Type ヘッダに multipart を指定しているものの、その is_multipart() メソッドは False を返すことがあります。もしこのようなメッセージが FeedParser によって解析されると、その defects 属性のリスト中には MultipartInvariantViolationDefect クラスのインスタンスが現れます。詳しい情報については email.errors を参照してください。

注記

[1]
Python 2.4 から導入された email パッケージバージョン 3.0 では、旧式の Parser は FeedParser によって書き直されました。そのためパーザの意味論と得られる結果は 2つのパーザで同一のものになります。

[2]
file-like object

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.3. email: MIME 文書を生成する

よくある作業のひとつは、メッセージオブジェクト構造からフラットな電子メールテキストを生成することです。この作業は smtplib や nntplib モジュールを使ってメッセージを送信したり、メッセージをコンソールに出力したりするときに必要になります。あるメッセージオブジェクト構造をとってきて、そこからフラットなテキスト文書を生成するのは Generator クラスの仕事です。

繰り返しになりますが、 email.parser モジュールと同じく、この機能は既存の Generator だけに限られるわけではありません。これらはご自身でゼロから作りあげることもできます。しかし、既存のジェネレータはほとんどの電子メールを標準に沿ったやり方で生成する方法を知っていますし、MIME メッセージも非 MIME メッセージも扱えます。さらにこれはフラットなテキストから Parser クラスを使ってメッセージ構造に変換し、それをまたフラットなテキストに戻しても、結果が冪等 [1] になるよう設計されています。一方で、プログラムによって構成された Message の Generator を使う場合、デフォルトの挿入によって Message オブジェクトを変えてしまうかもしれません。

email.generator モジュールからインポートされる Generator クラスで公開されているメソッドには、以下のようなものがあります:

class email.generator.Generator(outfp[, mangle_from_[, maxheaderlen]])

Generator クラスのコンストラクタは outfp と呼ばれるストリーム形式 [2] のオブジェクトひとつを引数にとります。 outfp は write() メソッドをサポートし、 Python 拡張 print 文の出力ファイルとして使えるようになっている必要があります。

オプション引数 mangle_from_ はフラグで、 True のときはメッセージ本体に現れる行頭のすべての From という文字列の最初に > という文字を追加します。これは、このような行が Unix の mailbox 形式のエンペローブヘッダ区切り文字列として誤認識されるのを防ぐための、移植性ある唯一の方法です (詳しくは WHY THE CONTENT-LENGTH FORMAT IS BAD (なぜ Content-Length 形式が有害か) [http://www.jwz.org/doc/content-length.html] を参照してください)。デフォルトでは mangle_from_ は True になっていますが、 Unix の mailbox 形式ファイルに出力しないのならばこれは False に設定してもかまいません。

オプション引数 maxheaderlen は連続していないヘッダの最大長を指定します。ひとつのヘッダ行が maxheaderlen (これは文字数です、tab は空白 8文字に展開されます) よりも長い場合、ヘッダは Header クラスで定義されているように途中で折り返され、間にはセミコロンが挿入されます。もしセミコロンが見つからない場合、そのヘッダは放置されます。ヘッダの折り返しを禁止するにはこの値にゼロを指定してください。デフォルトは 78 文字で、 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] で推奨されている (ですが強制ではありません) 値です。

これ以外のパブリックな Generator メソッドは以下のとおりです:

flatten(msg[, unixfrom])

msg を基点とするメッセージオブジェクト構造体の文字表現を出力します。出力先のファイルにはこの Generator インスタンスが作成されたときに指定されたものが使われます。各 subpart は深さ優先順序 (depth-first) で出力され、得られるテキストは適切に MIME エンコードされたものになっています。

オプション引数 unixfrom は、基点となるメッセージオブジェクトの最初の RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダが現れる前に、エンペローブヘッダ区切り文字列を出力することを強制するフラグです。そのメッセージオブジェクトがエンペローブヘッダをもたない場合、標準的なエンペローブヘッダが自動的に作成されます。デフォルトではこの値は False に設定されており、エンペローブヘッダ区切り文字列は出力されません。

注意: 各 subpart に関しては、エンペローブヘッダは出力されません。

バージョン 2.2.2 で追加.

clone(fp)

この Generator インスタンスの独立したクローンを生成し返します。オプションはすべて同一になっています。

バージョン 2.2.2 で追加.

write(s)

文字列 s を既定のファイルに出力します。ここでいう出力先は Generator コンストラクタに渡した outfp のことをさします。この関数はただ単に拡張 print 文で使われる Generator インスタンスに対してファイル操作風の API を提供するためだけのものです。

ユーザの便宜をはかるため、メソッド Message.as_string() と str(aMessage) (つまり Message.__str__() のことです) をつかえばメッセージオブジェクトを特定の書式でフォーマットされた文字列に簡単に変換することができます。詳細は email.message を参照してください。

email.generator モジュールはひとつの派生クラスも提供しています。これは DecodedGenerator と呼ばれるもので、 Generator 基底クラスと似ていますが、非 text 型の subpart を特定の書式でフォーマットされた表現形式で置きかえるところが違っています。

class email.generator.DecodedGenerator(outfp[, mangle_from_[, maxheaderlen[, fmt]]])

このクラスは Generator から派生したもので、メッセージの subpart をすべて渡り歩きます。subpart の主形式が text だった場合、これはその subpart のペイロードをデコードして出力します。オプション引数 _mangle_from_ および maxheaderlen の意味は基底クラス Generator のそれと同じです。

Subpart の主形式が text ではない場合、オプション引数 fmt がそのメッセージペイロードのかわりのフォーマット文字列として使われます。 fmt は %(keyword)s のような形式を展開し、以下のキーワードを認識します:

type – 非 text 型 subpart の MIME 形式

maintype – 非 text 型 subpart の MIME 主形式 (maintype)

subtype – 非 text 型 subpart の MIME 副形式 (subtype)

filename – 非 text 型 subpart のファイル名

description – 非 text 型 subpart につけられた説明文字列

encoding – 非 text 型 subpart の Content-transfer-encoding

fmt のデフォルト値は None です。こうすると以下の形式で出力します:

[Non-text (%(type)s) part of message omitted, filename %(filename)s]

バージョン 2.2.2 で追加.

バージョン 2.5 で変更: 以前の非推奨メソッド __call__() は削除されました。

注記

[1]
訳注: idempotent、その操作を何回くり返しても 1回だけ行ったのと結果が同じになること。

[2]
訳注: file-like object

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.4. email: 電子メールおよび MIME オブジェクトをゼロから作成する

ふつう、メッセージオブジェクト構造はファイルまたは何がしかのテキストをパーザに通すことで得られます。パーザは与えられたテキストを解析し、基底となる root のメッセージオブジェクトを返します。しかし、完全なメッセージオブジェクト構造を何もないところから作成することもまた可能です。個別の Message を手で作成することさえできます。実際には、すでに存在するメッセージオブジェクト構造をとってきて、そこに新たな Message オブジェクトを追加したり、あるものを別のところへ移動させたりできます。これは MIME メッセージを切ったりおろしたりするために非常に便利なインターフェイスを提供します。

新しいメッセージオブジェクト構造は Message インスタンスを作成することにより作れます。ここに添付ファイルやその他適切なものをすべて手で加えてやればよいのです。MIME メッセージの場合、 email パッケージはこれらを簡単におこなえるようにするためにいくつかの便利なサブクラスを提供しています。

以下がそのサブクラスです:

class email.mime.base.MIMEBase(_maintype, _subtype, **_params)

Module: email.mime.base

これはすべての Message の MIME 用サブクラスの基底となるクラスです。とくに MIMEBase のインスタンスを直接作成することは (可能ではありますが) ふつうはしないでしょう。 MIMEBase は単により特化された MIME 用サブクラスのための便宜的な基底クラスとして提供されています。

_maintype は Content-Type の主形式 (maintype) であり (text や image など)、 _subtype は Content-Type の副形式 (subtype) です (plain や gif など)。 _params は各パラメータのキーと値を格納した辞書であり、これは直接 Message.add_header() に渡されます。

MIMEBase クラスはつねに (_maintype 、 _subtype 、および _params にもとづいた) Content-Type ヘッダと、 MIME-Version ヘッダ (必ず 1.0 に設定される) を追加します。

class email.mime.nonmultipart.MIMENonMultipart

Module: email.mime.nonmultipart

MIMEBase のサブクラスで、これは multipart 形式でない MIME メッセージのための中間的な基底クラスです。このクラスのおもな目的は、通常 multipart 形式のメッセージに対してのみ意味をなす attach() メソッドの使用をふせぐことです。もし attach() メソッドが呼ばれた場合、これは MultipartConversionError 例外を発生します。

バージョン 2.2.2 で追加.

class email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]])

Module: email.mime.multipart

MIMEBase のサブクラスで、これは multipart 形式の MIME メッセージのための中間的な基底クラスです。オプション引数 _subtype はデフォルトでは mixed になっていますが、そのメッセージの副形式 (subtype) を指定するのに使うことができます。メッセージオブジェクトには multipart/_subtype という値をもつ Content-Type ヘッダとともに、 MIME-Version ヘッダが追加されるでしょう。

オプション引数 boundary は multipart の境界文字列です。これが None の場合 (デフォルト)、境界は必要に応じて計算されます（例えばメッセージがシリアライズされるときなど）。

_subparts はそのペイロードの subpart の初期値からなるシーケンスです。このシーケンスはリストに変換できるようになっている必要があります。新しい subpart はつねに Message.attach() メソッドを使ってそのメッセージに追加できるようになっています。

Content-Type ヘッダに対する追加のパラメータはキーワード引数 _params を介して取得あるいは設定されます。これはキーワード辞書になっています。

バージョン 2.2.2 で追加.

class email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]])

Module: email.mime.application

MIMENonMultipart のサブクラスである MIMEApplication クラスは MIME メッセージオブジェクトのメジャータイプ application を表します。 _data は生のバイト列が入った文字列です。オプション引数 _subtype は MIME のサブタイプを設定します。サブタイプのデフォルトは octet-stream です。

オプション引数の _encoder は呼び出し可能なオブジェクト(関数など)で、データの転送に使う実際のエンコード処理を行います。この呼び出し可能なオブジェクトは引数を1つ取り、それは MIMEApplication のインスタンスです。ペイロードをエンコードされた形式に変更するために get_payload() と set_payload() を使い、必要に応じて Content-Transfer-Encoding やその他のヘッダをメッセージオブジェクトに追加するべきです。デフォルトのエンコードは base64 です。組み込みのエンコーダの一覧は email.encoders モジュールを見てください。

_params は基底クラスのコンストラクタにそのまま渡されます。

バージョン 2.5 で追加.

class email.mime.audio.MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]])

Module: email.mime.audio

MIMEAudio クラスは MIMENonMultipart のサブクラスで、主形式 (maintype) が audio の MIME オブジェクトを作成するのに使われます。 _audiodata は実際の音声データを格納した文字列です。もしこのデータが標準の Python モジュール sndhdr によって認識できるものであれば、 Content-Type ヘッダの副形式 (subtype) は自動的に決定されます。そうでない場合はその画像の形式 (subtype) を _subtype で明示的に指定する必要があります。副形式が自動的に決定できず、 _subtype の指定もない場合は、 TypeError が発生します。

オプション引数 _encoder は呼び出し可能なオブジェクト (関数など) で、トランスポートのさいに画像の実際のエンコードをおこないます。このオブジェクトは MIMEAudio インスタンスの引数をひとつだけ取ることができます。この関数は、与えられたペイロードをエンコードされた形式に変換するのに get_payload() および set_payload() を使う必要があります。また、これは必要に応じて Content-Transfer-Encoding あるいはそのメッセージに適した何らかのヘッダを追加する必要があります。デフォルトのエンコーディングは base64 です。組み込みのエンコーダの詳細については email.encoders を参照してください。

_params は MIMEBase コンストラクタに直接渡されます。

class email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]])

Module: email.mime.image

MIMEImage クラスは MIMENonMultipart のサブクラスで、主形式 (maintype) が image の MIME オブジェクトを作成するのに使われます。 _imagedata は実際の画像データを格納した文字列です。もしこのデータが標準の Python モジュール imghdr によって認識できるものであれば、 Content-Type ヘッダの副形式 (subtype) は自動的に決定されます。そうでない場合はその画像の形式 (subtype) を _subtype で明示的に指定する必要があります。副形式が自動的に決定できず、 _subtype の指定もない場合は、 TypeError が発生します。

オプション引数 _encoder は呼び出し可能なオブジェクト (関数など) で、トランスポートのさいに画像の実際のエンコードをおこないます。このオブジェクトは MIMEImage インスタンスの引数をひとつだけ取ることができます。この関数は、与えられたペイロードをエンコードされた形式に変換するのに get_payload() および set_payload() を使う必要があります。また、これは必要に応じて Content-Transfer-Encoding あるいはそのメッセージに適した何らかのヘッダを追加する必要があります。デフォルトのエンコーディングは base64 です。組み込みのエンコーダの詳細については email.encoders を参照してください。

_params は MIMEBase コンストラクタに直接渡されます。

class email.mime.message.MIMEMessage(_msg[, _subtype])

Module: email.mime.message

MIMEMessage クラスは MIMENonMultipart のサブクラスで、主形式 (maintype) が message の MIME オブジェクトを作成するのに使われます。ペイロードとして使われるメッセージは _msg になります。これは Message クラス (あるいはそのサブクラス) のインスタンスでなければいけません。そうでない場合、この関数は TypeError を発生します。

オプション引数 _subtype はそのメッセージの副形式 (subtype) を設定します。デフォルトではこれは rfc822 になっています。

class email.mime.text.MIMEText(_text[, _subtype[, _charset]])

Module: email.mime.text

MIMEText クラスは MIMENonMultipart のサブクラスで、主形式 (maintype) が text の MIME オブジェクトを作成するのに使われます。ペイロードの文字列は _text になります。 _subtype には副形式 (subtype) を指定し、デフォルトは plain です。 _charset はテキストの文字セットで、 MIMENonMultipart コンストラクタに引数として渡されます。デフォルトではこの値は us-ascii になっています。 _text が unicode の場合には _charset の output_charset でエンコードされ、それ以外の場合にはそのまま使われます。

バージョン 2.4 で変更: 以前、推奨されない引数であった _encoding は撤去されました。 _charset 引数を基にして Content Transfer Encodnig が暗黙に決定されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.5. email: 国際化されたヘッダ

RFC 2822 [http://tools.ietf.org/html/rfc2822.html] は電子メールメッセージの形式を規定する基本規格です。これはほとんどの電子メールが ASCII 文字のみで構成されていたころ普及した RFC 822 [http://tools.ietf.org/html/rfc822.html] 標準から発展したものです。 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] は電子メールがすべて 7-bit ASCII 文字のみから構成されていると仮定して作られた仕様です。

もちろん、電子メールが世界的に普及するにつれ、この仕様は国際化されてきました。今では電子メールに言語依存の文字セットを使うことができます。基本規格では、まだ電子メールメッセージを 7-bit ASCII 文字のみを使って転送するよう要求していますので、多くの RFC でどうやって非ASCII の電子メールを RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 準拠な形式にエンコードするかが記述されています。これらの RFC は以下のものを含みます: RFC 2045 [http://tools.ietf.org/html/rfc2045.html] 、 RFC 2046 [http://tools.ietf.org/html/rfc2046.html] 、 RFC 2047 [http://tools.ietf.org/html/rfc2047.html] 、および RFC 2231 [http://tools.ietf.org/html/rfc2231.html] 。 email パッケージは、 email.header および email.charset モジュールでこれらの規格をサポートしています。

ご自分の電子メールヘッダ、たとえば Subject や To などのフィールドに非ASCII文字を入れたい場合、 Header クラスを使う必要があります。 Message オブジェクトの該当フィールドに文字列ではなく、 Header インスタンスを使うのです。 Header クラスは email.header モジュールからインポートしてください。たとえば:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> print msg.as_string()
Subject: =?iso-8859-1?q?p=F6stal?=

Subject フィールドに非ASCII文字をふくめていることに注目してください。ここでは、含めたいバイト列がエンコードされている文字セットを指定して Header インスタンスを作成することによって実現しています。のちにこの Message インスタンスからフラットなテキストを生成するさいに、この Subject フィールドは RFC 2047 [http://tools.ietf.org/html/rfc2047.html] 準拠の適切な形式にエンコードされます。MIME 機能のついているメーラなら、このヘッダに埋めこまれた ISO-8859-1 文字をただしく表示するでしょう。

バージョン 2.2.2 で追加.

以下は Header クラスの説明です:

class email.header.Header([s[, charset[, maxlinelen[, header_name[, continuation_ws[, errors]]]]]])

別の文字セットの文字列をふくむ MIME準拠なヘッダを作成します。

オプション引数 s はヘッダの値の初期値です。これが None の場合 (デフォルト)、ヘッダの初期値は設定されません。この値はあとから append() メソッドを呼びだすことによって追加することができます。 s はバイト文字列か、あるいは Unicode 文字列でもかまいません。この意味については append() の項を参照してください。

オプション引数 charset には 2つの目的があります。ひとつは append() メソッドにおける charset 引数と同じものです。もうひとつの目的は、これ以降 charset 引数を省略した append() メソッド呼び出しすべてにおける、デフォルト文字セットを決定するものです。コンストラクタに charset が与えられない場合 (デフォルト)、初期値の s および以後の append() 呼び出しにおける文字セットとして us-ascii が使われます。

行の最大長は maxlinelen によって明示的に指定できます。最初の行を (Subject などの s に含まれないフィールドヘッダの責任をとるため) 短く切りとる場合、 header_name にそのフィールド名を指定してください。 maxlinelen のデフォルト値は 76 であり、 header_name のデフォルト値は None です。これはその最初の行を長い、切りとられたヘッダとして扱わないことを意味します。

オプション引数 continuation_ws は RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 準拠の折り返し用余白文字で、ふつうこれは空白か、ハードウェアタブ文字 (hard tab) である必要があります。ここで指定された文字は複数にわたる行の行頭に挿入されます。 continuation_ws のデフォルト値は1つのスペース文字(” ”)です。

オプション引数 errors は、 append() メソッドにそのまま渡されます。

append(s[, charset[, errors]])

この MIME ヘッダに文字列 s を追加します。

オプション引数 charset がもし与えられた場合、これは Charset インスタンス (email.charset を参照) か、あるいは文字セットの名前でなければなりません。この場合は Charset インスタンスに変換されます。この値が None の場合 (デフォルト)、コンストラクタで与えられた charset が使われます。

s はバイト文字列か、Unicode 文字列です。これがバイト文字列 (isinstance(s, str) が真) の場合、 charset はその文字列のエンコーディングであり、これが与えられた文字セットでうまくデコードできないときは UnicodeError が発生します。

いっぽう s が Unicode 文字列の場合、 charset はその文字列の文字セットを決定するためのヒントとして使われます。この場合、 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 準拠のヘッダは RFC 2047 [http://tools.ietf.org/html/rfc2047.html] の規則をもちいて作成され、 Unicode 文字列は以下の文字セットを (この優先順位で) 適用してエンコードされます: us-ascii 、 charset で与えられたヒント、それもなければ utf-8 。最初の文字セットは UnicodeError をなるべくふせぐために使われます。

オプション引数 errors は unicode() 又は ustr.encode() の呼び出し時に使用し、デフォルト値は “strict” です。

encode([splitchars])

メッセージヘッダを RFC に沿ったやり方でエンコードします。おそらく長い行は折り返され、非ASCII部分は base64 または quoted-printable エンコーディングで包含されるでしょう。オプション引数 splitchars には長いASCII行を分割する文字の文字列を指定し、 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] の highest level syntactic breaks の大まかなサポートの為に使用します。この引数は RFC 2047 [http://tools.ietf.org/html/rfc2047.html] でエンコードされた行には影響しません。

Header クラスは、標準の演算子や組み込み関数をサポートするためのメソッドもいくつか提供しています。

__str__()

Header.encode() と同じです。 str(aHeader) などとすると有用でしょう。

__unicode__()

組み込みの unicode() 関数の補助です。ヘッダを Unicode 文字列として返します。

__eq__(other)

このメソッドは、ふたつの Header インスタンスどうしが等しいかどうか判定するのに使えます。

__ne__(other)

このメソッドは、ふたつの Header インスタンスどうしが異なっているかどうかを判定するのに使えます。

さらに、 email.header モジュールは以下のような便宜的な関数も提供しています。

email.header.decode_header(header)

文字セットを変換することなしに、メッセージのヘッダをデコードします。ヘッダの値は header に渡します。

この関数はヘッダのそれぞれのデコードされた部分ごとに、 (decoded_string, charset) という形式の 2要素タプルからなるリストを返します。 charset はヘッダのエンコードされていない部分に対しては None を、それ以外の場合はエンコードされた文字列が指定している文字セットの名前を小文字からなる文字列で返します。

以下はこの使用例です:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[('p\xf6stal', 'iso-8859-1')]

email.header.make_header(decoded_seq[, maxlinelen[, header_name[, continuation_ws]]])

decode_header() によって返される 2要素タプルのリストから Header インスタンスを作成します。

decode_header() はヘッダの値をとってきて、 (decoded_string, charset) という形式の 2要素タプルからなるリストを返します。ここで decoded_string はデコードされた文字列、 charset はその文字セットです。

この関数はこれらのリストの項目から、 Header インスタンスを返します。オプション引数 maxlinelen 、 header_name および continuation_ws は Header コンストラクタに与えるものと同じです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.6. email: 文字セットの表現

このモジュールは文字セットを表現する Charset クラスと電子メールメッセージにふくまれる文字セット間の変換、および文字セットのレジストリとこのレジストリを操作するためのいくつかの便宜的なメソッドを提供します。 Charset インスタンスは email パッケージ中にあるほかのいくつかのモジュールで使用されます。

このクラスは email.charset モジュールからimportしてください。

バージョン 2.2.2 で追加.

class email.charset.Charset([input_charset])

文字セットを email のプロパティに写像する。 Map character sets to their email properties.

このクラスはある特定の文字セットに対し、電子メールに課される制約の情報を提供します。また、与えられた適用可能な codec をつかって、文字セット間の変換をおこなう便宜的なルーチンも提供します。またこれは、ある文字セットが与えられたときに、その文字セットを電子メールメッセージのなかでどうやって RFC に準拠したやり方で使用するかに関する、できうるかぎりの情報も提供します。

文字セットによっては、それらの文字を電子メールのヘッダあるいはメッセージ本体で使う場合は quoted-printable 形式あるいは base64形式でエンコードする必要があります。またある文字セットはむきだしのまま変換する必要があり、電子メールの中では使用できません。

以下ではオプション引数 input_charset について説明します。この値はつねに小文字に強制的に変換されます。そして文字セットの別名が正規化されたあと、この値は文字セットのレジストリ内を検索し、ヘッダのエンコーディングとメッセージ本体のエンコーディング、および出力時の変換に使われる codec をみつけるのに使われます。たとえば input_charset が iso-8859-1 の場合、ヘッダおよびメッセージ本体は quoted-printable でエンコードされ、出力時の変換用 codec は必要ありません。もし input_charset が euc-jp ならば、ヘッダは base64 でエンコードされ、メッセージ本体はエンコードされませんが、出力されるテキストは euc-jp 文字セットから iso-2022-jp 文字セットに変換されます。

Charset インスタンスは以下のようなデータ属性をもっています:

input_charset

最初に指定される文字セットです。一般に通用している別名は、正式な 電子メール用の名前に変換されます (たとえば、 latin_1 は iso-8859-1 に変換されます)。デフォルトは 7-bit の us-ascii です。

header_encoding

この文字セットが電子メールヘッダに使われる前にエンコードされる必要がある場合、この属性は Charset.QP (quoted-printable エンコーディング)、 Charset.BASE64 (base64 エンコーディング)、あるいは最短の QP または BASE64 エンコーディングである Charset.SHORTEST に設定されます。そうでない場合、この値は None になります。

body_encoding

header_encoding と同じですが、この値はメッセージ本体のためのエンコーディングを記述します。これはヘッダ用のエンコーディングとは違うかもしれません。 body_encoding では、 Charset.SHORTEST を使うことはできません。

output_charset

文字セットによっては、電子メールのヘッダあるいはメッセージ本体に使う前にそれを変換する必要があります。もし input_charset がそれらの文字セットのどれかをさしていたら、この output_charset 属性はそれが出力時に変換される文字セットの名前をあらわしています。それ以外の場合、この値は None になります。

input_codec

input_charset を Unicode に変換するための Python 用 codec 名です。変換用の codec が必要ないときは、この値は None になります。

output_codec

Unicode を output_charset に変換するための Python 用 codec 名です。変換用の codec が必要ないときは、この値は None になります。この属性は input_codec と同じ値をもつことになるでしょう。

Charset インスタンスは、以下のメソッドも持っています:

get_body_encoding()

メッセージ本体のエンコードに使われる content-transfer-encoding の値を返します。

この値は使用しているエンコーディングの文字列 quoted-printable または base64 か、あるいは関数のどちらかです。後者の場合、これはエンコードされる Message オブジェクトを単一の引数として取るような関数である必要があります。この関数は変換後 Content-Transfer-Encoding ヘッダ自体を、なんであれ適切な値に設定する必要があります。

このメソッドは body_encoding が QP の場合 quoted-printable を返し、 body_encoding が BASE64 の場合 base64 を返します。それ以外の場合は文字列 7bit を返します。

convert(s)

文字列 s を input_codec から output_codec に変換します。

Charset.to_splittable(s)

おそらくマルチバイトの文字列を、安全に split できる形式に変換します。 s には split する文字列を渡します。

これは input_codec を使って文字列を Unicode にすることで、文字と文字の境界で (たとえそれがマルチバイト文字であっても) 安全に split できるようにします。

input_charset の文字列 s をどうやって Unicode に変換すればいいかが不明な場合、このメソッドは与えられた文字列そのものを返します。

Unicode に変換できなかった文字は、Unicode 置換文字 (Unicode replacement character) 'U+FFFD' に置換されます。

from_splittable(ustr[, to_output])

split できる文字列をエンコードされた文字列に変換しなおします。 ustr は “逆split” するための Unicode 文字列です。

このメソッドでは、文字列を Unicode からべつのエンコード形式に変換するために適切な codec を使用します。与えられた文字列が Unicode ではなかった場合、あるいはそれをどうやって Unicode から変換するか不明だった場合は、与えられた文字列そのものが返されます。

Unicode から正しく変換できなかった文字については、適当な文字 (通常は '?') に置き換えられます。

to_output が True の場合 (デフォルト)、このメソッドは output_codec をエンコードの形式として使用します。 to_output が False の場合、これは input_codec を使用します。

get_output_charset()

出力用の文字セットを返します。

これは output_charset 属性が None でなければその値になります。それ以外の場合、この値は input_charset と同じです。

encoded_header_len()

エンコードされたヘッダ文字列の長さを返します。これは quoted-printable エンコーディングあるいは base64 エンコーディングに対しても正しく計算されます。

header_encode(s[, convert])

文字列 s をヘッダ用にエンコードします。

convert が True の場合、文字列は入力用文字セットから出力用文字セットに自動的に変換されます。これは行の長さ問題のあるマルチバイトの文字セットに対しては役に立ちません (マルチバイト文字はバイト境界ではなく、文字ごとの境界で split する必要があります)。これらの問題を扱うには、高水準のクラスである Header クラスを使ってください (email.header を参照)。 convert の値はデフォルトでは False です。

エンコーディングの形式 (base64 または quoted-printable) は、 header_encoding 属性に基づきます。

body_encode(s[, convert])

文字列 s をメッセージ本体用にエンコードします。

convert が True の場合 (デフォルト)、文字列は入力用文字セットから出力用文字セットに自動的に変換されます。 header_encode() とは異なり、メッセージ本体にはふつうバイト境界の問題やマルチバイト文字セットの問題がないので、これはきわめて安全におこなえます。

エンコーディングの形式 (base64 または quoted-printable) は、 body_encoding 属性に基づきます。

Charset クラスには、標準的な演算と組み込み関数をサポートするいくつかのメソッドがあります。

__str__()

input_charset を小文字に変換された文字列型として返します。 __repr__() は、 __str__() の別名となっています。

__eq__(other)

このメソッドは、2つの Charset インスタンスが同じかどうかをチェックするのに使います。

__ne__(other)

このメソッドは、2つの Charset インスタンスが異なるかどうかをチェックするのに使います。

また、 email.charset モジュールには、グローバルな文字セット、文字セットの別名(エイリアス) および codec 用のレジストリに新しいエントリを追加する以下の関数もふくまれています:

email.charset.add_charset(charset[, header_enc[, body_enc[, output_charset]]])

文字の属性をグローバルなレジストリに追加します。

charset は入力用の文字セットで、その文字セットの正式名称を指定する必要があります。

オプション引数 header_enc および body_enc は quoted-printable エンコーディングをあらわす Charset.QP か、 base64 エンコーディングをあらわす Charset.BASE64 、最短の quoted-printable または base64 エンコーディングをあらわす Charset.SHORTEST 、あるいはエンコーディングなしの None のどれかになります。 SHORTEST が使えるのは header_enc だけです。デフォルトの値はエンコーディングなしの None になっています。

オプション引数 output_charset には出力用の文字セットが入ります。 Charset.convert() が呼ばれたときの変換はまず入力用の文字セットを Unicode に変換し、それから出力用の文字セットに変換されます。デフォルトでは、出力は入力と同じ文字セットになっています。

input_charset および output_charset はこのモジュール中の文字セット-codec 対応表にある Unicode codec エントリである必要があります。モジュールがまだ対応していない codec を追加するには、 add_codec() を使ってください。より詳しい情報については codecs モジュールの文書を参照してください。

グローバルな文字セット用のレジストリは、モジュールの global 辞書 CHARSETS 内に保持されています。

email.charset.add_alias(alias, canonical)

文字セットの別名 (エイリアス) を追加します。 alias はその別名で、たとえば latin-1 のように指定します。 canonical はその文字セットの正式名称で、たとえば iso-8859-1 のように指定します。

文字セットのグローバルな別名用レジストリは、モジュールの global 辞書 ALIASES 内に保持されています。

email.charset.add_codec(charset, codecname)

与えられた文字セットの文字と Unicode との変換をおこなう codec を追加します。

charset はある文字セットの正式名称で、 codecname は Python 用 codec の名前です。これは組み込み関数 unicode() の第2引数か、あるいは Unicode 文字列型の encode() メソッドに適した形式になっていなければなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.7. email: エンコーダ

何もないところから Message を作成するときしばしば必要になるのが、ペイロードをメールサーバに通すためにエンコードすることです。これはとくにバイナリデータを含んだ image/* や text/* タイプのメッセージで必要です。

email パッケージでは、 encoders モジュールにおいていくかの便宜的なエンコーディングをサポートしています。実際にはこれらのエンコーダは MIMEAudio および MIMEImage クラスのコンストラクタでデフォルトエンコーダとして使われています。すべてのエンコーディング関数は、エンコードするメッセージオブジェクトひとつだけを引数にとります。これらはふつうペイロードを取りだし、それをエンコードして、ペイロードをエンコードされたものにセットしなおします。これらはまた Content-Transfer-Encoding ヘッダを適切な値に設定します。

提供されているエンコーディング関数は以下のとおりです:

email.encoders.encode_quopri(msg)

ペイロードを quoted-printable 形式にエンコードし、 Content-Transfer-Encoding ヘッダを quoted-printable [1] に設定します。これはそのペイロードのほとんどが通常の印刷可能な文字からなっているが、印刷不可能な文字がすこしだけあるときのエンコード方法として適しています。

email.encoders.encode_base64(msg)

ペイロードを base64 形式でエンコードし、 Content-Transfer-Encoding ヘッダを base64 に変更します。これはペイロード中のデータのほとんどが印刷不可能な文字である場合に適しています。 quoted-printable 形式よりも結果としてはコンパクトなサイズになるからです。 base64 形式の欠点は、これが人間にはまったく読めないテキストになってしまうことです。

email.encoders.encode_7or8bit(msg)

これは実際にはペイロードを変更はしませんが、ペイロードの形式に応じて Content-Transfer-Encoding ヘッダを 7bit あるいは 8bit に適した形に設定します。

email.encoders.encode_noop(msg)

これは何もしないエンコーダです。 Content-Transfer-Encoding ヘッダを設定さえしません。

注記

[1]
注意: encode_quopri() を使ってエンコードすると、データ中のタブ文字や空白文字もエンコードされます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.8. email: 例外及び障害クラス

email.errors モジュールでは、以下の例外クラスが定義されています:

exception email.errors.MessageError

これは email パッケージが発生しうるすべての例外の基底クラスです。これは標準の Exception クラスから派生しており、追加のメソッドはまったく定義されていません。

exception email.errors.MessageParseError

これは Parser クラスが発生しうる例外の基底クラスです。 MessageError から派生しています。

exception email.errors.HeaderParseError

メッセージの RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダを解析している途中にある条件でエラーがおこると発生します。これは MessageParseError から派生しています。この例外が起こる可能性があるのは Parser.parse() メソッドと Parser.parsestr() メソッドです。

この例外が発生するのはメッセージ中で最初の RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダが現れたあとにエンベロープヘッダが見つかったとか、最初の RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダが現れる前に前のヘッダからの継続行が見つかったとかいう状況を含みます。あるいはヘッダでも継続行でもない行がヘッダ中に見つかった場合でもこの例外が発生します。

exception email.errors.BoundaryError

メッセージの RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダを解析している途中にある条件でエラーがおこると発生します。これは MessageParseError から派生しています。この例外が起こる可能性があるのは Parser.parse() メソッドと Parser.parsestr() メソッドです。

この例外が発生するのは、厳格なパーズ方式が用いられているときに、 multipart/* 形式の開始あるいは終了の文字列が見つからなかった場合などです。

exception email.errors.MultipartConversionError

この例外は、 Message オブジェクトに add_payload() メソッドを使ってペイロードを追加するとき、そのペイロードがすでに単一の値である (訳注: リストでない) にもかかわらず、そのメッセージの Content-Type ヘッダのメインタイプがすでに設定されていて、それが multipart 以外になってしまっている場合にこの例外が発生します。 MultipartConversionError は MessageError と組み込みの TypeError を両方継承しています。

Message.add_payload() はもはや推奨されないメソッドのため、この例外はめったに発生しません。しかしこの例外は attach() メソッドが MIMENonMultipart から派生したクラスのインスタンス (例: MIMEImage など) に対して呼ばれたときにも発生することがあります。

以下は FeedParser がメッセージの解析中に検出する障害 (defect) の一覧です。これらの障害は、問題が見つかったメッセージに追加されるため、たとえば multipart/alternative 内にあるネストしたメッセージが異常なヘッダをもっていた場合には、そのネストしたメッセージが障害を持っているが、その親メッセージには障害はないとみなされることに注意してください。

すべての障害クラスは email.errors.MessageDefect のサブクラスですが、これは例外とは 違います ので注意してください。

バージョン 2.4 で追加: 全ての障害クラスが追加された。

NoBoundaryInMultipartDefect – メッセージが multipart だと宣言されているのに、 boundary パラメータがない。

StartBoundaryNotFoundDefect – Content-Type ヘッダで宣言された開始境界がない。

FirstHeaderLineIsContinuationDefect – メッセージの最初のヘッダが継続行から始まっている。

MisplacedEnvelopeHeaderDefect – ヘッダブロックの途中に “Unix From” ヘッダがある。

MalformedHeaderDefect – コロンのないヘッダがある、あるいはそれ以外の異常なヘッダである。

MultipartInvariantViolationDefect – メッセージが multipart だと宣言されているのに、サブパートが存在しない。注意: メッセージがこの障害を持っているとき、 is_multipart() メソッドはたとえその content-type が multipart であっても false を返すことがあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.9. email: 雑用ユーティリティ

email.utils モジュールではいくつかの便利なユーティリティを提供しています。

email.utils.quote(str)

文字列 str 内のバックスラッシュをバックスラッシュ2つに置換した新しい文字列を返します。また、ダブルクォートはバックスラッシュ + ダブルクォートに置換されます。

email.utils.unquote(str)

文字列 str を 逆クォート した新しい文字列を返します。もし str の先頭あるいは末尾がダブルクォートだった場合、これらは単に切りおとされます。同様にもし str の先頭あるいは末尾が角ブラケット (<、>) だった場合も切りおとされます。

email.utils.parseaddr(address)

アドレスをパーズします。 To や Cc のようなアドレスをふくんだフィールドの値を与えると、構成部分の実名 と 電子メールアドレス を取り出します。パーズに成功した場合、これらの情報をタプル (realname, email_address) にして返します。失敗した場合は 2要素のタプル ('', '') を返します。

email.utils.formataddr(pair)

parseaddr() の逆で、実名と電子メールアドレスからなる 2要素のタプル(realname, email_address) を引数にとり、 To あるいは Cc ヘッダに適した形式の文字列を返します。タプル pair の第1要素が偽である場合、第2要素の値をそのまま返します。

email.utils.getaddresses(fieldvalues)

このメソッドは 2要素タプルのリストを parseaddr() と同じ形式で返します。 fieldvalues はたとえば Message.get_all() が返すような、ヘッダのフィールド値からなるシーケンスです。以下はある電子メールメッセージからすべての受け取り人を得る一例です:

from email.utils import getaddresses

tos = msg.get_all('to', [])
ccs = msg.get_all('cc', [])
resent_tos = msg.get_all('resent-to', [])
resent_ccs = msg.get_all('resent-cc', [])
all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)

email.utils.parsedate(date)

RFC 2822 [http://tools.ietf.org/html/rfc2822.html] に記された規則にもとづいて日付を解析します。しかし、メイラーによってはここで指定された規則に従っていないものがあり、そのような場合 parsedate() はなるべく正しい日付を推測しようとします。 date は RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 形式の日付を保持している文字列で、 "Mon, 20 Nov 1995 19:12:08 -0500" のような形をしています。日付の解析に成功した場合、 parsedate() は関数 time.mktime() に直接渡せる形式の9要素からなるタプルを返し、失敗した場合は None を返します。返されるタプルの 6、7、8番目は有効ではないので注意してください。

email.utils.parsedate_tz(date)

parsedate() と同様の機能を提供しますが、 None または 10要素のタプルを返すところが違います。最初の 9つの要素は time.mktime() に直接渡せる形式のものであり、最後の 10番目の要素は、その日付の時間帯の UTC (グリニッジ標準時の公式な呼び名です) に対するオフセットです [1] 。入力された文字列に時間帯が指定されていなかった場合、10番目の要素には None が入ります。タプルの 6、7、8番目は有効ではないので注意してください。

email.utils.mktime_tz(tuple)

parsedate_tz() が返す 10要素のタプルを UTC のタイムスタンプに変換します。与えられた時間帯が None である場合、時間帯として現地時間 (localtime) が仮定されます。マイナーな欠点: mktime_tz() はまず tuple の最初の 8要素を localtime として変換し、つぎに時間帯の差を加味しています。夏時間を使っている場合には、これは通常の使用にはさしつかえないものの、わずかな誤差を生じるかもしれません。

email.utils.formatdate([timeval[, localtime][, usegmt]])

日付を RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 形式の文字列で返します。例:

Fri, 09 Nov 2001 01:08:47 -0000

オプションとして float 型の値をもつ引数 timeval が与えられた場合、これは time.gmtime() および time.localtime() に渡されます。それ以外の場合、現在の時刻が使われます。

オプション引数 localtime はフラグです。これが True の場合、この関数は timeval を解析したあと UTC のかわりに現地時間 (localtime) の時間帯をつかって変換します。おそらく夏時間も考慮に入れられるでしょう。デフォルトではこの値は False で、UTC が使われます。

オプション引数 usegmt が True のときは、タイムゾーンを表すのに数値の -0000 ではなく ascii文字列である GMT が使われます。これは (HTTP などの) いくつかのプロトコルで必要です。この機能は localtime が False のときのみ適用されます。デフォルトは False です。

バージョン 2.4 で追加.

email.utils.make_msgid([idstring])

RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 準拠形式の Message-ID ヘッダに適した文字列を返します。オプション引数 idstring が文字列として与えられた場合、これはメッセージ ID の一意性を高めるのに利用されます。

email.utils.decode_rfc2231(s)

RFC 2231 [http://tools.ietf.org/html/rfc2231.html] に従って文字列 s をデコードします。

email.utils.encode_rfc2231(s[, charset[, language]])

RFC 2231 [http://tools.ietf.org/html/rfc2231.html] に従って s をエンコードします。オプション引数 charset および language が与えられた場合、これらは文字セット名と言語名として使われます。もしこれらのどちらも与えられていない場合、 s はそのまま返されます。 charset は与えられているが language が与えられていない場合、文字列 s は language の空文字列を使ってエンコードされます。

email.utils.collapse_rfc2231_value(value[, errors[, fallback_charset]])

ヘッダのパラメータが RFC 2231 [http://tools.ietf.org/html/rfc2231.html] 形式でエンコードされている場合、 Message.get_param() は 3要素からなるタプルを返すことがあります。ここには、そのパラメータの文字セット、言語、および値の順に格納されています。 collapse_rfc2231_value() はこのパラメータをひとつの Unicode 文字列にまとめます。オプション引数 errors は built-in である unicode() 関数の引数 errors に渡されます。このデフォルト値は replace となっています。オプション引数 fallback_charset は、もし RFC 2231 [http://tools.ietf.org/html/rfc2231.html] ヘッダの使用している文字セットが Python の知っているものではなかった場合の非常用文字セットとして使われます。デフォルトでは、この値は us-ascii です。

便宜上、 collapse_rfc2231_value() に渡された引数 value がタプルでない場合には、これは文字列である必要があります。その場合には unquote された文字列が返されます。

email.utils.decode_params(params)

RFC 2231 [http://tools.ietf.org/html/rfc2231.html] に従ってパラメータのリストをデコードします。 params は (content-type, string-value) のような形式の 2要素からなるタプルです。

バージョン 2.4 で変更: dump_address_pair() 関数は撤去されました。かわりに formataddr() 関数を使ってください。

バージョン 2.4 で変更: decode() 関数は撤去されました。かわりに Header.decode_header() メソッドを使ってください。

バージョン 2.4 で変更: encode() 関数は撤去されました。かわりに Header.encode() メソッドを使ってください。

注記

[1]
注意: この時間帯のオフセット値は time.timezone の値と符号が逆です。これは time.timezone が POSIX 標準に準拠しているのに対して、こちらは RFC 2822 [http://tools.ietf.org/html/rfc2822.html] に準拠しているからです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.10. email: イテレータ

Message.walk() メソッドを使うと、簡単にメッセージオブジェクトツリー内を次から次へとたどる (iteration) ことができます。 email.iterators モジュールはこのための高水準イテレータをいくつか提供します。

email.iterators.body_line_iterator(msg[, decode])

このイテレータは msg 中のすべてのサブパートに含まれるペイロードをすべて順にたどっていき、ペイロード内の文字列を 1行ずつ返します。サブパートのヘッダはすべて無視され、Python 文字列でないペイロードからなるサブパートも無視されます。これは readline() を使って、ファイルからメッセージを (ヘッダだけとばして) フラットなテキストとして読むのにいくぶん似ているかもしれません。

オプション引数 decode は、 Message.get_payload() にそのまま渡されます。

email.iterators.typed_subpart_iterator(msg[, maintype[, subtype]])

このイテレータは msg 中のすべてのサブパートをたどり、それらの中で指定されたMIME 形式 maintype と subtype をもつようなパートのみを返します。

subtype は省略可能であることに注意してください。これが省略された場合、サブパートの MIME 形式は maintype のみがチェックされます。じつは maintype も省略可能で、その場合にはデフォルトは text です。

つまり、デフォルトでは typed_subpart_iterator() は MIME 形式 text/* をもつサブパートを順に返していくというわけです。

以下の関数は役に立つデバッグ用ツールとして追加されたもので、パッケージとして公式なサポートのあるインターフェイスでは ありません 。

email.iterators._structure(msg[, fp[, level]])

そのメッセージオブジェクト構造の content-type をインデントつきで表示します。たとえば:

>>> msg = email.message_from_file(somefile)
>>> _structure(msg)
multipart/mixed
    text/plain
    text/plain
    multipart/digest
        message/rfc822
            text/plain
        message/rfc822
            text/plain
        message/rfc822
            text/plain
        message/rfc822
            text/plain
        message/rfc822
            text/plain
    text/plain

オプション引数 fp は出力を渡すためのストリーム [1] オブジェクトです。これは Python の拡張 print 文が対応できるようになっている必要があります。 level は内部的に使用されます。

注記

[1]
訳注: 原文では file-like。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.1. email — 電子メールと MIME 処理のためのパッケージ »

18.1.11. email: 使用例

ここでは email パッケージを使って電子メールメッセージを読む・書く・送信するいくつかの例を紹介します。より複雑な MIME メッセージについても扱います。

最初に、テキスト形式の単純なメッセージを作成・送信する方法です:

# Import smtplib for the actual sending function
import smtplib

# Import the email modules we'll need
from email.mime.text import MIMEText

# Open a plain text file for reading.  For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()

# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP()
s.connect()
s.sendmail(me, [you], msg.as_string())
s.close()

Parser() クラスの parse(filename) か parsestr(message_as_string) メソッドを使って簡単に RFC822 ヘッダの解析ができます。

# Import the email modules we'll need
from email.parser import Parser

#  If the e-mail headers are in a file, uncomment this line:
#headers = Parser().parse(open(messagefile, 'r'))

#  Or for parsing headers in a string, use:
headers = Parser().parsestr('From: <user@example.com>\n'
        'To: <someone_else@example.com>\n'
        'Subject: Test message\n'
        '\n'
        'Body would go here\n')

#  Now the header items can be accessed as a dictionary:
print 'To: %s' % headers['to']
print 'From: %s' % headers['from']
print 'Subject: %s' % headers['subject']

つぎに、あるディレクトリ内にある何枚かの家族写真をひとつの MIME メッセージに収めて送信する例です:

# Import smtplib for the actual sending function
import smtplib

# Here are the email package modules we'll need
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

COMMASPACE = ', '

# Create the container (outer) email message.
msg = MIMEMultipart()
msg['Subject'] = 'Our family reunion'
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = me
msg['To'] = COMMASPACE.join(family)
msg.preamble = 'Our family reunion'

# Assume we know that the image files are all in PNG format
for file in pngfiles:
    # Open the files in binary mode.  Let the MIMEImage class automatically
    # guess the specific image type.
    fp = open(file, 'rb')
    img = MIMEImage(fp.read())
    fp.close()
    msg.attach(img)

# Send the email via our own SMTP server.
s = smtplib.SMTP()
s.connect()
s.sendmail(me, family, msg.as_string())
s.close()

つぎはあるディレクトリに含まれている内容全体をひとつの電子メールメッセージとして送信するやり方です: [1]

#!/usr/bin/env python

"""Send the contents of a directory as a MIME message."""

import os
import sys
import smtplib
# For guessing MIME type based on file name extension
import mimetypes

from optparse import OptionParser

from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

COMMASPACE = ', '

def main():
    parser = OptionParser(usage="""\
Send the contents of a directory as a MIME message.

Usage: %prog [options]

Unless the -o option is given, the email is sent by forwarding to your local
SMTP server, which then does the normal delivery process.  Your local machine
must be running an SMTP server.
""")
    parser.add_option('-d', '--directory',
                      type='string', action='store',
                      help="""Mail the contents of the specified directory,
                      otherwise use the current directory.  Only the regular
                      files in the directory are sent, and we don't recurse to
                      subdirectories.""")
    parser.add_option('-o', '--output',
                      type='string', action='store', metavar='FILE',
                      help="""Print the composed message to FILE instead of
                      sending the message to the SMTP server.""")
    parser.add_option('-s', '--sender',
                      type='string', action='store', metavar='SENDER',
                      help='The value of the From: header (required)')
    parser.add_option('-r', '--recipient',
                      type='string', action='append', metavar='RECIPIENT',
                      default=[], dest='recipients',
                      help='A To: header value (at least one required)')
    opts, args = parser.parse_args()
    if not opts.sender or not opts.recipients:
        parser.print_help()
        sys.exit(1)
    directory = opts.directory
    if not directory:
        directory = '.'
    # Create the enclosing (outer) message
    outer = MIMEMultipart()
    outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)
    outer['To'] = COMMASPACE.join(opts.recipients)
    outer['From'] = opts.sender
    outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'

    for filename in os.listdir(directory):
        path = os.path.join(directory, filename)
        if not os.path.isfile(path):
            continue
        # Guess the content type based on the file's extension.  Encoding
        # will be ignored, although we should check for simple things like
        # gzip'd or compressed files.
        ctype, encoding = mimetypes.guess_type(path)
        if ctype is None or encoding is not None:
            # No guess could be made, or the file is encoded (compressed), so
            # use a generic bag-of-bits type.
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        if maintype == 'text':
            fp = open(path)
            # Note: we should handle calculating the charset
            msg = MIMEText(fp.read(), _subtype=subtype)
            fp.close()
        elif maintype == 'image':
            fp = open(path, 'rb')
            msg = MIMEImage(fp.read(), _subtype=subtype)
            fp.close()
        elif maintype == 'audio':
            fp = open(path, 'rb')
            msg = MIMEAudio(fp.read(), _subtype=subtype)
            fp.close()
        else:
            fp = open(path, 'rb')
            msg = MIMEBase(maintype, subtype)
            msg.set_payload(fp.read())
            fp.close()
            # Encode the payload using Base64
            encoders.encode_base64(msg)
        # Set the filename parameter
        msg.add_header('Content-Disposition', 'attachment', filename=filename)
        outer.attach(msg)
    # Now send or store the message
    composed = outer.as_string()
    if opts.output:
        fp = open(opts.output, 'w')
        fp.write(composed)
        fp.close()
    else:
        s = smtplib.SMTP()
        s.connect()
        s.sendmail(opts.sender, opts.recipients, composed)
        s.close()

if __name__ == '__main__':
    main()

つぎに、上のような MIME メッセージをどうやって展開してひとつのディレクトリ上の複数ファイルにするかを示します:

#!/usr/bin/env python

"""Unpack a MIME message into a directory of files."""

import os
import sys
import email
import errno
import mimetypes

from optparse import OptionParser

def main():
    parser = OptionParser(usage="""\
Unpack a MIME message into a directory of files.

Usage: %prog [options] msgfile
""")
    parser.add_option('-d', '--directory',
                      type='string', action='store',
                      help="""Unpack the MIME message into the named
                      directory, which will be created if it doesn't already
                      exist.""")
    opts, args = parser.parse_args()
    if not opts.directory:
        parser.print_help()
        sys.exit(1)

    try:
        msgfile = args[0]
    except IndexError:
        parser.print_help()
        sys.exit(1)

    try:
        os.mkdir(opts.directory)
    except OSError, e:
        # Ignore directory exists error
        if e.errno <> errno.EEXIST:
            raise

    fp = open(msgfile)
    msg = email.message_from_file(fp)
    fp.close()

    counter = 1
    for part in msg.walk():
        # multipart/* are just containers
        if part.get_content_maintype() == 'multipart':
            continue
        # Applications should really sanitize the given filename so that an
        # email message can't be used to overwrite important files
        filename = part.get_filename()
        if not filename:
            ext = mimetypes.guess_extension(part.get_type())
            if not ext:
                # Use a generic bag-of-bits extension
                ext = '.bin'
            filename = 'part-%03d%s' % (counter, ext)
        counter += 1
        fp = open(os.path.join(opts.directory, filename), 'wb')
        fp.write(part.get_payload(decode=True))
        fp.close()

if __name__ == '__main__':
    main()

つぎの例は、HTML メッセージを代替プレーンテキスト版付きで作るやりかたです: [2]

#! /usr/bin/python

import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# me == my email address
# you == recipient's email address
me = "my@email.com"
you = "your@email.com"

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Link"
msg['From'] = me
msg['To'] = you

# Create the body of the message (a plain-text and an HTML version).
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"
html = """\
<html>
  <head></head>
  <body>
    <p>Hi!<br>
       How are you?<br>
       Here is the <a href="http://www.python.org">link</a> you wanted.
    </p>
  </body>
</html>
"""

# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')

# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)

# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail(me, you, msg.as_string())
s.close()

注記

[1]
最初の思いつきと用例は Matthew Dixon Cowles のおかげです。

[2]
Martin Matejek が教えてくれました。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.2. json — JSON エンコーダおよびデコーダ

バージョン 2.6 で追加.

JSON (JavaScript Object Notation) [http://json.org] は JavaScript 文法 (ECMA-262 3rd edition) のサブセットで軽量のデータ交換形式として使われています。

json の API は標準ライブラリの marshal や pickle のユーザに馴染み深いものです。

基本的な Python オブジェクト階層のエンコーディング:

>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print json.dumps("\"foo\bar")
"\"foo\bar"
>>> print json.dumps(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'

コンパクトなエンコーディング:

>>> import json
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
'[1,2,3,{"4":5,"6":7}]'

見やすい表示:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

JSON のデコーディング:

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'streaming API']

JSON オブジェクトのデコーディング方法を誂える:

>>> import json
>>> def as_complex(dct):
...     if '__complex__' in dct:
...         return complex(dct['real'], dct['imag'])
...     return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
...     object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')

JSONEncoder の拡張:

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         return json.JSONEncoder.default(self, obj)
...
>>> dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']

シェルから json.tool を使って妥当性チェックをして見やすく表示:

$ echo '{"json":"obj"}' | python -mjson.tool
{
    "json": "obj"
}
$ echo '{ 1.2:3.4}' | python -mjson.tool
Expecting property name: line 1 column 2 (char 2)

ノート

このモジュールのデフォルト設定で生成される JSON は YAML のサブセットですので、その直列化にも使うことができるでしょう。

18.2.1. 基本的な使い方

json.dump(obj, fp[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, **kw]]]]]]]]]])

obj を JSON 形式の fp (.write() をサポートするファイル的オブジェクト) へのストリームとして直列化します。

skipkeys が True (デフォルトは False) ならば、基本型 (str, unicode, int, long, float, bool, None) 以外の辞書のキーは TypeError を送出せずに読み飛ばされます。

ensure_ascii が False (デフォルトは True) ならば、 fp へ書き込まれるチャンクは通常の Python における str から unicode への型強制ルールに従って unicode インスタンスになることがあります。 fp.write() が (codecs.getwriter() のように) 前もって unicode に対応していると判っているもの以外では恐らくこれによってエラーが起こるでしょう。

check_circular が False (デフォルトは True) ならば、コンテナ型の循環参照チェックが省かれ、循環参照があれば OverflowError (またはもっと悪い結果) に終わります。

allow_nan が False (デフォルトは True) ならば、許容範囲外の float 値 (nan, inf, -inf) を直列化しようとした場合、 JSON 仕様を厳格に守って JavaScript の等価なもの (NaN, Infinity, -Infinity) を使うことなく ValueError になります。

indent が非負の整数であれば、JSON の配列要素とオブジェクトメンバはそのインデントレベルで見やすく表示されます。インデントレベルが 0 か負であれば改行だけが挿入されます。 None (デフォルト) では最もコンパクトな表現が選択されます。

separators がタプル (item_separator, dict_separator) ならば、デフォルト区切り文字 (', ', ': ') の代わりに使われます。 (',', ':') が最もコンパクトな JSON の表現です。

encoding は文字列のエンコーディングで、デフォルトは UTF-8 です。

default(obj) は関数で、 obj の直列化可能なバージョンを返すか、さもなくば TypeError を送出します。デフォルトでは単に TypeError を送出します。

カスタマイズされた JSONEncoder のサブクラス (たとえば追加の型を直列化するように default() メソッドをオーバーライドしたもの) を使うには、 cls キーワード引数に指定します; 指定しなければ JSONEncoder が使われます。

ノート

pickle や marshal と違って、JSON は枠付きのプロトコル (framed protocol) ではないので、同じ fp に対して繰り返し dump() を呼び、たくさんのオブジェクトを直列化しようとすると、不正な JSON ファイルが作られてしまいます。

json.dumps(obj[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, **kw]]]]]]]]]])

obj を JSON 形式の str に直列化します。

ensure_ascii が False ならば、返値は unicode インスタンスになります。その他の引数は dump() におけるものと同じ意味です。

json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

直列化された fp (.read() をサポートするファイル的オブジェクトで JSON 文書を収めたもの) の内容を Python オブジェクトに戻します。

fp の内容が ASCII に基づいたしかし UTF-8 ではないエンコーディング (たとえば latin-1) を使っているならば、適切な encoding 名が指定されなければなりません。エンコーディングが ASCII に基づかないもの (UCS-2 など) であることは許されないので、 codecs.getreader(encoding)(fp) というように包むか、または単に unicode オブジェクトにデコードしたものを loads() に渡して下さい。

object_hook はオプションで渡す関数で、全てのオブジェクトリテラルのデコード結果 (dict) に対して呼ばれます。 object_hook の返り値は dict の代わりに使われます。この機能は独自のデコーダ (たとえば JSON-RPC クラスヒンティング) を実装するのに使えます。

object_pairs_hook はオプションで渡す関数で、ペアの順序付きリストのデコード結果に対して呼ばれます。 object_pairs_hook の返り値は dict の代わりに使われます。この機能はキーと値のデコードされる順序に依存する独自のデコーダ (たとえば collections.OrderedDict() は挿入の順序を記憶します) を実装するのに使えます。 object_hook も定義されている場合は、 object_pairs_hook が優先して使用されます。

バージョン 2.7 で変更: object_pairs_hook のサポートを追加しました。

parse_float は、もし指定されれば、全てのデコードされる JSON の浮動小数点数文字列に対して呼ばれます。デフォルトでは、 float(num_str) と等価です。これは JSON 浮動小数点数に対して他のデータ型やパーサ (たとえば decimal.Decimal) を使うのに使えます。

parse_int は、もし指定されれば、全てのデコードされる JSON の整数文字列に対して呼ばれます。デフォルトでは、 int(num_str) と等価です。これは JSON 整数に対して他のデータ型やパーサ (たとえば float) を使うのに使えます。

parse_constant は、もし指定されれば、次の文字列に対して呼ばれます: '-Infinity', 'Infinity', 'NaN', 'null', 'true', 'false' 。これは不正な JSON 数値に遭遇したときに例外を送出するのに使えます。

カスタマイズされた JSONDecoder のサブクラスを使うには、 cls キーワード引数に指定します; 指定しなかった場合は JSONDecoder が使われます。追加のキーワード引数はこのクラスのコンストラクタに引き渡されます。

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

直列化された s (str または unicode インスタンスで JSON 文書を含むもの) を Python オブジェクトに戻します。

s が ASCII に基づいたしかし UTF-8 ではないエンコーディング (たとえば latin-1) でエンコードされた str ならば、適切な encoding 名が指定されなければなりません。エンコーディングが ASCII に基づかないもの (UCS-2 など) であることは許されないので、まず unicode にデコードして下さい。

その他の引数は load() におけるものと同じ意味です。

18.2.2. エンコーダおよびデコーダ

class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

単純な JSON デコーダ。

デフォルトではデコーディングの際、以下の変換を行います。

JSON | Python
object | dict
array | list
string | unicode
number (int) | int, long
number (real) | float
true | True
false | False
null | None

また、このデコーダは NaN, Infinity, -Infinity を対応する float の値として、JSON の仕様からは外れますが、理解します。

encoding はこのインスタンスでデコードされる str オブジェクトを解釈するために使われるエンコーディング (デフォルトは UTF-8) を定めます。 unicode オブジェクトのデコーディングには影響を与えません。

注意して欲しいのは現状では ASCII のスーパーセットであるようなエンコーディングだけうまく動くということです。他のエンコーディングの文字列は unicode にして渡して下さい。

object_hook は、もし指定されれば、全てのデコードされた JSON オブジェクトに対して呼ばれその返値は与えられた dict の代わりに使われます。この機能は独自の脱直列化 (たとえば JSON-RPC クラスヒンティングをサポートするような) を提供するのに使えます。

object_pairs_hook は、もし指定されれば、全てのペアの順序付きリストにデコードされた JSON オブジェクトに対して呼ばれます。 object_pairs_hook の返り値は dict の代わりに使われます。この機能はキーと値のデコードされる順序に依存する独自のデコーダ (たとえば collections.OrderedDict() は挿入の順序を記憶します) を実装するのに使えます。 object_hook も定義されている場合は、 object_pairs_hook が優先して使用されます。

バージョン 2.7 で変更: object_pairs_hook のサポートを追加しました。

parse_float は、もし指定されれば、全てのデコードされる JSON の浮動小数点数文字列に対して呼ばれます。デフォルトでは、 float(num_str) と等価です。これは JSON 浮動小数点数に対して他のデータ型やパーサ (たとえば decimal.Decimal) を使うのに使えます。

parse_int は、もし指定されれば、全てのデコードされる JSON の整数文字列に対して呼ばれます。デフォルトでは、 int(num_str) と等価です。これは JSON 整数に対して他のデータ型やパーサ (たとえば float) を使うのに使えます。

parse_constant は、もし指定されれば、次の文字列に対して呼ばれます: '-Infinity', 'Infinity', 'NaN', 'null', 'true', 'false' 。これは不正な JSON 数値に遭遇したときに例外を送出するのに使えます。

strict が False (デフォルトは True) の場合、制御文字を文字列に含めることができます。ここで言う制御文字とは、 '\t' (タブ)、 '\n' 、 '\r' 、 '0' を含む 0-31 の範囲のコードを持つ文字のことです。

decode(s)

s (str または unicode インスタンスで JSON 文書を含むもの) の Python 表現を返します。

raw_decode(s)

s (str または unicode インスタンスで JSON 文書で始まるもの) から JSON 文書をデコードし、Python 表現と s の文書の終わるところのインデックスからなる 2 要素のタプルを返します。

このメソッドは後ろに余分なデータを従えた文字列から JSON 文書をデコードするのに使えます。

class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])

Python データ構造に対する拡張可能な JSON エンコーダ。

デフォルトでは以下のオブジェクトと型をサポートします:

Python | JSON
dict | object
list, tuple | array
str, unicode | string
int, long, float | number
True | true
False | false
None | null

このクラスを拡張して他のオブジェクトも認識するようにするには、サブクラスを作って default() メソッドを次のように実装します。もう一つ別のメソッドでオブジェクト o に対する直列化可能なオブジェクトを返すものを呼び出すようにします。変換できない時はスーパークラスの実装を (TypeError を送出させるために) 呼ばなければなりません。

skipkeys が False (デフォルト) ならば、str, int, long, float, None 以外のキーをエンコードする試みは TypeError に終わります。 skipkeys が True の場合は、それらのアイテムは単に読み飛ばされます。

ensure_ascii が True (デフォルト) ならば、入ってくるユニコード文字が全てエスケープされた str オブジェクトが出力になることが保証されます。 ensure_ascii が False の場合は、出力はユニコードオブジェクトです。

check_circular が True (デフォルト) ならば、リスト、辞書および自作でエンコードしたオブジェクトは循環参照がないかエンコード中にチェックされ、無限再帰 (これは OverflowError を引き起こします) を防止します。 True でない場合は、そういったチェックは施されません。

allow_nan が True (デフォルト) ならば、 NaN, Infinity, -Infinity はそのままエンコードされます。この振る舞いは JSON 仕様に従っていませんが、大半の JavaScript ベースのエンコーダ、デコーダと矛盾しません。 True でない場合は、そのような浮動小数点数をエンコードすると ValueError が送出されます。

sort_keys が True (デフォルトは False) ならば、辞書の出力がキーでソートされます。これは JSON の直列化がいつでも比較できるようになるので回帰試験の際に便利です。

indent が非負の整数であれば (デフォルトでは None です)、JSON の配列要素とオブジェクトメンバはそのインデントレベルで見やすく表示されます。インデントレベルが 0 ならば改行だけが挿入されます。 None では最もコンパクトな表現が選択されます。

separators はもし指定するなら (item_separator, key_separator) というタプルでなければなりません。デフォルトは (', ', ': ') です。最もコンパクトな JSON の表現を得たければ空白を削った (',', ':') を指定すればいいでしょう。

default はもし指定するなら関数で、それがなければ直列化できないオブジェクトに対して呼び出されます。その関数はオブジェクトを JSON でエンコードできるバージョンにして返すか、さもなければ TypeError を送出しなければなりません。

encoding が None でなければ、入力文字列は全て JSON エンコーディングに先立ってこのエンコーディングでユニコードに変換されます。デフォルトは UTF-8 です。

default(o)

このメソッドをサブクラスで実装する際には o に対して直列化可能なオブジェクトを返すか、基底クラスの実装を (TypeError を送出するために) 呼び出すかします。

たとえば、任意のイテレータをサポートするために、次のように実装します:

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   return JSONEncoder.default(self, o)

encode(o)

Python データ構造 o の JSON 文字列表現を返します。たとえば:

>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'

iterencode(o)

与えられたオブジェクト o をエンコードし、得られた文字列表現ごとに yield します。たとえば:

for chunk in JSONEncoder().iterencode(bigobject):
    mysocket.write(chunk)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.3. mailcap — mailcap ファイルの操作

mailcap ファイルは、メールリーダや Web ブラウザのような MIME 対応のアプリケーションが、異なる MIME タイプのファイルにどのように反応するかを設定するために使われます (“mailcap” の名前は “mail capability” から取られました)。例えば、ある mailcap ファイルに video/mpeg; xmpeg %s のような行が入っていたとします。ユーザが email メッセージや Web ドキュメント上でその MIME タイプ video/mpeg に遭遇すると、 %s はファイル名 (通常テンポラリファイルに属するものになります) に置き換えられ、ファイルを閲覧するためにxmpeg プログラムが自動的に起動されます。

mailcap の形式は RFC 1524 [http://tools.ietf.org/html/rfc1524.html], “A User Agent Configuration Mechanism For Multimedia Mail Format Information” で文書化されていますが、この文書はインターネット標準ではありません。しかしながら、 mailcap ファイルはほとんどの Unix システムでサポートされています。

mailcap.findmatch(caps, MIMEtype[, key[, filename[, plist]]])

2 要素のタプルを返します; 最初の要素は文字列で、実行すべきコマンド (os.system() に渡されます) が入っています。二つめの要素は与えられた MIME タイプに対する mailcap エントリです。一致する MIME タイプが見つからなかった場合、 (None, None) が返されます。

key は desired フィールドの値で、実行すべき動作のタイプを表現します; ほとんどの場合、単に MIME 形式のデータ本体を見たいと思うので、標準の値は ‘view’ になっています。与えられた MIME 型をもつ新たなデータ本体を作成した場合や、既存のデータ本体を置き換えたい場合には、’view’ の他に ‘compose’ および ‘edit’ を取ることもできます。

これらフィールドの完全なリストについては RFC 1524 [http://tools.ietf.org/html/rfc1524.html] を参照してください。

filename はコマンドライン中で %s に代入されるファイル名です; 標準の値は '/dev/null' で、たいていこの値を使いたいわけではないはずです。従って、ファイル名を指定してこのフィールドを上書きする必要があるでしょう。

plist は名前付けされたパラメタのリストです; 標準の値は単なる空のリストです。リスト中の各エントリはパラメタ名を含む文字列、等号 ('=')、およびパラメタの値でなければなりません。 mailcap エントリには %{foo} といったような名前つきのパラメタを含めることができ、’foo’ と名づけられたパラメタの値に置き換えられます。例えば、コマンドライン showpartial %{id} %{number} %{total} が mailcap ファイルにあり、 plist が ['id=1', 'number=2', 'total=3'] に設定されていれば、コマンドラインは 'showpartial 1 2 3' になります。

mailcap ファイル中では、オプションの “test” フィールドを使って、(計算機アーキテクチャや、利用しているウィンドウシステムといった) 何らかの外部条件をテストするよう指定することができます。 findmatch() はこれらの条件を自動的にチェックし、チェックが失敗したエントリを読み飛ばします。

mailcap.getcaps()

MIME タイプを mailcap ファイルのエントリに対応付ける辞書を返します。この辞書は findmatch() 関数に渡されるべきものです。エントリは辞書のリストとして記憶されますが、この表現形式の詳細について知っておく必要はないでしょう。

mailcap 情報はシステム上で見つかった全ての mailcap ファイルから導出されます。ユーザ設定の mailcap ファイル $HOME/.mailcap はシステムの mailcap ファイル /etc/mailcap 、 /usr/etc/mailcap 、および /usr/local/etc/mailcap の内容を上書きします。

以下に使用例を示します:

>>> import mailcap
>>> d=mailcap.getcaps()
>>> mailcap.findmatch(d, 'video/mpeg', filename='/tmp/tmp1223')
('xmpeg /tmp/tmp1223', {'view': 'xmpeg %s'})

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.4. mailbox — 様々な形式のメールボックス操作

このモジュールでは二つのクラス Mailbox および Message をディスク上のメールボックスとそこに収められたメッセージへのアクセスと操作のために定義しています。 Mailbox は辞書のようなキーからメッセージへの対応付けを提供しています。 Message は email.Message モジュールの Message を拡張して形式ごとの状態と振る舞いを追加しています。サポートされるメールボックスの形式は Maildir, mbox, MH, Babyl, MMDF です。

参考

Module email

メッセージの表現と操作

18.4.1. Mailbox オブジェクト

class mailbox.Mailbox

メールボックス。中を見られたり変更されたりします。

Mailbox 自体はインタフェースを定義し形式ごとのサブクラスに継承されるように意図されたもので、インスタンス化されることは想定されていません。インスタンス化したいならばサブクラスを代わりに使うべきです。

Mailbox のインタフェースは辞書風で、小さなキーがメッセージに対応します。キーは対象となる Mailbox インスタンスが発行するもので、そのインスタンスに対してのみ意味を持ちます。一つのキーは一つのメッセージにひも付けられ、その対応はメッセージが他のメッセージで置き換えられるような更新をされたあとも続きます。

メッセージを Mailbox インスタンスに追加するには集合風のメソッド add() を使います。また削除は del 文または集合風の remove() や discard() を使って行ないます。

Mailbox インタフェースのセマンティクスと辞書のそれとは注意すべき違いがあります。メッセージは、要求されるたびに新しい表現(典型的には Message インスタンス)が現在のメールボックスの状態に基づいて生成されます。同様に、メッセージが Mailbox インスタンスに追加される時も、渡されたメッセージ表現の内容がコピーされます。どちらの場合も Makebox インスタンスにメッセージ表現への参照は保たれません。

デフォルトの Mailbox イテレータはメッセージ表現ごとに繰り返すもので、辞書のイテレータのようにキーごとの繰り返しではありません。さらに、繰り返し中のメールボックスを変更することは安全であり整合的に定義されています。イテレータが作られた後にメールボックスに追加されたメッセージはそのイテレータからは見えません。そのイテレータが yield するまえにメールボックスから削除されたメッセージは黙ってスキップされますが、イテレータからのキーを使ったときにはそのキーに対応するメッセージが削除されているならば KeyError を受け取ることになります。

警告

十分な注意を、何か他のプロセスによっても同時に変更される可能性のあるメールボックスを更新する時は、払わなければなりません。そのようなタスクをこなすのに最も安全なメールボックス形式は Maildir で、 mbox のような単一ファイルの形式を並行した書き込みに利用するのは避けるように努力しましょう。メールボックスを更新する場面では、 必ず lock() と unlock() メソッドを、ファイル内のメッセージを読んだり書き込んだり削除したりといった操作をする前 に、呼び出してロックします。メールボックスをロックし損なうと、メッセージを失ったりメールボックス全体をぐちゃぐちゃにしたりする羽目に陥ります。

Mailbox インスタンスには次のメソッドがあります。

add(message)

メールボックスに message を追加し、それに割り当てられたキーを返します。

引数 message は Message インスタンス、 email.Message.Message インスタンス、文字列、ファイル風オブジェクト (テキストモードで開かれていなければなりませんが)を使えます。 message が適切な形式に特化した Message サブクラスのインスタンス (例えばメールボックスが mbox インスタンスのときの mboxMessage インスタンス)であれば、形式ごとの情報が利用されます。そうでなければ、形式ごとに必要な情報は適当なデフォルトが使われます。

remove(key)

__delitem__(key)

discard(key)

メールボックスから key に対応するメッセージを削除します。

対応するメッセージが無い場合、メソッドが remove() または __delitem__() として呼び出されている時は KeyError 例外が送出されます。しかし、 discard() として呼び出されている場合は例外は発生しません。基づいているメールボックス形式が別のプロセスからの平行した変更をサポートしているならば、この discard() の振る舞いの方が好まれるかもしれません。

__setitem__(key, message)

key に対応するメッセージを message で置き換えます。 key に対応しているメッセージが既に無くなっている場合 KeyError 例外が送出されます。

add() と同様に、引数の message には Message インスタンス、 email.Message.Message インスタンス、文字列、ファイル風オブジェクト (テキストモードで開かれていなければなりませんが)を使えます。 message が適切な形式に特化した Message サブクラスのインスタンス (例えばメールボックスが mbox インスタンスのときの mboxMessage インスタンス)であれば、形式ごとの情報が利用されます。そうでなければ、現在 key に対応するメッセージの形式ごとの情報が変更されずに残ります。

iterkeys()

keys()

iterkeys() として呼び出されると全てのキーについてのイテレータを返しますが、 keys() として呼び出されるとキーのリストを返します。

itervalues()

__iter__()

values()

itervalues() または __iter__() として呼び出されると全てのメッセージの表現についてのイテレータを返しますが、 values() として呼び出されるとその表現のリストを返します。メッセージは適切な形式ごとの Message サブクラスのインスタンスとして表現されるのが普通ですが、 Mailbox インスタンスが初期化されるときに指定すればお好みのメッセージファクトリを使うこともできます。

ノート

__iter__() は辞書のそれのようにキーについてのイテレータではありません。

iteritems()

items()

(key, message) ペア、ただし key はキーで message はメッセージ表現、のイテレータ(iteritems() として呼び出された場合)、またはリスト(items() として呼び出された場合)を返します。メッセージは適切な形式ごとの Message サブクラスのインスタンスとして表現されるのが普通ですが、 Mailbox インスタンスが初期化されるときに指定すればお好みのメッセージファクトリを使うこともできます。

get(key[, default=None])

__getitem__(key)

key に対応するメッセージの表現を返します。対応するメッセージが存在しない場合、 get() として呼び出されたなら default を返しますが、 __getitem__() として呼び出されたなら KeyError 例外が送出されます。メッセージは適切な形式ごとの Message サブクラスのインスタンスとして表現されるのが普通ですが、 Mailbox インスタンスが初期化されるときに指定すればお好みのメッセージファクトリを使うこともできます。

get_message(key)

key に対応するメッセージの表現を形式ごとの Message サブクラスのインスタンスとして返します。もし対応するメッセージが存在しなければ KeyError 例外が送出されます。

get_string(key)

key に対応するメッセージの表現を文字列として返します。もし対応するメッセージが存在しなければ KeyError 例外が送出されます。

get_file(key)

key に対応するメッセージの表現をファイル風表現として返します。もし対応するメッセージが存在しなければ KeyError 例外が送出されます。ファイル風オブジェクトはバイナリモードで開かれているように振る舞います。このファイルは必要がなくなったら閉じなければなりません。

ノート

他の表現方法とは違い、ファイル風オブジェクトはそれを作り出した Mailbox インスタンスやそれが基づいているメールボックスと独立である必要がありません。より詳細な説明は各サブクラスごとにあります。

has_key(key)

__contains__(key)

key がメッセージに対応していれば True を、そうでなければ False を返します。

__len__()

メールボックス中のメッセージ数を返します。

clear()

メールボックスから全てのメッセージを削除します。

pop(key[, default])

key に対応するメッセージの表現を返します。もし対応するメッセージが存在しなければ default が供給されていればその値を返し、そうでなければ KeyError 例外を送出します。メッセージは適切な形式ごとの Message サブクラスのインスタンスとして表現されるのが普通ですが、 Mailbox インスタンスが初期化されるときに指定すればお好みのメッセージファクトリを使うこともできます。

popitem()

任意に選んだ (key, message) ペアを返します。ただしここで key はキーで message はメッセージ表現です。もしメールボックスが空ならば、 KeyError 例外を送出します。メッセージは適切な形式ごとの Message サブクラスのインスタンスとして表現されるのが普通ですが、 Mailbox インスタンスが初期化されるときに指定すればお好みのメッセージファクトリを使うこともできます。

update(arg)

引数 arg は key から message へのマッピングまたは (key, message) ペアのイテレート可能オブジェクトでなければなりません。メールボックスは、各 key と message のペアについて __setitem__() を使ったかのように key に対応するメッセージが message になるように更新されます。 __setitem__() と同様に、 key は既存のメールボックス中のメッセージに対応しているものでなければならず、そうでなければ KeyError が送出されます。ですから、一般的には arg に Mailbox インスタンスを渡すのは間違いです。

ノート

辞書と違い、キーワード引数はサポートされていません。

flush()

保留されている変更をファイルシステムに書き込みます。 Mailbox のサブクラスによっては変更はいつも直ちにファイルに書き込まれ flush() は何もしないということもありますが、それでもこのメソッドを呼ぶように習慣付けておきましょう。

lock()

メールボックスの排他的アドバイザリロックを取得し、他のプロセスが変更しないようにします。ロックが取得できない場合 ExternalClashError が送出されます。ロック機構はメールボックス形式によって変わります。メールボックスの内容に変更を加えるときは いつも ロックを掛けるべきです。

unlock()

メールボックスのロックを、もしあれば、解放します。

close()

メールボックスをフラッシュし、必要ならばアンロックし、開いているファイルを閉じます。 Mailbox サブクラスによっては何もしないこともあります。

18.4.1.1. Maildir

class mailbox.Maildir(dirname[, factory=rfc822.Message[, create=True]])

Maildir 形式のメールボックスのための Mailbox のサブクラス。パラメータ factory は呼び出し可能オブジェクトで (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 factory が None ならば、 MaildirMessage がデフォルトのメッセージ表現として使われます。 create が True ならばメールボックスが存在しないときには作成します。

factory のデフォルトが rfc822.Message であったり、 path ではなく dirname という名前であったりというのは歴史的理由によるものです。 Maildir インスタンスが他の Mailbox サブクラスと同じように振る舞わせるためには、 factory に None をセットしてください。

Maildir はディレクトリ型のメールボックス形式でメール転送エージェント qmail 用に発明され、現在では多くの他のプログラムでもサポートされているものです。 Maildir メールボックス中のメッセージは共通のディレクトリ構造の下で個別のファイルに保存されます。このデザインにより、Maildir メールボックスは複数の無関係のプログラムからデータを失うことなくアクセスしたり変更したりできます。そのためロックは不要です。

Maildir メールボックスには三つのサブディレクトリ tmp, new, cur があります。メッセージはまず tmp サブディレクトリに瞬間的に作られた後、 new サブディレクトリに移動されて配送を完了します。メールユーザエージェントが引き続いて cur サブディレクトリにメッセージを移動しメッセージの状態についての情報をファイル名に追加される特別な “info” セクションに保存することができます。

Courier メール転送エージェントによって導入されたスタイルのフォルダもサポートされます。主たるメールボックスのサブディレクトリは '.' がファイル名の先頭であればフォルダと見なされます。フォルダ名は Maildir によって先頭の '.' を除いて表現されます。各フォルダはまた Maildir メールボックスですがさらにフォルダを含むことはできません。その代わり、論理的包含関係は例えば “Archived.2005.07” のような '.' を使ったレベル分けで表わされます。

ノート

本来の Maildir 仕様ではある種のメッセージのファイル名にコロン (':') を使う必要があります。しかしながら、オペレーティングシステムによってはこの文字をファイル名に含めることができないことがあります。そういった環境で Maildir のような形式を使いたい場合、代わりに使われる文字を指定する必要があります。感嘆符 ('!') を使うのが一般的な選択です。以下の例を見てください。

import mailbox
mailbox.Maildir.colon = '!'

colon 属性はインスタンスごとにセットしても構いません。

Maildir インスタンスには Mailbox の全てのメソッドに加え以下のメソッドもあります。

list_folders()

全てのフォルダ名のリストを返します。

get_folder(folder)

名前が folder であるフォルダを表わす Maildir インスタンスを返します。そのようなフォルダが存在しなければ NoSuchMailboxError 例外が送出されます。

add_folder(folder)

名前が folder であるフォルダを作り、それを表わす Maildir インスタンスを返します。

remove_folder(folder)

名前が folder であるフォルダを削除します。もしフォルダに一つでもメッセージが含まれていれば NotEmptyError 例外が送出されフォルダは削除されません。

clean()

過去36時間以内にアクセスされなかったメールボックス内の一時ファイルを削除します。 Maildir 仕様はメールを読むプログラムはときどきこの作業をすべきだとしています。

Maildir で実装された Mailbox のいくつかのメソッドには特別な注意が必要です。

add(message)

__setitem__(key, message)

update(arg)

警告

これらのメソッドは一意的なファイル名をプロセスIDに基づいて生成します。複数のスレッドを使う場合は、同じメールボックスを同時に操作しないようにスレッド間で調整しておかないと検知されない名前の衝突が起こりメールボックスを壊すかもしれません。

flush()

Maildir メールボックスへの変更は即時に適用されるので、このメソッドは何もしません。

lock()

unlock()

Maildir メールボックスはロックをサポート(または要求)しないので、このメソッドは何もしません。

close()

Maildir インスタンスは開いたファイルを保持しませんしメールボックスはロックをサポートしませんので、このメソッドは何もしません。

get_file(key)

ホストのプラットフォームによっては、返されたファイルが開いている間、元になったメッセージを変更したり削除したりできない場合があります。

参考

qmail の maildir man ページ [http://www.qmail.org/man/man5/maildir.html]

Maildir 形式のオリジナルの仕様

Using maildir format [http://cr.yp.to/proto/maildir.html]

Maildir 形式の発明者による注意書き。更新された名前生成規則と “info” の解釈についても含まれます。

Courier の maildir man ページ [http://www.courier-mta.org/maildir.html]

Maildir 形式のもう一つの仕様。フォルダをサポートする一般的な拡張について記述されています。

18.4.1.2. mbox

class mailbox.mbox(path[, factory=None[, create=True]])

mbox 形式のメールボックスのための Mailbox のサブクラス。パラメータ factory は呼び出し可能オブジェクトで (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 factory が None ならば、 mboxMessage がデフォルトのメッセージ表現として使われます。 create が True ならばメールボックスが存在しないときには作成します。

mbox 形式は Unixシステム上でメールを保存する古くからある形式です。 mbox メールボックスでは全てのメッセージが一つのファイルに保存されておりそれぞれのメッセージは “From ” という5文字で始まる行を先頭に付けられています。

mbox 形式には幾つかのバリエーションがあり、それぞれオリジナルの形式にあった欠点を克服すると主張しています。互換性のために、 mbox はオリジナルの(時に mboxo と呼ばれる) 形式を実装しています。すなわち、 Content-Length ヘッダはもしあっても無視され、メッセージのボディにある行頭の “From ” はメッセージを保存する際に “>From ” に変換されますが、この “>From ” は読み出し時にも “From ” に変換されません。

mbox で実装された Mailbox のいくつかのメソッドには特別な注意が必要です。

get_file(key)

mbox インスタンスに対し flush() や close() を呼び出した後でファイルを使用すると予期しない結果を引き起こしたり例外が送出されたりすることがあります。

lock()

unlock()

3種類のロック機構が使われます — ドットロッキングと、もし使用可能ならば flock() と lockf() システムコールです。

参考

qmail の mbox man ページ [http://www.qmail.org/man/man5/mbox.html]

mbox 形式の仕様および種々のバリエーション

tin の mbox man ページ [http://www.tin.org/bin/man.cgi?section=5&topic=mbox]

もう一つの mbox 形式の仕様でロックについての詳細を含む

Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad [http://www.jwz.org/doc/content-length.html]

バリエーションの一つではなくオリジナルの mbox を使う理由

“mbox” is a family of several mutually incompatible mailbox formats [http://homepages.tesco.net./~J.deBoynePollard/FGA/mail-mbox-formats.html]

mbox バリエーションの歴史

18.4.1.3. MH

class mailbox.MH(path[, factory=None[, create=True]])

MH 形式のメールボックスのための Mailbox のサブクラス。パラメータ factory は呼び出し可能オブジェクトで (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 factory が None ならば、 MHMessage がデフォルトのメッセージ表現として使われます。 create が True ならばメールボックスが存在しないときには作成します。

MH はディレクトリに基づいたメールボックス形式で MH Message Handling System というメールユーザエージェントのために発明されました。 MH メールボックス中のそれぞれのメッセージは一つのファイルとして収められています。 MH メールボックスにはメッセージの他に別の MH メールボックス (フォルダ と呼ばれます)を含んでもかまいません。フォルダは無限にネストできます。 MH メールボックスにはもう一つ シーケンス という名前付きのリストでメッセージをサブフォルダに移動することなく論理的に分類するものがサポートされています。シーケンスは各フォルダの .mh_sequences というファイルで定義されます。

MH クラスは MH メールボックスを操作しますが、 mh の動作の全てを模倣しようとはしていません。特に、 mh が状態と設定を保存する context や .mh_profile といったファイルは書き換えませんし影響も受けません。

MH インスタンスには Mailbox の全てのメソッドの他に次のメソッドがあります。

list_folders()

全てのフォルダの名前のリストを返します。

get_folder(folder)

folder という名前のフォルダを表わす MH インスタンスを返します。もしフォルダが存在しなければ NoSuchMailboxError 例外が送出されます。

add_folder(folder)

folder という名前のフォルダを作成し、それを表わす MH インスタンスを返します。

remove_folder(folder)

folder という名前のフォルダを削除します。フォルダにメッセージが一つでも残っていれば、 NotEmptyError 例外が送出されフォルダは削除されません。

get_sequences()

シーケンス名をキーのリストに対応付ける辞書を返します。シーケンスが一つもなければ空の辞書を返します。

set_sequences(sequences)

メールボックス中のシーケンスを get_sequences() で返されるような名前とキーのリストを対応付ける辞書 sequences に基づいて再定義します。

pack()

番号付けの間隔を詰める必要に応じてメールボックス中のメッセージの名前を付け替えます。シーケンスのリストのエントリもそれに応じて更新されます。

ノート

既に発行されたキーはこの操作によって無効になるのでそれ以降使ってはなりません。

MH で実装された Mailbox のいくつかのメソッドには特別な注意が必要です。

remove(key)

__delitem__(key)

discard(key)

これらのメソッドはメッセージを直ちに削除します。名前の前にコンマを付加してメッセージに削除の印を付けるという MH の規約は使いません。

lock()

unlock()

3種類のロック機構が使われます — ドットロッキングと、もし使用可能ならば flock() と lockf() システムコールです。 MH メールボックスに対するロックとは .mh_sequences のロックと、それが影響を与える操作中だけの個々のメッセージファイルに対するロックを意味します。

get_file(key)

ホストのプラットフォームによっては、返されたファイルが開いている間、元になったメッセージを変更したり削除したりできない場合があります。

flush()

MH メールボックスへの変更は即時に適用されますのでこのメソッドは何もしません。

close()

MH インスタンスは開いたファイルを保持しませんのでこのメソッドは unlock() と同じです。

参考

nmh - Message Handling System [http://www.nongnu.org/nmh/]

mh の改良版である nmh のホームページ

MH & nmh: Email for Users & Programmers [http://rand-mh.sourceforge.net/book/]

GPLライセンスの mh および nmh の本で、このメールボックス形式についての情報があります

18.4.1.4. Babyl

class mailbox.Babyl(path[, factory=None[, create=True]])

Babyl 形式のメールボックスのための Mailbox のサブクラス。パラメータ factory は呼び出し可能オブジェクトで (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 factory が None ならば、 BabylMessage がデフォルトのメッセージ表現として使われます。 create が True ならばメールボックスが存在しないときには作成します。

Babyl は単一ファイルのメールボックス形式で Emacs に付属している Rmail メールユーザエージェントで使われているものです。メッセージの開始は Control-Underscore ('\\037') および Control-L ('\\014') の二文字を含む行で示されます。メッセージの終了は次のメッセージの開始または最後のメッセージの場合には Control-Underscore を含む行で示されます。

Babyl メールボックス中のメッセージには二つのヘッダのセット、オリジナルヘッダといわゆる可視ヘッダ、があります。可視ヘッダは典型的にはオリジナルヘッダの一部を分り易いように再整形したり短くしたりしたものです。 Babyl メールボックス中のそれぞれのメッセージには ラベルというそのメッセージについての追加情報を記録する短い文字列のリストを伴い、メールボックス中に見出されるユーザが定義した全てのラベルのリストは Babyl オプションセクションに保持されます。

Babyl インスタンスには Mailbox の全てのメソッドの他に次のメソッドがあります。

get_labels()

メールボックスで使われているユーザが定義した全てのラベルのリストを返します。

ノート

メールボックスにどのようなラベルが存在するかを決めるのに、 Babyl オプションセクションのリストを参考にせず、実際のメッセージを捜索しますが、 Babyl セクションもメールボックスが変更されたときにはいつでも更新されます。

Babyl で実装された Mailbox のいくつかのメソッドには特別な注意が必要です。

get_file(key)

Babyl メールボックスにおいて、メッセージのヘッダはボディと繋がって格納されていません。ファイル風の表現を生成するために、ヘッダとボディが (StringIO モジュールの) ファイルと同じ API を持つ StringIO インスタンスに一緒にコピーされます。その結果、ファイル風オブジェクトは本当に元にしているメールボックスとは独立していますが、文字列表現と比べてメモリーを節約することにもなりません。

lock()

unlock()

3種類のロック機構が使われます — ドットロッキングと、もし使用可能ならば flock() と lockf() システムコールです。

参考

Format of Version 5 Babyl Files [http://quimby.gnus.org/notes/BABYL]

Babyl 形式の仕様

Reading Mail with Rmail [http://www.gnu.org/software/emacs/manual/html_node/emacs/Rmail.html]

Rmail のマニュアルで Babyl のセマンティクスについての情報も少しある

18.4.1.5. MMDF

class mailbox.MMDF(path[, factory=None[, create=True]])

MMDF 形式のメールボックスのための Mailbox のサブクラス。パラメータ factory は呼び出し可能オブジェクトで (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 factory が None ならば、 BabylMessage がデフォルトのメッセージ表現として使われます。 create が True ならばメールボックスが存在しないときには作成します。

MMDF は単一ファイルのメールボックス形式で Multichannel Memorandum Distribution Facility というメール転送エージェント用に発明されたものです。各メッセージは mbox と同様の形式で収められますが、前後を4つの Control-A ('\\001') を含む行で挟んであります。 mbox 形式と同じようにそれぞれのメッセージの開始は “From ” の5文字を含む行で示されますが、それ以外の場所での “From ” は格納の際 “>From ” には変えられません。それは追加されたメッセージ区切りによって新たなメッセージの開始と見間違うことが避けられるからです。

MMDF で実装された Mailbox のいくつかのメソッドには特別な注意が必要です。

get_file(key)

MMDF インスタンスに対し flush() や close() を呼び出した後でファイルを使用すると予期しない結果を引き起こしたり例外が送出されたりすることがあります。

lock()

unlock()

3種類のロック機構が使われます — ドットロッキングと、もし使用可能ならば flock() と lockf() システムコールです。

参考

tin の mmdf man page [http://www.tin.org/bin/man.cgi?section=5&topic=mmdf]

ニュースリーダ tin のドキュメント中の MMDF 形式仕様

MMDF [http://en.wikipedia.org/wiki/MMDF]

Multichannel Memorandum Distribution Facility についてのウィキペディアの記事

18.4.2. Message objects

class mailbox.Message([message])

email.Message モジュールの Message のサブクラス。 mailbox.Message のサブクラスはメールボックス形式ごとの状態と動作を追加します。

message が省略された場合、新しいインスタンスはデフォルトの空の状態で生成されます。 message が email.Message.Message インスタンスならばその内容がコピーされます。さらに、 message が Message インスタンスならば、形式固有の情報も可能な限り変換されます。 message が文字列またはファイルならば、読まれ解析されるべき RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 準拠のメッセージを含んでいなければなりません

サブクラスにより提供される形式ごとの状態と動作は様々ですが、一般に或るメールボックスに固有のものでないプロパティだけがサポートされます(おそらくプロパティのセットはメールボックス形式ごとに固有でしょうが)。例えば、単一ファイルメールボックス形式におけるファイルオフセットやディレクトリ式メールボックス形式におけるファイル名は保持されません、というのもそれらは元々のメールボックスにしか適用できないからです。しかし、メッセージがユーザに読まれたかどうかあるいは重要だとマークされたかどうかという状態は保持されます、というのはそれらはメッセージ自体に適用されるからです。

Mailbox インスタンスを使って取得したメッセージを表現するのに Message インスタンスが使われなければいけないとは要求していません。ある種の状況では Message による表現を生成するのに必要な時間やメモリーが受け入れられないこともあります。そういった状況では Mailbox インスタンスは文字列やファイル風オブジェクトの表現も提供できますし、 Mailbox インスタンスを初期化する際にメッセージファクトリーを指定することもできます。

18.4.2.1. MaildirMessage

class mailbox.MaildirMessage([message])

Maildir 固有の動作をするメッセージ。引数 message は Message のコンストラクタと同じ意味を持ちます。

通常、メールユーザエージェントは new サブディレクトリにある全てのメッセージをユーザが最初にメールボックスを開くか閉じるかした後で cur サブディレクトリに移動し、メッセージが実際に読まれたかどうかを記録します。 cur にある各メッセージには状態情報を保存するファイル名に付け加えられた “info” セクションがあります。(メールリーダの中には “info” セクションを new にあるメッセージに付けることもあります。) “info” セクションには二つの形式があります。一つは “2,” の後に標準化されたフラグのリストを付けたもの (たとえば “2,FR”)、もう一つは “1,” の後にいわゆる実験的情報を付け加えるものです。 Maildir の標準的なフラグは以下の通りです:

フラグ | 意味 | 説明
D | ドラフト(Draft) | 作成中
F | フラグ付き(Flagged) | 重要とされたもの
P | 通過(Passed) | 転送、再送またはバウンス
R | 返答済み(Replied) | 返答されたもの
S | 既読(Seen) | 読んだもの
T | ごみ(Trashed) | 削除予定とされたもの

MaildirMessage インスタンスは以下のメソッドを提供します。

get_subdir()

“new” (メッセージが new サブディレクトリに保存されるべき場合) または “cur” (メッセージが cur サブディレクトリに保存されるべき場合)のどちらかを返します。

ノート

メッセージは通常メールボックスがアクセスされた後、メッセージが読まれたかどうかに関わらず new から cur に移動されます。メッセージ msg は "S" not in msg.get_flags() が True ならば読まれています。

set_subdir(subdir)

メッセージが保存されるべきサブディレクトリをセットします。パラメータ subdir は “new” または “cur” のいずれかでなければなりません。

get_flags()

現在セットされているフラグを特定する文字列を返します。メッセージが標準 Maildir 形式に準拠しているならば、結果はアルファベット順に並べられたゼロまたは1回の 'D' 、 'F' 、 'P' 、 'R' 、 'S' 、 'T' をつなげたものです。空文字列が返されるのはフラグが一つもない場合、または “info” が実験的セマンティクスを使っている場合です。

set_flags(flags)

flags で指定されたフラグをセットし、他のフラグは下ろします。

add_flag(flag)

flags で指定されたフラグをセットしますが他のフラグは変えません。一度に二つ以上のフラグをセットすることは、 flag に2文字以上の文字列を指定すればできます。現在の “info” はフラグの代わりに実験的情報を使っていても上書きされます。

remove_flag(flag)

flags で指定されたフラグを下ろしますが他のフラグは変えません。一度に二つ以上のフラグを取り除くことは、 flag に2文字以上の文字列を指定すればできます。 “info” がフラグの代わりに実験的情報を使っている場合は現在の “info” は書き換えられません。

get_date()

メッセージの配送日時をエポックからの秒数を表わす浮動小数点数で返します。

set_date(date)

メッセージの配送日時を date にセットします。 date はエポックからの秒数を表わす浮動小数点数です。

get_info()

メッセージの “info” を含む文字列を返します。このメソッドは実験的 (即ちフラグのリストでない) “info” にアクセスし、また変更するのに役立ちます。

set_info(info)

“info” に文字列 info をセットします。

MaildirMessage インスタンスが mboxMessage や MMDFMessage のインスタンスに基づいて生成されるとき、 Status および X-Status ヘッダは省かれ以下の変換が行われます:

結果の状態 | mboxMessage または MMDFMessage の状態
“cur” サブディレクトリ | O フラグ
F フラグ | F フラグ
R フラグ | A フラグ
S フラグ | R フラグ
T フラグ | D フラグ

MaildirMessage インスタンスが MHMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | MHMessage の状態
“cur” サブディレクトリ | “unseen” シーケンス
“cur” サブディレクトリおよび S フラグ | “unseen” シーケンス無し
F フラグ | “flagged” シーケンス
R フラグ | “replied” シーケンス

MaildirMessage インスタンスが BabylMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | BabylMessage の状態
“cur” サブディレクトリ | “unseen” ラベル
“cur” サブディレクトリおよび S フラグ | “unseen” ラベル無し
P フラグ | “forwarded” または “resent” ラベル
R フラグ | “answered” ラベル
T フラグ | “deleted” ラベル

18.4.2.2. mboxMessage

class mailbox.mboxMessage([message])

mbox 固有の動作をするメッセージ。引数 message は Message のコンストラクタと同じ意味を持ちます。

mbox メールボックス中のメッセージは単一ファイルにまとめて格納されています。送り主のエンベロープアドレスおよび配送日時は通常メッセージの開始を示す “From ” から始まる行に記録されますが、正確なフォーマットに関しては mbox の実装ごとに大きな違いがあります。メッセージの状態を示すフラグ、たとえば読んだかどうかあるいは重要だとマークを付けられているかどうかといったようなもの、は典型的には Status および X-Status に収められます。

規定されている mbox メッセージのフラグは以下の通りです:

フラグ | 意味 | 説明
R | 既読(Read) | 読んだ
O | 古い(Old) | 以前に MUA に発見された
D | 削除(Deleted) | 削除予定
F | フラグ付き(Flagged) | 重要だとマークされた
A | 返答済み(Answered) | 返答した

“R” および “O” フラグは Status ヘッダに記録され、 “D”、”F”、”A” フラグは X-Status ヘッダに記録されます。フラグとヘッダは通常記述された順番に出現します。

mboxMessage インスタンスは以下のメソッドを提供します:

get_from()

mbox メールボックスのメッセージの開始を示す “From ” 行を表わす文字列を返します。先頭の “From ” および末尾の改行は含まれません。

set_from(from_[, time_=None])

“From ” 行を from_ にセットします。 from_ は先頭の “From ” や末尾の改行を含まない形で指定しなければなりません。利便性のために、 time_ を指定して適切に整形して from_ に追加させることができます。 time_ を指定する場合、それは struct_time インスタンス、 time.strftime() に渡すのに適したタプル、または True (この場合 time.gmtime() を使います) のいずれかでなければなりません。

get_flags()

現在セットされているフラグを特定する文字列を返します。メッセージが規定された形式に準拠しているならば、結果は次の順に並べられた 0回か1回の 'R' 、 'O' 、 'D' 、 'F' 、 'A' です。

set_flags(flags)

flags で指定されたフラグをセットして、他のフラグは下ろします。 flags は並べられたゼロまたは1回の 'R' 、 'O' 、 'D' 、 'F' 、 'A' です。

add_flag(flag)

flags で指定されたフラグをセットしますが他のフラグは変えません。一度に二つ以上のフラグをセットすることは、 flag に2文字以上の文字列を指定すればできます。

remove_flag(flag)

flags で指定されたフラグを下ろしますが他のフラグは変えません。一度に二つ以上のフラグを取り除くことは、 flag に2文字以上の文字列を指定すればできます。

mboxMessage インスタンスが MaildirMessage インスタンスに基づいて生成されるとき、 MaildirMessage インスタンスの配送日時に基づいて “From ” 行が作り出され、次の変換が行われます:

結果の状態 | MaildirMessage の状態
R フラグ | S フラグ
O フラグ | “cur” サブディレクトリ
D フラグ | T フラグ
F フラグ | F フラグ
A フラグ | R フラグ

mboxMessage インスタンスが MHMessage インスタンスに基づいて生成されるとき、以下の変換が行われます。

結果の状態 | MHMessage 状態
R フラグおよび O フラグ | “unseen” シーケンス無し
O フラグ | “unseen” シーケンス
F フラグ | “flagged” シーケンス
A フラグ | “replied” シーケンス

mboxMessage インスタンスが BabylMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | BabylMessage の状態
R フラグおよび O フラグ | “unseen” ラベル無し
O フラグ | “unseen” ラベル
D フラグ | “deleted” ラベル
A フラグ | “answered” ラベル

mboxMessage インスタンスが MMDFMessage インスタンスに基づいて生成されるとき、”From ” 行はコピーされ全てのフラグは直接対応します:

結果の状態 | MMDFMessage の状態
R フラグ | R フラグ
O フラグ | O フラグ
D フラグ | D フラグ
F フラグ | F フラグ
A フラグ | A フラグ

18.4.2.3. MHMessage

class mailbox.MHMessage([message])

MH 固有の動作をするメッセージ。引数 message は Message のコンストラクタと同じ意味を持ちます。

MH メッセージは伝統的な意味あいにおいてマークやフラグをサポートしません。しかし、MH メッセージにはシーケンスがあり任意のメッセージを論理的にグループ分けできます。いくつかのメールソフト(標準の mh や nmh はそうではありませんが) は他の形式におけるフラグとほぼ同じようにシーケンスを使います。

シーケンス | 説明
unseen | 読んではいないが既にMUAに見つけられている
replied | 返答した
flagged | 重要だとマークされた

MHMessage インスタンスは以下のメソッドを提供します:

get_sequences()

このメッセージを含むシーケンスの名前のリストを返す。

set_sequences(sequences)

このメッセージを含むシーケンスのリストをセットする。

add_sequence(sequence)

sequence をこのメッセージを含むシーケンスのリストに追加する。

remove_sequence(sequence)

sequence をこのメッセージを含むシーケンスのリストから除く。

MHMessage インスタンスが MaildirMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | MaildirMessage の状態
“unseen” シーケンス | S フラグ無し
“replied” シーケンス | R フラグ
“flagged” シーケンス | F フラグ

MHMessage インスタンスが mboxMessage や MMDFMessage のインスタンスに基づいて生成されるとき、 Status および X-Status ヘッダは省かれ以下の変換が行われます:

結果の状態 | mboxMessage または MMDFMessage の状態
“unseen” シーケンス | R フラグ無し
“replied” シーケンス | A フラグ
“flagged” シーケンス | F フラグ

MHMessage インスタンスが BabylMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | BabylMessage の状態
“unseen” シーケンス | “unseen” ラベル
“replied” シーケンス | “answered” ラベル

18.4.2.4. BabylMessage

class mailbox.BabylMessage([message])

Babyl 固有の動作をするメッセージ。引数 message は Message のコンストラクタと同じ意味を持ちます。

ある種のメッセージラベルは アトリビュート と呼ばれ、規約により特別な意味が与えられています。アトリビュートは以下の通りです:

ラベル | 説明
unseen | 読んでいないが既に MUA に見つかっている
deleted | 削除予定
filed | 他のファイルまたはメールボックスにコピーされた
answered | 返答済み
forwarded | 転送された
edited | ユーザによって変更された
resent | 再送された

デフォルトでは Rmail は可視ヘッダのみ表示します。 BabylMessage クラスはしかし、オリジナルヘッダをより完全だという理由で使います。可視ヘッダは望むならそのように指示してアクセスすることができます。

BabylMessage インスタンスは以下のメソッドを提供します:

get_labels()

メッセージに付いているラベルのリストを返します。

set_labels(labels)

メッセージに付いているラベルのリストを labels にセットします。

add_label(label)

メッセージに付いているラベルのリストに label を追加します。

remove_label(label)

メッセージに付いているラベルのリストから label を削除します。

get_visible()

ヘッダがメッセージの可視ヘッダでありボディが空であるような Message インスタンスを返します。

set_visible(visible)

メッセージの可視ヘッダを visible のヘッダと同じにセットします。引数 visible は Message インスタンスまたは email.Message.Message インスタンス、文字列、ファイル風オブジェクト(テキストモードで開かれてなければなりません)のいずれかです。

update_visible()

BabylMessage インスタンスのオリジナルヘッダが変更されたとき、可視ヘッダは自動的に対応して変更されるわけではありません。このメソッドは可視ヘッダを以下のように更新します。対応するオリジナルヘッダのある可視ヘッダはオリジナルヘッダの値がセットされます。対応するオリジナルヘッダの無い可視ヘッダは除去されます。そして、オリジナルヘッダにあって可視ヘッダに無い Date 、 From 、 Reply-To 、 To 、 CC 、 Subject は可視ヘッダに追加されます。

BabylMessage インスタンスが MaildirMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | MaildirMessage の状態
“unseen” ラベル | S フラグ無し
“deleted” ラベル | T フラグ
“answered” ラベル | R フラグ
“forwarded” ラベル | P フラグ

BabylMessage インスタンスが mboxMessage や MMDFMessage のインスタンスに基づいて生成されるとき、 Status および X-Status ヘッダは省かれ以下の変換が行われます:

結果の状態 | mboxMessage または MMDFMessage の状態
“unseen” ラベル | R フラグ無し
“deleted” ラベル | D フラグ
“answered” ラベル | A フラグ

BabylMessage インスタンスが MHMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | MHMessage の状態
“unseen” ラベル | “unseen” シーケンス
“answered” ラベル | “replied” シーケンス

18.4.2.5. MMDFMessage

class mailbox.MMDFMessage([message])

MMDF 固有の動作をするメッセージ。引数 message は Message のコンストラクタと同じ意味を持ちます。

mbox メールボックスのメッセージと同様に、MMDF メッセージは送り主のアドレスと配送日時が最初の “From ” で始まる行に記録されています。同様に、メッセージの状態を示すフラグは通常 Status および X-Status ヘッダに収められています。

よく使われる MMDF メッセージのフラグは mbox メッセージのものと同一で以下の通りです:

フラグ | 意味 | 説明
R | 既読(Read) | 読んだ
O | 古い(Old) | 以前に MUA に発見された
D | 削除(Deleted) | 削除予定
F | フラグ付き(Flagged) | 重要だとマークされた
A | 返答済み(Answered) | 返答した

“R” および “O” フラグは Status ヘッダに記録され、 “D”、”F”、”A” フラグは X-Status ヘッダに記録されます。フラグとヘッダは通常記述された順番に出現します。

MMDFMessage インスタンスは mboxMessage インスタンスと同一の以下のメソッドを提供します:

mailbox.get_from()

MMDF メールボックスのメッセージの開始を示す “From ” 行を表わす文字列を返します。先頭の “From ” および末尾の改行は含まれません。

mailbox.set_from(from_[, time_=None])

“From ” 行を from_ にセットします。 from_ は先頭の “From ” や末尾の改行を含まない形で指定しなければなりません。利便性のために、 time_ を指定して適切に整形して from_ に追加させることができます。 time_ を指定する場合、それは struct_time インスタンス、 time.strftime() に渡すのに適したタプル、または True (この場合 time.gmtime() を使います) のいずれかでなければなりません。

mailbox.get_flags()

現在セットされているフラグを特定する文字列を返します。メッセージが規定された形式に準拠しているならば、結果は次の順に並べられたゼロまたは1回の 'R' 、 'O' 、 'D' 、 'F' 、 'A' です。

mailbox.set_flags(flags)

flags で指定されたフラグをセットして、他のフラグは下ろします。 flags は並べられたゼロまたは1回の 'R' 、 'O' 、 'D' 、 'F' 、 'A' です。

mailbox.add_flag(flag)

flags で指定されたフラグをセットしますが他のフラグは変えません。一度に二つ以上のフラグをセットすることは、 flag に2文字以上の文字列を指定すればできます。

mailbox.remove_flag(flag)

flags で指定されたフラグを下ろしますが他のフラグは変えません。一度に二つ以上のフラグを取り除くことは、 flag に2文字以上の文字列を指定すればできます。

MMDFMessage インスタンスが MaildirMessage インスタンスに基づいて生成されるとき、 MaildirMessage インスタンスの配送日時に基づいて “From ” 行が作り出され、次の変換が行われます:

結果の状態 | MaildirMessage の状態
R フラグ | S フラグ
O フラグ | “cur” サブディレクトリ
D フラグ | T フラグ
F フラグ | F フラグ
A フラグ | R フラグ

MMDFMessage インスタンスが MHMessage インスタンスに基づいて生成されるとき、以下の変換が行われます。

結果の状態 | MHMessage 状態
R フラグおよび O フラグ | “unseen” シーケンス無し
O フラグ | “unseen” シーケンス
F フラグ | “flagged” シーケンス
A フラグ | “replied” シーケンス

MMDFMessage インスタンスが BabylMessage インスタンスに基づいて生成されるとき、以下の変換が行われます:

結果の状態 | BabylMessage の状態
R フラグおよび O フラグ | “unseen” ラベル無し
O フラグ | “unseen” ラベル
D フラグ | “deleted” ラベル
A フラグ | “answered” ラベル

MMDFMessage インスタンスが mboxMessage インスタンスに基づいて生成されるとき、”From ” 行はコピーされ全てのフラグは直接対応します:

結果の状態 | mboxMessage の状態
R フラグ | R フラグ
O フラグ | O フラグ
D フラグ | D フラグ
F フラグ | F フラグ
A フラグ | A フラグ

18.4.3. 例外

mailbox モジュールでは以下の例外クラスが定義されています:

exception mailbox.Error

他の全てのモジュール固有の例外の基底クラス。

exception mailbox.NoSuchMailboxError

メールボックスがあると思っていたが見つからなかった場合に送出されます。これはたとえば Mailbox のサブクラスを存在しないパスでインスタンス化しようとしたとき(かつ create パラメータは False であった場合)、あるいは存在しないフォルダを開こうとした時などに発生します。

exception mailbox.NotEmptyError

メールボックスが空であることを期待されているときに空でない場合、たとえばメッセージの残っているフォルダを削除しようとした時などに送出されます。

exception mailbox.ExternalClashError

メールボックスに関係したある条件がプログラムの制御を外れてそれ以上作業を続けられなくなった場合、たとえば他のプログラムが既に保持しているロックを取得しようとして失敗したとき、あるいは一意的に生成されたファイル名が既に存在していた場合などに送出されます。

exception mailbox.FormatError

ファイル中のデータが解析できない場合、たとえば MH インスタンスが壊れた .mh_sequences ファイルを読もうと試みた場合などに送出されます。

18.4.4. 撤廃されたクラスとメソッド

バージョン 2.6 で撤廃.

古いバージョンの mailbox モジュールはメッセージの追加や削除といったメールボックスの変更をサポートしていませんでした。また形式ごとのメッセージプロパティを表現するクラスも提供していませんでした。後方互換性のために、古いメールボックスクラスもまだ使うことができますが、できるだけ新しいクラスを使うべきです。古いクラスは Python 3.0 で削除されます。

古いメールボックスオブジェクトは繰り返しと一つの公開メソッドだけを提供していました:

oldmailbox.next()

メールボックスオブジェクトのコンストラクタに渡された、オプションの factory 引数を使って、メールボックス中の次のメッセージを生成して返します。標準の設定では、 factory は rfc822.Message オブジェクトです (rfc822 モジュールを参照してください)。メールボックスの実装により、このオブジェクトの fp 属性は真のファイルオブジェクトかもしれないし、複数のメールメッセージが単一のファイルに収められているなどの場合に、メッセージ間の境界を注意深く扱うためにファイルオブジェクトをシミュレートするクラスのインスタンスであるかもしれません。次のメッセージがない場合、このメソッドは None を返します。

ほとんどの古いメールボックスクラスは現在のメールボックスクラスと違う名前ですが、 Maildir だけは例外です。そのため、新しい方の Maildir クラスには next() メソッドが定義され、コンストラクタも他の新しいメールボックスクラスとは少し異なります。

古いメールボックスのクラスで名前が新しい対応物と同じでないものは以下の通りです:

class mailbox.UnixMailbox(fp[, factory])

全てのメッセージが単一のファイルに収められ、 From (From_ として知られています) 行によって分割されているような、旧来の Unix形式のメールボックスにアクセスします。ファイルオブジェクト fp はメールボックスファイルを指します。オプションの factory パラメタは新たなメッセージオブジェクトを生成するような呼び出し可能オブジェクトです。 factory は、メールボックスオブジェクトに対して next() メソッドを実行した際に、単一の引数、 fp を伴って呼び出されます。この引数の標準の値は rfc822.Message クラスです (rfc822 モジュール – および以下 – を参照してください)。

ノート

このモジュールの実装上の理由により、 fp オブジェクトはバイナリモードで開くようにしてください。特にWindows上では注意が必要です。

可搬性を最大限にするために、Unix形式のメールボックス内にあるメッセージは、正確に 'From ' (末尾の空白に注意してください) で始まる文字列が、直前の正しく二つの改行の後にくるような行で分割されます。現実的には広範なバリエーションがあるため、それ以外の From_ 行について考慮すべきではないのですが、現在の実装では先頭の二つの改行をチェックしていません。これはほとんどのアプリケーションでうまく動作します。

UnixMailbox クラスでは、ほぼ正確に From_ デリミタにマッチするような正規表現を用いることで、より厳密に From_ 行のチェックを行うバージョンを実装しています。 UnixMailbox ではデリミタ行が From name time の行に分割されるものと考えます。可搬性を最大限にするためには、代わりに PortableUnixMailbox クラスを使ってください。このクラスは UnixMailbox と同じですが、個々のメッセージは From 行だけで分割されるものとみなします。

class mailbox.PortableUnixMailbox(fp[, factory])

厳密性の低い UnixMailbox のバージョンで、メッセージを分割する行は From のみであると見なします。実際に見られるメールボックスのバリエーションに対応するため、 From 行における “name time” 部分は無視されます。メール処理ソフトウェアはメッセージ中の 'From ' で始まる行をクオートするため、この分割はうまく動作します。

class mailbox.MmdfMailbox(fp[, factory])

全てのメッセージが単一のファイルに収められ、4 つの control-A 文字によって分割されているような、MMDF 形式のメールボックスにアクセスします。ファイルオブジェクト fp はメールボックスファイルをさします。オプションの factory は UnixMailbox クラスにおけるのと同様です。

class mailbox.MHMailbox(dirname[, factory])

数字で名前のつけられた別々のファイルに個々のメッセージを収めたディレクトリである、MH メールボックスにアクセスします。メールボックスディレクトリの名前は dirname で渡します。 factory は UnixMailbox クラスにおけるのと同様です。

class mailbox.BabylMailbox(fp[, factory])

MMDF メールボックスと似ている、Babyl メールボックスにアクセスします。 Babyl 形式では、各メッセージは二つのヘッダからなるセット、 original ヘッダおよび visible ヘッダを持っています。 original ヘッダは '*** EOOH ***' (End-Of-Original-Headers) だけを含む行の前にあり、visible ヘッダは EOOH 行の後にあります。Babyl 互換のメールリーダは visible ヘッダのみを表示し、 BabylMailbox オブジェクトは visible ヘッダのみを含むようなメッセージを返します。メールメッセージは EOOH 行で始まり、 '\037\014' だけを含む行で終わります。 factory は UnixMailbox クラスにおけるのと同様です。

古いメールボックスクラスを撤廃された rfc822 モジュールではなく、 email モジュールと使いたいならば、以下のようにできます:

import email
import email.Errors
import mailbox

def msgfactory(fp):
    try:
        return email.message_from_file(fp)
    except email.Errors.MessageParseError:
        # Don't return None since that will
        # stop the mailbox iterator
        return ''

mbox = mailbox.UnixMailbox(fp, msgfactory)

一方、メールボックス内には正しい形式の MIME メッセージしか入っていないと分かっているのなら、単に以下のようにします:

import email
import mailbox

mbox = mailbox.UnixMailbox(fp, email.message_from_file)

18.4.5. 例

メールボックス中の面白そうなメッセージのサブジェクトを全て印字する簡単な例:

import mailbox
for message in mailbox.mbox('~/mbox'):
    subject = message['subject']       # Could possibly be None.
    if subject and 'python' in subject.lower():
        print subject

Babyl メールボックスから MH メールボックスへ全てのメールをコピーし、変換可能な全ての形式固有の情報を変換する:

import mailbox
destination = mailbox.MH('~/Mail')
destination.lock()
for message in mailbox.Babyl('~/RMAIL'):
    destination.add(mailbox.MHMessage(message))
destination.flush()
destination.unlock()

この例は幾つかのメーリングリストのメールをソートするものです。他のプログラムと平行して変更を加えることでメールが破損したり、プログラムを中断することでメールを失ったり、はたまた半端なメッセージがメールボックス中にあることで途中で終了してしまう、といったことを避けるように注意深く扱っています。:

import mailbox
import email.Errors

list_names = ('python-list', 'python-dev', 'python-bugs')

boxes = dict((name, mailbox.mbox('~/email/%s' % name)) for name in list_names)
inbox = mailbox.Maildir('~/Maildir', factory=None)

for key in inbox.iterkeys():
    try:
        message = inbox[key]
    except email.Errors.MessageParseError:
        continue                # The message is malformed. Just leave it.

    for name in list_names:
        list_id = message['list-id']
        if list_id and name in list_id:
            # Get mailbox to use
            box = boxes[name]

            # Write copy to disk before removing original.
            # If there's a crash, you might duplicate a message, but
            # that's better than losing a message completely.
            box.lock()
            box.add(message)
            box.flush()
            box.unlock()

            # Remove original message
            inbox.lock()
            inbox.discard(key)
            inbox.flush()
            inbox.unlock()
            break               # Found destination, so stop looking.

for box in boxes.itervalues():
    box.close()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.5. mhlib — MH のメールボックスへのアクセス機構

バージョン 2.6 で撤廃: mhlib は Python 3.0 では削除されています。代わりに mailbox をお使い下さい。

mhlib モジュールは MH フォルダおよびその内容に対する Python インタフェースを提供します。

このモジュールには、あるフォルダの集まりを表現する MH 、単一のフォルダを表現する Folder 、単一のメッセージを表現する Message 、の 3 つのクラスが入っています。

class mhlib.MH([path[, profile]])

MH は MH フォルダの集まりを表現します。

class mhlib.Folder(mh, name)

Folder クラスは単一のフォルダとフォルダ内のメッセージ群を表現します。

class mhlib.Message(folder, number[, name])

Message オブジェクトはフォルダ内の個々のメッセージを表現します。メッセージクラスは mimetools.Message から派生しています。

18.5.1. MH オブジェクト

MH インスタンスは以下のメソッドを持っています:

MH.error(format[, ...])

エラーメッセージを出力します – 上書きすることができます。

MH.getprofile(key)

プロファイルエントリ (設定されていなければ None) を返します。

MH.getpath()

メールボックスのパス名を返します。

MH.getcontext()

現在のフォルダ名を返します。

MH.setcontext(name)

現在のフォルダ名を設定します。

MH.listfolders()

トップレベルフォルダのリストを返します。

MH.listallfolders()

全てのフォルダを列挙します。

MH.listsubfolders(name)

指定したフォルダの直下にあるサブフォルダのリストを返します。

MH.listallsubfolders(name)

指定したフォルダの下にある全てのサブフォルダのリストを返します。

MH.makefolder(name)

新しいフォルダを生成します。

MH.deletefolder(name)

フォルダを削除します – サブフォルダが入っていてはいけません。

MH.openfolder(name)

新たな開かれたフォルダオブジェクトを返します。

18.5.2. Folder オブジェクト

Folder インスタンスは開かれたフォルダを表現し、以下のメソッドを持っています:

Folder.error(format[, ...])

エラーメッセージを出力します – 上書きすることができます。

Folder.getfullname()

フォルダの完全なパス名を返します。

Folder.getsequencesfilename()

フォルダ内のシーケンスファイルの完全なパス名を返します。

Folder.getmessagefilename(n)

フォルダ内のメッセージ n の完全なパス名を返します。

Folder.listmessages()

フォルダ内のメッセージの (番号の) リストを返します。

Folder.getcurrent()

現在のメッセージ番号を返します。

Folder.setcurrent(n)

現在のメッセージ番号を n に設定します。

Folder.parsesequence(seq)

msgs 文を解釈して、メッセージのリストにします。

Folder.getlast()

最新のメッセージを取得します。メッセージがフォルダにない場合には 0 を返します。

Folder.setlast(n)

最新のメッセージを設定します (内部使用のみ)。

Folder.getsequences()

フォルダ内のシーケンスからなる辞書を返します。シーケンス名がキーとして使われ、値はシーケンスに含まれるメッセージ番号のリストになります。

Folder.putsequences(dict)

フォルダ内のシーケンスからなる辞書 name: list を返します。

Folder.removemessages(list)

リスト中のメッセージをフォルダから削除します。

Folder.refilemessages(list, tofolder)

リスト中のメッセージを他のフォルダに移動します。

Folder.movemessage(n, tofolder, ton)

一つのメッセージを他のフォルダの指定先に移動します。

Folder.copymessage(n, tofolder, ton)

一つのメッセージを他のフォルダの指定先にコピーします。

18.5.3. Message オブジェクト

Message クラスは mimetools.Message のメソッドに加え、一つメソッドを持っています:

Message.openmessage(n)

新たな開かれたメッセージオブジェクトを返します (ファイル記述子を一つ消費します)。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.6. mimetools — MIME メッセージを解析するためのツール

バージョン 2.3 で撤廃: email パッケージを mimetools モジュールより優先して使うべきです。このモジュールは、下位互換性維持のためにのみ存在しています。Python 3.x では削除されています。

このモジュールは、 rfc822 モジュールの Message クラスのサブクラスと、マルチパート MIME や符合化メッセージの操作に役に立つ多くのユーティリティ関数を定義しています。

これには以下の項目が定義されています：

class mimetools.Message(fp[, seekable])

Message クラスの新しいインスタンスを返します。これは、 rfc822.Message クラスのサブクラスで、いくつかの追加のメソッドがあります(以下を参照のこと)。 seekable 引数は、 rfc822.Message のものと同じ意味を持ちます。

mimetools.choose_boundary()

パートの境界として使うことができる見込みが高いユニークな文字列を返します。その文字列は、 'hostipaddr.uid.pid.timestamp.random' の形をしています。

mimetools.decode(input, output, encoding)

オープンしたファイルオブジェクト input から、許される MIME encoding を使って符号化されたデータを読んで、オープンされたファイルオブジェクト output に復号化されたデータを書きます。 encoding に許される値は、 'base64', 'quoted-printable', 'uuencode', 'x-uuencode', 'uue', 'x-uue', '7bit', および '8bit' です。 '7bit' あるいは '8bit' で符号化されたメッセージを復号化しても何も効果がありません。入力が出力に単純にコピーされるだけです。

mimetools.encode(input, output, encoding)

オープンしたファイルオブジェクト input からデータを読んで、それを許される MIME encoding を使って符号化して、オープンしたファイルオブジェクト output に書きます。 encoding に許される値は、 decode() のものと同じです。

mimetools.copyliteral(input, output)

オープンしたファイル input から行を EOF まで読んで、それらをオープンしたファイル output に書きます。

mimetools.copybinary(input, output)

オープンしたファイル input からブロックを EOF まで読んで、それらをオープンしたファイル output に書きます。ブロックの大きさは現在 8192 に固定されています。

参考

Module email

圧縮電子メール操作パッケージ； mimetools モジュールに委譲。

Module rfc822

mimetools.Message のベースクラスを提供する。

Module multifile

MIME データのような、別個のパーツを含むファイルの読み込みをサポート。

http://faqs.cs.uu.nl/na-dir/mail/mime-faq/.html

MIME でよく訊ねられる質問。MIMEの概要に関しては、この文書の Part 1 の質問 1.1 への答えを見ること。

18.6.1. Message オブジェクトの追加メソッド

Message クラスは、 rfc822.Message メソッドに加えて、以下のメソッドを定義しています：

Message.getplist()

Content-Type ヘッダのパラメータリストを返します。これは文字列のリストです。 key=value の形のパラメータに対しては、key は小文字に変換されますが、value は変換されません。たとえば、もしメッセージに、ヘッダ Content-type: text/html; spam=1; Spam=2; Spam が含まれていれば、 getplist() は、Python リスト ['spam=1', 'spam=2', 'Spam'] を返すでしょう。

Message.getparam(name)

与えられた name の( name=value の形に対して getplist() が返す) 第1パラメータの value を返します。もし value が、’<...>‘ あるいは ‘"..."‘ のように引用符で囲まれていれば、これらは除去されます。

Message.getencoding()

Content-Transfer-Encoding メッセージヘッダで指定された符号化方式を返します。もしそのようなヘッダが存在しなければ、'7bit' を返します。符号化方式文字列は小文字に変換されます。

Message.gettype()

Content-Type ヘッダで指定された (type/subtype の形での) メッセージ型を返します。もしそのようなヘッダが存在しなければ、 'text/plain' を返します。型文字列は小文字に変換されます。

Message.getmaintype()

Content-Type ヘッダで指定された主要型を返します。もしそのようなヘッダが存在しなければ、 'text' を返します。主要型文字列は小文字に変換されます。

Message.getsubtype()

Content-Type ヘッダで指定された下位型を返します。もしそのようなヘッダが存在しなければ、 'plain' を返します。下位型文字列は小文字に変換されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.7. mimetypes — ファイル名を MIME 型へマップする

mimetypes モジュールは、ファイル名あるいは URL と、ファイル名拡張子に関連付けられた MIME 型とを変換します。ファイル名から MIME 型へと、 MIME 型からファイル名拡張子への変換が提供されます；後者の変換では符号化方式はサポートされていません。

このモジュールは、一つのクラスと多くの便利な関数を提供します。これらの関数がこのモジュールへの標準のインターフェースですが、アプリケーションによっては、そのクラスにも関係するかもしれません。

以下で説明されている関数は、このモジュールへの主要なインターフェースを提供します。たとえモジュールが初期化されていなくても、もしこれらの関数が、 init() がセットアップする情報に依存していれば、これらの関数は、 init() を呼びます。

mimetypes.guess_type(filename[, strict])

filename で与えられるファイル名あるいは URL に基づいて、ファイルの型を推定します。戻り値は、タプル (type, encoding) です、ここで type は、もし型が(拡張子がないあるいは未定義のため)推定できない場合は、 None を、あるいは、 MIME content-type ヘッダ に利用できる、 'type/subtype' の形の文字列です。

encoding は、符合化方式がない場合は None を、あるいは、符号化に使われるプログラムの名前 (たとえば、 compress あるいは gzip)です。符号化方式は Content-Encoding ヘッダとして使うのに適しており、 Content-Transfer-Encoding ヘッダには適して いません 。マッピングはテーブルドリブンです。符号化方式のサフィックスは大/小文字を区別します; データ型サフィックスは、最初大/小文字を区別して試し、それから大/小文字を区別せずに試します。

省略可能な strict は、既知の MIME 型のリストとして認識されるものが、 IANAに登録された [http://www.iana.org/assignments/media-types] 正式な型のみに限定されるかどうかを指定するフラグです。 strict が true (デフォルト)の時は、IANA 型のみがサポートされます; strict が false のときは、いくつかの追加の、非標準ではあるが、一般的に使用される MIME 型も認識されます。

mimetypes.guess_all_extensions(type[, strict])

type で与えられる MIME 型に基づいてファイルの拡張子を推定します。戻り値は、先頭のドット ('.')を含む、可能なファイル拡張子すべてを与える文字列のリストです。拡張子と特別なデータストリームとの関連付けは保証されませんが、 guess_type() によって MIME型 type とマップされます。

省略可能な strict は guess_type() 関数のものと同じ意味を持ちます。

mimetypes.guess_extension(type[, strict])

type で与えられる MIME 型に基づいてファイルの拡張子を推定します。戻り値は、先頭のドット ('.')を含む、ファイル拡張子を与える文字列のリストです。拡張子と特別なデータストリームとの関連付けは保証されませんが、 guess_type() によって MIME型 type とマップされます。もし type に対して拡張子が推定できない場合は、 None が返されます。

省略可能な strict は guess_type() 関数のものと同じ意味を持ちます。

モジュールの動作を制御するために、いくつかの追加の関数とデータ項目が利用できます。

mimetypes.init([files])

内部のデータ構造を初期化します。もし files が与えられていれば、これはデフォールトの type map を増やすために使われる、一連のファイル名でなければなりません。もし省略されていれば、使われるファイル名は knownfiles から取られます。 Windows であれば、現在のレジストリの設定が読み込まれます。 file あるいは knownfiles 内の各ファイル名は、それ以前に現れる名前より優先されます。繰り返し init() を呼び出すことは許されています。

バージョン 2.7 で変更: 前のバージョンでは、 Windows のレジストリの設定は無視されていました。

mimetypes.read_mime_types(filename)

ファイル filename で与えられた型のマップが、もしあればロードします。型のマップは、先頭の dot ('.') を含むファイル名拡張子を、 'type/subtype' の形の文字列にマッピングする辞書として返されます。もしファイル filename が存在しないか、読み込めなければ、 None が返されます。

mimetypes.add_type(type, ext[, strict])

mime型 type からのマッピングを拡張子 ext に追加します。拡張子がすでに既知であれば、新しい型が古いものに置き替わります。その型がすでに既知であれば、その拡張子が、既知の拡張子のリストに追加されます。

strict が True の時(デフォルト)は、そのマッピングは正式なMIME型に、そうでなければ、非標準のMIME型に追加されます。

mimetypes.inited

グローバルなデータ構造が初期化されているかどうかを示すフラグ。これは init() により true に設定されます。

mimetypes.knownfiles

共通にインストールされた型マップファイル名のリスト。これらのファイルは、普通 mime.types という名前であり、パッケージごとに異なる場所にインストールされます。

mimetypes.suffix_map

サフィックスをサフィックスにマップする辞書。これは、符号化方式と型が同一拡張子で示される符号化ファイルが認識できるように使用されます。例えば、 .tgz 拡張子は、符号化と型が別個に認識できるように .tar.gz にマップされます。

mimetypes.encodings_map

ファイル名拡張子を符号化方式型にマッピングする辞書

mimetypes.types_map

ファイル名拡張子をMIME型にマップする辞書

mimetypes.common_types

ファイル名拡張子を非標準ではあるが、一般に使われているMIME型にマップする辞書

MimeTypes クラスは、1つ以上のMIME-型データベースを必要とするアプリケーションに役に立つでしょう。

class mimetypes.MimeTypes([filenames])

このクラスは、MIME-型データベースを表現します。デフォールトでは、このモジュールの他のものと同じデータベースへのアクセスを提供します。初期データベースは、このモジュールによって提供されるもののコピーで、追加の mime.types -形式のファイルを、 read() あるいは readfp() メソッドを使って、データベースにロードすることで拡張されます。マッピング辞書も、もしデフォールトのデータが望むものでなければ、追加のデータをロードする前にクリアされます。

省略可能な filenames パラメータは、追加のファイルを、デフォールトデータベースの”トップに”ロードさせるのに使うことができます。

バージョン 2.2 で追加.

モジュールの使用例:

>>> import mimetypes
>>> mimetypes.init()
>>> mimetypes.knownfiles
['/etc/mime.types', '/etc/httpd/mime.types', ... ]
>>> mimetypes.suffix_map['.tgz']
'.tar.gz'
>>> mimetypes.encodings_map['.gz']
'gzip'
>>> mimetypes.types_map['.tgz']
'application/x-tar-gz'

18.7.1. Mime型オブジェクト

MimeTypes インスタンスは、 mimetypes モジュールのそれと非常によく似たインターフェースを提供します。

MimeTypes.suffix_map

サフィックスをサフィックスにマップする辞書。これは、符号化方式と型が同一拡張子で示されるような符号化ファイルが認識できるように使用されます。例えば、 .tgz 拡張子は、符号化方式と型が別個に認識できるように .tar.gz に対応づけられます。これは、最初はモジュールで定義されたグローバルな suffix_map のコピーです。

MimeTypes.encodings_map

ファイル名拡張子を符号化型にマッピングする辞書。これは、最初はモジュールで定義されたグローバルな encodings_map のコピーです。

MimeTypes.types_map

ファイル名拡張子をMIME型にマッピングするる辞書。これは、最初はモジュールで定義されたグローバルな types_map のコピーです。

MimeTypes.common_types

ファイル名拡張子を非標準ではあるが、一般に使われているMIME型にマップする辞書。これは、最初はモジュールで定義されたグローバルな common_types のコピーです。

MimeTypes.guess_extension(type[, strict])

guess_extension() 関数と同様ですが、オブジェクトに保存されたテーブルを使用します。

MimeTypes.guess_all_extensions(type[, strict])

guess_all_extensions() と同様ですが、オブジェクトに保存されたテーブルを参照します。

MimeTypes.guess_type(url[, strict])

guess_type() 関数と同様ですが、オブジェクトに保存されたテーブルを使用します。

MimeTypes.read(path)

MIME情報を、 path という名のファイルからロードします。これはファイルを解析するのに readfp() を使用します。

MimeTypes.readfp(file)

MIME型情報を、オープンしたファイルからロードします。ファイルは、標準の mime.types ファイルの形式でなければなりません。

MimeTypes.read_windows_registry()

MIME type 情報を Windows のレジストリから読み込みます。 Windows でのみ利用できます。

バージョン 2.7 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.8. MimeWriter — 汎用 MIME ファイルライター

バージョン 2.3 で撤廃: email パッケージを、 MimeWriter モジュールよりも優先して使用すべきです。このモジュールは、下位互換性維持のためだけに存在します。

このモジュールは、クラス MimeWriter を定義します。この MimeWriter クラスは、MIME マルチパートファイルを作成するための基本的なフォーマッタを実装します。これは出力ファイル内をあちこち移動することも、大量のバッファスペースを使うこともありません。あなたは、最終のファイルに現れるであろう順番に、パートを書かなければなりません。 MimeWriter は、あなたが追加するヘッダをバッファして、それらの順番を並び替えることができるようにします。

class MimeWriter.MimeWriter(fp)

MimeWriter クラスの新しいインスタンスを返します。渡される唯一の引数 fp は、書くために使用するファイルオブジェクトです。 StringIO オブジェクトを使うこともできることに注意して下さい。

18.8.1. MimeWriter オブジェクト

MimeWriter インスタンスには以下のメソッドがあります：

MimeWriter.addheader(key, value[, prefix])

MIMEメッセージに新しいヘッダ行を追加します。 key は、そのヘッダの名前であり、そして value で、そのヘッダの値を明示的に与えます。省略可能な引数 prefix は、ヘッダが挿入される場所を決定します; 0 は最後に追加することを意味し、 1 は先頭への挿入です。デフォールトは最後に追加することです。

MimeWriter.flushheaders()

今まで集められたヘッダすべてが書かれ(そして忘れられ)るようにします。これは、もし全く本体が必要でない場合に役に立ちます。例えば、ヘッダのような情報を保管するために(誤って)使用された、型 message/rfc822 のサブパート用。

MimeWriter.startbody(ctype[, plist[, prefix]])

メッセージの本体に書くのに使用できるファイルのようなオブジェクトを返します。コンテント-型は、与えられた ctype に設定され、省略可能なパラメータ plist は、コンテント-型定義のための追加のパラメータを与えます。 prefix は、そのデフォールトが先頭への挿入以外は addheader() でのように働きます。

MimeWriter.startmultipartbody(subtype[, boundary[, plist[, prefix]]])

メッセージ本体を書くのに使うことができるファイルのようなオブジェクトを返します。更に、このメソッドはマルチパートのコードを初期化します。ここで、 subtype が、そのマルチパートのサブタイプを、 boundary がユーザ定義の境界仕様を、そして plist が、そのサブタイプ用の省略可能なパラメータを定義します。 prefix は、 startbody() でのように働きます。サブパートは、 nextpart() を使って作成するべきです。

MimeWriter.nextpart()

マルチパートメッセージの個々のパートを表す、 MimeWriter の新しいインスタンスを返します。これは、そのパートを書くのにも、また複雑なマルチパートを再帰的に作成するのにも使うことができます。メッセージは、 nextpart() を使う前に, 最初 startmultipartbody() で初期化しなければなりません。

MimeWriter.lastpart()

これは、マルチパートメッセージの最後のパートを指定するのに使うことができ、マルチパートメッセージを書くときは いつでも 使うべきです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.9. mimify — 電子メールメッセージの MIME 処理

バージョン 2.3 で撤廃: mimify モジュールを使うよりも email パッケージを使うべきです。このモジュールは以前のバージョンとの互換性のために保守されているにすぎません。

mimify モジュールでは電子メールメッセージから MIME へ、および MIME から電子メールメッセージへの変換を行うための二つの関数を定義しています。電子メールメッセージは単なるメッセージでも、 MIME 形式でもかまいません。各パートは個別に扱われます。メッセージ (の一部) の MIME 化 (mimify) の際、7 ビット ASCII 文字を使って表現できない何らかの文字が含まれていた場合、メッセージの quoted-printable への符号化が伴います。メッセージが送信される前に編集しなければならない場合、 MIME 化および非 MIME 化は特に便利です。典型的な使用法は以下のようになります:

unmimify message
edit message
mimify message
send message

モジュールでは以下のユーザから呼び出し可能な関数と、ユーザが設定可能な変数を定義しています:

mimify.mimify(infile, outfile)

infile を outfile にコピーします。その際、パートを quoted-printable に変換し、必要なら MIME メールヘッダを追加します。 infile および outfile はファイルオブジェクト (実際には、 readline() メソッドを持つ (infile) か、 write() (outfile) メソッドを持つあらゆるオブジェクト) か、ファイル名を指す文字列を指定することができます。 infile および outfile が両方とも文字列の場合、同じ値にすることができます。

mimify.unmimify(infile, outfile[, decode_base64])

infile を outfile にコピーします。その際、全ての quoted-printable 化されたパートを復号化します。 infile および outfile はファイルオブジェクト (実際には、 readline() メソッドを持つ (infile) か、 write() (outfile) メソッドを持つあらゆるオブジェクト) か、ファイル名を指す文字列を指定することができます。 decode_base64 引数が与えられており、その値が真である場合、 base64 符号で符号化されているパートも同様に復号化されます。

mimify.mime_decode_header(line)

line 内の符号化されたヘッダ行が復号化されたものを返します。ISO 8859-1 文字セット (Latin-1) だけをサポートします。

mimify.mime_encode_header(line)

line 内のヘッダ行が MIME 符号化されたものを返します。

mimify.MAXLEN

標準では、非 ASCII 文字 (8 ビット目がセットされている文字) を含むか、 MAXLEN 文字 (標準の値は 200 です) よりも長い部分は quoted-printable 形式で符号化されます。

mimify.CHARSET

文字セットがメールヘッダで指定されていない場合指定しなければなりません。使われている文字セットを表す文字列は CHARSET に記憶されます。標準の値は ISO-8859-1 (Latin1 (latin-one) としても知られています)。

このモジュールはコマンドラインから利用することもできます。以下のような使用法:

mimify.py -e [-l length] [infile [outfile]]
mimify.py -d [-b] [infile [outfile]]

で、それぞれ符号化 (mimify) および復号化 (unmimify) を行います。標準の設定では infile は標準入力で、 putfile は標準出力です。入出力に同じファイルを指定することもできます。

符号化の際に -l オプションを与えた場合、 length で指定した長さより長い行があれば、その長さに含まれる部分が符号化されます。

復号化の際に -b オプションが与えられていれば、base64 パートも同様に復号化されます。

参考

Module quopri

MIME quoted-printable 形式ファイルのエンコードおよびデコード。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.10. multifile — 個別の部分を含んだファイル群のサポート

バージョン 2.5 で撤廃: multifile モジュールよりも email パッケージを使うべきです。このモジュールは後方互換性のためだけに存在しています。

MultiFile オブジェクトはテキストファイルを区分したものをファイル類似の入力オブジェクトとして扱えるようにし、指定した区切り文字 (delimiter) パタンに遭遇した際に '' が返されるようにします。このクラスの標準設定は MIME マルチパートメッセージを解釈する上で便利となるように設計されていますが、サブクラス化を行って幾つかのメソッドを上書きすることで、簡単に汎用目的に対応させることができます。

class multifile.MultiFile(fp[, seekable])

マルチファイル (multi-file) を生成します。このクラスは open() が返すファイルオブジェクトのような、 MultiFile インスタンスが行データを取得するための入力となるオブジェクトを引数としてインスタンス化を行わなければなりません。

MultiFile は入力オブジェクトの readline() 、 seek() 、および tell() メソッドしか参照せず、後者の二つのメソッドは個々の MIME パートにランダムアクセスしたい場合にのみ必要です。 MultiFile を seek できないストリームオブジェクトで使うには、オプションの seekable 引数の値を偽にしてください; これにより、入力オブジェクトの seek() および tail() メソッドを使わないようになります。

MultiFile の視点から見ると、テキストは三種類の行データ: データ、セクション分割子、終了マーカ、からなることを知っていると役に立つでしょう。 MultiFile は、多重入れ子構造になっている可能性のある、それぞれが独自のセクション分割子および終了マーカのパターンを持つメッセージパートをサポートするように設計されています。

参考

Module email

網羅的な電子メール操作パッケージ; multifile モジュールに取って代わります。

18.10.1. MultiFile オブジェクト

MultiFile インスタンスには以下のメソッドがあります:

MultiFile.readline(str)

一行データを読みます。その行が (セクション分割子や終了マーカや本物の EOF でない) データの場合、行データを返します。その行がもっとも最近スタックにプッシュされた境界パターンにマッチした場合、 '' を返し、マッチした内容が終了マーカかそうでないかによって self.last を 1 か 0 に設定します。行がその他のスタックされている境界パターンにマッチした場合、エラーが送出されます。背後のストリームオブジェクトにおけるファイルの終端に到達した場合、全ての境界がスタックから除去されていない限りこのメソッドは Error を送出します。

MultiFile.readlines(str)

このパートの残りの全ての行を文字列のリストとして返します。

MultiFile.read()

次のセクションまでの全ての行を読みます。読んだ内容を単一の (複数行にわたる) 文字列として返します。このメソッドには size 引数をとらないので注意してください！

MultiFile.seek(pos[, whence])

ファイルを seek します。 seek する際のインデクスは現在のセクションの開始位置からの相対位置になります。 pis および whence 引数はファイルの seek における引数と同じように解釈されます。

MultiFile.tell()

現在のセクションの先頭に対して相対的なファイル位置を返します。

MultiFile.next()

次のセクションまで行を読み飛ばします (すなわち、セクション分割子または終了マーカが消費されるまで行データを読みます)。次のセクションがあった場合には真を、終了マーカが発見された場合には偽を返します。最も最近スタックにプッシュされた境界パターンを最有効化します。

MultiFile.is_data(str)

str がデータの場合に真を返し、セクション分割子の可能性がある場合には偽を返します。このメソッドは行の先頭が (全ての MIME 境界が持っている) '--' 以外になっているかを調べるように実装されていますが、派生クラスで上書きできるように宣言されています。

このテストは実際の境界テストにおいて高速性を保つために使われているので注意してください; このテストが常に false を返す場合、テストが失敗するのではなく、単に処理が遅くなるだけです。

MultiFile.push(str)

境界文字列をスタックにプッシュします。この境界文字列の修飾されたバージョンが入力行に見つかった場合、セクション分割子または終了マーカであると解釈されます(どちらであるかは修飾に依存します。 RFC 2045 [http://tools.ietf.org/html/rfc2045.html] を参照してください)。それ以降の全てのデータ読み出しは、 pop() を呼んで境界文字列を除去するか、 next() を呼んで境界文字列を再有効化しないかぎり、ファイル終端を示す空文字列を返します。

一つ以上の境界をプッシュすることは可能です。もっとも最近プッシュされた境界に遭遇すると EOF が返ります; その他の境界に遭遇するとエラーが送出されます。

MultiFile.pop()

セクション境界をポップします。この境界はもはや EOF として解釈されません。

MultiFile.section_divider(str)

境界をセクション分割子にします。標準では、このメソッドは (全ての MIME 境界が持っている) '--' を境界文字列の先頭に追加しますが、これは派生クラスで上書きできるように宣言されています。末尾の空白は無視されることから考えて、このメソッドでは LF や CR-LF を追加する必要はありません。

MultiFile.end_marker(str)

境界文字列を終了マーカ行にします。標準では、このメソッドは (MIME マルチパートデータのメッセージ終了マーカのように) '--' を境界文字列の先頭に追加し、かつ '--' を境界文字列の末尾に追加しますが、これは派生クラスで上書きできるように宣言されています。末尾の空白は無視されることから考えて、このメソッドでは LF や CR-LF を追加する必要はありません。

最後に、 MultiFile インスタンスは二つの公開されたインスタンス変数を持っています:

MultiFile.level

現在のパートにおける入れ子の深さです。

MultiFile.last

最後に見つかったファイル終了イベントがメッセージ終了マーカであった場合に真となります。

18.10.2. MultiFile の例

import mimetools
import multifile
import StringIO

def extract_mime_part_matching(stream, mimetype):
    """Return the first element in a multipart MIME message on stream
    matching mimetype."""

    msg = mimetools.Message(stream)
    msgtype = msg.gettype()
    params = msg.getplist()

    data = StringIO.StringIO()
    if msgtype[:10] == "multipart/":

        file = multifile.MultiFile(stream)
        file.push(msg.getparam("boundary"))
        while file.next():
            submsg = mimetools.Message(file)
            try:
                data = StringIO.StringIO()
                mimetools.decode(file, data, submsg.getencoding())
            except ValueError:
                continue
            if submsg.gettype() == mimetype:
                break
        file.pop()
    return data.getvalue()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.11. rfc822 — RFC 2822 準拠のメールヘッダ読み出し

バージョン 2.3 で撤廃: rfc822 モジュールを使うよりも email パッケージを使うべきです。このモジュールは以前のバージョンとの互換性のために保守されているにすぎません。 Python 3.0 ではこのモジュールは削除されました。

このモジュールでは、インターネット標準 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] [1] で定義されている “電子メールメッセージ” を表現するクラス、 Message を定義しています。このメッセージはメッセージヘッダ群とメッセージボディの集まりからなります。このモジュールではまた、ヘルパークラス RFC 2822 [http://tools.ietf.org/html/rfc2822.html] アドレス群を解釈するための AddressList クラスを定義しています。 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] メッセージ固有の構文に関する情報は RFC を参照してください。

mailbox モジュールでは、多くのエンドユーザメールプログラムによって生成されるメールボックスを読み出すためのクラスを提供しています。

class rfc822.Message(file[, seekable])

Message インスタンスは入力オブジェクトをパラメタに与えてインスタンス化します。入力オブジェクトのメソッドのうち、Message が依存するのは readline() だけです; 通常のファイルオブジェクトは適格です。インスタンス化を行うと、入力オブジェクトからデリミタ行 (通常は空行 1 行) に到達するまでヘッダを読み出し、それらをインスタンス中に保持します。ヘッダの後のメッセージ本体は読み出しません。

このクラスは readline() メソッドをサポートする任意の入力オブジェクトを扱うことができます。入力オブジェクトが seek および tell できる場合、 rewindbody() メソッドが動作します。また、不正な行データを入力ストリームにプッシュバックできます。入力オブジェクトが seek できない一方で、入力行をプッシュバックする unread() メソッドを持っている場合、 Message は不正な行データにこのプッシュバックを使います。こうして、このクラスはバッファされているストリームから来るメッセージを解釈するのに使うことができます。

オプションの seekable 引数は、 lseek() システムコールが動作しないと分かるまでは tell() がバッファされたデータを無視するような、ある種の stdio ライブラリで回避手段として提供されています。可搬性を最大にするために、socket オブジェクトによって生成されたファイルのような、seek できないオブジェクトを渡す際には、最初に tell() が呼び出されないようにするために seekable 引数をゼロに設定すべきです。

ファイルとして読み出された入力行データは CR-LF と単一の改行 (line feed) のどちらで終端されていてもかまいません; 行データを記憶する前に、終端の CR-LF は単一の改行と置き換えられます。

ヘッダに対するマッチは全て大小文字に依存しません。例えば、 m['From'] 、 m['from'] 、および m['FROM'] は全て同じ結果になります。

class rfc822.AddressList(field)

RFC 2833 [http://tools.ietf.org/html/rfc2833.html] アドレスをカンマで区切ったものとして解釈される単一の文字列パラメタを使って、 AddressList ヘルパークラスをインスタンス化することができます。 (パラメタ None は空のリストを表します。)

rfc822.quote(str)

str 中のバックスラッシュが 2 つのバックスラッシュに置き換えられ、二重引用符がバックスラッシュ付きの二重引用符に置き換えられた、新たな文字列を返します。

rfc822.unquote(str)

str の 逆クオートされた 新たな文字列を返します。 str が二重引用符で囲われていた場合、二重引用符を剥ぎ取ります。同様に、 str が三角括弧で囲われていた場合にも剥ぎ取ります。

rfc822.parseaddr(address)

To や Cc といった、アドレスが入っているフィールドの値 address を解析し、含まれている “実名 (realname)” 部分および “電子メールアドレス” 部分に分けます。それらの情報からなるタプルを返します。解析が失敗した場合には 2 要素のタプル (None, None) を返します。

rfc822.dump_address_pair(pair)

parseaddr() の逆で、 (realname, email_address) 形式の 2 要素のタプルをとり、 To や Cc ヘッダに適した文字列値を返します。 pair の最初の要素が真値をとらない場合、二つ目の要素をそのまま返します。

rfc822.parsedate(date)

RFC 2822 [http://tools.ietf.org/html/rfc2822.html] の規則に従っている日付を解析しようと試みます。しかしながら、メイラによっては RFC 2822 [http://tools.ietf.org/html/rfc2822.html] で指定されているような書式に従わないため、そのような場合には parsedata() は正しい日付を推測しようと試みます。 date は 'Mon, 20 Nov 1995 19:12:08 -0500' のような RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 様式の日付を収めた文字列です。日付の解析に成功した場合、 parsedate() は time.mktime() にそのまま渡すことができるような 9 要素のタプルを返します; そうでない場合には None を返します。結果のインデックス 6、7、および 8 は有用な情報ではありません。

rfc822.parsedate_tz(date)

parsedate() と同じ機能を実現しますが、 None または 10 要素のタプルを返します; 最初の 9 要素は time.mktime() に直接渡すことができるようなタプルで、 10 番目の要素はその日のタイムゾーンにおける UTC (グリニッチ標準時の公式名称) からのオフセットです。(タイムゾーンオフセットの符号は、同じタイムゾーンにおける time.timezone 変数の符号と反転しています; 後者の変数が POSIX 標準に従っている一方、このモジュールは RFC 2822 [http://tools.ietf.org/html/rfc2822.html] に従っているからです。) 入力文字列がタイムゾーン情報を持たない場合、タプルの最後の要素は None になります。結果のインデックス 6、7、および 8 は有用な情報ではありません。

rfc822.mktime_tz(tuple)

parsedata_tz() が返す 10 要素のタプルを UTC タイムスタンプに変換します。タプル内のタイムゾーン要素が None の場合、地域の時刻を表しているものと家庭します。些細な欠陥: この関数はまず最初の 8 要素を地域における時刻として変換し、次にタイムゾーンの違いに対する補償を行います; これにより、夏時間の切り替え日前後でちょっとしたエラーが生じるかもしれません。通常の利用に関しては心配ありません。

参考

Module email

網羅的な電子メール処理パッケージです; rfc822 モジュールを代替します。

Module mailbox

エンドユーザのメールプログラムによって生成される、様々な mailbox 形式を読み出すためのクラス群。

Module mimetools

MIME エンコードされたメッセージを処理する rfc822.Message のサブクラス。

18.11.1. Message オブジェクト

Message インスタンスは以下のメソッドを持っています:

Message.rewindbody()

メッセージ本体の先頭を seek します。このメソッドはファイルオブジェクトが seek 可能である場合にのみ動作します。

Message.isheader(line)

ある行が正しい RFC 2822 [http://tools.ietf.org/html/rfc2822.html] ヘッダである場合、その行の正規化されたフィールド名 (インデクス指定の際に使われる辞書キー) を返します; そうでない場合 None を返します (解析をここで一度中断し、行データを入力ストリームに押し戻すことを意味します)。このメソッドをサブクラスで上書きすると便利なことがあります。

Message.islast(line)

与えられた line が Message の区切りとなるデリミタであった場合に真を返します。このデリミタ行は消費され、ファイルオブジェクトの読み位置はその直後になります。標準ではこのメソッドは単にその行が空行かどうかをチェックしますが、サブクラスで上書きすることもできます。

Message.iscomment(line)

与えられた行全体を無視し、単に読み飛ばすときに真を返します。標準では、これは控えメソッド (stub) であり、常に False を返しますが、サブクラスで上書きすることもできます。

Message.getallmatchingheaders(name)

name に一致するヘッダからなる行のリストがあれば、それらを全て返します。各物理行は連続した行内容であるか否かに関わらず別々のリスト要素になります。 name に一致するヘッダがない場合、空のリストを返します。

Message.getfirstmatchingheader(name)

name に一致する最初のヘッダと、その行に連続する (複数) 行からなる行データのリストを返します。 name に一致するヘッダがない場合 None を返します。

Message.getrawheader(name)

name に一致する最初のヘッダにおけるコロン以降のテキストが入った単一の文字列を返します。このテキストには、先頭の空白、末尾の改行、また後続の行がある場合には途中の改行と空白が含まれます。 name に一致するヘッダが存在しない場合には None を返します。

Message.getheader(name[, default])

name に一致する最後のヘッダから先頭および末尾の空白を剥ぎ取った単一の文字列を返します。途中にある空白は剥ぎ取られません。オプションの default 引数は、 name に一致するヘッダが存在しない場合に、別のデフォルト値を返すように指定するために使われます。デフォルトは None です。パースされたヘッダを得る方法としてはこれが好ましいでしょう。

Message.get(name[, default])

正規の辞書との互換性をより高めるための getheader() の別名 (alias) です。

Message.getaddr(name)

getheader(name) が返した文字列を解析して、 (full name, email address) からなるペアを返します。 name に一致するヘッダが無い場合、 (None, None) が返されます; そうでない場合、 full name および address は (空文字列をとりうる) 文字列になります。

例: m に最初の From ヘッダに文字列 'jack@cwi.nl (Jack Jansen)' が入っている場合、 m.getaddr('From') はペア ('Jack Jansen', 'jack@cwi.nl') になります。また、 'Jack Jansen <jack@cwi.nl>' であっても、全く同じ結果になります。

Message.getaddrlist(name)

getaddr(list) に似ていますが、複数のメールアドレスからなるリストが入ったヘッダ (例えば To ヘッダ) を解析し、 (full name, email address) のペアからなるリストを (たとえヘッダには一つしかアドレスが入っていなかったとしても) 返します。 name に一致するヘッダが無かった場合、空のリストを返します。

指定された名前に一致する複数のヘッダが存在する場合 (例えば、複数の Cc ヘッダが存在する場合)、全てのアドレスを解析します。指定されたヘッダが連続する行に収められている場合も解析されます。

Message.getdate(name)

getheader() を使ってヘッダを取得して解析し、 time.mktime() と互換な 9 要素のタプルにします; フィールド 6、7、および 8 は有用な値ではないので注意して下さい。 name に一致するヘッダが存在しなかったり、ヘッダが解析不能であった場合、 None を返します。

日付の解析は妖術のようなものであり、全てのヘッダが標準に従っているとは限りません。このメソッドは多くの発信源から集められた膨大な数の電子メールでテストされており、正しく動作することが分かっていますが、間違った結果を出力してしまう可能性はまだあります。

Message.getdate_tz(name)

getheader() を使ってヘッダを取得して解析し、10 要素のタプルにします; 最初の 9 要素は time.mktime() と互換性のあるタプルを形成し、10 番目の要素はその日におけるタイムゾーンの UTC からのオフセットを与える数字になります。 getdate() と同様に、 name に一致するヘッダがなかったり、解析不能であった場合、 None を返します。

Message インスタンスはまた、限定的なマップ型のインタフェースを持っています。すなわち: m[name] は m.getheader(name) に似ていますが、一致するヘッダがない場合 KeyError を送出します; len(m) 、 m.get(name[, default]) 、 name in m, m.keys() 、 m.values() m.items() 、および m.setdefault(name[, default]) は期待通りに動作します。ただし setdefault() は標準の設定値として空文字列をとります。 Message インスタンスはまた、マップ型への書き込みを行えるインタフェース m[name] = value および del m[name] をサポートしています。 Message オブジェクトでは、 clear() 、 copy() 、 popitem() 、あるいは update() といったマップ型インタフェースのメソッドはサポートしていません。 (get() および setdefault() のサポートは Python 2.2 でしか追加されていません。)

最後に、 Message インスタンスはいくつかの public なインスタンス変数を持っています:

Message.headers

ヘッダ行のセット全体が、(setitem を呼び出して変更されない限り) 読み出された順番に入れられたリストです。各行は末尾の改行を含んでいます。ヘッダを終端する空行はリストに含まれません。

Message.fp

インスタンス化の際に渡されたファイルまたはファイル類似オブジェクトです。この値はメッセージ本体を読み出すために使うことができます。

Message.unixfrom

メッセージに Unix From 行がある場合はその行、そうでなければ空文字列になります。この値は例えば mbox 形式のメールボックスファイルのような、あるコンテキスト中のメッセージを再生成するために必要です。

18.11.2. AddressList オブジェクト

AddressList インスタンスは以下のメソッドを持ちます:

AddressList.__len__()

アドレスリスト中のアドレスの数を返します。

AddressList.__str__()

アドレスリストの正規化 (canonicalize) された文字列表現を返します。アドレスはカンマで分割された “name” <host@domain> 形式になります。

AddressList.__add__(alist)

二つの AddressList 被演算子中の双方に含まれるアドレスについて、重複を除いた (集合和の) 全てのアドレスを含む新たな AddressList インスタンスを返します。

AddressList.__iadd__(alist)

__add__() のインプレース演算版です; AddressList インスタンスと右側値 alist との集合和をとり、その結果をインスタンス自体と置き換えます。

AddressList.__sub__(alist)

左側値の AddressList インスタンスのアドレスのうち、右側値中に含まれていないもの全てを含む (集合差分の) 新たな AddressList インスタンスを返します。

AddressList.__isub__(alist)

__sub__() のインプレース演算版で、 alist にも含まれているアドレスを削除します。

最後に、 AddressList インスタンスは public なインスタンス変数を一つ持ちます:

AddressList.addresslist

アドレスあたり一つの文字列ペアで構成されるタプルからなるリストです。各メンバ中では、最初の要素は正規化された名前部分で、二つ目は実際の配送アドレス ('@' で分割されたユーザ名と ホスト.ドメインからなるペア) です。

注記

[1]
このモジュールはもともと RFC 822 [http://tools.ietf.org/html/rfc822.html] に適合していたので、そういう名前になっています。その後、 RFC 2822 [http://tools.ietf.org/html/rfc2822.html] が RFC 822 [http://tools.ietf.org/html/rfc822.html] に対する更新としてリリースされました。このモジュールは RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 適合であり、特に RFC 822 [http://tools.ietf.org/html/rfc822.html] からの構文や意味付けに対する変更がなされています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.12. base64 — RFC 3548: Base16, Base32, Base64 データの符号化

このモジュールは、 RFC 3548 [http://tools.ietf.org/html/rfc3548.html] で定められた仕様によるデータの符号化 (エンコード、encoding) および復元 (デコード、decoding) を提供します。この RFC 標準では Base16, Base32 および Base64 が定義されており、これはバイナリ文字列とテキスト文字列とをエンコードあるいはデコードするためのアルゴリズムです。変換されたテキスト文字列は email で確実に送信したり、URL の一部として使用したり、HTTP POST リクエストの一部に含めることができます。これらの符号化アルゴリズムは uuencode で使われているものとは別物です。

このモジュールでは 2つのインターフェイスが提供されています。現代的なインターフェイスは、これら 3種類のアルファベット集合を使った文字列オブジェクトのエンコードおよびデコードをすべてサポートします。一方、レガシーなインターフェイスは、文字列とともにファイル風のオブジェクトに対するエンコード / デコードを提供しますが、Base64 標準のアルファベット集合しか使いません。

Python 2.4 で導入された現代的なインターフェイスは以下のものを提供します:

base64.b64encode(s[, altchars])

Base64 をつかって、文字列をエンコード (符号化) します。

s はエンコードする文字列です。オプション引数 altchars は最低でも 2 の長さをもつ文字列で (これ以降の文字は無視されます)、これは + と / の代わりに使われる代替アルファベットを指定します。これにより、アプリケーションはたとえば URL やファイルシステムの影響をうけない Base64 文字列を生成することができます。デフォルトの値は None で、これは標準の Base64 アルファベット集合が使われることを意味します。

エンコードされた文字列が返されます。

base64.b64decode(s[, altchars])

Base64 文字列をデコード (復元) します。

s にはデコードする文字列を渡します。オプション引数の altchars は最低でも 2 の長さをもつ文字列で (これ以降の文字は無視されます)、これは + と / の代わりに使われる代替アルファベットを指定します。

デコードされた文字列が返されます。 s が正しくパディングされていなかったり、規定のアルファベット以外の文字が含まれていた場合には TypeError が発生します。

base64.standard_b64encode(s)

標準の Base64 アルファベット集合をもちいて文字列 s をエンコード (符号化) します。

base64.standard_b64decode(s)

標準の Base64 アルファベット集合をもちいて文字列 s をデコード (復元) します。

base64.urlsafe_b64encode(s)

URL 用に安全なアルファベット集合をもちいて文字列 s をエンコード (符号化) します。これは、標準の Base64 アルファベット集合にある + のかわりに - を使い、 / のかわりに _ を使用します。出来上がった文字列には = が残っている可能性があります。

base64.urlsafe_b64decode(s)

URL 用に安全なアルファベット集合をもちいて文字列 s をデコード (復元) します。これは、標準の Base64 アルファベット集合にある + のかわりに - を使い、 / のかわりに _ を使用します。

base64.b32encode(s)

Base32 をつかって、文字列をエンコード (符号化) します。 s にはエンコードする文字列を渡し、エンコードされた文字列が返されます。

base64.b32decode(s[, casefold[, map01]])

Base32 をつかって、文字列をデコード (復元) します。

s にはエンコードする文字列を渡します。オプション引数 casefold は小文字のアルファベットを受けつけるかどうかを指定します。セキュリティ上の理由により、デフォルトではこれは False になっています。

RFC 3548 [http://tools.ietf.org/html/rfc3548.html] は付加的なマッピングとして、数字の 0 (零) をアルファベットの O (オー) に、数字の 1 (壱) をアルファベットの I (アイ) または L (エル) に対応させることを許しています。オプション引数は map01 は、 None でないときは、数字の 1 をどの文字に対応づけるかを指定します (map01 が None でないとき、数字の 0 はつねにアルファベットの O (オー) に対応づけられます)。セキュリティ上の理由により、これはデフォルトでは None になっているため、 0 および 1 は入力として許可されていません。

デコードされた文字列が返されます。 s が正しくパディングされていなかったり、規定のアルファベット以外の文字が含まれていた場合には TypeError が発生します。

base64.b16encode(s)

Base16 をつかって、文字列をエンコード (符号化) します。

s にはエンコードする文字列を渡し、エンコードされた文字列が返されます。

base64.b16decode(s[, casefold])

Base16 をつかって、文字列をデコード (復元) します。

s にはエンコードする文字列を渡します。オプション引数 casefold は小文字のアルファベットを受けつけるかどうかを指定します。セキュリティ上の理由により、デフォルトではこれは False になっています。

デコードされた文字列が返されます。 s が正しくパディングされていなかったり、規定のアルファベット以外の文字が含まれていた場合には TypeError が発生します。

レガシーなインターフェイスは以下のものを提供します:

base64.decode(input, output)

input の中身をデコードした結果を output に出力します。 input 、 output ともにファイルオブジェクトか、ファイルオブジェクトと同じインターフェースを持ったオブジェクトである必要があります。 input は input.read() が空文字列を返すまで読まれます。

base64.decodestring(s)

文字列 s をデコードして結果のバイナリデータを返します。 s には一行以上のbase64形式でエンコードされたデータが含まれている必要があります。

base64.encode(input, output)

input の中身をbase64形式でエンコードした結果を output に出力します。 input 、 output ともにファイルオブジェクトか、ファイルオブジェクトと同じインターフェースを持ったオブジェクトである必要があります。 input は input.read() が空文字列を返すまで読まれます。 encode() はエンコードされたデータと改行文字('\n')を出力します。

base64.encodestring(s)

文字列 s (任意のバイナリデータを含むことができます)をr base64形式でエンコードした結果の(1行以上の文字列)データを返します。 encodestring() はエンコードされた一行以上のデータと改行文字 ('\n')を出力します。

モジュールの使用例:

>>> import base64
>>> encoded = base64.b64encode('data to be encoded')
>>> encoded
'ZGF0YSB0byBiZSBlbmNvZGVk'
>>> data = base64.b64decode(encoded)
>>> data
'data to be encoded'

参考

Module binascii

ASCII からバイナリへ、バイナリからASCIIへの変換をサポートするモジュール。

RFC 1521 [http://tools.ietf.org/html/rfc1521.html] - MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies

Section 5.2, “Base64 Content-Transfer-Encoding,” provides the definition of the base64 encoding.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.13. binhex — binhex4 形式ファイルのエンコードおよびデコード

このモジュールは binhex4 形式のファイルに対するエンコードやデコードを行います。binhex4 は Macintosh のファイルを ASCII で表現できるようにしたものです。Macintosh 上では、ファイルと finder 情報の両方のフォークがエンコード (またはデコード) されます。他のプラットフォームではデータフォークだけが処理されます。

ノート

Python 3.0 で特別な Macintosh サポートは削除されました。

binhex モジュールでは以下の関数を定義しています:

binhex.binhex(input, output)

ファイル名 input のバイナリファイルをファイル名 output の binhex 形式ファイルに変換します。 output パラメタはファイル名でも (write() および close() メソッドをサポートするような) ファイル様オブジェクトでもかまいません。

binhex.hexbin(input[, output])

binhex 形式のファイル input をデコードします。 input はファイル名でも、 write() および close() メソッドをサポートするようなファイル様オブジェクトでもかまいません。変換結果のファイルはファイル名 output になります。この引数が省略された場合、出力ファイルは binhex ファイルの中から復元されます。

以下の例外も定義されています:

exception binhex.Error

binhex 形式を使ってエンコードできなかった場合 (例えば、ファイル名が filename フィールドに収まらないくらい長かった場合など) や、入力が正しくエンコードされた binhex 形式のデータでなかった場合に送出される例外です。

参考

binascii モジュール

ASCII からバイナリ、およびバイナリから ASCII への変換をサポートするモジュール。

18.13.1. 注記

別のより強力なエンコーダおよびデコーダへのインタフェースが存在します。詳しくはソースを参照してください。

非 Macintosh プラットフォームでテキストファイルをエンコードしたりデコードしたりする場合でも、古い Macintosh の改行文字変換 (行末をキヤリッジリターンとする) が行われます。

このドキュメントを書いている時点では、 hexbin() はいつも正しく動作するわけではないようです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.14. binascii — バイナリデータと ASCIIデータとの間での変換

binascii モジュールにはバイナリと ASCIIコード化されたバイナリ表現との間の変換を行うための多数のメソッドが含まれています。通常、これらの関数を直接使う必要はなく、 uu 、 base64 や binhex といった、ラッパ(wrapper)モジュールを使うことになるでしょう。 binascii モジュールは、高レベルなモジュールで利用される、高速な C で書かれた低レベル関数を提供しています。

binascii モジュールでは以下の関数を定義します:

binascii.a2b_uu(string)

uuencode された 1 行のデータをバイナリに変換し、変換後のバイナリデータを返します。最後の行を除いて、通常 1 行には(バイナリデータで) 45 バイトが含まれます。入力データの先頭には空白文字が連続していてもかまいません。

binascii.b2a_uu(data)

バイナリデータを uuencode して 1 行の ASCII 文字列に変換します。戻り値は変換後の 1 行の文字列で、改行を含みます。 data の長さは 45 バイト以下でなければなりません。

binascii.a2b_base64(string)

base64 でエンコードされたデータのブロックをバイナリに変換し、変換後のバイナリデータを返します。一度に 1 行以上のデータを与えてもかまいません。

binascii.b2a_base64(data)

バイナリデータを base64 でエンコードして 1 行の ASCII 文字列に変換します。戻り値は変換後の 1 行の文字列で、改行文字を含みます。 base64 標準を遵守するためには、 data の長さは 57 バイト以下でなくてはなりません。

binascii.a2b_qp(string[, header])

quoted-printable 形式のデータをバイナリに変換し、バイナリデータを返します。一度に 1 行以上のデータを渡すことができます。オプション引数 header が与えられており、かつその値が真であれば、アンダースコアは空白文字にデコードされます。

binascii.b2a_qp(data[, quotetabs, istext, header])

バイナリデータを quoted-printable 形式でエンコードして 1 行から複数行の ASCII 文字列に変換します。変換後の文字列を返します。オプション引数 quptetabs が存在し、かつその値が真であれば、全てのタブおよび空白文字もエンコードされます。オプション引数 istext が存在し、かつその値が真であれば、改行はエンコードされませんが、行末の空白文字はエンコードされます。オプション引数 header が存在し、かつその値が真である場合、空白文字はRFC1522にしたがってアンダースコアにエンコードされます。オプション引数 header が存在し、かつその値が偽である場合、改行文字も同様にエンコードされます。そうでない場合、復帰 (linefeed) 文字の変換によってバイナリデータストリームが破損してしまうかもしれません。

binascii.a2b_hqx(string)

binhex4 形式の ASCII 文字列データを RLE 展開を行わないでバイナリに変換します。文字列はバイナリのバイトデータを完全に含むような長さか、または (binhex4 データの最後の部分の場合) 余白のビットがゼロになっていなければなりません。

binascii.rledecode_hqx(data)

data に対し、binhex4 標準に従って RLE 展開を行います。このアルゴリズムでは、あるバイトの後ろに 0x90 がきた場合、そのバイトの反復を指示しており、さらにその後ろに反復カウントが続きます。カウントが 0 の場合 0x90 自体を示します。このルーチンは入力データの末端における反復指定が不完全でないかぎり解凍されたデータを返しますが、不完全な場合、例外 Incomplete が送出されます。

binascii.rlecode_hqx(data)

binhex4 方式の RLE 圧縮を data に対して行い、その結果を返します。

binascii.b2a_hqx(data)

バイナリを hexbin4 エンコードして ASCII 文字列に変換し、変換後の文字列を返します。引数の data はすでに RLE エンコードされていなければならず、その長さは (最後のフラグメントを除いて) 3 で割り切れなければなりません。

binascii.crc_hqx(data, crc)

data の binhex4 CRC 値を計算します。初期値は crc で、計算結果を返します。

binascii.crc32(data[, crc])

32 ビットチェックサムである CRC-32 を data に対して計算します。初期値は crc です。これは ZIP ファイルのチェックサムと同じです。このアルゴリズムはチェックサムアルゴリズムとして設計されたもので、一般的なハッシュアルゴリズムには向きません。以下のようにして使います:

print binascii.crc32("hello world")
# Or, in two pieces:
crc = binascii.crc32("hello")
crc = binascii.crc32(" world", crc) & 0xffffffff
print 'crc32 = 0x%08x' % crc

ノート

全ての Python のバージョン、全てのプラットフォームに渡って同じ数値を生成しようとするならば、crc32(data) & 0xffffffff を使って下さい。チェックサムをバイナリ形式そのままでだけ扱うならばこのような細工は必要ありません。返値は符号に関係なく正しい32ビットのバイナリ表現だからです。

バージョン 2.6 で変更: 返値はどのプラットフォームでも [-2**31, 2**31-1] の範囲の値です。過去においては返値はあるプラットフォームでは符号付きでまた別のところでは符号無しでした。3.0 における振る舞いに合わせるためには & 0xffffffff を施して下さい。

バージョン 3.0 で変更: 返値はどのプラットフォームでも [0, 2**32-1] の範囲の符号無しです。

binascii.b2a_hex(data)

binascii.hexlify(data)

バイナリデータ data の16進数表現を返します。 data の各バイトは対応する 2 桁の16進数表現に変換されます。従って、変換結果の文字列は data の 2 倍の長さになります。

binascii.a2b_hex(hexstr)

binascii.unhexlify(hexstr)

16 進数表記の文字列 hexstr の表すバイナリデータを返します。この関数は b2a_hex() の逆です。 hexstr は 16進数字 (大文字でも小文字でもかまいません) を偶数個含んでいなければなりません。そうでないばあい、例外 TypeError が送出されます。

exception binascii.Error

エラーが発生した際に送出される例外です。通常はプログラムのエラーです。

exception binascii.Incomplete

変換するデータが不完全な場合に送出される例外です。通常はプログラムのエラーではなく、多少追加読み込みを行って再度変換を試みることで対処できます。

参考

base64 モジュール

MIME 電子メールメッセージで使われる base64 エンコードのサポート。

binhex モジュール

Macintosh で使われる binhex フォーマットのサポート。

uu モジュール

Unixで使われる UU エンコードのサポート。

quopri モジュール

MIME 電子メールメッセージで使われる quoted-printable エンコードのサポート。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.15. quopri — MIME quoted-printable 形式データのエンコードおよびデコード

このモジュールは RFC 1521 [http://tools.ietf.org/html/rfc1521.html]: “MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies” で定義されている quoted-printable による伝送のエンコードおよびデコードを行います。 quoted-printable エンコーディングは比較的印字不可能な文字の少ないデータのために設計されています; 画像ファイルを送るときのように印字不可能な文字がたくさんある場合には、 base64 モジュールで利用できる base64 エンコーディングのほうがよりコンパクトになります。

参考

最新バージョンの quopri モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/quopri.py?view=markup]

quopri.decode(input, output[, header])

ファイル input の内容をデコードして、デコードされたバイナリデータをファイル output に書き出します。 input および output はファイルか、ファイルオブジェクトのインタフェースを真似たオブジェクトでなければなりません。 input は input.readline() が空文字列を返すまで読みつづけられます。オプション引数 header が存在し、かつその値が真である場合、アンダースコアは空白文字にデコードされます。これは RFC 1522 [http://tools.ietf.org/html/rfc1522.html]: “MIME (Multipurpose Internet Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text” で記述されているところの “Q”-エンコードされたヘッダをデコードするのに使われます。

quopri.encode(input, output, quotetabs)

ファイル input の内容をエンコードして、quoted-printable 形式にエンコードされたデータをファイル output に書き出します。 input および output はファイルか、ファイルオブジェクトのインタフェースを真似たオブジェクトでなければなりません。 input は input.readline() が空文字列を返すまで読みつづけられます。 quotetabs はデータ中に埋め込まれた空白文字やタブを変換するかどうか制御するフラグです; この値が真なら、それらの空白をエンコードします。偽ならエンコードせずそのままにしておきます。行末のスペースやタブは RFC 1521 [http://tools.ietf.org/html/rfc1521.html] に従って常に変換されるので注意してください。

quopri.decodestring(s[, header])

decode() に似ていますが、文字列を入力として受け取り、デコードされた文字列を返します。

quopri.encodestring(s[, quotetabs])

encode() に似ていますが、文字列を入力として受け取り、エンコードされた文字列を返します。 quotetabs はオプション (デフォルトは 0 です) で、この値はそのまま encode() に渡されます。

参考

mimify モジュール

MIME メッセージを処理するための汎用ユーティリティ。

base64 モジュール

MIME base64 形式データのエンコードおよびデコード

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

18. インターネット上のデータの操作 »

18.16. uu — uuencode形式のエンコードとデコード

このモジュールではファイルをuuencode形式(任意のバイナリデータをASCII文字列に変換したもの)にエンコード、デコードする機能を提供します。引数としてファイルが仮定されている所では、ファイルのようなオブジェクトが利用できます。後方互換性のために、パス名を含む文字列も利用できるようにしていて、対応するファイルを開いて読み書きします。しかし、このインタフェースは利用しないでください。呼び出し側でファイルを開いて(Windowsでは 'rb' か 'wb' のモードで)利用する方法が推奨されます。

このコードはLance Ellinghouseによって提供され、Jack Jansenによって更新されました。

参考

最新バージョンの uu module Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/uu.py?view=markup]

uu モジュールでは以下の関数を定義しています。

uu.encode(in_file, out_file[, name[, mode]])

in_file を out_file にエンコードします。エンコードされたファイルには、デフォルトでデコード時に利用されるname と mode を含んだヘッダがつきます。省略された場合には、 in_file から取得された名前か '-' という文字と、 0666 がそれぞれデフォルト値として与えられます。

uu.decode(in_file[, out_file[, mode]])

uuencode形式でエンコードされた in_file をデコードして varout_file に書き出します。もし out_file がパス名でかつファイルを作る必要があるときには、 mode がパーミッションの設定に使われます。 out_file と mode のデフォルト値は in_file のヘッダから取得されます。しかし、ヘッダで指定されたファイルが既に存在していた場合は、 uu.Error が送出されます。

誤った実装のuuencoderによる入力で、エラーから復旧できた場合、 decode() は標準エラー出力に警告を表示するかもしれません。 quiet を真にすることでこの警告を抑制することができます。

exception uu.Error

Exception のサブクラスで、 uu.decode() によって、さまざまな状況で送出される可能性があります。上で紹介された場合以外にも、ヘッダのフォーマットが間違っている場合や、入力ファイルが途中で区切れた場合にも送出されます。

参考

binascii モジュール

ASCII からバイナリへ、バイナリからASCIIへの変換をサポートするモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール

Python は様々な構造化データマークアップ形式を扱うための、様々なモジュールをサポートしています。これらは標準化一般マークアップ言語 (SGML) およびハイパーテキストマークアップ言語 (HTML)、そして可拡張性マークアップ言語 (XML) を扱うためのいくつかのインタフェースからなります。

注意すべき重要な点として、 xml パッケージは少なくとも一つの SAX に対応した XML パーザが利用可能でなければなりません。 Python 2.3 からは Expat パーザが Python に取り込まれているので、 xml.parsers.expat モジュールは常に利用できます。また、 PyXML 追加パッケージ [http://pyxml.sourceforge.net/] についても知りたいと思うかもしれません; このパッケージは Python 用の拡張された XML ライブラリセットを提供します。

xml.dom および xml.sax パッケージのドキュメントは Python による DOM および SAX インタフェースへのバインディングに関する定義です。

19.1. HTMLParser — HTML および XHTML のシンプルなパーザ

19.1.1. HTML パーザアプリケーションの例

19.2. sgmllib — 単純な SGML パーザ

19.3. htmllib — HTML 文書の解析器

19.3.1. HTMLParser オブジェクト

19.4. htmlentitydefs — HTML 一般エンティティの定義

19.5. xml.parsers.expat — Expat を使った高速な XML 解析

19.5.1. XMLParser Objects

19.5.2. ExpatError 例外

19.5.3. 例

19.5.4. 内容モデルの記述

19.5.5. Expat エラー定数

19.6. xml.dom — 文書オブジェクトモデル (DOM) API

19.6.1. モジュールの内容

19.6.2. DOM 内のオブジェクト

19.6.2.1. DOMImplementation オブジェクト

19.6.2.2. Node オブジェクト

19.6.2.3. NodeList オブジェクト

19.6.2.4. DocumentType オブジェクト

19.6.2.5. Document オブジェクト

19.6.2.6. Element オブジェクト

19.6.2.7. Attr オブジェクト

19.6.2.8. NamedNodeMap Objects

19.6.2.9. Comment オブジェクト

19.6.2.10. Text オブジェクトおよび CDATASection オブジェクト

19.6.2.11. ProcessingInstruction オブジェクト

19.6.2.12. 例外

19.6.3. 適合性

19.6.3.1. 型の対応付け

19.6.3.2. アクセサメソッド

19.7. xml.dom.minidom — 軽量な DOM 実装

19.7.1. DOM オブジェクト

19.7.2. DOM の例

19.7.3. minidom と DOM 標準

19.8. xml.dom.pulldom — 部分的な DOM ツリー構築のサポート

19.8.1. DOMEventStream オブジェクト

19.9. xml.sax — SAX2 パーサのサポート

19.9.1. SAXException オブジェクト

19.10. xml.sax.handler — SAX ハンドラの基底クラス

19.10.1. ContentHandler オブジェクト

19.10.2. DTDHandler オブジェクト

19.10.3. EntityResolver オブジェクト

19.10.4. ErrorHandler オブジェクト

19.11. xml.sax.saxutils — SAX ユーティリティ

19.12. xml.sax.xmlreader — XML パーサのインタフェース

19.12.1. XMLReader オブジェクト

19.12.2. IncrementalParser オブジェクト

19.12.3. Locator オブジェクト

19.12.4. InputSource オブジェクト

19.12.5. The Attributes インタフェース

19.12.6. AttributesNS インタフェース

19.13. xml.etree.ElementTree — ElementTree XML API

19.13.1. 関数

19.13.2. Element オブジェクト

19.13.3. ElementTree オブジェクト

19.13.4. QName オブジェクト

19.13.5. TreeBuilder オブジェクト

19.13.6. XMLParser オブジェクト

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.1. HTMLParser — HTML および XHTML のシンプルなパーザ

ノート

HTMLParser モジュールは Python 3.0 で html.parser に改名されました。ソースを 3.0 用に移行する際には 2to3 がインポートを自動的に直してくれます。

バージョン 2.2 で追加.

このモジュールでは HTMLParser クラスを定義します。このクラスは HTML (ハイパーテキスト記述言語、 HyperText Mark-up Language) および XHTML で書式化されているテキストファイルを解釈するための基礎となります。 htmllib にあるパーザと違って、このパーザは sgmllib の SGML パーザに基づいてはいません。

class HTMLParser.HTMLParser

HTMLParser クラスは引数なしでインスタンス化します。

HTMLParser インスタンスに HTML データが入力されると、タグが開始したとき、及び終了したときに関数を呼び出します。 HTMLParser クラスは、ユーザが行いたい動作を提供するために上書きできるようになっています。

htmllib のパーザと違い、このパーザは終了タグが開始タグと一致しているか調べたり、外側のタグ要素が閉じるときに内側で明示的に閉じられていないタグ要素のタグ終了ハンドラを呼び出したりはしません。

例外も定義されています:

exception HTMLParser.HTMLParseError

パーズ中にエラーに遭遇した場合に HTMLParser クラスが送出する例外です。この例外は三つの属性を提供しています: msg はエラーの内容を説明する簡単なメッセージ、 lineno は壊れたマークアップ構造を検出した場所の行番号、 offset は問題のマークアップ構造の行内での開始位置を示す文字数です。

HTMLParser インスタンスは以下のメソッドを提供します:

HTMLParser.reset()

インスタンスをリセットします。未処理のデータは全て失われます。インスタンス化の際に非明示的に呼び出されます。

HTMLParser.feed(data)

パーザにテキストを入力します。入力が完全なタグ要素で構成されている場合に限り処理が行われます; 不完全なデータであった場合、新たにデータが入力されるか、 close() が呼び出されるまでバッファされます。

HTMLParser.close()

全てのバッファされているデータについて、その後にファイル終了マークが続いているとみなして強制的に処理を行います。このメソッドは入力データの終端で行うべき追加処理を定義するために派生クラスで上書きすることができますが、再定義を行ったクラスでは常に、 HTMLParser 基底クラスのメソッド close() を呼び出さなくてはなりません。

HTMLParser.getpos()

現在の行番号およびオフセット値を返します。

HTMLParser.get_starttag_text()

最も最近開かれた開始タグのテキスト部分を返します。このテキストは必ずしも元データを構造化する上で必須ではありませんが、 “広く知られている (as deployed)” HTML を扱ったり、入力を最小限の変更で再生成 (属性間の空白をそのままにする、など) したりする場合に便利なことがあります。

HTMLParser.handle_starttag(tag, attrs)

このメソッドはタグの開始部分を処理するために呼び出されます。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

tag 引数はタグの名前で、小文字に変換されています。 attrs 引数は (name, value) のペアからなるリストで、タグの <> 括弧内にある属性が収められています。 name は小文字に変換され、 value 内の引用符は取り除かれ、文字参照とエンティティ参照は置換されます。例えば、タグ <A HREF="http://www.cwi.nl/"> を処理する場合、このメソッドは handle_starttag('a', [('href', 'http://www.cwi.nl/')]) として呼び出されます。

バージョン 2.6 で変更: 属性中の htmlentitydefs の全てのエンティティ参照が置換されるようになりました。

HTMLParser.handle_startendtag(tag, attrs)

handle_starttag() と似ていますが、パーザが XHTML 形式の空タグ (<a .../>) に遭遇した場合に呼び出されます。この特定の語彙情報 (lexical information) が必要な場合、このメソッドをサブクラスで上書きすることができます; 標準の実装では、単に handle_starttag() および handle_endtag() を呼ぶだけです。

HTMLParser.handle_endtag(tag)

このメソッドはあるタグ要素の終了タグを処理するために呼び出されます。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。 tag 引数はタグの名前で、小文字に変換されています。

HTMLParser.handle_data(data)

このメソッドは、他のメソッドに当てはまらない任意のデータを処理するために呼び出されます。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

HTMLParser.handle_charref(ref)

このメソッドはタグ外の &#ref; 形式の文字参照 (character reference) を処理するために呼び出されます。 ref には、先頭の &# および末尾の ; は含まれません。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

HTMLParser.handle_entityref(name)

このメソッドはタグ外の &name; 形式の一般のエンティティ参照 (entity reference) name を処理するために呼び出されます。 name には、先頭の & および末尾の ; は含まれません。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

HTMLParser.handle_comment(data)

このメソッドはコメントに遭遇した場合に呼び出されます。 comment 引数は文字列で、 -- および -- デリミタ間の、デリミタ自体を除いたテキストが収められています。例えば、コメント <!--text--> があると、このメソッドは引数 'text' で呼び出されます。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

HTMLParser.handle_decl(decl)

パーザが SGML の doctype 宣言を読み出した際に呼び出されるメソッドです。 decl パラメタは <!...> 記述内の宣言内容全体になります。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

HTMLParser.unknown_decl(data)

パーザが認識できない SGML 宣言を読み出した際に呼び出されるメソッドです。 data パラメタは <!...> 記述内の宣言内容全体になります。派生クラスで上書きすると良いかもしれません。基底クラスの実装では HTMLParseError を送出します。

HTMLParser.handle_pi(data)

処理指令に遭遇した場合に呼び出されます。 data には、処理指令全体が含まれ、例えば <?proc color='red'> という処理指令の場合、 handle_pi("proc color='red'") のように呼び出されます。このメソッドは派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

ノート

The HTMLParser クラスでは、処理指令に SGML の構文を使用します。末尾に '?' がある XHTML の処理指令では、 '?' が data に含まれることになります。

exception HTMLParser.HTMLParseError

HTML の構文に沿わないパターンを発見したときに送出される例外です。 HTML 構文法上の全てのエラーを発見できるわけではないので注意してください。

19.1.1. HTML パーザアプリケーションの例

基礎的な例として、 HTMLParser クラスを使い、発見したタグを出力する、非常に基礎的な HTML パーザを以下に示します。

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        print "Encountered the beginning of a %s tag" % tag

    def handle_endtag(self, tag):
        print "Encountered the end of a %s tag" % tag

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.2. sgmllib — 単純な SGML パーザ

バージョン 2.6 で撤廃: sgmllib は Python 3.0 で削除されました。

このモジュールでは SGML (Standard Generalized Mark-up Language: 汎用マークアップ言語標準) で書式化されたテキストファイルを解析するための基礎として働く SGMLParser クラスを定義しています。実際には、このクラスは完全な SGML パーザを提供しているわけではありません — このクラスは HTML で用いられているような SGML だけを解析し、モジュール自体も htmllib モジュールの基礎にするためだけに存在しています。XHTML をサポートし、少し異なったインタフェースを提供しているもう一つの HTML パーザは、 HTMLParser モジュールで使うことができます。

class sgmllib.SGMLParser

SGMLParser クラスは引数無しでインスタンス化されます。このパーザは以下の構成を認識するようにハードコードされています:

<tag attr="value" ...> と </tag> で表されるタグの開始部と終了部。

&#name; 形式をとる文字の数値参照。

&name; 形式をとるエンティティ参照。

<!--text--> 形式をとる SGML コメント。末尾の > とその直前にある -- の間にはスペース、タブ、改行を入れることができます。

例外が以下のように定義されます:

exception sgmllib.SGMLParseError

SGMLParser クラスで構文解析中にエラーに出逢うとこの例外が発生します。

バージョン 2.1 で追加.

SGMLParser インスタンスは以下のメソッドを持っています:

SGMLParser.reset()

インスタンスをリセットします。未処理のデータは全て失われます。このメソッドはインスタンス生成時に非明示的に呼び出されます。

SGMLParser.setnomoretags()

タグの処理を停止します。以降の入力をリテラル入力 (CDATA) として扱います。(この機能は HTML タグ <PAINTEXT> を実装できるようにするためだけに提供されています)

SGMLParser.setliteral()

リテラルモード (CDATA モード) に移行します。

SGMLParser.feed(data)

テキストをパーザに入力します。入力は完全なエレメントから成り立つ場合に限り処理されます; 不完全なデータは追加のデータが入力されるか、 close() が呼び出されるまでバッファに蓄積されます。

SGMLParser.close()

バッファに蓄積されている全てのデータについて、直後にファイル終了記号が来た時のようにして強制的に処理します。このメソッドは派生クラスで再定義して、入力の終了時に追加の処理行うよう定義することができますが、このメソッドの再定義されたバージョンでは常に close() を呼び出さなければなりません。

SGMLParser.get_starttag_text()

もっとも最近開かれた開始タグのテキストを返します。通常、構造化されたデータの処理をする上でこのメソッドは必要ありませんが、 “広く知られている (as deployed)” HTML を扱ったり、入力を最小限の変更で再生成 (属性間の空白をそのままにする、など) したりする場合に便利なことがあります。

SGMLParser.handle_starttag(tag, method, attributes)

このメソッドは start_tag() か do_tag() のどちらかのメソッドが定義されている開始タグを処理するために呼び出されます。 tag 引数はタグの名前で、小文字に変換されています。 method 引数は開始タグの意味解釈をサポートするために用いられるバインドされたメソッドです。 attributes 引数は (name, value) のペアからなるリストで、タグの <> 括弧内にある属性が収められています。

name は小文字に変換されます。 value 内の二重引用符とバックスラッシュも変換され、と同時に知られている文字参照および知られているエンティティ参照でセミコロンで終端されているものも変換されます(通常、エンティティ参照は任意の非英数文字で終端されてよいのですが、これを許すと非常に一般的な <A HREF="url?spam=1&eggs=2"> 　において eggs が正当なエンティティ参照であるようなケースを破綻させます)。

例えば、タグ <A HREF="http://www.cwi.nl/"> を処理する場合、このメソッドは unknown_starttag('a', [('href', 'http://www.cwi.nl/')]) として呼び出されます。基底クラスの実装では、単に method を単一の引数 attributes と共に呼び出します。

バージョン 2.5 で追加: 属性値中のエンティティおよび文字参照の扱い.

SGMLParser.handle_endtag(tag, method)

このメソッドは end_tag() メソッドの定義されている終了タグを処理するために呼び出されます。 tag 引数はタグの名前で、小文字に変換されており、 method 引数は終了タグの意味解釈をサポートするために使われるバインドされたメソッドです。 end_tag() メソッドが終了エレメントとして定義されていない場合、ハンドラは一切呼び出されません。基底クラスの実装では単に method を呼び出します。

SGMLParser.handle_data(data)

このメソッドは何らかのデータを処理するために呼び出されます。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

SGMLParser.handle_charref(ref)

このメソッドは &#ref; 形式の文字参照 (character reference) を処理するために呼び出されます。基底クラスの実装は、 convert_charref() を使って参照を文字列に変換します。もしそのメソッドが文字列を返せば handle_data() を呼び出します。そうでなければ、エラーを処理するために unknown_charref(ref) が呼び出されます。

バージョン 2.5 で変更: ハードコードされた変換に代わり convert_charref() を使います.

SGMLParser.convert_charref(ref)

文字参照を文字列に変換するか、 None を返します。 ref は文字列として渡される参照です。基底クラスでは ref は 0-255 の範囲の十進数でなければなりません。そしてコードポイントをメソッド convert_codepoint() を使って変換します。もし ref が不正もしくは範囲外ならば、 None を返します。このメソッドはデフォルト実装の handle_charref() から、あるいは属性値パーザから呼び出されます。

バージョン 2.5 で追加.

SGMLParser.convert_codepoint(codepoint)

コードポイントを str の値に変換します。もしそれが適切ならばエンコーディングをここで扱うこともできますが、 sgmllib の残りの部分はこの問題に関知しません。

バージョン 2.5 で追加.

SGMLParser.handle_entityref(ref)

このメソッドは ref を一般エンティティ参照として、 &ref; 形式のエンティティ参照を処理するために呼び出されます。このメソッドは、 ref を convert_entityref() に渡して変換します。変換結果が返された場合、変換された文字を引数にして handle_data() を呼び出します; そうでない場合、 unknown_entityref(ref) を呼び出します。標準では entitydefs は &amp; 、 &apos 、 &gt; 、 &lt; 、および &quot; の変換を定義しています。

バージョン 2.5 で変更: ハードコードされた変換に代わり convert_entityref() を使います.

SGMLParser.convert_entityref(ref)

名前付きエンティティ参照を str の値に変換するか、または None を返します。変換結果は再パーズしません。 ref はエンティティの名前部分だけです。デフォルトの実装ではインスタンス(またはクラス)変数の entitydefs というエンティティ名から対応する文字列へのマッピングから ref を探します。もし ref に対応する文字列が見つからなければメソッドは None を返します。このメソッドは handle_entityref() のデフォルト実装からおよび属性値パーザから呼び出されます。

バージョン 2.5 で追加.

SGMLParser.handle_comment(comment)

このメソッドはコメントに遭遇した場合に呼び出されます。 comment 引数は文字列で、 <!-- and --> デリミタ間の、デリミタ自体を除いたテキストが収められています。例えば、コメント <!--text--> があると、このメソッドは引数 'text' で呼び出されます。基底クラスの実装では何も行いません。

SGMLParser.handle_decl(data)

パーザが SGML 宣言を読み出した際に呼び出されるメソッドです。実際には、 DOCTYPE は HTML だけに見られる宣言ですが、パーザは宣言間の相違 (や誤った宣言) を判別しません。 DOCTYPE の内部サブセット宣言はサポートされていません。 decl パラメタは <!...> 記述内の宣言内容全体になります。基底クラスの実装では何も行いません。

SGMLParser.report_unbalanced(tag)

個のメソッドは対応する開始エレメントのない終了タグが発見された時に呼び出されます。

SGMLParser.unknown_starttag(tag, attributes)

未知の開始タグを処理するために呼び出されるメソッドです。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

SGMLParser.unknown_endtag(tag)

This method is called to process an unknown end tag. 未知の終了タグを処理するために呼び出されるメソッドです。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

SGMLParser.unknown_charref(ref)

このメソッドは解決不能な文字参照数値を処理するために呼び出されます。標準で何が処理可能かは handle_charref() を参照してください。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

SGMLParser.unknown_entityref(ref)

未知のエンティティ参照を処理するために呼び出されるメソッドです。派生クラスで上書きするためのメソッドです; 基底クラスの実装では何も行いません。

上に挙げたメソッドを上書きしたり拡張したりするのとは別に、派生クラスでは以下の形式のメソッドを定義して、特定のタグを処理することもできます。入力ストリーム中のタグ名は大小文字の区別に依存しません; メソッド名中の tag は小文字でなければなりません:

SGMLParser.start_tag(attributes)

このメソッドは開始タグ tag を処理するために呼び出されます。 do_tag() よりも高い優先順位があります。 attributes 引数は上の handle_starttag() で記述されているのと同じ意味です。

SGMLParser.do_tag(attributes)

このメソッドは start_tag() メソッドが定義されていない開始タグ tag を処理するために呼び出されます。 attributes 引数は上の handle_starttag() で記述されているのと同じ意味です。

SGMLParser.end_tag()

このメソッドは終了タグ tag を処理するために呼び出されます。

パーザは開始されたエレメントのうち、終了タグがまだ見つかっていないもののスタックを維持しているので注意してください。 start_tag() で処理されたタグだけがスタックにプッシュされます。are pushed on this stack. Definition of an それらのタグに対する end_tag() メソッドの定義はオプションです。 do_tag() や unknown_tag() で処理されるタグについては、 end_tag() を定義してはいけません; 定義されていても使われることはありません。あるタグに対して start_tag() および do_tag() メソッドの両方が存在する場合、 start_tag() が優先されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.3. htmllib — HTML 文書の解析器

バージョン 2.6 で撤廃: htmllib モジュールは Python 3.0 で削除されました。

このモジュールでは、ハイパーテキスト記述言語 (HTML, HyperText Mark-up Language) 形式で書式化されたテキストファイルを解析するための基盤として役立つクラスを定義しています。このクラスは I/O と直接的には接続されません — このクラスにはメソッドを介して文字列形式の入力を提供する必要があり、出力を生成するには “フォーマッタ (formatter)” オブジェクトのメソッドを何度か呼び出さなくてはなりません。

HTMLParser クラスは、機能を追加するために他のクラスの基底クラスとして利用するように設計されており、ほとんどのメソッドが拡張したり上書きしたりできるようになっています。さらにこのクラスは sgmllib モジュールで定義されている SGMLParser クラスから派生しており、その機能を拡張しています。 HTMLParser の実装は、 RFC 1866 [http://tools.ietf.org/html/rfc1866.html] で解説されている HTML 2.0 記述言語をサポートします。 formatter では 2 つのフォーマッタオブジェクト実装が提供されています; フォーマッタのインタフェースについての情報は formatter モジュールのドキュメントを参照してください。

以下は sgmllib.SGMLParser で定義されているインタフェースの概要です:

インスタンスにデータを与えるためのインタフェースは feed() メソッドで、このメソッドは文字列を引数に取ります。このメソッドに一度に与えるテキストは必要に応じて多くも少なくもできます; というのは p.feed(a);p.feed(b) は p.feed(a+b) と同じ効果を持つからです。与えられたデータが完全な HTML マークアップ文を含む場合、それらの文は即座に処理されます; 不完全なマークアップ構造はバッファに保存されます。全ての未処理データを強制的に処理させるには、 close() メソッドを呼び出します。

例えば、ファイルの全内容を解析するには:

parser.feed(open('myfile.html').read())
parser.close()

のようにします。

HTML タグに対して意味付けを定義するためのインタフェースはとても単純です: サブクラスを派生して、 start_tag() 、 end_tag() 、あるいは do_tag() といったメソッドを定義するだけです。パーザはこれらのメソッドを適切なタイミングで呼び出します: start_tag() や do_tag() は <tag ...> の形式の開始タグに遭遇した時に呼び出されます; end_tag() は <tag> の形式の終了タグに遭遇した時に呼び出されます。 <H1> ... </H1> のように開始タグが終了タグと対応している必要がある場合、クラス中で start_tag() が定義されていなければなりません; <P> のように終了タグが必要ない場合、クラス中では do_tag() を定義しなければなりません。

このモジュールではパーザクラスと例外を一つづつ定義しています:

class htmllib.HTMLParser(formatter)

基底となる HTML パーザクラスです。XHTML 1.0 仕様 (http://www.w3.org/TR/xhtml1) 勧告で要求されている全てのエンティティ名をサポートしています。また、全ての HTML 2.0 の要素および HTML 3.0、3.2 の多くの要素のハンドラを定義しています。

exception htmllib.HTMLParseError

HTMLParser クラスがパーズ処理中にエラーに遭遇した場合に送出する例外です。

バージョン 2.4 で追加.

参考

Module formatter

抽象化された書式イベントの流れを writer オブジェクト上の特定の出力イベントに変換するためのインターフェース。

Module HTMLParser

HTML パーザのひとつです。やや低いレベルでしか入力を扱えませんが、XHTML を扱うことができるように設計されています。”広く知られている HTML (HTML as deployed)” では使われておらずかつ XHTML では正しくないとされる SGML 構文のいくつかは実装されていません。

Module htmlentitydefs

XHTML 1.0 エンティティに対する置換テキストの定義。

Module sgmllib

HTMLParser の基底クラス。

19.3.1. HTMLParser オブジェクト

タグメソッドに加えて、 HTMLParser クラスではタグメソッドで利用するためのいくつかのメソッドとインスタンス変数を提供しています。

HTMLParser.formatter

パーザに関連付けられているフォーマッタインスタンスです。

HTMLParser.nofill

ブール値のフラグで、空白文字を縮約したくないときには真、縮約するときには偽にします。一般的には、この値を真にするのは、 <PRE> 要素の中のテキストのように、文字列データが “書式化済みの (preformatted)” 場合だけです。標準の値は偽です。この値は handle_data() および save_end() の操作に影響します。

HTMLParser.anchor_bgn(href, name, type)

このメソッドはアンカー領域の先頭で呼び出されます。引数は <A> タグの属性で同じ名前を持つものに対応します。標準の実装では、ドキュメント内のハイパーリンク (<A> タグの HREF 属性) を列挙したリストを維持しています。ハイパーリンクのリストはデータ属性 anchorlist で手に入れることができます。

HTMLParser.anchor_end()

このメソッドはアンカー領域の末尾で呼び出されます。標準の実装では、テキストの注釈マーカを追加します。マーカは anchor_bgn() で作られたハイパーリンクリストのインデクス値です。

HTMLParser.handle_image(source, alt[, ismap[, align[, width[, height]]]])

このメソッドは画像を扱うために呼び出されます。標準の実装では、単に handle_data() に alt の値を渡すだけです。

HTMLParser.save_bgn()

文字列データをフォーマッタオブジェクトに送らずにバッファに保存する操作を開始します。保存されたデータは save_end() で取得してください。 save_bgn() / save_end() のペアを入れ子構造にすることはできません。

HTMLParser.save_end()

文字列データのバッファリングを終了し、以前 save_bgn() を呼び出した時点から保存されている全てのデータを返します。 nofill フラグが偽の場合、空白文字は全てスペース文字一文字に置き換えられます。予め save_bgn() を呼ばないでこのメソッドを呼び出すと TypeError 例外が送出されます。

19.4. htmlentitydefs — HTML 一般エンティティの定義

ノート

Python 3.0 で htmlentitydefs モジュールは html.entities と改名されました。ソースを 3.0 用に変換する際には 2to3 ツールが自動的に import を直してくれます。

このモジュールでは entitydefs 、 codepoint2name 、 entitydefs の三つの辞書を定義しています。 entitydefs は htmllib モジュールで HTMLParser クラスの entitydefs メンバを定義するために使われます。このモジュールでは XHTML 1.0 で定義された全てのエンティティを提供しており、 Latin-1 キャラクタセット (ISO-8859-1)の簡単なテキスト置換を行う事ができます。

htmlentitydefs.entitydefs

各 XHTML 1.0 エンティティ定義について、ISO Latin-1 における置換テキストへの対応付けを行っている辞書です。

htmlentitydefs.name2codepoint

HTMLのエンティティ名をUnicodeのコードポイントに変換するための辞書です。

バージョン 2.3 で追加.

htmlentitydefs.codepoint2name

UnicodeのコードポイントをHTMLのエンティティ名に変換するための辞書です。

バージョン 2.3 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.5. xml.parsers.expat — Expat を使った高速な XML 解析

バージョン 2.0 で追加.

xml.parsers.expat モジュールは、検証 (validation) を行わない XML パーザ (parser, 解析器)、Expat への Python インタフェースです。モジュールは一つの拡張型 xmlparser を提供します。これは XMLパーザの現在の状況を表します。一旦 xmlparser オブジェクトを生成すると、オブジェクトの様々な属性をハンドラ関数 (handler function) に設定できます。その後、XML 文書をパーザに入力すると、 XML文書の文字列とマークアップに応じてハンドラ関数が呼び出されます。

このモジュールでは、Expatパーザへのアクセスを提供するために pyexpat モジュールを使用します。 pyexpat モジュールの直接使用は撤廃されています。

このモジュールは、例外を一つと型オブジェクトを一つ提供しています。

exception xml.parsers.expat.ExpatError

Expat がエラーを報告したときに例外を送出します。 Expatのエラーを解釈する上での詳細な情報は、 ExpatError 例外を参照してください。

exception xml.parsers.expat.error

ExpatError への別名です。

xml.parsers.expat.XMLParserType

ParserCreate() 関数から返された戻り値の型を示します。

xml.parsers.expat モジュールには以下の 2 つの関数が収められています:

xml.parsers.expat.ErrorString(errno)

与えられたエラー番号 errno を解説する文字列を返します。

xml.parsers.expat.ParserCreate([encoding[, namespace_separator]])

新しい xmlparser オブジェクトを作成し、返します。 encoding が指定されていた場合、XMLデータで使われている文字列のエンコード名でなければなりません。 Expatは、Pythonのように多くのエンコードをサポートしておらず、またエンコーディングのレパートリを拡張することはできません; サポートするエンコードは、UTF-8, UTF-16, ISO-8859-1 (Latin1), ASCII です。 encoding [1] が指定されると、文書に対する明示的、非明示的なエンコード指定を上書き (override) します。

Expat はオプションで XML 名前空間の処理を行うことができます。これは引数 namespace_separator に値を指定することで有効になります。この値は、1文字の文字列でなければなりません; 文字列が誤った長さを持つ場合には ValueError が送出されます (None は値の省略と見なされます)。名前空間の処理が可能なとき、名前空間に属する要素と属性が展開されます。要素のハンドラである StartElementHandler と EndElementHandler に渡された要素名は、名前空間の URI、名前空間の区切り文字、要素名のローカル部を連結したものになります。名前空間の区切り文字が 0 バイト (chr(0)) の場合、名前空間の URI とローカル部は区切り文字なしで連結されます。

たとえば、 namespace_separator に空白文字(' ')がセットされ、次のような文書が解析されるとします。

<?xml version="1.0"?>
<root xmlns    = "http://default-namespace.org/"
      xmlns:py = "http://www.python.org/ns/">
  <py:elem1 />
  <elem2 xmlns="" />
</root>

StartElementHandler は各要素ごとに次のような文字列を受け取ります。

http://default-namespace.org/ root
http://www.python.org/ns/ elem1
elem2

参考

The Expat XML Parser [http://www.libexpat.org/]

Expatプロジェクトのホームページ

19.5.1. XMLParser Objects

xmlparser オブジェクトは以下のようなメソッドを持ちます。

xmlparser.Parse(data[, isfinal])

文字列 data の内容を解析し、解析されたデータを処理するための適切な関数を呼び出します。このメソッドを最後に呼び出す時は isfinal を真にしなければなりません。 data は空の文字列を取ることもできます。

xmlparser.ParseFile(file)

file オブジェクトから読み込んだXMLデータを解析します。 file には read(nbytes) メソッドのみが必要です。このメソッドはデータがなくなった場合に空文字列を返さねばなりません。。

xmlparser.SetBase(base)

(XML) 宣言中のシステム識別子中の相対 URI を解決するための、基底 URI を設定します。相対識別子の解決はアプリケーションに任されます: この値は関数 ExternalEntityRefHandler() や NotationDeclHandler(), UnparsedEntityDeclHandler() に引数 base としてそのまま渡されます。

xmlparser.GetBase()

以前の SetBase() によって設定された基底 URI を文字列の形で返します。 SetBase() が呼ばれていないときには None を返します。

xmlparser.GetInputContext()

現在のイベントを発生させた入力データを文字列として返します。データはテキストの入っているエンティティが持っているエンコードになります。イベントハンドラがアクティブでないときに呼ばれると、戻り値は None となります。

バージョン 2.1 で追加.

xmlparser.ExternalEntityParserCreate(context[, encoding])

親となるパーザで解析された内容が参照している、外部で解析されるエンティティを解析するために使える “子の” パーザを作成します。 context パラメータは、以下に記すように ExternalEntityRefHandler() ハンドラ関数に渡される文字列でなければなりません。子のパーザは ordered_attributes, returns_unicode, specified_attributes が現在のパーザの値に設定されて生成されます。

xmlparser.SetParamEntityParsing(flag)

パラメーターエンティティ (外部DTDサブセットを含む) の解析を制御します。 flag の有効な値は、 XML_PARAM_ENTITY_PARSING_NEVER, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, XML_PARAM_ENTITY_PARSING_ALWAYS です。 flag の設定をしたら true を返します。

xmlparser.UseForeignDTD([flag])

flag の値をデフォルトのtrueにすると、Expatは代わりのDTDをロードするため、すべての引数に None を設定して ExternalEntityRefHandler を呼び出します。XML文書が文書型定義を持っていなければ、 ExternalEntityRefHandler が呼び出しますが、 StartDoctypeDeclHandler と EndDoctypeDeclHandler は呼び出されません。

flag にfalseを与えると、メソッドが前回呼ばれた時のtrueの設定が解除されますが、他には何も起こりません。

このメソッドは Parse() または ParseFile() メソッドが呼び出される前にだけ呼び出されます;これら2つのメソッドのどちらかが呼び出されたあとにメソッドが呼ばれると、 code に定数 errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING が設定されて例外 ExpatError が送出されます。

バージョン 2.3 で追加.

xmlparser オブジェクトは次のような属性を持ちます:

xmlparser.buffer_size

buffer_text が真の時に使われるバッファのサイズです。この属性に新しい整数値を代入することで違うバッファサイズにできます。サイズが変えられるときにバッファはフラッシュされます。

バージョン 2.3 で追加.

バージョン 2.6 で変更: バッファサイズが変えられるようになりました。

xmlparser.buffer_text

この値を真にすると、 xmlparser オブジェクトが Expatから返されたもとの内容をバッファに保持するようになります。これにより可能なときに何度も CharacterDataHandler() を呼び出してしまうようなことを避けることができます。Expatは通常、文字列のデータを行末ごと大量に破棄するため、かなりパフォーマンスを改善できるはずです。この属性はデフォルトでは偽で、いつでも変更可能です。

バージョン 2.3 で追加.

xmlparser.buffer_used

buffer_text が利用可能なとき、バッファに保持されたバイト数です。これらのバイトはUTF-8でエンコードされたテキストを表します。この属性は buffer_text が偽の時には意味がありません。

バージョン 2.3 で追加.

xmlparser.ordered_attributes

この属性をゼロ以外の整数にすると、報告される(XMLノードの) 属性を辞書型ではなくリスト型にします。属性は文書のテキスト中の出現順で示されます。それぞれの属性は、2つのリストのエントリ: 属性名とその値、が与えられます。 (このモジュールの古いバージョンでも、同じフォーマットが使われています。) デフォルトでは、この属性はデフォルトでは偽となりますが、いつでも変更可能です。

バージョン 2.1 で追加.

xmlparser.returns_unicode

この属性をゼロ以外の整数にすると、ハンドラ関数に Unicode 文字列が渡されます。 returns_unicode が False の時には、UTF-8でエンコードされたデータを含む 8 ビット文字列がハンドラに渡されます。Pythonがユニコードサポートつきでビルドされている場合、この値はデフォルトで True です。

バージョン 1.6 で変更: 戻り値の型がいつでも変更できるように変更されたはずです.

xmlparser.specified_attributes

ゼロ以外の整数にすると、パーザは文書のインスタンスで特定される属性だけを報告し、属性宣言から導出された属性は報告しないようになります。この属性が指定されたアプリケーションでは、XMLプロセッサの振る舞いに関する標準に従うために必要とされる (文書型) 宣言によって、どのような付加情報が利用できるのかということについて特に注意を払わなければなりません。デフォルトで、この属性は偽となりますが、いつでも変更可能です。

バージョン 2.1 で追加.

以下の属性には、 xmlparser オブジェクトで最も最近に起きたエラーに関する値が入っており、また Parse() または ParseFile() メソッドが xml.parsers.expat.ExpatError 例外を送出した際にのみ正しい値となります。

xmlparser.ErrorByteIndex

エラーが発生したバイトのインデクスです。

xmlparser.ErrorCode

エラーを特定する数値によるコードです。この値は ErrorString() に渡したり、 errors オブジェクトで定義された内容と比較できます。

xmlparser.ErrorColumnNumber

エラーの発生したカラム番号です。

xmlparser.ErrorLineNumber

エラーの発生した行番号です。

以下の属性は xmlparser オブジェクトがその時パースしている位置に関する値を保持しています。コールバックがパースイベントを報告している間、これらの値はイベントの生成した文字列の先頭の位置を指し示します。コールバックの外から参照された時には、（対応するコールバックであるかにかかわらず）直前のパースイベントの位置を示します。

バージョン 2.4 で追加.

xmlparser.CurrentByteIndex

パーサへの入力の、現在のバイトインデックス。

xmlparser.CurrentColumnNumber

パーサへの入力の、現在のカラム番号。

xmlparser.CurrentLineNumber

パーサへの入力の、現在の行番号。

以下に指定可能なハンドラのリストを示します。 xmlparser オブジェクト o にハンドラを指定するには、 o.handlername = func を使用します。 handlername は、以下のリストに挙げた値をとらねばならず、また func は正しい数の引数を受理する呼び出し可能なオブジェクトでなければなりません。引数は特に明記しない限り、すべて文字列となります。

xmlparser.XmlDeclHandler(version, encoding, standalone)

XML 宣言が解析された時に呼ばれます。XML宣言とは、XML勧告の適用バージョン (オプション)、文書テキストのエンコード、そしてオプションの “スタンドアロン” の宣言です。 version と encoding は returns_unicode 属性によって指示された型を示す文字列となり、 standalone は、文書がスタンドアロンであると宣言される場合には 1 に、文書がスタンドアロンでない場合には 0 に、スタンドアロン宣言を省略する場合には -1 になります。このハンドラは Expat のバージョン1.95.0以降のみ使用できます。

バージョン 2.1 で追加.

xmlparser.StartDoctypeDeclHandler(doctypeName, systemId, publicId, has_internal_subset)

Expatが文書型宣言 <!DOCTYPE ...)を解析し始めたときに呼び出されます。 doctypeName は、与えられた値がそのまま Expat に提供されます。 systemId と publicId パラメタが指定されている場合、それぞれシステムと公開識別子を与えます。省略する時には None にします。文書が内部的な文書宣言のサブセット (internal document declaration subset) を持つか、サブセット自体の場合、 has_internal_subset は true になります。このハンドラには、Expat version 1.2以上が必要です。

xmlparser.EndDoctypeDeclHandler()

Expatが文書型宣言の解析を終えたときに呼び出されます。このハンドラには、Expat version 1.2以上が必要です。

xmlparser.ElementDeclHandler(name, model)

それぞれの要素型宣言ごとに呼び出されます。 name は要素型の名前であり、 model は内容モデル (content model) の表現です。

xmlparser.AttlistDeclHandler(elname, attname, type, default, required)

ひとつの要素型で宣言される属性ごとに呼び出されます。属性リストの宣言が 3つの属性を宣言したとすると、このハンドラはひとつの属性に1度づつ、 3度呼び出されます。 elname は要素名であり、これに対して宣言が適用され、 attname が宣言された属性名となります。属性型は文字列で、 type として渡されます; 取りえる値は、 'CDATA', 'ID', 'IDREF', ... です。 default は、属性が文書のインスタンスによって指定されていないときに使用されるデフォルト値を与えます。デフォルト値(#IMPLIED values)が存在しないときには None を与えます。文書のインスタンスによって属性値が与えられる必要のあるときには required がtrueになります。このメソッドはExpat version 1.95.0 以上が必要です。

xmlparser.StartElementHandler(name, attributes)

要素の開始を処理するごとに呼び出されます。 name は要素名を格納した文字列で、 attributes はその値に属性名を対応付ける辞書型です。

xmlparser.EndElementHandler(name)

要素の終端を処理するごとに呼び出されます。

xmlparser.ProcessingInstructionHandler(target, data)

Called for every processing instruction. 処理命令を処理するごとに呼び出されます。

xmlparser.CharacterDataHandler(data)

文字データを処理するときに呼びだされます。このハンドラは通常の文字データ、 CDATAセクション、無視できる空白文字列のために呼び出されます。これらを識別しなければならないアプリケーションは、要求された情報を収集するために StartCdataSectionHandler, EndCdataSectionHandler, and ElementDeclHandler コールバックメソッドを使用できます。

xmlparser.UnparsedEntityDeclHandler(entityName, base, systemId, publicId, notationName)

解析されていない (NDATA) エンティティ宣言を処理するために呼び出されます。このハンドラは Expat ライブラリのバージョン1.2のためだけに存在します; より最近のバージョンでは、代わりに EntityDeclHandler を使用してください (根底にある Expat ライブラリ内の関数は、撤廃されたものであると宣言されています)。

xmlparser.EntityDeclHandler(entityName, is_parameter_entity, value, base, systemId, publicId, notationName)

エンティティ宣言ごとに呼び出されます。パラメタと内部エンティティについて、 value はエンティティ宣言の宣言済みの内容を与える文字列となります; 外部エンティティの時には None となります。解析済みエンティティの場合、 notationName パラメタは None となり、解析されていないエンティティの時には記法 (notation) 名となります。 is_parameter_entity は、エンティティがパラメタエンティティの場合真に、一般エンティティ (general entitiy) の場合には偽になります (ほとんどのアプリケーションでは、一般エンティティのことしか気にする必要がありません)。このハンドラは Expat ライブラリのバージョン1.95.0 以降でのみ使用できます。

バージョン 2.1 で追加.

xmlparser.NotationDeclHandler(notationName, base, systemId, publicId)

記法の宣言 (notation declaration) で呼び出されます。 notationName, base, systemId, および publicId を与える場合、文字列にします。public な識別子が省略された場合、 publicId は None になります。

xmlparser.StartNamespaceDeclHandler(prefix, uri)

要素が名前空間宣言を含んでいる場合に呼び出されます。名前空間宣言は、宣言が配置されている要素に対して StartElementHandler が呼び出される前に処理されます。

xmlparser.EndNamespaceDeclHandler(prefix)

名前空間宣言を含んでいたエレメントの終了タグに到達したときに呼び出されます。このハンドラは、要素に関する名前空間宣言ごとに、 StartNamespaceDeclHandler とは逆の順番で一度だけ呼び出され、各名前空間宣言のスコープが開始されたことを示します。このハンドラは、要素が終了する際、対応する EndElementHandler が呼ばれた後に呼び出されます。

xmlparser.CommentHandler(data)

コメントで呼び出されます。 data はコメントのテキストで、先頭の ‘<!- -‘ と末尾の ‘- ->‘ を除きます。

xmlparser.StartCdataSectionHandler()

CDATA セクションの開始時に呼び出されます。CDATA セクションの構文的な開始と終了位置を識別できるようにするには、このハンドラと EndCdataSectionHandler が必要です。

xmlparser.EndCdataSectionHandler()

CDATA セクションの終了時に呼び出されます。

xmlparser.DefaultHandler(data)

XML 文書中で、適用可能なハンドラが指定されていない文字すべてに対して呼び出されます。この文字とは、検出されたことが報告されるが、ハンドラは指定されていないようなコンストラクト (construct) の一部である文字を意味します。

xmlparser.DefaultHandlerExpand(data)

DefaultHandler() と同じですが、内部エンティティの展開を禁止しません。エンティティ参照はデフォルトハンドラに渡されません。

xmlparser.NotStandaloneHandler()

XML 文書がスタンドアロンの文書として宣言されていない場合に呼び出されます。外部サブセットやパラメタエンティティへの参照が存在するが、XML 宣言が XML 宣言中で standalone 変数を yes に設定していない場合に起きます。このハンドラが 0 を返すと、パーザは XML_ERROR_NOT_STANDALONE を発生させます。このハンドラが設定されていなければ、パーザは前述の事態で例外を送出しません。

xmlparser.ExternalEntityRefHandler(context, base, systemId, publicId)

外部エンティティの参照時に呼び出されます。 base は現在の基底 (base) で、以前の SetBase() で設定された値になっています。 public、および system の識別子である、 systemId と publicId が指定されている場合、値は文字列です; public 識別子が指定されていない場合、 publicId は None になります。 context の値は不明瞭なものであり、以下に記述するようにしか使ってはなりません。

外部エンティティが解析されるようにするには、このハンドラを実装しなければなりません。このハンドラは、 ExternalEntityParserCreate(context) を使って適切なコールバックを指定し、子パーザを生成して、エンティティを解析する役割を担います。このハンドラは整数を返さねばなりません; 0 を返した場合、パーザは XML_ERROR_EXTERNAL_ENTITY_HANDLING エラーを送出します。そうでないばあい、解析を継続します。

このハンドラが与えられておらず、 DefaultHandler コールバックが指定されていれば、外部エンティティは DefaultHandler で報告されます。

19.5.2. ExpatError 例外

ExpatError 例外はいくつかの興味深い属性を備えています:

ExpatError.code

特定のエラーにおける Expat の内部エラー番号です。この値はこのモジュールの errors オブジェクトで定義されている定数のいずれかに一致します。

バージョン 2.1 で追加.

ExpatError.lineno

エラーが検出された場所の行番号です。最初の行の番号は 1 です。

バージョン 2.1 で追加.

ExpatError.offset

エラーが発生した場所の行内でのオフセットです。最初のカラムの番号は 0 です。

バージョン 2.1 で追加.

19.5.3. 例

以下のプログラムでは、与えられた引数を出力するだけの三つのハンドラを定義しています。

import xml.parsers.expat

# 3 handler functions
def start_element(name, attrs):
    print 'Start element:', name, attrs
def end_element(name):
    print 'End element:', name
def char_data(data):
    print 'Character data:', repr(data)

p = xml.parsers.expat.ParserCreate()

p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data

p.Parse("""<?xml version="1.0"?>
<parent id="top"><child1 name="paul">Text goes here</child1>
<child2 name="fred">More text</child2>
</parent>""")

このプログラムの出力は以下のようになります:

Start element: parent {'id': 'top'}
Start element: child1 {'name': 'paul'}
Character data: 'Text goes here'
End element: child1
Character data: '\n'
Start element: child2 {'name': 'fred'}
Character data: 'More text'
End element: child2
Character data: '\n'
End element: parent

19.5.4. 内容モデルの記述

内容モデルは入れ子になったタプルを使って記述されています。各タプルには 4 つの値: 型、限定詞 (quantifier)、名前、そして子のタプル、が収められています。子のタプルは単に内容モデルを記述したものです。

最初の二つのフィールドの値は xml.parsers.expat モジュールの model オブジェクトで定義されている定数です。これらの定数は二つのグループ: モデル型 (model type) グループと限定子 (quantifier) グループ、に取りまとめられます。

以下にモデル型グループにおける定数を示します:

xml.parsers.expat.XML_CTYPE_ANY

モデル名で指定された要素は ANY の内容モデルを持つと宣言されます。

xml.parsers.expat.XML_CTYPE_CHOICE

指定されたエレメントはいくつかのオプションから選択できるようになっています; (A | B | C) のような内容モデルで用いられます。

xml.parsers.expat.XML_CTYPE_EMPTY

EMPTY であると宣言されている要素はこのモデル型を持ちます。

xml.parsers.expat.XML_CTYPE_MIXED

xml.parsers.expat.XML_CTYPE_NAME

xml.parsers.expat.XML_CTYPE_SEQ

順々に続くようなモデルの系列を表すモデルがこのモデル型で表されます。 (A, B, C) のようなモデルで用いられます。

限定子グループにおける定数を以下に示します:

xml.parsers.expat.XML_CQUANT_NONE

修飾子 (modifier) が指定されていません。従って A のように、厳密に一つだけです。

xml.parsers.expat.XML_CQUANT_OPT

このモデルはオプションです: A? のように、一つか全くないかです。

xml.parsers.expat.XML_CQUANT_PLUS

このモデルは (A+ のように) 一つかそれ以上あります。

xml.parsers.expat.XML_CQUANT_REP

このモデルは A* のようにゼロ回以上あります。

19.5.5. Expat エラー定数

以下の定数は xml.parsers.expat モジュールにおける errors オブジェクトで提供されています。これらの定数は、エラーが発生した際に送出される ExpatError 例外オブジェクトのいくつかの属性を解釈する上で便利です。

errors オブジェクトは以下の属性を持ちます:

xml.parsers.expat.XML_ERROR_ASYNC_ENTITY

xml.parsers.expat.XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF

属性値中のエンティティ参照が、内部エンティティではなく外部エンティティを参照しました。

xml.parsers.expat.XML_ERROR_BAD_CHAR_REF

文字参照が、XML では正しくない (illegal) 文字を参照しました (例えば 0 や ‘&#0;‘)。

xml.parsers.expat.XML_ERROR_BINARY_ENTITY_REF

エンティティ参照が、記法 (notation) つきで宣言されているエンティティを参照したため、解析できません。

xml.parsers.expat.XML_ERROR_DUPLICATE_ATTRIBUTE

一つの属性が一つの開始タグ内に一度より多く使われています。

xml.parsers.expat.XML_ERROR_INCORRECT_ENCODING

xml.parsers.expat.XML_ERROR_INVALID_TOKEN

入力されたバイトが文字に適切に関連付けできない際に送出されます; 例えば、UTF-8 入力ストリームにおける NUL バイト (値 0) などです。

xml.parsers.expat.XML_ERROR_JUNK_AFTER_DOC_ELEMENT

空白以外の何かがドキュメント要素の後にあります。

xml.parsers.expat.XML_ERROR_MISPLACED_XML_PI

入力データの先頭以外の場所に XML 定義が見つかりました。

xml.parsers.expat.XML_ERROR_NO_ELEMENTS

このドキュメントには要素が入っていません (XML では全てのドキュメントは確実にトップレベルの要素を一つ持つよう要求しています)。

xml.parsers.expat.XML_ERROR_NO_MEMORY

Expat が内部メモリを確保できませんでした。

xml.parsers.expat.XML_ERROR_PARAM_ENTITY_REF

パラメタエンティティが許可されていない場所で見つかりました。

xml.parsers.expat.XML_ERROR_PARTIAL_CHAR

入力に不完全な文字が見つかりました。

xml.parsers.expat.XML_ERROR_RECURSIVE_ENTITY_REF

エンティティ参照中に、同じエンティティへの別の参照が入っていました; おそらく違う名前で参照しているか、間接的に参照しています。

xml.parsers.expat.XML_ERROR_SYNTAX

何らかの仕様化されていない構文エラーに遭遇しました。

xml.parsers.expat.XML_ERROR_TAG_MISMATCH

終了タグが最も内側で開かれている開始タグに一致しません。

xml.parsers.expat.XML_ERROR_UNCLOSED_TOKEN

何らかの (開始タグのような) トークンが閉じられないまま、ストリームの終端や次のトークンに遭遇しました。

xml.parsers.expat.XML_ERROR_UNDEFINED_ENTITY

定義されていないエンティティへの参照が行われました。

xml.parsers.expat.XML_ERROR_UNKNOWN_ENCODING

ドキュメントのエンコードが Expat でサポートされていません。

xml.parsers.expat.XML_ERROR_UNCLOSED_CDATA_SECTION

CDATAセクションが閉じられていません。

xml.parsers.expat.XML_ERROR_EXTERNAL_ENTITY_HANDLING

xml.parsers.expat.XML_ERROR_NOT_STANDALONE

XML文書が”standalone”だと宣言されており NotStandaloneHandler が設定され 0 が返されているにもかかわらず、パーサは”standalone”ではないと判別しました。

xml.parsers.expat.XML_ERROR_UNEXPECTED_STATE

xml.parsers.expat.XML_ERROR_ENTITY_DECLARED_IN_PE

xml.parsers.expat.XML_ERROR_FEATURE_REQUIRES_XML_DTD

その操作を完了するにはDTDのサポートが必要ですが、ExpatがDTDのサポートをしない設定になっています。これは xml.parsers.expat モジュールの標準的なビルドでは報告されません。

xml.parsers.expat.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING

パースが始まったあとで動作の変更が要求されました。これはパースが開始される前にのみ変更可能です。（現在のところ） UseForeignDTD() によってのみ送出されます。

xml.parsers.expat.XML_ERROR_UNBOUND_PREFIX

名前空間の処理を有効すると宣言されていないプレフィックスが見つかります。

xml.parsers.expat.XML_ERROR_UNDECLARING_PREFIX

XML文書はプレフィックスに対応した名前空間宣言を削除しようとしました。

xml.parsers.expat.XML_ERROR_INCOMPLETE_PE

パラメータエンティティは不完全なマークアップを含んでいます。

xml.parsers.expat.XML_ERROR_XML_DECL

XML文書中に要素がありません。

xml.parsers.expat.XML_ERROR_TEXT_DECL

外部エンティティ中のテキスト宣言にエラーがあります。

xml.parsers.expat.XML_ERROR_PUBLICID

パブリックID中に許可されていない文字があります。

xml.parsers.expat.XML_ERROR_SUSPENDED

要求された操作は一時停止されたパーサで行われていますが、許可されていない操作です。このエラーは追加の入力を行なおうとしている場合、もしくはパーサが停止しようとしている場合にも送出されます。

xml.parsers.expat.XML_ERROR_NOT_SUSPENDED

パーサを一時停止しようとしましたが、停止されませんでした。

xml.parsers.expat.XML_ERROR_ABORTED

Pythonアプリケーションには通知されません。

xml.parsers.expat.XML_ERROR_FINISHED

要求された操作で、パース対象となる入力が完了したと判断しましたが、入力は受理されませんでした。このエラーは追加の入力を行なおうとしている場合、もしくはパーサが停止しようとしている場合に送出されます。

xml.parsers.expat.XML_ERROR_SUSPEND_PE

注記

[1]
XML の出力に含まれるエンコーディング文字列は適切な標準に適合していなければなりません。たとえば、”UTF-8” は正当ですが、”UTF8” は違います。 http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl と http://www.iana.org/assignments/character-sets を参照して下さい。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.6. xml.dom — 文書オブジェクトモデル (DOM) API

バージョン 2.0 で追加.

文書オブジェクトモデル、または “DOM” は、ワールドワイドウェブコンソーシアム (World Wide Web Consortium, W3C) による、XML ドキュメントにアクセスしたり変更を加えたりするための、プログラミング言語間共通の API です。DOM 実装によって、XML ドキュメントはツリー構造として表現されます。また、クライアントコード側でツリー構造をゼロから構築できるようになります。さらに、前述の構造に対して、よく知られたインタフェースをもつ一連のオブジェクトを通したアクセス手段も提供します。

DOM はランダムアクセスを行うアプリケーションで非常に有用です。 SAX では、一度に閲覧することができるのはドキュメントのほんの一部分です。ある SAX 要素に注目している際には、別の要素をアクセスすることはできません。またテキストノードに注目しているときには、その中に入っている要素をアクセスすることができません。 SAX によるアプリケーションを書くときには、プログラムがドキュメント内のどこを処理しているのかを追跡するよう、コードのどこかに記述する必要があります。SAX 自体がその作業を行ってくれることはありません。さらに、XML ドキュメントに対する先読み (look ahead) が必要だとすると不運なことになります。

アプリケーションによっては、ツリーにアクセスできなければイベント駆動モデルを実現できません。もちろん、何らかのツリーを SAX イベントに応じて自分で構築することもできるでしょうが、 DOM ではそのようなコードを書かなくてもよくなります。 DOM は XML データに対する標準的なツリー表現なのです。

文書オブジェクトモデルは、W3C によっていくつかの段階、W3C の用語で言えば “レベル (level)” で定義されています。 Python においては、 DOM API への対応付けは実質的には DOM レベル 2 勧告に基づいています。

DOM アプリケーションは、普通は XML を DOM に解析するところから始まります。どのようにして解析を行うかについては DOM レベル 1 では全くカバーしておらず、レベル 2 では限定的な改良だけが行われました: レベル 2 では Document を生成するメソッドを提供する DOMImplementation オブジェクトクラスがありますが、実装に依存しない方法で XML リーダ(reader)/パーザ(parser)/文書ビルダ (Document builder) にアクセスする方法はありません。また、既存の Document オブジェクトなしにこれらのメソッドにアクセスするような、よく定義された方法もありません。 Python では、各々の DOM 実装で getDOMImplementation() が定義されているはずです。 DOM レベル 3 ではロード(Load)/ストア(Store) 仕様が追加され、リーダのインタフェースにを定義していますが、Python 標準ライブラリではまだ利用することができません。

DOM 文書オブジェクトを生成したら、そのプロパティとメソッドを使って XML 文書の一部にアクセスできます。これらのプロパティは DOM 仕様で定義されています; 本リファレンスマニュアルでは、 Python において DOM 仕様がどのように解釈されているかを記述しています。

W3C から提供されている仕様は、 DOM API を Java、ECMAScript、および OMG IDL で定義しています。ここで定義されている Python での対応づけは、大部分がこの仕様の IDL 版に基づいていますが、厳密な準拠は必要とされていません (実装で IDL の厳密な対応付けをサポートするのは自由ですが)。API への対応付けに関する詳細な議論は 適合性 を参照してください。

参考

Document Object Model (DOM) Level 2 Specification [http://www.w3.org/TR/DOM-Level-2-Core/]

Python DOM API が準拠している W3C 勧告。

Document Object Model (DOM) Level 1 Specification [http://www.w3.org/TR/REC-DOM-Level-1/]

xml.dom.minidom でサポートされている W3C の DOM に関する勧告。

Python Language Mapping Specification [http://www.omg.org/spec/PYTH/1.2/PDF]

このドキュメントでは OMG IDL から Python への対応付けを記述しています。

19.6.1. モジュールの内容

xml.dom には、以下の関数が収められています:

xml.dom.registerDOMImplementation(name, factory)

ファクトリ関数 (factory function) factory を名前 name で登録します。ファクトリ関数は DOMImplementation インタフェースを実装するオブジェクトを返さなければなりません。ファクトリ関数は毎回同じオブジェクトを返すこともでき、呼び出されるたびに、特定の実装 (例えば実装が何らかのカスタマイズをサポートしている場合) における、適切な新たなオブジェクトを返すこともできます。

xml.dom.getDOMImplementation([name[, features]])

適切な DOM 実装を返します name は、よく知られた DOM 実装のモジュール名か、 None になります。 None でない場合、対応するモジュールを import して、import が成功した場合 DOMImplementation オブジェクトを返します。 name が与えられておらず、環境変数 PYTHON_DOM が設定されていた場合、 DOM 実装を見つけるのに環境変数が使われます。

name が与えられない場合、利用可能な実装を調べて、指定された機能 (feature) セットを持つものを探します。実装が見つからなければ ImportError を送出します。 features のリストは (feature, version) のペアからなるシーケンスで、利用可能な DOMImplementation オブジェクトの hasFeature() メソッドに渡されます。

いくつかの便利な定数も提供されています:

xml.dom.EMPTY_NAMESPACE

DOM 内のノードに名前空間が何も関連づけられていないことを示すために使われる値です。この値は通常、ノードの namespaceURI の値として見つかったり、名前空間特有のメソッドに対する namespaceURI パラメタとして使われます。

バージョン 2.2 で追加.

xml.dom.XML_NAMESPACE

Namespaces in XML [http://www.w3.org/TR/REC-xml-names/] (4 節) で定義されている、予約済みプレフィクス (reserved prefix) xml に関連付けられた名前空間 URI です。

バージョン 2.2 で追加.

xml.dom.XMLNS_NAMESPACE

Document Object Model (DOM) Level 2 Core Specification [http://www.w3.org/TR/DOM-Level-2-Core/core.html] (1.1.8 節) で定義されている、名前空間宣言への名前空間 URI です。

バージョン 2.2 で追加.

xml.dom.XHTML_NAMESPACE

XHTML 1.0: The Extensible HyperText Markup Language [http://www.w3.org/TR/xhtml1/] (3.1.1 節) で定義されている、XHTML 名前空間 URI です。

バージョン 2.2 で追加.

加えて、 xml.dom には基底となる Node クラスと DOM 例外クラスが収められています。このモジュールで提供されている Node クラスは DOM 仕様で定義されているメソッドや属性は何ら実装していません; これらは具体的な DOM 実装において提供しなければなりません。このモジュールの一部として提供されている Node クラスでは、具体的な Node オブジェクトの nodeType 属性として使う定数を提供しています; これらの定数は、DOM 仕様に適合するため、クラスではなくモジュールのレベルに配置されています。

19.6.2. DOM 内のオブジェクト

DOM について最も明確に限定しているドキュメントは W3C による DOM 仕様です。

DOM 属性は単純な文字列としてだけではなく、ノードとして操作されるかもしれないので注意してください。とはいえ、そうしなければならない場合はかなり稀なので、今のところ記述されていません。

インタフェース | 節 | 目的
DOMImplementation | DOMImplementation オブジェクト | 根底にある実装へのインタフェース。
Node | Node オブジェクト | ドキュメント内の大部分のオブジェクトのに対する基底インタフェース。
NodeList | NodeList オブジェクト | ノードの列に対するインタフェース。
DocumentType | DocumentType オブジェクト | ドキュメントを処理するために必要な宣言についての情報。
Document | Document オブジェクト | ドキュメント全体を表現するオブジェクト。
Element | Element オブジェクト | ドキュメント階層内の要素ノード。
Attr | Attr オブジェクト | 階層ノード上の属性値。
Comment | Comment オブジェクト | ソースドキュメント内のコメント表現。
Text | Text オブジェクトおよび CDATASection オブジェクト | ドキュメント内のテキスト記述を含むノード。
ProcessingInstruction | ProcessingInstruction オブジェクト | 処理命令 (processing instruction) 表現。

さらに追加の節として、 Python で DOM を利用するために定義されている例外について記述しています。

19.6.2.1. DOMImplementation オブジェクト

DOMImplementation インタフェースは、利用している DOM 実装において特定の機能が利用可能かどうかを決定するための方法をアプリケーションに提供します。DOM レベル 2 では、 DOMImplementation を使って新たな Document オブジェクトや DocumentType オブジェクトを生成する機能も追加しています。

DOMImplementation.hasFeature(feature, version)

機能名 feature とバージョン番号 version で識別される機能（feature）が実装されていればtrueを返します。

DOMImplementation.createDocument(namespaceUri, qualifiedName, doctype)

新たな(DOMのスーパークラスである) Document クラスのオブジェクトを返します。このクラスは namespaceUri と qualifiedName が設定された子クラス Element のオブジェクトを所有しています。 doctype は createDocumentType() によって生成された DocumentType クラスのオブジェクト、または None である必要があります。 Python DOM APIでは、子クラスである Element を作成しないことを示すために、はじめの２つの引数を None に設定することができます。

DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)

新たな DocumentType クラスのオブジェクトを返します。このオブジェクトは qualifiedName 、 publicId 、そして systemId 文字列をふくんでおり、XML文書の形式情報を表現しています。

19.6.2.2. Node オブジェクト

XML 文書の全ての構成要素は Node のサブクラスです。

Node.nodeType

ノード (node) の型を表現する整数値です。型に対応する以下のシンボル定数: ELEMENT_NODE 、 ATTRIBUTE_NODE 、 TEXT_NODE 、 CDATA_SECTION_NODE 、 ENTITY_NODE 、 PROCESSING_INSTRUCTION_NODE 、 COMMENT_NODE 、 DOCUMENT_NODE 、 DOCUMENT_TYPE_NODE 、 NOTATION_NODE 、が Node オブジェクトで定義されています。読み出し専用の属性です。

Node.parentNode

現在のノードの親ノードか、文書ノードの場合には None になります。この値は常に Node オブジェクトか None になります。 Element ノードの場合、この値はルート要素 (root element) の場合を除き親要素 (parent element) となり、ルート要素の場合には Document オブジェクトとなります。 Attr ノードの場合、この値は常に None となります。読み出し専用の属性です。

Node.attributes

属性オブジェクトの NamedNodeMap です。要素だけがこの属性に実際の値を持ちます; その他のオブジェクトでは、この属性を None にします。読み出し専用の属性です。

Node.previousSibling

このノードと同じ親ノードを持ち、直前にくるノードです。例えば、 self 要素のの開始タグの直前にくる終了タグを持つ要素です。もちろん、XML 文書は要素だけで構成されているだけではないので、直前にくる兄弟関係にある要素 (sibling) はテキストやコメント、その他になる可能性があります。このノードが親ノードにおける先頭の子ノードである場合、属性値は None になります。読み出し専用の属性です。

Node.nextSibling

このノードと同じ親ノードを持ち、直後にくるノードです。例えば、 previousSibling も参照してください。このノードが親ノードにおける末尾頭の子ノードである場合、属性値は None になります。読み出し専用の属性です。

Node.childNodes

このノード内に収められているノードからなるリストです。読み出し専用の属性です。

Node.firstChild

このノードに子ノードがある場合、その先頭のノードです。そうでない場合 None になります。読み出し専用の属性です。

Node.lastChild

このノードに子ノードがある場合、その末尾のノードです。そうでない場合 None になります。読み出し専用の属性です。

Node.localName

tagName にコロンがあれば、コロン以降の部分に、なければ tagName 全体になります。値は文字列です。

Node.prefix

tagName のコロンがあれば、コロン以前の部分に、なければ空文字列になります。値は文字列か、 None になります。

Node.namespaceURI

要素名に関連付けられた名前空間です。文字列か None になります。読み出し専用の属性です。

Node.nodeName

この属性はノード型ごとに異なる意味を持ちます; 詳しくは DOM 仕様を参照してください。この属性で得られることになる情報は、全てのノード型では tagName 、属性では name プロパティといったように、常に他のプロパティで得ることができます。全てのノード型で、この属性の値は文字列か None になります。読み出し専用の属性です。

Node.nodeValue

この属性はノード型ごとに異なる意味を持ちます; 詳しくは DOM 仕様を参照してください。その序今日は nodeName と似ています。この属性の値は文字列か None になります。

Node.hasAttributes()

ノードが何らかの属性を持っている場合に真を返します。

Node.hasChildNodes()

ノードが何らかの子ノードを持っている場合に真を返します。

Node.isSameNode(other)

other がこのノードと同じノードを参照している場合に真を返します。このメソッドは、何らかのプロキシ (proxy) 機構を利用するような DOM 実装で特に便利です (一つ以上のオブジェクトが同じノードを参照するかもしれないからです)。

ノート

このメソッドは DOM レベル 3 API で提案されており、まだ “ワーキングドラフト(working draft)” の段階です。しかし、このインタフェースだけは議論にはならないと考えられます。 W3C による変更は必ずしも Python DOM インタフェースにおけるこのメソッドに影響するとは限りません (ただしこのメソッドに対する何らかの新たな W3C API もサポートされるかもしれません)。

Node.appendChild(newChild)

現在のノードの子ノードリストの末尾に新たな子ノードを追加し、 newChild を返します。もしノードが既にツリーにあれば、最初に削除されます。

Node.insertBefore(newChild, refChild)

新たな子ノードを既存の子ノードの前に挿入します。 refChild は現在のノードの子ノードである場合に限られます; そうでない場合、 ValueError が送出されます。 newChild が返されます。もし refChild が None なら、 newChild を子ノードリストの最後に挿入します。

Node.removeChild(oldChild)

子ノードを削除します。 oldChild はこのノードの子ノードでなければなりません。そうでない場合、 ValueError が送出されます。成功した場合 oldChild が返されます。 oldChild をそれ以降使わない場合、 unlink() メソッドを呼び出さなければなりません。

Node.replaceChild(newChild, oldChild)

既存のノードと新たなノードを置き換えます。この操作は oldChild が現在のノードの子ノードである場合に限られます; そうでない場合、 ValueError が送出されます。

Node.normalize()

一続きのテキスト全体を一個の Text インスタンスとして保存するために隣接するテキストノードを結合します。これにより、多くのアプリケーションで DOM ツリーからのテキスト処理が簡単になります。

バージョン 2.1 で追加.

Node.cloneNode(deep)

このノードを複製 (clone) します。 deep を設定すると、子ノードも同様に複製することを意味します。複製されたノードを返します。

19.6.2.3. NodeList オブジェクト

NodeList は、ノードからなるシーケンスを表現します。これらのオブジェクトは DOM コア勧告 (DOM Core recommendation) において、二通りに使われています: Element オブジェクトでは、子ノードのリストを提供するのに NodeList を利用します。また、このインタフェースにおける Node の getElementsByTagName() および getElementsByTagNameNS() メソッドは、クエリに対する結果を表現するのに NodeList を利用します。

DOM レベル 2 勧告では、これらのオブジェクトに対し、メソッドと属性を一つづつ定義しています:

NodeList.item(i)

シーケンスに i 番目の要素がある場合にはその要素を、そうでない場合には None を返します。 i はゼロよりも小さくてはならず、シーケンスの長さ以上であってはなりません。

NodeList.length

シーケンス中のノードの数です。

この他に、Python の DOM インタフェースでは、 NodeList オブジェクトを Python のシーケンスとして使えるようにするサポートが追加されていることが必要です。 NodeList の実装では、全て __len__() と __getitem__() をサポートしなければなりません; このサポートにより、 for 文内で NodeList にわたる繰り返しと、組み込み関数 len() の適切なサポートができるようになります。

DOM 実装が文書の変更をサポートしている場合、 NodeList の実装でも __setitem__() および __delitem__() メソッドをサポートしなければなりません。

19.6.2.4. DocumentType オブジェクト

文書で宣言されている記法 (notation) やエンティティ (entity) に関する (外部サブセット(external subset) がパーザから利用でき、情報を提供できる場合にはそれも含めた) 情報は、 DocumentType オブジェクトから手に入れることができます。文書の DocumentType は、 Document オブジェクトの doctype 属性で入手することができます; 文書の DOCTYPE 宣言がない場合、文書の doctype 属性は、このインタフェースを持つインスタンスの代わりに None に設定されます。

DocumentType は Node を特殊化したもので、以下の属性を加えています:

DocumentType.publicId

文書型定義 (document type definition) の外部サブセットに対する公開識別子 (public identifier) です。文字列または None になります。

DocumentType.systemId

文書型定義 (document type definition) の外部サブセットに対するシステム識別子 (system identifier) です。文字列の URI または None になります。

DocumentType.internalSubset

ドキュメントの完全な内部サブセットを与える文字列です。サブセットを囲むブラケットは含みません。ドキュメントが内部サブセットを持たない場合、この値は None です。

DocumentType.name

DOCTYPE 宣言でルート要素の名前が与えられている場合、その値になります。

DocumentType.entities

外部エンティティの定義を与える NamedNodeMap です。複数回定義されているエンティティに対しては、最初の定義だけが提供されます (その他は XML 勧告での要求仕様によって無視されます)。パーザによって情報が提供されないか、エンティティが定義されていない場合には、この値は None になることがあります。

DocumentType.notations

記法の定義を与える NamedNodeMap です。複数回定義されている記法名に対しては、最初の定義だけが提供されます (その他は XML 勧告での要求仕様によって無視されます)。パーザによって情報が提供されないか、エンティティが定義されていない場合には、この値は None になることがあります。

19.6.2.5. Document オブジェクト

Document は XML ドキュメント全体を表現し、その構成要素である要素、属性、処理命令、コメント等が入っています。 Document は Node からプロパティを継承していることを思い出してください。

Document.documentElement

ドキュメントの唯一無二のルート要素です。

Document.createElement(tagName)

新たな要素ノードを生成して返します。要素は、生成された時点ではドキュメント内に挿入されません。 insertBefore() や appendChild() のような他のメソッドの一つを使って明示的に挿入を行う必要があります。

Document.createElementNS(namespaceURI, tagName)

名前空間を伴う新たな要素ノードを生成して返します。 tagName にはプレフィクス (prefix) があってもかまいません。要素は、生成された時点では文書内に挿入されません。 insertBefore() や appendChild() のような他のメソッドの一つを使って明示的に挿入を行う必要があります。 appendChild().

Document.createTextNode(data)

パラメタで渡されたデータの入ったテキストノードを生成して返します。他の生成 (create) メソッドと同じく、このメソッドは生成されたノードをツリーに挿入しません。

Document.createComment(data)

パラメタで渡されたデータの入ったコメントノードを生成して返します。他の生成 (create) メソッドと同じく、このメソッドは生成されたノードをツリーに挿入しません。

Document.createProcessingInstruction(target, data)

パラメタで渡された target および data の入った処理命令ノードを生成して返します。他の生成 (create) メソッドと同じく、このメソッドは生成されたノードをツリーに挿入しません。

Document.createAttribute(name)

属性ノードを生成して返します。このメソッドは属性ノードを特定の要素に関連づけることはしません。新たに生成された属性インスタンスを使うには、適切な Element オブジェクトの setAttributeNode() を使わなければなりません。

Document.createAttributeNS(namespaceURI, qualifiedName)

名前空間を伴う新たな属性ノードを生成して返します。 tagName にはプレフィクス (prefix) があってもかまいません。このメソッドは属性ノードを特定の要素に関連づけることはしません。新たに生成された属性インスタンスを使うには、適切な Element オブジェクトの setAttributeNode() を使わなければなりません。

Document.getElementsByTagName(tagName)

全ての下位要素 (直接の子要素、子要素の子要素、等) から、特定の要素型名を持つものを検索します。

Document.getElementsByTagNameNS(namespaceURI, localName)

全ての下位要素 (直接の子要素、子要素の子要素、等) から、特定の名前空間 URI とローカル名 (local name) を持つものを検索します。ローカル名は名前空間におけるプレフィクス以降の部分です。

19.6.2.6. Element オブジェクト

Element は Node のサブクラスです。このため Node クラスの全ての属性を継承します。

Element.tagName

要素型名です。名前空間使用の文書では、要素型名中にコロンがあるかもしれません。値は文字列です。

Element.getElementsByTagName(tagName)

Document クラス内における同名のメソッドと同じです。

Element.getElementsByTagNameNS(namespaceURI, localName)

Document クラス内における同名のメソッドと同じです。

Element.hasAttribute(name)

指定要素に name で渡した名前の属性が存在していれば true を返します。

Element.hasAttributeNS(namespaceURI, localName)

指定要素に namespaceURI と localName で指定した名前の属性が存在していれば true を返します。

Element.getAttribute(name)

name で指定した属性の値を文字列として返します。もし、属性が存在しない、もしくは属性に値が設定されていない場合、空の文字列が返されます。

Element.getAttributeNode(attrname)

attrname で指定された属性の Attr ノードを返します。

Element.getAttributeNS(namespaceURI, localName)

namespaceURI と localName によって指定した属性の値を文字列として返します。もし、属性が存在しない、もしくは属性に値が設定されていない場合、空の文字列が返されます。

Element.getAttributeNodeNS(namespaceURI, localName)

指定した namespaceURI および localName を持つ属性値をノードとして返します。

Element.removeAttribute(name)

名前で指定された属性を削除します。該当する属性がなければ、 NotFoundErr が送出されます。

Element.removeAttributeNode(oldAttr)

oldAttr が属性リストにある場合、削除して返します。 oldAttr が存在しない場合、 NotFoundErr が送出されます。

Element.removeAttributeNS(namespaceURI, localName)

名前で指定された属性を削除します。このメソッドは qname ではなく localName を使うので注意してください。該当する属性がなくても例外は送出されません。

Element.setAttribute(name, value)

文字列を使って属性値を設定します。

Element.setAttributeNode(newAttr)

新たな属性ノードを要素に追加します。 name 属性が既存の属性に一致した場合、必要に応じて属性を置き換えます。置換が生じると、古い属性ノードが返されます。 newAttr がすでに使われていれば、 InuseAttributeErr が送出されます。

Element.setAttributeNodeNS(newAttr)

新たな属性ノードを要素に追加します。 namespaceURI および localName 属性が既存の属性に一致した場合、必要に応じて属性を置き換えます。置換が生じると、古い属性ノードが返されます。 newAttr がすでに使われていれば、 InuseAttributeErr が送出されます。

Element.setAttributeNS(namespaceURI, qname, value)

指定された namespaceURI および qname で与えられた属性の値を文字列で設定します。qname は属性の完全な名前であり、この点が上記のメソッドと違うので注意してください。

19.6.2.7. Attr オブジェクト

Attr は Node を継承しており、全ての属性を受け継いでいます。

Attr.name

要素型名です。名前空間使用の文書では、要素型名中にコロンが含まれるかもしれません。

Attr.localName

名前にコロンがあればコロン以降の部分に、なければ名前全体になります。

Attr.prefix

名前にコロンがあればコロン以前の部分に、なければ空文字列になります。

Attr.value

その要素の text value. これは nodeValue 属性の別名です。

19.6.2.8. NamedNodeMap Objects

NamedNodeMap は Node を継承して いません 。

NamedNodeMap.length

属性リストの長さです。

NamedNodeMap.item(index)

特定のインデクスを持つ属性を返します。属性の並び方は任意ですが、 DOM 文書が生成されている間は一定になります。各要素は属性ノードです。属性値はノードの value 属性で取得してください。

このクラスをよりマップ型的な動作ができるようにする実験的なメソッドもあります。そうしたメソッドを使うこともできますし、 Element オブジェクトに対して、標準化された getAttribute*() ファミリのメソッドを使うこともできます。

19.6.2.9. Comment オブジェクト

Comment は XML 文書中のコメントを表現します。 Comment は Node のサブクラスですが、子ノードを持つことはありません。

Comment.data

文字列によるコメントの内容です。この属性には、コメントの先頭にある <!- - と末尾にある - -> 間の全ての文字が入っていますが、 <!- - と - -> 自体は含みません。

19.6.2.10. Text オブジェクトおよび CDATASection オブジェクト

Text インタフェースは XML 文書内のテキストを表現します。パーザおよび DOM 実装が DOM の XML 拡張をサポートしている場合、 CDATA でマークされた区域 (section) に入れられている部分テキストは CDATASection オブジェクトに記憶されます。これら二つのインタフェースは同一のものですが、 nodeType 属性が異なります。

これらのインタフェースは Node インタフェースを拡張したものです。しかし子ノードを持つことはできません。

Text.data

文字列によるテキストノードの内容です。

ノート

CDATASection ノードの利用は、ノードが完全な CDATA マーク区域を表現するという意味ではなく、ノードの内容が CDATA 区域の一部であるということを意味するだけです。単一の CDATA セクションは文書ツリー内で複数のノードとして表現されることがあります。二つの隣接する CDATASection ノードが、異なる CDATA マーク区域かどうかを決定する方法はありません。

19.6.2.11. ProcessingInstruction オブジェクト

XML 文書内の処理命令を表現します; Node インタフェースを継承していますが、子ノードを持つことはできません。

ProcessingInstruction.target

最初の空白文字までの処理命令の内容です。読み出し専用の属性です。

ProcessingInstruction.data

最初の空白文字以降の処理命令の内容です。

19.6.2.12. 例外

バージョン 2.1 で追加.

DOM レベル 2 勧告では、単一の例外 DOMException と、どの種のエラーが発生したかをアプリケーションが決定できるようにする多くの定数を定義しています。 DOMException インスタンスは、特定の例外に関する適切な値を提供する code 属性を伴っています。

Python DOM インタフェースでは、上記の定数を提供していますが、同時に一連の例外を拡張して、DOM で定義されている各例外コードに対して特定の例外が存在するようにしています。 DOM の実装では、適切な特定の例外を送出しなければならず、各例外は code 属性に対応する適切な値を伴わなければなりません。

exception xml.dom.DOMException

全ての特定の DOM 例外で使われている基底例外クラスです。この例外クラスは直接インスタンス化することができません。

exception xml.dom.DomstringSizeErr

指定された範囲のテキストが文字列に収まらない場合に送出されます。この例外は Python の DOM 実装で使われるかどうかは判っていませんが、 Python で書かれていない DOM 実装から送出される場合があります。

exception xml.dom.HierarchyRequestErr

挿入できない型のノードを挿入しようと試みたときに送出されます。

exception xml.dom.IndexSizeErr

メソッドに与えたインデクスやサイズパラメタが負の値や許容範囲の値を超えた際に送出されます。

exception xml.dom.InuseAttributeErr

文書中にすでに存在する Attr ノードを挿入しようと試みた際に送出されます。

exception xml.dom.InvalidAccessErr

パラメタまたは操作が根底にあるオブジェクトでサポートされていない場合に送出されます。

exception xml.dom.InvalidCharacterErr

この例外は、文字列パラメタが、現在使われているコンテキストで XML 1.0 勧告によって許可されていない場合に送出されます。例えば、要素型に空白の入った Element ノードを生成しようとすると、このエラーが送出されます。

exception xml.dom.InvalidModificationErr

ノードの型を変更しようと試みた際に送出されます。

exception xml.dom.InvalidStateErr

定義されていないオブジェクトや、もはや利用できなくなったオブジェクトを使おうと試みた際に送出されます。

exception xml.dom.NamespaceErr

Namespaces in XML [http://www.w3.org/TR/REC-xml-names/] に照らして許可されていない方法でオブジェクトを変更しようと試みた場合、この例外が送出されます。

exception xml.dom.NotFoundErr

参照しているコンテキスト中に目的のノードが存在しない場合に送出される例外です。例えば、 NamedNodeMap.removeNamedItem() は渡されたノードがノードマップ中に存在しない場合にこの例外を送出します。

exception xml.dom.NotSupportedErr

要求された方のオブジェクトや操作が実装でサポートされていない場合に送出されます。

exception xml.dom.NoDataAllowedErr

データ属性をサポートしないノードにデータを指定した際に送出されます。

exception xml.dom.NoModificationAllowedErr

オブジェクトに対して (読み出し専用ノードに対する修正のように) 許可されていない修正を行おうと試みた際に送出されます。

exception xml.dom.SyntaxErr

無効または不正な文字列が指定された際に送出されます。

exception xml.dom.WrongDocumentErr

ノードが現在属している文書と異なる文書に挿入され、かつある文書から別の文書へのノードの移行が実装でサポートされていない場合に送出されます。

DOM 勧告で定義されている例外コードは、以下のテーブルに従って上記の例外と対応付けられます:

定数 | 例外
DOMSTRING_SIZE_ERR | DomstringSizeErr
HIERARCHY_REQUEST_ERR | HierarchyRequestErr
INDEX_SIZE_ERR | IndexSizeErr
INUSE_ATTRIBUTE_ERR | InuseAttributeErr
INVALID_ACCESS_ERR | InvalidAccessErr
INVALID_CHARACTER_ERR | InvalidCharacterErr
INVALID_MODIFICATION_ERR | InvalidModificationErr
INVALID_STATE_ERR | InvalidStateErr
NAMESPACE_ERR | NamespaceErr
NOT_FOUND_ERR | NotFoundErr
NOT_SUPPORTED_ERR | NotSupportedErr
NO_DATA_ALLOWED_ERR | NoDataAllowedErr
NO_MODIFICATION_ALLOWED_ERR | NoModificationAllowedErr
SYNTAX_ERR | SyntaxErr
WRONG_DOCUMENT_ERR | WrongDocumentErr

19.6.3. 適合性

この節では適合性に関する要求と、Python DOM API、W3C DOM 勧告、および OMG IDL の Python API への対応付けとの間の関係について述べます。

19.6.3.1. 型の対応付け

DOM 仕様で使われている基本的な IDL 型は、以下のテーブルに従って Python の型に対応付けられています。

IDL 型 | Python 型
boolean | IntegerType (値 0 または 1) による
int | IntegerType
long int | IntegerType
unsigned int | IntegerType

さらに、勧告で定義されている DOMString は、Python 文字列または Unicode 文字列に対応付けられます。アプリケーションでは、 DOM から文字列が返される際には常に Unicode を扱えなければなりません。

IDL の null 値は None に対応付けられており、 API で null の使用が許されている場所では常に受理されるか、あるいは実装によって提供されるはずです。

19.6.3.2. アクセサメソッド

OMG IDL から Python への対応付けは、 IDL attribute 宣言へのアクセサ関数の定義を、Java による対応付けが行うのとほとんど同じように行います。

IDL 宣言の対応付け

readonly attribute string someValue;
         attribute string anotherValue;

は、三つのアクセサ関数: someValue に対する “get” メソッド (_get_someValue())、そして anotherValue に対する “get” および “set” メソッド (_get_anotherValue() および _set_anotherValue()) を生み出します。とりわけ、対応付けでは、IDL 属性が通常の Python 属性としてアクセス可能であることは必須ではありません: object.someValue が動作することは必須 ではなく 、 AttributeError を送出してもかまいません。

しかしながら、Python DOM API では、通常の属性アクセスが動作することが必須です。これは、Python IDL コンパイラによって生成された典型的なサロゲーションはまず動作することはなく、DOM オブジェクトが CORBA を解してアクセスされる場合には、クライアント上でラッパオブジェクトが必要であることを意味します。 CORBA DOM クライアントでは他にもいくつか考慮すべきことがある一方で、 CORBA を介して DOM を使った経験を持つ実装者はこのことを問題視していません。 readonly であると宣言された属性は、全ての DOM 実装で書き込みアクセスを制限しているとは限りません。

Python DOM API では、アクセサ関数は必須ではありません。アクセサ関数が提供された場合、 Python IDL 対応付けによって定義された形式をとらなければなりませんが、属性は Python から直接アクセスすることができるので、それらのメソッドは必須ではないと考えられます。 readonly であると宣言された属性に対しては、 “set” アクセサを提供してはなりません。

このIDLでの定義はW3C DOM APIの全ての要件を実装しているわけではありません。例えば、一部のオブジェクトの概念や getElementsByTagName() が”live”であることなどです。 Python DOM API はこれらの要件を実装することを強制しません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.7. xml.dom.minidom — 軽量な DOM 実装

バージョン 2.0 で追加.

xml.dom.minidom は、軽量な文書オブジェクトモデルインタフェースの実装です。この実装では、完全な DOM よりも単純で、かつ十分に小さくなるよう意図しています。

DOM アプリケーションは典型的に、XML を DOM に解析 (parse) することで開始します。 xml.dom.minidom では、以下のような解析用の関数を介して行います:

from xml.dom.minidom import parse, parseString

dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name

datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource)   # parse an open file

dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')

parse() 関数はファイル名か、開かれたファイルオブジェクトを引数にとることができます。

xml.dom.minidom.parse(filename_or_file[, parser[, bufsize]])

与えられた入力から Document を返します。 filename_or_file はファイル名でもファイルオブジェクトでもかまいません。 parser を指定する場合、SAX2 パーザオブジェクトでなければなりません。この関数はパーザの文書ハンドラを変更し、名前空間サポートを有効にします; (エンティティリゾルバ (entity resolver) のような) 他のパーザ設定は前もっておこなわなければなりません。

XML データを文字列で持っている場合、 parseString() を代わりに使うことができます:

xml.dom.minidom.parseString(string[, parser])

string を表現する Document を返します。このメソッドは文字列に対する StringIO オブジェクトを生成して、そのオブジェクトを parse() に渡します。

これらの関数は両方とも、文書の内容を表現する Document オブジェクトを返します。

parse() や parseString() といった関数が行うのは、 XML パーザを、何らかの SAX パーザからくる解析イベント (parse event) を受け取って DOM ツリーに変換できるような “DOM ビルダ (DOM builder)” に結合することです。関数は誤解を招くような名前になっているかもしれませんが、インタフェースについて学んでいるときには理解しやすいでしょう。文書の解析はこれらの関数が戻るより前に完結します; 要するに、これらの関数自体はパーザ実装を提供しないということです。

“DOM 実装” オブジェクトのメソッドを呼び出して Document を生成することもできます。このオブジェクトは、 xml.dom パッケージ、または xml.dom.minidom モジュールの getDOMImplementation() 関数を呼び出して取得できます。 xml.dom.minidom モジュールの実装を使うと、常に minidom 実装の Document インスタンスを返します。一方、 xml.dom 版の関数では、別の実装によるインスタンスを返すかもれません (PyXML package [http://pyxml.sourceforge.net/] がインストールされているとそうなるでしょう)。 Document を取得したら、DOM を構成するために子ノードを追加していくことができます:

from xml.dom.minidom import getDOMImplementation

impl = getDOMImplementation()

newdoc = impl.createDocument(None, "some_tag", None)
top_element = newdoc.documentElement
text = newdoc.createTextNode('Some textual content.')
top_element.appendChild(text)

DOM 文書オブジェクトを手にしたら、XML 文書のプロパティやメソッドを使って、文書の一部にアクセスすることができます。これらのプロパティは DOM 仕様で定義されています。文書オブジェクトの主要なプロパティは documentElement プロパティです。このプロパティは XML 文書の主要な要素: 他の全ての要素を保持する要素、を与えます。以下にプログラム例を示します:

dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"

DOMツリーを使い終えた後に、 unlink() メソッドを呼び出すことで利用されなくなったオブジェクトが早くクリーンアップされるように助けることができます。 unlink() は、 DOM API に対する xml.dom.minidom 特有の拡張です。ノードに対して unlink() を呼び出した後は、ノードとその下位ノードは本質的には無意味なものとなります。このメソッドを呼び出さなくても、 Python のガベージコレクタがいつかはツリーのオブジェクトを後片付けします。

参考

Document Object Model (DOM) Level 1 Specification [http://www.w3.org/TR/REC-DOM-Level-1/]

xml.dom.minidom でサポートされている DOM の W3C 勧告。

19.7.1. DOM オブジェクト

Python の DOM API 定義は xml.dom モジュールドキュメントの一部として与えられています。この節では、 xml.dom の API と xml.dom.minidom との違いについて列挙します。

Node.unlink()

DOM との内部的な参照を破壊して、循環参照ガベージコレクションを持たないバージョンの Python でもガベージコレクションされるようにします。循環参照ガベージコレクションが利用できても、このメソッドを使えば、大量のメモリをすぐに使えるようにできるため、必要なくなったらすぐにこのメソッドを DOM オブジェクトに対して呼ぶのが良い習慣です。このメソッドは Document オブジェクトに対してだけ呼び出せばよいのですが、あるノードの子ノードを放棄するために子ノードに対して呼び出してもかまいません。

Node.writexml(writer[, indent=""[, addindent=""[, newl=""]]])

XML を writer オブジェクトに書き込みます。 writer は、ファイルオブジェクトインタフェースの write() に該当するメソッドを持たなければなりません。 indent パラメタには現在のノードのインデントを指定します。 addindent パラメタには現在のノードの下にサブノードを追加する際のインデント増分を指定します。 newl には、改行時に行末を終端する文字列を指定します。

Document ノードでは、追加のキーワード引数 encoding を使って XML ヘッダの encoding フィールドを指定することができます。

バージョン 2.1 で変更: 美しい出力をサポートするため、新たなキーワード引数 indent 、 addindent 、および newl が追加されました.

バージョン 2.3 で変更: Document ノードに対して、追加のキーワード引数 encoding を使って、 XML ヘッダの encoding フィールドを指定できるようになりました.

Node.toxml([encoding])

DOM が表現している XML を文字列にして返します。

引数がなければ、 XML ヘッダは encoding を指定せず、文書内の全ての文字をデフォルトエンコード方式で表示できない場合、結果は Unicode 文字列となります。この文字列を UTF-8 以外のエンコード方式でエンコードするのは不正であり、なぜなら UTF-8 が XML のデフォルトエンコード方式だからです。

明示的な encoding [1] 引数があると、結果は指定されたエンコード方式によるバイト文字列となります。引数を常に指定するよう推奨します。表現不可能なテキストデータの場合に UnicodeError が送出されるのを避けるため、encoding 引数は “utf-8” に指定するべきです。

バージョン 2.3 で変更: encoding が追加されました。 writexml() を参照して下さい。

Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])

美しく出力されたバージョンの文書を返します。 indent はインデントを行うための文字で、デフォルトはタブです; newl には行末で出力される文字列を指定し、デフォルトは \n です。

バージョン 2.1 で追加.

バージョン 2.3 で変更: encoding 引数が追加されました。 writexml() を参照して下さい。

以下の標準 DOM メソッドは、 xml.dom.minidom では特別な注意をする必要があります:

Node.cloneNode(deep)

このメソッドは Python 2.0 にパッケージされているバージョンの xml.dom.minidom にはありましたが、これには深刻な障害があります。以降のリリースでは修正されています。

19.7.2. DOM の例

以下のプログラム例は、かなり現実的な単純なプログラムの例です。特にこの例に関しては、DOM の柔軟性をあまり活用してはいません。

import xml.dom.minidom

document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>

<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""

dom = xml.dom.minidom.parseString(document)

def getText(nodelist):
    rc = ""
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc = rc + node.data
    return rc

def handleSlideshow(slideshow):
    print "<html>"
    handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
    slides = slideshow.getElementsByTagName("slide")
    handleToc(slides)
    handleSlides(slides)
    print "</html>"

def handleSlides(slides):
    for slide in slides:
        handleSlide(slide)

def handleSlide(slide):
    handleSlideTitle(slide.getElementsByTagName("title")[0])
    handlePoints(slide.getElementsByTagName("point"))

def handleSlideshowTitle(title):
    print "<title>%s</title>" % getText(title.childNodes)

def handleSlideTitle(title):
    print "<h2>%s</h2>" % getText(title.childNodes)

def handlePoints(points):
    print "<ul>"
    for point in points:
        handlePoint(point)
    print "</ul>"

def handlePoint(point):
    print "<li>%s</li>" % getText(point.childNodes)

def handleToc(slides):
    for slide in slides:
        title = slide.getElementsByTagName("title")[0]
        print "<p>%s</p>" % getText(title.childNodes)

handleSlideshow(dom)

19.7.3. minidom と DOM 標準

xml.dom.minidom モジュールは、本質的には DOM 1.0 互換の DOM に、いくつかの DOM 2 機能 (主に名前空間機能) を追加したものです。

Python における DOM インタフェースは率直なものです。以下の対応付け規則が適用されます:

インタフェースはインスタンスオブジェクトを介してアクセスされます。アプリケーション自身から、クラスをインスタンス化してはなりません; Document オブジェクト上で利用可能な生成関数 (creator function) を使わなければなりません。派生インタフェースでは基底インタフェースの全ての演算 (および属性) に加え、新たな演算をサポートします。

演算はメソッドとして使われます。DOM では in パラメタのみを使うので、引数は通常の順番 (左から右へ) で渡されます。オプション引数はありません。 void 演算は None を返します。

IDL 属性はインスタンス属性に対応付けられます。OMG IDL 言語における Python への対応付けとの互換性のために、属性 foo はアクセサメソッド _get_foo() および _set_foo() でもアクセスできます。 readonly 属性は変更してはなりません; とはいえ、これは実行時には強制されません。

short int 、 unsigned int 、 unsigned long long 、および boolean 型は、全て Python 整数オブジェクトに対応付けられます。

DOMString 型は Python 文字列型に対応付けられます。 xml.dom.minidom ではバイト文字列 (byte string) および Unicode 文字列のどちらかに対応づけられますが、通常 Unicode 文字列を生成します。 DOMString 型の値は、W3C の DOM 仕様で、IDL null 値になってもよいとされている場所では None になることもあります。

const 宣言を行うと、 (xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE のように) 対応するスコープ内の変数に対応付けを行います; これらは変更してはなりません。

DOMException は現状では xml.dom.minidom でサポートされていません。その代わり、 xml.dom.minidom は、 TypeError や AttributeError といった標準の Python 例外を使います。

NodeList オブジェクトは Python の組み込みリスト型を使って実装されています。 Python 2.2 からは、これらのオブジェクトは DOM 仕様で定義されたインタフェースを提供していますが、それ以前のバージョンの Python では、公式の API をサポートしていません。しかしながら、これらの API は W3C 勧告で定義されたインタフェースよりも “Python 的な” ものになっています。

以下のインタフェースは xml.dom.minidom では全く実装されていません:

DOMTimeStamp

DocumentType (added in Python 2.1)

DOMImplementation (added in Python 2.1)

CharacterData

CDATASection

Notation

Entity

EntityReference

DocumentFragment

これらの大部分は、ほとんどの DOM のユーザにとって一般的な用途として有用とはならないような XML 文書内の情報を反映しています。

注記

[1]
XML の出力に含まれるエンコーディング文字列は適切な標準に適合していなければなりません。たとえば、”UTF-8” は正当ですが、”UTF8” は違います。 http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl と http://www.iana.org/assignments/character-sets を参照して下さい。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.8. xml.dom.pulldom — 部分的な DOM ツリー構築のサポート

バージョン 2.0 で追加.

xml.dom.pulldom では、SAX イベントから、文書の文書オブジェクトモデル表現の選択された一部分だけを構築できるようにします。

class xml.dom.pulldom.PullDOM([documentFactory])

xml.sax.handler.ContentHandler 実装です ...

class xml.dom.pulldom.DOMEventStream(stream, parser, bufsize)

...

class xml.dom.pulldom.SAX2DOM([documentFactory])

xml.sax.handler.ContentHandler 実装です ...

xml.dom.pulldom.parse(stream_or_string[, parser[, bufsize]])

...

xml.dom.pulldom.parseString(string[, parser])

...

xml.dom.pulldom.default_bufsize

parse() の bufsize パラメタのデフォルト値です。

バージョン 2.1 で変更: この変数の値は parse() を呼び出す前に変更することができ、その場合新たな値が効果を持つようになります.

19.8.1. DOMEventStream オブジェクト

DOMEventStream.getEvent()

...

DOMEventStream.expandNode(node)

...

DOMEventStream.reset()

...

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.9. xml.sax — SAX2 パーサのサポート

バージョン 2.0 で追加.

xml.sax パッケージは Python 用の Simple API for XML (SAX) インターフェースを実装した数多くのモジュールを提供しています。またパッケージには SAX 例外と SAX API 利用者が頻繁に利用するであろう有用な関数群も含まれています。

その関数群は以下の通りです:

xml.sax.make_parser([parser_list])

SAX XMLReader オブジェクトを作成して返します。パーサには最初に見つかったものが使われます。 parser_list を指定する場合は、 create_parser() 関数を含んでいるモジュール名のシーケンスを与える必要があります。 parser_list のモジュールはデフォルトのパーサのリストに優先して使用されます。

xml.sax.parse(filename_or_stream, handler[, error_handler])

SAX パーサを作成してドキュメントをパースします。 filename_or_stream として指定するドキュメントはファイル名、ファイル・オブジェクトのいずれでもかまいません。 handler パラメータには SAX ContentHandler のインスタンスを指定します。 error_handler には SAX ErrorHandler のインスタンスを指定します。これが指定されていないときは、すべてのエラーで SAXParseException 例外が発生します。関数の戻り値はなく、すべての処理は handler に渡されます。

xml.sax.parseString(string, handler[, error_handler])

parse() に似ていますが、こちらはパラメータ string で指定されたバッファをパースします。

典型的な SAX アプリケーションでは3種類のオブジェクト(リーダ、ハンドラ、入力元)が用いられます(ここで言うリーダとはパーサを指しています)。言い換えると、プログラムはまず入力元からバイト列、あるいは文字列を読み込み、一連のイベントを発生させます。発生したイベントはハンドラ・オブジェクトによって振り分けられます。さらに言い換えると、リーダがハンドラのメソッドを呼び出すわけです。つまり SAX アプリケーションには、リーダ・オブジェクト、(作成またはオープンされる)入力元のオブジェクト、ハンドラ・オブジェクト、そしてこれら3つのオブジェクトを連携させることが必須なのです。前処理の最後の段階でリーダは入力をパースするために呼び出されます。パースの過程で入力データの構造、構文にもとづいたイベントにより、ハンドラ・オブジェクトのメソッドが呼び出されます。

これらのオブジェクトは(通常アプリケーション側でインスタンスを作成しない)インターフェースに相当するものです。 Python はインターフェースという明確な概念を提供していないため、形としてはクラスが用いられています。しかし提供されるクラスを継承せずに、アプリケーション側で独自に実装することも可能です。 InputSource 、 Locator 、 Attributes 、 AttributesNS 、 XMLReader の各インターフェースは xml.sax.xmlreader モジュールで定義されています。ハンドラ・インターフェースは xml.sax.handler で定義されています。しばしばアプリケーション側で直接インスタンスが作成される InputSource とハンドラ・クラスは利便性のため xml.sax にも含まれています。これらのインターフェースに関しては後に解説します。

このほかに xml.sax は次の例外クラスも提供しています。

exception xml.sax.SAXException(msg[, exception])

XML エラーと警告をカプセル化します。このクラスには XML パーサとアプリケーションで発生するエラーおよび警告の基本的な情報を持たせることができます。また機能追加や地域化のためにサブクラス化することも可能です。なお ErrorHandler で定義されているハンドラがこの例外のインスタンスを受け取ることに注意してください。実際に例外を発生させることは必須でなく、情報のコンテナとして利用されることもあるからです。

インスタンスを作成する際 msg はエラー内容を示す可読データにしてください。オプションの exception パラメータは None もしくはパース用コードで補足、渡って来る情報でなければなりません。

このクラスはSAX 例外の基底クラスになります。

exception xml.sax.SAXParseException(msg, exception, locator)

パースエラー時に発生する SAXException のサブクラスです。パースエラーに関する情報として、このクラスのインスタンスが SAX ErrorHandler インターフェースのメソッドに渡されます。このクラスは SAXException 同様 SAX Locator インターフェースもサポートしています。

exception xml.sax.SAXNotRecognizedException(msg[, exception])

SAX XMLReader が認識できない機能やプロパティに遭遇したとき発生させる SAXException のサブクラスです。 SAX アプリケーションや拡張モジュールにおいて同様の目的にこのクラスを利用することもできます。

exception xml.sax.SAXNotSupportedException(msg[, exception])

SAX XMLReader が要求された機能をサポートしていないとき発生させる SAXException のサブクラスです。 SAX アプリケーションや拡張モジュールにおいて同様の目的にこのクラスを利用することもできます。

参考

SAX: The Simple API for XML [http://www.saxproject.org/]

SAX API 定義に関し中心となっているサイトです。 Java による実装とオンライン・ドキュメントが提供されています。実装と SAX API の歴史に関する情報のリンクも掲載されています。

Module xml.sax.handler

アプリケーションが提供するオブジェクトのインターフェース定義

Module xml.sax.saxutils

SAX アプリケーション向けの有用な関数群

Module xml.sax.xmlreader

パーサが提供するオブジェクトのインターフェース定義

19.9.1. SAXException オブジェクト

SAXException 例外クラスは以下のメソッドをサポートしています。

SAXException.getMessage()

エラー状態を示す可読メッセージを返します。

SAXException.getException()

カプセル化した例外オブジェクトまたは None を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.10. xml.sax.handler — SAX ハンドラの基底クラス

バージョン 2.0 で追加.

SAX API はコンテント・ハンドラ、DTD ハンドラ、エラー・ハンドラ、エンティティ・リゾルバという4つのハンドラを規定しています。通常アプリケーション側で実装する必要があるのは、これらのハンドラが発生させるイベントのうち、処理したいものへのインターフェースだけです。インターフェースは1つのオブジェクトにまとめることも、複数のオブジェクトに分けることも可能です。ハンドラはすべてのメソッドがデフォルトで実装されるように、 xml.sax.handler で提供される基底クラスを継承しなくてはなりません。

class xml.sax.handler.ContentHandler

アプリケーションにとって最も重要なメインの SAX コールバック・インターフェースです。このインターフェースで発生するイベントの順序はドキュメント内の情報の順序を反映しています。

class xml.sax.handler.DTDHandler

DTD イベントのハンドラです。

未構文解析エンティティや属性など、パースに必要な DTD イベントの抽出だけをおこなうインターフェースです。

class xml.sax.handler.EntityResolver

エンティティ解決用の基本インターフェースです。このインターフェースを実装したオブジェクトを作成しパーサに登録することで、パーサはすべての外部エンティティを解決するメソッドを呼び出すようになります。

class xml.sax.handler.ErrorHandler

エラーや警告メッセージをアプリケーションに通知するためにパーサが使用するインターフェースです。このオブジェクトのメソッドが、エラーをただちに例外に変換するか、あるいは別の方法で処理するかの制御をしています。

これらのクラスに加え、 xml.sax.handler は機能やプロパティ名のシンボル定数を提供しています。

xml.sax.handler.feature_namespaces

値: "http://xml.org/sax/features/namespaces"

true: 名前空間の処理を有効にする。

false: オプションで名前空間の処理を無効にする (暗黙に namespace-prefixes も無効にする - デフォルト )。

アクセス: (パース時) リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.feature_namespace_prefixes

値: "http://xml.org/sax/features/namespace-prefixes"

true: 名前空間宣言で用いられているオリジナルのプリフィックス名と属性を通知する。

false: 名前空間宣言で用いられている属性を通知しない。オプションでオリジナルのプリフィックス名も通知しない(デフォルト)。

アクセス: (パース時) リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.feature_string_interning

値: "http://xml.org/sax/features/string-interning"

true: すべての要素名、プリフィックス、属性、名前、名前空間、URI、ローカル名を組込みの intern 関数を使ってシンボルに登録する。

false: 名前のすべてを必ずしもシンボルに登録しない(デフォルト)。

アクセス: (パース時) リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.feature_validation

値: "http://xml.org/sax/features/validation"

true: すべての妥当性検査エラーを通知する(external-general-entities とexternal-parameter-entities が暗黙の前提になっている)。

false: 妥当性検査エラーを通知しない。

アクセス: (パース時) リードオンリー; (パース時以外)読み書き可

xml.sax.handler.feature_external_ges

値: "http://xml.org/sax/features/external-general-entities"

true: 外部一般(テキスト)エンティティの取り込みをおこなう。

false: 外部一般エンティティを取り込まない。

アクセス: (パース時)リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.feature_external_pes

値: "http://xml.org/sax/features/external-parameter-entities"

true: 外部 DTD サブセットを含むすべての外部パラメータ・エンティティの取り込みをおこなう。

false: 外部パラーメタ・エンティティおよび外部 DTD サブセットを取り込まない。

アクセス: (パース時) リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.all_features

すべての機能の一覧。

xml.sax.handler.property_lexical_handler

値: "http://xml.org/sax/properties/lexical-handler"

データ型: xml.sax.sax2lib.LexicalHandler (Python 2 では未サポート)

説明: コメントなど字句解析イベント用のオプション拡張ハンドラ。

アクセス: 読み書き可

xml.sax.handler.property_declaration_handler

値: "http://xml.org/sax/properties/declaration-handler"

データ型: xml.sax.sax2lib.DeclHandler (Python 2 では未サポート)

説明: ノーテーションや未解析エンティティをのぞく DTD 関連イベント用のオプション拡張ハンドラ。

アクセス: 読み書き可

xml.sax.handler.property_dom_node

値: "http://xml.org/sax/properties/dom-node"

データ型: org.w3c.dom.Node (Python 2 では未サポート)

説明: パース時は DOM イテレータにおけるカレントDOM ノード、非パース時はルート DOM ノードを指す。

アクセス: (パース時) リードオンリー; (パース時以外) 読み書き可

xml.sax.handler.property_xml_string

値: "http://xml.org/sax/properties/xml-string"

データ型: 文字列

説明: カレント・イベントの元になったリテラル文字列

アクセス: リードオンリー

xml.sax.handler.all_properties

既知のプロパティ名の全リスト。

19.10.1. ContentHandler オブジェクト

ContentHandler はアプリケーション側でサブクラス化して利用することが前提になっています。パーサは入力ドキュメントのイベントにより、それぞれに対応する以下のメソッドを呼び出します。

ContentHandler.setDocumentLocator(locator)

アプリケーションにドキュメント・イベントの発生位置を通知するためにパーサから呼び出されます。

SAX パーサによるロケータの提供は強く推奨されています(必須ではありません)。もし提供する場合は、DocumentHandler インターフェースのどのメソッドよりも先にこのメソッドが呼び出されるようにしなければなりません。

アプリケーションはパーサがエラーを通知しない場合でもロケータによって、すべてのドキュメント関連イベントの終了位置を知ることが可能になります。典型的な利用方法としては、アプリケーション側でこの情報を使い独自のエラーを発生させること(文字コンテンツがアプリケーション側で決めた規則に沿っていない場合等)があげられます。しかしロケータが返す情報は検索エンジンなどで利用するものとしてはおそらく不充分でしょう。

ロケータが正しい情報を返すのは、インターフェースからイベントの呼出しが実行されている間だけです。それ以外のときは使用すべきでありません。

ContentHandler.startDocument()

ドキュメントの開始通知を受け取ります。

SAX パーサはこのインターフェースやDTDHandler のどのメソッド (setDocumentLocator() を除く)よりも先にこのメソッドを一度だけ呼び出します。

ContentHandler.endDocument()

ドキュメントの終了通知を受け取ります。

SAX パーサはこのメソッドを一度だけ、パース過程の最後に呼び出します。パーサは(回復不能なエラーで)パース処理を中断するか、あるいは入力の最後に到達するまでこのメソッドを呼び出しません。

ContentHandler.startPrefixMapping(prefix, uri)

プリフィックスと URI の名前空間の関連付けを開始します。

このイベントから返る情報は通常の名前空間処理では使われません。 SAX XML リーダは feature_namespaces 機能が有効になっている場合(デフォルト)、要素と属性名のプリフィックスを自動的に置換するようになっています。

しかしアプリケーション側でプリフィックスを文字データや属性値の中で扱う必要が生じることもあります。この場合プリフィックスの自動展開は保証されないため、必要に応じ startPrefixMapping() や endPrefixMapping() イベントからアプリケーションに提供される情報を用いてプリフィックスの展開をおこないます。

startPrefixMapping() と endPrefixMapping() イベントは相互に正しい入れ子関係になることが保証されていないので注意が必要です。すべての startPrefixMapping() は対応する startElement() の前に発生し、 endPrefixMapping() イベントは対応する endElement() の後で発生しますが、その順序は保証されていません。

ContentHandler.endPrefixMapping(prefix)

プリフィックスと URI の名前空間の関連付けを終了します。

詳しくは startPrefixMapping() を参照してください。このイベントは常に対応する endElement() の後で発生しますが、複数の endPrefixMapping() イベントの順序は特に保証されません。

ContentHandler.startElement(name, attrs)

非名前空間モードで要素の開始を通知します。

name パラーメータには要素型の raw XML 1.0名を文字列として、 attrs パラメータには要素の属性を保持する Attributes インターフェース (The Attributes インタフェース を参照) オブジェクトをそれぞれ指定します。 attrs として渡されたオブジェクトはパーサで再利用することも可能ですが、属性のコピーを保持するためにこれを参照し続けるのは確実な方法ではありません。属性のコピーを保持したいときは attrs オブジェクトの copy() メソッドを用いてください。

ContentHandler.endElement(name)

非名前空間モードで要素の終了を通知します。

name パラメータには startElement() イベント同様の要素型名を指定します。

ContentHandler.startElementNS(name, qname, attrs)

名前空間モードで要素の開始を通知します。

name パラーメータには要素型を (uri, localname) のタプルとして、 qname パラメータにはソース・ドキュメントで用いられている raw XML 1.0名、 attrs には要素の属性を保持する AttributesNS インターフェース (AttributesNS インタフェース を参照) のインスタンスをそれぞれ指定します。要素に関連付けられた名前空間がないときは、 name コンポーネントの uri が None になります。 attrs として渡されたオブジェクトはパーサで再利用することも可能ですが、属性のコピーを保持するためにこれを参照し続けるのは確実な方法ではありません。属性のコピーを保持したいときは attrs オブジェクトの copy() メソッドを用いてください。

feature_namespace_prefixes 機能が有効になっていなければ、パーサで qname を None にセットすることも可能です。

ContentHandler.endElementNS(name, qname)

非名前空間モードで要素の終了を通知します。

name パラメータには startElementNS() イベント同様の要素型を指定します。 qname パラメータも同じです。

ContentHandler.characters(content)

文字データの通知を受け取ります。

パーサは文字データのチャンクごとにこのメソッドを呼び出して通知します。 SAX パーサは一連の文字データを単一のチャンクとして返す場合と複数のチャンクに分けて返す場合がありますが、ロケータの情報が正しく保たれるように、一つのイベントの文字データは常に同じ外部エンティティのものでなければなりません。

content はユニコード文字列、バイト文字列のどちらでもかまいませんが、 expat リーダ・モジュールは常にユニコード文字列を生成するようになっています。

ノート

Python XML SIG が提供していた初期 SAX 1 では、このメソッドにもっと JAVA 風のインターフェースが用いられています。しかし Python で採用されている大半のパーサでは古いインターフェースを有効に使うことができないため、よりシンプルなものに変更されました。古いコードを新しいインターフェースに変更するには、古い offset と length パラメータでスライスせずに、 content を指定するようにしてください。

ContentHandler.ignorableWhitespace(whitespace)

要素コンテンツに含まれる無視可能な空白文字の通知を受け取ります。

妥当性検査をおこなうパーサは無視可能な空白文字(W3C XML 1.0 勧告のセクション 2.10 参照)のチャンクごとに、このメソッドを使って通知しなければなりません。妥当性検査をしないパーサもコンテンツモデルの利用とパースが可能な場合、このメソッドを利用することが可能です。

SAX パーサは一連の空白文字を単一のチャンクとして返す場合と複数のチャンクに分けて返す場合がありますが、ロケータの情報が正しく保たれるように、一つのイベントの文字データは常に同じ外部エンティティのものでなければなりません。

ContentHandler.processingInstruction(target, data)

処理命令の通知を受け取ります。

パーサは処理命令が見つかるたびにこのメソッドを呼び出します。処理命令はメインのドキュメント要素の前や後にも発生することがあるので注意してください。

SAX パーサがこのメソッドを使って XML 宣言(XML 1.0 のセクション 2.8)やテキスト宣言(XML 1.0 のセクション 4.3.1)の通知をすることはありません。

ContentHandler.skippedEntity(name)

スキップしたエンティティの通知を受け取ります。

パーサはエンティティをスキップするたびにこのメソッドを呼び出します。妥当性検査をしないプロセッサは(外部 DTD サブセットで宣言されているなどの理由で)宣言が見当たらないエンティティをスキップします。すべてのプロセッサは feature_external_ges および feature_external_pes 属性の値によっては外部エンティティをスキップすることがあります。

19.10.2. DTDHandler オブジェクト

DTDHandler インスタンスは以下のメソッドを提供します。

DTDHandler.notationDecl(name, publicId, systemId)

表記法宣言イベントの通知を捕捉します。

DTDHandler.unparsedEntityDecl(name, publicId, systemId, ndata)

未構文解析エンティティ宣言イベントの通知を受け取ります。

19.10.3. EntityResolver オブジェクト

EntityResolver.resolveEntity(publicId, systemId)

エンティティのシステム識別子を解決し、文字列として読み込んだシステム識別子あるいは InputSource オブジェクトのいずれかを返します。デフォルトの実装では systemId を返します。

19.10.4. ErrorHandler オブジェクト

このインターフェースのオブジェクトは XMLReader からのエラーや警告の情報を受け取るために使われます。このインターフェースを実装したオブジェクトを作成し XMLReader に登録すると、パーサは警告やエラーの通知のためにそのオブジェクトのメソッドを呼び出すようになります。エラーには警告、回復可能エラー、回復不能エラーの3段階があります。すべてのメソッドは SAXParseException だけをパラメータとして受け取ります。受け取った例外オブジェクトを raise することで、エラーや警告は例外に変換されることもあります。

ErrorHandler.error(exception)

パーサが回復可能なエラーを検知すると呼び出されます。このメソッドが例外を raise しないとパースは継続されますが、アプリケーション側ではエラー以降のドキュメント情報を期待していないこともあります。パーサが処理を継続した場合、入力ドキュメント内のほかのエラーを見つけることができます。

ErrorHandler.fatalError(exception)

パーサが回復不能なエラーを検知すると呼び出されます。このメソッドが return した後、すぐにパースを停止することが求められています。

ErrorHandler.warning(exception)

パーサが軽微な警告情報をアプリケーションに通知するために呼び出されます。このメソッドが return した後もパースを継続し、ドキュメント情報をアプリケーションに送り続けるよう求められています。このメソッドで例外を発生させた場合、パースは中断されてしまいます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.11. xml.sax.saxutils — SAX ユーティリティ

バージョン 2.0 で追加.

モジュール xml.sax.saxutils には SAX アプリケーションの作成に役立つ多くの関数やクラスも含まれており、直接利用したり、基底クラスとして使うことができます。

xml.sax.saxutils.escape(data[, entities])

文字列データ内の '&', '<', '>' をエスケープします。

オプションの entities パラメータに辞書を渡すことで、そのほかの文字をエスケープさせることも可能です。辞書のキーと値はすべて文字列で、キーに指定された文字は対応する値に置換されます。 '&', '<', '>' は entities が与えられるかどうかに関わらず、常にエスケープします。

xml.sax.saxutils.unescape(data[, entities])

エスケープされた文字列 '&amp;', '&lt;', '&gt;' を元の文字に戻します。

オプションの entities パラメータに辞書を渡すことで、そのほかの文字をエスケープさせることも可能です。辞書のキーと値はすべて文字列で、キーに指定された文字は対応する値に置換されます。 '&amp;', '&lt;', '&gt;' は entities が与えられるかどうかに関わらず、常に元の文字に戻します。

バージョン 2.3 で追加.

xml.sax.saxutils.quoteattr(data[, entities])

escape() に似ていますが、 data は属性値の作成に使われます。戻り値はクォート済みの data で、置換する文字の追加も可能です。 quoteattr() はクォートすべき文字を data の文脈から判断し、クォートすべき文字を残さないように文字列をエンコードします。

data の中にシングル・クォート、ダブル・クォートがあれば、両方ともエンコードし、全体をダブルクォートで囲みます。戻り値の文字列はそのままで属性値として利用できます。:

>>> print "<element attr=%s>" % quoteattr("ab ' cd \" ef")
<element attr="ab ' cd &quot; ef">

この関数は参照具象構文を使って、 HTML や SGML の属性値を生成するのに便利です。

バージョン 2.2 で追加.

class xml.sax.saxutils.XMLGenerator([out[, encoding]])

このクラスは ContentHandler インターフェースの実装で、SAX イベントを XML ドキュメントに書き戻します。つまり、 XMLGenerator をコンテント・ハンドラとして用いると、パースしたオリジナル・ドキュメントの複製が作れるのです。 out に指定するのはファイル風のオブジェクトで、デフォルトは sys.stdout です。 encoding は出力ストリームのエンコーディングで、デフォルトは 'iso-8859-1' です。

class xml.sax.saxutils.XMLFilterBase(base)

このクラスは XMLReader とクライアント・アプリケーションのイベント・ハンドラとの間に位置するものとして設計されています。デフォルトでは何もせず、ただリクエストをリーダに、イベントをハンドラに、それぞれ加工せず渡すだけです。しかし、サブクラスでメソッドをオーバーライドすると、イベント・ストリームやリクエストを加工してから渡すように変更可能です。

xml.sax.saxutils.prepare_input_source(source[, base])

この関数は引き数に入力ソース、オプションとして URL を取り、読み取り可能な解決済み InputSource オブジェクトを返します。入力ソースは文字列、ファイル風オブジェクト、 InputSource のいずれでも良く、この関数を使うことで、パーサは様々な source パラメータを parse() に渡すことが可能になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.12. xml.sax.xmlreader — XML パーサのインタフェース

バージョン 2.0 で追加.

各 SAX パーサは Python モジュールとして XMLReader インタフェースを実装しており、関数 create_parser() を提供しています。この関数は新たなパーサ・オブジェクトを生成する際、 xml.sax.make_parser() から引き数なしで呼び出されます。

class xml.sax.xmlreader.XMLReader

SAX パーサが継承可能な基底クラスです。

class xml.sax.xmlreader.IncrementalParser

入力ソースをパースする際、すべてを一気に処理しないで、途中でドキュメントのチャンクを取得したいことがあります。SAX リーダは通常、ファイル全体を一気に読み込まずチャンク単位で処理するのですが、全体の処理が終わるまで parse() は return しません。つまり、IncrementalParser インタフェースは parse() にこのような排他的挙動を望まないときに使われます。

パーサのインスタンスが作成されると、feed メソッドを通じてすぐに、データを受け入れられるようになります。close メソッドの呼出しでパースが終わると、パーサは新しいデータを受け入れられるように、reset メソッドを呼び出されなければなりません。

これらのメソッドをパース処理の途中で呼び出すことはできません。つまり、パースが実行された後で、パーサから return する前に呼び出す必要があるのです。

なお、SAX 2.0 ドライバを書く人のために、XMLReader インタフェースの parse メソッドがデフォルトで、IncrementalParser の feed、close、reset メソッドを使って実装されています。

class xml.sax.xmlreader.Locator

SAX イベントとドキュメントの位置を関連付けるインタフェースです。locator オブジェクトは DocumentHandler メソッドを呼び出している間だけ正しい情報を返し、それ以外とのときに呼び出すと、予測できない結果が返ります。情報を取得できない場合、メソッドは None を返すこともあります。

class xml.sax.xmlreader.InputSource([systemId])

XMLReader がエンティティを読み込むために必要な情報をカプセル化します。

このクラスには公開識別子、システム識別子、(場合によっては文字エンコーディング情報を含む)バイト・ストリーム、そしてエンティティの文字ストリームなどの情報が含まれます。

アプリケーションは XMLReader.parse() メソッドに渡す引き数、または EntityResolver.resolveEntity の戻り値としてこのオブジェトを作成します。

InputSource はアプリケーション側に属します。 XMLReader はアプリケーションから渡された InputSource オブジェクトの変更を許していませんが、コピーを作り、それを変更することは可能です。

class xml.sax.xmlreader.AttributesImpl(attrs)

Attributes インタフェース ( The Attributes インタフェース 参照)の実装です。辞書風のオブジェクトで、 startElement() 内で要素の属性表示をおこないます。多くの辞書風オブジェクト操作に加え、ほかにもインタフェースに記述されているメソッドを、多数サポートしています。このクラスのオブジェクトはリーダによってインスタンスを作成しなければなりません。また、 attrs は属性名と属性値を含む辞書風オブジェクトでなければなりません。

class xml.sax.xmlreader.AttributesNSImpl(attrs, qnames)

AttributesImpl を名前空間認識型に改良したクラスで、 startElementNS() に渡されます。 AttributesImpl の派生クラスですが、 namespaceURI と localname 、この2つのタプルを解釈します。さらに、元のドキュメントに出てくる修飾名を返す多くのメソッドを提供します。このクラスは AttributesNS インタフェース (AttributesNS インタフェース 参照) の実装です。

19.12.1. XMLReader オブジェクト

XMLReader は次のメソッドをサポートします。:

XMLReader.parse(source)

入力ソースを処理し、SAX イベントを発生させます。 source オブジェクトにはシステム識別子(入力ソースを特定する文字列 – 一般にファイル名やURL)、ファイル風オブジェクト、または InputSource オブジェクトを指定できます。 parse() から return された段階で、入力データの処理は完了、パーサ・オブジェクトは破棄ないしリセットされます。なお、現在の実装はバイト・ストリームのみをサポートしており、文字ストリームの処理は将来の課題になっています。

XMLReader.getContentHandler()

現在の ContentHandler を返します。

XMLReader.setContentHandler(handler)

現在の ContentHandler をセットします。 ContentHandler がセットされていない場合、コンテント・イベントは破棄されます。

XMLReader.getDTDHandler()

現在の DTDHandler を返します。

XMLReader.setDTDHandler(handler)

現在の DTDHandler をセットします。 DTDHandler がセットされていない場合、DTD イベントは破棄されます。

XMLReader.getEntityResolver()

現在の EntityResolver を返します。

XMLReader.setEntityResolver(handler)

現在の EntityResolver をセットします。 EntityResolver がセットされていない場合、外部エンティティとして解決されるべきものが、システム識別子として解釈されてしまうため、該当するものがなければ結果的にエラーとなります。

XMLReader.getErrorHandler()

現在の ErrorHandler を返します。

XMLReader.setErrorHandler(handler)

現在のエラー・ハンドラをセットします。 ErrorHandler がセットされていない場合、エラーは例外を発生し、警告が表示されます。

XMLReader.setLocale(locale)

アプリケーションにエラーや警告のロカール設定を許可します。

SAX パーサにとって、エラーや警告の地域化は必須ではありません。しかし、パーサは要求されたロカールをサポートしていない場合、SAX 例外を発生させなければなりません。アプリケーションはパースの途中でロカールを変更することもできます。

XMLReader.getFeature(featurename)

機能 featurename の現在の設定を返します。その機能が認識できないときは、 SAXNotRecognizedException を発生させます。広く使われている機能名の一覧はモジュール xml.sax.handler に書かれています。

XMLReader.setFeature(featurename, value)

機能名 featurename に値 value をセットします。その機能が認識できないときは、 SAXNotRecognizedException を発生させます。また、パーサが指定された機能や設定をサポートしていないときは、 SAXNotSupportedException を発生させます。

XMLReader.getProperty(propertyname)

属性名 propertyname の現在の値を返します。その属性が認識できないときは、 SAXNotRecognizedException を発生させます。広く使われている属性名の一覧はモジュール xml.sax.handler に書かれています。

XMLReader.setProperty(propertyname, value)

属性名 propertyname に値 value をセットします。その機能が認識できないときは、 SAXNotRecognizedException を発生させます。また、パーサが指定された機能や設定をサポートしていないときは、 SAXNotSupportedException を発生させます。

19.12.2. IncrementalParser オブジェクト

IncrementalParser のインスタンスは次の追加メソッドを提供します。:

IncrementalParser.feed(data)

data のチャンクを処理します。

IncrementalParser.close()

ドキュメントの終わりを決定します。終わりに達した時点でドキュメントが整形式であるかどうかを判別、ハンドラを起動後、パース時に使用した資源を解放します。

IncrementalParser.reset()

このメソッドは close が呼び出された後、次のドキュメントをパース可能にするため、パーサのリセットするのに呼び出されます。close 後、reset を呼び出さずに parse や feed を呼び出した場合の戻り値は未定義です。

19.12.3. Locator オブジェクト

Locator のインスタンスは次のメソッドを提供します。:

Locator.getColumnNumber()

現在のイベントが終了する列番号を返します。

Locator.getLineNumber()

現在のイベントが終了する行番号を返します。

Locator.getPublicId()

現在の文書イベントの公開識別子を返します。

Locator.getSystemId()

現在のイベントのシステム識別子を返します。

19.12.4. InputSource オブジェクト

InputSource.setPublicId(id)

この InputSource の公開識別子をセットします。

InputSource.getPublicId()

この InputSource の公開識別子を返します。

InputSource.setSystemId(id)

この InputSource のシステム識別子をセットします。

InputSource.getSystemId()

この InputSource のシステム識別子を返します。

InputSource.setEncoding(encoding)

この InputSource の文字エンコーディングをセットします。

指定するエンコーディングは XML エンコーディング宣言として定義された文字列でなければなりません(セクション 4.3.3 の XML 勧告を参照)。

InputSource のエンコーディング属性は、 InputSource がたとえ文字ストリームを含んでいたとしても、無視されます。

InputSource.getEncoding()

この InputSource の文字エンコーディングを取得します。

InputSource.setByteStream(bytefile)

この入力ソースのバイトストリーム(Python のファイル風オブジェクトですが、バイト列と文字の相互変換はサポートしません)を設定します。

なお、文字ストリームが指定されてもSAX パーサは無視し、バイト・ストリームを使って指定された URI に接続しようとします。

アプリケーション側でバイト・ストリームの文字エンコーディングを知っている場合は、setEncoding メソッドを使って指定する必要があります。

InputSource.getByteStream()

この入力ソースのバイトストリームを取得します。

getEncoding メソッドは、このバイト・ストリームの文字エンコーディングを返します。認識できないときは None を返します。

InputSource.setCharacterStream(charfile)

この入力ソースの文字ストリームをセットします(ストリームは Python 1.6 の Unicode-wrapped なファイル風オブジェクトで、ユニコード文字列への変換をサポートしていなければなりません)。

なお、文字ストリームが指定されても SAX パーサは無視、システム識別子とみなし、バイト・ストリームを使って URI に接続しようとします。

InputSource.getCharacterStream()

この入力ソースの文字ストリームを取得します。

19.12.5. The Attributes インタフェース

Attributes オブジェクトは copy(), get(), has_key(), items(), keys(), values() などを含む、マッピング・プロトコルの一部を実装したものです。さらに次のメソッドも提供されています。:

Attributes.getLength()

属性の数を返す。

Attributes.getNames()

属性の名前を返す。

Attributes.getType(name)

属性名 name のタイプを返す。通常は 'CDATA'

Attributes.getValue(name)

属性 name の値を返す。

19.12.6. AttributesNS インタフェース

このインタフェースは Attributes インタフェース (The Attributes インタフェース 参照) のサブタイプです。 Attributes インタフェースがサポートしているすべてのメソッドは AttributesNS オブジェクトでも利用可能です。

そのほか、次のメソッドがサポートされています。:

AttributesNS.getValueByQName(name)

修飾名の値を返す。

AttributesNS.getNameByQName(name)

修飾名 name に対応する (namespace, localname) のペアを返す。

AttributesNS.getQNameByName(name)

(namespace, localname) のペアに対応する修飾名を返す。

AttributesNS.getQNames()

すべての属性の修飾名を返す。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

19. 構造化マークアップツール »

19.13. xml.etree.ElementTree — ElementTree XML API

バージョン 2.5 で追加.

Element 型は柔軟性のあるコンテナオブジェクトで、階層的データ構造をメモリーに格納するようにデザインされています。この型は言わばリストと辞書の間の子のようなものです。

各エレメントは関連する多くのプロパティを具えています:

このエレメントがどういう種類のデータを表現しているかを同定する文字列であるタグ(別の言い方をすればエレメントの型)

幾つもの属性(Python 辞書に収められます)

テキスト文字列

オプションの末尾文字列

幾つもの子エレメント(Python シーケンスに収められます)

element のインスタンスを作るには、 Element コンストラクタや SubElement() ファクトリー関数を使います。

ElementTree クラスはエレメントの構造を包み込み、それと XML を行き来するのに使えます。

この API の C 実装である xml.etree.cElementTree も使用可能です。

チュートリアルその他のドキュメントへのリンクについては http://effbot.org/zone/element-index.htm を参照して下さい。 Fredrik Lundh のページも xml.etree.ElementTree の開発バージョンの置き場所です。

バージョン 2.7 で変更: ElementTree API が 1.3 に更新されました。より詳しい情報については、 Introducing ElementTree 1.3 [http://effbot.org/zone/elementtree-13-intro.htm] を参照してください。

19.13.1. 関数

xml.etree.ElementTree.Comment(text=None)

コメント・エレメントのファクトリーです。このファクトリー関数は、標準のシリアライザでは XML コメントにシリアライズされる特別な要素を作ります。コメント文字列は byte 文字列でも Unicode 文字列でも構いません。 text はそのコメント文字列を含んだ文字列です。コメントを表わすエレメントのインスタンスを返します。

xml.etree.ElementTree.dump(elem)

エレメントの木もしくはエレメントの構造を sys.stdout に書き込みます。この関数はデバグ目的でだけ使用してください。

出力される形式の正確なところは実装依存です。このバージョンでは、通常の XML ファイルとして書き込まれます。

elem はエレメントの木もしくは個別のエレメントです。

xml.etree.ElementTree.fromstring(text)

文字列定数で与えられた XML 断片を構文解析します。 XML() 関数と同じです。 text は XML データの文字列です。 Element インスタンスを返します。

xml.etree.ElementTree.fromstringlist(sequence, parser=None)

文字列のシーケンスからXMLドキュメントを解析します。 sequence は XML データのフラグメントを格納した、 list かその他のシーケンスです。 parser はオプションの parser インスタンスです。指定されなかった場合、標準の XMLParser パーサーが利用されます。 Elment インスタンスを返します。

バージョン 2.7 で追加.

xml.etree.ElementTree.iselement(element)

オブジェクトが正当なエレメント・オブジェクトであるかをチェックします。 element はエレメント・インスタンスです。引数がエレメント・オブジェクトならば真値を返します。

xml.etree.ElementTree.iterparse(source, events=None, parser=None)

XML 断片を構文解析してエレメントの木を漸増的に作っていき、その間進行状況をユーザーに報告します。 source は XML データを含むファイル名またはファイル風オブジェクト。 events は報告すべきイベントのリスト。省略された場合は “end” イベントだけが報告されます。 parser はオプションの引数で、パーサーのインスタンスを指定します。指定されなかった場合は標準の XMLParser が利用されます。 (event, elem) ペアのイテレータ(iterator)を返します。

ノート

iterparse() は “start” イベントを送り出すとき開始タグの “>” なる文字を見たことだけを保証しますので、アトリビュートは定義されますが、その時点ではテキストの内容もテール・アトリビュートもまだ定義されていません。同じことは子エレメントにも言えて、その時点ではあるともないとも言えません。

全部が揃ったエレメントが必要ならば、”end” イベントを探すようにして下さい。

xml.etree.ElementTree.parse(source, parser=None)

XML 断片を構文解析して element tree にします。 source は XML データを含むファイル名またはファイル風オブジェクト。 parser はオプションの構文解析器インスタンスです。これが与えられない場合、標準の XMLParser パーサーが使われます。 ElementTree インスタンスを返します。

xml.etree.ElementTree.ProcessingInstruction(target, text=None)

PI エレメントのファクトリー。このファクトリー関数は XML の処理命令(processing instruction) としてシリアライズされる特別なエレメントを作ります。 target は PI ターゲットを含んだ文字列です。 text は与えられるならば PI コンテンツを含んだ文字列です。 PI を表わすエレメント・インスタンスを返します。

xml.etree.ElementTree.register_namespace(prefix, uri)

名前空間の prefix を登録します。レジストリはグローバルで、与えられた prefix か名前空間URI のどちらかの既存のマッピングは全て削除されます。 prefix は名前空間の prefix です。 uri は名前空間のURIです。この名前空間のタグや属性は、可能な限り与えられた prefix をつけてシリアライズされます。

バージョン 2.7 で追加.

xml.etree.ElementTree.SubElement(parent, tag[, attrib[, **extra]])

子エレメントのファクトリー。この関数はエレメント・インスタンスを作り、それを既存のエレメントに追加します。

エレメント名、アトリビュート名およびアトリビュート値は byte 文字列でも Unicode 文字列でも構いません。 parent は親エレメントです。 tag はエレメント名です。 attrib はオプションの辞書で、エレメントのアトリビュートを含んでいます。 extra は追加のアトリビュートで、キーワード引数として与えられたものです。エレメント・インスタンスを返します。

xml.etree.ElementTree.tostring(element, encoding="us-ascii", method="xml")

XML エレメントを全ての子エレメントを含めて表現する文字列を生成します。 element は Element のインスタンスです。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 method は "xml", "html", "text" のいずれか(デフォルトは "xml") です。 XML データを含んだエンコードされた文字列を返します。

xml.etree.ElementTree.tostringlist(element, encoding="us-ascii", method="xml")

XML エレメントを全ての子エレメントを含めて表現する文字列を生成します。 element は Element のインスタンスです。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 method は "xml", "html", "text" のいずれか(デフォルトは "xml") です。 XML データを含んだエンコードされた文字列のリストを返します。これは、 "".join(tostringlist(element)) == tostring(element) であること以外、なにか特定のシーケンスになることは保証していません。

バージョン 2.7 で追加.

xml.etree.ElementTree.XML(text, parser=None)

文字列定数で与えられた XML 断片を構文解析します。この関数は Python コードに「XML リテラル」を埋め込むのに使えます。 text は XML データを含んだ文字列です。 parser はオプションで、パーサーのインスタンスです。指定されなかった場合は、標準の XMLParser パーサーを利用します。 Element のインスタンスを返します。

xml.etree.ElementTree.XMLID(text, parser=None)

文字列定数で与えられた XML 断片を構文解析し、エレメント ID からエレメントへのマッピングを与える辞書も同時に返します。 text は XMLデータを含んだ文字列です。 parser はオプションで、パーサーのインスタンスです。指定されなかった場合は、標準の XMLParser パーサーを利用します。 Element のインスタンスと辞書のタプルを返します。

19.13.2. Element オブジェクト

xml.etree.ElementTree.Element(tag[, attrib][, **extra])

エレメントクラス。この関数は Element インタフェースを定義すると同時に、そのリファレンス実装を提供します。

エレメント名、アトリビュート名およびアトリビュート値は bytes 文字列でも Unicode 文字列でも構いません。 tag はエレメント名です。 attrib はオプションの辞書で、エレメントのアトリビュートを含んでいます。 extra は追加のアトリビュートで、キーワード引数として与えられたものです。エレメント・インスタンスを返します。

xml.etree.ElementTree.tag

このエレメントが表すデータの種類を示す文字列です(言い替えると、エレメントの型です)。

xml.etree.ElementTree.text

text アトリビュートはエレメントに結びつけられた付加的なデータを保持するのに使われます。名前が示唆しているようにこのアトリビュートはたいてい文字列ですが、アプリケーション固有のオブジェクトであって構いません。エレメントが XML ファイルから作られたものならば、このアトリビュートはエレメント・タグの間にあるテキストを丸ごと含みます。

xml.etree.ElementTree.tail

tail アトリビュートはエレメントに結びつけられた付加的なデータを保持するのに使われます。このアトリビュートはたいてい文字列ですが、アプリケーション固有のオブジェクトであって構いません。エレメントが XML ファイルから作られたものならば、このアトリビュートはエレメントの終了タグと次のタグの直前までの間に見つかったテキストを丸ごと含みます。

xml.etree.ElementTree.attrib

エレメントのアトリビュートを保持する辞書です。次のことに注意しましょう。 attrib は普通の書き換え可能な Python の辞書ではあるのですが、 ElementTree の実装によっては別の内部表現を選択して要求されたときにだけ辞書を作るようにするかもしれません。そうした実装の利益を享受するために、可能な限り下記の辞書メソッドを通じて使いましょう。

以下の辞書風メソッドがエレメントのアトリビュートに対して働きます。

xml.etree.ElementTree.clear()

エレメントをリセットします。全ての子孫エレメントを削除し、アトリビュートをクリアし、 test と tail を None にセットします。

xml.etree.ElementTree.get(key, default=None)

エレメントの key という名前のアトリビュートを取得します。

アトリビュートの値、またはアトリビュートがない場合は default を返します。

xml.etree.ElementTree.items()

エレメントのアトリビュートを (名前, 値) ペアのシーケンスとして返します。返されるアトリビュートの順番は決まっていません。

xml.etree.ElementTree.keys()

エレメントのアトリビュート名をリストとして返します。返される名前の順番は決まっていません。

xml.etree.ElementTree.set(key, value)

エレメントのアトリビュート key に value をセットします。

以下のメソッドはエレメントの子(サブエレメント)に対して働きます。

xml.etree.ElementTree.append(subelement)

エレメント subelement をこのエレメントの内部にあるサブエレメントのリストの最後に追加します。

xml.etree.ElementTree.extend(subelements)

シーケンスオブジェクト subelements から 0個以上のサブエレメントを追加します。サブエレメントが有効なオブジェクトでない場合は AssertionError を発生させます。

バージョン 2.7 で追加.

xml.etree.ElementTree.find(match)

match にマッチする最初のサブエレメントを探します。 match はタグ名かパス(path)です。エレメント・インスタンスまたは None を返します。

xml.etree.ElementTree.findall(match)

タグ名かパスにマッチする全てのサブエレメントを探します。全てのマッチするエレメントを、ドキュメント上の順序で含むリストを返します。

xml.etree.ElementTree.findtext(match, default=None)

match にマッチする最初のサブエレメントのテキストを探します。 match はタグ名かパスです。最初にマッチするエレメントの text を返すか、エレメントが見あたらなかった場合 default を返します。マッチしたエレメントに text がなければ空文字列が返されるので気を付けましょう。

xml.etree.ElementTree.getchildren()

バージョン 2.7 で撤廃: list(elem) を使うか、 Element に対してイテレートしてください。

xml.etree.ElementTree.getiterator(tag=None)

バージョン 2.7 で撤廃: Element.iter() メソッドを使ってください。

xml.etree.ElementTree.insert(index, element)

サブエレメントをこのエレメントの与えられた位置に挿入します。

xml.etree.ElementTree.iter(tag=None)

現在のエレメントを根とするツリーのイテレータ(iterator)を作ります。イテレータは現在のエレメントとそれ以下の全てのエレメントを、文書中での出現順(深さ優先順)でイテレートします。 tag が None または '*' でない場合は、与えられたタグに等しいものについてのみイテレータから返されます。イテレート中にツリー構造が変更された場合の結果は未定義です。

xml.etree.ElementTree.iterfind(match)

タグ名かパスにマッチする全てのサブエレメントを探します。全てのマッチするエレメントをドキュメント上の順序で yield するイテレート可能オブジェクトを返します。

バージョン 2.7 で追加.

xml.etree.ElementTree.itertext()

text のイテレータを作成します。このイテレータは、このエレメントと全てのサブエレメントをドキュメント上の順序で巡回し、全ての内部の text を返します。

バージョン 2.7 で追加.

xml.etree.ElementTree.makeelement(tag, attrib)

現在のエレメントと同じ型の新しいエレメント・オブジェクトを作ります。このメソッドは呼び出さずに、 SubElement() ファクトリー関数を使って下さい。

xml.etree.ElementTree.remove(subelement)

現在のエレメントから subelement を削除します。 find* メソッド群と違ってこのメソッドはエレメントをインスタンスの同一性で比較します。タグや内容では比較しません。

Element オブジェクトは以下のシーケンス型のメソッドを、サブエレメントを操作するためにサポートします: __delitem__(), __getitem__(), __setitem__(), __len__().

注意: サブエレメントを持たないエレメントの真偽値は False になります。この挙動は将来のバージョンで変更されるかもしれません。直接真偽値をテストするのでなく、 len(elem) か elem is None を利用してください。

element = root.find('foo')

if not element:  # careful!
    print "element not found, or element has no subelements"

if element is None:
    print "element not found"

19.13.3. ElementTree オブジェクト

class xml.etree.ElementTree.ElementTree(element=None, file=None)

ElementTree ラッパー・クラス。このクラスはエレメントの全階層を表現し、さらに標準 XML との相互変換を追加しています。

element は根エレメントです。木はもし file が与えられればその XML の内容により初期化されます。

_setroot(element)

この木の根エレメントを置き換えます。したがって現在の木の内容は破棄され、与えられたエレメントが代わりに使われます。注意して使ってください。 element はエレメント・インスタンスです。

find(match)

match にマッチする最初のトップレベルのエレメントを探します。 match はタグ名かパスです。 getroot().find(path) と同じです。最初に条件に合ったエレメント、または見つからない時は None を返します。

findall(match)

タグ名かパスにマッチする全てのサブエレメントを探します。 getroot().findall(match) と同じです。 match はタグ名かパスです。条件に合った全てのエレメントを、ドキュメント上の順序で格納したリストを返します。

findtext(match, default=None)

子孫エレメントの中で与えられたタグを持つ最初のもののテキストを見つけます。 getroot().findtext(match) と同じです。 match はタグ名かパスです。 default はエレメントが見つからなかった場合に返される値です。条件に合った最初のエレメントのテキスト、または見つからなかった場合にはデフォルト値を返します。もしエレメントが見つかったもののテキストがなかった場合には、このメソッドは空文字列を返すということに気をつけてください。

getiterator(tag=None)

バージョン 2.7 で撤廃: 代わりに ElementTree.iter() メソッドを利用してください。

getroot()

この木の根エレメントを返します。

iter(tag=None)

ルートエレメントに対する、ツリーを巡回するイテレータを返します。イテレータはツリーの全てのエレメントに渡ってセクション順にループします。 tag は探したいタグです(デフォルトでは全てのエレメントを返します)。

iterfind(match)

タグ名かパスにマッチする全てのサブエレメントを返します。 getroot().iterfind(match) と同じです。全てのマッチするエレメントをドキュメント順に yield するイテレート可能オブジェクトを返します。

バージョン 2.7 で追加.

parse(source, parser=None)

外部の XML 断片をこのエレメントの木に読み込みます。 source は XML データを含むファイル名またはファイル風オブジェクト。 parser はオプションの構文解析器インスタンスです。これが与えられない場合、標準の XMLParser パーサーが使われます。断片の根エレメントを返します。

write(file, encoding="us-ascii", xml_declaration=None, method="xml")

エレメントの木をファイルに XML として書き込みます。 file はファイル名またはファイル風オブジェクトで書き込み用に開かれたもの。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 xml_declaration は、 XML 宣言がファイルに書かれるかどうかを制御します。 False の場合は常に書かれず、 True の場合は常に書かれ、 None の場合は US-ASCII か UTF-8 以外の場合に書かれます (デフォルトは None です)。 method は "xml", "html", "text" のいづれかです (デフォルトは "xml" です)。エンコードされた文字列を返します。

次に示すのがこれから操作する XML ファイルです:

<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>Moved to <a href="http://example.org/">example.org</a>
        or <a href="http://example.com/">example.com</a>.</p>
    </body>
</html>

第1段落の全てのリンクの “target” アトリビュートを変更する例:

>>> from xml.etree.ElementTree import ElementTree
>>> tree = ElementTree()
>>> tree.parse("index.xhtml")
<Element 'html' at 0xb77e6fac>
>>> p = tree.find("body/p")     # Finds first occurrence of tag p in body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a"))   # Returns list of all links
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links:             # Iterates through all found links
...     i.attrib["target"] = "blank"
>>> tree.write("output.xhtml")

19.13.4. QName オブジェクト

class xml.etree.ElementTree.QName(text_or_uri, tag=None)

QName ラッパー。このクラスは QName アトリビュート値をラップし、出力時に真っ当な名前空間の扱いを得るために使われます。 text_or_uri は {uri}local という形式の QName 値を含む文字列、または tag 引数が与えられた場合には QName の URI 部分の文字列です。 tag が与えられた場合、一つめの引数は URI と解釈され、この引数はローカル名と解釈されます。 QName インスタンスは不透明です。

19.13.5. TreeBuilder オブジェクト

class xml.etree.ElementTree.TreeBuilder(element_factory=None)

汎用のエレメント構造ビルダー。これは start, data, end のメソッド呼び出しの列を整形式のエレメント構造に変換します。このクラスを使うと、好みの XML 構文解析器、または他の XML に似た形式の構文解析器を使って、エレメント構造を作り出すことができます。 element_factory が与えられた場合には、新しい Element インスタンスを作る際にこれを呼び出します。

close()

ビルダーのバッファをフラッシュし、最上位の文書エレメントを返します。 Element インスタンスを返します。

data(data)

現在のエレメントにテキストを追加します。 data は文字列です。 bytes 文字列もしくは Unicode 文字列でなければなりません。

end(tag)

現在のエレメントを閉じます。 tag はエレメントの名前です。閉じられたエレメントを返します。

start(tag, attrs)

新しいエレメントを開きます。 tag はエレメントの名前です。 attrs はエレメントのアトリビュートを保持した辞書です。開かれたエレメントを返します。

加えて、カスタムの TreeBuilder オブジェクトは以下のメソッドを提供できます。

doctype(name, pubid, system)

doctype 宣言を処理します。 name は doctype 名です。 pubid は公式の識別子です。 system はシステム識別子です。このメソッドはデフォルトの TreeBuilder クラスには存在しません。

バージョン 2.7 で追加.

19.13.6. XMLParser オブジェクト

XML ソースからエレメント構造を作るもので、expat 構文解析器に基づいています。 html は前もって定義された HTML エンティティです。このオプションは現在の実装ではサポートされていません。 target はターゲットとなるオブジェクトです。省略された場合、標準の TreeBuilder クラスのインスタンスが使われます。

class xml.etree.ElementTree.XMLParser(html=0, target=None, encoding=None)

expat パーサーを利用した、XML ソースデータからの Element 構造ビルダー。 html は定義済みの HTML エンティティです。このフラグは現在の実装ではサポートされていません。 target はターゲットオブジェクトです。省略された場合、ビルダーは標準の TreeBuilder クラスのインスタンスを利用します。 encoding [1] はオプションで、与えられた場合は XML ファイルで指定されたエンコーディングをオーバーライドします。

close()

構文解析器にデータを供給するのを終わりにします。エレメント構造を返します。

doctype(name, pubid, system)

バージョン 2.7 で撤廃: カスタムの TreeBuilder target で TreeBuilder.doctype() メソッドを定義してください。

feed(data)

構文解析器にデータを供給します。 data はエンコードされたデータです。

XMLParser.feed() は target の start() メソッドをそれぞれの開始タグに対して呼び、また end() メソッドを終了タグに対して呼び、そしてデータは data() メソッドで処理されます。 XMLParser.close() は target の close() メソッドを呼びます。 XMLParser は木構造を構築する以外にも使えます。以下の例は、XML ファイルの最高の深さを数えます:

>>> from xml.etree.ElementTree import XMLParser
>>> class MaxDepth:                     # The target object of the parser
...     maxDepth = 0
...     depth = 0
...     def start(self, tag, attrib):   # Called for each opening tag.
...         self.depth += 1
...         if self.depth > self.maxDepth:
...             self.maxDepth = self.depth
...     def end(self, tag):             # Called for each closing tag.
...         self.depth -= 1
...     def data(self, data):
...         pass            # We do not need to do anything with data.
...     def close(self):    # Called when all data has been parsed.
...         return self.maxDepth
...
>>> target = MaxDepth()
>>> parser = XMLParser(target=target)
>>> exampleXml = """
... <a>
...   <b>
...   </b>
...   <b>
...     <c>
...       <d>
...       </d>
...     </c>
...   </b>
... </a>"""
>>> parser.feed(exampleXml)
>>> parser.close()
4

注記

[1]
XML の出力に含まれるエンコーディング文字列は適切な標準に適合していなければなりません。たとえば、”UTF-8” は正当ですが、”UTF8” は違います。 http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl と http://www.iana.org/assignments/character-sets を参照して下さい。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援

この章で記述されるモジュールは、インターネットプロトコルを実装し、関連技術の支援を行います。それらは全てPythonで実装されています。これらのモジュールの大部分は、システム依存のモジュール socket が存在することが必要ですが、これは現在ではほとんどの一般的なプラットフォーム上でサポートされています。ここに概観を示します。

20.1. webbrowser — 便利なウェブブラウザコントローラー

20.1.1. ブラウザコントローラーオブジェクト

20.2. cgi — CGI (ゲートウェイインタフェース規格) のサポート

20.2.1. はじめに

20.2.2. cgi モジュールを使う

20.2.3. 高水準インタフェース

20.2.4. 古いクラス群

20.2.5. 関数

20.2.6. セキュリティへの配慮

20.2.7. CGI スクリプトを Unix システムにインストールする

20.2.8. CGI スクリプトをテストする

20.2.9. CGI スクリプトをデバッグする

20.2.10. よくある問題と解決法

20.3. cgitb — CGI スクリプトのトレースバック管理機構

20.4. wsgiref — WSGI ユーティリティとリファレンス実装

20.4.1. wsgiref.util – WSGI 環境のユーティリティ

20.4.2. wsgiref.headers – WSGI レスポンスヘッダツール群

20.4.3. wsgiref.simple_server – シンプルな WSGI HTTP サーバ

20.4.4. wsgiref.validate — WSGI 準拠チェッカー

20.4.5. wsgiref.handlers – サーバ／ゲートウェイのベースクラス

20.4.6. 例

20.5. urllib — URL による任意のリソースへのアクセス

20.5.1. 高レベルインタフェース

20.5.2. ユーティリティー関数

20.5.3. URL Opener オブジェクト

20.5.4. urllib の制限

20.5.5. 使用例

20.6. urllib2 — URL を開くための拡張可能なライブラリ

20.6.1. Request オブジェクト

20.6.2. OpenerDirector オブジェクト

20.6.3. BaseHandler オブジェクト

20.6.4. HTTPRedirectHandler オブジェクト

20.6.5. HTTPCookieProcessor オブジェクト

20.6.6. ProxyHandler オブジェクト

20.6.7. HTTPPasswordMgr オブジェクト

20.6.8. AbstractBasicAuthHandler オブジェクト

20.6.9. HTTPBasicAuthHandler オブジェクト

20.6.10. ProxyBasicAuthHandler オブジェクト

20.6.11. AbstractDigestAuthHandler オブジェクト

20.6.12. HTTPDigestAuthHandler オブジェクト

20.6.13. ProxyDigestAuthHandler オブジェクト

20.6.14. HTTPHandler オブジェクト

20.6.15. HTTPSHandler オブジェクト

20.6.16. FileHandler オブジェクト

20.6.17. FTPHandler オブジェクト

20.6.18. CacheFTPHandler オブジェクト

20.6.19. UnknownHandler オブジェクト

20.6.20. HTTPErrorProcessor オブジェクト

20.6.21. 例

20.7. httplib — HTTP プロトコルクライアント

20.7.1. HTTPConnection オブジェクト

20.7.2. HTTPResponse オブジェクト

20.7.3. 例

20.8. ftplib — FTPプロトコルクライアント

20.8.1. FTP オブジェクト

20.8.2. FTP_TLS オブジェクト

20.9. poplib — POP3 プロトコルクライアント

20.9.1. POP3 オブジェクト

20.9.2. POP3 の例

20.10. imaplib — IMAP4 プロトコルクライアント

20.10.1. IMAP4 オブジェクト

20.10.2. IMAP4 の使用例

20.11. nntplib — NNTP プロトコルクライアント

20.11.1. NNTP オブジェクト

20.12. smtplib — SMTP プロトコルクライアント

20.12.1. SMTP オブジェクト

20.12.2. SMTP 使用例

20.13. smtpd — SMTP サーバー

20.13.1. SMTPServer オブジェクト

20.13.2. DebuggingServer オブジェクト

20.13.3. PureProxy オブジェクト

20.13.4. MailmanProxy Objects

20.14. telnetlib — Telnet クライアント

20.14.1. Telnet オブジェクト

20.14.2. Telnet Example

20.15. uuid — RFC 4122 に準拠した UUID オブジェクト

20.15.1. 例

20.16. urlparse — URL を解析して構成要素にする

20.16.1. urlparse() および urlsplit() の結果

20.17. SocketServer — ネットワークサーバ構築のためのフレームワーク

20.17.1. サーバ生成に関するノート

20.17.2. Serverオブジェクト

20.17.3. RequestHandlerオブジェクト

20.17.4. 例

20.17.4.1. SocketServer.TCPServer の例

20.17.4.2. SocketServer.UDPServer の例

20.17.4.3. 平行処理の Mix-in

20.18. BaseHTTPServer — 基本的な機能を持つ HTTP サーバ

20.18.1. 他の例

20.19. SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ

20.20. CGIHTTPServer — CGI 実行機能付き HTTP リクエスト処理機構

20.21. cookielib — HTTP クライアント用の Cookie 処理

20.21.1. CookieJar および FileCookieJar オブジェクト

20.21.2. FileCookieJar のサブクラスと web ブラウザとの連携

20.21.3. CookiePolicy オブジェクト

20.21.4. DefaultCookiePolicy オブジェクト

20.21.5. Cookie オブジェクト

20.21.6. 使用例

20.22. Cookie — HTTPの状態管理

20.22.1. Cookieオブジェクト

20.22.2. Morselオブジェクト

20.22.3. 例

20.23. xmlrpclib — XML-RPC クライアントアクセス

20.23.1. ServerProxy オブジェクト

20.23.2. Boolean オブジェクト

20.23.3. DateTime オブジェクト

20.23.4. Binary オブジェクト

20.23.5. Fault オブジェクト

20.23.6. ProtocolError オブジェクト

20.23.7. MultiCall オブジェクト

20.23.8. 補助関数

20.23.9. クライアントのサンプル

20.23.10. クライアントとサーバーの利用例

20.24. SimpleXMLRPCServer — 基本的なXML-RPCサーバー

20.24.1. SimpleXMLRPCServer オブジェクト

20.24.1.1. SimpleXMLRPCServer の例

20.24.2. CGIXMLRPCRequestHandler

20.25. DocXMLRPCServer — セルフ-ドキュメンティング XML-RPC サーバ

20.25.1. DocXMLRPCServer オブジェクト

20.25.2. DocCGIXMLRPCRequestHandler

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.1. webbrowser — 便利なウェブブラウザコントローラー

webbrowser モジュールにはウェブベースのドキュメントを表示するための、とてもハイレベルなインターフェースが定義されています。たいていの環境では、このモジュールの open() を呼び出すだけで正しく動作します。

Unixでは、X11上でグラフィカルなブラウザが選択されますが、グラフィカルなブラウザが利用できなかったり、X11が利用できない場合はテキストモードのブラウザが使われます。もしテキストモードのブラウザが使われたら、ユーザがブラウザから抜け出すまでプロセスの呼び出しはブロックされます。

環境変数 BROWSER が存在するならプラットフォームのデフォルトであるブラウザのリストをオーバーライドし、 os.pathsep で区切られたリストの順にブラウザの起動を試みます。リストの中の値に %s が含まれていたら、テキストモードのブラウザのコマンドラインとして %s の代わりにURLが引数として解釈されます；もし %s が含まれなければ、起動するブラウザの名前として単純に解釈されます。 [1]

非UnixプラットフォームあるいはUnix上でリモートブラウザが利用可能な場合、制御プロセスはユーザがブラウザを終了するのを待ちませんが、ディスプレイにブラウザのウィンドウを表示させたままにします。Unix上でリモートブラウザが利用可能でない場合、制御プロセスは新しいブラウザを立ち上げ、待ちます。

webbrowser スクリプトをこのモジュールのコマンドラインインタフェースとして使うことができます。スクリプトは引数に一つの URL を受け付けます。また次のオプション引数を受け付けます。 -n により可能ならば新しいブラウザウィンドウで指定された URL を開きます。一方、 -t では新しいブラウザのページ(「タブ」) で開きます。当然ながらこれらのオプションは排他的です。

以下の例外が定義されています:

exception webbrowser.Error

ブラウザのコントロールエラーが起こると発生する例外。

以下の関数が定義されています:

webbrowser.open(url[, new=0[, autoraise=True]])

デフォルトのブラウザで url を表示します。 new が 0 なら、 url はブラウザの今までと同じウィンドウで開きます。 new が 1 なら、可能であればブラウザの新しいウィンドウが開きます。 new が 2 なら、可能であればブラウザの新しいタブが開きます。 autoraise が True なら、可能であればウィンドウが前面に表示されます（多くのウィンドウマネージャではこの変数の設定に関わらず、前面に表示されます）。

幾つかのプラットフォームにおいて、ファイル名をこの関数で開こうとすると、 OSによって関連付けられたプログラムが起動されます。しかし、この動作はポータブルではありませんし、サポートされていません。

バージョン 2.5 で変更: new を 2 にもできるようになりました.

webbrowser.open_new(url)

可能であれば、デフォルトブラウザの新しいウィンドウで url を開きますが、そうでない場合はブラウザのただ１つのウィンドウで url を開きます。

webbrowser.open_new_tab(url)

可能であれば、デフォルトブラウザの新しいページ(「タブ」)で url を開きますが、そうでない場合は open_new() と同様に振る舞います。

バージョン 2.5 で追加.

webbrowser.get([name])

ブラウザの種類 name のコントローラーオブジェクトを返します。もし name が空文字列なら、呼び出した環境に適したデフォルトブラウザのコントローラーを返します。

webbrowser.register(name, constructor[, instance])

ブラウザの種類 name を登録します。ブラウザの種類が登録されたら、 get() でそのブラウザのコントローラーを呼び出すことができます。 instance が指定されなかったり、 None なら、インスタンスが必要な時には constructor がパラメータなしに呼び出されて作られます。 instance が指定されたら、 constructor は呼び出されないので、 None でかまいません。

この登録は、変数 BROWSER を設定するか、 get() を空文字列でなく、宣言したハンドラの名前と一致する引数とともに呼び出すときだけ、役に立ちます。

いくつかの種類のブラウザがあらかじめ定義されています。このモジュールで定義されている、関数 get() に与えるブラウザの名前と、それぞれのコントローラークラスのインスタンスを以下の表に示します。

Type Name | Class Name | Notes
'mozilla' | Mozilla('mozilla') |
'firefox' | Mozilla('mozilla') |
'netscape' | Mozilla('netscape') |
'galeon' | Galeon('galeon') |
'epiphany' | Galeon('epiphany') |
'skipstone' | BackgroundBrowser('skipstone') |
'kfmclient' | Konqueror() | (1)
'konqueror' | Konqueror() | (1)
'kfm' | Konqueror() | (1)
'mosaic' | BackgroundBrowser('mosaic') |
'opera' | Opera() |
'grail' | Grail() |
'links' | GenericBrowser('links') |
'elinks' | Elinks('elinks') |
'lynx' | GenericBrowser('lynx') |
'w3m' | GenericBrowser('w3m') |
'windows-default' | WindowsDefault | (2)
'internet-config' | InternetConfig | (3)
'macosx' | MacOSX('default') | (4)

Notes:

“Konqueror”はUnixのKDEデスクトップ環境のファイルマネージャで、KDEが動作している時にだけ意味を持ちます。何か信頼できる方法でKDEを検出するのがいいでしょう；変数 KDEDIR では十分ではありません。また、KDE 2で konqueror コマンドを使うときにも、”kfm”が使われます — Konquerorを動作させるのに最も良い方法が実装によって選択されます。

Windowsプラットフォームのみ。

Mac OSプラットフォームのみ；標準MacPythonモジュール ic を必要とします。

Mac OS X プラットフォームのみ。

簡単な例を示します。

url = 'http://www.python.org/'

# Open URL in a new tab, if a browser window is already open.
webbrowser.open_new_tab(url + 'doc/')

# Open URL in new window, raising the window if possible.
webbrowser.open_new(url)

20.1.1. ブラウザコントローラーオブジェクト

ブラウザコントローラーには以下のメソッドが定義されていて、モジュールレベルの便利な 3 つの関数に相当します:

controller.open(url[, new=0[, autoraise=True]])

このコントローラーでハンドルされたブラウザで url を表示します。 new が 1 なら、可能であればブラウザの新しいウィンドウが開きます。 new が 2 なら、可能であればブラウザの新しいページ(「タブ」)が開きます。

controller.open_new(url)

可能であれば、このコントローラーでハンドルされたブラウザの新しいウィンドウで url を開きますが、そうでない場合はブラウザのただ１つのウィンドウで url を開きます。 open_new() の別名。

controller.open_new_tab(url)

可能であれば、このコントローラーでハンドルされたブラウザの新しいページ(「タブ」)で url を開きますが、そうでない場合は open_new() と同じです。

バージョン 2.5 で追加.

注記

[1]
ここでブラウザの名前が絶対パスで書かれていない場合は PATH 環境変数で与えられたディレクトリから探し出されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.2. cgi — CGI (ゲートウェイインタフェース規格) のサポート

ゲートウェイインタフェース規格 (CGI) に準拠したスクリプトをサポートするためのモジュールです。

このモジュールでは、 Python で CGI スクリプトを書く際に使える様々なユーティリティを定義しています。

20.2.1. はじめに

CGI スクリプトは、HTTP サーバによって起動され、通常は HTML の <FORM> または <ISINDEX> エレメントを通じてユーザが入力した内容を処理します。

ほとんどの場合、CGI スクリプトはサーバ上の特殊なディレクトリ cgi-bin の下に置きます。HTTP サーバは、まずスクリプトを駆動するためのシェルの環境変数に、リクエストの全ての情報 (クライアントのホスト名、リクエストされている URL、クエリ文字列、その他諸々) を設定し、スクリプトを実行した後、スクリプトの出力をクライアントに送信します。

スクリプトの入力端もクライアントに接続されていて、この経路を通じてフォームデータを読み込むこともあります。それ以外の場合には、フォームデータは URL の一部分である「クエリ文字列」を介して渡されます。このモジュールでは、上記のケースの違いに注意しつつ、 Python スクリプトに対しては単純なインタフェースを提供しています。このモジュールではまた、スクリプトをデバッグするためのユーティリティも多数提供しています。また、最近はフォームを経由したファイルのアップロードをサポートしています (ブラウザ側がサポートしていればです)。

CGI スクリプトの出力は 2 つのセクションからなり、空行で分割されています。最初のセクションは複数のヘッダからなり、後続するデータがどのようなものかをクライアントに通知します。最小のヘッダセクションを生成するための Python のコードは以下のようなものです:

print "Content-Type: text/html"     # 以降のデータが HTML であることを示す行
print                               # ヘッダ部の終了を示す空行

二つ目のセクションは通常、ヘッダやインラインイメージ等の付属したテキストをうまくフォーマットして表示できるようにした HTML です。以下に単純な HTML を出力する Python コードを示します:

print "<TITLE>CGI script output</TITLE>"
print "<H1>This is my first CGI script</H1>"
print "Hello, world!"

20.2.2. cgi モジュールを使う

先頭には import cgi と書いてください。 from cgi import * と書いてはなりません — このモジュールでは、以前のバージョンとの互換性を持たせるため、内部で呼び出す名前を多数定義しており、それらをユーザの名前空間に存在させる必要はないからです。

新たにスクリプトを書く際には、以下の行を付加するかどうか検討してください:

import cgitb
cgitb.enable()

これによって、特別な例外処理が有効にされ、エラーが発生した際にブラウザ上に詳細なレポートを出力するようになります。ユーザにスクリプトの内部を見せたくないのなら、以下のようにしてレポートをファイルに保存できます:

import cgitb
cgitb.enable(display=0, logdir="/tmp")

スクリプトを開発する際には、この機能はとても役に立ちます。 cgitb が生成する報告はバグを追跡するためにかかる時間を大幅に減らせるような情報を提供してくれます。スクリプトをテストし終わり、正確に動作することを確認したら、いつでも cgitb の行を削除できます。

入力されたフォームデータを取得するには、 FieldStorage クラスを使うのが最良の方法です。このモジュールで定義されている他のクラスのほとんどは以前のバージョンとの互換性のためのものです。インスタンス生成は引数なしで必ず 1 度だけ行います。これにより、標準入力または環境変数からフォームの内容を読み出します (どちらから読み出すかは、複数の環境変数の値が CGI 標準に従ってどう設定されているかで決まります)。インスタンスが標準入力を使うかもしれないので、インスタンス生成を行うのは一度だけにしなければなりません。

FieldStorage のインスタンスは Python の辞書のようにインデクスを使って参照できます。 in 演算子を使って包含検査でき、辞書の標準メソッド keys() や組み込み関数 len() もサポートしています。空の文字列を含むフォームのフィールドは無視され、辞書には入りません; そういった値を保持するには、 FieldStorage のインスタンスを生成する時にオプションの keep_blank_values キーワード引数を true に設定してください。

例えば、以下のコード (Content-Type ヘッダと空行はすでに出力された後とします) は name および addr フィールドが両方とも空の文字列に設定されていないか調べます:

form = cgi.FieldStorage()
if "name" not in form or "addr" not in form:
    print "<H1>Error</H1>"
    print "Please fill in the name and addr fields."
    return
print "<p>name:", form["name"].value
print "<p>addr:", form["addr"].value
...further form processing here...

ここで、 form[key] で参照される各フィールドはそれ自体が FieldStorage (または MiniFieldStorage 。フォームのエンコードによって変わります) のインスタンスです。インスタンスの属性 value の内容は対応するフィールドの値で、文字列になります。 getvalue() メソッドはこの文字列値を直接返します。 getvalue() の 2 つめの引数にオプションの値を与えると、リクエストされたキーが存在しない場合に返すデフォルトの値になります。

入力されたフォームデータに同じ名前のフィールドが二つ以上あれば、 form[key] で得られるオブジェクトは FieldStorage や MiniFieldStorage のインスタンスではなく、そうしたインスタンスのリストになります。この場合、 form.getvalue(key) も同様に、文字列からなるリストを返します。もしこうした状況が起きうると思うなら (HTML のフォームに同じ名前をもったフィールドが複数含まれているのなら) 、組み込み関数 isinstance() を使って、返された値が単一のインスタンスかインスタンスのリストかどうか調べてください。例えば、以下のコードは任意の数のユーザ名フィールドを結合し、コンマで分割された文字列にします:

value = form.getvalue("username", "")
if isinstance(value, list):
    # Multiple username fields specified
    usernames = ",".join(value)
else:
    # Single or no username field specified
    usernames = value

フィールドがアップロードされたファイルを表している場合、 value 属性や getvalue() メソッドを使ってフィールドの値にアクセスすると、ファイルの内容を全て文字列としてメモリ上に読み込んでしまいます。これは望ましくない機能かもしれません。アップロードされたファイルがあるかどうかは filename 属性および file 属性のいずれかで調べられます。その後、以下のようにして file 属性から落ち着いてデータを読み出せます:

fileitem = form["userfile"]
if fileitem.file:
    # It's an uploaded file; count lines
    linecount = 0
    while 1:
        line = fileitem.file.readline()
        if not line: break
        linecount = linecount + 1

アップロードされたファイルの内容を取得している間にエラーが発生した場合 (例えば、ユーザーがバックやキャンセルボタンで submit を中断した場合)、そのフィールドのオブジェクトの done 属性には -1 が設定されます。

現在ドラフトとなっているファイルアップロードの標準仕様では、一つのフィールドから (再帰的な multipart/* エンコーディングを使って) 複数のファイルがアップロードされる可能性を受け入れています。この場合、アイテムは辞書形式の FieldStorage アイテムとなります。複数ファイルかどうかは type 属性が multipart/form-data (または multipart/* にマッチする他の MIME 型) になっているかどうかを調べれば判別できます。この場合、トップレベルのフォームオブジェクトと同様にして再帰的に個別処理できます。

フォームが「古い」形式で入力された場合 (クエリ文字列または単一の application/x-www-form-urlencoded データで入力された場合)、データ要素の実体は MiniFieldStorage クラスのインスタンスになります。この場合、 list 、 file 、および filename 属性は常に None になります。

フォームがPOSTによって送信され、クエリー文字列も持っていた場合、 FieldStorage と MiniFieldStorage の両方が含まれます。

20.2.3. 高水準インタフェース

バージョン 2.2 で追加.

前節では CGI フォームデータを FieldStorage クラスを使って読み出す方法について解説しました。この節では、フォームデータを分かりやすく直感的な方法で読み出せるようにするために追加された、より高水準のインタフェースについて記述します。このインタフェースは前節で説明した技術を撤廃するものではありません — 例えば、前節の技術は依然としてファイルのアップロードを効率的に行う上で便利です。

このインタフェースは 2 つの単純なメソッドからなります。このメソッドを使えば、一般的な方法でフォームデータを処理でき、ある名前のフィールドに入力された値が一つなのかそれ以上なのかを心配する必要がなくなります。

前節では、一つのフィールド名に対して二つ以上の値が入力されるかもしれない場合には、常に以下のようなコードを書くよう学びました:

item = form.getvalue("item")
if isinstance(item, list):
    # The user is requesting more than one item.
else:
    # The user is requesting only one item.

こういった状況は、例えば以下のように、同じ名前を持った複数のチェックボックスからなるグループがフォームに入っているような場合によく起きます:

<input type="checkbox" name="item" value="1" />
<input type="checkbox" name="item" value="2" />

しかしながら、ほとんどの場合、あるフォーム中で特定の名前を持ったコントロールはただ一つしかないので、その名前に関連付けられた値はただ一つしかないはずだと考えるでしょう。そこで、スクリプトには例えば以下のようなコードを書くでしょう:

user = form.getvalue("user").upper()

このコードの問題点は、クライアント側がスクリプトにとって常に有効な入力を提供するとは期待できないところにあります。例えば、もし好奇心旺盛なユーザがもう一つの user=foo ペアをクエリ文字列に追加したら、 getvalue('user') メソッドは文字列ではなくリストを返すため、このスクリプトはクラッシュするでしょう。リストに対して upper() メソッドを呼び出すと、引数が有効でない (リスト型はその名前のメソッドを持っていない) ため、例外 AttributeError を送出します。

従って、フォームデータの値を読み出しには、得られた値が単一の値なのか値のリストなのかを常に調べるコードを使うのが適切でした。これでは煩わしく、より読みにくいスクリプトになってしまいます。

ここで述べる高水準のインタフェースで提供している getfirst() や getlist() メソッドを使うと、もっと便利にアプローチできます。

FieldStorage.getfirst(name[, default])

フォームフィールド name に関連付けられた値をつねに一つだけ返す軽量メソッドです。同じ名前で 1 つ以上の値がポストされている場合、このメソッドは最初の値だけを返します。フォームから値を受信する際の値の並び順はブラウザ間で異なる可能性があり、特定の順番であるとは期待できないので注意してください。 [1]

指定したフォームフィールドや値がない場合、このメソッドはオプションの引数 default を返します。このパラメタを指定しない場合、標準の値は None に設定されます。

FieldStorage.getlist(name)

このメソッドはフォームフィールド name に関連付けられた値を常にリストにして返します。 name に指定したフォームフィールドや値が存在しない場合、このメソッドは空のリストを返します。値が一つだけ存在する場合、要素を一つだけ含むリストを返します。

これらのメソッドを使うことで、以下のようにナイスでコンパクトにコードを書けます:

import cgi
form = cgi.FieldStorage()
user = form.getfirst("user", "").upper()    # This way it's safe.
for item in form.getlist("item"):
    do_something(item)

20.2.4. 古いクラス群

バージョン 2.6 で撤廃: これらのクラスは、 cgi モジュールの以前のバージョンに入っており、以前のバージョンとの互換性のために現在もサポートされています。新しいアプリケーションでは FieldStorage クラスを使うべきです。

SvFormContentDict は単一の値しか持たないフォームデータの内容を辞書として記憶します; このクラスでは、各フィールド名はフォーム中に一度しか現れないと仮定しています。

FormContentDict は複数の値を持つフォームデータの内容を辞書として記憶します (フォーム要素は値のリストです); フォームが同じ名前を持ったフィールドを複数含む場合に便利です。

他のクラス (FormContent 、 InterpFormContentDict) は非常に古いアプリケーションとの後方互換性のために存在します。

20.2.5. 関数

より細かく CGI をコントロールしたり、このモジュールで実装されているアルゴリズムを他の状況で利用したい場合には、以下の関数が便利です。

cgi.parse(fp[, keep_blank_values[, strict_parsing]])

環境変数、またはファイルからからクエリを解釈します (ファイルは標準で sys.stdin になります) keep_blank_values および strict_parsing パラメタはそのまま urlparse.parse_qs() に渡されます。

cgi.parse_qs(qs[, keep_blank_values[, strict_parsing]])

この関数はこのモジュールでは廃止予定です。代わりに urlparse.parse_qs() を利用してください。この関数は後方互換性のためだけに残されています。

cgi.parse_qsl(qs[, keep_blank_values[, strict_parsing]])

この関数はこのモジュールでは廃止予定です。代わりに urlparse.parse_qsl() を利用してください。この関数は後方互換性のためだけに残されています。

cgi.parse_multipart(fp, pdict)

(ファイル入力のための) multipart/form-data 型の入力を解釈します。引数は入力ファイルを示す fp と Content-Type ヘッダ内の他のパラメタを含む辞書 pdict です。

urlparse.parse_qs() と同じく辞書を返します。辞書のキーはフィールド名で、対応する値は各フィールドの値でできたリストです。この関数は簡単に使えますが、数メガバイトのデータがアップロードされると考えられる場合にはあまり適していません — その場合、より柔軟性のある FieldStorage を代りに使ってください。

マルチパートデータがネストしている場合、各パートを解釈できないので注意してください — 代りに FieldStorage を使ってください。

cgi.parse_header(string)

(Content-Type のような) MIME ヘッダを解釈し、ヘッダの主要値と各パラメタからなる辞書にします。

cgi.test()

メインプログラムから利用できる堅牢性テストを行う CGI スクリプトです。最小の HTTP ヘッダと、HTML フォームからスクリプトに供給された全ての情報を書式化して出力します。

cgi.print_environ()

シェル変数を HTML に書式化して出力します。

cgi.print_form(form)

フォームを HTML に初期化して出力します。

cgi.print_directory()

現在のディレクトリを HTML に書式化して出力します。

cgi.print_environ_usage()

意味のある (CGI の使う) 環境変数を HTML で出力します。

cgi.escape(s[, quote])

文字列 s 中の文字 '&' 、 '<' 、および '>' を HTML で正しく表示できる文字列に変換します。それらの文字が中に入っているかもしれないようなテキストを出力する必要があるときに使ってください。オプションの引数 quote の値が真であれば、二重引用符文字 (") も変換します; この機能は <a href="..."> のように二重引用符で区切られた HTML の属性値を出力に含めるのに役立ちます。単引用符は変換されないことに注意して下さい。

クオートされる値が単引用符か二重引用符、またはその両方を含む可能性がある場合は、代りに xml.sax.saxutils の quoteattr() 関数を検討してください。

20.2.6. セキュリティへの配慮

重要なルールが一つあります: ( 関数 os.system() または os.popen() 、またはその他の同様の機能によって ) 外部プログラムを呼び出すなら、クライアントから受信した任意の文字列をシェルに渡していないことをよく確かめてください。これはよく知られているセキュリティホールであり、これによって Web のどこかにいる悪賢いハッカーが、だまされやすい CGI スクリプトに任意のシェルコマンドを実行させてしまえます。URL の一部やフィールド名でさえも信用してはいけません。CGI へのリクエストはあなたの作ったフォームから送信されるとは限らないからです！

安全な方法をとるために、フォームから入力された文字をシェルに渡す場合、文字列に入っているのが英数文字、ダッシュ、アンダースコア、およびピリオドだけかどうかを確認してください。

20.2.7. CGI スクリプトを Unix システムにインストールする

あなたの使っている HTTP サーバのドキュメントを読んでください。そしてローカルシステムの管理者と一緒にどのディレクトリに CGI スクリプトをインストールすべきかを調べてください; 通常これはサーバのファイルシステムツリー内の cgi-bin ディレクトリです。

あなたのスクリプトが “others” によって読み取り可能および実行可能であることを確認してください; Unix ファイルモードは 8 進表記で 0755 です (chmod 0755 filename を使ってください)。スクリプトの最初の行の 1 カラム目が、 #! で開始し、その後に Python インタプリタへのパス名が続いていることを確認してください。例えば:

#!/usr/local/bin/python

Python インタプリタが存在し、”others” によって実行可能であることを確かめてください。

あなたのスクリプトが読み書きしなければならないファイルが全て “others” によって読み出しや書き込み可能であることを確かめてください — 読み出し可能のファイルモードは 0644 で、書き込み可能のファイルモードは 0666 になるはずです。これは、セキュリティ上の理由から、 HTTP サーバがあなたのスクリプトを特権を全く持たないユーザ “nobody” の権限で実行するからです。この権限下では、誰でもが読める (書ける、実行できる) ファイルしか読み出し (書き込み、実行) できません。スクリプト実行時のディレクトリや環境変数のセットもあなたがログインしたときの設定と異なります。特に、実行ファイルに対するシェルの検索パス (PATH) や Python のモジュール検索パス (PYTHONPATH)が何らかの値に設定されていると期待してはいけません。

モジュールを Python の標準設定におけるモジュール検索パス上にないディレクトリからロードする必要がある場合、他のモジュールを取り込む前にスクリプト内で検索パスを変更できます。例えば:

import sys
sys.path.insert(0, "/usr/home/joe/lib/python")
sys.path.insert(0, "/usr/local/lib/python")

(この方法では、最後に挿入されたディレクトリが最初に検索されます！)

非 Unix システムにおける説明は変わるでしょう; あなたの使っている HTTP サーバのドキュメントを調べてください (普通は CGI スクリプトに関する節があります)。

20.2.8. CGI スクリプトをテストする

残念ながら、 CGI スクリプトは普通、コマンドラインから起動しようとしても動きません。また、コマンドラインから起動した場合には完璧に動作するスクリプトが、不思議なことにサーバからの起動では失敗することがあります。しかし、スクリプトをコマンドラインから実行してみなければならない理由が一つあります: もしスクリプトが文法エラーを含んでいれば、Python インタプリタはそのプログラムを全く実行しないため、 HTTP サーバはほとんどの場合クライアントに謎めいたエラーを送信するからです。

スクリプトが構文エラーを含まないのにうまく動作しないなら、次の節に読み進むしかありません。

20.2.9. CGI スクリプトをデバッグする

何よりもまず、些細なインストール関連のエラーでないか確認してください — 上の CGI スクリプトのインストールに関する節を注意深く読めば時間を大いに節約できます。もしインストールの手続きを正しく理解しているか不安なら、このモジュールのファイル (cgi.py) をコピーして、CGI スクリプトとしてインストールしてみてください。このファイルはスクリプトとして呼び出すと、スクリプトの実行環境とフォームの内容を HTML フォームに出力します。正しいモードなどをフォームに与えて、リクエストを送ってみてください。標準的な cgi-bin ディレクトリにインストールされていれば、以下のような URL をブラウザに入力してリクエストを送信できるはずです:

http://yourhostname/cgi-bin/cgi.py?name=Joe+Blow&addr=At+Home

もしタイプ 404 のエラーになるなら、サーバはスクリプトを発見できないでいます – おそらくあなたはスクリプトを別のディレクトリに入れる必要があるのでしょう。他のエラーになるなら、先に進む前に解決しなければならないインストール上の問題があります。もし実行環境の情報とフォーム内容 (この例では、各フィールドはフィールド名 “addr” に対して値 “At Home”、およびフィールド名 “name” に対して “Joe Blow” ) が綺麗にフォーマットされて表示されるなら、 cgi.py スクリプトは正しくインストールされています。同じ操作をあなたの自作スクリプトに対して行えば、スクリプトをデバッグできるようになるはずです。

次のステップでは cgi モジュールの test() 関数を呼び出すことになります: メインプログラムコードを以下の 1 行、

cgi.test()

と置き換えてください。この操作で cgi.py ファイル自体をインストールした時と同じ結果を出力するはずです。

通常の Python スクリプトが例外を処理しきれずに送出した場合 (様々な理由: モジュール名のタイプミス、ファイルが開けなかった、など)、 Python インタプリタはナイスなトレースバックを出力して終了します。 Python インタプリタはあなたの CGI スクリプトが例外を送出した場合にも同様に振舞うので、トレースバックは大抵HTTP サーバのいずれかのログファイルに残るかまったく無視されるかです。

幸運なことに、あなたが自作のスクリプトで 何らかの コードを実行できるようになったら、 cgitb モジュールを使って簡単にトレースバックをブラウザに送信できます。まだそうでないなら、以下の2行:

import cgitb;
cgitb.enable()

をスクリプトの先頭に追加してください。そしてスクリプトを再度走らせます; 問題が発生すれば、クラッシュの原因を見出せるような詳細な報告を読めます。

cgitb モジュールのインポートに問題がありそうだと思うなら、(組み込みモジュールだけを使った) もっと堅牢なアプローチを取れます:

import sys
sys.stderr = sys.stdout
print "Content-Type: text/plain"
print
...your code here...

このコードは Python インタプリタがトレースバックを出力することに依存しています。出力のコンテント型はプレーンテキストに設定されており、全ての HTML 処理を無効にしています。スクリプトがうまく動作する場合、生の HTML コードがクライアントに表示されます。スクリプトが例外を送出する場合、最初の 2 行が出力された後、トレースバックが表示されます。HTML の解釈は行われないので、トレースバックを読めるはずです。

20.2.10. よくある問題と解決法

ほとんどの HTTP サーバはスクリプトの実行が完了するまで CGI からの出力をバッファします。このことは、スクリプトの実行中にクライアントが進捗状況報告を表示できないことを意味します。

上のインストールに関する説明を調べましょう。

HTTP サーバのログファイルを調べましょう。(別のウィンドウで tail -f logfile を実行すると便利かもしれません！)

常に python script.py などとして、スクリプトが構文エラーでないか調べましょう。

スクリプトに構文エラーがないなら、 import cgitb; cgitb.enable() をスクリプトの先頭に追加してみましょう。

外部プログラムを起動するときには、スクリプトがそのプログラムを見つけられるようにしましょう。これは通常、絶対パス名を使うことを意味します — PATH は普通、あまり CGI スクリプトにとって便利でない値に設定されています。

外部のファイルを読み書きする際には、CGI スクリプトを動作させるときに使われる userid でファイルを読み書きできるようになっているか確認しましょう: userid は通常、Web サーバを動作させている userid か、Web サーバの suexec 機能で明示的に指定している userid になります。

CGI スクリプトを set-uid モードにしてはいけません。これはほとんどのシステムで動作せず、セキュリティ上の信頼性もありません。

注記

[1]
最近のバージョンの HTML 仕様ではフィールドの値を供給する順番を取り決めてはいますが、ある HTTP リクエストがその取り決めに準拠したブラウザから受信したものかどうか、そもそもブラウザから送信されたものかどうかの判別は退屈で間違いやすいので注意してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.3. cgitb — CGI スクリプトのトレースバック管理機構

バージョン 2.2 で追加.

cgitb モジュールでは、Python スクリプトのための特殊な例外処理を提供します。(実はこの説明は少し的外れです。このモジュールはもともと徹底的なトレースバック情報を CGI スクリプトで生成した HTML 内に表示するための設計されました。その後この情報を平文テキストでも表示できるように一般化されています。) このモジュールの有効化後に捕捉されない例外が生じた場合、詳細で書式化された報告が Web ブラウザに送信されます。この報告には各レベルにおけるソースコードの抜粋が示されたトレースバックと、現在動作している関数の引数やローカルな変数が収められており、問題のデバッグを助けます。オプションとして、この情報をブラウザに送信する代わりにファイルに保存することもできます。

この機能を有効化するためには、単に自作の CGI スクリプトの最初に以下の2行を追加します:

import cgitb
cgitb.enable()

enable() 関数のオプションは、報告をブラウザに表示するかどうかと、後で解析するためにファイルに報告をログ記録するかどうかを制御します。

cgitb.enable([display[, logdir[, context[, format]]]])

この関数は、 sys.excepthook を設定することで、インタプリタの標準の例外処理を cgitb モジュールに肩代わりさせるようにします。

オプションの引数 display は標準で 1 になっており、この値は 0 にしてトレースバックをブラウザに送らないように抑制することもできます。引数 logdir はログファイルを配置するディレクトリです。オプションの引数 context は、トレースバックの中で現在の行の周辺の何行を表示するかです; この値は標準で 5 です。オプションの引数 format が "html" の場合、出力は HTML に書式化されます。その他の値を指定すると平文テキストの出力を強制します。デフォルトの値は "html" です。

cgitb.handler([info])

この関数は標準の設定 (ブラウザに報告を表示しますがファイルにはログを書き込みません) を使って例外を処理します。この関数は、例外を捕捉した際に cgitb を使って報告したい場合に使うことができます。オプションの info 引数は、例外の型、例外の値、トレースバックオブジェクトからなる 3 要素のタプルでなければなりません。これは sys.exc_info() によって返される値と全く同じです。 info 引数が与えられていない場合、現在の例外は sys.exc_info() から取得されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.4. wsgiref — WSGI ユーティリティとリファレンス実装

バージョン 2.5 で追加.

Web Server Gateway Interface (WSGI) は、Web サーバソフトウェアと Python で記述された Web アプリケーションとの標準インターフェースです。標準インターフェースを持つことで、WSGI をサポートするアプリケーションを幾つもの異なる Web サーバで使うことが容易になります。

Web サーバとプログラミングフレームワークの作者だけが、WSGI デザインのあらゆる細部や特例などを知る必要があります。WSGI アプリケーションをインストールしたり、既存のフレームワークを使ったアプリケーションを記述するだけの皆さんは、全てについて理解する必要はありません。

wsgiref は WSGI 仕様のリファレンス実装で、これは Web サーバやフレームワークに WSGI サポートを加えるのに利用できます。これは WSGI 環境変数やレスポンスヘッダを操作するユーティリティ、 WSGI サーバ実装時のベースクラス、WSGI アプリケーションを提供する デモ用 HTTP サーバ、それと WSGI サーバとアプリケーションの WSGI 仕様 (PEP 333 [http://www.python.org/dev/peps/pep-0333]) 準拠のバリデーションツールを提供します。

http://www.wsgi.org に、WSGIに関するさらなる情報と、チュートリアルやその他のリソースへのリンクがあります。

20.4.1. wsgiref.util – WSGI 環境のユーティリティ

このモジュールは WSGI 環境で使う様々なユーティリティ関数を提供します。 WSGI 環境は PEP 333 [http://www.python.org/dev/peps/pep-0333] で記述されているような HTTP リクエスト変数を含む辞書です。全ての environ パラメータを取る関数は WSGI 準拠の辞書を与えられることを期待しています；細かい仕様については PEP 333 [http://www.python.org/dev/peps/pep-0333] を参照してください。

wsgiref.util.guess_scheme(environ)

environ 辞書の HTTPS 環境変数を調べることで wsgi.url_scheme が “http” か “https” のどちらであるべきか推測し、その結果を返します。戻り値は文字列です。

この関数は、CGI や FastCGI のような CGI に似たプロトコルをラップするゲートウェイを作成する場合に便利です。典型的には、それらのプロトコルを提供するサーバが SSL 経由でリクエストを受け取った場合には HTTPS 変数に値 “1” “yes”、または “on” を持つでしょう。そのため、この関数はそのような値が見つかった場合には “https” を返し、そうでなければ “http” を返します。

wsgiref.util.request_uri(environ[, include_query=1])

リクエスト URI 全体 (オプションでクエリ文字列を含む) を、 PEP 333 [http://www.python.org/dev/peps/pep-0333] の “URL 再構築(URL Reconstruction)” にあるアルゴリズムを使って返します。 include_query が false の場合、クエリ文字列は結果となる文字列には含まれません。

wsgiref.util.application_uri(environ)

PATH_INFO と QUERY_STRING 変数が無視されることを除けば request_url() に似ています。結果はリクエストによって指定されたアプリケーションオブジェクトのベース URI です。

wsgiref.util.shift_path_info(environ)

PATH_INFO から SCRIPT_NAME に一つの名前をシフトしてその名前を返します。 environ 辞書は 変更されます 。 PATH_INFO や SCRIPT_NAME のオリジナルをそのまま残したい場合にはコピーを使ってください。

PATH_INFO にパスセグメントが何も残っていなければ、 None が返されます。

典型的なこのルーチンの使い方はリクエスト URI のそれぞれの要素の処理で、例えばパスを一連の辞書のキーとして取り扱う場合です。このルーチンは、渡された環境を、ターゲット URL で示される別の WSGI アプリケーションの呼び出しに合うように調整します。例えば、 /foo に WSGI アプリケーションがあったとして、そしてリクエスト URL パスが /foo/bar/baz で、 /foo の WSGI アプリケーションが shift_path_info() を呼んだ場合、これは “bar” 文字列を受け取り、 environ は /foo/bar の WSGI アプリケーションへの受け渡しに適するように更新されます。つまり、 SCRIPT_NAME は /foo から /foo/bar に変わって、 PATH_INFO は /bar/baz から /baz に変化するのです。

PATH_INFO が単に “/” の場合、このルーチンは空の文字列を返し、 SCRIPT_NAME の末尾にスラッシュを加えます、これはたとえ空のパスセグメントが通常は無視され、そして SCRIPT_NAME は通常スラッシュで終わる事が無かったとしてもです。これは意図的な振る舞いで、このルーチンでオブジェクト巡回(object traversal) をした場合に /x で終わる URI と /x/ で終わるものをアプリケーションが識別できることを保証するためのものです。

wsgiref.util.setup_testing_defaults(environ)

environ をテスト用に自明なデフォルト値で更新します。

このルーチンは WSGI に必要な様々なパラメータを追加します。そのようなパラメータとして HTTP_HOST 、 SERVER_NAME 、 SERVER_PORT 、 REQUEST_METHOD 、 SCRIPT_NAME 、 PATH_INFO 、そして PEP 333 [http://www.python.org/dev/peps/pep-0333] で定義されている wsgi.* 変数群が含まれます。このルーチンはデフォルト値を提供するだけで、これらの変数の既存設定は一切置きかえません。

このルーチンは、ダミー環境をセットアップすることによって WSGI サーバとアプリケーションのユニットテストを容易にすることを意図しています。これは実際の WSGI サーバやアプリケーションで使うべきではありません。なぜならこのデータは偽物なのです！

利用例:

from wsgiref.util import setup_testing_defaults
from wsgiref.simple_server import make_server

# 比較的シンプルなWSGIアプリケーション。 setup_testing_defaults に
# よって更新されたあとの environment 辞書を表示する
def simple_app(environ, start_response):
    setup_testing_defaults(environ)

    status = '200 OK'
    headers = [('Content-type', 'text/plain')]

    start_response(status, headers)

    ret = ["%s: %s\n" % (key, value)
           for key, value in environ.iteritems()]
    return ret

httpd = make_server('', 8000, simple_app)
print "Serving on port 8000..."
httpd.serve_forever()

上記の環境用関数に加えて、 wsgiref.util モジュールも以下のようなその他のユーティリティを提供します：

wsgiref.util.is_hop_by_hop(header_name)

‘header_name’ が RFC 2616 [http://tools.ietf.org/html/rfc2616.html] で定義されている HTTP/1.1 の “Hop-by-Hop” ヘッダの場合に true を返します。

class wsgiref.util.FileWrapper(filelike[, blksize=8192])

ファイル風オブジェクトをイテレータ(iterator)に変換するラッパです。結果のオブジェクトは __getitem__() と __iter__() 両方をサポートしますが、これは Python 2.1 と Jython の互換性のためです。オブジェクトがイテレートされる間、オプションの blksize パラメータがくり返し filelike オブジェクトの read() メソッドに渡されて受け渡す文字列を取得します。 read() が空文字列を返した場合、イテレーションは終了して再開されることはありません。

filelike に close() メソッドがある場合、返されたオブジェクトも close() メソッドを持ち、これが呼ばれた場合には filelike オブジェクトの close() メソッドを呼び出します。

利用例:

from StringIO import StringIO
from wsgiref.util import FileWrapper

# ファイル風オブジェクトとして StringIO バッファを使用しています
filelike = StringIO("This is an example file-like object"*10)
wrapper = FileWrapper(filelike, blksize=5)

for chunk in wrapper:
    print chunk

20.4.2. wsgiref.headers – WSGI レスポンスヘッダツール群

このモジュールは単一のクラス、 Headers を提供し、WSGI レスポンスヘッダの操作をマップに似たインターフェースで便利にします。

class wsgiref.headers.Headers(headers)

headers をラップするマップ風オブジェクトを生成します。これは PEP 333 [http://www.python.org/dev/peps/pep-0333] に定義されるようなヘッダの名前／値のタプルのリストです。新しい Headers オブジェクトに与えられた変更は、一緒に作成された headers リストを直接更新します。

Headers オブジェクトは典型的なマッピング操作をサポートし、これには __getitem__() 、 get() 、 __setitem__() 、 setdefault() 、 __delitem__() 、 __contains__() と has_key() を含みます。これらメソッドのそれぞれにおいて、キーはヘッダ名で（大文字小文字は区別しません）、値はそのヘッダ名に関連づけられた最初の値です。ヘッダを設定すると既存のヘッダ値は削除され、ラップされたヘッダのリストの末尾に新しい値が加えられます。既存のヘッダの順番は一般に維持され、ラップされたリストの最後に新しいヘッダが追加されます。

辞書とは違って、 Headers オブジェクトはラップされたヘッダリストに存在しないキーを取得または削除しようとした場合にもエラーを発生しません。単に、存在しないヘッダの取得は None を返し、存在しないヘッダの削除は何もしません。

Headers オブジェクトは keys() 、 values() 、 items() メソッドもサポートします。複数の値を持つヘッダがある場合には、 keys() と items() で返されるリストは同じキーを一つ以上含むことがあります。 Header オブジェクトの len() は、その items() の長さと同じであり、ラップされたヘッダリストの長さと同じです。実際、 items() メソッドは単にラップされたヘッダリストのコピーを返しているだけです。

Headers オブジェクトに対して str() を呼ぶと、HTTP レスポンスヘッダとして送信するのに適した形に整形された文字列を返します。それぞれのヘッダはコロンとスペースで区切られた値と共に一列に並んでいます。それぞれの行はキャリッジリターンとラインフィードで終了し、文字列は空行で終了しています。

これらのマッピングインターフェースと整形機能に加えて、 Headers オブジェクトは複数の値を持つヘッダの取得と追加、MIME パラメータでヘッダを追加するための以下のようなメソッド群も持っています：

get_all(name)

指定されたヘッダの全ての値のリストを返します。

返されるリストは、元々のヘッダリストに現れる順、またはこのインスタンスに追加された順に並んでいて、重複を含む場合があります。削除されて加えられたフィールドは全てヘッダリストの末尾に付きます。与えられた name に対するフィールドが何もなければ、空のリストが返ります。

add_header(name, value, **_params)

(複数の値を持つ可能性のある) ヘッダを、キーワード引数を通じて指定するオプションの MIME パラメータと共に追加します。

name は追加するヘッダフィールドです。このヘッダフィールドに MIME パラメータを設定するためにキーワード引数を使うことができます。それぞれのパラメータは文字列か None でなければいけません。パラメータ中のアンダースコアはダッシュ (-) に変換されます。これは、ダッシュが Python の識別子としては不正なのですが、多くの MIME パラメータはダッシュを含むためです。パラメータ値が文字列の場合、これはヘッダ値のパラメータに name="value" の形で追加されます。この値がもし None の場合、パラメータ名だけが追加されます。（これは値なしの MIME パラメータの場合に使われます。）使い方の例は、

h.add_header('content-disposition', 'attachment', filename='bud.gif')

上記はこのようなヘッダを追加します

Content-Disposition: attachment; filename="bud.gif"

20.4.3. wsgiref.simple_server – シンプルな WSGI HTTP サーバ

このモジュールは WSGI アプリケーションを提供するシンプルな HTTP サーバです (BaseHTTPServer がベースです)。個々のサーバインスタンスは単一の WSGI アプリケーションを、特定のホストとポート上で提供します。もし一つのホストとポート上で複数のアプリケーションを提供したいならば、 PATH_INFO をパースして個々のリクエストでどのアプリケーションを呼び出すか選択するような WSGI アプリケーションを作る必要があります。（例えば、 wsgiref.util から shift_path_info() を利用します。）

wsgiref.simple_server.make_server(host, port, app[, server_class=WSGIServer[, handler_class=WSGIRequestHandler]])

host と port 上で待機し、 app へのコネクションを受け付ける WSGI サーバを作成します。戻り値は与えられた server_class のインスタンスで、指定された handler_class を使ってリクエストを処理します。 app は PEP 333 [http://www.python.org/dev/peps/pep-0333] で定義されるところの WSGI アプリケーションでなければいけません。

使用例：

from wsgiref.simple_server import make_server, demo_app

httpd = make_server('', 8000, demo_app)
print "Serving HTTP on port 8000..."

# プロセスが kill されるまでリクエストに応える
httpd.serve_forever()

# 代替：１つのリクエストを受けて終了する
httpd.handle_request()

wsgiref.simple_server.demo_app(environ, start_response)

この関数は小規模ながら完全な WSGI アプリケーションで、 “Hello world!” メッセージと、 environ パラメータに提供されているキー／値のペアを含むテキストページを返します。これは WSGI サーバ (wsgiref.simple_server のような) がシンプルな WSGI アプリケーションを正しく実行できるかを確かめるのに便利です。

class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass)

WSGIServer インスタンスを作成します。 server_address は (host,port) のタプル、そして RequesthandlerClass はリクエストの処理に使われる BaseHTTPServer.BaseHTTPRequestHandler のサブクラスでなければいけません。

make_server() が細かい調整をやってくれるので、通常はこのコンストラクタを呼ぶ必要はありません。

WSGIServer は BaseHTTPServer.HTTPServer のサブクラスなので、その全てのメソッド (serve_forever() や handle_request() のような) が利用できます。 WSGIServer も以下のような WSGI 固有メソッドを提供します：

set_app(application)

呼び出し可能 (callable) な application をリクエストを受け取る WSGI アプリケーションとして設定します。

get_app()

現在設定されている呼び出し可能 (callable) アプリケーションを返します。

しかしながら、通常はこれらの追加されたメソッドを使う必要はありません。 set_app() は普通は make_server() によって呼ばれ、 get_app() は主にリクエストハンドラインスタンスの便宜上存在するからです。

class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server)

与えられた request （すなわちソケット）の HTTP ハンドラ、 client_address ((host,port) のタプル)、 server (WSGIServer インスタンス) の HTTP ハンドラを作成します。

このクラスのインスタンスを直接生成する必要はありません；これらは必要に応じて WSGIServer オブジェクトによって自動的に生成されます。しかしながら、このクラスをサブクラス化し、 make_server() 関数に handler_class として与えることは可能でしょう。サブクラスにおいてオーバーライドする意味のありそうなものは：

get_environ()

リクエストに対する WSGI 環境を含む辞書を返します。デフォルト実装では WSGIServer オブジェクトの base_environ 辞書属性のコンテンツをコピーし、それから HTTP リクエスト由来の様々なヘッダを追加しています。このメソッド呼び出し毎に、 PEP 333 [http://www.python.org/dev/peps/pep-0333] に指定されている関連する CGI 環境変数を全て含む新規の辞書を返さなければいけません。

get_stderr()

wsgi.errors ストリームとして使われるオブジェクトを返します。デフォルト実装では単に sys.stderr を返します。

handle()

HTTP リクエストを処理します。デフォルト実装では実際の WGI アプリケーションインターフェースを実装するのに wsgiref.handlers クラスを使ってハンドラインスタンスを作成します。

20.4.4. wsgiref.validate — WSGI 準拠チェッカー

WSGI アプリケーションのオブジェクト、フレームワーク、サーバまたはミドルウェアの作成時には、その新規のコードを wsgiref.validate を使って準拠の検証をすると便利です。このモジュールは WSGI サーバやゲートウェイと WSGI アプリケーションオブジェクト間の通信を検証する WSGI アプリケーションオブジェクトを作成する関数を提供し、双方のプロトコル準拠をチェックします。

このユーティリティは完全な PEP 333 [http://www.python.org/dev/peps/pep-0333] 準拠を保証するものでないことは注意してください；このモジュールでエラーが出ないことは必ずしもエラーが存在しないことを意味しません。しかしこのモジュールがエラーを出したならば、ほぼ確実にサーバかアプリケーションのどちらかが 100% 準拠ではありません。

このモジュールは lan Bicking の “Python Paste” ライブラリの paste.lint モジュールをベースにしています。

wsgiref.validate.validator(application)

application をラップし、新しい WSGI アプリケーションオブジェクトを返します。返されたアプリケーションは全てのリクエストを元々の application に転送し、 application とそれを呼び出すサーバの両方が WSGI 仕様と RFC 2616 の両方に準拠しているかをチェックします。

何らかの非準拠が検出されると、 AssertionError 例外が送出されます；しかし、このエラーがどう扱われるかはサーバ依存であることに注意してください。例えば、 wsgiref.simple_server とその他 wsgiref.handlers ベースのサーバ（エラー処理メソッドが他のことをするようにオーバライドしていないもの）は単純にエラーが発生したというメッセージとトレースバックのダンプを sys.stderr やその他のエラーストリームに出力します。

このラッパは、疑わしいものの実際には PEP 333 [http://www.python.org/dev/peps/pep-0333] で禁止されていないかもしれない挙動を指摘するために warnings モジュールを使って出力を生成します。これらは Python のコマンドラインオプションや warnings API で抑制されなければ、 sys.stderr (wsgi.errors では ありません 。ただし、たまたま同一のオブジェクトだった場合を除く)に書き出されます。

利用例:

from wsgiref.validate import validator
from wsgiref.simple_server import make_server

# 意図的に規格に準拠していない callable
# バリデーションは失敗する
def simple_app(environ, start_response):
    status = '200 OK' # HTTP Status
    headers = [('Content-type', 'text/plain')] # HTTP Headers
    start_response(status, headers)

    # リストを返す必要があるので、これは規格違反です。
    # バリデータはそれを教えてくれるでしょう。
    return "Hello World"

# これはバリデータでラップされたアプリケーションです
validator_app = validator(simple_app)

httpd = make_server('', 8000, validator_app)
print "Listening on port 8000...."
httpd.serve_forever()

20.4.5. wsgiref.handlers – サーバ／ゲートウェイのベースクラス

このモジュールは WSGI サーバとゲートウェイ実装のベースハンドラクラスを提供します。これらのベースクラスは、 CGI 風の環境と、それに加えて入力、出力そしてエラーストリームが与えられることで、 WSGI アプリケーションとの通信の大部分を処理します。

class wsgiref.handlers.CGIHandler

sys.stdin 、 sys.stdout 、 stderr そして os.environ 経由での CGI ベースの呼び出しです。これは、もしあなたが WSGI アプリケーションを持っていて、これを CGI スクリプトとして実行したい場合に有用です。単に CGIHandler().run(app) を起動してください。 app はあなたが起動したい WSGI アプリケーションオブジェクトです。

このクラスは BaseCGIHandler のサブクラスで、これは wsgi.run_once を true、 wsgi.multithread を false、そして wsgi.multiprocess を true にセットし、常に sys と os を、必要な CGI ストリームと環境を取得するために使用します。

class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ[, multithread=True[, multiprocess=False]])

CGIHandler に似ていますが、 sys と os モジュールを使う代わりに CGI 環境と I/O ストリームを明示的に指定します。 multithread と multiprocess の値は、ハンドラインスタンスにより実行されるアプリケーションの wsgi.multithread と wsgi.multiprocess フラグの設定に使われます。

このクラスは SimpleHandler のサブクラスで、HTTP の “本サーバ” でないソフトウェアと使うことを意図しています。もしあなたが Status: ヘッダを HTTP ステータスを送信するのに使うようなゲートウェイプロトコルの実装（CGI、FastCGI、SCGIなど）を書いている場合、おそらく SimpleHandler ではなくこのクラスをサブクラス化するとよいでしょう。

class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ[, multithread=True[, multiprocess=False]])

BaseCGIHandler と似ていますが、HTTP の本サーバと使うためにデザインされています。もしあなたが HTTP サーバ実装を書いている場合、おそらく BaseCGIHandler ではなくこのクラスをサブクラス化するとよいでしょう。

このクラスは BaseHandler のサブクラスです。これは __init__() 、 get_stdin() 、 get_stderr() 、 add_cgi_vars() 、 _write() 、 _flush() をオーバーライドして、コンストラクタから明示的に環境とストリームを設定するようにしています。与えられた環境とストリームは stdin 、 stdout 、 stderr それに environ 属性に保存されています。

class wsgiref.handlers.BaseHandler

これは WSGI アプリケーションを実行するための抽象ベースクラスです。それぞれのインスタンスは一つの HTTP リクエストを処理します。しかし原理上は複数のリクエスト用に再利用可能なサブクラスを作成することができます。

BaseHandler インスタンスは外部から利用されるたった一つのメソッドを持ちます：

run(app)

指定された WSGI アプリケーション、 app を実行します。

その他の全ての BaseHandler のメソッドはアプリケーション実行プロセスでこのメソッドから呼ばれます。したがって、それらは主にそのプロセスのカスタマイズのために存在しています。

以下のメソッドはサブクラスでオーバーライドされなければいけません：

_write(data)

文字列の data をクライアントへの転送用にバッファします。このメソッドが実際にデータを転送しても OK です：下部システムが実際にそのような区別をしている場合に効率をより良くするために、 BaseHandler は書き出しとフラッシュ操作を分けているからです。

_flush()

バッファされたデータをクライアントに強制的に転送します。このメソッドは何もしなくても OK です（すなわち、 _write() が実際にデータを送る場合）。

get_stdin()

現在処理中のリクエストの wsgi.input としての利用に適当な入力ストリームオブジェクトを返します。

get_stderr()

現在処理中のリクエストの wsgi.errors としての利用に適当な出力ストリームオブジェクトを返します。

add_cgi_vars()

現在のリクエストの CGI 変数を environ 属性に追加します。

オーバーライドされることの多いメソッド及び属性を以下に挙げます。しかし、このリストは単にサマリであり、オーバーライド可能な全てのメソッドは含んでいません。カスタマイズした BaseHandler サブクラスを作成しようとする前に docstring やソースコードでさらなる情報を調べてください。

WSGI 環境のカスタマイズのための属性とメソッド：

wsgi_multithread

wsgi.multithread 環境変数で使われる値。 BaseHandler ではデフォルトが true ですが、別のサブクラスではデフォルトで（またはコンストラクタによって設定されて）異なる値を持つことがあります。

wsgi_multiprocess

wsgi.multiprocess 環境変数で使われる値。 BaseHandler ではデフォルトが true ですが、別のサブクラスではデフォルトで（またはコンストラクタによって設定されて）異なる値を持つことがあります。

wsgi_run_once

wsgi.run_once 環境変数で使われる値。 BaseHandler ではデフォルトが false ですが、 CGIHandler はデフォルトでこれを true に設定します。

os_environ

全てのリクエストの WSGI 環境に含まれるデフォルトの環境変数。デフォルトでは wsgiref.handlers がインポートされた時点の os.environ のコピーですが、サブクラスはクラスまたはインスタンスレベルでそれら自身のものを作ることができます。デフォルト値は複数のクラスとインスタンスで共有されるため、この辞書は読み取り専用と考えるべきだという点に注意してください。

server_software

origin_server 属性が設定されている場合、この属性の値がデフォルトの SERVER_SOFTWARE WSGI 環境変数の設定や HTTP レスポンス中のデフォルトの Server: ヘッダの設定に使われます。これは (BaseCGIHandler や CGIHandler のような) HTTP オリジンサーバでないハンドラでは無視されます。

get_scheme()

現在のリクエストで使われている URL スキームを返します。デフォルト実装は wsgiref.util の guess_scheme() を使い、現在のリクエストの envion 変数に基づいてスキームが”http” か “https” かを推測します。

setup_environ()

environ 属性を、フル実装 (fully-populated) の WSGI 環境に設定します。デフォルトの実装は、上記全てのメソッドと属性、加えて get_stdin() 、 get_stderr() 、 add_cgi_vars() メソッドと wsgi_file_wrapper 属性を利用します。これは、キーが存在せず、 origin_server 属性が true 値で server_software 属性も設定されている場合に SERVER_SOFTWARE を挿入します。

例外処理のカスタマイズのためのメソッドと属性：

log_exception(exc_info)

exec_info タプルをサーバログに記録します。 exc_info は (type, value, traceback) のタプルです。デフォルトの実装は単純にトレースバックをリクエストの wsgi.errors ストリームに書き出してフラッシュします。サブクラスはこのメソッドをオーバーライドしてフォーマットを変更したり出力先の変更、トレースバックを管理者にメールしたりその他適切と思われるいかなるアクションも取ることができます。

traceback_limit

デフォルトの log_exception() メソッドで出力されるトレースバック出力に含まれる最大のフレーム数です。 None ならば、全てのフレームが含まれます。

error_output(environ, start_response)

このメソッドは、ユーザに対してエラーページを出力する WSGI アプリケーションです。これはクライアントにヘッダが送出される前にエラーが発生した場合にのみ呼び出されます。

このメソッドは sys.exc_info() を使って現在のエラー情報にアクセスでき、その情報はこれを呼ぶときに start_response に渡すべきです (PEP 333 [http://www.python.org/dev/peps/pep-0333] の “Error Handling” セクションに記述があります)。

デフォルト実装は単に error_status 、 error_headers 、 error_body 属性を出力ページの生成に使います。サブクラスではこれをオーバーライドしてもっと動的なエラー出力をすることができます。

しかし、セキュリティの観点からは診断をあらゆるユーザに吐き出すことは推奨されないことに気をつけてください；理想的には、診断的な出力を有効にするには何らかの特別なことをする必要があるようにすべきで、これがデフォルト実装では何も含まれていない理由です。

error_status

エラーレスポンスで使われる HTTP ステータスです。これは PEP 333 [http://www.python.org/dev/peps/pep-0333] で定義されているステータス文字列です；デフォルトは 500 コードとメッセージです。

error_headers

エラーレスポンスで使われる HTTP ヘッダです。これは PEP 333 [http://www.python.org/dev/peps/pep-0333] で述べられているような、 WSGI レスポンスヘッダ ((name, value) タプル) のリストであるべきです。デフォルトのリストはコンテントタイプを text/plain にセットしているだけです。

error_body

エラーレスポンスボディ。これは HTTP レスポンスのボディ文字列であるべきです。これはデフォルトではプレーンテキストで “A server error occurred. Please contact the administrator.” です。

PEP 333 [http://www.python.org/dev/peps/pep-0333] の “オプションのプラットフォーム固有のファイルハンドリング” 機能のためのメソッドと属性：

wsgi_file_wrapper

wsgi.file_wrapper ファクトリ、または None です。この属性のデフォルト値は wsgiref.util の FileWrapper クラスです。

sendfile()

オーバーライドしてプラットフォーム固有のファイル転送を実装します。このメソッドはアプリケーションの戻り値が wsgi_file_wrapper 属性で指定されたクラスのインスタンスの場合にのみ呼ばれます。これはファイルの転送が成功できた場合には true を返して、デフォルトの転送コードが実行されないようにするべきです。このデフォルトの実装は単に false 値を返します。

その他のメソッドと属性：

origin_server

この属性はハンドラの _write() と _flush() が、特別に Status: ヘッダに HTTP ステータスを求めるような CGI 風のゲートウェイプロトコル経由でなく、クライアントと直接通信をするような場合には true 値に設定されているべきです。

この属性のデフォルト値は BaseHandler では true ですが、 BaseCGIHandler と CGIHandler では false です。

http_version

origin_server が true の場合、この文字列属性はクライアントへのレスポンスセットの HTTP バージョンの設定に使われます。デフォルトは "1.0" です。

20.4.6. 例

これは動作する “Hello World” WSGIアプリケーションです。

from wsgiref.simple_server import make_server

# 全ての WSGI アプリケーションには application オブジェクト - 2つの
# 引数を受け取る callable オブジェクトが必要です。この目的のために、
# ここでは関数を使用しています (関数に限らず、例えばクラスを使用できる
# ことに注意してください)。関数に渡された最初の引数は CGI スタイルの
# 環境変数を含む辞書であり、 2 番目の変数は callable オブジェクトです
# (PEP 333 を見てください)。
def hello_world_app(environ, start_response):
    status = '200 OK' # HTTP Status
    headers = [('Content-type', 'text/plain')] # HTTP Headers
    start_response(status, headers)

    # 返されたオブジェクトは表示されます
    return ["Hello World"]

httpd = make_server('', 8000, hello_world_app)
print "Serving on port 8000..."

# プロセスが kill されるまで実行する
httpd.serve_forever()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.5. urllib — URL による任意のリソースへのアクセス

ノート

urllib モジュールは、Python 3.0では urllib.request, urllib.parse, urllib.error モジュールに分解されました。 2to3 ツールが自動的にソースコードのimportを修正します。また、 urllib.urlopen() 関数は削除され、 urllib2.urlopen() が残りました。

このモジュールはワールドワイドウェブ (World Wide Web) を介してデータを取り寄せるための高レベルのインタフェースを提供します。特に、関数 urlopen() は組み込み関数 open() と同様に動作し、ファイル名の代わりにファイルユニバーサルリソースロケータ (URL) を指定することができます。いくつかの制限はあります — URL は読み出し専用でしか開けませんし、seek 操作を行うことはできません。

警告

HTTPS URL を開くときに、サーバ証明書を検証しようとはしません。自己責任でお使い下さい。

20.5.1. 高レベルインタフェース

urllib.urlopen(url[, data[, proxies]])

URL で表されるネットワーク上のオブジェクトを読み込み用に開きます。 URL がスキーム識別子を持たないか、スキーム識別子が file: である場合、ローカルシステムのファイルが (広範囲の改行サポートなしで) 開かれます。それ以外の場合はネットワーク上のどこかにあるサーバへのソケットを開きます。接続を作ることができない場合、例外 IOError が送出されます。全ての処理がうまくいけば、ファイル類似のオブジェクトが返されます。このオブジェクトは以下のメソッド: read(), readline(), readlines(), fileno(), close(), info(), getcode(), geturl() をサポートします。また、イテレータ(iterator)プロトコルも正しくサポートしています。注意: read() の引数を省略または負の値を指定しても、データストリームの最後まで読みこむ訳ではありません。ソケットからすべてのストリームを読み込んだことを決定する一般的な方法は存在しません。

info(), getcode(), geturl() メソッドを除き、これらのメソッドはファイルオブジェクトと同じインタフェースを持っています — このマニュアルの ファイルオブジェクト セクションを参照してください。 (このオブジェクトは組み込みのファイルオブジェクトではありませんが、まれに本物の組み込みファイルオブジェクトが必要な場所で使うことができません)

info() メソッドは開いた URL に関連付けられたメタ情報を含む mimetools.Message クラスのインスタンスを返します。 URL へのアクセスメソッドが HTTP である場合、メタ情報中のヘッダ情報はサーバが HTML ページを返すときに先頭に付加するヘッダ情報です (Content-Length および Content-Type を含みます)。アクセスメソッドが FTP の場合、ファイル取得リクエストに応答してサーバがファイルの長さを返したときには (これは現在では普通になりましたが) Content-Length ヘッダがメタ情報に含められます。 Content-type ヘッダは MIME タイプが推測可能なときにメタ情報に含められます。アクセスメソッドがローカルファイルの場合、返されるヘッダ情報にはファイルの最終更新日時を表す Date エントリ、ファイルのサイズを示す Content-Length エントリ、そして推測されるファイル形式の Content-Type エントリが含まれます。 mimetools モジュールを参照してください。

geturl() メソッドはページの実際の URL を返します。場合によっては、HTTP サーバはクライアントの要求を他の URL に振り向け (redirect 、リダイレクト ) します。関数 urlopen() はユーザに対してリダイレクトを透過的に行いますが、呼び出し側にとってクライアントがどの URL にリダイレクトされたかを知りたいときがあります。 geturl() メソッドを使うと、このリダイレクトされた URL を取得できます。

getcode() メソッドは、レスポンスと共に送られてきたHTTPステータスコードを返します。 URLがHTTP URLでなかった場合は、 None を返します。

url に http: スキーム識別子を使う場合、 data 引数を与えて POST 形式のリクエストを行うことができます (通常リクエストの形式は GET です)。引数 data は標準の application/x-www-form-urlencoded 形式でなければなりません; 以下の urlencode() 関数を参照してください。

urlopen() 関数は認証を必要としないプロキシ (proxy) に対して透過的に動作します。Unix または Windows 環境では、 Python を起動する前に、環境変数 http_proxy, ftp_proxy にそれぞれのプロキシサーバを指定する URL を設定してください。例えば ('%' はコマンドプロンプトです):

% http_proxy="http://www.someproxy.com:3128"
% export http_proxy
% python
...

no_proxy 環境変数は、proxyを利用せずにアクセスするべきホストを指定するために利用されます。設定する場合は、カンマ区切りの、ホストネーム suffix のリストで、オプションとして :port を付けることができます。例えば、 cern.ch,ncsa.uiuc.edu,some.host:8080.

Windows 環境では、プロキシを指定する環境変数が設定されていない場合、プロキシの設定値はレジストリの Internet Settings セクションから取得されます。

Mac OS X では、 urlopen() はプロキシの情報をシステム設定フレームワーク (Mac OS X System Configuration Framework) から取得します。これはシステム環境設定のネットワークパネルから設定できます。

別の方法として、オプション引数 proxies を使って明示的にプロキシを設定することができます。この引数はスキーム名をプロキシの URL にマップする辞書型のオブジェクトでなくてはなりません。空の辞書を指定するとプロキシを使いません。 None (デフォルトの値です) を指定すると、上で述べたように環境変数で指定されたプロキシ設定を使います。例えば:

# http://www.someproxy.com:3128 を http プロキシに使う
proxies = {'http': 'http://www.someproxy.com:3128'}
filehandle = urllib.urlopen(some_url, proxies=proxies)
# プロキシを使わない
filehandle = urllib.urlopen(some_url, proxies={})
# 環境変数からプロキシを使う - 両方の表記とも同じ意味です。
filehandle = urllib.urlopen(some_url, proxies=None)
filehandle = urllib.urlopen(some_url)

認証を必要とするプロキシは現在のところサポートされていません。これは実装上の制限 (implementation limitation) と考えています。

バージョン 2.3 で変更: proxies のサポートを追加しました。

バージョン 2.6 で変更: 結果オブジェクトに getcode() を追加し、 no_proxy 環境変数に対応しました。

バージョン 2.6 で撤廃: urlopen() 関数は、Python 3.0では urllib2.urlopen() に取って変わられるため、廃止予定(deprecated)になりました。

urllib.urlretrieve(url[, filename[, reporthook[, data]]])

URL で表されるネットワーク上のオブジェクトを、必要に応じてローカルなファイルにコピーします。URL がローカルなファイルを指定していたり、オブジェクトのコピーが正しくキャッシュされていれば、そのオブジェクトはコピーされません。タプル (filename, headers) を返し、 filename はローカルで見つかったオブジェクトに対するファイル名で、 headers は urlopen() が返した (おそらくキャッシュされているリモートの) オブジェクトに info() を適用して得られるものになります。 urlopen() と同じ例外を送出します。

2 つめの引数がある場合、オブジェクトのコピー先となるファイルの位置を指定します (もしなければ、ファイルの場所は一時ファイル (tmpfile) の置き場になり、名前は適当につけられます)。 3 つめの引数がある場合、ネットワークとの接続が確立された際に一度呼び出され、以降データのブロックが読み出されるたびに呼び出されるフック関数 (hook function) を指定します。フック関数には 3 つの引数が渡されます; これまで転送されたブロック数のカウント、バイト単位で表されたブロックサイズ、ファイルの総サイズです。3 つ目のファイルの総サイズは、ファイル取得の際の応答時にファイルサイズを返さない古い FTP サーバでは -1 になります。

url が http: スキーム識別子を使っていた場合、オプション引数 data を与えることで POST リクエストを行うよう指定することができます (通常リクエストの形式は GET です)。 data 引数は標準の application/x-www-form-urlencoded 形式でなくてはなりません; 以下の urlencode() 関数を参照してください。

バージョン 2.5 で変更: urlretrieve() は、予想 (これは Content-Length ヘッダにより通知されるサイズです) よりも取得できるデータ量が少ないことを検知した場合、 ContentTooShortError を発生します。これは、例えば、ダウンロードが中断された場合などに発生します。

Content-Length は下限として扱われます: より多いデータがある場合、 urlretrieve() はそのデータを読みますが、より少ないデータしか取得できない場合、これは exception を発生します。

このような場合にもダウンロードされたデータを取得することは可能で、これは exception インスタンスの content 属性に保存されています。

Content-Length ヘッダが無い場合、 urlretrieve() はダウンロードされたデータのサイズをチェックできず、単にそれを返します。この場合は、ダウンロードは成功したと見なす必要があります。

urllib._urlopener

パブリック関数 urlopen() および urlretrieve() は FancyURLopener クラスのインスタンスを生成します。インスタンスは要求された動作に応じて使用されます。この機能をオーバライドするために、プログラマは URLopener または FancyURLopener のサブクラスを作り、そのクラスから生成したインスタンスを変数 urllib._urlopener に代入した後、呼び出したい関数を呼ぶことができます。例えば、アプリケーションが URLopener が定義しているのとは異なった User-Agent ヘッダを指定したい場合があるかもしれません。この機能は以下のコードで実現できます:

import urllib

class AppURLopener(urllib.FancyURLopener):
    version = "App/1.7"

urllib._urlopener = AppURLopener()

urllib.urlcleanup()

以前の urlretrieve() で生成された可能性のあるキャッシュを消去します。

20.5.2. ユーティリティー関数

urllib.quote(string[, safe])

string に含まれる特殊文字を %xx エスケープで置換（quote）します。アルファベット、数字、および文字 '_.-' はに対しては quote 処理を行いません。この関数はデフォルトでは URL の path セクションに対するクォートを想定しています。オプションのパラメタ safe は quote 処理しない追加の文字を指定します — デフォルトの値は '/' です。

例: quote('/~connolly/') は '/%7econnolly/' になります。

urllib.quote_plus(string[, safe])

quote() と似ていますが、加えて空白文字をプラス記号 (“+”) に置き換えます。これは HTML フォームの値をURLに付加するクエリ文字列にする際に必要な機能です。もとの文字列におけるプラス記号は safe に含まれていない限りエスケープ置換されます。上と同様に、 safe のデフォルトの値は '/' です。

urllib.unquote(string)

%xx エスケープをエスケープが表す 1 文字に置き換えます。

例: unquote('/%7Econnolly/') は '/~connolly/' になります。

urllib.unquote_plus(string)

unquote() と似ていますが、加えてプラス記号を空白文字に置き換えます。これは quote 処理された HTML フォームの値を元に戻すのに必要な機能です。

urllib.urlencode(query[, doseq])

マップ型オブジェクト、または 2要素のタプルからなるシーケンスを、 “パーセントエンコードされた (percent-encoded)” 文字列に変換して、上述の urlopen() のオプション引数 data に適した形式にします。この関数はフォームのフィールド値でできた辞書を POST 型のリクエストに渡すときに便利です。返される文字列は key=value のペアを '&' で区切ったシーケンスで、 key と value の双方は上の quote_plus() でクォートされます。 2つの要素をもったタプルからなるシーケンスが引数 query として使われた場合、各タプルの最初の値が key で、2 番目の値が value になります。どちらのケースでも value にはシーケンスを入れることができ、その場合オプションのパラメタ doseq の評価結果が真であったなら、その key の各々の value に対して '&' で区切られた key=value のペアが生成されます。このときエンコードされた文字列中のパラメタの順番はシーケンス中のタプルの順番と同じになります。 urlparse モジュールでは、関数 parse_qs() および parse_qsl() を提供しており、クエリ文字列を解析して Python のデータ構造にするのに利用できます。

urllib.pathname2url(path)

ローカルシステムにおける記法で表されたパス名 path を、URL におけるパス部分の形式に変換します。この関数は完全な URL を生成するわけではありません。返される値は常に quote() を使って quote 処理されたものになります。

urllib.url2pathname(path)

URL のパスの部分 path をパーセントエンコードされた URL の形式からローカルシステムにおけるパス記法に変換します。この関数は path をデコードするために unquote() を使います。

urllib.getproxies()

このヘルパ関数はスキーマからプロキシサーバーのURLへのマッピングを行う辞書を返します。この関数はまず、どのOSでも最初に <scheme>_proxy という名前の環境変数をスキャンします。そこで見つからなかった場合、 Max OS X の場合は Mac OSX システム環境設定を、 Windows の場合はシステムレジストリを参照します。

20.5.3. URL Opener オブジェクト

class urllib.URLopener([proxies[, **x509]])

URL をオープンし、読み出すためのクラスの基礎クラス (base class)です。 http:, ftp:, file: 以外のスキームを使ったオブジェクトのオープンをサポートしたいのでないかぎり、 FancyURLopener を使おうと思うことになるでしょう。

デフォルトでは、 URLopener クラスは User-Agent ヘッダとして urllib/VVV を送信します。ここで VVV は urllib のバージョン番号です。アプリケーションで独自の User-Agent ヘッダを送信したい場合は、 URLopener かまたは FancyURLopener のサブクラスを作成し、サブクラス定義においてクラス属性 version を適切な文字列値に設定することで行うことができます。

オプションのパラメタ proxies はスキーム名をプロキシの URL にマップする辞書でなくてはなりません。空の辞書はプロキシ機能を完全にオフにします。デフォルトの値は None で、この場合、 urlopen() の定義で述べたように、プロキシを設定する環境変数が存在するならそれを使います。

追加のキーワードパラメタは x509 に集められますが、これは https: スキームを使った際のクライアント認証に使われることがあります。キーワード引数 key_file および cert_file が SSL 鍵と証明書を設定するためにサポートされています; クライアント認証をするには両方が必要です。

URLopener オブジェクトは、サーバがエラーコードを返した時には IOError を発生します。

open(fullurl[, data])

適切なプロトコルを使って fullurl を開きます。このメソッドはキャッシュとプロキシ情報を設定し、その後適切な open メソッドを入力引数つきで呼び出します。認識できないスキームが与えられた場合、 open_unknown() が呼び出されます。 data 引数は urlopen() の引数 data と同じ意味を持っています。

open_unknown(fullurl[, data])

オーバライド可能な、未知のタイプの URL を開くためのインタフェースです。

retrieve(url[, filename[, reporthook[, data]]])

url のコンテンツを取得し、 filename に書き込みます。返り値はタプルで、ローカルシステムにおけるファイル名と、応答ヘッダを含む mimetools.Message オブジェクト(URLがリモートを指している場合)、または None (URL がローカルを指している場合) からなります。呼び出し側の処理はその後 filename を開いて内容を読み出さなくてはなりません。 filename が与えられており、かつ URL がローカルシステム上のファイルを示している場合、入力ファイル名が返されます。 URL がローカルのファイルを示しておらず、かつ filename が与えられていない場合、ファイル名は入力 URL の最後のパス構成要素につけられた拡張子と同じ拡張子を tempfile.mktemp() につけたものになります。 reporthook を与える場合、この変数は 3 つの数値パラメタを受け取る関数でなくてはなりません。この関数はデータの塊 (chunk) がネットワークから読み込まれるたびに呼び出されます。ローカルの URL を与えた場合 reporthook は無視されます。

url が http: スキーム識別子を使っている場合、オプションの引数 data を与えて POST リクエストを行うよう指定できます(通常のリクエストの形式は GET です)。引数 data は標準の application/x-www-form-urlencoded 形式でなくてはなりません; 上の urlencode() を参照して下さい。

version

URL をオープンするオブジェクトのユーザエージェントを指定する変数です。 urllib を特定のユーザエージェントであるとサーバに通知するには、サブクラスの中でこの値をクラス変数として値を設定するか、コンストラクタの中でベースクラスを呼び出す前に値を設定してください。

class urllib.FancyURLopener(...)

FancyURLopener は URLopener のサブクラスで、以下の HTTP レスポンスコード: 301、302、303、 307、および 401 を取り扱う機能を提供します。レスポンスコード 30x に対しては、 Location ヘッダを使って実際の URL を取得します。レスポンスコード 401 (認証が要求されていることを示す) に対しては、BASIC認証 (basic HTTP authintication) が行われます。レスポンスコード 30x に対しては、最大で maxtries 属性に指定された数だけ再帰呼び出しを行うようになっています。この値はデフォルトで 10 です。

その他のレスポンスコードについては、 http_error_default() が呼ばれます。これはサブクラスでエラーを適切に処理するようにオーバーライドすることができます。

ノート

RFC 2616 [http://tools.ietf.org/html/rfc2616.html] によると、 POST 要求に対する 301 および 302 応答はユーザの承認無しに自動的にリダイレクトしてはなりません。実際は、これらの応答に対して自動リダイレクトを許すブラウザでは POST を GET に変更しており、 urllib でもこの動作を再現します。

コンストラクタに与えるパラメタは URLopener と同じです。

ノート

基本的な HTTP 認証を行う際、 FancyURLopener インスタンスは prompt_user_passwd() メソッドを呼び出します。このメソッドはデフォルトでは実行を制御している端末上で認証に必要な情報を要求するように実装されています。必要ならば、このクラスのサブクラスにおいてより適切な動作をサポートするために prompt_user_passwd() メソッドをオーバライドしてもかまいません。

FancyURLopener クラスはオーバライド可能な追加のメソッドを提供しており、適切な振る舞いをさせることができます:

prompt_user_passwd(host, realm)

指定されたセキュリティ領域 (security realm) 下にある与えられたホストにおいて、ユーザ認証に必要な情報を返すための関数です。この関数が返す値は (user, password) 、からなるタプルなくてはなりません。値はベーシック認証 (basic authentication) で使われます。

このクラスでの実装では、端末に情報を入力するようプロンプトを出します; ローカルの環境において適切な形で対話型モデルを使うには、このメソッドをオーバライドしなければなりません。

exception urllib.ContentTooShortError(msg[, content])

この例外は urlretrieve() 関数が、ダウンロードされたデータの量が予期した量 (Content-Length ヘッダで与えられる) よりも少ないことを検知した際に発生します。 content 属性には (恐らく途中までの) ダウンロードされたデータが格納されています。

バージョン 2.5 で追加.

20.5.4. urllib の制限

現在のところ、以下のプロトコルだけがサポートされています: HTTP、 (バージョン 0.9 および 1.0)、 FTP、およびローカルファイル。

urlretrieve() のキャッシュ機能は、有効期限ヘッダ (Expiration time header) を正しく処理できるようにハックするための時間を取れるまで、無効にしてあります。

ある URL がキャッシュにあるかどうか調べるような関数があればと思っています。。

後方互換性のため、 URL がローカルシステム上のファイルを指しているように見えるにも関わらずファイルを開くことができなければ、 URL は FTP プロトコルを使って再解釈されます。この機能は時として混乱を招くエラーメッセージを引き起こします。

関数 urlopen() および urlretrieve() は、ネットワーク接続が確立されるまでの間、一定でない長さの遅延を引き起こすことがあります。このことは、これらの関数を使ってインタラクティブな Web クライアントを構築するのはスレッドなしには難しいことを意味します。

urlopen() または urlretrieve() が返すデータはサーバが返す生のデータです。このデータはバイナリデータ (画像データ等) 、生テキスト (plain text)、または (例えば) HTML でもかまいません。HTTP プロトコルはリプライヘッダ (reply header) にデータのタイプに関する情報を返します。タイプは Content-Type ヘッダを見ることで推測できます。返されたデータがHTML であれば、 htmllib を使ってパースすることができます。

FTP プロトコルを扱うコードでは、ファイルとディレクトリを区別できません。このことから、アクセスできないファイルを指している URL からデータを読み出そうとすると、予期しない動作を引き起こす場合があります。 URL が / で終わっていれば、ディレクトリを指しているものとみなして、それに適した処理を行います。しかし、ファイルの読み出し操作が 550 エラー (URL が存在しないか、主にパーミッションの理由でアクセスできない) になった場合、 URL がディレクトリを指していて、末尾の / を忘れたケースを処理するため、パスをディレクトリとして扱います。このために、パーミッションのためにアクセスできないファイルを fetch しようとすると、FTP コードはそのファイルを開こうとして 550 エラーに陥り、次にディレクトリ一覧を表示しようとするため、誤解を生むような結果を引き起こす可能性があるのです。よく調整された制御が必要なら、 ftplib モジュールを使うか、 FancyURLopener をサブクラス化するか、 _urlopener を変更して目的に合わせるよう検討してください。

このモジュールは認証を必要とするプロキシをサポートしません。将来実装されるかもしれません。

urllib モジュールは URL 文字列を解釈したり構築したりする (ドキュメント化されていない) ルーチンを含んでいますが、URL を操作するためのインタフェースとしては、 urlparse モジュールをお勧めします。

20.5.5. 使用例

以下は GET メソッドを使ってパラメタを含む URL を取得するセッションの例です:

>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print f.read()

以下は POST メソッドを代わりに使った例です:

>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
>>> print f.read()

以下の例では、環境変数による設定内容に対して上書きする形で HTTP プロキシを明示的に設定しています:

>>> import urllib
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.FancyURLopener(proxies)
>>> f = opener.open("http://www.python.org")
>>> f.read()

以下の例では、環境変数による設定内容に対して上書きする形で、まったくプロキシを使わないよう設定しています:

>>> import urllib
>>> opener = urllib.FancyURLopener({})
>>> f = opener.open("http://www.python.org/")
>>> f.read()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.6. urllib2 — URL を開くための拡張可能なライブラリ

ノート

urllib2 モジュールは、Python 3.0で urllib.request, urllib.error に分割されました。 2to3 ツールが自動的にソースコードのimportを修正します。

urllib2 モジュールは基本的な認証、暗号化認証、リダイレクション、クッキー、その他の介在する複雑なアクセス環境において (大抵は HTTP で) URL を開くための関数とクラスを定義します。

urllib2 モジュールでは以下の関数を定義しています:

urllib2.urlopen(url[, data][, timeout])

URL url を開きます。 url は文字列でも Request オブジェクトでもかまいません。

警告

HTTPS のリクエストはサーバーの認証を一切行いません。

data はサーバに送信する追加のデータを示す文字列か、そのようなデータが無ければ None を指定します。現時点でHTTPリクエストは data をサポートする唯一のリクエスト形式です; data パラメタが指定が指定された場合、HTTP リクエストは GET でなく POST になります。 data は標準的な application/x-www-form-urlencoded 形式のバッファでなくてはなりません。 urllib.urlencode() 関数はマップ型か2タプルのシーケンスを取り、この形式の文字列を返します。 urllib2 モジュールは HTTP/1.1 リクエストを Connection:close ヘッダ付きで送信します。

オプションの timeout 引数は、接続開始などのブロックする操作におけるタイムアウト時間を秒数で指定します。 (指定されなかった場合、グローバルのデフォルトタイムアウト時間が利用されます) この引数は、 HTTP, HTTPS, FTP 接続でのみ有効です。

この関数は以下の 2 つのメソッドを持つファイル類似のオブジェクトを返します:

geturl() — 取得されたリソースの URL を返します。主に、リダイレクトが発生したかどうかを確認するために利用します。

info() — 取得されたページのヘッダーなどのメタ情報を、 mimetools.Message インスタンスとして返します。 (Quick Reference to HTTP Headers [http://www.cs.tut.fi/~jkorpela/http.html] を参照してください)

エラーが発生した場合 URLError を送出します。

どのハンドラもリクエストを処理しなかった場合には None を返すことがあるので注意してください (デフォルトでインストールされるグローバルハンドラの OpenerDirector は、 UnknownHandler を使って上記の問題が起きないようにしています)。

さらに、プロキシが設定されているときは、デフォルトでインストールされる ProxyHandler がリクエストを処理するようになっています。

バージョン 2.6 で変更: timeout 引数が追加されました。

urllib2.install_opener(opener)

標準で URL を開くオブジェクトとして OpenerDirector のインスタンスをインストールします。このコードは引数が本当に OpenerDirector のインスタンスであるかどうかはチェックしないので、適切なインタフェースを持ったクラスは何でも動作します。

urllib2.build_opener([handler, ...])

与えられた順番に URL ハンドラを連鎖させる OpenerDirector のインスタンスを返します。 handler は BaseHandler または BaseHandler のサブクラスのインスタンスのどちらかです (どちらの場合も、コンストラクトは引数無しで呼び出せるようになっていなければなりません) 。以下のクラス:

ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor

については、そのクラスのインスタンスか、そのサブクラスのインスタンスが handler に含まれていない限り、 handler よりも先に連鎖します。

Python が SSL をサポートするように設定してインストールされている場合 (すなわち、 ssl モジュールを import できる場合) HTTPSHandler も追加されます。

Python 2.3 からは、 BaseHandler サブクラスでも handler_order メンバ変数を変更して、ハンドラリスト内での場所を変更できるようになりました。

状況に応じて、以下の例外が送出されます:

exception urllib2.URLError

ハンドラが何らかの問題に遭遇した場合、この例外 (またはこの例外から派生した例外)を送出します。この例外は IOError のサブクラスです。

reason

このエラーの原因。メッセージ文字列か、他の例外のインスタンス(リモートURLの場合は socket.error, ローカルURLの場合は OSError)。

exception urllib2.HTTPError

これは例外(URLError のサブクラス)ですが、このオブジェクトは例外でないファイル類似のオブジェクトとして返り値に使うことができます (urlopen() が返すのと同じものです)。この機能は、例えばサーバからの認証リクエストのように、変わった HTTP エラーを処理するのに役立ちます。

code

RFC 2616 [http://www.faqs.org/rfcs/rfc2616.html] に定義されているHTTPステータスコード。この数値型の値は、 BaseHTTPServer.BaseHTTPRequestHandler.responses の辞書に登録されているコードに対応します。

以下のクラスが提供されています:

class urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])

このクラスは URL リクエストを抽象化したものです。

url は有効な URL を指す文字列でなくてはなりません。

data はサーバに送信する追加のデータを示す文字列か、そのようなデータが無ければ None を指定します。現時点でHTTP リクエストは data をサポートする唯一のリクエスト形式です; data パラメタが指定が指定された場合、HTTP リクエストは GET でなく POST になります。 data は標準的な application/x-www-form-urlencoded 形式のバッファでなくてはなりません。 urllib.urlencode() 関数はマップ型か2タプルのシーケンスを取り、この形式の文字列を返します。

headers は辞書でなくてはなりません。この辞書は add_header() を辞書のキーおよび値を引数として呼び出した時と同じように扱われます。この引数はよく、ブラウザが何であるかを特定する User-Agent ヘッダを偽装するために用いられます。幾つかのHTTPサーバーが、スクリプトからのアクセスを禁止するために、一般的なブラウザの User-Agent ヘッダーしか許可しないからです。例えば、 Mozilla Firefox は User-Agent に "Mozilla/5. (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11" のように設定し、 urllib2 はデフォルトで "Python-urllib/2.6" (Python 2.6の場合)と設定します。

最後の二つの引数は、サードパーティの HTTP クッキーを正しく扱いたい場合にのみ関係してきます:

origin_req_host は、 RFC 2965 [http://tools.ietf.org/html/rfc2965.html] で定義されている元のトランザクションにおけるリクエストホスト (request-host of the origin transaction) です。デフォルトの値は cookielib.request_host(self) です。この値は、ユーザによって開始された元々のリクエストにおけるホスト名や IP アドレスです。例えば、もしリクエストがある HTML ドキュメント内の画像を指していれば、この値は画像を含んでいるページへのリクエストにおけるリクエストホストになるはずです。

unverifiable は、 RFC 2965 [http://tools.ietf.org/html/rfc2965.html] の定義において、該当するリクエストが証明不能 (unverifiable) であるかどうかを示します。デフォルトの値は False です。証明不能なリクエストとは、ユーザが受け入れの可否を選択できないような URL を持つリクエストのことです。例えば、リクエストが HTML ドキュメント中の画像であり、ユーザがこの画像を自動的に取得するかどうかを選択できない場合には、証明不能フラグは True になります。

class urllib2.OpenerDirector

OpenerDirector クラスは、 BaseHandler の連鎖的に呼び出して URL を開きます。このクラスはハンドラをどのように連鎖させるか、またどのようにエラーをリカバリするかを管理します。

class urllib2.BaseHandler

このクラスはハンドラ連鎖に登録される全てのハンドラがベースとしているクラスです – このクラスでは登録のための単純なメカニズムだけを扱います。

class urllib2.HTTPDefaultErrorHandler

HTTP エラー応答のための標準のハンドラを定義します; 全てのレスポンスに対して、例外 HTTPError を送出します。

class urllib2.HTTPRedirectHandler

リダイレクションを扱うクラスです。

class urllib2.HTTPCookieProcessor([cookiejar])

HTTP Cookie を扱うためのクラスです。

class urllib2.ProxyHandler([proxies])

このクラスはプロキシを通過してリクエストを送らせます。引数 proxies を与える場合、プロトコル名からプロキシの URL へ対応付ける辞書でなくてはなりません。標準では、プロキシのリストを環境変数 <protocol>_proxy から読み出します。

プロキシ環境変数が設定されていない場合は、 Windows 環境では、レジストリのインターネット設定セクションからプロキシ設定を手に入れ、 Mac OS X 環境では、 OS X システム設定フレームワーク (System Configuration Framework) からプロキシ情報を取得します。

自動検出されたproxyを無効にするには、空の辞書を渡してください。

class urllib2.HTTPPasswordMgr

(realm, uri) -> (user, password) の対応付けデータベースを保持します。

class urllib2.HTTPPasswordMgrWithDefaultRealm

(realm, uri) -> (user, password) の対応付けデータベースを保持します。レルム None はその他諸々のレルムを表し、他のレルムが該当しない場合に検索されます。

class urllib2.AbstractBasicAuthHandler([password_mgr])

このクラスはHTTP 認証を補助するための混ぜ込みクラス (mixin class) です。遠隔ホストとプロキシの両方に対応しています。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.HTTPBasicAuthHandler([password_mgr])

遠隔ホストとの間での認証を扱います。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクトを参照してください。

class urllib2.ProxyBasicAuthHandler([password_mgr])

プロキシとの間での認証を扱います。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクトを参照してください。

class urllib2.AbstractDigestAuthHandler([password_mgr])

このクラスはHTTP 認証を補助するための混ぜ込みクラス (mixin class) です。遠隔ホストとプロキシの両方に対応しています。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクト を参照してください。

class urllib2.HTTPDigestAuthHandler([password_mgr])

遠隔ホストとの間での認証を扱います。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクトを参照してください。

class urllib2.ProxyDigestAuthHandler([password_mgr])

プロキシとの間での認証を扱います。 password_mgr を与える場合、 HTTPPasswordMgr と互換性がなければなりません; 互換性のためにサポートしなければならないインタフェースについての情報はセクション HTTPPasswordMgr オブジェクトを参照してください。

class urllib2.HTTPHandler

HTTP の URL を開きます。

class urllib2.HTTPSHandler

HTTPS の URL を開きます。

class urllib2.FileHandler

ローカルファイルを開きます。

class urllib2.FTPHandler

FTP の URL を開きます。

class urllib2.CacheFTPHandler

FTP の URL を開きます。遅延を最小限にするために、開かれている FTP 接続に対するキャッシュを保持します。

class urllib2.UnknownHandler

その他諸々のためのクラスで、未知のプロトコルの URL を開きます。

20.6.1. Request オブジェクト

以下のメソッドは Request の全ての公開インタフェースを記述します。従ってサブクラスではこれら全てのメソッドをオーバライドしなければなりません。

Request.add_data(data)

Request のデータを data に設定します。この値は HTTP ハンドラ以外のハンドラでは無視されます。HTTP ハンドラでは、データはバイト文字列でなくてはなりません。このメソッドを使うとリクエストの形式が GET から POST に変更されます。

Request.get_method()

HTTP リクエストメソッドを示す文字列を返します。このメソッドは HTTP リクエストだけに対して意味があり、現状では常に 'GET' か 'POST' のいずれかの値を返します。

Request.has_data()

インスタンスが None でないデータを持つかどうかを返します。

Request.get_data()

インスタンスのデータを返します。

Request.add_header(key, val)

リクエストに新たなヘッダを追加します。ヘッダは HTTP ハンドラ以外のハンドラでは無視されます。HTTP ハンドラでは、引数はサーバに送信されるヘッダのリストに追加されます。同じ名前を持つヘッダを 2 つ以上持つことはできず、 key の衝突が生じた場合、後で追加したヘッダが前に追加したヘッダを上書きします。現時点では、この機能は HTTP の機能を損ねることはありません。というのは、複数回呼び出したときに意味を持つようなヘッダには、どれもただ一つのヘッダを使って同じ機能を果たすための (ヘッダ特有の) 方法があるからです。

Request.add_unredirected_header(key, header)

リダイレクトされたリクエストには追加されないヘッダを追加します。

バージョン 2.4 で追加.

Request.has_header(header)

インスタンスが名前つきヘッダであるかどうかを (通常のヘッダと非リダイレクトヘッダの両方を調べて) 返します。

バージョン 2.4 で追加.

Request.get_full_url()

コンストラクタで与えられた URL を返します。

Request.get_type()

URL のタイプ — いわゆるスキーム (scheme) — を返します。

Request.get_host()

接続を行う先のホスト名を返します。

Request.get_selector()

セレクタ — サーバに送られる URL の一部分 — を返します。

Request.set_proxy(host, type)

リクエストがプロキシサーバを経由するように準備します。 host および type はインスタンスのもとの設定と置き換えられます。インスタンスのセレクタはコンストラクタに与えたもともとの URL になります。

Request.get_origin_req_host()

RFC 2965 [http://tools.ietf.org/html/rfc2965.html] の定義よる、始原トランザクションのリクエストホストを返します。 Request コンストラクタのドキュメントを参照してください。

Request.is_unverifiable()

リクエストが RFC 2965 [http://tools.ietf.org/html/rfc2965.html] の定義における証明不能リクエストであるかどうかを返します。 Request コンストラクタのドキュメントを参照してください。

20.6.2. OpenerDirector オブジェクト

OpenerDirector インスタンスは以下のメソッドを持っています:

OpenerDirector.add_handler(handler)

handler は BaseHandler のインスタンスでなければなりません。以下のメソッドを使った検索が行われ、URL を取り扱うことが可能なハンドラの連鎖が追加されます (HTTP エラーは特別扱いされているので注意してください)。

protocol_open — ハンドラが protocol の URL を開く方法を知っているかどうかを調べます。

http_error_type — ハンドラが HTTP エラーコード type の処理方法を知っていることを示すシグナルです。

protocol_error — ハンドラが (http でない) protocol のエラーを処理する方法を知っていることを示すシグナルです。

protocol_request — ハンドラが protocol リクエストのプリプロセス方法を知っていることを示すシグナルです。

protocol_response — ハンドラが protocol リクエストのポストプロセス方法を知っていることを示すシグナルです。

OpenerDirector.open(url[, data][, timeout])

与えられた url (リクエストオブジェクトでも文字列でもかまいません) を開きます。オプションとして data を与えることができます。引数、返り値、および送出される例外は urlopen() と同じです (urlopen() の場合、標準でインストールされているグローバルな OpenerDirector の open() メソッドを呼び出します) 。オプションの timeout 引数は、接続開始のようなブロックする処理におけるタイムアウト時間を秒数で指定します。(指定しなかった場合は、グローバルのデフォルト設定が利用されます) タイムアウト機能は、 HTTP, HTTPS, FTP 接続でのみ有効です。

バージョン 2.6 で変更: timeout 引数が追加されました

OpenerDirector.error(proto[, arg[, ...]])

与えられたプロトコルにおけるエラーを処理します。このメソッドは与えられたプロトコルにおける登録済みのエラーハンドラを (プロトコル固有の) 引数で呼び出します。 HTTP プロトコルは特殊なケースで、特定のエラーハンドラを選び出すのに HTTP レスポンスコードを使います; ハンドラクラスの http_error_*() メソッドを参照してください。

返り値および送出される例外は urlopen() と同じものです。

OpenerDirector オブジェクトは、以下の 3 つのステージに分けて URL を開きます:

各ステージで OpenerDirector オブジェクトのメソッドがどのような順で呼び出されるかは、ハンドラインスタンスの並び方で決まります。

protocol_request 形式のメソッドを持つ全てのハンドラに対してそのメソッドを呼び出し、リクエストのプリプロセスを行います。

protocol_open 形式のメソッドを持つハンドラを呼び出し、リクエストを処理します。このステージは、ハンドラが None でない値 (すなわちレスポンス) を返すか、例外 (通常は URLError) を送出した時点で終了します。例外は伝播 (propagate) できます。

実際には、上のアルゴリズムではまず default_open() という名前のメソッドを呼び出します。このメソッドが全て None を返す場合、同じアルゴリズムを繰り返して、今度は protocol_open 形式のメソッドを試します。メソッドが全て None を返すと、さらに同じアルゴリズムを繰り返して unknown_open() を呼び出します。

これらのメソッドの実装には、親となる OpenerDirector インスタンスの open() や error() といったメソッド呼び出しが入る場合があるので注意してください。

protocol_response 形式のメソッドを持つ全てのハンドラに対してそのメソッドを呼び出し、リクエストのポストプロセスを行います。

20.6.3. BaseHandler オブジェクト

BaseHandler オブジェクトは直接的に役に立つ 2 つのメソッドと、その他として派生クラスで使われることを想定したメソッドを提供します。以下は直接的に使うためのメソッドです:

BaseHandler.add_parent(director)

親オブジェクトとして、 director を追加します。

BaseHandler.close()

全ての親オブジェクトを削除します。

以下のメンバおよびメソッドは BaseHandler から派生したクラスでのみ使われます:

ノート

慣習的に、 protocol_request() や protocol_response() といったメソッドを定義しているサブクラスは *Processor と名づけ、その他は * Handler と名づけることになっています

BaseHandler.parent

有効な OpenerDirector です。この値は違うプロトコルを使って URL を開く場合やエラーを処理する際に使われます。

BaseHandler.default_open(req)

このメソッドは BaseHandler では定義されて いません 。しかし、全ての URL をキャッチさせたいなら、サブクラスで定義する必要があります。

このメソッドが定義されていた場合、 OpenerDirector から呼び出されます。このメソッドは OpenerDirector のメソッド open() が返す値について記述されているようなファイル類似のオブジェクトか、 None を返さなくてはなりません。このメソッドが送出する例外は、真に例外的なことが起きない限り、 URLError を送出しなければなりません (例えば、 MemoryError を URLError をマップしてはいけません)。

このメソッドはプロトコル固有のオープンメソッドが呼び出される前に呼び出されます。

BaseHandler.protocol_open(req)

(“protocol” は実際にはプロトコル名です)

このメソッドは BaseHandler では定義されて いません 。しかし protocol の URL をキャッチしたいなら、サブクラスで定義する必要があります。

このメソッドが定義されていた場合、 OpenerDirector から呼び出されます。戻り値は default_open() と同じでなければなりません。

BaseHandler.unknown_open(req)

このメソッドは BaseHandler では定義されて いません 。しかし URL を開くための特定のハンドラが登録されていないような URL をキャッチしたいなら、サブクラスで定義する必要があります。

このメソッドが定義されていた場合、 OpenerDirector から呼び出されます。戻り値は default_open() と同じでなければなりません。

BaseHandler.http_error_default(req, fp, code, msg, hdrs)

このメソッドは BaseHandler では定義されて いません 。しかしその他の処理されなかった HTTP エラーを処理する機能をもたせたいなら、サブクラスで定義する必要があります。このメソッドはエラーに遭遇した OpenerDirector から自動的に呼び出されます。その他の状況では普通呼び出すべきではありません。

req は Request オブジェクトで、 fp は HTTP エラー本体を読み出せるようなファイル類似のオブジェクトになります。 code は 3 桁の 10 進数からなるエラーコードで、 msg ユーザ向けのエラーコード解説です。 hdrs はエラー応答のヘッダをマップしたオブジェクトです。

返される値および送出される例外は urlopen() と同じものでなければなりません。

BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)

nnn は 3 桁の 10 進数からなる HTTP エラーコードでなくてはなりません。このメソッドも BaseHandler では定義されていませんが、サブクラスのインスタンスで定義されていた場合、エラーコード nnn の HTTP エラーが発生した際に呼び出されます。

特定の HTTP エラーに対する処理を行うためには、このメソッドをサブクラスでオーバライドする必要があります。

引数、返される値、および送出される例外は http_error_default() と同じものでなければなりません。

BaseHandler.protocol_request(req)

(“protocol” は実際にはプロトコル名です)

このメソッドは BaseHandler では 定義されていません が、サブクラスで特定の protocol のリクエストのプリプロセスを行いたい場合には定義する必要があります。

このメソッドが定義されていると、親となる OpenerDirector から呼び出されます。その際、 req は Request オブジェクトになります。戻り値は Request オブジェクトでなければなりません。

BaseHandler.protocol_response(req, response)

(“protocol” は実際にはプロトコル名です)

このメソッドは BaseHandler では 定義されていません が、サブクラスで特定の protocol のリクエストのポストプロセスを行いたい場合には定義する必要があります。

このメソッドが定義されていると、親となる OpenerDirector から呼び出されます。その際、 req は Request オブジェクトになります。 response は urlopen() の戻り値と同じインタフェースを実装したオブジェクトになります。戻り値もまた、 urlopen() の戻り値と同じインタフェースを実装したオブジェクトでなければなりません。

20.6.4. HTTPRedirectHandler オブジェクト

ノート

HTTP リダイレクトによっては、このモジュールのクライアントコード側での処理を必要とします。その場合、 HTTPError が送出されます。様々なリダイレクトコードの厳密な意味に関する詳細は RFC 2616 [http://tools.ietf.org/html/rfc2616.html] を参照してください。

HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)

リダイレクトの通知に応じて、 Request または None を返します。このメソッドは http_error_30*() メソッドにおいて、リダイレクトの通知をサーバから受信した際に、デフォルトの実装として呼び出されます。リダイレクトを起こす場合、新たな Request を生成して、 http_error_30*() が newurl へリダイレクトを実行できるようにします。そうでない場合、他のどのハンドラにもこの URL を処理させたくなければ HTTPError を送出し、リダイレクト処理を行うことはできないが他のハンドラなら可能かもしれない場合には None を返します。

ノート

このメソッドのデフォルトの実装は、 RFC 2616 [http://tools.ietf.org/html/rfc2616.html] に厳密に従ったものではありません。 RFC 2616 [http://tools.ietf.org/html/rfc2616.html] では、 POST リクエストに対する 301 および 302 応答が、ユーザの承認なく自動的にリダイレクトされてはならないと述べています。現実には、ブラウザは POST を GET に変更することで、これらの応答に対して自動的にリダイレクトを行えるようにしています。デフォルトの実装でも、この挙動を再現しています。

HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)

Location: か URI: のURL にリダイレクトします。このメソッドは HTTP における ‘moved permanently’ レスポンスを取得した際に親オブジェクトとなる OpenerDirector によって呼び出されます。

HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)

http_error_301() と同じですが、’found’ レスポンスに対して呼び出されます。

HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)

http_error_301() と同じですが、’see other’ レスポンスに対して呼び出されます。

HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)

http_error_301() と同じですが、’temporary redirect’ レスポンスに対して呼び出されます。

20.6.5. HTTPCookieProcessor オブジェクト

バージョン 2.4 で追加.

HTTPCookieProcessor インスタンスは属性をひとつだけ持ちます:

HTTPCookieProcessor.cookiejar

クッキーの入っている cookielib.CookieJar オブジェクトです。

20.6.6. ProxyHandler オブジェクト

ProxyHandler.protocol_open(request)

(“protocol” は実際にはプロトコル名です)

ProxyHandler は、コンストラクタで与えた辞書 proxies にプロキシが設定されているような protocol 全てについて、メソッド protocol_open を持つことになります。このメソッドは request.set_proxy() を呼び出して、リクエストがプロキシを通過できるように修正します。その後連鎖するハンドラの中から次のハンドラを呼び出して実際にプロトコルを実行します。

20.6.7. HTTPPasswordMgr オブジェクト

以下のメソッドは HTTPPasswordMgr および HTTPPasswordMgrWithDefaultRealm オブジェクトで利用できます。

HTTPPasswordMgr.add_password(realm, uri, user, passwd)

uri は単一の URI でも複数の URI からなるシーケンスでもかまいません。 realm 、 user および passwd は文字列でなくてはなりません。このメソッドによって、 realm と与えられた URI の上位 URI に対して (user, passwd) が認証トークンとして使われるようになります。

HTTPPasswordMgr.find_user_password(realm, authuri)

与えられたレルムおよび URI に対するユーザ名またはパスワードがあればそれを取得します。該当するユーザ名／パスワードが存在しない場合、このメソッドは (None, None) を返します。

HTTPPasswordMgrWithDefaultRealm オブジェクトでは、与えられた realm に対して該当するユーザ名/パスワードが存在しない場合、レルム None が検索されます。

20.6.8. AbstractBasicAuthHandler オブジェクト

AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

ユーザ名／パスワードを取得し、再度サーバへのリクエストを試みることで、サーバからの認証リクエストを処理します。 authreq はリクエストにおいてレルムに関する情報が含まれているヘッダの名前、 host は認証を行う対象の URL とパスを指定します、 req は (失敗した) Request オブジェクト、そして headers はエラーヘッダでなくてはなりません。

host は、オーソリティ (例 "python.org") か、オーソリティコンポーネントを含む URL (例 "http://python.org") です。どちらの場合も、オーソリティはユーザ情報コンポーネントを含んではいけません (なので、 "python.org" や "python.org:80" は正しく、 "joe:password@python.org" は不正です) 。

20.6.9. HTTPBasicAuthHandler オブジェクト

HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)

認証情報がある場合、認証情報付きで再度リクエストを試みます。

20.6.10. ProxyBasicAuthHandler オブジェクト

ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)

認証情報がある場合、認証情報付きで再度リクエストを試みます。

20.6.11. AbstractDigestAuthHandler オブジェクト

AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)

authreq はリクエストにおいてレルムに関する情報が含まれているヘッダの名前、 host は認証を行う対象のホスト名、 req は (失敗した) Request オブジェクト、そして headers はエラーヘッダでなくてはなりません。

20.6.12. HTTPDigestAuthHandler オブジェクト

HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)

認証情報がある場合、認証情報付きで再度リクエストを試みます。

20.6.13. ProxyDigestAuthHandler オブジェクト

ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)

認証情報がある場合、認証情報付きで再度リクエストを試みます。

20.6.14. HTTPHandler オブジェクト

HTTPHandler.http_open(req)

HTTP リクエストを送ります。 req.has_data() に応じて、 GET または POST のどちらでも送ることができます。

20.6.15. HTTPSHandler オブジェクト

HTTPSHandler.https_open(req)

HTTPS リクエストを送ります。 req.has_data() に応じて、 GET または POST のどちらでも送ることができます。

20.6.16. FileHandler オブジェクト

FileHandler.file_open(req)

ホスト名がない場合、またはホスト名が 'localhost' の場合にファイルをローカルでオープンします。そうでない場合、プロトコルを ftp に切り替え、 parent を使って再度オープンを試みます。

20.6.17. FTPHandler オブジェクト

FTPHandler.ftp_open(req)

req で表されるファイルを FTP 越しにオープンします。ログインは常に空のユーザネームおよびパスワードで行われます。

20.6.18. CacheFTPHandler オブジェクト

CacheFTPHandler オブジェクトは FTPHandler オブジェクトに以下のメソッドを追加したものです:

CacheFTPHandler.setTimeout(t)

接続のタイムアウトを t 秒に設定します。

CacheFTPHandler.setMaxConns(m)

キャッシュ付き接続の最大接続数を m に設定します。

20.6.19. UnknownHandler オブジェクト

UnknownHandler.unknown_open()

例外 URLError を送出します。

20.6.20. HTTPErrorProcessor オブジェクト

バージョン 2.4 で追加.

HTTPErrorProcessor.unknown_open()

HTTP エラーレスポンスを処理します。

エラーコード 200 の場合、レスポンスオブジェクトを即座に返します。

200 以外のエラーコードの場合、 OpenerDirector.error() を介して protocol_error_code メソッドに仕事を引き渡します。最終的にどのハンドラもエラーを処理しなかった場合、 urllib2.HTTPDefaultErrorHandler が HTTPError を送出します。

20.6.21. 例

以下の例では、 python.org のメインページを取得して、その最初の 100 バイト分を表示します:

>>> import urllib2
>>> f = urllib2.urlopen('http://www.python.org/')
>>> print f.read(100)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<?xml-stylesheet href="./css/ht2html

今度は CGI の標準入力にデータストリームを送信し、CGI が返すデータを読み出します。この例は Python が SSL をサポートしている場合にのみ動作することに注意してください。

>>> import urllib2
>>> req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',
...                       data='This data is passed to stdin of the CGI')
>>> f = urllib2.urlopen(req)
>>> print f.read()
Got Data: "This data is passed to stdin of the CGI"

上の例で使われているサンプルの CGI は以下のようになっています:

#!/usr/bin/env python
import sys
data = sys.stdin.read()
print 'Content-type: text-plain\n\nGot Data: "%s"' % data

以下はベーシック HTTP 認証の例です:

import urllib2
# ベーシック HTTP 認証をサポートする OpenerDirector を作成する...
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
                          uri='https://mahler:8092/site-updates.py',
                          user='klem',
                          passwd='kadidd!ehopper')
opener = urllib2.build_opener(auth_handler)
# ...urlopen から利用できるよう、グローバルにインストールする
urllib2.install_opener(opener)
urllib2.urlopen('http://www.example.com/login.html')

build_opener() はデフォルトで沢山のハンドラを提供しており、その中に ProxyHandler があります。デフォルトでは、 ProxyHandler は <scheme>_proxy という環境変数を使います。ここで <scheme> は URL スキームです。例えば、 HTTP プロキシの URL を得るには、環境変数 http_proxy を読み出します。

この例では、デフォルトの ProxyHandler を置き換えてプログラム的に作成したプロキシ URL を使うようにし、 ProxyBasicAuthHandler でプロキシ認証サポートを追加します。

proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib2.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')

opener = urllib2.build_opener(proxy_handler, proxy_auth_handler)
# 今回は OpenerDirector をインストールするのではなく直接使います:
opener.open('http://www.example.com/login.html')

以下は HTTP ヘッダを追加する例です:

headers 引数を使って Request コンストラクタを呼び出す方法の他に、以下のようにできます:

import urllib2
req = urllib2.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
r = urllib2.urlopen(req)

OpenerDirector は全ての Request に User-Agent ヘッダを自動的に追加します。これを変更するには:

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')

のようにします。

また、 Request が urlopen() (や OpenerDirector.open()) に渡される際には、いくつかの標準ヘッダ (Content-Length, Content-Type および Host) も追加されることを忘れないでください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.7. httplib — HTTP プロトコルクライアント

ノート

httplib モジュールは、Python 3.0 では http.client にリネームされました。 2to3 ツールが自動的にソースコードのimportを修正します。

このモジュールでは HTTP および HTTPS プロトコルのクライアント側を実装しているクラスを定義しています。通常、このモジュールは直接使いません — urllib モジュールが HTTP や HTTPS を使った URL を扱う上でこのモジュールを使います。

ノート

HTTPS のサポートは、SSL をサポートするように socket モジュールをコンパイルした場合にのみ利用できます。

このモジュールでは以下のクラスを提供しています:

class httplib.HTTPConnection(host[, port[, strict[, timeout[, source_address]]]])

HTTPConnection インスタンスは、HTTP サーバとの一回のトランザクションを表現します。インスタンスの生成はホスト名とオプションのポート番号を与えて行います。ポート番号を指定しなかった場合、ホスト名文字列が host:port の形式であれば、ホスト名からポート番号を導き、そうでない場合には標準の HTTP ポート番号 (80) を使います。

オプションの引数 strict に True が渡された場合(デフォルトでは False)、ステータスラインが正しい(valid)　HTTP/1.0 もしくは 1.1 status line としてパースできなかった時に、 BadStatusLine 例外を発生させます。

オプションの引数 timeout が渡された場合、ブロックする処理(コネクション接続など) のタイムアウト時間(秒数)として利用されます。(渡されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます。)

オプションの引数 source_address を (host, port) という形式のタプルにすると HTTP 接続の接続元アドレスとして使用します。

例えば、以下の呼び出しは全て同じサーバの同じポートに接続するインスタンスを生成します:

>>> h1 = httplib.HTTPConnection('www.cwi.nl')
>>> h2 = httplib.HTTPConnection('www.cwi.nl:80')
>>> h3 = httplib.HTTPConnection('www.cwi.nl', 80)
>>> h3 = httplib.HTTPConnection('www.cwi.nl', 80, timeout=10)

バージョン 2.0 で追加.

バージョン 2.6 で変更: timeout 引数が追加されました

バージョン 2.7 で変更: source_address 引数が追加されました

class httplib.HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address]]]]]])

HTTPConnection のサブクラスで、セキュアなサーバと通信するために SSL を使います。標準のポート番号は 443 です。 key_file には、秘密鍵を格納したPEM形式ファイルのファイル名を指定します。 cert_file には、PEM形式の証明書チェーンファイルを指定します。

警告

この関数はサーバ証明書の検査を行いません

バージョン 2.6 で変更: timeout 引数が追加されました

バージョン 2.7 で変更: source_address 引数が追加されました

class httplib.HTTPResponse(sock[, debuglevel=0][, strict=0])

コネクションに成功したときに、このクラスのインスタンスが返されます。ユーザーから直接利用されることはありません。

バージョン 2.0 で追加.

class httplib.HTTPMessage

HTTPMessage のインスタンスは、 HTTP レスポンスヘッダを格納するために利用されます。 mimetools.Message クラスを利用して実装されていて、 HTTP ヘッダを扱うための便利な関数を提供しています。このクラスはユーザーが直接インスタンス生成するものではありません。

必要に応じて以下の例外が送出されます:

exception httplib.HTTPException

このモジュールにおける他の例外クラスの基底クラスです。 Exception のサブクラスです。

バージョン 2.0 で追加.

exception httplib.NotConnected

HTTPException サブクラスです。

バージョン 2.0 で追加.

exception httplib.InvalidURL

HTTPException のサブクラスです。ポート番号を指定したものの、その値が数字でなかったり空のオブジェクトであった場合に送出されます。

バージョン 2.3 で追加.

exception httplib.UnknownProtocol

HTTPException のサブクラスです。

exception httplib.UnknownTransferEncoding

HTTPException のサブクラスです。

exception httplib.IllegalKeywordArgument

HTTPException のサブクラスです。

exception httplib.UnimplementedFileMode

HTTPException のサブクラスです。

exception httplib.IncompleteRead

HTTPException のサブクラスです。

exception httplib.ImproperConnectionState

HTTPException のサブクラスです。

exception httplib.CannotSendRequest

ImproperConnectionState のサブクラスです。

exception httplib.CannotSendHeader

ImproperConnectionState のサブクラスです。

exception httplib.ResponseNotReady

ImproperConnectionState のサブクラスです。

exception httplib.BadStatusLine

HTTPException のサブクラスです。サーバが理解できない HTTP 状態コードで応答した場合に送出されます。

このモジュールで定義されている定数は以下の通りです:

httplib.HTTP_PORT

HTTP プロトコルの標準のポート (通常は 80) です。

httplib.HTTPS_PORT

HTTPS プロトコルの標準のポート (通常は 443) です。

また、整数の状態コードについて以下の定数が定義されています:

Constant | Value | Definition
CONTINUE | 100 | HTTP/1.1, RFC 2616, Section 10.1.1 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1]
SWITCHING_PROTOCOLS | 101 | HTTP/1.1, RFC 2616, Section 10.1.2 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2]
PROCESSING | 102 | WEBDAV, RFC 2518, Section 10.1 [http://www.webdav.org/specs/rfc2518.html#STATUS_102]
OK | 200 | HTTP/1.1, RFC 2616, Section 10.2.1 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1]
CREATED | 201 | HTTP/1.1, RFC 2616, Section 10.2.2 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2]
ACCEPTED | 202 | HTTP/1.1, RFC 2616, Section 10.2.3 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3]
NON_AUTHORITATIVE_INFORMATION | 203 | HTTP/1.1, RFC 2616, Section 10.2.4 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4]
NO_CONTENT | 204 | HTTP/1.1, RFC 2616, Section 10.2.5 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5]
RESET_CONTENT | 205 | HTTP/1.1, RFC 2616, Section 10.2.6 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6]
PARTIAL_CONTENT | 206 | HTTP/1.1, RFC 2616, Section 10.2.7 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7]
MULTI_STATUS | 207 | WEBDAV RFC 2518, Section 10.2 [http://www.webdav.org/specs/rfc2518.html#STATUS_207]
IM_USED | 226 | Delta encoding in HTTP, RFC 3229 [http://tools.ietf.org/html/rfc3229.html], Section 10.4.1
MULTIPLE_CHOICES | 300 | HTTP/1.1, RFC 2616, Section 10.3.1 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1]
MOVED_PERMANENTLY | 301 | HTTP/1.1, RFC 2616, Section 10.3.2 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2]
FOUND | 302 | HTTP/1.1, RFC 2616, Section 10.3.3 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3]
SEE_OTHER | 303 | HTTP/1.1, RFC 2616, Section 10.3.4 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4]
NOT_MODIFIED | 304 | HTTP/1.1, RFC 2616, Section 10.3.5 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5]
USE_PROXY | 305 | HTTP/1.1, RFC 2616, Section 10.3.6 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6]
TEMPORARY_REDIRECT | 307 | HTTP/1.1, RFC 2616, Section 10.3.8 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8]
BAD_REQUEST | 400 | HTTP/1.1, RFC 2616, Section 10.4.1 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1]
UNAUTHORIZED | 401 | HTTP/1.1, RFC 2616, Section 10.4.2 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2]
PAYMENT_REQUIRED | 402 | HTTP/1.1, RFC 2616, Section 10.4.3 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3]
FORBIDDEN | 403 | HTTP/1.1, RFC 2616, Section 10.4.4 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4]
NOT_FOUND | 404 | HTTP/1.1, RFC 2616, Section 10.4.5 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5]
METHOD_NOT_ALLOWED | 405 | HTTP/1.1, RFC 2616, Section 10.4.6 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6]
NOT_ACCEPTABLE | 406 | HTTP/1.1, RFC 2616, Section 10.4.7 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7]
PROXY_AUTHENTICATION_REQUIRED | 407 | HTTP/1.1, RFC 2616, Section 10.4.8 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8]
REQUEST_TIMEOUT | 408 | HTTP/1.1, RFC 2616, Section 10.4.9 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9]
CONFLICT | 409 | HTTP/1.1, RFC 2616, Section 10.4.10 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10]
GONE | 410 | HTTP/1.1, RFC 2616, Section 10.4.11 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11]
LENGTH_REQUIRED | 411 | HTTP/1.1, RFC 2616, Section 10.4.12 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12]
PRECONDITION_FAILED | 412 | HTTP/1.1, RFC 2616, Section 10.4.13 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13]
REQUEST_ENTITY_TOO_LARGE | 413 | HTTP/1.1, RFC 2616, Section 10.4.14 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14]
REQUEST_URI_TOO_LONG | 414 | HTTP/1.1, RFC 2616, Section 10.4.15 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15]
UNSUPPORTED_MEDIA_TYPE | 415 | HTTP/1.1, RFC 2616, Section 10.4.16 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16]
REQUESTED_RANGE_NOT_SATISFIABLE | 416 | HTTP/1.1, RFC 2616, Section 10.4.17 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17]
EXPECTATION_FAILED | 417 | HTTP/1.1, RFC 2616, Section 10.4.18 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18]
UNPROCESSABLE_ENTITY | 422 | WEBDAV, RFC 2518, Section 10.3 [http://www.webdav.org/specs/rfc2518.html#STATUS_422]
LOCKED | 423 | WEBDAV RFC 2518, Section 10.4 [http://www.webdav.org/specs/rfc2518.html#STATUS_423]
FAILED_DEPENDENCY | 424 | WEBDAV, RFC 2518, Section 10.5 [http://www.webdav.org/specs/rfc2518.html#STATUS_424]
UPGRADE_REQUIRED | 426 | HTTP Upgrade to TLS, RFC 2817 [http://tools.ietf.org/html/rfc2817.html], Section 6
INTERNAL_SERVER_ERROR | 500 | HTTP/1.1, RFC 2616, Section 10.5.1 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1]
NOT_IMPLEMENTED | 501 | HTTP/1.1, RFC 2616, Section 10.5.2 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2]
BAD_GATEWAY | 502 | HTTP/1.1 RFC 2616, Section 10.5.3 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3]
SERVICE_UNAVAILABLE | 503 | HTTP/1.1, RFC 2616, Section 10.5.4 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4]
GATEWAY_TIMEOUT | 504 | HTTP/1.1 RFC 2616, Section 10.5.5 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5]
HTTP_VERSION_NOT_SUPPORTED | 505 | HTTP/1.1, RFC 2616, Section 10.5.6 [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6]
INSUFFICIENT_STORAGE | 507 | WEBDAV, RFC 2518, Section 10.6 [http://www.webdav.org/specs/rfc2518.html#STATUS_507]
NOT_EXTENDED | 510 | An HTTP Extension Framework, RFC 2774 [http://tools.ietf.org/html/rfc2774.html], Section 7

httplib.responses

このディクショナリは、HTTP 1.1ステータスコードをW3Cの名前にマップしたものです。

たとえば httplib.responses[httplib.NOT_FOUND] は 'Not Found' となります。

バージョン 2.5 で追加.

20.7.1. HTTPConnection オブジェクト

HTTPConnection インスタンスには以下のメソッドがあります:

HTTPConnection.request(method, url[, body[, headers]])

このメソッドは、 HTTP 要求メソッド method およびセレクタ url を使って、要求をサーバに送ります。 body 引数を指定する場合、ヘッダが終了した後に送信する文字列データでなければなりません。もしくは、開いているファイルオブジェクトを body に渡すこともできます。その場合、そのファイルの内容が送信されます。このファイルオブジェクトは、 fileno() と read() メソッドをサポートしている必要があります。ヘッダの Content-Length は自動的に正しい値に設定されます。 headers 引数は要求と同時に送信される拡張 HTTP ヘッダの内容からなるマップ型でなくてはなりません。

バージョン 2.6 で変更: body にファイルオブジェクトを渡せるようになりました

HTTPConnection.getresponse()

サーバに対して HTTP 要求を送り出した後に呼び出されなければりません。要求に対する応答を取得します。 HTTPResponse インスタンスを返します。

ノート

すべての応答を読み込んでからでなければ新しい要求をサーバに送ることはできないことに注意しましょう。

HTTPConnection.set_debuglevel(level)

デバッグレベル (印字されるデバッグ出力の量) を設定します。標準のデバッグレベルは 0 で、デバッグ出力を全く印字しません。

HTTPConnection.set_tunnel(host, port=None, headers=None)

HTTP トンネリング接続のホスト名とポート番号を設定します。通常はプロキシサーバを通して HTTP 接続を行うときに必要になります。

ヘッダのパラメータは CONNECT リクエストで送信するために他の HTTP ヘッダにマッピングされます。

バージョン 2.7 で追加.

HTTPConnection.connect()

オブジェクトを生成するときに指定したサーバに接続します。

HTTPConnection.close()

サーバへの接続を閉じます。

上で説明した request() メソッドを使うかわりに、以下の4つの関数を使用して要求をステップバイステップで送信することもできます。

HTTPConnection.putrequest(request, selector[, skip_host[, skip_accept_encoding]])

サーバへの接続が確立したら、最初にこのメソッドを呼び出さなくてはなりません。このメソッドは request 文字列、 selector 文字列、そして HTTP バージョン (HTTP/1.1) からなる一行を送信します。 Host: や Accept-Encoding: ヘッダの自動送信を無効にしたい場合 (例えば別のコンテンツエンコーディングを受け入れたい場合) には、 skip_host や skip_accept_encoding を偽でない値に設定してください。

HTTPConnection.putheader(header, argument[, ...])

RFC 822 [http://tools.ietf.org/html/rfc822.html] 形式のヘッダをサーバに送ります。この処理では、 header 、コロンとスペース、そして最初の引数からなる 1 行をサーバに送ります。追加の引数を指定した場合、継続して各行にタブ一つと引数の入った引数行が送信されます。

HTTPConnection.endheaders()

サーバに空行を送り、ヘッダ部が終了したことを通知します。

HTTPConnection.send(data)

サーバにデータを送ります。このメソッドは endheaders() が呼び出された直後で、かつ getreply() が呼び出される前に使わなければなりません。

20.7.2. HTTPResponse オブジェクト

HTTPResponse インスタンスは以下のメソッドと属性を持ちます:

HTTPResponse.read([amt])

応答の本体全体か、 amt バイトまで読み出して返します。

HTTPResponse.getheader(name[, default])

ヘッダ name の内容を取得して返すか、該当するヘッダがない場合には default を返します。

HTTPResponse.getheaders()

(header, value) のタプルからなるリストを返します。

バージョン 2.4 で追加.

HTTPResponse.fileno()

ソケットの fileno を返します。

HTTPResponse.msg

応答ヘッダを含む mimetools.Message インスタンスです。

HTTPResponse.version

サーバが使用した HTTP プロトコルバージョンです。10 は HTTP/1.0 を、 11 は HTTP/1.1 を表します。

HTTPResponse.status

サーバから返される状態コードです。

HTTPResponse.reason

サーバから返される応答の理由文です。

20.7.3. 例

以下は GET リクエストの送信方法を示した例です。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.python.org")
>>> conn.request("GET", "/index.html")
>>> r1 = conn.getresponse()
>>> print r1.status, r1.reason
200 OK
>>> data1 = r1.read()
>>> conn.request("GET", "/parrot.spam")
>>> r2 = conn.getresponse()
>>> print r2.status, r2.reason
404 Not Found
>>> data2 = r2.read()
>>> conn.close()

次の例のセッションでは、 HEAD メソッドを利用しています。 HEAD メソッドは全くデータを返さないことに注目してください。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.python.org")
>>> conn.request("HEAD","/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> data = res.read()
>>> print len(data)
0
>>> data == ''
True

以下は POST リクエストの送信方法を示した例です:

>>> import httplib, urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
...            "Accept": "text/plain"}
>>> conn = httplib.HTTPConnection("musi-cal.mojam.com:80")
>>> conn.request("POST", "/cgi-bin/query", params, headers)
>>> response = conn.getresponse()
>>> print response.status, response.reason
200 OK
>>> data = response.read()
>>> conn.close()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.8. ftplib — FTPプロトコルクライアント

このモジュールでは FTP クラスと、それに関連するいくつかの項目を定義しています。 FTP クラスは、FTPプロトコルのクライアント側の機能を備えています。このクラスを使うとFTPのいろいろな機能の自動化、例えば他のFTPサーバのミラーリングといったことを実行するPythonプログラムを書くことができます。また、 urllib モジュールもFTPを使うURLを操作するのにこのクラスを使っています。 FTP (File Transfer Protocol)についての詳しい情報はInternet RFC 959 [http://tools.ietf.org/html/rfc959.html] を参照して下さい。

ftplib モジュールを使ったサンプルを以下に示します:

>>> from ftplib import FTP
>>> ftp = FTP('ftp.cwi.nl')   # ホストのデフォルトポートへ接続
>>> ftp.login()               # ユーザ名 anonymous、パスワード anonyumou
s@
>>> ftp.retrlines('LIST')     # ディレクトリの内容をリストアップ
total 24418
drwxrwsr-x   5 ftp-usr  pdmaint     1536 Mar 20 09:48 .
dr-xr-srwt 105 ftp-usr  pdmaint     1536 Mar 21 14:32 ..
-rw-r--r--   1 ftp-usr  pdmaint     5305 Mar 20 09:48 INDEX
 .
 .
 .
>>> ftp.retrbinary('RETR README', open('README', 'wb').write)
'226 Transfer complete.'
>>> ftp.quit()

このモジュールは以下の項目を定義しています。

class ftplib.FTP([host[, user[, passwd[, acct[, timeout]]]]])

FTP クラスの新しいインスタンスを返します。 host が与えられると、 connect(host) メソッドが実行されます。 user が与えられると、さらに login(user, passwd, acct) メソッドが実行されます（この passwd と acct は指定されなければデフォルトでは空文字列です）。

オプションの timeout 引数は、コネクションの接続時など、ブロックする操作におけるタイムアウト時間を秒数で指定します。 (指定されなかった場合、グローバルのデフォルトタイムアウト設定が利用されます。)

バージョン 2.6 で変更: timeout が追加されました。

class ftplib.FTP_TLS([host[, user[, passwd[, acct[, keyfile[, certfile[, timeout]]]]]]])

RFC 4217 [http://tools.ietf.org/html/rfc4217.html] に記述されている TLS サポートを FTP に加えた FTP のサブクラスです。認証の前に FTP コントロール接続を暗示的にセキュアにし、通常通りに port 21 に接続します。データ接続をセキュアにするには、ユーザが prot_p() メソッドを呼び出してそれを明示的に要求しなければなりません。 keyfile と certfile は省略可できます – これらは、SSL 接続のための、 PEM フォーマットの秘密鍵と証明書チェーンファイル名を含むことができます。

バージョン 2.7 で追加.

FTP_TLS クラスを使ったサンプルセッションはこちらです:

>>> from ftplib import FTP_TLS
>>> ftps = FTP_TLS('ftp.python.org')
>>> ftps.login()           # 制御チャネルをセキュアにする前に匿名でログインする
>>> ftps.prot_p()          # セキュアなデータ接続に移行する
>>> ftps.retrlines('LIST') # ディレクトリの内容をセキュアに列挙する
total 9
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
-rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg
'226 Transfer complete.'
>>> ftps.quit()
>>>

exception ftplib.error_reply

サーバから想定外の応答があった時に発生する例外。

exception ftplib.error_temp

一時的エラーを表すエラーコード(400–499の範囲の応答コード)を受け取った時に発生する例外。

exception ftplib.error_perm

永久エラーを表すエラーコード(500–599の範囲の応答コード)を受け取った時に発生する例外。

exception ftplib.error_proto

File Transfer Protocol の応答仕様に適合しない、すなわち1–5の数字で始まらない応答コードをサーバから受け取った時に発生する例外。

ftplib.all_errors

FTP インスタンスのメソッド実行時、FTP接続で（プログラミングのエラーと考えられるメソッドの実行によって）発生する全ての例外（タプル形式）。この例外には以上の４つのエラーはもちろん、 socket.error と IOError も含まれます。

参考

Module netrc

.netrc ファイルフォーマットのパーザ。 .netrc ファイルは、 FTPクライアントがユーザにプロンプトを出す前に、ユーザ認証情報をロードするのによく使われます。

Pythonのソースディストリビューションの Tools/scripts/ftpmi rror.py ファイルは、FTPサイトあるいはその一部をミラーリングするスクリプトで、 ftplib モジュールを使っています。このモジュールを適用した応用例として使うことができます。

20.8.1. FTP オブジェクト

いくつかのコマンドは２つのタイプについて実行します：１つはテキストファイルで、もう１つはバイナリファイルを扱います。これらのメソッドのテキストバージョンでは lines 、バイナリバージョンでは binary の語がメソッド名の終わりについています。

FTP インスタンスには以下のメソッドがあります：

FTP.set_debuglevel(level)

インスタンスのデバッグレベルを設定します。この設定によってデバッグ時に出力される量を調節します。デフォルトは 0 で、何も出力されません。 1 なら、一般的に１つのコマンドあたり１行の適当な量のデバッグ出力を行います。 2 以上なら、コントロール接続で受信した各行を出力して、最大のデバッグ出力をします。

FTP.connect(host[, port[, timeout]])

指定されたホストとポートに接続します。ポート番号のデフォルト値はFTPプロトコルの仕様で定められた 21 です。他のポート番号を指定する必要はめったにありません。この関数はひとつのインスタンスに対して一度だけ実行すべきです；インスタンスが作られた時にホスト名が与えられていたら、呼び出すべきではありません。これ以外の他の全てのメソッドは接続された後で実行可能となります。

The optional timeout parameter specifies a timeout in seconds for the connection attempt. If no timeout is passed, the global default timeout setting will be used.

オプションの timeout 引数は、コネクションの接続におけるタイムアウト時間を秒数で指定します。 timeout が渡されなかった場合、グローバルのデフォルトタイムアウト設定が利用されます。

バージョン 2.6 で変更: timeout が追加されました

FTP.getwelcome()

接続して最初にサーバから送られてくるウェルカムメッセージを返します。（このメッセージには、ユーザにとって適切な注意書きやヘルプ情報が含まれることがあります。）

FTP.login([user[, passwd[, acct]]])

与えられた user でログインします。 passwd と acct のパラメータは省略可能で、デフォルトでは空文字列です。もし user が指定されないなら、デフォルトで 'anonymous' になります。もし user が 'anonymous' なら、デフォルトの passwd は 'anonymous@' になります。この関数は各インスタンスについて一度だけ、接続が確立した後に呼び出さなければなりません。インスタンスが作られた時にホスト名とユーザ名が与えられていたら、このメソッドを実行すべきではありません。ほとんどのFTPコマンドはクライアントがログインした後に実行可能になります。 acct 引数は “accounting information” を提供します。ほとんどのシステムはこれを実装していません。

FTP.abort()

実行中のファイル転送を中止します。これはいつも機能するわけではありませんが、やってみる価値はあります。

FTP.sendcmd(command)

シンプルなコマンド文字列をサーバに送信して、受信した文字列を返します。

FTP.voidcmd(command)

シンプルなコマンド文字列をサーバに送信して、その応答を扱います。応答コードが成功に関係するもの(200–299の範囲にあるコード)なら何も返しません。それ以外は error_reply を発生します。

FTP.retrbinary(command, callback[, maxblocksize[, rest]])

バイナリ転送モードでファイルを受信します。 command は適切な RETR コマンド： 'RETR filename' でなければなりません。関数 callback は、受信したデータブロックのそれぞれに対して、データブロックを１つの文字列の引数として呼び出されます。省略可能な引数 maxblocksize は、実際の転送を行うのに作られた低レベルのソケットオブジェクトから読み込む最大のチャンクサイズを指定します（これは callback に与えられるデータブロックの最大サイズにもなります）。妥当なデフォルト値が設定されます。 rest は、 transfercmd() メソッドと同じものです。

FTP.retrlines(command[, callback])

ASCII転送モードでファイルとディレクトリのリストを受信します。 command は、適切な RETR コマンド(retrbinary() を参照)あるいは LIST, NLST, MLSD のようなコマンド(通常は文字列 'LIST')でなければなりません。 LIST は、ファイルのリストとそれらのファイルに関する情報を受信します。 NLST は、ファイル名のリストを受信します。サーバによっては、 MLSD は機械で読めるリストとそれらのファイルに関する情報を受信します。関数 callback は末尾のCRLFを取り除いた各行を引数にして実行されます。デフォルトでは callback は sys.stdout に各行を表示します。

FTP.set_pasv(boolean)

boolean がtrueなら”パッシブモード”をオンにし、そうでないならパッシブモードをオフにします。（Python 2.0以前ではデフォルトでパッシブモードはオフにされていましたが、 Python 2.1以後ではデフォルトでオンになっています。）

FTP.storbinary(command, file[, blocksize, callback, rest])

バイナリ転送モードでファイルを転送します。 command は適切な STOR コマンド： "STOR filename" でなければなりません。 file は開かれたファイルオブジェクトで、 read() メソッドで EOFまで読み込まれ、ブロックサイズ blocksize でデータが転送されます。引数 blocksize のデフォルト値は8192です。 callback はオプションの引数で、引数を1つとる呼び出し可能オブジェクトを渡します。各データブロックが送信された後に、そのブロックを引数にして呼び出されます。 rest は、 transfercmd() メソッドにあるものと同じ意味です。

バージョン 2.1 で変更: blocksize のデフォルト値が追加されました.

バージョン 2.6 で変更: callback 引数が追加されました。

バージョン 2.7 で変更: rest パラメタが追加されました。

FTP.storlines(command, file[, callback])

ASCII転送モードでファイルを転送します。 command は適切な STOR コマンドでなければなりません (storbinary() を参照)。 file は開かれたファイルオブジェクトで、 readline() メソッドでEOFまで読み込まれ、各行がデータが転送されます。 callback はオプションの引数で、引数を1つとる呼び出し可能オブジェクトを渡します。各行が送信された後に、その行数を引数にして呼び出されます。

バージョン 2.6 で変更: callback 引数が追加されました。

FTP.transfercmd(cmd[, rest])

データ接続中に転送を初期化します。もし転送中なら、 EPRT あるいは PORT コマンドと、 cmd で指定したコマンドを送信し、接続を続けます。サーバがパッシブなら、 EPSV あるいは PASV コマンドを送信して接続し、転送コマンドを開始します。どちらの場合も、接続のためのソケットを返します。

省略可能な rest が与えられたら、 REST コマンドがサーバに送信され、 rest を引数として与えます。 rest は普通、要求したファイルのバイトオフセット値で、最初のバイトをとばして指定したオフセット値からファイルのバイト転送を再開するよう伝えます。しかし、RFC 959では rest が印字可能なASCIIコード33から126の範囲の文字列からなることを要求していることに注意して下さい。したがって、 transfercmd() メソッドは rest を文字列に変換しますが、文字列の内容についてチェックしません。もし REST コマンドをサーバが認識しないなら、例外 error_re ply が発生します。この例外が発生したら、引数 rest なしに transfercmd() を実行します。

FTP.ntransfercmd(cmd[, rest])

transfercmd() と同様ですが、データと予想されるサイズとのタプルを返します。もしサイズが計算できないなら、サイズの代わりに None が返されます。 cmd と rest は transfercmd() のものと同じです。

FTP.nlst(argument[, ...])

NLST コマンドで返されるファイル名のリストを返します。省略可能な argument は、リストアップするディレクトリです（デフォルトではサーバのカレントディレクトリです）。 NLST コマンドに非標準である複数の引数を渡すことができます。

FTP.dir(argument[, ...])

LIST コマンドで返されるディレクトリ内のリストを作り、標準出力へ出力します。省略可能な argument は、リストアップするディレクトリです（デフォルトではサーバのカレントディレクトリです）。 LIST コマンドに非標準である複数の引数を渡すことができます。もし最後の引数が関数なら、 retrlines() のように callback として使われます；デフォルトでは sys.stdout に印字します。このメソッドは None を返します。

FTP.rename(fromname, toname)

サーバ上のファイルのファイル名 fromname を toname へ変更します。

FTP.delete(filename)

サーバからファイル filename を削除します。成功したら応答のテキストを返し、そうでないならパーミッションエラーでは error_perm を、他のエラーでは error_reply を返します。

FTP.cwd(pathname)

サーバのカレントディレクトリを設定します。

FTP.mkd(pathname)

サーバ上に新たにディレクトリを作ります。

FTP.pwd()

サーバ上のカレントディレクトリのパスを返します。

FTP.rmd(dirname)

サーバ上のディレクトリ dirname を削除します。

FTP.size(filename)

サーバ上のファイル filename のサイズを尋ねます。成功したらファイルサイズが整数で返され、そうでないなら None が返されます。 SIZE コマンドは標準化されていませんが、多くの普通のサーバで実装されていることに注意して下さい。

FTP.quit()

サーバに QUIT コマンドを送信し、接続を閉じます。これは接続を閉じるのに”礼儀正しい”方法ですが、 QUIT コマンドに反応してサーバの例外が発生するかもしれません。この例外は、 close() メソッドによって FTP インスタンスに対するその後のコマンド使用が不可になっていることを示しています（下記参照）。

FTP.close()

接続を一方的に閉じます。既に閉じた接続に対して実行すべきではありません（例えば quit() を呼び出して成功した後など）。この実行の後、 FTP インスタンスはもう使用すべきではありません（ close() あるいは quit() を呼び出した後で、 login() メソッドをもう一度実行して再び接続を開くことはできません）。

20.8.2. FTP_TLS オブジェクト

FTP_TLS クラスは FTP を継承し、さらにオブジェクトを定義します。

FTP_TLS.ssl_version

使用する SSL のバージョン (デフォルトは TLSv1) です。

FTP_TLS.auth()

ssl_version() 属性で指定されたものに従って、 TLS または SSL を使い、セキュアコントロール接続をセットアップします。

FTP_TLS.prot_p()

セキュアデータ接続をセットアップします。

FTP_TLS.prot_c()

平文データ接続をセットアップします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.9. poplib — POP3 プロトコルクライアント

このモジュールは、 POP3 クラスを定義します。これはPOP3サーバへの接続と、 RFC 1725 [http://tools.ietf.org/html/rfc1725.html] に定められたプロトコルを実装します。 POP3 クラスは minimalとoptinalという2つのコマンドセットをサポートします。モジュールは POP3_SSL クラスも提供します。このクラスは下位のプロトコルレイヤーにSSLを使ったPOP3サーバへの接続を提供します。

POP3についての注意事項は、それが広くサポートされているにもかかわらず、既に時代遅れだということです。幾つも実装されているPOP3サーバーの品質は、貧弱なものが多数を占めています。もし、お使いのメールサーバーがIMAPをサポートしているなら、 imaplib や IMAP4 が使えます。 IMAPサーバーは、より良く実装されている傾向があります。

poplib モジュールでは、ひとつのクラスが提供されています。

class poplib.POP3(host[, port[, timeout]])

このクラスが、実際にPOP3プロトコルを実装します。インスタンスが初期化されるときに、コネクションが作成されます。 port が省略されると、POP3標準のポート(110)が使われます。オプションの timeout 引数は、接続時のタイムアウト時間を秒数で指定します。 (指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます。)

バージョン 2.6 で変更: timeout が追加されました

class poplib.POP3_SSL(host[, port[, keyfile[, certfile]]])

POP3 クラスのサブクラスで、SSLでカプセル化されたソケットによる POPサーバへの接続を提供します。 port が指定されていない場合、 POP3-over-SSL標準の995番ポートが使われます。 keyfile と certfile もオプションで - SSL接続に使われる PEMフォーマットの秘密鍵と信頼された＃＃を含みます。

バージョン 2.4 で追加.

1つの例外が、 poplib モジュールのアトリビュートとして定義されています。

exception poplib.error_proto

例外は、このモジュール内で起こったすべてのエラーで発生します。(socket モジュールからのエラーは捕まえず、そのまま伝播します) 例外の理由は文字列としてコンストラクタに渡されます。

参考

Module imaplib

The standard Python IMAP module.

Frequently Asked Questions About Fetchmail [http://www.catb.org/~esr/fetchmail/fetchmail-FAQ.html]

POP/IMAPクライアント fetchmail のFAQ。POPプロトコルをベースにしたアプリケーションを書くときに有用な、POP3サーバの種類や RFCへの適合度といった情報を収集しています。

20.9.1. POP3 オブジェクト

POP3コマンドはすべて、それと同じ名前のメソッドとしてlower-caseで表現されます。そしてそのほとんどは、サーバからのレスポンスとなるテキストを返します。

POP3 クラスのインスタンスは以下のメソッドを持ちます。

POP3.set_debuglevel(level)

インスタンスのデバッグレベルを指定します。これはデバッギングアウトプットの表示量をコントロールします。デフォルト値の 0 は、デバッギングアウトプットを表示しません。値を 1 とすると、デバッギングアウトプットの表示量を適当な量にします。これは大体、リクエストごと1行になります。値を 2 以上にすると、デバッギングアウトプットの表示量を最大にします。コントロール中の接続で送受信される各行をログに出力します。

POP3.getwelcome()

POP3サーバーから送られるグリーティングメッセージを返します。

POP3.user(username)

userコマンドを送出します。応答はパスワード要求を表示します。

POP3.pass_(password)

パスワードを送出します。応答は、メッセージ数とメールボックスのサイズを含みます。注：サーバー上のメールボックスは quit() が呼ばれるまでロックされます。

POP3.apop(user, secret)

POP3サーバーにログオンするのに、よりセキュアなAPOP認証を使用します。

POP3.rpop(user)

POP3サーバーにログオンするのに、（UNIXのr-コマンドと同様の）RPOP認証を使用します。

POP3.stat()

メールボックスの状態を得ます。結果は2つのintegerからなるタプルとなります。 (message count, mailbox size).

POP3.list([which])

メッセージのリストを要求します。結果は (response, ['mesg_num octets', ...], octets) という形式で表されます。 which が与えられると、それによりメッセージを指定します。

POP3.retr(which)

which 番のメッセージ全体を取り出し、そのメッセージに既読フラグを立てます。結果は (response, ['line', ...], octets) という形式で表されます。

POP3.dele(which)

which 番のメッセージに削除のためのフラグを立てます。ほとんどのサーバで、QUITコマンドが実行されるまでは実際の削除は行われません（もっとも良く知られた例外は Eudora QPOPで、その配送メカニズムはRFCに違反しており、どんな切断状況でも削除操作を未解決にしています）。

POP3.rset()

メールボックスの削除マークすべてを取り消します。

POP3.noop()

何もしません。接続保持のために使われます。

POP3.quit()

Signoff: commit changes, unlock mailbox, drop connection. サインオフ：変更をコミットし、メールボックスをアンロックして、接続を破棄します。

POP3.top(which, howmuch)

メッセージヘッダと howmuch で指定した行数のメッセージを、 which で指定したメッセージ分取り出します。結果は以下のような形式となります。 (response, ['line', ...], octets).

このメソッドはPOP3のTOPコマンドを利用し、RETRコマンドのように、メッセージに既読フラグをセットしません。残念ながら、TOPコマンドはRFCでは貧弱な仕様しか定義されておらず、しばしばノーブランドのサーバーでは（その仕様が）守られていません。このメソッドを信用してしまう前に、実際に使用するPOPサーバーでテストをしてください。

POP3.uidl([which])

（ユニークIDによる）メッセージダイジェストのリストを返します。 which が設定されている場合、結果はユニークIDを含みます。それは 'response mesgnum uid という形式のメッセージ、または (response, ['mesgnum uid', ...], octets) という形式のリストとなります。

POP3_SSL クラスのインスタンスは追加のメソッドを持ちません。このサブクラスのインターフェイスは親クラスと同じです。

20.9.2. POP3 の例

これは（エラーチェックもない）最も小さなサンプルで、メールボックスを開いて、すべてのメッセージを取り出し、プリントします。

import getpass, poplib

M = poplib.POP3('localhost')
M.user(getpass.getuser())
M.pass_(getpass.getpass())
numMessages = len(M.list()[1])
for i in range(numMessages):
    for j in M.retr(i+1)[1]:
        print j

モジュールの末尾に、より広い範囲の使用例となるtestセクションがあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.10. imaplib — IMAP4 プロトコルクライアント

このモジュールでは三つのクラス、 IMAP4, IMAP4_SSL と IMAP4_stream を定義します。これらのクラスは IMAP4 サーバへの接続をカプセル化し、 RFC 2060 [http://tools.ietf.org/html/rfc2060.html] に定義されている IMAP4rev1 クライアントプロトコルの大規模なサブセットを実装しています。このクラスは IMAP4 (RFC 1730 [http://tools.ietf.org/html/rfc1730.html]) 準拠のサーバと後方互換性がありますが、 STATUS コマンドは IMAP4 ではサポートされていないので注意してください。

imaplib モジュール内では三つのクラスを提供しており、 IMAP4 は基底クラスとなります:

class imaplib.IMAP4([host[, port]])

このクラスは実際の IMAP4 プロトコルを実装しています。インスタンスが初期化された際に接続が生成され、プロトコルバージョン (IMAP4 または IMAP4rev1) が決定されます。 host が指定されていない場合、 '' (ローカルホスト) が用いられます。 port が省略された場合、標準の IMAP4 ポート番号 (143) が用いられます。

例外は IMAP4 クラスの属性として定義されています:

exception IMAP4.error

何らかのエラー発生の際に送出される例外です。例外の理由は文字列としてコンストラクタに渡されます。

exception IMAP4.abort

IMAP4 サーバのエラーが生じると、この例外が送出されます。この例外は IMAP4.error のサブクラスです。通常、インスタンスを閉じ、新たなインスタンスを再び生成することで、この例外から復旧できます。

exception IMAP4.readonly

この例外は書き込み可能なメールボックスの状態がサーバによって変更された際に送出されます。この例外は IMAP4.error のサブクラスです。他の何らかのクライアントが現在書き込み権限を獲得しており、メールボックスを開きなおして書き込み権限を再獲得する必要があります。

このモジュールではもう一つ、安全 (secure) な接続を使ったサブクラスがあります:

class imaplib.IMAP4_SSL([host[, port[, keyfile[, certfile]]]])

IMAP4 から派生したサブクラスで、SSL 暗号化ソケットを介して接続を行います (このクラスを利用するためには SSL サポート付きでコンパイルされた socket モジュールが必要です) 。 host が指定されていない場合、 '' (ローカルホスト) が用いられます。 port が省略された場合、標準の IMAP4-over-SSL ポート番号 (993) が用いられます。 keyfile および certfile もオプションです - これらは SSL 接続のための PEM 形式の秘密鍵 (private key) と認証チェイン (certificate chain) ファイルです。

さらにもう一つのサブクラスは、子プロセスで確立した接続を使用する場合に使用します。

class imaplib.IMAP4_stream(command)

IMAP4 から派生したサブクラスで、 command を os.popen2() に渡して作成される stdin/stdout ディスクリプタと接続します。

バージョン 2.3 で追加.

以下のユーティリティ関数が定義されています:

imaplib.Internaldate2tuple(datestr)

IMAP4 の INTERNALDATE 文字列を解析してそれに相当するローカルタイムを返します。戻り値は time.struct_time のインスタンスか、文字列のフォーマットが不正な場合は None です。

imaplib.Int2AP(num)

整数を [A .. P] からなる文字集合を用いて表現した文字列に変換します。

imaplib.ParseFlags(flagstr)

IMAP4 FLAGS 応答を個々のフラグからなるタプルに変換します。

imaplib.Time2Internaldate(date_time)

date_time を IMAP4 の INTERNALDATE 表現形式に変換します。戻り値は "DD-Mmm-YYYY HH:MM:SS +HHMM" (ダブルクォートを含む) の形をした文字列です。 date_time 引数は (time.time() が返す) epoch からの経過秒数を表す数値 (int か float) か、(time.localtime() が返す) ローカルタイムを表現する 9要素タプルか、ダブルクォートされた文字列です。文字列だった場合、それがすでに正しいフォーマットになっていると仮定されます。

IMAP4 メッセージ番号は、メールボックスに対する変更が行われた後には変化します; 特に、 EXPUNGE 命令はメッセージの削除を行いますが、残ったメッセージには再度番号を振りなおします。従って、メッセージ番号ではなく、 UID 命令を使い、その UID を利用するよう強く勧めます。

モジュールの末尾に、より拡張的な使用例が収められたテストセクションがあります。

参考

プロトコルに関する記述、およびプロトコルを実装したサーバのソースとバイナリは、全てワシントン大学の IMAP Information Center (http://www.washington.edu/imap/) にあります。

20.10.1. IMAP4 オブジェクト

全ての IMAP4rev1 命令は、同じ名前のメソッドで表されており、大文字のものも小文字のものもあります。

命令に対する引数は全て文字列に変換されます。例外は AUTHENTICATE の引数と APPEND の最後の引数で、これは IMAP4 リテラルとして渡されます。必要に応じて (IMAP4 プロトコルが感知対象としている文字が文字列に入っており、かつ丸括弧か二重引用符で囲われていなかった場合) 文字列はクオートされます。しかし、 LOGIN 命令の password 引数は常にクオートされます。文字列がクオートされないようにしたい (例えば STORE 命令の flags 引数) 場合、文字列を丸括弧で囲んでください (例: r'(\Deleted)')。

各命令はタプル: (type, [data, ...]) を返し、 type は通常 'OK' または 'NO' です。 data は命令に対する応答をテキストにしたものか、命令に対する実行結果です。各 data は文字列かタプルとなります。タプルの場合、最初の要素はレスポンスのヘッダで、次の要素にはデータが格納されます。 (ie: ‘literal’ value)

以下のコマンドにおける message_set オプションは、操作の対象となるひとつあるいは複数のメッセージを指す文字列です。単一のメッセージ番号 ('1') かメッセージ番号の範囲 ('2:4')、あるいは連続していないメッセージをカンマでつなげたもの ('1:3,6:9') となります。範囲指定でアスタリスクを使用すると、上限を無限とすることができます ('3:*')。

IMAP4 のインスタンスは以下のメソッドを持っています:

IMAP4.append(mailbox, flags, date_time, message)

指定された名前のメールボックスに message を追加します。

IMAP4.authenticate(mechanism, authobject)

認証命令です — 応答の処理が必要です。

mechanism は利用する認証メカニズムを与えます。認証メカニズムはインスタンス変数 capabilities の中に AUTH=mechanism という形式で現れる必要があります。

authobject は呼び出し可能なオブジェクトである必要があります。

data = authobject(response)

これはサーバで継続応答を処理するためによばれます。これは(おそらく)暗号化されて、サーバへ送られた data を返します。もしクライアントが中断応答 * を送信した場合にはこれは None を返します。

IMAP4.check()

サーバ上のメールボックスにチェックポイントを設定します。 Checkpoint mailbox on server.

IMAP4.close()

現在選択されているメールボックスを閉じます。削除されたメッセージは書き込み可能メールボックスから除去されます。 LOGOUT 前に実行することを勧めます。

IMAP4.copy(message_set, new_mailbox)

message_set で指定したメッセージ群を new_mailbox の末尾にコピーします。

IMAP4.create(mailbox)

mailbox と名づけられた新たなメールボックスを生成します。

IMAP4.delete(mailbox)

mailbox と名づけられた古いメールボックスを削除します。

IMAP4.deleteacl(mailbox, who)

mailbox における who についてのACLを削除(権限を削除)します。

バージョン 2.4 で追加.

IMAP4.expunge()

選択されたメールボックスから削除された要素を永久に除去します。各々の削除されたメッセージに対して、 EXPUNGE 応答を生成します。返されるデータには EXPUNGE メッセージ番号を受信した順番に並べたリストが入っています。

IMAP4.fetch(message_set, message_parts)

メッセージ (の一部) を取りよせます。 message_parts はメッセージパートの名前を表す文字列を丸括弧で囲ったもので、例えば: "(UID BODY[TEXT])" のようになります。返されるデータはメッセージパートのエンベロープ情報とデータからなるタプルです。

IMAP4.getacl(mailbox)

mailbox に対する ACL を取得します。このメソッドは非標準ですが、 Cyrus サーバでサポートされています。

IMAP4.getannotation(mailbox, entry, attribute)

mailbox に対する ANNOTATION を取得します。このメソッドは非標準ですが、 Cyrus サーバでサポートされています。

バージョン 2.5 で追加.

IMAP4.getquota(root)

quota root により、リソース使用状況と制限値を取得します。このメソッドは RFC 2087 [http://tools.ietf.org/html/rfc2087.html] で定義されている IMAP4 QUOTA 拡張の一部です。

バージョン 2.3 で追加.

IMAP4.getquotaroot(mailbox)

mailbox に対して quota root を実行した結果のリストを取得します。このメソッドは RFC 2087 [http://tools.ietf.org/html/rfc2087.html] で定義されている IMAP4 QUOTA 拡張の一部です。

バージョン 2.3 で追加.

IMAP4.list([directory[, pattern]])

pattern にマッチする directory メールボックス名を列挙します。 directory の標準の設定値は最上レベルのメールフォルダで、 pattern は標準の設定では全てにマッチします。返されるデータには LIST 応答のリストが入っています。

IMAP4.login(user, password)

平文パスワードを使ってクライアントを照合します。 password はクオートされます。

IMAP4.login_cram_md5(user, password)

パスワードの保護のため、クライアント認証時に CRAM-MD5 だけを使用します。これは、 CAPABILITY レスポンスに AUTH=CRAM-MD5 が含まれる場合のみ有効です。

バージョン 2.3 で追加.

IMAP4.logout()

サーバへの接続を遮断します。サーバからの BYE 応答を返します。

IMAP4.lsub([directory[, pattern]])

購読しているメールボックス名のうち、ディレクトリ内でパターンにマッチするものを列挙します。 directory の標準の設定値は最上レベルのメールフォルダで、 pattern は標準の設定では全てにマッチします。返されるデータには返されるデータはメッセージパートエンベロープ情報とデータからなるタプルです。

IMAP4.myrights(mailbox)

mailboxにおける自分のACLを返します。(すなわち自分がmailboxで持っている権限を返します。)

バージョン 2.4 で追加.

IMAP4.namespace()

RFC2342で定義されるIMAP名前空間を返します。

バージョン 2.3 で追加.

IMAP4.noop()

サーバに NOOP を送信します。

IMAP4.open(host, port)

host 上の port に対するソケットを開きます。このメソッドは IMAP4 のコンストラクタから暗黙的に呼び出されます。このメソッドで確立された接続オブジェクトは read, readline, send, shutdown メソッドで使われます。このメソッドはオーバライドすることができます。

IMAP4.partial(message_num, message_part, start, length)

メッセージの後略された部分を取り寄せます。返されるデータはメッセージパートエンベロープ情報とデータからなるタプルです。

IMAP4.proxyauth(user)

user として認証されたものとします。認証された管理者がユーザの代理としてメールボックスにアクセスする際に使用します。

バージョン 2.3 で追加.

IMAP4.read(size)

遠隔のサーバから size バイト読み出します。このメソッドはオーバライドすることができます。

IMAP4.readline()

遠隔のサーバから一行読み出します。このメソッドはオーバライドすることができます。

IMAP4.recent()

サーバに更新を促します。新たなメッセージがない場合応答は None になり、そうでない場合 RECENT 応答の値になります。

IMAP4.rename(oldmailbox, newmailbox)

oldmailbox という名前のメールボックスを newmailbox に名称変更します。

IMAP4.response(code)

応答 code を受信していれば、そのデータを返し、そうでなければ None を返します。通常の形式 (usual type) ではなく指定したコードを返します。

IMAP4.search(charset, criterion[, ...])

条件に合致するメッセージをメールボックスから検索します。 charset は None でもよく、この場合にはサーバへの要求内に CHARSET は指定されません。IMAP プロトコルは少なくとも一つの条件 (criterion) が指定されるよう要求しています; サーバがエラーを返した場合、例外が送出されます。

例:

# M is a connected IMAP4 instance...
typ, msgnums = M.search(None, 'FROM', '"LDJ"')

# or:
typ, msgnums = M.search(None, '(FROM "LDJ")')

IMAP4.select([mailbox[, readonly]])

メールボックスを選択します。返されるデータは mailbox 内のメッセージ数 (EXISTS 応答) です。標準の設定では mailbox は 'INBOX' です。 readonly が設定された場合、メールボックスに対する変更はできません。

IMAP4.send(data)

遠隔のサーバに data を送信します。このメソッドはオーバライドすることができます。

IMAP4.setacl(mailbox, who, what)

ACL を mailbox に設定します。このメソッドは非標準ですが、 Cyrus サーバでサポートされています。

IMAP4.setannotation(mailbox, entry, attribute[, ...])

ANNOTATION を mailbox に設定します。このメソッドは非標準ですが、 Cyrus サーバでサポートされています。

バージョン 2.5 で追加.

IMAP4.setquota(root, limits)

quota root のリソースを limits に設定します。このメソッドは RFC 2087 [http://tools.ietf.org/html/rfc2087.html] で定義されている IMAP4 QUOTA 拡張の一部です。

バージョン 2.3 で追加.

IMAP4.shutdown()

open で確立された接続を閉じます。 IMAP4.logout() は暗黙的にこのメソッドを呼び出します。このメソッドはオーバライドすることができます。

IMAP4.socket()

サーバへの接続に使われているソケットインスタンスを返します。

IMAP4.sort(sort_criteria, charset, search_criterion[, ...])

sort 命令は search に結果の並べ替え (sort) 機能をつけた変種です。返されるデータには、条件に合致するメッセージ番号をスペースで分割したリストが入っています。 sort 命令は search_criterium の前に二つの引数を持ちます; sort_criteria のリストを丸括弧で囲ったものと、検索時の charset です。 search と違って、検索時の charset は必須です。 uid sort 命令もあり、 search に対する uid search と同じように sort 命令に対応します。 sort 命令はまず、charset 引数の指定に従って searching criteria の文字列を解釈し、メールボックスから与えられた検索条件に合致するメッセージを探します。次に、合致したメッセージの数を返します。

IMAP4rev1 拡張命令です。

IMAP4.status(mailbox, names)

mailbox の指定ステータス名の状態情報を要求します。

IMAP4.store(message_set, command, flag_list)

メールボックス内のメッセージ群のフラグ設定を変更します。 command は RFC 2060 [http://tools.ietf.org/html/rfc2060.html] のセクション 6.4.6 で指定されているもので、 “FLAGS”, “+FLAGS”, あるいは “-FLAGS” のいずれかとなります。オプションで末尾に ”.SILENT” がつくこともあります。

たとえば、すべてのメッセージに削除フラグを設定するには次のようにします。

typ, data = M.search(None, 'ALL')
for num in data[0].split():
   M.store(num, '+FLAGS', '\\Deleted')
M.expunge()

IMAP4.subscribe(mailbox)

新たなメールボックスを購読 (subscribe) します。

IMAP4.thread(threading_algorithm, charset, search_criterion[, ...])

thread コマンドは search にスレッドの概念を加えた変形版です。返されるデータは空白で区切られたスレッドメンバのリストを含んでいます。

各スレッドメンバは0以上のメッセージ番号からなり、空白で区切られており、親子関係を示しています。

thread コマンドは search_criterion 引数の前に2つの引数を持っています。 threading_algorithm と charset です。 search コマンドとは違い、 charset は必須です。 search に対する uid search と同様に、 thread にも uid thread があります。

thread コマンドはまずメールボックス中のメッセージを、charsetを用いた検索条件で検索します。その後マッチしたメッセージを指定されたスレッドアルゴリズムでスレッド化して返します.

これは IMAP4rev1 の拡張コマンドです。

バージョン 2.4 で追加.

IMAP4.uid(command, arg[, ...])

command args を、メッセージ番号ではなく UID で指定されたメッセージ群に対して実行します。命令内容に応じた応答を返します。少なくとも一つの引数を与えなくてはなりません; 何も与えない場合、サーバはエラーを返し、例外が送出されます。

IMAP4.unsubscribe(mailbox)

古いメールボックスの購読を解除 (unsubscribe) します。

IMAP4.xatom(name[, arg[, ...]])

サーバから CAPABILITY 応答で通知された単純な拡張命令を許容 (allow) します。

IMAP4_SSL のインスタンスは追加のメソッドを一つだけ持ちます:

IMAP4_SSL.ssl()

サーバへの安全な接続に使われる SSLObject インスタンスを返します。

以下の属性が IMAP4 のインスタンス上で定義されています:

IMAP4.PROTOCOL_VERSION

サーバから返された CAPABILITY 応答にある、サポートされている最新のプロトコルです。

IMAP4.debug

デバッグ出力を制御するための整数値です。初期値はモジュール変数 Debug から取られます。3 以上の値にすると各命令をトレースします。

20.10.2. IMAP4 の使用例

以下にメールボックスを開き、全てのメッセージを取得して印刷する最小の (エラーチェックをしない) 使用例を示します:

import getpass, imaplib

M = imaplib.IMAP4()
M.login(getpass.getuser(), getpass.getpass())
M.select()
typ, data = M.search(None, 'ALL')
for num in data[0].split():
    typ, data = M.fetch(num, '(RFC822)')
    print 'Message %s\n%s\n' % (num, data[0][1])
M.close()
M.logout()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.11. nntplib — NNTP プロトコルクライアント

このモジュールでは、クラス NNTP を定義しています。このクラスは NNTP プロトコルのクライアント側を実装しています。このモジュールを使えば、ニュースリーダや記事投稿プログラム、または自動的にニュース記事を処理するプログラムを実装することができます。NNTP (Network News Transfer Protocol、ネットニュース転送プロトコル) の詳細については、インターネット RFC 977 [http://tools.ietf.org/html/rfc977.html] を参照してください。

以下にこのモジュールの使い方の小さな例を二つ示します。ニュースグループに関する統計情報を列挙し、最新 10 件の記事を出力するには以下のようにします:

>>> s = NNTP('news.gmane.org')
>>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last
Group gmane.comp.python.committers has 1071 articles, range 1 to 1071
>>> resp, subs = s.xhdr('subject', first + '-' + last)
>>> for id, sub in subs[-10:]: print id, sub
...
1062 Re: Mercurial Status?
1063 Re: [python-committers]  (Windows) buildbots on 3.x
1064 Re: Mercurial Status?
1065 Re: Mercurial Status?
1066 Python 2.6.6 status
1067 Commit Privileges for Ask Solem
1068 Re: Commit Privileges for Ask Solem
1069 Re: Commit Privileges for Ask Solem
1070 Re: Commit Privileges for Ask Solem
1071 2.6.6 rc 2
>>> s.quit()
'205 Bye!'

ファイルから記事を投稿するには、以下のようにします。 (この例では記事番号は有効な番号を指定していて、あなたがそのニュースグループに投稿する権限を持っていると仮定しています)

>>> s = NNTP('news.gmane.org')
>>> f = open('/tmp/article')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
'205 Bye!'

このモジュール自体では以下の内容を定義しています:

class nntplib.NNTP(host[, port [, user[, password [, readermode] [, usenetrc]]]])

ホスト host 上で動作し、ポート番号 port で要求待ちをしている NNTP サーバとの接続を表現する新たな NNTP クラスのインスタンスを返します。標準の port は 119 です。オプションの user および password が与えられているか、または /.netrc に適切な認証情報が指定されていて usenetrc が真 (デフォルト) の場合、 AUTHINFO USER および AUTHINFO PASS 命令を使ってサーバに対して身元証明および認証を行います。オプションのフラグ readermode が真の場合、認証の実行に先立って mode reader 命令が送信されます。reader モードは、ローカルマシン上の NNTP サーバに接続していて、 group のような reader 特有の命令を呼び出したい場合に便利なことがあります。予期せず NNTPPermanentError に遭遇したなら、 readermode を設定する必要があるかもしれません。 readermode のデフォルト値は None です。 usenetrc のデフォルト値は True です。

バージョン 2.4 で変更: usenetrc 引数を追加しました.

exception nntplib.NNTPError

標準の例外 Exception から派生しており、 nntplib モジュールが送出する全ての例外の基底クラスです。

exception nntplib.NNTPReplyError

期待はずれの応答がサーバから返された場合に送出される例外です。以前のバージョンとの互換性のために、 error_reply はこのクラスと等価になっています。

exception nntplib.NNTPTemporaryError

エラーコードの範囲が 400-499 のエラーを受信した場合に送出される例外です。以前のバージョンとの互換性のために、 error_temp はこのクラスと等価になっています。

exception nntplib.NNTPPermanentError

エラーコードの範囲が 500-599 のエラーを受信した場合に送出される例外です。以前のバージョンとの互換性のために、 error_perm はこのクラスと等価になっています。

exception nntplib.NNTPProtocolError

サーバから返される応答が 1–5 の範囲の数字で始まっていない場合に送出される例外です。以前のバージョンとの互換性のために、 error_proto はこのクラスと等価になっています。

exception nntplib.NNTPDataError

応答データ中に何らかのエラーが存在する場合に送出される例外です。以前のバージョンとの互換性のために、 error_data はこのクラスと等価になっています。

20.11.1. NNTP オブジェクト

NNTP インスタンスは以下のメソッドを持っています。全てのメソッドにおける戻り値のタプルで最初の要素となる response は、サーバの応答です: この文字列は 3 桁の数字からなるコードで始まります。サーバの応答がエラーを示す場合、上記のいずれかの例外が送出されます。

NNTP.getwelcome()

サーバに最初に接続した際に送信される応答中のウェルカムメッセージを返します。(このメッセージには時に、ユーザにとって重要な免責事項やヘルプ情報が入っています。)

NNTP.set_debuglevel(level)

インスタンスのデバッグレベルを設定します。このメソッドは印字されるデバッグ出力の量を制御します。標準では 0 に設定されていて、これはデバッグ出力を全く印字しません。 1 はそこそこの量、一般に NNTP 要求や応答あたり 1 行のデバッグ出力を生成します。値が 2 やそれ以上の場合、(メッセージテキストを含めて) NNTP 接続上で送受信された全ての内容を一行ごとにログ出力する、最大限のデバッグ出力を生成します。

NNTP.newgroups(date, time[, file])

NEWSGROUPS 命令を送信します。 date 引数は 'yymmdd' の形式を取り、日付を表します。 time 引数は 'hhmmss' の形式をとり、時刻を表します。与えられた日付および時刻以後新たに出現したニュースグループ名のリストを groups として、 (response, groups) を返します。 file 引数が指定されている場合、 NEWGROUPS コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。

NNTP.newnews(group, date, time[, file])

NEWNEWS 命令を送信します。ここで、 group はグループ名または '*' で、 date および time は newsgrups() における引数と同じ意味を持ちます。 (response, articles) からなるペアを返し、 articles はメッセージ ID のリストです。 file 引数が指定されている場合、 NEWNEWS コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。

NNTP.list([file])

LIST 命令を送信します。 (response, list) からなるペアを返します。 list はタプルからなるリストです。各タプルは (group, last, first, flag) の形式をとり、 group がグループ名、 last および first はそれぞれ最新および最初の記事の記事番号 (を表す文字列)、そして flag は投稿が可能な場合には 'y', そうでない場合には 'n', グループがモデレート (moderated) されている場合には 'm' となります。(順番に注意してください: last, first の順です。) file 引数が指定されている場合、 LIST コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。

NNTP.descriptions(grouppattern)

LIST NEWSGROUPS 命令を送信します。 grouppattern は RFC2980 の定義に従う wildmat 文字列です (実際には、 DOS や UNIX のシェルワイルドカード文字列と同じです)。 (response,list) からなるペアを返し、 list はタプル (name, title) リストになります。

バージョン 2.4 で追加.

NNTP.description(group)

単一のグループ group から説明文字列を取り出します。 (‘group’ が実際には wildmat 文字列で) 複数のグループがマッチした場合、最初にマッチしたものを返します。何もマッチしなければ空文字列を返します。

このメソッドはサーバからの応答コードを省略します。応答コードが必要なら、 descriptions() を使ってください。

バージョン 2.4 で追加.

NNTP.group(name)

GROUP 命令を送信します。 name はグループ名です。タプル (response, count, first, last, name) を返します。 count はグループ中の記事数 (の推定値) で、 first はグループ中の最初の記事番号、 last はグループ中の最新の記事番号、 name はグループ名です。記事番号は文字列で返されます。

NNTP.help([file])

HELP 命令を送信します。 (response, list) からなるペアを返します。 list はヘルプ文字列からなるリストです。 file 引数が指定されている場合、 HELP コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。

NNTP.stat(id)

STAT 命令を送信します。 id は ('<' と '>' に囲まれた形式の) メッセージ ID か、 (文字列の) 記事番号です。三つ組み (response, number, id) を返します。 number は (文字列の) 記事番号で、 id は ('<' と '>' に囲まれた形式の) メッセージ ID です。

NNTP.next()

NEXT 命令を送信します。 stat() のような応答を返します。

NNTP.last()

LAST 命令を送信します。 stat() のような応答を返します。

NNTP.head(id)

HEAD 命令を送信します。 id は stat() におけるのと同じ意味を持ちます。 (response, number, id, list) からなるタプルを返します。最初の 3 要素は stat() と同じもので、 list は記事のヘッダからなるリスト (まだ解析されておらず、末尾の改行が取り去られたヘッダ行のリスト) です。

NNTP.body(id[, file])

BODY 命令を送信します。 id は stat() におけるのと同じ意味を持ちます。 file 引数が与えられている場合、記事本体 (body) はファイルに保存されます。 file が文字列の場合、このメソッドはその名前を持つファイルオブジェクトを開き、記事を書き込んで閉じます。 file がファイルオブジェクトの場合、 write() を呼び出して記事本体を記録します。 head() のような戻り値を返します。 file が与えられていた場合、返される list は空のリストになります。

NNTP.article(id)

ARTICLE 命令を送信します。 id は stat() におけるのと同じ意味を持ちます。 head() のような戻り値を返します。

NNTP.slave()

SLAVE 命令を送信します。サーバの response を返します。

NNTP.xhdr(header, string[, file])

XHDR 命令を送信します、この命令は RFC には定義されていませんが、一般に広まっている拡張です。 header 引数は、例えば 'subject' といったヘッダキーワードです。 string 引数は 'first-last' の形式でなければならず、ここで first および last は検索の対象とする記事範囲の最初と最後の記事番号です。 (response, list) のペアを返します。 list は (id, text) のペアからなるリストで、 id が (文字列で表した) 記事番号、 text がその記事のヘッダテキストです。 file 引数が指定されている場合、 XHDR コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。

NNTP.post(file)

POST 命令を使って記事をポストします。 file 引数は開かれているファイルオブジェクトで、その内容は readline() メソッドを使って EOF まで読み出されます。内容は必要なヘッダを含め、正しい形式のニュース記事でなければなりません。 post() メソッドは . で始まる行を自動的にエスケープします。

NNTP.ihave(id, file)

IHAVE 命令を送信します。 id は ('<' と '>' に囲まれた) メッセージ ID です。応答がエラーでない場合、 file を post() と全く同じように扱います。

NNTP.date()

タプル (response, date, time) を返します。このタプルには newnews() および newgroups() メソッドに合った形式の、現在の日付および時刻が入っています。これはオプションの NNTP 拡張なので、全てのサーバでサポートされているとは限りません。

NNTP.xgtitle(name[, file])

XGTITLE 命令を処理し、 (response, list) からなるペアを返します。 list は (name, title) を含むタプルのリストです。 file 引数が指定されている場合、 XHDR コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。これはオプションの NNTP 拡張なので、全てのサーバでサポートされているとは限りません。

RFC2980 では、 “この拡張は撤廃すべきである” と主張しています。 descriptions() または description() を使うようにしてください。

NNTP.xover(start, end[, file])

(resp, list) からなるペアを返します。 list はタプルからなるリストで、各タプルは記事番号 start および end の間に区切られた記事です。各タプルは (article number, subject, poster, date, id, references, size, lines) の形式をとります。 file 引数が指定されている場合、 XHDR コマンドの出力結果はファイルに格納されます。 file が文字列の場合、この文字列をファイル名としてファイルをオープンし、書き込み後にクローズします。 file がファイルオブジェクトの場合、オブジェクトの write() メソッドを呼び出して出力結果を格納します。 file が指定されている場合は戻り値として空のリストを返します。これはオプションの NNTP 拡張なので、全てのサーバでサポートされているとは限りません。

NNTP.xpath(id)

(resp, path) からなるペアを返します。 path はメッセージ ID が id である記事のディレクトリパスです。これはオプションの NNTP 拡張なので、全てのサーバでサポートされているとは限りません。

NNTP.quit()

QUIT 命令を送信し、接続を閉じます。このメソッドを呼び出した後は、NTTP オブジェクトの他のいかなるメソッドも呼び出してはいけません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.12. smtplib — SMTP プロトコルクライアント

smtplib モジュールは、SMTPまたはESMTPのリスナーデーモンを備えた任意のインターネット上のホストにメールを送るために使用することができる SMTPクライアント・セッション・オブジェクトを定義します。 SMTPおよびESMTPオペレーションの詳細は、 RFC 821 [http://tools.ietf.org/html/rfc821.html] (Simple Mail Transfer Protocol) や RFC 1869 [http://tools.ietf.org/html/rfc1869.html] (SMTP Service Extensions)を調べてください。

class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

SMTP インスタンスはSMTPコネクションをカプセル化し、 SMTPとESMTPの命令をサポートをします。オプションであるhostとportを与えた場合は、 SMTPクラスのインスタンスが作成されると同時に、 connect() メソッドを呼び出し初期化されます。また、ホストから応答が無い場合は、 SMTPConnectError が上げられます。オプションの timeout 引数を与える場合、コネクションの接続時などのブロックする操作におけるタイムアウト時間を秒数で設定します。(指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます)

普通に使う場合は、初期化と接続を行ってから、 sendmail() と quit() メソッドを呼びます。使用例は先の方で記載しています。

バージョン 2.6 で変更: timeout が追加されました

class smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])

SMTP_SSL のインスタンスは SMTP のインスタンスと全く同じように動作します。 SMTP_SSL は、接続の最初の段階からSSLが要求され、 starttls() では対応できない場合にのみ利用されるべきです。 host が指定されなかった場合は、localhostが利用されます。 port が指定されなかった場合は、標準の SMTP-over-SSL ポート(465) が利用されます。 keyfile と certfile もオプションで、SSL接続のための、PEMフォーマットのプライベートキーと、証明パス(certificate chain)ファイルを指定することができます。オプションの timeout 引数を与える場合、コネクションの接続時などのブロックする操作におけるタイムアウト時間を秒数で設定します。(指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます)

バージョン 2.6 で追加.

class smtplib.LMTP([host[, port[, local_hostname]]])

ESMTPに非常に似ているLMTPプロトコルは、SMTPクライアントに基づいています。 LMTPにはよくUnixソケットが利用されるので、 connect() メソッドは通常の host:port サーバーと同じようにUnixソケットもサポートしています。 Unixソケットを指定するには、 host 引数に、 ‘/’ で始まる絶対パスを指定します。

認証は、通常のSMTP機構を利用してサポートされています。 Unixソケットを利用する場合、LMTPは通常認証をサポートしたり要求したりはしません。しかし、あなたが必要であれば、利用することができます。

バージョン 2.6 で追加.

このモジュールの例外には次のものがあります:

exception smtplib.SMTPException

このモジュールの例外クラスのベースクラスです。

exception smtplib.SMTPServerDisconnected

この例外はサーバが突然コネクションを切断するか、もしくは SMTP インスタンスを生成する前にコネクションを張ろうとした場合に上げられます。

exception smtplib.SMTPResponseException

SMTPのエラーコードを含んだ例外のクラスです。これらの例外はSMTPサーバがエラーコードを返すときに生成されます。エラーコードは smtp_code 属性に格納されます。また、 smtp_error 属性にはエラーメッセージが格納されます。

exception smtplib.SMTPSenderRefused

送信者のアドレスが弾かれたときに上げられる例外です。全ての SMTPResponseException 例外に、 SMTPサーバが弾いた’sender’アドレスの文字列がセットされます。

exception smtplib.SMTPRecipientsRefused

全ての受取人アドレスが弾かれたときに上げられる例外です。各受取人のエラーは属性 recipients によってアクセス可能で、 SMTP.sendmail() が返す辞書と同じ並びの辞書になっています。

exception smtplib.SMTPDataError

SMTPサーバが、メッセージのデータを受け入れることを拒絶した時に上げられる例外です。

exception smtplib.SMTPConnectError

サーバへの接続時にエラーが発生した時に上げられる例外です。

exception smtplib.SMTPHeloError

サーバーが HELO メッセージを弾いた時に上げられる例外です。

exception smtplib.SMTPAuthenticationError

SMTP 認証が失敗しました。最もあり得る可能性は、サーバーがユーザ名/パスワードのペアを受付なかった事です。

参考

RFC 821 [http://tools.ietf.org/html/rfc821.html] - Simple Mail Transfer Protocol

SMTP のプロトコル定義です。このドキュメントでは SMTP のモデル、操作手順、プロトコルの詳細についてカバーしています。

RFC 1869 [http://tools.ietf.org/html/rfc1869.html] - SMTP Service Extensions

SMTP に対する ESMTP 拡張の定義です。このドキュメントでは、新たな命令による SMTP の拡張、サーバによって提供される命令を動的に発見する機能のサポート、およびいくつかの追加命令定義について記述しています。

20.12.1. SMTP オブジェクト

SMTP クラスインスタンスは次のメソッドを提供します:

SMTP.set_debuglevel(level)

コネクション間でやりとりされるメッセージ出力のレベルをセットします。メッセージの冗長さは level に応じて決まります。

SMTP.connect([host[, port]])

ホスト名とポート番号をもとに接続します。デフォルトはlocalhostの標準的なSMTPポート(25番)に接続します。もしホスト名の末尾がコロン(':')で、後に番号がついている場合は、「ホスト名:ポート番号」として扱われます。このメソッドはコンストラクタにホスト名及びポート番号が指定されている場合、自動的に呼び出されます。

SMTP.docmd(cmd[, argstring])

サーバへコマンド cmd を送信します。オプション引数 argstring はスペース文字でコマンドに連結します。戻り値は、整数値のレスポンスコードと、サーバからの応答の値をタプルで返します。 (サーバからの応答が数行に渡る場合でも一つの大きな文字列で返します。)

通常、この命令を明示的に使う必要はありませんが、自分で拡張するする時に使用するときに役立つかもしれません。

応答待ちのときに、サーバへのコネクションが失われると、 SMTPServerDisconnected が上がります。

SMTP.helo([hostname])

SMTPサーバに HELO コマンドで身元を示します。デフォルトではhostname引数はローカルホストを指します。サーバーが返したメッセージは、オブジェクトの help_resp 属性に格納されます。

通常は sendmail() が呼びだすため、これを明示的に呼び出す必要はありません。

SMTP.ehlo([hostname])

EHLO を利用し、ESMTPサーバに身元を明かします。デフォルトではhostname引数はローカルホストのFQDNです。また、ESMTPオプションのために応答を調べたものは、 has_extn() に備えて保存されます。また、幾つかの情報を属性に保存します: サーバーが返したメッセージは ehlo_resp 属性に、 does_esmtp 属性はサーバーがESMTPをサポートしているかどうかによって true か false に、 esmtp_features 属性は辞書で、サーバーが対応しているSMTP サービス拡張の名前と、もしあればそのパラメータを格納します。

has_extn() をメールを送信する前に使わない限り、明示的にこのメソッドを呼び出す必要があるべきではなく、 sendmail() が必要とした場合に呼ばれます。、

SMTP.ehlo_or_helo_if_needed()

このメソッドは、現在のセッションでまだ EHLO か HELO コマンドが実行されていない場合、 ehlo() and/or helo() メソッドを呼び出します。このメソッドは先に ESMTP EHLO を試します。

SMTPHeloError

サーバーが HELO に正しく返事しなかった.

バージョン 2.6 で追加.

SMTP.has_extn(name)

name が拡張SMTPサービスセットに含まれている場合には True を返し、そうでなければ False を返します。大小文字は区別されません。

SMTP.verify(address)

VRFY を利用してSMTPサーバにアドレスの妥当性をチェックします。妥当である場合はコード250と完全な RFC 822 [http://tools.ietf.org/html/rfc822.html] アドレス(人名)のタプルを返します。それ以外の場合は、400以上のエラーコードとエラー文字列を返します。

ノート

ほとんどのサイトはスパマーの裏をかくためにSMTPの VRFY は使用不可になっています。

SMTP.login(user, password)

認証が必要なSMTPサーバにログインします。認証に使用する引数はユーザ名とパスワードです。まだセッションが無い場合は、 EHLO または HELO コマンドでセッションを作ります。ESMTPの場合は EHLO が先に試されます。認証が成功した場合は通常このメソッドは戻りますが、例外が起こった場合は以下の例外が上がります:

SMTPHeloError

サーバが HELO に返答できなかった。

SMTPAuthenticationError

サーバがユーザ名/パスワードでの認証に失敗した。

SMTPException

どんな認証方法も見付からなかった。

SMTP.starttls([keyfile[, certfile]])

TLS(Transport Layer Security)モードでSMTPコネクションを出し、全てのSMTPコマンドは暗号化されます。これは ehlo() をもう一度呼びだすときにするべきです。

keyfile と certfile が提供された場合に、 socket モジュールの ssl() 関数が通るようになります。

もしまだ EHLO か HELO コマンドが実行されていない場合、このメソッドは ESMTP EHLO を先に試します。

バージョン 2.6 で変更.

SMTPHeloError

サーバーが HELO に正しく返事しなかった

SMTPException

サーバーが STARTTLS 拡張に対応していない

バージョン 2.6 で変更.

RuntimeError

実行中の Python インタプリタで、 SSL/TLS サポートが利用できない

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

メールを送信します。必要な引数は RFC 822 [http://tools.ietf.org/html/rfc822.html] のfromアドレス文字列、 RFC 822 [http://tools.ietf.org/html/rfc822.html] のtoアドレス文字列またはアドレス文字列のリスト、メッセージ文字列です。送信側は MAIL FROM コマンドで使用される mail_options の ESMTPオプション(8bitmime のような)のリストを得るかもしれません。

全ての RCPT コマンドで使われるべきESMTPオプション (例えば DSN コマンド)は、 rcpt_options を通して利用することができます。(もし送信先別にESMTPオプションを使う必要があれば、メッセージを送るために mail() 、 rcpt() 、 data() といった下位レベルのメソッドを使う必要があります。)

ノート

配送エージェントは from_addr 、 to_addrs 引数を使い、メッセージのエンベロープを構成します。 SMTP はメッセージヘッダを修正しません。

まだセッションが無い場合は、 EHLO または HELO コマンドでセッションを作ります。ESMTPの場合は EHLO が先に試されます。また、サーバがESMTP対応ならば、メッセージサイズとそれぞれ指定されたオプションも渡します。(featureオプションがあればサーバの広告をセットします) EHLO が失敗した場合は、ESMTPオプションの無い HELO が試されます。

このメソッドは最低でも1つの受信者にメールが受け入れられたときは普通に戻りますが、そうでない場合は例外を投げます。このメソッドが例外を投げられなければ、誰かが送信したメールを得るべきです。また、例外を投げれなかった場合は、拒絶された受取人ごとへの1つのエントリーと共に、辞書を返します。各エントリーは、サーバーによって送られたSMTPエラーコードおよびエラーメッセージのタプルを含んでいます。

このメソッドは次の例外を上げることがあります:

SMTPRecipientsRefused

全ての受信を拒否され、誰にもメールが届けられませんでした。例外オブジェクトの recipients 属性は、受信拒否についての情報の入った辞書オブジェクトです。 (辞書は少なくとも一つは受信されたときに似ています)。

SMTPHeloError

サーバが HELP に返答しませんでした。

SMTPSenderRefused

サーバが from_addr を弾きました。

SMTPDataError

サーバが予期しないエラーコードを返しました。(受信拒否以外)

また、この他の注意として、例外が上がった後もコネクションは開いたままになっています。

SMTP.quit()

SMTPセッションを終了し、コネクションを閉じます。 SMTP QUIT コマンドの結果を返します。

バージョン 2.6 で変更: 結果を返すようになりました

下位レベルのメソッドは標準SMTP/ESMTPコマンド HELP 、 RSET 、 NOOP 、 MAIL 、 RCPT 、 DATA に対応しています。通常これらは直接呼ぶ必要はなく、また、ドキュメントもありません。詳細はモジュールのコードを調べてください。

20.12.2. SMTP 使用例

次の例は最低限必要なメールアドレス(‘To’ と ‘From’)を含んだメッセージを送信するものです。この例では RFC 822 [http://tools.ietf.org/html/rfc822.html] ヘッダの加工もしていません。メッセージに含まれるヘッダは、メッセージに含まれる必要があり、特に、明確な’To’、と’From’アドレスはメッセージヘッダに含まれている必要があります。

import smtplib
import string

def prompt(prompt):
    return raw_input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print "Enter message, end with ^D (Unix) or ^Z (Windows):"

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs, ", ")))
while 1:
    try:
        line = raw_input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print "Message length is " + repr(len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

ノート

多くの場合、 email パッケージの機能を使って email メッセージを構築し、それを文字列に変換して、 sendmail() で送信する、という手順を用います。 email: 使用例 を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.13. smtpd — SMTP サーバー

このモジュールでは、 SMTP サーバを実装するためのクラスをいくつか提供しています。一つは何も行わない、オーバライドできる汎用のサーバで、その他の二つでは特定のメール送信ストラテジを提供しています。

20.13.1. SMTPServer オブジェクト

class smtpd.SMTPServer(localaddr, remoteaddr)

新たな SMTPServer オブジェクトを作成します。このオブジェクトはローカルのアドレス localaddr に関連づけ (bind) されます。オブジェクトは remoteaddr を上流の SMTP リレー先にします。このクラスは asyncore.dispatcher を継承しており、インスタンス化時に自身を asyncore のイベントループに登録します。

process_message(peer, mailfrom, rcpttos, data)

このクラスでは NotImplementedError 例外を送出します。受信したメッセージを使って何か意味のある処理をしたい場合にはこのメソッドをオーバライドしてください。コンストラクタの remoteaddr に渡した値は _remoteaddr 属性で参照できます。 peer はリモートホストのアドレスで、 mailfrom はメッセージエンベロープの発信元 (envelope originator) 、 rcpttos はメッセージエンベロープの受信対象、そして data は電子メールの内容が入った(RFC 2822 [http://tools.ietf.org/html/rfc2822.html] 形式の)文字列です。

20.13.2. DebuggingServer オブジェクト

class smtpd.DebuggingServer(localaddr, remoteaddr)

新たなデバッグ用サーバを生成します。引数は SMTPServer と同じです。メッセージが届いても無視し、標準出力に出力します。

20.13.3. PureProxy オブジェクト

class smtpd.PureProxy(localaddr, remoteaddr)

新たな単純プロキシ (pure proxy) サーバを生成します。引数は SMTPServer と同じです。全てのメッセージを remoteaddr にリレーします。このオブジェクトを動作させるとオープンリレーを作成してしまう可能性が多分にあります。注意してください。

20.13.4. MailmanProxy Objects

class smtpd.MailmanProxy(localaddr, remoteaddr)

新たな単純プロキシサーバを生成します。引数は SMTPServer と同じです。全てのメッセージを remoteaddr にリレーしますが、ローカルの mailman の設定に remoteaddr がある場合には mailman を使って処理します。このオブジェクトを動作させるとオープンリレーを作成してしまう可能性が多分にあります。注意してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.14. telnetlib — Telnet クライアント

telnetlib モジュールでは、Telnet プロトコルを実装している Telnet クラスを提供します。Telnet プロトコルについての詳細は RFC 854 [http://tools.ietf.org/html/rfc854.html] を参照してください。加えて、このモジュールでは Telnet プロトコルにおける制御文字 (下を参照してください) と、telnet オプションに対するシンボル定数を提供しています。telnet オプションに対するシンボル名は arpa/telnet.h の TELOPT_ がない状態での定義に従います。伝統的に arpa/telnet.h に含められていない telnet オプションのシンボル名については、このモジュールのソースコード自体を参照してください。

telnet コマンドのシンボル定数は、IAC、DONT、DO、WONT、WILL、SE (サブネゴシエーション終了)、NOP (何もしない)、DM (データマーク)、 BRK (ブレーク)、IP (プロセス割り込み)、AO (出力中断)、 AYT (応答確認)、EC (文字削除)、EL (行削除)、GA (進め)、SB ( サブネゴシエーション開始) です。

class telnetlib.Telnet([host[, port[, timeout]]])

Telnet は Telnet サーバへの接続を表現します。デフォルトでは、 Telnet クラスのインスタンスは最初はサーバに接続していません。接続を確立するには open() を使わなければなりません。別の方法として、コンストラクタに host とオプションの port を渡すことができます。この場合はコンストラクタの呼び出しが返る以前にサーバへの接続が確立されます。オプション引数の timeout が渡された場合、コネクション接続時のタイムアウト時間を秒数で指定します。 (指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます。)

すでに接続の開かれているンスタンスを再度開いてはいけません。

このクラスは多くの read_*() メソッドを持っています。これらのメソッドのいくつかは、接続の終端を示す文字を読み込んだ場合に EOFError を送出するので注意してください。例外を送出するのは、これらの関数が終端に到達しなくても空の文字列を返す可能性があるからです。詳しくは下記の個々の説明を参照してください。

バージョン 2.6 で変更: timeout が追加されました

参考

RFC 854 [http://tools.ietf.org/html/rfc854.html] - Telnet プロトコル仕様 (Telnet Protocol Specification)

Telnet プロトコルの定義。

20.14.1. Telnet オブジェクト

Telnet インスタンスは以下のメソッドを持っています:

Telnet.read_until(expected[, timeout])

expected で指定された文字列を読み込むか、 timeout で指定された秒数が経過するまで読み込みます。

与えられた文字列に一致する部分が見つからなかった場合、読み込むことができたもの全てを返します。これは空の文字列になる可能性があります。接続が閉じられ、転送処理済みのデータが得られない場合には EOFError が送出されます。

Telnet.read_all()

EOFに到達するまでの全てのデータを読み込みます; 接続が閉じられるまでブロックします。

Telnet.read_some()

EOF に到達しない限り、少なくとも 1 バイトの転送処理済みデータを読み込みます。EOF に到達した場合は '' を返します。すぐに読み出せるデータが存在しない場合にはブロックします。

Telnet.read_very_eager()

I/O によるブロックを起こさずに読み出せる全てのデータを読み込みます (eager モード)。

接続が閉じられており、転送処理済みのデータとして読み出せるものがない場合には EOFError が送出されます。それ以外の場合で、単に読み出せるデータがない場合には '' を返します。 IAC シーケンス操作中でないかぎりブロックしません。

Telnet.read_eager()

現在すぐに読み出せるデータを読み出します。

接続が閉じられており、転送処理済みのデータとして読み出せるものがない場合には EOFError が送出されます。それ以外の場合で、単に読み出せるデータがない場合には '' を返します。 IAC シーケンス操作中でないかぎりブロックしません。

Telnet.read_lazy()

すでにキューに入っているデータを処理して返します (lazy モード)。

接続が閉じられており、読み出せるデータがない場合には EOFError を送出します。それ以外の場合で、転送処理済みのデータで読み出せるものがない場合には '' を返します。 IAC シーケンス操作中でないかぎりブロックしません。

Telnet.read_very_lazy()

すでに処理済みキューに入っているデータを処理して返します (very lazy モード)。

接続が閉じられており、読み出せるデータがない場合には EOFError を送出します。それ以外の場合で、転送処理済みのデータで読み出せるものがない場合には '' を返します。このメソッドは決してブロックしません。

Telnet.read_sb_data()

SB/SE ペア (サブオプション開始／終了) の間に収集されたデータを返します。 SE コマンドによって起動されたコールバック関数はこれらのデータにアクセスしなければなりません。

このメソッドはけっしてブロックしません。

バージョン 2.3 で追加.

Telnet.open(host[, port])

サーバホストに接続します。第二引数はオプションで、ポート番号を指定します。標準の値は通常の Telnet ポート番号 (23) です。オプション引数の timeout が渡された場合、コネクション接続時などのブロックする操作のタイムアウト時間を秒数で指定します。 (指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます。)

すでに接続しているインスタンスで再接続を試みてはいけません。

バージョン 2.6 で変更: timeout が追加されました

Telnet.msg(msg[, *args])

デバッグレベルが > 0 のとき、デバッグ用のメッセージを出力します。追加の引数が存在する場合、標準の文字列書式化演算子 % を使って msg 中の書式指定子に代入されます。

Telnet.set_debuglevel(debuglevel)

デバッグレベルを設定します。 debuglevel が大きくなるほど、 (sys.stdout に) デバッグメッセージがたくさん出力されます。

Telnet.close()

接続を閉じます。

Telnet.get_socket()

内部的に使われているソケットオブジェクトです。

Telnet.fileno()

内部的に使われているソケットオブジェクトのファイル記述子です。

Telnet.write(buffer)

ソケットに文字列を書き込みます。このとき IAC 文字については 2 度送信します。接続がブロックした場合、書き込みがブロックする可能性があります。接続が閉じられた場合、 socket.error が送出されるかもしれません。

Telnet.interact()

非常に低機能の telnet クライアントをエミュレートする対話関数です。

Telnet.mt_interact()

interact() のマルチスレッド版です。

Telnet.expect(list[, timeout])

正規表現のリストのうちどれか一つにマッチするまでデータを読みます。

第一引数は正規表現のリストです。コンパイルされたもの (re.RegexObject のインスタンス) でも、コンパイルされていないもの (文字列) でもかまいません。オプションの第二引数はタイムアウトで、単位は秒です; 標準の値は無期限に設定されています。

3 つの要素からなるタプル: 最初にマッチした正規表現のインデクス; 返されたマッチオブジェクト; マッチ部分を含む、マッチするまでに読み込まれたテキストデータ、を返します。

ファイル終了子が見つかり、かつ何もテキストデータが読み込まれなかった場合、 EOFError が送出されます。そうでない場合で何もマッチしなかった場合には (-1, None, text) が返されます。ここで text はこれまで受信したテキストデータです (タイムアウトが発生した場合には空の文字列になる場合もあります)。

正規表現の末尾が (.* のような) 貪欲マッチングになっている場合や、入力に対して 1 つ以上の正規表現がマッチする場合には、その結果は決定不能で、I/O のタイミングに依存するでしょう。

Telnet.set_option_negotiation_callback(callback)

telnet オプションが入力フローから読み込まれるたびに、 callback が (設定されていれば) 以下の引数形式: callback(telnet socket, command (DO/DONT/WILL/WONT), option) で呼び出されます。その後 telnet オプションに対しては telnetlib は何も行いません。

20.14.2. Telnet Example

典型的な使い方を表す単純な例を示します:

import getpass
import sys
import telnetlib

HOST = "localhost"
user = raw_input("Enter your remote account: ")
password = getpass.getpass()

tn = telnetlib.Telnet(HOST)

tn.read_until("login: ")
tn.write(user + "\n")
if password:
    tn.read_until("Password: ")
    tn.write(password + "\n")

tn.write("ls\n")
tn.write("exit\n")

print tn.read_all()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.15. uuid — RFC 4122 に準拠した UUID オブジェクト

バージョン 2.5 で追加.

このモジュールでは immutable（変更不能）な UUID オブジェクト（ UUID クラス）と RFC 4122 [http://tools.ietf.org/html/rfc4122.html] の定めるバージョン 1、3、4、5 の UUID を生成するための uuid1(), uuid2(), uuid3(), uuid4(), uuid(), が提供されています。

もしユニークな ID が必要なだけであれば、おそらく uuid1() か uuid4() をコールすれば良いでしょう。 uuid1() はコンピュータのネットワークアドレスを含む UUID を生成するためにプライバシーを侵害するかもしれない点に注意してください。 uuid4() はランダムな UUID を生成します。

class uuid.UUID([hex[, bytes[, bytes_le[, fields[, int[, version]]]]]])

32 桁の 16 進数文字列、 bytes に 16 バイトの文字列、 bytes_le 引数に 16 バイトのリトルエンディアンの文字列、 field 引数に 6 つの整数のタプル（32ビット time_low, 16 ビット time_mid, 16ビット time_hi_version, 8ビット clock_seq_hi_variant, 8ビット clock_seq_low, 48ビット node ）、または int に一つの 128 ビット整数のいずれかから UUID を生成します。16 進数が与えられた時、波括弧、ハイフン、それと URN 接頭辞は無視されます。例えば、これらの表現は全て同じ UUID を払い出します。

UUID('{12345678-1234-5678-1234-567812345678}')
UUID('12345678123456781234567812345678')
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
UUID(bytes='\x12\x34\x56\x78'*4)
UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
              '\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
UUID(int=0x12345678123456781234567812345678)

hex, bytes, bytes_le, fields, または int のうち、どれかただ一つだけが与えられなければいけません。 version 引数はオプションです；与えられた場合、結果の UUID は与えられた hex, bytes, bytes_le, fields, または int をオーバーライドして、 RFC 4122 に準拠した variant と version ナンバーのセットを持つことになります。 bytes_le, fields, or int.

UUID インスタンスは以下の読み取り専用属性を持ちます：

UUID.bytes

16 バイト文字列（バイトオーダーがビッグエンディアンの 6 つの整数フィールドを持つ）のUUID。

UUID.bytes_le

16 バイト文字列（ time_low, time_mid, time_hi_version をリトルエンディアンで持つ）の UUID。

UUID.fields

UUID の 6 つの整数フィールドを持つタプルで、これは 6 つの個別の属性と 2 つの派生した属性としても取得可能です。

フィールド | 意味
time_low | UUID の最初の 32 ビット
time_mid | UUID の次の 16 ビット
time_hi_version | UUID の次の 16 ビット
clock_seq_hi_variant | UUID の次の 8 ビット
clock_seq_low | UUID の次の 8 ビット
node | UUID の最後の 48 ビット
time | 60 ビットのタイムスタンプ
clock_seq | 14 ビットのシーケンス番号

UUID.hex

32 文字の 16 進数文字列での UUID。

UUID.int

128 ビット整数での UUID。

UUID.urn

RFC 4122 で規定される URN での UUID。

UUID.variant

UUID の内部レイアウトを決定する UUID の variant。これは整数の定数 The UUID variant, which determines the internal layout of the UUID. This will be one of the integer constants RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, 又は RESERVED_FUTURE のいずれかになります。

UUID.version

UUID の version 番号（1 から 5、variant が RFC_4122 である場合だけ意味があります）。

The uuid モジュールには以下の関数があります：

uuid.getnode()

48 ビットの正の整数としてハードウェアアドレスを取得します。最初にこれを起動すると、別個のプログラムが立ち上がって非常に遅くなることがあります。もしハードウェアを取得する試みが全て失敗すると、ランダムな 48 ビットに RFC 4122 で推奨されているように 8 番目のビットを 1 に設定した数を使います。 “ハードウェアアドレス” とはネットワークインターフェースの MAC アドレスを指し、複数のネットワークインターフェースを持つマシンの場合、それらのどれか一つの MAC アドレスが返るでしょう。

uuid.uuid1([node[, clock_seq]])

UUID をホスト ID、シーケンス番号、現在時刻から生成します。 node が与えられなければ、 getnode() がハードウェアアドレス取得のために使われます。 clock_seq が与えられると、これはシーケンス番号として使われます；さもなくば 14 ビットのランダムなシーケンス番号が選ばれます。

uuid.uuid3(namespace, name)

UUID を名前空間識別子（これは UUID です）と名前（文字列です）の MD5 ハッシュから生成します。

uuid.uuid4()

ランダムな UUID を生成します。

uuid.uuid5(namespace, name)

名前空間識別子（これは UUID です）と名前（文字列です）の SHA-1 ハッシュから生成します。

uuid モジュールは uuid3() または uuid5() で利用するために次の名前空間識別子を定義しています。

uuid.NAMESPACE_DNS

この名前空間が指定された場合、 name 文字列は完全修飾ドメイン名です。

uuid.NAMESPACE_URL

この名前空間が指定された場合、 name 文字列は URL です。

uuid.NAMESPACE_OID

この名前空間が指定された場合、 name 文字列は ISO OID です。

uuid.NAMESPACE_X500

この名前空間が指定された場合、 name 文字列は X.500 DN の DER またはテキスト出力形式です。

The uuid モジュールは以下の定数を variant 属性が取りうる値として定義しています：

uuid.RESERVED_NCS

NCS 互換性のために予約されています。

uuid.RFC_4122

RFC 4122 [http://tools.ietf.org/html/rfc4122.html] で与えられた UUID レイアウトを指定します。

uuid.RESERVED_MICROSOFT

Microsoft の互換性のために予約されています。

uuid.RESERVED_FUTURE

将来のために予約されています。

参考

RFC 4122 [http://tools.ietf.org/html/rfc4122.html] - A Universally Unique IDentifier (UUID) URN Namespace

この仕様は UUID のための Uniform Resource Name 名前空間、 UUID の内部フォーマットと UUID の生成方法を定義しています。

20.15.1. 例

典型的な uuid モジュールの利用方法を示します：

>>> import uuid

# UUID をホスト ID と現在時刻に基づいて生成します
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

# 名前空間 UUID と名前の MD5 ハッシュを使って UUID を生成します
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

# ランダムな UUID を作成します
>>> uuid.uuid4()
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

# 名前空間 UUID と名前の SHA-1 ハッシュを使って UUID を生成します
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

# 16 進数文字列から UUID を生成します（波括弧とハイフンは無視されます）
>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

# UUID を標準的な 16 進数の文字列に変換します
>>> str(x)
'00010203-0405-0607-0809-0a0b0c0d0e0f'

# 生の 16 バイトの UUID を取得します
>>> x.bytes
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

# 16 バイトの文字列から UUID を生成します
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.16. urlparse — URL を解析して構成要素にする

ノート

urlparse モジュールは Python 3 では urllib.parse にリネームされました。 2to3 ツールはソースコードのimportを自動的に Python 3 用に修正します。

このモジュールでは URL (Uniform Resource Locator) 文字列をその構成要素 (アドレススキーム、ネットワーク上の位置、パスその他) に分解したり、構成要素を URL に組みなおしたり、”相対 URL (relative URL)” を指定した “基底 URL (base URL)” に基づいて絶対 URL に変換するための標準的なインタフェースを定義しています。

このモジュールは相対 URL のインターネット RFC に対応するように設計されました (そして RFC の初期ドラフトのバグを発見しました！)。サポートされる URL スキームは以下の通りです: file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais 。

バージョン 2.5 で追加: sftp および sips スキームのサポートが追加されました.

参考

最新バージョンの urlparse module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/urlparse.py?view=markup]

urlparse モジュールには以下の関数が定義されています。

urlparse.urlparse(urlstring[, scheme[, allow_fragments]])

URL を解釈して 6 つの構成要素にし、6 要素のタプルを返します。このタプルは URL の一般的な構造: scheme://netloc/path;parameters?query#fragment に対応しています。各タプル要素は文字列で、空の場合もあります。構成要素がさらに小さい要素に分解されることはありません (例えばネットワーク上の位置は単一の文字列になります)。また % によるエスケープは展開されません。上で示された区切り文字がタプルの各要素の一部分として含まれることはありませんが、 path 要素の先頭のスラッシュがある場合には例外です。たとえば以下のようになります。

>>> from urlparse import urlparse
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
>>> o   # doctest: +NORMALIZE_WHITESPACE
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> o.scheme
'http'
>>> o.port
80
>>> o.geturl()
'http://www.cwi.nl:80/%7Eguido/Python.html'

RFC 1808 [http://tools.ietf.org/html/rfc1808.html] にある文法仕様に基づき、 urlparse は ‘//’ で始まる場合にのみ netloc を認識します。それ以外の場合は、入力は相対URLであると推定され、 path 部分で始まることになります。

>>> from urlparse import urlparse
>>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
           params='', query='', fragment='')
>>> urlparse('www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='', path='www.cwi.nl:80/%7Eguido/Python.html',
           params='', query='', fragment='')
>>> urlparse('help/Python.html')
ParseResult(scheme='', netloc='', path='help/Python.html', params='',
           query='', fragment='')

scheme 引数が指定されている場合、標準のアドレススキームを表し、アドレススキームを指定していない URL に対してのみ使われます。この引数の標準の値は空文字列です。

allow_fragments 引数が偽の場合、URL のアドレススキームがフラグメント指定をサポートしていても指定できなくなります。この引数の標準の値は True です。

戻り値は実際には tuple のサブクラスのインスタンスです。このクラスには以下の読み出し専用の便利な属性が追加されています。

属性 | インデクス | 値 | 指定されなかった場合の値
scheme | 0 | URL スキーム | 空文字列
netloc | 1 | ネットワーク上の位置 | 空文字列
path | 2 | 階層的パス | 空文字列
params | 3 | 最後のパス要素に対するパラメータ | 空文字列
query | 4 | クエリ要素 | 空文字列
fragment | 5 | フラグメント指定子 | 空文字列
username |  | ユーザ名 | None
password |  | パスワード | None
hostname |  | ホスト名 (小文字) | None
port |  | ポート番号を表わす整数 (もしあれば) | None

結果オブジェクトのより詳しい情報は urlparse() および urlsplit() の結果 節を参照してください。

バージョン 2.5 で変更: 戻り値に属性が追加されました.

バージョン 2.7 で変更: IPv6 の URL パースに対応しました。

urlparse.parse_qs(qs[, keep_blank_values[, strict_parsing]])

文字列引数として渡されたクエリ文字列 (application/x-www-form-urlencoded 型のデータ) を解釈します。解釈されたデータを辞書として返します。辞書のキーは一意なクエリ変数名で、値は各変数名に対する値からなるリストです。

オプションの引数 keep_blank_values は、パーセントエンコードされたクエリの中の値が入っていないクエリの値を空白文字列と見なすかどうかを示すフラグです。値が真であれば、値の入っていないフィールドは空文字列のままになります。標準では偽で、値の入っていないフィールドを無視し、そのフィールドはクエリに含まれていないものとして扱います。

オプションの引数 strict_pasing はパース時のエラーをどう扱うかを決めるフラグです。値が偽なら (標準の設定です)、エラーは暗黙のうちに無視します。値が真なら ValueError 例外を送出します。

辞書等をクエリ文字列に変換する場合は urllib. urlencode() 関数を使用してください。

バージョン 2.6 で追加: cgi モジュールからコピーされてきました。

urlparse.parse_qsl(qs[, keep_blank_values[, strict_parsing]])

文字列引数として渡されたクエリ文字列 (application/x-www-form-urlencoded 型のデータ) を解釈します。解釈されたデータは名前と値のペアからなるリストです。

オプションの引数 keep_blank_values は、パーセントエンコードされたクエリ中で値の入っていないものを空文字列と見なすかどうかを示すフラグです。値が真であれば、値の入っていないフィールドは空文字列のままになります。標準では偽で、値の入っていないフィールドを無視し、そのフィールドはクエリに含まれていないものとして扱います。

オプションの引数 strict_pasing はパース時のエラーをどう扱うかを決めるフラグです。値が偽なら (標準の設定です)、エラーは暗黙のうちに無視します。値が真なら ValueError 例外を送出します。

ペアのリストからクエリ文字列を生成する場合には urllib.urlencode() 関数を使用します。

バージョン 2.6 で追加: cgi モジュールからコピーされてきました。

urlparse.urlunparse(parts)

urlparse() が返すような形式のタプルから URL を構築します。 parts 引数は任意の 6 要素イテラブルです。解析された元の URL が、不要な区切り文字を持っていた場合には、多少違いはあるが等価な URL になるかもしれません。 (例えばクエリ内容が空の ? のようなもので、RFC はこれらを等価だと述べています。)

urlparse.urlsplit(urlstring[, scheme[, allow_fragments]])

urlparse() に似ていますが、URL から params を切り離しません。このメソッドは通常、URL の path 部分において、各セグメントにパラメタ指定をできるようにした最近の URL 構文 (RFC 2396 [http://tools.ietf.org/html/rfc2396.html] 参照) が必要な場合に、 urlparse() の代わりに使われます。パスセグメントとパラメタを分割するためには分割用の関数が必要です。この関数は 5 要素のタプル: (アドレススキーム、ネットワーク上の位置、パス、クエリ、フラグメント指定子) を返します。

戻り値は実際には tuple のサブクラスのインスタンスです。このクラスには以下の読み出し専用の便利な属性が追加されています。

属性 | インデクス | 値 | 指定されなかった場合の値
scheme | 0 | URL スキーム | 空文字列
netloc | 1 | ネットワーク上の位置 | 空文字列
path | 2 | 階層的パス | 空文字列
query | 3 | クエリ要素 | 空文字列
fragment | 4 | フラグメント指定子 | 空文字列
username |  | ユーザ名 | None
password |  | パスワード | None
hostname |  | ホスト名 (小文字) | None
port |  | ポート番号を表わす整数 (もしあれば) | None

結果オブジェクトのより詳しい情報は urlparse() および urlsplit() の結果 節を参照してください。

バージョン 2.2 で追加.

バージョン 2.5 で変更: 戻り値に属性が追加されました.

urlparse.urlunsplit(parts)

urlsplit() が返すような形式のタプル中のエレメントを組み合わせて、文字列の完全な URL にします。 parts 引数は任意の 5 要素イテラブルです。解析された元の URL が、不要な区切り文字を持っていた場合には、多少違いはあるが等価な URL になるかもしれません。 (例えばクエリ内容が空の ? のようなもので、RFC はこれらを等価だと述べています。)

バージョン 2.2 で追加.

urlparse.urljoin(base, url[, allow_fragments])

“基底 URL”(base)と別のURL(url)を組み合わせて、完全な URL (“絶対 URL”) を構成します。ぶっちゃけ、この関数は基底 URL の要素、特にアドレススキーム、ネットワーク上の位置、およびパス (の一部) を使って、相対 URL にない要素を提供します。以下の例のようになります。

>>> from urlparse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'

allow_fragments 引数は urlparse() における引数と同じ意味とデフォルトを持ちます。

ノート

url が(// か scheme:// で始まっている)絶対URLであれば、その url のホスト名と/もしくは scheme は、結果に反映されます。例えば:

>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
...         '//www.python.org/%7Eguido')
'http://www.python.org/%7Eguido'

もしこの動作が望みのものでない場合は、 url を urlsplit() と urlunsplit() で先に処理して、 scheme と netloc を削除してください。

urlparse.urldefrag(url)

url がフラグメント指定子を含む場合、フラグメント指定子を持たないバージョンに修正された url と、別の文字列に分割されたフラグメント指定子を返します。 url 中にフラグメント指定子がない場合、そのままの url と空文字列を返します。

参考

RFC 3986 [http://tools.ietf.org/html/rfc3986.html] - Uniform Resource Identifiers

これが現在の標準規格(STD66)です。 urlparse モジュールに対するすべての変更は、この規格を確認しなければなりません。後方互換性のため、あるいは、メジャーなブラウザに見られる事実上標準となった URL 解析への要求のために、この規格から外れている部分があります。

RFC 2732 [http://tools.ietf.org/html/rfc2732.html] - Format for Literal IPv6 Addresses in URL’s.

この規格は IPv6 の URL を解析するときの要求事項を記述しています。

RFC 2396 [http://tools.ietf.org/html/rfc2396.html] - Uniform Resource Identifiers (URI): Generic Syntax

この RFC では Uniform Resource Name (URN) と Uniform Resource Locator (URL) の両方に対する一般的な文法的要求事項を記述しています。

RFC 2368 [http://tools.ietf.org/html/rfc2368.html] - The mailto URL scheme.

mailto URL スキームに対する文法的要求事項.

RFC 1808 [http://tools.ietf.org/html/rfc1808.html] - Relative Uniform Resource Locators

この RFC には絶対 URL と相対 URL を結合するための規則がボーダケースの取扱い方を決定する “異常な例” つきで収められています。

RFC 1738 [http://tools.ietf.org/html/rfc1738.html] - Uniform Resource Locators (URL)

この RFC では絶対 URL の形式的な文法と意味付けを仕様化しています。

20.16.1. urlparse() および urlsplit() の結果

urlparse() および urlsplit() から得られる結果オブジェクトはそれぞれ tuple 型のサブクラスです。これらのクラスはそれぞれの関数の説明の中で述べたような属性とともに、追加のメソッドを一つ提供しています。

ParseResult.geturl()

再結合された形で元の URL の文字列を返します。この文字列は元の URL とは次のような点で異なるかもしれません。スキームは常に小文字に正規化されます。また空の要素は省略されます。特に、空のパラメータ、クエリ、フラグメント識別子は取り除かれます。

このメソッドの結果は再び解析に回されたとしても不動点となります。

>>> import urlparse
>>> url = 'HTTP://www.Python.org/doc/#'

>>> r1 = urlparse.urlsplit(url)
>>> r1.geturl()
'http://www.Python.org/doc/'

>>> r2 = urlparse.urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'

バージョン 2.5 で追加.

以下のクラスが解析結果の実装を提供します。

class urlparse.BaseResult

具体的な結果クラスたちの基底クラスです。このクラスがほとんどの属性の定義を与えます。しかし geturl() メソッドは提供しません。このクラスは tuple から派生していますが、 __init__() や __new__() をオーバーライドしません。

class urlparse.ParseResult(scheme, netloc, path, params, query, fragment)

urlparse() の結果のための具体クラスです。 __new__() メソッドをオーバーライドして正しい個数の引数が引き渡されたことを確認するようにしています。

class urlparse.SplitResult(scheme, netloc, path, query, fragment)

urlsplit() の結果のための具体クラスです。 __new__() メソッドをオーバーライドして正しい個数の引数が引き渡されたことを確認するようにしています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.17. SocketServer — ネットワークサーバ構築のためのフレームワーク

ノート

SocketServer モジュールは、Python 3では socketserver にリネームされました。 2to3 ツールが、ソースコード内のimportを自動的にPython3用に修正します。

SocketServer モジュールはネットワークサーバを実装するタスクを単純化します。

このモジュールには 4 つのサーバクラスがあります: TCPServer は、クライアントとサーバ間に継続的なデータ流路を提供する、インターネット TCP プロトコルを使います。 UDPServer は、順序通りに到着しなかったり、転送中に喪失してしまってもかまわない情報の断続的なパケットである、データグラムを使います。 UnixStreamServer および UnixDatagramServer クラスも同様ですが、Unix ドメインソケットを使います; 従って非 Unix プラットフォームでは利用できません。ネットワークプログラミングについての詳細は、W. Richard Steven 著 UNIX Network Programming や、 Ralph Davis 著 Win32 Network Programming のような書籍を参照してください。

これらの 4 つのクラスは要求を 同期的に (synchronously) 処理します; 各要求は次の要求を開始する前に完結していなければなりません。同期的な処理は、サーバで大量の計算を必要とする、あるいはクライアントが処理するには時間がかかりすぎるような大量のデータを返す、といった理由によってリクエストに長い時間がかかる状況には向いていません。こうした状況の解決方法は別のプロセスを生成するか、個々の要求を扱うスレッドを生成することです; ForkingMixIn および ThreadingMixIn 配合クラス (mix-in classes) を使えば、非同期的な動作をサポートできます。

サーバの作成にはいくつかのステップがあります。最初に、 BaseRequestHandler クラスをサブクラス化して要求処理クラス (request hander class) を生成し、その handle() メソッドを上書きしなければなりません; このメソッドで入力される要求を処理します。次に、サーバクラスのうち一つをインスタンス化して、サーバのアドレスと要求処理クラスを渡さなければなりません。最後に、サーバオブジェクトの handle_request() または serve_forever() メソッドを呼び出して、単一または多数の要求を処理します。

ThreadingMixIn から継承してスレッドを利用した接続を行う場合、突発的な通信切断時の処理を明示的に指定する必要があります。 ThreadingMixIn クラスには daemon_threads 属性があり、サーバがスレッドの終了を待ち合わせるかどうかを指定する事ができます。スレッドが独自の処理を行う場合は、このフラグを明示的に指定します。デフォルトは False で、Pythonは ThreadingMixIn クラスが起動した全てのスレッドが終了するまで実行し続けます。

サーバクラス群は使用するネットワークプロトコルに関わらず、同じ外部メソッドおよび属性を持ちます。

20.17.1. サーバ生成に関するノート

継承図にある五つのクラスのうち四つは四種類の同期サーバを表わしています。

+------------+
| BaseServer |
+------------+
      |
      v
+-----------+        +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+        +------------------+
      |
      v
+-----------+        +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+        +--------------------+

UnixDatagramServer は UDPServer から派生していて、 UnixStreamServer からではないことに注意してください — IP と Unix ストリームサーバの唯一の違いはアドレスファミリーでそれは両方の Unix サーバクラスで単純に繰り返されています。

それぞれのタイプのサーバのフォークしたりスレッド実行したりするバージョンは ForkingMixIn および ThreadingMixIn ミクシン(mix-in)クラスを使って作ることができます。たとえば、スレッド実行する UDP サーバクラスは以下のようにして作られます。

class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass

ミクシンクラスは UDPServer で定義されるメソッドをオーバライドするために、先に来なければなりません。様々なメンバ変数を設定することで元になるサーバ機構の振る舞いを変えられます。

サービスの実装には、 BaseRequestHandler からクラスを派生させてその handle() メソッドを再定義しなければなりません。このようにすれば、サーバクラスと要求処理クラスを結合して様々なバージョンのサービスを実行することができます。要求処理クラスはデータグラムサービスかストリームサービスかで異なることでしょう。この違いは処理サブクラス StreamRequestHandler または DatagramRequestHandler を使うという形で隠蔽できます。

もちろん、まだ頭を使わなければなりません! たとえば、サービスがリクエストによっては書き換えられるようなメモリ上の状態を使うならば、フォークするサーバを使うのは馬鹿げています。というのも子プロセスでの書き換えは親プロセスで保存されている初期状態にも親プロセスから分配される各子プロセスの状態にも届かないからです。この場合、スレッド実行するサーバを使うことはできますが、共有データの一貫性を保つためにロックを使わなければならなくなるでしょう。

一方、全てのデータが外部に(たとえばファイルシステムに)保存される HTTP サーバを作っているのだとすると、同期クラスではどうしても一つの要求が処理されている間サービスが「耳の聞こえない」状態を呈することになります — この状態はもしクライアントが要求した全てのデータをゆっくり受け取るととても長い時間続きかねません。こういう場合にはサーバをスレッド実行したりフォークすることが適切です。

ある場合には、要求の一部を同期的に処理する一方で、要求データに依って子プロセスをフォークして処理を終了させる、といった方法も適当かもしれません。こうした処理方法は同期サーバを使って要求処理クラスの handle() メソッドの中で自分でフォークするようにして実装することができます。

スレッドも fork() もサポートされない環境で (もしくはサービスにとってそれらがあまりに高価についたり不適切な場合に) 多数の同時要求を捌くもう一つのアプローチは、部分的に処理し終えた要求のテーブルを自分で管理し、次にどの要求に対処するか (または新しく入ってきた要求を扱うかどうか)を決めるのに select() を使う方法です。これは(もしスレッドやサブプロセスが使えなければ)特にストリームサービスに対して重要で、そのようなサービスでは各クライアントが潜在的に長く接続し続けます。この問題を管理する別の方法について、 asyncore モジュールを参照してください。

20.17.2. Serverオブジェクト

class SocketServer.BaseServer

これは、このモジュールにある全てのサーバーオブジェクトの基底クラスです。このクラスは、ここから説明するインタフェースを定義していますが、そのほとんどを実装していません。実装はサブクラスで行われます。

BaseServer.fileno()

サーバが要求待ちを行っているソケットのファイル記述子を整数で返します。この関数は一般的に、同じプロセス中の複数のサーバを監視できるようにするために、 select.select() に渡されます。

BaseServer.handle_request()

単一の要求を処理します。この関数は以下のメソッド: get_request() 、 verify_request() 、および process_request() を順番に呼び出します。ハンドラ中でユーザによって提供された handle() が例外を送出した場合、サーバの handle_error() メソッドが呼び出されます。 self.timeout 秒以内にリクエストが来なかった場合、 handle_timeout() が呼ばれて、 handle_request() が終了します。

BaseServer.serve_forever()

shutdown() を呼ばれるまで、リクエストを処理し続けます。 shutdown が呼ばれたかどうかを、 poll_interval 秒ごとにポーリングします。

BaseServer.shutdown()

serve_forever() ループに停止するように指示し、停止されるまで待ちます。

バージョン 2.6 で追加.

BaseServer.address_family

サーバのソケットが属しているプロトコルファミリです。一般的な値は socket.AF_INET および socket.AF_UNIX です。

BaseServer.RequestHandlerClass

ユーザが提供する要求処理クラスです; 要求ごとにこのクラスのインスタンスが生成されます。

BaseServer.server_address

サーバが要求待ちを行うアドレスです。アドレスの形式はプロトコルファミリによって異なります。詳細は socket モジュールを参照してください。インターネットプロトコルでは、この値は例えば ('127.0.0.1', 80) のようにアドレスを与える文字列と整数のポート番号を含むタプルです。

BaseServer.socket

サーバが入力の要求待ちを行うためのソケットオブジェクトです。

サーバクラスは以下のクラス変数をサポートします:

BaseServer.allow_reuse_address

サーバがアドレスの再使用を許すかどうかを示す値です。この値は標準で False で、サブクラスで再使用ポリシを変更するために設定することができます。

BaseServer.request_queue_size

要求待ち行列 (queue) のサイズです。単一の要求を処理するのに長時間かかる場合には、サーバが処理中に届いた要求は最大 request_queue_size 個まで待ち行列に置かれます。待ち行列が一杯になると、それ以降のクライアントからの要求は “接続拒否 (Connection denied)” エラーになります。標準の値は通常 5 ですが、この値はサブクラスで上書きすることができます。

BaseServer.socket_type

サーバが使うソケットの型です; 一般的な2つの値は、 socket.SOCK_STREAM と socket.SOCK_DGRAM です。

BaseServer.timeout

タイムアウト時間(秒)、もしくは、タイムアウトを望まない場合に None 。 handle_request() がこの時間内にリクエストを受信しない場合、 handle_timeout() メソッドが呼ばれます。

TCPServer のような基底クラスのサブクラスで上書きできるサーバメソッドは多数あります; これらのメソッドはサーバオブジェクトの外部のユーザにとっては役にたたないものです。

BaseServer.finish_request()

RequestHandlerClass をインスタンス化し、 handle() メソッドを呼び出して、実際に要求を処理します。

BaseServer.get_request()

ソケットから要求を受理して、クライアントとの通信に使われる 新しい ソケットオブジェクト、およびクライアントのアドレスからなる、 2 要素のタプルを返します。

BaseServer.handle_error(request, client_address)

この関数は RequestHandlerClass の handle() メソッドが例外を送出した際に呼び出されます。標準の動作では標準出力へトレースバックを出力し、後続する要求を継続して処理します。

BaseServer.handle_timeout()

この関数は timeout 属性が None 以外に設定されて、リクエストがないままタイムアウト秒数が過ぎたときに呼ばれます。 fork型サーバーでのデフォルトの動作は、終了した子プロセスの情報を集めるようになっています。スレッド型サーバーではこのメソッドは何もしません。

BaseServer.process_request(request, client_address)

finish_request() を呼び出して、 RequestHandlerClass() のインスタンスを生成します。必要なら、この関数から新たなプロセスかスレッドを生成して要求を処理することができます; その処理は ForkingMixIn または ThreadingMixIn クラスが行います。

BaseServer.server_activate()

サーバのコンストラクタによって呼び出され、サーバを活動状態にします。デフォルトではサーバのソケットを listen() するだけです。このメソッドは上書きできます。

BaseServer.server_bind()

サーバのコンストラクタによって呼び出され、適切なアドレスにソケットをバインドします。このメソッドは上書きできます。

BaseServer.verify_request(request, client_address)

ブール値を返さなければなりません; 値が True の場合には要求が処理され、 False の場合には要求は拒否されます。サーバへのアクセス制御を実装するためにこの関数を上書きすることができます。標準の実装では常に True を返します。

20.17.3. RequestHandlerオブジェクト

要求処理クラスでは、新たな handle() メソッドを定義しなくてはならず、また以下のメソッドのいずれかを上書きすることができます。各要求ごとに新たなインスタンスが生成されます。

RequestHandler.finish()

handle() メソッドが呼び出された後、何らかの後始末を行うために呼び出されます。標準の実装では何も行いません。 setup() または handle() が例外を送出した場合には、この関数は呼び出されません。

RequestHandler.handle()

この関数では、クライアントからの要求を実現するために必要な全ての作業を行わなければなりません。デフォルト実装では何もしません。この作業の上で、いくつかのインスタンス属性を利用することができます; クライアントからの要求は self.request です; クライアントのアドレスは self.client_address です; そしてサーバごとの情報にアクセスする場合には、サーバインスタンスを self.server で取得できます。

self.request の型はサービスがデータグラム型かストリーム型かで異なります。ストリーム型では、 self.request はソケットオブジェクトです; データグラムサービスでは、 self.request は文字列とソケットのタプルになります。しかし、この違いは要求処理サブクラスの StreamRequestHandler や DatagramRequestHandler を使うことで隠蔽することができます。これらのクラスでは setup() および finish() メソッドを上書きしており、 self.rfile および self.wfile 属性を提供しています。 self.rfile および self.wfile は、要求データを取得したりクライアントにデータを返すために、それぞれ読み出し、書き込みを行うことができます。

RequestHandler.setup()

handle() メソッドより前に呼び出され、何らかの必要な初期化処理を行います。標準の実装では何も行いません。

20.17.4. 例

20.17.4.1. SocketServer.TCPServer の例

サーバーサイドの例です:

import SocketServer

class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "%s wrote:" % self.client_address[0]
        print self.data
        # just send back the same data, but upper-cased
        self.request.send(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()

別の、ストリーム(標準のファイル型のインタフェースを利用して通信をシンプルにしたファイルライクオブジェクト)を使うリクエストハンドラクラスの例です:

class MyTCPHandler(SocketServer.StreamRequestHandler):

    def handle(self):
        # self.rfile is a file-like object created by the handler;
        # we can now use e.g. readline() instead of raw recv() calls
        self.data = self.rfile.readline().strip()
        print "%s wrote:" % self.client_address[0]
        print self.data
        # Likewise, self.wfile is a file-like object used to write back
        # to the client
        self.wfile.write(self.data.upper())

先ほどとの違いは、 readline() の呼び出しが、改行を受け取るまで recv() を複数回呼び出すことです。 1回の recv() の呼び出しは、クライアント側から1回の send() 呼び出しで送信された分しか受け取りません。

クライアントサイドの例:

import socket
import sys

HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])

# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to server and send data
sock.connect((HOST, PORT))
sock.send(data + "\n")

# Receive data from the server and shut down
received = sock.recv(1024)
sock.close()

print "Sent:     %s" % data
print "Received: %s" % received

この例の出力は次のようになります。

サーバー:

$ python TCPServer.py
127.0.0.1 wrote:
hello world with TCP
127.0.0.1 wrote:
python is nice

クライアント:

$ python TCPClient.py hello world with TCP
Sent:     hello world with TCP
Received: HELLO WORLD WITH TCP
$ python TCPClient.py python is nice
Sent:     python is nice
Received: PYTHON IS NICE

20.17.4.2. SocketServer.UDPServer の例

サーバーサイドの例です:

import SocketServer

class MyUDPHandler(SocketServer.BaseRequestHandler):
    """
    This class works similar to the TCP handler class, except that
    self.request consists of a pair of data and client socket, and since
    there is no connection the client address must be given explicitly
    when sending data back via sendto().
    """

    def handle(self):
        data = self.request[0].strip()
        socket = self.request[1]
        print "%s wrote:" % self.client_address[0]
        print data
        socket.sendto(data.upper(), self.client_address)

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
    server.serve_forever()

クライアントサイドの例です:

import socket
import sys

HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])

# SOCK_DGRAM is the socket type to use for UDP sockets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# As you can see, there is no connect() call; UDP has no connections.
# Instead, data is directly sent to the recipient via sendto().
sock.sendto(data + "\n", (HOST, PORT))
received = sock.recv(1024)

print "Sent:     %s" % data
print "Received: %s" % received

この例の出力は、TCPサーバーの例と全く同じようになります。

20.17.4.3. 平行処理の Mix-in

複数の接続を平行に処理するハンドラを作るには、 ThreadingMixIn か ForkingMixIn クラスを利用します。

ThreadingMixIn クラスの利用例:

import socket
import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.currentThread()
        response = "%s: %s" % (cur_thread.getName(), data)
        self.request.send(response)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    sock.send(message)
    response = sock.recv(1024)
    print "Received: %s" % response
    sock.close()

if __name__ == "__main__":
    # Port 0 means to select an arbitrary unused port
    HOST, PORT = "localhost", 0

    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
    ip, port = server.server_address

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.setDaemon(True)
    server_thread.start()
    print "Server loop running in thread:", server_thread.getName()

    client(ip, port, "Hello World 1")
    client(ip, port, "Hello World 2")
    client(ip, port, "Hello World 3")

    server.shutdown()

この例の出力は次のようになります:

$ python ThreadedTCPServer.py
Server loop running in thread: Thread-1
Received: Thread-2: Hello World 1
Received: Thread-3: Hello World 2
Received: Thread-4: Hello World 3

ForkingMixIn クラスは同じように利用することができます。この場合、サーバーはリクエスト毎に新しいプロセスを作成します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.18. BaseHTTPServer — 基本的な機能を持つ HTTP サーバ

ノート

BaseHTTPServer モジュールは Python 3.0 では http.server に統合されました。ソースコードを 3.0 用に変換する時は、 2to3 ツールが自動的に import を修正します。

このモジュールでは、 HTTP サーバ (Web サーバ) を実装するための二つののクラスを定義しています。通常、このモジュールが直接使用されることはなく、特定の機能を持つ Web サーバを構築するために使われます。 SimpleHTTPServer および CGIHTTPServer モジュールを参照してください。

最初のクラス, HTTPServer は SocketServer.TCPServer のサブクラスで、従って SocketServer.BaseServer インタフェースを実装しています。 HTTPServer は HTTP ソケットを生成してリクエスト待ち (listen) を行い、リクエストをハンドラに渡します。サーバを作成して動作させるためのコードは以下のようになります:

def run(server_class=BaseHTTPServer.HTTPServer,
        handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()

class BaseHTTPServer.HTTPServer(server_address, RequestHandlerClass)

このクラスは TCPServer 型のクラスの上に構築されており、サーバのアドレスをインスタンス変数 server_name および server_port に記憶します。サーバはハンドラからアクセス可能で、通常 server インスタンス変数でアクセスします。

class BaseHTTPServer.BaseHTTPRequestHandler(request, client_address, server)

このクラスはサーバに到着したリクエストを処理します。このメソッド自体では、実際のリクエストに応答することはできません; (GET や POST のような) 各リクエストメソッドを処理するためにはサブクラス化しなければなりません。 BaseHTTPRequestHandler では、サブクラスで使うためのクラスやインスタンス変数、メソッド群を数多く提供しています。

このハンドラはリクエストを解釈し、次いでリクエスト形式ごとに固有のメソッドを呼び出します。メソッド名はリクエストの名称から構成されます。例えば、リクエストメソッド SPAM に対しては、 do_SPAM() メソッドが引数なしで呼び出されます。リクエストに関連する情報は全て、ハンドラのインスタンス変数に記憶されています。サブクラスでは __init__() メソッドを上書きしたり拡張したりする必要はありません。

BaseHTTPRequestHandler は以下のインスタンス変数を持っています:

BaseHTTPServer.client_address

HTTP クライアントのアドレスを参照している、 (host, port) の形式をとるタプルが入っています。

BaseHTTPServer.server

server インスタンスが入っています。

BaseHTTPServer.command

HTTP 命令 (リクエスト形式) が入っています。例えば 'GET' です。

BaseHTTPServer.path

リクエストされたパスが入っています。

BaseHTTPServer.request_version

リクエストのバージョン文字列が入っています。例えば 'HTTP/1.0' です。

BaseHTTPServer.headers

MessageClass クラス変数で指定されたクラスのインスタンスを保持しています。このインスタンスは HTTP リクエストのヘッダを解釈し、管理しています。

BaseHTTPServer.rfile

入力ストリームが入っており、そのファイルポインタはオプション入力データ部の先頭を指しています。

BaseHTTPServer.wfile

クライアントに返送する応答を書き込むための出力ストリームが入っています。このストリームに書き込む際には、HTTP プロトコルに従った形式をとらなければなりません。

BaseHTTPRequestHandler は以下のクラス変数を持っています:

BaseHTTPServer.server_version

サーバのソフトウェアバージョンを指定します。この値は上書きする必要が生じるかもしれません。書式は複数の文字列を空白で分割したもので、各文字列はソフトウェア名[/バージョン] の形式をとります。例えば、 'BaseHTTP/0.2' です。

BaseHTTPServer.sys_version

Python 処理系のバージョンが, version_string メソッドや server_version クラス変数で利用可能な形式で入っています。例えば 'Python/1.4' です。

BaseHTTPServer.error_message_format

クライアントに返すエラー応答を構築するための書式化文字列を指定します。この文字列は丸括弧で囲ったキー文字列で指定する形式を使うので、書式化の対象となる値は辞書でなければなりません。キー code は整数で、HTTP エラーコードを特定する数値です。 message は文字列で、何が発生したかを表す (詳細な) エラーメッセージが入ります。 explain はエラーコード番号の説明です。 message および explain の標準の値は response クラス変数でみつけることができます。

BaseHTTPServer.error_content_type

エラーレスポンスをクライアントに送信する時に使う Content-Type HTTP ヘッダを指定します。デフォルトでは 'text/html' です。

バージョン 2.6 で追加: 以前は、 Content-Type は常に 'text/html' でした。

BaseHTTPServer.protocol_version

この値には応答に使われる HTTP プロトコルのバージョンを指定します。 'HTTP/1.1' に設定されると、サーバは持続的 HTTP 接続を許可します; しかしその場合、サーバは全てのクライアントに対する応答に、正確な値を持つ Content-Length ヘッダを (send_header() を使って) 含め なければなりません 。以前のバージョンとの互換性を保つため、標準の設定値は 'HTTP/1.0' です。

BaseHTTPServer.MessageClass

HTTP ヘッダを解釈するための rfc822.Message 類似のクラスを指定します。通常この値が上書きされることはなく、標準の値 mimetools.Message になっています。

BaseHTTPServer.responses

この変数はエラーコードを表す整数を二つの要素をもつタプルに対応付けます。タプルには短いメッセージと長いメッセージが入っています。例えば、 {code: (shortmessage, longmessage)} といったようになります。 shortmessage は通常、エラー応答における message キーの値として使われ、 longmessage は explain キーの値として使われます (error_message_format クラス変数を参照してください) 。

BaseHTTPRequestHandler インスタンスは以下のメソッドを持っています:

BaseHTTPServer.handle()

handle_one_request() を一度だけ (持続的接続が有効になっている場合には複数回) 呼び出して、HTTPリクエストを処理します。このメソッドを上書きする必要はまったくありません; そうする代わりに適切な do_*() を実装してください。

BaseHTTPServer.handle_one_request()

このメソッドはリクエストを解釈し、適切な do_*() メソッドに転送します。このメソッドを上書きする必要はまったくありません。

BaseHTTPServer.send_error(code[, message])

完全なエラー応答をクライアントに送信し、ログ記録します。 code は数値型で、HTTP エラーコードを指定します。 message はオプションで、より詳細なメッセージテキストです。完全なヘッダのセットが送信された後, error_message_format クラス変数を使って組み立てられたテキストが送られます。

BaseHTTPServer.send_response(code[, message])

応答ヘッダを送信し、受理したリクエストをログ記録します。HTTP 応答行が送られた後、 Server および Date ヘッダが送られます。これら二つのヘッダはそれぞれ version_string() および date_time_string() メソッドで取り出します。

BaseHTTPServer.send_header(keyword, value)

出力ストリームに特定の HTTP ヘッダを書き込みます。 keyword はヘッダのキーワードを指定し、 value にはその値を指定します。

BaseHTTPServer.end_headers()

応答中の HTTP ヘッダの終了を示す空行を送信します。

BaseHTTPServer.log_request([code[, size]])

受理された (成功した) リクエストをログに記録します。 code にはこの応答に関連付けられた HTTP コード番号を指定します。応答メッセージの大きさを知ることができる場合、 size パラメタに渡すとよいでしょう。

BaseHTTPServer.log_error(...)

リクエストを遂行できなかった際に、エラーをログに記録します。標準では、メッセージを log_message() に渡します。従って同じ引数 (format と追加の値) を取ります。

BaseHTTPServer.log_message(format, ...)

任意のメッセージを sys.stderr にログ記録します。このメソッドは通常、カスタムのエラーログ記録機構を作成するために上書きされます。 format 引数は標準の printf 形式の書式化文字列で, log_message() に渡された追加の引数は書式化の入力として適用されます。ログ記録される全てのメッセージには、クライアントのアドレスおよび現在の日付、時刻が先頭に付けられます。

BaseHTTPServer.version_string()

サーバソフトウェアのバージョン文字列を返します。この文字列はクラス変数 server_version および sys_version を組み合わせたものです。

BaseHTTPServer.date_time_string([timestamp])

メッセージヘッダ向けに書式化された、 timestamp (time.time() のフォーマットである必要があります)で与えられた日時を返します。もし timestamp が省略された場合には、現在の日時が使われます。

出力は 'Sun, 06 Nov 1994 08:49:37 GMT' のようになります。

バージョン 2.5 で追加: timestamp パラメータ.

BaseHTTPServer.log_date_time_string()

ログ記録向けに書式化された、現在の日付および時刻を返します。

BaseHTTPServer.address_string()

ログ記録向けに書式化された、クライアントのアドレスを返します。このときクライアントの IP アドレスに対する名前解決を行います。

20.18.1. 他の例

永遠ではなく、何かの条件が満たされるまでの間実行するサーバーを作るには:

def run_while_true(server_class=BaseHTTPServer.HTTPServer,
                   handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
    """
    This assumes that keep_running() is a function of no arguments which
    is tested initially and after each request.  If its return value
    is true, the server continues.
    """
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    while keep_running():
        httpd.handle_request()

参考

Module CGIHTTPServer

CGI スクリプトをサポートするように拡張されたリクエストハンドラ。

Module SimpleHTTPServer

ドキュメントルートの下にあるファイルに対する要求への応答のみに制限した基本リクエストハンドラ。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.19. SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ

ノート

SimpleHTTPServer モジュールは、Python 3では http.server にリネームされました。 2to3 ツールが、ソースコード内のimportを自動的にPython 3用に修正します。

SimpleHTTPServer モジュールは、 SimpleHTTPRequestHandler クラス1つを提供しています。このクラスは、 BaseHTTPServer.BaseHTTPRequestHandler に対して互換性のあるインタフェースを持っています。

SimpleHTTPServer モジュールでは以下のクラスを定義しています:

class SimpleHTTPServer.SimpleHTTPRequestHandler(request, client_address, server)

このクラスは、現在のディレクトリ以下にあるファイルを、HTTP リクエストにおけるディレクトリ構造に直接対応付けて提供します。

リクエストの解釈のような、多くの作業は基底クラス BaseHTTPServer.BaseHTTPRequestHandler で行われます。このクラスは関数 do_GET() および do_HEAD() を実装しています。

SimpleHTTPRequestHandler では以下のメンバ変数を定義しています:

server_version

この値は "SimpleHTTP/" + __version__ になります。 __version__ はこのモジュールで定義されている値です。

extensions_map

拡張子を MIME 型指定子に対応付ける辞書です。標準の型指定は空文字列で表され、この値は application/octet-stream と見なされます。対応付けは大小文字の区別をするので、小文字のキーのみを入れるべきです。

SimpleHTTPRequestHandler では以下のメソッドを定義しています:

do_HEAD()

このメソッドは 'HEAD' 型のリクエスト処理を実行します: すなわち、 GET リクエストの時に送信されるものと同じヘッダを送信します。送信される可能性のあるヘッダについての完全な説明は do_GET() メソッドを参照してください。

do_GET()

リクエストを現在の作業ディレクトリからの相対的なパスとして解釈することで、リクエストをローカルシステム上のファイルと対応付けます。

リクエストがディレクトリに対応付けられた場合、 index.html または index.htm をこの順序でチェックします。もしファイルを発見できればその内容を、そうでなければディレクトリ一覧を list_directory() メソッドで生成して、返します。このメソッドは os.listdir() をディレクトリのスキャンに用いており、 listdir() が失敗した場合には 404 応答が返されます。

リクエストがファイルに対応付けられた場合、そのファイルを開いて内容を返します。要求されたファイルを開く際に何らかの IOError 例外が送出された場合、リクエストは 404 、 'File not found' エラーに対応づけられます。そうでない場合、コンテントタイプが extensions_map 変数を用いて推測されます。

出力は 'Content-type:' と推測されたコンテントタイプで、その後にファイルサイズを示す 'Content-Lenght;' ヘッダと、ファイルの更新日時を示す 'Last-Modified:' ヘッダが続きます。

そしてヘッダの終了を示す空白行が続き、さらにその後にファイルの内容が続きます。このファイルはコンテントタイプが text/ で始まっている場合はテキストモードで、そうでなければバイナリモードで開かれます。

SimpleHTTPServer モジュールの test() 関数は SimpleHTTPRequestHandler をハンドラとして使うサーバを作る例になっています。

バージョン 2.5 で追加: 'Last-Modified' ヘッダ.

SimpleHTTPServer モジュールを使って現在のディレクトリ以下にあるファイルにアクセスできるだけの、非常に初歩的な Web サーバを立ち上げる方法は以下の通りです。

import SimpleHTTPServer
import SocketServer

PORT = 8000

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()

インタプリタの -m スイッチで SimpleHTTPServer モジュールと ポート番号を指定して直接実行することもできます。上の例と同じように、ここで立ち上がったサーバは現在のディレクトリ以下のファイルへのアクセスを提供します。

python -m SimpleHTTPServer 8000

参考

Module BaseHTTPServer

Web サーバおよび要求ハンドラの基底クラス実装。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.20. CGIHTTPServer — CGI 実行機能付き HTTP リクエスト処理機構

ノート

BaseHTTPServer モジュールは Python 3.0 では http.server に統合されました。ソースコードを 3.0 用に変換する時は、 2to3 ツールが自動的に import を修正します。

CGIHTTPServer モジュールでは、 BaseHTTPServer.BaseHTTPRequestHandler 互換のインタフェースを持ち、 SimpleHTTPServer.SimpleHTTPRequestHandler の動作を継承していますが CGI スクリプトを動作することもできる、 HTTP 要求処理機構クラスを定義しています。

ノート

このモジュールは CGI スクリプトを Unix および Windows システム上で実行させることができます。

ノート

CGIHTTPRequestHandler クラスで実行されるCGIスクリプトは HTTP コード200 (スクリプトの出力が後に続く)を実行に先立って出力される (これがステータスコードになります) ため、リダイレクト(コード302)を行なうことができません。

CGIHTTPServer モジュールでは、以下のクラスを定義しています:

class CGIHTTPServer.CGIHTTPRequestHandler(request, client_address, server)

このクラスは、現在のディレクトリかその下のディレクトリにおいて、ファイルか CGI スクリプト出力を提供するために使われます。 HTTP 階層構造からローカルなディレクトリ構造への対応付けは SimpleHTTPServer.SimpleHTTPRequestHandler と全く同じなので注意してください。

このクラスでは、ファイルが CGI スクリプトであると推測された場合、これをファイルして提供する代わりにスクリプトを実行します。他の一般的なサーバ設定は特殊な拡張子を使って CGI スクリプトであることを示すのに対し、ディレクトリベースの CGI だけが使われます。

do_GET() および do_HEAD() 関数は、HTTP 要求が cgi_directories パス以下のどこかを指している場合、ファイルを提供するのではなく、CGI スクリプトを実行してその出力を提供するように変更されています。

CGIHTTPRequestHandler では以下のデータメンバを定義しています:

cgi_directories

この値は標準で ['/cgi-bin', '/htbin'] であり、CGI スクリプトを含んでいることを示すディレクトリを記述します。

CGIHTTPRequestHandler では以下のメソッドを定義しています:

do_POST()

このメソッドは、CGI スクリプトでのみ許されている 'POST' 型の HTTP 要求に対するサービスを行います。 CGI でない url に対して POST を試みた場合、出力は Error 501, “Can only POST to CGI scripts” になります。

セキュリティ上の理由から、CGI スクリプトはユーザ nobody の UID で動作するので注意してください。 CGI スクリプトが原因で発生した問題は、Error 403 に変換されます。

使用例については、 test() 関数の実装を参照してください。

参考

Module BaseHTTPServer

Web サーバとリクエスト処理機構を実装した基底クラスです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.21. cookielib — HTTP クライアント用の Cookie 処理

ノート

cookielib モジュールは、Python 3では http.cookiejar にリネームされました。 2to3 ツールは自動的にソースコード内のimportをPython 3用に修正します。

バージョン 2.4 で追加.

cookielib モジュールは HTTP クッキーの自動処理をおこなうクラスを定義します。これは小さなデータの断片 – クッキー – を要求する web サイトにアクセスする際に有用です。クッキーとは web サーバの HTTP レスポンスによってクライアントのマシンに設定され、のちの HTTP リクエストをおこなうさいにサーバに返されるものです。

標準的な Netscape クッキープロトコルおよび RFC 2965 [http://tools.ietf.org/html/rfc2965.html] で定義されているプロトコルの両方を処理できます。RFC 2965 の処理はデフォルトではオフになっています。 RFC 2109 [http://tools.ietf.org/html/rfc2109.html] のクッキーは Netscape クッキーとして解析され、のちに有効な ‘ポリシー’ に従って Netscapeまたは RFC 2965 クッキーとして処理されます。但し、インターネット上の大多数のクッキーは Netscapeクッキーです。 cookielib はデファクトスタンダードの Netscape クッキープロトコル (これは元々 Netscape が策定した仕様とはかなり異なっています) に従うようになっており、RFC 2109 で導入された max-age や port などのクッキー属性にも注意を払います。

ノート

Set-Cookie や Set-Cookie2 ヘッダに現れる多種多様なパラメータの名前 (domain や expires など) は便宜上 属性 と呼ばれますが、ここでは Python の属性と区別するため、かわりに クッキー属性 と呼ぶことにします。

このモジュールは以下の例外を定義しています:

exception cookielib.LoadError

この例外は FileCookieJar インスタンスがファイルからクッキーを読み込むのに失敗した場合に発生します。

以下のクラスが提供されています:

class cookielib.CookieJar(policy=None)

policy は CookiePolicy インターフェイスを実装するオブジェクトです。

CookieJar クラスには HTTP クッキーを保管します。これは HTTP リクエストに応じてクッキーを取り出し、それを HTTP レスポンスの中で返します。必要に応じて、 CookieJar インスタンスは保管されているクッキーを自動的に破棄します。このサブクラスは、クッキーをファイルやデータベースに格納したり取り出したりする操作をおこなう役割を負っています。

class cookielib.FileCookieJar(filename, delayload=None, policy=None)

policy は CookiePolicy インターフェイスを実装するオブジェクトです。これ以外の引数については、該当する属性の説明を参照してください。

FileCookieJar はディスク上のファイルからのクッキーの読み込み、もしくは書き込みをサポートします。実際には、 load() または revert() のどちらかのメソッドが呼ばれるまでクッキーは指定されたファイルからはロード されません 。このクラスのサブクラスは FileCookieJar のサブクラスと web ブラウザとの連携 節で説明します。

class cookielib.CookiePolicy

このクラスは、あるクッキーをサーバから受け入れるべきか、そしてサーバに返すべきかを決定する役割を負っています。

class cookielib.DefaultCookiePolicy(blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False)

コンストラクタはキーワード引数しか取りません。 blocked_domains はドメイン名からなるシーケンスで、ここからは決してクッキーを受けとらないし、このドメインにクッキーを返すこともありません。 allowed_domains が None でない場合、これはこのドメインのみからクッキーを受けとり、返すという指定になります。これ以外の引数については CookiePolicy および DefaultCookiePolicy オブジェクトの説明をごらんください。

DefaultCookiePolicy は Netscape および RFC 2965 クッキーの標準的な許可 / 拒絶のルールを実装しています。デフォルトでは、RFC 2109 のクッキー (Set-Cookie の version クッキー属性が 1 で受けとられるもの) は RFC 2965 のルールで扱われます。しかし、RFC 2965処理が無効に設定されているか rfc2109_as_netscape が Trueの場合、RFC 2109クッキーは CookieJar インスタンスによって Cookie のインスタンスの version 属性を 0に設定する事で Netscapeクッキーに「ダウングレード」されます。また DefaultCookiePolicy にはいくつかの細かいポリシー設定をおこなうパラメータが用意されています。

class cookielib.Cookie

このクラスは Netscape クッキー、RFC 2109 のクッキー、および RFC 2965 のクッキーを表現します。 cookielib のユーザが自分で Cookie インスタンスを作成することは想定されていません。かわりに、必要に応じて CookieJar インスタンスの make_cookies() を呼ぶことになっています。

参考

Module urllib2

クッキーの自動処理をおこない URL を開くモジュールです。

Module Cookie

HTTP のクッキークラスで、基本的にはサーバサイドのコードで有用です。 cookielib および Cookie モジュールは互いに依存してはいません。

http://wp.netscape.com/newsref/std/cookie_spec.html

元祖 Netscape のクッキープロトコルの仕様です。今でもこれが主流のプロトコルですが、現在のメジャーなブラウザ (と cookielib) が実装している「Netscape クッキープロトコル」は cookie_spec.html で述べられているものとおおまかにしか似ていません。

RFC 2109 [http://tools.ietf.org/html/rfc2109.html] - HTTP State Management Mechanism

RFC 2965 によって過去の遺物になりました。 Set-Cookie の version=1 で使います。

RFC 2965 [http://tools.ietf.org/html/rfc2965.html] - HTTP State Management Mechanism

Netscape プロトコルのバグを修正したものです。 Set-Cookie のかわりに Set-Cookie2 を使いますが、普及してはいません。

http://kristol.org/cookie/errata.html

RFC 2965 に対する未完の正誤表です。

RFC 2964 [http://tools.ietf.org/html/rfc2964.html] - Use of HTTP State Management

20.21.1. CookieJar および FileCookieJar オブジェクト

CookieJar オブジェクトは保管されている Cookie オブジェクトをひとつずつ取り出すための、イテレータ(iterator)・プロトコルをサポートしています。

CookieJar は以下のようなメソッドを持っています:

CookieJar.add_cookie_header(request)

request に正しい Cookie ヘッダを追加します。

ポリシーが許すようであれば (CookieJar の CookiePolicy インスタンスにある属性のうち、 rfc2965 および hide_cookie2 がそれぞれ真と偽であるような場合)、必要に応じて Cookie2 ヘッダも追加されます。

request オブジェクト (通常は urllib2.Request インスタンス) は、 urllib2 のドキュメントに記されているように、 get_full_url(), get_host(), get_type(), unverifiable(), get_origin_req_host(), has_header(), get_header(), header_items() および add_unredirected_header() の各メソッドをサポートしている必要があります。

CookieJar.extract_cookies(response, request)

HTTP response からクッキーを取り出し、ポリシーによって許可されていればこれを CookieJar 内に保管します。

CookieJar は response 引数の中から許可されている Set-Cookie および Set-Cookie2 ヘッダを探しだし、適切に (CookiePolicy.set_ok() メソッドの承認におうじて) クッキーを保管します。

response オブジェクト (通常は urllib2.urlopen() あるいはそれに類似する呼び出しによって得られます) は info() メソッドをサポートしている必要があります。これは getallmatchingheaders() メソッドのあるオブジェクト (通常は mimetools.Message インスタンス) を返すものです。

request オブジェクト (通常は urllib2.Request インスタンス) は urllib2 のドキュメントに記されているように、 get_full_url(), get_host(), unverifiable() および get_origin_req_host() の各メソッドをサポートしている必要があります。この request はそのクッキーの保存が許可されているかを検査するとともに、クッキー属性のデフォルト値を設定するのに使われます。

CookieJar.set_policy(policy)

使用する CookiePolicy インスタンスを指定します。

CookieJar.make_cookies(response, request)

response オブジェクトから得られた Cookie オブジェクトからなるシーケンスを返します。

response および request 引数で要求されるインスタンスについては、 extract_cookies() の説明を参照してください。

CookieJar.set_cookie_if_ok(cookie, request)

ポリシーが許すのであれば、与えられた Cookie を設定します。

CookieJar.set_cookie(cookie)

与えられた Cookie を、それが設定されるべきかどうかのポリシーのチェックを行わずに設定します。

CookieJar.clear([domain[, path[, name]]])

いくつかのクッキーを消去します。

引数なしで呼ばれた場合は、すべてのクッキーを消去します。引数がひとつ与えられた場合、その domain に属するクッキーのみを消去します。ふたつの引数が与えられた場合、指定された domain と URL path に属するクッキーのみを消去します。引数が 3つ与えられた場合、 domain, path および name で指定されるクッキーが消去されます。

与えられた条件に一致するクッキーがない場合は KeyError を発生させます。

CookieJar.clear_session_cookies()

すべてのセッションクッキーを消去します。

保存されているクッキーのうち、 discard 属性が真になっているものすべてを消去します (通常これは max-age または expires のどちらのクッキー属性もないか、あるいは明示的に discard クッキー属性が指定されているものです)。対話的なブラウザの場合、セッションの終了はふつうブラウザのウィンドウを閉じることに相当します。

注意: ignore_discard 引数に真を指定しないかぎり、 save() メソッドはセッションクッキーは保存しません。

さらに FileCookieJar は以下のようなメソッドを実装しています:

FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)

クッキーをファイルに保存します。

この基底クラスは NotImplementedError を発生させます。サブクラスはこのメソッドを実装しないままにしておいてもかまいません。

filename はクッキーを保存するファイルの名前です。 filename が指定されない場合、 self.filename が使用されます (このデフォルト値は、それが存在する場合は、コンストラクタに渡されています)。 self.filename も None の場合は ValueError が発生します。

ignore_discard : 破棄されるよう指示されていたクッキーでも保存します。 ignore_expires : 期限の切れたクッキーでも保存します。

ここで指定されたファイルがもしすでに存在する場合は上書きされるため、以前にあったクッキーはすべて消去されます。保存したクッキーはあとで load() または revert() メソッドを使って復元することができます。

FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)

ファイルからクッキーを読み込みます。

それまでのクッキーは新しいものに上書きされない限り残ります。

ここでの引数の値は save() と同じです。

名前のついたファイルはこのクラスがわかるやり方で指定する必要があります。さもないと LoadError が発生します。さらに、例えばファイルが存在しないような時に IOError が発生する場合があります。

ノート

(IOError を発行する)Python 2.4との後方互換性のために、 LoadError は IOError のサブクラスです。

FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)

すべてのクッキーを破棄し、保存されているファイルから読み込み直します。

revert() は load() と同じ例外を発生させる事ができます。失敗した場合、オブジェクトの状態は変更されません。

FileCookieJar インスタンスは以下のような公開の属性をもっています:

FileCookieJar.filename

クッキーを保存するデフォルトのファイル名を指定します。この属性には代入することができます。

FileCookieJar.delayload

真であれば、クッキーを読み込むさいにディスクから遅延読み込み (lazy) します。この属性には代入することができません。この情報は単なるヒントであり、 (ディスク上のクッキーが変わらない限りは) インスタンスのふるまいには影響を与えず、パフォーマンスのみに影響します。 CookieJar オブジェクトはこの値を無視することもあります。標準ライブラリに含まれている FileCookieJar クラスで遅延読み込みをおこなうものはありません。

20.21.2. FileCookieJar のサブクラスと web ブラウザとの連携

クッキーの読み書きのために、以下の CookieJar サブクラスが提供されています。

class cookielib.MozillaCookieJar(filename, delayload=None, policy=None)

Mozilla の cookies.txt ファイル形式 (この形式はまた Lynx と Netscape ブラウザによっても使われています) でディスクにクッキーを読み書きするための FileCookieJar です。

ノート

Firefox 3 は、 cookie を cookies.txt ファイルフォーマットで保存しません。

ノート

このクラスは RFC 2965 クッキーに関する情報を失います。また、より新しいか、標準でない port などのクッキー属性についての情報も失います。

警告

もしクッキーの損失や欠損が望ましくない場合は、クッキーを保存する前にバックアップを取っておくようにしてください (ファイルへの読み込み / 保存をくり返すと微妙な変化が生じる場合があります)。

また、 Mozilla の起動中にクッキーを保存すると、 Mozilla によって内容が破壊されてしまうことにも注意してください。

class cookielib.LWPCookieJar(filename, delayload=None, policy=None)

libwww-perl のライブラリである Set-Cookie3 ファイル形式でディスクにクッキーを読み書きするための FileCookieJar です。これはクッキーを人間に可読な形式で保存するのに向いています。

20.21.3. CookiePolicy オブジェクト

CookiePolicy インターフェイスを実装するオブジェクトは以下のようなメソッドを持っています:

CookiePolicy.set_ok(cookie, request)

クッキーがサーバから受け入れられるべきかどうかを表わす boolean 値を返します。

cookie は cookielib.Cookie インスタンスです。 request は CookieJar.extract_cookies() の説明で定義されているインターフェイスを実装するオブジェクトです。

CookiePolicy.return_ok(cookie, request)

クッキーがサーバに返されるべきかどうかを表わす boolean 値を返します。

cookie は cookielib.Cookie インスタンスです。 request は CookieJar.add_cookie_header() の説明で定義されているインターフェイスを実装するオブジェクトです。

CookiePolicy.domain_return_ok(domain, request)

与えられたクッキーのドメインに対して、そこにクッキーを返すべきでない場合には false を返します。

このメソッドは高速化のためのものです。これにより、すべてのクッキーをある特定のドメインに対してチェックする (これには多数のファイル読みこみを伴なう場合があります) 必要がなくなります。 domain_return_ok() および path_return_ok() の両方から true が返された場合、すべての決定は return_ok() に委ねられます。

もし、このクッキードメインに対して domain_return_ok() が true を返すと、つぎにそのクッキーのパス名に対して path_return_ok() が呼ばれます。そうでない場合、そのクッキードメインに対する path_return_ok() および return_ok() は決して呼ばれることはありません。 path_return_ok() が true を返すと、 return_ok() がその Cookie オブジェクト自身の全チェックのために呼ばれます。そうでない場合、そのクッキーパス名に対する return_ok() は決して呼ばれることはありません。

注意: domain_return_ok() は request ドメインだけではなく、すべての cookie ドメインに対して呼ばれます。たとえば request ドメインが "www.example.com" だった場合、この関数は ".example.com" および "www.example.com" の両方に対して呼ばれることがあります。同じことは path_return_ok() にもいえます。

request 引数は return_ok() で説明されているとおりです。

CookiePolicy.path_return_ok(path, request)

与えられたクッキーのパス名に対して、そこにクッキーを返すべきでない場合には false を返します。

domain_return_ok() の説明を参照してください。

上のメソッドの実装にくわえて、 CookiePolicy インターフェイスの実装では以下の属性を設定する必要があります。これはどのプロトコルがどのように使われるべきかを示すもので、これらの属性にはすべて代入することが許されています。

CookiePolicy.netscape

Netscape プロトコルを実装していることを示します。

CookiePolicy.rfc2965

RFC 2965 プロトコルを実装していることを示します。

CookiePolicy.hide_cookie2

Cookie2 ヘッダをリクエストに含めないようにします (このヘッダが存在する場合、私たちは RFC 2965 クッキーを理解するということをサーバに示すことになります)。

もっとも有用な方法は、 DefaultCookiePolicy をサブクラス化した CookiePolicy クラスを定義して、いくつか (あるいはすべて) のメソッドをオーバーライドすることでしょう。 CookiePolicy 自体はどのようなクッキーも受け入れて設定を許可する「ポリシー無し」ポリシーとして使うこともできます (これが役に立つことはあまりありませんが)。

20.21.4. DefaultCookiePolicy オブジェクト

クッキーを受けつけ、またそれを返す際の標準的なルールを実装します。

RFC 2965 クッキーと Netscape クッキーの両方に対応しています。デフォルトでは、RFC 2965 の処理はオフになっています。

自分のポリシーを提供するいちばん簡単な方法は、このクラスを継承して、自分用の追加チェックの前にオーバーライドした元のメソッドを呼び出すことです:

import cookielib
class MyCookiePolicy(cookielib.DefaultCookiePolicy):
    def set_ok(self, cookie, request):
        if not cookielib.DefaultCookiePolicy.set_ok(self, cookie, request):
            return False
        if i_dont_want_to_store_this_cookie(cookie):
            return False
        return True

CookiePolicy インターフェイスを実装するのに必要な機能に加えて、このクラスではクッキーを受けとったり設定したりするドメインを許可したり拒絶したりできるようになっています。ほかにも、 Netscape プロトコルのかなり緩い規則をややきつくするために、いくつかの厳密性のスイッチがついています (いくつかの良性クッキーをブロックする危険性もありますが)。

ドメインのブラックリスト機能やホワイトリスト機能も提供されています (デフォルトではオフになっています)。ブラックリストになく、(ホワイトリスト機能を使用している場合は) ホワイトリストにあるドメインのみがクッキーを設定したり返したりすることを許可されます。コンストラクタの引数 blocked_domains 、および blocked_domains() と set_blocked_domains() メソッドを使ってください (allowed_domains に関しても同様の対応する引数とメソッドがあります)。ホワイトリストを設定した場合は、それを None にすることでホワイトリスト機能をオフにすることができます。

ブラックリストあるいはホワイトリスト中にあるドメインのうち、ドット (.) で始まっていないものは、正確にそれと一致するドメインのクッキーにしか適用されません。たとえばブラックリスト中のエントリ "example.com" は、 "example.com" にはマッチしますが、 "www.example.com" にはマッチしません。一方ドット (.) で始まっているドメインは、より特化されたドメインともマッチします。たとえば、 ".example.com" は、 "www.example.com" と "www.coyote.example.com" の両方にマッチします (が、 "example.com" 自身にはマッチしません)。IP アドレスは例外で、つねに正確に一致する必要があります。たとえば、かりに blocked_domains が "192.168.1.2" と ".168.1.2" を含んでいたとして、192.168.1.2 はブロックされますが、 193.168.1.2 はブロックされません。

DefaultCookiePolicy は以下のような追加メソッドを実装しています:

DefaultCookiePolicy.blocked_domains()

ブロックしているドメインのシーケンスを (タプルとして) 返します。

DefaultCookiePolicy.set_blocked_domains(blocked_domains)

ブロックするドメインを設定します。

DefaultCookiePolicy.is_blocked(domain)

domain がクッキーを授受しないブラックリストに載っているかどうかを返します。

DefaultCookiePolicy.allowed_domains()

None あるいは明示的に許可されているドメインを (タプルとして) 返します。

DefaultCookiePolicy.set_allowed_domains(allowed_domains)

許可するドメイン、あるいは None を設定します。

DefaultCookiePolicy.is_not_allowed(domain)

domain がクッキーを授受するホワイトリストに載っているかどうかを返します。

DefaultCookiePolicy インスタンスは以下の属性をもっています。これらはすべてコンストラクタから同じ名前の引数をつかって初期化することができ、代入してもかまいません。

DefaultCookiePolicy.rfc2109_as_netscape

Trueの場合、 CookieJar のインスタンスに RFC 2109 クッキー (即ち Set-Cookie ヘッダのVersion cookie属性の値が1のクッキー)を Netscapeクッキーへ、 Cookie インスタンスのversion属性を0に設定する事でダウングレードするように要求します。デフォルトの値は None であり、この場合 RFC 2109 クッキーは RFC 2965 処理が無効に設定されている場合に限りダウングレードされます。それ故に RFC 2109 クッキーはデフォルトではダウングレードされます。

バージョン 2.5 で追加.

一般的な厳密性のスイッチ:

DefaultCookiePolicy.strict_domain

サイトに、国別コードとトップレベルドメインだけからなるドメイン名 (.co.uk, .gov.uk, .co.nz など) を設定させないようにします。これは完璧からはほど遠い実装であり、いつもうまくいくとは限りません!

RFC 2965 プロトコルの厳密性に関するスイッチ:

DefaultCookiePolicy.strict_rfc2965_unverifiable

検証不可能なトランザクション (通常これはリダイレクトか、別のサイトがホスティングしているイメージの読み込み要求です) に関する RFC 2965 の規則に従います。この値が偽の場合、検証可能性を基準にしてクッキーがブロックされることは 決して ありません。

Netscape プロトコルの厳密性に関するスイッチ:

DefaultCookiePolicy.strict_ns_unverifiable

検証不可能なトランザクションに関する RFC 2965 の規則を Netscape クッキーに対しても適用します。

DefaultCookiePolicy.strict_ns_domain

Netscape クッキーに対するドメインマッチングの規則をどの程度厳しくするかを指示するフラグです。とりうる値については下の説明を見てください。

DefaultCookiePolicy.strict_ns_set_initial_dollar

Set-Cookie: ヘッダで、 '$' で始まる名前のクッキーを無視します。

DefaultCookiePolicy.strict_ns_set_path

要求した URI にパスがマッチしないクッキの設定を禁止します。

strict_ns_domain はいくつかのフラグの集合です。これはいくつかの値を or することで構成します (たとえば DomainStrictNoDots|DomainStrictNonDomain は両方のフラグが設定されていることになります)。

DefaultCookiePolicy.DomainStrictNoDots

クッキーを設定するさい、ホスト名のプレフィクスにドットが含まれるのを禁止します (例: www.foo.bar.com は .bar.com のクッキーを設定することはできません、なぜなら www.foo はドットを含んでいるからです)。

DefaultCookiePolicy.DomainStrictNonDomain

domain クッキー属性を明示的に指定していないクッキーは、そのクッキーを設定したドメインと同一のドメインだけに返されます (例: example.com からのクッキーに domain クッキー属性がない場合、そのクッキーが spam.example.com に返されることはありません)。

DefaultCookiePolicy.DomainRFC2965Match

クッキーを設定するさい、RFC 2965 の完全ドメインマッチングを要求します。

以下の属性は上記のフラグのうちもっともよく使われる組み合わせで、便宜をはかるために提供されています。

DefaultCookiePolicy.DomainLiberal

0 と同じです (つまり、上述の Netscape のドメイン厳密性フラグがすべてオフにされます)。

DefaultCookiePolicy.DomainStrict

DomainStrictNoDots|DomainStrictNonDomain と同じです。

20.21.5. Cookie オブジェクト

Cookie インスタンスは、さまざまなクッキーの標準で規定されている標準的なクッキー属性とおおまかに対応する Python 属性をもっています。しかしデフォルト値を決める複雑なやり方が存在しており、また max-age および expires クッキー属性は同じ値をもつことになっているので、また RFC 2109クッキーは cookielib によって version 1から version 0 (Netscape)クッキーへ ‘ダウングレード’ される場合があるため、この対応は 1対 1 ではありません。

CookiePolicy メソッド内でのごくわずかな例外を除けば、これらの属性に代入する必要はないはずです。このクラスは内部の一貫性を保つようにはしていないため、代入するのは自分のやっていることを理解している場合のみにしてください。

Cookie.version

整数または None 。 Netscape クッキーはバージョン 0 であり、 RFC 2965 および RFC 2109 クッキーはバージョン 1 です。しかし、 cookielib は RFC 2109クッキーを Netscapeクッキー (version が 0)に’ダウングレード’する場合がある事に注意して下さい。

Cookie.name

クッキーの名前 (文字列)。

Cookie.value

クッキーの値 (文字列)、あるいは None 。

Cookie.port

ポートあるいはポートの集合をあらわす文字列 (例: ‘80’ または ‘80,8080’)、あるいは None 。

Cookie.path

クッキーのパス名 (文字列、例: '/acme/rocket_launchers')。

Cookie.secure

そのクッキーを返せるのが安全な接続のみならば真を返します。

Cookie.expires

クッキーの期限が切れる日時をあわらす整数 (エポックから経過した秒数)、あるいは None 。 is_expired() も参照してください。

Cookie.discard

これがセッションクッキーであれば真を返します。

Cookie.comment

このクッキーの働きを説明する、サーバからのコメント文字列、あるいは None 。

Cookie.comment_url

このクッキーの働きを説明する、サーバからのコメントのリンク URL、あるいは None 。

Cookie.rfc2109

RFC 2109クッキー(即ち Set-Cookie ヘッダにあり、かつVersion cookie属性の値が1のクッキー)の場合、Trueを返します。 cookielib が RFC 2109クッキーを Netscapeクッキー (version が 0)に’ダウングレード’する場合があるので、この属性が提供されています。

バージョン 2.5 で追加.

Cookie.port_specified

サーバがポート、あるいはポートの集合を (Set-Cookie / Set-Cookie2 ヘッダ内で) 明示的に指定していれば真を返します。

Cookie.domain_specified

サーバがドメインを明示的に指定していれば真を返します。

Cookie.domain_initial_dot

サーバが明示的に指定したドメインが、ドット ('.') で始まっていれば真を返します。

クッキーは、オプションとして標準的でないクッキー属性を持つこともできます。これらは以下のメソッドでアクセスできます:

Cookie.has_nonstandard_attr(name)

そのクッキーが指定された名前のクッキー属性をもっている場合には真を返します。

Cookie.get_nonstandard_attr(name, default=None)

クッキーが指定された名前のクッキー属性をもっていれば、その値を返します。そうでない場合は default を返します。

Cookie.set_nonstandard_attr(name, value)

指定された名前のクッキー属性を設定します。

Cookie クラスは以下のメソッドも定義しています:

Cookie.is_expired([now=None])

サーバが指定した、クッキーの期限が切れるべき時が過ぎていれば真を返します。 now が指定されているときは (エポックから経過した秒数です)、そのクッキーが指定された時間において期限切れになっているかどうかを判定します。

20.21.6. 使用例

はじめに、もっとも一般的な cookielib の使用例をあげます:

import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

以下の例では、 URL を開く際に Netscape や Mozilla または Lynx のクッキーを使う方法を示しています (クッキーファイルの位置は Unix/Netscape の慣例にしたがうものと仮定しています):

import os, cookielib, urllib2
cj = cookielib.MozillaCookieJar()
cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

つぎの例は DefaultCookiePolicy の使用例です。 RFC 2965 クッキーをオンにし、Netscape クッキーを設定したり返したりするドメインに対してより厳密な規則を適用します。そしていくつかのドメインからクッキーを設定あるいは返還するのをブロックしています:

import urllib2
from cookielib import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(
    rfc2965=True, strict_ns_domain=DefaultCookiePolicy.DomainStrict,
    blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar(policy)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.22. Cookie — HTTPの状態管理

ノート

Python 3.0 では Cookie モジュールは http.cookies にリネームされました。ソースコードを 3.0 用に変換する時は、 2to3 ツールが自動的に import を修正します。

Cookie モジュールはHTTPの状態管理機能であるcookieの概念を抽象化、定義しているクラスです。単純な文字列のみで構成されるcookieのほか、シリアル化可能なあらゆるデータ型でクッキーの値を保持するための機能も備えています。

このモジュールは元々 RFC 2109 [http://tools.ietf.org/html/rfc2109.html] と RFC 2068 [http://tools.ietf.org/html/rfc2068.html] に定義されている構文解析の規則を厳密に守っていました。しかし、MSIE 3.0xがこれらのRFCで定義された文字の規則に従っていないことが判明したため、結局、やや厳密さを欠く構文解析規則にせざるを得ませんでした。

ノート

正しくない cookie に遭遇した場合、 CookieError 例外を送出します。なので、ブラウザから持ってきた cookie データを parse するときには常に CookieError 例外を catch して不正な cookie に備えるべきです。

exception Cookie.CookieError

属性や Set-Cookie ヘッダが正しくないなど、 RFC 2109 [http://tools.ietf.org/html/rfc2109.html] に合致していないときに発生する例外です。

class Cookie.BaseCookie([input])

このクラスはキーが文字列、値が Morsel インスタンスで構成される辞書風オブジェクトです。値に対するキーを設定するときは、値がキーと値を含む Morsel に変換されることに注意してください。

input が与えられたときは、そのまま load() メソッドへ渡されます。

class Cookie.SimpleCookie([input])

このクラスは BaseCookie の派生クラスで、 value_decode() は与えられた値の正当性を確認するように、 value_encode() は str() で文字列化するようにそれぞれオーバライドします。

class Cookie.SerialCookie([input])

このクラスは BaseCookie の派生クラスで、 value_decode() と value_encode() をそれぞれ pickle.loads() と pickle.dumps() を実行するようにオーバーライドします。

バージョン 2.3 で撤廃: このクラスを使ってはいけません! 信頼できないcookieのデータから pickle 化された値を読み込むことは、あなたのサーバ上で任意のコードを実行するために pickle 化した文字列の作成が可能であることを意味し、重大なセキュリティホールとなります。

class Cookie.SmartCookie([input])

このクラスは BaseCookie の派生クラスで、 value_decode() を、値が pickle 化されたデータとして正当なときは pickle.loads() を実行、そうでないときはその値自体を返すようにオーバーライドします。また value_encode() を、値が文字列以外のときは pickle.dumps() を実行、文字列のときはその値自体を返すようにオーバーライドします。

バージョン 2.3 で撤廃: SerialCookie と同じセキュリティ上の注意が当てはまります。

関連して、さらなるセキュリティ上の注意があります。後方互換性のため、 Cookie モジュールは Cookie というクラス名を SmartCookie のエイリアスとしてエクスポートしています。これはほぼ確実に誤った措置であり、将来のバージョンでは削除することが適当と思われます。アプリケーションにおいて SerialCookie クラスを使うべきでないのと同じ理由で Cookie クラスを使うべきではありません。

参考

Module cookielib

Web クライアント 向けの HTTP クッキー処理です。 cookielib と Cookie は互いに独立しています。

RFC 2109 [http://tools.ietf.org/html/rfc2109.html] - HTTP State Management Mechanism

このモジュールが実装しているHTTPの状態管理に関する規格です。

20.22.1. Cookieオブジェクト

BaseCookie.value_decode(val)

文字列表現を値にデコードして返します。戻り値の型はどのようなものでも許されます。このメソッドは BaseCookie において何も実行せず、オーバーライドされるためにだけ存在します。

BaseCookie.value_encode(val)

エンコードした値を返します。元の値はどのような型でもかまいませんが、戻り値は必ず文字列となります。このメソッドは BaseCookie において何も実行せず、オーバーライドされるためにだけ存在します。

通常 value_encode() と value_decode() はともに value_decode の処理内容から逆算した範囲に収まっていなければなりません。

BaseCookie.output([attrs[, header[, sep]]])

HTTPヘッダ形式の文字列表現を返します。 attrs と header はそれぞれ Morsel の output() メソッドに送られます。 sep はヘッダの連結に用いられる文字で、デフォルトは '\r\n' (CRLF)となっています。

バージョン 2.5 で変更: デフォルトのセパレータを '\n' 　から、クッキーの使用にあわせた.

BaseCookie.output([attrs[, header[, sep]]])

HTTPヘッダ形式の文字列表現を返します。

BaseCookie.js_output([attrs])

ブラウザがJavaScriptをサポートしている場合、HTTPヘッダを送信した場合と同様に動作する埋め込み可能なJavaScript snippetを返します。

attrs の意味は output() と同じです。

BaseCookie.load(rawdata)

rawdata が文字列であれば、 HTTP_COOKIE として処理し、その値を Morsel として追加します。辞書の場合は次と同様の処理をおこないます。

for k, v in rawdata.items():
    cookie[k] = v

20.22.2. Morselオブジェクト

class Cookie.Morsel

RFC 2109 [http://tools.ietf.org/html/rfc2109.html] の属性をキーと値で保持するabstractクラスです。

Morselは辞書風のオブジェクトで、キーは次のような RFC 2109 [http://tools.ietf.org/html/rfc2109.html] 準拠の定数となっています。

expires

path

comment

domain

max-age

secure

version

httponly

httponly 属性は、 cookie が HTTP リクエストでのみ送信されて、 JavaScript からのはアクセスできない事を示します。これはいくつかのクロスサイトスクリプティングの脅威を和らげることを意図しています。

キーの大小文字は区別されません。

バージョン 2.6 で追加: httponly 属性が追加されました。

Morsel.value

クッキーの値。

Morsel.coded_value

実際に送信する形式にエンコードされたcookieの値。

Morsel.key

cookieの名前。

Morsel.set(key, value, coded_value)

メンバ key 、 value 、 coded_value に値をセットします。

Morsel.isReservedKey(K)

K が Morsel のキーであるかどうかを判定します。

Morsel.output([attrs[, header]])

MoselをHTTPヘッダ形式の文字列表現にして返します。 attrs を指定しない場合、デフォルトですべての属性を含めます。 attrs を指定する場合、属性をリストで渡さなければなりません。 header のデフォルトは "Set-Cookie:" です。

Morsel.js_output([attrs])

ブラウザがJavaScriptをサポートしている場合、HTTPヘッダを送信した場合と同様に動作する埋め込み可能なJavaScript snippetを返します。

attrs の意味は output() と同じです。

Morsel.OutputString([attrs])

Moselの文字列表現をHTTPやJavaScriptで囲まずに出力します。

attrs の意味は output() と同じです。

20.22.3. 例

次の例は Cookie の使い方を示したものです。

>>> import Cookie
>>> C = Cookie.SimpleCookie()
>>> C["fig"] = "newton"
>>> C["sugar"] = "wafer"
>>> print C # generate HTTP headers
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> print C.output() # same thing
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> C = Cookie.SimpleCookie()
>>> C["rocky"] = "road"
>>> C["rocky"]["path"] = "/cookie"
>>> print C.output(header="Cookie:")
Cookie: rocky=road; Path=/cookie
>>> print C.output(attrs=[], header="Cookie:")
Cookie: rocky=road
>>> C = Cookie.SimpleCookie()
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> print C
Set-Cookie: chips=ahoy
Set-Cookie: vienna=finger
>>> C = Cookie.SimpleCookie()
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
>>> print C
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
>>> C = Cookie.SimpleCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> print C
Set-Cookie: oreo=doublestuff; Path=/
>>> C["twix"] = "none for you"
>>> C["twix"].value
'none for you'
>>> C = Cookie.SimpleCookie()
>>> C["number"] = 7 # equivalent to C["number"] = str(7)
>>> C["string"] = "seven"
>>> C["number"].value
'7'
>>> C["string"].value
'seven'
>>> print C
Set-Cookie: number=7
Set-Cookie: string=seven
>>> # SerialCookie と SmartCookie は非推奨です。
>>> # これらを使うとセキュリティーホールができることがあります。
>>> C = Cookie.SerialCookie()
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["number"].value
7
>>> C["string"].value
'seven'
>>> print C
Set-Cookie: number="I7\012."
Set-Cookie: string="S'seven'\012p1\012."
>>> C = Cookie.SmartCookie()
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["number"].value
7
>>> C["string"].value
'seven'
>>> print C
Set-Cookie: number="I7\012."
Set-Cookie: string=seven

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.23. xmlrpclib — XML-RPC クライアントアクセス

ノート

xmlrpclib モジュールは、Python 3では xmlrpc.client にリネームされました。 2to3 ツールは、自動的にソースコードのimportをPython 3用に修正します。

バージョン 2.2 で追加.

XML-RPCはXMLを利用した遠隔手続き呼び出し(Remote Procedure Call)の一種で、HTTPをトランスポートとして使用します。XML- RPCでは、クライアントはリモートサーバ(URIで指定されたサーバ)上のメソッドをパラメータを指定して呼び出し、構造化されたデータを取得します。このモジュールは、XML-RPCクライアントの開発をサポートしており、Pythonオブジェクトに適合する転送用XMLの変換の全てを行います。

class xmlrpclib.ServerProxy(uri[, transport[, encoding[, verbose[, allow_none[, use_datetime]]]]])

ServerProxy は、リモートのXML-RPCサーバとの通信を管理するオブジェクトです。最初のパラメータはURI(Uniform Resource Indicator)で、通常はサーバのURLを指定します。2番目のパラメータにはトランスポート・ファクトリを指定する事ができます。トランスポート・ファクトリを省略した場合、URLが https: ならモジュール内部の SafeTransport インスタンスを使用し、それ以外の場合にはモジュール内部の Transport インスタンスを使用します。オプションの 3 番目の引数はエンコード方法で、デフォルトでは UTF-8 です。オプションの 4 番目の引数はデバッグフラグです。 allow_none が真の場合、Python の定数 None は XML に翻訳されます; デフォルトの動作は None に対して TypeError を送出します。この仕様は XML-RPC 仕様でよく用いられている拡張ですが、全てのクライアントやサーバでサポートされているわけではありません; 詳細記述については http://ontosys.com/xml-rpc/extensions.html を参照してください。 use_datetime フラグは datetime.datetime のオブジェクトとして日付/時刻を表現する時に使用し、デフォルトでは false に設定されています。呼び出しに datetime.datetime のオブジェクトを渡すことができます。

HTTP及びHTTPS通信の両方で、 http://user:pass@host:port/path のようなHTTP基本認証のための拡張URL構文をサポートしています。 user:pass はbase64でエンコードしてHTTPの’Authorization ‘ヘッダとなり、XML-RPCメソッド呼び出し時に接続処理の一部としてリモートサーバに送信されます。リモートサーバが基本認証を要求する場合のみ、この機能を利用する必要があります。

生成されるインスタンスはリモートサーバへのプロクシオブジェクトで、RPC呼び出しを行う為のメソッドを持ちます。リモートサーバがイントロスペクション APIをサポートしている場合は、リモートサーバのサポートするメソッドを検索 (サービス検索)やサーバのメタデータの取得なども行えます。

ServerProxy インスタンスのメソッドは引数としてPythonの基礎型とオブジェクトを受け取り、戻り値としてPythonの基礎型かオブジェクトを返します。以下の型をXMLに変換(XMLを通じてマーシャルする)する事ができます (特別な指定がない限り、逆変換でも同じ型として変換されます):

名前 | 意味
boolean | 定数 True と False
整数 | そのまま
浮動小数点 | そのまま
文字列 | そのまま
配列 | 変換可能な要素を含むPythonシーケンス。戻り値はリスト。
構造体 | Pythonの辞書。キーは文字列のみ。全ての値は変換可能でなくてはならない。ユーザー定義型を渡すこともできます。 __dict__ の属性のみ転送されます。
日付 | エポックからの経過秒数(DateTime クラスのインスタンスとして渡す) もしくは、 datetime.datetime のインスタンス
バイナリ | Binary ラッパクラスのインスタンス

上記のXML-RPCでサポートする全データ型を使用することができます。メソッド呼び出し時、XML- RPCサーバエラーが発生すると Fault インスタンスを送出し、HTTP/HTTPSトランスポート層でエラーが発生した場合には ProtocolError を送出します。 Error をベースとする Fault と ProtocolError の両方が発生します。 Python 2.2以降では組み込み型のサブクラスを作成する事ができますが、現在のところxmlrpclibではそのようなサブクラスのインスタンスをマーシャルすることはできません。

文字列を渡す場合、 <, >, & などのXMLで特殊な意味を持つ文字は自動的にエスケープされます。しかし、ASCII値0〜31の制御文字(もちろん、タブ’TAB’,改行’LF’,リターン’CR’は除く)などのXMLで使用することのできない文字を使用することはできず、使用するとそのXML-RPCリクエストはwell-formedなXMLとはなりません。そのような文字列を渡す必要がある場合は、後述の Binary ラッパクラスを使用してください。

Server は、上位互換性の為に ServerProxy の別名として残されています。新しいコードでは ServerProxy を使用してください。

バージョン 2.5 で変更: use_datetime フラグが追加されました

バージョン 2.6 で変更: ニュースタイルクラス(new-style class)も、 __dict__ 属性を持っていて、特別な方法でマーシャルされている親クラスを持っていなければ、渡すことができます。

参考

XML-RPC HOWTO [http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html]

週種類のプログラミング言語で記述された XML-RPCの操作とクライアントソフトウェアの素晴らしい説明が掲載されています。 XML- RPCクライアントの開発者が知っておくべきことがほとんど全て記載されています。

XML-RPC-Hacks page [http://xmlrpc-c.sourceforge.net/hacks.php]

イントロスペクションとマルチコールをサポートしているオープンソースの拡張ライブラリについて説明しています。

XML-RPC Introspection [http://xmlrpc-c.sourceforge.net/introspection.html]

インストロペクションをサポートする、 XML-RPC プロトコルの拡張を解説しています。

XML-RPC Specification [http://www.xmlrpc.com/spec]

公式の仕様

Unofficial XML-RPC Errata [http://effbot.org/zone/xmlrpc-errata.htm]

Fredrik Lundh による “unofficial errata, intended to clarify certain details in the XML-RPC specification, as well as hint at ‘best practices’ to use when designing your own XML-RPC implementations.”

20.23.1. ServerProxy オブジェクト

ServerProxy インスタンスの各メソッドはそれぞれXML-RPCサーバの遠隔手続き呼び出しに対応しており、メソッドが呼び出されると名前と引数をシグネチャとしてRPCを実行します(同じ名前のメソッドでも、異なる引数シグネチャによってオーバロードされます)。RPC実行後、変換された値を返すか、または Fault オブジェクトもしくは ProtocolError オブジェクトでエラーを通知します。

予約メンバ system から、XMLイントロスペクションAPIの一般的なメソッドを利用する事ができます。

ServerProxy.system.listMethods()

XML-RPCサーバがサポートするメソッド名(system以外)を格納する文字列のリストを返します。

ServerProxy.system.methodSignature(name)

XML-RPCサーバで実装されているメソッドの名前を指定し、利用可能なシグネチャの配列を取得します。シグネチャは型のリストで、先頭の型は戻り値の型を示し、以降はパラメータの型を示します。

XML-RPCでは複数のシグネチャ(オーバロード)を使用することができるので、単独のシグネチャではなく、シグネチャのリストを返します。

シグネチャは、メソッドが使用する最上位のパラメータにのみ適用されます。例えばあるメソッドのパラメータが構造体の配列で戻り値が文字列の場合、シグネチャは単に”文字列, 配列” となります。パラメータが三つの整数で戻り値が文字列の場合は”文字列, 整数, 整数, 整数”となります。

メソッドにシグネチャが定義されていない場合、配列以外の値が返ります。 Pythonでは、この値はlist以外の値となります。

ServerProxy.system.methodHelp(name)

XML-RPCサーバで実装されているメソッドの名前を指定し、そのメソッドを解説する文書文字列を取得します。文書文字列を取得できない場合は空文字列を返します。文書文字列にはHTMLマークアップが含まれます

20.23.2. Boolean オブジェクト

このクラスは全てのPythonの値で初期化することができ、生成されるインスタンスは指定した値の真偽値によってのみ決まります。Booleanという名前から想像される通りに各種のPython演算子を実装しており、 __cmp__(), __repr__(), __int__(), __nonzero__() で定義される演算子を使用することができます。

以下のメソッドは、主に内部的にアンマーシャル時に使用されます:

Boolean.encode(out)

出力ストリームオブジェクト out に、XML-RPCエンコーディングのBoolean値を出力します。

動作する例です。サーバー側:

import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer

def is_even(n):
    return n%2 == 0

server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(is_even, "is_even")
server.serve_forever()

上記のサーバーに対するクライアント側:

import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
print "3 is even: %s" % str(proxy.is_even(3))
print "100 is even: %s" % str(proxy.is_even(100))

20.23.3. DateTime オブジェクト

このクラスは、エポックからの秒数、タプルで表現された時刻、ISO 8601形式の時間/日付文字列、 datetime.datetime, のインスタンスのいずれかで初期化することができます。このクラスには以下のメソッドがあり、主にコードをマーシャル/アンマーシャルするための内部処理を行います。

DateTime.decode(string)

文字列をインスタンスの新しい時間を示す値として指定します。

DateTime.encode(out)

出力ストリームオブジェクト out に、XML-RPCエンコーディングの DateTime 値を出力します。

また、 __cmp__() と __repr__() で定義される演算子を使用することができます。

20.23.4. Binary オブジェクト

このクラスは、文字列(NULを含む)で初期化することができます。 Binary の内容は、属性で参照します。

Binary.data

Binary インスタンスがカプセル化しているバイナリデータ。このデータは8bitクリーンです。

以下のメソッドは、主に内部的にマーシャル/アンマーシャル時に使用されます:

Binary.decode(string)

指定されたbase64文字列をデコードし、インスタンスのデータとします。

Binary.encode(out)

バイナリ値をbase64でエンコードし、出力ストリームオブジェクト out に出力します。

エンコードされたデータは、 RFC 2045 section 6.8 [http://tools.ietf.org/html/rfc2045#section-6.8] にある通り、76文字ごとに改行されます。これは、XMC-RPC仕様が作成された時のデ・ファクト・スタンダードのbase64です。

また、 __cmp__() で定義される演算子を使用することができます。

バイナリオブジェクトの使用例です。 XML-RPCごしに画像を転送します。

from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib

def python_logo():
     with open("python_logo.jpg", "rb") as handle:
         return xmlrpclib.Binary(handle.read())

server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(python_logo, 'python_logo')

server.serve_forever()

クライアント側は画像を取得して、ファイルに保存します。

import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
with open("fetched_python_logo.jpg", "wb") as handle:
    handle.write(proxy.python_logo().data)

20.23.5. Fault オブジェクト

Fault オブジェクトは、XML-RPCのfaultタグの内容をカプセル化しており、以下のメンバを持ちます:

Fault.faultCode

失敗のタイプを示す文字列。

Fault.faultString

失敗の診断メッセージを含む文字列。

以下のサンプルでは、複素数型のオブジェクトを返そうとして、故意に Fault を起こしています。

from SimpleXMLRPCServer import SimpleXMLRPCServer

# A marshalling error is going to occur because we're returning a
# complex number
def add(x,y):
    return x+y+0j

server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(add, 'add')

server.serve_forever()

上記のサーバーに対するクライアント側のコード:

import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
try:
    proxy.add(2, 5)
except xmlrpclib.Fault, err:
    print "A fault occurred"
    print "Fault code: %d" % err.faultCode
    print "Fault string: %s" % err.faultString

20.23.6. ProtocolError オブジェクト

ProtocolError オブジェクトはトランスポート層で発生したエラー(URI で指定したサーバが見つからなかった場合に発生する404 ‘not found’など)の内容を示し、以下のメンバを持ちます:

ProtocolError.url

エラーの原因となったURIまたはURL。

ProtocolError.errcode

エラーコード。

ProtocolError.errmsg

エラーメッセージまたは診断文字列。

ProtocolError.headers

エラーの原因となったHTTP/HTTPSリクエストを含む文字列。

次の例では、XMLRPC サーバを指していない URI を利用して、故意に ProtocolError を発生させています。

import xmlrpclib

# create a ServerProxy with an URI that doesn't respond to XMLRPC requests
proxy = xmlrpclib.ServerProxy("http://www.google.com/")

try:
    proxy.some_method()
except xmlrpclib.ProtocolError, err:
    print "A protocol error occurred"
    print "URL: %s" % err.url
    print "HTTP/HTTPS headers: %s" % err.headers
    print "Error code: %d" % err.errcode
    print "Error message: %s" % err.errmsg

20.23.7. MultiCall オブジェクト

バージョン 2.4 で追加.

遠隔のサーバに対する複数の呼び出しをひとつのリクエストにカプセル化する方法は、http://www.xmlrpc.com/discuss/msgReader%241208 で示されています。

class xmlrpclib.MultiCall(server)

巨大な (boxcar) メソッド呼び出しに使えるオブジェクトを作成します。 server には最終的に呼び出しを行う対象を指定します。作成した MultiCall オブジェクトを使って呼び出しを行うと、即座に None を返し、呼び出したい手続き名とパラメタに保存するだけに留まります。オブジェクト自体を呼び出すと、それまでに保存しておいたすべての呼び出しを単一の system.multicall リクエストの形で伝送します。呼び出し結果はジェネレータ(generator)になります。このジェネレータにわたってイテレーションを行うと、個々の呼び出し結果を返します。

以下にこのクラスの使い方を示します。

このクラスの使用例です。サーバー側のコード:

from SimpleXMLRPCServer import SimpleXMLRPCServer

def add(x,y):
    return x+y

def subtract(x, y):
    return x-y

def multiply(x, y):
    return x*y

def divide(x, y):
    return x/y

# A simple server with simple arithmetic functions
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_multicall_functions()
server.register_function(add, 'add')
server.register_function(subtract, 'subtract')
server.register_function(multiply, 'multiply')
server.register_function(divide, 'divide')
server.serve_forever()

このサーバーに対する、クライアント側のコード:

import xmlrpclib

proxy = xmlrpclib.ServerProxy("http://localhost:8000/")
multicall = xmlrpclib.MultiCall(proxy)
multicall.add(7,3)
multicall.subtract(7,3)
multicall.multiply(7,3)
multicall.divide(7,3)
result = multicall()

print "7+3=%d, 7-3=%d, 7*3=%d, 7/3=%d" % tuple(result)

20.23.8. 補助関数

xmlrpclib.boolean(value)

Pythonの値を、XML-RPCのBoolean定数 True または False に変換します。

xmlrpclib.dumps(params[, methodname[, methodresponse[, encoding[, allow_none]]]])

params を XML-RPC リクエストの形式に変換します。 methodresponse が真の場合、XML-RPC レスポンスの形式に変換します。 params に指定できるのは、引数からなるタプルか Fault 例外クラスのインスタンスです。 methodresponse が真の場合、単一の値だけを返します。従って、 params の長さも 1 でなければなりません。 encoding を指定した場合、生成される XML のエンコード方式になります。デフォルトは UTF-8 です。 Python の None は標準の XML-RPC には利用できません。 None を使えるようにするには、 allow_none を真にして、拡張機能つきにしてください。

xmlrpclib.loads(data[, use_datetime])

XML-RPC リクエストまたはレスポンスを (params, methodname) の形式をとる Python オブジェクトにします。 params は引数のタプルです。 methodname は文字列で、パケット中にメソッド名がない場合には None になります。例外条件を示す XML-RPC パケットの場合には、 Fault 例外を送出します。 use_datetime フラグは datetime.datetime のオブジェクトとして日付/時刻を表現する時に使用し、デフォルトでは false に設定されています。

バージョン 2.5 で変更: use_datetime フラグを追加.

20.23.9. クライアントのサンプル

# simple test program (from the XML-RPC specification)
from xmlrpclib import ServerProxy, Error

# server = ServerProxy("http://localhost:8000") # local server
server = ServerProxy("http://betty.userland.com")

print server

try:
    print server.examples.getStateName(41)
except Error, v:
    print "ERROR", v

XML-RPCサーバにプロキシを経由して接続する場合、カスタムトランスポートを定義する必要があります。以下に例を示します:

import xmlrpclib, httplib

class ProxiedTransport(xmlrpclib.Transport):
    def set_proxy(self, proxy):
        self.proxy = proxy
    def make_connection(self, host):
        self.realhost = host
        h = httplib.HTTP(self.proxy)
        return h
    def send_request(self, connection, handler, request_body):
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
    def send_host(self, connection, host):
        connection.putheader('Host', self.realhost)

p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpclib.Server('http://time.xmlrpc.com/RPC2', transport=p)
print server.currentTime.getCurrentTime()

20.23.10. クライアントとサーバーの利用例

SimpleXMLRPCServer の例 を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.24. SimpleXMLRPCServer — 基本的なXML-RPCサーバー

ノート

SimpleXMLRPCServer モジュールは、Python 3では xmlrpc.server モジュールに統合されました。 2to3 ツールが自動的にソースコード内のimportを修正します。

バージョン 2.2 で追加.

SimpleXMLRPCServer モジュールはPythonで記述された基本的なXML-RPC サーバーフレームワークを提供します。サーバーはスタンドアロンであるか、 SimpleXMLRPCServer を使うか、 CGIXMLRPCRequestHandler を使って CGI 環境に組み込まれるかの、いずれかです。

class SimpleXMLRPCServer.SimpleXMLRPCServer(addr[, requestHandler[, logRequests[, allow_none[, encoding[, bind_and_activate]]]]])

新しくサーバーインスタンスを作成します。このクラスはXML-RPCプロトコルで呼ばれる関数の登録のためのメソッドを提供します。引数 requestHandler には、リクエストハンドラーインスタンスのファクトリーを設定します。デフォルトは SimpleXMLRPCRequestHandler です。引数 addr と requestHandler は SocketServer.TCPServer のコンストラクターに引き渡されます。もし引数 logRequests が真(true)であれば、(それがデフォルトですが、)リクエストはログに記録されます。偽(false)である場合にはログは記録されません。引数 allow_none と encoding は xmlrpclib に引き継がれ、サーバーから返されるXML-RPCレスポンスを制御します。 bind_and_activate 引数は、コンストラクタの呼び出し直後に server_bind() と server_activate() を呼ぶかどうかを指定します。デフォルトでは True です。この引数に False を指定することで、バインドする前に、 allow_reuse_address クラス変数を操作することができます。 (訳注: 同じ名前のインスタンス変数を追加することで、クラス変数をオーバーライドすることができます。)

バージョン 2.5 で変更: 引数 allow_none と encoding が追加されました.

バージョン 2.6 で変更: bind_and_activate 引数が追加されました。

class SimpleXMLRPCServer.CGIXMLRPCRequestHandler([allow_none[, encoding]])

CGI 環境における XML-RPC リクエストハンドラーを、新たに作成します。引数 allow_none と encoding は xmlrpclib に引き継がれ、サーバーから返されるXML-RPCレスポンスを制御します。

バージョン 2.3 で追加.

バージョン 2.5 で変更: 引数 allow_none と encoding が追加されました.

class SimpleXMLRPCServer.SimpleXMLRPCRequestHandler

新しくリクエストハンドラーインスタンスを作成します。このリクエストハンドラーは POST リクエストを受け持ち、 SimpleXMLRPCServer のコンストラクターの引数 logRequests に従ったログ出力を行います。

20.24.1. SimpleXMLRPCServer オブジェクト

SimpleXMLRPCServer クラスは SocketServer.TCPServer のサブクラスで、基本的なスタンドアロンの XML-RPC サーバーを作成する手段を提供します。

SimpleXMLRPCServer.register_function(function[, name])

XML- RPCリクエストに応じる関数を登録します。引数 name が与えられている場合はその値が、関数 function に関連付けられます。これが与えられない場合は function.__name__ の値が用いられます。引数 name は通常の文字列でもユニコード文字列でも良く、Pythonで識別子として正しくない文字(” . “ピリオドなど )を含んでいても。

SimpleXMLRPCServer.register_instance(instance[, allow_dotted_names])

オブジェクトを登録し、そのオブジェクトの register_function() で登録されていないメソッドを公開します。もし、 instance がメソッド _dispatch() を定義していれば、 _dispatch() が、リクエストされたメソッド名とパラメータの組を引数として呼び出されます。そして、 _dispatch() の返り値が結果としてクライアントに返されます。そのAPIは def _dispatch(self, method, params) (注意: params は可変引数リストではありません)です。仕事をするために下位の関数を呼ぶ時には、その関数は func(*params) のように呼ばれます。 _dispatch() の返り値はクライアントへ結果として返されます。もし、 instance がメソッド _dispatch() を定義していなければ、リクエストされたメソッド名がそのインスタンスに定義されているメソッド名から探されます。

もしオプション引数 allow_dotted_names が真(true)で、インスタンスがメソッド _dispatch() を定義していないとき、リクエストされたメソッド名がピリオドを含む場合は、（訳注：通常のPythonでのピリオドの解釈と同様に）階層的にオブジェクトを探索します。そして、そこで見つかったオブジェクトをリクエストから渡された引数で呼び出し、その返り値をクライアントに返します。

警告

allow_dotted_names オプションを有効にすると、侵入者にあなたのモジュールのグローバル変数にアクセスすることを許し、あなたのコンピュータで任意のコードを実行することを許すことがあります。このオプションは安全な閉じたネットワークでのみお使い下さい。

バージョン 2.3.5, で変更: 2.4.1 allow_dotted_names はセキュリティホールを塞ぐために追加されました。以前のバージョンは安全ではありません.

SimpleXMLRPCServer.register_introspection_functions()

XML-RPC のイントロスペクション関数、 system.listMethods 、 system.methodHelp 、 system.methodSignature を登録します。

バージョン 2.3 で追加.

SimpleXMLRPCServer.register_multicall_functions()

XML-RPC における複数の要求を処理する関数 system.multicall を登録します。

SimpleXMLRPCServer.rpc_paths

この属性値はXML-RPCリクエストを受け付けるURLの正当なパス部分をリストするタプルでなければなりません。これ以外のパスへのリクエストは404「そのようなページはありません」 HTTPエラーになります。このタプルが空の場合は全てのパスが正当であると見なされます。デフォルト値は ('/', '/RPC2') です。

バージョン 2.5 で追加.

SimpleXMLRPCRequestHandler.encode_threshold

この属性が None でない場合、クライアントが受け付けるのであれば、この値よりも大きいサイズのレスポンスを gzip transfer encoding を利用して圧縮されます、デフォルト値は、だいたいTCPの1パケットに収まるように 1400 です。

バージョン 2.7 で追加.

20.24.1.1. SimpleXMLRPCServer の例

サーバーのコード:

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

# Create server
server = SimpleXMLRPCServer(("localhost", 8000),
                            requestHandler=RequestHandler)
server.register_introspection_functions()

# Register pow() function; this will use the value of
# pow.__name__ as the name, which is just 'pow'.
server.register_function(pow)

# Register a function under a different name
def adder_function(x,y):
    return x + y
server.register_function(adder_function, 'add')

# Register an instance; all the methods of the instance are
# published as XML-RPC methods (in this case, just 'div').
class MyFuncs:
    def div(self, x, y):
        return x // y

server.register_instance(MyFuncs())

# Run the server's main loop
server.serve_forever()

以下のクライアントコードは上のサーバーで使えるようになったメソッドを呼び出します:

import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8000')
print s.pow(2,3)  # Returns 2**3 = 8
print s.add(2,3)  # Returns 5
print s.div(5,2)  # Returns 5//2 = 2

# Print list of available methods
print s.system.listMethods()

20.24.2. CGIXMLRPCRequestHandler

CGIXMLRPCRequestHandler クラスは、Python の CGI スクリプトに送られた XML-RPC リクエストを処理するときに使用できます

CGIXMLRPCRequestHandler.register_function(function[, name])

XML-RPC リクエストに応じる関数を登録します。引数 name が与えられている場合はその値が、関数 function に関連付けられます。これが与えられない場合は function.__name__ の値が用いられます。引数 name は通常の文字列でもユニコード文字列でも良く、Pythonで識別子として正しくない文字(” . “ピリオドなど )を含んでもかまいません。

CGIXMLRPCRequestHandler.register_instance(instance)

オブジェクトを登録し、そのオブジェクトの register_function() で登録されていないメソッドを公開します。もし、 instance がメソッド _dispatch() を定義していれば、 _dispatch() が、リクエストされたメソッド名とパラメータの組を引数として呼び出されます。そして、 _dispatch() の返り値が結果としてクライアントに返されます。もし、 instance がメソッド _dispatch() を定義していなければ、リクエストされたメソッド名がそのインスタンスに定義されているメソッド名から探されます。リクエストされたメソッド名がピリオドを含む場合は、（訳注：通常のPythonでのピリオドの解釈と同様に）階層的にオブジェクトを探索します。そして、そこで見つかったオブジェクトをリクエストから渡された引数で呼び出し、その返り値をクライアントに返します。

CGIXMLRPCRequestHandler.register_introspection_functions()

XML-RPC のイントロスペクション関数、 system.listMethods 、 system.methodHelp 、 system.methodSignature を登録します。

CGIXMLRPCRequestHandler.register_multicall_functions()

XML-RPC における複数の要求を処理する関数 system.multicall を登録します。

CGIXMLRPCRequestHandler.handle_request([request_text = None])

XML-RPC リクエストを処理します。 request_text で渡されるのは、HTTP サーバーに提供された POST データです。何も渡されなければ標準入力からのデータが使われます。

以下に例を示します。

class MyFuncs:
    def div(self, x, y) : return x // y

handler = CGIXMLRPCRequestHandler()
handler.register_function(pow)
handler.register_function(lambda x,y: x+y, 'add')
handler.register_introspection_functions()
handler.register_instance(MyFuncs())
handler.handle_request()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

20. インターネットプロトコルとその支援 »

20.25. DocXMLRPCServer — セルフ-ドキュメンティング XML-RPC サーバ

DocXMLRPCServer モジュールは、Python 3では xmlrpc.server モジュールに統合されました。 2to3 ツールは、ソースコード内のimportを自動的にPython 3用に修正します。

バージョン 2.3 で追加.

DocXMLRPCServer モジュールは SimpleXMLRPCServer クラスを拡張し、HTTP GET リクエストに対し HTML ドキュメントを返します。サーバは DocXMLRPCServer を使ったスタンドアロン環境、 DocCGIXMLRPCRequestHandler を使った CGI 環境の2つがあります。

class DocXMLRPCServer.DocXMLRPCServer(addr[, requestHandler[, logRequests[, allow_none[, encoding[, bind_and_activate]]]]])

当たなサーバ・インスタンスを生成します。各パラメータの内容は SimpleXMLRPCServer.SimpleXMLRPCServer のものと同じですが、 requestHandler のデフォルトは DocXMLRPCRequestHandler になっています。

class DocXMLRPCServer.DocCGIXMLRPCRequestHandler

CGI環境に XMR-RPC リクエスト・ハンドラの新たなインスタンスを生成します。

class DocXMLRPCServer.DocXMLRPCRequestHandler

リクエスト・ハンドラの新たなインスタンスを生成します。このリクエスト・ハンドラは XML-RPC POST リクエスト、ドキュメントの GET、そして DocXMLRPCServer コンストラクタに与えられた logRequests パラメータ設定を優先するため、ロギングの変更をサポートします。

20.25.1. DocXMLRPCServer オブジェクト

DocXMLRPCServer は SimpleXMLRPCServer.SimpleXMLRPCServer の派生クラスで、セルフ- ドキュメンティングの手段と XML-RPC サーバ機能を提供します。HTTP POST リクエストは XML-RPC メソッドの呼び出しとして扱われます。HTTP GET リクエストは pydoc スタイルの HTML ドキュメント生成のリクエストとして扱われます。これはサーバが自分自身のドキュメントを Web ベースで提供可能であることを意味します。

DocXMLRPCServer.set_server_title(server_title)

生成する HTML ドキュメントのタイトルをセットします。このタイトルは HTML の title 要素として使われます。

DocXMLRPCServer.set_server_name(server_name)

生成する HTML ドキュメントの名前をセットします。この名前は HTML 冒頭の h1 要素に使われます。

DocXMLRPCServer.set_server_documentation(server_documentation)

生成する HTML ドキュメントの本文をセットします。この本文はドキュメント中の名前の下にパラグラフとして出力されます。

20.25.2. DocCGIXMLRPCRequestHandler

DocCGIXMLRPCRequestHandler は SimpleXMLRPCServer.CGIXMLRPCRequestHandler の派生クラスで、セルフ- ドキュメンティングの手段と XML-RPC CGI スクリプト機能を提供します。HTTP POST リクエストは XML-RCP メソッドの呼び出しとして扱われます。 HTTP GET リクエストは pydoc スタイルの HTML ドキュメント生成のリクエストとして扱われます。これはサーバが自分自身のドキュメントを Web ベースで提供可能であることを意味します。

DocCGIXMLRPCRequestHandler.set_server_title(server_title)

生成する HTML ドキュメントのタイトルをセットします。このタイトルは HTML の title 要素として使われます。

DocCGIXMLRPCRequestHandler.set_server_name(server_name)

生成する HTML ドキュメントの名前をセットします。この名前は HTML 冒頭の h1 要素に使われます。

DocCGIXMLRPCRequestHandler.set_server_documentation(server_documentation)

生成する HTML ドキュメントの本文をセットします。この本文はドキュメント中の名前の下にパラグラフとして出力されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス

この章で記述されているモジュールは、主にマルチメディアアプリケーションに役立つさまざまなアルゴリズムまたはインターフェイスを実装しています。これらのモジュールはインストール時の自由裁量に応じて利用できます。

以下に概要を示します。

21.1. audioop — 生の音声データを操作する

21.2. imageop — 生の画像データを操作する

21.3. aifc — AIFFおよびAIFCファイルの読み書き

21.4. sunau — Sun AUファイルの読み書き

21.4.1. AU_read オブジェクト

21.4.2. AU_write オブジェクト

21.5. wave — WAVファイルの読み書き

21.5.1. Wave_read オブジェクト

21.5.2. Wave_write オブジェクト

21.6. chunk — IFFチャンクデータの読み込み

21.7. colorsys — 色体系間の変換

21.8. imghdr — 画像の形式を決定する

21.9. sndhdr — サウンドファイルの識別

21.10. ossaudiodev — OSS互換オーディオデバイスへのアクセス

21.10.1. オーディオデバイスオブジェクト

21.10.2. ミキサデバイスオブジェクト

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.1. audioop — 生の音声データを操作する

audioop モジュールは音声データを操作する関数を収録しています。このモジュールは、Python 文字列型中に入っている 8, 16, 32 ビットの符号付き整数でできた音声データ、すなわち al および sunaudiodev で使われているのと同じ形式の音声データを操作します。特に指定の無いかぎり、スカラ量を表す要素はすべて整数型になっています。

このモジュールはa-LAW、u-LAWそしてIntel/DVI ADPCMエンコードをサポートしています。

複雑な操作のうちいくつかはサンプル幅が 16 ビットのデータに対してのみ働きますが、それ以外は常にサンプル幅を操作のパラメタとして (バイト単位で) 渡します。

このモジュールでは以下の変数と関数を定義しています：

exception audioop.error

この例外は、未知のサンプル当たりのバイト数を指定した時など、全般的なエラーに対して送出されます。

audioop.add(fragment1, fragment2, width)

パラメタに渡した 2 つのデータを加算した結果を返します。 width はサンプル幅をバイトで表したもので、 1 、 2 、 4 のうちいずれかです。 2 つのデータは同じサンプル幅でなければなりません。

audioop.adpcm2lin(adpcmfragment, width, state)

Intel/DVI ADPCM 形式のデータをリニア (linear) 形式にデコードします。 ADPCM 符号化方式の詳細については lin2adpcm() の説明を参照して下さい。 (sample, newstate) からなるタプルを返し、サンプルは width に指定した幅になります。

audioop.alaw2lin(fragment, width)

a-LAW形式のデータをリニア (linear) 形式に変換します。 a-LAW形式は常に 8 ビットのサンプルを使用するので、ここでは width は単に出力データのサンプル幅となります。

バージョン 2.5 で追加.

audioop.avg(fragment, width)

データ中の全サンプルの平均値を返します。

audioop.avgpp(fragment, width)

データ中の全サンプルの平均 peak-peak 振幅を返します。フィルタリングを行っていない場合、このルーチンの有用性は疑問です。

audioop.bias(fragment, width, bias)

元データの各サンプルにバイアスを加えたデータを返します。

audioop.cross(fragment, width)

引数に渡したデータ中のゼロ交差回数を返します。

audioop.findfactor(fragment, reference)

rms(add(fragment, mul(reference, -F))) を最小にするような係数 F 、すなわち、 reference に乗算したときにもっとも fragment に近くなるような値を返します。 fragment と reference のサンプル幅はいずれも 2バイトでなければなりません。

このルーチンの実行に要する時間は len(fragment) に比例します。

audioop.findfit(fragment, reference)

reference を可能な限り fragment に一致させようとします (fragment は reference より長くなければなりません)。この処理は (概念的には) fragment からスライスをいくつか取り出し、それぞれについて findfactor() を使って最良な一致を計算し、誤差が最小の結果を選ぶことで実現します。 fragment と reference のサンプル幅は両方とも2バイトでなければなりません。 (offset, factor) からなるタプルを返します。 offset は最適な一致箇所が始まる fragment のオフセット値（整数）で、 factor は findfactor() の返す係数 (浮動小数点数) です。

audioop.findmax(fragment, length)

fragment から、長さが length サンプル (バイトではありません!) で最大のエネルギーを持つスライス、すなわち、 rms(fragment[i *2:(i+length)* 2]) を最大にするようなスライスを探し、 i を返します。データのはサンプル幅は 2バイトでなければなりません。

このルーチンの実行に要する時間は len(fragment) に比例します。

audioop.getsample(fragment, width, index)

データ中の index サンプル目の値を返します。

audioop.lin2adpcm(fragment, width, state)

データを 4 ビットの Intel/DVI ADPCM 符号化方式に変換します。 ADPCM 符号化方式とは適応符号化方式の一つで、あるサンプルと (可変の) ステップだけ離れたその次のサンプルとの差を 4 ビットの整数で表現する方式です。 Intel/DVI ADPCMアルゴリズムは IMA (国際MIDI協会) に採用されているので、おそらく標準になるはずです。

state はエンコーダの内部状態が入ったタプルです。エンコーダは (adpcmfrag, newstate) のタプルを返し、次に lin2adpcm() を呼び出す時に newstate を渡さねばなりません。最初に呼び出す時には state に None を渡してもかまいません。 adpcmfrag は ADPCMで符号化されたデータで、バイト当たり 2 つの4ビット値がパックされています。

audioop.lin2alaw(fragment, width)

音声データの各サンプルを a-LAW 符号でエンコードし、Python文字列として返します。a-LAW とは音声符号化方式の一つで、約 13 ビットに相当するダイナミックレンジをわずか 8 ビットで実現できます。 Sun やその他の音声ハードウェアで使われています。

バージョン 2.5 で追加.

audioop.lin2lin(fragment, width, newwidth)

サンプル幅を 1、2、4 バイト形式の間で変換します。

ノート

.WAV のような幾つかのオーディオフォーマットでは、16bitと32bitのサンプルは符号付きですが、 8bitのサンプルは符号なしです。そのため、そのようなフォーマットで8bitに変換する場合は、変換結果に128を足さなければなりません。

new_frames = audioop.lin2lin(frames, old_width, 1) new_frames = audioop.bias(new_frames, 1, 128)

逆に、8bitから16bitや32bitに変換する場合も、同じことが言えます。

audioop.lin2ulaw(fragment, width)

音声データの各サンプルを u-LAW 符号でエンコードし、Python文字列として返します。 u-LAW とは音声符号化方式の一つで、約 14 ビットに相当するダイナミックレンジをわずか 8 ビットで実現できます。 Sun やその他の音声ハードウェアで使われています。

audioop.minmax(fragment, width)

音声データ全サンプル中における最小値と最大値からなるタプルを返します。

audioop.max(fragment, width)

音声データ全サンプルの 絶対値 の最大値を返します。

audioop.maxpp(fragment, width)

音声データの最大 peak-peak 振幅を返します。

audioop.mul(fragment, width, factor)

元のデータの全サンプルに浮動小数点数 factor を掛けたデータを返します。オーバフローが起きても例外を送出せず無視します。

audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])

入力したデータのフレームレートを変換します。

state は変換ルーチンの内部状態を入れたタプルです。変換ルーチンは (newfragment, newstate) を返し、次に ratecv() を呼び出す時には newstate を渡さなねばなりません。最初の呼び出しでは None を渡します。

引数 weightA と weightB は単純なデジタルフィルタのパラメタで、デフォルト値はそれぞれ 1 と 0 です。

audioop.reverse(fragment, width)

データ内のサンプルの順序を逆転し、変更されたデータを返します。

audioop.rms(fragment, width)

データの自乗平均根(root-mean-square)、すなわち sqrt(sum(S_i^2)/n を返します。これはオーディオ信号の強度 (power) を測る一つの目安です。

audioop.tomono(fragment, width, lfactor, rfactor)

ステレオ音声データをモノラル音声データに変換します。左チャネルのデータに lfactor 、右チャネルのデータに rfactor を掛けた後、二つのチャネルの値を加算して単一チャネルの信号を生成します。

audioop.tostereo(fragment, width, lfactor, rfactor)

モノラル音声データをステレオ音声データに変換します。ステレオ音声データの各サンプル対は、モノラル音声データの各サンプルをそれぞれ左チャネルは lfactor 倍、右チャネルは rfactor 倍して生成します。

audioop.ulaw2lin(fragment, width)

u-LAW で符号化されている音声データを線形に符号化された音声データに変換します。 u-LAW 符号化は常にサンプル当たり 8 ビットを使うため、 width は出力音声データのサンプル幅にしか使われません。

mul() や max() といった操作はモノラルとステレオを区別しない、すなわち全てのデータを平等に扱うということに注意してください。この仕様が問題になるようなら、あらかじめステレオ音声データを二つのモノラル音声データに分割しておき、操作後に再度統合してください。そのような例を以下に示します:

def mul_stereo(sample, width, lfactor, rfactor):
    lsample = audioop.tomono(sample, width, 1, 0)
    rsample = audioop.tomono(sample, width, 0, 1)
    lsample = audioop.mul(lsample, width, lfactor)
    rsample = audioop.mul(rsample, width, rfactor)
    lsample = audioop.tostereo(lsample, width, 1, 0)
    rsample = audioop.tostereo(rsample, width, 0, 1)
    return audioop.add(lsample, rsample, width)

ADPCM エンコーダを使って音声データの入ったネットワークパケットを構築する際、自分のプロトコルを (パケットロスに耐えられるように) ステートレス (stateless) にしたいなら、データだけでなく状態変数 (state) も伝送せねばなりません。このとき、伝送するのはエンコード後状態 (エンコーダの返す値) ではなく、エンコーダの初期状態 (lin2adpcm() に渡した値) initial なので注意してください。 struct.struct() を使って状態変数をバイナリ形式で保存したいなら、最初の要素 (予測値) は 16 ビットで、次の値 (デルタ係数: delta index) は 8 ビットで符号化できます。

このモジュールの ADPCM 符号のテストは自分自身に対してのみ行っており、他の ADPCM 符号との間では行っていません。作者が仕様を誤解している部分もあるかもしれず、それぞれの標準との間で相互運用できない場合もあり得ます。

find*() ルーチンは一見滑稽に見えるかもしれません。これらの関数の主な目的はエコー除去 (echo cancellation) にあります。エコー除去を十分高速に行うには、出力サンプル中から最も大きなエネルギーを持った部分を取り出し、この部分が入力サンプル中のどこにあるかを調べ、入力サンプルから出力サンプル自体を減算します:

def echocancel(outputdata, inputdata):
    pos = audioop.findmax(outputdata, 800)    # 1/10秒
    out_test = outputdata[pos*2:]
    in_test = inputdata[pos*2:]
    ipos, factor = audioop.findfit(in_test, out_test)
    # Optional (for better cancellation):
    # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
    #              out_test)
    prefill = '\0'*(pos+ipos)* 2
    postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
    outputdata = prefill + audioop.mul(outputdata,2,-factor) + postfill
    return audioop.add(inputdata, outputdata, 2)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.2. imageop — 生の画像データを操作する

バージョン 2.6 で撤廃: imageop モジュールは Python 3.0 では削除されます。

imageop モジュールは画像に関する便利な演算がふくまれています。Python文字列に保存されている8または32ビットのピクセルから構成される画像を操作します。これは gl.lrectwrite() と imgfile モジュールが使用しているものと同じフォーマットです。

モジュールは次の変数と関数を定義しています:

exception imageop.error

この例外はピクセル当りの未知のビット数などのすべてのエラーで発生させられます。

imageop.crop(image, psize, width, height, x0, y0, x1, y1)

image の選択された部分を返します。 image は width × height の大きさで、 psize バイトのピクセルから構成されなければなりません。 x0, y0, x1 および y1 は gl.lrectread() パラメータと同様です。すなわち、境界は新画像に含まれます。新しい境界は画像の内部である必要はありません。旧画像の外側になるピクセルは値をゼロに設定されます。 x0 が x1 より大きければ、新画像は鏡像反転されます。y軸についても同じことが適用されます。

imageop.scale(image, psize, width, height, newwidth, newheight)

image を大きさ newwidth × newheight に伸縮させて返します。補間は行われません。ばかばかしいほど単純なピクセルの複製と間引きを行い伸縮させます。そのため、コンピュータで作った画像やディザ処理された画像は伸縮した後見た目が良くありません。

imageop.tovideo(image, psize, width, height)

垂直ローパスフィルタ処理を画像全体に行います。それぞれの目標ピクセルを垂直に並んだ二つの元ピクセルから計算することで行います。このルーチンの主な用途としては、画像がインターレース走査のビデオ装置に表示された場合に極端なちらつきを抑えるために用います。そのため、この名前があります。

imageop.grey2mono(image, width, height, threshold)

全ピクセルを二値化することによって、深さ8ビットのグレースケール画像を深さ1ビットの画像へ変換します。処理後の画像は隙間なく詰め込まれ、おそらく mono2grey() の引数としてしか使い道がないでしょう。

imageop.dither2mono(image, width, height)

(ばかばかしいほど単純な)ディザ処理アルゴリズムを用いて、8ビットグレースケール画像を1ビットのモノクロ画像に変換します。

imageop.mono2grey(image, width, height, p0, p1)

1ビットモノクロが象画像を8ビットのグレースケールまたはカラー画像に変換します。入力で値ゼロの全てのピクセルは出力では値 p0 を取り、値0の入力ピクセルは出力では値 p1 を取ります。白黒のモノクロ画像をグレースケールへ変換するためには、値 0 と 255 をそれぞれ渡してください。

imageop.grey2grey4(image, width, height)

ディザ処理を行わずに、8ビットグレースケール画像を4ビットグレースケール画像へ変換します。

imageop.grey2grey2(image, width, height)

ディザ処理を行わずに、8ビットグレースケール画像を2ビットグレースケール画像に変換します。

imageop.dither2grey2(image, width, height)

ディザ処理を行い、8ビットグレースケール画像を2ビットグレースケール画像へ変換します。 dither2mono() については、ディザ処理アルゴリズムは現在とても単純です。

imageop.grey42grey(image, width, height)

4ビットグレースケール画像を8ビットグレースケール画像へ変換します。

imageop.grey22grey(image, width, height)

2ビットグレースケール画像を8ビットグレースケール画像へ変換します。

imageop.backward_compatible

0 にセットすると、このモジュールの関数は、リトルエンディアンのシステムで以前のバージョンと互換性のない方法でマルチバイトピクセル値を表現するようになります。このモジュールはもともと SGI 向けに書かれたのですが、SGI はビッグエンディアンのシステムであり、この変数を設定しても何の影響もありません。とはいえ、このコードはもともとどこでも動作するように考えて作られたわけではないので、バイトオーダに関する仮定が相互利用向けではありませんでした。この変数を 0 にすると、リトルエンディアンのシステムではバイトオーダを反転して、ビッグエンディアンと同じにします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.3. aifc — AIFFおよびAIFCファイルの読み書き

このモジュールはAIFFとAIFF-Cファイルの読み書きをサポートします。 AIFF（Audio Interchange File Format）はデジタルオーディオサンプルをファイルに保存するためのフォーマットです。 AIFF-CはAIFFの新しいバージョンで、オーディオデータの圧縮に対応しています。

ノート

操作のいくつかはIRIX上でのみ動作します；そういう操作ではIRIXでのみ利用できる cl モジュールをインポートしようとして、 ImportError を発生します。

オーディオファイルには、オーディオデータについて記述したパラメータがたくさん含まれています。サンプリングレートあるいはフレームレートは、1秒あたりのオーディオサンプル数です。チャンネル数は、モノラル、ステレオ、4チャンネルかどうかを示します。フレームはそれぞれ、チャンネルごとに一つのサンプルからなります。サンプルサイズは、一つのサンプルの大きさをバイト数で示したものです。したがって、一つのフレームは nchannels * samplesize バイトからなり、1秒間では nchannels * samplesize * framerate バイトで構成されます。

例えば、CD品質のオーディオは2バイト（16ビット）のサンプルサイズを持っていて、2チャンネル（ステレオ）であり、44,100フレーム／秒のフレームレートを持っています。そのため、フレームサイズは4バイト（2*2）で、 1秒間では2*2*44100バイト（176,400バイト）になります。

aifc モジュールは以下の関数を定義しています：

aifc.open(file[, mode])

AIFFあるいはAIFF-Cファイルを開き、後述するメソッドを持つインスタンスを返します。引数 file はファイルを示す文字列か、ファイルオブジェクトのいずれかです。 mode は、読み込み用に開くときには 'r' か 'rb' のどちらかで、書き込み用に開くときには 'w' か 'wb' のどちらかでなければなりません。もし省略されたら、 file.mode が存在すればそれが使用され、なければ 'rb' が使われます。書き込み用にこのメソッドを使用するときには、これから全部でどれだけのサンプル数を書き込むのか分からなかったり、 writeframesraw() と setnframes() を使わないなら、ファイルオブジェクトはシーク可能でなければなりません。

ファイルが open() によって読み込み用に開かれたときに返されるオブジェクトには、以下のメソッドがあります：

aifc.getnchannels()

オーディオチャンネル数（モノラルなら1、ステレオなら2）を返します。

aifc.getsampwidth()

サンプルサイズをバイト数で返します。

aifc.getframerate()

サンプリングレート（1秒あたりのオーディオフレーム数）を返します。

aifc.getnframes()

ファイルの中のオーディオフレーム数を返します。

aifc.getcomptype()

オーディオファイルで使用されている圧縮形式を示す4文字の文字列を返します。AIFFファイルでは 'NONE' が返されます。

aifc.getcompname()

オーディオファイルの圧縮形式を人に判読可能な形にしたものを返します。 AIFFファイルでは 'not compressed' が返されます。

aifc.getparams()

以上の全ての値を上の順に並べたタプルを返します。

aifc.getmarkers()

オーディオファイルのマーカーのリストを返します。一つのマーカーは三つの要素のタプルです。要素の1番目はマークID（整数）、2番目はマーク位置のフレーム数をデータの始めから数えた値（整数）、3番目はマークの名称（文字列）です。

aifc.getmark(id)

与えられた id のマークの要素を getmarkers() で述べたタプルで返します。

aifc.readframes(nframes)

オーディオファイルの次の nframes 個のフレームを読み込んで返します。返されるデータは、全チャンネルの圧縮されていないサンプルをフレームごとに文字列にしたものです。

aifc.rewind()

読み込むポインタをデータの始めに巻き戻します。次に readframes() を使用すると、データの始めから読み込みます。

aifc.setpos(pos)

指定したフレーム数の位置にポインタを設定します。

aifc.tell()

現在のポインタのフレーム位置を返します。

aifc.close()

AIFFファイルを閉じます。このメソッドを呼び出したあとでは、オブジェクトはもう使用できません。

ファイルが open() によって書き込み用に開かれたときに返されるオブジェクトには、 readframes() と setpos() を除く上述の全てのメソッドがあります。さらに以下のメソッドが定義されています。 get*() メソッドは、対応する set*() を呼び出したあとでのみ呼び出し可能です。最初に writeframes() あるいは writeframesraw() を呼び出す前に、フレーム数を除く全てのパラメータが設定されていなければなりません。

aifc.aiff()

AIFFファイルを作ります。デフォルトではAIFF-Cファイルが作られますが、ファイル名が '.aiff' で終わっていればAIFFファイルが作られます。

aifc.aifc()

AIFF-Cファイルを作ります。デフォルトではAIFF-Cファイルが作られますが、ファイル名が '.aiff' で終わっていればAIFFファイルが作られます。

aifc.setnchannels(nchannels)

オーディオファイルのチャンネル数を設定します。

aifc.setsampwidth(width)

オーディオのサンプルサイズをバイト数で設定します。

aifc.setframerate(rate)

サンプリングレートを1秒あたりのフレーム数で設定します。

aifc.setnframes(nframes)

オーディオファイルに書き込まれるフレーム数を設定します。もしこのパラメータが設定されていなかったり正しくなかったら、ファイルはシークに対応していなければなりません。

aifc.setcomptype(type, name)

圧縮形式を設定します。もし設定しなければ、オーディオデータは圧縮されません。 AIFFファイルは圧縮できません。変数nameは圧縮形式を人に判読可能にしたもので、変数typeは4文字の文字列でなければなりません。現在のところ、以下の圧縮形式がサポートされています： NONE, ULAW, ALAW, G722。

aifc.setparams(nchannels, sampwidth, framerate, com ptype, compname)

上の全パラメータを一度に設定します。引数はそれぞれのパラメータからなるタプルです。つまり、 setparams() の引数として、 getparams() を呼び出した結果を使うことができます。

aifc.setmark(id, pos, name)

指定したID（1以上）、位置、名称でマークを加えます。このメソッドは、 close() の前ならいつでも呼び出すことができます。

aifc.tell()

出力ファイルの現在の書き込み位置を返します。 setmark() との組み合わせで使うと便利です。

aifc.writeframes(data)

出力ファイルにデータを書き込みます。このメソッドは、オーディオファイルのパラメータを設定したあとでのみ呼び出し可能です。

aifc.writeframesraw(data)

オーディオファイルのヘッダ情報が更新されないことを除いて、 writeframes() と同じです。

aifc.close()

AIFFファイルを閉じます。ファイルのヘッダ情報は、オーディオデータの実際のサイズを反映して更新されます。このメソッドを呼び出したあとでは、オブジェクトはもう使用できません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.4. sunau — Sun AUファイルの読み書き

sunau モジュールは、Sun AUサウンドフォーマットへの便利なインターフェースを提供します。このモジュールは、 aifc モジュールや wave モジュールと互換性のあるインターフェースを備えています。

オーディオファイルはヘッダとそれに続くデータから構成されます。ヘッダのフィールドは以下の通りです：

フィールド | 内容
magic word | 4バイト文字列 .snd
header size | infoを含むヘッダのサイズをバイト数で示したもの。
data size | データの物理サイズをバイト数で示したもの。
encoding | オーディオサンプルのエンコード形式。
sample rate | サンプリングレート。
# of channels | サンプルのチャンネル数。
info | オーディオファイルについての説明をASCII文字列で示したもの（null バイトで埋められます）。

infoフィールド以外の全てのヘッダフィールドは4バイトの大きさです。ヘッダフィールドはbig-endianでエンコードされた、計32ビットの符合なし整数です。

sunau モジュールは以下の関数を定義しています：

sunau.open(file, mode)

file が文字列ならその名前のファイルを開き、そうでないならファイルのようにシーク可能なオブジェクトとして扱います。 mode は以下のうちのいずれかです。

'r'

読み込みのみのモード。

'w'

書き込みのみのモード。

読み込み／書き込み両方のモードで開くことはできないことに注意して下さい。

'r' の mode は AU_read オブジェクトを返し、 'w' と 'wb' の mode は AU_write オブジェクトを返します。

sunau.openfp(file, mode)

open() と同義。後方互換性のために残されています。

sunau モジュールは以下の例外を定義しています：

exception sunau.Error

Sun AUの仕様や実装に対する不適切な操作により何か実行不可能となった時に発生するエラー。

sunau モジュールは以下のデータアイテムを定義しています：

sunau.AUDIO_FILE_MAGIC

big-endianで保存された正規のSun AUファイルは全てこの整数で始まります。これは文字列 .snd を整数に変換したものです。

sunau.AUDIO_FILE_ENCODING_MULAW_8

sunau.AUDIO_FILE_ENCODING_LINEAR_8

sunau.AUDIO_FILE_ENCODING_LINEAR_16

sunau.AUDIO_FILE_ENCODING_LINEAR_24

sunau.AUDIO_FILE_ENCODING_LINEAR_32

sunau.AUDIO_FILE_ENCODING_ALAW_8

AUヘッダのencodingフィールドの値で、このモジュールでサポートしているものです。

sunau.AUDIO_FILE_ENCODING_FLOAT

sunau.AUDIO_FILE_ENCODING_DOUBLE

sunau.AUDIO_FILE_ENCODING_ADPCM_G721

sunau.AUDIO_FILE_ENCODING_ADPCM_G722

sunau.AUDIO_FILE_ENCODING_ADPCM_G723_3

sunau.AUDIO_FILE_ENCODING_ADPCM_G723_5

AUヘッダのencodingフィールドの値のうち既知のものとして追加されているものですが、このモジュールではサポートされていません。

21.4.1. AU_read オブジェクト

上述の open() によって返されるAU_readオブジェクトには、以下のメソッドがあります：

AU_read.close()

ストリームを閉じ、このオブジェクトのインスタンスを使用できなくします。（これはオブジェクトのガベージコレクション時に自動的に呼び出されます。）

AU_read.getnchannels()

オーディオチャンネル数（モノラルなら 1 、ステレオなら 2 ）を返します。

AU_read.getsampwidth()

サンプルサイズをバイト数で返します。

AU_read.getframerate()

サンプリングレートを返します。

AU_read.getnframes()

オーディオフレーム数を返します。

AU_read.getcomptype()

圧縮形式を返します。 'ULAW', 'ALAW', 'NONE' がサポートされている形式です。

AU_read.getcompname()

getcomptype() を人に判読可能な形にしたものです。上述の形式に対して、それぞれ 'CCITT G.711 u-law', 'CCITT G.711 A-law', 'not compressed' がサポートされています。

AU_read.getparams()

get*() メソッドが返すのと同じ (nchannels,  sampwidth, framerate, nframes, comptype, compname) のタプルを返します。

AU_read.readframes(n)

n 個のオーディオフレームの値を読み込んで、バイトごとに文字に変換した文字列を返します。データはlinear形式で返されます。もし元のデータがu-LAW形式なら、変換されます。

AU_read.rewind()

ファイルのポインタをオーディオストリームの先頭に戻します。

以下の2つのメソッドは共通の”位置”を定義しています。”位置”は他の関数とは独立して実装されています。

AU_read.setpos(pos)

ファイルのポインタを指定した位置に設定します。 tell() で返される値を pos として使用しなければなりません。

AU_read.tell()

ファイルの現在のポインタ位置を返します。返される値はファイルの実際の位置に対して何も操作はしません。

以下の2つのメソッドは aifc モジュールとの互換性のために定義されていますが、何も面白いことはしません。

AU_read.getmarkers()

None を返します。

AU_read.getmark(id)

エラーを発生します。

21.4.2. AU_write オブジェクト

上述の open() によって返されるWave_writeオブジェクトには、以下のメソッドがあります：

AU_write.setnchannels(n)

チャンネル数を設定します。

AU_write.setsampwidth(n)

サンプルサイズを（バイト数で）設定します。

AU_write.setframerate(n)

フレームレートを設定します。

AU_write.setnframes(n)

フレーム数を設定します。あとからフレームが書き込まれるとフレーム数は変更されます。

AU_write.setcomptype(type, name)

圧縮形式とその記述を設定します。 'NONE' と 'ULAW' だけが、出力時にサポートされている形式です。

AU_write.setparams(tuple)

tuple は (nchannels, sampwidth, framerate, nframes, comptype, compname) で、それぞれ set*() のメソッドの値にふさわしいものでなければなりません。全ての変数を設定します。

AU_write.tell()

ファイルの中の現在位置を返します。 AU_read.tell() と AU_read.setpos() メソッドでお断りしたことがこのメソッドにも当てはまります。

AU_write.writeframesraw(data)

nframes の修正なしにオーディオフレームを書き込みます。

AU_write.writeframes(data)

オーディオフレームを書き込んで nframes を修正します。

AU_write.close()

nframes が正しいか確認して、ファイルを閉じます。このメソッドはオブジェクトの削除時に呼び出されます。

writeframes() や writeframesraw() メソッドを呼び出したあとで、どんなパラメータを設定しようとしても不正となることに注意して下さい。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.5. wave — WAVファイルの読み書き

wave モジュールは、WAVサウンドフォーマットへの便利なインターフェイスを提供するモジュールです。

このモジュールは圧縮／展開をサポートしていませんが、モノラル／ステレオには対応しています。

wave モジュールは、以下の関数と例外を定義しています。

wave.open(file[, mode])

file が文字列ならその名前のファイルを開き、そうでないならシーク可能な file like オブジェクトとして扱います。 mode は以下のうちのいずれかです。

'r', 'rb'

読み込みのみのモード。

'w', 'wb'

書き込みのみのモード。

WAVファイルに対して読み込み／書き込み両方のモードで開くことはできないことに注意して下さい。 'r' と 'rb' の mode は Wave_read オブジェクトを返し、 'w' と 'wb' の mode は Wave_write オブジェクトを返します。 mode が省略されていて、ファイルのようなオブジェクトが file として渡されると、 file.mode が mode のデフォルト値として使われます（必要であれば、さらにフラグ 'b' が付け加えられます）。

file like オブジェクトを渡した場合、 wave オブジェクトの close() メソッドを呼び出してもその file like オブジェクトを close しません。 file like オブジェクトの close は呼び出し側の責任になります。

wave.openfp(file, mode)

open() と同義。後方互換性のために残されています。

exception wave.Error

WAVの仕様を犯したり、実装の欠陥に遭遇して何か実行不可能となった時に発生するエラー。

21.5.1. Wave_read オブジェクト

open() によって返される Wave_read オブジェクトには、以下のメソッドがあります：

Wave_read.close()

wave によって開かれていた場合はストリームを閉じ、このオブジェクトのインスタンスを使用できなくします。これはオブジェクトのガベージコレクション時に自動的に呼び出されます。

Wave_read.getnchannels()

オーディオチャンネル数（モノラルなら 1 、ステレオなら 2 ）を返します。

Wave_read.getsampwidth()

サンプルサイズをバイト数で返します。

Wave_read.getframerate()

サンプリングレートを返します。

Wave_read.getnframes()

オーディオフレーム数を返します。

Wave_read.getcomptype()

圧縮形式を返します（ 'NONE' だけがサポートされている形式です）。

Wave_read.getcompname()

getcomptype() を人に判読可能な形にしたものです。通常、 'NONE' に対して 'not compressed' が返されます。

Wave_read.getparams()

get*() メソッドが返すのと同じ (nchannels,  sampwidth, framerate, nframes, comptype, compname) のタプルを返します。

Wave_read.readframes(n)

現在のポインタから n 個のオーディオフレームの値を読み込んで、バイトごとに文字に変換して文字列を返します。

Wave_read.rewind()

ファイルのポインタをオーディオストリームの先頭に戻します。

以下の2つのメソッドは aifc モジュールとの互換性のために定義されていますが、何も面白いことはしません。

Wave_read.getmarkers()

None を返します。

Wave_read.getmark(id)

エラーを発生します。

以下の2つのメソッドは共通の”位置”を定義しています。”位置”は他の関数とは独立して実装されています。

Wave_read.setpos(pos)

ファイルのポインタを指定した位置に設定します。

Wave_read.tell()

ファイルの現在のポインタ位置を返します。

21.5.2. Wave_write オブジェクト

open() によって返される Wave_write オブジェクトには、以下のメソッドがあります：

Wave_write.close()

nframes が正しいか確認して、ファイルが wave によって開かれていた場合は閉じます。このメソッドはオブジェクトがガベージコレクションされるときに呼び出されます。

Wave_write.setnchannels(n)

チャンネル数を設定します。

Wave_write.setsampwidth(n)

サンプルサイズを n バイトに設定します。

Wave_write.setframerate(n)

サンプリングレートを n に設定します。

Wave_write.setnframes(n)

フレーム数を n に設定します。あとからフレームが書き込まれるとフレーム数は変更されます。

Wave_write.setcomptype(type, name)

圧縮形式とその記述を設定します。現在のところ、非圧縮を示す圧縮形式 NONE だけがサポートされています。

Wave_write.setparams(tuple)

tuple は (nchannels, sampwidth, framerate, nframes, comptype, compname) で、それぞれ set*() のメソッドの値にふさわしいものでなければなりません。全ての変数を設定します。

Wave_write.tell()

ファイルの中の現在位置を返します。 Wave_read.tell() と Wave_read.setpos() メソッドでお断りしたことがこのメソッドにも当てはまります。

Wave_write.writeframesraw(data)

nframes の修正なしにオーディオフレームを書き込みます。

Wave_write.writeframes(data)

オーディオフレームを書き込んで nframes を修正します。

writeframes() や writeframesraw() メソッドを呼び出したあとで、どんなパラメータを設定しようとしても不正となることに注意して下さい。そうすると wave.Error を発生します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.6. chunk — IFFチャンクデータの読み込み

このモジュールはEA IFF 85チャンクを使用しているファイルの読み込みのためのインターフェースを提供します。 [1] このフォーマットは少なくとも、Audio Interchange File Format (AIFF/AIFF-C) とReal Media File Format (RMFF)で使われています。 WAVEオーディオファイルフォーマットも厳密に対応しているので、このモジュールで読み込みできます。チャンクは以下の構造を持っています：

Offset値 | 長さ | 内容
0 | 4 | チャンクID
4 | 4 | big- endianで示したチャンクのサイズで、ヘッダは含みません
8 | n | バイトデータで、 n はこれより先のフィールドのサイズ
8 + n | 0 or 1 | n が奇数ならチャンクの整頓のために埋められるバイト

IDはチャンクの種類を識別する4バイトの文字列です。

サイズフィールド（big-endianでエンコードされた32ビット値）は、8バイトのヘッダを含まないチャンクデータのサイズを示します。

普通、IFFタイプのファイルは1個かそれ以上のチャンクからなります。このモジュールで定義される Chunk クラスの使い方として提案しているのは、それぞれのチャンクの始めにインスタンスを作り、終わりに達するまでそのインスタンスから読み取り、その後で新しいインスタンスを作るということです。ファイルの終わりで新しいインスタンスを作ろうとすると、 EOFError の例外が発生して失敗します。

class chunk.Chunk(file[, align, bigendian, inclheader])

チャンクを表現するクラス。引数 file はファイルのようなオブジェクトであることが想定されています。このクラスのインスタンスは一つだけ特別に許可されています。必要とされるメソッドは read() だけです。もし seek() と tell() メソッドが呼び出されて例外を発生させなかったら、これらのメソッドも動作します。これらのメソッドが呼び出されて例外を発生させても、オブジェクトを変化させないようになっています。

省略可能な引数 align がtrueなら、チャンクデータが偶数個で2バイトごとに整頓されていると想定します。もし align がfalseなら、チャンクデータが奇数個になっていると想定します。デフォルト値はtrueです。

もし省略可能な引数 bigendian がfalseなら、チャンクサイズは little-endianであると想定します。この引数の設定はWAVEオーディオファイルで必要です。デフォルト値はtrueです。

もし省略可能な引数 inclheader がtrueなら、チャンクのヘッダから得られるサイズはヘッダのサイズを含んでいると想定します。デフォルト値はfalseです。

Chunk オブジェクトには以下のメソッドが定義されています：

getname()

チャンクの名前（ID）を返します。これはチャンクの始めの4バイトです。

getsize()

チャンクのサイズを返します。

close()

オブジェクトを閉じて、チャンクの終わりまで飛びます。これは元のファイル自体は閉じません。

残りの以下のメソッドは、 close() メソッドを呼び出した後に呼び出すと例外 IOError を発生します。

isatty()

False を返します。

seek(pos[, whence])

チャンクの現在位置を設定します。引数 whence は省略可能で、デフォルト値は 0 （ファイルの絶対位置）です；他に 1 （現在位置から相対的にシークします）と 2 （ファイルの末尾から相対的にシークします）の値を取ります。何も値は返しません。もし元のファイルがシークに対応していなければ、前方へのシークのみが可能です。

tell()

チャンク内の現在位置を返します。

read([size])

チャンクから最大で size バイト（ size バイトを読み込むまで、少なくともチャンクの最後に行き着くまで）読み込みます。もし引数 size が負か省略されたら、チャンクの最後まで全てのデータを読み込みます。バイト値は文字列のオブジェクトとして返されます。チャンクの最後に行き着いたら、空文字列を返します。

skip()

チャンクの最後まで飛びます。さらにチャンクの read() を呼び出すと、 '' が返されます。もしチャンクの内容に興味がないなら、このメソッドを呼び出してファイルポインタを次のチャンクの始めに設定します。

注記

[1]
“EA IFF 85” Standard for Interchange Format Files, Jerry Morrison, Electronic Arts, January 1985.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.7. colorsys — 色体系間の変換

colorsys モジュールは、計算機のディスプレイモニタで使われている RGB (Red Green Blue) 色空間で表された色と、他の 3 種類の色座標系: YIQ, HLS (Hue Lightness Saturation: 色相、彩度、飽和) および HSV (Hue Saturation Value: 色相、彩度、明度) との間の双方向の色値変換を定義します。これらの色空間における色座標系は全て浮動小数点数で表されます。 YIQ 空間では、Y 軸は 0 から 1 ですが、 I および Q 軸は正の値も負の値もとり得ます。他の色空間では、各軸は全て 0 から 1 の値をとります。

参考

色空間に関するより詳細な情報は http://www.poynton.com/ColorFAQ.html と http://www.cambridgeincolour.com/tutorials/color-spaces.htm にあります。

colorsys モジュールでは、以下の関数が定義されています:

colorsys.rgb_to_yiq(r, g, b)

RGB から YIQ に変換します。

colorsys.yiq_to_rgb(y, i, q)

YIQ から RGB に変換します。

colorsys.rgb_to_hls(r, g, b)

RGB から HLS に変換します。

colorsys.hls_to_rgb(h, l, s)

HLS から RGB に変換します。

colorsys.rgb_to_hsv(r, g, b)

RGB から HSV に変換します。

colorsys.hsv_to_rgb(h, s, v)

HSV から RGB に変換します。

サンプルコード:

>>> import colorsys
>>> colorsys.rgb_to_hsv(.3, .4, .2)
(0.25, 0.5, 0.4)
>>> colorsys.hsv_to_rgb(0.25, 0.5, 0.4)
(0.3, 0.4, 0.2)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.8. imghdr — 画像の形式を決定する

imghdr モジュールはファイルやバイトストリームに含まれる画像の形式を決定します。

imghdr モジュールは次の関数を定義しています:

imghdr.what(filename[, h])

filename という名前のファイル内の画像データをテストし、画像形式を表す文字列を返します。オプションの h が与えられた場合は、 filename は無視され、テストするバイトストリームを含んでいると h は仮定されます。

以下に what() からの戻り値とともにリストするように、次の画像形式が認識されます:

Value | Image format
'rgb' | SGI ImgLib Files
'gif' | GIF 87a and 89a Files
'pbm' | Portable Bitmap Files
'pgm' | Portable Graymap Files
'ppm' | Portable Pixmap Files
'tiff' | TIFF Files
'rast' | Sun Raster Files
'xbm' | X Bitmap Files
'jpeg' | JPEG data in JFIF or Exif formats
'bmp' | BMP files
'png' | Portable Network Graphics

バージョン 2.5 で追加: Exif の検出.

この変数に追加することで、あなたは imghdr が認識できるファイル形式のリストを拡張できます:

imghdr.tests

個別のテストを行う関数のリスト。それぞれの関数は二つの引数をとります: バイトストリームとオープンされたファイルのようにふるまうオブジェクト。 what() がバイトストリームとともに呼び出されたときは、ファイルのようにふるまうオブジェクトは None でしょう。

テストが成功した場合は、テスト関数は画像形式を表す文字列を返すべきです。あるいは、失敗した場合は None を返すべきです。

例:

>>> import imghdr
>>> imghdr.what('/tmp/bass.gif')
'gif'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.9. sndhdr — サウンドファイルの識別

sndhdr モジュールには、ファイルに保存されたサウンドデータの形式を識別するのに便利な関数が定義されています。どんな形式のサウンドデータがファイルに保存されているのか識別可能な場合、これらの関数は (type, sampling_rate, channels, frames, bits_per_sample) のタプルを返します。 type はデータの形式を示す文字列で、 'aifc', 'aiff', 'au', 'hcom', 'sndr', 'sndt', 'voc', 'wav', '8svx', 'sb', 'ub', 'ul' のうちの一つです。 sampling_rate は実際のサンプリングレート値で、未知の場合や読み取ることが出来なかった場合は 0 です。同様に、 channels はチャンネル数で、識別できない場合や読み取ることが出来なかった場合は 0 です。 frames はフレーム数で、識別できない場合は -1 です。タプルの最後の要素 bits_per_sample はサンプルサイズを示すビット数ですが、A-LAWなら 'A', u-LAWなら 'U' です。

sndhdr.what(filename)

whathdr() を使って、ファイル filename に保存されたサウンドデータの形式を識別します。識別可能なら上記のタプルを返し、識別できない場合は None を返します。

sndhdr.whathdr(filename)

ファイルのヘッダ情報をもとに、保存されたサウンドデータの形式を識別します。ファイル名は filename で渡されます。識別可能なら上記のタプルを返し、識別できない場合は None を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

21. マルチメディアサービス »

21.10. ossaudiodev — OSS互換オーディオデバイスへのアクセス

バージョン 2.3 で追加.

このモジュールを使うとOSS (Open Sound System) オーディオインターフェースにアクセスできます。 OSSはオープンソースあるいは商用のUnixで広く利用でき、Linux (カーネル 2.4まで) とFreeBSDで標準のオーディオインターフェースです。

参考

Open Sound System Programmer’s Guide [http://www.opensound.com/pguide/oss.pdf]

OSS C API の公式ドキュメント

このモジュールではOSSデバイスドライバーが提供している多くの定数を定義しています; 定数のリストについては Linux や FreeBSDの <sys/soundcard.h> を参照してください。

ossaudiodev では以下の変数と関数を定義しています:

exception ossaudiodev.error

何らかのエラーのときに送出される例外です。引数は何が誤っているかを示す文字列です。

(ossaudiodev が open() 、 write() 、 ioctl() などのシステムコールからエラーを受け取った場合には IOError を送出します。 ossaudiodev が直接エラーを検出した場合には OSSAudioError になります。)

(以前のバージョンとの互換性のため、この例外クラスは ossaudiodev.error としても利用できます。)

ossaudiodev.open([device], mode)

オーディオデバイスを開き、OSSオーディオデバイスオブジェクトを返します。このオブジェクトは read() 、 write() 、 fileno() といったファイル類似オブジェクトのメソッドを数多くサポートしています。 (とはいえ、伝統的な Unix の read/write における意味づけと OSS デバイスの read/write との間には微妙な違いがあります)。また、オーディオ特有の多くのメソッドがあります;メソッドの完全なリストについては下記を参照してください。

device は使用するオーディオデバイスファイルネームです。もしこれが指定されないなら、このモジュールは使うデバイスとして最初に環境変数 AUDIODEV を参照します。見つからなければ /dev/dsp を参照します。

mode は読み出し専用アクセスの場合には 'r' 、書き込み専用 (プレイバック) アクセスの場合には 'w' 、読み書きアクセスの場合には 'rw' にします。多くのサウンドカードは一つのプロセスが一度にレコーダとプレーヤのどちらかしか開けないようにしているため、必要な操作に応じたデバイスだけを開くようにするのがよいでしょう。また、サウンドカードには半二重 (half- duplex) 方式のものがあります: こうしたカードでは、デバイスを読み出しまたは書き込み用に開くことはできますが、両方同時には開けません。

呼び出しの文法が普通と異なることに注意してください: 最初の 引数は省略可能で、2番目が必須です。これは ossaudiodev にとってかわられた古い linuxaudiodev との互換性のためという歴史的な産物です。

ossaudiodev.openmixer([device])

ミキサデバイスを開き、OSSミキサデバイスオブジェクトを返します。 device は使用するミキサデバイスのファイル名です。 device を指定しない場合、モジュールはまず環境変数 AUDIODEV を参照して使用するデバイスを探します。見つからなければ、 /dev/mixer を参照します。

21.10.1. オーディオデバイスオブジェクト

オーディオデバイスに読み書きできるようになるには、まず 3 つのメソッドを正しい順序で呼び出さねばなりません:

setfmt() で出力形式を設定し、

channels() でチャンネル数を設定し、

speed() でサンプリングレートを設定します。

この代わりに setparameters() メソッドを呼び出せば、三つのオーディオパラメタを一度で設定できます。 setparameters() は便利ですが、多くの状況で柔軟性に欠けるでしょう。

open() の返すオーディオデバイスオブジェクトには以下のメソッドおよび(読み出し専用の)属性があります:

oss_audio_device.close()

オーディオデバイスを明示的に閉じます。オーディオデバイスは、読み出しや書き込みが終了したら必ず閉じねばなりません。閉じたオブジェクトを再度開くことはできません。

oss_audio_device.fileno()

デバイスに関連付けられているファイル記述子を返します。

oss_audio_device.read(size)

オーディオ入力から size バイトを読みだし、 Python 文字列型にして返します。多くの Unix デバイスドライバと違い、ブロックデバイスモード (デフォルト) の OSS オーディオデバイスでは、要求した量のデータ全体を取り込むまで read() がブロックします。

oss_audio_device.write(data)

Python 文字列 data の内容をオーディオデバイスに書き込み、書き込まれたバイト数を返します。オーディオデバイスがブロックモード (デフォルト) の場合、常に文字列データ全体を書き込みます (前述のように、これは通常のUnix デバイスの振舞いとは異なります)。デバイスが非ブロックモードの場合、データの一部が書き込まれないことがあります — writeall() を参照してください。

oss_audio_device.writeall(data)

Python文字列の data 全体をオーディオデバイスに書き込みます。オーディオデバイスがデータを受け取れるようになるまで待機し、書き込めるだけのデータを書き込むという操作を、 data を全て書き込み終わるまで繰り返します。デバイスがブロックモード (デフォルト) の場合には、このメソッドは write() と同じです。 writeall() が有用なのは非ブロックモードだけです。実際に書き込まれたデータの量と渡したデータの量は必ず同じになるので、戻り値はありません。

以下のメソッドの各々は ioctl() システムコール一つ一つに対応しています。対応関係ははっきりしています: 例えば、 setfmt() は SNDCTL_DSP_SETFMT ioctl に対応していますし、 sync() は SNDCTL_DSP_SYNC に対応しています (このシンボル名は OSS のドキュメントを参照する時に助けになるでしょう)。根底にある ioctl() が失敗した場合、これらの関数は全て IOError を送出します。

oss_audio_device.nonblock()

デバイスを非ブロックモードにします。いったん非ブロックモードにしたら、ブロックモードは戻せません。

oss_audio_device.getfmts()

サウンドカードがサポートしているオーディオ出力形式をビットマスクで返します。以下はOSSでサポートされているフォーマットの一部です。

フォーマット | 説明
AFMT_MU_LAW | 対数符号化 (Sun の .au 形式や /dev/audio で使われている形式)
AFMT_A_LAW | 対数符号化
AFMT_IMA_ADPCM | Interactive Multimedia Association で定義されている 4:1 圧縮形式
AFMT_U8 | 符号なし 8 ビットオーディオ
AFMT_S16_LE | 符号つき 16 ビットオーディオ、リトルエンディアンバイトオーダ (Intelプロセッサで使われている形式)
AFMT_S16_BE | 符号つき 16 ビットオーディオ、ビッグエンディアンバイトオーダ (68k、PowerPC、Sparcで使われている形式)
AFMT_S8 | 符号つき 8 ビットオーディオ
AFMT_U16_LE | 符号なし 16 ビットリトルエンディアンオーディオ
AFMT_U16_BE | 符号なし 16 ビットビッグエンディアンオーディオ

オーディオ形式の完全なリストは OSS の文書をひもといてください。ただ、ほとんどのシステムは、こうした形式のサブセットしかサポートしていません。古めのデバイスの中には AFMT_U8 だけしかサポートしていないものがあります。現在使われている最も一般的な形式は AFMT_S16_LE です。

oss_audio_device.setfmt(format)

現在のオーディオ形式を format に設定しようと試みます — format については getfmts() のリストを参照してください。実際にデバイスに設定されたオーディオ形式を返します。要求通りの形式でないこともあります。 AFMT_QUERY を渡すと現在デバイスに設定されているオーディオ形式を返します。

oss_audio_device.channels(num_channels)

出力チャネル数を num_channels に設定します。 1 はモノラル、2 はステレオです。いくつかのデバイスでは2つより多いチャンネルを持つものもありますし、ハイエンドなデバイスではモノラルをサポートしないものもあります。デバイスに設定されたチャンネル数を返します。

oss_audio_device.speed(samplerate)

サンプリングレートを1秒あたり samplerate に設定しようと試み、実際に設定されたレートを返します。たいていのサウンドデバイスでは任意のサンプリングレートをサポートしていません。一般的なレートは以下の通りです:

レート | 説明
8000 | /dev/audio のデフォルト
11025 | 会話音声の録音に使われるレート
22050 |
44100 | (サンプルあたり 16 ビットで 2 チャネルの場合) CD 品質のオーディオ
96000 | (サンプル当たり 24 ビットの場合) DVD 品質のオーディオ

oss_audio_device.sync()

サウンドデバイスがバッファ内の全てのデータを再生し終えるまで待機します。 (デバイスを閉じると暗黙のうちに sync() が起こります) OSS のドキュメント上では、 sync() を使うよりデバイスを一度閉じて開き直すよう勧めています。

oss_audio_device.reset()

再生あるいは録音を即座に中止して、デバイスをコマンドを受け取れる状態に戻します。OSSのドキュメントでは、 reset() を呼び出した後に一度デバイスを閉じ、開き直すよう勧めています。

oss_audio_device.post()

ドライバに出力の一時停止 (pause) が起きそうであることを伝え、ドライバが一時停止をより賢く扱えるようにします。短いサウンドエフェクトを再生した直後やユーザ入力待ちの前、またディスク I/O 前などに使うことになるでしょう。

以下のメソッドは、複数の ioctl() を組み合わせたり、 ioctl() と単純な計算を組み合わせたりした便宜用メソッドです。

oss_audio_device.setparameters(format, nchannels, samplerate[, strict=False])

主要なオーディオパラメタ、サンプル形式、チャネル数、サンプルレートを一つのメソッド呼び出しで設定します。 format 、 nchannels および samplerate には、それぞれ setfmt() 、 channels() および speed() と同じやり方で値を設定します。 strict の値が真の場合、 setparameters() は値が実際に要求通りにデバイスに設定されたかどうか調べ、違っていれば OSSAudioError を送出します。実際にデバイスドライバが設定したパラメタ値を表す (format, nchannels, samplerate) からなるタプルを返します (setfmt() 、 channels() および speed() の返す値と同じです)。

以下に例を示します:

(fmt, channels, rate) = dsp.setparameters(fmt, channels, rate)

これは、以下と同等です

fmt = dsp.setfmt(fmt)
channels = dsp.channels(channels)
rate = dsp.rate(channels)

oss_audio_device.bufsize()

ハードウェアのバッファサイズをサンプル数で返します。

oss_audio_device.obufcount()

ハードウェアバッファ上に残っていてまだ再生されていないサンプル数を返します。

oss_audio_device.obuffree()

ブロックを起こさずにハードウェアの再生キューに書き込めるサンプル数を返します。

オーディオデバイスオブジェクトは読み出し専用の属性もサポートしています:

oss_audio_device.closed

デバイスが閉じられたかどうかを示す真偽値です。

oss_audio_device.name

デバイスファイルの名前を含む文字列です。

oss_audio_device.mode

ファイルの I/O モードで、 "r", "rw", "w" のどれかです。

21.10.2. ミキサデバイスオブジェクト

ミキサオブジェクトには、2つのファイル類似メソッドがあります:

oss_mixer_device.close()

すでに開かれているミキサデバイスファイルを閉じます。ファイルを閉じた後でミキサを使おうとすると、 IOError を送出します。

oss_mixer_device.fileno()

開かれているミキサデバイスファイルのファイルハンドルナンバを返します。

以下はオーディオミキシング固有のメソッドです。

oss_mixer_device.controls()

このメソッドは、利用可能なミキサコントロール (SOUND_MIXER_PCM や SOUND_MIXER_SYNTH のように、ミキシングを行えるチャネル) を指定するビットマスクを返します。このビットマスクは利用可能な全てのミキサコントロールのサブセットです — 定数 SOUND_MIXER_* はモジュールレベルで定義されています。例えば、もし現在のミキサオブジェクトがPCM ミキサをサポートしているか調べるには、以下のPythonコードを実行します:

if mixer.controls() & (1 << ossaudiodev.SOUND_MIXER_PCM):
    # PCM is supported
    ... code ...

ほとんどの用途には、 SOUND_MIXER_VOLUME (マスタボリューム) と SOUND_MIXER_PCM コントロールがあれば十分でしょう — とはいえ、ミキサを使うコードを書くときには、コントロールを選ぶ時に柔軟性を持たせるべきです。例えば Gravis Ultrasound には SOUND_MIXER_VOLUME がありません。

oss_mixer_device.stereocontrols()

ステレオミキサコントロールを示すビットマスクを返します。ビットが立っているコントロールはステレオであることを示し、立っていないコントロールはモノラルか、ミキサがサポートしていないコントロールである (どちらの理由かは controls() と組み合わせて使うことで判別できます) ことを示します。

ビットマスクから情報を得る例は関数 controls() のコード例を参照してください。

oss_mixer_device.reccontrols()

録音に使用できるミキサコントロールを特定するビットマスクを返します。ビットマスクから情報を得る例は関数 controls() のコード例を参照してください。

oss_mixer_device.get(control)

指定したミキサコントロールのボリュームを返します。 2 要素のタプル (left_volume,right_volume) を返します。ボリュームの値は 0 (無音) から100 (最大) で示されます。コントロールがモノラルでも2要素のタプルが返されますが、2つの要素の値は同じになります。

不正なコントロールを指定した場合は OSSAudioError を送出します。また、サポートされていないコントロールを指定した場合には IOError を送出します。

oss_mixer_device.set(control, (left, right))

指定したミキサコントロールのボリュームを (left,right) に設定します。 left と right は整数で、0 (無音) から100 (最大) の間で指定せねばなりません。呼び出しに成功すると新しいボリューム値を 2 要素のタプルで返します。サウンドカードによっては、ミキサの分解能上の制限から、指定したボリュームと厳密に同じにはならない場合があります。

不正なコントロールを指定した場合や、指定したボリューム値が範囲外であった場合、 IOError を送出します。

oss_mixer_device.get_recsrc()

現在録音のソースに使われているコントロールを示すビットマスクを返します。

oss_mixer_device.set_recsrc(bitmask)

録音のソースを指定にはこの関数を使ってください。呼び出しに成功すると、新たな録音の (場合によっては複数の) ソースを示すビットマスクを返します; 不正なソースを指定すると IOError を送出します。現在の録音のソースとしてマイク入力を設定するには、以下のようにします:

mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

22. 国際化

この章で解説されるモジュールは、プログラムのメッセージで使用される言語を選択したり、または出力を地域の習慣に従って変更するメカニズムを提供して、言語や地域に依存しないソフトの開発を手助けします。

この章で解説されるモジュールの一覧は:

22.1. gettext — 多言語対応に関する国際化サービス

22.1.1. GNU gettext API

22.1.2. クラスに基づいた API

22.1.2.1. NullTranslations クラス

22.1.2.2. GNUTranslations クラス

22.1.2.3. Solaris メッセージカタログ機構のサポート

22.1.2.4. Catalog コンストラクタ

22.1.3. プログラムやモジュールを国際化する

22.1.3.1. モジュールを地域化する

22.1.3.2. アプリケーションを地域化する

22.1.3.3. 動作中 (on the fly) に言語を切り替える

22.1.3.4. 翻訳処理の遅延解決

22.1.3.5. gettext() vs. lgettext()

22.1.4. 謝辞

22.2. locale — 国際化サービス

22.2.1. ロケールの背景、詳細、ヒント、助言および補足説明

22.2.2. Python 拡張の作者と、Python を埋め込むようなプログラムに関して

22.2.3. メッセージカタログへのアクセス

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

22. 国際化 »

22.1. gettext — 多言語対応に関する国際化サービス

gettext モジュールは、 Python によるモジュールやアプリケーションの国際化 (I18N, I-nternationalizatio-N) および地域化 (L10N, L-ocalizatio-N) サービスを提供します。このモジュールは GNU gettext メッセージカタログへの API と、より高レベルで Python ファイルに適しているクラスに基づいた API の両方をサポートしてます。以下で述べるインタフェースを使うことで、モジュールやアプリケーションのメッセージをある自然言語で記述しておき、翻訳されたメッセージのカタログを与えて他の異なる自然言語の環境下で動作させることができます。

ここでは Python のモジュールやアプリケーションを地域化するためのいくつかのヒントも提供しています。

22.1.1. GNU gettext API

gettext モジュールでは、以下の GNU gettext API に非常に良く似た API を提供しています。この API を使う場合、メッセージ翻訳の影響はアプリケーション全体に及ぼすことになります。アプリケーションが単一の言語しか扱わず、各言語に依存する部分をユーザのロケール情報によって選ぶのなら、ほとんどの場合この方法でやりたいことを実現できます。Python モジュールを地域化していたり、アプリケーションの実行中に言語を切り替えたい場合、おそらくクラスに基づいた API を使いたくなるでしょう。

gettext.bindtextdomain(domain[, localedir])

domain をロケール辞書 localedir に結び付け (bind) ます。具体的には、 gettext は与えられたドメインに対するバイナリ形式の .mo ファイルを、(Unixでは) localedir/language/LC_MESSAGES/domain.mo から探します。ここで languages はそれぞれ環境変数 LANGUAGE 、 LC_ALL 、 LC_MESSAGES 、および LANG の中から検索されます。

localedir が省略されるか None の場合、現在 domain に結び付けられている内容が返されます。 [1]

gettext.bind_textdomain_codeset(domain[, codeset])

domain を codeset に結び付けて、 gettext() ファミリの関数が返す文字列のエンコード方式を変更します。 codeset を省略すると、現在結び付けられているコードセットを返します。

バージョン 2.4 で追加.

gettext.textdomain([domain])

現在のグローバルドメインを調べたり変更したりします。 domain が None の場合、現在のグローバルドメインが返されます。それ以外の場合にはグローバルドメインは domain に設定され、設定されたグローバルドメインを返します。

gettext.gettext(message)

現在のグローバルドメイン、言語、およびロケール辞書に基づいて、 message の特定地域向けの翻訳を返します。通常、ローカルな名前空間ではこの関数に _() という別名をつけます (下の例を参照してください)。

gettext.lgettext(message)

gettext() と同じですが、 bind_textdomain_codeset() で特にエンコードを指定しない限り、翻訳結果を優先システムエンコーディング (preferred system encoding) で返します。

バージョン 2.4 で追加.

gettext.dgettext(domain, message)

gettext() と同様ですが、指定された domain からメッセージを探します。

gettext.ldgettext(message)

dgettext() と同じですが、 bind_textdomain_codeset() で特にエンコードを指定しない限り、翻訳結果を優先システムエンコーディング (preferred system encoding) で返します。

バージョン 2.4 で追加.

gettext.ngettext(singular, plural, n)

gettext() と同様ですが、複数形の場合を考慮しています。翻訳文字列が見つかった場合、 n の様式を適用し、その結果得られたメッセージを返します (言語によっては二つ以上の複数形があります)。翻訳文字列が見つからなかった場合、 n が 1 なら singular を返します; そうでない場合 plural を返します。

複数形の様式はカタログのヘッダから取り出されます。様式は C または Python の式で、自由な変数 n を持ちます; 式の評価値はカタログ中の複数形のインデクスとなります。 .po ファイルで用いられる詳細な文法と、様々な言語における様式については、GNU gettext ドキュメントを参照してください。

バージョン 2.3 で追加.

gettext.lngettext(message)

ngettext() と同じですが、 bind_textdomain_codeset() で特にエンコードを指定しない限り、翻訳結果を優先システムエンコーディング (preferred system encoding) で返します。

バージョン 2.4 で追加.

gettext.dngettext(domain, singular, plural, n)

ngettext() と同様ですが、指定された domain からメッセージを探します。

バージョン 2.3 で追加.

gettext.ldngettext(message)

dngettext() と同じですが、 bind_textdomain_codeset() で特にエンコードを指定しない限り、翻訳結果を優先システムエンコーディング (preferred system encoding) で返します。

バージョン 2.4 で追加.

GNU gettext では dcgettext() も定義していますが、このメソッドはあまり有用ではないと思われるので、現在のところ実装されていません。

以下にこの API の典型的な使用法を示します:

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')

22.1.2. クラスに基づいた API

クラス形式の gettext モジュールのAPI は GNU gettext API よりも高い柔軟性と利便性を持っています。 Python のアプリケーションやモジュールを地域化するにはこちらを使う方を勧めます。 gettext では、GNU .mo 形式のファイルを解釈し、標準の 8 ビット文字列または Unicode 文字列形式でメッセージを返す “翻訳” クラスを定義しています。この “翻訳” クラスのインスタンスも、組み込み名前空間に関数 _() として組みこみ (install) できます。

gettext.find(domain[, localedir[, languages[, all]]])

この関数は標準的な .mo ファイル検索アルゴリズムを実装しています。 textdomain() と同じく、 domain を引数にとります。オプションの localedir は bindtextdomain() と同じです。またオプションの languages は文字列を列挙したリストで、各文字列は言語コードを表します。

localedir が与えられていない場合、標準のシステムロケールディレクトリが使われます。 [2]

languages が与えられなかった場合、以下の環境変数: LANGUAGE 、 LC_ALL 、 LC_MESSAGES 、および LANG が検索されます。空でない値を返した最初の候補が languages 変数として使われます。この環境変数は言語名をコロンで分かち書きしたリストを含んでいなければなりません。 find() はこの文字列をコロンで分割し、言語コードの候補リストを生成します。

find() は次に言語コードを展開および正規化し、リストの各要素について、以下のパス構成:

localedir/language/LC_MESSAGES/domain.mo

からなる実在するファイルの探索を反復的に行います。 find() は上記のような実在するファイルで最初に見つかったものを返します。該当するファイルが見つからなかった場合、 None が返されます。 all が与えられていれば、全ファイル名のリストが言語リストまたは環境変数で指定されている順番に並べられたものを返します。

gettext.translation(domain[, localedir[, languages[, class_[, fallback[, codeset]]]]])

Translations インスタンスを domain 、 localedir 、および languages に基づいて生成して返します。 domain 、 localedir 、および languages はまず関連付けられている .mo ファイルパスのリストを取得するために find() に渡されます。同じ .mo ファイル名を持つインスタンスはキャッシュされます。実際にインスタンス化されるクラスは class_ が与えられていればそのクラスが、そうでない時には GNUTranslations です。クラスのコンストラクタは単一の引数としてファイルオブジェクトを取らなくてはなりません。 codeset を指定した場合、翻訳文字列のエンコードに使う文字セットを変更します。

複数のファイルが発見された場合、後で見つかったファイルは前に見つかったファイルの代替でと見なされ、後で見つかった方が利用されます。代替の設定を可能にするには、 copy.copy() を使ってキャッシュから翻訳オブジェクトを複製します; こうすることで、実際のインスタンスデータはキャッシュのものと共有されます。

.mo ファイルが見つからなかった場合、 fallback が偽 (標準の設定です) ならこの関数は IOError を送出し、 fallback が真なら NullTranslations インスタンスが返されます。

バージョン 2.4 で変更: codeset パラメタを追加しました.

gettext.install(domain[, localedir[, unicode[, codeset[, names]]]])

translation() に domain 、 localedir 、および codeset を渡してできる関数 _() を Python の組み込み名前空間に組み込みます。 unicode フラグは translation() の返す翻訳オブジェクトの install() メソッドに渡されます。

names パラメタについては、翻訳オブジェクトの install() メソッドの説明を参照ください。

以下に示すように、通常はアプリケーション中の文字列を関数 _() の呼び出しで包み込んで翻訳対象候補であることを示します:

print _('This string will be translated.')

利便性を高めるためには、 _() 関数を Python の組み込み名前空間に組み入れる必要があります。こうすることで、アプリケーション内の全てのモジュールからアクセスできるようになります。

バージョン 2.4 で変更: codeset パラメタを追加しました.

バージョン 2.5 で変更: names パラメタを追加しました.

22.1.2.1. NullTranslations クラス

翻訳クラスは、元のソースファイル中のメッセージ文字列から翻訳されたメッセージ文字列への変換を実際に実装しているクラスです。全ての翻訳クラスが基底クラスとして用いるクラスが NullTranslations です; このクラスでは独自の特殊な翻訳クラスを実装するために使うことができる基本的なインタフェースを以下に NullTranslations のメソッドを示します:

class gettext.NullTranslations([fp])

オプションのファイルオブジェクト fp を取ります。この引数は基底クラスでは無視されます。このメソッドは “保護された (protected)” インスタンス変数 _info および _charset を初期化します。これらの変数の値は派生クラスで設定することができます。同様に _fallback も初期化しますが、この値は add_fallback() で設定されます。その後、 fp が None でない場合 self._parse(fp) を呼び出します。

_parse(fp)

基底クラスでは何もしない (no-op) ようになっています。このメソッドの役割はファイルオブジェクト fp を引数に取り、ファイルからデータを読み出し、メッセージカタログを初期化することです。サポートされていないメッセージカタログ形式を使っている場合、その形式を解釈するためにはこのメソッドを上書きしなくてはなりません。

add_fallback(fallback)

fallback を現在の翻訳オブジェクトの代替オブジェクトとして追加します。翻訳オブジェクトが与えられたメッセージに対して翻訳メッセージを提供できない場合、この代替オブジェクトに問い合わせることになります。

gettext(message)

代替オブジェクトが設定されている場合、 gettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを返します。派生クラスで上書きするメソッドです。

lgettext(message)

代替オブジェクトが設定されている場合、 lgettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを返します。派生クラスで上書きするメソッドです。

バージョン 2.4 で追加.

ugettext(message)

代替オブジェクトが設定されている場合、 gettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを Unicode 文字列で返します。派生クラスで上書きするメソッドです。

ngettext(singular, plural, n)

代替オブジェクトが設定されている場合、 ngettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを返します。派生クラスで上書きするメソッドです。

バージョン 2.3 で追加.

lngettext(singular, plural, n)

代替オブジェクトが設定されている場合、 lngettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを返します。派生クラスで上書きするメソッドです。

バージョン 2.4 で追加.

ungettext(singular, plural, n)

代替オブジェクトが設定されている場合、 ungettext() を代替オブジェクトに転送します。そうでない場合、翻訳されたメッセージを Unicode 文字列で返します。派生クラスで上書きするメソッドです。

バージョン 2.3 で追加.

info()

“protected” の _info 変数を返します。

charset()

“protected” の _charset 変数を返します。

output_charset()

翻訳メッセージとして返す文字列のエンコードを決める、 “protected” の _output_charset 変数を返します。

バージョン 2.4 で追加.

set_output_charset(charset)

翻訳メッセージとして返す文字列のエンコードを決める、 “protected” の変数 _output_charset を変更します。

バージョン 2.4 で追加.

install([unicode[, names]])

unicode フラグが偽の場合、このメソッドは self.gettext() を組み込み名前空間に組み入れ、 _ と結び付けます。 unicode が真の場合、 self.gettext() の代わりに self.ugettext() を結び付けます。標準では unicode は偽です。

names パラメタには、 _() 以外に組み込みの名前空間にインストールしたい関数名のシーケンスを指定します。サポートしている名前は 'gettext' (unicode フラグの設定に応じて self.gettext() あるいは self.ugettext() のいずれかに対応します)、 'ngettext' (unicode フラグの設定に応じて self.ngettext() あるいは self.ungettext() のいずれかに対応します)、 'lgettext' および 'lngettext' です。

この方法はアプリケーションで _() 関数を利用できるようにするための最も便利な方法ですが、唯一の手段でもあるので注意してください。この関数はアプリケーション全体、とりわけ組み込み名前空間に影響するので、地域化されたモジュールで _() を組み入れることができないのです。その代わりに、以下のコード:

import gettext
t = gettext.translation('mymodule', ...)
_ = t.gettext

を使って _() を使えるようにしなければなりません。

この操作は _() をモジュール内だけのグローバル名前空間に組み入れるので、モジュール内の _() の呼び出しだけに影響します。

バージョン 2.5 で変更: names パラメタを追加しました.

22.1.2.2. GNUTranslations クラス

gettext モジュールでは NullTranslations から派生したもう一つのクラス: GNUTranslations を提供しています。このクラスはビッグエンディアン、およびリトルエンディアン両方のバイナリ形式の GNU gettext .mo ファイルを読み出せるように _parse() を上書きしています。また、このクラスはメッセージ id とメッセージ文字列の両方を Unicode に型強制します。

このクラスではまた、翻訳カタログ以外に、オプションのメタデータを読み込んで解釈します。GNU gettext では、空の文字列に対する変換先としてメタデータを取り込むことが慣習になっています。このメタデータは RFC 822 [http://tools.ietf.org/html/rfc822.html] 形式の key: value のペアになっており、 Project-Id-Version キーを含んでいなければなりません。キー Content-Type があった場合、 charset の特性値 (property) は “保護された” _charset インスタンス変数を初期化するために用いられます。値がない場合には、デフォルトとして None が使われます。エンコードに用いられる文字セットが指定されている場合、カタログから読み出された全てのメッセージ id とメッセージ文字列は、指定されたエンコードを用いて Unicode に変換されます。 ugettext() は常に Unicode を返し、 gettext() はエンコードされた 8 ビット文字列を返します。どちらのメソッドにおける引数 id の場合も、Unicode 文字列か US-ASCII 文字のみを含む 8 ビット文字列だけが受理可能です。国際化されたPython プログラムでは、メソッドの Unicode 版 (すなわち ugettext() や ungettext()) の利用が推奨されています。

key/value ペアの集合全体は辞書型データ中に配置され、”保護された” _info インスタンス変数に設定されます。

.mo ファイルのマジックナンバーが不正な場合、あるいはその他の問題がファイルの読み出し中に発生した場合、 GNUTranslations クラスのインスタンス化で IOError が送出されることがあります。

以下のメソッドは基底クラスの実装からオーバライドされています:

GNUTranslations.gettext(message)

カタログから message id を検索して、対応するメッセージ文字列を、カタログの文字セットが既知のエンコードの場合、エンコードされた 8 ビット文字列として返します。 message id に対するエントリがカタログに存在せず、フォールバックが設定されている場合、フォールバック検索はオブジェクトの gettext() メソッドに転送されます。そうでない場合、 message id 自体が返されます。

GNUTranslations.ugettext(message)

カタログから message id を検索して、対応するメッセージ文字列を、 Unicode でエンコードして返します。 message id に対するエントリがカタログに存在せず、フォールバックが設定されている場合、フォールバック検索はオブジェクトの ugettext() メソッドに転送されます。そうでない場合、 message id 自体が返されます。

GNUTranslations.ngettext(singular, plural, n)

メッセージ id に対する複数形を検索します。カタログに対する検索では singular がメッセージ id として用いられ、 n にはどの複数形を用いるかを指定します。返されるメッセージ文字列は 8 ビットの文字列で、カタログの文字セットが既知の場合にはその文字列セットでエンコードされています。

メッセージ id がカタログ中に見つからず、フォールバックオブジェクトが指定されている場合、メッセージ検索要求はフォールバックオブジェクトの ngettext() メソッドに転送されます。そうでない場合、 n が 1 ならば singular が返され、それ以外に対しては plural が返されます。

バージョン 2.3 で追加.

GNUTranslations.ungettext(singular, plural, n)

メッセージ id に対する複数形を検索します。カタログに対する検索では singular がメッセージ id として用いられ、 n にはどの複数形を用いるかを指定します。返されるメッセージ文字列は Unicode 文字列です。

メッセージ id がカタログ中に見つからず、フォールバックオブジェクトが指定されている場合、メッセージ検索要求はフォールバックオブジェクトの ungettext() メソッドに転送されます。そうでない場合、 n が 1 ならば singular が返され、それ以外に対しては plural が返されます。

以下に例を示します。:

n = len(os.listdir('.'))
cat = GNUTranslations(somefile)
message = cat.ungettext(
    'There is %(num)d file in this directory',
    'There are %(num)d files in this directory',
    n) % {'num': n}

バージョン 2.3 で追加.

22.1.2.3. Solaris メッセージカタログ機構のサポート

Solaris オペレーティングシステムでは、独自の .mo バイナリファイル形式を定義していますが、この形式に関するドキュメントが手に入らないため、現時点ではサポートされていません。

22.1.2.4. Catalog コンストラクタ

GNOME では、James Henstridge によるあるバージョンの gettext モジュールを使っていますが、このバージョンは少し異なった API を持っています。ドキュメントに書かれている利用法は:

import gettext
cat = gettext.Catalog(domain, localedir)
_ = cat.gettext
print _('hello world')

となっています。過去のモジュールとの互換性のために、 Catalog() は前述の translation() 関数の別名になっています。

このモジュールと Henstridge のバージョンとの間には一つ相違点があります: 彼のカタログオブジェクトはマップ型の API を介したアクセスがサポートされていましたが、この API は使われていないらしく、現在はサポートされていません。

22.1.3. プログラムやモジュールを国際化する

国際化 (I18N, I-nternationalizatio-N) とは、プログラムを複数の言語に対応させる操作を指します。地域化 (L10N, L-ocalizatio-N) とは、すでに国際化されているプログラムを特定地域の言語や文化的な事情に対応させることを指します。Python プログラムに多言語メッセージ機能を追加するには、以下の手順を踏む必要があります:

プログラムやモジュールで翻訳対象とする文字列に特殊なマークをつけて準備します

マークづけをしたファイルに一連のツールを走らせ、生のメッセージカタログを生成します

特定の言語へのメッセージカタログの翻訳を作成します

メッセージ文字列を適切に変換するために gettext モジュールを使います

ソースコードを I18N 化する準備として、ファイル内の全ての文字列を探す必要があります。翻訳を行う必要のある文字列はどれも _('...') — すなわち関数 _() の呼び出しで包むことでマーク付けしなくてはなりません。例えば以下のようにします:

filename = 'mylog.txt'
message = _('writing a log message')
fp = open(filename, 'w')
fp.write(message)
fp.close()

この例では、文字列 'writing a log message' が翻訳対象候補としてマーク付けされており、文字列 'mylog.txt' および 'w' はされていません。

Python の配布物には、ソースコードに準備作業を行った後でメッセージカタログの生成を助ける 2 つのツールが付属します。これらはバイナリ配布の場合には付属していたりしなかったりしますが、ソースコード配布には入っており、 Tools/i18n ディレクトリにあります。

pygettext プログラム [3] は全ての Python ソースコードを走査し、予め翻訳対象としてマークした文字列を探し出します。このツールは GNU gettext プログラムと同様ですが、Python ソースコードの機微について熟知している反面、C 言語や C++言語のソースコードについては全く知りません。(C 言語による拡張モジュールのように) C 言語のコードも翻訳対象にしたいのでない限り、 GNU gettext は必要ありません。

pygettext は、テキスト形式 Uniforum スタイルによる人間が判読可能なメッセージカタログ .pot ファイル群を生成します。このファイル群はソースコード中でマークされた全ての文字列と、それに対応する翻訳文字列のためのプレースホルダを含むファイルで構成されています。 pygettext はコマンドライン形式のスクリプトで、 xgettext と同様のコマンドラインインタフェースをサポートします; 使用法についての詳細を見るには:

pygettext.py --help

を起動してください。

これら .pot ファイルのコピーは次に、サポート対象の各自然言語について、言語ごとのバージョンを作成する個々の人間の翻訳者に頒布されます。翻訳者たちはプレースホルダ部分を埋めて言語ごとのバージョンをつくり、 .po ファイルとして返します。(Tools/i18n ディレクトリ内の) msgfmt.py [4] プログラムを使い、翻訳者から返された .po ファイルから機械可読な .mo バイナリカタログファイルを生成します。 .mo ファイルは、 gettext モジュールが実行時に実際の翻訳処理を行うために使われます。

gettext モジュールをソースコード中でどのように使うかは単一のモジュールを国際化するのか、それともアプリケーション全体を国際化するのかによります。次のふたつのセクションで、それぞれについて説明します。

22.1.3.1. モジュールを地域化する

モジュールを地域化する場合、グローバルな変更、例えば組み込み名前空間への変更を行わないように注意しなければなりません。GNU gettext API ではなく、クラスベースの API を使うべきです。

仮に対象のモジュール名を “spam” とし、モジュールの各言語における翻訳が収められた .mo ファイルが /usr/share/locale に GNU gettext 形式で置かれているとします。この場合、モジュールの最初で以下のようにします:

import gettext
t = gettext.translation('spam', '/usr/share/locale')
_ = t.lgettext

翻訳オブジェクトが .po ファイル中の Unicode 文字列を返すようになっているのなら、上の代わりに以下のようにします:

import gettext
t = gettext.translation('spam', '/usr/share/locale')
_ = t.ugettext

22.1.3.2. アプリケーションを地域化する

アプリケーションを地域化するのなら、関数 _() をグローバルな組み込み名前空間に組み入れなければならず、これは通常アプリケーションの主ドライバ (main driver) ファイルで行います。この操作によって、アプリケーション独自のファイルは明示的に各ファイルで _() の組み入れを行わなくても単に _('...') を使うだけで済むようになります。

単純な場合では、単に以下の短いコードをアプリケーションの主ドライバファイルに追加するだけです:

import gettext
gettext.install('myapplication')

ロケールディレクトリや unicode フラグを設定する必要がある場合、それらの値を install() 関数に渡すことができます:

import gettext
gettext.install('myapplication', '/usr/share/locale', unicode=1)

22.1.3.3. 動作中 (on the fly) に言語を切り替える

多くの言語を同時にサポートする必要がある場合、複数の翻訳インスタンスを生成して、例えば以下のコード:

import gettext

lang1 = gettext.translation('myapplication', languages=['en'])
lang2 = gettext.translation('myapplication', languages=['fr'])
lang3 = gettext.translation('myapplication', languages=['de'])

# start by using language1
lang1.install()

# ... time goes by, user selects language 2
lang2.install()

# ... more time goes by, user selects language 3
lang3.install()

のように、インスタンスを明示的に切り替えてもかまいません。

22.1.3.4. 翻訳処理の遅延解決

コードを書く上では、ほとんどの状況で文字列はコードされた場所で翻訳されます。しかし場合によっては、翻訳対象として文字列をマークはするが、その後実際に翻訳が行われるように遅延させる必要が生じます。古典的な例は以下のようなコートです:

animals = ['mollusk',
           'albatross',
           'rat',
           'penguin',
           'python', ]
# ...
for a in animals:
    print a

ここで、リスト animals 内の文字列は翻訳対象としてマークはしたいが、文字列が出力されるまで実際に翻訳を行うのは避けたいとします。

こうした状況を処理する一つの方法を以下に示します:

def _(message): return message

animals = [_('mollusk'),
           _('albatross'),
           _('rat'),
           _('penguin'),
           _('python'), ]

del _

# ...
for a in animals:
    print _(a)

ダミーの _() 定義が単に文字列をそのまま返すようになっているので、上のコードはうまく動作します。かつ、このダミーの定義は、組み込み名前空間に置かれた _() の定義で (del 命令を実行するまで) 一時的に上書きすることができます。もしそれまでに _() をローカルな名前空間に持っていたら注意してください。

二つ目の例における _() の使い方では、”a” は文字列リテラルではないので、 pygettext プログラムが翻訳可能な対象として識別しません。

もう一つの処理法は、以下の例のようなやり方です:

def N_(message): return message

animals = [N_('mollusk'),
           N_('albatross'),
           N_('rat'),
           N_('penguin'),
           N_('python'), ]

# ...
for a in animals:
    print _(a)

この例の場合では、翻訳可能な文字列を関数 N_() でマーク付けしており [5] 、 _() の定義とは全く衝突しません。しかしメッセージ展開プログラムには翻訳対象の文字列が N_() でマークされていることを教える必要が出てくるでしょう。 pygettext および xpot は両方とも、コマンドライン上のスイッチでこの機能をサポートしています。

22.1.3.5. gettext() vs. lgettext()

Python 2.4 からは、 lgettext() ファミリが導入されました。この関数の目的は、現行の GNU gettext 実装によりよく準拠した別の関数を提供することにあります。翻訳メッセージファイル中で使われているのと同じコードセットを使って文字列をエンコードして返す gettext() と違い、これらの関数は locale.getpreferredencoding() の返す優先システムエンコーディングを使って翻訳メッセージ文字列をエンコードして返します。また、Python 2.4 では、翻訳メッセージ文字列で使われているコードセットを明示的に選べるようにする関数が新たに導入されていることにも注意してください。コードセットを明示的に設定すると、 lgettext() でさえ、指定したコードセットで翻訳メッセージ文字列を返します。これは GNU gettext 実装が期待している仕様と同じです。

22.1.4. 謝辞

以下の人々が、このモジュールのコード、フィードバック、設計に関する助言、過去の実装、そして有益な経験談による貢献をしてくれました:

Peter Funk

James Henstridge

Juan David Ibáñez Palomar

Marc-André Lemburg

Martin von Löwis

François Pinard

Barry Warsaw

注記

[1]
標準でロケールが収められているディレクトリはシステム依存です; 例えば、RedHat Linux では /usr/share/locale ですが、 Solaris では /usr/lib/locale です。 gettext モジュールはこうしたシステム依存の標準設定をサポートしません; その代わりに sys.prefix/share/locale を標準の設定とします。この理由から、常にアプリケーションの開始時に絶対パスで明示的に指定して bindtextdomain() を呼び出すのが最良のやり方ということになります。

[2]
上の bindtextdomain() に関する脚注を参照してください。

[3]
同様の作業を行う xpot と呼ばれるプログラムを François Pinard が書いています。このプログラムは彼の po-utils パッケージの一部で、 http://po-utils.progiciels-bpi.ca/ で入手できます。

[4]
msgfmt.py は GNU msgfmt とバイナリ互換ですが、より単純で、Python だけを使った実装がされています。このプログラムと pygettext.py があれば、通常 Python プログラムを国際化するために GNU gettext パッケージをインストールする必要はありません。

[5]
この N_() をどうするかは全くの自由です; MarkThisStringForTranslation() などとしてもかまいません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

22. 国際化 »

22.2. locale — 国際化サービス

locale モジュールは POSIX ロケールデータベースおよびロケール関連機能へのアクセスを提供します。 POSIX ロケール機構を使うことで、プログラマはソフトウェアが実行される各国における詳細を知らなくても、アプリケーション上で特定の地域文化に関係する部分を扱うことができます。

locale モジュールは、 _locale を被うように実装されており、ANSI C ロケール実装を使っている _locale が利用可能なら、こちらを先に使うようになっています。

locale モジュールでは以下の例外と関数を定義しています:

exception locale.Error

setlocale() が失敗したときに送出される例外です。

locale.setlocale(category[, locale])

locale を指定する場合、文字列、 (language code, encoding) 、からなるタプル、または None をとることができます。 locale がタプルのの場合、ロケール別名解決エンジンによって文字列に変換されます。 locale が与えられていて、かつ None でない場合、 setlocale() は category の設定を変更します。変更することのできるカテゴリは以下に列記されており、値はロケール設定の名前です。空の文字列を指定すると、ユーザの環境における標準設定になります。ロケールの変更に失敗した場合、 Error が送出されます。成功した場合、新たなロケール設定が返されます。

locale が省略されたり None の場合、 category の現在の設定が返されます。

setlocale() はほとんどのシステムでスレッド安全ではありません。アプリケーションを書くとき、大抵は以下のコード

import locale
locale.setlocale(locale.LC_ALL, '')

から書き始めます。これは全てのカテゴリをユーザの環境における標準設定 (大抵は環境変数 LANG で指定されています) に設定します。その後複数スレッドを使ってロケールを変更したりしない限り、問題は起こらないはずです。

バージョン 2.0 で変更: 引数 locale の値としてタプルをサポートしました。

locale.localeconv()

地域的な慣行のデータベースを辞書として返します。辞書は以下の文字列をキーとして持っています:

カテゴリ | キー名 | 意味
LC_NUMERIC | 'decimal_point' | 小数点を表す文字です。
| 'grouping' | 'thousands_sep' が来るかもしれない場所を相対的に表した数からなる配列です。配列が CHAR_MAX で終端されている場合、それ以上の桁では桁数字のグループ化を行いません。配列が 0 で終端されている場合、最後に指定したグループが反復的に使われます。
| 'thousands_sep' | 桁グループ間を区切るために使われる文字です。
LC_MONETARY | 'int_curr_symbol' | 国際通貨を表現する記号です。
| 'currency_symbol' | 地域的な通貨を表現する記号です。
| 'p_cs_precedes/n_cs_precedes' | 通貨記号が値の前につくかどうかです (それぞれ正の値、負の値を表します)。
| 'p_sep_by_space/n_sep_by_space' | 通貨記号と値との間にスペースを入れるかどうかです (それぞれ正の値、負の値を表します)。
| 'mon_decimal_point' | 金額表示の際に使われる小数点です。
| 'frac_digits' | 金額を地域的な方法で表現する際の小数点以下の桁数です。
| 'int_frac_digits' | 金額を国際的な方法で表現する際の小数点以下の桁数です。
| 'mon_thousands_sep' | 金額表示の際に桁区切り記号です。
| 'mon_grouping' | 'grouping' と同じで、金額表示の際に使われます。
| 'positive_sign' | 正の値の金額表示に使われる記号です。
| 'negative_sign' | 負の値の金額表示に使われる記号です。
| 'p_sign_posn/n_sign_posn' | 符号の位置です (それぞれ正の値と負の値を表します)。以下を参照ください。

数値形式の値に CHAR_MAX を設定すると、そのロケールでは値が指定されていないことを表します。

'p_sign_posn' および 'n_sing_posn' の取り得る値は以下の通りです。

値 | 説明
0 | 通貨記号および値は丸括弧で囲われます。
1 | 符号は値と通貨記号より前に来ます。
2 | 符号は値と通貨記号の後に続きます。
3 | 符号は値の直前に来ます。
4 | 符号は値の直後に来ます。
CHAR_MAX | このロケールでは特に指定しません。

locale.nl_langinfo(option)

ロケール特有の情報を文字列として返します。この関数は全てのシステムで利用可能なわけではなく、指定できる option もプラットフォーム間で大きく異なります。引数として使えるのは、locale モジュールで利用可能なシンボル定数を表す数字です。

関数 nl_langinfo() は以下のキーのうち一つを受理します。ほとんどの記述は GNU C ライブラリ中の対応する説明から引用されています。

locale.CODESET

選択されたロケールで用いられている文字エンコーディングの名前を文字列で取得します。

locale.D_T_FMT

日付と時刻をロケール特有の方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.D_FMT

日付をロケール特有の方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.T_FMT

時刻をロケール特有の方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.T_FMT_AMPM

時刻を午前／午後の書式で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

DAY_1 ... DAY_7

1 週間中の n 番目の曜日名を取得します。

ノート

ロケール US における、 DAY_1 を日曜日とする慣行に従っています。国際的な (ISO 8601) 月曜日を週の初めとする慣行ではありません。

ABDAY_1 ... ABDAY_7

1 週間中の n 番目の曜日名を略式表記で取得します。

MON_1 ... MON_12

n 番目の月の名前を取得します。

ABMON_1 ... ABMON_12

n 番目の月の名前を略式表記で取得します。

locale.RADIXCHAR

基数点 (小数点ドット、あるいは小数点コンマ、等) を取得します。

locale.THOUSEP

1000 単位桁区切り (3 桁ごとのグループ化) の区切り文字を取得します。

locale.YESEXPR

肯定／否定で答える質問に対する肯定回答を正規表現関数で認識するために利用できる正規表現を取得します。

ノート

表現は C ライブラリの regex() 関数に合ったものでなければならず、これは re で使われている構文とは異なるかもしれません。

locale.NOEXPR

肯定／否定で答える質問に対する否定回答を正規表現関数で認識するために利用できる正規表現を取得します。

locale.CRNCYSTR

通貨シンボルを取得します。シンボルを値の前に表示させる場合には “-” 、値の後ろに表示させる場合には “+” 、シンボルを基数点と置き換える場合には ”.” を前につけます。

locale.ERA

現在のロケールで使われている年代を表現する値を取得します。

ほとんどのロケールではこの値を定義していません。この値を設定しているロケールの例は日本です。日本では、日付の伝統的な表示法に、時の天皇に対応する元号名を含めます。

通常この値を直接指定する必要はありません。 E を書式化文字列に指定することで、関数 strftime() がこの情報を使うようになります。返される文字列の様式は決められていないので、異なるシステム間で様式に関する同じ知識が使えると期待してはいけません。

locale.ERA_D_T_FMT

日付および時間をロケール固有の年代に基づいた方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.ERA_D_FMT

日付をロケール固有の年代に基づいた方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.ERA_T_FMT

時刻をロケール固有の年代に基づいた方法で表現するために、 strftime() の書式化文字列として用いることのできる文字列を取得します。

locale.ALT_DIGITS

返される値は 0 から 99 までの 100 個の値の表現です。

locale.getdefaultlocale([envvars])

標準のロケール設定を取得しようと試み、結果をタプル (language code, encoding) の形式で返します。 POSIXによると、 setlocale(LC_ALL, '') を呼ばなかったプログラムは、移植可能な 'C' ロケール設定を使います。 setlocale(LC_ALL, '') を呼ぶことで、 LANG 変数で定義された標準のロケール設定を使うようになります。 Python では現在のロケール設定に干渉したくないので、上で述べたような方法でその挙動をエミュレーションしています。

他のプラットフォームとの互換性を維持するために、環境変数 LANG だけでなく、引数 envvars で指定された環境変数のリストも調べられます。 envvars は標準では GNU gettext で使われているサーチパスになります; パスには必ず変数名 LANG が含まれているからです。GNU gettext サーチパスは 'LANGUAGE' 、 'LC_ALL' 、 'LC_CTYPE' 、および 'LANG' が列挙した順番に含まれています。

'C' の場合を除き、言語コードは RFC 1766 [http://tools.ietf.org/html/rfc1766.html] に対応します。 language code および encoding が決定できなかった場合、 None になるかもしれません。

バージョン 2.0 で追加.

locale.getlocale([category])

与えられたロケールカテゴリに対する現在の設定を、 language code 、 encoding を含むシーケンスで返します。 category として LC_ALL 以外の LC_* の値の一つを指定できます。標準の設定は LC_CTYPE です。

'C' の場合を除き、言語コードは RFC 1766 [http://tools.ietf.org/html/rfc1766.html] に対応します。 language code および encoding が決定できなかった場合、 None になるかもしれません。

バージョン 2.0 で追加.

locale.getpreferredencoding([do_setlocale])

テキストデータをエンコードする方法を、ユーザの設定に基づいて返します。ユーザの設定は異なるシステム間では異なった方法で表現され、システムによってはプログラミング的に得ることができないこともあるので、この関数が返すのはただの推測です。

システムによっては、ユーザの設定を取得するために setlocale() を呼び出す必要があるため、この関数はスレッド安全ではありません。 setlocale() を呼び出す必要がない、または呼び出したくない場合、 do_setlocale を False に設定する必要があります。

バージョン 2.3 で追加.

locale.normalize(localename)

与えたロケール名を規格化したロケールコードを返します。返されるロケールコードは setlocale() で使うために書式化されています。規格化が失敗した場合、もとの名前がそのまま返されます。

与えたエンコードがシステムにとって未知の場合、標準の設定では、この関数は setlocale() と同様に、エンコーディングをロケールコードにおける標準のエンコーディングに設定します。

バージョン 2.0 で追加.

locale.resetlocale([category])

category のロケールを標準設定にします。

標準設定は getdefaultlocale() を呼ぶことで決定されます。 category は標準で LC_ALL になっています。

バージョン 2.0 で追加.

locale.strcoll(string1, string2)

現在の LC_COLLATE 設定に従って二つの文字列を比較します。他の比較を行う関数と同じように、 string1 が string2 に対して前に来るか、後に来るか、あるいは二つが等しいかによって、それぞれ負の値、正の値、あるいは 0 を返します。

locale.strxfrm(string)

文字列を組み込み関数 cmp() で使える形式に変換し、かつロケールに則した結果を返します。この関数は同じ文字列が何度も比較される場合、例えば文字列からなるシーケンスを順序付けて並べる際に使うことができます。

locale.format(format, val[, grouping[, monetary]])

数値 val を現在の LC_NUMERIC の設定に基づいて書式化します。書式は % 演算子の慣行に従います。浮動小数点数については、必要に応じて浮動小数点が変更されます。 grouping が真なら、ロケールに配慮した桁数の区切りが行われます。

monetary が真なら、桁区切り記号やグループ化文字列を用いて変換を行います。

この関数や、1文字の指定子でしか動作しないことに注意しましょう。フォーマット文字列を使う場合は format_string() を使用します。

バージョン 2.5 で変更: monetary パラメータが追加されました.

locale.format_string(format, val[, grouping])

format % val 形式のフォーマット指定子を、現在のロケール設定を考慮したうえで処理します。

バージョン 2.5 で追加.

locale.currency(val[, symbol[, grouping[, international]]])

数値 val を、現在の LC_MONETARY の設定にあわせてフォーマットします。

symbol が真の場合は、返される文字列に通貨記号が含まれるようになります。これはデフォルトの設定です。 grouping が真の場合(これはデフォルトではありません)は、値をグループ化します。 international が真の場合(これはデフォルトではありません)は、国際的な通貨記号を使用します。

この関数は’C’ロケールでは動作しないことに注意しましょう。まず最初に setlocale() でロケールを設定する必要があります。

バージョン 2.5 で追加.

locale.str(float)

浮動小数点数を str(float) と同じように書式化しますが、ロケールに配慮した小数点が使われます。

locale.atof(string)

文字列を LC_NUMERIC で設定された慣行に従って浮動小数点に変換します。

locale.atoi(string)

文字列を LC_NUMERIC で設定された慣行に従って整数に変換します。

locale.LC_CTYPE

文字タイプ関連の関数のためのロケールカテゴリです。このカテゴリの設定に従って、モジュール string における関数の振る舞いが変わります。

locale.LC_COLLATE

文字列を並べ替えるためのロケールカテゴリです。 locale モジュールの関数 strcoll() および strxfrm() が影響を受けます。

locale.LC_TIME

時刻を書式化するためのロケールカテゴリです。 time.strftime() はこのカテゴリに設定されている慣行に従います。

locale.LC_MONETARY

金額に関係する値を書式化するためのロケールカテゴリです。設定可能なオプションは関数 localeconv() で得ることができます。

locale.LC_MESSAGES

メッセージ表示のためのロケールカテゴリです。現在 Python はアプリケーション毎にロケールに対応したメッセージを出力する機能はサポートしていません。 os.strerror() が返すような、オペレーティングシステムによって表示されるメッセージはこのカテゴリによって影響を受けます。

locale.LC_NUMERIC

数字を書式化するためのロケールカテゴリです。関数 format() 、 atoi() 、 atof() および locale モジュールの str() が影響を受けます。他の数値書式化操作は影響を受けません。

locale.LC_ALL

全てのロケール設定を総合したものです。ロケールを変更する際にこのフラグが使われた場合、そのロケールにおける全てのカテゴリを設定しようと試みます。一つでも失敗したカテゴリがあった場合、全てのカテゴリにおいて設定変更を行いません。このフラグを使ってロケールを取得した場合、全てのカテゴリにおける設定を示す文字列が返されます。この文字列は、後に設定を元に戻すために使うことができます。

locale.CHAR_MAX

localeconv() の返す特別な値のためのシンボル定数です。

例:

>>> import locale
>>> loc = locale.getlocale() # get current locale
# use German locale; name might vary with platform
>>> locale.setlocale(locale.LC_ALL, 'de_DE')
>>> locale.strcoll('f\xe4n', 'foo') # compare a string containing an umlaut
>>> locale.setlocale(locale.LC_ALL, '') # use user's preferred locale
>>> locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
>>> locale.setlocale(locale.LC_ALL, loc) # restore saved locale

22.2.1. ロケールの背景、詳細、ヒント、助言および補足説明

C 標準では、ロケールはプログラム全体にわたる特性であり、その変更は高価な処理であるとしています。加えて、頻繁にロケールを変更するようなひどい実装はコアダンプを引き起こすこともあります。このことがロケールを正しく利用する上で苦痛となっています。

そもそも、プログラムが起動した際、ロケールはユーザの希望するロケールにかかわらず C です。プログラムは setlocale(LC_ALL, '') を呼び出して、明示的にユーザの希望するロケール設定を行わなければなりません。

setlocale() をライブラリルーチン内で呼ぶことは、それがプログラム全体に及ぼす副作用の面から、一般的によくない考えです。ロケールを保存したり復帰したりするのもよくありません: 高価な処理であり、ロケールの設定が復帰する以前に起動してしまった他のスレッドに悪影響を及ぼすからです。

もし、汎用を目的としたモジュールを作っていて、ロケールによって影響をうけるような操作 (例えば string.lower() や time.strftime() の書式の一部) のロケール独立のバージョンが必要ということになれば、標準ライブラリルーチンを使わずに何とかしなければなりません。よりましな方法は、ロケール設定が正しく利用できているか確かめることです。最後の手段は、あなたのモジュールが C ロケール以外の設定には互換性がないとドキュメントに書くことです。

string モジュールの大小文字の変換を行う関数はロケール設定によって影響を受けます。 setlocale() 関数を呼んで LC_CTYPE 設定を変更した場合、変数 string.lowercase 、 string.uppercase および string.letters は計算しなおされます。例えば from string import letters のように、 ‘from ... import ...’ を使ってこれらの変数を使っている場合には、それ以降の setlocale() の影響を受けないので注意してください。

ロケールに従って数値操作を行うための唯一の方法はこのモジュールで特別に定義されている関数: atof() 、 atoi() 、 format() 、 str() を使うことです。

22.2.2. Python 拡張の作者と、Python を埋め込むようなプログラムに関して

拡張モジュールは、現在のロケールを調べる以外は、決して setlocale() を呼び出してはなりません。しかし、返される値もロケールの復帰のために使えるだけなので、さほど便利とはいえません (例外はおそらくロケールが C かどうか調べることでしょう)。

ロケールを変更するために Python コードで locale モジュールを使った場合、Python を埋め込んでいるアプリケーションにも影響を及ぼします。Python を埋め込んでいるアプリケーションに影響が及ぶことを望まない場合、 config.c ファイル内の組み込みモジュールのテーブルから _locale 拡張モジュール (ここで全てを行っています) を削除し、共有ライブラリから _locate モジュールにアクセスできないようにしてください。

22.2.3. メッセージカタログへのアクセス

C ライブラリの gettext インタフェースが提供されているシステムでは、 locake モジュールでそのインタフェースを公開しています。このインタフェースは関数 gettext() 、 dgettext() 、 dcgettext() 、 textdomain() 、 bindtextdomain() 、および bind_textdomain_codeset() からなります。これらは gettext モジュールの同名の関数に似ていますが、メッセージカタログとして C ライブラリのバイナリフォーマットを使い、メッセージカタログを探すために C ライブラリのサーチアルゴリズムを使います。

Python アプリケーションでは、通常これらの関数を呼び出す必要はないはずで、代わりに gettext を呼ぶべきです。例外として知られているのは、内部で gettext() または dcgettext() を呼び出すような C ライブラリにリンクするアプリケーションです。こうしたアプリケーションでは、ライブラリが正しいメッセージカタログを探せるようにテキストドメイン名を指定する必要があります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

23. プログラムのフレームワーク

この章で解説されるモジュールはあなたのプログラムの大枠を規定するフレームワークです。現状では、ここで解説されるモジュールは全てコマンドラインインタフェースを書くためのものです。

この章の完全な一覧は:

23.1. cmd — 行指向のコマンドインタープリタのサポート

23.1.1. Cmdオブジェクト

23.2. shlex — 単純な字句解析

23.2.1. モジュールの内容

23.2.2. shlex オブジェクト

23.2.3. 解析規則

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

23. プログラムのフレームワーク »

23.1. cmd — 行指向のコマンドインタープリタのサポート

Cmd クラスでは、行指向のコマンドインタープリタを書くための簡単なフレームワークを提供します。テストハーネスや管理ツール、そして、後により洗練されたインターフェイスでラップするプロトタイプとして、こうしたインタープリタはよく役に立ちます。

参考

最新バージョンの cmd モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/cmd.py?view=markup]

class cmd.Cmd([completekey[, stdin[, stdout]]])

Cmd インスタンス、あるいはサブクラスのインスタンスは、行指向のインタープリタ・フレームワークです。 Cmd 自身をインスタンス化することはありません。むしろ、 Cmd のメソッドを継承したり、アクションメソッドをカプセル化するために、あなたが自分で定義するインタープリタクラスのスーパークラスとしての便利です。

オプション引数 completekey は、補完キーの readline 名です。デフォルトは Tab です。 completekey が None でなく、 readline が利用できるならば、コマンド補完は自動的に行われます。

オプション引数 stdin と stdout には、Cmd またはそのサブクラスのインスタンスが入出力に使用するファイルオブジェクトを指定します。省略時には sys.stdin と sys.stdout が使用されます。

引数に渡した stdin を使いたい場合は、インスタンスの use_rawinput 属性を False にセットしてください。そうしないと stdin は無視されます。

バージョン 2.3 で変更: 引数 stdin と stdout を追加.

23.1.1. Cmdオブジェクト

Cmd インスタンスは、次のメソッドを持ちます:

Cmd.cmdloop([intro])

プロンプトを繰り返し出力し、入力を受け取り、受け取った入力から取り去った先頭の語を解析し、その行の残りを引数としてアクションメソッドへディスパッチします。

オプションの引数は、最初のプロンプトの前に表示されるバナーあるいはイントロ用の文字列です (これはクラスメンバ intro をオーバーライドします)。

readline モジュールがロードされているなら、入力は自動的に bash のような履歴リスト編集機能を受け継ぎます(例えば、 Control-P は直前のコマンドへのスクロールバック、 Control-N は次のものへ進む、 Control-F はカーソルを右へ非破壊的に進める、 Control-B はカーソルを非破壊的に左へ移動させる等)。

入力のファイル終端は、文字列 'EOF' として渡されます。

メソッド do_foo() を持っている場合に限って、インタープリタのインスタンスはコマンド名 foo を認識します。特別な場合として、文字 '?' で始まる行はメソッド do_help() へディスパッチします。他の特別な場合として、文字 '!' で始まる行はメソッド do_shell() へディスパッチします(このようなメソッドが定義されている場合)。

このメソッドは postcmd() メソッドが真を返したときに return します。 postcmd() に対する stop 引数は、このコマンドが対応する do_*() メソッドからの返り値です。

補完が有効になっているなら、コマンドの補完が自動的に行われます。また、コマンド引数の補完は、引数 text, line, begidx, および endidx と共に complete_foo() を呼び出すことによって行われます。 text は、マッチしようとしている文字列の先頭の語です。返されるマッチは全てそれで始まっていなければなりません。 line は始めの空白を除いた現在の入力行です。 begidx と endidx は先頭のテキストの始まりと終わりのインデックスで、引数の位置に依存した異なる補完を提供するのに使えます。

Cmd のすべてのサブクラスは、定義済みの do_help() を継承します。このメソッドは、(引数 'bar' と共に呼ばれたとすると)対応するメソッド help_bar() を呼び出します。そのメソッドが存在しない場合、 do_bar() の docstring があればそれを表示します。引数がなければ、 do_help() は、すべての利用可能なヘルプ見出し(すなわち、対応する help_*() メソッドを持つすべてのコマンドまたは docstring を持つコマンド)をリストアップします。また、文書化されていないコマンドでも、すべてリストアップします。

Cmd.onecmd(str)

プロンプトに答えてタイプしたかのように引数を解釈実行します。これをオーバーライドすることがあるかもしれませんが、通常は必要ないでしょう。便利な実行フックについては、 precmd() と postcmd() メソッドを参照してください。戻り値は、インタープリタによるコマンドの解釈実行をやめるかどうかを示すフラグです。コマンド str に対応する do_*() メソッドがある場合、そのメソッドの返り値が返されます。そうでない場合は default() メソッドからの返り値が返されます。

Cmd.emptyline()

プロンプトに空行が入力されたときに呼び出されるメソッド。このメソッドがオーバーライドされていないなら、最後に入力された空行でないコマンドが繰り返されます。

Cmd.default(line)

コマンドの先頭の語が認識されないときに、入力行に対して呼び出されます。このメソッドがオーバーライドされていないなら、エラーメッセージを表示して戻ります。

Cmd.completedefault(text, line, begidx, endidx)

利用可能なコマンド固有の complete_*() が存在しないときに、入力行を補完するために呼び出されるメソッド。デフォルトでは、空行を返します。

Cmd.precmd(line)

コマンド行 line が解釈実行される直前、しかし入力プロンプトが作られ表示された後に実行されるフックメソッド。このメソッドは Cmd 内のスタブであって、サブクラスでオーバーライドされるために存在します。戻り値は onecmd() メソッドが実行するコマンドとして使われます。 precmd() の実装では、コマンドを書き換えるかもしれないし、あるいは単に変更していない line を返すかもしれません。

Cmd.postcmd(stop, line)

コマンドディスパッチが終わった直後に実行されるフックメソッド。このメソッドは Cmd 内のスタブで、サブクラスでオーバーライドされるために存在します。 line は実行されたコマンド行で、 stop は postcmd() の呼び出しの後に実行を停止するかどうかを示すフラグです。これは onecmd() メソッドの戻り値です。このメソッドの戻り値は、 stop に対応する内部フラグの新しい値として使われます。偽を返すと、実行を続けます。

Cmd.preloop()

cmdloop() が呼び出されたときに一度だけ実行されるフックメソッド。このメソッドは Cmd 内のスタブであって、サブクラスでオーバーライドされるために存在します。

Cmd.postloop()

cmdloop() が戻る直前に一度だけ実行されるフックメソッド。このメソッドは Cmd 内のスタブであって、サブクラスでオーバーライドされるために存在します。

Cmd のサブクラスのインスタンスは、公開されたインスタンス変数をいくつか持っています:

Cmd.prompt

入力を求めるために表示されるプロンプト。

Cmd.identchars

コマンドの先頭の語として受け入れられる文字の文字列。

Cmd.lastcmd

最後の空でないコマンドプリフィックス。

Cmd.intro

イントロあるいはバナーとして表示される文字列。 cmdloop() メソッドに引数を与えるために、オーバーライドされるかもしれません。

Cmd.doc_header

ヘルプ出力に文書化されたコマンドのセクションがある場合に表示するヘッダ。

Cmd.misc_header

ヘルプの出力にその他のヘルプ見出しがある(すなわち、 do_*() メソッドに対応していない help_*() メソッドが存在する)場合に表示するヘッダ。

Cmd.undoc_header

ヘルプ出力に文書化されていないコマンドのセクションがある(すなわち、対応する help_*() メソッドを持たない do_*() メソッドが存在する)場合に表示するヘッダ。

Cmd.ruler

ヘルプメッセージのヘッダの下に、区切り行を表示するために使われる文字。空のときは、ルーラ行が表示されません。デフォルトでは、 '=' です。

Cmd.use_rawinput

フラグで、デフォルトでは真です。真ならば、 cmdloop() はプロンプトを表示して次のコマンド読み込むために raw_input() を使います。偽ならば、 sys.stdout.write() と sys.stdin.readline() が使われます。 (これが意味するのは、 readline を import することによって、それをサポートするシステム上では、インタープリタが自動的に Emacs 形式の行編集とコマンド履歴のキーストロークをサポートするということです。)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

23. プログラムのフレームワーク »

23.2. shlex — 単純な字句解析

バージョン 1.5.2 で追加.

shlex クラスは Unix シェルを思わせる単純な構文に対する字句解析器を簡単に書けるようにします。このクラスはしばしば、 Python アプリケーションのための実行制御ファイルのような小規模言語を書く上で便利です。

ノート

モジュール shlex は今のところユニコード入力をサポートしていません。

23.2.1. モジュールの内容

shlex モジュールは以下の関数を定義します。

shlex.split(s[, comments[, posix]])

シェル類似の文法を使って、文字列 s を分割します。 comments が False (デフォルト値) の場合、受理した文字列内のコメントを解析しません (shlex インスタンスの commenters メンバの値を空文字列にします)。この関数はデフォルトでは POSIX モードで動作し、 posix 引数が false の場合は non-POSIX モードで動作します。

バージョン 2.3 で追加.

バージョン 2.6 で変更: posix パラメータを追加。

ノート

split() 関数は shlex クラスのインスタンスを利用するので、 s に None を渡すと標準入力から分割する文字列を読み込みます。

shlex モジュールは以下のクラスを定義します。

class shlex.shlex([instream[, infile[, posix]]])

shlex クラスとサブクラスのインスタンスは、字句解析器オブジェクトです。初期化引数を与えると、どこから文字を読み込むかを指定できます。指定先は read() メソッドと readline() メソッドを持つファイル/ストリーム類似オブジェクトか、文字列でなくてはいけません（文字列が受理されるようになったのは Python 2.3 以降）。引数が与えられなければ、 sys.stdin から入力を受け付けます。第 2 引数は、ファイル名を表す文字列で、 infile メンバの値の初期値を決定します。 instream 引数が省略された場合や、この値が sys.stdin である場合、第2引数のデフォルト値は “stdin” になります。 posix 引数は Python 2.3 で導入されました。これは動作モードを定義します。 posix が真でない場合（デフォルト）、 shlex インスタンスは互換モードで動作します。 POSIX モードで動作中、 shlex は、できる限り POSIX シェルの解析規則に似せようとします。

参考

Module ConfigParser

Windows .ini ファイルに似た設定ファイルのパーザ。

23.2.2. shlex オブジェクト

shlex インスタンスは以下のメソッドを持っています:

shlex.get_token()

トークンを一つ返します。トークンが push_token() で使ってスタックに積まれていた場合、トークンをスタックからポップします。そうでない場合、トークンを一つ入力ストリームから読み出します。読み出し即時にファイル終了子に遭遇した場合、 self.eof (非 POSIX モードでは空文字列 ('')、POSIX モードでは None) が返されます。

shlex.push_token(str)

トークンスタックに引数文字列をスタックします。

shlex.read_token()

生 (raw) のトークンを読み出します。プッシュバックスタックを無視し、かつソースリクエストを解釈しません (通常これは便利なエントリポイントではありません。完全性のためにここで記述されています)。

shlex.sourcehook(filename)

shlex がソースリクエスト (下の source を参照してください) を検出した際、このメソッドはその後に続くトークンを引数として渡され、ファイル名と開かれたファイル類似オブジェクトからなるタプルを返すとされています。

通常、このメソッドはまず引数から何らかのクオートを剥ぎ取ります。処理後の引数が絶対パス名であった場合か、以前に有効になったソースリクエストが存在しない場合か、以前のソースが (sys.stdin のような) ストリームであった場合、この結果はそのままにされます。そうでない場合で、処理後の引数が相対パス名の場合、ソースインクルードスタックにある直前のファイル名からディレクトリ部分が取り出され、相対パスの前の部分に追加されます (この動作は C 言語プリプロセッサにおける #include "file.h" の扱いと同様です) 。

これらの操作の結果はファイル名として扱われ、タプルの最初の要素として返されます。同時にこのファイル名で open() を呼び出した結果が二つ目の要素になります (注意: インスタンス初期化のときとは引数の並びが逆になっています！)

このフックはディレクトリサーチパスや、ファイル拡張子の追加、その他の名前空間に関するハックを実装できるようにするために公開されています。 ‘close’ フックに対応するものはありませんが、shlex インスタンスはソースリクエストされている入力ストリームが EOF を返した時には close() を呼び出します。

ソーススタックをより明示的に操作するには、 push_source() および pop_source() メソッドを使ってください。

shlex.push_source(stream[, filename])

入力ソースストリームを入力スタックにプッシュします。ファイル名引数が指定された場合、以後のエラーメッセージ中で利用することができます。 sourcehook() メソッドが内部で使用しているのと同じメソッドです。

バージョン 2.1 で追加.

shlex.pop_source()

最後にプッシュされた入力ソースを入力スタックからポップします。字句解析器がスタック上の入力ストリームの EOF に到達した際に利用するメソッドと同じです。

バージョン 2.1 で追加.

shlex.error_leader([file[, line]])

このメソッドはエラーメッセージの論述部分を Unix C コンパイラエラーラベルの形式で生成します; この書式は '"%s", line %d: ' で、 %s は現在のソースファイル名で置き換えられ、 %d は現在の入力行番号で置き換えられます (オプションの引数を使ってこれらを上書きすることもできます)。

このやり方は、 shlex のユーザに対して、Emacs やその他の Unix ツール群が解釈できる一般的な書式でのメッセージを生成することを推奨するために提供されています。

shlex サブクラスのインスタンスは、字句解析を制御したり、デバッグに使えるような public なインスタンス変数を持っています:

shlex.commenters

コメントの開始として認識される文字列です。コメントの開始から行末までのすべてのキャラクタ文字は無視されます。標準では単に '#' が入っています。

shlex.wordchars

複数文字からなるトークンを構成するためにバッファに蓄積していくような文字からなる文字列です。標準では、全ての ASCII 英数字およびアンダースコアが入っています。

shlex.whitespace

空白と見なされ、読み飛ばされる文字群です。空白はトークンの境界を作ります。標準では、スペース、タブ、改行 (linefeed) および復帰 (carriage-return) が入っています。

shlex.escape

エスケープ文字と見なされる文字群です。これは POSIX モードでのみ使われ、デフォルトでは '\' だけが入っています。

バージョン 2.3 で追加.

shlex.quotes

文字列引用符と見なされる文字群です。トークンを構成する際、同じクオートが再び出現するまで文字をバッファに蓄積します (すなわち、異なるクオート形式はシェル中で互いに保護し合う関係にあります)。標準では、ASCII 単引用符および二重引用符が入っています。

shlex.escapedquotes

quotes のうち、 escape で定義されたエスケープ文字を解釈する文字群です。これは POSIX モードでのみ使われ、デフォルトでは '"' だけが入っています。

バージョン 2.3 で追加.

shlex.whitespace_split

この値が True であれば、トークンは空白文字でのみで分割されます。たとえば shlex がシェル引数と同じ方法で、コマンドラインを解析するのに便利です。

バージョン 2.3 で追加.

shlex.infile

現在の入力ファイル名です。クラスのインスタンス化時に初期設定されるか、その後のソースリクエストでスタックされます。エラーメッセージを構成する際にこの値を調べると便利なことがあります。

shlex.instream

shlex インスタンスが文字を読み出している入力ストリームです。

shlex.source

このメンバ変数は標準で None を取ります。この値に文字列を代入すると、その文字列は多くのシェルにおける source キーワードに似た、字句解析レベルでのインクルード要求として認識されます。すなわち、その直後に現れるトークンをファイル名として新たなストリームを開き、そのストリームを入力として、EOF に到達するまで読み込まれます。新たなストリームの EOF に到達した時点で close() が呼び出され、入力は元の入力ストリームに戻されます。ソースリクエストは任意のレベルの深さまでスタックしてかまいません。

shlex.debug

このメンバ変数が数値で、かつ 1 またはそれ以上の値の場合、 shlex インスタンスは動作に関する冗長な進捗報告を出力します。この出力を使いたいなら、モジュールのソースコードを読めば詳細を学ぶことができます。

shlex.lineno

ソース行番号 (遭遇した改行の数に 1 を加えたもの) です。

shlex.token

トークンバッファです。例外を捕捉した際にこの値を調べると便利なことがあります。

shlex.eof

ファイルの終端を決定するのに使われるトークンです。非 POSIX モードでは空文字列 ('') 、POSIX モードでは None が入ります。

23.2.3. 解析規則

非 POSIX モードで動作中の shlex は以下の規則に従おうとします。

ワード内の引用符を認識しない (Do"Not"Separate は単一ワード Do"Not"Separate として解析されます)

エスケープ文字を認識しない

引用符で囲まれた文字列は、引用符内の全ての文字リテラルを保持する

閉じ引用符でワードを区切る ("Do"Separate は、 "Do" と Separate であると解析されます)

whitespace_split が False の場合、wordchar、 whitespace または quote として宣言されていない全ての文字を、単一の文字トークンとして返す。 True の場合、 shlex は空白文字でのみ単語を区切る。

空文字列 ('') で EOF を送出する

引用符に囲んであっても、空文字列を解析しない

POSIX モードで動作中の shlex は以下の解析規則に従おうとします。

引用符を取り除き、引用符で単語を分解しない ("Do"Not"Separate" は単一ワード DoNotSeparate として解析されます)

引用符で囲まれないエスケープ文字群 ('\' など) は直後に続く文字のリテラル値を保持する

escapedquotes でない引用符文字 ("'" など) で囲まれている全ての文字のリテラル値を保持する

引用符に囲まれた escapedquotes に含まれる文字 ('"' など) は、 escape に含まれる文字を除き、全ての文字のリテラル値を保持する。エスケープ文字群は使用中の引用符、または、そのエスケープ文字自身が直後にある場合のみ、特殊な機能を保持する。他の場合にはエスケープ文字は普通の文字とみなされる。

None で EOF を送出する

引用符に囲まれた空文字列 ('') を許す

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス

Tk/Tcl は長きにわたり Python の不可欠な一部でありつづけています。 Tk/Tcl は頑健でプラットホームに依存しないウィンドウ構築ツールキットであり、 Python プログラマは Tkinter モジュールやその拡張の Tix, ttk モジュールを使って利用できます。

Tkinter モジュールは、 Tcl/Tk 上に作られた軽量なオブジェクト指向のレイヤです。 Tkinter を使うために Tcl コードを書く必要はありませんが、Tk のドキュメントや、場合によっては Tcl のドキュメントを調べる必要があるでしょう。 Tkinter は Tk のウィジェットを Python のクラスとして実装しているラッパをまとめたものです。加えて、内部モジュール _tkinter では、 Python と Tcl がやり取りできるようなスレッド安全なメカニズムを提供しています。

Tkinter の一番素晴らしい点は速く、そして普通に Pythonに付属してくることです。標準ドキュメントが頼りないものだとしても、代わりになるものが入手可能です: リファレンス、チュートリアル、書籍その他です。 Tkinter は古臭いルックアンドフィールでも有名ですが、その点は Tk 8.5 で幅広く改善されました。とはいえ、興味を引きそうな GUI ライブラリは他にも多数あります。そういったものについてはもっと知りたい人は 他のグラフィカルユーザインタフェースパッケージ節を参照してください。

24.1. Tkinter — Tcl/Tk への Python インタフェース

24.1.1. Tkinter モジュール

24.1.2. Tkinter お助け手帳 (life preserver)

24.1.2.1. この節の使い方

24.1.2.2. 簡単なHello Worldプログラム

24.1.3. Tcl/Tk を (本当に少しだけ) 見渡してみる

24.1.4. 基本的な Tk プログラムと Tkinter との対応関係

24.1.5. Tk と Tkinter はどのように関わっているのか

24.1.6. 簡単なリファレンス

24.1.6.1. オプションの設定

24.1.6.2. Packer

24.1.6.3. Packer のオプション

24.1.6.4. ウィジェット変数を関連付ける

24.1.6.5. ウィンドウマネジャ

24.1.6.6. Tk オプションデータ型

24.1.6.7. バインドとイベント

24.1.6.8. index パラメータ

24.1.6.9. 画像

24.2. ttk — Tk themed widgets

24.2.1. Ttk を使う

24.2.2. Ttk ウィジェット

24.2.3. ウィジェット

24.2.3.1. 標準オプション

24.2.3.2. スクロール可能ウィジェットのオプション

24.2.3.3. ラベルオプション

24.2.3.4. 互換性オプション

24.2.3.5. ウィジェットの状態

24.2.3.6. ttk.Widget

24.2.4. コンボボックス

24.2.4.1. オプション

24.2.4.2. 仮想イベント

24.2.4.3. ttk.Combobox

24.2.5. ノートブック

24.2.5.1. オプション

24.2.5.2. タブオプション

24.2.5.3. タブ識別子

24.2.5.4. 仮想イベント

24.2.5.5. ttk.Notebook

24.2.6. プログレスバー

24.2.6.1. オプション

24.2.6.2. ttk.Progressbar

24.2.7. セパレータ

24.2.7.1. オプション

24.2.8. サイズグリップ

24.2.8.1. プラットフォーム固有のメモ

24.2.8.2. バグ

24.2.9. ツリービュー

24.2.9.1. オプション

24.2.9.2. 要素オプション

24.2.9.3. タグオプション

24.2.9.4. カラム識別子

24.2.9.5. 仮想イベント

24.2.9.6. ttk.Treeview

24.2.10. Ttk スタイル

24.2.10.1. レイアウト

24.3. Tix — Tkの拡張ウィジェット

24.3.1. Tixを使う

24.3.2. Tixウィジェット

24.3.2.1. 基本ウィジェット

24.3.2.2. ファイルセレクタ

24.3.2.3. ハイアラキカルリストボックス

24.3.2.4. タビュラーリストボックス

24.3.2.5. 管理ウィジェット

24.3.2.6. 画像タイプ

24.3.2.7. その他のウィジェット

24.3.2.8. ジオメトリマネジャを作る

24.3.3. Tixコマンド

24.4. ScrolledText — スクロールするテキストウィジェット

24.5. turtle — Tkのためのタートルグラフィックス

24.5.1. はじめに

24.5.2. Turtle および Screen のメソッド概観

24.5.2.1. Turtle のメソッド

24.5.2.2. TurtleScreen/Screen のメソッド

24.5.3. RawTurtle/Turtle のメソッドと対応する関数

24.5.3.1. Turtle の動き

24.5.3.2. Turtle の状態を知る

24.5.3.3. 設定と計測

24.5.3.4. Pen の制御

24.5.3.4.1. 描画状態

24.5.3.4.2. 色の制御

24.5.3.4.3. 塗りつぶし

24.5.3.4.4. さらなる描画の制御

24.5.3.5. タートルの状態

24.5.3.5.1. 可視性

24.5.3.5.2. 見た目

24.5.3.6. イベントを利用する

24.5.3.7. 特別な Turtle のメソッド

24.5.3.8. 合成形の使用に関する補遺

24.5.4. TurtleScreen/Screen のメソッドと対応する関数

24.5.4.1. ウィンドウの制御

24.5.4.2. アニメーションの制御

24.5.4.3. スクリーンイベントを利用する

24.5.4.4. 設定と特殊なメソッド

24.5.4.5. Screen 独自のメソッド、TurtleScreen から継承したもの以外

24.5.5. turtle モジュールのパブリッククラス

24.5.6. ヘルプと設定

24.5.6.1. ヘルプの使い方

24.5.6.2. ドキュメント文字列の翻訳

24.5.6.3. Screen および Turtle の設定方法

24.5.7. デモスクリプト

24.6. IDLE

24.6.1. メニュー

24.6.1.1. Fileメニュー

24.6.1.2. Editメニュー

24.6.1.3. Windowsメニュー

24.6.1.4. Debugメニュー( Python シェルウィンドウ内のみ)

24.6.2. 基本的な編集とナビゲーション

24.6.2.1. 自動的な字下げ

24.6.2.2. Python Shellウィンドウ

24.6.3. 構文の色づけ

24.6.4. スタートアップ

24.6.4.1. コマンドラインの使い方

24.7. 他のグラフィカルユーザインタフェースパッケージ

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.1. Tkinter — Tcl/Tk への Python インタフェース

Tkinter モジュール (“Tk インタフェース”) は、 Tk GUI ツールキットに対する標準の Python インタフェースです。 Tk と Tkinter はほとんどの Unix プラットフォームの他、 Windows システム上でも利用できます。 (Tk 自体は Python の一部ではありません。 Tk は ActiveState で保守されています。)

ノート

Tkinter は Python 3.0 において tkinter に改名されました。 2to3 ツールはソースの 3.0 への変換時に自動的に import を対応させます。

参考

Python Tkinter Resources [http://www.python.org/topics/tkinter/]

Python Tkinter Topic Guide では、Tk を Python から利用する上での情報と、その他の Tk にまつわる情報源を数多く提供しています。

An Introduction to Tkinter [http://www.pythonware.com/library/an-introduction-to-tkinter.htm]

Fredrik Lundh のオンラインリファレンス資料です。

Tkinter reference: a GUI for Python [http://infohost.nmt.edu/tcc/help/pubs/lang.html]

オンラインリファレンス資料です。

Python and Tkinter Programming [http://www.amazon.com/exec/obidos/ASIN/1884777813]

John Graysonによる解説書 (ISBN 1-884777-81-3) です。

24.1.1. Tkinter モジュール

ほとんどの場合、本当に必要となるのは Tkinter モジュールだけですが、他にもいくつかの追加モジュールを利用できます。 Tk インタフェース自体は _tkinter と言う名前のバイナリモジュール内にあります。このモジュールに入っているのは Tk への低水準のインタフェースであり、アプリケーションプログラマが直接使ってはなりません。 _tkinter は通常共有ライブラリ (や DLL) になっていますが、 Python インタプリタに静的にリンクされていることもあります。

Tk インタフェースモジュールの他にも、 Tkinter には Python モジュールが数多く入っています。最も重要なモジュールは、 Tkinter 自体と Tkconstants と呼ばれるモジュールの二つです。前者は自動的に後者を import するので、以下のように一方のモジュールを import するだけで Tkinter を使えるようになります:

import Tkinter

あるいは、よく使うやり方で:

from Tkinter import *

のようにします。

class Tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=1)

Tk クラスは引数なしでインスタンス化します。これは Tk のトップレベルウィジェットを生成します。通常、トップレベルウィジェットはアプリケーションのメインウィンドウになります。それぞれのインスタンスごとに固有の Tcl インタプリタが関連づけられます。

バージョン 2.4 で変更: useTk パラメタが追加されました.

Tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=0)

Tcl() はファクトリ関数で、 Tk クラスで生成するオブジェクトとよく似たオブジェクトを生成します。ただし Tk サブシステムを初期化しません。この関数は、余分なトップレベルウィンドウを作る必要がなかったり、 (X サーバを持たない Unix/Linux システムなどのように) 作成できない環境において Tcl インタプリタを駆動したい場合に便利です。 Tcl() で生成したオブジェクトに対して loadtk() メソッドを呼び出せば、トップレベルウィンドウを作成 (して、Tk サブシステムを初期化) します。

バージョン 2.4 で追加.

Tk をサポートしているモジュールには、他にも以下のようなモジュールがあります:

ScrolledText

垂直スクロールバー付きのテキストウィジェットです。

tkColorChooser

ユーザに色を選択させるためのダイアログです。

tkCommonDialog

このリストの他のモジュールが定義しているダイアログの基底クラスです。

tkFileDialog

ユーザが開きたいファイルや保存したいファイルを指定できるようにする共通のダイアログです。

tkFont

フォントの扱いを補助するためのユーティリティです。

tkMessageBox

標準的な Tk のダイアログボックスにアクセスします。

tkSimpleDialog

基本的なダイアログと便宜関数 (convenience function) です。

Tkdnd

Tkinter 用のドラッグアンドドロップのサポートです。実験的なサポートで、Tk DND に置き替わった時点で撤廃されるはずです。

turtle

Tk ウィンドウ上でタートルグラフィックスを実現します。

これらも Python 3.0 で改名されました。新たな tkinter パッケージのサブモジュールになったのです。

24.1.2. Tkinter お助け手帳 (life preserver)

この節は、 Tk や Tkinter を全て網羅したチュートリアルを目指しているわけではありません。むしろ、Tkinter のシステムを学ぶ上での指針を示すための、その場しのぎ的なマニュアルです。

謝辞:

Tkinter は Steen Lumholt と Guido van Rossum が作成しました。

Tk は John Ousterhout が Berkeley の在籍中に作成しました。

この Life Preserver は Virginia 大学の Matt Conway 他が書きました。

html へのレンダリングやたくさんの編集は、Ken Manheimer が FrameMaker 版から行いました。

Fredrik Lundh はクラスインタフェース詳細な説明を書いたり内容を改訂したりして、現行の Tk 4.2 に合うようにしました。

Mike Clarkson はドキュメントをLaTeX 形式に変換し、リファレンスマニュアルのユーザインタフェースの章をコンパイルしました。

24.1.2.1. この節の使い方

この節は二つの部分で構成されています: 前半では、背景となることがらを (大雑把に) 網羅しています。後半は、キーボードの横に置けるような手軽なリファレンスになっています。

「ホゲホゲ (blah) するにはどうしたらよいですか」という形の問いに答えようと思うなら、まず Tk で「ホゲホゲ」する方法を調べてから、このドキュメントに戻ってきてその方法に対応する Tkinter の関数呼び出しに変換するのが多くの場合最善の方法になります。 Python プログラマが Tk ドキュメンテーションを見れば、たいてい正しい Python コマンドの見当をつけられます。従って、 Tkinter を使うには Tk についてほんの少しだけ知っていればよいということになります。このドキュメントではその役割を果たせないので、次善の策として、すでにある最良のドキュメントについていくつかヒントを示しておくことにしましょう:

Tk の man マニュアルのコピーを手に入れるよう強く勧めます。とりわけ最も役立つのは mann ディレクトリ内にあるマニュアルです。 man3 のマニュアルページは Tk ライブラリに対する C インタフェースについての説明なので、スクリプト書きにとって取り立てて役に立つ内容ではありません。

Addison-Wesley は John Ousterhout の書いた Tcl and the Tk Toolkit (ISBN 0-201-63337-X) という名前の本を出版しています。この本は初心者向けの Tcl と Tk の良い入門書です。内容は網羅的ではなく、詳細の多くは man マニュアル任せにしています。

たいていの場合、 Tkinter.py は参照先としては最後の地 (last resort) ですが、それ以外の手段で調べても分からない場合には救いの地 (good place) になるかもしれません。

参考

ActiveState Tclホームページ [http://tcl.activestate.com/]

Tk/Tcl の開発は ActiveState で大々的に行われています。

Tcl and the Tk Toolkit [http://www.amazon.com/exec/obidos/ASIN/020163337X]

Tcl を考案した John Ousterhout による本です。

Practical Programming in Tcl and Tk [http://www.amazon.com/exec/obidos/ASIN/0130220280]

Brent Welch の百科事典のような本です。

24.1.2.2. 簡単なHello Worldプログラム

from Tkinter import *

class Application(Frame):
    def say_hi(self):
        print "hi there, everyone!"

    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"]   = "red"
        self.QUIT["command"] =  self.quit

        self.QUIT.pack({"side": "left"})

        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

24.1.3. Tcl/Tk を (本当に少しだけ) 見渡してみる

クラス階層は複雑に見えますが、実際にプログラムを書く際には、アプリケーションプログラマはほとんど常にクラス階層の最底辺にあるクラスしか参照しません。

注意:

クラスのいくつかは、特定の関数を一つの名前空間下にまとめるために提供されています。こうしたクラスは個別にインスタンス化するためのものではありません。

Tk クラスはアプリケーション内で一度だけインスタンス化するようになっています。アプリケーションプログラマが明示的にインスタンス化する必要はなく、他のクラスがインスタンス化されると常にシステムが作成します。

Widget クラスもまた、インスタンス化して使うようにはなっていません。このクラスはサブクラス化して「実際の」ウィジェットを作成するためのものです。(C++ で言うところの、 ‘抽象クラス (abstract class)’ です)。

このリファレンス資料を活用するには、Tk の短いプログラムを読んだり、 Tk コマンドの様々な側面を知っておく必要がままあるでしょう。 (下の説明の Tkinter 版は、基本的な Tk プログラムと Tkinter との対応関係 節を参照してください。)

Tk スクリプトは Tcl プログラムです。全ての Tcl プログラムに同じく、 Tk スクリプトはトークンをスペースで区切って並べます。 Tk ウィジェットとは、ウィジェットの クラス 、ウィジェットの設定を行う オプション 、そしてウィジェットに役立つことをさせる アクションをあわせたものに過ぎません。

Tk でウィジェットを作るには、常に次のような形式のコマンドを使います:

classCommand newPathname options

classCommand

どの種類のウィジェット (ボタン、ラベル、メニュー、...) を作るかを表します。

newPathname

作成するウィジェットにつける新たな名前です。Tk 内の全ての名前は一意になっていなければなりません。一意性を持たせる助けとして、 Tk 内のウィジェットは、ファイルシステムにおけるファイルと同様、パス名 (pathname) を使って名づけられます。トップレベルのウィジェット、すなわち ルート は . (ピリオド) という名前になり、その子ウィジェット階層もピリオドで区切ってゆきます。ウィジェットの名前は、例えば .myApp.controlPanel.okButton のようになります。

options

ウィジェットの見た目を設定します。場合によってはウィジェットの挙動も設定します。オプションはフラグと値がリストになった形式をとります。 Unix のシェルコマンドのフラグと同じように、フラグの前には ‘-‘ がつき、複数の単語からなる値はクオートで囲まれます。

以下に例を示します:

button   .fred   -fg red -text "hi there"
   ^       ^     \_____________________/
   |       |                |
 class    new            options
command  widget  (-opt val -opt val ...)

ウィジェットを作成すると、ウィジェットへのパス名は新しいコマンドになります。この新たな widget command は、プログラマが新たに作成したウィジェットに action を実行させる際のハンドル (handle) になります。C では someAction(fred, someOptions) と表し、 C++ では fred.someAction(someOptions) と表すでしょう。Tkでは:

.fred someAction someOptions

のようにします。オブジェクト名 .fred はドットから始まっているので注意してください。

読者の想像の通り、 someAction に指定できる値はウィジェットのクラスに依存しています: fred がボタンなら .fred disable はうまくいきます (fred はグレーになります) が、fred がラベルならうまくいきません (Tkではラベルの無効化をサポートしていないからです)。

someOptions に指定できる値はアクションの内容に依存しています。 disable のようなアクションは引数を必要としませんが、テキストエントリボックスの delete コマンドのようなアクションにはテキストを削除する範囲を指定するための引数が必要になります。

24.1.4. 基本的な Tk プログラムと Tkinter との対応関係

Tkのクラスコマンドは、Tkinterのクラスコンストラクタに対応しています。

button .fred                =====>  fred = Button()

オブジェクトの親 (master) は、オブジェクトの作成時に指定した新たな名前から非明示的に決定されます。Tkinter では親を明示的に指定します。

button .panel.fred          =====>  fred = Button(panel)

Tk の設定オプションは、ハイフンをつけたタグと値の組からなるリストで指定します。Tkinter では、オプションはキーワード引数にしてインスタンスのコンストラクタに指定したり、 config() にキーワード引数を指定して呼び出したり、インデクス指定を使ってインスタンスに代入したりして設定します。オプションの設定についてはオプションの設定 節を参照してください。

button .fred -fg red        =====>  fred = Button(panel, fg = "red")
.fred configure -fg red     =====>  fred["fg"] = red
                            OR ==>  fred.config(fg = "red")

Tk でウィジェットにアクションを実行させるには、ウィジェット名をコマンドにして、その後にアクション名を続け、必要に応じて引数 (オプション) を続けます。 Tkinter では、クラスインスタンスのメソッドを呼び出して、ウィジェットのアクションを呼び出します。あるウィジェットがどんなアクション (メソッド) を実行できるかは、 Tkinter.py モジュール内にリストされています。

.fred invoke                =====>  fred.invoke()

Tk でウィジェットを packer (ジオメトリマネジャ) に渡すには、 pack コマンドをオプション引数付きで呼び出します。 Tkinter では Pack クラスがこの機能すべてを握っていて、様々な pack の形式がメソッドとして実装されています。 Tkinter のウィジェットは全て Packer からサブクラス化されているため、pack 操作にまつわる全てのメソッドを継承しています。 Form ジオメトリマネジャに関する詳しい情報については Tix モジュールのドキュメントを参照してください。

pack .fred -side left       =====>  fred.pack(side = "left")

24.1.5. Tk と Tkinter はどのように関わっているのか

上から下に、呼び出しの階層構造を説明してゆきます:

あなたのアプリケーション (Python)

まず、 Python アプリケーションが Tkinter を呼び出します。

Tkinter ( Python モジュール)

上記の呼び出し (例えば、ボタンウィジェットの作成) は、 Tkinter モジュール内で実現されており、Python で書かれています。この Python で書かれた関数は、コマンドと引数を解析して変換し、あたかもコマンドが Python スクリプトではなく Tk スクリプトから来たようにみせかけます。

tkinter (C)

上記のコマンドと引数は tkinter (小文字です。注意してください) 拡張モジュール内の C 関数に渡されます。

Tk Widgets (C and Tcl)

上記の C 関数は、Tk ライブラリを構成する C 関数の入った別の C モジュールへの呼び出しを行えるようになっています。 Tk は C と Tcl を少し使って実装されています。 Tk ウィジェットの Tcl 部分は、ウィジェットのデフォルト動作をバインドするために使われ、Python で書かれた Tkinter モジュールが import される時点で一度だけ実行されます。(ユーザがこの過程を目にすることはありません。)

Tk (C)

Tkウィジェットの Tk 部分で実装されている最終的な対応付け操作によって...

Xlib (C)

Xlib ライブラリがスクリーン上にグラフィックスを描きます。

24.1.6. 簡単なリファレンス

24.1.6.1. オプションの設定

オプションは、色やウィジェットの境界線幅などを制御します。オプションの設定には三通りの方法があります:

オブジェクトを作成する時にキーワード引数を使う

fred = Button(self, fg = "red", bg = "blue")

オブジェクトを作成した後、オプション名を辞書インデックスのように扱う

fred["fg"] = "red"
fred["bg"] = "blue"

オブジェクトを生成した後、config()メソッドを使って複数の属性を更新する

fred.config(fg = "red", bg = "blue")

オプションとその振る舞いに関する詳細な説明は、該当するウィジェットの Tk の man マニュアルを参照してください。

man マニュアルには、各ウィジェットの “STANDARD OPTIONS (標準オプション)” と “WIDGET SPECIFIC OPTIONS (ウィジェット固有のオプション)” がリストされていることに注意しましょう。前者は多くのウィジェットに共通のオプションのリストで、後者は特定のウィジェットに特有のオプションです。標準オプションの説明は man マニュアルの options(3) にあります。

このドキュメントでは、標準オプションとウィジェット固有のオプションを区別していません。オプションによっては、ある種のウィジェットに適用できません。あるウィジェットがあるオプションに対応しているかどうかは、ウィジェットのクラスによります。例えばボタンには command オプションがありますが、ラベルにはありません。

あるウィジェットがどんなオプションをサポートしているかは、ウィジェットの man マニュアルにリストされています。また、実行時にウィジェットの config() メソッドを引数なしで呼び出したり、 keys() メソッドを呼び出したりして問い合わせることもできます。メソッド呼び出しを行うと辞書型の値を返します。この辞書は、オプションの名前がキー (例えば 'relief') になっていて、値が 5 要素のタプルになっています。

bg のように、いくつかのオプションはより長い名前を持つ共通のオプションに対する同義語になっています (bg は “background” を短縮したものです)。短縮形のオプション名を config() に渡すと、 5 要素ではなく 2 要素のタプルを返します。このタプルには、同義語の名前と「本当の」オプション名が入っています (例えば ('bg', 'background'))。

インデックス | 意味 | 例
0 | オプション名 | 'relief'
1 | データベース検索用のオプション名 | 'relief'
2 | データベース検索用のオプションクラス | 'Relief'
3 | デフォルト値 | 'raised'
4 | 現在の値 | 'groove'

例:

>>> print fred.config()
{'relief' : ('relief', 'relief', 'Relief', 'raised', 'groove')}

もちろん、実際に出力される辞書には利用可能なオプションが全て表示されます。上の表示例は単なる例にすぎません。

24.1.6.2. Packer

packer は Tk のジオメトリ管理メカニズムの一つです。ジオメトリマネジャは、複数のウィジェットの位置を、それぞれのウィジェットを含むコンテナ - 共通の マスタ (master) からの相対で指定するために使います。やや扱いにくい placer (あまり使われないのでここでは取り上げません) と違い、packer は定性的な関係を表す指定子 - 上 (above) 、〜の左 (to the left of) 、 引き延ばし (filling) など - を受け取り、厳密な配置座標の決定を全て行ってくれます。

どんな マスタ ウィジェットでも、大きさは内部の “スレイブ (slave) ウィジェット” の大きさで決まります。 packer は、スレイブウィジェットを pack 先のマスタウィジェット中のどこに配置するかを制御するために使われます。望みのレイアウトを達成するには、ウィジェットをフレームにパックし、そのフレームをまた別のフレームにパックできます。さらに、一度パックを行うと、それ以後の設定変更に合わせて動的に並べ方を調整します。

ジオメトリマネジャがウィジェットのジオメトリを確定するまで、ウィジェットは表示されないので注意してください。初心者のころにはよくジオメトリの確定を忘れてしまい、ウィジェットを生成したのに何も表示されず驚くことになります。ウィジェットは、(例えば packer の pack() メソッドを適用して) ジオメトリを確定した後で初めて表示されます。

pack() メソッドは、キーワード引数つきで呼び出せます。キーワード引数は、ウィジェットをコンテナ内のどこに表示するか、メインのアプリケーションウィンドウをリサイズしたときにウィジェットがどう振舞うかを制御します。以下に例を示します:

fred.pack()                     # デフォルトでは、side = "top"
fred.pack(side = "left")
fred.pack(expand = 1)

24.1.6.3. Packer のオプション

packer と packer の取りえるオプションについての詳細は、man マニュアルや John Ousterhout の本の183ページを参照してください。

anchor

アンカーの型です。 packer が区画内に各スレイブを配置する位置を示します。

expand

ブール値で、 0 または 1 になります。

fill

指定できる値は 'x' 、 'y' 、 'both' 、 'none' です。

ipadx と ipady

スレイブウィジェットの各側面の内側に行うパディング幅を表す長さを指定します。

padx と pady

スレイブウィジェットの各側面の外側に行うパディング幅を表す長さを指定します。

side

指定できる値は 'left', 'right', 'top', 'bottom' です。

24.1.6.4. ウィジェット変数を関連付ける

ウィジェットによっては、(テキスト入力ウィジェットのように) 特殊なオプションを使って、現在設定されている値をアプリケーション内の変数に直接関連付けできます。このようなオプションには variable, textvariable, onvalue, offvalue および value があります。この関連付けは双方向に働きます: 変数の値が何らかの理由で変更されると、関連付けされているウィジェットも更新され、新しい値を反映します。

残念ながら、現在の Tkinter の実装では、 variable や textvariable オプションでは任意の Python の値をウィジェットに渡せません。この関連付け機能がうまく働くのは、 Tkinter モジュール内で Variable というクラスからサブクラス化されている変数によるオプションだけです。

Variable には、 StringVar, IntVar, DoubleVar, BooleanVar といった便利なサブクラスがすでにすでに数多く定義されています。こうした変数の現在の値を読み出したければ、 get() メソッドを呼び出します。また、値を変更したければ set() メソッドを呼び出します。このプロトコルに従っている限り、それ以上なにも手を加えなくてもウィジェットは常に現在値に追従します。

例えば:

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()

        self.entrythingy = Entry()
        self.entrythingy.pack()

        # アプリケーション変数です
        self.contents = StringVar()
        # 変数の値を設定します
        self.contents.set("this is a variable")
        # エントリウィジェットに変数の値を監視させます
        self.entrythingy["textvariable"] = self.contents

        # ユーザがリターンキーを押した時にコールバックを呼び出させます
        # これで、このプログラムは、ユーザがリターンキーを押すと
        # アプリケーション変数の値を出力するようになります。
        self.entrythingy.bind('<Key-Return>',
                              self.print_contents)

    def print_contents(self, event):
        print "hi. contents of entry is now ---->", \
              self.contents.get()

24.1.6.5. ウィンドウマネジャ

Tk には、ウィンドウマネジャとやり取りするための wm というユーティリティコマンドがあります。 wm コマンドにオプションを指定すると、タイトルや配置、アイコンビットマップなどを操作できます。 Tkinter では、こうしたコマンドは Wm クラスのメソッドとして実装されています。トップレベルウィジェットは Wm クラスからサブクラス化されているので、 Wm のメソッドを直接呼び出せます。

あるウィジェットの入っているトップレベルウィンドウを取得したい場合、大抵は単にウィジェットのマスタを参照するだけですみます。とはいえ、ウィジェットがフレーム内にパックされている場合、マスタはトップレベルウィンドウではありません。任意のウィジェットの入っているトップレベルウィンドウを知りたければ _root() メソッドを呼び出してください。このメソッドはアンダースコアがついていますが、これはこの関数が Tkinter の実装の一部であり、Tk の機能に対するインタフェースではないことを示しています。

以下に典型的な使い方の例をいくつか挙げます:

from Tkinter import *
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()

# アプリケーションを作成します
myapp = App()

#
# ウィンドウマネジャクラスのメソッドを呼び出します。
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)

# プログラムを開始します
myapp.mainloop()

24.1.6.6. Tk オプションデータ型

anchor

指定できる値はコンパスの方位です: "n" 、 "ne" 、 "e" 、 "se" 、 "s" 、 "sw" 、 "w" 、 "nw" 、および "center" 。

bitmap

八つの組み込み、名前付きビットマップ: 'error' 、 'gray25' 、 'gray50' 、 'hourglass' 、 'info' 、 'questhead' 、 'question' 、 'warning' 。 X ビットマップファイル名を指定するために、 "@/usr/contrib/bitmap/gumby.bit" のような @ を先頭に付けたファイルへの完全なパスを与えてください。

boolean

整数0または1、あるいは、文字列 "yes" または "no" を渡すことができます。

callback

これは引数を取らない Python 関数ならどれでも構いません。例えば:

def print_it():
        print "hi there"
fred["command"] = print_it

color

色は rgb.txt ファイルの X カラーの名前か、または RGB 値を表す文字列として与えられます。 RGB 値を表す文字列は、4ビット: "#RGB", 8 bit: "#RRGGBB", 12 bit” "#RRRGGGBBB", あるいは、16 bit "#RRRRGGGGBBBB" の範囲を取ります。ここでは、R,G,Bは適切な十六進数ならどんなものでも表します。詳細は、Ousterhout の本の160ページを参照してください。

cursor

cursorfont.h の標準Xカーソル名を、接頭語 XC_ 無しで使うことができます。例えば、handカーソル(XC_hand2)を得るには、文字列 "hand2" を使ってください。あなた自身のビットマップとマスクファイルを指定することもできます。 Ousterhout の本の179ページを参照してください。

distance

スクリーン上の距離をピクセルか絶対距離のどちらかで指定できます。ピクセルは数として与えられ、絶対距離は文字列として与えられます。絶対距離を表す文字列は、単位を表す終了文字 (センチメートルには c 、インチには i 、ミリメートルには m 、プリンタのポイントには p)を伴います。例えば、3.5インチは "3.5i" と表現します。

font

Tkは {courier 10 bold} のようなリストフォント名形式を使います。正の数のフォントサイズはポイント単位で表され。負の数のサイズはピクセル単位で表されます。

geometry

これは widthxheight 形式の文字列です。ここでは、ほとんどのウィジェットに対して幅と高さピクセル単位で (テキストを表示するウィジェットに対しては文字単位で)表されます。例えば: fred["geometry"] = "200x100" 。

justify

指定できる値は文字列です: "left" 、 "center" 、 "right" 、そして "fill" 。

region

これは空白で区切られた四つの要素をもつ文字列です。各要素は指定可能な距離です(以下を参照)。例えば: "2 3 4 5" と "3i 2i 4.5i 2i" と "3c 2c 4c 10.43c" は、すべて指定可能な範囲です。

relief

ウィジェットのボーダのスタイルが何かを決めます。指定できる値は: "raised" 、 "sunken" 、 "flat" 、 "groove" 、と "ridge" 。

scrollcommand

これはほとんど常にスクロールバー・ウィジェットの set() メソッドですが、一引数を取るどんなウィジェットメソッドでもあり得ます。例えば、 Python ソース配布の Demo/tkinter/matt/canvas-with-scrollbars.py ファイルを参照してください。

wrap:

次の中の一つでなければなりません: "none" 、 "char" 、あるいは "word" 。

24.1.6.7. バインドとイベント

ウィジェットコマンドからの bind メソッドによって、あるイベントを待つことと、そのイベント型が起きたときにコールバック関数を呼び出すことができるようになります。 bind メソッドの形式は:

def bind(self, sequence, func, add=''):

ここでは:

sequence

は対象とするイベントの型を示す文字列です。 (詳細については、bind の man ページと John Ousterhout の本の201ページを参照してください。)

func

は一引数を取り、イベントが起きるときに呼び出される Python 関数です。イベント・インスタンスが引数として渡されます。 (このように実施される関数は、一般に callbacks として知られています。)

add

はオプションで、 '' か '+' のどちらかです。空文字列を渡すことは、このイベントが関係する他のどんなバインドをもこのバインドが置き換えることを意味します。 '+' を使う仕方は、この関数がこのイベント型にバインドされる関数のリストに追加されることを意味しています。

例えば:

def turnRed(self, event):
    event.widget["activeforeground"] = "red"

self.button.bind("<Enter>", self.turnRed)

イベントのウィジェットフィールドが turnRed() コールバック内でどのようにアクセスされているかに注意してください。このフィールドは X イベントを捕らえるウィジェットを含んでいます。以下の表はあなたがアクセスできる他のイベントフィールドとそれらの Tk での表現方法の一覧です。Tk man ページを参照するときに役に立つでしょう。

Tk      Tkinterイベントフィールド       Tk      Tkinterイベントフィールド
--      -------------------------       --      -------------------------
%f      focus                           %A      char
%h      height                          %E      send_event
%k      keycode                         %K      keysym
%s      state                           %N      keysym_num
%t      time                            %T      type
%w      width                           %W      widget
%x      x                               %X      x_root
%y      y                               %Y      y_root

24.1.6.8. index パラメータ

たくさんのウィジェットが渡される”index”パラメータを必要とします。これらはテキストウィジェットでの特定の場所や、エントリウィジェットでの特定の文字、あるいは、メニューウィジェットでの特定のメニュー項目を指定するために使われます。

エントリウィジェットのインデックス(インデックス、ビューインデックスなど)

エントリウィジェットは表示されているテキスト内の文字位置を参照するオプションを持っています。テキストウィジェットにおけるこれらの特別な位置にアクセスするために、これらの Tkinter 関数を使うことができます:

AtEnd()

テキストの最後の位置を参照します

AtInsert()

テキストカーソルの位置を参照します

AtSelFirst()

選択されたテキストの先頭の位置を指します

AtSelLast()

選択されているテキストおよび最終的に選択されたテキストの末尾の位置を示します。

At(x[, y])

ピクセル位置 x, y (テキストを一行だけ含むテキストエントリウィジェットの場合には y は使われない)の文字を参照します。

テキストウィジェットのインデックス

テキストウィジェットに対するインデックス記法はとても機能が豊富で、 Tk manページでよく説明されています。

メニューのインデックス(menu.invoke()、menu.entryconfig()など)

メニューに対するいくつかのオプションとメソッドは特定のメニュー項目を操作します。メニューインデックスはオプションまたはパラメータのために必要とされるときはいつでも、以下のものを渡すことができます:

頭から数えられ、0で始まるウィジェットの数字の位置を指す整数。

文字列 'active' 、現在カーソルがあるメニューの位置を指します。

最後のメニューを指す文字列 "last" 。

@6 のような @ が前に来る整数。ここでは、整数がメニューの座標系における y ピクセル座標として解釈されます。

文字列 "none" 、どんなメニューエントリもまったく指しておらず、ほとんどの場合、すべてのエントリの動作を停止させるために menu.activate() と一緒に使われます。そして、最後に、

メニューの先頭から一番下までスキャンしたときに、メニューエントリのラベルに一致したパターンであるテキスト文字列。このインデックス型は他すべての後に考慮されることに注意してください。その代わりに、それは last 、 active または none とラベル付けされたメニュー項目への一致は上のリテラルとして解釈されることを意味します。

24.1.6.9. 画像

Bitmap/Pixelmap 画像を Tkinter.Image のサブクラスを使って作ることができます:

BitmapImage は X11 ビットマップデータに対して使えます。

PhotoImage は GIF と PPM/PGM カラービットマップに対して使えます。

画像のどちらの型でも file または data オプションを使って作られます (その上、他のオプションも利用できます)。

image オプションがウィジェットにサポートされるところならどこでも、画像オブジェクトを使うことができます(例えば、ラベル、ボタン、メニュー)。これらの場合では、Tk は画像への参照を保持しないでしょう。画像オブジェクトへの最後の Python の参照が削除されたときに、おまけに画像データが削除されます。そして、どこで画像が使われていようとも、Tk は空の箱を表示します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.2. ttk — Tk themed widgets

ttk モジュールは Tk 8.5 で導入された Tk のテーマ付きウィジェットへのアクセスを提供します。 Tk 8.5 が無い環境で Python がコンパイルされていた場合でも、 Tile がインストールされていればこのモジュールはそれを使おうとします。しかし、 X11 上のフォントのアンチエイリアスや透過ウィンドウ (X11 ではコンポジションウィンドウマネージャが必要です) などの新しい Tk が提供している機能は使えません。

ttk の基本的なアイディアは、拡張可能性のためにウィジェットの動作を実装するコードと見た目を記述するコードを分離することです。

参考

Tk Widget Styling Support [http://www.tcl.tk/cgi-bin/tct/tip/48]

Tk のテーマサポートの立ち上げのドキュメント

24.2.1. Ttk を使う

Ttk を使い始めるために、モジュールをインポートします:

import ttk

しかしこのようなコードでは

from Tkinter import *

このように使いたいことがあるかもしれません

from Tkinter import *
from ttk import *

このように書くと、いくつかの ttk ウィジェット (Button, Checkbutton, Entry, Frame, Label, LabelFrame, Menubutton, PanedWindow, Radiobutton, Scale, Scrollbar) は自動的に Tk ウィジェットを置き換えます。

これにはプラットフォームをまたいでより良い見た目を得られるという、直接的な利益がありますが、ウィジェットは完全な互換性を持っているわけではないことに注意してください。一番の違いは “fg” や “bg” やその他のスタイルに関係するウィジェットのオプションが Ttk ウィジェットから無くなっていることです。同じ (もしくはより良い) 見た目にするためには ttk.Style を使ってください。

参考

Converting existing applications to use the Tile widgets [http://tktable.sourceforge.net/tile/doc/converting.txt]

Tcl において、アプリケーションを新しいウィジェットに移行するときに出てくる典型的な差異について書かれているテキスト

24.2.2. Ttk ウィジェット

Ttk には 17 のウィジェットがあり、そのうち 11 は Tkinter に既にあるものです: Button, Checkbutton, Entry, Frame, Label, LabelFrame, Menubutton, PanedWindow, Radiobutton, Scale, Scrollbar 。新しい 6 つのウィジェットクラスは次のものです: Combobox, Notebook, Progressbar, Separator, Sizegrip, Treeview 。これらのクラスは全て Widget の子クラスです。

上にも書いた通り、スタイルの記述コードと同様に見た目も変わっていることに気付くでしょう。それを見せるために、非常に簡単な例を以下に示します。

Tk のコード

l1 = Tkinter.Label(text="Test", fg="black", bg="white")
l2 = Tkinter.Label(text="Test", fg="black", bg="white")

それに相当する Ttk のコード

style = ttk.Style()
style.configure("BW.TLabel", foreground="black", background="white")

l1 = ttk.Label(text="Test", style="BW.TLabel")
l2 = ttk.Label(text="Test", style="BW.TLabel")

TtkStyling についての情報は Style クラスの文書を読んでください。

24.2.3. ウィジェット

ttk.Widget はTk のテーマ付きウィジェットがサポートしている標準のオプションやメソッドを定義するもので、これを直接インスタンス化するものではありません。

24.2.3.1. 標準オプション

全ての ttk ウィジェットは以下のオプションを受け付けます:

オプション | 説明
class | ウィンドウクラスを指定します。このクラスはオプションデータベースにウィンドウの他のオプションについて問い合わせを行うときに使われ、これによりウィンドウのデフォルトのバインドタグを決定したり、ウィジェットのデフォルトのレイアウトやスタイルを選択します。これは読み取り専用のオプションでウィンドウが作られるときにのみ指定できます。
cursor | このウィジェットで使うマウスカーソルを指定します。空文字列 (デフォルト) が設定されている場合は、カーソルは親ウィジェットのものを引き継ぎます。
takefocus | キーボードによる移動のときにウィンドウがフォーカスを受け入れるかを決定します。 0 、 1 、空文字列のいずれかを返します。 0 の場合、キーボードによる移動でそのウィンドウは常にスキップされます。 1 の場合、そのウィンドウが表示されているときに限り入力フォーカスを受け入れます。空文字列は、移動スクリプトによってウィンドウにフォーカスを当てるかどうかが決まることを意味します。
style | 独自のウィジェットスタイルを指定するのに使われます。

24.2.3.2. スクロール可能ウィジェットのオプション

以下のオプションはスクロールバーで操作されるウィジェットが持っているオプションです。

オプション
説明

xscrollcommand

水平方向のスクロールバーとのやり取りに使われます。

ウィジェットのウィンドウが再描画されたとき, ウィジェットは scrollcommand に基いて Tcl コマンドを生成します。

通常このオプションにはあるスクロールバーの Scrollbar.set() メソッドが設定されます。こうすると、ウィンドウの見た目が変わったときにスクロールバーの状態も更新されます。

yscrollcommand
垂直方向のスクロールバーとのやり取りに使われます。詳しいことは、上記を参照してください。

24.2.3.3. ラベルオプション

以下のオプションはラベルやボタンやボタンに類似したウィジェットが持っているオプションです。

オプション
説明

text
ウィジェットに表示される文字列を指定します。

textvariable
text オプションの代わりに使う値の変数名を指定します。

underline
このオプションを設定すると、文字列の中で下線を引く文字のインデックス (0 基点) を指定します。下線が引かれた文字はショートカットとして使われます。

image
表示する画像を指定します。これは 1 つ以上の要素を持つリストです。先頭の要素はデフォルトの画像名です。残りの要素は Style.map() で定義されているような状態名と値のペアの並びで、ウィジェットがある状態、もしくはある状態の組み合わせにいるときに使用する別の画像を指定します。このリストにある全ての画像は同じサイズでなればなりません。

compound

text オプションと image オプションが両方とも指定されていた場合に、テキストに対して画像をどう配置するかを指定します。

text: テキストのみ表示する

image: 画像のみ表示する

top, bottom, left, right: それぞれ画像をテキストの上、下、左、右に配置する。

none: デフォルト。もしあれば画像を表示し、そうでなければテキストを表示する

width
0 より大きい場合、テキストラベルを作成するのにどれくらいのスペースを使うかを文字の幅で指定します。 0 より小さい場合、最小の幅が指定されます。 0 もしくは無指定の場合、テキストラベルに対して自然な幅が使われます。

24.2.3.4. 互換性オプション

オプション | 説明
state | “normal” か “disabled” に設定され、 “disabled” 状態のビットをコントロールします。これは書き込み専用のオプションです: これを設定するとウィジェットの状態を変更できますが、 Widget.state() メソッドはこのオプションに影響を及ぼしません。

24.2.3.5. ウィジェットの状態

ウィジェットの状態は独立した状態フラグのビットマップです。

フラグ | 説明
active | マウスカーソルがウィジェットの上にあり、マウスのボタンをクリックすることで何らかの動作をさせられます。
disabled | プログラムによってウィジェットは無効化されています。
focus | ウィジェットにキーボードフォーカスがあります。
pressed | ウィジェットは押されています。
selected | チェックボタンやラジオボタンのようなウィジェットでの “オン” や “チェック有” や “選択中” に当たります。
background | Windows と Mac には “アクティブな” もしくは最前面のウィンドウという概念があります。背面のウィンドウにあるウィジェットには background 状態が設定され、最前面のウィンドウにあるウィジェットでは解除されます。
readonly | ウィジェットはユーザからの変更を受け付けません。
alternate | ウィジェット特有の切り替え表示になっています。
invalid | ウィジェットの値が不正です。

状態仕様は状態名の並びになっていて、状態名の先頭にはビットがオフになっていることを示す感嘆符が付くことがあります。

24.2.3.6. ttk.Widget

以下に書かれているメソッドに加えて、 ttk.Widget クラスは Tkinter.Widget.cget() メソッドと Tkinter.Widget.configure() メソッドをサポートしています。

class ttk.Widget

identify(x, y)

x y の位置にある要素の名前、もしくはその位置に要素が無ければ空文字列を返します。

x と y はウィジェットに対するピクセル単位の座標です。

instate(statespec[, callback=None[, *args[, **kw]]])

ウィジェットの状態をチェックします。コールバックが指定されていない場合、ウィジェットの状態が statespec に一致していれば True 、そうでなければ False を返します。コールバックが指定されていて、ウィジェットの状態が statespec に一致している場合、引数に args を指定してそのコールバックを呼び出します。

state([statespec=None])

ウィジェットの状態を変更したり、取得したりします。 statespec が指定されている場合、それに応じてウィジェットの状態を設定し、どのフラグが変更されたかを示す新しい statespec を返します。 statespec が指定されていない場合、現在の状態フラグを返します。

通常 statespec はリストもしくはタプルです。

24.2.4. コンボボックス

ttk.Combobox ウィジェットはテキストフィールドと値のポップダウンリストを結び付けます。このウィジェットは Entry の子クラスです。

Widget から継承したメソッド (Widget.cget(), Widget.configure(), Widget.identify(), Widget.instate(), Widget.state()) と Entry から継承したメソッド (Entry.bbox(), Entry.delete(), Entry.icursor(), Entry.index(), Entry.inset(), Entry.selection(), Entry.xview()) に加え、このクラスには ttk.Combobox で説明するメソッドがあります。

24.2.4.1. オプション

このウィジェットは以下のオプションを受け付けます:

オプション | 説明
exportselection | 真偽値を取る。設定されている場合、ウィジェットの選択はウィンドウマネージャの選択とリンクしています。(例えば、 Misc.selection_get() を実行することで得られます。)
justify | ウィジェットの中でテキストをどう配置するかを指定します。 “left”, “center”, “right” のうちのどれか 1 つです。
height | ポップダウンリストの高さを行数で指定します。
postcommand | コンボボックスの値を表示する直前に呼び出される、 (Misc.register() などで登録した) スクリプトです。どの値を表示するかについても指定できます。
state | “normal”, “readonly”, “disabled” のどれか 1 つです。 “readonly” 状態では、直接入力値を編集することはできず、ユーザはドロップダウンリストから値を 1 つ選ぶことしかできません。 “normal” 状態では、テキストフィールドは直接編集できます。 “disabled” 状態では、コンボボックスは一切反応しません。
textvariable | コンボボックスの値とリンクさせる変数名を指定します。その変数の値が変更されたとき、ウィジェットの値は更新されます。ウィジェットの値が更新されたときも同様です。 Tkinter.StringVar を参照してください。
values | ドロップダウンリストに表示する値のリストを指定します。
width | 入力ウィンドウに必要な幅をウィジェットのフォントの平均的なサイズの文字で測った、文字数を指定します。

24.2.4.2. 仮想イベント

コンボボックスウィジェットは、ユーザが値のリストから1つ選んだときに仮想イベント <<ComboboxSelected>> を生成します。

24.2.4.3. ttk.Combobox

class ttk.Combobox

current([newindex=None])

newindex が指定されている場合、コンボボックスの値がドロップダウンリストの newindex の位置にある値に設定されます。そうでない場合、現在の値のインデックスを、もしくは現在の値がリストに含まれていないなら -1 を返します。

get()

コンボボックスの現在の値を返します。

set(value)

コンボボックスの値を value に設定します。

24.2.5. ノートブック

Ttk ノートブックウィジェットは複数のウィンドウを管理し、同時に 1 つのウィンドウを表示します。それぞれの子ウィンドウはタブの関連付けられていて、ユーザはそれを選択して表示されているウィンドウを切り替えます。

24.2.5.1. オプション

このウィジェットは以下のオプションを受け付けます:

オプション | 説明
height | 0 より大きな値が設定されている場合、 (内部のパディングやタブを含まない) ペイン領域に必要な高さを指定します。設定されていない場合、全てのペインの高さの最大値が使われます。
padding | ノートブックの外周に付け足す追加の領域の量を指定します。パディングは最大 4 個の長さ指定のリストです: 左、上、右、下の順で指定します。4 個より少ない場合、デフォルトで下は上と、右は左と、上は左と同じ値が、それぞれ使われます。
width | 0 より大きな値が指定されている場合、 (内部のパディングを含まない) ペイン領域に必要な幅を指定します。設定されていない場合、全てのペインの幅の最大値が使われます。

24.2.5.2. タブオプション

タブ用のオプションもあります:

オプション | 説明
state | “normal”, “disabled”, “hidden” のうちどれか 1 つです。 “disabled” の場合、タブは選択することができません。 “hidden” の場合、タブは表示されません。
sticky | ペイン領域の中に子ウィンドウがどう置かれるかを指定します。指定する値は “n”, “s”, “e”, “w” からなる 0 文字以上の文字列です。配置マネージャの grid() と同様に、それぞれの文字は子ウィンドウが (北、南、東、西の) どの辺に対して追随するかに対応しています。
padding | ノートブックとこのペインの間に付け足す追加の領域の量を指定します。文法はこのウィジェットの padding オプションと同じです。
text | タブに表示するテキストを指定します。
image | タブに表示する画像を指定します。 Widget のラベルオプション の説明を参照してください。
compound | text オプションと image オプションが両方指定されているときにテキストに対して画像をどう表示するかを指定します。指定する値については ラベルオプション を参照してください。
underline | テキスト中の下線を引く文字のインデックス (0 基点) を指定します。 Notebook.enable_traversal() が呼ばれていた場合、下線が引かれた文字はショートカットとして使われます。

24.2.5.3. タブ識別子

ttk.Notebook のいくつかのメソッドにある tab_id は以下の形式を取ります:

0 からタブの数の間の整数。

子ウィンドウの名前。

タブを指し示す “@x,y” という形式の位置指定。

現在選択されているタブを指し示すリテラル文字列 “current”。

タブ数を返すリテラル文字列 “end” (Notebook.index() でのみ有効)。

24.2.5.4. 仮想イベント

このウィジェットは新しいタブが選択された後に仮想イベント <<NotebookTabChanged>> を生成します。

24.2.5.5. ttk.Notebook

class ttk.Notebook

add(child, **kw)

ノートブックに新しいタブを追加します。

ウィンドウが現在ノートブックによって管理されているが隠れている場合、以前の位置に復元します。

利用可能なオプションのリストについては タブオプション を参照してください。

forget(tab_id)

tab_id で指定されたタブを削除します。関連付けられていたウィンドウは切り離され、管理対象でなくなります。

hide(tab_id)

tab_id で指定されたタブを隠します。

タブは表示されませんが、関連付いているウィンドウはノートブックによって保持されていて、その設定も記憶されています。隠れたタブは add() コマンドで復元できます。

identify(x, y)

x y の位置にあるタブの名前を、そこにタブが無ければ空文字列を返します。

index(tab_id)

tab_id で指定されたタブのインデックスを、 tab_id が文字列の “end” だった場合はタブの総数を返します。

insert(pos, child, **kw)

指定された位置にペインを挿入します。

pos は文字列の “end” か整数のインデックスか管理されている子ウィンドウの名前です。 child が既にノートブックの管理対象だった場合、指定された場所に移動させます。

利用可能なオプションのリストについては タブオプション を参照してください。

select([tab_id])

指定された tab_id を選択します。

関連付いている子ウィンドウは表示され、直前に選択されていたウィンドウは (もし異なれば) 表示されなくなります。 tab_id が指定されていない場合は、現在選択されているペインのウィジェット名を返します。

tab(tab_id[, option=None[, **kw]])

指定された tab_id のオプションを問い合わせたり、変更したりします。

kw が与えられなかった場合、タブのオプション値の辞書を返します。 option が指定されていた場合、その option の値を返します。それ以外の場合は、オプションに対応する値が設定されます。

tabs()

ノートブックに管理されているウィンドウのリストを返します。

enable_traversal()

このノートブックを含む最上位にあるウィンドウでのキーボード移動を可能にします。

これによりノートブックを含んだ最上位にあるウィンドウに対し、以下のキーバインディングが追加されます:

Control-Tab: 現在選択されているタブの 1 つ次のタブを選択します。

Shift-Control-Tab: 現在選択されているタブの 1 つ前のタブを選択します。

Alt-K: K があるタブの (下線が引かれた) ショートカットキーだとして、そのタブを選択します。

ネストしたノートブックも含め、1 つのウィンドウの最上位にある複数のノートブックのキーボード移動が可能になることもあります。しかしノートブック上の移動は、全てのペインが同じノートブックを親としているときのみ正しく動作します。

24.2.6. プログレスバー

ttk.Progressbar ウィジェットは長く走る処理の状態を表示します。このウィジェットは 2 つのモードで動作します: 決定的モードでは、全ての処理の総量のうち完了した量を表示します。非決定的モードでは、今何か処理が行われていることをユーザに示します。

24.2.6.1. オプション

このウィジェットは以下のオプションを受け付けます:

オプション | 説明
orient | “horizontal” もしくは “vertical” のいずれかです。プログレスバーの方向を指定します。
length | プログレスバーの長さを指定します。 (水平方向の場合は幅、垂直方向の場合は高さです)
mode | “determinate” か “indeterminate” のいずれかです。
maximum | 最大値を数値で指定します。デフォルトは 100 です。
value | プログレスバーの現在値です。決定的 (“determinate”) モードでは、完了した処理の量を表します。非決定的 (“indeterminate”) モードでは、 maximum を法として解釈され、値が maximum に達したときにプログレスバーは 1 “サイクル” を完了したことになります。
variable | value オプションとリンクさせる変数名です。指定されている場合、変数の値が変更されるとプログレスバーの値は自動的にその値に設定されます。
phase | 読み取り専用のオプションです。このウィジェットの値が 0 より大きく、かつ決定的モードでは最大値より小さいときに、ウィジェットが定期的にこのオプションの値を増加させます。このオプションは現在の画面テーマが追加のアニメーション効果を出すのに使います。

24.2.6.2. ttk.Progressbar

class ttk.Progressbar

start([interval])

自動増加モードを開始します: interval ミリ秒ごとに Progressbar.step() を繰り返し呼び出すタイマーイベントを設定します。引数で指定しない場合は、 interval はデフォルトで 50 ミリ秒になります。

step([amount])

プログレスバーの値を amount だけ増加させます。

引数で指定しない場合は、 amount はデフォルトで 1.0 になります。

stop()

自動増加モードを停止します: このプログレスバーの Progressbar.start() で開始された繰り返しのタイマーイベントを全てキャンセルします。

24.2.7. セパレータ

ttk.Separator ウィジェットは水平もしくは垂直のセパレータを表示します。

ttk.Widget から継承したメソッド以外にメソッドを持ちません。

24.2.7.1. オプション

このウィジェットは以下のオプションを受け付けます:

オプション | 説明
orient | “horizontal” か “vertical” のいずれかです。セパレータの方向を指定します。

24.2.8. サイズグリップ

(グローボックスとしても知られる) ttk.Sizegrip ウィジェットは、押してつまみ部分をドラッグすることで最上位のウィンドウのサイズを変更できます。

このウィジェットは ttk.Widget から継承したもの以外のオプションとメソッドを持ちません。

24.2.8.1. プラットフォーム固有のメモ

Mac OS X では、最上位のウィンドウにはデフォルトで組み込みのサイズグリップが含まれています。組み込みのグリップが Sizegrip を隠してしまうので、 Sizegrip を追加するのは無害です。

24.2.8.2. バグ

最上位のウィンドウの位置がスクリーンに対して右や下に指定されている場合 (などなど....)、 Sizegrip ウィジェットはウィンドウのサイズ変更をしません。

このウィジェットは “南東” 方向のサイズ変更しかサポートしていません。

24.2.9. ツリービュー

ttk.Treeview ウィジェットは階層のある要素 (アイテム) の集まりを表示します。それぞれの要素はテキストラベル、オプションの画像、オプションのデータのリストを持っています。データはラベルの後に続くカラムに表示されます。

データが表示される順序はウィジェットの displaycolumns オプションで制御されます。ツリーウィジェットはカラムヘッダを表示することもできます。カラムには数字もしくはウィジェットの columns オプションにある名前でアクセスできます。カラム識別子 を参照してください。

それぞれの要素は一意な名前で識別されます。要素の作成時に識別子が与えられなかった場合、ウィジェットが要素の識別子を生成します。このウィジェットには {} という名前の特別なルート要素があります。ルート要素自身は表示されません; その子要素たちが階層の最上位に現れます。

それぞれの要素はタグのリストも持っていて、イベントバインディングと個別の要素を関連付け、要素の見た目を管理するのに使えます。

ツリービューウィジェットは水平方向と垂直方向のスクロールをサポートしていて、スクロール可能ウィジェットのオプション に記述してあるオプションと Treeview.xview() メソッドおよび Treeview.yview() メソッドが使えます。

24.2.9.1. オプション

このウィジェットは以下のオプションを受け付けます:

オプション
説明

columns
カラム数とその名前を指定するカラム識別子のリストです。

displaycolumns
どのデータカラムをどの順序で表示するかを指定する、 (名前もしくは整数のインデックスの) カラム識別子のリストか、文字列 “#all” です。

height
表示する行数を指定します。メモ: 表示に必要な幅はカラム幅の合計から決定されます。

padding
ウィジェットの内部のパディングのサイズを指定します。パディングは最大 4 個の長さ指定のリストです。

selectmode

組み込みのクラスバインディングが選択状態をどう管理するかを指定します。設定する値は “extended”, “browse”, “none” のどれか 1 つです。 “extended” に設定した場合 (デフォルト)、複数の要素が選択できます。 “browse” に設定した場合、同時に 1 つの要素しか選択できません。 “none” に設定した場合、選択を変更することはできません。

このオプションの値によらず、アプリケーションのコードと関連付けられているタグからは好きなように選択状態を設定できます。

show

ツリーのどの要素を表示するかを指定する、以下にある値を 0 個以上含むリストです。

tree: カラム #0 にツリーのラベルを表示します。

headings: ヘッダ行を表示します。

デフォルトは “tree headings” 、つまり全ての要素を表示します。

メモ: show=”tree” が指定されていない場合でも、カラム #0 は常にツリーカラムを参照します。

24.2.9.2. 要素オプション

以下の要素オプションは、ウィジェットの insert コマンドと item コマンドで要素に対して指定できます。

オプション
説明

text
アイテムに表示するテキストラベルです。

image
ラベルの左に表示される Tk 画像です。

values

要素に関連付けられている値のリストです。

それぞれの要素はウィジェットの columns オプションと同じ数の値を持たなければいけません。 columns オプションより少ない場合、残りの値は空として扱われます。 columns オプションより多い場合、余計な値は無視されます。

open
要素の子供を表示するか隠すかを指示する真偽値です。

tags
この要素に関連付いているタグのリストです。

24.2.9.3. タグオプション

以下のオプションはタグに対して設定できます:

オプション | 説明
foreground | テキストの色を指定します。
background | セルや要素の背景色を指定します。
font | テキストを描画するときに使うフォントを指定します。
image | 要素の image オプションが空だった場合に使用する画像を指定します。

24.2.9.4. カラム識別子

カラム識別子は以下のいずれかの形式を取ります:

columns オプションのリストにある名前。

n 番目のデータカラムを指し示す整数 n 。

n を整数として n 番目の表示されているカラムを指し示す #n という形式の文字列。

メモ:

要素のオプション値は実際に格納されている順序とは違った順序で表示されることがあります。

show=”tree” が指定されていない場合でも、カラム #0 は常にツリーカラムを指しています。

データカラムを指す数字は、要素の values オプションのリストのインデックスです; 表示カラムを指す数字は、値が表示されているツリーのカラム番号です。ツリーラベルはカラム #0 に表示されます。 displaycolumns オプションが設定されていない場合は、 n 番目のデータカラムはカラム #n+1 に表示されます。再度言っておくと、 カラム #0 は常にツリーカラムを指します 。

24.2.9.5. 仮想イベント

ツリービューは以下の仮想イベントを生成します。

イベント | 説明
<<TreeviewSelect>> | 選択状態が変更されたときに生成されます。
<<TreeviewOpen>> | フォーカスが当たっている要素に open=True が設定される直前に生成されます。
<<TreeviewClose>> | フォーカスが当たっている要素に open=False が設定された直後に生成されます。

Treeview.focus() メソッドと Treeview.selection() メソッドは変更を受けた要素を判別するのに使えます。

24.2.9.6. ttk.Treeview

class ttk.Treeview

bbox(item[, column=None])

(ツリービューウィジェットのウィンドウを基準として) 指定された item のバウンディングボックス情報を (x 座標, y 座標, 幅, 高さ) の形式で返します。

column が指定されている場合は、セルのバウンディングボックスを返します。 (例えば、閉じた状態の要素の子供であったり、枠外にスクロールされていて) item が見えなくなっている場合は、空文字列が返されます。

get_children([item])

item の子要素のリストを返します。

item が指定されていなかった場合は、ルート要素の子供が返されます。

set_children(item, *newchildren)

item の子要素を newchildren で置き換えます。

item にいる子供のうち newchildren にないものはツリーから切り離されます。 newchildren にあるどの要素も item の祖先であってはいけません。 newchildren を指定しなかった場合は、 item の子要素が全て切り離されることに注意してください。

column(column[, option=None[, **kw]])

指定した column のオプションを問い合わせたり、変更したりします。

kw が与えられなかった場合は、カラムのオプション値の辞書が返されます。 option が指定されていた場合は、その option の値が返されます。それ以外の場合は、オプションに値を設定します。

設定できるオプションとその値は次の通りです:

id

カラム名を返します。これは読み取り専用のオプションです。

anchor: 標準の Tk anchor の値

このカラムでセルに対してテキストをどう配置するかを指定します。

minwidth: 幅

カラムの最小幅をピクセル単位で表したものです。ツリービューウィジェットは、ウィジェットのサイズが変更されたりカラムをユーザがドラッグして移動させたりしたときに、このオプションで指定した幅より狭くすることはありません。

stretch: True もしくは False

ウィジェットがサイズ変更されたとき、カラムの幅をそれに合わせるかどうかを指定します。

width: 幅

カラムの幅をピクセル単位で表したものです。

ツリーカラムの設定を行うには、 column = “#0” を付けてこのメソッドを呼び出してください。

delete(*items)

指定された items とその子孫たち全てを削除します。

ルート要素は削除されません。

detach(*items)

指定された items を全てツリーから切り離します。

The items and all of their descendants are still present, and may be reinserted at another point in the tree, but will not be displayed. その要素と子孫たちは依然として存在していて、ツリーの別の場所に再度挿入することができますが、隠された状態になり表示はされません。

ルート要素は切り離されません。

exists(item)

指定された item がツリーの中にあれば True を返します。

focus([item=None])

item が指定されていた場合は、 item にフォーカスを当てます。そうでない場合は、現在フォーカスが当たっている要素が、どの要素にもフォーカスが当たっていない場合は ‘’ が返されます。

heading(column[, option=None[, **kw]])

指定された column の heading のオプションを問い合わせたり、変更したりします。

kw が与えられなかった場合は、見出しのオプション値の辞書が返されます。 option が指定されている場合は、 option の値が返されます。それ以外の場合は、オプションに値を設定します。

設定できるオプションとその値は次の通りです:

text: テキスト

カラムの見出しに表示するテキスト。

image: 画像名

カラムの見出しの右に表示する画像を指定します。

anchor: anchor

見出しのテキストをどう配置するかを指定します。標準の Tk anchor の値です。

command: コールバック

見出しラベルがクリックされたときに実行されるコールバックです。

ツリーカラムの見出しの設定を行うには、 column = “#0” を付けてこのメソッドを呼び出してください。

identify(component, x, y)

x y で与えられた場所にある指定された component の説明を返します。その場所に指定された component が無い場合は空文字列を返します。 (訳注: component には “region”, “item”, “column”, “row”, “element” が指定でき、それぞれ “cell”, “heading” などの場所の名前、要素の識別子、 #n という形式のカラム名、その行にある要素の識別子、 “text”, “padding” などの画面構成要素の名前を返します。)

identify_row(y)

y 座標が y の位置にある要素の識別子を返します。

identify_column(x)

x 座標が x の位置にあるセルのデータカラムの識別子を返します。

ツリーカラムは #0 という識別子を持ちます。

identify_region(x, y)

以下のうち 1 つを返します:

region | 意味
heading | ツリーの見出し領域
separator | 2 つのカラム見出しの間のスペース
tree | ツリーの領域
cell | データセル

使用可能バージョン: Tk 8.6

identify_element(x, y)

x y の位置にある画面構成要素の名前を返します。

使用可能バージョン: Tk 8.6

index(item)

親要素の子要素リストの中での item のインデックスを返します。

insert(parent, index[, iid=None[, **kw]])

新しい要素を作り、その要素の識別子を返します。

parent は親となる要素の識別子で、空文字列にすると新しい要素を最上位に作成します。 index は整数もしくは “end” という値で、それによって親要素の子要素リストのどこに新しい要素を挿入するかを指定します。 index が 0 以下だった場合は、新しい要素は先頭に挿入されます; index が現在の子要素の数以上だった場合は末尾に挿入されます。 iid が指定された場合は、要素の識別子として使われます; iid はまだツリーに存在していないものに限ります。それ以外の場合は、一意な識別子が生成されます。

使用できるオプションのリストについては 要素オプション を参照してください。

item(item[, option[, **kw]])

指定された item のオプションを問い合わせたり、変更したりします。

オプションが与えられなかった場合は、要素のオプションと値が辞書の形で返されます。 option が指定された場合は、そのオプションの値が返されます。それ以外の場合は、 kw で与えられたようにオプションに値が設定されます。

move(item, parent, index)

item を parent の子要素リストの index の位置に移動します。

要素を自身の子孫の下に移動させるのは許されていません。 index が 0 以下の場合、 item は先頭に移動されます; 子要素の数以上だった場合、末尾に移動されます。 item が切り離された状態の場合は、再度取り付けられます。

next(item)

item の 1 つ下の兄弟の識別子を、 item が親にとって一番下の子供だった場合 ‘’ を返します。

parent(item)

item の親の識別子を、 item が階層の最上位にいた場合 ‘’ を返します。

prev(item)

item の 1 つ上の兄弟の識別子を、 item が親にとって一番上の子供だった場合 ‘’ を返します。

reattach(item, parent, index)

Treeview.move() のエイリアスです。

see(item)

item を見える状態にします。

item の全ての子孫の open オプションを True にし、必要であれば item がツリーの見える範囲に来るようにウィジェットをスクロールさせます。

selection([selop=None[, items=None]])

selop が指定されなかった場合は、選択されている要素を返します。そうでなければ、以下の選択メソッドに従って動作します。 (訳注: selop には “set”, “add”, “remove”, “toggle” のうち 1 つが指定できます。 items にはそれぞれのメソッドの引数を指定します。)

selection_set(items)

新しく選択状態の要素が items になります。

selection_add(items)

選択状態の要素として items を追加します。

selection_remove(items)

選択状態の要素から items を取り除きます。

selection_toggle(items)

items のそれぞれの要素の選択状態を入れ替えます。

set(item[, column=None[, value=None]])

1 引数で呼び出された場合、指定された item のカラムと値のペアからなる辞書を返します。 2 引数で呼び出された場合、指定された column の現在の値を返します。 3 引数で呼び出された場合、与えられた item の column を指定された値 value に設定します。

tag_bind(tagname[, sequence=None[, callback=None]])

与えられたイベント sequence 用のコールバックをタグ tagname にバインドします。イベントが要素に渡ってきたときに、要素の tags オプションのそれぞれのコールバックが呼び出されます。

tag_configure(tagname[, option=None[, **kw]])

指定された tagname のオプションを問い合わせたり、変更したりします。

kw が与えられなかった場合、 tagname のオプション設定を辞書の形で返します。 option が指定された場合、指定された tagname の option の値を返します。それ以外の場合、与えられた tagname のオプションに値を設定します。

tag_has(tagname[, item])

item が指定されていた場合、指定された item が与えられた tagname を持っているかどうかに従って 1 または 0 が返されます。そうでない場合、指定されたタグを持つ全ての要素のリストを返します。

使用可能バージョン: Tk 8.6

xview(*args)

ツリービューの水平方向の位置を問い合わせたり、変更したりします。

yview(*args)

ツリービューの垂直方向の位置を問い合わせたり、変更したりします。

24.2.10. Ttk スタイル

ttk のそれぞれのウィジェットにはスタイルが関連付けられていて、それと動的もしくはデフォルトで設定される要素のオプションによってウィジェットを構成する要素とその配置を指定します。デフォルトではスタイル名はウィジェットのクラス名と同じですが、ウィジェットの style オプションで上書きすることができます。ウィジェットのクラス名が分からない場合は、 Misc.winfo_class() (somewidget.winfo_class()) メソッドを使ってください。

参考

Tcl‘2004 conference presentation [http://tktable.sourceforge.net/tile/tile-tcl2004.pdf]

この文書ではテーマエンジンがどう動くかを説明しています

class ttk.Style

このクラスはスタイルデータベースを操作するために使われます。

configure(style, query_opt=None, **kw)

style の指定されたオプションのデフォルト値を問い合わせたり、設定したりします。

kw のそれぞれのキーはオプション名で値はそのオプションの値の文字列です。

例えば、全てのデフォルトのボタンをパディングのある平らな見た目にし背景の色を変更するには以下のようにします

import ttk
import Tkinter

root = Tkinter.Tk()

ttk.Style().configure("TButton", padding=6, relief="flat",
   background="#ccc")

btn = ttk.Button(text="Sample")
btn.pack()

root.mainloop()

map(style, query_opt=None, **kw)

style の指定されたオプションの動的な値を問い合わせたり、設定したりします。

kw のそれぞれのキーはオプション名で、値はタプルやリストや何か他の好きなものでグループ化された状態仕様 (statespec) を要素とするリストやタプルです。状態仕様は 1 つもしくは複数の状態と値の組み合わせです。

例

import Tkinter
import ttk

root = Tkinter.Tk()

style = ttk.Style()
style.map("C.TButton",
    foreground=[('pressed', 'red'), ('active', 'blue')],
    background=[('pressed', '!disabled', 'black'), ('active', 'white')]
    )

colored_btn = ttk.Button(text="Test", style="C.TButton").pack()

root.mainloop()

あるオプションに対する状態と値の組 (states, value) の並び順はスタイルに影響を与えることに注意してください。例えば、 foreground オプションの順序を [('active', 'blue'), ('pressed', 'red')] に変更した場合、ウィジェットがアクティブもしくは押された状態のとき前面が青くなります。

lookup(style, option[, state=None[, default=None]])

style の指定された option の値を返します。

state を指定する場合は、1 つ以上の状態名の並びである必要があります。 default 引数が指定されていた場合は、オプション指定が見付からなかったときに代わりに返される値として使われます。

デフォルトでボタンがどのフォントを使うかを調べるには、以下のように実行します

import ttk

print ttk.Style().lookup("TButton", "font")

layout(style[, layoutspec=None])

与えられた style でのウィジェットのレイアウトを定義します。 layoutspec が省略されていた場合は、与えられたスタイルのレイアウト仕様を返します。

layoutspec を指定する場合は、リストもしくは (文字列を除いた) 何か他のシーケンス型である必要があります。それぞれの要素はタプルで、レイアウト名を 1 番目の要素とし、 2 番目の要素は レイアウト で説明されているフォーマットである必要があります。

フォーマットを理解するために以下の例を見てください (何かを使い易くするための例ではありません)

import ttk
import Tkinter

root = Tkinter.Tk()

style = ttk.Style()
style.layout("TMenubutton", [
   ("Menubutton.background", None),
   ("Menubutton.button", {"children":
       [("Menubutton.focus", {"children":
           [("Menubutton.padding", {"children":
               [("Menubutton.label", {"side": "left", "expand": 1})]
           })]
       })]
   }),
])

mbtn = ttk.Menubutton(text='Text')
mbtn.pack()
root.mainloop()

element_create(elementname, etype, *args, **kw)

与えられた etype (“image”, “from”, “vsapi” のいずれか) の現在のテーマに新しい要素を作成します。最後の “vsapi” は Windows XP と Vista の Tk 8.6a のみで使用可能でここでは説明しません。

“image” が使われた場合、 args はデフォルトの画像名の後ろに状態仕様と値のペア (これが画像仕様です) を並べたものである必要があります。 kw には以下のオプションが指定できます:

border=padding

padding は 4 個以下の整数のリストで、それぞれ左、上、右、下の縁の幅を指定します。

height=height

要素の最小の高さを指定します。0 より小さい場合は、画像の高さをデフォルトとして使用します。

padding=padding

要素の内部のパディングを指定します。指定されない場合は、 border の値がデフォルトとして使われます。

sticky=spec

1 つ外側の枠に対し画像をどう配置するかを指定します。 spec は “n”, “s”, “w”, “e” の文字を 0 個以上含みます。

width=width

要素の最小の幅を指定します。0 より小さい場合は、画像の幅をデフォルトとして使用します。

etype の値として “from” が使われた場合は、 element_create() が現在の要素を複製します。 args は要素の複製元のテーマの名前と、オプションで複製する要素を含んでいる必要があります。複製元の要素が指定されていなかった場合、空要素が使用され、 kw は破棄されます。

element_names()

現在のテーマに定義されている要素のリストを返します。

element_options(elementname)

elementname のオプションのリストを返します。

theme_create(themename[, parent=None[, settings=None]])

新しいテーマを作成します。

themename が既に存在していた場合はエラーになります。 parent が指定されていた場合は、新しいテーマは親テーマからスタイルや要素やレイアウトを継承します。 settings が指定された場合は、 theme_settings() で使われるのと同じ形式である必要があります。

theme_settings(themename, settings)

一時的に現在のテーマを themename に設定し、指定された settings を適用した後、元のテーマを復元します。

settings のそれぞれのキーはスタイル名で値はさらに ‘configure’, ‘map’, ‘layout’, ‘element create’ をキーとして持ち、その値はそれぞれ Style.configure(), Style.map(), Style.layout(), Style.element_create() メソッドで指定するのと同じ形式である必要があります。

例として、コンボボックスの default テーマを少し変更してみましょう

import ttk
import Tkinter

root = Tkinter.Tk()

style = ttk.Style()
style.theme_settings("default", {
   "TCombobox": {
       "configure": {"padding": 5},
       "map": {
           "background": [("active", "green2"),
                          ("!disabled", "green4")],
           "fieldbackground": [("!disabled", "green3")],
           "foreground": [("focus", "OliveDrab1"),
                          ("!disabled", "OliveDrab2")]
       }
   }
})

combo = ttk.Combobox().pack()

root.mainloop()

theme_names()

全ての既存のテーマのリストを返します。

theme_use([themename])

themename が与えられなかった場合は、現在使用中のテーマ名を返します。そうでない場合は、現在のテーマを themename に設定し、全てのウィジェットを再描画し、 <<ThemeChanged>> イベントを発生させます。

24.2.10.1. レイアウト

レイアウトはオプションを取らない場合はただの None にできますし、そうでない場合は要素をどう配置するかを指定するオプションの辞書になります。レイアウト機構は単純化したジオメトリマネージャを使っています: 最初に空間が与えられ、それぞれの要素に分割された空間が配分されます。設定できるオプションと値は次の通りです:

side: 辺の名前

要素を空間のどちら側に配置するかを指定します; top, right, bottom, left のどれか 1 つです。省略された場合は、要素は空間全体を占めます。

sticky: n, s, w, e から 0 個以上

配分された空間の内部に要素をどう配置するかを指定します。

unit: 0 か 1

If set to 1, causes the element and all of its descendants to be treated as a single element for the purposes of Widget.identify() et al. It’s used for things like scrollbar thumbs with grips. 1 を設定した場合、要素とその

children: [内部レイアウト... ]

要素の内部に配置する要素のリストを指定します。リストのそれぞれの要素はタプル (もしくは他のシーケンス型) で、それの 1 番目の要素はレイアウト名でそれ以降は Layout です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.3. Tix — Tkの拡張ウィジェット

Tix (Tk Interface Extension) モジュールは豊富な追加ウィジェットを提供します。標準 Tk ライブラリには多くの有用なウィジェットがありますが、完全では決してありません。 Tix ライブラリは標準 Tk に欠けている一般的に必要とされるウィジェットの大部分を提供します: HList 、 ComboBox 、 Control (別名SpinBox) および各種のスクロール可能なウィジェット。 Tix には、一般的に幅広い用途に役に立つたくさんのウィジェットも含まれています: NoteBook 、 FileEntry 、 PanedWindow など。それらは40以上あります。

これら全ての新しいウィジェットと使うと、より便利でより直感的なユーザインタフェース作成し、あなたは新しい相互作用テクニックをアプリケーションに導入することができます。アプリケーションとユーザに特有の要求に合うように、大部分のアプリケーションウィジェットを選ぶことによって、アプリケーションを設計できます。

ノート

Tix は Python 3.0 で tkinter.tix と改名されました。 2to3 ツールはソースの変換時に自動的に import を対応させます。

参考

Tix Homepage [http://tix.sourceforge.net/]

Tix のホームページ。ここには追加ドキュメントとダウンロードへのリンクがあります。

Tix Man Pages [http://tix.sourceforge.net/dist/current/man/]

manページと参考資料のオンライン版。

Tix Programming Guide [http://tix.sourceforge.net/dist/current/docs/tix-book/tix.book.html]

プログラマ用参考資料のオンライン版。

Tix Development Applications [http://tix.sourceforge.net/Tide/]

Tix と Tkinter プログラムの開発のための Tix アプリケーション。 Tideアプリケーションは Tk または Tkinter に基づいて動作します。また、リモートで Tix/Tk/Tkinter アプリケーションを変更やデバグするためのインスペクタ TixInspect が含まれます。

24.3.1. Tixを使う

class Tix.Tix(screenName[, baseName[, className]])

たいていはアプリケーションのメインウィンドウを表すTixのトップレベルウィジェット。それには Tcl インタープリタが付随します。

Tix モジュールのクラスは Tkinter モジュールのクラスをサブクラス化します。前者は後者をインポートします。だから、Tkinter と一緒に Tix を使うためにやらなければならないのは、モジュールを一つインポートすることだけです。一般的に、 Tix をインポートし、トップレベルでの Tkinter.Tk の呼び出しを Tix.Tk に置き換えるだけでよいのです:

import Tix
from Tkconstants import *
root = Tix.Tk()

Tix を使うためには、通常 Tk ウィジェットのインストールと平行して、 Tix ウィジェットをインストールしなければなりません。インストールをテストするために、次のことを試してください:

import Tix
root = Tix.Tk()
root.tk.eval('package require Tix')

これが失敗した場合は、先に進む前に解決しなければならない問題が Tk のインストールにあることになります。インストールされた Tix ライブラリを指定するためには環境変数 TIX_LIBRARY を使ってください。 Tk 動的オブジェクトライブラリ (tk8183.dll または libtk8183.so) を含むディレクトリと同じディレクトリに、動的オブジェクトライブラリ (tix8183.dll または libtix8183.so)があるかどうかを確かめてください。動的オブジェクトライブラリのあるディレクトリには、 pkgIndex.tcl (大文字、小文字を区別します) という名前のファイルも含まれているべきで、それには次の一行が含まれます:

package ifneeded Tix 8.1 [list load "[file join $dir tix8183.dll]" Tix]

24.3.2. Tixウィジェット

Tix [http://tix.sourceforge.net/dist/current/man/html/TixCmd/TixIntro.htm] は40個以上のウィジェットクラスを Tkinter のレパートリーに導入します。標準配布の Demo/tix ディレクトリには、 Tix ウィジェットのデモがあります。

24.3.2.1. 基本ウィジェット

class Tix.Balloon

ヘルプを提示するためにウィジェット上にポップアップする Balloon [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixBalloon.htm]。ユーザがカーソルをBalloonウィジェットが束縛されているウィジェット内部へ移動させたとき、説明のメッセージが付いた小さなポップアップウィンドウがスクリーン上に表示されます。

class Tix.ButtonBox

ButtonBox [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixButtonBox.htm] ウィジェットは、 Ok Cancel のためだけに普通は使われるようなボタンボックスを作成します。

class Tix.ComboBox

ComboBox [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm] ウィジェットはMS Windowsのコンボボックスコントロールに似ています。ユーザはエントリ・サブウィジェットでタイプするか、リストボックス・サブウィジェットから選択するかのどちらかで選択肢を選びます。

class Tix.Control

Control [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixControl.htm] ウィジェットは SpinBox ウィジェットとしても知られています。ユーザは二つの矢印ボタンを押すか、またはエントリに直接値を入力して値を調整します。新しい値をユーザが定義した上限と下限に対してチェックします。

class Tix.LabelEntry

LabelEntry [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelEntry.htm] ウィジェットはエントリウィジェットとラベルを一つのメガウィジェットにまとめたものです。”記入形式”型のインタフェースの作成を簡単に行うために使うことができます。

class Tix.LabelFrame

LabelFrame [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixLabelFrame.htm] ウィジェットはフレームウィジェットとラベルを一つのメガウィジェットにまとめたものです。LabelFrameウィジェット内部にウィジェットを作成するためには、 frame サブウィジェットに対して新しいウィジェットを作成し、それらを frame サブウィジェット内部で取り扱います。

class Tix.Meter

Meter [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixMeter.htm] ウィジェットは実行に時間のかかるバックグラウンド・ジョブの進み具合を表示するために使用できます。

class Tix.OptionMenu

OptionMenu [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixOptionMenu.htm] はオプションのメニューボタンを作成します。

class Tix.PopupMenu

PopupMenu [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPopupMenu.htm] ウィジェットは tk_popup コマンドの代替品として使用できます。 Tix PopupMenu ウィジェットの利点は、操作するためにより少ないアプリケーション・コードしか必要としないことです。

class Tix.Select

Select [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixSelect.htm] ウィジェットはボタン・サブウィジェットのコンテナです。ユーザに対する選択オプションのラジオボックスまたはチェックボックス形式を提供するために利用することができます。

class Tix.StdButtonBox

StdButtonBox [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixStdButtonBox.htm] ウィジェットは、Motif に似たダイアログボックスのための標準的なボタンのグループです。

24.3.2.2. ファイルセレクタ

class Tix.DirList

DirList [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirList.htm] ウィジェットは、ディレクトリのリストビュー(その前のディレクトリとサブディレクトリ)を表示します。ユーザはリスト内の表示されたディレクトリの一つを選択したり、あるいは他のディレクトリへ変更したりできます。

class Tix.DirTree

DirTree [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirTree.htm] ウィジェットはディレクトリのツリービュー(その前のディレクトリとそのサブディレクトリ)を表示します。ユーザはリスト内に表示されたディレクトリの一つを選択したり、あるいは他のディレクトリに変更したりできます。

class Tix.DirSelectDialog

DirSelectDialog [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixDirSelectDialog.htm] ウィジェットは、ダイアログウィンドウにファイルシステム内のディレクトリを提示します。望みのディレクトリを選択するために、ユーザはファイルシステムを介して操作するこのダイアログウィンドウを利用できます。

class Tix.DirSelectBox

DirSelectBox は標準 Motif(TM) ディレクトリ選択ボックスに似ています。ユーザがディレクトリを選択するために一般的に使われます。DirSelectBox は主に最近 ComboBox ウィジェットに選択されたディレクトリを保存し、すばやく再選択できるようにします。

class Tix.ExFileSelectBox

ExFileSelectBox [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixExFileSelectBox.htm] ウィジェットは、たいてい tixExFileSelectDialog ウィジェット内に組み込まれます。ユーザがファイルを選択するのに便利なメソッドを提供します。 ExFileSelectBox ウィジェットのスタイルは、MS Windows 3.1 の標準ファイルダイアログにとてもよく似ています。

class Tix.FileSelectBox

FileSelectBox [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileSelectBox.htm] は標準的な Motif(TM) ファイル選択ボックスに似ています。ユーザがファイルを選択するために一般的に使われます。FileSelectBox は主に最近 ComboBox ウィジェットに選択されたファイルを保存し、素早く再選択できるようにします。

class Tix.FileEntry

FileEntry [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixFileEntry.htm] ウィジェットはファイル名を入力するために使うことができます。ユーザは手でファイル名をタイプできます。その代わりに、ユーザはエントリの横に並んでいるボタンウィジェットを押すことができます。それはファイル選択ダイアログを表示します。

24.3.2.3. ハイアラキカルリストボックス

class Tix.HList

HList [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixHList.htm] ウィジェットは階層構造をもつどんなデータ(例えば、ファイルシステムディレクトリツリー)でも表示するために使用できます。リストエントリは字下げされ、階層のそれぞれの場所に応じて分岐線で接続されます。

class Tix.CheckList

CheckList [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixCheckList.htm] ウィジェットは、ユーザが選ぶ項目のリストを表示します。CheckList は Tk のチェックリストやラジオボタンより多くの項目を扱うことができることを除いて、チェックボタンあるいはラジオボタンウィジェットと同じように動作します。

class Tix.Tree

Tree [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTree.htm] ウィジェットは階層的なデータをツリー形式で表示するために使うことができます。ユーザはツリーの一部を開いたり閉じたりすることによって、ツリーの見えを調整できます。

24.3.2.4. タビュラーリストボックス

class Tix.TList

TList [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixTList.htm] ウィジェットは、表形式でデータを表示するために使うことができます。 TList ウィジェットのリスト・エントリは、Tkのリストボックス・ウィジェットのエントリに似ています。主な差は、(1) TList ウィジェットはリスト・エントリを二次元形式で表示でき、(2) リスト・エントリに対して複数の色やフォントだけでなく画像も使うことができるということです。

24.3.2.5. 管理ウィジェット

class Tix.PanedWindow

PanedWindow [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixPanedWindow.htm] ウィジェットは、ユーザがいくつかのペインのサイズを対話的に操作できるようにします。ペインは垂直または水平のどちらかに配置されます。ユーザは二つのペインの間でリサイズ・ハンドルをドラッグしてペインの大きさを変更します。

class Tix.ListNoteBook

ListNoteBook [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixListNoteBook.htm] ウィジェットは、 TixNoteBook ウィジェットにとてもよく似ています。ノートのメタファを使って限られた空間をに多くのウィンドウを表示するために使われます。ノートはたくさんのページ(ウィンドウ)に分けられています。ある時には、これらのページの一つしか表示できません。ユーザは hlist サブウィジェットの中の望みのページの名前を選択することによって、これらのページを切り替えることができます。

class Tix.NoteBook

NoteBook [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixNoteBook.htm] ウィジェットは、ノートのメタファを多くのウィンドウを表示することができます。ノートはたくさんのページに分けられています。ある時には、これらのページの一つしか表示できません。ユーザは NoteBook ウィジェットの一番上にある目に見える”タブ”を選択することで、これらのページを切り替えることができます。

24.3.2.6. 画像タイプ

Tix モジュールは次のものを追加します:

全ての Tix と Tkinter ウィジェットに対して XPM ファイルからカラー画像を作成する pixmap [http://tix.sourceforge.net/dist/current/man/html/TixCmd/pixmap.htm] 機能。

Compound [http://tix.sourceforge.net/dist/current/man/html/TixCmd/compound.htm] 画像タイプは複数の水平方向の線から構成される画像を作成するために使うことができます。それぞれの線は左から右に並べられた一連のアイテム(テキスト、ビットマップ、画像あるいは空白)から作られます。例えば、Tk のButton ウィジェットの中にビットマップとテキスト文字列を同時に表示するためにcompound画像は使われます。

24.3.2.7. その他のウィジェット

class Tix.InputOnly

InputOnly [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixInputOnly.htm] ウィジェットは、ユーザから入力を受け付けます。それは、 bind コマンドを使って行われます(Unixのみ)。

24.3.2.8. ジオメトリマネジャを作る

加えて、 Tix は次のものを提供することで Tkinter を補強します:

class Tix.Form

Tkウィジェットに対する接続ルールに基づいたジオメトリマネジャを 作成(Form)します [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixForm.htm] 。

24.3.3. Tixコマンド

class Tix.tixCommand

tixコマンド [http://tix.sourceforge.net/dist/current/man/html/TixCmd/tix.htm] は Tix の内部状態と Tix アプリケーション・コンテキストのいろいろな要素へのアクセスを提供します。これらのメソッドによって操作される情報の大部分は、特定のウィンドウというよりむしろアプリケーション全体かスクリーンあるいはディスプレイに関するものです。

現在の設定を見るための一般的な方法は、

import Tix
root = Tix.Tk()
print root.tix_configure()

tixCommand.tix_configure([cnf], **kw)

Tix アプリケーション・コンテキストの設定オプションを問い合わせたり、変更したりします。オプションが指定されなければ、利用可能なオプションすべてのディクショナリを返します。オプションが値なしで指定された場合は、メソッドは指定されたオプションを説明するリストを返します(このリストはオプションが指定されていない場合に返される値に含まれている、指定されたオプションに対応するサブリストと同一です)。一つ以上のオプション-値のペアが指定された場合は、メソッドは与えられたオプションが与えられた値を持つように変更します。この場合は、メソッドは空文字列を返します。オプションは設定オプションのどれでも構いません。

tixCommand.tix_cget(option)

option によって与えられた設定オプションの現在の値を返します。オプションは設定オプションのどれでも構いません。

tixCommand.tix_getbitmap(name)

ビットマップディレクトリの一つの中の name.xpm または name と言う名前のビットマップファイルの場所を見つけ出します (tix_addbitmapdir() メソッドを参照してください)。 tix_getbitmap() を使うことで、アプリケーションにビットマップファイルのパス名をハードコーディングすることを避けることができます。成功すれば、文字 @ を先頭に付けたビットマップファイルの完全なパス名を返します。戻り値をTkとTixウィジェットの bitmap オプションを設定するために使うことができます。

tixCommand.tix_addbitmapdir(directory)

Tix は tix_getimage() と tix_getbitmap() メソッドが画像ファイルを検索するディレクトリのリストを保持しています。標準ビットマップディレクトリは $TIX_LIBRARY/bitmaps です。 tix_addbitmapdir() メソッドは directory をこのリストに追加します。そのメソッドを使うことによって、アプリケーションの画像ファイルを tix_getimage() または tix_getbitmap() メソッドを使って見つけることができます。

tixCommand.tix_filedialog([dlgclass])

このアプリケーションからの異なる呼び出しの間で共有される可能性があるファイル選択ダイアログを返します。最初に呼ばれた時に、このメソッドはファイル選択ダイアログ・ウィジェットを作成します。このダイアログはその後のすべての tix_filedialog() への呼び出しで返されます。オプションの dlgclass パラメータは、要求されているファイル選択ダイアログ・ウィジェットの型を指定するために文字列として渡されます。指定可能なオプションは tix 、 FileSelectDialog あるいは tixExFileSelectDialog です。

tixCommand.tix_getimage(self, name)

ビットマップディレクトリの一つの中の name.xpm 、 name.xbm または name.ppm という名前の画像ファイルの場所を見つけ出します(上の tix_addbitmapdir() メソッドを参照してください)。同じ名前(だが異なる拡張子)のファイルが一つ以上ある場合は、画像のタイプがXディスプレイの深さに応じて選択されます。xbm画像はモノクロディスプレイの場合に選択され、カラー画像はカラーディスプレイの場合に選択されます。 tix_getimage() を使うことによって、アプリケーションに画像ファイルのパス名をハードコーディングすることを避けられます。成功すれば、このメソッドは新たに作成した画像の名前を返し、Tk と Tix ウィジェットの image オプションを設定するためにそれを使うことができます。

tixCommand.tix_option_get(name)

Tixのスキーム・メカニズムによって保持されているオプションを得ます。

tixCommand.tix_resetoptions(newScheme, newFontSet[, newScmPrio])

Tix アプリケーションのスキームとフォントセットを newScheme と newFontSet それぞれへと再設定します。これはこの呼び出し後に作成されたそれらのウィジェットだけに影響します。そのため、Tix アプリケーションのどんなウィジェットを作成する前に resetoptions メソッドを呼び出すのが最も良いのです。

オプション・パラメータ newScmPrio を、Tix スキームによって設定される Tk オプションの優先度レベルを再設定するために与えることができます。

Tk が X オプションデータベースを扱う方法のため、Tix がインポートされ初期化された後に、カラースキームとフォントセットを tix_config() メソッドを使って再設定することができません。その代わりに、 tix_resetoptions() メソッドを使わなければならないのです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.4. ScrolledText — スクロールするテキストウィジェット

ScrolledText モジュールは”正しい動作”をするように設定された垂直スクロールバーをもつ基本的なテキストウィジェットを実装する同じ名前のクラスを提供します。 ScrolledText クラスを使うことは、テキストウィジェットとスクロールバーを直接設定するより簡単です。コンストラクタは Tkinter.Text クラスのものを同じです。

ノート

ScrolledText は Python 3.0 で tkinter.scrolledtext に改名されました。 2to3 ツールはソースの 3.0 への変換時に自動的に import を対応させます。

テキストウィジェットとスクロールバーは Frame の中に一緒にpackされ、 Grid と Pack ジオメトリマネジャのメソッドはFrame オブジェクトから得られます。これによって、もっとも標準的なジオメトリマネジャの振る舞いにするために、直接 ScrolledText ウィジェットを使えるようになります。

特定の制御が必要ならば、以下の属性が利用できます:

ScrolledText.frame

テキストとスクロールバーウィジェットを取り囲むフレーム。

ScrolledText.vbar

スクロールバーウィジェット。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.5. turtle — Tkのためのタートルグラフィックス

24.5.1. はじめに

タートルグラフィックスは子供にプログラミングを紹介するのによく使われます。タートルグラフィックスは Wally Feurzig と Seymore Papert が 1966 年に開発した Logo プログラミング言語の一部でした。

x-y 平面の (0, 0) から動き出すロボット亀を想像してみて下さい。 turtle.forward(15) という命令を出すと、その亀が (スクリーン上で!) 15 ピクセル分顔を向けている方向に動き、動きに沿って線を引きます。 turtle.left(25) という命令を出すと、今度はその場で25度反時計回りに回ります。

これらの命令と他の同様な命令を組み合わせることで、複雑な形や絵が簡単に描けます。

turtle モジュールは同じ名前を持った Python 2.5 までのモジュールの拡張された再実装です。

再実装に際しては古い turtle モジュールのメリットをそのままに、 (ほぼ) 100% 互換性を保つようにしました。すなわち、まず第一に、学習中のプログラマがモジュールを -n スイッチを付けて走らせている IDLE の中から全てのコマンド、クラス、メソッドを対話的に使えるようにしました。

turtle モジュールはオブジェクト指向と手続き指向の両方の方法でタートルグラフィックス・プリミティブを提供します。グラフィックスの基礎として Tkinter を使っているために、Tk をサポートした Python のバージョンが必要です。

オブジェクト指向インターフェイスでは、本質的に 2+2 のクラスを使います:

TurtleScreen クラスはタートルが絵を描きながら走り回る画面を定義します。そのコンストラクタには Tkinter.Canvas または ScrolledCanvas を渡す必要があります。 turtle をアプリケーションの一部として用いたい場合にはこれを使うべきです。

Screen() 関数は TurtleScreen のサブクラスのシングルトンオブジェクトを返します。 turtle をグラフィクスを使う一つの独立したツールとして使う場合には、この関数を呼び出すべきです。シングルトンなので、そのクラスからの継承はできません。

TurtleScreen/Screen の全てのメソッドは関数としても、すなわち、手続き指向インターフェイスの一部としても存在しています。

RawTurtle (別名: RawPen) は TurtleScreen 上に絵を描く Turtle オブジェクトを定義します。コンストラクタには Canvas, ScrolledCanvas, TurtleScreen のいずれかを引数として渡して RawTurtle オブジェクトがどこに絵を描くかを教えます。

RawTurtle の派生はサブクラス Turtle (別名: Pen) で、 “唯一の” Screen (既に与えられているのでなければ自動的に作られたインスタンス) に絵を描きます。

RawTurtle/Turtle の全てのメソッドは関数としても、すなわち、手続き指向インターフェイスの一部としても存在しています。

手続き型インターフェイスでは Screen および Turtle クラスのメソッドを元にした関数を提供しています。その名前は対応するメソッドと一緒です。 Screen のメソッドを元にした関数が呼び出されるといつでも screen オブジェクトが自動的に作られます。 Turtle のメソッドを元にした関数が呼び出されるといつでも(名無しの) turtle オブジェクトが自動的に作られます。

複数のタートルを一つのスクリーン上で使いたい場合、オブジェクト指向インターフェイスを使わなければなりません。

ノート

以下の文書では関数に対する引数リストが与えられています。メソッドでは、勿論、ここでは省略されている self が第一引数になります。

24.5.2. Turtle および Screen のメソッド概観

24.5.2.1. Turtle のメソッド

Turtle の動き

移動および描画

forward() | fd()

backward() | bk() | back()

right() | rt()

left() | lt()

goto() | setpos() | setposition()

setx()

sety()

setheading() | seth()

home()

circle()

dot()

stamp()

clearstamp()

clearstamps()

undo()

speed()

Turtle の状態を知る

position() | pos()

towards()

xcor()

ycor()

heading()

distance()

設定と計測

degrees()

radians()

Pen の制御

描画状態

pendown() | pd() | down()

penup() | pu() | up()

pensize() | width()

pen()

isdown()

色の制御

color()

pencolor()

fillcolor()

塗りつぶし

fill()

begin_fill()

end_fill()

さらなる描画の制御

reset()

clear()

write()

タートルの状態

可視性

showturtle() | st()

hideturtle() | ht()

isvisible()

見た目

shape()

resizemode()

shapesize() | turtlesize()

settiltangle()

tiltangle()

tilt()

イベントを利用する

onclick()

onrelease()

ondrag()

特別な Turtle のメソッド

begin_poly()

end_poly()

get_poly()

clone()

getturtle() | getpen()

getscreen()

setundobuffer()

undobufferentries()

tracer()

window_width()

window_height()

24.5.2.2. TurtleScreen/Screen のメソッド

ウィンドウの制御

bgcolor()

bgpic()

clear() | clearscreen()

reset() | resetscreen()

screensize()

setworldcoordinates()

アニメーションの制御

delay()

tracer()

update()

スクリーンイベントを利用する

listen()

onkey()

onclick() | onscreenclick()

ontimer()

設定と特殊なメソッド

mode()

colormode()

getcanvas()

getshapes()

register_shape() | addshape()

turtles()

window_height()

window_width()

Screen 独自のメソッド

bye()

exitonclick()

setup()

title()

24.5.3. RawTurtle/Turtle のメソッドと対応する関数

この節のほとんどの例では turtle という名前の Turtle インスタンスを使います。

24.5.3.1. Turtle の動き

turtle.forward(distance)

turtle.fd(distance)

パラメタ:
distance – 数 (整数または浮動小数点数)

タートルが頭を向けている方へ、タートルを距離 distance だけ前進させます。

>>> turtle.position()
(0.00, 0.00)
>>> turtle.forward(25)
>>> turtle.position()
(25.00,0.00)
>>> turtle.forward(-75)
>>> turtle.position()
(-50.00,0.00)

turtle.back(distance)

turtle.bk(distance)

turtle.backward(distance)

パラメタ:
distance – 数

タートルが頭を向けている方と反対方向へ、タートルを距離 distance だけ後退させます。タートルの向きは変えません。

>>> turtle.position()
(0.00,0.00)
>>> turtle.backward(30)
>>> turtle.position()
(-30.00,0.00)

turtle.right(angle)

turtle.rt(angle)

パラメタ:
angle – 数 (整数または浮動小数点数)

タートルを angle 単位だけ右に回します。 (単位のデフォルトは度ですが、 degrees() と radians() 関数を使って設定できます。) 角度の向きはタートルのモードによって意味が変わります。 mode() を参照してください。

>>> turtle.heading()
22.0
>>> turtle.right(45)
>>> turtle.heading()
337.0

turtle.left(angle)

turtle.lt(angle)

パラメタ:
angle – 数 (整数または浮動小数点数)

タートルを angle 単位だけ左に回します。 (単位のデフォルトは度ですが、 degrees() と radians() 関数を使って設定できます。) 角度の向きはタートルのモードによって意味が変わります。 mode() を参照してください。

>>> turtle.heading()
22.0
>>> turtle.left(45)
>>> turtle.heading()
67.0

turtle.goto(x, y=None)

turtle.setpos(x, y=None)

turtle.setposition(x, y=None)

パラメタ:

x – 数または数のペア/ベクトル

y – 数または None

y が None の場合、 x は座標のペアかまたは Vec2D (たとえば pos() で返されます) でなければなりません。

タートルを指定された絶対位置に移動します。ペンが下りていれば線を引きます。タートルの向きは変わりません。

>>> tp = turtle.pos()
>>> tp
(0.00,0.00)
>>> turtle.setpos(60,30)
>>> turtle.pos()
(60.00,30.00)
>>> turtle.setpos((20,80))
>>> turtle.pos()
(20.00,80.00)
>>> turtle.setpos(tp)
>>> turtle.pos()
(0.00,0.00)

turtle.setx(x)

パラメタ:
x – 数 (整数または浮動小数点数)

タートルの第一座標を x にします。第二座標は変わりません。

>>> turtle.position()
(0.00,240.00)
>>> turtle.setx(10)
>>> turtle.position()
(10.00,240.00)

turtle.sety(y)

パラメタ:
y – 数 (整数または浮動小数点数)

タートルの第二座標を y にします。第一座標は変わりません。

>>> turtle.position()
(0.00,40.00)
>>> turtle.sety(-10)
>>> turtle.position()
(0.00,-10.00)

turtle.setheading(to_angle)

turtle.seth(to_angle)

パラメタ:
to_angle – 数 (整数または浮動小数点数)

タートルの向きを to_angle に設定します。以下はよく使われる方向を度で表わしたものです:

標準モード | logo モード
0 - 東 | 0 - 北
90 - 北 | 90 - 東
180 - 西 | 180 - 南
270 - 南 | 270 - 西

>>> turtle.setheading(90)
>>> turtle.heading()
90.0

turtle.home()

タートルを原点 – 座標 (0, 0) – に移動し、向きを開始方向に設定します (開始方向はモードに依って違います。 mode() を参照してください)。

>>> turtle.heading()
90.0
>>> turtle.position()
(0.00,-10.00)
>>> turtle.home()
>>> turtle.position()
(0.00,0.00)
>>> turtle.heading()
0.0

turtle.circle(radius, extent=None, steps=None)

パラメタ:

radius – 数

extent – 数 (または None)

steps – 整数 (または None)

半径 radius の円を描きます。中心はタートルの左 radius ユニットの点です。 extent – 角度です – は円のどの部分を描くかを決定します。 extent が与えられなければ、デフォルトで完全な円になります。 extent が完全な円でない場合は、弧の一つの端点は、現在のペンの位置です。 radius が正の場合、弧は反時計回りに描かれます。そうでなければ、時計回りです。最後にタートルの向きが extent 分だけ変わります。

円は内接する正多角形で近似されます。 steps でそのために使うステップ数を決定します。この値は与えられなければ自動的に計算されます。また、これを正多角形の描画に利用することもできます。

>>> turtle.home()
>>> turtle.position()
(0.00,0.00)
>>> turtle.heading()
0.0
>>> turtle.circle(50)
>>> turtle.position()
(-0.00,0.00)
>>> turtle.heading()
0.0
>>> turtle.circle(120, 180)  # 半円を描きます
>>> turtle.position()
(0.00,240.00)
>>> turtle.heading()
180.0

turtle.dot(size=None, *color)

パラメタ:

size – 1 以上の整数 (与えられる場合には)

color – 色を表わす文字列またはタプル

直径 size の丸い点を color で指定された色で描きます。 size が与えられなかった場合、pensize+4 と 2*pensize の大きい方が使われます。

>>> turtle.home()
>>> turtle.dot()
>>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
>>> turtle.position()
(100.00,-0.00)
>>> turtle.heading()
0.0

turtle.stamp()

キャンバス上の現在タートルがいる位置にタートルの姿のハンコを押します。そのハンコに対して stamp_id が返されますが、これを使うと後で clearstamp(stamp_id) のように呼び出して消すことができます。

>>> turtle.color("blue")
>>> turtle.stamp()
11
>>> turtle.fd(50)

turtle.clearstamp(stampid)

パラメタ:
stampid – 整数で、先立つ stamp() 呼出しで返された値でなければなりません

stampid に対応するハンコを消します。

>>> turtle.position()
(150.00,-0.00)
>>> turtle.color("blue")
>>> astamp = turtle.stamp()
>>> turtle.fd(50)
>>> turtle.position()
(200.00,-0.00)
>>> turtle.clearstamp(astamp)
>>> turtle.position()
(200.00,-0.00)

turtle.clearstamps(n=None)

パラメタ:
n – 整数 (または None)

全ての、または最初の/最後の n 個のハンコを消します。 n が None の場合、全てのハンコを消します。 n が正の場合には最初の n 個、 n が負の場合には最後の n 個を消します。

>>> for i in range(8):
...     turtle.stamp(); turtle.fd(30)
13
14
15
16
17
18
19
20
>>> turtle.clearstamps(2)
>>> turtle.clearstamps(-2)
>>> turtle.clearstamps()

turtle.undo()

最後の(繰り返すことにより複数の)タートルの動きを取り消します。取り消しできる動きの最大数は undobuffer のサイズによって決まります。

>>> for i in range(4):
...     turtle.fd(50); turtle.lt(80)
...
>>> for i in range(8):
...     turtle.undo()

turtle.speed(speed=None)

パラメタ:
speed – 0 から 10 までの整数またはスピードを表わす文字列(以下の説明を参照)

タートルのスピードを 0 から 10 までの範囲の整数に設定します。引数が与えられない場合は現在のスピードを返します。

与えられた数字が 10 より大きかったり 0.5 より小さかったりした場合は、スピードは 0 になります。スピードを表わす文字列は次のように数字に変換されます:

“fastest”: 0

“fast”: 10

“normal”: 6

“slow”: 3

“slowest”: 1

1 から 10 までのスピードを上げていくにつれて線を描いたりタートルが回ったりするアニメーションがだんだん速くなります。

注意: speed = 0 はアニメーションを無くします。 forward/backward ではタートルがジャンプし、left/right では瞬時に方向を変えます。

>>> turtle.speed()
3
>>> turtle.speed('normal')
>>> turtle.speed()
6
>>> turtle.speed(9)
>>> turtle.speed()
9

24.5.3.2. Turtle の状態を知る

turtle.position()

turtle.pos()

タートルの現在位置を (Vec2D のベクトルとして) 返します。

>>> turtle.pos()
(440.00,-0.00)

turtle.towards(x, y=None)

パラメタ:

x – 数または数のペア/ベクトルまたはタートルのインスタンス

y – x が数ならば数、そうでなければ None

タートルの位置から指定された (x,y) への直線の角度を返します。この値はタートルの開始方向にそして開始方向はモード (“standard”/”world” または “logo”) に依存します。

>>> turtle.goto(10, 10)
>>> turtle.towards(0,0)
225.0

turtle.xcor()

タートルの x 座標を返します。

>>> turtle.home()
>>> turtle.left(50)
>>> turtle.forward(100)
>>> turtle.pos()
(64.28,76.60)
>>> print turtle.xcor()
64.2787609687

turtle.ycor()

タートルの y 座標を返します。

>>> turtle.home()
>>> turtle.left(60)
>>> turtle.forward(100)
>>> print turtle.pos()
(50.00,86.60)
>>> print turtle.ycor()
86.6025403784

turtle.heading()

タートルの現在の向きを返します (返される値はタートルのモードに依存します。 mode() を参照してください)。

>>> turtle.home()
>>> turtle.left(67)
>>> turtle.heading()
67.0

turtle.distance(x, y=None)

パラメタ:

x – 数または数のペア/ベクトルまたはタートルのインスタンス

y – x が数ならば数、そうでなければ None

タートルから与えられた (x,y) あるいはベクトルあるいは渡されたタートルへの距離を、タートルのステップを単位として測った値を返します。

>>> turtle.home()
>>> turtle.distance(30,40)
50.0
>>> turtle.distance((30,40))
50.0
>>> joe = Turtle()
>>> joe.forward(77)
>>> turtle.distance(joe)
77.0

24.5.3.3. 設定と計測

turtle.degrees(fullcircle=360.0)

パラメタ:
fullcircle – 数

角度を計る単位「度」を、円周を何等分するかという値に指定します。デフォルトは360等分で通常の意味での度です。

>>> turtle.home()
>>> turtle.left(90)
>>> turtle.heading()
90.0

角度の単位をグラード(grad. gon, grade, gradian とも呼ばれ、
90度の 1/100)に変更する
>>> turtle.degrees(400.0)
>>> turtle.heading()
100.0
>>> turtle.degrees(360)
>>> turtle.heading()
90.0

turtle.radians()

角度を計る単位をラジアンにします。 degrees(2*math.pi) と同じ意味です。

>>> turtle.home()
>>> turtle.left(90)
>>> turtle.heading()
90.0
>>> turtle.radians()
>>> turtle.heading()
1.5707963267948966

24.5.3.4. Pen の制御

24.5.3.4.1. 描画状態

turtle.pendown()

turtle.pd()

turtle.down()

ペンを下ろします – 動くと線が引かれます。

turtle.penup()

turtle.pu()

turtle.up()

ペンを上げます – 動いても線は引かれません。

turtle.pensize(width=None)

turtle.width(width=None)

パラメタ:
width – 正の数

線の太さを width にするか、または現在の太さを返します。 resizemode が “auto” でタートルの形が多角形の場合、その多角形も同じ太さで描画されます。引数が渡されなければ、現在の pensize が返されます。

>>> turtle.pensize()
1
>>> turtle.pensize(10)   # これ以降幅 10 の線が描かれます

turtle.pen(pen=None, **pendict)

パラメタ:

pen – 以下にリストされたキーをもった辞書

pendict – 以下にリストされたキーをキーワードとするキーワード引数

ペンの属性を “pen-dictionary” に以下のキー/値ペアで設定するかまたは返します。

“shown”: True/False

“pendown”: True/False

“pencolor”: 色文字列または色タプル

“fillcolor”: 色文字列または色タプル

“pensize”: 正の数

“speed”: 0 から 10 までの整数

“resizemode”: “auto” または “user” または “noresize”

“stretchfactor”: (正の数, 正の数)

“outline”: 正の数

“tilt”: 数

この辞書を以降の pen() 呼出しに渡して以前のペンの状態に復旧することができます。さらに一つ以上の属性をキーワード引数として渡すこともできます。一つの文で幾つものペンの属性を設定するのに使えます。

>>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
>>> sorted(turtle.pen().items())
[('fillcolor', 'black'), ('outline', 1), ('pencolor', 'red'),
 ('pendown', True), ('pensize', 10), ('resizemode', 'noresize'),
 ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)]
>>> penstate=turtle.pen()
>>> turtle.color("yellow", "")
>>> turtle.penup()
>>> sorted(turtle.pen().items())
[('fillcolor', ''), ('outline', 1), ('pencolor', 'yellow'),
 ('pendown', False), ('pensize', 10), ('resizemode', 'noresize'),
 ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)]
>>> turtle.pen(penstate, fillcolor="green")
>>> sorted(turtle.pen().items())
[('fillcolor', 'green'), ('outline', 1), ('pencolor', 'red'),
 ('pendown', True), ('pensize', 10), ('resizemode', 'noresize'),
 ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)]

turtle.isdown()

もしペンが下りていれば True を、上がっていれば False を返します。

>>> turtle.penup()
>>> turtle.isdown()
False
>>> turtle.pendown()
>>> turtle.isdown()
True

24.5.3.4.2. 色の制御

turtle.pencolor(*args)

ペンの色(pencolor)を設定するかまたは返します。

4種類の入力形式が受け入れ可能です:

pencolor()

現在のペンの色を色指定文字列またはタプルで返します (例を見て下さい)。次の color/pencolor/fillcolor の呼び出しへの入力に使うこともあるでしょう。

pencolor(colorstring)

ペンの色を colorstring に設定します。その値は Tk の色指定文字列で、 "red", "yellow", "#33cc8c" のような文字列です。

pencolor((r, g, b))

ペンの色を r, g, b のタプルで表された RGB の色に設定します。各 r, g, b は 0 から colormode の間の値でなければなりません。ここで colormode は 1.0 か 255 のどちらかです (colormode() を参照)。

pencolor(r, g, b)

ペンの色を r, g, b で表された RGB の色に設定します。各 r, g, b は 0 から colormode の間の値でなければなりません。

タートルの形(turtleshape)が多角形の場合、多角形の外側が新しく設定された色で描かれます。

>>> colormode()
1.0
>>> turtle.pencolor()
'red'
>>> turtle.pencolor("brown")
>>> turtle.pencolor()
'brown'
>>> tup = (0.2, 0.8, 0.55)
>>> turtle.pencolor(tup)
>>> turtle.pencolor()
(0.2, 0.8, 0.5490196078431373)
>>> colormode(255)
>>> turtle.pencolor()
(51, 204, 140)
>>> turtle.pencolor('#32c18f')
>>> turtle.pencolor()
(50, 193, 143)

turtle.fillcolor(*args)

塗りつぶしの色(fillcolor)を設定するかまたは返します。

4種類の入力形式が受け入れ可能です:

fillcolor()

現在の塗りつぶしの色を色指定文字列またはタプルで返します (例を見て下さい)。次の color/pencolor/fillcolor の呼び出しへの入力に使うこともあるでしょう。

fillcolor(colorstring)

塗りつぶしの色を colorstring に設定します。その値は Tk の色指定文字列で、 "red", "yellow", "#33cc8c" のような文字列です。

fillcolor((r, g, b))

塗りつぶしの色を r, g, b のタプルで表された RGB の色に設定します。各 r, g, b は 0 から colormode の間の値でなければなりません。ここで colormode は 1.0 か 255 のどちらかです (colormode() を参照)。

fillcolor(r, g, b)

塗りつぶしの色を r, g, b で表された RGB の色に設定します。各 r, g, b は 0 から colormode の間の値でなければなりません。

タートルの形(turtleshape)が多角形の場合、多角形の内側が新しく設定された色で描かれます。

>>> turtle.fillcolor("violet")
>>> turtle.fillcolor()
'violet'
>>> col = turtle.pencolor()
>>> col
(50, 193, 143)
>>> turtle.fillcolor(col)
>>> turtle.fillcolor()
(50, 193, 143)
>>> turtle.fillcolor('#ffffff')
>>> turtle.fillcolor()
(255, 255, 255)

turtle.color(*args)

ペンの色(pencolor)と塗りつぶしの色(fillcolor)を設定するかまたは返します。

いくつかの入力形式が受け入れ可能です。形式ごとに 0 から 3 個の引数を以下のように使います:

color()

現在のペンの色と塗りつぶしの色を pencolor() および fillcolor() で返される色指定文字列またはタプルのペアで返します。

color(colorstring), color((r,g,b)), color(r,g,b)

pencolor() の入力と同じですが、塗りつぶしの色とペンの色、両方を与えられた値に設定します。

color(colorstring1, colorstring2), color((r1,g1,b1), (r2,g2,b2))

pencolor(colorstring1) および fillcolor(colorstring2) を呼び出すのと等価です。もう一つの入力形式についても同様です。

タートルの形(turtleshape)が多角形の場合、多角形の内側も外側も新しく設定された色で描かれます。

>>> turtle.color("red", "green")
>>> turtle.color()
('red', 'green')
>>> color("#285078", "#a0c8f0")
>>> color()
((40, 80, 120), (160, 200, 240))

こちらも参照: スクリーンのメソッド colormode() 。

24.5.3.4.3. 塗りつぶし

turtle.fill(flag)

パラメタ:
flag – True/False (またはそれぞれ 1/0)

塗りつぶしたい形を描く前に fill(True) を呼び出し、それが終わったら fill(False) を呼び出します。引数なしで呼び出されたときは、塗りつぶしの状態(fillstate)の値 (True なら塗りつぶす、 False なら塗りつぶさない)を返します。

>>> turtle.fill(True)
>>> for _ in range(3):
...    turtle.forward(100)
...    turtle.left(120)
...
>>> turtle.fill(False)

turtle.begin_fill()

塗りつぶしたい図形を描く直前に呼び出します。 fill(True) と等価です。

turtle.end_fill()

最後に呼び出された begin_fill() の後に描かれた図形を塗りつぶします。 fill(False) と等価です。

>>> turtle.color("black", "red")
>>> turtle.begin_fill()
>>> turtle.circle(80)
>>> turtle.end_fill()

24.5.3.4.4. さらなる描画の制御

turtle.reset()

タートルの描いたものをスクリーンから消し、タートルを中心に戻して、全ての変数をデフォルト値に設定し直します。

>>> turtle.goto(0,-22)
>>> turtle.left(100)
>>> turtle.position()
(0.00,-22.00)
>>> turtle.heading()
100.0
>>> turtle.reset()
>>> turtle.position()
(0.00,0.00)
>>> turtle.heading()
0.0

turtle.clear()

タートルの描いたものをスクリーンから消します。タートルは動かしません。タートルの状態と位置、それに他のタートルたちの描いたものは影響を受けません。

turtle.write(arg, move=False, align="left", font=("Arial", 8, "normal"))

パラメタ:

arg – TurtleScreen に書かれるオブジェクト

move – True/False

align – 文字列 “left”, “center”, right” のどれか

font – 三つ組み (fontname, fontsize, fonttype)

文字を書きます— arg の文字列表現を、現在のタートルの位置に、 align (“left”, “center”, right” のどれか) に従って、与えられたフォントで。もし move が True ならば、ペンは書いた文の右下隅に移動します。デフォルトでは、 move は False です。

>>> turtle.write("Home = ", True, align="center")
>>> turtle.write((0,0), True)

24.5.3.5. タートルの状態

24.5.3.5.1. 可視性

turtle.hideturtle()

turtle.ht()

タートルを見えなくします。複雑な図を描いている途中、タートルが見えないようにするのは良い考えです。というのもタートルを隠すことで描画が目に見えて速くなるからです。

>>> turtle.hideturtle()

turtle.showturtle()

turtle.st()

タートルが見えるようにします。

>>> turtle.showturtle()

turtle.isvisible()

タートルが見えている状態ならば True を、隠されていれば False を返します。

>>> turtle.hideturtle()
>>> turtle.isvisible()
False
>>> turtle.showturtle()
>>> turtle.isvisible()
True

24.5.3.5.2. 見た目

turtle.shape(name=None)

パラメタ:
name – 形の名前(shapename)として正しい文字列

タートルの形を与えられた名前(name)の形に設定するか、もしくは名前が与えられなければ現在の形の名前を返します。 name という名前の形は TurtleScreen の形の辞書に載っていなければなりません。最初は次の多角形が載っています: “arrow”, “turtle”, “circle”, “square”, “triangle”, “classic”。形についての扱いを学ぶには Screen のメソッド register_shape() を参照して下さい。

>>> turtle.shape()
'classic'
>>> turtle.shape("turtle")
>>> turtle.shape()
'turtle'

turtle.resizemode(rmode=None)

パラメタ:
rmode – 文字列 “auto”, “user”, “noresize” のどれか

サイズ変更のモード(resizemode)を “auto”, “user”, “noresize” のどれかに設定します。もし rmode が与えられなければ、現在のサイズ変更モードを返します。それぞれのサイズ変更モードは以下の効果を持ちます:

“auto”: ペンのサイズに対応してタートルの見た目を調整します。

“user”: 伸長係数(stretchfactor)およびアウトライン幅(outlinewidth)の値に対応してタートルの見た目を調整します。これらの値は shapesize() で設定します。

“noresize”: タートルの見た目を調整しません。

resizemode(“user”) は shapesize() に引数を渡したときに呼び出されます。

>>> turtle.resizemode()
'noresize'
>>> turtle.resizemode("auto")
>>> turtle.resizemode()
'auto'

turtle.shapesize(stretch_wid=None, stretch_len=None, outline=None)

turtle.turtlesize(stretch_wid=None, stretch_len=None, outline=None)

パラメタ:

stretch_wid – 正の数

stretch_len – 正の数

outline – 正の数

ペンの属性 x/y-伸長係数および/またはアウトラインを返すかまたは設定します。サイズ変更のモードは “user” に設定されます。サイズ変更のモードが “user” に設定されたときかつそのときに限り、タートルは伸長係数(stretchfactor)に従って伸長されて表示されます。 stretch_wid は進行方向に直交する向きの伸長係数で、 stretch_len は進行方向に沿ったの伸長係数、 outline はアウトラインの幅を決めるものです。

>>> turtle.shapesize()
(1, 1, 1)
>>> turtle.resizemode("user")
>>> turtle.shapesize(5, 5, 12)
>>> turtle.shapesize()
(5, 5, 12)
>>> turtle.shapesize(outline=8)
>>> turtle.shapesize()
(5, 5, 8)

turtle.tilt(angle)

パラメタ:
angle – 数

タートルの形(turtleshape)を現在の傾斜角から角度(angle)だけ回転します。このときタートルの進む方向は 変わりません 。

>>> turtle.reset()
>>> turtle.shape("circle")
>>> turtle.shapesize(5,2)
>>> turtle.tilt(30)
>>> turtle.fd(50)
>>> turtle.tilt(30)
>>> turtle.fd(50)

turtle.settiltangle(angle)

パラメタ:
angle – 数

タートルの形(turtleshape)を現在の傾斜角に関わらず、指定された角度(angle)の向きに回転します。タートルの進む方向は 変わりません 。

>>> turtle.reset()
>>> turtle.shape("circle")
>>> turtle.shapesize(5,2)
>>> turtle.settiltangle(45)
>>> turtle.fd(50)
>>> turtle.settiltangle(-45)
>>> turtle.fd(50)

turtle.tiltangle()

現在の傾斜角を返します。すなわち、タートルの形が向いている角度と進んでいく方向との間の角度を返します。

>>> turtle.reset()
>>> turtle.shape("circle")
>>> turtle.shapesize(5,2)
>>> turtle.tilt(45)
>>> turtle.tiltangle()
45.0

24.5.3.6. イベントを利用する

turtle.onclick(fun, btn=1, add=None)

パラメタ:

fun – 2引数の関数でキャンバスのクリックされた点の座標を引数として呼び出されるものです

num – マウスボタンの番号、デフォルトは 1 (左マウスボタン)

add – True または False – True ならば、新しい束縛が追加されますが、そうでなければ、以前の束縛を置き換えます。

fun をタートルのマウスクリック(mouse-click)イベントに束縛します。 fun が None ならば、既存の束縛が取り除かれます。無名タートル、つまり手続き的なやり方の例です:

>>> def turn(x, y):
...     left(180)
...
>>> onclick(turn)  # タートルをクリックすると回転します
>>> onclick(None)  # イベント束縛は消去されます

turtle.onrelease(fun, btn=1, add=None)

パラメタ:

fun – 2引数の関数でキャンバスのクリックされた点の座標を引数として呼び出されるものです

num – マウスボタンの番号、デフォルトは 1 (左マウスボタン)

add – True または False – True ならば、新しい束縛が追加されますが、そうでなければ、以前の束縛を置き換えます。

fun をタートルのマウスボタンリリース(mouse-button-release)イベントに束縛します。 fun が None ならば、既存の束縛が取り除かれます。

>>> class MyTurtle(Turtle):
...     def glow(self,x,y):
...         self.fillcolor("red")
...     def unglow(self,x,y):
...         self.fillcolor("")
...
>>> turtle = MyTurtle()
>>> turtle.onclick(turtle.glow)     # タートル上でクリックすると塗りつぶしの色が赤に
>>> turtle.onrelease(turtle.unglow) # リリース時に透明に

turtle.ondrag(fun, btn=1, add=None)

パラメタ:

fun – 2引数の関数でキャンバスのクリックされた点の座標を引数として呼び出されるものです

num – マウスボタンの番号、デフォルトは 1 (左マウスボタン)

add – True または False – True ならば、新しい束縛が追加されますが、そうでなければ、以前の束縛を置き換えます。

fun をタートルのマウスムーブ(mouse-move)イベントに束縛します。 fun が None ならば、既存の束縛が取り除かれます。

注意: 全てのマウスムーブイベントのシーケンスに先立ってマウスクリックイベントが起こります。

>>> turtle.ondrag(turtle.goto)

この後、タートルをクリックしてドラッグするとタートルはスクリーン上を動きそれによって(ペンが下りていれば)手書きの線ができあがります

24.5.3.7. 特別な Turtle のメソッド

turtle.begin_poly()

多角形の頂点の記録を開始します。現在のタートル位置が最初の頂点です。

turtle.end_poly()

多角形の頂点の記録を停止します。現在のタートル位置が最後の頂点です。この頂点が最初の頂点と結ばれます。

turtle.get_poly()

最後に記録された多角形を返します。

>>> turtle.home()
>>> turtle.begin_poly()
>>> turtle.fd(100)
>>> turtle.left(20)
>>> turtle.fd(30)
>>> turtle.left(60)
>>> turtle.fd(50)
>>> turtle.end_poly()
>>> p = turtle.get_poly()
>>> register_shape("myFavouriteShape", p)

turtle.clone()

位置、向きその他のプロパティがそっくり同じタートルのクローンを作って返します。

>>> mick = Turtle()
>>> joe = mick.clone()

turtle.getturtle()

turtle.getpen()

Turtle オブジェクトそのものを返します。唯一の意味のある使い方: 無名タートルを返す関数として使う。

>>> pet = getturtle()
>>> pet.fd(50)
>>> pet
<turtle.Turtle object at 0x...>

turtle.getscreen()

タートルが描画中の TurtleScreen オブジェクトを返します。 TurtleScreen のメソッドをそのオブジェクトに対して呼び出すことができます。

>>> ts = turtle.getscreen()
>>> ts
<turtle._Screen object at 0x...>
>>> ts.bgcolor("pink")

turtle.setundobuffer(size)

パラメタ:
size – 整数または None

アンドゥバッファを設定または無効化します。 size が整数ならばそのサイズの空のアンドゥバッファを用意します。 size の値はタートルのアクションを何度 undo() メソッド/関数で取り消せるかの最大数を与えます。 size が None ならば、アンドゥバッファは無効化されます。

>>> turtle.setundobuffer(42)

turtle.undobufferentries()

アンドゥバッファのエントリー数を返します。

>>> while undobufferentries():
...     undo()

turtle.tracer(flag=None, delay=None)

対応する TurtleScreen のメソッドの複製です。

バージョン 2.6 で撤廃.

turtle.window_width()

turtle.window_height()

どちらも対応する TurtleScreen のメソッドの複製です。

バージョン 2.6 で撤廃.

24.5.3.8. 合成形の使用に関する補遺

合成されたタートルの形、つまり幾つかの色の違う多角形から成るような形を使うには、以下のように補助クラス Shape を直接使わなければなりません:

タイプ “compound” の空の Shape オブジェクトを作ります。

addcomponent() メソッドを使って、好きなだけここにコンポーネントを追加します。

例えば:

>>> s = Shape("compound")
>>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
>>> s.addcomponent(poly1, "red", "blue")
>>> poly2 = ((0,0),(10,-5),(-10,-5))
>>> s.addcomponent(poly2, "blue", "red")

こうして作った Shape を Screen の形のリスト(shapelist) に追加して使います:

>>> register_shape("myshape", s)
>>> shape("myshape")

ノート

Shape クラスは register_shape() の内部では違った使われ方をします。アプリケーションを書く人が Shape クラスを扱わなければならないのは、上で示したように合成された形を使うとき だけ です。

24.5.4. TurtleScreen/Screen のメソッドと対応する関数

この節のほとんどの例では screen という名前の TurtleScreen インスタンスを使います。

24.5.4.1. ウィンドウの制御

turtle.bgcolor(*args)

パラメタ:
args – 色文字列または 0 から colormode の範囲の数3つ、またはそれを三つ組みにしたもの

TurtleScreen の背景色を設定するかまたは返します。

>>> screen.bgcolor("orange")
>>> screen.bgcolor()
'orange'
>>> screen.bgcolor("#800080")
>>> screen.bgcolor()
(128, 0, 128)

turtle.bgpic(picname=None)

パラメタ:
picname – 文字列で gif ファイルの名前 "nopic" 、または None

背景の画像を設定するかまたは現在の背景画像(backgroundimage)の名前を返します。 picname がファイル名ならば、その画像を背景に設定します。 picname が "nopic" ならば、(もしあれば)背景画像を削除します。 picname が None ならば、現在の背景画像のファイル名を返します。

>>> screen.bgpic()
"nopic"
>>> screen.bgpic("landscape.gif")
>>> screen.bgpic()
"landscape.gif"

turtle.clear()

turtle.clearscreen()

全ての図形と全てのタートルを TurtleScreen から削除します。そして空になった TurtleScreen をリセットして初期状態に戻します: 白い背景、背景画像もイベント束縛もなく、トレーシングはオンです。

ノート

この TurtleScreen メソッドはグローバル関数としては clearscreen という名前でだけ使えます。グローバル関数 clear は Turtle メソッドの clear から派生した別ものです。

turtle.reset()

turtle.resetscreen()

スクリーン上の全てのタートルをリセットしその初期状態に戻します。

ノート

この TurtleScreen メソッドはグローバル関数としては resetscreen という名前でだけ使えます。グローバル関数 reset は Turtle メソッドの reset から派生した別ものです。

turtle.screensize(canvwidth=None, canvheight=None, bg=None)

パラメタ:

canvwidth – 正の整数でピクセル単位の新しいキャンバス幅(canvaswidth)

canvheight – 正の整数でピクセル単位の新しいキャンバス高さ(canvasheight)

bg – 色文字列または色タプルで新しい背景色

引数が渡されなければ、現在の (キャンバス幅, キャンバス高さ) を返します。そうでなければタートルが描画するキャンバスのサイズを変更します。描画ウィンドウには影響しません。キャンバスの隠れた部分を見るためにはスクロールバーを使って下さい。このメソッドを使うと、以前はキャンバスの外にあったそうした図形の一部を見えるようにすることができます。

>>> screen.screensize()
(400, 300)
>>> turtle.screensize(2000,1500)
>>> screen.screensize()
(2000, 1500)

# 逃げ出してしまったタートルを探すためとかね ;-)

turtle.setworldcoordinates(llx, lly, urx, ury)

パラメタ:

llx – 数でキャンバスの左下隅の x-座標

lly – 数でキャンバスの左下隅の y-座標

urx – 数でキャンバスの右上隅の x-座標

ury – 数でキャンバスの右上隅の y-座標

ユーザー定義座標系を準備し必要ならばモードを “world” に切り替えます。この動作は screen.reset() を伴います。すでに “world” モードになっていた場合、全ての図形は新しい座標に従って再描画されます。

重要なお知らせ: ユーザー定義座標系では角度が歪むかもしれません。

>>> screen.reset()
>>> screen.setworldcoordinates(-50,-7.5,50,7.5)
>>> for _ in range(72):
...     left(10)
...
>>> for _ in range(8):
...     left(45); fd(2)   # 正八角形

24.5.4.2. アニメーションの制御

turtle.delay(delay=None)

パラメタ:
delay – 正の整数

描画の遅延(delay)をミリ秒単位で設定するかまたはその値を返します。 (これは概ね引き続くキャンバス更新の時間間隔です。) 遅延が大きくなると、アニメーションは遅くなります。

オプション引数:

>>> screen.delay()
10
>>> screen.delay(5)
>>> screen.delay()
5

turtle.tracer(n=None, delay=None)

パラメタ:

n – 非負整数

delay – 非負整数

タートルのアニメーションをオン・オフし、描画更新の遅延を設定します。 n が与えられた場合、通常のスクリーン更新のうち 1/n しか実際に実行されません。 (複雑なグラフィックスの描画を加速するのに使えます。) 二つ目の引数は遅延の値を設定します(delay() も参照)。

>>> screen.tracer(8, 25)
>>> dist = 2
>>> for i in range(200):
...     fd(dist)
...     rt(90)
...     dist += 2

turtle.update()

TurtleScreen の更新を実行します。トレーサーがオフの時に使われます。

RawTurtle/Turtle のメソッド speed() も参照して下さい。

24.5.4.3. スクリーンイベントを利用する

turtle.listen(xdummy=None, ydummy=None)

TurtleScreen に(キー・イベントを収集するために)フォーカスします。ダミー引数は listen() を onclick メソッドに渡せるようにするためのものです。

turtle.onkey(fun, key)

パラメタ:

fun – 引数なしの関数または None

key – 文字列: キー (例 “a”) またはキー・シンボル (例 “space”)

fun を指定されたキーのキーリリース(key-release)イベントに束縛します。 fun が None ならばイベント束縛は除かれます。注意: キー・イベントを登録できるようにするためには TurtleScreen はフォーカスを持っていないとなりません(listen() を参照)。

>>> def f():
...     fd(50)
...     lt(60)
...
>>> screen.onkey(f, "Up")
>>> screen.listen()

turtle.onclick(fun, btn=1, add=None)

turtle.onscreenclick(fun, btn=1, add=None)

パラメタ:

fun – 2引数の関数でキャンバスのクリックされた点の座標を引数として呼び出されるものです

num – マウスボタンの番号、デフォルトは 1 (左マウスボタン)

add – True または False – True ならば、新しい束縛が追加されますが、そうでなければ、以前の束縛を置き換えます。

fun をタートルのマウスクリック(mouse-click)イベントに束縛します。 fun が None ならば、既存の束縛が取り除かれます。

Example for a screen という名の TurtleScreen インスタンスと turtle という名前の Turtle インスタンスの例:

>>> screen.onclick(turtle.goto) # この後、TurtleScreen をクリックすると
>>>                             # タートルをクリックされた点に
>>>                             # 移動させることになります
>>> screen.onclick(None)  # イベント束縛を取り除きます

ノート

この TurtleScreen メソッドはグローバル関数としては onscreenclick という名前でだけ使えます。グローバル関数 onclick は Turtle メソッドの onclick から派生した別ものです。

turtle.ontimer(fun, t=0)

パラメタ:

fun – 引数なし関数

t – 数 >= 0

t ミリ秒後に fun を呼び出すタイマーを仕掛けます。

>>> running = True
>>> def f():
...     if running:
...         fd(50)
...         lt(60)
...         screen.ontimer(f, 250)
>>> f()   ### タートルが歩き続けます
>>> running = False

24.5.4.4. 設定と特殊なメソッド

turtle.mode(mode=None)

パラメタ:
mode – 文字列 “standard”, “logo”, “world” のいずれか

タートルのモード(“standard”, “logo”, “world” のいずれか)を設定してリセットします。モードが渡されなければ現在のモードが返されます。

モード “standard” は古い turtle 互換です。モード “logo” は Logo タートルグラフィックスとほぼ互換です。モード “world” はユーザーの定義した「世界座標(world coordinates)」を使います。重要なお知らせ: このモードでは x/y 比が 1 でないと角度が歪むかもしれません。

モード | タートルの向きの初期値 | 正の角度
“standard” | 右 (東) 向き | 反時計回り
“logo” | 上 (北) 向き | 時計回り

>>> mode("logo")   # タートルが北を向くようにリセットします
>>> mode()
'logo'

turtle.colormode(cmode=None)

パラメタ:
cmode – 1.0 か 255 のどちらかの値

色モード(colormode)を返すか、または 1.0 か 255 のどちらかの値に設定します。設定した後は、色トリプルの r, g, b 値は 0 から cmode の範囲になければなりません。

>>> screen.colormode(1)
>>> turtle.pencolor(240, 160, 80)
Traceback (most recent call last):
     ...
TurtleGraphicsError: bad color sequence: (240, 160, 80)
>>> screen.colormode()
1.0
>>> screen.colormode(255)
>>> screen.colormode()
255
>>> turtle.pencolor(240,160,80)

turtle.getcanvas()

この TurtleScreen の Canvas を返します。 Tkinter の Canvas を使って何をするか知っている人には有用です。

>>> cv = screen.getcanvas()
>>> cv
<turtle.ScrolledCanvas instance at 0x...>

turtle.getshapes()

現在使うことのできる全てのタートルの形のリストを返します。

>>> screen.getshapes()
['arrow', 'blank', 'circle', ..., 'turtle']

turtle.register_shape(name, shape=None)

turtle.addshape(name, shape=None)

この関数を呼び出す三つの異なる方法があります:

name が gif ファイルの名前で shape が None: 対応する画像の形を取り込みます。

>>> screen.register_shape("turtle.gif")

ノート

画像の形はタートルが向きを変えても 回転しません ので、タートルがどちらを向いているか見ても判りません!

name が任意の文字列で shape が座標ペアのタプル: 対応する多角形を取り込みます。

>>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))

name が任意の文字列で shape が (合成形の) Shape オブジェクト: 対応する合成形を取り込みます。

タートルの形を TurtleScreen の形リスト(shapelist)に加えます。このように登録された形だけが shape(shapename) コマンドに使えます。

turtle.turtles()

スクリーン上のタートルのリストを返します。

>>> for turtle in screen.turtles():
...     turtle.color("red")

turtle.window_height()

タートルウィンドウの高さを返します。

>>> screen.window_height()
480

turtle.window_width()

タートルウィンドウの幅を返します。

>>> screen.window_width()
640

24.5.4.5. Screen 独自のメソッド、TurtleScreen から継承したもの以外

turtle.bye()

タートルグラフィックス(turtlegraphics)のウィンドウを閉じます。

turtle.exitonclick()

スクリーン上のマウスクリックに bye() メソッドを束縛します。

設定辞書中の “using_IDLE” の値が False (デフォルトです) の場合、さらにメインループ(mainloop)に入ります。注意: もし IDLE が -n スイッチ(サブプロセスなし)付きで使われているときは、この値は turtle.cfg の中で True とされているべきです。この場合、IDLE のメインループもクライアントスクリプトから見てアクティブです。

turtle.setup(width=_CFG["width"], height=_CFG["height"], startx=_CFG["leftright"], starty=_CFG["topbottom"])

メインウィンドウのサイズとポジションを設定します。引数のデフォルト値は設定辞書に収められており、 turtle.cfg ファイルを通じて変更できます。

パラメタ:

width – 整数ならばピクセル単位のサイズ、浮動小数点数ならばスクリーンに対する割合 (スクリーンの 50% がデフォルト)

height – 整数ならばピクセル単位の高さ、浮動小数点数ならばスクリーンに対する割合 (スクリーンの 75% がデフォルト)

startx – 正の数ならばスクリーンの左端からピクセル単位で測った開始位置、負の数ならば右端から、None ならば水平方向に真ん中

startx – 正の数ならばスクリーンの上端からピクセル単位で測った開始位置、負の数ならば下端から、None ならば垂直方向に真ん中

>>> screen.setup (width=200, height=200, startx=0, starty=0)
>>>              # ウィンドウを 200×200 ピクセルにして, スクリーンの左上に
>>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
>>>              # ウィンドウをスクリーンの 75% かける 50% にして, スクリーンの真ん中に

turtle.title(titlestring)

パラメタ:
titlestring – タートルグラフィックスウィンドウのタイトルバーに表示される文字列

ウインドウのタイトルを titlestring に設定します。

>>> screen.title("Welcome to the turtle zoo!")

24.5.5. turtle モジュールのパブリッククラス

class turtle.RawTurtle(canvas)

class turtle.RawPen(canvas)

パラメタ:
canvas – Tkinter.Canvas, ScrolledCanvas, TurtleScreen のいずれか

タートルを作ります。タートルには上の「Turtle/RawTurtle のメソッド」で説明した全てのメソッドがあります。

class turtle.Turtle

RawTurtle のサブクラスで同じインターフェイスを持ちますが、最初に必要になったとき自動的に作られる Screen オブジェクトに描画します。

class turtle.TurtleScreen(cv)

パラメタ:
cv – Tkinter.Canvas

上で説明した setbg() のようなスクリーン向けのメソッドを提供します。

class turtle.Screen

TurtleScreen のサブクラスで 4つのメソッドが加わっています 。

class turtle.ScrolledCanvas(master)

パラメタ:
master – この ScrolledCanvas すなわちスクロールバーの付いた Tkinter canvas を収める Tkinter ウィジェット

タートルたちが遊び回る場所として自動的に ScrolledCanvas を提供する Screen クラスによって使われます

class turtle.Shape(type_, data)

パラメタ:
type_ – 文字列 “polygon”, “image”, “compound” のいずれか

形をモデル化するデータ構造。ペア (type_, data) は以下の仕様に従わなければなりません。

type_ | data
“polygon” | 多角形タプル、すなわち座標ペアのタプル
“image” | 画像 (この形式は内部的にのみ使用されます!)
“compound” | None (合成形は addcomponent() メソッドを使って作らなければなりません)

addcomponent(poly, fill, outline=None)

パラメタ:

poly – 多角形、すなわち数のペアのタプル

fill – poly を塗りつぶす色

outline – poly のアウトラインの色 (与えられた場合)

例:

>>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
>>> s = Shape("compound")
>>> s.addcomponent(poly, "red", "blue")
>>> # .. もっと成分を増やした後 register_shape() を使います

合成形の使用に関する補遺 を参照。

class turtle.Vec2D(x, y)

2次元ベクトルのクラスで、タートルグラフィックスを実装するための補助クラス。タートルグラフィックスを使ったプログラムでも有用でしょう。タプルから派生しているので、ベクターはタプルです!

以下の演算が使えます (a, b はベクトル、 k は数):

a + b ベクトル和

a - b ベクトル差

a * b 内積

k * a および a * k スカラー倍

abs(a) a の絶対値

a.rotate(angle) 回転

24.5.6. ヘルプと設定

24.5.6.1. ヘルプの使い方

Screen と Turtle クラスのパブリックメソッドはドキュメント文字列で網羅的に文書化されていますので、Python のヘルプ機能を通じてオンラインヘルプとして利用できます:

IDLE を使っているときは、打ち込んだ関数/メソッド呼び出しのシグニチャとドキュメント文字列の一行目がツールチップとして表示されます。

help() をメソッドや関数に対して呼び出すとドキュメント文字列が表示されます:

>>> help(Screen.bgcolor)
Help on method bgcolor in module turtle:

bgcolor(self, *args) unbound turtle.Screen method
    Set or return backgroundcolor of the TurtleScreen.

    Arguments (if given): a color string or three numbers
    in the range 0..colormode or a 3-tuple of such numbers.

      >>> screen.bgcolor("orange")
      >>> screen.bgcolor()
      "orange"
      >>> screen.bgcolor(0.5,0,0.5)
      >>> screen.bgcolor()
      "#800080"

>>> help(Turtle.penup)
Help on method penup in module turtle:

penup(self) unbound turtle.Turtle method
    Pull the pen up -- no drawing when moving.

    Aliases: penup | pu | up

    No argument

    >>> turtle.penup()

メソッドに由来する関数のドキュメント文字列は変更された形をとります:

>>> help(bgcolor)
Help on function bgcolor in module turtle:

bgcolor(*args)
    Set or return backgroundcolor of the TurtleScreen.

    Arguments (if given): a color string or three numbers
    in the range 0..colormode or a 3-tuple of such numbers.

    Example::

      >>> bgcolor("orange")
      >>> bgcolor()
      "orange"
      >>> bgcolor(0.5,0,0.5)
      >>> bgcolor()
      "#800080"

>>> help(penup)
Help on function penup in module turtle:

penup()
    Pull the pen up -- no drawing when moving.

    Aliases: penup | pu | up

    No argument

    Example:
    >>> penup()

これらの変更されたドキュメント文字列はインポート時にメソッドから導出される関数定義と一緒に自動的に作られます。

24.5.6.2. ドキュメント文字列の翻訳

Screen と Turtle クラスのパブリックメソッドについて、キーがメソッド名で値がドキュメント文字列である辞書を作るユーティリティがあります。

turtle.write_docstringdict(filename="turtle_docstringdict")

パラメタ:
filename – ファイル名として使われる文字列

ドキュメント文字列辞書(docstring-dictionary)を作って与えられたファイル名の Python スクリプトに書き込みます。この関数はわざわざ呼び出さなければなりません (タートルグラフィックスのクラスから使われることはありません)。ドキュメント文字列辞書は filename.py という Python スクリプトに書き込まれます。ドキュメント文字列の異なった言語への翻訳に対するテンプレートとして使われることを意図したものです。

もしあなたが(またはあなたの生徒さんが) turtle を自国語のオンラインヘルプ付きで使いたいならば、ドキュメント文字列を翻訳してできあがったファイルをたとえば turtle_docstringdict_german.py という名前で保存しなければなりません。

さらに turtle.cfg ファイルで適切な設定をしておけば、このファイルがインポート時に読み込まれて元の英語のドキュメント文字列を置き換えます。

この文書を書いている時点ではドイツ語とイタリア語のドキュメント文字列辞書が存在します。 ( glingl@aon.at にリクエストして下さい。)

24.5.6.3. Screen および Turtle の設定方法

初期デフォルト設定では古い turtle の見た目と振る舞いを真似るようにして、互換性を最大限に保つようにしています。

このモジュールの特性を反映した、あるいは個々人の必要性 (たとえばクラスルームでの使用)に合致した、異なった設定を使いたい場合、設定ファイル turtle.cfg を用意してインポート時に読み込ませその設定に従わせることができます。

初期設定は以下の turtle.cfg に対応します:

width = 0.5
height = 0.75
leftright = None
topbottom = None
canvwidth = 400
canvheight = 300
mode = standard
colormode = 1.0
delay = 10
undobuffersize = 1000
shape = classic
pencolor = black
fillcolor = black
resizemode = noresize
visible = True
language = english
exampleturtle = turtle
examplescreen = screen
title = Python Turtle Graphics
using_IDLE = False

いくつかピックアップしたエントリーの短い説明:

最初の4行は Screen.setup() メソッドの引数に当たります。

5行目6行目は Screen.screensize() メソッドの引数に当たります。

shape は最初から用意されている形ならどれでも使えます(arrow, turtle など)。詳しくは help(shape) をお試し下さい。

塗りつぶしの色(fillcolor)を使いたくない(つまりタートルを透明にしたい)場合、 fillcolor = "" と書かなければなりません。 (しかし全ての空でない文字列は cfg ファイル中で引用符を付けてはいけません)

タートルにその状態を反映させるためには resizemode = auto とします。

たとえば language = italian とするとドキュメント文字列辞書(docstringdict) として turtle_docstringdict_italian.py がインポート時に読み込まれます (もしそれがインポートパス、たとえば turtle と同じディレクトリにあれば)。

exampleturtle および examplescreen はこれらのオブジェクトのドキュメント文字列内での呼び名を決めます。メソッドのドキュメント文字列から関数のドキュメント文字列に変換する際に、これらの名前は取り除かれます。

using_IDLE: IDLE とその -n スイッチ(サブプロセスなし)を常用するならば、この値を True に設定して下さい。これにより exitonclick() がメインループ(mainloop)に入るのを阻止します。

turtle.cfg ファイルは turtle の保存されているディレクトリと現在の作業ディレクトリに追加的に存在し得ます。後者が前者の設定をオーバーライドします。

Demo/turtle ディレクトリにも turtle.cfg ファイルがあります。デモを実際に(できればデモビュワーからでなく)実行してそこに書かれたものとその効果を学びましょう。

24.5.7. デモスクリプト

ソース配布物の Demo/turtle ディレクトリにデモスクリプト一式があります。

内容は以下の通りです:

新しい turtle モジュールの 15 の異なった特徴を示すデモスクリプト一式

ソースコードを眺めつつスクリプトを実行できるデモビュワー turtleDemo.py 。 14 個が Examples メニューからアクセスできます。もちろんそれらを独立して実行することもできます。

turtledemo_two_canvases.py は同時に二つのキャンバスを使用するデモです。これはビュワーからは実行できません。

turtle.cfg ファイルも同じディレクトリにあり、設定ファイルの書き方の例としても参考にできます。

デモスクリプトは以下の通りです:

名前 | 説明 | 特徴
bytedesign | 複雑な古典的タートルグラフィックスパターン | tracer(), delay, update()
chaos | verhust 力学系のグラフ化, コンピュータの計算が常識的な予想に反する場合があることを示します。 | 世界座標系
clock | コンピュータの時間を示すアナログ時計 | タートルが時計の針, ontimer
colormixer | r, g, b の実験 | ondrag()
fractalcurves | Hilbert & Koch 曲線 | 再帰
lindenmayer | 民俗的数学 (インド kolams) | L-システム
minimal_hanoi | ハノイの塔 | ハノイ盤として正方形のタートル (shape, shapesize)
paint | 超極小主義的描画プログラム | onclick()
peace | 初歩的 | turtle: 見た目とアニメーション
penrose | 凧と矢による非周期的タイリング | stamp()
planet_and_moon | 重力系のシミュレーション | 合成形, Vec2D
tree | (図形的) 幅優先木 (ジェネレータを使って) | clone()
wikipedia | タートルグラフィックスについての wikipedia の記事の例 | clone(), undo()
yingyang | もう一つの初歩的な例 | circle()

楽しんでね!

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.6. IDLE

IDLE は tkinter GUI ツールキットをつかって作られた Python IDE です。

IDLE は次のような特徴があります:

tkinter GUIツールキットを使って、100% ピュア Python でコーディングされています

クロスプラットホーム: Windows と Unix で動作します

多段 Undo、 Python 対応の色づけや他にもたくさんの機能 (例えば、自動的な字下げや呼び出し情報の表示)をもつマルチウィンドウ・テキストエディタ

Python シェルウィンドウ(別名、対話インタープリタ)

デバッガ(完全ではありませんが、ブレークポイントの設定や値の表示、ステップ実行ができます)

24.6.1. メニュー

24.6.1.1. Fileメニュー

New window

新しい編集ウィンドウを作成します

Open...

既存のファイルをオープンします

Open module...

既存のモジュールをオープンします(sys.pathを検索します)

Class browser

現在のファイルの中のクラスとモジュールを示します

Path browser

sys.pathディレクトリ、モジュール、クラスおよびメソッドを示します

Save

現在のウィンドウを対応するファイルにセーブします(未セーブのウィンドウには、ウィンドウタイトルの前後に*があります)

Save As...

現在のウィンドウを新しいファイルへセーブします。そのファイルが対応するファイルになります

Save Copy As...

現在のウィンドウを対応するファイルを変えずに異なるファイルにセーブします。

Close

現在のウィンドウを閉じます(未セーブの場合はセーブするか質問します)

Exit

すべてのウィンドウを閉じてIDLEを終了します(未セーブの場合はセーブするか質問します)

24.6.1.2. Editメニュー

Undo

現在のウィンドウに対する最後の変更をUndo(取り消し)します(最大で1000個の変更)

Redo

現在のウィンドウに対する最後にundoされた変更をRedo(再実行)します

Cut

システムのクリップボードへ選択された部分をコピーします。それから選択された部分を削除します

Copy

選択された部分をシステムのクリップボードへコピーします

Paste

システムのクリップボードをウィンドウへ挿入します

Select All

編集バッファの内容全体を選択します

Find...

たくさんのオプションをもつ検索ダイアログボックスを開きます

Find again

最後の検索を繰り返します

Find selection

選択された文字列を検索します

Find in Files...

検索するファイルに対する検索ダイアログボックスを開きます

Replace...

検索と置換ダイアログボックスを開きます

Go to line

行番号を尋ね、その行を表示します

Indent region

選択された行を右へ空白4個分シフトします

Dedent region

選択された行を左へ空白4個分シフトします

Comment out region

選択された行の先頭に##を挿入します

Uncomment region

選択された行から先頭の#あるいは##を取り除きます

Tabify region

先頭 の一続きの空白をタブに置き換えます

Untabify region

すべての タブを適切な数の空白に置き換えます

Expand word

あなたがタイプした語を同じバッファの別の語に一致するように展開します。異なる展開を得るためには繰り返します

Format Paragraph

現在の空行で区切られた段落を再フォーマットします

Import module

現在のモジュールをインポートまたはリロードします

Run script

現在のファイルを__main__名前空間内で実行します

24.6.1.3. Windowsメニュー

Zoom Height

ウィンドウを標準サイズ(24x80)と最大の高さの間で切り替えます

このメニューの残りはすべての開いたウィンドウの名前の一覧になっています。一つを選ぶとそれを最前面に持ってくることができます(必要ならばアイコン化をやめさせます)

24.6.1.4. Debugメニュー( Python シェルウィンドウ内のみ)

Go to file/line

挿入ポイントの周りからファイル名と行番号を探し、ファイルをオープンし、その行を表示します

Open stack viewer

最後の例外のスタックトレースバックを表示します

Debugger toggle

デバッガの下、シェル内でコマンドを実行します

JIT Stack viewer toggle

トレースバック上のスタックビューアをオープンします

24.6.2. 基本的な編集とナビゲーション

Backspace は左側を削除し、 Del は右側を削除します

矢印キーと Page Up/Page Down はそれぞれ移動します

Home/End は行の始め/終わりへ移動します

C-Home/C-End はファイルの始め/終わりへ移動します

C-B 、 C-P 、 C-A 、 C-E 、 C-D 、 C-L を含む、いくつかの Emacs バインディングも動作します

24.6.2.1. 自動的な字下げ

ブロックの始まりの文の後、次の行は4つの空白(Python Shell ウィンドウでは、一つのタブ)で字下げされます。あるキーワード(break、return など)の後では、次の行は字下げが解除(dedent)されます。先頭の字下げでは、 Backspace は4つの空白があれば削除します。 Tab は1-4つの空白(Python Shell ウィンドウでは一つのタブ)を挿入します。edit メニューの indent/dedent region コマンドも参照してください。

24.6.2.2. Python Shellウィンドウ

C-C 実行中のコマンドを中断します

C-D ファイル終端(end-of-file)を送り、 >>> プロンプトでタイプしていた場合はウィンドウを閉じます

Alt-p あなたがタイプしたことに一致する以前のコマンドを取り出します

Alt-n 次を取り出します

Return 以前のコマンドを取り出しているときは、そのコマンド

Alt-/ (語を展開します)ここでも便利です

24.6.3. 構文の色づけ

色づけはバックグランド”スレッド”で適用され、そのため時折色付けされないテキストが見えます。カラースキームを変えるには、 config.txt の [Colors] 節を編集してください。

Python の構文の色:

キーワード

オレンジ

文字列

緑

コメント

赤

定義

青

シェルの色:

コンソールの出力

茶色

stdout

青

stderr

暗い緑

stdin

黒

24.6.4. スタートアップ

-s オプションとともに起動すると、IDLEは環境変数 IDLESTARTUP か PYTHONSTARTUP で参照されているファイルを実行します。 IDLEはまず IDLESTARTUP をチェックし、あれば参照しているファイルを実行します。 IDLESTARTUP が無ければ、IDLEは PYTHONSTARTUP をチェックします。これらの環境変数で参照されているファイルは、IDLEシェルでよく使う関数を置いたり、一般的なモジュールのimport文を実行するのに便利です。

加えて、 Tk もスタートアップファイルがあればそれをロードします。そのTkのファイルは無条件にロードされることに注意してください。このファイルは .Idle.py で、ユーザーのホームディレクトリから探されます。このファイルの中の文は Tk の名前空間で実行されるので、IDLE の Pythonシェルで使う関数をimportするのには使えません。

24.6.4.1. コマンドラインの使い方

idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ...

-c コマンドこのコマンドを実行します
-d          デバッガを有効にします
-e          編集モード、引数は編集するファイルです
-s          $IDLESTARTUPまたは$PYTHONSTARTUPを最初に実行します
-t タイトルシェルウィンドウのタイトルを設定します

引数がある場合:

-e が使われる場合は、引数は編集のためにオープンされるファイルで、 sys.argv はIDLE自体へ渡される引数を反映します。

そうではなく、 -c が使われる場合には、すべての引数が sys.argv[1:...] の中に置かれ、 sys.argv[0] が '-c' に設定されます。

そうではなく、 -e も -c も使われない場合は、最初の引数は sys.argv[1:...] にある残りの引数とスクリプト名に設定される sys.argv[0] と一緒に実行されるスクリプトです。スクリプト名が ‘-‘ のときは、実行されるスクリプトはありませんが、対話的な Python セッションが始まります。引数はまだ sys.argv にあり利用できます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

24. Tkを用いたグラフィカルユーザインターフェイス »

24.7. 他のグラフィカルユーザインタフェースパッケージ

Tkinter に付け加えられるたくさんの拡張ウィジェットがあります。

参考

Python メガウィジェット [http://pmw.sourceforge.net/]

Tkinter モジュールを使い Python で高レベルの複合ウィジェットを構築するためのツールキットです。基本クラスとこの基礎の上に構築された柔軟で拡張可能なメガウィジェットから構成されています。これらのメガウィジェットはノートブック、コンボボックス、選択ウィジェット、ペインウィジェット、スクロールするウィジェット、ダイアログウィンドウなどを含みます。BLT に対する Pmw.Blt インタフェースを持ち、busy、graph、stripchart、tabset および vector コマンドが利用できます。

Pmwの最初のアイディアは、Michael McLennan による Tk itcl 拡張 [incr Tk] と Mark Ulferts による [incr Widgets] から得ました。メガウィジェットのいくつかは itcl から Python へ直接変換したものです。 [incr Widgets] が提供するウィジェットとほぼ同等のものを提供します。そして、Tix と同様にほぼ完成しています。しかしながら、ツリーを描くための Tix の高速な HList ウィジェットが欠けています。

Tkinter3000 Widget Construction Kit (WCK) [http://tkinter.effbot.org/]

は、新しい Tkinter ウィジェットを、 Python で書けるようにするライブラリです。WCK フレームワークは、ウィジェットの生成、設定、スクリーンの外観、イベント操作における、完全な制御を提供します。Tk/Tcl レイヤーを通してデータ転送する必要がなく、直接 Python のデータ構造を操作することができるので、 WCK ウィジェットは非常に高速で軽量になり得ます。

主要なクロスプラットフォーム (Windows, Mac OS X, Unix 系) GUI ツールキットで Python でも使えるものは:

参考

PyGTK [http://www.pygtk.org/]

は GTK [http://www.gtk.org/] ウィジェットセットのための一連のバインディングです。C のものより少しだけ高レベルなオブジェクト指向インタフェースを提供します。Tkinter が提供するよりも沢山のウィジェットがあり、Python に特化した参考資料も良いものがあります。 GNOME [http://www.gnome.org] に対しても、バインディングがあります。良く知られた PyGTK アプリケーションとしては、 PythonCAD [http://www.pythoncad.org/] 。オンライン チュートリアル [http://www.pygtk.org/pygtk2tutorial/index.html] が手に入ります。

PyQt [http://www.riverbankcomputing.co.uk/software/pyqt/]

PyQtは sip でラップされた Qt ツールキットへのバインディングです。Qt は Unix、Windows および Mac OS X で利用できる大規模な C++ GUI ツールキットです。 sip は Python クラスとして C++ ライブラリに対するバインディングを生成するためのツールキットで、特に Python 用に設計されています。 PyQt3 バインディング向けの書籍に Boudewijn Rempt 著 GUI Programming with Python: QT Edition [http://www.commandprompt.com/community/pyqt/] があります。 PyQt4 向けにも Mark Summerfield 著 Rapid GUI Programming with Python and Qt [http://www.qtrac.eu/pyqtbook.html] があります。

wxPython [http://www.wxpython.org]

wxPython はクロスプラットフォームの Python 用 GUI ツールキットで、人気のある wxWidgets [http://www.wxwidgets.org/] (旧名 wxWindows) C++ ツールキットに基づいて作られています。このツールキットは Windows, Mac OS X および Unix システムのアプリケーションに、それぞれのプラットフォームのネイティブなウィジェットを可能ならば利用して (Unix系のシステムではGTK+)、ネイティブなルック＆フィールを提供します。多彩なウィジェットの他に、オンラインドキュメントや場面に応じたヘルプ、印刷、HTML 表示、低級デバイスコンテキスト描画、ドラッグ＆ドロップ、システムクリップボードへのアクセス、XML に基づいたリソースフォーマット、さらにユーザ寄贈のモジュールからなる成長し続けているライブラリ等々をwxPython は提供しています。wxPython を扱った書籍として Noel Rappin、Robin Dunn 著 wxPython in Action [http://www.amazon.com/exec/obidos/ASIN/1932394621] があります。

PyGTK、PyQt および wxPython は全て現代的なルック＆フィールを具え Tkinter より豊富なウィジェットがあります。これらに加えて、他にも Python 用 GUI ツールキットが、クロスプラットフォームのもの、プラットフォーム固有のものを含め、沢山あります。Python Wiki の GUI Programming [http://wiki.python.org/moin/GuiProgramming] ページも参照してください。もっとずっと完全なリストや、GUI ツールキット同士の比較をしたドキュメントへのリンクがあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール

この章で紹介されるモジュールはソフトウェアを書くことを支援します。たとえば、 pydoc モジュールはモジュールの内容からドキュメントを生成します。 doctest と unittest モジュールでは、自動的に実行して予想通りの出力が生成されるか確認するユニットテストを書くことができます。 2to3 は Python2.x 用のソースコードを正当な Python 3.x コードに翻訳できます。

この章で解説されるモジュールの完全な一覧は:

25.1. pydoc — ドキュメント生成とオンラインヘルプシステム

25.2. doctest — 対話的な実行例をテストする

25.2.1. 簡単な利用法: docstring 中の実行例をチェックする

25.2.2. 簡単な利用法: テキストファイル中の実行例をチェックする

25.2.3. doctest のからくり

25.2.3.1. どの docstring が検証されるのか?

25.2.3.2. docstring 内の実行例をどのように認識するのか?

25.2.3.3. 実行コンテキストとは何か?

25.2.3.4. 例外はどう扱えばよいか?

25.2.3.5. オプションフラグとディレクティブ

25.2.3.6. 注意

25.2.4. 基本 API

25.2.5. 単体テスト API

25.2.6. 拡張 API

25.2.6.1. DocTest オブジェクト

25.2.6.2. Example オブジェクト

25.2.6.3. DocTestFinder オブジェクト

25.2.6.4. DocTestParser オブジェクト

25.2.6.5. DocTestRunner オブジェクト

25.2.6.6. OutputChecker オブジェクト

25.2.7. デバッグ

25.2.8. アドバイス

25.3. unittest — ユニットテストフレームワーク

25.3.1. 基礎的な例

25.3.2. コマンドラインインタフェース

25.3.2.1. コマンドラインオプション

25.3.3. テストディスカバリ

25.3.4. テストの構成

25.3.5. 既存テストコードの再利用

25.3.6. テストのスキップと意図的な失敗

25.3.7. クラスと関数

25.3.7.1. テストクラス

25.3.7.1.1. 廃止予定のエイリアス

25.3.7.2. テストのグルーピング

25.3.7.3. テストのロードと起動

25.3.7.3.1. load_tests プロトコル

25.3.8. クラスとモジュールの修正

25.3.8.1. setUpClass と tearDownClass

25.3.8.2. setUpModule と tearDownModule

25.3.9. シグナルハンドリング

25.4. 2to3 - Python 2 から 3 への自動コード変換

25.4.1. 2to3 の使用

25.4.2. 変換プログラム

25.4.3. lib2to3 - 2to3’s library

25.5. test — Python用回帰テストパッケージ

25.5.1. test パッケージのためのユニットテストを書く

25.5.2. コマンドラインインタフェースを利用してテストを実行する

25.5.3. test.test_support — テストのためのユーティリティ関数

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール »

25.1. pydoc — ドキュメント生成とオンラインヘルプシステム

バージョン 2.1 で追加.

pydoc モジュールは、Pythonモジュールから自動的にドキュメントを生成します。生成されたドキュメントをテキスト形式でコンソールに表示したり、 Web ブラウザにサーバとして提供したり、HTMLファイルとして保存したりできます。

組み込み関数の help() を使うことで、対話型のインタプリタからオンラインヘルプを起動することができます。コンソール用のテキスト形式のドキュメントをつくるのにオンラインヘルプでは pydoc を使っています。 pydoc をPythonインタプリタからはなく、オペレーティングシステムのコマンドプロンプトから起動した場合でも、同じテキスト形式のドキュメントを見ることができます。例えば、以下をshellから実行すると

pydoc sys

sys モジュールのドキュメントを、Unix の man コマンドのような形式で表示させることができます。 pydoc の引数として与えることができるのは、関数名・モジュール名・パッケージ名、また、モジュールやパッケージ内のモジュールに含まれるクラス・メソッド・関数へのドット”.”形式での参照です。 pydoc への引数がパスと解釈されるような場合で(オペレーティングシステムのパス区切り記号を含む場合です。例えばUnixならば “/”(スラッシュ)含む場合になります)、さらに、そのパスがPythonのソースファイルを指しているなら、そのファイルに対するドキュメントが生成されます。

ノート

オブジェクトとそのドキュメントを探すために、 pydoc はドキュメント対象のモジュールを import します。そのため、モジュールレベルのコードはそのときに実行されます。 if __name__ == '__main__': ガードを使って、ファイルがスクリプトとして実行したときのみコードを実行し、importされたときには実行されないようにして下さい。

引数の前に -w フラグを指定すると、コンソールにテキストを表示させるかわりにカレントディレクトリにHTMLドキュメントを生成します。

引数の前に -k フラグを指定すると、引数をキーワードとして利用可能な全てのモジュールの概要を検索します。検索のやりかたは、Unixの man コマンドと同様です。モジュールの概要というのは、モジュールのドキュメントの一行目のことです。

また、 pydoc を使うことでローカルマシンに Web browserから閲覧可能なドキュメントを提供するHTTPサーバーを起動することもできます。 pydoc -p 1234 とすると、HTTPサーバーをポート1234に起動します。これで、お好きなWebブラウザを使って http://localhost:1234/ からドキュメントを見ることができます。 pydoc -g はサーバーを起動したうえで、検索用に小さい Tkinter ベースのGUIを表示します。

pydoc でドキュメントを生成する場合、その時点での環境とパス情報に基づいてモジュールがどこにあるのか決定されます。そのため、 pydoc spam を実行した場合につくられるドキュメントは、 Pythonインタプリタを起動して import spam と入力したときに読み込まれるモジュールに対するドキュメントになります。

コアモジュールのドキュメントは http://docs.python.org/library/ にあると仮定されています。これは、ライブラリリファレンスマニュアルを置いている異なるURLかローカルディレクトリを環境変数 PYTHONDOCS に設定することでオーバーライドすることができます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール »

25.2. doctest — 対話的な実行例をテストする

doctest モジュールは、対話的 Python セッションのように見えるテキストを探し出し、セッションの内容を実行して、そこに書かれている通りに振舞うかを調べます。 doctest は以下のような用途によく使われています。

モジュールの docstring (ドキュメンテーション文字列) 中にある対話実行例のすべてが書かれている通りに動作するか検証することで、 docstring の内容が最新かどうかチェックする。

テストファイルやテストオブジェクト中の対話実行例が期待通りに動作するかを検証することで、回帰テストを実現します。

入出力例を豊富に使ったパッケージのチュートリアルドキュメントが書けます。入出力例と解説文のどちらに注目するかによって、ドキュメントは「読めるテスト」にも「実行できるドキュメント」にもなります。

以下に完全かつ短い実行例を示します。

"""
This is the "example" module.

The example module supplies one function, factorial().  For example,

>>> factorial(5)
120
"""

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    If the result is small enough to fit in an int, return an int.
    Else return a long.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> [factorial(long(n)) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000L
    >>> factorial(30L)
    265252859812191058636308480000000L
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000L

    It must also not be ridiculously large:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # 1e300 のような値を捕らえる
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result

if __name__ == "__main__":
    import doctest
    doctest.testmod()

example.py をコマンドラインから直接実行すると、 doctest はその魔法を働かせます。

$ python example.py
$

出力は何もありません！ しかしこれが正常で、すべての実行例が正しく動作することを意味しています。スクリプトに -v を与えると、 doctest は何を行おうとしているのかを記録した詳細なログを出力し、最後にまとめを出力します。

$ python example.py -v
Trying:
    factorial(5)
Expecting:
    120
ok
Trying:
    [factorial(n) for n in range(6)]
Expecting:
    [1, 1, 2, 6, 24, 120]
ok
Trying:
    [factorial(long(n)) for n in range(6)]
Expecting:
    [1, 1, 2, 6, 24, 120]
ok

といった具合で、最後には

Trying:
    factorial(1e100)
Expecting:
    Traceback (most recent call last):
        ...
    OverflowError: n too large
ok
2 items passed all tests:
   1 tests in __main__
   8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
$

doctest の生産的な利用を始めるために知る必要があるのはこれだけです！さあやってみましょう。詳細な事柄は後続の各節ですべて説明しています。 doctest の例は、標準の Python テストスイートやライブラリ中に沢山あります。標準のテストファイル Lib/test/test_doctest.py には、特に役に立つ例があります。

25.2.1. 簡単な利用法: docstring 中の実行例をチェックする

doctest を試す簡単な方法 (とはいえ、いつもそうする必要はないのですが) は、各モジュール M の最後を、以下のようにして締めくくることです。

if __name__ == "__main__":
    import doctest
    doctest.testmod()

こうすると、 doctest は M 中の docstring を検査します。

モジュールをスクリプトとして実行すると、docstring 中の実行例が実行され、検証されます。

python M.py

docstring に書かれた実行例の実行が失敗しない限り、何も表示されません。失敗すると、失敗した実行例と、その原因が (場合によっては複数) 標準出力に印字され、最後に ***Test Failed*** N failures. という行を出力します。ここで、 N は失敗した実行例の数です。

一方、 -v スイッチをつけて走らせると

python M.py -v

実行を試みたすべての実行例について詳細に報告し、最後に各種まとめを行った内容が標準出力に印字されます。

verbose=True を testmod() に渡せば、詳細報告 (verbose) モードを強制できます。また、 verbose=False にすれば禁止できます。どちらの場合にも、 testmod() は sys.argv 上のスイッチを調べません。(したがって、 -v をつけても効果はありません)。

Python 2.6 からは testmod() を実行するコマンドラインショートカットがあります。 Python インタプリタに doctest モジュールを標準ライブラリから直接実行して、テストするモジュール名をコマンドライン引数に与えます。

python -m doctest -v example.py

こうすると example.py を単体モジュールとしてインポートして、それに対して testmod() を実行します。このファイルがパッケージの一部で他のサブモジュールをそのパッケージからインポートしている場合はうまく動かないことに注意してください。

testmod() の詳しい情報は 基本 API 節を参照してください。

25.2.2. 簡単な利用法: テキストファイル中の実行例をチェックする

doctest のもう一つの簡単な用途は、テキストファイル中にある対話実行例に対するテストです。これには testfile() 関数を使います。

import doctest
doctest.testfile("example.txt")

この短いスクリプトは、 example.txt というファイルの中に入っている対話モードの Python 操作例すべてを実行して、その内容を検証します。ファイルの内容は一つの巨大な docstring であるかのように扱われます; ファイルが Python プログラムである必要はありません！例えば、 example.txt には以下のような内容が入っているとします。

``example`` モジュール
======================

``factorial`` の使い方
----------------------

これは reStructuredText 形式で書かれたテキストファイルの例です。
最初に ``factorial`` を ``example`` モジュールからインポートします。

    >>> from example import factorial

そして、インポートした ``factorial`` を使います:

    >>> factorial(6)
    120

doctest.testfile("example.txt") を実行すると、このドキュメント内のエラーを見つけ出します。

File "./example.txt", line 14, in example.txt
Failed example:
    factorial(6)
Expected:
    120
Got:
    720

testmod() と同じく、 testfile() は実行例が失敗しない限り何も表示しません。実行例が失敗すると、失敗した実行例とその原因が (場合によっては複数) testmod() と同じ書式で標準出力に書き出されます。

デフォルトでは、 testfile() は自分自身を呼び出したモジュールのあるディレクトリを探します。その他の場所にあるファイルを見に行くように testfile() に指示するためのオプション引数についての説明は 基本 API 節を参照してください。

testmod() と同様に testfile() の冗長性 (verbosity) はコマンドラインスイッチ -v またはオプションのキーワード引数 verbose によって指定できます。

Python 2.6 からは testfile() を実行するコマンドラインショートカットがあります。 Python インタプリタに doctest モジュールを標準ライブラリから直接実行して、テストするモジュール名をコマンドライン引数に与えます。

python -m doctest -v example.txt

ファイル名が .py で終っていないので、 doctest は testmod() ではなく testfile() を使って実行するのだと判断します。

testfile() の詳細は 基本 API 節を参照してください。

25.2.3. doctest のからくり

この節では、doctest のからくり: どの docstring を見に行くのか、どのように対話実行例を見つけ出すのか、どんな実行コンテキストを使うのか、例外をどう扱うか、上記の振る舞いを制御するためにどのようなオプションフラグを使うか、について詳しく吟味します。こうした情報は、 doctest に対応した実行例を書くために必要な知識です; 書いた実行例に対して実際に doctest を実行する上で必要な情報については後続の節を参照してください。

25.2.3.1. どの docstring が検証されるのか?

モジュールの docstring と、すべての関数、クラスおよびメソッドの docstring が検索されます。モジュールに import されたオブジェクトは検索されません。

加えて、 M.__test__ が存在し、 “真の値を持つ” 場合、この値は辞書でなければならず、辞書の各エントリは (文字列の) 名前を関数オブジェクト、クラスオブジェクト、または文字列へとマップします。 M.__test__ から得られた関数およびクラスオブジェクトの docstring は、その名前がプライベートなものでも検索され、文字列の場合にはそれが docstring であるかのように扱われます。出力においては、 M.__test__ におけるキー K は、

<name of M>.__test__.K

のように表示されます。

検索中に見つかったクラスも同様に再帰的に検索が行われ、クラスに含まれているメソッドおよびネストされたクラスについて docstring のテストが行われます。

バージョン 2.4 で変更: “プライベート名” の概念は廃止されたため、ドキュメント化されなくなりました。

25.2.3.2. docstring 内の実行例をどのように認識するのか?

ほとんどの場合、対話コンソールセッション上でのコピー／ペーストはうまく動作します。とはいえ、 doctest は特定の Python シェルの振る舞いを正確にエミュレーションしようとするわけではありません。

>>> # コメントは無視されます
>>> x = 12
>>> x
12
>>> if x == 13:
...     print "yes"
... else:
...     print "no"
...     print "NO"
...     print "NO!!!"
...
no
NO
NO!!!
>>>

コードを含む最後の '>>> ' または '... ' 行の直下に期待する出力結果が置かれます。 (出力結果がもしあれば) それは次の '>>> ' 行か、すべて空白文字の行まで続きます。

詳細事項:

期待する出力結果には、空白だけの行が入っていてはなりません。そのような行は期待する出力結果の終了を表すと見なされるからです。もし期待する出力結果の内容に空白行が入っている場合には、空白行が入るべき場所すべてに <BLANKLINE> を入れてください。

バージョン 2.4 で追加: <BLANKLINE> が追加されました; 以前のバージョンでは、空白行を含む出力結果を扱う方法がありませんでした。

ハードタブはすべて 8 カラムのタブストップを使ってスペースに展開されます。テストコードによって生成された出力におけるタブは変更されていません。サンプル出力におけるハードタブはすべて展開 される ので、これが意味するのは、コード出力がハードタブを含んでいるなら、そのような doctest が成功するのは NORMALIZE_WHITESPACE オプションまたはディレクティブが有効な場合だけだということです。あるいは、テストの一部として出力を得て、それを期待値と比較するようにテストを書き直すことができます。このようなソース中のタブの取り扱いは試行錯誤の結果で、最も誤りの傾向が少ないことが示された方法です。カスタムな DocTestParser クラスを書くことによって、タブを扱うのに異なるアルゴリズムを使うことができます。

バージョン 2.4 で変更: 新たにタブをスペースに展開するようになりました; 以前のバージョンはハードタブを保存しようとしていたので、混乱させるようなテスト結果になってしまっていました。

標準出力への出力は取り込まれますが、標準エラーは取り込まれません (例外発生時のトレースバックは別の方法で取り込まれます)。

対話セッションにおいて、バックスラッシュを用いて次の行に続ける場合や、その他の理由でバックスラッシュを用いる場合、raw docstring を使ってバックスラッシュを入力どおりに扱わせるようにしなければなりません。

>>> def f(x):
...     r'''Backslashes in a raw docstring: m\n'''
>>> print f.__doc__
Backslashes in a raw docstring: m\n

こうしなければ、バックスラッシュは文字列の一部として解釈されてしまいます。例えば、上の例の “\n” は改行文字として認識されてしまうでしょう。こうする代わりに、(raw docstring を使わずに) doctest 版の中ではバックスラッシュをすべて二重にしてもかまいません。

>>> def f(x):
...     '''Backslashes in a raw docstring: m\\n'''
>>> print f.__doc__
Backslashes in a raw docstring: m\n

開始カラムはどこでもかまいません。

>>> assert "Easy!"
      >>> import math
          >>> math.floor(1.9)
          1.0

期待する出力結果の先頭部にある空白文字列は、実行例の開始部分にあたる '>>> ' 行の先頭にある空白文字列と同じだけ取り除かれます。

25.2.3.3. 実行コンテキストとは何か?

デフォルトでは、 doctest はテストを行うべき docstring を見つけるたびに M のグローバル名前空間の 浅いコピー を使い、テストの実行によってモジュールの実際のグローバル名前空間を変更しないようにし、かつ M 内で行ったテストが痕跡を残して偶発的に別のテストを誤って動作させないようにしています。したがって、実行例中では M 内のトップレベルで定義されたすべての名前と、 docstring が動作する以前に定義された名前を自由に使えます。個々の実行例は他の docstring 中で定義された名前を参照できません。

testmod() や testfile() に globs=your_dict を渡し、自前の辞書を実行コンテキストとして使うこともできます。

25.2.3.4. 例外はどう扱えばよいか?

トレースバックが実行例によって生成される唯一の出力なら問題ありません。単にトレースバックを貼り付けてください。 [1] トレースバックには、頻繁に変更されがちな情報 (例えばファイルパスや行番号など) が入っているものなので、これは受け入れるテスト結果に柔軟性を持たせようと doctest が苦労している部分の一つです。

簡単な例を示しましょう。

>>> [1, 2, 3].remove(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: list.remove(x): x not in list

この doctest は、 ValueError が送出され、その詳細情報が list.remove(x): x not in list である場合に成功します。

例外が発生したときの期待する出力はトレースバックヘッダから始まっていなければなりません。トレースバックの形式は以下の二通りの行のいずれかで、実行例の最初の行と同じインデントでなければりません。

Traceback (most recent call last):
Traceback (innermost last):

トレースバックヘッダの後ろにトレースバックスタックが続いてもかまいませんが、 doctest はその内容を無視します。普通はトレースバックスタックを省略するか、対話セッションからそのままコピーしてきます。

トレースバックスタックの後ろにはもっとも有意義な部分、例外の型と詳細情報の入った行があります。これは通常トレースバックの最後の行ですが、例外が複数行の詳細情報を持っている場合、複数の行にわたることもあります。

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: multi
    line
detail

上の例では、最後の 3 行 (ValueError から始まる行) における例外の型と詳細情報だけが比較され、それ以外の部分は無視されます。

バージョン 2.4 で変更: 以前のバージョンでは、複数行にわたる例外の詳細を扱えませんでした。

例外を扱うコツは、実行例をドキュメントとして読む上で明らかに価値のある情報でない限り、トレースバックスタックは省略する、ということです。したがって、先ほどの例は以下のように書くべきでしょう。

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
    ...
ValueError: multi
    line
detail

トレースバックの扱いは非常に特殊なので注意してください。特に、上の書き直した実行例では、 ... の扱いは doctest の ELLIPSIS オプションとは独立しています。この例での省略記号は何かの省略を表しているかもしれませんし、コンマや数字が 3 個 (または 300 個) かもしれませんし、 Monty Python のスキットをインデントして書き写したものかもしれません。

以下の詳細はずっと覚えておく必要はないのですが、一度目を通しておいてください。

doctest は期待する出力の出所が print 文なのか例外なのかを推測できません。したがって、例えば期待する出力が ValueError: 42 is prime であるような実行例は、 ValueError が実際に送出された場合と、万が一期待する出力と同じ文字列を print した場合の両方で成功してしまいます。現実的には、通常の出力がトレースバックヘッダから始まることはないので、実際に問題になることはないでしょう。

トレースバックスタック (がある場合) の各行は、実行例の最初の行よりも深くインデントされているか、または 英数文字以外で始まっていなければなりません。トレースバックヘッダ以後に現れる行のうち、インデントが等しく英数文字で始まる最初の行は例外の詳細情報が書かれた行とみなされるからです。もちろん、本物のトレースバックでは正しく動作します。

doctest のオプション IGNORE_EXCEPTION_DETAIL を指定した場合、最も左端のコロン以後の全ての内容と、例外名の中の全てのモジュール情報が無視されます。

対話シェルでは、 SyntaxError の場合にトレースバックヘッダが省略されることがあります。しかし doctest にとっては、例外を例外でないものと区別するためにトレースバックヘッダが必要です。そこで、トレースバックヘッダを省略するような SyntaxError をテストする必要があるというごく稀なケースでは、実行例にトレースバックヘッダを手作業で追加する必要があるでしょう。

SyntaxError の場合、 Python は構文エラーの起きた場所を ^ マーカで表示します。

>>> 1 1
  File "<stdin>", line 1
    1 1
      ^
SyntaxError: invalid syntax

例外の型と詳細情報の前にエラー位置を示す行がくるため、 doctest はこの行を調べません。例えば、以下の例では、間違った場所に ^ マーカを入れても成功してしまいます。

>>> 1 1
  File "<stdin>", line 1
    1 1
    ^
SyntaxError: invalid syntax

25.2.3.5. オプションフラグとディレクティブ

doctest では、その挙動の様々な側面をたくさんのオプションフラグで制御しています。各フラグのシンボル名はモジュールの定数として提供されており、論理和で組み合わせて様々な関数に渡せるようになっています。シンボル名は doctest のディレクティブ (directive, 下記参照) としても使えます。

最初に説明するオプション群は、テストのセマンティクスを決めます。すなわち、実際にテストを実行したときの出力と実行例中の期待する出力とが一致しているかどうかを doctest がどのように判断するかを制御します。

doctest.DONT_ACCEPT_TRUE_FOR_1

デフォルトでは、期待する出力ブロックに単に 1 だけが入っており、実際の出力ブロックに 1 または True だけが入っていた場合、これらの出力は一致しているとみなされます。 0 と False の場合も同様です。 DONT_ACCEPT_TRUE_FOR_1 を指定すると、こうした値の読み替えを行いません。デフォルトの挙動で読み替えを行うのは、最近の Python で多くの関数の戻り値型が整数型からブール型に変更されたことに対応するためです; 読み替えを行う場合、”通常の整数” の出力を期待する出力とするような doctest も動作します。このオプションはそのうちなくなるでしょうが、ここ数年はそのままでしょう。

doctest.DONT_ACCEPT_BLANKLINE

デフォルトでは、期待する出力ブロックに <BLANKLINE> だけの入った行がある場合、その行は実際の出力における空行に一致するようになります。完全な空行を入れてしまうと期待する出力がそこで終わっているとみなされてしまうため、期待する出力に空行を入れたい場合にはこの方法を使わなければなりません。 DONT_ACCEPT_BLANKLINE を指定すると、 <BLANKLINE> の読み替えを行わなくなります。

doctest.NORMALIZE_WHITESPACE

このフラグを指定すると、連続する空白 (空白と改行文字) は互いに等価であるとみなします。期待する出力における任意の空白列は実際の出力における任意の空白と一致します。デフォルトでは、空白は厳密に一致しなければなりません。 NORMALIZE_WHITESPACE は、期待する出力の内容が非常に長いために、ソースコード中でその内容を複数行に折り返して書きたい場合に特に便利です。

doctest.ELLIPSIS

このフラグを指定すると、期待する出力中の省略記号マーカ (...) が実際の出力中の任意の部分文字列と一致するようになります。部分文字列は行境界にわたるものや空文字列を含みます。したがって、このフラグを使うのは単純な内容を対象にする場合にとどめましょう。複雑な使い方をすると、正規表現に .* を使ったときのように “しまった、マッチしすぎた！ (match too much!)” と驚くことになりかねません。

doctest.IGNORE_EXCEPTION_DETAIL

このフラグを指定すると、期待する実行結果に例外が入るような実行例で、期待通りの型の例外が送出された場合に、例外の詳細情報が一致していなくてもテストが成功します。例えば、期待する出力が ValueError: 42 であるような実行例は、実際に送出された例外が ValueError: 3*14 でも成功しますが、 TypeError が送出されるといった場合には成功しません。

これは Python 3 doctest レポートにおいて使われるモジュール名も無視します。従って、以下の 2 つのテストは、Python 2.7 と Python 3.2 (またはそれ以降) のどちらでも同じように動作します:

>>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
CustomError: message

>>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
my_module.CustomError: message

なお、 ELLIPSIS を使っても例外メッセージの詳細を無視することができますが、モジュールの詳細が例外名の一部として表示されるかどうかに依存するようなテストは、やはり失敗します。また、 IGNORE_EXCEPTION_DETAIL と Python 2.3 の詳細情報を使うことが、例外の詳細に影響されず、なおかつ Python 2.3 以前 の Python (これらのリリースは doctest ディレクティブをサポートせず、これらを無関係なコメントとして無視します) で成功する doctest を書くための、唯一の明確な方法です。例えば、例外の詳細情報は 2.4 で変更され、 “doesn’t” の代わりに “does not” と書くようになりましたが:

>>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment

とすると、 Python 2.3 以降の Python バージョンでテストを成功させることができます。

バージョン 2.7 で変更: IGNORE_EXCEPTION_DETAIL は、テストにおいて例外を含むモジュールに関する情報も無視するようになりました。

doctest.SKIP

このフラグを指定すると、実行例は一切実行されません。こうした機能は doctest の実行例がドキュメントとテストを兼ねていて、ドキュメントのためには含めておかなければならないけれどチェックされなくても良い、というような文脈で役に立ちます。例えば、実行例の出力がランダムであるとか、テストドライバーには利用できないリソースに依存している場合などです。

SKIP フラグは一時的に実行例を”コメントアウト”するのにも使えます。

バージョン 2.5 で追加.

doctest.COMPARISON_FLAGS

上記の比較フラグすべての論理和をとったビットマスクです。

二つ目のオプション群は、テストの失敗を報告する方法を制御します。

doctest.REPORT_UDIFF

このオプションを指定すると、期待する出力および実際の出力が複数行になるときにテストの失敗結果を unified diff 形式を使って表示します。

doctest.REPORT_CDIFF

このオプションを指定すると、期待する出力および実際の出力が複数行になるときにテストの失敗結果を context diff 形式を使って表示します。

doctest.REPORT_NDIFF

このオプションを指定すると、期待する出力と実際の出力との間の差分を difflib.Differ を使って算出します。使われているアルゴリズムは有名な ndiff.py ユーティリティと同じです。これは、行単位の差分と同じように行内の差分にマーカをつけられるようにする唯一の手段です。例えば、期待する出力のある行に数字の 1 が入っていて、実際の出力には l が入っている場合、不一致の起きているカラム位置を示すキャレットの入った行が一行挿入されます。

doctest.REPORT_ONLY_FIRST_FAILURE

このオプションを指定すると、各 doctest で最初にエラーの起きた実行例だけを表示し、それ以後の実行例の出力を抑制します。これにより、正しく書かれた実行例が、それ以前の実行例の失敗によっておかしくなってしまった場合に、 doctest がそれを報告しないようになります。とはいえ、最初に失敗を引き起こした実行例とは関係なく誤って書かれた実行例の報告も抑制してしまいます。 REPORT_ONLY_FIRST_FAILURE を指定した場合、実行例がどこかで失敗しても、それ以後の実行例を続けて実行し、失敗したテストの総数を報告します; 出力が抑制されるだけです。

doctest.REPORTING_FLAGS

上記のエラー報告に関するフラグすべての論理和をとったビットマスクです。

「doctest ディレクティブ」を使うと、個々の実行例に対してオプションフラグの設定を変更できます。 doctest ディレクティブは特殊な Python コメント文として表現され、実行例のソースコードの後に続けます。

directive             ::=  "#" "doctest:" directive_options
directive_options     ::=  directive_option ("," directive_option)\*
directive_option      ::=  on_or_off directive_option_name
on_or_off             ::=  "+" \| "-"
directive_option_name ::=  "DONT_ACCEPT_BLANKLINE" \| "NORMALIZE_WHITESPACE" \| ...

+ や - とディレクティブオプション名の間に空白を入れてはなりません。ディレクティブオプション名は上で説明したオプションフラグ名のいずれかです。

ある実行例の doctest ディレクティブは、その実行例だけの doctest の振る舞いを変えます。ある特定の挙動を有効にしたければ + を、無効にしたければ - を使います。

例えば、以下のテストは成功します。

>>> print range(20) #doctest: +NORMALIZE_WHITESPACE
[0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
10,  11, 12, 13, 14, 15, 16, 17, 18, 19]

ディレクティブがない場合、実際の出力には一桁の数字の間に二つスペースが入っていないこと、実際の出力は 1 行になることから、テストは成功しないはずです。別のディレクティブを使って、このテストを成功させることもできます。

>>> print range(20) # doctest:+ELLIPSIS
[0, 1, ..., 18, 19]

複数のディレクティブは、一つの物理行の中にコンマで区切って指定できます。

>>> print range(20) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[0,    1, ...,   18,    19]

一つの実行例中で複数のディレクティブコメントを使った場合、それらは組み合わされます。

>>> print range(20) # doctest: +ELLIPSIS
...                 # doctest: +NORMALIZE_WHITESPACE
[0,    1, ...,   18,    19]

この実行例で分かるように、実行例にはディレクティブだけを含む ... 行を追加することができます。この書きかたは、実行例が長すぎるためにディレクティブを同じ行に入れると収まりが悪い場合に便利です。

>>> print range(5) + range(10,20) + range(30,40) + range(50,60)
... # doctest: +ELLIPSIS
[0, ..., 4, 10, ..., 19, 30, ..., 39, 50, ..., 59]

フォルトではすべてのオプションが無効になっており、ディレクティブは特定の実行例だけに影響を及ぼすので、通常意味があるのは有効にするためのオプション (+ のついたディレクティブ) だけです。とはいえ、 doctest を実行する関数はオプションフラグを指定してデフォルトとは異なった挙動を実現できるので、そのような場合には - を使った無効化オプションも意味を持ちます。

バージョン 2.4 で追加: doctest ディレクティブおよび関連する定数 DONT_ACCEPT_BLANKLINE, NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL, REPORT_UDIFF, REPORT_CDIFF, REPORT_NDIFF, REPORT_ONLY_FIRST_FAILURE, COMPARISON_FLAGS, および REPORTING_FLAGS が追加されました。

新たなオプションフラグ名を登録する方法もありますが、 doctest の内部をサブクラスで拡張しない限り、意味はないでしょう。

doctest.register_optionflag(name)

名前 name の新たなオプションフラグを作成し、作成されたフラグの整数値を返します。 register_optionflag() は OutputChecker や DocTestRunner をサブクラス化して、その中で新たに作成したオプションをサポートさせる際に使います。 register_optionflag() は以下のような定形文で呼び出さなければなりません。

MY_FLAG = register_optionflag('MY_FLAG')

バージョン 2.4 で追加.

25.2.3.6. 注意

doctest では、期待する出力に対する完全一致を厳格に求めます。一致しない文字が一文字でもあると、テストは失敗してしまいます。このため、 Python が出力に関して何を保証していて、何を保証していないかを正確に知っていないと度々混乱させられることでしょう。例えば、辞書を出力する際、 Python はキーと値のペアが常に特定の順番で並ぶよう保証してはいません。したがって、以下のようなテスト

>>> foo()
{"Hermione": "hippogryph", "Harry": "broomstick"}

は失敗するかもしれないのです! 回避するには

>>> foo() == {"Hermione": "hippogryph", "Harry": "broomstick"}
True

とするのが一つのやり方です。別のやり方は、

>>> d = foo().items()
>>> d.sort()
>>> d
[('Harry', 'broomstick'), ('Hermione', 'hippogryph')]

です。

他のやり方もありますが、あとは自分で考えてみてください。

以下のように、オブジェクトアドレスを埋め込むような結果を print するのもよくありません。

>>> id(1.0) # いつか確実に失敗する
7948648
>>> class C: pass
>>> C()   # インスタンスに対するデフォルトの repr() にはアドレスが埋め込まれる
<__main__.C instance at 0x00AC18F0>

ELLIPSIS ディレクティブを使うと、上のような例をうまく解決できます。

>>> C() #doctest: +ELLIPSIS
<__main__.C instance at 0x...>

浮動小数点数もまた、プラットフォーム間での微妙な出力の違いの原因となります。というのも、Python は浮動小数点の書式化をプラットフォームの C ライブラリに委ねており、この点では、C ライブラリはプラットフォーム間で非常に大きく異なっているからです。

>>> 1./7  # 危険
0.14285714285714285
>>> print 1./7 # 多少は安全
0.142857142857
>>> print round(1./7, 6) # より安全
0.142857

I/2.**J の形式になる数値はどのプラットフォームでもうまく動作するので、私はこの形式の数値を生成するように doctest の実行例を工夫しています。

>>> 3./4  # 絶対に安全
0.75

単純な分数は人間にとっても理解しやすく、良いドキュメントを書くために役に立ちます。

25.2.4. 基本 API

数 testmod() と testfile() は、ほとんどの基本的な用途に十分な doctest インタフェースを提供しています。これら二つの関数についてあまり形式的でない入門が読みたければ、簡単な利用法: docstring 中の実行例をチェックする 節や 簡単な利用法: テキストファイル中の実行例をチェックする 節を参照してください。

doctest.testfile(filename[, module_relative][, name][, package][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, parser][, encoding])

filename 以外の引数はすべてオプションで、キーワード引数形式で指定しなければなりません。

filename に指定したファイル内にある実行例をテストします。 (failure_count, test_count) を返します。

オプション引数の module_relative は、ファイル名をどのように解釈するかを指定します。

module_relative が True (デフォルト) の場合、 filename は OS に依存しないモジュールの相対パスになります。デフォルトでは、このパスは関数 testfile() を呼び出しているモジュールからの相対パスになります; ただし、 package 引数を指定した場合には、パッケージからの相対になります。 OS への依存性を除くため、 filename ではパスを分割する文字に / を使わなければならず、絶対パスにしてはなりません (パス文字列を / で始めてはなりません)。

module_relative が False の場合、 filename は OS 依存のパスを示します。パスは絶対パスでも相対パスでもかまいません; 相対パスにした場合、現在の作業ディレクトリを基準に解決します。

オプション引数 name には、テストの名前を指定します; デフォルトの場合や None を指定した場合、 os.path.basename(filename) になります。

オプション引数 package には、 Python パッケージを指定するか、モジュール相対のファイル名の場合には相対の基準ディレクトリとなる Python パッケージの名前を指定します。パッケージを指定しない場合、関数を呼び出しているモジュールのディレクトリを相対の基準ディレクトリとして使います。 module_relative を False に指定している場合、 package を指定するとエラーになります。

オプション引数 globs には辞書を指定します。この辞書は、実行例を実行する際のグローバル変数として用いられます。 doctest はこの辞書の浅いコピーを生成するので、実行例は白紙の状態からスタートします。デフォルトの場合や None を指定した場合、新たな空の辞書になります。

オプション引数 extraglobs には辞書を指定します。この辞書は、実行例を実行する際にグローバル変数にマージされます。マージは dict.update() のように振舞います: globs と extraglobs との間に同じキー値がある場合、両者を合わせた辞書中には extraglobs の方の値が入ります。この仕様は、パラメータ付きで doctest を実行するという、やや進んだ機能です。例えば、一般的な名前を使って基底クラス向けに doctest を書いておき、その後で辞書で一般的な名前からテストしたいサブクラスへの対応付けを行う辞書を extraglobs に渡して、様々なサブクラスをテストできます。

オプション引数 verbose が真の場合、様々な情報を出力します。偽の場合にはテストの失敗だけを報告します。デフォルトの場合や None を指定した場合、 sys.argv に -v を指定しない限りこの値は真になりません。

オプション引数 report が真の場合、テストの最後にサマリを出力します。それ以外の場合には何も出力しません。 verbose モードの場合、サマリには詳細な情報を出力しますが、そうでない場合にはサマリはとても簡潔になります (実際には、すべてのテストが成功した場合には何も出力しません)。

オプション引数 optionflags は、各オプションフラグの論理和をとった値を指定します。 オプションフラグとディレクティブ節を参照してください。

オプション引数 raise_on_error の値はデフォルトでは偽です。真にすると、最初のテスト失敗や予期しない例外が起きたときに例外を送出します。このオプションを使うと、失敗の原因を検死デバッグ (post-mortem debug) できます。デフォルトの動作では、実行例の実行を継続します。

オプション引数 parser には、 DocTestParser (またはそのサブクラス) を指定します。このクラスはファイルから実行例を抽出するために使われます。デフォルトでは通常のパーザ (DocTestParser()) です。

オプション引数 encoding にはファイルをユニコードに変換する際に使われるエンコーディングを指定します。

バージョン 2.4 で追加.

バージョン 2.5 で変更: encoding パラメータが追加されました。

doctest.testmod([m][, name][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, exclude_empty])

引数はすべてオプションで、 m 以外の引数はキーワード引数として指定しなければなりません。

モジュール m (m を指定しないか None にした場合には __main__) から到達可能な関数およびクラスの docstring 内にある実行例をテストします。 m.__doc__ 内の実行例からテストを開始します。

また、辞書 m.__test__ が存在し、 None でない場合、この辞書から到達できる実行例もテストします。 m.__test__ は、(文字列の) 名前から関数、クラスおよび文字列への対応付けを行っています。関数およびクラスの場合には、その docstring 内から実行例を検索します。文字列の場合には、docstring と同じようにして実行例の検索を直接実行します。

モジュール m に属するオブジェクトにつけられた docstring のみを検索します。

(failure_count, test_count) を返します。

オプション引数 name には、モジュールの名前を指定します。デフォルトの場合や None を指定した場合には、 m.__name__ を使います。

オプション引数 exclude_empty はデフォルトでは偽になっています。この値を真にすると、doctest を持たないオブジェクトを考慮から外します。デフォルトの設定は依存のバージョンとの互換性を考えたハックであり、 doctest.master.summarize() と testmod() を合わせて利用しているようなコードでも、テスト実行例を持たないオブジェクトから出力を得るようにしています。新たに追加された DocTestFinder のコンストラクタの exclude_empty はデフォルトで真になります。

オプション引数 extraglobs, verbose, report, optionflags, raise_on_error, および globs は上で説明した testfile() の引数と同じです。ただし、 globs のデフォルト値は m.__dict__ になります。

バージョン 2.3 で変更: optionflags パラメータが追加されました。

バージョン 2.4 で変更: extraglobs, raise_on_error および exclude_empty パラメータが追加されました。

バージョン 2.5 で変更: オプション引数 isprivate は、2.4 では非推奨でしたが、廃止されました。

単一のオブジェクトに関連付けられた doctest を実行するための関数もあります。この関数は以前のバージョンとの互換性のために提供されています。この関数を廃止する予定はありませんが、役に立つことはほとんどありません。

doctest.run_docstring_examples(f, globs[, verbose][, name][, compileflags][, optionflags])

オブジェクト f に関連付けられた実行例をテストします。 f はモジュール、関数、またはクラスオブジェクトです。

引数 globs に辞書を指定すると、その浅いコピーを実行コンテキストに使います。

オプション引数 name はテスト失敗時のメッセージに使われます。デフォルトの値は NoName です。

オプション引数 verbose の値を真にすると、テストが失敗しなくても出力を生成します。デフォルトでは、実行例のテストに失敗したときのみ出力を生成します。

オプション引数 compileflags には、実行例を実行するときに Python バイトコードコンパイラが使うフラグを指定します。デフォルトの場合や None を指定した場合、フラグは globs 内にある future 機能セットに対応したものになります。

オプション引数 optionflags は、上で述べた testfile() と同様の働きをします。

25.2.5. 単体テスト API

doctest 化したモジュールのコレクションが増えるにつれ、すべての doctest をシステマティックに実行したいと思うようになるはずです。 Python 2.4 以前の doctest には Tester というほとんどドキュメント化されていないクラスがあり、複数のモジュールの doctest を統合する初歩的な手段を提供していました。 Tester は非力であり、実際のところ、もっときちんとした Python のテストフレームワークが unittest モジュールで構築されており、複数のソースコードからのテストを統合する柔軟な方法を提供しています。そこで Python 2.4 では doctest の Tester クラスを廃止し、モジュールや doctest の入ったテキストファイルから unittest テストスイートを作成できるような二つの関数を doctest 側で提供するようにしました。 unittest によるテスト発見と統合するには、テストモジュールに load_tests() 関数を含めてください。

import unittest
import doctest
import my_module_with_doctests

def load_tests(loader, tests, ignore):
    tests.addTests(doctest.DocTestSuite(my_module_with_doctests))
    return tests

doctest の入ったテキストファイルやモジュールから unittest.TestSuite インスタンスを生成するための主な関数は二つあります。

doctest.DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding])

単一または複数のテキストファイルに入っている doctest 形式のテストを、 unittest.TestSuite インスタンスに変換します。

この関数の返す unittest.TestSuite インスタンスは、 unittest フレームワークで動作させ、各ファイルの実行例を対話的に実行するためのものです。ファイル内の何らかの実行例の実行に失敗すると、この関数で生成した単体テストは失敗し、該当するテストの入っているファイルの名前と、 (場合によりだいたいの) 行番号の入った failureException 例外を送出します。

関数には、テストを行いたい一つまたは複数のファイルへのパスを (文字列で) 渡します。

DocFileSuite() には、キーワード引数でオプションを指定できます。

オプション引数 module_relative は paths に指定したファイル名をどのように解釈するかを指定します。

module_relative が True (デフォルト) の場合、 filename は OS に依存しないモジュールの相対パスになります。デフォルトでは、このパスは関数 testfile() を呼び出しているモジュールからの相対パスになります; ただし、 package 引数を指定した場合には、パッケージからの相対になります。 OS への依存性を除くため、 filename ではパスを分割する文字に / を使わなければならず、絶対パスにしてはなりません (パス文字列を / で始めてはなりません)。

module_relative が False の場合、 filename は OS 依存のパスを示します。パスは絶対パスでも相対パスでもかまいません; 相対パスにした場合、現在の作業ディレクトリを基準に解決します。

オプション引数 package には、 Python パッケージを指定するか、モジュール相対のファイル名の場合には相対の基準ディレクトリとなる Python パッケージの名前を指定します。パッケージを指定しない場合、関数を呼び出しているモジュールのディレクトリを相対の基準ディレクトリとして使います。 module_relative を False に指定している場合、 package を指定するとエラーになります。

オプション引数 setUp には、テストスイートのセットアップに使う関数を指定します。この関数は、各ファイルのテストを実行する前に呼び出されます。 setUp 関数は DocTest オブジェクトに引き渡されます。 setUp は globs 属性を介してテストのグローバル変数にアクセスできます。

オプション引数 tearDown には、テストを解体 (tear-down) するための関数を指定します。この関数は、各ファイルのテストの実行を終了するたびに呼び出されます。 tearDown 関数は DocTest オブジェクトに引き渡されます。 tearDown は globs 属性を介してテストのグローバル変数にアクセスできます。

オプション引数 globs は辞書で、テストのグローバル変数の初期値が入ります。この辞書は各テストごとに新たにコピーして使われます。デフォルトでは globs は空の新たな辞書です。

オプション引数 optionflags には、テストを実行する際にデフォルトで適用される doctest オプションを OR で結合して指定します。オプションフラグとディレクティブ 節を参照してください。結果レポートに関するオプションを指定するより適切な方法は下記の set_unittest_reportflags() の説明を参照してください。

オプション引数 parser には、ファイルからテストを抽出するために使う DocTestParser (またはサブクラス) を指定します。デフォルトは通常のパーザ (DocTestParser()) です。

オプション引数 encoding にはファイルをユニコードに変換する際に使われるエンコーディングを指定します。

バージョン 2.4 で追加.

バージョン 2.5 で変更: グローバル変数 __file__ が追加され DocFileSuite() を使ってテキストファイルから読み込まれた doctest に提供されます。

バージョン 2.5 で変更: encoding パラメータが追加されました。

doctest.DocTestSuite([module][, globs][, extraglobs][, test_finder][, setUp][, tearDown][, checker])

doctest のテストを unittest.TestSuite に変換します。

この関数の返す unittest.TestSuite インスタンスは、 unittest フレームワークで動作させ、モジュール内の各 doctest を実行するためのものです。何らかの doctest の実行に失敗すると、この関数で生成した単体テストは失敗し、該当するテストの入っているファイルの名前と、 (場合によりだいたいの) 行番号の入った failureException 例外を送出します。

オプション引数 module には、テストしたいモジュールの名前を指定します。 module にはモジュールオブジェクトまたは (ドット表記の) モジュール名を指定できます。 module を指定しない場合、この関数を呼び出しているモジュールになります。

オプション引数 globs は辞書で、テストのグローバル変数の初期値が入ります。この辞書は各テストごとに新たにコピーして使われます。デフォルトでは glob は空の新たな辞書です。

オプション引数 extraglobs には追加のグローバル変数セットを指定します。この変数セットは globs に統合されます。デフォルトでは、追加のグローバル変数はありません。

オプション引数 test_finder は、モジュールから doctest を抽出するための DocTestFinder オブジェクト (またはその代替となるオブジェクト) です。

オプション引数 setUp 、 tearDown 、および optionflags は上の DocFileSuite() と同じです。

バージョン 2.3 で追加.

バージョン 2.4 で変更: globs, extraglobs, test_finder, setUp, tearDown, および optionflags パラメータが追加されました。また、この関数は doctest の検索に testmod() と同じテクニックを使うようになりました。

裏側では DocTestSuite() は doctest.DocTestCase インスタンスから unittest.TestSuite を作成しており、 DocTestCase は unittest.TestCase のサブクラスになっています。 DocTestCase についてはここでは説明しません (これは内部実装上の詳細だからです) が、そのコードを調べてみれば、 unittest の組み込みの詳細に関する疑問を解決できるはずです。

同様に、 DocFileSuite() は doctest.DocFileCase インスタンスから unittest.TestSuite を作成し、 DocFileCase は DocTestCase のサブクラスになっています。

そのため、 unittest.TestSuite クラスを生成するどちらの方法も DocTestCase のインスタンスを実行します。これは次のような微妙な理由で重要です: doctest 関数を自分で実行する場合、オプションフラグを doctest 関数に渡すことで、 doctest のオプションを直接操作できます。しかしながら、 unittest フレームワークを書いている場合には、いつどのようにテストを動作させるかを unittest が完全に制御してしまいます。フレームワークの作者はたいてい、 doctest のレポートオプションを (コマンドラインオプションで指定するなどして) 操作したいと考えますが、 unittest を介して doctest のテストランナーにオプションを渡す方法は存在しないのです。

このため、 doctest では、以下の関数を使って、 unittest サポートに特化したレポートフラグ表記方法もサポートしています。

doctest.set_unittest_reportflags(flags)

doctest のレポートフラグをセットします。

引数 flags にはオプションフラグを OR で結合して渡します。オプションフラグとディレクティブ 節を参照してください。「レポートフラグ」しか使えません。

この関数で設定した内容はモジュール全体にわたるものであり、関数呼び出し以後に unittest モジュールから実行されるすべての doctest に影響します: DocTestCase の runTest() メソッドは、 DocTestCase インスタンスが作成された際に、現在のテストケースに指定されたオプションフラグを見に行きます。レポートフラグが指定されていない場合 (通常の場合で、望ましいケースです)、 doctest の unittest レポートフラグが OR で結合され、doctest を実行するために作成される DocTestRunner インスタンスに渡されます。 DocTestCase インスタンスを構築する際に何らかのレポートフラグが指定されていた場合、 doctest の unittest レポートフラグは無視されます。

この関数は、関数を呼び出す前に有効になっていた unittest レポートフラグの値を返します。

バージョン 2.4 で追加.

25.2.6. 拡張 API

基本 API は、 doctest を使いやすくするための簡単なラッパであり、柔軟性があってほとんどのユーザの必要を満たしています; とはいえ、もっとテストをきめ細かに制御したい場合や、 doctest の機能を拡張したい場合、拡張 API (advanced API) を使わなければなりません。

拡張 API は、doctest ケースから抽出した対話モードでの実行例を記憶するための二つのコンテナクラスを中心に構成されています。

Example: 1つの Python 文 (statement) と、その期待する出力をペアにしたもの。

DocTest: Example の集まり。通常一つの docstring やテキストファイルから抽出されます。

その他に、 doctest の実行例を検索、構文解析、実行、チェックするための処理クラスが以下のように定義されています。

DocTestFinder: 与えられたモジュールからすべての docstring を検索し、 DocTestParser を使って対話モードでの実行例が入ったすべての docstring から DocTest を生成します。

DocTestParser: (オブジェクトの docstring 等の) 文字列から DocTest オブジェクトを生成します。

DocTestRunner: DocTest 内の実行例を実行し、 OutputChecker を使って出力を検証します。

OutputChecker: doctest 実行例から実際に出力された結果を期待する出力と比較し、両者が一致するか判別します。

これらの処理クラスの関係を図にまとめると、以下のようになります。

                            list of:
+------+                   +---------+
|module| --DocTestFinder-> | DocTest | --DocTestRunner-> results
+------+    |        ^     +---------+     |       ^    (printed)
            |        |     | Example |     |       |
            v        |     |   ...   |     v       |
           DocTestParser   | Example |   OutputChecker
                           +---------+

25.2.6.1. DocTest オブジェクト

class doctest.DocTest(examples, globs, name, filename, lineno, docstring)

単一の名前空間内で実行される doctest 実行例の集まりです。コンストラクタの引数は DocTest インスタンス中の同名のメンバ変数の初期化に使われます。

バージョン 2.4 で追加.

DocTest では、以下のメンバ変数を定義しています。これらの変数はコンストラクタで初期化されます。直接変更してはなりません。

examples

対話モードにおける実行例それぞれをエンコードしていて、テストで実行される、 Example オブジェクトからなるリストです。

globs

実行例を実行する名前空間 (いわゆるグローバル変数) です。このメンバは、名前から値への対応付けを行っている辞書です。実行例が名前空間に対して (新たな変数を束縛するなど) 何らかの変更を行った場合、 globs への反映はテストの実行後に起こります。

name

DocTest を識別する名前の文字列です。通常、この値はテストを取り出したオブジェクトかファイルの名前になります。

filename

DocTest を取り出したファイルの名前です; ファイル名が未知の場合や DocTest をファイルから取り出したのでない場合には None になります。

lineno

filename 中で DocTest のテスト実行例が始まっている行の行番号です。行番号は、ファイルの先頭を 0 として数えます。

docstring

テストを取り出した docstring 自体を現す文字列です。 docstring 文字列を得られない場合や、文字列からテスト実行例を取り出したのでない場合には None になります。

25.2.6.2. Example オブジェクト

class doctest.Example(source, want[, exc_msg][, lineno][, indent][, options])

ひとつの Python 文と、それに対する期待する出力からなる、単一の対話的モードの実行例です。コンストラクタの引数は Example インスタンス中の同名のメンバ変数の初期化に使われます。

バージョン 2.4 で追加.

Example では、以下のメンバ変数を定義しています。これらの変数はコンストラクタで初期化されます。直接変更してはなりません。

source

実行例のソースコードが入った文字列です。ソースコードは単一の Python で、末尾は常に改行です。コンストラクタは必要に応じて改行を追加します。

want

実行例のソースコードを実行した際の期待する出力 (標準出力と、例外が生じた場合にはトレースバック) です。 want の末尾は、期待する出力がまったくない場合を除いて常に改行になります。期待する出力がない場合には空文字列になります。コンストラクタは必要に応じて改行を追加します。

exc_msg

実行例が例外を生成すると期待される場合の例外メッセージです。例外を送出しない場合には None です。この例外メッセージは、 traceback.format_exception_only() の戻り値と比較されます。値が None でない限り、 exc_msg は改行で終わっていなければなりません; コンストラクタは必要に応じて改行を追加します。

lineno

この実行例を含む文字列における実行例が始まる行番号です。行番号は文字列の先頭を 0 として数えます。

indent

実行例の入っている文字列のインデント、すなわち実行例の最初のプロンプトより前にある空白文字の数です。

options

オプションフラグを True または False に対応付けている辞書です。実行例に対するデフォルトオプションを上書きするために用いられます。この辞書に入っていないオプションフラグはデフォルトの状態 (DocTestrunner の optionflags の内容) のままになります。

25.2.6.3. DocTestFinder オブジェクト

class doctest.DocTestFinder([verbose][, parser][, recurse][, exclude_empty])

与えられたオブジェクトについて、そのオブジェクト自身の docstring か、そのオブジェクトに含まれるオブジェクトの docstring から DocTest を抽出する処理クラスです。現在のところ、モジュール、関数、クラス、メソッド、静的メソッド、クラスメソッド、プロパティから DocTest を抽出できます。

オプション引数 verbose を使うと、抽出処理の対象となるオブジェクトを表示できます。デフォルトは False (出力を行わない) です。

オプション引数 parser には、 docstring から DocTest を抽出するのに使う DocTestParser オブジェクト (またはその代替となるオブジェクト) を指定します。

オプション引数 recurse が偽の場合、 DocTestFinder.find() は与えられたオブジェクトだけを調べ、そのオブジェクトに含まれる他のオブジェクトを調べません。

オプション引数 exclude_empty が偽の場合、 DocTestFinder.find() は空の docstring を持つオブジェクトもテスト対象に含めます。

バージョン 2.4 で追加.

DocTestFinder では以下のメソッドを定義しています。

find(obj[, name][, module][, globs][, extraglobs])

obj または obj 内に入っているオブジェクトの docstring 中で定義されている DocTest のリストを返します。

オプション引数 name には、オブジェクトの名前を指定します。この名前は、関数が返す DocTest の名前になります。 name を指定しない場合、 obj.__name__ を使います。

オプションのパラメータ module は、指定したオブジェクトを収めているモジュールを指定します。 module を指定しないか、 None を指定した場合には、正しいモジュールを自動的に決定しようと試みます。オブジェクトのモジュールは以下のような役割を果たします。

globs を指定していない場合、オブジェクトのモジュールはデフォルトの名前空間になります。

他のモジュールから import されたオブジェクトに対して DocTestFinder が DocTest を抽出するのを避けるために使います (module 由来でないオブジェクトを無視します)。

オブジェクトの入っているファイル名を調べるために使います。

オブジェクトがファイル内の何行目にあるかを調べる手助けにします。

module が False の場合には、モジュールの検索を試みません。これは正確さを欠くような使い方で、通常 doctest 自体のテストにしか使いません。 module が False の場合、または module が None で自動的に的確なモジュールを見つけ出せない場合には、すべてのオブジェクトは (non-existent) モジュールに属するとみなされ、そのオブジェクト内のすべてのオブジェクトに対して (再帰的に) doctest の検索を行います。

各 DocTest のグローバル変数は、 globs と extraglobs を合わせたもの (extraglobs 内の束縛が globs 内の束縛を上書きする) になります。各々の DocTest に対して、グローバル変数を表す辞書の新たな浅いコピーを生成します。 globs を指定しない場合に使われるのデフォルト値は、モジュールを指定していればそのモジュールの __dict__ になり、指定していなければ {} になります。 extraglobs を指定しない場合、デフォルトの値は {} になります。

25.2.6.4. DocTestParser オブジェクト

class doctest.DocTestParser

対話モードの実行例を文字列から抽出し、それを使って DocTest オブジェクトを生成するために使われる処理クラスです。

バージョン 2.4 で追加.

DocTestParser では以下のメソッドを定義しています。

get_doctest(string, globs, name, filename, lineno)

指定した文字列からすべての doctest 実行例を抽出し、 DocTest オブジェクト内に集めます。

globs, name, filename, および lineno は新たに作成される DocTest オブジェクトの属性になります。詳しくは DocTest のドキュメントを参照してください。

get_examples(string[, name])

指定した文字列からすべての doctest 実行例を抽出し、 Example オブジェクトからなるリストにして返します。各 Example の行番号は 0 から数えます。オプション引数 name はこの文字列につける名前で、エラーメッセージにしか使われません。

parse(string[, name])

指定した文字列を、実行例とその間のテキストに分割し、実行例を Example オブジェクトに変換し、 Example と文字列からなるリストにして返します。各 Example の行番号は 0から数えます。オプション引数 name はこの文字列につける名前で、エラーメッセージにしか使われません。

25.2.6.5. DocTestRunner オブジェクト

class doctest.DocTestRunner([checker][, verbose][, optionflags])

DocTest 内の対話モード実行例を実行し、検証する際に用いられる処理クラスです。

期待する出力と実際の出力との比較は OutputChecker で行います。比較は様々なオプションフラグを使ってカスタマイズできます; 詳しくは オプションフラグとディレクティブ を参照してください。オプションフラグでは不十分な場合、コンストラクタに OutputChecker のサブクラスを渡して比較方法をカスタマイズできます。

テストランナーの表示出力の制御には二つの方法があります。一つ目は、 TestRunner.run() に出力用の関数を渡すというものです。この関数は、表示すべき文字列を引数にして呼び出されます。デフォルトは sys.stdout.write です。出力を取り込んで処理するだけでは不十分な場合、 DocTestRunner をサブクラス化し、 report_start(), report_success(), report_unexpected_exception(), および report_failure() をオーバライドすればカスタマイズできます。

オプションのキーワード引数 checker には、 OutputChecker オブジェクト (またはその代替となるオブジェクト) を指定します。このオブジェクトは doctest 実行例の期待する出力と実際の出力との比較を行う際に使われます。

オプションのキーワード引数 verbose は、 DocTestRunner の出すメッセージの冗長性を制御します。 verbose が True の場合、各実行例を実行する都度、その実行例についての情報を出力します。 verbose が False の場合、テストの失敗だけを出力します。 verbose を指定しない場合や None を指定した場合、コマンドラインスイッチ -v を使った場合にのみ verbose 出力を適用します。

オプションのキーワード引数 optionflags を使うと、テストランナーが期待される出力と実際の出力を比較する方法や、テストの失敗を表示する方法を制御できます。詳しくは オプションフラグとディレクティブ 節を参照してください。

バージョン 2.4 で追加.

DocTestRunner では、以下のメソッドを定義しています。

report_start(out, test, example)

テストランナーが実行例を処理しようとしているときにレポートを出力します。 DocTestRunner の出力をサブクラスでカスタマイズできるようにするためのメソッドです。直接呼び出してはなりません。

example は処理する実行例です。 test は example の入っているテストです。 out は出力用の関数で、 DocTestRunner.run() に渡されます。

report_success(out, test, example, got)

与えられた実行例が正しく動作したことを報告します。このメソッドは DocTestRunner のサブクラスで出力をカスタマイズできるようにするために提供されています; 直接呼び出してはなりません。

example は処理する実行例です。 got は実行例から実際に得られた出力です。 test は example の入っているテストです。 out は出力用の関数で、 DocTestRunner.run() に渡されます。

report_failure(out, test, example, got)

与えられた実行例が正しく動作しなかったことを報告します。このメソッドは DocTestRunner のサブクラスで出力をカスタマイズできるようにするために提供されています; 直接呼び出してはなりません。

example は処理する実行例です。 got は実行例から実際に得られた出力です。 test は example の入っているテストです。 out は出力用の関数で、 DocTestRunner.run() に渡されます。

report_unexpected_exception(out, test, example, exc_info)

与えられた実行例が期待とは違う例外を送出したことを報告します。このメソッドは DocTestRunner のサブクラスで出力をカスタマイズできるようにするために提供されています; 直接呼び出してはなりません。

example は処理する実行例です。 exc_info には予期せず送出された例外の情報を入れたタプル (sys.exc_info() の返す内容) になります。 test は example の入っているテストです。 out は出力用の関数で、 DocTestRunner.run() に渡されます。

run(test[, compileflags][, out][, clear_globs])

test 内の実行例 (DocTest オブジェクト) を実行し、その結果を出力用の関数 out を使って表示します。

実行例は名前空間 test.globs の下で実行されます。 clear_globs が真 (デフォルト) の場合、名前空間はテストの実行後に消去され、ガベージコレクションを促します。テストの実行完了後にその内容を調べたければ、 clear_globs を False にしてください。

compileflags には、実行例を実行する際に Python コンパイラに適用するフラグセットを指定します。 compileflags を指定しない場合、デフォルト値は globs で適用されている future-import フラグセットになります。

各実行例の出力は DocTestRunner の出力チェッカで検査され、その結果は DocTestRunner.report_*() メソッドで書式化されます。

summarize([verbose])

この DocTestRunner が実行したすべてのテストケースのサマリを出力し、名前付きタプル (named tuple) TestResults(failed, attempted) を返します。

オプションの verbose 引数を使うと、どのくらいサマリを詳しくするかを制御できます。冗長度を指定しない場合、 DocTestRunner 自体の冗長度を使います。

バージョン 2.6 で変更: 名前付きタプル (named tuple) を使うようになりました。

25.2.6.6. OutputChecker オブジェクト

class doctest.OutputChecker

doctest 実行例を実際に実行したときの出力が期待する出力と一致するかどうかをチェックするために使われるクラスです。 OutputChecker では、与えられた二つの出力を比較して、一致する場合には真を返す check_output() と、二つの出力間の違いを説明する文字列を返す output_difference() の、二つのメソッドがあります。

バージョン 2.4 で追加.

OutputChecker では以下のメソッドを定義しています。

check_output(want, got, optionflags)

実行例から実際に得られた出力 (got) と、期待する出力 (want) が一致する場合にのみ True を返します。二つの文字列がまったく同一の場合には常に一致するとみなしますが、テストランナーの使っているオプションフラグにより、厳密には同じ内容になっていなくても一致するとみなす場合もあります。オプションフラグについての詳しい情報は オプションフラグとディレクティブ 節を参照してください。

output_difference(example, got, optionflags)

与えられた実行例の期待する出力 (want)と、実際に得られた出力 (got) の間の差異を解説している文字列を返します。 optionflags は want と got を比較する際に使われるオプションフラグのセットです。

25.2.7. デバッグ

doctest では、doctest 実行例をデバッグするメカニズムをいくつか提供しています。

doctest を実行可能な Python プログラムに変換し、 Python デバッガ pdb で実行できるようにするための関数がいくつかあります。

DocTestRunner のサブクラス DebugRunner クラスがあります。このクラスは、最初に失敗した実行例に対して例外を送出します。例外には実行例に関する情報が入っています。この情報は実行例の検死デバッグに利用できます。

DocTestSuite() の生成する unittest テストケースは、 debug() メソッドをサポートしています。 debug() は unittest.TestCase で定義されています。

pdb.set_trace() を doctest 実行例の中で呼び出しておけば、その行が実行されたときに Python デバッガが組み込まれます。デバッガを組み込んだあとは、変数の現在の値などを調べられます。たとえば、以下のようなモジュールレベルの docstring の入ったファイル a.py があるとします。

"""
>>> def f(x):
...     g(x*2)
>>> def g(x):
...     print x+3
...     import pdb; pdb.set_trace()
>>> f(3)
9
"""

対話セッションは以下のようになるでしょう。

>>> import a, doctest
>>> doctest.testmod(a)
--Return--
> <doctest a[1]>(3)g()->None
-> import pdb; pdb.set_trace()
(Pdb) list
  1     def g(x):
  2         print x+3
  3  ->     import pdb; pdb.set_trace()
[EOF]
(Pdb) print x
6
(Pdb) step
--Return--
> <doctest a[0]>(2)f()->None
-> g(x*2)
(Pdb) list
  1     def f(x):
  2  ->     g(x*2)
[EOF]
(Pdb) print x
3
(Pdb) step
--Return--
> <doctest a[2]>(1)?()->None
-> f(3)
(Pdb) cont
(0, 3)
>>>

バージョン 2.4 で変更: pdb.set_trace() を doctest の中で有効に使えるようになりました。

以下は、doctest を Python コードに変換して、できたコードをデバッガ下で実行できるようにするための関数です。

doctest.script_from_examples(s)

実行例の入ったテキストをスクリプトに変換します。

引数 s は doctest 実行例の入った文字列です。この文字列は Python スクリプトに変換され、その中では s の doctest 実行例が通常のコードに、それ以外は Python のコメント文になります。生成したスクリプトを文字列で返します。例えば、

import doctest
print doctest.script_from_examples(r"""
    Set x and y to 1 and 2.
    >>> x, y = 1, 2

    Print their sum:
    >>> print x+y
    3
""")

は、

# Set x and y to 1 and 2.
x, y = 1, 2
#
# Print their sum:
print x+y
# Expected:
## 3

になります。

この関数は内部的に他の関数から使われていますが (下記参照) 、対話セッションを Python スクリプトに変換したいような場合にも便利でしょう。

バージョン 2.4 で追加.

doctest.testsource(module, name)

あるオブジェクトの doctest をスクリプトに変換します。

引数 module はモジュールオブジェクトか、対象の doctest を持つオブジェクトの入ったモジュールのドット表記名です。引数 name は対象の doctest を持つオブジェクトの (モジュール内の) 名前です。対象オブジェクトの docstring を上記の script_from_examples() で説明した方法で Python スクリプトに変換してできた文字列を返します。例えば、 a.py モジュールのトップレベルに関数 f() がある場合、以下のコード

import a, doctest
print doctest.testsource(a, "a.f")

を実行すると、 f() の docstring から doctest をコードに変換し、それ以外をコメントにしたスクリプトを出力します。

バージョン 2.3 で追加.

doctest.debug(module, name[, pm])

オブジェクトの持つ doctest をデバッグします。

module および name 引数は上の testsource() と同じです。指定したオブジェクトの docstring から合成された Python スクリプトは一時ファイルに書き出され、その後 Python デバッガ pdb の制御下で実行されます。

ローカルおよびグローバルの実行コンテキストには、 module.__dict__ の浅いコピーが使われます。

オプション引数 pm は、検死デバッグを行うかどうかを指定します。 pm が真の場合、スクリプトファイルは直接実行され、スクリプトが送出した例外が処理されないまま終了した場合にのみデバッガが立ち入ります。その場合、 pdb.post_mortem() によって検死デバッグを起動し、処理されなかった例外から得られたトレースバックオブジェクトを渡します。 pm を指定しないか値を偽にした場合、 pdb.run() に適切な execfile() 呼び出しを渡して、最初からデバッガの下でスクリプトを実行します。

バージョン 2.3 で追加.

バージョン 2.4 で変更: 引数 pm が追加されました。

doctest.debug_src(src[, pm][, globs])

文字列中の doctest をデバッグします。

上の debug() に似ていますが、doctest の入った文字列は src 引数で直接指定します。

オプション引数 pm は上の debug() と同じ意味です。

オプション引数 globs には、ローカルおよびグローバルな実行コンテキストの両方に使われる辞書を指定します。 globs を指定しない場合や None にした場合、空の辞書を使います。辞書を指定した場合、実際の実行コンテキストには浅いコピーが使われます。

バージョン 2.4 で追加.

DebugRunner クラス自体や DebugRunner クラスが送出する特殊な例外は、テストフレームワークの作者にとって非常に興味のあるところですが、ここでは概要しか述べられません。詳しくはソースコード、とりわけ DebugRunner の docstring (それ自体 doctest です!) を参照してください。

class doctest.DebugRunner([checker][, verbose][, optionflags])

テストの失敗に遭遇するとすぐに例外を送出するようになっている DocTestRunner のサブクラスです。予期しない例外が生じると、 UnexpectedException 例外を送出します。この例外には、テスト、実行例、もともと送出された例外が入っています。期待する出力と実際の出力が一致しないために失敗した場合には、 DocTestFailure 例外を送出します。この例外には、テスト、実行例、実際の出力が入っています。

コンストラクタのパラメータやメソッドについては、 拡張 API 節の DocTestRunner のドキュメントを参照してください。

DebugRunner インスタンスの送出する例外には以下の二つがあります。

exception doctest.DocTestFailure(test, example, got)

doctest 実行例の実際の出力が期待する出力と一致しなかったことを示すために DocTestRunner が送出する例外です。コンストラクタの引数は、インスタンスの同名のメンバ変数を初期化するために使われます。

DocTestFailure では以下のメンバ変数を定義しています。

DocTestFailure.test

実行例が失敗した時に実行されていた DocTest オブジェクトです。

DocTestFailure.example

失敗した Example オブジェクトです。

DocTestFailure.got

実行例の実際の出力です。

exception doctest.UnexpectedException(test, example, exc_info)

doctest 実行例が予期しない例外を送出したことを示すために DocTestRunner が送出する例外です。コンストラクタの引数は、インスタンスの同名のメンバ変数を初期化するために使われます。

UnexpectedException では以下のメンバ変数を定義しています。

UnexpectedException.test

実行例が失敗した時に実行されていた DocTest オブジェクトです。

UnexpectedException.example

失敗した Example オブジェクトです。

UnexpectedException.exc_info

予期しない例外についての情報の入ったタプルで、 sys.exc_info() が返すのと同じものです。

25.2.8. アドバイス

冒頭でも触れたように、 doctest は、

docstring 内の実行例をチェックする

回帰テストを行う

実行可能なドキュメント/読めるテストの実現

という三つの主な用途を持つようになりました。

これらの用途にはそれぞれ違った要求があるので、区別して考えるのが重要です。特に、 docstring を曖昧なテストケースに埋もれさせてしまうとドキュメントとしては最悪です。

docstring の例は注意深く作成してください。 doctest の作成にはコツがあり、きちんと学ぶ必要があります — 最初はすんなりできないでしょう。実行例はドキュメントに本物の価値を与えます。良い例は、たくさんの言葉と同じ価値を持つことがしばしばあります。注意深くやれば、例はユーザにとっては非常に有益であり、時を経るにつれて、あるいは状況が変わった際に、何度も修正するのにかかる時間を節約するという形で、きっと見返りを得るでしょう。私は今でも、自分の doctest 実行例が “無害な” 変更を行った際にうまく動作しなくなることに驚いています。

説明テキストの作成をけちらなければ、 doctest は回帰テストの優れたツールにもなり得ます。説明文と実行例を交互に記述していけば、実際に何をどうしてテストしているのかもっと簡単に把握できるようになるでしょう。もちろん、コードベースのテストに詳しくコメントを入れるのも手ですが、そんなことをするプログラマはほとんどいません。多くの人々が、 doctest のアプローチをとった方がきれいにテストを書けると気づいています。おそらく、これは単にコード中にコメントを書くのが少し面倒だからという理由でしょう。私はもう少し穿った見方もしています。 doctest ベースのテストを書くときの自然な態度は、自分のソフトウェアのよい点を説明しようとして、実行例を使って説明しようとするときの態度そのものだからだ、という理由です。それゆえに、テストファイルは自然と単純な機能の解説から始め、論理的により複雑で境界条件的なケースに進むような形になります。結果的に、一見ランダムに見えるような個別の機能をテストしている個別の関数の集まりではなく、首尾一貫した説明ができるようになるのです。 doctest によるテストの作成はまったく別の取り組み方であり、テストと説明の区別をなくして、まったく違う結果を生み出すのです。

回帰テストは特定のオブジェクトやファイルにまとめておくのがよいでしょう。回帰テストの組み方にはいくつか選択肢があります。

テストケースを対話モードの実行例にして入れたテキストファイルを書き、 testifle() や DocFileSuite() を使ってそのファイルをテストします。この方法をお勧めします。最初から doctest を使うようにしている新たなプロジェクトでは、この方法が一番簡単です。

_regrtest_topic という名前の関数を定義します。この関数には、あるトピックに対応するテストケースの入った docstring が一つだけ入っています。この関数はモジュールと同じファイルの中にも置けますし、別のテストファイルに分けてもかまいません。

回帰テストのトピックをテストケースの入った docstring に対応付けた辞書 __test__ 辞書を定義します。

注記

[1]
期待する出力結果と例外の両方を含んだ例はサポートされていません。一方の終わりと他方の始まりを見分けようとするのはエラーの元になりがちですし、解りにくいテストになってしまいます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール »

25.3. unittest — ユニットテストフレームワーク

バージョン 2.1 で追加.

(読者の方がすでにテストの基本概念についてなじみがあるようでしたら、この部分をとばして the list of assert methods に進むと良いでしょう。)

この Python ユニットテストフレームワークは時に “PyUnit” とも呼ばれ、 Kent Beck と Erich Gamma による JUnit の Python 版です。 JUnit はまた Kent の Smalltalk 用テストフレームワークの Java 版で、どちらもそれぞれの言語で業界標準のユニットテストフレームワークとなっています。

unittest では、テストの自動化・初期設定と終了処理の共有・テストの分類・テスト実行と結果レポートの分離などの機能を提供しており、 unittest のクラスを使って簡単にたくさんのテストを開発できるようになっています。

このようなことを実現するために unittest では、テストを以下のような構成で開発します。

test fixture (テストフィクスチャー)

test fixture とは、テスト実行のために必要な準備や終了処理を指します。例: テスト用データベースの作成・ディレクトリ・サーバプロセスの起動など。

test case (テストケース)

test case はテストの最小単位で、各入力に対する結果をチェックします。テストケースを作成する場合は、 unittest が提供する TestCase クラスを基底クラスとして利用することができます。

test suite (テストスイート)

test suite はテストケースとテストスイートの集まりで、同時に実行しなければならないテストをまとめる場合に使用します。

test runner (テストランナー)

test runner はテストの実行と結果表示を管理するコンポーネントです。ランナーはグラフィカルインターフェースでもテキストインターフェースでも良いですし、何も表示せずにテスト結果を示す値を返すだけの場合もあります。

unittest では、テストケースとテストフィクスチャーを、 TestCase クラスと FunctionTestCase クラスで提供しています。 TestCase クラスは新規にテストを作成する場合に使用し、 FunctionTestCase は既存のテストを unittest に組み込む場合に使用します。テストフィクスチャーの設定処理と終了処理は、 TestCase では setUp() メソッドと tearDown() をオーバーライドして記述し、 FunctionTestCase では初期設定・終了処理を行う既存の関数をコンストラクタで指定します。テスト実行時、まずテストフィクスチャーの初期設定が最初に実行されます。初期設定が正常終了した場合、テスト実行後にはテスト結果に関わらず終了処理が実行されます。 TestCase の各インスタンスが実行するテストは一つだけで、テストフィクスチャーは各テストごとに新しく作成されます。

テストスイートは TestSuite クラスで実装されており、複数のテストとテストスイートをまとめる事ができます。テストスイートを実行すると、スイートと子スイートに追加されている全てのテストが実行されます。

テストランナーは run() メソッドを持つオブジェクトです。このメソッドは引数として TestCase か TestSuite オブジェクトを受け取り、テスト結果を TestResult オブジェクトで戻します。 unittest ではデフォルトでテスト結果を標準エラーに出力する TextTestRunner をサンプルとして実装しています。これ以外のランナー (グラフィックインターフェース用など) を実装する場合でも、特別なクラスから派生させて実装する必要はありません。

参考

Module doctest

もうひとつのテストをサポートするモジュールで、本モジュールと趣きが異なっています。

unittest2: ユニットテストの新機能の Python 2.4-2.6 向けバックポート [http://pypi.python.org/pypi/unittest2]

Python 2.7 になり多くの機能が unittest に追加されました。特に、テストディスカバリが追加されました。 unittest2 を導入する事で以前のバージョンの Python でもこれらの機能を使えます。

Simple Smalltalk Testing: With Patterns [http://www.XProgramming.com/testfram.htm]

Kent Beck のテスティングフレームワークに関する原論文で、ここに記載されたパターンを unittest が使用しています。

Nose [http://code.google.com/p/python-nose/] と py.test [http://pytest.org]

サードパーティのユニットテストフレームワークで軽量な文法でテストを書くことができます。例えば、 assert func(10) == 42 のように書きます。

The Python Testing Tools Taxonomy [http://pycheesecake.org/wiki/PythonTestingToolsTaxonomy]

多くの Python のテストツールが一覧で紹介されています。ファンクショナルテストのフレームワークやモックライブラリも掲載されています。

Testing in Python Mailing List [http://lists.idyll.org/listinfo/testing-in-python]

Python でテストやテストツールについての議論に特化したグループです。

25.3.1. 基礎的な例

unittest モジュールには、テストの開発や実行の為の優れたツールが用意されており、この節では、その一部を紹介します。ほとんどのユーザとっては、ここで紹介するツールだけで十分でしょう。

以下は、 random モジュールの三つの関数をテストするスクリプトです。:

import random
import unittest

class TestSequenceFunctions(unittest.TestCase):

    def setUp(self):
        self.seq = range(10)

    def test_shuffle(self):
        # make sure the shuffled sequence does not lose any elements
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))

        # should raise an exception for an immutable sequence
        self.assertRaises(TypeError, random.shuffle, (1,2,3))

    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)

    def test_sample(self):
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

if __name__ == '__main__':
    unittest.main()

テストケースは、 unittest.TestCase のサブクラスとして作成します。メソッド名が test で始まる三つのメソッドがテストです。テストランナーはこの命名規約によってテストを行うメソッドを検索します。

これらのテスト内では、予定の結果が得られていることを確かめるために assertEqual() を、条件のチェックに assertTrue() を、例外が発生する事を確認するために assertRaises() をそれぞれ呼び出しています。 assert 文の代わりにこれらのメソッドを使用すると、テストランナーでテスト結果を集計してレポートを作成する事ができます。

setUp() メソッドが定義されている場合、テストランナーは各テストを実行する前に setUp() メソッドを呼び出します。同様に、 tearDown() メソッドが定義されている場合は各テストの実行後に呼び出します。上のサンプルでは、それぞれのテスト用に新しいシーケンスを作成するために setUp() を使用しています。

サンプルの末尾が、簡単なテストの実行方法です。 unittest.main() は、テストスクリプトのコマンドライン用インターフェースです。コマンドラインから起動された場合、上記のスクリプトから以下のような結果が出力されます:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

簡略化した結果を出力したり、コマンドライン以外からも起動する等のより細かい制御が必要であれば、 unittest.main() を使用せずに別の方法でテストを実行します。例えば、上記サンプルの最後の2行は以下のように書くことができます:

suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

変更後のスクリプトをインタープリタや別のスクリプトから実行すると、以下の出力が得られます:

test_choice (__main__.TestSequenceFunctions) ... ok
test_sample (__main__.TestSequenceFunctions) ... ok
test_shuffle (__main__.TestSequenceFunctions) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.110s

OK

以上が unittest モジュールでよく使われる機能で、ほとんどのテストではこれだけでも十分です。基礎となる概念や全ての機能については以降の章を参照してください。

25.3.2. コマンドラインインタフェース

ユニットテストモジュールはコマンドラインから使うこともできます。モジュール、クラス、もしくは、特定のテストメソッドで定義されたテストを実行します。:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

引数として渡す事ができるのは、テストが定義されたモジュール名、もしくはクラス、メソッドのフルパス名です。

テスト実行時に（冗長な）詳細を表示するには -f フラグを渡します。:

python -m unittest -v test_module

コマンドラインプションの一覧を表示するには以下のコマンドを実行します。:

python -m unittest -h

バージョン 2.7 で変更: 以前のバージョンでは、特定のメソッドでしか実行できず、モジュールやクラスは指定できませんでした。

25.3.2.1. コマンドラインオプション

unittest には以下のコマンドラインオプションがあります:

-b, --buffer

標準出力と標準エラーのストリームをテスト実行の間バッファリングします。テストが成功している間は結果の出力は破棄されます。テストが失敗、もしくはエラーが発生した場合には、結果にエラーメッセージが追加されたうえで通常通り出力されます。

-c, --catch

control-C を実行中のテストが終了するまで遅延させ、そこまでの結果を出力します。二回目の control-C は、通常通り KeyboardInterrupt の例外を発生させます。

この機能の仕組みについては、 `Signal Handling`_ を参照してください。

-f, --failfast

初回のエラーもしくは失敗の時にテストを停止します。

バージョン 2.7 で追加: コマンドラインオプションの -b, -c および -f が追加されました。

このコマンドラインは、プロジェクト内の全テストを実行したり、サブセットのみを実行したりといった、テストディスカバリを使用することもできます。

25.3.3. テストディスカバリ

バージョン 2.7 で追加.

unittest はシンプルなテストディスカバリをサポートします。このテストディスカバリに対応するために、テストが定義された全ファイルは modules もしくは packages としてプロジェクトの最上位のディスカバリでインポート可能である必要があります。（つまり、これらのファイルは identifiers として有効である必要があるということです。）

テストディスカバリは TestLoader.discover() で実装されています。しかし、コマンドラインからも使う事ができます。コマンドラインからは以下のように使用します。:

cd project_directory
python -m unittest discover

discover サブコマンドには以下のオプションがあります。

-v, --verbose

詳細な出よr区

-s directory

ディスカバリを開始するディレクトリ （デフォルトは ‘.’）

-p pattern

テストファイル名を識別するパターン （デフォルトは ‘test*.py’）

-t directory

プロジェクトの最上位のディスカバリのディレクトリ （デフォルトは開始のディレクトリ）

The -s, -p, and -t options can be passed in as positional arguments in that order. The following two command lines are equivalent:

:option:`-s` 、 :option:`-p` 、および :option:`-t` の各オプションは、

この順番で指定すれば位置固定の引数として指定する事ができます。以下の二つのコマンドは同じ結果になります。:

python -m unittest discover -s project_directory -p '*_test.py'
python -m unittest discover project_directory '*_test.py'

パスを渡すのはもちろんのこと、例えば myproject.subpackage.test のように、パッケージ名をスタートディレクトリとして渡すことができます。指定したパッケージがインポートされ、そのパッケージのファイルシステム上のパスがスタートディレクトリになります。

ご用心

テストディスカバリはテストをインポートすることで読み込みます。テストディスカバリは一度、指定した開始ディレクトリから全テストファイルを探索し、そのファイルのパスをパッケージ名に変換してインポートします。例えば、 foo/bar/baz.py は foo.bar.baz としてインポートされます。

もしパッケージをグローバルにインストールしていて、インストールしたのとは異なるパッケージのコピーをディスカバリしようとすると、間違った場所からインポートして しまうかもしれません 。このような状態になるとテストディスカバリは警告を出し、停止します。

スタートディレクトリとしてディレクトリのパスではなくパッケージ名を指定した場合は、いずれかの場所からインポートされます。この場合は警告が表示されません。

テストモジュールとテストパッケージは、テストのロードとディスカバリをカスタマイズすることができます。そのために `load_tests protocol`_ を使用します。

25.3.4. テストの構成

ユニットテストの基礎となる構築要素は、 test case — セットアップと正しさのチェックを行う、独立したシナリオ — です。 unittest では、テストケースは unittest モジュールの TestCase クラスのインスタンスで示します。テストケースを作成するには TestCase のサブクラスを記述するか、または FunctionTestCase を使用します。

TestCase から派生したクラスのインスタンスは、このオブジェクトだけで一件のテストと初期設定・終了処理を行います。

TestCase インスタンスは外部から完全に独立し、単独で実行する事も、他の任意のテストと一緒に実行する事もできなければなりません。

以下のように、 TestCase のサブクラスは runTest() をオーバライドし、必要なテスト処理を記述するだけで簡単に書くことができます:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def runTest(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50,50), 'incorrect default size')

何らかのテストを行う場合、ベースクラス TestCase の assert*() メソッドを使用してください。テストが失敗すると例外が送出され、 unittest はテスト結果を failure とします。その他の例外は error となります。これによりどこに問題があるかが判ります。 failure は間違った結果 (6 になるはずが 5 だった) で発生します。 error は間違ったコード (たとえば間違った関数呼び出しによる TypeError) で発生します。

テストの実行方法については後述とし、まずはテストケースインスタンスの作成方法を示します。テストケースインスタンスは、以下のように引数なしでコンストラクタを呼び出して作成します。:

testCase = DefaultWidgetSizeTestCase()

似たようなテストを数多く行う場合、同じ環境設定処理を何度も必要となります。例えば上記のような Widget のテストが 100 種類も必要な場合、それぞれのサブクラスで Widget オブジェクトを生成する処理を記述するのは好ましくありません。

このような場合、初期化処理は setUp() メソッドに切り出し、テスト実行時にテストフレームワークが自動的に実行するようにすることができます:

import unittest

class SimpleWidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):
    def runTest(self):
        self.assertEqual(self.widget.size(), (50,50),
                        'incorrect default size')

class WidgetResizeTestCase(SimpleWidgetTestCase):
    def runTest(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                        'wrong size after resize')

テスト中に setUp() メソッドで例外が発生した場合、テストフレームワークはテストを実行することができないとみなし、 runTest() を実行しません。

同様に、終了処理を tearDown() メソッドに記述すると、 runTest() メソッド終了後に実行されます:

import unittest

class SimpleWidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()
        self.widget = None

setUp() が正常終了した場合、 runTest() が成功したかどうかに従って tearDown() が実行されます。

このような、テストを実行する環境を fixture と呼びます。

JUnit では、多数の小さなテストケースを同じテスト環境で実行する場合、全てのテストについて DefaultWidgetSizeTestCase のような SimpleWidgetTestCase のサブクラスを作成する必要があります。これは時間のかかる、うんざりする作業ですので、 unittest ではより簡単なメカニズムを用意しています:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()
        self.widget = None

    def test_default_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

この例では runTest() がありませんが、二つのテストメソッドを定義しています。このクラスのインスタンスは test_*() メソッドのどちらか一方の実行と、 self.widget の生成・解放を行います。この場合、テストケースインスタンス生成時に、コンストラクタの引数として実行するメソッド名を指定します:

defaultSizeTestCase = WidgetTestCase('test_default_size')
resizeTestCase = WidgetTestCase('test_resize')

unittest では test suite によってテストケースインスタンスをテスト対象の機能によってグループ化することができます。 test suite は、 unittest の TestSuite クラスで作成します。:

widgetTestSuite = unittest.TestSuite()
widgetTestSuite.addTest(WidgetTestCase('test_default_size'))
widgetTestSuite.addTest(WidgetTestCase('test_resize'))

各テストモジュールで、テストケースを組み込んだテストスイートオブジェクトを作成する呼び出し可能オブジェクトを用意しておくと、テストの実行や参照が容易になります:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_size'))
    suite.addTest(WidgetTestCase('test_resize'))
    return suite

または:

def suite():
    tests = ['test_default_size', 'test_resize']

    return unittest.TestSuite(map(WidgetTestCase, tests))

一般的には、 TestCase のサブクラスには良く似た名前のテスト関数が複数定義されますので、 unittest ではテストスイートを作成して個々のテストで満たすプロセスを自動化するのに使う TestLoader を用意しています。たとえば、:

suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)

は WidgetTestCase.test_default_size() と WidgetTestCase.test_resize を走らせるテストスイートを作成します。 TestLoader は自動的にテストメソッドを識別するのに 'test' というメソッド名の接頭辞を使います。

いろいろなテストケースが実行される順序は、テスト関数名を組み込みの文字列の順番に従って決まります。

システム全体のテストを行う場合など、テストスイートをさらにグループ化したい場合がありますが、このような場合、 TestSuite インスタンスには TestSuite と同じように TestSuite を追加する事ができます。:

suite1 = module1.TheTestSuite()
suite2 = module2.TheTestSuite()
alltests = unittest.TestSuite([suite1, suite2])

テストケースやテストスイートは (widget.py のような) テスト対象のモジュール内にも記述できますが、テストは (test_widget.py のような) 独立したモジュールに置いた方が以下のような点で有利です:

テストモジュールだけをコマンドラインから実行することができる。

テストコードと出荷するコードを分離する事ができる。

テストコードを、テスト対象のコードに合わせて修正する誘惑に駆られにくい。

テストコードは、テスト対象コードほど頻繁に更新されない。

テストコードをより簡単にリファクタリングすることができる。

Cで書いたモジュールのテストは、どっちにしろ独立したモジュールとなる。

テスト戦略を変更した場合でも、ソースコードを変更する必要がない。

25.3.5. 既存テストコードの再利用

既存のテストコードが有るとき、このテストを unittest で実行しようとするために古いテスト関数をいちいち TestCase クラスのサブクラスに変換するのは大変です。

このような場合は、 unittest では TestCase のサブクラスである FunctionTestCase クラスを使い、既存のテスト関数をラップします。初期設定と終了処理も行なえます。

以下のテストコードがあった場合:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

テストケースインスタンスは次のように作成します:

testcase = unittest.FunctionTestCase(testSomething)

初期設定、終了処理が必要な場合は、次のように指定します:

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

既存のテストスイートからの移行を容易にするため、 unittest は AssertionError の送出でテストの失敗を示すような書き方もサポートしています。しかしながら、 TestCase.fail*() および TestCase.assert*() メソッドを使って明確に書くことが推奨されています。 unittest の将来のバージョンでは、 AssertionError は別の目的に使用される可能性が有ります。

ノート

FunctionTestCase を使って既存のテストを unittest ベースのテスト体系に変換することができますが、この方法は推奨されません。時間を掛けて TestCase のサブクラスに書き直した方が将来的なテストのリファクタリングが限りなく易しくなります。

既存のテストが doctest を使って書かれている場合もあるでしょう。その場合、 doctest は DocTestSuite クラスを提供します。このクラスは、既存の doctestベースのテストから、自動的に unittest.TestSuite のインスタンスを作成します。

25.3.6. テストのスキップと意図的な失敗

バージョン 2.7 で追加.

unittest は特定のテストメソッドやテストクラス全体をスキップする仕組みを備えています。さらに、この機能はテスト結果を「意図的な失敗」とすることができ、テストが失敗しても TestResult の失敗数にはカウントされなくなります。

テストをスキップするには、 単に skip() デコレータ(decorator) を使用するか、条件を表現するための skip() に類するデコレータを使用します。

スキップは以下のようになります。

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

このサンプルを詳細モードで実行すると以下のように出力されます。

test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 3 tests in 0.005s

OK (skipped=3)

テストクラスは以下のようにメソッドをスキップすることができます。

@skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

TestCase.setUp() もスキップすることができます。この機能はセットアップの対象のリソースが使用不可能な状態の時に便利です。

意図的な失敗の機能を使用するには、 expectedFailure() デコレータを使います。

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

独自のスキップ用のデコレータも簡単に作成することができます。そのためには、独自のデコレータのスキップしたい時点で skip() を呼び出します。以下のデコレータはオブジェクトに指定した属性が無い場合にテストをスキップします。

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{0!r} doesn't have {1!r}".format(obj, attr))

以下のデコレータはテストのスキップと意図的な失敗を実装しています。

unittest.skip(reason)

デコレートしたテストを無条件でスキップします。 reason にはテストをスキップした理由を記載します。

unittest.skipIf(condition, reason)

condition が真の場合に、デコレートしたテストをスキップします。

unittest.skipUnless(condition, reason)

condition が偽の場合に、デコレートしたテストをスキップします。

unittest.expectedFailure()

テストの失敗が意図的であることを表します。該当のテストが失敗しても、そのテストは失敗にカウントされません。

スキップしたテストの前後では、 setUp() および tearDown() は実行されません。同様に、スキップしたテストクラスの前後では、 setUpClass() および

tearDownClass() は実行されません。

25.3.7. クラスと関数

この節では、 unittest モジュールのAPIの詳細について説明します。

25.3.7.1. テストクラス

class unittest.TestCase([methodName])

TestCase クラスのインスタンスは、 unittest の世界におけるテストの最小実行単位を示します。このクラスをベースクラスとして使用し、必要なテストを具象サブクラスに実装します。 TestCase クラスでは、テストランナーがテストを実行するためのインターフェースと、各種のチェックやテスト失敗をレポートするためのメソッドを実装しています。

それぞれの TestCase クラスのインスタンスはただ一つのテストメソッド、 methodName という名のメソッドを実行します。既に次のような例を扱ったことを憶えているでしょうか。:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_size'))
    suite.addTest(WidgetTestCase('test_resize'))
    return suite

ここでは、それぞれが一つずつのテストを実行するような WidgetTestCase の二つのインスタンスを作成しています。

methodName のデフォルトは runTest() です。

TestCase のインスタンスのメソッドは3種類のグループに分けられます。 1つ目のグループのメソッドはテストの実行で使用します。2つ目のグループのメソッドは条件の確認および失敗のレポートといったテストの実装で使用されます。3つ目のグループである問い合わせ用のメソッドはテスト自身の情報を収集するために使用します。

はじめのグループ（テスト実行）に含まれるメソッドは以下の通りです。

setUp()

テストフィクスチャの準備のために呼び出されるメソッドです。テストメソッドの直前に呼び出されます。このメソッドを実行中に例外が発生した場合、テストの失敗ではなくエラーとされます。デフォルトの実装では何も行いません。

tearDown()

テストメソッドが実行され、結果が記録された直後に呼び出されるメソッドです。このメソッドはテストメソッドで例外が投げられても呼び出されます。そのため、サブクラスでこのメソッドを実装する場合は、内部状態を確認することが必要になるでしょう。メソッドを実行中に例外が発生した場合、テストの失敗ではなくエラーとみなされます。このメソッドは、テストの結果に関わらず setUp() が成功した場合にのみ呼ばれます。デフォルトの実装では何も行いません。

setUpClass()

クラス内に定義されたテストが実行される前に呼び出されるクラスメソッドです。 setUpClass はクラスを唯一の引数として取り、 classmethod() でデコレートされている必要があります。

@classmethod
def setUpClass(cls):
    ...

詳しくは `Class and Module Fixtures`_ を参照してください。

バージョン 2.7 で追加.

tearDownClass()

クラス内に定義されたテストが実行された後に呼び出されるクラスメソッドです。 tearDownClass はクラスを唯一の引数として取り、 classmethod() でデコレートされている必要があります。

@classmethod
def tearDownClass(cls):
    ...

詳しくは `Class and Module Fixtures`_ を参照してください。

バージョン 2.7 で追加.

run(result=None)

テストを実行し、テスト結果を result に指定されたテスト結果オブジェクトに渡します。 result 省略されるか None か渡された場合、一時的な結果オブジェクトを（ defaultTestCase() メソッドを呼んで）生成して使用しますが run() の呼び出し元には渡されません。

このメソッドは、単に TestCase インスタンスの呼び出した場合と同様に振る舞います。

skipTest(reason)

現在のテストでテストクラスもしくは setUp() をスキップする場合に呼ばれます。詳細については、 テストのスキップと意図的な失敗 を参照してください。

バージョン 2.7 で追加.

debug()

テスト結果を収集せずにテストを実行します。例外が呼び出し元に通知されます。また、テストをデバッガで実行することができます。

TestCase クラスには、条件の確認と失敗のレポートのために以下のメソッドが定義されています。

メソッド | 確認事項 | 初出
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a, b) | a is b | 2.7
assertIsNot(a, b) | a is not b | 2.7
assertIsNone(x) | x is None | 2.7
assertIsNotNone(x) | x is not None | 2.7
assertIn(a, b) | a in b | 2.7
assertNotIn(a, b) | a not in b | 2.7
assertIsInstance(a, b) | isinstance(a, b) | 2.7
assertNotIsInstance(a, b) | not isinstance(a, b) | 2.7

（ assertRaises() と assertRaisesRegexp() を除く）すべてのアサートメソッドには msg 引数を指定することができ、テストの失敗時のエラーメッセージで使用されます。（ longMessage も参照してください。）

assertEqual(first, second, msg=None)

first と second が等しいことをテストします。両者が比較出来ない場合は、テストが失敗します。

さらに、 first と second が厳密に同じ型であり、その型が、list, tuple, dict, set, frozenset もしくは unicode のいずれか、または addTypeEqualityFunc() で比較関数が登録されている型の場合には、デフォルトのエラーメッセージを生成するために、その型特有の比較関数が呼ばれます。（ list of type-specific methods も参照してください。）

バージョン 2.7 で変更: 型特有の比較関数の自動呼び出しを追加。

assertNotEqual(first, second, msg=None)

first と second が等しくないことをテストします。両者が比較出来ない場合は、テストが失敗します。

assertTrue(expr, msg=None)

assertFalse(expr, msg=None)

expr が真（偽）であることをテストします。

このメソッドは、 bool(expr) is True と等価であり、 expr is True と等価ではないことに注意が必要です（後者のためには、 assertIs(expr, True) が用意されています）。また、専用のメソッドが使用できる場合には、そちらを使用してください（例えば assertTrue(a == b) の代わりに assertEqual(a, b) を使用してください）。そうすることにより、テスト失敗時のエラーメッセージを詳細に表示することができます。

assertIs(first, second, msg=None)

assertIsNot(first, second, msg=None)

first と second が同じオブジェクトであること（そうでないこと）をテストします。

バージョン 2.7 で追加.

assertIsNone(expr, msg=None)

assertIsNotNone(expr, msg=None)

expr が None であること（そうでないこと）をテストします。

バージョン 2.7 で追加.

assertIn(first, second, msg=None)

assertNotIn(first, second, msg=None)

first が second に含まれること（そうでないこと）をテストします。

バージョン 2.7 で追加.

assertIsInstance(obj, cls, msg=None)

assertNotIsInstance(obj, cls, msg=None)

obj が cls のインスタンスであること（そうでないこと）をテストします。（この cls は、 isinstance() が扱うことのできる、クラスもしくはクラスのタプルである必要があります。）

バージョン 2.7 で追加.

例外と例外発生時の警告を確認するために以下のメソッドを使用することができます。

メソッド | 確認事項 | 初出
assertRaises(exc, fun, *args, **kwds) | fun(*args, **kwds) raises exc |
assertRaisesRegexp(exc, re, fun, *args, **kwds) | fun(*args, **kwds) raises exc and the message matches re | 2.7

assertRaises(exception, callable, *args, **kwds)

assertRaises(exception)

callable を呼び出した時に例外が発生することをテストします。 assertRaises() で指定した位置パラメータとキーワードパラメータを該当メソッドに渡します。 exception が投げられた場合にテストが成功します。また、他の例外が投げられた場合はエラー、例外が投げられなかった場合は失敗になります。複数の例外をキャッチする場合には、例外クラスのタプルを exception に指定してください。

exception 引数のみが渡された場合には、コンテキストマネージャが返されます。これにより関数名を渡す形式ではなく、インラインでテスト対象のコードを書くことができます。

with self.assertRaises(SomeException):
    do_something()

このコンテキストマネージャは exception で指定されたオブジェクトを格納します。これにより、例外発生時の詳細な確認をおこなうことができます。:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

バージョン 2.7 で変更: コンテキストマネージャとして assertRaises() を使用する機能を追加。

assertRaisesRegexp(exception, regexp, callable, *args, **kwds)

assertRaisesRegexp(exception, regexp)

assertRaises() と同等ですが、例外の文字列表現が正規表現オブジェクトにマッチすることもテストします。 regexp は正規表現オブジェクトか、 re.search() が扱える正規表現が書かれた文字列である必要があります。例えば以下のようになります。

self.assertRaisesRegexp(ValueError, 'invalid literal for.*XYZ$',
                        int, 'XYZ')

もしくは

with self.assertRaisesRegexp(ValueError, 'literal'):
   int('XYZ')

バージョン 2.7 で追加.

さらに特有の確認を行うために以下のメソッドが用意されています。

メソッド | 確認項目 | 初出
assertAlmostEqual(a, b) | round(a-b, 7) == 0 |
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 |
assertGreater(a, b) | a > b | 2.7
assertGreaterEqual(a, b) | a >= b | 2.7
assertLess(a, b) | a < b | 2.7
assertLessEqual(a, b) | a <= b | 2.7
assertRegexpMatches(s, re) | regex.search(s) | 2.7
assertNotRegexpMatches(s, re) | not regex.search(s) | 2.7
assertItemsEqual(a, b) | sorted(a) == sorted(b) and works with unhashable objs | 2.7
assertDictContainsSubset(a, b) | all the key/value pairs in a exist in b | 2.7

assertAlmostEqual(first, second, places=7, msg=None, delta=None)

assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

first と second が近似的に等しい（等しくない）ことをテストします。この比較は、*places* （デフォルト7）で指定した小数位で丸めた差分をゼロと比べることでおこないます。これらのメソッドは、（ round() と同様に）

小数位 を指定するのであって、*有効桁数* を指定するのではないことに注意してください。

places の代わりに delta が渡された場合には、 first と second の差分が delta より大きい（小さい）ことをテストします。

delta と places の両方が指定された場合は TypeError が投げられます。

バージョン 2.7 で変更: assertAlmostEqual() は、オブジェクトが等しい場合には自動で近似的に等しいとみなすようになりました。 assertNotAlmostEqual() は、オブジェクトが等しい場合には自動的に失敗するようになりました。 delta 引数が追加されました。

assertGreater(first, second, msg=None)

assertGreaterEqual(first, second, msg=None)

assertLess(first, second, msg=None)

assertLessEqual(first, second, msg=None)

first が second と比べて、メソッド名に対応して >, >=, < もしくは <= であることをテストします。そうでない場合はテストが失敗します。

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

バージョン 2.7 で追加.

assertRegexpMatches(text, regexp, msg=None)

regexp の検索が text とマッチすることをテストします。テスト失敗時には、エラーメッセージにパターンと text が表示されます（もしくは、パターンと意図しないかたちでマッチした text の一部が表示されます）。 regexp は正規表現オブジェクトか、 re.search() が扱える正規表現が書かれた文字列である必要があります。

バージョン 2.7 で追加.

assertNotRegexpMatches(text, regexp, msg=None)

regexp の検索が text とマッチしないことをテストします。テスト失敗時には、エラーメッセージにマッチしたパターンと text が表示されます。 regexp は正規表現オブジェクトか、 re.search() が扱える正規表現が書かれた文字列である必要があります。

バージョン 2.7 で追加.

assertItemsEqual(actual, expected, msg=None)

シーケンス expected が actual と同じ要素を含んでいることをテストします。要素の順序はテスト結果に影響しません。要素が含まれていない場合には、シーケンスの差分がエラーメッセージとして表示されます。

actual と expected の比較では、重複した要素は無視 されません 。両者に同じ数の要素が含まれていることを検証します。このメソッドは assertEqual(sorted(expected), sorted(actual)) と同等に振る舞うことに加えて、ハッシュ化できないオブジェクトのシーケンスでも動作します。

バージョン 2.7 で追加.

assertDictContainsSubset(expected, actual, msg=None)

辞書 actual のキー/バリューペアが expected のスーパーセットになっているかどうかをテストします。そうなっていない場合には、足りないキーとバリューの一覧がエラーメッセージに表示されます。

バージョン 2.7 で追加.

バージョン 3.2 で撤廃.

assertEqual() メソッドは、同じ型のオブジェクトの等価性確認のために、型ごとに特有のメソッドにディスパッチします。これらのメソッドは、ほとんどの組み込み型用のメソッドは既に実装されています。さらに、 addTypeEqualityFunc() を使う事で新たなメソッドを登録することができます。

addTypeEqualityFunc(typeobj, function)

assertEqual() で呼び出される型特有のメソッドを登録します。登録するメソッドは、 比較する2つのオブジェクトの型がが厳密に typeobj と同じ（サブクラスでもいけません）の場合に等価性を確認します。 function は assertEqual() と同様に、2つの位置固定引数と、3番目に msg=None のキーワード引数を取れる必要があります。このメソッドは、始めの2つに指定したパラメータ間の差分を検出した時に self.failureException(msg) の例外を投げる必要があります。この例外を投げる際は、出来る限り、エラーの内容が分かる有用な情報と差分の詳細をエラーメッセージに含めてください。

バージョン 2.7 で追加.

assertEqual() が自動的に呼び出す型特有のメソッドの概要を以下の表示に記載しています。これらのメソッドは通常は直接呼び出す必要がないことに注意が必要です。

メソッド | 比較の対象 | 初出
assertMultiLineEqual(a, b) | strings | 2.7
assertSequenceEqual(a, b) | sequences | 2.7
assertListEqual(a, b) | lists | 2.7
assertTupleEqual(a, b) | tuples | 2.7
assertSetEqual(a, b) | sets or frozensets | 2.7
assertDictEqual(a, b) | dicts | 2.7

assertMultiLineEqual(first, second, msg=None)

複数行の文字列 first が文字列 second と等しいことをテストします。等しくない場合には、両者の差分がハイライトされてエラーメッセージに表示されます。このメソッドは、デフォルトで、 assertEqual() が string を比較するときに自動的に使用します。

バージョン 2.7 で追加.

assertSequenceEqual(seq1, seq2, msg=None, seq_type=None)

2つのシーケンスが等しいことをテストします。 seq_type が指定された場合、 seq1 と seq2 が seq_type のインスタンスで無い場合にはテストが失敗します。シーケンスどうしが異なる場合には、両者の差分がエラーメッセージに表示されます。

このメソッドは直接 assertEqual() からは呼ばれませんが、 assertListEqual() と assertTupleEqual() の実装で使われています。

バージョン 2.7 で追加.

assertListEqual(list1, list2, msg=None)

assertTupleEqual(tuple1, tuple2, msg=None)

2つのリストまたはタプルが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。2つのパラメータの型が異なる場合にはテストがエラーになります。このメソッドは、デフォルトで、 assertEqual() が list または tuple を比較するときに自動的に使用します。

バージョン 2.7 で追加.

assertSetEqual(set1, set2, msg=None)

2つのセットが等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、 assertEqual() が set もしくは frozenset を比較するときに自動的に使用します。

set1 or set2 のいずれかに set.difference() が無い場合にはテストは失敗します。

バージョン 2.7 で追加.

assertDictEqual(expected, actual, msg=None)

2つの辞書が等しいかどうかをテストします。等しくない場合には、両者の差分を表示します。このメソッドは、デフォルトで、 assertEqual() が dict を比較するときに自動的に使用します。

バージョン 2.7 で追加.

最後に、 TestCase の残りのメソッドと属性を紹介します。

fail(msg=None)

無条件にテストを失敗させます。エラーメッセージの表示に、 msg または None が使われます。

failureException

test() メソッドが送出する例外を指定するクラス属性です。例えばテストフレームワークで追加情報を付した特殊な例外が必要になる場合、この例外のサブクラスとして作成します。この属性の初期値は AssertionError です。

longMessage

この属性に True が設定された場合、 assert methods で指定したすべての明示的な失敗メッセージが、通常の失敗メッセージに追加されます。通常の失敗メッセージには、オブジェクトに関する有用な情報が含まれています。例えば、 assertEqual は異なるオブジェクトの repr を表示します。この属性を True にすることで、カスタマイズしたエラーメッセージを通常のメッセージに追加することができます。

この属性はデフォルトで False になっていて、カスタムメッセージが渡されても表示しないようになっています。

アサートメソッドを呼び出す前に、インスタンス属性として True または False を指定することで、この設定をオーバーライドすることができます。

バージョン 2.7 で追加.

maxDiff

この属性は、アサーションメソッドが失敗をレポートする時に表示する差分の長さをコントロールします。デフォルトは 80*8 文字です。この属性が影響するメソッドは、 assertSequenceEqual() （およびこのメソッドに委譲するシーケンス比較メソッド）、 assertDictEqual() と assertMultiLineEqual() です。

maxDiff に None を指定すると差分表示の上限がなくなります。

バージョン 2.7 で追加.

テストフレームワークは、テスト情報を収集するために以下のメソッドを使用します。

countTestCases()

テストオブジェクトに含まれるテストの数を返します。 TestCase インスタンスは常に 1 を返します。

defaultTestResult()

このテストケースクラスで使われるテスト結果クラスのインスタンスを ( もし run() メソッドに他の結果インスタンスが提供されないならば ) 返します。

TestCase インスタンスに対しては、いつも TestResult のインスタンスですので、 TestCase のサブクラスでは必要に応じてこのメソッドをオーバライドしてください。

id()

テストケースを特定する文字列を返します。通常、 id はモジュール名・クラス名を含む、テストメソッドのフルネームを指定します。

shortDescription()

テストの説明を一行分、または説明がない場合には None を返します。デフォルトでは、テストメソッドの docstring の先頭の一行、または None を返します。

addCleanup(function, *args, **kwargs)

tearDown() の後に呼び出される関数を追加します。この関数はリソースのクリーンアップのために使用します。追加された関数は、追加された順と逆の順番で呼び出されます（LIFO）。 addCleanup() に渡された引数とキーワード引数が追加された関数にも渡されます。

setUp() が失敗した場合、つまり tearDown() が呼ばれなかった場合でも、追加されたクリーンアップ関数は呼び出されます。

バージョン 2.7 で追加.

doCleanups()

このメソッドは、 tearDown() の後、もしくは、 setUp() が例外を投げた場合は setUp() の後に、無条件で呼ばれます。

このメソッドは、 addCleanup() で追加された関数を呼び出す責務を担います。もし、クリーンアップ関数を tearDown() より前に呼び出す必要がある場合には、 doCleanups() を明示的に呼び出してください。

doCleanups() は、どこで呼び出されても、クリーンアップ関数をスタックから削除して実行します。

バージョン 2.7 で追加.

class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)

このクラスでは TestCase インターフェースの内、テストランナーがテストを実行するためのインターフェースだけを実装しており、テスト結果のチェックやレポートに関するメソッドは実装していません。既存のテストコードを unittest によるテストフレームワークに組み込むために使用します。

25.3.7.1.1. 廃止予定のエイリアス

歴史的な経緯で、 TestCase のいくつかのエイリアスは廃止予定となりました。以下の表に、廃止予定のエイリアスをまとめます。

メソッド名 | 廃止予定のエリアス
assertEqual() | failUnlessEqual, assertEquals
assertNotEqual() | failIfEqual
assertTrue() | failUnless, assert_
assertFalse() | failIf
assertRaises() | failUnlessRaises
assertAlmostEqual() | failUnlessAlmostEqual
assertNotAlmostEqual() | failIfAlmostEqual

バージョン 2.7 で撤廃: 表の第2列のエイリアスを廃止予定

25.3.7.2. テストのグルーピング

class unittest.TestSuite(tests=())

このクラスは、個々のテストケースやテストスイートの集約を示します。通常のテストケースと同じようにテストランナーで実行するためのインタフェースを備えています。 TestSuite インスタンスを実行することはスイートの繰り返しを使って個々のテストを実行することと同じです。

引数 tests が指定された場合、それはテストケースに亘る繰り返し可能オブジェクトまたは内部でスイートを組み立てるための他のテストスイートでなければなりません。後からテストケースやスイートをコレクションに付け加えるためのメソッドも提供されています。

TestSuite は TestCase オブジェクトのように振る舞います。違いは、スイートにはテストを実装しない点にあります。代わりに、テストをまとめてグループ化して、同時に実行します。 TestSuite のインスタンスにテスト追加するためのメソッドが用意されています。

addTest(test)

TestCase 又は TestSuite のインスタンスをスイートに追加します。

addTests(tests)

イテラブル tests に含まれる全ての TestCase 又は TestSuite のインスタンスをスイートに追加します。

このメソッドは test 上のイテレーションをしながらそれぞれの要素に addTest() を呼び出すのと等価です。

TestSuite クラスは TestCase と以下のメソッドを共有します。

run(result)

スイート内のテストを実行し、結果を result で指定した結果オブジェクトに収集します。 TestCase.run() と異なり、 TestSuite.run() では必ず結果オブジェクトを指定する必要があります。

debug()

このスイートに関連づけられたテストを結果を収集せずに実行します。これによりテストで送出された例外は呼び出し元に伝わるようになり、デバッガの下でのテスト実行をサポートできるようになります。

countTestCases()

このテストオブジェクトによって表現されるテストの数を返します。これには個別のテストと下位のスイートも含まれます。

__iter__()

TestSuite でグループ化されたテストはイテレータでアクセスできます。サブクラスは __iter__() をオーバーライドすることで、テストへのアクセスを定義します。1つのメソッド内でこのメソッドは何度も呼ばれる可能性があることに注意してください（例えば、テスト数のカウントと等価性の比較）。そのため、イテレーションを繰り返しても同じテストを返すように実装してください。

バージョン 2.7 で変更: 以前のバージョンでは TestSuite はイテレータではなく、直接テストにアクセスしていました。そのため、 __iter__() をオーバーラードしてもテストにアクセスできませんでした。

通常、 TestSuite の run() メソッドは TestRunner が起動するため、ユーザが直接実行する必要はありません。

25.3.7.3. テストのロードと起動

class unittest.TestLoader

TestLoader クラスはクラスとモジュールからテストスイートを生成します。通常、このクラスのインスタンスを明示的に生成する必要はありません。 unittest モジュールの unittest.defaultTestLoader を共用インスタンスとして使用することができます。しかし、このクラスのサブクラスやインスタンスで、属性をカスタマイズすることができます。

TestLoader のオブジェクトには以下のメソッドがあります。

loadTestsFromTestCase(testCaseClass)

TestCase の派生クラス testCaseClass に含まれる全テストケースのスイートを返します。

loadTestsFromModule(module)

指定したモジュールに含まれる全テストケースのスイートを返します。このメソッドは module 内の TestCase 派生クラスを検索し、見つかったクラスのテストメソッドごとにクラスのインスタンスを作成します。

ノート

TestCase クラスを基底クラスとしてクラス階層を構築すると fixture や補助的な関数をうまく共用することができますが、基底クラスに直接インスタンス化できないテストメソッドがあると、この loadTestsFromModule() を使うことができません。この場合でも、 fixture が全て別々で定義がサブクラスにある場合は使用することができます。

モジュールが load_tests 関数を用意している場合、この関数がテストのロードに使われます。これによりテストのロードをカスタマイズできます。これが `load_tests protocol`_ です。

バージョン 2.7 で変更: load_tests をサポートしました。

loadTestsFromName(name, module=None)

文字列で指定される全テストケースを含むスイートを返します。

name には “ドット修飾名” でモジュールかテストケースクラス、テストケースクラス内のメソッド、 TestSuite インスタンスまたは TestCase か TestSuite のインスタンスを返す呼び出し可能オブジェクトを指定します。このチェックはここで挙げた順番に行なわれます。すなわち、候補テストケースクラス内のメソッドは「呼び出し可能オブジェクト」としてではなく「テストケースクラス内のメソッド」として拾い出されます。

例えば SampleTests モジュールに TestCase から派生した SampleTestCase クラスがあり、 SampleTestCase にはテストメソッド test_one() ・ test_two() ・ test_three() があるとします。この場合、 name に 'SampleTests.SampleTestCase' と指定すると、 SampleTestCase の三つのテストメソッドを実行するテストスイートが作成されます。 'SampleTests.SampleTestCase.test_two' と指定すれば、 test_two() だけを実行するテストスイートが作成されます。インポートされていないモジュールやパッケージ名を含んだ名前を指定した場合は自動的にインポートされます。

また、 module を指定した場合、 module 内の name を取得します。

loadTestsFromNames(names, module=None)

loadTestsFromName() と同じですが、名前を一つだけ指定するのではなく、複数の名前のシーケンスを指定する事ができます。戻り値は names 中の名前で指定されるテスト全てを含むテストスイートです。

getTestCaseNames(testCaseClass)

testCaseClass 中の全てのメソッド名を含むソート済みシーケンスを返します。 testCaseClass は TestCase のサブクラスでなければなりません。

discover(start_dir, pattern='test*.py', top_level_dir=None)

すべてのテストモジュールを指定された開始ディレクトリから検索して返します。再帰的にサブディレクトリも検索します。 pattern にマッチしたテストファイルだけがロードの対象になります。（シェルスタイルのパターンマッチングが使われます。）その中で、インポート可能なもジュール（つまりPythonの識別子として有効であるということです）がロードされます。

すべてのテストモジュールはプロジェクトのトップレベルからインポート可能である必要があります。開始ディレクトリがトップレベルディレクトリでない場合は、トップレベルディレクトリが分離できなくてはいけません。

例えば、シンタックスエラーなどで、モジュールのインポートに失敗した場合、エラーが記録され、ディスカバリ自体は続けられます。

テストパッケージ名（ __init__.py の置かれたディレクトリ名） がパターンにマッチした場合、 load_tests 関数がチェックされます。この関数が存在している場合、この関数に loader, tests, pattern が渡され呼び出されます。

load_tests が存在して、ディスカバリがパッケージ内を再帰的な検索を続けている途中で ない 場合、 load_tests はそのパッケージ内の全てのテストをロードする責務を担います。

意図的にパターンはローダの属性として保持されないようになっています。それにより、パッケージが自分自身のディスカバリを続ける事ができます。 top_level_dir は保持されるため、 loader.discover() に引数として渡す必要はありません。

バージョン 2.7 で追加.

以下の属性は、サブクラス化またはインスタンスの属性値を変更して TestLoader をカスタマイズする場合に使用します。

testMethodPrefix

テストメソッドの名前と判断されるメソッド名の接頭語を示す文字列。デフォルト値は 'test' です。

この値は getTestCaseNames() と全ての loadTestsFrom*() メソッドに影響を与えます。

sortTestMethodsUsing

getTestCaseNames() および全ての loadTestsFrom*() メソッドでメソッド名をソートする際に使用する比較関数。デフォルト値は組み込み関数 cmp() です。ソートを行なわないようにこの属性に None を指定することもできます。

suiteClass

テストのリストからテストスイートを構築する呼び出し可能オブジェクト。メソッドを持つ必要はありません。デフォルト値は TestSuite です。

この値は全ての loadTestsFrom*() メソッドに影響を与えます。

class unittest.TestResult

このクラスはどのテストが成功しどのテストが失敗したかという情報を収集するのに使います。

TestResult は、複数のテスト結果を記録します。 TestCase クラスと TestSuite クラスのテスト結果を正しく記録しますので、テスト開発者が独自にテスト結果を管理する処理を開発する必要はありません。

unittest を利用したテストフレームワークでは、 TestRunner.run() が返す TestResult インスタンスを参照し、テスト結果をレポートします。

以下の属性は、テストの実行結果を検査する際に使用することができます。

errors

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは予想外の例外を送出したテストに対応します。

バージョン 2.2 で変更: sys.exc_info() の結果ではなく、フォーマットしたトレースバックを保存します。

failures

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは TestCase.fail*() や TestCase.assert*() メソッドを使って見つけ出した失敗に対応します。

バージョン 2.2 で変更: sys.exc_info() の結果ではなく、フォーマットしたトレースバックを保存します。

skipped

TestCase インスタンスと理由の文字列の2要素タプルからなるリストを保持します。

バージョン 2.7 で追加.

expectedFailures

TestCase と例外のトレースバック情報をフォーマットした文字列の 2 要素タプルからなるリスト。それぞれのタプルは意図した失敗に対応します。

unexpectedSuccesses

意図した失敗のマークが付いていながら成功してしまった TestCase のインスタンスのリスト。

shouldStop

True が設定されると stop() によりテストの実行が停止します。

testsRun

これまでに実行したテストの総数です。

buffer

True が設定されると、 sys.stdout と sys.stderr は、 startTest() から stopTest() が呼ばれるまでの間バッファリングされます。実際に、結果が sys.stdout と sys.stderr に出力されるのは、テストが失敗するかエラーが発生した時になります。表示の際には、全ての失敗 / エラーメッセージが表示されます。

バージョン 2.7 で追加.

failfast

True が設定されると、 stop() が始めの失敗もしくはエラーの時に呼び出され、テストの実行が終了します。

バージョン 2.7 で追加.

wasSuccessful()

これまでに実行したテストが全て成功していれば True を、それ以外なら False を返します。

stop()

このメソッドを呼び出して TestResult の shouldStop 属性に True をセットすることで、実行中のテストは中断しなければならないというシグナルを送ることができます。 TestRunner オブジェクトはこのフラグを尊重してそれ以上のテストを実行することなく復帰しなければなりません。

たとえばこの機能は、ユーザのキーボード割り込みを受け取って TextTestRunner クラスがテストフレームワークを停止させるのに使えます。 TestRunner の実装を提供する対話的なツールでも同じように使用することができます。

以下のメソッドは内部データ管理用のメソッドですが、対話的にテスト結果をレポートするテストツールを開発する場合などにはサブクラスで拡張することができます。

startTest(test)

test を実行する直前に呼び出されます。

stopTest(test)

test の実行直後に、テスト結果に関わらず呼び出されます。

startTestRun(test)

全てのテストが実行される前に一度だけ実行されます。

バージョン 2.7 で追加.

stopTestRun(test)

全てのテストが実行された後に一度だけ実行されます。

バージョン 2.7 で追加.

addError(test, err)

テスト test 実行中に、想定外の例外が発生した場合に呼び出されます。 err は sys.exc_info() が返すタプル (type, value, traceback) です。

デフォルトの実装では、タプル、 (test, formatted_err) をインスタンスの errors 属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。

addFailure(test, err)

テストが失敗した場合に呼び出されます。 err は sys.exc_info() が返すタプル (type, value, traceback) です。

デフォルトの実装では、タプル、 (test, formatted_err) をインスタンスの errors 属性に追加します。ここで、 formatted_err は、 err から導出される、整形されたトレースバックです。

addSuccess(test)

テストケース test が成功した場合に呼び出されます。

デフォルトの実装では何もしません。

addSkip(test, reason)

test がスキップされた時に呼び出されます。 reason はスキップの際に渡された理由の文字列です。

デフォルトの実装では、 (test, reason) のタプルをインスタンスの skipped 属性に追加します。

addExpectedFailure(test, err)

expectedFailure() のデコレータでマークされた test が失敗した時に呼び出されます。

デフォルトの実装では (test, formatted_err) のタプルをインスタンスの expectedFailures に追加します。ここで formatted_err は err から派生した整形されたトレースバックです。

addUnexpectedSuccess(test)

expectedFailure() のデコレータでマークされた test が成功した時に呼び出されます。

デフォルトの実装ではテストをインスタンスの unexpectedSuccesses 属性に追加します。

unittest.defaultTestLoader

TestLoader のインスタンスで、共用することが目的です。 TestLoader をカスタマイズする必要がなければ、新しい TestLoader オブジェクトを作らずにこのインスタンスを使用します。

class unittest.TextTestRunner(stream=sys.stderr, descriptions=True, verbosity=1)

実行結果を標準エラーに出力する、単純なテストランナー。いくつかの設定項目がありますが、非常に単純です。グラフィカルなテスト実行アプリケーションでは、独自のテストランナーを作成してください。

_makeResult()

このメソッドは run() で使われる TestResult のインスタンスを返します。このメソッドは明示的に呼び出す必要はありませんが、サブクラスで TestResult をカスタマイズすることができます。

_makeResult() は、 TextTestRunner のコンストラクタで resultclass 引数として渡されたクラスもしくはコーラブルオブジェクトをインスタンス化します。 resultclass が指定されていない場合には、デフォルトで TextTestResult が使用されます。結果のクラスは以下の引数が渡されインスタンス化されます。

stream, descriptions, verbosity

unittest.main([module[, defaultTest[, argv[, testRunner[, testLoader[, exit[, verbosity[, failfast[, catchbreak[, buffer]]]]]]]]]])

unittest.main([module[, defaultTest[, argv[, testRunner[, testLoader]]]]])

テストを実行するためのコマンドラインプログラム。この関数を使えば、簡単に実行可能なテストモジュールを作成する事ができます。一番簡単なこの関数の使い方は、以下の行をテストスクリプトの最後に置くことです。

if __name__ == '__main__':
    unittest.main()

You can run tests with more detailed information by passing in the verbosity argument:

if __name__ == '__main__':
    unittest.main(verbosity=2)

引数、 testRunner は、test runner class、あるいは、そのインスタンスのどちらでも構いません。でフォルトでは main はテストが成功したか失敗したかに対応した終了コードと共に sys.exit() を呼び出します。

main は、 exit=False を指定する事で対話的なインタプリタから使用することもできます。この引数を指定すると、 sys.exit() を呼ばずに、結果のみを出力します。

>>> from unittest import main
>>> main(module='test_module', exit=False)

failfast, catchbreak と buffer は、 `command-line options`_ にある同名のオプションと同じ効果のあるパラメータです。

main を呼び出すと、 TestProgram のインスタンスが返されます。このインスタンスは、 result 属性にテスト結果を保持します。

バージョン 2.7 で変更: exit, verbosity, failfast, catchbreak と buffer パラメータが追加されました。

25.3.7.3.1. load_tests プロトコル

バージョン 2.7 で追加.

モジュールやパッケージには、 load_tests と呼ばれる関数を実装できます。これにより、通常のテスト実行時やテストディスカバリ時のテストのロードされ方をカスタマイズできます。

テストモジュールが load_tests を定義していると、それが TestLoader.loadTestsFromModule() から呼ばれます。引数は以下です:

load_tests(loader, standard_tests, None)

これは TestSuite を返すべきです。

loader はローディングを行う TestLoader のインスタンスです。 standard_tests は、そのモジュールからデフォルトでロードされるテストです。これは、テストの標準セットのテストの追加や削除のみを行いたいテストモジュールに一般に使われます。第三引数は、パッケージをテストディスカバリの一部としてロードするときに使われます。

特定の TestCase クラスのセットからテストをロードする典型的な load_tests 関数は、このようになります:

test_cases = (TestCase1, TestCase2, TestCase3)

def load_tests(loader, tests, pattern):
    suite = TestSuite()
    for test_class in test_cases:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    return suite

ディスカバリが開始されると、パッケージ名にマッチするパターンを、コマンドラインまたは:meth:TestLoader.discover に与えることで、 __init__.py に load_tests があるか調べられます。

ノート

デフォルトのパターンは ‘test*.py’ です。これは、 ‘test’ で始まる全ての Python ファイルにマッチしますが、テストディレクトリには絶対にマッチ しません 。

‘test*’ のようなパターンは、モジュールだけでなくテストパッケージにもマッチします。

パッケージ __init__.py が load_tests を定義していると、それが呼び出され、ディスカバリはそれ以上パッケージ内で続けられません。 load_tests が以下の引数で呼び出されます:

load_tests(loader, standard_tests, pattern)

これはパッケージ内のすべてのテストを表す TestSuite を返すべきです。 (standard_tests には、 __init__.py から収集されたテストのみが含まれます。)

パターンは load_tests に渡されるので、パッケージは自由にテストディスカバリを継続 (必要なら変更) できます。テストパッケージに ‘何もしない’ load_tests 関数は次のようになります。:

def load_tests(loader, standard_tests, pattern):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

25.3.8. クラスとモジュールの修正

クラスレベルとモジュールレベルの修正が TestSuite に実装されました。テストスイートが新しいクラスのテストに出会うと、以前のクラス (があれば) から tearDownClass() が呼び出され、その後に新しいクラスから setUpClass() が呼び出されます。

同様に、テストが以前のテストとは異なるモジュールからのテストであるとき、まず以前のモジュールから tearDownModule が実行され、その後に新しいモジュールから setUpModule が実行されます。

すべてのテストが実行された後、最後の tearDownClass と tearDownModule が実行されます。

なお、共通の修正は、テストの並列化などの [潜在的な] 機能と同時にはうまくいかず、テストの分離を中断します。気をつけて使うべきです。

unittest テストローダによるテスト作成のデフォルトの順序では、同じモジュールやクラスからのテストはすべて同じグループにまとめられます。これにより、 setUpClass / setUpModule (など) は、一つのクラスやモジュールにつき一度だけ呼ばれます。この順序をバラバラにし、異なるモジュールやクラスのテストが並ぶようにすると、共通の修正関数は、一度のテストで複数回呼ばれるようにもなります。

共通の修正は、普通でない順序に合わせることを意図していません。共通の修正を望まないフレームワークのために、 BaseTestSuite がまだ存在しています。

共通の修正関数のいずれかの中で送出された例外があれば、そのテストはエラーとして報告されます。対応するテストインスタンスが無いので、(TestCase と同じインタフェースの) _ErrorHolder オブジェクトが生成され、エラーを表します。貴方が標準 unittest テストランナーであればこの詳細は問題になりませんが、貴方はそれが関係するフレームワーク作者かもしれません。

25.3.8.1. setUpClass と tearDownClass

これらは、クラスメソッドとして実装されなければなりません:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

基底クラスの setUpClass および tearDownClass を使いたいなら、それらを自分で呼び出さなければなりません。 TestCase の実装は空です。

setUpClass の中で例外が送出されたら、クラス内のテストは実行されず、 tearDownClass も実行されません。スキップされたクラスは setUpClass も tearDownClass も実行されません。例外が SkipTest 例外であると、そのクラスはエラーとしてではなくスキップされたものとして報告されます。

25.3.8.2. setUpModule と tearDownModule

これらは、関数として実装されなければなりません:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

setUpModule の中で例外が送出されたら、モジュール内のテストは実行されず、 tearDownModule も実行されません。例外が SkipTest 例外であると、そのモジュールはエラーとしてではなくスキップされたものとして報告されます。

25.3.9. シグナルハンドリング

unittest の -c/--catch コマンドラインオプションや、 unittest.main() の catchbreak パラメタは、テスト実行中の control-C の処理をよりフレンドリーにします。中断捕捉動作を有効である場合、 control-C が押されると、現在実行されているテストまで完了され、そのテストランが終わると今までの結果が報告されます。control-C がもう一度押されると、通常通り KeyboardInterrupt が送出されます。

シグナルハンドラを処理する control-c は、独自の signal.SIGINT ハンドラをインストールするコードやテストの互換性を保とうとします。 unittest ハンドラが呼ばれ、それがインストールされた signal.SIGINT ハンドラで なければ 、すなわちテスト中のシステムに置き換えられて移譲されたなら、それはデフォルトのハンドラを呼び出します。インストールされたハンドラを置き換えて委譲するようなコードは、通常その動作を期待するからです。 unittest の control-c 処理を無効にしたいような個別のテストには、 removeHandler() デコレータが使えます。

フレームワークの作者がテストフレームワーク内で control-c 処理を有効にするための、いくつかのユーティリティ関数があります。

unittest.installHandler()

control-c ハンドラをインストールします。(主にユーザが control-c を押したことにより) signal.SIGINT が受け取られると、登録した結果すべてに stop() が呼び出されます。

バージョン 2.7 で追加.

unittest.registerResult(result)

control-c 処理のために TestResult を登録します。結果を登録するとそれに対する弱参照が格納されるので、結果がガベージコレクトされるのを妨げません。

control-c 処理が有効でなければ、 TestResult オブジェクトの登録には副作用がありません。ですからテストフレームワークは、処理が有効か無効かにかかわらず、作成する全ての結果を無条件に登録できます。

バージョン 2.7 で追加.

unittest.removeResult(result)

登録された結果を削除します。一旦結果が削除されると、control-c が押された際にその結果オブジェクトに対して stop() が呼び出されなくなります。

バージョン 2.7 で追加.

unittest.removeHandler(function=None)

引数なしで呼び出されたとき、control-c ハンドラがインストールされていると、この関数はそれを取り除きます。この関数は、テストが実行されている間だけ一時的にハンドラを取り除くテストデコレータとしても使えます。

@unittest.removeHandler def test_signal_handling(self):

...

バージョン 2.7 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール »

25.4. 2to3 - Python 2 から 3 への自動コード変換

2to3 は、 Python 2.x のソースコードを読み込み、一連の 変換プログラムを適用して Python 3.x のコードに変換するプログラムです。標準ライブラリはほとんど全てのコードを取り扱うのに十分な変換プログラムを含んでいます。ただし 2to3 を構成している lib2to3 は柔軟かつ一般的なライブラリなので、 2to3 のために自分で変換プログラムを書くこともできます。 lib2to3 は、 Python コードを自動編集する必要がある場合にも適用することができます。

25.4.1. 2to3 の使用

2to3 は大抵の場合、 Python インタープリターと共に、スクリプトとしてインストールされます。場所は、 Python のルートディレクトリにある、 Tools/scripts ディレクトリです。

2to3 に与える基本の引数は、変換対象のファイル、もしくは、ディレクトリのリストです。ディレクトリの場合は、 Python ソースコードを再帰的に探索します。

Python 2.x のサンプルコード、 example.py を示します。

def greet(name):
    print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

これは、コマンドラインから 2to3 を呼び出すことで、 Python 3.x コードに変換されます。

$ 2to3 example.py

オリジナルのソースファイルに対する差分が表示されます。 2to3 は必要となる変更をソースファイルに書き込むこともできます (もちろんオリジナルのバックアップも作成されます)。変更の書き戻しは -w フラグによって有効化されます。

$ 2to3 -w example.py

変換後、 example.py は以下のようになります。

def greet(name):
    print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)

変換処理を通じて、コメントと、インデントは保存されます。

デフォルトでは、 2to3 は一連の 事前定義された変換プログラム を実行します。 -l フラグは、利用可能な変換プログラムの一覧を表示します。 -f フラグにより、実行する変換プログラムを明示的に与えることもできます。下記の例では、 imports と has_key 変換プログラムだけを実行します。

$ 2to3 -f imports -f has_key example.py

このコマンドは apply 以外のすべての変換プログラムを実行します。

$ 2to3 -x apply example.py

いくつかの変換プログラムは 明示的 、つまり、デフォルトでは実行されず、コマンドラインで実行するものとして列記する必要があります。デフォルトの変換プログラムに idioms 変換プログラムを追加して実行するには、下記のようにします。

$ 2to3 -f all -f idioms example.py

ここで、 all を指定することで、全てのデフォルトの変換プログラムを有効化できることに注意して下さい。

2to3 がソースコードに修正すべき点を見つけても、自動的には修正できない場合もあります。この場合、 2to3 はファイルの変更点の下に警告を表示します。 3.x に準拠したコードにするために、あなたはこの警告に対処しなくてはなりません。

2to3 は doctest の修正もできます。このモードを有効化するには -d フラグを指定して下さい。 doctest だけ が修正されることに注意して下さい。これは、モジュールが有効な Python コードであることを要求しないということでもあります。例えば、 reST ドキュメント中の doctest に似たサンプルコードなども、このオプションで修正することができます。

-v は、変換処理のより詳しい情報の出力を有効化します。

いくつかの print 文は関数呼び出しとしても文としても解析できるので、 2to3 は print 関数を含むファイルを常に読めるとは限りません。 2to3 は from __future__ import print_function コンパイラディレクティブが存在することを検出すると、内部の文法を変更して print() を関数として解釈するようになります。 -p フラグによって手動でこの変更を有効化することもできます。 print 文を変換済みのコードに対して変換プログラムを適用するには -p を使用してください。

25.4.2. 変換プログラム

コード変形の各ステップは変換プログラムに隠蔽されます。 2to3 -l コマンドは変換プログラムのリストを表示します。 上記 の通り、それぞれの変換プログラムを個別に有効化したり無効化したりすることができます。ここではそれらをさらに詳細に説明します。

apply

apply() の使用を削除します。例えば apply(function, *args, **kwargs) は function(*args, **kwargs) に変換されます。

basestring

basestring を str に変換します。

buffer

buffer を memoryview に変換します。 memoryview API は buffer と似ているものの厳密に同じではないので、この変換プログラムはオプションです。

callable

callable(x) を isinstance(x, collections.Callable) に変換し、必要なら collections のインポートを追加します。

dict

辞書をイテレートするメソッドを修正します。 dict.iteritems() は dict.items() に、 dict.iterkeys() は dict.keys() に、 dict.itervalues() は dict.values() に変換されます。同様に dict.viewitems(), dict.viewkeys() dict.viewvalues() はそれぞれ dict.items(), dict.keys(), dict.values() に変換されます。また、 list の呼び出しの中で dict.items(), dict.keys(), dict.values() を使用している場合はそれをラップします。

except

except X, T を except X as T に変換します。

exec

exec 文を exec() 関数に変換します。

execfile

execfile() の使用を削除します。 execfile() への引数は open(), compile(), exec() の呼び出しでラップされます。

exitfunc

sys.exitfunc への代入を atexit モジュールの使用に変更します。

filter

list 呼び出しの中で filter() を使用している部分をラップします。

funcattrs

名前が変更された関数の属性を修正します。例えば my_function.func_closure は my_function.__closure__ に変換されます。

future

from __future__ import new_feature 文を削除します。

getcwdu

os.getcwdu() を os.getcwd() に置き換えます。

has_key

dict.has_key(key) を key in dict に変更します。

idioms

このオプションの変換プログラムは、 Python コードをより Python らしい書き方にするいくつかの変形を行います。 type(x) is SomeClass や type(x) == SomeClass のような型の比較は isinstance(x, SomeClass) に変換されます。 while 1 は while True になります。また、適切な場所では sorted() が使われるようにします。例えば、このブロックは:

L = list(some_iterable)
L.sort()

次のように変更されます:

L = sorted(some_iterable)

import

暗黙の相対インポート (sibling imports) を検出して、明示的な相対インポート (relative imports) に変換します。

imports

標準ライブラリ中のモジュール名の変更を扱います。

imports2

標準ライブラリ中の別のモジュール名の変更を扱います。単に技術的な制約のために imports とは別になっています。

input

input(prompt) を eval(input(prompt)) に変換します。

intern

intern() を sys.intern() に変換します。

isinstance

isinstance() の第 2 引数の重複を修正します。例えば isinstance(x, (int, int)) は isinstance(x, (int)) に変換されます。

itertools_imports

itertools.ifilter(), itertools.izip(), itertools.imap() のインポートを削除します。また itertools.ifilterfalse() のインポートを itertools.filterfalse() に変換します。

itertools

itertools.ifilter(), itertools.izip(), itertools.imap() を使っている箇所を同等の組み込み関数で置き換えます。 itertools.ifilterfalse() は itertools.filterfalse() に変換されます。

long

long リテラルの末尾の L を取り除き、 long を int に変更します。

map

list 呼び出しの中の map() をラップします。また、 map(None, x) を list(x) に変換します。 from future_builtins import map を使うと、この変換プログラムを無効にできます。

metaclass

古いメタクラス構文 (クラス定義中の __metaclass__ = Meta) を、新しい構文 (class X(metaclass=Meta)) に変換します。

methodattrs

古いメソッドの属性名を修正します。例えば meth.im_func は meth.__func__ に変換されます。

ne

古い不等号の構文 <> を != に変換します。

next

イテレータの next() メソッドの使用を next() 関数に変換します。また next() メソッドを __next__() に変更します。

nonzero

__nonzero__() を __bool__() に変更します。

numliterals

8進数リテラルを新しい構文に変換します。

paren

リスト内包表記で必要になる括弧を追加します。例えば [x for x in 1, 2] は [x for x in (1, 2)] になります。

print

print 文を print() 関数に変換します。

raise

raise E, V を raise E(V) に、 raise E, V, T を raise E(V).with_traceback(T) に変換します。例外の代わりにタプルを使用することは 3.0 で削除されたので、 E がタプルならこの変換は不正確になります。

raw_input

raw_input() を input() に変換します。

reduce

reduce() が functools.reduce() に移動されたことを扱います。

renames

sys.maxint を sys.maxsize に変更します。

repr

バッククォートを使った repr を repr() 関数に置き換えます。

set_literal

set コンストラクタの使用を set リテラルに置換します. この変換プログラムはオプションです。

standard_error

StandardError を Exception に変更します。

sys_exc

廃止された sys.exc_value, sys.exc_type, sys.exc_traceback の代わりに sys.exc_info() を使うように変更します。

throw

ジェネレータの throw() メソッドの API 変更を修正します。

tuple_params

関数定義における暗黙的なタプルパラメータの展開を取り除きます。この変換プログラムによって一時変数が追加されます。

types

types モジュールのいくつかのメンバオブジェクトが削除されたことによって壊れたコードを修正します。

unicode

unicode を str に変更します。

urllib

urllib と urllib2 が urllib パッケージに変更されたことを扱います。

ws_comma

コンマ区切りの要素から余計な空白を取り除きます。この変換プログラムはオプションです。

xrange

xrange() を range() に変更して、既存の range() 呼び出しを list でラップします。

xreadlines

for x in file.xreadlines() を for x in file に変更します。

zip

list 呼び出しの中で使われている zip() をラップします。これは from future_builtins import zip が見つかった場合は無効にされます。

25.4.3. lib2to3 - 2to3’s library

ノート

lib2to3 API は安定しておらず、将来、劇的に変更されるかも知れないと考えるべきです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

25. 開発ツール »

25.5. test — Python用回帰テストパッケージ

ノート

test パッケージは、 Python の内部で使用されるためのものです。ドキュメントが書かれたのは Python のコア開発者の利便性を考えてのことです。 Python の標準ライブラリ以外でこのパッケージを使用することは、あまりお勧めできません。ここで触れられているコードは、Python のリリースの間に予告なく変更されたり削除されたりすることがあります。

test パッケージには、Python 用の全ての回帰テストの他に、 test.test_support モジュールと test.regrtest モジュールが入っています。 test.test_support はテストを充実させるために使い、 test.regrtest はテストスイートを実行するのに使います。

test パッケージ内のモジュールのうち、名前が test_ で始まるものは、特定のモジュールや機能に対するテストスイートです。新しいテストはすべて unittest か doctest モジュールを使って書くようにしてください。古いテストのいくつかは、 sys.stdout への出力を比較する「従来の」テスト形式になっていますが、この形式のテストは廃止予定です。

参考

Module unittest

PyUnit 回帰テストを書く。

Module doctest

ドキュメンテーション文字列に埋め込まれたテスト。

25.5.1. test パッケージのためのユニットテストを書く

unittest モジュールを使ってテストを書く場合、幾つかのガイドラインに従うことが推奨されます。 1つは、テストモジュールの名前を、 test_ で始め、テスト対象となるモジュール名で終えることです。テストモジュール中のテストメソッドは名前を test_ で始めて、そのメソッドが何をテストしているかという説明で終えます。これはテスト実行プログラムが、そのメソッドをテストメソッドとして認識するために必要です。また、テストメソッドにはドキュメンテーション文字列を入れるべきではありません。コメント（例えば # True あるいは False だけを返すテスト関数 ）を使用して、テストメソッドのドキュメントを記述してください。これは、ドキュメンテーション文字列が存在する場合はその内容が出力されてしまうため、どのテストを実行しているのかをいちいち表示したくないからです。

以下のような決まり文句を使います:

import unittest
from test import test_support

class MyTestCase1(unittest.TestCase):

    # Only use setUp() and tearDown() if necessary

    def setUp(self):
        ... code to execute in preparation for tests ...

    def tearDown(self):
        ... code to execute to clean up after tests ...

    def test_feature_one(self):
        # Test feature one.
        ... testing code ...

    def test_feature_two(self):
        # Test feature two.
        ... testing code ...

    ... more test methods ...

class MyTestCase2(unittest.TestCase):
    ... same structure as MyTestCase1 ...

... more test classes ...

def test_main():
    test_support.run_unittest(MyTestCase1,
                              MyTestCase2,
                              ... list other tests ...
                              )

if __name__ == '__main__':
    test_main()

この定型的なコードによって、テストスイートを regrtest.py から起動できると同時に、スクリプト自体からも実行できるようになります。

回帰テストの目的はコードを解き明かすことです。そのためには以下のいくつかのガイドラインに従ってください:

テストスイートから、すべてのクラス、関数および定数を実行するべきです。これには外部に公開される外部APIだけでなく「プライベートな」コードも含みます。

ホワイトボックス・テスト（対象のコードの詳細を元にテストを書くこと）を推奨します。ブラックボックス・テスト（公開されるインタフェース仕様だけをテストすること）は、すべての境界条件を確実にテストするには完全ではありません。

すべての取りうる値を、無効値も含めてテストするようにしてください。そのようなテストを書くことで、全ての有効値が通るだけでなく、不適切な値が正しく処理されることも確認できます。

コード内のできる限り多くのパスを網羅してください。分岐するように入力を調整したテストを書くことで、コードの多くのパスをたどることができます。

テスト対象のコードにバグが発見された場合は、明示的にテスト追加するようにしてください。そのようなテストを追加することで、将来コードを変更した際にエラーが再発することを防止できます。

テストの後始末（例えば一時ファイルをすべて閉じたり削除したりすること）を必ず行ってください。

テストがオペレーティングシステムの特定の状況に依存する場合、テスト開始時に条件を満たしているかを検証してください。

import するモジュールをできるかぎり少なくし、可能な限り早期に import を行ってください。そうすることで、てテストの外部依存性を最小限にし、モジュールの import による副作用から生じる変則的な動作を最小限にできます。

できる限りテストコードを再利用するようにしましょう。時として、入力の違いだけを記述すれば良くなるくらい、テストコードを小さくすることができます。例えば以下のように、サブクラスで入力を指定することで、コードの重複を最小化することができます:

class TestFuncAcceptsSequences(unittest.TestCase):

    func = mySuperWhammyFunction

    def test_func(self):
        self.func(self.arg)

class AcceptLists(TestFuncAcceptsSequences):
    arg = [1, 2, 3]

class AcceptStrings(TestFuncAcceptsSequences):
    arg = 'abc'

class AcceptTuples(TestFuncAcceptsSequences):
    arg = (1, 2, 3)

参考

Test Driven Development

コードより前にテストを書く方法論に関する Kent Beck の著書

25.5.2. コマンドラインインタフェースを利用してテストを実行する

test.regrtest はスクリプトとして Python の回帰テストスイートを実行できます。 -m オプションを利用して、 python -m test.regrtest として実行します。スクリプトを実行すると、自動的に test パッケージ内のすべての回帰テストを実行し始めます。パッケージ内の名前が test_ で始まる全モジュールを見つけ、それをインポートし、もしあるなら関数 test_main() を実行してテストを行います。実行するテストの名前もスクリプトに渡される可能性があります。単一の回帰テストを指定 (python -m test.regrtest test_spam) すると、出力を最小限にします。テストが成功したかあるいは失敗したかだけを出力するので、出力は最小限になります。

直接 test.regrtest を実行すると、テストに利用するリソースを設定できます。これを行うには、 -u コマンドラインオプションを使います。すべてのリソースを使うには、 python -m test.regrtest -uall を実行します。 -u のオプションに all を指定すると、すべてのリソースを有効にします。(よくある場合ですが) 何か一つを除く全てが必要な場合、カンマで区切った不要なリソースのリストを all の後に並べます。コマンド python -m test.regrtest -uall,-audio,-largefile とすると、 audio と largefile リソースを除く全てのリソースを使って test.regrtest を実行します。すべてのリソースのリストと追加のコマンドラインオプションを出力するには、 python -m test.regrtest -h を実行してください。

テストを実行しようとするプラットフォームによっては、回帰テストを実行する別の方法があります。 Unix では、Python をビルドしたトップレベルディレクトリで make test を実行できます。 Windows上では、 PCBuild ディレクトリから rt.bat を実行すると、すべての回帰テストを実行します。

25.5.3. test.test_support — テストのためのユーティリティ関数

ノート

test.test_support モジュールは、Python 3では test.support にリネームされました。

test.test_support モジュールでは、 Python の回帰テストに対するサポートを提供しています。

このモジュールは次の例外を定義しています:

exception test.test_support.TestFailed

テストが失敗したとき送出される例外です。これは、 unittest ベースのテストでは廃止予定で、 unittest.TestCase の assertXXX メソッドが推奨されます。

exception test.test_support.ResourceDenied

unittest.TestSkipped のサブクラスです。（ネットワーク接続のような）リソースが利用できないとき送出されます。 requires() 関数によって送出されます。

test.test_support モジュールでは、以下の定数を定義しています:

test.test_support.verbose

冗長な出力が有効な場合は True です。実行中のテストについてのより詳細な情報が欲しいときにチェックします。 verbose は test.regrtest によって設定されます。

test.test_support.have_unicode

ユニコードサポートが利用可能ならば True になります。

test.test_support.is_jython

実行中のインタプリタが Jython ならば True になります。

test.test_support.TESTFN

テンポラリファイルの名前として安全に利用できる名前に設定されます。作成した一時ファイルは全て閉じ、unlink (削除) せねばなりません。

test.test_support モジュールでは、以下の関数を定義しています:

test.test_support.forget(module_name)

モジュール名 module_name を sys.modules から取り除き、モジュールのバイトコンパイル済みファイルを全て削除します。

test.test_support.is_resource_enabled(resource)

resource が有効で利用可能ならば True を返します。利用可能なリソースのリストは、 test.regrtest がテストを実行している間のみ設定されます。

test.test_support.requires(resource[, msg])

resource が利用できなければ、 ResourceDenied を送出します。その場合、 msg は ResourceDenied の引数になります。 __name__ が "__main__" である関数にから呼び出された場合には常に True を返します。テストを test.regrtest から実行するときに使われます。

test.test_support.findfile(filename)

filename という名前のファイルへのパスを返します。一致するものが見つからなければ、 filename 自体を返します。 filename 自体もファイルへのパスでありえるので、 filename が返っても失敗ではありません。

test.test_support.run_unittest(*classes)

渡された unittest.TestCase サブクラスを実行します。この関数は名前が test_ で始まるメソッドを探して、テストを個別に実行します。

引数に文字列を渡すことも許可されています。その場合、文字列は sys.module のキーでなければなりません。指定された各モジュールは、 unittest.TestLoader.loadTestsFromModule() でスキャンされます。この関数は、よく次のような test_main() 関数の形で利用されます。

def test_main():
    test_support.run_unittest(__name__)

この関数は、名前で指定されたモジュールの中の全ての定義されたテストを実行します。

test.test_support.check_warnings(*filters, quiet=True)

warning が正しく発行されているかどうかチェックする、 warnings.catch_warnings() を使いやすくするラッパーです。これは、 warnings.simplefilter() を always に設定して、記録された結果を自動的に検証するオプションと共に warnings.catch_warnings(record=True) を呼ぶのとほぼ同じです。

check_warnings は ("message regexp", WarningCategory) の形をした 2要素タプルをポジション引数として受け取ります。1つ以上の filters が与えられた場合や、オプションのキーワード引数 quiet が False の場合、警告が期待通りであるかどうかをチェックします。指定された各 filter は最低でも1回は囲われたコード内で発生した警告とマッチしなければテストが失敗しますし、指定されたどの filter ともマッチしない警告が発生してもテストが失敗します。前者のチェックを無効にするには、 quiet を True にします。

引数が1つもない場合、デフォルトでは次のようになります:

check_warnings(("", Warning), quiet=True)

この場合、全ての警告は補足され、エラーは発生しません。

コンテキストマネージャーに入る時、 WarningRecorder インスタンスが返されます。このレコーダーオブジェクトの warnings 属性から、 catch_warnings() から得られる警告のリストを取得することができます。便利さのために、レコーダーオブジェクトから直接、一番最近に発生した警告を表すオブジェクトの属性にアクセスできます(以下にある例を参照してください)。警告が1つも発生しなかった場合、それらの全ての属性は None を返します。

レコーダーオブジェクトの reset() メソッドは警告リストをクリアします。

コンテキストマネージャーは次のようにして使います:

with check_warnings(("assertion is always true", SyntaxWarning),
                    ("", UserWarning)):
    exec('assert(False, "Hey!")')
    warnings.warn(UserWarning("Hide me!"))

この場合、どちらの警告も発生しなかった場合や、それ以外の警告が発生した場合は、 check_warnings() はエラーを発生させます。

警告が発生したかどうかだけでなく、もっと詳しいチェックが必要な場合は、次のようなコードになります:

with check_warnings(quiet=True) as w:
    warnings.warn("foo")
    assert str(w.args[0]) == "foo"
    warnings.warn("bar")
    assert str(w.args[0]) == "bar"
    assert str(w.warnings[0].args[0]) == "foo"
    assert str(w.warnings[1].args[0]) == "bar"
    w.reset()
    assert len(w.warnings) == 0

全ての警告をキャプチャし、テストコードがその警告を直接テストします。

バージョン 2.6 で追加.

バージョン 2.7 で変更: 新しいオプション引数 filters と quiet

test.test_support.check_py3k_warnings(*filters, quiet=False)

check_warnings() と似ていますが、 Python 3 互換性警告のためのものです。 sys.py3kwarning == 1 の時、警告が実際に発生していることをチェックします。 sys.py3kwarning == 0 の時、警告が発生していないことをチェックします。ポジション引数として ("message regexp", WarningCategory) の形をした 2要素タプルを受け取ります。オプション引数 quiet が True のとき、filter になにもマッチしなくても失敗しません。引数がない場合は次と同じになります:

check_py3k_warnings(("", DeprecationWarning), quiet=False)

バージョン 2.7 で追加.

test.test_support.captured_stdout()

これは、 with 文の body で sys.stdout として StringIO.StringIO オブジェクトを利用するコンテキストマネージャーです。このオブジェクトは、 with 文の as 節で受け取ることができます。

使用例:

with captured_stdout() as s:
    print "hello"
assert s.getvalue() == "hello"

バージョン 2.6 で追加.

test.test_support.import_module(name, deprecated=False)

この関数は name で指定されたモジュールを import して返します。通常の import と異なり、この関数はモジュールを import できなかった場合に unittest.SkipTest 例外を発生させます。

deprecated が True の場合、 import 中はモジュールとパッケージの廃止メッセージが抑制されます。

バージョン 2.7 で追加.

test.test_support.import_fresh_module(name, fresh=(), blocked=(), deprecated=False)

この関数は、 name で指定された Python モジュールを、 import 前に sys.modules から削除することで新規に import してそのコピーを返します。 reload() 関数と違い、もとのモジュールはこの操作によって影響をうけません。

fresh は、同じように import 前に sys.modules から削除されるモジュール名の iterable です。

blocked もモジュール名の iterable で、 import 中にモジュールキャッシュ内でその名前を 0 に置き換えることで、そのモジュールを import しようとすると ImportError を発生させます。

指定されたモジュールと fresh や blocked 引数内のモジュール名は import 前に保存され、 fresh import が完了したら sys.modules に戻されます。

deprecated が True の場合、 import 中はモジュールとパッケージの廃止メッセージが抑制されます。

この関数はモジュールを import できなかった場合に unittest.SkipTest 例外を発生させます。

使用例:

# Get copies of the warnings module for testing without
# affecting the version being used by the rest of the test suite
# One copy uses the C implementation, the other is forced to use
# the pure Python fallback implementation
py_warnings = import_fresh_module('warnings', blocked=['_warnings'])
c_warnings = import_fresh_module('warnings', fresh=['_warnings'])

バージョン 2.7 で追加.

test.test_support モジュールは以下のクラスを定義しています。

class test.test_support.TransientResource(exc[, **kwargs])

このクラスのインスタンスはコンテキストマネージャーで、指定された型の例外が発生した場合に ResourceDenied 例外を発生させます。キーワード引数は全て、 with 文の中で発生した全ての例外の属性名/属性値と比較されます。全てのキーワード引数が例外の属性に一致した場合に、 ResourceDenied 例外が発生します。

バージョン 2.6 で追加.

class test.test_support.EnvironmentVarGuard

一時的に環境変数をセット・アンセットするためのクラスです。このクラスのインスタンスはコンテキストマネージャーとして利用されます。また、 os.environ に対する参照・更新を行う完全な辞書のインタフェースを持ちます。コンテキストマネージャーが終了した時、このインスタンス経由で環境変数へ行った全ての変更はロールバックされます。

バージョン 2.6 で追加.

バージョン 2.7 で変更: 辞書のインタフェースを追加しました。

EnvironmentVarGuard.set(envvar, value)

一時的に、 envvar を value にセットします。

EnvironmentVarGuard.unset(envvar)

一時的に envvar をアンセットします。

class test.test_support.WarningsRecorder

ユニットテスト時にwarningを記録するためのクラスです。上の、 check_warnings() のドキュメントを参照してください。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル

ここに含まれるライブラリは Python での開発を手助けするものです。デバッガはコードのステップ実行や、スタックフレームの解析、ブレークポイントの設定などを可能にします。プロファイラはコードを実行して実行時間の詳細を晒すことでプログラムのボトルネックを見つけることを可能にします。

26.1. bdb — デバッガーフレームワーク

26.2. pdb — Python デバッガ

26.3. デバッガコマンド

26.4. Python プロファイラ

26.4.1. プロファイラとは

26.4.2. かんたんユーザマニュアル

26.4.3. 決定論的プロファイリングとは

26.4.4. リファレンスマニュアル – profile と cProfile

26.4.4.1. Stats クラス

26.4.5. 制限事項

26.4.6. キャリブレーション (補正)

26.4.7. 拡張 — プロファイラの改善

26.5. hotshot — ハイパフォーマンス・ロギング・プロファイラ

26.5.1. プロファイル・オブジェクト

26.5.2. hotshot データの利用

26.5.3. 使用例

26.6. timeit — 小さなコード断片の実行時間計測

26.6.1. コマンドライン・インターフェース

26.6.2. 使用例

26.7. trace — Python ステートメント実行のトレースと追跡

26.7.1. コマンドラインからの利用

26.7.1.1. 主要なオプション

26.7.1.2. 修飾的オプション

26.7.1.3. フィルターオプション

26.7.2. プログラミングインターフェース

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.1. bdb — デバッガーフレームワーク

bdb モジュールは、ブレークポイントを設定したり、デバッガー経由で実行を管理するような、基本的なデバッガー機能を提供します

以下の例外が定義されています。

exception bdb.BdbQuit

Bdb クラスが、デバッガーを終了させるために投げる例外。

bdb モジュールは2つのクラスを定義しています。

class bdb.Breakpoint(self, file, line[, temporary=0[, cond=None[, funcname=None]]])

このクラスはテンポラリブレークポイント、無視するカウント、無効化と再有効化、条件付きブレークポイントを実装しています。

ブレークポイントは bpbynumber という名前のリストで番号によりインデックスされ、 bplist により (file, line) の形でインデックスされます。 bpbynumber は Breakpoint クラスのインスタンスを指しています。一方 bplist は、同じ行に複数のブレークポイントが設定される場合があるので、インスタンスのリストを指しています。

ブレークポイントを作るとき、設定されるファイル名は正規化されていなければなりません。 funcname が設定されたとき、ブレークポイントはその関数の最初の行が実行されたときにヒットカウントにカウントされます。条件付ブレークポイントは毎回カウントされます。

Breakpoint インスタンスは以下のメソッドを持ちます。

deleteMe()

このブレークポイントをファイル/行に関連付けられたリストから削除します。このブレークポイントがその行に設定された最後のブレークポイントだった場合、そのファイル/行に対するエントリ自体を削除します。

enable()

このブレークポイントを有効にします。

disable()

このブレークポイントを無効にします。

pprint([out])

このブレークポイントに関するすべての情報を表示します。

ブレークポイント番号

テンポラリブレークポイントかどうか

ファイル/行の位置

ブレークする条件

次のN回無視されるか

ヒットカウント

class bdb.Bdb(skip=None)

Bdb クラスは一般的なPythonデバッガーの基本クラスとして振舞います。

このクラスはトレース機能の詳細を扱います。ユーザーとのインタラクションは、派生クラスが実装するべきです。標準ライブラリのデバッガクラス (pdb.Pdb) がその利用例です。

skip 引数は、もし与えられたならグロブ形式のモジュール名パターンの iterable でなければなりません。デバッガはこれらのパターンのどれかにマッチするモジュールで発生したフレームにステップインしなくなります。フレームが特定のモジュールで発生したかどうかは、フレームのグローバル変数の __name__ によって決定されます。

バージョン 2.7 で追加: skip 引数

以下の Bdb のメソッドは、通常オーバーライドする必要はありません。

canonic(filename)

標準化されたファイル名を取得するための補助関数。標準化されたファイル名とは、 (大文字小文字を区別しないファイルシステムにおいて)大文字小文字を正規化し、絶対パスにしたものです。ファイル名が “<” と “>” で囲まれていた場合はそれを取り除いたものです。

reset()

botframe, stopframe, returnframe, quitting 属性を、デバッグを始められる状態に設定します。

trace_dispatch(frame, event, arg)

この関数は、デバッグされているフレームのトレース関数としてインストールされます。戻り値は新しいトレース関数(殆どの場合はこの関数自身)です。

デフォルトの実装は、実行しようとしている event (文字列として渡されます) の種類に基づいてフレームのディスパッチ方法を決定します。 event は次のうちのどれかです。

"line": 新しい行を実行しようとしています。

"call": 関数が呼び出されているか、別のコードブロックに入ります。

"return": 関数か別のコードブロックからreturnしようとしています。

"exception": 例外が発生しました。

"c_call": C関数を呼び出そうとしています。

"c_return": C関数からreturnしました。

"c_exception": C関数が例外を発生させました。

Pythonのイベントに対しては、以下の専用の関数群が呼ばれます。Cのイベントに対しては何もしません。

arg 引数は以前のイベントに依存します。

トレース関数についてのより詳しい情報は、 sys.settrace() のドキュメントを参照してください。コードとフレームオブジェクトについてのより詳しい情報は、 標準型の階層を参照してください。

dispatch_line(frame)

デバッガーが現在の行で止まるべきであれば、 user_line() メソッド (サブクラスでオーバーライドされる)を呼び出します。 Bdb.quitting フラグ(user_line() から設定できます)が設定されていた場合、 BdbQuit 例外を発生させます。このスコープのこれからのトレースのために、 trace_dispatch() メソッドの参照を返します。

dispatch_call(frame, arg)

デバッガーがこの関数呼び出しで止まるべきであれば、 user_call() メソッド (サブクラスでオーバーライドされる)を呼び出します。 Bdb.quitting フラグ(user_line() から設定できます)が設定されていた場合、 BdbQuit 例外を発生させます。このスコープのこれからのトレースのために、 trace_dispatch() メソッドの参照を返します。

dispatch_return(frame, arg)

デバッガーがこの関数からのリターンで止まるべきであれば、 user_call() メソッド (サブクラスでオーバーライドされる)を呼び出します。 Bdb.quitting フラグ(user_line() から設定できます)が設定されていた場合、 BdbQuit 例外を発生させます。このスコープのこれからのトレースのために、 trace_dispatch() メソッドの参照を返します。

dispatch_exception(frame, arg)

デバッガーがこの例外発生で止まるべきであれば、 user_call() メソッド (サブクラスでオーバーライドされる)を呼び出します。 Bdb.quitting フラグ(user_line() から設定できます)が設定されていた場合、 BdbQuit 例外を発生させます。このスコープのこれからのトレースのために、 trace_dispatch() メソッドの参照を返します。

通常、継承クラスは以下のメソッド群をオーバーライドしません。しかし、停止やブレークポイント機能を再定義したい場合には、オーバーライドすることもあります。

stop_here(frame)

このメソッドは frame がコールスタック中で botframe よりも下にあるかチェックします。 botframe はデバッグを開始したフレームです。

break_here(frame)

このメソッドは、 frame に属するファイル名と行に、あるいは、少なくとも現在の関数にブレークポイントがあるかどうかをチェックします。ブレークポイントがテンポラリブレークポイントだった場合、このメソッドはそのブレークポイントを削除します。

break_anywhere(frame)

このメソッドは、現在のフレームのファイル名の中にブレークポイントが存在するかどうかをチェックします。

継承クラスはデバッガー操作をするために以下のメソッド群をオーバーライドするべきです。

user_call(frame, argument_list)

このメソッドは、呼ばれた関数の中でブレークする必要がある可能性がある場合に、 dispatch_call() から呼び出されます。

user_line(frame)

このメソッドは、 stop_here() か break_here() が True を返したときに、 dispatch_line() から呼び出されます。

user_return(frame, return_value)

このメソッドは、 stop_here() が True を返したときに、 dispatch_return() から呼び出されます。

user_exception(frame, exc_info)

このメソッドは、 stop_here() が True を返したときに、 dispatch_exception() から呼び出されます。

do_clear(arg)

ブレークポイントがテンポラリブレークポイントだったときに、それをどう削除するかを決定します。

継承クラスはこのメソッドを実装しなければなりません。

継承クラスとクライアントは、ステップ状態に影響を及ぼすために以下のメソッドを呼び出すことができます。

set_step()

コードの次の行でストップします。

set_next(frame)

与えられたフレームかそれより下(のフレーム)にある、次の行でストップします。

set_return(frame)

指定されたフレームから抜けるときにストップします。

set_until(frame)

現在の行番号よりも大きい行番号に到達したとき、あるいは、現在のフレームから戻るときにストップします。

set_trace([frame])

frame からデバッグを開始します。 frame が指定されなかった場合、デバッグは呼び出し元のフレームから開始します。

set_continue()

ブレークポイントに到達するか終了したときにストップします。もしブレークポイントが1つも無い場合、システムのトレース関数を None に設定します。

set_quit()

quitting 属性を True に設定します。これにより、次回の dispatch_*() メソッドのどれかの呼び出しで、 BdbQuit 例外を発生させます。

継承クラスとクライアントは以下のメソッドをブレークポイント操作に利用できます。これらのメソッドは、何か悪いことがあればエラーメッセージを含む文字列を返し、すべてが順調であれば None を返します。

set_break(filename, lineno[, temporary=0[, cond[, funcname]]])

新しいブレークポイントを設定します。引数の lineno 行が filename に存在しない場合、エラーメッセージを返します。 filename は、 canonic() メソッドで説明されているような、標準形である必要があります。

clear_break(filename, lineno)

filename の lineno 行にあるブレークポイントを削除します。もしブレークポイントが無かった場合、エラーメッセージを返します。

clear_bpbynumber(arg)

Breakpoint.bpbynumber の中で arg のインデックスを持つブレークポイントを削除します。 arg が数値でないか範囲外の場合、エラーメッセージを返します。

clear_all_file_breaks(filename)

filename に含まれるすべてのブレークポイントを削除します。もしブレークポイントが無い場合、エラーメッセージを返します。

clear_all_breaks()

すべてのブレークポイントを削除します。

get_break(filename, lineno)

filename の lineno にブレークポイントが存在するかどうかをチェックします。

get_breaks(filename, lineno)

filename の lineno にあるすべてのブレークポイントを返します。ブレークポイントが存在しない場合は空のリストを返します。

get_file_breaks(filename)

filename の中のすべてのブレークポイントを返します。ブレークポイントが存在しない場合は空のリストを返します。

get_all_breaks()

セットされているすべてのブレークポイントを返します。

継承クラスとクライアントは以下のメソッドを呼んでスタックトレースを表現するデータ構造を取得することができます。

get_stack(f, t)

与えられたフレームおよび上位(呼び出し側)と下位のすべてのフレームに対するレコードのリストと、上位フレームのサイズを得ます。

format_stack_entry(frame_lineno[, lprefix=': '])

(frame, lineno) で指定されたスタックエントリに関する次のような情報を持つ文字列を返します。

そのフレームを含むファイル名の標準形

関数名、もしくは "<lambda>"

入力された引数

戻り値

(あれば)その行のコード

以下の2つのメソッドは、文字列として渡された文(statement)をデバッグするもので、クライアントから利用されます。

run(cmd[, globals[, locals]])

exec 文を利用して文を実行しデバッグします。 globals はデフォルトでは __main__.__dict__ で、 locals はデフォルトでは globals です。

runeval(expr[, globals[, locals]])

eval() 関数を利用して式を実行しデバッグします。 globals と locals は run() と同じ意味です。

runctx(cmd, globals, locals)

後方互換性のためのメソッドです。 run() を使ってください。

runcall(func, *args, **kwds)

1つの関数呼び出しをデバッグし、その結果を返します。

最後に、このモジュールは以下の関数を提供しています。

bdb.checkfuncname(b, frame)

この場所でブレークする必要があるかどうかを、ブレークポイント b が設定された方法に依存する方法でチェックします。

ブレークポイントが行番号で設定されていた場合、この関数は b.line が、同じく引数として与えられた frame の中の行に一致するかどうかをチェックします。ブレークポイントが関数名で設定されていた場合、この関数は frame が指定された関数のものであるかどうかと、その関数の最初の行であるかどうかをチェックします。

bdb.effective(file, line, frame)

指定されたソースコード中の行に(有効な)ブレークポイントがあるかどうかを判断します。ブレークポイントと、テンポラリブレークポイントを削除して良いかどうかを示すフラグからなるタプルを返します。マッチするブレークポイントが存在しない場合は (None, None) を返します。

bdb.set_trace()

Bdb クラスのインスタンスを使って、呼び出し元のフレームからデバッグを開始します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.2. pdb — Python デバッガ

モジュール pdb はPythonプログラム用の対話的ソースコードデバッガを定義します。 (条件付き)ブレークポイントの設定やソース行レベルでのシングルステップ実行、スタックフレームのインスペクション、ソースコードリスティングおよびいかなるスタックフレームのコンテキストにおける任意のPythonコードの評価をサポートしています。事後解析デバッギングもサポートし、プログラムの制御下で呼び出すことができます。

デバッガは拡張可能です — 実際にはクラス Pdb として定義されています。現在これについてのドキュメントはありませんが、ソースを読めば簡単に理解できます。拡張インターフェースはモジュール bdb と cmd を使っています。

デバッガのプロンプトは (Pdb) です。デバッガに制御された状態でプログラムを実行するための典型的な使い方は:

>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)

他のスクリプトをデバッグするために、 pdb.py をスクリプトとして呼び出すこともできます。例えば:

python -m pdb myscript.py

スクリプトとして pdb を起動すると、デバッグ中のプログラムが異常終了した時に pdb が自動的に事後デバッグモードに入ります。事後デバッグ後 (またはプログラムの正常終了後) には、 pdb はプログラムを再起動します。自動再起動を行った場合、 pdb の状態 (ブレークポイントなど) はそのまま維持されるので、たいていの場合、プログラム終了時にデバッガも終了させるよりも便利なはずです。

バージョン 2.4 で追加: 事後デバッグ後の再起動機能が追加されました.

実行するプログラムをデバッガで分析する典型的な使い方は:

import pdb; pdb.set_trace()

をデバッガで分析したい場所に挿入することです。そうすることで、コードの中の以下に続く文をステップ実行できます、そして、 c コマンドでデバッガを走らせることなく続けることもできます。

クラッシュしたプログラムを調べるための典型的な使い方は:

>>> import pdb
>>> import mymodule
>>> mymodule.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "./mymodule.py", line 4, in test
    test2()
  File "./mymodule.py", line 3, in test2
    print spam
NameError: spam
>>> pdb.pm()
> ./mymodule.py(3)test2()
-> print spam
(Pdb)

モジュールは以下の関数を定義しています。それぞれが少しづつ違った方法でデバッガに入ります:

pdb.run(statement[, globals[, locals]])

デバッガに制御された状態で(文字列として与えられた) statement を実行します。デバッガプロンプトはあらゆるコードが実行される前に現れます。ブレークポイントを設定し、 continue とタイプできます。あるいは、文を step や next を使って一つづつ実行することができます (これらのコマンドはすべて下で説明します) 。オプションの globals と locals 引数はコードを実行する環境を指定します。デフォルトでは、モジュール __main__ の辞書が使われます。 (exec 文または eval() 組み込み関数の説明を参照してください。)

pdb.runeval(expression[, globals[, locals]])

デバッガの制御もとで(文字列として与えられる) expression を評価します。 runeval() がリターンしたとき、式の値を返します。その他の点では、この関数は run() と同様です。

pdb.runcall(function[, argument, ...])

function (関数またはメソッドオブジェクト、文字列ではありません) を与えられた引数とともに呼び出します。 runcall() がリターンしたとき、関数呼び出しが返したものは何でも返します。デバッガプロンプトは関数に入るとすぐに現れます。

pdb.set_trace()

スタックフレームを呼び出したところでデバッガに入ります。たとえコードが別の方法でデバッグされている最中でなくても (例えば、アサーションが失敗するとき)、これはプログラムの所定の場所でブレークポイントをハードコードするために役に立ちます。

pdb.post_mortem([traceback])

与えられた traceback オブジェクトの事後解析デバッギングに入ります。もし traceback が与えられなければ、その時点で取り扱っている例外のうちのひとつを使います。 (デフォルト動作をさせるには、例外を取り扱っている最中である必要があります。)

pdb.pm()

sys.last_traceback のトレースバックの事後解析デバッギングに入ります。

run* 関数と set_trace() は、 Pdb クラスをインスタンス化して同名のメソッドを実行することのエイリアス関数です。それ以上の機能を利用したい場合は、インスタンス化を自分でしなければなりません。

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None)

Pdb はデバッガークラスです。

completekey, stdin, stdout 引数は、基底にある cmd.Cmd クラスに渡されます。そちらの解説を参照してください。

skip 引数が指定された場合、 glob スタイルのモジュール名パターンの iterable (イテレート可能オブジェクト) でなければなりません。デバッガはこのパターンのどれかにマッチするモジュールに属するフレームにはステップ・インしません。 [1]

skip を使ってトレースする呼び出しの例:

import pdb; pdb.Pdb(skip=['django.*']).set_trace()

バージョン 2.7 で追加: skip 引数

run(statement[, globals[, locals]])

runeval(expression[, globals[, locals]])

runcall(function[, argument, ...])

set_trace()

上で説明された関数のドキュメントを参照してください。

26.3. デバッガコマンド

デバッガは以下のコマンドを認識します。ほとんどのコマンドは一文字または二文字に省略することができます。例えば、 h(elp) が意味するのは、ヘルプコマンドを入力するために h か help のどちらか一方を使うことができるということです ( が、 he や hel は使えず、また H や Help 、 HELP も使えません ) 。コマンドの引数は空白 ( スペースまたはタブ ) で区切られなければなりません。オプションの引数はコマンド構文の角括弧 ([]) の中に入れなければなりません。角括弧をタイプしてはいけません。コマンド構文における選択肢は垂直バー (|) で区切られます。

空行を入力すると入力された直前のコマンドを繰り返します。例外: 直前のコマンドが list コマンドならば、次の11行がリストされます。

デバッガが認識しないコマンドは Python 文とみなして、デバッグしているプログラムのコンテキストおいて実行されます。 Python 文は感嘆符 (!) を前に付けることもできます。これはデバッグ中のプログラムを調査する強力な方法です。変数を変更したり関数を呼び出したりすることさえ可能です。このような文で例外が発生した場合には例外名がプリントされますが、デバッガの状態は変化しません。

複数のコマンドを ;; で区切って一行で入力することができます。 (一つだけの ; は使われません。なぜなら、 Python パーサへ渡される行内の複数のコマンドのための分離記号だからです。) コマンドを分割するために何も知的なことはしていません。たとえ引用文字列の途中であっても、入力は最初の ;; 対で分割されます。

デバッガはエイリアスをサポートします。エイリアスはパラメータを持つことができ、調査中のコンテキストに対して人がある程度柔軟に対応できます。

ファイル .pdbrc はユーザのホームディレクトリか、またはカレントディレクトリにあります。それはまるでデバッガのプロンプトでタイプしたかのように読み込まれて実行されます。これは特にエイリアスのために便利です。両方のファイルが存在する場合、ホームディレクトリのものが最初に読まれ、そこに定義されているエイリアスはローカルファイルにより上書きされることがあります。

h(elp) [command]

引数なしでは、利用できるコマンドの一覧をプリントします。引数として command がある場合は、そのコマンドについてのヘルプをプリントします。 help pdb は完全ドキュメンテーションファイルを表示します。環境変数 PAGER が定義されているならば、代わりにファイルはそのコマンドへパイプされます。 command 引数が識別子でなければならないので、 ! コマンドについてのヘルプを得るためには help exec と入力しなければなりません。

w(here)

スタックの底にある最も新しいフレームと一緒にスタックトレースをプリントします。矢印はカレントフレームを指し、それがほとんどのコマンドのコンテキストを決定します。

d(own)

( より新しいフレームに向かって ) スタックトレース内でカレントフレームを1レベル下げます。

u(p)

( より古いフレームに向かって ) スタックトレース内でカレントフレームを1レベル上げます。

b(reak) [[filename:]lineno | function [, condition]]

lineno 引数がある場合は、現在のファイルのその場所にブレークポイントを設定します。 function 引数がある場合は、その関数の中の最初の実行可能文にブレークポイントを設定します。別のファイル ( まだロードされていないかもしれないもの ) のブレークポイントを指定するために、行番号はファイル名とコロンをともに先頭に付けられます。ファイルは sys.path にそって検索されます。各ブレークポイントは番号を割り当てられ、その番号を他のすべてのブレークポイントコマンドが参照することに注意してください。

第二引数を指定する場合、その値は式で、その評価値が真でなければブレークポイントは有効になりません。

引数なしの場合は、それぞれのブレークポイントに対して、そのブレークポイントに行き当たった回数、現在の通過カウント ( ignore count ) と、もしあれば関連条件を含めてすべてのブレークポイントをリストします。

tbreak [[filename:]lineno | function[, condition]]

一時的なブレークポイントで、最初にそこに達したときに自動的に取り除かれます。引数は break と同じです。

cl(ear) [filename:lineno | bpnumber [bpnumber ...]]

filename:lineno 引数を与えると、その行にある全てのブレークポイントを解除します。スペースで区切られたブレークポイントナンバーのリストを与えると、それらのブレークポイントを解除します。引数なしの場合は、すべてのブレークポイントを解除します ( が、はじめに確認します ) 。

disable [bpnumber [bpnumber ...]]

スペースで区切られたブレークポイントナンバーのリストとして与えられるブレークポイントを無効にします。ブレークポイントを無効にすると、プログラムの実行を止めることができなくなりますが、ブレークポイントの解除と違いブレークポイントのリストに残ったままになり、 (再び)有効にすることができます。

enable [bpnumber [bpnumber ...]]

指定したブレークポイントを有効にします。

ignore bpnumber [count]

与えられたブレークポイントナンバーに通過カウントを設定します。 count が省略されると、通過カウントは 0 に設定されます。通過カウントがゼロになったとき、ブレークポイントが機能する状態になります。ゼロでないときは、そのブレークポイントが無効にされず、どんな関連条件も真に評価されていて、ブレークポイントに来るたびに count が減らされます。

condition bpnumber [condition]

condition はブレークポイントが取り上げられる前に真と評価されなければならない式です。 condition がない場合は、どんな既存の条件も取り除かれます。すなわち、ブレークポイントは無条件になります。

commands [bpnumber]

ブレークポイントナンバー bpnumber にコマンドのリストを指定します。コマンドそのものはその後の行に続けます。 ‘end’ だけからなる行を入力することでコマンド群の終わりを示します。例を挙げます:

(Pdb) commands 1
(com) print some_variable
(com) end
(Pdb)

ブレークポイントからコマンドを取り除くには、 commands のあとに end だけを続けます。つまり、コマンドを一つも指定しないようにします。

bpnumber 引数が指定されない場合、最後にセットされたブレークポイントを参照することになります。

ブレークポイントコマンドはプログラムを走らせ直すのに使えます。ただ continue コマンドや step、その他実行を再開するコマンドを使えば良いのです。

実行を再開するコマンド ( 現在のところ continue, step, next, return, jump, quit とそれらの省略形 ) によって、コマンドリストは終了するものと見なされます ( コマンドにすぐ end が続いているかのように ) 。というのも実行を再開すれば ( それが単純な next や step であっても ) 別のブレークポイントに到達するかもしれないからです。そのブレークポイントにさらにコマンドリストがあれば、どちらのリストを実行すべきか状況が曖昧になります。

コマンドリストの中で ‘silent’ コマンドを使うと、ブレークポイントで停止したという通常のメッセージはプリントされません。この振る舞いは特定のメッセージを出して実行を続けるようなブレークポイントでは望ましいものでしょう。他のコマンドが何も画面出力をしなければ、そのブレークポイントに到達したというサインを見ないことになります。

バージョン 2.5 で追加.

s(tep)

現在の行を実行し、最初に実行可能なものがあらわれたときに (呼び出された関数の中か、現在の関数の次の行で) 停止します。

n(ext)

現在の関数の次の行に達するか、あるいは関数が返るまで実行を継続します。 ( next と step の差は step が呼び出された関数の内部で停止するのに対し、 next は呼び出された関数を ( ほぼ ) 全速力で実行し、現在の関数内の次の行で停止するだけです。)

unt(il)

行番号が現在行より大きくなるまで、もしくは、現在のフレームから戻るまで、実行を続けます。

バージョン 2.6 で追加.

r(eturn)

現在の関数が返るまで実行を継続します。

c(ont(inue))

ブレークポイントに出会うまで、実行を継続します。

j(ump) lineno

次に実行する行を指定します。最も底のフレーム中でのみ実行可能です。前に戻って実行したり、不要な部分をスキップして先の処理を実行する場合に使用します。

ジャンプには制限があり、例えば for ループの中には飛び込めませんし、 finally 節の外にも飛ぶ事ができません。

l(ist) [first[, last]]

現在のファイルのソースコードをリスト表示します。引数なしの場合は、現在の行の周囲を11行リストするか、または前のリストの続きを表示します。引数が一つある場合は、その行の周囲を11行表示します。引数が二つの場合は、与えられた範囲をリスト表示します。第二引数が第一引数より小さいときは、カウントと解釈されます。

a(rgs)

現在の関数の引数リストをプリントします。

p expression

現在のコンテキストにおいて expression を評価し、その値をプリントします。 (注意: print も使うことができますが、デバッガコマンドではありません — これは Python の print 文を実行します。)

pp expression

pprint モジュールを使って例外の値が整形されることを除いて p コマンドと同様です。

alias [name [command]]

name という名前の command を実行するエイリアスを作成します。コマンドは引用符で囲まれていては いけません 。入れ替え可能なパラメータは %1 、 %2 などで指し示され、さらに %* は全パラメータに置き換えられます。コマンドが与えられなければ、 name に対する現在のエイリアスを表示します。引数が与えられなければ、すべてのエイリアスがリストされます。

エイリアスは入れ子になってもよく、 pdb プロンプトで合法的にタイプできるどんなものでも含めることができます。内部 pdb コマンドをエイリアスによって上書きすることが できます 。そのとき、このようなコマンドはエイリアスが取り除かれるまで隠されます。エイリアス化はコマンド行の最初の語へ再帰的に適用されます。行の他のすべての語はそのままです。

例として、二つの便利なエイリアスがあります (特に .pdbrc ファイルに置かれたときに):

#Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
#Print instance variables in self
alias ps pi self

unalias name

指定したエイリアスを削除します。

[!]statement

現在のスタックフレームのコンテキストにおいて(一行の) statement を実行します。文の最初の語がデバッガコマンドと共通でない場合は、感嘆符を省略することができます。グローバル変数を設定するために、同じ行に global コマンドとともに代入コマンドの前に付けることができます。:

(Pdb) global list_options; list_options = ['-l']
(Pdb)

run [args ...]

デバッグ中のプログラムを再実行します。もし引数が与えられると、 “shlex” で分割され、結果が新しい sys.argv として使われます。ヒストリー、ブレークポイント、アクション、そして、デバッガーオプションは引き継がれます。 “restart” は “run” の別名です。

バージョン 2.6 で追加.

q(uit)

デバッガを終了します。実行しているプログラムは中断されます。

注記

[1]
フレームが属するモジュールは、そのフレームのグローバルの __name__ によって決定されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.4. Python プロファイラ

Copyright © 1994, by InfoSeek Corporation, all rights reserved.

執筆者 James Roskind [1]

Permission to use, copy, modify, and distribute this Python software and its associated documentation for any purpose (subject to the restriction in the following sentence) without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of InfoSeek not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. This permission is explicitly restricted to the copying and modification of the software to remain in Python, compiled Python, or other languages (such as C) wherein the modified or derived code is exclusively imported into a Python module.

INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

26.4.1. プロファイラとは

プロファイラ とは、様々な統計値を算出してプログラムの実行効率を調べるためのプログラムです。この文書では、 cProfile, profile, pstats モジュールが提供するプロファイラ機能について解説します。このプロファイラは Python プログラムに対する 決定論的プロファイリング を行います。また、プロファイル結果の検証を素早く行えるように、レポート生成用のツールも提供されています。

Python 標準ライブラリは3つの異なるプロファイラを提供しています。

cProfile はほとんどのユーザーに推奨されるモジュールです。 C言語で書かれた拡張モジュールで、オーバーヘッドが少ないため長時間実行されるプログラムのプロファイルに適しています。 Brett Rosen と Ted Czotter によって提供された lsprof に基づいています。

バージョン 2.5 で追加.

profile はピュア Python モジュールで、 cProfile モジュールはこのモジュールのインタフェースを真似ています。対象プログラムに相当のオーバーヘッドが生じます。もしプロファイラに何らかの拡張をしたいのであれば、こちらのモジュールを拡張する方が簡単でしょう。 Copyright © 1994, by InfoSeek Corporation.

バージョン 2.4 で変更: 組み込みの関数やメソッドで消費された時間も報告するようになりました。

hotshot は、後処理時間の長さと引き換えにプロファイル中のオーバーヘッドを小さくすることに主眼を置いた実験的な C モジュールでした。このモジュールはもう保守されておらず、将来のバージョンのPythonからは外されるかもしれません。

バージョン 2.5 で変更: 以前より意味のある結果が得られているはずです。かつては時間計測の中核部分に致命的なバグがありました.

profile と cProfile の両モジュールは同じインタフェースを提供しているので、ほぼ取り替え可能です。 cProfile はずっと小さなオーバーヘッドで動きますが、まだ新しく、全てのシステムで使えるとは限らないでしょう。 cProfile は実際には _lsprof 内部モジュールに被せられた互換性レイヤです。 hotshot モジュールは特別な使い道のために取っておいてあります。

26.4.2. かんたんユーザマニュアル

この節は “マニュアルなんか読みたくない人”のために書かれています。ここではきわめて簡単な概要説明とアプリケーションのプロファイリングを手っ取り早く行う方法だけを解説します。

エントリポイント foo() を持つアプリケーションをプロファイルしたいとき、モジュールに次の内容を追加します。

import cProfile
cProfile.run('foo()')

(お使いのシステムで cProfile が使えないときは代わりに profile を使って下さい)

このように書くことで foo() を実行すると同時に一連の情報 (プロファイル) が表示されます。この方法は、インタプリタ上で作業をしている場合、最も便利なやり方です。プロファイルの結果をファイルに残し、後で検証したいときは、 run() の第2引数にファイル名を指定します。

import cProfile
cProfile.run('foo()', 'fooprof')

ファイル cProfile.py を使って、別のスクリプトをプロファイルすることも可能です。次のように実行します。

python -m cProfile myscript.py

cProfile.py はコマンドラインから2つのオプション引数を受け取ります。

cProfile.py [-o output_file] [-s sort_order]

-s は標準出力にのみ適用されます (つまり、 -o が与えられなかった場合)。利用可能なソートの値は、 Stats のドキュメントをご覧ください。

プロファイル内容を確認するときは、 pstats モジュールのメソッドを使用します。統計データの読み込みは次のようにします。

import pstats
p = pstats.Stats('fooprof')

Stats クラス (上記コードはこのクラスのインスタンスを生成するだけの内容です) は p に読み込まれたデータを操作したり、表示したりするための各種メソッドを備えています。先に cProfile.run() を実行したとき表示された内容と同じものは、3つのメソッド呼び出しにより実現できます。

p.strip_dirs().sort_stats(-1).print_stats()

最初のメソッドはモジュール名からファイル名の前に付いているパス部分を取り除きます。 2番目のメソッドはエントリをモジュール名/行番号/名前に基づいてソートします。 3番目のメソッドですべての統計情報を出力します。次のようなソートメソッドも使えます。

p.sort_stats('name')
p.print_stats()

最初の行ではリストを関数名でソートしています。2行目で情報を出力しています。さらに次の内容も試してください。

p.sort_stats('cumulative').print_stats(10)

このようにすると、関数が消費した累計時間でソートして、さらにその上位10件だけを表示します。どのアルゴリズムが時間を多く消費しているのか知りたいときは、この方法が役に立つはずです。

ループで多くの時間を消費している関数はどれか調べたいときは、次のようにします。

p.sort_stats('time').print_stats(10)

上記はそれぞれの関数で消費された時間でソートして、上位10件の関数の情報が表示されます。

次の内容も試してください。

p.sort_stats('file').print_stats('__init__')

このようにするとファイル名でソートされ、そのうちクラスの初期化メソッド (メソッド名 __init__) に関する統計情報だけが表示されます。

p.sort_stats('time', 'cum').print_stats(.5, 'init')

上記は時間 (time) をプライマリキー、累計時間 (cumulative time) をセカンダリキーにしてソートした後でさらに条件を絞って統計情報を出力します。 .5 は上位 50% だけを選択することを意味し、さらにその中から文字列 init を含むものだけが表示されます。

どの関数がどの関数を呼び出しているのかを知りたければ、次のようにします (p は最後に実行したときの状態でソートされています)。

p.print_callers(.5, 'init')

このようにすると、関数ごとの呼び出し側関数の一覧が得られます。

さらに詳しい機能を知りたければマニュアルを読むか、次の関数の実行結果から内容を推察してください。

p.print_callees()
p.add('fooprof')

スクリプトとして起動した場合、 pstats モジュールはプロファイルのダンプを読み込み、分析するための統計ブラウザとして動きます。シンプルな行指向のインタフェース (cmd を使って実装) とヘルプ機能を備えています。

26.4.3. 決定論的プロファイリングとは

決定論的プロファイリング とは、すべての 関数呼び出し, 関数からのリターン, 例外発生 をモニターし、正確なタイミングを記録することで、イベント間の時間、つまりどの時間にユーザコードが実行されているのかを計測するやり方です。もう一方の 統計的プロファイリング (このモジュールでこの方法は採用していません) とは、有効なインストラクションポインタからランダムにサンプリングを行い、プログラムのどこで時間が使われているかを推定する方法です。後者の方法は、オーバヘッドが少ないものの、プログラムのどこで多くの時間が使われているか、その相対的な示唆に留まります。

Python の場合、実行中は必ずインタプリタが動作しているため、決定論的プロファイリングを行うにあたり、計測用にコードを追加する必要はありません。 Python は自動的に各イベントに フック (オプションのコールバック) を提供します。加えて Python のインタプリタという性質によって、実行時に大きなオーバーヘッドを伴う傾向がありますが、それに比べると一般的なアプリケーションでは決定論的プロファイリングで追加される処理のオーバーヘッドは少ない傾向にあります。結果的に、決定論的プロファイリングは少ないコストで Python プログラムの実行時間に関する詳細な統計を得られる方法となっているのです。

呼び出し回数はコード中のバグ発見にも使用できます (とんでもない数の呼び出しが行われている部分)。インライン拡張の対象とすべき部分を見つけるためにも使えます (呼び出し頻度の高い部分)。内部時間の統計は、注意深く最適化すべき”ホットループ”の発見にも役立ちます。累積時間の統計は、アルゴリズム選択に関連した高レベルのエラー検知に役立ちます。なお、このプロファイラは再帰的なアルゴリズム実装の累計時間を計ることが可能で、通常のループを使った実装と直接比較することもできるようになっています。

26.4.4. リファレンスマニュアル – profile と cProfile

プロファイラの主要なエントリポイントはグローバル関数 profile.run() (または cProfile.run()) です。この関数は、通常プロファイル情報の作成に使われます。 pstats.Stats クラスのメソッドを使ってプロファイル情報を整形出力します。以下はすべての標準エントリポイントと関数の解説です。さらにいくつかのコードの詳細を知りたければ、「プロファイラの拡張」を読んでください。派生クラスを使ってプロファイラを”改善”する方法やモジュールのソースコードの読み方が述べられています。

cProfile.run(command[, filename])

この関数はオプション引数として exec 文に渡すファイル名を指定できます。このルーチンは必ず最初の引数の exec を試み、実行結果からプロファイル情報を収集しようとします。ファイル名が指定されていないときは、各行の標準名文字列 (ファイル名/行数/関数名) でソートされた簡単なレポートが表示されます。以下はその出力例です。

      2706 function calls (2004 primitive calls) in 4.504 CPU seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     2    0.006    0.003    0.953    0.477 pobject.py:75(save_objects)
  43/3    0.533    0.012    0.749    0.250 pobject.py:99(evaluate)
 ...

最初の行は2706回の関数呼び出しがあったことを示しています。このうち2004回は プリミティブ なものです。プリミティブ な呼び出しとは、再帰によるものではない関数呼び出しを指します。次の行 Ordered by: standard name は、一番右側の欄の文字列を使ってソートされたことを意味します。各カラムの見出しの意味は次の通りです。

ncalls

呼び出し回数

tottime

この関数が消費した時間の合計 (下位の関数呼び出しの時間は除く)

percall

tottime を ncalls で割った値

cumtime

下位の関数を含むこの関数の (実行開始から終了までの) 消費時間の合計。この項目は再帰的な関数においても正確に計測されます。

percall

cumtime をプリミティブな呼び出し回数で割った値

filename:lineno(function)

その関数のファイル名、行番号、関数名

(43/3 など) 最初の欄に2つの数字が表示されている場合、最初の値は呼び出し回数、 2番目はプリミティブな呼び出しの回数を表しています。関数が再帰していない場合はどちらの回数も同じになるため、1つの数値しか表示されません。

cProfile.runctx(command, globals, locals[, filename])

この関数は run() に似ていますが、 command 文字列に対するグローバル辞書とローカル辞書の引数が追加されています。

プロファイラデータの分析は Stats クラスを使って行います。

ノート

Stats クラスは pstats モジュールで定義されています。

class pstats.Stats(filename[, stream=sys.stdout[, ...]])

このコンストラクタは filename で指定した (単一または複数の) ファイルから “統計情報オブジェクト”のインスタンスを生成します。 Stats オブジェクトはレポートを出力するメソッドを通じて操作します。また、他の出力ストリームをキーワード引数 stream で指定できます。

上記コンストラクタで指定するファイルは、使用する Stats に対応したバージョンの profile または cProfile で作成されたものでなければなりません。将来のバージョンのプロファイラとの互換性は 保証されておらず 、他のプロファイラとの互換性もないことに注意してください。複数のファイルを指定した場合、同一の関数の統計情報はすべて合算され、複数のプロセスで構成される全体をひとつのレポートで検証することが可能になります。既存の Stats オブジェクトに別のファイルの情報を追加するときは、 add() メソッドを使用します。

バージョン 2.5 で変更: stream 引数が追加されました.

26.4.4.1. Stats クラス

Stats には次のメソッドがあります。

Stats.strip_dirs()

Stats クラスのこのメソッドは、ファイル名の前に付いているすべてのパス情報を取り除くためのものです。出力の幅を80文字以内に収めたいときに重宝します。このメソッドはオブジェクトを変更するため、取り除いたパス情報は失われます。パス情報除去の操作後、オブジェクトが保持するデータエントリは、オブジェクトの初期化、ロード直後と同じように”ランダムに”並んでいます。 strip_dirs() を実行した結果、2つの関数名が区別できない (両者が同じファイルの同じ行番号で同じ関数名となった) 場合、一つのエントリに合算されされます。

Stats.add(filename[, ...])

Stats クラスのこのメソッドは、既存のプロファイリングオブジェクトに情報を追加します。引数は対応するバージョンの profile.run() または cProfile.run() によって生成されたファイルの名前でなくてはなりません。関数の名前が区別できない (ファイル名、行番号、関数名が同じ) 場合、一つの関数の統計情報として合算されます。

Stats.dump_stats(filename)

Stats オブジェクトに読み込まれたデータを、ファイル名 filename のファイルに保存します。ファイルが存在しない場合は新たに作成され、すでに存在する場合には上書きされます。このメソッドは profile.Profile クラスおよび cProfile.Profile クラスの同名のメソッドと等価です。

バージョン 2.3 で追加.

Stats.sort_stats(key[, ...])

このメソッドは Stats オブジェクトを指定した基準に従ってソートします。典型的には引数にソートのキーにしたい項目を示す文字列を指定します (例: 'time' や 'name' など)。

2つ以上のキーが指定された場合、2つ目以降のキーは、それ以前のキーで等価となったデータエントリの再ソートに使われます。たとえば sort_stats('name', 'file') とした場合、まずすべてのエントリが関数名でソートされた後、同じ関数名で複数のエントリがあればファイル名でソートされます。

キー名には他のキーと判別可能である限り綴りを省略して名前を指定できます。現在のバージョンで定義されているキー名は以下の通りです。

正式名 | 内容
'calls' | 呼び出し回数
'cumulative' | 累積時間
'file' | ファイル名
'module' | モジュール名
'pcalls' | プリミティブな呼び出し回数
'line' | 行番号
'name' | 関数名
'nfl' | 関数名/ファイル名/行番号
'stdname' | 標準名
'time' | 内部時間

すべての統計情報のソート結果は降順 (最も多く時間を消費したものが一番上に来る) となることに注意してください。ただし、関数名、ファイル名、行数に関しては昇順 (アルファベット順) になります。 'nfl' と 'stdname' には微妙な違いがあります。標準名 (standard name) とは表示された名前によるソートで、埋め込まれた行番号のソート順が特殊です。たとえば、 (ファイル名が同じで) 3、20、40という行番号のエントリがあった場合、20、3、40 の順に表示されます。一方 'nfl' は行番号を数値として比較します。要するに、 sort_stats('nfl') は sort_stats('name', 'file', 'line') と指定した場合と同じになります。

後方互換性のため、数値を引数に使った -1, 0, 1, 2 の形式もサポートしています。それぞれ 'stdname', 'calls', 'time', 'cumulative' として処理されます。引数をこの旧スタイルで指定した場合、最初のキー (数値キー) だけが使われ、複数のキーを指定しても2番目以降は無視されます。

Stats.reverse_order()

Stats クラスのこのメソッドは、オブジェクト内の情報のリストを逆順にソートします。デフォルトでは選択したキーに応じて昇順、降順が適切に選ばれることに注意してください。

Stats.print_stats([restriction, ...])

Stats クラスのこのメソッドは、 profile.run() の項で述べたプロファイルのレポートを出力します。

出力するデータの順序はオブジェクトに対し最後に行った sort_stats() による操作に基づきます (add() と strip_dirs() による制限にも支配されます)。

引数は (もし与えられると) リストを重要なエントリのみに制限するために使われます。初期段階でリストはプロファイルした関数の完全な情報を持っています。制限の指定は、 (行数を指定する) 整数、 (行のパーセンテージを指定する) 0.0 から 1.0 までの割合を指定する小数、 (出力する standard name にマッチする) 正規表現のいずれかを使って行います。正規表現は Python 1.5b1 で導入された re モジュールで使える Perl スタイルのものです。複数の制限が指定された場合、指定の順に適用されます。たとえば次のようになります。

print_stats(.1, 'foo:')

上記の場合まず出力するリストは全体の10%に制限され、さらにファイル名の一部に文字列 .*foo: を持つ関数だけが出力されます。

print_stats('foo:', .1)

こちらの例の場合、リストはまずファイル名に .*foo: を持つ関数だけに制限され、その中の最初の 10% だけが出力されます。

Stats.print_callers([restriction, ...])

Stats クラスのこのメソッドは、プロファイルのデータベースの中から何らかの関数呼び出しを行った関数をすべて出力します。出力の順序は print_stats() によって与えられるものと同じです。出力を制限する引数も同じです。各呼び出し側関数についてそれぞれ一行ずつ表示されます。フォーマットは統計を作り出したプロファイラごとに微妙に異なります。

profile の場合、呼び出し側関数の後に括弧で囲まれて表示される数値はその呼び出しが何回行われたかを示しています。利便性のため、 2番目の括弧なしで表示される数値によって、関数が消費した累積時間を表しています。

cProfile の場合、各呼び出し側関数の後に3つの数字が付きます。呼び出しが何回行われたかと、この呼び出し側関数からの呼び出しによって現在の関数内で消費された合計時間および累積時間です。

Stats.print_callees([restriction, ...])

Stats クラスのこのメソッドは、指定した関数から呼び出された関数のリストを出力します。呼び出し側、呼び出される側の方向は逆ですが、引数と出力の順序に関しては print_callers() と同じです。

26.4.5. 制限事項

一つの制限はタイミング情報の正確さに関するものです。決定論的プロファイラには正確さに関する根本的問題があります。最も明白な制限は、 (一般に) “クロック”は .001 秒の精度しかないということです。これ以上の精度で計測することはできません。仮に充分な精度が得られたとしても、”誤差”が計測の平均値に影響を及ぼすことがあります。この最初の誤差を取り除いたとしても、それがまた別の誤差を引き起こす原因となります。

もう一つの問題として、イベントを検知してからプロファイラがその時刻を実際に 取得 するまでに “いくらかの時間がかかる” ことです。同様に、イベントハンドラが終了する時にも、時刻を取得して (そしてその値を保存して) から、ユーザコードが処理を再開するまでの間に遅延が発生します。結果的に多く呼び出される関数または多数の関数から呼び出される関数の情報にはこの種の誤差が蓄積する傾向にあります。このようにして蓄積される誤差は、典型的にはクロックの精度を下回ります (1クロック以下) が、一方でこの時間が累計して非常に大きな値になることも あり得ます 。

この問題はオーバーヘッドの小さい cProfile よりも profile においてより重要です。そのため、 profile は誤差が確率的に (平均値で) 減少するようにプラットフォームごとに補正する機能を備えています。プロファイラに補正を施すと (最小二乗の意味で) 正確さが増しますが、ときには数値が負の値になってしまうこともあります (呼び出し回数が極めて少なく、確率の神があなたに意地悪をしたとき :-) )。プロファイルの結果に負の値が出力されても 驚かないでください 。これは補正を行った場合にのみ生じることで、補正を行わない場合に比べて計測結果は実際にはより正確になっているはずだからです。

26.4.6. キャリブレーション (補正)

profile のプロファイラは time 関数呼び出しおよびその値を保存するためのオーバーヘッドを補正するために、各イベントの処理時間から定数を引きます。デフォルトでこの定数の値は 0 です。以下の手順で、プラットフォームに合った、より適切な定数が得られます (前節「制限事項」の説明を参照)。

import profile
pr = profile.Profile()
for i in range(5):
    print pr.calibrate(10000)

calibrate メソッドは引数として与えられた数だけ Python の呼び出しを行います。直接呼び出す場合と、プロファイラを使って呼び出す場合の両方が実施され、それぞれの時間が計測されます。その結果、プロファイラのイベントに隠されたオーバーヘッドが計算され、その値は浮動小数として返されます。たとえば、 800 MHz の Pentium で Windows 2000 を使用、 Python の time.clock() をタイマとして使った場合、値はおよそ 12.5e-6 となります。

この手順で使用しているオブジェクトはほぼ一定の結果を返します。非常に 早いコンピュータを使う場合、もしくはタイマの性能が貧弱な場合は、一定の結果を得るために引数に 100000 や 1000000 といった大きな値を指定する必要があるかもしれません。

一定の結果が得られたら、それを使う方法には3通りあります。 [2]

import profile

# 1. 算出した補正値 (your_computed_bias) をこれ以降生成する
#    Profile インスタンスに適用する。
profile.Profile.bias = your_computed_bias

# 2. 特定の Profile インスタンスに補正値を適用する。
pr = profile.Profile()
pr.bias = your_computed_bias

# 3. インスタンスのコンストラクタに補正値を指定する。
pr = profile.Profile(bias=your_computed_bias)

選択肢がある場合は、補正値は小さめに設定した方が良いでしょう。プロファイルの結果に負の値が表われる”頻度が低く”なるはずです。

26.4.7. 拡張 — プロファイラの改善

profile モジュールおよび cProfile モジュールの Profile クラスは、プロファイラの機能を拡張するために派生クラスを作成することを前提に書かれています。しかしその方法を説明するには、 Profile の内部動作について詳細な解説が必要となるため、ここでは述べません。もし拡張を行いたいのであれば、使用するモジュールのソースを注意深く読む必要があります。

プロファイラが時刻を取得する方法を変更したいだけなら (たとえば、実測時間やプロセスの経過時間を使いたい場合)、時刻取得用の関数を Profile クラスのコンストラクタに指定することができます。

pr = profile.Profile(your_time_func)

この結果生成されるプロファイラは時刻取得に your_time_func() を呼び出すようになります。

profile.Profile

your_time_func() は単一の数値、あるいは (os.times() と同じように) その合計が累計時間を示すリストを返すようになっていなければなりません。関数が1つの数値、あるいは長さ2の数値のリストを返すようになっていれば、ディスパッチルーチンには特別な高速化バージョンが使われます。

選択する時刻取得関数によって、プロファイラクラスを補正する必要があることに注意してください。多くのマシンにおいて、プロファイル時のオーバヘッドを少なくする方法として、タイマは長整数を返すのが最善です (os.times() は浮動小数のタプルを返すので おすすめできません)。タイマをより正確なものに置き換えたいならば、派生クラスでそのディスパッチメソッドを適切なタイマ呼び出しと適切な補正を行うように書き直す必要があります。

cProfile.Profile

your_time_func() は単一の数値を返さなければなりません。もしこれが整数を返す関数ならば、2番目の引数に単位時間当たりの実際の持続時間を指定してクラスのコンスタラクタを呼び出すことができます。たとえば、 your_integer_time_func() が1000分の1秒単位で計測した時間を返すとすると、 Profile インスタンスを次のように生成することができます。

pr = profile.Profile(your_integer_time_func, 0.001)

cProfile.Profile クラスはキャリブレーションができないので、自前のタイマ関数は注意を払って使う必要があり、またそれは可能な限り速くなければなりません。自前のタイマ関数で最高の結果を得るには、 _lsprof 内部モジュールの C ソースファイルにハードコードする必要があるかもしれません。

注記

[1]
アップデートと LaTeX への変換は Guido van Rossum によるもの。さらに Python 2.5 の新しい cProfile モジュールの文書を統合するアップデートは Armin Rigo による。

[2]
Python 2.2 より前のバージョンではプロファイラのソースコードに補正値として埋め込まれた定数を直接編集する必要がありました。今でも同じことは可能ですが、その方法は説明しません。なぜなら、もうソースを編集する必要がないからです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.5. hotshot — ハイパフォーマンス・ロギング・プロファイラ

バージョン 2.2 で追加.

このモジュールは _hotshot C モジュールへのより良いインターフェースを提供します。Hotshot は既存の profile に置き換わるものです。その大半が C で書かれているため、 profile に比べパフォーマンス上の影響がはるかに少なく済みます。

ノート

hotshot は C モジュールでプロファイル中のオーバーヘッドを極力小さくすることに焦点を絞っており、その代わりに後処理時間の長さというつけを払います。通常の使用法についてはこのモジュールではなく cProfile を使うことを推奨します。 hotshot は保守されておらず、将来的には標準ライブラリから外されるかもしれません。

バージョン 2.5 で変更: 以前より意味のある結果が得られているはずです。かつては時間計測の中核部分に致命的なバグがありました.

ノート

hotshot プロファイラはまだスレッド環境ではうまく動作しません。測定したいコード上でプロファイラを実行するためにスレッドを使わない版のスクリプトを使う方法が有用です。

class hotshot.Profile(logfile[, lineevents[, linetimings]])

プロファイラ・オブジェクト。引数 logfile はプロファイル・データのログを保存するファイル名です。引数 lineevents はソースコードの1 行ごとにイベントを発生させるか、関数の呼び出し/リターンのときだけ発生させるかを指定します。デフォルトの値は 0 (関数の呼び出し/ リターンのときだけログを残す)です。引数 linetimings は時間情報を記録するかどうかを指定します。デフォルトの値は 1 (時間情報を記録する)です。

26.5.1. プロファイル・オブジェクト

プロファイル・オブジェクトは以下のメソッドを持っています。

Profile.addinfo(key, value)

プロファイル出力の際、任意のラベル名を追加します。

Profile.close()

ログファイルを閉じ、プロファイラを終了します。

Profile.fileno()

プロファイラのログファイルのファイル・ディスクリプタを返します。

Profile.run(cmd)

スクリプト環境で exec 互換文字列のプロファイルをおこないます。 __main__ モジュールのグローバル変数は、スクリプトのグローバル変数、ローカル変数の両方に使われます。

Profile.runcall(func, *args, **keywords)

単一の呼び出し可能オブジェクトのプロファイルをおこないます。位置依存引数やキーワード引数を追加して呼び出すオブジェクトに渡すこともできます。呼び出しの結果はそのまま返されます。例外が発生したときはプロファイリングが無効になり、例外をそのまま伝えるようになっています。

Profile.runctx(cmd, globals, locals)

指定した環境で exec 互換文字列の評価をおこないます。文字列のコンパイルはプロファイルを開始する前におこなわれます。

Profile.start()

プロファイラを開始します。

Profile.stop()

プロファイラを停止します。

26.5.2. hotshot データの利用

バージョン 2.2 で追加.

このモジュールは hotshot プロファイル・データを標準の pstats オブジェクトにロードします。

hotshot.stats.load(filename)

filename から hotshot データを読み込み、 pstats.Stats クラスのインスタンスを返します。

参考

Module profile

profile モジュールの Stats クラス

26.5.3. 使用例

これは Python の”ベンチマーク” pystone を使った例です。実行にはやや時間がかかり、巨大な出力ファイルを生成するので注意してください。

>>> import hotshot, hotshot.stats, test.pystone
>>> prof = hotshot.Profile("stones.prof")
>>> benchtime, stones = prof.runcall(test.pystone.pystones)
>>> prof.close()
>>> stats = hotshot.stats.load("stones.prof")
>>> stats.strip_dirs()
>>> stats.sort_stats('time', 'calls')
>>> stats.print_stats(20)
         850004 function calls in 10.090 CPU seconds

   Ordered by: internal time, call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    3.295    3.295   10.090   10.090 pystone.py:79(Proc0)
   150000    1.315    0.000    1.315    0.000 pystone.py:203(Proc7)
    50000    1.313    0.000    1.463    0.000 pystone.py:229(Func2)
 .
 .
 .

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.6. timeit — 小さなコード断片の実行時間計測

バージョン 2.3 で追加.

このモジュールは Python の小さなコード断片の時間を簡単に計測する手段を提供します。インターフェースはコマンドラインとメソッドとして呼び出し可能なものの両方を備えています。また、このモジュールは実行時間の計測にあたり陥りがちな落し穴に対する様々な対策が取られています。詳しくは、 O’Reilly の Python Cookbook、”Algorithms” の章にある Tim Peters が書いた解説を参照してください。

このモジュールには次のパブリック・クラスが定義されています。

class timeit.Timer([stmt='pass'[, setup='pass'[, timer=<timer function>]]])

小さなコード断片の実行時間計測をおこなうためのクラスです。

コンストラクタは引数として、時間計測の対象となる文、セットアップに使用する追加の文、タイマ関数を受け取ります。文のデフォルト値は両方とも 'pass' で、タイマ関数はプラットフォーム依存(モジュールの doc string を参照)です。 stmt と setup は複数行の文字列リテラルを含まない限り、改行や ; で区切られた複数の文を入れることができます。

最初の文の実行時間を計測には timeit() メソッドを使用します。また timeit() を複数回呼び出し、その結果のリストを返す repeat() メソッドも用意されています。

バージョン 2.6 で変更: stmt と setup 引数は、引数なしで呼び出し可能なオブジェクトを受け取れるようになりました。呼び出し可能オブジェクトを利用すると、 timeit() メソッドから実行されるときに、タイマーの中で指定されたオブジェクトの呼び出しを行ないます。この場合、関数呼び出しが増えるために、オーバーヘッドが少し増えることに注意してください。

Timer.print_exc([file=None])

計測対象コードのトレースバックを出力するためのヘルパー。

利用例:

t = Timer(...)       # try/except の外側で
try:
    t.timeit(...)    # または t.repeat(...)
except:
    t.print_exc()

標準のトレースバックより優れた点は、コンパイルしたテンプレートのソース行が表示されることです。オプションの引数 file にはトレースバックの出力先を指定します。デフォルトは sys.stderr になっています。

Timer.repeat([repeat=3[, number=1000000]])

timeit() を複数回呼び出します。

このメソッドは timeit() を複数回呼び出し、その結果をリストで返すユーティリティ関数です。最初の引数には timeit() を呼び出す回数を指定します。2番目の引数は timeit() へ引数として渡す 数値 です。

ノート

結果のベクトルから平均値や標準偏差を計算して出力させたいと思うかもしれませんが、それはあまり意味がありません。多くの場合、最も低い値がそのマシンが与えられたコード断片を実行する場合の下限値です。結果のうち高めの値は、Python のスピードが一定しないために生じたものではなく、時刻取得の際他のプロセスと衝突がおこったため、正確さが損なわれた結果生じたものです。したがって、結果のうち min() だけが見るべき値となります。この点を押さえた上で、統計的な分析よりも常識的な判断で結果を見るようにしてください。

Timer.timeit([number=1000000])

メイン文の実行時間を number 回取得します。このメソッドはセットアップ文を1回だけ実行し、メイン文を指定回数実行するのにかかった秒数を浮動小数で返します。引数はループを何回実行するかの指定で、デフォルト値は 100万回です。メイン文、セットアップ文、タイマ関数はコンストラクタで指定されたものを使用します。

ノート

デフォルトでは、 timeit() は時間計測中、一時的にガーベッジコレクション(garbage collection)を切ります。このアプローチの利点は、個別の測定結果を比較しやすくなることです。不利な点は、GC が測定している関数のパフォーマンスの重要な一部かもしれないということです。そうした場合、 setup 文字列の最初の文で GC を再度有効にすることができます。例えば

timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()

Python 2.6 から、このモジュールに2つの便利関数が追加されました。

timeit.repeat(stmt[, setup[, timer[, repeat=3[, number=1000000]]]])

指定された stmt, setup, timer を使って Timer インスタンスを作成し、指定された repeat, number を使ってその repeat() メソッドを実行します。

バージョン 2.6 で追加.

timeit.timeit(stmt[, setup[, timer[, number=1000000]]])

指定された stmt, setup, timer を使って Timer インスタンスを作成し、指定された number を使ってその timeit() メソッドを実行します。

バージョン 2.6 で追加.

26.6.1. コマンドライン・インターフェース

コマンドラインからプログラムとして呼び出す場合は、次の書式を使います。

python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]

以下のオプションが使用できます。

-n N, --number=N

‘statement’ を何回実行するか

-r N, --repeat=N

タイマを何回リピートするか(デフォルトは 3)

-s S, --setup=S

最初に1回だけ実行する文 (デフォルトは pass)

-t, --time

time.time() を使用する (Windows を除くすべてのプラットフォームのデフォルト)

-c, --clock

time.clock() を使用する(Windows のデフォルト)

-v, --verbose

時間計測の結果をそのまま詳細な数値でくり返し表示する

-h, --help

簡単な使い方を表示して終了する

文は複数行指定することもできます。その場合、各行は独立した文として引数に指定されたものとして処理します。クォートと行頭のスペースを使って、インデントした文を使うことも可能です。この複数行のオプションは -s においても同じ形式で指定可能です。

オプション -n でループの回数が指定されていない場合、10回から始めて、所要時間が 0.2 秒になるまで回数を増やすことで適切なループ回数が自動計算されるようになっています。

デフォルトのタイマ関数はプラットフォーム依存です。Windows の場合、 time.clock() はマイクロ秒の精度がありますが、 time.time() は 1/60 秒の精度しかありません。一方 Unixの場合、 time.clock() でも 1/100 秒の精度があり、 time.time() はもっと正確です。いずれのプラットフォームにおいても、デフォルトのタイマ関数は CPU 時間ではなく通常の時間を返します。つまり、同じコンピュータ上で別のプロセスが動いている場合、タイミングの衝突する可能性があるということです。正確な時間を割り出すために最善の方法は、時間の取得を数回くり返しその中の最短の時間を採用することです。 -r オプションはこれをおこなうもので、デフォルトのくり返し回数は3回になっています。多くの場合はデフォルトのままで充分でしょう。 Unixの場合 time.clock() を使って CPU 時間で測定することもできます。

ノート

pass 文の実行による基本的なオーバーヘッドが存在することに注意してください。ここにあるコードはこの事実を隠そうとはしておらず、注意を払う必要があります。基本的なオーバーヘッドは引数なしでプログラムを起動することにより計測できます。

基本的なオーバヘッドは Python のバージョンによって異なります。 Python 2.3 とそれ以前の Python の公平な比較をおこなう場合、古い方の Python は -O オプションで起動し SET_LINENO 命令の実行時間が含まれないようにする必要があります。

26.6.2. 使用例

以下に2つの使用例を記載します (ひとつはコマンドライン・インターフェースによるもの、もうひとつはモジュール・インターフェースによるものです)。内容はオブジェクトの属性の有無を調べるのに hasattr() を使った場合と try / except を使った場合の比較です。

% timeit.py 'try:' '  str.__nonzero__' 'except AttributeError:' '  pass'
100000 loops, best of 3: 15.7 usec per loop
% timeit.py 'if hasattr(str, "__nonzero__"): pass'
100000 loops, best of 3: 4.26 usec per loop
% timeit.py 'try:' '  int.__nonzero__' 'except AttributeError:' '  pass'
1000000 loops, best of 3: 1.43 usec per loop
% timeit.py 'if hasattr(int, "__nonzero__"): pass'
100000 loops, best of 3: 2.23 usec per loop

>>> import timeit
>>> s = """\
... try:
...     str.__nonzero__
... except AttributeError:
...     pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
17.09 usec/pass
>>> s = """\
... if hasattr(str, '__nonzero__'): pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
4.85 usec/pass
>>> s = """\
... try:
...     int.__nonzero__
... except AttributeError:
...     pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
1.97 usec/pass
>>> s = """\
... if hasattr(int, '__nonzero__'): pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
3.15 usec/pass

定義した関数に timeit モジュールがアクセスできるようにするために、 import 文の入った setup 引数を渡すことができます:

def test():
    "Stupid test function"
    L = []
    for i in range(100):
        L.append(i)

if __name__=='__main__':
    from timeit import Timer
    t = Timer("test()", "from __main__ import test")
    print t.timeit()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

26. デバッグとプロファイル »

26.7. trace — Python ステートメント実行のトレースと追跡

trace モジュールはプログラム実行のトレースを可能にし、 generate ステートメントのカバレッジリストを注釈付きで生成して、呼び出し元/呼び出し先の関連やプログラム実行中に実行された関数のリストを出力します。これは別個のプログラム中またはコマンドラインから利用することができます。

参考

最新バージョンの trace module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/trace.py?view=markup]

26.7.1. コマンドラインからの利用

trace モジュールはコマンドラインから起動することができます。これは次のように単純です。

python -m trace --count -C . somefile.py ...

これで、 somefile.py の実行中に import された Python モジュールの注釈付きリストがカレントディレクトリに生成されます。

--help

使い方を表示して終了します。

--version

モジュールのバージョンを表示して終了します。

26.7.1.1. 主要なオプション

trace を実行する時、以下のオプションのうち少なくとも1つを指定しなければなりません。 --listfuncs オプションは --trace および --counts オプションと互いに排他的です。つまり --listfuncs オプションを指定した場合 --trace や --counts は指定できず、逆も然りです。

-c, --count

プログラム完了時に、それぞれのステートメントが何回実行されたかを示す注釈付きリストのファイルを生成します。下記の --coverdir, --file, --no-report も参照。

-t, --trace

実行されるままに行を表示します。

-l, --listfuncs

プログラム実行の際に実行された関数を表示します。

-r, --report

--count と --file 引数を使った、過去のプログラム実行結果から注釈付きリストのファイルを生成します。コードを実行するわけではありません。

-T, --trackcalls

プログラム実行によって明らかになった呼び出しの関連を表示します。

26.7.1.2. 修飾的オプション

-f, --file=<file>

複数回にわたるトレース実行についてカウント(count)を蓄積するファイルに名前をつけます。 --count オプションと一緒に使って下さい。

-C, --coverdir=<dir>

レポートファイルを保存するディレクトリを指定します。 package.module についてのカバレッジレポートは dir/package/module.cover に書き込まれます。

-m, --missing

注釈付きリストの生成時に、実行されなかった行に >>>>>> の印を付けます。

-s, --summary

--count または --report の利用時に、処理されたファイルそれぞれの簡潔なサマリを標準出力(stdout)に書き出します。

-R, --no-report

注釈付きリストを生成しません。これは --count を何度か走らせてから最後に単一の注釈付きリストを生成するような場合に便利です。

-g, --timing

各行の先頭にプログラム開始からの時間を付けます。トレース中にだけ使われます。

26.7.1.3. フィルターオプション

これらのオプションは複数回指定できます。

--ignore-module=<mod>

指定されたモジュールと（パッケージだった場合は）そのサブモジュールを無視します。引数はカンマ区切りのモジュール名リストです。

--ignore-dir=<dir>

指定されたディレクトリとサブディレクトリ中のモジュールとパッケージを全て無視します。引数は os.pathsep で区切られたディレクトリのリストです。

26.7.2. プログラミングインターフェース

class trace.Trace([count=1[, trace=1[, countfuncs=0[, countcallers=0[, ignoremods=()[, ignoredirs=()[, infile=None[, outfile=None[, timing=False]]]]]]]]])

文(statement)や式(expression)の実行をトレースするオブジェクトを作成します。全てのパラメタがオプションです。 count は行数を数えます。 trace は行実行のトレースを行います。 countfuncs は実行中に呼ばれた関数を列挙します。 countcallers は呼び出しの関連の追跡を行います。 ignoremods は無視するモジュールやパッケージのリストです。 ignoredirs は無視するパッケージやモジュールを含むディレクトリのリストです。 infile は保存された集計(count)情報を読むファイルの名前です。 outfile は更新された集計(count)情報を書き出すファイルの名前です。 timing は、タイムスタンプをトレース開始時点からの相対秒数で表示します。

run(cmd)

コマンドを実行して、現在のトレースパラメータに基づいてその実行から統計情報を集めます。 cmd は、 exec() に渡せるような文字列か code オブジェクトです。

runctx(cmd[, globals=None[, locals=None]])

指定された globals と locals 環境下で、コマンドを実行して、現在のトレースパラメータに基づいてその実行から統計情報を集めます。 cmd は、 exec() に渡せるような文字列か code オブジェクトです。定義しない場合、 globals と locals はデフォルトで空の辞書となります。

runfunc(func, *args, **kwds)

与えられた引数の func を、 Trace オブジェクトのコントロール下で現在のトレースパラメタのもとに呼び出します。

results()

与えられた Trace インスタンスの run, runctx, runfunc の以前の呼び出しについて集計した結果を納めた CoverageResults オブジェクトを返します。蓄積されたトレース結果はリセットしません。

class trace.CoverageResults

カバレッジ結果のコンテナで、 Trace.results() で生成されるものです。ユーザーが直接生成するものではありません。

update(other)

別の CoverageResults オブジェクトのデータを統合します。

write_results([show_missing=True[, summary=False[, coverdir=None]]])

カバレッジ結果を書き出します。ヒットしなかった行も出力するには show_missing を指定します。モジュールごとのサマリーを出力に含めるには summary を指定します。 coverdir に指定するのは結果ファイルを出力するディレクトリです。 None の場合は各ソースファイルごとの結果がそれぞれのディレクトリに置かれます。

簡単な例でプログラミングインターフェースの使い方を見てみましょう

import sys
import trace

# Trace オブジェクトを、無視するもの、トレースや行カウントのいずれか
# または両方を行うか否かを指定して作成します。
tracer = trace.Trace(
    ignoredirs=[sys.prefix, sys.exec_prefix],
    trace=0,
    count=1)

# 与えられたトレーサを使って、コマンドを実行します。
tracer.run('main()')

# 出力先を /tmp としてレポートを作成します。
r = tracer.results()
r.write_results(show_missing=True, coverdir="/tmp")

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス

この章では、 Python インタープリタや Python 環境に深く関連する各種の機能を解説します。以下に一覧を示します:

27.1. sys — システムパラメータと関数

27.2. sysconfig — Python の構成情報にアクセスする

27.2.1. 構成変数

27.2.2. インストールパス

27.2.3. その他の関数

27.3. __builtin__ — 組み込みオブジェクト

27.4. future_builtins — Python 3 のビルトイン

27.5. __main__ — トップレベルのスクリプト環境

27.6. warnings — 警告の制御

27.6.1. 警告カテゴリ

27.6.2. 警告フィルタ

27.6.2.1. デフォルトの警告フィルタ

27.6.3. 一時的に警告を抑制する

27.6.4. 警告のテスト

27.6.5. コードを新しいバージョンの Python のために更新する

27.6.6. 利用可能な関数

27.6.7. 利用可能なコンテキストマネージャー

27.7. contextlib — with -構文コンテキストのためのユーティリティ

27.8. abc — 抽象基底クラス

27.9. atexit — 終了ハンドラ

27.9.1. atexit の例

27.10. traceback — スタックトレースの表示または取得

27.10.1. トレースバックの例

27.11. __future__ — future 文の定義

27.12. gc — ガベージコレクタインターフェース

27.13. inspect — 活動中のオブジェクトの情報を取得する

27.13.1. 型とメンバー

27.13.2. ソースコードの情報取得

27.13.3. クラスと関数

27.13.4. インタープリタスタック

27.14. site — サイト固有の設定フック

27.15. user — ユーザー設定のフック

27.16. fpectl — 浮動小数点例外の制御

27.16.1. 例

27.16.2. 制限と他に考慮すべきこと

27.17. distutils — Python モジュールの構築とインストール

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.1. sys — システムパラメータと関数

このモジュールでは、インタープリタで使用・管理している変数や、インタープリタの動作に深く関連する関数を定義しています。このモジュールは常に利用可能です。

sys.argv

Pythonスクリプトに渡されたコマンドライン引数のリスト。 argv[0] はスクリプトの名前となりますが、フルパス名かどうかは、OSによって異なります。コマンドライン引数に -c を付けて Pythonを起動した場合、 argv[0] は文字列 '-c' となります。スクリプト名なしでPythonを起動した場合、 argv[0] は空文字列になります。

標準入力もしくはコマンドライン引数で指定されたファイルのリストに渡ってループするには、 fileinput モジュールを参照してください。

sys.byteorder

プラットフォームのバイト順を示します。ビッグエンディアン (最上位バイトが先頭) のプラットフォームでは 'big', リトルエンディアン (最下位バイトが先頭) では 'little' となります。

バージョン 2.0 で追加.

sys.subversion

3つ組 (repo, branch, version) で Python インタプリタの Subversion 情報を表します。 repo はリポジトリの名前で、 'CPython' 。 branch は 'trunk', 'branches/name' または 'tags/name' のいずれかの形式の文字列です。 version はもしインタプリタが Subversion のチェックアウトからビルドされたものならば svnversion の出力であり、リビジョン番号 (範囲) とローカルでの変更がある場合には最後に ‘M’ が付きます。ツリーがエクスポートされたもの (または svnversion が取得できない) で、 branch がタグならば Include/patchlevel.h のリビジョンになります。それ以外の場合には None です。

バージョン 2.5 で追加.

sys.builtin_module_names

コンパイル時にPythonインタープリタに組み込まれた、全てのモジュール名のタプル(この情報は、他の手段では取得することができません。 modules.keys() は、インポートされたモジュールのみのリストを返します。)

sys.call_tracing(func, args)

トレーシングが有効な間、 func(*args) を呼び出します。トレーシングの状態は保存され、後で復元されます。これは、別のコードをチェックポイントから再帰的にデバッグするために、デバッガから呼び出されることを意図しています。

sys.copyright

Pythonインタープリタの著作権を表示する文字列。

sys._clear_type_cache()

内部の型キャッシュをクリアします。型キャッシュは属性とメソッドの検索を高速化するために利用されます。この関数は、参照リークをデバッグするときに不要な参照を削除するため だけ に利用してください。

この関数は、内部的かつ特殊な目的にのみ利用されるべきです。

バージョン 2.6 で追加.

sys._current_frames()

各スレッドの識別子を関数が呼ばれた時点のそのスレッドでアクティブになっている一番上のスタックフレームに結びつける辞書を返します。モジュール traceback の関数を使えばそのように与えられたフレームのコールスタックを構築できます。

この関数はデッドロックをデバッグするのに非常に有効です。デッドロック状態のスレッドの協調動作を必要としませんし、そういったスレッドのコールスタックはデッドロックである限り凍り付いたままです。デッドロックにないスレッドのフレームについては、そのフレームを調べるコードを呼んだ時にはそのスレッドの現在の実行状況とは関係ないところを指し示しているかもしれません。

この関数は外部に見せない特別な目的でのみ使われるべきです。

バージョン 2.5 で追加.

sys.dllhandle

Python DLLのハンドルを示す整数。利用可能: Windows

sys.displayhook(value)

value が None 以外の場合、 value を sys.stdout に出力して __builtin__._ に保存します。

sys.displayhook は、Pythonの対話セッションで入力された式(expression)が評価されたときに呼び出されます。対話セッションの出力をカスタマイズする場合、 sys.displayhook に引数の数が一つの関数を指定します。

sys.excepthook(type, value, traceback)

指定したトレースバックと例外を sys.stderr に出力します。

例外が発生し、その例外が捕捉されない場合、インタープリタは例外クラス・例外インスタンス・トレースバックオブジェクトを引数として sys.excepthook を呼び出します。対話セッション中に発生した場合はプロンプトに戻る直前に呼び出され、Pythonプログラムの実行中に発生した場合はプログラムの終了直前に呼び出されます。このトップレベルでの例外情報出力処理をカスタマイズする場合、 sys.excepthook に引数の数が三つの関数を指定します。

sys.__displayhook__

sys.__excepthook__

それぞれ、起動時の displayhook と excepthook の値を保存しています。この値は、 displayhook と excepthook に不正なオブジェクトが指定された場合に、元の値に復旧するために使用します。

sys.exc_info()

この関数は、現在処理中の例外を示す三つの値のタプルを返します。この値は、現在のスレッド・現在のスタックフレームのものです。現在のスタックフレームが例外処理中でない場合、例外処理中のスタックフレームが見つかるまで次々とその呼び出し元スタックフレームを調べます。ここで、”例外処理中” とは “except 節を実行中、または実行した” フレームを指します。どのスタックフレームでも、最後に処理した例外の情報のみを参照することができます。

スタック上で例外が発生していない場合、三つの None のタプルを返します。例外が発生している場合、 (type, value, traceback) を返します。 type は、処理中の例外の型を示します (クラスオブジェクト)。 value は、例外パラメータ (例外に 関連する値 または raise の第二引数。 type がクラスオブジェクトの場合は常にクラスインスタンス) です。 traceback は、トレースバックオブジェクトで、例外が発生した時点でのコールスタックをカプセル化したオブジェクトです(リファレンスマニュアル参照)。

exc_clear() が呼び出されると、現在のスレッドで他の例外が発生するか、又は別の例外を処理中のフレームに実行スタックが復帰するまで、 exc_info() は三つの None を返します。

警告

例外処理中に戻り値の traceback をローカル変数に代入すると循環参照が発生し、関数内のローカル変数やトレースバックが参照している全てのオブジェクトは解放されなくなります。特にトレースバック情報が必要ではなければ exctype, value = sys.exc_info()[:2] のように例外型と例外オブジェクトのみを取得するようにして下さい。もしトレースバックが必要な場合には、処理終了後にdeleteして下さい。このdeleteは、 try ... finally ...で行うと良いでしょう。

ノート

Python 2.2 以降では、ガベージコレクションが有効であればこのような到達不能オブジェクトは自動的に削除されます。しかし、循環参照を作らないようにしたほうが効率的です。

sys.exc_clear()

この関数は、現在のスレッドで処理中、又は最後に発生した例外の情報を全てクリアします。この関数を呼び出すと、現在のスレッドで他の例外が発生するか、又は別の例外を処理中のフレームに実行スタックが復帰するまで、 exc_info() は三つの None を返します。

この関数が必要となることは滅多にありません。ロギングやエラー処理などで最後に発生したエラーの報告を行う場合などに使用します。また、リソースを解放してオブジェクトの終了処理を起動するために使用することもできますが、オブジェクトが実際にされるかどうかは保障の限りではありません。

バージョン 2.3 で追加.

sys.exc_type

sys.exc_value

sys.exc_traceback

バージョン 1.5 で撤廃: exc_info() を使用してください

これらの変数はグローバル変数なのでスレッド毎の情報を示すことができません。この為、マルチスレッドなプログラムでは安全に参照することはできません。例外処理中でない場合、 exc_type の値は None となり、 exc_value と exc_traceback は未定義となります。

sys.exec_prefix

Python のプラットフォーム依存なファイルがインストールされているディレクトリ名(サイト固有)。デフォルトでは、この値は '/usr/local' ですが、ビルド時に configure の --exec-prefix 引数で指定することができます。全ての設定ファイル(pyconfig.h など)は exec_prefix + '/lib/pythonversion/config' に、共有ライブラリは exec_prefix + '/lib/pythonversion/lib-dynload' にインストールされます (但し version は version[:3])。

sys.executable

Python インタープリタの実行ファイルの名前を示す文字列。このような名前が意味を持つシステムでは利用可能。

sys.exit([arg])

Python を終了します。 exit() は SystemExit を送出するので、 try ステートメントの finally 節に終了処理を記述したり、上位レベルで例外を捕捉して exit 処理を中断したりすることができます。

オプション引数 arg には、終了ステータスとして整数(デフォルトは0）または整数以外の型のオブジェクトを指定することができます。整数を指定した場合、シェル等は 0 は”正常終了”、 0 以外の整数を”異常終了”として扱います。多くのシステムでは、有効な終了ステータスは 0-127 で、これ以外の値を返した場合の動作は未定義です。システムによっては特定の終了コードに個別の意味を持たせている場合がありますが、このような定義は僅かしかありません。 Unix プログラムでは文法エラーの場合には 2 を、それ以外のエラーならば 1 を返します。 arg に None を指定した場合は、数値の 0 を指定した場合と同じです。それ以外のオブジェクトを指定すると、そのオブェクトが sys.stderr に出力され、終了コードとして 1 を返します。エラー発生時には sys.exit("エラーメッセージ") と書くと、簡単にプログラムを終了することができます。

究極には、 exit() は例外を送出する “だけ” なので、これがメインスレッドから呼び出されたときは、プロセスを終了するだけで、例外は遮断されません。

sys.exitfunc

この値はモジュールに存在しませんが、ユーザプログラムでプログラム終了時に呼び出される終了処理関数として、引数の数が 0 の関数を設定することができます。この関数は、インタープリタ終了時に呼び出されます。 exitfunc に指定することができる終了処理関数は一つだけですので、複数のクリーンアップ処理が必要な場合は atexit モジュールを使用してください。

ノート

プログラムがシグナルで kill された場合、 Python 内部で致命的なエラーが発生した場合、 os._exit() が呼び出された場合には、終了処理関数は呼び出されません。

バージョン 2.4 で撤廃: atexit を使ってください。

sys.flags

属性とシーケンスを利用して、コマンドラインフラグの状態を提供しています。属性は読み込み専用になっています。

属性 | フラグ
debug | -d
py3k_warning | -3
division_warning | -Q
division_new | -Qnew
inspect | -i
interactive | -i
optimize | -O or -OO
dont_write_bytecode | -B
no_user_site | -s
no_site | -S
ignore_environment | -E
tabcheck | -t or -tt
verbose | -v
unicode | -U
bytes_warning | -b

バージョン 2.6 で追加.

sys.float_info

属性とシーケンスを利用して、 float 型に関する情報を提供します。精度と内部表現に関する情報を含みます。プログラミング言語 ‘C’ の標準ヘッダファイル float.h に定義された様々な浮動小数点定数に対応する値の詳細については、1999 ISO/IEC C standard [C99] の 4.2.4.2.2 章を参照して下さい。

属性 | float.h のマクロ | 説明
epsilon | DBL_EPSILON | 1と、その次の表現可能なfloat値の差
dig | DBL_DIG | 浮動小数点数で正確に表示できる最大の10進数桁; 以下参照
mant_dig | DBL_MANT_DIG | 浮動小数点精度: 浮動小数点数の主要部の桁 base-radix
max | DBL_MAX | floatが表せる最大の(infiniteではない)値
max_exp | DBL_MAX_EXP | floatが radix**(e-1) で表現可能な、最大の整数 e
max_10_exp | DBL_MAX_10_EXP | floatが 10**e で表現可能な、最大の整数 e
min | DBL_MIN | floatが表現可能な最小の正の値
min_exp | DBL_MIN_EXP | radix**(e-1) が正規化floatであるような最小の整数 e
min_10_exp | DBL_MIN_10_EXP | 10**e が正規化floatであるような最小の整数 e
radix | FLT_RADIX | 指数部の基数
rounds | FLT_ROUNDS | 算術演算で利用される丸めモードを表す定数

sys.float_info.dig に対してはさらに説明が必要です。もし、文字列 s が表す 10進数の有効桁数がたかだか sys.float_info.dig のときには、 s を浮動小数点数に変換して戻すと同じ10進数

>>> import sys
>>> sys.float_info.dig
15
>>> s = '3.14159265358979'    # decimal string with 15 significant digits
>>> format(float(s), '.15g')  # convert to float and back -> same value
'3.14159265358979'

ただ、文字列が有効桁数 sys.float_info.dig より多い場合には、常に復元されるとは限りません:

 >>> s = '9876543211234567'    # 16 significant digits is too many!
 >>> format(float(s), '.16g')  # conversion changes value
'9876543211234568'

バージョン 2.6 で追加.

sys.float_repr_style

repr() 関数が浮動小数点数に対してどう振る舞うかを指し示す文字列です。この文字列が値 'short' を持てば、有限の浮動小数点数 x に対して、 repr(x) は float(repr(x)) == x を満たす短い文字列を返そうとします。これは、 Python 2.7 以降での標準の振る舞いです。そうでなければ、 float_repr_style は値 'legacy' を持ち、 repr(x) は 2.7 以前のバージョンの Python と同じように振る舞います。

バージョン 2.7 で追加.

sys.getcheckinterval()

インタプリタの “チェックインターバル (check interval)” を返します; setcheckinterval() を参照してください。

バージョン 2.3 で追加.

sys.getdefaultencoding()

現在の Unicode 処理のデフォルトエンコーディング名を返します。

バージョン 2.0 で追加.

sys.getdlopenflags()

dlopen() で指定されるフラグを返します。このフラグは dl と DLFCN で定義されています。

利用可能: Unix.

バージョン 2.2 で追加.

sys.getfilesystemencoding()

Unicode ファイル名をシステムのファイル名に変換する際に使用するエンコード名を返します。システムのデフォルトエンコーディングを使用する場合には None を返します。

Mac OS X では、エンコーディングは utf-8 となります。

Unix では、エンコーディングは nl_langinfo(CODESET) が返すユーザの設定となります。 nl_langinfo(CODESET) が失敗すると None を返します。

Windows NT+ では、 Unicode をファイル名として使用できるので変換の必要はありません。 getfilesystemencoding() は 'mbcs' を返しますが、これはある Unicode 文字列をバイト文字列に明示的に変換して、ファイル名として使うと同じファイルを指すようにしたい場合に、アプリケーションが使わねばならないエンコーディングです。

Windows 9x では、エンコーディングは “mbcs” となります。

バージョン 2.3 で追加.

sys.getrefcount(object)

object の参照数を返します。 object は(一時的に) getrefcount() からも参照されるため、参照数は予想される数よりも 1 多くなります。

sys.getrecursionlimit()

現在の最大再帰数を返します。最大再帰数は、Python インタープリタスタックの最大の深さです。この制限は Python プログラムが無限に再帰し、C スタックがオーバーフローしてクラッシュすることを防止するために設けられています。この値は setrecursionlimit() で指定することができます。

sys.getsizeof(object[, default])

object のサイズをバイト数で返します。 object は任意の型のオブジェクトです。全てのビルトイン型は正しい値を返します。サードパーティー製の型については実装依存になります。

default 引数が与えられると、オブジェクト型がサイズを取得する手段を提供していない場合に返されます。与えられてない場合には TypeError 例外が発生します。

getsizeof() は object の __sizeof__ メソッドを呼び出し、そのオブジェクトがガベージコレクタに管理されていた場合はガベージコレクタのオーバーヘッドを増やします。

バージョン 2.6 で追加.

sys._getframe([depth])

コールスタックからフレームオブジェクトを取得します。オプション引数 depth を指定すると、スタックのトップから depth だけ下のフレームオブジェクトを取得します。 depth がコールスタックよりも深ければ、 ValueError が発生します。 depth のデフォルト値は 0 で、この場合はコールスタックのトップのフレームを返します。

CPython implementation detail: この関数は、内部的な、特殊な用途にのみ利用することができます。この関数の存在は全ての Python 実装で保証されるものではありません。

sys.getprofile()

setprofile() 関数などで設定した profiler 関数を取得します。

バージョン 2.6 で追加.

sys.gettrace()

settrace() 関数などで設定した trace 関数を取得します。

CPython implementation detail: gettrace() 関数は、デバッガ、プロファイラ、カバレッジツールなどの実装に使うことのみを想定しています。この関数の振る舞いは言語定義ではなく実装プラットフォームの一部です。そのため、他の Python 実装では利用できないかもしれません。

バージョン 2.6 で追加.

sys.getwindowsversion()

実行中の Windows バージョンを示す、名前付きタプルを返します。名前付けされた要素は、 major, minor, build, platform, service_pack, service_pack_minor, service_pack_major, suite_mask, および product_type です。 service_pack は、文字列を含み、それ以外は整数です。この構成要素には名前でもアクセスできるので、 sys.getwindowsversion()[0] は sys.getwindowsversion().major と等価です。先行のバージョンとの互換性のため、最初の 5 要素がインデクシングで得られます。

platform は、以下の値となります:

定数 | プラットフォーム
0 (VER_PLATFORM_WIN32s) | Win32s on Windows 3.1
1 (VER_PLATFORM_WIN32_WINDOWS) | Windows 95/98/ME
2 (VER_PLATFORM_WIN32_NT) | Windows NT/2000/XP/x64
3 (VER_PLATFORM_WIN32_CE) | Windows CE

product_type は、以下の値のいずれかになります。:

定数 | 意味
1 (VER_NT_WORKSTATION) | システムはワークステーションです。
2 (VER_NT_DOMAIN_CONTROLLER) | システムはドメインコントローラです。
3 (VER_NT_SERVER) | システムはサーバですが、ドメインコントローラではありません。

この関数は、Win32 GetVersionEx() 関数を呼び出します。これらのフィールドに関する詳細は OSVERSIONINFOEX() についてのマイクロソフトのドキュメントを参照してください。

利用可能: Windows.

バージョン 2.3 で追加.

バージョン 2.7 で変更: 名前付きタプルに変更され、 service_pack_minor, service_pack_major, suite_mask, および product_type が追加されました。

sys.hexversion

単精度整数にエンコードされたバージョン番号。この値は新バージョン(正規リリース以外であっても)ごとにかならず増加します。例えば、Python 1.5.2 以降でのみ動作するプログラムでは、以下のようなチェックを行います。

if sys.hexversion >= 0x010502F0:
    # use some advanced feature
    ...
else:
    # use an alternative implementation or warn the user
    ...

hexversion は hex() で16進数に変換しなければ値の意味がわかりません。より読みやすいバージョン番号が必要な場合には version_info を使用してください。

hexversion は以下のレイアウトで表される 32-bit 数です:

ビット (ビッグエンディアンオーダ) | 意味
1-8 | PY_MAJOR_VERSION (2.1.0a3 の 2)
9-16 | PY_MINOR_VERSION (2.1.0a3 の 1)
17-24 | PY_MICRO_VERSION (2.1.0a3 の 0)
25-28 | PY_RELEASE_LEVEL (アルファでは 0xA 、ベータでは 0xB 、リリース候補では 0xC 、そして最終版は 0xF)
29-32 | PY_RELEASE_SERIAL (the 3 in 2.1.0a3 の 0 、最終リリースでは 0)

従って、 2.1.0a3 は hexversion で 0x020100a3 です。

バージョン 1.5.2 で追加.

sys.long_info

Python における整数の内部表現に関する情報を保持する、構造体のシーケンスです。この属性は読み込み専用です。

属性 | 説明
bits_per_digit | 各桁に保持されるビットの数です。Python の整数は、内部的に 2**long_info.bits_per_digit を基数として保存されます。
sizeof_digit | 桁を表すのに使われる、バイトで表した C 型の大きさです。

バージョン 2.7 で追加.

sys.last_type

sys.last_value

sys.last_traceback

通常は定義されておらず、捕捉されない例外が発生してインタープリタがエラーメッセージとトレースバックを出力した場合にのみ設定されます。この値は、対話セッション中にエラーが発生したとき、デバッグモジュールをロード (例:import pdb; pdb.pm() など。詳細は pdb — Python デバッガ を参照)して発生したエラーを調査する場合に利用します。デバッガをロードすると、プログラムを再実行せずに情報を取得することができます。

変数の意味は、上の exc_info() の戻り値と同じです。対話セッションを実行するスレッドは常に1つだけなので、 exc_type のようにスレッドに関する問題は発生しません。

sys.maxint

Pythonの整数型でサポートされる、最大の整数。この値は最低でも 2**31-1 です。最大の負数は -maxint-1 となります。正負の最大数が非対称ですが、これは 2 の補数計算を行うためです。

sys.maxsize

プラットフォームの Py_ssize_t 型がサポートしている最大の正の整数。したがって、リスト、文字列、辞書、その他コンテナ型の最大のサイズ。

sys.maxunicode

Unicode 文字の最大のコードポイントを示す整数。この値は、オプション設定で Unicode 文字の保存形式として USC-2 と UCS-4 のいずれを指定したかによって異なります。

sys.meta_path

finder オブジェクトのリストです。 finder オブジェクトの find_module() メソッドは、 import するモジュールを探すために呼び出されます。 import するモジュールがパッケージに含まれる場合、親パッケージの __path__ 属性が第 2 引数として渡されます。そのメソッドは、モジュールが見つからなかった場合は None を、見つかった場合は loader を返します。

sys.meta_path は、デフォルトの暗黙の finder や、 sys.path よりも先に検索されます。

オリジナルの仕様については、 PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。

sys.modules

ロード済みモジュールのモジュール名とモジュールオブジェクトの辞書。強制的にモジュールを再読み込みする場合などに使用します。この辞書からモジュールを削除するのは、 reload() の呼び出しと等価では ありません 。

sys.path

モジュールを検索するパスを示す文字列のリスト。 PYTHONPATH 環境変数と、インストール時に指定したデフォルトパスで初期化されます。

開始時に初期化された後、リストの先頭(path[0])には Python インタープリタを起動するために指定したスクリプトのディレクトリが挿入されます。スクリプトのディレクトリがない(インタープリタで対話セッションで起動された時や、スクリプトを標準入力から読み込む場合など)場合、 path[0] には空文字列となり、Python はカレントディレクトリからモジュールの検索を開始します。スクリプトディレクトリは、 PYTHONPATH で指定したディレクトリの 前 に挿入されますので注意が必要です。

必要に応じて、プログラム内で自由に変更することができます。

バージョン 2.3 で変更: Unicode 文字列が無視されなくなりました.

参考

site モジュールのドキュメントで、 .pth ファイルを使って sys.path を拡張する方法を解説しています。

sys.path_hooks

path を引数にとって、その path に対する finder の作成を試みる呼び出し可能オブジェクトのリスト。 finder の作成に成功したら、その呼出可能オブジェクトのは finder を返します。失敗した場合は、 ImportError を発生させます。

オリジナルの仕様は PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。

sys.path_importer_cache

finder オブジェクトのキャッシュとなる辞書。キーは sys.path_hooks に渡される path で、値は見つかった finder オブジェクト。 path が有効なファイルシステムパスであり、かつ finder が sys.path_hooks から見つからない場合、暗黙のデフォルト finder を利用するという意味で None が格納されます。 path が既存のパスではない場合、 imp.NullImporter が格納されます。

オリジナルの仕様は PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。

sys.platform

プラットフォームを識別する文字列で、 path にプラットフォーム別のサブディレクトリを追加する場合などに利用します。

Unix システムでは、この値は uname -s が返す小文字のOS名を前半に、 uname -r が返すバージョン名を後半に追加したものになります。例えば、 'sunos5' や 'linux2' といった具合です。この値はPythonをビルドした時のものです 。それ以外のシステムでは、次のような値になります。 :

システム | platform の値
Windows | 'win32'
Windows/Cygwin | 'cygwin'
Mac OS X | 'darwin'
OS/2 | 'os2'
OS/2 EMX | 'os2emx'
RiscOS | 'riscos'
AtheOS | 'atheos'

sys.prefix

サイト固有の、プラットフォームに依存しないファイルを格納するディレクトリを示す文字列。デフォルトでは '/usr/local' になります。この値はビルド時に configure スクリプトの --prefix 引数で指定する事ができます。 Python　ライブラリの主要部分は prefix + '/lib/pythonversion' にインストールされ、プラットフォーム非依存なヘッダファイル(pyconfig.h 以外)は prefix + '/include/pythonversion' に格納されます (但し version は version[:3])。

sys.ps1

sys.ps2

インタープリタの一次プロンプト、二次プロンプトを指定する文字列。対話モードで実行中のみ定義され、初期値は '>>> ' と '... ' です。文字列以外のオブジェクトを指定した場合、インタープリタが対話コマンドを読み込むごとにオブジェクトの str() を評価します。この機能は、動的に変化するプロンプトを実装する場合に利用します。

sys.py3kwarning

Python 3.0 warning flag の状態を格納する Bool 値。 Python が -3 オプションを付けて起動された場合は True になります。 (この値は定数として扱ってください。この変数を変更しても、Python 3.0 warning の動作には影響しません)

バージョン 2.6 で追加.

sys.dont_write_bytecode

この値が true の時、 Python はソースモジュールを import するときに .pyc や .pyo ファイルを生成しません。この値は -B コマンドラインオプションと PYTHONDONTWRITEBYTECODE 環境変数の値によって起動時に True か False に設定されます。しかし、実行時にこの変数を変更して、バイトコード生成を制御することもできます。

バージョン 2.6 で追加.

sys.setcheckinterval(interval)

インタープリタの”チェック間隔”を示す整数値を指定します。この値はスレッドスイッチやシグナルハンドラのチェックを行う周期を決定します。デフォルト値は 100 で、この場合 100 の仮想命令を実行するとチェックを行います。この値を大きくすればスレッドを利用するプログラムのパフォーマンスが向上します。この値が 0 以下の場合、全ての仮想命令を実行するたびにチェックを行い、レスポンス速度と最大になりますがオーバヘッドもまた最大となります。

sys.setdefaultencoding(name)

現在の Unicode 処理のデフォルトエンコーディング名を設定します。 name に一致するエンコーディングが見つからない場合、 LookupError が発生します。この関数は、 site モジュールの実装が、 sitecustomize モジュールから使用するためだけに定義されています。 site から呼び出された後、この関数は sys から削除されます。

バージョン 2.0 で追加.

sys.setdlopenflags(n)

インタープリタが拡張モジュールをロードする時、 dlopen() で使用するフラグを設定します。 sys.setdlopenflags(0) とすれば、モジュールインポート時にシンボルの遅延解決を行う事ができます。シンボルを拡張モジュール間で共有する場合には、 sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL) と指定します。フラグの定義名は dl か DLFCN で定義されています。 DLFCN が存在しない場合、 h2py スクリプトを使って /usr/include/dlfcn.h から生成することができます。

利用可能: Unix.

バージョン 2.2 で追加.

sys.setprofile(profilefunc)

システムのプロファイル関数を登録します。プロファイル関数は、 Python のソースコードプロファイルを行う関数で、 Python で記述することができます。詳細は Python プロファイラ を参照してください。プロファイル関数はトレース関数(settrace() 参照)と似ていますが、ソース行が実行されるごとに呼び出されるのではなく、関数の呼出しと復帰時のみ呼び出されます(例外が発生している場合でも、復帰時のイベントは発生します)。プロファイル関数はスレッド毎に設定することができますが、プロファイラはスレッド間のコンテキスト切り替えを検出することはできません。従って、マルチスレッド環境でのプロファイルはあまり意味がありません。 setprofile() は常に None を返します。

sys.setrecursionlimit(limit)

Python インタープリタの、スタックの最大の深さを limit に設定します。この制限は Python プログラムが無限に再帰し、 C スタックがオーバーフローしてクラッシュすることを防止するために設けられています。

limit の最大値はプラットフォームによって異なります。深い再帰処理が必要な場合にはプラットフォームがサポートしている範囲内でより大きな値を指定することができますが、この値が大きすぎればクラッシュするので注意が必要です。

sys.settrace(tracefunc)

システムのトレース関数を登録します。トレース関数は Python のソースデバッガを実装するために使用することができます。トレース関数はスレッド毎に設定することができるので、デバッグを行う全てのスレッドで settrace() を呼び出し、トレース関数を登録してください。

Trace関数は3つの引数: frame, event, arg を受け取る必要があります。 event は文字列です。 'call', 'line', 'return', 'exception', 'c_call', 'c_return', 'c_exception' のどれかが渡されます。 arg はイベントの種類によって異なります。

trace 関数は (event に 'call' を渡された状態で) 新しいローカルスコープに入るたびに呼ばれます。この場合、そのスコープで利用するローカルの trace 関数か、そのスコープを trace しないのであれば None を返します。

ローカル trace 関数は自身への参照 (もしくはそのスコープの以降の trace を行う別の関数) を返すべきです。もしくは、そのスコープの trace を止めるために None を返します。

event には以下の意味があります。

'call'

関数が呼び出された(もしくは、何かのコードブロックに入った)。グローバルの trace 関数が呼ばれる。 arg は None が渡される。戻り値はローカルの trace 関数。

'line'

インタプリタが新しい行を実行しようとしている。または、ループの条件で最実行しようとしている。ローカルの trace 関数が呼ばれる。 arg は None 。戻り値は新しいローカルの trace 関数。これがどのように振る舞うかの詳細な説明は、 Objects/lnotab_notes.txt を参照のこと。

'return'

関数(あるいは別のコードブロック)から戻ろうとしている。ローカルの trace 関数が呼ばれる。 arg は返されようとしている値、または、このイベントが例外が送出されることによって起こったなら None 。 trace 関数の戻り値は無視される。

'exception'

例外が発生した。ローカルの trace 関数が呼ばれる。 arg は (exception, value, traceback) のタプル。戻り値は新しいローカルの trace 関数。

'c_call'

C 関数(拡張関数かビルトイン関数)が呼ばれようとしている。 arg は C 関数オブジェクト。

'c_return'

C 関数から戻った。 arg は C の関数オブジェクト。

'c_exception'

C 関数が例外を発生させた。 arg は C の関数オブジェクト。

例外が呼び出しチェインを辿って伝播していくことに注意してください。 'exception' イベントは各レベルで発生します。

code と frame オブジェクトについては、 標準型の階層 を参照してください。

CPython implementation detail: settrace() 関数は、デバッガ、プロファイラ、カバレッジツール等で使うためだけのものです。この関数の挙動は言語定義よりも実装プラットフォームの分野の問題で、全ての Python 実装で利用できるとは限りません。

sys.settscdump(on_flag)

on_flag が真の場合、Pentium タイムスタンプカウンタを使った VM 計測結果のダンプ出力を有効にします。 on_flag をオフにするとダンプ出力を無効化します。この関数は Python を --with-tsc つきでコンパイルしたときにのみ利用できます。ダンプの内容を理解したければ、 Python ソースコード中の Python/ceval.c を読んでください。

バージョン 2.4 で追加.

CPython implementation detail: この関数は CPython の実装の詳細に密接に結びついています、そのため他の Python 実装では実装されていないでしょう。

sys.stdin

sys.stdout

sys.stderr

インタープリタの標準入力・標準出力・標準エラー出力に対応するファイルオブジェクト。 stdin はスクリプトの読み込みを除く全ての入力処理で使用され、 input() や raw_input() も stdin から読み込みます。 stdout は、 print や式(expression)の評価結果、 input(), raw_input() のプロンプトの出力先となります。インタープリタのプロンプトは(ほとんど) stderr に出力されます。 stdout と stderr は必ずしも組み込みのファイルオブジェクトである必要はなく、 write() メソッドを持つオブジェクトであれば使用することができます。 stdout と stderr を別のオブジェクトに置き換えても、 os.popen(), os.system(), os の exec*() などから起動されたプロセスが使用する標準 I/O ストリームは変更されません。

sys.__stdin__

sys.__stdout__

sys.__stderr__

それぞれ起動時の stdin, stderr, stdout の値を保存します。終了処理時に利用されます。また、 sys.std* オブジェクトが(訳注:別のファイルライクオブジェクトに)リダイレクトされている場合でも、本当の標準ストリームに表示する場合に利用できます。

また、標準ストリームを置き換えたオブジェクトが壊れた場合に、動作する本物のファイルをリストアするために利用することもできます。しかし、明示的に置き換え前のストリームを保存しておき、そのオブジェクトをリストアする事を推奨します。

sys.tracebacklimit

捕捉されない例外が発生した時、出力されるトレースバック情報の最大レベル数を指定する整数値(デフォルト値は 1000)。 0 以下の値が設定された場合、トレースバック情報は出力されず例外型と例外値のみが出力されます。

sys.version

Pythonインタープリタのバージョンとビルド番号・使用コンパイラなどの情報を示す文字列です。この文字列は Python 対話インタプリタが起動したときに表示されます。バージョン情報はここから抜き出さずに platform が提供する version_info を使って下さい。

sys.api_version

使用中のインタープリタの C API バージョン。 Python と拡張モジュール間の不整合をデバッグする場合などに利用できます。

バージョン 2.3 で追加.

sys.version_info

バージョン番号を示す５つの値のタプル:major, minor, micro, releaselevel, serial 。 releaselevel 以外は全て整数です。 releaselevel の値は、 'alpha', 'beta', 'candidate', 'final' の何れかです。 Python 2.0 の version_info は、 (2, 0, 0, 'final', 0) となります。構成要素には名前でもアクセスできるので、 sys.version_info[0] は sys.version_info.major と等価、などになります。

バージョン 2.0 で追加.

バージョン 2.7 で変更: 構成する属性に名前をつけました。

sys.warnoptions

この値は、warnings framework 内部のみ使用され、変更することはできません。詳細は warnings を参照してください。

sys.winver

Windows プラットフォームで、レジストリのキーとなるバージョン番号。 Python DLL の文字列リソース 1000 に設定されています。通常、この値は version の先頭三文字となります。この値は参照専用で、別の値を設定しても Python が使用するレジストリキーを変更することはできません。利用可能: Windows.

Citations

[C99]
ISO/IEC 9899:1999. “Programming languages – C.” A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf .

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.2. sysconfig — Python の構成情報にアクセスする

バージョン 2.7 で追加.

sysconfig モジュールは、 インストールパスのリストや、現在のプラットフォームに関連した構成などの、 Python の構成情報 (configuration information) へのアクセスを提供します。

27.2.1. 構成変数

Python の配布物は、 Python 自体のバイナリや、 distutils によってコンパイルされる外部のC拡張をビルドするのに必要な、 Makefile と pyconfig.h ヘッダーファイルを含んでいます。

sysconfig はこれらのファイルに含まれる全ての変数を辞書に格納し、 get_config_vars() や get_config_var() でアクセスできるようにします。

Windows では構成変数はだいぶ少なくなります。

sysconfig.get_config_vars(*args)

引数がない場合、現在のプラットフォームに関する全ての構成変数の辞書を返します。

引数がある場合、各引数を構成変数辞書から検索した結果の変数のリストを返します。

各引数において、変数が見つからなかった場合は None が返されます。

sysconfig.get_config_var(name)

1つの変数 name を返します。 get_config_vars().get(name) と同じです。

name が見つからない場合、 None を返します。

使用例:

>>> import sysconfig
>>> sysconfig.get_config_var('Py_ENABLE_SHARED')
0
>>> sysconfig.get_config_var('LIBDIR')
'/usr/local/lib'
>>> sysconfig.get_config_vars('AR', 'CXX')
['ar', 'g++']

27.2.2. インストールパス

Python はプラットフォームとインストールオプションに依存して、異なるインストールスキームを利用します。このスキームは、 os.name の値に基づいてユニークな識別子で sysconfig に格納されます。

Distutils やそれに基づいたシステムによって新しいコンポーネントをインストールするときは、同じスキームに従ってファイルを正しい場所にコピーします。

Python は現在7つのスキームをサポートしています:

posix_prefix: Linux や Mac OS X などの Posix プラットフォーム用のスキームです。これは Python やコンポーネントをインストールするときに使われるデフォルトのスキームです。

posix_home: インストール時に home オプションが利用された場合における、 Posix プラットフォーム用のスキームです。このスキームはコンポーネントが Distutils に特定の home prefix を指定してインストールされたときに利用されます。

posix_user: Distutils に user オプションを指定してコンポーネントをインストールするときに使われる、Posix プラットフォーム用のスキームです。このスキームはユーザーのホームディレクトリ以下に配置されたパスヲ定義します。

nt: Windows などの NT プラットフォーム用のスキームです。

nt_user: user オプションが利用された場合の、 NT プラットフォーム用のスキームです。

os2: OS/2 プラットフォーム用のスキームです。

os2_home: user オプションが利用された場合の、 OS/2 プラットフォーム用のスキームです。

各スキームは、ユニークな識別子を持ったいくつかのパスの集合から成っています。現在 Python は8つのパスを利用します:

stdlib: プラットフォーム非依存の、標準 Python ライブラリファイルを格納するディレクトリ.

platstdlib: プラットフォーム依存の、標準 Python ライブラリファイルを格納するディレクトリ.

platlib: プラットフォーム依存の、 site ごとのファイルを格納するディレクトリ

purelib: プラットフォーム非依存の、 site ごとのファイルを格納するディレクトリ

include: プラットフォーム非依存のヘッダーファイルを格納するディレクトリ

platinclude: プラットフォーム依存の、ヘッダーファイルを格納するディレクトリ

scripts: スクリプトファイルのためのディレクトリ

data: データファイルのためのディレクトリ

sysconfig はこれらのパスを決定するためのいくつかの関数を提供しています。

sysconfig.get_scheme_names()

現在 sysconfig でサポートされている全てのスキームを格納したタプルを返します。

sysconfig.get_path_names()

現在 sysconfig でサポートされている全てのパス名を格納したタプルを返します。

sysconfig.get_path(name[, scheme[, vars[, expand]]])

scheme で指定されたインストールスキームから、 path name に従ってインストールパスを返します。

name は get_path_names() が返すリストに含まれる値でなければなりません。

sysconfig はインストールパスを、パス名、プラットフォーム、展開される変数に従って格納します。例えば、 nt スキームでの stdlib パスは {base}/Lib になります。

get_path() はパスを展開するのに get_config_vars() が返す変数を利用します。全ての変数は各プラットフォームにおいてデフォルト値を持っていて、この関数を呼び出したときにデフォルト値を取得する場合があります。

scheme が指定された場合、 get_scheme_names() が返すリストに含まれる値でなければなりません。指定されなかった場合は、現在のプラットフォームでのデフォルトスキームが利用されます。

bars が指定された場合、 get_config_vars() が返す辞書をアップデートする変数辞書でなければなりません。

expand が False に設定された場合、パスは変数を使って展開されません。

name が見つからなかった場合、 None を返します。

sysconfig.get_paths([scheme[, vars[, expand]]])

インストールスキームに基づいた全てのインストールパスを格納した辞書を返します。詳しい情報は get_path() を参照してください。

scheme が指定された場合、 get_scheme_names() が返すリストに含まれる値でなければなりません。指定されなかった場合は、現在のプラットフォームでのデフォルトスキームが利用されます。

bars が指定された場合、 get_config_vars() が返す辞書をアップデートする変数辞書でなければなりません。

expand が False に設定された場合、パスは変数を使って展開されません。

scheme が実在するスキームでなかった場合、 get_paths() は KeyError を発生させます。

27.2.3. その他の関数

sysconfig.get_python_version()

MAJOR.MINOR の型の Python バージョン番号文字列を返します。 sys.version[:3] に似ています。

sysconfig.get_platform()

現在のプラットフォームを識別するための文字列を返します。

この関数は主に、プラットフォーム依存のビルドディレクトリやビルド済み配布物を判別するのに利用します。典型的に、OS名とバージョンと(os.uname() で提供される)アーキテクチャを含みますが、実際の情報はOS依存です。例えば、 IRIX ではアーキテクチャは重要ではない(IRIX は SGI のハードでしか動きません) のに対して、 Linux ではカーネルバージョンが重要な情報ではありません。

返される値の例:

linux-i586

linux-alpha (?)

solaris-2.6-sun4u

irix-5.3

irix64-6.2

Windows では以下のどれかを返します:

win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)

win-ia64 (64bit Windows on Itanium)

win32 (all others - specifically, sys.platform is returned)

Mac OS X では以下のどれかを返すかもしれません:

macosx-10.6-ppc

macosx-10.4-ppc64

macosx-10.3-i386

macosx-10.4-fat

その他の非POSIXプラットフォームでは、現在のところ単に sys.platform を返します。

sysconfig.is_python_build()

現在の Python インストールがソースからビルドされた場合に True を返します。

sysconfig.parse_config_h(fp[, vars])

config.h スタイルのファイルを解析します。

fp は config.h スタイルのファイルを指すファイルライクオブジェクトです。

name/value ペアを格納した辞書を返します。第二引数にオプションの辞書が渡された場合、新しい辞書ではなくその辞書を利用し、ファイルから読み込んだ値で更新します。

sysconfig.get_config_h_filename()

pyconfig.h のパスを返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.3. __builtin__ — 組み込みオブジェクト

このモジュールは Python の全ての「組み込み」識別子に直接アクセスするためのものです。例えば __builtin__.open は組み込み関数 open() の完全な名前です。

通常このモジュールはほとんどのアプリケーションで明示的にアクセスされることはありませんが、組み込みの値と同じ名前のオブジェクトを提供するモジュールが同時にその名前の組み込みオブジェクトも必要とするような場合には有用です。たとえば、組み込みの open() をラップした open() という関数を実装したいモジュールがあったとすると、 __builtin__ モジュールは次のように直接的に使われます。

import __builtin__

def open(path):
    f = __builtin__.open(path, 'r')
    return UpperCaser(f)

class UpperCaser:
    '''Wrapper around a file that converts output to upper-case.'''

    def __init__(self, f):
        self._f = f

    def read(self, count=-1):
        return self._f.read(count).upper()

    # ...

CPython implementation detail:

ほとんどのモジュールではグローバル変数の一部として __builtins__ ('s' に注意) が利用できるようになっています。 __builtins__ の内容は通常 __builtin__ モジュールそのものか、あるいは __builtin__ モジュールの __dict__ 属性です。これは実装の詳細部分なので、異なる Python の実装では __builtins__ は使われていないこともあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.4. future_builtins — Python 3 のビルトイン

バージョン 2.6 で追加.

このモジュールは、Python 2.x に存在するけれども、 Python 3では異なった動作をするために、Python 2.xのビルトイン名前空間に追加できない関数を提供します。

代わりに、Python 3のビルトイン関数と互換性のあるコードを書きたい場合は、次のように、このモジュールからその関数をimportしてください。

from future_builtins import map, filter

... code using Python 3-style map and filter ...

Python 2のコードをPython 3用に変換する 2to3 ツールは、この利用方法を検出し、新しいビルトイン関数をそのまま利用します。

ノート

Python 3の print() 関数は、Python 2でもビルトイン関数です。しかし、future文で指定しない限り、利用することができません。

from __future__ import print_function

利用できるビルトイン関数は、以下の通りです。

future_builtins.ascii(object)

repr() と同じ値を返します。 Python 3 では、 repr() は表示可能なUnicode文字をエスケープせずに返し、 ascii() はその文字列をバックスラッシュでエスケープします。 future_builtins.ascii() を repr() の代わりに利用することで、 ASCII文字列を必要としていることを明示できます。

future_builtins.filter(function, iterable)

itertools.ifilter() と同じように動作します。

future_builtins.hex(object)

ビルトイン hex() と同じように動作しますが、 __hex__() の代わりに、 __index__() メソッドを利用して整数を取得し、それを16進数文字列に変換します。

future_builtins.map(function, iterable, ...)

itertools.imap() と同じように動作します。

future_builtins.oct(object)

ビルトイン oct() と同じように動作しますが、 __oct__() の代わりに、 __index__() メソッドを利用して整数を取得し、それを16進数文字列に変換します。

future_builtins.zip(*iterables)

itertools.izip() と同じように動作します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.5. __main__ — トップレベルのスクリプト環境

このモジュールはPythonインタプリタのメインプログラムがコマンドを実行する際の環境をあらわしています。このモジュールを利用することで、通常は無名のこの環境にアクセスすることができます。実行されるコマンドは標準入力、スクリプトファイルあるいは対話環境での入力プロンプトから入力されます。この環境はPythonスクリプトをメインプログラムとして実行される際によく使われる”条件付きスクリプト”の一節が実行される環境です。

if __name__ == "__main__":
    main()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.6. warnings — 警告の制御

バージョン 2.1 で追加.

警告メッセージは一般に、ユーザに警告しておいた方がよいような状況下にプログラムが置かれているが、その状況は (通常は) 例外を送出したりそのプログラムを終了させるほどの正当な理由がないといった状況で発されます。例えば、プログラムが古いモジュールを使っている場合には警告を発したくなるかもしれません。

Python プログラマは、このモジュールの warn() 関数を使って警告を発することができます。(C 言語のプログラマは PyErr_WarnEx() を使います; 詳細は 例外処理 を参照してください)。

警告メッセージは通常 sys.stderr に出力されますが、その処理方法は柔軟に変更することができます。すべての警告を無視することも、警告を例外に変更することもできます。警告の処理方法は警告カテゴリ (以下参照)、警告メッセージテキスト、そして警告を発したソースコード上の場所に基づいて変更することができます。ソースコード上の同じ場所に対して特定の警告が繰り返された場合、通常は抑制されます。

警告制御には 2 つの段階 (stage) があります: 第一に、警告が発されるたびに、メッセージを出力すべきかどうかの決定が行われます; 次に、メッセージを出力するなら、メッセージはユーザによって設定が可能なフックを使って書式化され印字されます。

警告メッセージを出力するかどうかの決定は、警告フィルタによって制御されます。警告フィルタは一致規則 (matching rule)と動作からなるシーケンスです。 filterwarnings() を呼び出して一致規則をフィルタに追加することができ、 resetwarnings() を呼び出してフィルタを標準設定の状態にリセットすることができます。

警告メッセージの印字は showwarning() を呼び出して行うことができ、この関数は上書きすることができます; この関数の標準の実装では、 formatwarning() を呼び出して警告メッセージを書式化しますが、この関数についても自作の実装を使うことができます。

27.6.1. 警告カテゴリ

警告カテゴリを表現する組み込み例外は数多くあります。このカテゴリ化は警告をグループごとフィルタする上で便利です。現在以下の警告カテゴリクラスが定義されています:

クラス | 記述
Warning | すべての警告カテゴリクラスの基底クラスです。 Exception のサブクラスです。
UserWarning | warn() の標準のカテゴリです。
DeprecationWarning | その機能が廃止されていることを示す警告カテゴリの基底クラスです。 (デフォルトでは無視されます)
SyntaxWarning | その文法機能があいまいであることを示す警告カテゴリの基底クラスです。
RuntimeWarning | そのランタイム機能があいまいであることを示す警告カテゴリの基底クラスです。
FutureWarning | その構文の意味付けが将来変更される予定であることを示す警告カテゴリの基底クラスです。
PendingDeprecationWarning | 将来その機能が廃止されることを示す警告カテゴリの基底クラスです(デフォルトでは無視されます)。
ImportWarning | モジュールのインポート処理中に引き起こされる警告カテゴリの基底クラスです(デフォルトでは無視されます)。
UnicodeWarning | Unicode に関係した警告カテゴリの基底クラスです。

これらは厳密に言えば組み込み例外ですが、概念的には警告メカニズムに属しているのでここで記述されています。

標準の警告カテゴリをユーザの作成したコード上でサブクラス化することで、さらに別の警告カテゴリを定義することができます。警告カテゴリは常に Warning クラスのサブクラスでなければなりません。

バージョン 2.7 で変更: DeprecationWarning はデフォルトでは無視されます。

27.6.2. 警告フィルタ

警告フィルタは、ある警告を無視すべきか、表示すべきか、あるいは (例外を送出する) エラーにするべきかを制御します。

概念的には、警告フィルタは複数のフィルタ仕様からなる順番リストを維持しています; 何らかの特定の警告が生じると、一致するものが見つかるまでリスト中の各フィルタとの照合が行われます; 一致したフィルタ仕様がその警告の処理方法を決定します。フィルタの各エントリは (action, message, category, module, lineno) からなるタプルです。ここで、

action は以下の文字列のうちの一つです:

値

処理方法

"error"

一致した警告を例外に変えます

"ignore"

一致した警告を出力しません

"always"

一致した警告を常に出力します

"default"

一致した警告のうち、警告の原因になったソースコード上の場所ごとに、最初の警告のみ出力します。

"module"

一致した警告のうち、警告の原因になったモジュールごとに、最初の警告のみ出力します。

"once"

一致した警告のうち、警告の原因になった場所にかかわらず最初の警告のみ出力します。

message は正規表現を含む文字列で、メッセージはこのパターンに一致しなければなりません (常に大小文字の区別をしないようにコンパイルされます)。

category はクラス (Warning のサブクラス) です。警告クラスはこのクラスのサブクラスに一致しなければなりません。

module は正規表現を含む文字列で、モジュール名はこのパターンに一致しなければなりません (常に大小文字の区別をしないようにコンパイルされます)。

lineno は整数で、警告が発生した場所の行番号に一致しなければなりません。 0 の場合はすべての行と一致します。

Warning クラスは組み込みの Exception クラスから派生しているので、警告をエラーに変換するには単に category(message) を raise します。

警告フィルタは Python インタプリタのコマンドラインに渡される -W オプションで初期化されます。インタプリタは -W オプションに渡されるすべての引数を sys.warnoptions に変換せずに保存します; warnings モジュールは最初に import された際にこれらの引数を解釈します (無効なオプションは sys.stderr にメッセージを出力した上で無視されます)。

27.6.2.1. デフォルトの警告フィルタ

デフォルトで、 Python はいくつかの警告フィルタをインストールします。これはコマンドラインオプション -W か filterwarnings() 関数でオーバーライドできます。

PendingDeprecationWarning, ImportWarning は無視されます。

-b オプションが1度か2度指定されない限り、 BytesWarning は無視されます。 -b の時は警告が表示され、 -bb の時は例外になります。

27.6.3. 一時的に警告を抑制する

廃止予定の関数など、警告を発生させることが分かっているコードを利用する場合に、そのような警告を表示したくなければ、 catch_warnings コンテキストマネージャーを使って警告を抑制することができます。

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()

このサンプルのコンテキストマネージャーの中では、すべての警告が無視されています。これで、他の廃止予定のコードを含まない(つもりの)部分まで警告を抑止せずに、廃止予定だと分かっているコードだけ警告を表示させないようにすることができます。注意: これが保証できるのはシングルスレッドのアプリケーションだけです。 2つ以上のスレッドが同時に catch_warnings コンテキストマネージャーを使用した場合、動作は未定義です。

27.6.4. 警告のテスト

コードが警告を発生させることをテストするには、 catch_warnings コンテキストマネージャーを利用します。このクラスを使うと、一時的に警告フィルタを操作してテストに利用できます。例えば、次のコードでは、発生したすべての警告を取得してチェックしています。

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)

always の代わりに error を利用することで、すべての警告で例外を発生させることができます。 1つ気をつけないといけないのは、一度 once/default ルールによって発生した警告は、フィルタに何をセットしているかにかかわらず、警告レジストリをクリアしない限りは 2度と発生しません。

コンテキストマネージャーが終了したら、警告フィルタはコンテキストマネージャーに入る前のものに戻されます。これは、テスト中に予期しない方法で警告フィルタが変更され、テスト結果が中途半端になる事を予防します。このモジュールの showwarning() 関数も元の値に戻されます。注意: これが保証できるのはシングルスレッドのアプリケーションだけです。 2つ以上のスレッドが同時に catch_warnings コンテキストマネージャを使用した場合、動作は未定義です。

同じ種類の警告を発生させる複数の操作をテストする場合、各操作が新しい警告を発生させている事を確認するのは大切な事です。 (例えば、警告を例外として発生させて各操作が例外を発生させることを確認したり、警告リストの長さが各操作で増加していることを確認したり、警告リストを各操作の前に毎回クリアする事ができます。)

27.6.5. コードを新しいバージョンの Python のために更新する

開発者にしか興味の無い警告はデフォルトでは無視されるようになりました。なので、通常、コードをテストするときには無視されている例外を表示するようにするべきです。これは -Wd コマンドライン引数 (-W default の省略形) をインタプリタに指定することで可能です。これはデフォルトでは無視されているものも含めた全ての警告に対して、デフォルトの動作を有効にします。この動作を変更するためには、 -W への引数を変更します。例えば、 -W error のようにします。何が可能かについての詳細は、 -W フラグを参照してください。

プログラムから -Wd と同じ事をするには、次のようにします:

warnings.simplefilter('default')

このコードは可能な限り早く実行してください。そうすることで、どの警告を発生させるかの登録が、将来の警告がどう扱われるかについて思わぬ影響を与えることを避けることができます。

いくつかの警告がデフォルトで無視されているのは、開発者向けの警告をユーザーに見せることを避けるためです。ユーザーがどのインタプリタを使ってコードを実行するのかを必ずしも制御できるわけではないので、自分のコードのリリースサイクルの間に新しいバージョンの Python がリリースされるかもしれません。新しいインタプリタは、古いインタプリタが出さなかった新しい警告を発生させるかもしれません。例えば、利用しているモジュールに対して DeprecationWarning が発生されることがあります。開発者としては、廃止予定のモジュールを利用していることに対する通知は有益ですが、一般ユーザーにとってはこの情報はノイズでしか無く、何の役にも立ちません。

27.6.6. 利用可能な関数

warnings.warn(message[, category[, stacklevel]])

警告を発するか、無視するか、あるいは例外を送出します。 category 引数が与えられた場合、警告カテゴリクラスでなければなりません (上記を参照してください); 標準の値は UserWarning です。 message を Warning インスタンスで代用することもできますが、この場合 category は無視され、 message.__class__ が使われ、メッセージ文は str(message) になります。発された例外が前述した警告フィルタによってエラーに変更された場合、この関数は例外を送出します。引数 stacklevel は Python でラッパー関数を書く際に利用することができます。例えば

def deprecation(message):
    warnings.warn(message, DeprecationWarning, stacklevel=2)

こうすることで、警告が参照するソースコード部分を、 deprecation() 自身ではなく deprecation() を呼び出した側にできます (というのも、前者の場合は警告メッセージの目的を台無しにしてしまうからです)。

warnings.warn_explicit(message, category, filename, lineno[, module[, registry[, module_globals]]])

warn() の機能に対する低レベルのインタフェースで、メッセージ、警告カテゴリ、ファイル名および行番号、そしてオプションのモジュール名およびレジストリ情報 (モジュールの __warningregistry__ 辞書) を明示的に渡します。モジュール名は標準で .py が取り去られたファイル名になります; レジストリが渡されなかった場合、警告が抑制されることはありません。 message が文字列のとき、 category は Warning のサブクラスでなければなりません。また message は Warning のインスタンスであってもよく、この場合 category は無視されます。

module_globals は、もし与えられるならば、警告が発せられるコードが使っているグローバル名前空間でなければなりません。(この引数は zipfile やその他の非ファイルシステムのインポート元の中にあるモジュールのソースを表示することをサポートするためのものです)

バージョン 2.5 で変更: module_globals 引数が追加されました

warnings.warnpy3k(message[, category[, stacklevel]])

Python 3.x で廃止予定についての警告を発生させます。 Pythonが -3 オプション付きで実行されているときのみ警告が表示されます。 warn() と同じく、 message は文字列で、 category は Warninp のサブクラスである必要があります。 warnpy3k() は DeprecationWarning をデフォルトのwarningクラスとして利用しています。

バージョン 2.6 で追加.

warnings.showwarning(message, category, filename, lineno[, file[, line]])

警告をファイルに書き込みます。標準の実装では、 formatwarning(message, category, filename, lineno, line) を呼び出し、返された文字列を file に書き込みます。 file は標準では sys.stderr です。この関数は warnings.showwarning に別の実装を代入して置き換えることができます。 line は警告メッセージに含めるソースコードの1行です。 line が与えられない場合、 showwarning() は filename と lineno から行を取得することを試みます。

バージョン 2.7 で変更: line 引数のサポートが必須になりました。

warnings.formatwarning(message, category, filename, lineno[, line])

警告を通常の方法で書式化します。返される文字列内には改行が埋め込まれている可能性があり、かつ文字列は改行で終端されています。 line は警告メッセージに含まれるソースコードの1行です。 line が渡されない場合、 formatwarning() は filename と fileno から行の取得を試みます。

バージョン 2.6 で変更: line 引数を追加しました。

warnings.filterwarnings(action[, message[, category[, module[, lineno[, append]]]]])

警告フィルタ仕様 のリストにエントリを一つ挿入します。標準ではエントリは先頭に挿入されます; append が真ならば、末尾に挿入されます。この関数は引数の型をチェックし、 message および module の正規表現をコンパイルしてから、これらをタプルにして警告フィルタのリストに挿入します。二つのエントリが特定の警告に合致した場合、リストの先頭に近い方のエントリが後方にあるエントリに優先します。引数が省略されると、標準ではすべてにマッチする値に設定されます。

warnings.simplefilter(action[, category[, lineno[, append]]])

単純なエントリを 警告フィルタ仕様 のリストに挿入します。引数の意味は filterwarnings() と同じですが、この関数により挿入されるフィルタはカテゴリと行番号が一致していればすべてのモジュールのすべてのメッセージに合致しますので、正規表現は必要ありません。

warnings.resetwarnings()

警告フィルタをリセットします。これにより、 -W コマンドラインオプションによるもの simplefilter() 呼び出しによるものを含め、 filterwarnings() の呼び出しによる影響はすべて無効化されます。

27.6.7. 利用可能なコンテキストマネージャー

class warnings.catch_warnings([*, record=False, module=None])

警告フィルタと showwarning() 関数をコピーし、終了時に復元するコンテキストマネージャーです。 record 引数が False (デフォルト値)だった場合、コンテキスト開始時には None を返します。もし record が True だった場合、リストを返します。このリストにはカスタムの showwarning() 関数(この関数は同時に sys.stdout への出力を抑制します)によってオブジェクトが継続的に追加されます。リストの中の各オブジェクトは、 showwarning() 関数の引数と同じ名前の属性を持っています。

module 引数は、保護したいフィルタを持つモジュールを取ります。 warnings を import して得られるモジュールの代わりに利用されます。この引数は、主に warnings モジュール自体をテストする目的で追加されました。

ノート

catch_warnings マネージャーは、モジュールの showwarning() 関数と内部のフィルタ仕様のリストを置き換え、その後復元することによって動作しています。これは、コンテキストマネージャーがグローバルな状態を変更していることを意味していて、したがってスレッドセーフではありません。

ノート

Python 3.0 では、 catch_warnings コンストラクタの引数はキーワード引数のみになりました。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.7. contextlib — with -構文コンテキストのためのユーティリティ

バージョン 2.5 で追加.

このモジュールは with 構文に関わる一般的なタスクのためのユーティリティを提供します。詳しい情報は、 コンテキストマネージャ型 と with文とコンテキストマネージャ を参照してください。

参考

最新バージョンの contextlib Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/contextlib.py?view=markup]

提供されている関数:

contextlib.contextmanager(func)

この関数は with 構文コンテキストマネージャのファクトリ関数を定義するためのデコレータ (decorator) です。新しいクラスを作ったり __enter__() と __exit__() のメソッドを別々にしなくても、ファクトリ関数を定義することができます。

簡単な例（実際にHTMLを生成する方法としてはお勧めできません！）

from contextlib import contextmanager

@contextmanager
def tag(name):
    print "<%s>" % name
    yield
    print "</%s>" % name

>>> with tag("h1"):
...    print "foo"
...
<h1>
foo
</h1>

デコレート対象の関数は呼び出されたときにジェネレータ(generator)-イテレータを返す必要があります。このイテレータは値をちょうど一つ yield しなければなりません。 with 構文の as 節が存在するなら、その値は as 節のターゲットへ束縛されることになります。

ジェネレータが yield を実行した箇所で with 文のネストされたブロックが実行されます。ブロックから抜けた後でジェネレータは再開されます。ブロック内で処理されない例外が発生した場合は、ジェネレータ内部の yield を実行した箇所で例外が再送出されます。このように、（もしあれば）エラーを捕捉したり、クリーンアップ処理を確実に実行したりするために、 try...except...finally 構文を使うことができます。例外を捕捉する目的が、（完全に例外を抑制してしまうのではなく）単に例外のログをとるため、もしくはあるアクションを実行するためなら、ジェネレータはその例外を再送出しなければなりません。例外を再送出しない場合、ジェネレータコンテキストマネージャは with 文に対して例外が処理されたことを示し、 with 文の直後の文から実行を再開します。

contextlib.nested(mgr1[, mgr2[, ...]])

複数のコンテキストマネージャを一つのネストされたコンテキストマネージャへ結合します。

この関数は、 with 文にマルチマネージャー形式ができたために非推奨になりました。

この関数の with 文のマルチマネージャー形式に対する唯一の利点は、引数のアンパックによって、次の例のように可変数個のコンテキストマネージャーを扱えることです。

with nested(*managers):
    do_something()

ネストされたコンテキストマネージャのうちのいずれかの __exit__() メソッドが例外を抑制すべきと判断した場合、外側にある残りのすべてのコンテキストマネージャに例外情報が渡されないということに注意してください。同様に、ネストされたコンテキストマネージャのうちのいずれかの __exit__() メソッドが例外を送出したならば、それ以前の例外状態は失われ、新しい例外が外側にある残りのすべてのコンテキストマネージャの __exit__() メソッドに渡されます。一般的に __exit__() メソッドが例外を送出することは避けるべきであり、特に渡された例外を再送出すべきではありません。

この関数が非推奨になった理由に、2つの大きな問題があります。 1つ目は、全てのコンテキストマネージャーが関数が呼び出される前に構築されることです。内側のコンテキストマネージャーの __new__() と __init__() メソッドは外側のコンテキストマネージャーの内側に入っていません。つまり、例えば nested() を2つのファイルを開くために利用した場合、 2つめのファイルを開くのに失敗すると1つめのファイルが正しく close されないというプログラムエラーになります。

2つ目の問題は、内側のコンテキストマネージャーの1つの __enter__() メソッドが例外を発生させたときに、外側のコンテキストマネージャーの __exit__() メソッドがその例外を捕まえて抑制させてしまうことで、この場合に with の body 部分の実行がスキップされるのではなく RuntimeError が発生する恐れがあります。

可変数個のコンテキストマネージャーのネストをサポートしなければならない場合、 warnings モジュールを利用してこの関数が発生させる DeprecationWarning を抑制するか、この関数を参考にしてアプリケーション独自の実装をすることができます。

バージョン 2.7 で撤廃: with 文がこの関数の機能を(この関数と違って奇妙なエラーを発生させることなしに) 直接サポートしました。

contextlib.closing(thing)

ブロックの完了時に thing を close するコンテキストマネージャを返します。これは基本的に以下と等価です

from contextlib import contextmanager

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

そして、明示的に page を close する必要なしに、このように書くことができます:

from contextlib import closing
import urllib

with closing(urllib.urlopen('http://www.python.org')) as page:
    for line in page:
        print line

たとえエラーが発生したとしても、 with ブロックを出るときに page.close() が呼ばれます。

参考

PEP 0343 [http://www.python.org/dev/peps/pep-0343] - The “with” statement

仕様、背景、および、Python with 文の例。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.8. abc — 抽象基底クラス

バージョン 2.6 で追加.

このモジュールは Python に PEP 3119 [http://www.python.org/dev/peps/pep-3119] で概要が示された抽象基底クラス (abstract base class, ABC) を定義する基盤を提供します。なぜこれが Python に付け加えられたかについてはその PEP を参照してください。 (ABC に基づいた数の型階層を扱った PEP 3141 [http://www.python.org/dev/peps/pep-3141] と numbers モジュールも参照してください。)

collections モジュールには ABC から派生した具象クラスがいくつかあります。これらから、もちろんですが、さらに派生させることもできます。また collections モジュールにはいくつかの ABC もあって、あるクラスやインスタンスが特定のインタフェースを提供しているかどうか、たとえばハッシュ可能かあるいはマッピングか、をテストできます。

このモジュールは以下のクラスを提供します:

class abc.ABCMeta

抽象基底クラス(ABC)を定義するためのメタクラス。

ABC を作るときにこのメタクラスを使います。ABC は直接的にサブクラス化することができ、ミックスイン(mix-in)クラスのように振る舞います。また、無関係な具象クラス(組み込み型でも構いません)と無関係な ABC を “仮想的サブクラス” として登録できます – これらとその子孫は組み込み関数 issubclass() によって登録した ABC のサブクラスと判定されますが、登録した ABC は MRO (Method Resolution Order, メソッド解決順)には現れませんし、この ABC のメソッド実装が(super() を通してだけでなく)呼び出し可能になるわけでもありません。 [1]

メタクラス ABCMeta を使って作られたクラスには以下のメソッドがあります:

register(subclass)

subclass を “仮想的サブクラス” としてこの ABC に登録します。たとえば:

from abc import ABCMeta

class MyABC:
    __metaclass__ = ABCMeta

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)

また、次のメソッドを抽象基底クラスの中でオーバーライドできます:

__subclasshook__(subclass)

(クラスメソッドとして定義しなければなりません。)

subclass がこの ABC のサブクラスと見なせるかどうかチェックします。これによって ABC のサブクラスと見なしたい全てのクラスについて register() を呼び出すことなく issubclass の振る舞いをさらにカスタマイズできます。 (このクラスメソッドは ABC の __subclasscheck__() メソッドから呼び出されます。)

このメソッドは True, False または NotImplemented を返さなければなりません。 True を返す場合は、 subclass はこの ABC のサブクラスと見なされます。 False を返す場合は、たとえ通常の意味でサブクラスであっても ABC のサブクラスではないと見なされます。 NotImplemented の場合、サブクラスチェックは通常のメカニズムに戻ります。

この概念のデモとして、次の ABC 定義の例を見てください:

class Foo(object):
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)

ABC MyIterable は標準的なイテラブルのメソッド __iter__() を抽象メソッドとして定義します。ここで与えられている実装はサブクラスから呼び出されることがそれでもあり得ます。 get_iterator() メソッドも MyIterable 抽象基底クラスの一部ですが、抽象的でない派生クラスでオーバーライドされなくても構いません。

ここで定義されるクラスメソッド __subclasshook__() の意味は、__iter__() メソッドがクラスの(または __mro__ でアクセスされる基底クラスの一つの) __dict__ にある場合にもそのクラスが MyIterable だと見なされるということです。

最後に、一番下の行は Foo を __iter__() メソッドを定義しないにもかかわらず MyIterable の仮想的サブクラスにします (Foo は古い様式の __len__() と __getitem__() を用いた繰り返しのプロトコルを使っています)。これによって Foo のメソッドとして get_iterator が手に入るわけではないことに注意してください。それは別に提供されています。

以下のデコレータも提供しています:

abc.abstractmethod(function)

抽象メソッドを示すデコレータです。

このデコレータを使うにはクラスのメタクラスが ABCMeta であるかまたは派生したものであることが求められます。 ABCMeta から派生したメタクラスを持つクラスは全ての抽象メソッドおよびプロパティをオーバーライドしない限りインスタンス化できません。抽象メソッドは普通の ‘super’ 呼び出し機構を使って呼び出すことができます。

クラスに動的に抽象メソッドを追加する、あるいはメソッドやクラスが作られた後から抽象的かどうかの状態を変更しようと試みることは、サポートされません。 abstractmethod() が影響を与えるのは正規の継承により派生したサブクラスのみで、ABC の register() メソッドで登録された “仮想的サブクラス” は影響されません。

使用例:

class C:
    __metaclass__ = ABCMeta
    @abstractmethod
    def my_abstract_method(self, ...):
        ...

ノート

Java の抽象メソッドと違い、これらの抽象メソッドは実装を持ち得ます。この実装は super() メカニズムを通してそれをオーバーライドしたクラスから呼び出すことができます。これは協調的多重継承を使ったフレームワークにおいて super 呼び出しの終点として有効です。

abc.abstractproperty([fget[, fset[, fdel[, doc]]]])

組み込みの property() のサブクラスで、抽象プロパティであることを示します。

この関数を使うにはクラスのメタクラスが ABCMeta であるかまたは派生したものであることが求められます。 ABCMeta から派生したメタクラスを持つクラスは全ての抽象メソッドおよびプロパティをオーバーライドしない限りインスタンス化できません。抽象プロパティは普通の ‘super’ 呼び出し機構を使って呼び出すことができます。

使用例:

class C:
    __metaclass__ = ABCMeta
    @abstractproperty
    def my_abstract_property(self):
        ...

この例は読み取り専用のプロパティを定義しています。読み書きできる抽象プロパティを「長い」形式のプロパティ宣言を使って定義することもできます:

class C:
    __metaclass__ = ABCMeta
    def getx(self): ...
    def setx(self, value): ...
    x = abstractproperty(getx, setx)

注記

[1]
C++ プログラマは Python の仮想的基底クラスの概念は C++ のものと同じではないということを銘記すべきです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.9. atexit — 終了ハンドラ

バージョン 2.0 で追加.

atexit モジュールでは、後始末関数を登録するための関数を一つだけ定義しています。この関数を使って登録した後始末関数は、インタプリタが終了するときに自動的に実行されます。

参考

最新バージョンの atexit Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/atexit.py?view=markup]

ノート

プログラムが Python で処理されないシグナルで停止させられたとき、Python の致命的な内部エラーが検出されたとき、あるいは os._exit() が呼び出されたときには、このモジュールを通して登録した関数は呼び出されません。

このモジュールは、 sys.exitfunc 変数の提供している機能の代用となるインタフェースです。

ノート

sys.exitfunc を設定する他のコードとともに使用した場合には、このモジュールは正しく動作しないでしょう。特に、他のコア Python モジュールでは、プログラマの意図を知らなくても atexit を自由に使えます。 sys.exitfunc を使っている人は、代わりに atexit を使うコードに変換してください。 sys.exitfunc を設定するコードを変換するには、 atexit を import し、 sys.exitfunc へ束縛されていた関数を登録するのが最も簡単です。

atexit.register(func[, *args[, **kargs]])

終了時に実行される関数として func を登録します。すべての func へ渡すオプションの引数を、 register() へ引数としてわたさなければなりません。

通常のプログラムの終了時、例えば sys.exit() が呼び出されるとき、あるいは、メインモジュールの実行が完了したときに、登録された全ての関数を、最後に登録されたものから順に呼び出します。通常、より低レベルのモジュールはより高レベルのモジュールより前に import されるので、後で後始末が行われるという仮定に基づいています。

終了ハンドラの実行中に例外が発生すると、(SystemExit 以外の場合は)トレースバックを表示して、例外の情報を保存します。全ての終了ハンドラに動作するチャンスを与えた後に、最後に送出された例外を再送出します。

バージョン 2.6 で変更: この関数をデコレータとして利用できるように、 func を返すようになりました。以前は None を返していたので、デコレータとして利用しようとすると、関数名の変数に None が代入されてしまっていました。

参考

Module readline

readline ヒストリファイルを読み書きするための atexit の有用な例です。

27.9.1. atexit の例

次の簡単な例では、あるモジュールを import した時にカウンタを初期化しておき、プログラムが終了するときにアプリケーションがこのモジュールを明示的に呼び出さなくてもカウンタが更新されるようにする方法を示しています。

try:
    _count = int(open("/tmp/counter").read())
except IOError:
    _count = 0

def incrcounter(n):
    global _count
    _count = _count + n

def savecounter():
    open("/tmp/counter", "w").write("%d" % _count)

import atexit
atexit.register(savecounter)

register() に指定した固定引数とキーワードパラメタは登録した関数を呼び出す際に渡されます。

def goodbye(name, adjective):
    print 'Goodbye, %s, it was %s to meet you.' % (name, adjective)

import atexit
atexit.register(goodbye, 'Donny', 'nice')

# or:
atexit.register(goodbye, adjective='nice', name='Donny')

デコレータ(decorator)として利用する例:

import atexit

@atexit.register
def goodbye():
    print "You are now leaving the Python sector."

もちろん、デコレータとして利用できるのは、その関数が引数を受け取らない場合に限られます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.10. traceback — スタックトレースの表示または取得

このモジュールは Python プログラムのスタックトレースを抽出し、書式を整え、表示するための標準インターフェースを提供します。モジュールがスタックトレースを表示するとき、 Python インタープリタの動作を正確に模倣します。インタープリタの”ラッパー”の場合のように、プログラムの制御の元でスタックトレースを表示したいと思ったときに役に立ちます。

モジュールは traceback オブジェクトを使います — これは変数 sys.exc_traceback (非推奨)と sys.last_traceback に保存され、 sys.exc_info() から三番目の項目として返されるオブジェクト型です。

モジュールは次の関数を定義します:

traceback.print_tb(traceback[, limit[, file]])

traceback から limit までのスタックトレース項目を出力します。 limit が省略されるか None の場合は、すべての項目が表示されます。 file が省略されるか None の場合は、 sys.stderr へ出力されます。それ以外の場合は、出力を受けるためのオープンされたファイルまたはファイル風 (file-like) オブジェクトでなければなりません。

traceback.print_exception(type, value, traceback[, limit[, file]])

例外情報と traceback から limit までのスタックトレース項目を file へ出力します。これは以下のような点で print_tb() とは異なります: (1) traceback が None でない場合は、ヘッダ Traceback (most recent call last): を出力します。 (2) スタックトレースの後に例外 type と value を出力します。 (3) type が SyntaxError であり、 value が適切な形式の場合は、エラーのおおよその位置を示すカレットを付けて構文エラーが起きた行を出力します。

traceback.print_exc([limit[, file]])

これは print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file) の省略表現です。 (非推奨の変数を使う代わりにスレッドセーフな方法で同じ情報を引き出すために、実際には sys.exc_info() を使います。)

traceback.format_exc([limit])

これは、 print_exc(limit) に似ていますが、ファイルに出力する代わりに文字列を返します。

バージョン 2.4 で追加.

traceback.print_last([limit[, file]])

これは print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file) の省略表現です。一般に、例外が対話的なプロンプトに達した後にだけ機能します (sys.last_type 参照)。

traceback.print_stack([f[, limit[, file]]])

この関数は呼び出された時点からのスタックトレースを出力します。オプションの f 引数は代わりの最初のスタックフレームを指定するために使えます。オプションの limit と file 引数は print_exception() と同じ意味を持ちます。

traceback.extract_tb(traceback[, limit])

トレースバックオブジェクト traceback から limit まで取り出された”前処理済み”スタックトレース項目のリストを返します。スタックトレースの代わりの書式設定を行うために役に立ちます。 limit が省略されるか None の場合は、すべての項目が取り出されます。 “前処理済み”スタックトレース項目とは4要素のタプル (filename, line number, function name, text) で、スタックトレースに対して通常出力される情報を表しています。 text は前後の空白を取り除いた文字列です。ソースが利用できない場合は None です。

traceback.extract_stack([f[, limit]])

現在のスタックフレームから生のトレースバックを取り出します。戻り値は extract_tb() と同じ形式です。オプションの f と limit 引数は print_stack() と同じ意味を持ちます。

traceback.format_list(list)

extract_tb() または extract_stack() が返すタプルのリストが与えられると、出力の準備を整えた文字列のリストを返します。結果として生じるリストの中の各文字列は、引数リストの中の同じインデックスの要素に対応します。各文字列は末尾に改行が付いています。さらに、ソーステキスト行が None でないそれらの要素に対しては、文字列は内部に改行を含んでいるかもしれません。

traceback.format_exception_only(type, value)

トレースバックの例外部分を書式化します。引数は sys.last_type と sys.last_value のような例外の型と値です。戻り値はそれぞれが改行で終わっている文字列のリストです。通常、リストは一つの文字列を含んでいます。しかし、 SyntaxError 例外に対しては、 (出力されるときに) 構文エラーが起きた場所についての詳細な情報を示す行をいくつか含んでいます。どの例外が起きたのかを示すメッセージは、常にリストの最後の文字列です。

traceback.format_exception(type, value, tb[, limit])

スタックトレースと例外情報を書式化します。引数は print_exception() の対応する引数と同じ意味を持ちます。戻り値は文字列のリストで、それぞれの文字列は改行で終わり、そのいくつかは内部に改行を含みます。これらの行が連結されて出力される場合は、厳密に print_exception() と同じテキストが出力されます。

traceback.format_tb(tb[, limit])

format_list(extract_tb(tb, limit)) の省略表現。

traceback.format_stack([f[, limit]])

format_list(extract_stack(f, limit)) の省略表現。

traceback.tb_lineno(tb)

トレースバックオブジェクトに設定された現在の行番号を返します。 Python 2.3より前のバージョンでは、 -O フラグが渡されたときに tb.tb_lineno が正しく更新されなかったため、この関数は必要でした。 2.3以降のバージョンでは不要です。

27.10.1. トレースバックの例

この簡単な例では基本的な read-eval-print ループを実装しています。標準的な Python の対話インタープリタループに似ていますが、 Python のものより便利ではありません。インタープリタループのより完全な実装については、 code モジュールを参照してください。

import sys, traceback

def run_user_code(envdir):
    source = raw_input(">>> ")
    try:
        exec source in envdir
    except:
        print "Exception in user code:"
        print '-'*60
        traceback.print_exc(file=sys.stdout)
        print '-'*60

envdir = {}
while 1:
    run_user_code(envdir)

以下の例は、例外とトレースバックに対する print と format の違いをデモします。

import sys, traceback

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return tuple()[0]

try:
    lumberjack()
except IndexError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print "*** print_tb:"
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print "*** print_exception:"
    traceback.print_exception(exc_type, exc_value, exc_traceback,
                              limit=2, file=sys.stdout)
    print "*** print_exc:"
    traceback.print_exc()
    print "*** format_exc, first and last line:"
    formatted_lines = traceback.format_exc().splitlines()
    print formatted_lines[0]
    print formatted_lines[-1]
    print "*** format_exception:"
    print repr(traceback.format_exception(exc_type, exc_value,
                                          exc_traceback))
    print "*** extract_tb:"
    print repr(traceback.extract_tb(exc_traceback))
    print "*** format_tb:"
    print repr(traceback.format_tb(exc_traceback))
    print "*** tb_lineno:", exc_traceback.tb_lineno

この例の出力は次のようになります。

*** print_tb:
  File "<doctest...>", line 10, in <module>
    lumberjack()
*** print_exception:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_death()
IndexError: tuple index out of range
*** print_exc:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_death()
IndexError: tuple index out of range
*** format_exc, first and last line:
Traceback (most recent call last):
IndexError: tuple index out of range
*** format_exception:
['Traceback (most recent call last):\n',
 '  File "<doctest...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\n',
 'IndexError: tuple index out of range\n']
*** extract_tb:
[('<doctest...>', 10, '<module>', 'lumberjack()'),
 ('<doctest...>', 4, 'lumberjack', 'bright_side_of_death()'),
 ('<doctest...>', 7, 'bright_side_of_death', 'return tuple()[0]')]
*** format_tb:
['  File "<doctest...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\n']
*** tb_lineno: 10

次の例は、スタックの print と format の違いを示しています。

>>> import traceback
>>> def another_function():
...     lumberstack()
...
>>> def lumberstack():
...     traceback.print_stack()
...     print repr(traceback.extract_stack())
...     print repr(traceback.format_stack())
...
>>> another_function()
  File "<doctest>", line 10, in <module>
    another_function()
  File "<doctest>", line 3, in another_function
    lumberstack()
  File "<doctest>", line 6, in lumberstack
    traceback.print_stack()
[('<doctest>', 10, '<module>', 'another_function()'),
 ('<doctest>', 3, 'another_function', 'lumberstack()'),
 ('<doctest>', 7, 'lumberstack', 'print repr(traceback.extract_stack())')]
['  File "<doctest>", line 10, in <module>\n    another_function()\n',
 '  File "<doctest>", line 3, in another_function\n    lumberstack()\n',
 '  File "<doctest>", line 8, in lumberstack\n    print repr(traceback.format_stack())\n']

最後の例は、残りの幾つかの関数のデモをします。

>>> import traceback
>>> traceback.format_list([('spam.py', 3, '<module>', 'spam.eggs()'),
...                        ('eggs.py', 42, 'eggs', 'return "bacon"')])
['  File "spam.py", line 3, in <module>\n    spam.eggs()\n',
 '  File "eggs.py", line 42, in eggs\n    return "bacon"\n']
>>> an_error = IndexError('tuple index out of range')
>>> traceback.format_exception_only(type(an_error), an_error)
['IndexError: tuple index out of range\n']

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.11. __future__ — future 文の定義

__future__ は実際にモジュールであり、次の3つの役割があります。

import 文を解析する既存のツールを混乱させることを避け、インポートしようとしているモジュールを見つけられるようにするため。

2.1 以前のリリースで future 文 が実行された場合に、最低でもランタイム例外を投げるようにするため。 (__future__ のインポートは失敗します。なぜなら、 2.1 以前にはそういう名前のモジュールはなかったからです。)

互換性のない変化がいつ言語に導入され、いつ言語の一部になる — あるいは、なった — のかを文書化するため。これは実行できる形式で書かれたドキュメントなので、 __future__ をインポートしてその中身を調べることでプログラムから調査することができます。

__future__.py のそれぞれの文は次のような形式をしています:

FeatureName = _Feature(OptionalRelease, MandatoryRelease,
                       CompilerFlag)

ここで、普通は、 OptionalRelease は MandatoryRelease より小さく、2つとも sys.version_info と同じフォーマットの5つのタプルからなります。

(PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int
 PY_MINOR_VERSION, # the 1; an int
 PY_MICRO_VERSION, # the 0; an int
 PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string
 PY_RELEASE_SERIAL # the 3; an int
)

OptionalRelease はその機能が導入された最初のリリースを記録します。

まだ時期が来ていない MandatoryRelease の場合、 MandatoryRelease はその機能が言語の一部となるリリースを記します。

その他の場合、 MandatoryRelease はその機能がいつ言語の一部になったのかを記録します。そのリリースから、あるいはそれ以降のリリースでは、この機能を使う際に future 文は必要ではありませんが、 future 文を使い続けても構いません。

MandatoryRelease は None になるかもしれません。つまり、予定された機能が破棄されたということです。

_Feature クラスのインスタンスには対応する2つのメソッド、 getOptionalRelease() と getMandatoryRelease() があります。

CompilerFlag は、動的にコンパイルされるコードでその機能を有効にするために、組み込み関数 compile() の第4引数に渡す(ビットフィールド)フラグです。このフラグは _Feature インスタンスの compilier_flag 属性に保存されています。

機能の記述が __future__ から削除されたことはまだありません。 Python 2.1 で future 文が導入されて以来、この仕組みを使って以下の機能が言語に導入されてきました。

feature | optional in | mandatory in | effect
nested_scopes | 2.1.0b1 | 2.2 | PEP 227 [http://www.python.org/dev/peps/pep-0227]: Statically Nested Scopes
generators | 2.2.0a1 | 2.3 | PEP 255 [http://www.python.org/dev/peps/pep-0255]: Simple Generators
division | 2.2.0a2 | 3.0 | PEP 238 [http://www.python.org/dev/peps/pep-0238]: Changing the Division Operator
absolute_import | 2.5.0a1 | 2.7 | PEP 328 [http://www.python.org/dev/peps/pep-0328]: Imports: Multi-Line and Absolute/Relative
with_statement | 2.5.0a1 | 2.6 | PEP 343 [http://www.python.org/dev/peps/pep-0343]: The “with” Statement
print_function | 2.6.0a2 | 3.0 | PEP 3105 [http://www.python.org/dev/peps/pep-3105]: Make print a function
unicode_literals | 2.6.0a2 | 3.0 | PEP 3112 [http://www.python.org/dev/peps/pep-3112]: Bytes literals in Python 3000

参考

future 文 (future statement)

コンパイラがどのように future インポートを扱うか

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.12. gc — ガベージコレクタインターフェース

このモジュールは、循環ガベージコレクタの無効化・検出頻度の調整・デバッグオブションの設定などを行うインターフェースを提供します。また、検出した到達不能オブジェクトのうち、解放する事ができないオブジェクトを参照する事もできます。循環ガベージコレクタはPyhonの参照カウントを補うためのものなので、もしプログラム中で循環参照が発生しない事が明らかな場合には検出をする必要はありません。自動検出は、 gc.disable() で停止する事ができます。メモリリークをデバッグするときには、 gc.set_debug(gc.DEBUG_LEAK) とします。これは gc.DEBUG_SAVEALL を含んでいることに注意しましょう。ガベージとして検出されたオブジェクトは、インスペクション用に gc.garbage に保存されます。

gc モジュールは、以下の関数を提供しています。

gc.enable()

自動ガベージコレクションを有効にします。

gc.disable()

自動ガベージコレクションを無効にします。

gc.isenabled()

自動ガベージコレクションが有効なら真を返します。

gc.collect([generation])

引数を指定しない場合は、全ての検出を行います。オプションの引数 generation は、どの世代を検出するかを (0 から 2 までの) 整数値で指定します。無効な世代番号を指定した場合は ValueError が発生します。検出した到達不可オブジェクトの数を返します。

バージョン 2.5 で変更: オプションの引数 generation が追加されました.

バージョン 2.6 で変更: 幾つかの組み込み型のフリーリストは、最高(第二)世代のGC、あるいはフルGCが実行されるたびにクリアされます。幾つかの型(特に int と float)では、実装によっては、フリーリスト内の全てのオブジェクトが開放されるとは限りません。

gc.set_debug(flags)

ガベージコレクションのデバッグフラグを設定します。デバッグ情報は sys.stderr に出力されます。デバッグフラグは、下の値の組み合わせを指定する事ができます。

gc.get_debug()

現在のデバッグフラグを返します。

gc.get_objects()

現在追跡しているオブジェクトのリストを返します。このリストには、戻り値のリスト自身は含まれていません。

バージョン 2.2 で追加.

gc.set_threshold(threshold0[, threshold1[, threshold2]])

ガベージコレクションの閾値（検出頻度）を指定します。 threshold0 を 0 にすると、検出は行われません。

GCは、オブジェクトを走査された回数に従って3世代に分類します。新しいオブジェクトは最も若い(0 世代)に分類されます。もし、そのオブジェクトがガベージコレクションで削除されなければ、次に古い世代に分類されます。もっとも古い世代は 2 世代で、この世代に属するオブジェクトは他の世代に移動しません。ガベージコレクタは、最後に検出を行ってから生成・削除したオブジェクトの数をカウントしており、この数によって検出を開始します。オブジェクトの生成数 - 削除数が threshold0 より大きくなると、検出を開始します。最初は 0 世代のオブジェクトのみが検査されます。 0 世代の検査が threshold1 回実行されると、 1 世代のオブジェクトの検査を行います。同様に、 1 世代が threshold2 回検査されると、 2 世代の検査を行います。

gc.get_count()

現在の検出数を、 (count0, count1, count2) のタプルで返します。

バージョン 2.5 で追加.

gc.get_threshold()

現在の検出閾値を、 (threshold0, threshold1, threshold2) のタプルで返します。

gc.get_referrers(*objs)

objsで指定したオブジェクトのいずれかを参照しているオブジェクトのリストを返します。この関数では、ガベージコレクションをサポートしているコンテナのみを返します。他のオブジェクトを参照していても、ガベージコレクションをサポートしていない拡張型は含まれません。

尚、戻り値のリストには、すでに参照されなくなっているが、循環参照の一部でまだガベージコレクションで回収されていないオブジェクトも含まれるので注意が必要です。有効なオブジェクトのみを取得する場合、 get_referrers() の前に collect() を呼び出してください。

get_referrers() から返されるオブジェクトは作りかけや利用できない状態である場合があるので、利用する際には注意が必要です。 get_referrers() をデバッグ以外の目的で利用するのは避けてください。

バージョン 2.2 で追加.

gc.get_referents(*objs)

引数で指定したオブジェクトのいずれかから参照されている、全てのオブジェクトのリストを返します。参照先のオブジェクトは、引数で指定したオブジェクトの Cレベルメソッド tp_traverse で取得し、全てのオブジェクトが直接到達可能な全てのオブジェクトを返すわけではありません。 tp_traverse はガベージコレクションをサポートするオブジェクトのみが実装しており、ここで取得できるオブジェクトは循環参照の一部となる可能性のあるオブジェクトのみです。従って、例えば整数オブジェクトが直接到達可能であっても、このオブジェクトは戻り値には含まれません。

バージョン 2.3 で追加.

gc.is_tracked(obj)

obj がGCに管理されていたら True を返し、それ以外の場合は False を返します。一般的なルールとして、アトミックな(訳注:他のオブジェクトを参照しないで単一で値を表す型。 int や str など)型のインスタンスは管理されず、それ以外の型 (コンテナ型、ユーザー定義型など) のインスタンスは管理されます。しかし、いくつかの型では専用の最適化を行い、シンプルなインスタンスの場合に GCのオーバーヘッドを減らしています。 (例: 全ての key と value がアトミック型の値である dict)

>>> gc.is_tracked(0)
False
>>> gc.is_tracked("a")
False
>>> gc.is_tracked([])
True
>>> gc.is_tracked({})
False
>>> gc.is_tracked({"a": 1})
False
>>> gc.is_tracked({"a": []})
True

バージョン 2.7 で追加.

以下の変数は読み込み専用です。(変更することはできますが、再バインドする事はできません。）

gc.garbage

到達不能であることが検出されたが、解放する事ができないオブジェクトのリスト（回収不能オブジェクト）。デフォルトでは、 __del__() メソッドを持つオブジェクトのみが格納されます。 [1]

__del__() メソッドを持つオブジェクトが循環参照に含まれている場合、その循環参照全体と、循環参照からのみ到達する事ができるオブジェクトは回収不能となります。このような場合には、Pythonは安全に __del__() を呼び出す順番を決定する事ができないため、自動的に解放することはできません。もし安全な解放順序がわかるのであれば、 garbage リストを参照して循環参照を破壊する事ができます。循環参照を破壊した後でも、そのオブジェクトは garbage リストから参照されているため、解放されません。解放するためには、循環参照を破壊した後、 del gc.garbage[:] のように garbage からオブジェクトを削除する必要があります。一般的には __del__() を持つオブジェクトが循環参照の一部とはならないように配慮し、 garbage はそのような循環参照が発生していない事を確認するために利用する方が良いでしょう。

DEBUG_SAVEALL が設定されている場合、全ての到達不能オブジェクトは解放されずにこのリストに格納されます。

以下は set_debug() に指定することのできる定数です。

gc.DEBUG_STATS

検出中に統計情報を出力します。この情報は、検出頻度を最適化する際に有益です。

gc.DEBUG_COLLECTABLE

見つかった回収可能オブジェクトの情報を出力します。

gc.DEBUG_UNCOLLECTABLE

見つかった回収不能オブジェクト（到達不能だが、ガベージコレクションで解放する事ができないオブジェクト）の情報を出力します。回収不能オブジェクトは、 garbade リストに追加されます。

gc.DEBUG_INSTANCES

DEBUG_COLLECTABLE か DEBUG_UNCOLLECTABLE が設定されている場合、見つかったインスタンスオブジェクトの情報を出力します。

gc.DEBUG_OBJECTS

DEBUG_COLLECTABLE か DEBUG_UNCOLLECTABLE が設定されている場合、見つかったインスタンスオブジェクト以外のオブジェクトの情報を出力します。

gc.DEBUG_SAVEALL

設定されている場合、全ての到達不能オブジェクトは解放されずに garbage に追加されます。これはプログラムのメモリリークをデバッグするときに便利です。

gc.DEBUG_LEAK

プログラムのメモリリークをデバッグするときに指定します。（ DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_INSTANCES |  DEBUG_OBJECTS | DEBUG_SAVEALL と同じ。）

注記

[1]
Python 2.2より前のバージョンでは、 __del__() メソッドを持つオブジェクトだけでなく、全ての到達不能オブジェクトが格納されていた。）

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.13. inspect — 活動中のオブジェクトの情報を取得する

バージョン 2.1 で追加.

inspect は、 活動中のオブジェクト (モジュール、クラス、メソッド、関数、トレースバック、フレームオブジェクト、コードオブジェクトなど) から情報を取得する関数を定義しており、クラスの内容を調べたり、メソッドのソースコードを取得したり、関数の引数リストを取り出して整形したり、詳細なトレースバックを表示するのに必要な情報を取得したりするために利用できます。

このモジュールの機能は4種類に分類することができます。型チェック、ソースコードの情報取得、クラスや関数からの情報取得、インタープリタのスタック情報の調査です。

27.13.1. 型とメンバー

getmembers() は、クラスやモジュールなどのオブジェクトからメンバーを取得します。名前が”is”で始まる16個の関数は、主に getmembers() の第2引数として利用するために提供されています。以下のような特殊属性を参照できるかどうか調べる時にも使えるでしょう。

型 | 属性 | 説明 | 注
module | __doc__ | ドキュメント文字列 |
| __file__ | ファイル名 (組み込みモジュールには存在しません) |
class | __doc__ | ドキュメント文字列 |
| __module__ | クラスを定義しているモジュールの名前 |
method | __doc__ | ドキュメント文字列 |
| __name__ | メソッドが定義された時の名前 |
| im_class | メソッドを呼び出すために必要なクラスオブジェクト | (1)
| im_func または __func__ | メソッドを実装している関数オブジェクト |
| im_self または __self__ | メソッドに結合しているインスタンス、または None |
function | __doc__ | ドキュメント文字列 |
| __name__ | 関数が定義された時の名前 |
| func_code | 関数をコンパイルしたバイトコード (bytecode) を格納するコードオブジェクト |
| func_defaults | 引数のデフォルト値のタプル |
| func_doc | (__doc__と同じ) |
| func_globals | 関数を定義した時のグローバル名前空間 |
| func_name | (__name__と同じ) |
generator | __iter__ | コンテナを通したイテレーションのために定義されます |
| close | イテレーションを停止するために、ジェネレータの内部で GeneratorExitexception を発生させます |
| gi_code | コードオブジェクト |
| gi_frame | フレームオブジェクト。ジェネレータが終了したあとは None になることもあります |
| gi_running | ジェネレータが実行中の時は 1 それ以外の場合は 0 |
| next | コンテナから次の要素を返します |
| send | ジェネレータを再開して、現在の yield 式の結果となる値を送ります |
| throw | ジェネレータ内部で例外を発生させるために用います |
traceback | tb_frame | このレベルのフレームオブジェクト |
| tb_lasti | 最後に実行しようとしたバイトコード中のインストラクションを示すインデックス |
| tb_lineno | 現在の Python ソースコードの行番号 |
| tb_next | このオブジェクトの内側 (このレベルから呼び出された) のトレースバックオブジェクト |
frame | f_back | 外側 (このフレームを呼び出した) のフレームオブジェクト |
| f_builtins | このフレームで参照している組み込み名前空間 |
| f_code | このフレームで実行しているコードオブジェクト |
| f_exc_traceback | このフレームで例外が発生した場合にはトレースバックオブジェクト、それ以外なら None |
| f_exc_type | このフレームで例外が発生した場合には例外型、それ以外なら None |
| f_exc_value | このフレームで例外が発生した場合には例外の値、それ以外なら None |
| f_globals | このフレームで参照しているグローバル名前空間 |
| f_lasti | 最後に実行しようとしたバイトコードのインデックス |
| f_lineno | 現在の Python ソースコードの行番号 |
| f_locals | このフレームで参照しているローカル名前空間 |
| f_restricted | 制限実行モードなら1、それ以外なら0 |
| f_trace | このフレームのトレース関数、または None |
code | co_argcount | 引数の数 (* や ** 引数は含まない) |
| co_code | コンパイルされたバイトコードそのままの文字列 |
| co_consts | バイトコード中で使用している定数のタプル |
| co_filename | コードオブジェクトを生成したファイルのファイル名 |
| co_firstlineno | Python ソースコードの先頭行 |
| co_flags | 以下の値の組み合わせ: 1=optimized | 2=newlocals | 4=*arg | 8=**arg |
| co_lnotab | 行番号からバイトコードインデックスへの変換表を文字列にエンコードしたもの |
| co_name | コードオブジェクトが定義されたときの名前 |
| co_names | ローカル変数名のタプル |
| co_nlocals | ローカル変数の数 |
| co_stacksize | 必要とされる仮想マシンのスタックスペース |
| co_varnames | 引数名とローカル変数名のタプル |
builtin | __doc__ | ドキュメント文字列 |
| __name__ | 関数、メソッドの元々の名前 |
| __self__ | メソッドが結合しているインスタンス、または None |

Note:

バージョン 2.2 で変更: im_class は、以前はメソッドを定義しているクラスを指していました。

inspect.getmembers(object[, predicate])

オブジェクトの全メンバーを、 (名前, 値) の組み合わせのリストで返します。リストはメンバー名でソートされています。 predicate が指定されている場合、 predicate の戻り値が真となる値のみを返します。

ノート

getmembers() は、引数がクラスの場合にメタクラス属性を返しません。 (この動作は dir() 関数に合わせてあります。)

inspect.getmoduleinfo(path)

path で指定したファイルがモジュールであれば、そのモジュールが Python でどのように解釈されるかを示す (name, suffix, mode, module_type) のタプルを返します。モジュールでなければ None を返します。 name はパッケージ名を含まないモジュール名、 suffix はファイル名からモジュール名を除いた残りの部分 (ドット区切りの拡張子であってはなりません)、 mode は open() で指定されるファイルモード ('r' または 'rb')、 module_type はモジュールタイプを示す整数で、 imp で定義している定数のいずれかが指定されます。モジュールタイプについては imp を参照してください。

バージョン 2.6 で変更: 名前付きタプル (named tuple) の ModuleInfo(name, suffix, mode, module_type) を返します。

inspect.getmodulename(path)

path で指定したファイルの、パッケージ名を含まないモジュール名を返します。この処理は、インタープリタがモジュールを検索する時と同じアルゴリズムで行われます。ファイルがこのアルゴリズムで見つからない場合には None が返ります。

inspect.ismodule(object)

オブジェクトがモジュールの場合は真を返します。

inspect.isclass(object)

オブジェクトが、ビルトインもしくは Python で作られたクラスの場合に真を返します。

inspect.ismethod(object)

オブジェクトがメソッドの場合は真を返します。

inspect.isfunction(object)

オブジェクトが Python の関数(lambda 式で生成されたものを含む) である場合に真を返します。

inspect.isgeneratorfunction(object)

object が Python のジェネレータ関数であるときに真を返します。

バージョン 2.6 で追加.

inspect.isgenerator(object)

object がジェネレータであるときに真を返します。

バージョン 2.6 で追加.

inspect.istraceback(object)

オブジェクトがトレースバックの場合は真を返します。

inspect.isframe(object)

オブジェクトがフレームの場合は真を返します。

inspect.iscode(object)

オブジェクトがコードの場合は真を返します。

inspect.isbuiltin(object)

オブジェクトが組み込み関数か束縛済みのビルトインメソッドの場合に真を返します。

inspect.isroutine(object)

オブジェクトがユーザ定義か組み込みの関数またはメソッドの場合は真を返します。

inspect.isabstract(object)

object が抽象規定型 (ABC) であるときに真を返します。

バージョン 2.6 で追加.

inspect.ismethoddescriptor(object)

オブジェクトがメソッドデスクリプタであり、 ismethod(), isclass(), isfunction(), isbuiltin() でない場合に真を返します。

この機能は Python 2.2 から新たに追加されたもので、例えば int.__add__ は真になります。このテストをパスするオブジェクトは __get__ 属性を持ちますが __set__ 属性を持ちません。それ以外の属性を持っているかもしれません。通常 __name__ を持っていますし、しばしば __doc__ も持っています。

デスクリプタを使って実装されたメソッドで、上記のいずれかのテストもパスしているものは、 ismethoddescriptor() では偽を返します。これは単に他のテストの方がもっと確実だからです – 例えば、 ismethod() をパスしたオブジェクトは im_func 属性などを持っていると期待できます。

inspect.isdatadescriptor(object)

オブジェクトがデータデスクリプタの場合に真を返します。

データデスクリプタは __get__ および __set__ 属性の両方を持ちます。データデスクリプタの例は (Python 上で定義された) プロパティや getset やメンバーです。後者のふたつは C で定義されており、個々の型に特有のテストも行います。そのため、Python の実装よりもより確実です。通常、データデスクリプタは __name__ や __doc__ 属性を持ちます (プロパティ、 getset 、メンバーは両方の属性を持っています) が、保証されているわけではありません。

バージョン 2.3 で追加.

inspect.isgetsetdescriptor(object)

オブジェクトが getset デスクリプタの場合に真を返します。

CPython implementation detail:

getset とは、拡張モジュールで PyGetSetDef 構造体を用いて定義された属性のことです。そのような型を持たない Python 実装の場合は、このメソッドは常に False を返します。

バージョン 2.5 で追加.

inspect.ismemberdescriptor(object)

オブジェクトがメンバーデスクリプタの場合に真を返します。

CPython implementation detail:

メンバーデスクリプタとは、拡張モジュールで PyMemberDef 構造体を用いて定義された属性のことです。そのような型を持たない Python 実装の場合は、このメソッドは常に False を返します。

バージョン 2.5 で追加.

27.13.2. ソースコードの情報取得

inspect.getdoc(object)

cleandoc() でクリーンアップされた、オブジェクトのドキュメンテーション文字列を取得します。

inspect.getcomments(object)

オブジェクトがクラス、関数、メソッドのいずれかの場合は、オブジェクトのソースコードの直後にあるコメント行 (複数行) を、単一の文字列として返します。オブジェクトがモジュールの場合、ソースファイルの先頭にあるコメントを返します。

inspect.getfile(object)

オブジェクトを定義している (テキストまたはバイナリの) ファイルの名前を返します。オブジェクトが組み込みモジュール、クラス、関数の場合は TypeError 例外が発生します。

inspect.getmodule(object)

オブジェクトを定義しているモジュールを推測します。

inspect.getsourcefile(object)

オブジェクトを定義している Python ソースファイルの名前を返します。オブジェクトが組み込みのモジュール、クラス、関数の場合には、 TypeError 例外が発生します。

inspect.getsourcelines(object)

オブジェクトのソース行のリストと開始行番号を返します。引数にはモジュール、クラス、メソッド、関数、トレースバック、フレーム、コードオブジェクトを指定することができます。戻り値は指定したオブジェクトに対応するソースコードのソース行リストと元のソースファイル上での開始行となります。ソースコードを取得できない場合は IOError が発生します。

inspect.getsource(object)

オブジェクトのソースコードを返します。引数にはモジュール、クラス、メソッド、関数、トレースバック、フレーム、コードオブジェクトを指定することができます。ソースコードは単一の文字列で返します。ソースコードを取得できない場合は IOError が発生します。

inspect.cleandoc(doc)

インデントされた docstring から、コードブロックまでのインデントを削除します。 2行目以降では行頭の空白は一様に削除されます。全てのタブはスペースに展開されます。

バージョン 2.6 で追加.

27.13.3. クラスと関数

inspect.getclasstree(classes[, unique])

リストで指定したクラスの継承関係から、ネストしたリストを作成します。ネストしたリストには、直前の要素から派生したクラスが格納されます。各要素は長さ2のタプルで、クラスと基底クラスのタプルを格納しています。 unique が真の場合、各クラスは戻り値のリスト内に一つだけしか格納されません。真でなければ、多重継承を利用したクラスとその派生クラスは複数回格納される場合があります。

inspect.getargspec(func)

Python 関数の引数名とデフォルト値を取得します。戻り値は長さ4のタプルで、次の値を返します: (args, varargs, keywords, defaults) 。 args は引数名のリストです (ネストしたリストが格納される場合があります)。 varargs と keywords は * 引数と ** 引数の名前で、引数がなければ None となります。 defaults は引数のデフォルト値のタプルか、デフォルト値がない場合は None です。このタプルに n 個の要素があれば、各要素は args の後ろから n 個分の引数のデフォルト値となります。

バージョン 2.6 で変更: ArgSpec(args, varargs, keywords, defaults) 形式の名前付きタプル (named tuple) を返します。

inspect.getargvalues(frame)

指定したフレームに渡された引数の情報を取得します。戻り値は長さ4のタプルで、次の値を返します: (args, varargs, keywords, locals). args は引数名のリストです (ネストしたリストが格納される場合があります)。 varargs と keywords は * 引数と ** 引数の名前で、引数がなければ None となります。 locals は指定したフレームのローカル変数の辞書です。

バージョン 2.6 で変更: ArgInfo(args, varargs, keywords, locals) 形式の名前付きタプル (named tuple) を返します。

inspect.formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])

getargspec() で取得した4つの値を読みやすく整形します。 format* 引数はオプションで、名前と値を文字列に変換する整形関数を指定することができます。

inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])

getargvalues() で取得した4つの値を読みやすく整形します。 format* 引数はオプションで、名前と値を文字列に変換する整形関数を指定することができます。

inspect.getmro(cls)

cls クラスの基底クラス (cls 自身も含む) を、メソッドの優先順位順に並べたタプルを返します。結果のリスト内で各クラスは一度だけ格納されます。メソッドの優先順位はクラスの型によって異なります。非常に特殊なユーザ定義のメタクラスを使用していない限り、 cls が戻り値の先頭要素となります。

inspect.getcallargs(func[, *args][, **kwds])

args と kwds を、 Python の関数もしくはメソッド func を呼び出した場合と同じように引数名に束縛します。束縛済みメソッド(bound method)の場合、最初の引数(慣習的に self という名前が付けられます)にも、関連づけられたインスタンスを束縛します。引数名 (* や ** 引数が存在すればその名前も) に args と kwds からの値をマップした辞書を返します。 func を正しく呼び出せない場合、つまり func(*args, **kwds) がシグネチャの不一致のために例外を投げるような場合には、それと同じ型で同じか似ているメッセージの例外を発生させます。例:

>>> from inspect import getcallargs
>>> def f(a, b=1, *pos, **named):
...     pass
>>> getcallargs(f, 1, 2, 3)
{'a': 1, 'named': {}, 'b': 2, 'pos': (3,)}
>>> getcallargs(f, a=2, x=4)
{'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()}
>>> getcallargs(f)
Traceback (most recent call last):
...
TypeError: f() takes at least 1 argument (0 given)

バージョン 2.7 で追加.

27.13.4. インタープリタスタック

以下の関数には、戻り値として”フレームレコード”を返す関数があります。 “フレームレコード”は長さ6のタプルで、以下の値を格納しています: フレームオブジェクト、ファイル名、実行中の行番号、関数名、コンテキストのソース行のリスト、ソース行のリストにおける実行中の行のインデックス。

ノート

フレームレコードの最初の要素などのフレームオブジェクトへの参照を保存すると、循環参照になってしまう場合があります。循環参照ができると、 Python の循環参照検出機能を有効にしていたとしても関連するオブジェクトが参照しているすべてのオブジェクトが解放されにくくなり、明示的に参照を削除しないとメモリ消費量が増大する恐れがあります。

参照の削除を Python の循環参照検出機能にまかせることもできますが、 finally 節で循環参照を解除すれば確実にフレーム (とそのローカル変数) は削除されます。また、循環参照検出機能は Python のコンパイルオプションや gc.disable() で無効とされている場合がありますので注意が必要です。例：

def handle_stackframe_without_leak():
    frame = inspect.currentframe()
    try:
        # do something with the frame
    finally:
        del frame

以下の関数でオプション引数 context には、戻り値のソース行リストに何行分のソースを含めるかを指定します。ソース行リストには、実行中の行を中心として指定された行数分のリストを返します。

inspect.getframeinfo(frame[, context])

フレームまたはトレースバックオブジェクトの情報を取得します。フレームレコードの先頭要素を除いた、長さ5のタプルを返します。

バージョン 2.6 で変更: Traceback(filename, lineno, function, code_context, index) 形式の名前付きタプル (named tuple) を返します。

inspect.getouterframes(frame[, context])

指定したフレームと、その外側の全フレームのフレームレコードを返します。外側のフレームとは frame が生成されるまでのすべての関数呼び出しを示します。戻り値のリストの先頭は frame のフレームレコードで、末尾の要素は frame のスタックにある最も外側のフレームのフレームレコードとなります。

inspect.getinnerframes(traceback[, context])

指定したフレームと、その内側の全フレームのフレームレコードを返します。内のフレームとは frame から続く一連の関数呼び出しを示します。戻り値のリストの先頭は traceback のフレームレコードで、末尾の要素は例外が発生した位置を示します。

inspect.currentframe()

呼び出し元のフレームオブジェクトを返します。

CPython implementation detail:

この関数はインタプリタの Python スタックフレームサポートに依存します。これは Python のすべての実装に存在している保証はありません。 Python スタックフレームサポートのない環境では、この関数は None を返します。

inspect.stack([context])

呼び出し元スタックのフレームレコードのリストを返します。最初の要素は呼び出し元のフレームレコードで、末尾の要素はスタックにある最も外側のフレームのフレームレコードとなります。

inspect.trace([context])

実行中のフレームと処理中の例外が発生したフレームの間のフレームレコードのリストを返します。最初の要素は呼び出し元のフレームレコードで、末尾の要素は例外が発生した位置を示します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.14. site — サイト固有の設定フック

このモジュールは初期化中に自動的にインポートされます。自動インポートはインタプリタの -S オプションで禁止できます。

このモジュールをインポートすることで、サイト固有のパスをモジュール検索パスへ付け加えます。

サイト固有のパスは、前部と後部から構築される最大で四つまでのディレクトリから始めます。前部には、 sys.prefix と sys.exec_prefix を使用します。空の前部は省略されます。後部には、まず空文字列を使い、次に lib/site-packages (Windows) または lib/python|version|/site-packages, そして lib/site-python (Unix と Macintosh)を使います。前部-後部の組み合わせのそれぞれに対して、それが存在するディレクトリを参照しているかどうかを調べ、もしそうならば sys.path へ追加します。そして、パス設定ファイルを新しく追加されたパスからも検索します。

パス設定ファイルは package.pth という形式の名前をもつファイルで、上の4つのディレクトリのひとつにあります。その内容は sys.path に追加される追加項目(一行に一つ)です。存在しない項目は sys.path へは決して追加されませんが、項目が(ファイルではなく) ディレクトリを参照しているかどうかはチェックされません。項目が sys.path へ二回以上追加されることはありません。空行と # で始まる行は読み飛ばされます。 import で始まる(そしてその後ろにスペースかタブが続く)行は実行されます。

バージョン 2.6 で変更: import キーワードの後ろにスペースかタブが必要になりました。

例えば、 sys.prefix と sys.exec_prefix が /usr/local に設定されていると仮定します。そのときPython X.Y ライブラリは /usr/local/lib/pythonX.Y にインストールされています(ここで、 sys.version の最初の三文字だけがインストールパス名を作るために使われます)。ここにはサブディレクトリ /usr/local/lib/pythonX.Y|/site-packages があり、その中に三つのサブディレクトリ foo, bar および spam と二つのパス設定ファイル foo.pth と bar.pth をもつと仮定します。 foo.pth には以下のものが記載されていると想定してください:

# foo package configuration

foo
bar
bletch

また、 bar.pth には:

# bar package configuration

bar

が記載されているとします。そのとき、次のバージョンごとのディレクトリが sys.path へこの順番んで追加されます:

/usr/local/lib/pythonX.Y/site-packages/bar
/usr/local/lib/pythonX.Y/site-packages/foo

bletch は存在しないため省略されるということに注意してください。 bar ディレクトリは foo ディレクトリの前に来ます。なぜなら、 bar.pth がアルファベット順で foo.pth の前に来るからです。また、 spam はどちらのパス設定ファイルにも記載されていないため、省略されます。

これらのパス操作の後に、 sitecustomize という名前のモジュールをインポートしようします。そのモジュールは任意のサイト固有のカスタマイゼーションを行うことができます。 ImportError 例外が発生してこのインポートに失敗した場合は、何も表示せずに無視されます。

いくつかの非Unixシステムでは、 sys.prefix と sys.exec_prefix は空で、パス操作は省略されます。しかし、 sitecustomize のインポートはそのときでも試みられます。

site.PREFIXES

siteパッケージディレクトリのprefixのリスト

バージョン 2.6 で追加.

site.ENABLE_USER_SITE

ユーザーサイトディレクトリのステータスを示すフラグ。 Trueの場合、ユーザーサイトディレクトリが有効で sys.path に追加されていることを意味しています。 None の場合、セキュリティ上の理由でユーザーサイトディレクトリが無効になっていることを示しています。

バージョン 2.6 で追加.

site.USER_SITE

現在のPythonバージョン用のユーザーサイトディレクトリのパス。もしくは None.

バージョン 2.6 で追加.

site.USER_BASE

ユーザーサイトディレクトリのベースディレクトリ

バージョン 2.6 で追加.

PYTHONNOUSERSITE

バージョン 2.6 で追加.

PYTHONUSERBASE

バージョン 2.6 で追加.

site.addsitedir(sitedir, known_paths=None)

ディレクトリを sys.path に追加して、その中の pth ファイルも処理する。

site.getsitepackages()

全てのグローバルの site-packages (site-python が含まれる場合もある) ディレクトリを含むリストを返します。

バージョン 2.7 で追加.

site.getuserbase()

“ユーザーベース” ディレクトリのパスを返します。

“ユーザーベース” ディレクトリをデータを保存するために使うことができます。グローバル変数 USER_BASE がまだ初期化されていない場合、その初期化を行います。

バージョン 2.7 で追加.

site.getusersitepackages()

ユーザー専用の site-packages ディレクトリパスを返します。

グローバル変数 USER_SITE が初期化されていない場合、初期化します。

バージョン 2.7 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.15. user — ユーザー設定のフック

バージョン 2.6 で撤廃: user モジュールはPython 3.0では削除されます。

ポリシーとして、Pythonは起動時にユーザー毎の設定を行うコードを実行することはしません(ただし対話型セッションで環境変数 PYTHONSTARTUP が設定されていた場合にはそのスクリプトを実行します。)。

しかしながら、プログラムやサイトによっては、プログラムが要求した時にユーザーごとの設定ファイルを実行できると便利なこともあります。このモジュールはそのような機構を実装しています。この機構を利用したいプログラムでは、以下の文を実行してください。

import user

user モジュールはユーザーのホームディレクトリの .pythonrc.py ファイルを探し、オープンできるならグローバル名前空間で実行します(execfile() を利用します)。この段階で発生したエラーはcatchされません。 user モジュールをimportしたプログラムに影響します。ホームディレクトリは環境変数 HOME が仮定されていますが、もし設定されていなければカレントディレクトリが使われます。

ユーザーの .pythonrc.py ではPythonのバージョンに従って異なる動作を行うために sys.version のテストを行うことが考えられます。

ユーザーへの警告: .pythonrc.py ファイルに書く内容には慎重になってください。どのプログラムが利用しているかわからない状況で、標準のモジュールや関数のふるまいを替えることはおすすめできません。

この機構を使おうとするプログラマへの提案: あなたのパッケージ向けのオプションをユーザーが設定できるようにするシンプルな方法は、 .pythonrc.py ファイルで変数を定義して、あなたのプログラムでテストする方法です。たとえば、 spam モジュールでメッセージ出力のレベルを替える user.spam_verbose 変数を参照するには以下のようにします:

import user

verbose = bool(getattr(user, "spam_verbose", 0))

(ユーザが spam_verbose をファイル .pythonrc.py 内で定義していない時に getattr() の3引数形式は使われます。)

大規模な設定の必要があるプログラムではプログラムごとの設定ファイルを作るといいです。

セキュリティやプライバシーに配慮するプログラムではこのモジュールをimport し ない でください。このモジュールを使うと、ユーザーは .pythonrc.py に任意のコードを書くことで簡単に侵入することができてしまいます。

汎用のモジュールではこのモジュールをimportし ない でください。 importしたプログラムの動作にも影響してしまいます。

参考

Module site

サイト毎のカスタマイズを行う機構

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.16. fpectl — 浮動小数点例外の制御

ノート

fpectl モジュールはデフォルトではビルドされません。このモジュールの利用は推奨されておらず、熟練者以外がこのモジュールを使うのは危険です。このモジュールの制限についての詳細は、 制限と他に考慮すべきこと 節を参照してください。

ほとんどのコンピュータはいわゆるIEEE-754標準に準拠した浮動小数点演算を実行します。実際のどんなコンピュータでも、浮動小数点演算が普通の浮動小数点数では表せない結果になることがあります。例えば、次を試してください。

>>> import math
>>> math.exp(1000)
inf
>>> math.exp(1000) / math.exp(1000)
nan

(上の例は多くのプラットホームで動作します。DEC Alphaは例外かもしれません。) “Inf”は”infinity(無限)”を意味するIEEE-754における特殊な非数値の値で、”nan”は”not a number(数ではない)”を意味します。ここで留意すべき点は、その計算を行うようにPythonに求めたときに非数値の結果以外に特別なことは何も起きないというです。事実、それはIEEE-754標準に規定されたデフォルトのふるまいで、それで良ければここで読むのを止めてください。

いくつかの環境では、誤った演算がなされたところで例外を発生し、処理を止めることがより良いでしょう。 fpectl モジュールはそんな状況で使うためのものです。いくつかのハードウェア製造メーカーの浮動小数点ユニットを制御できるようにします。つまり、IEEE-754例外Division by Zero、OverflowあるいはInvalid Operationが起きたときはいつでも SIGFPE が生成させるように、ユーザが切り替えられるようにします。あなたのpythonシステムを構成しているCコードの中へ挿入される一組のラッパーマクロと協力して、 SIGFPE は捕捉され、Python FloatingPointError 例外へ変換されます。

fpectl モジュールは次の関数を定義しています。また、所定の例外を発生します:

fpectl.turnon_sigfpe()

SIGFPE を生成するように切り替え、適切なシグナルハンドラを設定します。

fpectl.turnoff_sigfpe()

浮動小数点例外のデフォルトの処理に再設定します。

exception fpectl.FloatingPointError

turnon_sigfpe() が実行された後に、IEEE-754例外であるDivision by Zero、OverflowまたはInvalid operationの一つを発生する浮動小数点演算は、次にこの標準Python例外を発生します。

27.16.1. 例

以下の例は fpectl モジュールの使用を開始する方法とモジュールのテスト演算について示しています。

>>> import fpectl
>>> import fpetest
>>> fpectl.turnon_sigfpe()
>>> fpetest.test()
overflow        PASS
FloatingPointError: Overflow

div by 0        PASS
FloatingPointError: Division by zero
  [ more output from test elided ]
>>> import math
>>> math.exp(1000)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
FloatingPointError: in math_1

27.16.2. 制限と他に考慮すべきこと

特定のプロセッサをIEEE-754浮動小数点エラーを捕らえるように設定することは、現在アーキテクチャごとの基準に基づきカスタムコードを必要とします。あなたの特殊なハードウェアを制御するために fpectl を修正することもできます。

IEEE-754例外のPython例外への変換には、ラッパーマクロ PyFPE_START_PROTECT と PyFPE_END_PROTECT があなたのコードに適切な方法で挿入されていることが必要です。Python自身は fpectl モジュールをサポートするために修正されていますが、数値解析にとって興味ある多くの他のコードはそうではありません。

fpectl モジュールはスレッドセーフではありません。

参考

このモジュールがどのように動作するのかについてより学習するときに、ソースディストリビューションの中のいくつかのファイルは興味を引くものでしょう。インクルードファイル Include/pyfpe.h では、このモジュールの実装について同じ長さで議論されています。 Modules/fpetestmodule.c には、いくつかの使い方の例があります。多くの追加の例が Objects/floatobject.c にあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

27. Python ランタイムサービス »

27.17. distutils — Python モジュールの構築とインストール

distutils パッケージは、現在インストールされている Python に追加するためのモジュール構築、および実際のインストールを支援します。新規のモジュールは 100%-pure Python でも、C で書かれた拡張モジュールでも、あるいは Python と C 両方のコードが入っているモジュールからなる Python パッケージでもかまいません。

このパッケージは、二つの別の章で詳しく説明されています。

参考

Python モジュールの配布

このマニュアルは Python モジュールの開発者およびパッケージ担当に向けたものです。ここでは、現在インストールされている Python に簡単に追加できる distutils ベースのパッケージをどうやって用意するかについて説明しています。

Python モジュールのインストール

現在インストールされている Python にモジュールを追加するための情報が書かれた “管理者” 向けのマニュアルです。この文書を読むのに Python プログラマである必要はありません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

28. カスタム Python インタプリタ

この章で解説されるモジュールで Python の対話インタプリタに似たインタフェースを書くことができます。もし Python そのもの以外に何か特殊な機能をサポートした Python インタプリタを作りたければ、 code モジュールを参照してください。 (codeop モジュールはより低レベルで、不完全(かもしれない) Python コード断片のコンパイルをサポートするために使われます。)

この章で解説されるモジュールの完全な一覧は:

28.1. code — インタプリタ基底クラス

28.1.1. 対話的なインタプリタオブジェクト

28.1.2. 対話的なコンソールオブジェクト

28.2. codeop — Pythonコードをコンパイルする

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

28. カスタム Python インタプリタ »

28.1. code — インタプリタ基底クラス

code モジュールはread-eval-print (読み込み-評価-表示)ループをPythonで実装するための機能を提供します。対話的なインタプリタプロンプトを提供するアプリケーションを作るために使える二つのクラスと便利な関数が含まれています。

class code.InteractiveInterpreter([locals])

このクラスは構文解析とインタプリタ状態(ユーザの名前空間)を取り扱います。入力バッファリングやプロンプト出力、または入力ファイル指定を扱いません(ファイル名は常に明示的に渡されます)。オプションの locals 引数はその中でコードが実行される辞書を指定します。その初期値は、キー '__name__' が '__console__' に設定され、キー '__doc__' が None に設定された新しく作られた辞書です。

class code.InteractiveConsole([locals[, filename]])

対話的なPythonインタプリタの振る舞いを厳密にエミュレートします。このクラスは InteractiveInterpreter を元に作られていて、通常の sys.ps1 と sys.ps2 をつかったプロンプト出力と入力バッファリングが追加されています。

code.interact([banner[, readfunc[, local]]])

read-eval-printループを実行するための便利な関数。これは InteractiveConsole の新しいインスタンスを作り、 readfunc が与えられた場合は raw_input() メソッドとして使われるように設定します。 local が与えられた場合は、インタプリタループのデフォルト名前空間として使うために InteractiveConsole コンストラクタへ渡されます。そして、インスタンスの interact() メソッドは見出しとして使うために渡される banner を受け取り実行されます。コンソールオブジェクトは使われた後捨てられます。

code.compile_command(source[, filename[, symbol]])

この関数はPythonのインタプリタメインループ(別名、read-eval-printループ)をエミュレートしようとするプログラムにとって役に立ちます。扱いにくい部分は、ユーザが(完全なコマンドや構文エラーではなく)さらにテキストを入力すれば完全になりうる不完全なコマンドを入力したときを決定することです。この関数は*ほとんど*の場合に実際のインタプリタメインループと同じ決定を行います。

source はソース文字列です。 filename はオプションのソースが読み出されたファイル名で、デフォルトで '<input>' です。 symbol はオプションの文法の開始記号で、 'single' (デフォルト)または 'eval' のどちらかにすべきです。

コマンドが完全で有効ならば、コードオブジェクトを返します(compile(source, filename, symbol) と同じ)。コマンドが完全でないならば、 None を返します。コマンドが完全で構文エラーを含む場合は、 SyntaxError を発生させます。または、コマンドが無効なリテラルを含む場合は、 OverflowError もしくは ValueError を発生させます。

28.1.1. 対話的なインタプリタオブジェクト

InteractiveInterpreter.runsource(source[, filename[, symbol]])

インタプリタ内のあるソースをコンパイルし実行します。引数は compile_command() のものと同じです。 filename のデフォルトは '<input>' で、 symbol は 'single' です。あるいくつかのことが起きる可能性があります:

入力はが正しくない。 compile_command() が例外(SyntaxError か OverflowError)を起こした場合。 showsyntaxerror() メソッドの呼び出によって、構文トレースバックが表示されるでしょう。 runsource() は False を返します。

入力が完全でなく、さらに入力が必要。 compile_command() が None を返した場合。 runsource() は True を返します。

入力が完全。 compile_command() がコードオブジェクトを返した場合。 (SystemExit を除く実行時例外も処理する) runcode() を呼び出すことによって、コードは実行されます。 runsource() は False を返します。

次の行を要求するために sys.ps1 か sys.ps2 のどちらを使うかを決定するために、戻り値を利用できます。

InteractiveInterpreter.runcode(code)

コードオブジェクトを実行します。例外が生じたときは、トレースバックを表示するために showtraceback() が呼び出されます。伝わることが許されている SystemExit を除くすべての例外が捉えられます。

KeyboardInterrupt についての注意。このコードの他の場所でこの例外が生じる可能性がありますし、常に捕らえることができるとは限りません。呼び出し側はそれを処理するために準備しておくべきです。

InteractiveInterpreter.showsyntaxerror([filename])

起きたばかりの構文エラーを表示します。複数の構文エラーに対して一つあるのではないため、これはスタックトレースを表示しません。 filename が与えられた場合は、Pythonのパーサが与えるデフォルトのファイル名の代わりに例外の中へ入れられます。なぜなら、文字列から読み込んでいるときはパーサは常に '<string>' を使うからです。出力は write() メソッドによって書き込まれます。

InteractiveInterpreter.showtraceback()

起きたばかりの例外を表示します。スタックの最初の項目を取り除きます。なぜなら、それはインタプリタオブジェクトの実装の内部にあるからです。出力は write() メソッドによて書き込まれます。

InteractiveInterpreter.write(data)

文字列を標準エラーストリーム(sys.stderr)へ書き込みます。必要に応じて適切な出力処理を提供するために、派生クラスはこれをオーバーライドすべきです。

28.1.2. 対話的なコンソールオブジェクト

InteractiveConsole クラスは InteractiveInterpreter のサブクラスです。以下の追加メソッドだけでなく、インタプリタオブジェクトのすべてのメソッドも提供します。

InteractiveConsole.interact([banner])

対話的なPythonコンソールをそっくりにエミュレートします。オプションのbanner引数は最初のやりとりの前に表示するバナーを指定します。デフォルトでは、標準Pythonインタプリタが表示するものと同じようなバナーを表示します。それに続けて、実際のインタプリタと混乱しないように(とても似ているから!)括弧の中にコンソールオブジェクトのクラス名を表示します。

InteractiveConsole.push(line)

ソーステキストの一行をインタプリタへ送ります。その行の末尾に改行がついていてはいけません。内部に改行を持っているかもしれません。その行はバッファへ追加され、ソースとして連結された内容が渡されインタプリタの runsource() メソッドが呼び出されます。コマンドが実行されたか、有効であることをこれが示している場合は、バッファはリセットされます。そうでなければ、コマンドが不完全で、その行が付加された後のままバッファは残されます。さらに入力が必要ならば、戻り値は True です。その行がある方法で処理されたならば、 False です(これは runsource() と同じです)。

InteractiveConsole.resetbuffer()

入力バッファから処理されていないソーステキストを取り除きます。

InteractiveConsole.raw_input([prompt])

プロンプトを書き込み、一行を読み込みます。返る行は末尾に改行を含みません。ユーザがEOFキーシーケンスを入力したときは、 EOFError を発生させます。基本実装では、組み込み関数 raw_input() を使います。サブクラスはこれを異なる実装と置き換えるかもしれません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

28. カスタム Python インタプリタ »

28.2. codeop — Pythonコードをコンパイルする

codeop モジュールは、 code モジュールで行われているようなPythonの read-eval-printループをエミュレートするユーティリティを提供します。そのため、このモジュールを直接利用する場面はあまり無いでしょう。プログラムにこのようなループを含めたい場合は、 code モジュールの方が便利です。

この仕事には二つの部分があります:

入力の一行がPythonの文として完全であるかどうかを見分けられること: 簡単に言えば、次が ‘>>>‘ か、あるいは ‘...‘ かどうかを見分けます。

どのfuture文をユーザが入力したのかを覚えていること。したがって、実質的にそれに続く入力をこれらとともにコンパイルすることができます。

codeop モジュールはこうしたことのそれぞれを行う方法とそれら両方を行う方法を提供します。

前者は実行するには:

codeop.compile_command(source[, filename[, symbol]])

Pythonコードの文字列であるべき source をコンパイルしてみて、 source が有効なPythonコードの場合はコードオブジェクトを返します。このような場合、コードオブジェクトのファイル名属性は、デフォルトで '<input>' である filename でしょう。 source が有効なPythonコードでは ない が、有効なPythonコードの接頭語である場合には、 None を返します。

source に問題がある場合は、例外を発生させます。無効なPython構文がある場合は、 SyntaxError を発生させます。また、無効なリテラルがある場合は、 OverflowError または ValueError を発生させます。

symbol 引数は source が文としてコンパイルされるか('single' 、デフォルト) 、または式としてコンパイルされたかどうかを決定します('eval')。他のどんな値も ValueError を発生させる原因となります。

ノート

ソースの終わりに達する前に、成功した結果をもってパーサは構文解析を止めることがあります。このような場合、後ろに続く記号はエラーとならずに無視されます。例えば、バックスラッシュの後ろに改行が2つあって、その後ろにゴミがあるかもしれません。パーサのAPIがより良くなればすぐに、この挙動は修正されるでしょう。

class codeop.Compile

このクラスのインスタンスは組み込み関数 compile() とシグネチャが一致する __call__() メソッドを持っていますが、インスタンスが __future__ 文を含むプログラムテキストをコンパイルする場合は、インスタンスは有効なその文とともに続くすべてのプログラムテキストを’覚えていて’コンパイルするという違いがあります。

class codeop.CommandCompiler

このクラスのインスタンスは compile_command() とシグネチャが一致する __call__() メソッドを持っています。インスタンスが __future__ 文を含むプログラムテキストをコンパイルする場合に、インスタンスは有効なその文とともにそれに続くすべてのプログラムテキストを’覚えていて’コンパイルするという違いがあります。

バージョン間の互換性についての注意: Compile と CommandCompiler はPython 2.2で導入されました。2.2のfuture-tracking機能を有効にするだけでなく、 2.1とPythonのより以前のバージョンとの互換性も保ちたい場合は、次のように書くことができます

try:
    from codeop import CommandCompiler
    compile_command = CommandCompiler()
    del CommandCompiler
except ImportError:
    from codeop import compile_command

これは影響の小さい変更ですが、あなたのプログラムにおそらく望まれないグローバル状態を導入します。または、次のように書くこともできます:

try:
    from codeop import CommandCompiler
except ImportError:
    def CommandCompiler():
        from codeop import compile_command
        return compile_command

そして、新たなコンパイラオブジェクトが必要となるたびに CommandCompiler を呼び出します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

29. 制限実行 (restricted execution)

警告

Python 2.3 で、既知の容易に修正できないセキュリティーホールのために、これらのモジュールは無効にされています。 rexec や Bastion モジュールを使った古いコードを読むときに助けになるよう、モジュールのドキュメントだけは残されています。

制限実行 (restricted execution) とは、信頼できるコードと信頼できないコードを区別できるようにするための Python における基本的なフレームワークです。このフレームワークは、信頼できる Python コード (スーパバイザ (supervisor)) が、パーミッションに制限のかけられた “拘束セル (padded cell)” を生成し、このセル中で信頼のおけないコードを実行するという概念に基づいています。信頼のおけないコードはこの拘束セルを破ることができず、信頼されたコードで提供され、管理されたインタフェースを介してのみ、傷つきやすいシステムリソースとやりとりすることができます。 “制限実行” という用語は、”安全な Python (safe-Python)” を裏から支えるものです。というのは、真の安全を定義することは難しく、制限された環境を生成する方法によって決められるからです。制限された環境は入れ子にすることができ、このとき内側のセルはより縮小されることはあるが決して拡大されることのない特権を持ったサブセルを生成します。

Python の制限実行モデルの興味深い側面は、信頼されないコードに提供されるインタフェースが、信頼されるコードに提供されるそれらと同じ名前を持つということです。このため、制限された環境で動作するよう設計されたコードを書く上で特殊なインタフェースを学ぶ必要がありません。また、拘束セルの厳密な性質はスーパバイザによって決められるため、アプリケーションによって異なる制限を課すことができます。例えば、信頼されないコードが指定したディレクトリ内の何らかのファイルを読み出すが決して書き込まないということが “安全” と考えられるかもしれません。この場合、スーパバイザは組み込みの open() 関数について、 mode パラメタが 'w' の時に例外を送出するように再定義できます。また例えば、”安全” とは、 filename パラメタに対して chroot() に似た操作を施して、ルートパスがファイルシステム上の何らかの安全な “砂場 (sandbox)” 領域に対する相対パスになるようにすることかもしれません。この場合でも、信頼されないコードは依然として、もとの呼び出しインタフェースを持ったままの組み込みの open() 関数を制限環境中に見出します。ここでは、関数に対する意味付け (semantics) は同じですが、許可されないパラメタが使われようとしているとスーパバイザが判断した場合には IOError が送出されます。

Python のランタイムシステムは、特定のコードブロックが制限実行モードかどうかを、グローバル変数の中の __builtins__ オブジェクトの一意性をもとに判断します: オブジェクトが標準の __builtin__ モジュール (の辞書) の場合、コードは非制限下にあるとみなされます。それ以外は制限下にあるとみなされます。

制限実行モードで動作する Python コードは、拘束セルから侵出しないように設計された数多くの制限に直面します。例えば、関数オブジェクト属性 func_globals や、クラスおよびインスタンスオブジェクトの属性 __dict__ は利用できません。

二つのモジュールが、制限実行環境を立ち上げるためのフレームワークを提供しています:

29.1. rexec — 制限実行のフレームワーク

29.1.1. RExec オブジェクト

29.1.2. 制限された環境を定義する

29.1.3. 例

29.2. Bastion — オブジェクトに対するアクセスの制限

参考

Grail Home Page [http://grail.sourceforge.net/]

Python で書かれたインターネットブラウザ Grail です。Python で書かれたアプレットをサポートするために、上記のモジュールを使っています。 Grail における Python 制限実行モードの利用に関する詳しい情報は、Web サイトで入手することができます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

29. 制限実行 (restricted execution) »

29.1. rexec — 制限実行のフレームワーク

バージョン 2.6 で撤廃: rexec モジュールは Python 3.0 で削除されました。

バージョン 2.3 で変更: Disabled module.

警告

このドキュメントは、 rexec モジュールを使用している古いコードを読む際の参照用として残されています。

このモジュールには RExec クラスが含まれています。このクラスは、 r_eval() 、 r_execfile() 、 r_exec() および r_import() メソッドをサポートし、これらは標準の Python 関数 eval() 、 execfile() および exec と import 文の制限されたバージョンです。この制限された環境で実行されるコードは、安全であると見なされたモジュールや関数だけにアクセスします; RExec をサブクラス化すれば、望むように能力を追加および削除できます。

警告

rexec モジュールは、下記のように動作するべく設計されてはいますが、注意深く書かれたコードなら利用できてしまうかもしれない、既知の脆弱性がいくつかあります。従って、”製品レベル” のセキュリティを要する状況では、 rexec の動作をあてにするべきではありません。製品レベルのセキュリティを求めるなら、サブプロセスを介した実行や、あるいは処理するコードとデータの両方に対する非常に注意深い “浄化” が必要でしょう。上記の代わりに、 rexec の既知の脆弱性に対するパッチ当ての手伝いも歓迎します。

ノート

RExec クラスは、プログラムコードによるディスクファイルの読み書きや TCP/IP ソケットの利用といった、安全でない操作の実行を防ぐことができます。しかし、プログラムコードよる非常に大量のメモリや処理時間の消費に対して防御することはできません。

class rexec.RExec([hooks[, verbose]])

RExec クラスのインスタンスを返します。

hooks は、 RHooks クラスあるいはそのサブクラスのインスタンスです。 hooks が省略されているか None であれば、デフォルトの RHooks クラスがインスタンス化されます。 rexec モジュールが (組み込みモジュールを含む) あるモジュールを探したり、あるモジュールのコードを読んだりする時は常に、 rexec がじかにファイルシステムに出て行くことはありません。その代わり、あらかじめ RHooks クラスに渡しておいたり、コンストラクタで生成された RHooks インスタンスのメソッドを呼び出します。

(実際には、 RExec オブジェクトはこれらを呼び出しません — 呼び出しは、 RExec オブジェクトの一部であるモジュールローダオブジェクトによって行われます。これによって別のレベルの柔軟性が実現されます。この柔軟性は、制限された環境内で import 機構を変更する時に役に立ちます。 )

代替の RHooks オブジェクトを提供することで、モジュールをインポートする際に行われるファイルシステムへのアクセスを制御することができます。このとき、各々のアクセスが行われる順番を制御する実際のアルゴリズムは変更されません。例えば、 RHooks オブジェクトを置き換えて、ILU のようなある種の RPC メカニズムを介することで、全てのファイルシステムの要求をどこかにあるファイルサーバに渡すことができます。 Grail のアプレットローダは、アプレットを URL からディレクトリ上に import する際にこの機構を使っています。

もし verbose が true であれば、追加のデバッグ出力が標準出力に送られます。

制限された環境で実行するコードも、やはり sys.exit() 関数を呼ぶことができることを知っておくことは大事なことです。制限されたコードがインタプリタから抜けだすことを許さないためには、いつでも、制限されたコードが、 SystemExit 例外をキャッチする try / except 文とともに実行するように、呼び出しを防御します。制限された環境から sys.exit() 関数を除去するだけでは不十分です – 制限されたコードは、やはり raise SystemExit を使うことができてしまいます。 SystemExit を取り除くことも、合理的なオプションではありません; いくつかのライブラリコードはこれを使っていますし、これが利用できなくなると中断してしまうでしょう。

参考

Grail のホームページ [http://grail.sourceforge.net/]

Grail はすべて Python で書かれた Web ブラウザです。これは、 rexec モジュールを、Python アプレットをサポートするのに使っていて、このモジュールの使用例として使うことができます。

29.1.1. RExec オブジェクト

RExec インスタンスは以下のメソッドをサポートします:

RExec.r_eval(code)

code は、Python の式を含む文字列か、あるいはコンパイルされたコードオブジェクトのどちらかでなければなりません。そしてこれらは制限された環境の __main__ モジュールで評価されます。式あるいはコードオブジェクトの値が返されます。

RExec.r_exec(code)

code は、1行以上の Python コードを含む文字列か、コンパイルされたコードオブジェクトのどちらかでなければなりません。そしてこれらは、制限された環境の __main__ モジュールで実行されます。

RExec.r_execfile(filename)

ファイル filename 内の Python コードを、制限された環境の __main__ モジュールで実行します。

名前が s_ で始まるメソッドは、 r_ で始まる関数と同様ですが、そのコードは、標準 I/O ストリーム sys.stdin 、 sys.stderr および sys.stdout の制限されたバージョンへのアクセスが許されています。

RExec.s_eval(code)

code は、Python 式を含む文字列でなければなりません。そして制限された環境で評価されます。

RExec.s_exec(code)

code は、1行以上のPython コードを含む文字列でなければなりません。そして制限された環境で実行されます。

RExec.s_execfile(code)

ファイル filename に含まれた Python コードを制限された環境で実行します。

RExec オブジェクトは、制限された環境で実行されるコードによって暗黙のうちに呼ばれる、さまざまなメソッドもサポートしなければなりません。これらのメソッドをサブクラス内でオーバライドすることによって、制限された環境が強制するポリシを変更します。

RExec.r_import(modulename[, globals[, locals[, fromlist]]])

モジュール modulename をインポートし、もしそのモジュールが安全でないとみなされるなら、 ImportError 例外を発生します。

RExec.r_open(filename[, mode[, bufsize]])

open() が制限された環境で呼ばれるとき、呼ばれるメソッドです。引数は open() のものと同じであり、ファイルオブジェクト (あるいはファイルオブジェクトと互換性のあるクラスインスタンス)が返されます。 RExec のデフォルトの動作は、任意のファイルを読み取り用にオープンすることを許可しますが、ファイルに書き込もうとすることは許しません。より制限の少ない r_open() の実装については、以下の例を見て下さい。

RExec.r_reload(module)

モジュールオブジェクト module を再ロードして、それを再解析し再初期化します。

RExec.r_unload(module)

モジュールオブジェクト module をアンロードします (それを制限された環境の sys.modules 辞書から取りのぞきます)。

および制限された標準 I/O ストリームへのアクセスが可能な同等のもの:

RExec.s_import(modulename[, globals[, locals[, fromlist]]])

モジュール modulename をインポートし、もしそのモジュールが安全でないとみなされるなら、 ImportError 例外を発生します。

RExec.s_reload(module)

モジュールオブジェクト module を再ロードして、それを再解析し再初期化します。

RExec.s_unload(module)

モジュールオブジェクト module をアンロードします。

29.1.2. 制限された環境を定義する

RExec クラスには以下のクラス属性があります。それらは、 __init__() メソッドが使います。それらを既存のインスタンス上で変更しても何の効果もありません; そうする代わりに、 RExec のサブクラスを作成して、そのクラス定義でそれらに新しい値を割り当てます。そうすると、新しいクラスのインスタンスは、これらの新しい値を使用します。これらの属性のすべては、文字列のタプルです。

RExec.nok_builtin_names

制限された環境で実行するプログラムでは利用でき ない であろう、組み込み関数の名前を格納しています。 RExec に対する値は、 ('open', 'reload', '__import__') です。 (これは例外です。というのは、組み込み関数のほとんど大多数は無害だからです。この変数をオーバライドしたいサブクラスは、基本クラスからの値から始めて、追加した許されない関数を連結していかなければなりません – 危険な関数が新しく Python に追加された時は、それらも、このモジュールに追加します。)

RExec.ok_builtin_modules

安全にインポートできる組み込みモジュールの名前を格納しています。 RExec に対する値は、 ('audioop', 'array', 'binascii', 'cmath', 'errno', 'imageop', 'marshal', 'math', 'md5', 'operator', 'parser', 'regex', 'select', 'sha', '_sre', 'strop', 'struct', 'time') です。この変数をオーバーライドする場合も、同様な注意が適用されます – 基本クラスからの値を使って始めます。

RExec.ok_path

import が制限された環境で実行される時に検索されるディレクトリーを格納しています。 RExec に対する値は、(モジュールがロードされた時は) 制限されないコードの sys.path と同一です。

RExec.ok_posix_names

制限された環境で実行するプログラムで利用できる、 os モジュール内の関数の名前を格納しています。 RExec に対する値は、 ('error', 'fstat', 'listdir', 'lstat', 'readlink', 'stat', 'times', 'uname', 'getpid', 'getppid', 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid') です。

RExec.ok_sys_names

制限された環境で実行するプログラムで利用できる、 sys モジュール内の関数名と変数名を格納しています。 RExec に対する値は、 ('ps1', 'ps2', 'copyright', 'version', 'platform', 'exit', 'maxint') です。

RExec.ok_file_types

モジュールがロードすることを許されているファイルタイプを格納しています。各ファイルタイプは、 imp モジュールで定義された整数定数です。意味のある値は、 PY_SOURCE 、 PY_COMPILED および C_EXTENSION です。 RExec に対する値は、 (C_EXTENSION, PY_SOURCE) です。サブクラスで PY_COMPILED を追加することは推奨されません; 攻撃者が、バイトコンパイルしたでっちあげのファイル(.pyc)を、例えば、あなたの公開 FTP サーバの /tmp に書いたり、 /incoming にアップロードしたりして、とにかくあなたのファイルシステム内に置くことで、制限された実行モードから抜け出ることができるかもしれないからです。

29.1.3. 例

標準の RExec クラスよりも、若干、もっと緩めたポリシを望んでいるとしましょう。例えば、もし /tmp 内のファイルへの書き込みを喜んで許すならば、 RExec クラスを次のようにサブクラス化できます:

class TmpWriterRExec(rexec.RExec):
    def r_open(self, file, mode='r', buf=-1):
        if mode in ('r', 'rb'):
            pass
        elif mode in ('w', 'wb', 'a', 'ab'):
            # ファイル名をチェックします :  /tmp/ で始まらなければなりません
            if file[:5]!='/tmp/':
                raise IOError(" /tmp 以外へは書き込みできません")
            elif (string.find(file, '/../') >= 0 or
                 file[:3] == '../' or file[-3:] == '/..'):
                raise IOError("ファイル名の '..' は禁じられています")
        else: raise IOError("open() モードが正しくありません")
        return open(file, mode, buf)

上のコードは、完全に正しいファイル名でも、時には禁止する場合があることに注意して下さい; 例えば、制限された環境でのコードでは、 /tmp/foo/../bar というファイルはオープンできないかもしれません。これを修正するには、 r_open() メソッドが、そのファイル名を /tmp/bar に単純化しなければなりません。そのためには、ファイル名を分割して、それにさまざまな操作を行う必要があります。セキュリティが重大な場合には、より複雑で微妙なセキュリティホールを抱え込むかもしれない一般性のあるコードよりも、制限が余りにあり過ぎるとしても単純なコードを書く方が、望ましいでしょう。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

29. 制限実行 (restricted execution) »

29.2. Bastion — オブジェクトに対するアクセスの制限

バージョン 2.6 で撤廃: Bastion モジュールは Python 3.0 で削除されました。

バージョン 2.3 で変更: Disabled module.

ノート

このドキュメントは、Bastion モジュールを使用している古いコードを読む際の参照用として残されています。

辞書によると、バスチョン (bastion、要塞) とは、”防衛された領域や地点”、または “最後の砦と考えられているもの” であり、オブジェクトの特定の属性へのアクセスを禁じる方法を提供するこのモジュールにふさわしい名前です。制限モード下のプログラムに対して、あるオブジェクトにおける特定の安全な属性へのアクセスを許可し、かつその他の安全でない属性へのアクセスを拒否するには、要塞オブジェクトは常に rexec モジュールと共に使われなければなりません。

Bastion.Bastion(object[, filter[, name[, class]]])

オブジェクト object を保護し、オブジェクトに対する要塞オブジェクトを返します。オブジェクトの属性に対するアクセスの試みは全て、 filter 関数によって認可されなければなりません; アクセスが拒否された場合 AttributeError 例外が送出されます。

filter が存在する場合、この関数は属性名を含む文字列を受理し、その属性に対するアクセスが許可される場合には真を返さなければなりません; filter が偽を返す場合、アクセスは拒否されます。標準のフィルタは、アンダースコア ('_') で始まる全ての関数に対するアクセスを拒否します。 name の値が与えられた場合、要塞オブジェクトの文字列表現は <Bastion for name> になります; そうでない場合、 repr(object) が使われます。

class が存在する場合、 BastionClass のサブクラスでなくてはなりません; 詳細は bastion.py のコードを参照してください。 BastionClass の標準設定を上書きする必要はほとんどないはずです。

class Bastion.BastionClass(getfunc, name)

実際に要塞オブジェクトを実装しているクラスです。このクラスは Bastion() によって使われる標準のクラスです。 getfunc 引数は関数で、唯一の引数である属性の名前を与えて呼び出した際、制限された実行環境に対して、開示すべき属性の値を返します。 name は BastionClass インスタンスの repr() を構築するために使われます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート

この章で解説されるモジュールは他のPythonモジュールをインポートする新しい方法と、インポート処理をカスタマイズするためのフックを提供します。

この章で解説されるモジュールの完全な一覧は:

30.1. imp — import 内部へアクセスする

30.1.1. 例

30.2. importlib – __import__() の便利なラッパー

30.3. imputil — Import ユーティリティ

30.3.1. Examples

30.4. zipimport — Zip アーカイブからモジュールを import する

30.4.1. zipimporter オブジェクト

30.4.2. 使用例

30.5. pkgutil — パッケージ拡張ユーティリティ

30.6. modulefinder — スクリプト中で使われているモジュールを検索する

30.6.1. ModuleFinder の使用例

30.7. runpy — Python モジュールの位置特定と実行

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.1. imp — import 内部へアクセスする

このモジュールは import 文を実装するために使われているメカニズムへのインターフェイスを提供します。次の定数と関数が定義されています:

imp.get_magic()

バイトコンパイルされたコードファイル(.pyc ファイル)を認識するために使われるマジック文字列値を返します。 (この値は Python の各バージョンで異なります。)

imp.get_suffixes()

3要素のタプルのリストを返します。それぞれのタプルは特定の種類のモジュールを説明しています。各タプルは (suffix, mode, type) という形式です。ここで、 suffix は探すファイル名を作るためにモジュール名に追加する文字列です。そのファイルをオープンするために、 mode は組み込み open() 関数へ渡されるモード文字列です (これはテキストファイル対しては 'r' 、バイナリファイルに対しては 'rb' となります)。 type はファイル型で、以下で説明する値 PY_SOURCE, PY_COMPILED あるいは、 C_EXTENSION の一つを取ります。

imp.find_module(name[, path])

モジュール name を見つけようとします。 path が省略されるか None ならば、 sys.path によって与えられるディレクトリ名のリストが検索されます。しかし、最初にいくつか特別な場所を検索します。まず、所定の名前をもつ組み込みモジュール(C_BUILTIN)を見つけようとします。それから、フリーズされたモジュール(PY_FROZEN)、そしていくつかのシステムでは他の場所が同様に検索されます (Windowsでは、特定のファイルを指すレジストリの中を見ます)。

それ以外の場合、 path はディレクトリ名のリストでなければなりません。上の get_suffixes() が返す拡張子のいずれかを伴ったファイルを各ディレクトリの中で検索します。リスト内の有効でない名前は黙って無視されます(しかし、すべてのリスト項目は文字列でなければなりません)。

検索が成功すれば、戻り値は3要素のタプル (file, pathname, description) です:

file は先頭に位置合わせされたオープンファイルオブジェクトで、 pathname は見つかったファイルのパス名です。そして、 description は get_suffixes() が返すリストに含まれているような3要素のタプルで、見つかったモジュールの種類を説明しています。

モジュールがファイルとして存在していなければ、返された file は None で、 pathname は空文字列、 description タプルはその拡張子とモードに対して空文字列を含みます。モジュール型は上の括弧の中に示されます。検索が失敗すれば、 ImportError が発生します。他の例外は引数または環境に問題があることを示唆します。

モジュールがパッケージならば、 file は None で、 pathname はパッケージのパスで description タプルの最後の項目は PKG_DIRECTORY です。

この関数は階層的なモジュール名(ドットを含んだ名前)を扱いません。 P.M 、すなわち、パッケージ P のサブモジュール M を見つけるためには、パッケージ P を見つけてロードするために find_module() と load_module() を使い、それから P.__path__ に設定された path 引数とともに find_module() を使ってください。 P 自身がドット名のときは、このレシピを再帰的に適用してください。

imp.load_module(name, file, pathname, description)

find_module() を使って(あるいは、互換性のある結果を作り出す検索を行って)以前見つけたモジュールをロードします。この関数はモジュールをインポートするという以上のことを行います: モジュールが既にインポートされているならば、 reload() と同じです! name 引数は(これがパッケージのサブモジュールならばパッケージ名を含む)完全なモジュール名を示します。 file 引数はオープンしたファイルで、 pathname は対応するファイル名です。モジュールがパッケージであるかファイルからロードされようとしていないとき、これらはそれぞれ None と '' であっても構いません。 get_suffixes() が返すように description 引数はタプルで、どの種類のモジュールがロードされなければならないかを説明するものです。

ロードが成功したならば、戻り値はモジュールオブジェクトです。そうでなければ、例外(たいていは ImportError)が発生します。

重要: file 引数が None でなければ、例外が発生した場合でも呼び出し側にはそれを閉じる責任があります。これを行うには、 try ... finally 文を使うことが最も良いです。

imp.new_module(name)

name という名前の新しい空モジュールオブジェクトを返します。このオブジェクトは sys.modules に挿入され ません 。

imp.lock_held()

現在インポートロックが維持されているならば、 True を返します。そうでなければ、 False を返します。スレッドのないプラットホームでは、常に False を返します。

スレッドのあるプラットホームでは、インポートが完了するまでインポートを実行するスレッドは内部ロックを維持します。このロックは元のインポートが完了するまで他のスレッドがインポートすることを阻止します。言い換えると、元のスレッドがそのインポート(および、もしあるならば、それによって引き起こされるインポート) の途中で構築した不完全なモジュールオブジェクトを、他のスレッドが見られないようにします。

imp.acquire_lock()

実行中のスレッドでインタープリタのインポートロックを取得します。インポートフックは、スレッドセーフのためにこのロックを取得しなければなりません。

一旦スレッドがインポートロックを取得したら、その同じスレッドはブロックされることなくそのロックを再度取得できます。スレッドはロックを取得するのと同じだけ解放しなければなりません。

スレッドのないプラットホームではこの関数は何もしません。

バージョン 2.3 で追加.

imp.release_lock()

インタープリタのインポートロックを解放します。スレッドのないプラットホームではこの関数は何もしません。

バージョン 2.3 で追加.

整数値をもつ次の定数はこのモジュールの中で定義されており、 find_module() の検索結果を表すために使われます。

imp.PY_SOURCE

ソースファイルとしてモジュールが発見された。

imp.PY_COMPILED

コンパイルされたコードオブジェクトファイルとしてモジュールが発見された。

imp.C_EXTENSION

動的にロード可能な共有ライブラリとしてモジュールが発見された。

imp.PKG_DIRECTORY

パッケージディレクトリとしてモジュールが発見された。

imp.C_BUILTIN

モジュールが組み込みモジュールとして発見された。

imp.PY_FROZEN

モジュールがフリーズされたモジュールとして発見された(init_frozen() を参照)。

以下の定数と関数は旧バージョンのものです。 find_module() や load_module() を使えば同様の機能を利用できます。これらは後方互換性のために残されています:

imp.SEARCH_ERROR

使われていません。

imp.init_builtin(name)

name という名前の組み込みモジュールを初期化し、そのモジュールオブジェクトを sys.modules に格納した上で返します。モジュールが既に初期化されている場合は、 再度 初期化されます。再初期化は組み込みモジュールの __dict__ を sys.modules のエントリーに結びつけられたキャッシュモジュールからコピーする過程を含みます。 name という名前の組み込みモジュールがない場合は、 None を返します。

imp.init_frozen(name)

name という名前のフリーズされたモジュールを初期化し、モジュールオブジェクトを返します。モジュールが既に初期化されている場合は、 再度 初期化されます。 name という名前のフリーズされたモジュールがない場合は、 None を返します。 (フリーズされたモジュールは Python で書かれたモジュールで、そのコンパイルされたバイトコードオブジェクトが Python の freeze ユーティリティを使ってカスタムビルド版の Python インタープリタへ組み込まれています。差し当たり、 Tools/freeze/ を参照してください。)

imp.is_builtin(name)

name という名前の再初期化できる組み込みモジュールがある場合は、 1 を返します。 name という名前の再初期化できない組み込みモジュールがある場合は、 -1 を返します (init_builtin() を参照してください)。 name という名前の組み込みモジュールがない場合は、 0 を返します。

imp.is_frozen(name)

name という名前のフリーズされたモジュール(init_frozen() を参照)がある場合は、 True を返します。または、そのようなモジュールがない場合は、 False を返します。

imp.load_compiled(name, pathname[, file])

バイトコンパイルされたコードファイルとして実装されているモジュールをロードして初期化し、そのモジュールオブジェクトを返します。モジュールが既に初期化されている場合は、 再度 初期化されます。 name 引数はモジュールオブジェクトを作ったり、アクセスするために使います。 pathname 引数はバイトコンパイルされたコードファイルを指します。 file 引数はバイトコンパイルされたコードファイルで、バイナリモードでオープンされ、先頭からアクセスされます。現在は、ユーザ定義のファイルをエミュレートするクラスではなく、実際のファイルオブジェクトでなければなりません。

imp.load_dynamic(name, pathname[, file])

動的ロード可能な共有ライブラリとして実装されているモジュールをロードして初期化します。モジュールが既に初期化されている場合は、 再度 初期化します。再初期化はモジュールのキャッシュされたインスタンスの __dict__ 属性を sys.modules にキャッシュされたモジュールの中で使われた値に上書きコピーする過程を含みます。 pathname 引数は共有ライブラリを指していなければなりません。 name 引数は初期化関数の名前を作るために使われます。共有ライブラリの initname() という名前の外部C関数が呼び出されます。オプションの file 引数は無視されます。 (注意: 共有ライブラリはシステムに大きく依存します。また、すべてのシステムがサポートしているわけではありません。)

imp.load_source(name, pathname[, file])

Python ソースファイルとして実装されているモジュールをロードして初期化し、モジュールオブジェクトを返します。モジュールが既に初期化されている場合は、 再度 初期化します。 name 引数はモジュールオブジェクトを作成したり、アクセスしたりするために使われます。 pathname 引数はソースファイルを指します。 file 引数はソースファイルで、テキストとして読み込むためにオープンされ、先頭からアクセスされます。現在は、ユーザ定義のファイルをエミュレートするクラスではなく、実際のファイルオブジェクトでなければなりません。 (拡張子 .pyc または .pyo をもつ)正しく対応するバイトコンパイルされたファイルが存在する場合は、与えられたソースファイルを構文解析する代わりにそれが使われることに注意してください。

class imp.NullImporter(path_string)

NullImporter 型は PEP 302 [http://www.python.org/dev/peps/pep-0302] インポートフックで、何もモジュールが見つからなかったときの非ディレクトリパス文字列を処理します。この型を既存のディレクトリや空文字列に対してコールすると ImportError が発生します。それ以外の場合は NullImporter のインスタンスが返されます。

Python は、ディレクトリでなく sys.path_hooks のどのパスフックでも処理されていないすべてのパスエントリに対して、この型のインスタンスを sys.path_importer_cache に追加します。このインスタンスが持つメソッドは次のひとつです。

find_module(fullname[, path])

このメソッドは常に None を返し、要求されたモジュールが見つからなかったことを表します。

バージョン 2.5 で追加.

30.1.1. 例

次の関数は Python 1.4 までの標準 import 文(階層的なモジュール名がない)をエミュレートします。 (この 実装 はそのバージョンでは動作しないでしょう。なぜなら、 find_module() は拡張されており、また load_module() が 1.4 で追加されているからです。)

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()

階層的なモジュール名を実装し、 reload() 関数を含むより完全な例はモジュール knee にあります。 knee モジュールは Python のソースディストリビューションの中の Demo/imputil/ にあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.2. importlib – __import__() の便利なラッパー

バージョン 2.7 で追加.

このモジュールは、 Python 3.1 にある import の完全な実装を提供している同じ名前のパッケージの小さなサブセットです。このモジュールが提供しているものは、 2.7 から 3.1 への移行をしやすくするためのものです。

importlib.import_module(name, package=None)

モジュールをインポートします。 name 引数は、インポートするモジュールを指定する絶対形式もしくは相対形式の名前です。 (例: pkg.mod か ..mod) name が相対形式で与えられた場合、 package 引数にパッケージ名を解決する基準点となるパッケージを指定しなければなりません。 (例: import_module('..mod', 'pkg.subpkg') は pkg.mod をインポートします) 指定されたモジュールは sys.modules に追加され、返されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.3. imputil — Import ユーティリティ

バージョン 2.6 で撤廃: imputil モジュールは Python 3.0 で削除されました。

このモジュールは手軽で役に立つ import フックを改造する機構を提供します。古い ihooks と比較すると、 imputil は import 関数を改造するのに劇的に単純で直截なアプローチをとります。

class imputil.ImportManager([fs_imp])

import 処理を管理します。

install([namespace])

この ImportManager を指定された名前空間にインストールします。

uninstall()

以前の import 機構に戻します。

add_suffix(suffix, importFunc)

内緒です。

class imputil.Importer

標準 import 関数を置き換える基底クラス。

import_top(name)

トップレベルのモジュールを import します。

get_code(parent, modname, fqname)

与えられたモジュールに対するコードを見つけて取ってきます。

parent は import するコンテキストを定義する親モジュールを指定します。 None でも構いません。その場合探すべきコンテキストは特にないことを意味します。

modname は親の内部の (ドットの付かない) 単独のモジュールを指定します。

fqname 完全修飾(fully-qualified)モジュール名を指定します。これは (潜在的に) ドット付けられたモジュール名前空間の “root” から modname までの名前です。

parent が無ければ、modname==fqname です。

このメソッドは None または3要素タプルを返します。

モジュールが見つからなければ None が返されます。

2または3要素のタプルの最初の要素は整数の 0 か 1 で、見つかったモジュールがパッケージかそうでないかを指定します。

2番目の要素はモジュールのコードオブジェクトです (このコードは新しいモジュールの名前空間の中で実行されます)。この要素はまた完全に読み込まれたモジュールオブジェクト (たとえば共有ライブラリから読み込まれてものなど) でもありえます。

3番目の要素はコードオブジェクトが実行される前に新しいモジュールに挿入する名前/値ペアの辞書です。この要素はモジュールのコードが特定の値 (たとえばどこでモジュールが見つかったかといった) を予期している場合に供給されます。 2番目の要素がモジュールオブジェクトであるときは、これらの名前/値はモジュールが読み込まれ/初期化された 後で 挿入されます。

class imputil.BuiltinImporter

ビルトインおよび凍結されたモジュール用の import 機構をエミュレートします。 Importer クラスのサブクラスです。

get_code(parent, modname, fqname)

内緒です。

imputil.py_suffix_importer(filename, finfo, fqname)

内緒です。

class imputil.DynLoadSuffixImporter([desc])

内緒です。

import_file(filename, finfo, fqname)

内緒です。

30.3.1. Examples

これは階層的モジュール import の再実装です。

このコードは読むためのもので、実行するためのものではありません。しかしながら、まあ動きます – 必要なのは “import knee” することだけです。

(名前はこのモジュールの不格好な前身 “ni” との語呂合わせです)

import sys, imp, __builtin__

# Replacement for __import__()
def import_hook(name, globals=None, locals=None, fromlist=None):
    parent = determine_parent(globals)
    q, tail = find_head_package(parent, name)
    m = load_tail(q, tail)
    if not fromlist:
        return q
    if hasattr(m, "__path__"):
        ensure_fromlist(m, fromlist)
    return m

def determine_parent(globals):
    if not globals or  not globals.has_key("__name__"):
        return None
    pname = globals['__name__']
    if globals.has_key("__path__"):
        parent = sys.modules[pname]
        assert globals is parent.__dict__
        return parent
    if '.' in pname:
        i = pname.rfind('.')
        pname = pname[:i]
        parent = sys.modules[pname]
        assert parent.__name__ == pname
        return parent
    return None

def find_head_package(parent, name):
    if '.' in name:
        i = name.find('.')
        head = name[:i]
        tail = name[i+1:]
    else:
        head = name
        tail = ""
    if parent:
        qname = "%s.%s" % (parent.__name__, head)
    else:
        qname = head
    q = import_module(head, qname, parent)
    if q: return q, tail
    if parent:
        qname = head
        parent = None
        q = import_module(head, qname, parent)
        if q: return q, tail
    raise ImportError("No module named " + qname)

def load_tail(q, tail):
    m = q
    while tail:
        i = tail.find('.')
        if i < 0: i = len(tail)
        head, tail = tail[:i], tail[i+1:]
        mname = "%s.%s" % (m.__name__, head)
        m = import_module(head, mname, m)
        if not m:
            raise ImportError("No module named " + mname)
    return m

def ensure_fromlist(m, fromlist, recursive=0):
    for sub in fromlist:
        if sub == "*":
            if not recursive:
                try:
                    all = m.__all__
                except AttributeError:
                    pass
                else:
                    ensure_fromlist(m, all, 1)
            continue
        if sub != "*" and not hasattr(m, sub):
            subname = "%s.%s" % (m.__name__, sub)
            submod = import_module(sub, subname, m)
            if not submod:
                raise ImportError("No module named " + subname)

def import_module(partname, fqname, parent):
    try:
        return sys.modules[fqname]
    except KeyError:
        pass
    try:
        fp, pathname, stuff = imp.find_module(partname,
                                              parent and parent.__path__)
    except ImportError:
        return None
    try:
        m = imp.load_module(fqname, fp, pathname, stuff)
    finally:
        if fp: fp.close()
    if parent:
        setattr(parent, partname, m)
    return m

# Replacement for reload()
def reload_hook(module):
    name = module.__name__
    if '.' not in name:
        return import_module(name, name, None)
    i = name.rfind('.')
    pname = name[:i]
    parent = sys.modules[pname]
    return import_module(name[i+1:], name, parent)

# Save the original hooks
original_import = __builtin__.__import__
original_reload = __builtin__.reload

# Now install our hooks
__builtin__.__import__ = import_hook
__builtin__.reload = reload_hook

importers モジュール (Python の配布されているソースの Demo/imputil/ の中にあります) ももう一つの例として参照して下さい。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.4. zipimport — Zip アーカイブからモジュールを import する

バージョン 2.3 で追加.

このモジュールは、 Python モジュール (*.py, *.py[co]) やパッケージを ZIP 形式のアーカイブから import できるようにします。通常、 zipimport を明示的に使う必要はありません; 組み込みの import は、 sys.path の要素が ZIP アーカイブへのパスを指している場合にこのモジュールを自動的に使います。

普通、 sys.path はディレクトリ名の文字列からなるリストです。このモジュールを使うと、 sys.path の要素に ZIP ファイルアーカイブを示す文字列を使えるようになります。ZIP アーカイブにはサブディレクトリ構造を含めることができ、パッケージの import をサポートさせしたり、アーカイブ内のパスを指定してサブディレクトリ下から import を行わせたりできます。例えば、 /tmp/example.zip/lib/ のように指定すると、アーカイブ中の lib/ サブディレクトリ下だけから import を行います。

ZIP アーカイブ内にはどんなファイルを置いてもかまいませんが、 import できるのは .py および .py[co] だけです。動的モジュール (.pyd, .so) の ZIP import は行えません。アーカイブ内に .py ファイルしか入っていない場合、 Python がアーカイブを変更して、 .py ファイルに対応する .pyc や .pyo ファイルを追加したりはしません。つまり、ZIP アーカイブ中に .pyc が入っていない場合、 import はやや低速になるかもしれないので注意してください。

ZIP アーカイブからロードしたモジュールに対して組み込み関数 reload() を呼び出すと失敗します; reload() が必要になるということは、実行時に ZIP ファイルが置き換えられてしまうことになり、あまり起こりそうにない状況だからです。

アーカイブコメント付きの ZIP アーカイブは現在のところ未サポートです。

参考

PKZIP Application Note [http://www.pkware.com/documents/casestudies/APPNOTE.TXT]

ZIP ファイル形式の作者であり、ZIP で使われているアルゴリズムの作者でもある Phil Katz による、ZIP ファイル形式についてのドキュメントです。

PEP 273 [http://www.python.org/dev/peps/pep-0273] - Import Modules from Zip Archives

このモジュールの実装も行った、James C. Ahlstrom による PEP です。 Python 2.3 は PEP 273 の仕様に従っていますが、 Just van Rossum の書いた import フックによる実装を使っています。 import フックは PEP 302 で解説されています。

PEP 302 [http://www.python.org/dev/peps/pep-0302] - New Import Hooks

このモジュールを動作させる助けになっている import フックの追加を提案している PEP です。

このモジュールでは例外を一つ定義しています:

exception zipimport.ZipImporterError

zipimporter オブジェクトが送出する例外です。 ImportError のサブクラスなので、 ImportError としても捕捉できます。

30.4.1. zipimporter オブジェクト

zipimporter は ZIP ファイルを import するためのクラスです。

class zipimport.zipimporter(archivepath)

新たな zipimporter インスタンスを生成します。 archivepath は ZIP ファイルへのパスかまたは ZIP ファイル中の特定のパスへのパスでなければなりません。たとえば、 foo/bar.zip/lib という archivepath の場合、 foo/bar.zip という ZIP ファイル(が存在するものとして)の中の lib ディレクトリにあるモジュールを探しに行きます。 archivepath が有効な ZIP アーカイブを指していない場合、 ZipImportError を送出します。

find_module(fullname[, path])

fullname に指定したモジュールを検索します。 fullname は完全指定の (ドット表記の) モジュール名でなければなりません。モジュールが見つかった場合には zipimporter インスタンス自体を返し、そうでない場合には None を返します。 path 引数は無視されます — この引数は importer プロトコルとの互換性を保つためのものです。

get_code(fullname)

fullname に指定したモジュールのコードオブジェクトを返します。モジュールがない場合には ZipImportError を送出します。

get_data(pathname)

pathname に関連付けられたデータを返します。該当するファイルが見つからなかった場合には IOError を送出します。

get_filename(fullname)

指定されたモジュールが import さた場合、そのモジュールに設定した __file__ の値を返します。モジュールが見つからなかった場合は ZipImportError 例外を発生させます。

バージョン 2.7 で追加.

get_source(fullname)

fullname に指定したモジュールのソースコードを返します。モジュールが見つからなかった場合には ZipImportError を送出します。モジュールは存在するが、ソースコードがない場合には None を返します。

is_package(fullname)

fullname で指定されたモジュールがパッケージの場合に True を返します。モジュールが見つからなかった場合には ZipImportError を送出します。

load_module(fullname)

fullname に指定したモジュールをロードします。 fullname は完全指定の (ドット表記の) モジュール名でなくてはなりません。 import 済みのモジュールを返します。モジュールがない場合には ZipImportError を送出します。

archive

importer に紐付けられた ZIP ファイルのファイル名で、サブパスは含まれません。

prefix

ZIP ファイル中のモジュールを検索するサブパスです。この文字列は ZIP ファイルの根を指している zipimporter オブジェクトでは空です。

アトリビュート archive と prefix とは、スラッシュでつなげると、 zipimporter コンストラクタに渡された元々の archivepath 引数と等しくなります。

30.4.2. 使用例

モジュールを ZIP アーカイブから import する例を以下に示します - zipimport モジュールが明示的に使われていないことに注意してください。

$ unzip -l /tmp/example.zip
Archive:  /tmp/example.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # パス先頭に .zip ファイル追加
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.5. pkgutil — パッケージ拡張ユーティリティ

このモジュールはインポートシステムの、特にパッケージサポートに関するユーティリティです。

バージョン 2.3 で追加.

pkgutil.extend_path(path, name)

パッケージを構成するモジュールの検索パスを拡張します。パッケージの __init__.py で次のように書くことを意図したものです。

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

上記はパッケージの __path__ に sys.path の全ディレクトリのサブディレクトリとしてパッケージ名と同じ名前を追加します。これは1つの論理的なパッケージの異なる部品を複数のディレクトリに分けて配布したいときに役立ちます。

同時に *.pkg の * の部分が name 引数に指定された文字列に一致するファイルの検索もおこないます。この機能は import で始まる特別な行がないことを除き *.pth ファイルに似ています (site の項を参照)。 *.pkg は重複のチェックを除き、信頼できるものとして扱われます。 *.pkg ファイルの中に見つかったエントリはファイルシステム上に実在するか否かを問わず、そのまますべてパスに追加されます。(このような仕様です。)

入力パスがリストでない場合(フリーズされたパッケージのとき)は何もせずにリターンします。入力パスが変更されていなければ、アイテムを末尾に追加しただけのコピーを返します。

sys.path はシーケンスであることが前提になっています。 sys.path の要素の内、実在するディレクトリを指す(ユニコードまたは8ビットの)文字列となっていないものは無視されます。ファイル名として使ったときにエラーが発生する sys.path のユニコード要素がある場合、この関数(os.path.isdir() を実行している行)で例外が発生する可能性があります。

class pkgutil.ImpImporter(dirname=None)

Python の “クラシック” インポートアルゴリズムをラップする PEP 302 [http://www.python.org/dev/peps/pep-0302] Importer.

dirname が文字列の場合、そのディレクトリを検索する PEP 302 [http://www.python.org/dev/peps/pep-0302] importer を作成します。 dirname が None のとき、現在の sys.path とフリーズされた、あるいはビルトインの全てのモジュールを検索する PEP 302 [http://www.python.org/dev/peps/pep-0302] importer を作成します。

ImpImporter は現在のところ sys.meta_path に配置しての利用をサポートしていないことに注意してください。

class pkgutil.ImpLoader(fullname, file, filename, etc)

Python の “クラシック” インポートアルゴリズムをラップする PEP 302 [http://www.python.org/dev/peps/pep-0302] Loader.

pkgutil.find_loader(fullname)

fullname に対する PEP 302 [http://www.python.org/dev/peps/pep-0302] “loader” オブジェクトを検索します。

fullname にドットが含まれる場合、パスはそのモジュールを含むパッケージの __path__ でなければなりません。モジュールが見つからない場合や import できない場合は None を返します。この関数は iter_importers() を利用しているので、それと同じように、 Windows レジストリなどのプラットフォーム依存の特別な import 場所に関する制限があります。

pkgutil.get_importer(path_item)

指定された path_item に対する PEP 302 [http://www.python.org/dev/peps/pep-0302] importer を取得します。

path hook により新しい importer が作成された場合は、それは sys.path_importer_cache にキャッシュされます。

importer が存在しない場合、基本 import 機構のラッパーを返します。このラッパーは importer cache にはキャッシュされません。(代わりに None が insert されます)

キャッシュ (やその一部) は、 sys.path_hooks のリスキャンが必要になった場合は手動でクリアすることができます。

pkgutil.get_loader(module_or_name)

module_or_name に対する PEP 302 [http://www.python.org/dev/peps/pep-0302] “loader” を取得します。

module か package が通常の import 機構によってアクセスできる場合、その機構の該当部分に対するラッパーを返します。モジュールが見つからなかったり import できない場合は None を返します。指定された名前のモジュールがまだ import されていない場合、そのモジュールを含むパッケージが(あれば)そのパッケージの __path__ を確立するために import されます。

この関数は iter_importers() を利用しているので、それと同じように、 Windows レジストリなどのプラットフォーム依存の特別な import 場所に関する制限があります。

pkgutil.iter_importers(fullname='')

指定されたモジュール名に対する PEP 302 [http://www.python.org/dev/peps/pep-0302] importer を yield します。

fullname が ‘.’ を含む場合、返される importer は fullname モジュールを持つパッケージのものになり、それ以外の場合は sys.meta_path, sys.path, そして Python の “クラシック” import 機構の順のどれかになります。指定されたモジュールがパッケージ内にある場合、この関数を実行した副作用としてそのパッケージが import されます。

標準の import 機構がファイルを別の場所から探す、 PEP 302 [http://www.python.org/dev/peps/pep-0302] 以外の機構 (例: Windows レジストリ) はある程度までサポートされていますが、それは sys.path の 後に 検索されます。通常、それらの場所は、 sys.path のエントリに隠されないように sys.path の 前に 検索されます。

これは動作の違いは問題になり得るので、モジュールやパッケージ名は sys.path と非 PEP 302 [http://www.python.org/dev/peps/pep-0302] のファイルシステム機構のどれかとの、どちらからもアクセスできる必要があります。こうすると、エミュレート時は前者から、ビルトインの import 機構は後者からモジュールやパッケージを見つけます。

この動作の食い違いにより、以下の種類の要素が影響を受けるかもしれません: imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY.

pkgutil.iter_modules(path=None, prefix='')

path があればその全てのサブモジュールに対して、 path が None なら sys.path の全てのトップレベルモジュールに対して、 (module_loader, name, ispkg) のタプルを yield します。

path は None か、モジュールを検索する path のリストのどちらかでなければなりません。

prefix は出力の全てのモジュール名の頭に出力する文字列です。

pkgutil.walk_packages(path=None, prefix='', onerror=None)

path があれば再帰的にその中のモジュール全てに対して、 path が None ならばアクセスできる全てのモジュールに対して、 (module_loader, name, ispkg) のタプルを yield します。

path は None か、モジュールを検索するパスのリストでなければなりません。

prefix は出力される全てのモジュール名の先頭に出力されます。

この関数は与えられた path 上の全ての パッケージ (全てのモジュール ではない) を、サブモジュールを検索するのに必要な __path__ 属性にアクセスするために import します。

onerror は、パッケージを import しようとしたときに何かの例外が発生した場合に、 1つの引数(import しようとしていたパッケージの名前)で呼び出される関数です。 onerror 関数が提供されない場合、 ImportError は補足され無視されます。それ以外の全ての例外は伝播し、検索を停止させます。

例:

# list all modules python can access
walk_packages()

# list all submodules of ctypes
walk_packages(ctypes.__path__, ctypes.__name__ + '.')

pkgutil.get_data(package, resource)

パッケージからリソースを取得します。

この関数は PEP 302 [http://www.python.org/dev/peps/pep-0302] ローダーの get_data() API のラッパーです。 package 引数は標準的なモジュール形式 (foo.bar) のパッケージ名でなければなりません。 resource 引数は / をパス区切りに使った相対ファイル名の形式です。親ディレクトリを .. としたり、ルートからの (/ で始まる) 名前を使うことはできません。

この関数が返すのは指定されたリソースの内容であるバイナリ文字列です。

ファイルシステム中に位置するパッケージで既にインポートされているものに対しては、次と大体同じです:

d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()

パッケージを見出せなかったりロードできなかったり、あるいは get_data() をサポートしない PEP 302 [http://www.python.org/dev/peps/pep-0302] ローダーを使ったりした場合は、 None が返されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.6. modulefinder — スクリプト中で使われているモジュールを検索する

バージョン 2.3 で追加.

このモジュールでは、スクリプト中で import されているモジュールセットを調べるために使える ModuleFinder クラスを提供しています。 modulefinder.py はまた、Python スクリプトのファイル名を引数に指定してスクリプトとして実行し、 import されているモジュールのレポートを出力させることもできます。

modulefinder.AddPackagePath(pkg_name, path)

pkg_name という名前のパッケージの在り処が path であることを記録します。

modulefinder.ReplacePackage(oldname, newname)

実際にはパッケージ内で oldname という名前になっているモジュールを newname という名前で指定できるようにします。この関数の主な用途は、 _xmlplus パッケージが xml パッケージに置き換わっている場合の処理でしょう。

class modulefinder.ModuleFinder([path=None, debug=0, excludes=[], replace_paths=[]])

このクラスでは run_script() および report() メソッドを提供しています。これらのメソッドは何らかのスクリプト中で import されているモジュールの集合を調べます。 path はモジュールを検索する先のディレクトリ名からなるリストです。 path を指定しない場合、 sys.path を使います。 debug にはデバッグレベルを設定します; 値を大きくすると、実行している内容を表すデバッグメッセージを出力します。 excludes は検索から除外するモジュール名です。 replace_paths には、モジュールパス内で置き換えられるパスをタプル (oldpath, newpath) からなるリストで指定します。

report()

スクリプトで import しているモジュールと、そのパスからなるリストを列挙したレポートを標準出力に出力します。モジュールを見つけられなかったり、モジュールがないように見える場合にも報告します。

run_script(pathname)

pathname に指定したファイルの内容を解析します。ファイルには Python コードが入っていなければなりません。

modules

モジュール名をモジュールに結びつける辞書。 ModuleFinder の使用例 を参照して下さい。

30.6.1. ModuleFinder の使用例

解析対象のスクリプトはこれ (bacon.py) です:

import re, itertools

try:
    import baconhameggs
except ImportError:
    pass

try:
    import guido.python.ham
except ImportError:
    pass

bacon.py のレポートを出力するスクリプトです:

from modulefinder import ModuleFinder

finder = ModuleFinder()
finder.run_script('bacon.py')

print 'Loaded modules:'
for name, mod in finder.modules.iteritems():
    print '%s: ' % name,
    print ','.join(mod.globalnames.keys()[:3])

print '-'*50
print 'Modules not imported:'
print '\n'.join(finder.badmodules.iterkeys())

出力例です (アーキテクチャに依って違ってくるかもしれません):

Loaded modules:
_types:
copy_reg:  _inverted_registry,_slotnames,__all__
sre_compile:  isstring,_sre,_optimize_unicode
_sre:
sre_constants:  REPEAT_ONE,makedict,AT_END_LINE
sys:
re:  __module__,finditer,_expand
itertools:
__main__:  re,itertools,baconhameggs
sre_parse:  __getslice__,_PATTERNENDERS,SRE_FLAG_UNICODE
array:
types:  __module__,IntType,TypeType
---------------------------------------------------
Modules not imported:
guido.python.ham
baconhameggs

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

30. モジュールのインポート »

30.7. runpy — Python モジュールの位置特定と実行

バージョン 2.5 で追加.

runpy モジュールは Python のモジュールをインポートせずにその位置を特定したり実行したりするのに使われます。その主な目的はファイルシステムではなく Python のモジュール名前空間を使って位置を特定したスクリプトの実行を可能にする -m コマンドラインスイッチを実装することです。

runpy モジュールは2つの関数を提供しています:

runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)

指定されたモジュールのコードを実行し、実行後のモジュールグローバル辞書を返します。モジュールのコードはまず標準インポート機構(詳細は PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照) を使ってモジュールの位置を特定され、まっさらなモジュール名前空間で実行されます。

指定されたモジュール名が通常のモジュールではなくパッケージを参照していた場合、そのパッケージが import された後その中の __main__ モジュールが実行され、実行後のモジュールグローバル辞書を返します。

オプションの辞書型引数 init_globals はコードを実行する前にモジュールグローバル辞書に前もって必要な設定しておくのに使われます。与えられた辞書は変更されません。その辞書の中に以下に挙げる特別なグローバル変数が定義されていたとしても、それらの定義は run_module 関数によってオーバーライドされます。

特別なグローバル変数 __name__, __file__, __loader__, __package__ はモジュールコードが実行される前にグローバル辞書にセットされます。 (この変数群は修正される最小セットです。これ以外の変数もインタプリタの実装の詳細として暗黙的に設定されるかもしれません)

__name__ は、オプション引数 run_name が None でない場合、指定されたモジュールがパッケージであれば mod_name + '.__main__' に、そうでなければ mod_name 引数の値がセットされます。

__file__ はモジュールローダにより与えられた名前がセットされます。もしローダがファイル名情報を取得可能にしなければ、この変数の値は None になります。

__loader__ はモジュールのコードを取得するのに使われる PEP 302 [http://www.python.org/dev/peps/pep-0302] のモジュールローダがセットされます(このローダは標準のインポート機構に対するラッパーかもしれません)。

__package__ は指定されたモジュールがパッケージだった場合は mod_name に、それ以外の場合は mod_name.rpartition('.')[0] に設定されます。

引数 alter_sys が与えられて True に評価されるならば、 sys.argv[0] は __file__ の値で更新され sys.modules[__name__] は実行されるモジュールの一時的モジュールオブジェクトで更新されます。 sys.argv[0] と sys.modules[__name__] はどちらも関数が処理を戻す前にもとの値に復旧します。

この sys に対する操作はスレッドセーフではないということに注意してください。他のスレッドは部分的に初期化されたモジュールを見たり、入れ替えられた引数リストを見たりするかもしれません。この関数をスレッド化されたコードから起動するときは sys モジュールには手を触れないことが推奨されます。

バージョン 2.7 で変更: Added ability to execute packages by looking for a __main__ submodule

runpy.run_path(file_path, init_globals=None, run_name=None)

指定されたファイルシステム上の場所にあるコードを実行して、結果としてそのモジュールグローバル辞書を返します。通常の CPython 実行時にコマンドラインで指定するスクリプト名と同じく、指定できるパスは Python ソースファイル、コンパイルされたバイトコードファイル、もしくは __main__ モジュールを含む有効な sys.path エントリ(例: トップレベルに __main__.py ファイルを持つ zip ファイル)です。

シンプルなスクリプトを指定した場合は、指定されたコードはシンプルに新しいモジュール名前空間で実行されます。有効な sys.path エントリ (一般的には zip ファイルかディレクトリ) を指定した場合は、最初にそのエントリが sys.path の先頭に追加されます。次に更新した sys.path を元に __main__ モジュールを検索して実行します。指定された場所に __main__ モジュールが無かった時、 sys.path のどこか他のエントリに存在する別の __main__ を実行してしまう可能性があることに注意してください。

オプションの辞書型引数 init_globals はコードを実行する前にモジュールグローバル辞書に前もって必要な設定しておくのに使われます。与えられた辞書は変更されません。その辞書の中に以下に挙げる特別なグローバル変数が定義されていたとしても、それらの定義は run_path() 関数によってオーバーライドされます。

特別なグローバル変数 __name__, __file__, __loader__, __package__ はモジュールコードが実行される前にグローバル辞書にセットされます。 (この変数群は修正される最小セットです。これ以外の変数もインタプリタの実装の詳細として暗黙的に設定されるかもしれません)

__name__ は、オプション引数 run_name が None でない場合、 run_name に設定され、それ以外の場合は '<run_path>' に設定されます。

__file__ はモジュールローダにより与えられた名前がセットされます。もしローダがファイル名情報を取得可能にしなければ、この変数の値は None になります。シンプルなスクリプトの場合、これは file_path になるでしょう。

__loader__ はモジュールのコードを取得するのに使われる PEP 302 [http://www.python.org/dev/peps/pep-0302] のモジュールローダがセットされます(このローダは標準のインポート機構に対するラッパーかもしれません)。シンプルなスクリプトの場合、これは None になるでしょう。

__package__ は __name__.rpartition('.')[0] に設定されます。

sys モジュールに対していくつかの変更操作が行われます。まず、 sys.path が上記のように修正されます。 sys.argv[0] は file_path に更新され、 sys.modules[__name__] は実行されるモジュールのための一時モジュールオブジェクトに更新されます。 sys の要素に対する全ての変更は、この関数から戻る前に元に戻されます。

run_module() と違い、 sys に対する変更はオプションではありません。これらの変更は sys.path エントリの実行に必要不可欠だからです。スレッドセーフ性に関する制限はこの関数にも存在します。この関数をマルチスレッドプログラムから実行する場合は、 import lock によりシリアライズして実行するか、別プロセスに委譲してください。

バージョン 2.7 で追加.

参考

PEP 338 [http://www.python.org/dev/peps/pep-0338] - Executing modules as scripts

Nick Coghlan によって書かれ実装された PEP

PEP 366 [http://www.python.org/dev/peps/pep-0366] - Main module explicit relative imports

Nick Coghlan によって書かれ実装された PEP

コマンドラインと環境 - CPython コマンドライン詳細

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス

PythonにはPython言語を使って作業するときに役に立つモジュールがたくさん提供されています。これらのモジュールはトークンの切り出し、パース、構文解析、バイトコードのディスアセンブリおよびその他のさまざまな機能をサポートしています。

これらのモジュールには、次のものが含まれています:

31.1. parser — Python 解析木にアクセスする

31.1.1. ST オブジェクトを作成する

31.1.2. ST オブジェクトを変換する

31.1.3. ST オブジェクトに対する問い合わせ

31.1.4. 例外とエラー処理

31.1.5. ST オブジェクト

31.1.6. 例: compile() のエミュレーション

31.2. 抽象構文木

31.2.1. Node クラス

31.2.2. 抽象文法 (Abstract Grammar)

31.2.3. ast ヘルパー

31.3. symtable — コンパイラの記号表へのアクセス

31.3.1. 記号表の生成

31.3.2. 記号表の検査

31.4. symbol — Python 解析木と共に使われる定数

31.5. token — Python 解析木と共に使われる定数

31.6. keyword — Python キーワードチェック

31.7. tokenize — Pythonソースのためのトークナイザ

31.8. tabnanny — あいまいなインデントの検出

31.9. pyclbr — Python クラスブラウザサポート

31.9.1. Class オブジェクト

31.9.2. Function オブジェクト

31.10. py_compile — Python ソースファイルのコンパイル

31.11. compileall — Python ライブラリをバイトコンパイル

31.11.1. コマンドラインでの使用

31.11.2. パブリックな関数

31.12. dis — Python バイトコードの逆アセンブラ

31.12.1. Python バイトコード命令

31.13. pickletools — pickle 開発者のためのツール群

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.1. parser — Python 解析木にアクセスする

parser モジュールは Python の内部パーサとバイトコード・コンパイラへのインターフェイスを提供します。このインターフェイスの第一の目的は、 Python コードから Python の式の解析木を編集したり、これから実行可能なコードを作成したりできるようにすることです。これは任意の Python コードの断片を文字列として構文解析や変更を行うより良い方法です。なぜなら、構文解析がアプリケーションを作成するコードと同じ方法で実行されるからです。その上、高速です。

ノート

Python 2.5 以降、抽象構文木 (AST) の生成・コンパイルの段階に割り込むには ast モジュールを使うのがずっとお手軽です。

parser モジュールはこの文書に書かれている名前の “st” を “ast” に置き換えたものも使えるようにしてあります。こうした名前は Python 2.5 で AST を扱い始める前の AST が他になかった頃から名残です。このことはまた関数の引数が st ではなく ast と呼ばれていることの理由でもあります。 “ast” 系の名前は Python 3.0 で無くなります。

このモジュールについて注意すべきことが少しあります。それは作成したデータ構造を利用するために重要なことです。この文書は Python コードの解析木を編集するためのチュートリアルではありませんが、 parser モジュールを使った例をいくつか示しています。

もっとも重要なことは、内部パーサが処理する Python の文法についてよく理解しておく必要があるということです。言語の文法に関する完全な情報については、 Python 言語リファレンス を参照してください。標準の Python ディストリビューションに含まれるファイル Grammar/Grammar の中で定義されている文法仕様から、パーサ自身は作成されています。このモジュールが作成する ST オブジェクトの中に格納される解析木は、下で説明する expr() または suite() 関数によって作られるときに内部パーサから実際に出力されるものです。 sequence2st() が作る ST オブジェクトは忠実にこれらの構造をシミュレートしています。言語の形式文法が改訂されるために、 “正しい” と考えられるシーケンスの値が Python のあるバージョンから別のバージョンで変化することがあるということに注意してください。しかし、 Python のあるバージョンから別のバージョンへテキストのソースのままコードを移せば、目的のバージョンで正しい解析木を常に作成できます。ただし、インタープリタの古いバージョンへ移行する際に、最近の言語コンストラクトをサポートしていないことがあるという制限だけがあります。ソースコードが常に前方互換性があるのに対して、一般的に解析木はあるバージョンから別のバージョンへの互換性がありません。

st2list() または st2tuple() から返されるシーケンスのそれぞれの要素は単純な形式です。文法の非終端要素を表すシーケンスは常に一より大きい長さを持ちます。最初の要素は文法の生成規則を識別する整数です。これらの整数は C ヘッダファイル Include/graminit.h と Python モジュール symbol の中の特定のシンボル名です。シーケンスに付け加えられている各要素は、入力文字列の中で認識されたままの形で生成規則の構成要素を表しています: これらは常に親と同じ形式を持つシーケンスです。この構造の注意すべき重要な側面は、 if_stmt の中のキーワード if のような親ノードの型を識別するために使われるキーワードがいかなる特別な扱いもなくノードツリーに含まれているということです。例えば、 if キーワードはタプル (1, 'if') と表されます。ここで、 1 は、ユーザが定義した変数名と関数名を含むすべての NAME トークンに対応する数値です。行番号情報が必要なときに返される別の形式では、同じトークンが (1, 'if', 12) のように表されます。ここでは、 12 が終端記号の見つかった行番号を表しています。

終端要素は同じ方法で表現されますが、子の要素や識別されたソーステキストの追加は全くありません。上記の if キーワードの例が代表的なものです。終端記号のいろいろな型は、 C ヘッダファイル Include/token.h と Python モジュール token で定義されています。

ST オブジェクトはこのモジュールの機能をサポートするために必要ありませんが、三つの目的から提供されています: アプリケーションが複雑な解析木を処理するコストを償却するため、 Python のリストやタプル表現に比べてメモリ空間を保全する解析木表現を提供するため、解析木を操作する追加モジュールを C で作ることを簡単にするため。 ST オブジェクトを使っていることを隠すために、簡単な “ラッパー” クラスを Python で作ることができます。

parser モジュールは二、三の別々の目的のために関数を定義しています。もっとも重要な目的は ST オブジェクトを作ることと、 ST オブジェクトを解析木とコンパイルされたコードオブジェクトのような他の表現に変換することです。しかし、 ST オブジェクトで表現された解析木の型を調べるために役に立つ関数もあります。

参考

symbol モジュール

解析木の内部ノードを表す便利な定数。

token モジュール

便利な解析木の葉のノードを表す定数とノード値をテストするための関数。

31.1.1. ST オブジェクトを作成する

ST オブジェクトはソースコードあるいは解析木から作られます。 ST オブジェクトをソースから作るときは、 'eval' と 'exec' 形式を作成するために別々の関数が使われます。

parser.expr(source)

まるで compile(source, 'file.py', 'eval') への入力であるかのように、 expr() 関数はパラメータ source を構文解析します。解析が成功した場合は、 ST オブジェクトは内部解析木表現を保持するために作成されます。そうでなければ、適切な例外を発生させます。

parser.suite(source)

まるで compile(source, 'file.py', 'exec') への入力であるかのように、 suite() 関数はパラメータ source を構文解析します。解析が成功した場合は、 ST オブジェクトは内部解析木表現を保持するために作成されます。そうでなければ、適切な例外を発生させます。

parser.sequence2st(sequence)

この関数はシーケンスとして表現された解析木を受け取り、可能ならば内部表現を作ります。木が Python の文法に合っていることと、すべてのノードが Python のホストバージョンで有効なノード型であることを確認した場合は、 ST オブジェクトが内部表現から作成されて呼び出し側へ返されます。内部表現の作成に問題があるならば、あるいは木が正しいと確認できないならば、 ParserError 例外を発生します。この方法で作られた ST オブジェクトが正しくコンパイルできると決めつけない方がよいでしょう。 ST オブジェクトが compilest() へ渡されたとき、コンパイルによって送出された通常の例外がまだ発生するかもしれません。これは(MemoryError 例外のような)構文に関係していない問題を示すのかもしれないし、 del f(0) を解析した結果のようなコンストラクトが原因であるかもしれません。このようなコンストラクトは Python のパーサを逃れますが、バイトコードインタープリタによってチェックされます。

終端トークンを表すシーケンスは、 (1, 'name') 形式の二つの要素のリストか、または (1, 'name', 56) 形式の三つの要素のリストです。三番目の要素が存在する場合は、有効な行番号だとみなされます。行番号が指定されるのは、入力木の終端記号の一部に対してです。

parser.tuple2st(sequence)

これは sequence2st() と同じ関数です。このエントリポイントは後方互換性のために維持されています。

31.1.2. ST オブジェクトを変換する

作成するために使われた入力に関係なく、 ST オブジェクトはリスト木またはタプル木として表される解析木へ変換されるか、または実行可能なオブジェクトへコンパイルされます。解析木は行番号情報を持って、あるいは持たずに抽出されます。

parser.st2list(ast[, line_info])

この関数は呼び出し側から ast に ST オブジェクトを受け取り、解析木と等価な Python のリストを返します。結果のリスト表現はインスペクションあるいはリスト形式の新しい解析木の作成に使うことができます。リスト表現を作るためにメモリが利用できる限り、この関数は失敗しません。解析木がインスペクションのためだけにつかわれるならば、メモリの消費量と断片化を減らすために st2tuple() を代わりに使うべきです。リスト表現が必要とされるとき、この関数はタプル表現を取り出して入れ子のリストに変換するよりかなり高速です。

line_info が真ならば、トークンを表すリストの三番目の要素として行番号情報がすべての終端トークンに含まれます。与えられた行番号はトークン が終わる 行を指定していることに注意してください。フラグが偽または省略された場合は、この情報は省かれます。

parser.st2tuple(ast[, line_info])

この関数は呼び出し側から ast に ST オブジェクトを受け取り、解析木と等価な Python のタプルを返します。リストの代わりにタプルを返す以外は、この関数は st2list() と同じです。

line_info が真ならば、トークンを表すリストの三番目の要素として行番号情報がすべての終端トークンに含まれます。フラグが偽または省略された場合は、この情報は省かれます。

parser.compilest(ast[, filename='<syntax-tree>'])

exec 文の一部として使える、あるいは、組み込み eval() 関数への呼び出しとして使えるコードオブジェクトを生成するために、 Python バイトコードコンパイラを ST オブジェクトに対して呼び出すことができます。この関数はコンパイラへのインターフェイスを提供し、 filename パラメータで指定されるソースファイル名を使って、 ast からパーサへ内部解析木を渡します。 filename に与えられるデフォルト値は、ソースが ST オブジェクトだったことを示唆しています。

ST オブジェクトをコンパイルすることは、コンパイルに関する例外を引き起こすことになるかもしれません。例としては、 del f(0) の解析木によって発生させられる SyntaxError があります: この文は Python の形式文法としては正しいと考えられますが、正しい言語コンストラクトではありません。この状況に対して発生する SyntaxError は、実際には Python バイトコンパイラによって通常作り出されます。これが parser モジュールがこの時点で例外を発生できる理由です。解析木のインスペクションを行うことで、コンパイルが失敗するほとんどの原因をプログラムによって診断することができます。

31.1.3. ST オブジェクトに対する問い合わせ

ST が式または suite として作成されたかどうかをアプリケーションが決定できるようにする二つの関数が提供されています。これらの関数のどちらも、 ST が expr() または suite() を通してソースコードから作られたかどうか、あるいは、 sequence2st() を通して解析木から作られたかどうかを決定できません。

parser.isexpr(ast)

ast が 'eval' 形式を表している場合に、この関数は真を返します。そうでなければ、偽を返します。これは役に立ちます。なぜならば、通常は既存の組み込み関数を使ってもコードオブジェクトに対してこの情報を問い合わせることができないからです。このどちらのようにも compilest() によって作成されたコードオブジェクトに問い合わせることはできませんし、そのコードオブジェクトは組み込み compile() 関数によって作成されたコードオブジェクトと同じであることに注意してください。

parser.issuite(ast)

ST オブジェクトが(通常 “suite” として知られる) 'exec' 形式を表しているかどうかを報告するという点で、この関数は isexpr() に酷似しています。追加の構文が将来サポートされるかもしれないので、この関数が not isexpr(ast) と等価であるとみなすのは安全ではありません。

31.1.4. 例外とエラー処理

parser モジュールは例外を一つ定義していますが、 Python ランタイム環境の他の部分が提供する別の組み込み例外を発生させることもあります。各関数が発生させる例外の情報については、それぞれ関数を参照してください。

exception parser.ParserError

parser モジュール内部で障害が起きたときに発生する例外。普通の構文解析中に発生する組み込みの SyntaxError ではなく、一般的に妥当性確認が失敗した場合に引き起こされます。例外の引数としては、障害の理由を説明する文字列である場合と、 sequence2st() へ渡される解析木の中の障害を引き起こすシーケンスを含むタプルと説明用の文字列である場合があります。モジュール内の他の関数の呼び出しは単純な文字列値を検出すればよいだけですが、 sequence2st() の呼び出しはどちらの例外の型も処理できる必要があります。

普通は構文解析とコンパイル処理によって発生する例外を、関数 compilest() 、 expr() および suite() が発生させることに注意してください。このような例外には組み込み例外 MemoryError 、 OverflowError 、 SyntaxError および SystemError が含まれます。こうした場合には、これらの例外が通常その例外に関係する全ての意味を伝えます。詳細については、各関数の説明を参照してください。

31.1.5. ST オブジェクト

ST オブジェクト間の順序と等値性の比較がサポートされています。 (pickle モジュールを使った) ST オブジェクトのピクルス化もサポートされています。

parser.STType

expr() 、 suite() と sequence2st() が返すオブジェクトの型。

ST オブジェクトは次のメソッドを持っています:

ST.compile([filename])

compilest(st, filename) と同じ。

ST.isexpr()

isexpr(st) と同じ。

ST.issuite()

issuite(st) と同じ。

ST.tolist([line_info])

st2list(ast, line_info) と同じ。

ST.totuple([line_info])

st2tuple(ast, line_info) と同じ。

31.1.6. 例: compile() のエミュレーション

たくさんの有用な演算を構文解析とバイトコード生成の間に行うことができますが、もっとも単純な演算は何もしないことです。このため、 parser モジュールを使って中間データ構造を作ることは次のコードと等価です。

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10

parser モジュールを使った等価な演算はやや長くなりますが、 ST オブジェクトとして中間内部解析木が維持されるようにします:

>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10

ST とコードオブジェクトの両方が必要なアプリケーションでは、このコードを簡単に利用できる関数にまとめることができます:

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.2. 抽象構文木

バージョン 2.5 で追加: 低級モジュール _ast はノード・クラスだけ含みます。

バージョン 2.6 で追加: 高級モジュール ast は全てのヘルパーを含みます。

ast モジュールは、Python アプリケーションで Python の抽象構文木を処理しやすくするものです。抽象構文そのものは、Python のリリースごとに変化する可能性があります。このモジュールを使用すると、現在の文法をプログラム上で知る助けになるでしょう。

抽象構文木を作成するには、 ast.PyCF_ONLY_AST を組み込み関数 compile() のフラグとして渡すか、あるいはこのモジュールで提供されているヘルパー関数 parse() を使います。その結果は、 ast.AST を継承したクラスのオブジェクトのツリーとなります。抽象構文木は組み込み関数 compile() を使って Python コード・オブジェクトにコンパイルすることができます。

参考

最新バージョンの ast module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/ast.py?view=markup]

31.2.1. Node クラス

class ast.AST

このクラスは全ての AST ノード・クラスの基底です。実際のノード・クラスは 後ほど 示す Parser/Python.asdl ファイルから派生したものです。これらのクラスは _ast C モジュールで定義され、 ast にもエクスポートし直されています。

抽象文法の左辺のシンボル一つずつにそれぞれ一つのクラスがあります (たとえば ast.stmt や ast.expr)。それに加えて、右辺のコンストラクタ一つずつにそれぞれ一つのクラスがあり、これらのクラスは左辺のツリーのクラスを継承しています。たとえば、 BinOp は ast.expr から継承しています。代替を伴った生成規則 (production rules with alternatives) (別名 “sums”) の場合、左辺は抽象クラスとなり、特定のコンストラクタ・ノードのインスタンスのみが作成されます。

_fields

各具象クラスは属性 _fields を持っており、すべての子ノードの名前をそこに保持しています。

具象クラスのインスタンスは、各子ノードに対してそれぞれひとつの属性を持っています。この属性は、文法で定義された型となります。たとえば ast.BinOp のインスタンスは left という属性を持っており、その型は ast.expr です。

これらの属性が、文法上 (クエスチョンマークを用いて) オプションであるとマークされている場合は、その値が None となることもあります。属性が0個以上の複数の値をとりうる場合 (アスタリスクでマークされている場合) は、値は Python のリストで表されます。全ての属性は AST を compile() でコンパイルする際には存在しなければならず、そして妥当な値でなければなりません。

lineno

col_offset

ast.expr や ast.stmt のサブクラスのインスタンスにはさらに lineno や col_offset といった属性があります。 lineno はソーステキスト上の行番号 (1 から数え始めるので、最初の行の行番号は 1 となります)、そして col_offset はノードが生成した最初のトークンの UTF-8 バイトオフセットとなります。 UTF-8 オフセットが記録される理由は、パーサが内部で UTF-8 を使用するからです。

クラス ast.T のコンストラクタは引数を次のように解析します:

位置による引数があるとすれば、 T._fields にあるのと同じだけの個数が無ければなりません。これらの引数はそこにある名前を持った属性として割り当てられます。

キーワード引数があるとすれば、それらはその名前の属性にその値を割り当てられます。

たとえば、 ast.UnaryOp ノードを生成して属性を埋めるには、次のようにすることができます:

node = ast.UnaryOp()
node.op = ast.USub()
node.operand = ast.Num()
node.operand.n = 5
node.operand.lineno = 0
node.operand.col_offset = 0
node.lineno = 0
node.col_offset = 0

もしくはよりコンパクトにも書けます:

node = ast.UnaryOp(ast.USub(), ast.Num(5, lineno=0, col_offset=0),
                   lineno=0, col_offset=0)

バージョン 2.6 で追加: 上で説明したコンストラクタが付け加えられました。 Python 2.5 においてはノードは引数なしのコンストラクタを呼び出して生成した後、全ての属性をセットしていかなければなりませんでした。

31.2.2. 抽象文法 (Abstract Grammar)

このモジュールでは文字列定数 __version__ を定義しています。これは、以下に示すファイルの Subversion リビジョン番号です。

抽象文法は、現在次のように定義されています。

-- ASDL's five builtin types are identifier, int, string, object, bool

module Python version "$Revision: 62047 $"
{
	mod = Module(stmt* body)
	    | Interactive(stmt* body)
	    | Expression(expr body)

	    -- not really an actual node but useful in Jython's typesystem.
	    | Suite(stmt* body)

	stmt = FunctionDef(identifier name, arguments args,
                            stmt* body, expr* decorator_list)
	      | ClassDef(identifier name, expr* bases, stmt* body, expr *decorator_list)
	      | Return(expr? value)

	      | Delete(expr* targets)
	      | Assign(expr* targets, expr value)
	      | AugAssign(expr target, operator op, expr value)

	      -- not sure if bool is allowed, can always use int
 	      | Print(expr? dest, expr* values, bool nl)

	      -- use 'orelse' because else is a keyword in target languages
	      | For(expr target, expr iter, stmt* body, stmt* orelse)
	      | While(expr test, stmt* body, stmt* orelse)
	      | If(expr test, stmt* body, stmt* orelse)
	      | With(expr context_expr, expr? optional_vars, stmt* body)

	      -- 'type' is a bad name
	      | Raise(expr? type, expr? inst, expr? tback)
	      | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
	      | TryFinally(stmt* body, stmt* finalbody)
	      | Assert(expr test, expr? msg)

	      | Import(alias* names)
	      | ImportFrom(identifier module, alias* names, int? level)

	      -- Doesn't capture requirement that locals must be
	      -- defined if globals is
	      -- still supports use as a function!
	      | Exec(expr body, expr? globals, expr? locals)

	      | Global(identifier* names)
	      | Expr(expr value)
	      | Pass | Break | Continue

	      -- XXX Jython will be different
	      -- col_offset is the byte offset in the utf8 string the parser uses
	      attributes (int lineno, int col_offset)

	      -- BoolOp() can use left & right?
	expr = BoolOp(boolop op, expr* values)
	     | BinOp(expr left, operator op, expr right)
	     | UnaryOp(unaryop op, expr operand)
	     | Lambda(arguments args, expr body)
	     | IfExp(expr test, expr body, expr orelse)
	     | Dict(expr* keys, expr* values)
	     | ListComp(expr elt, comprehension* generators)
	     | GeneratorExp(expr elt, comprehension* generators)
	     -- the grammar constrains where yield expressions can occur
	     | Yield(expr? value)
	     -- need sequences for compare to distinguish between
	     -- x < 4 < 3 and (x < 4) < 3
	     | Compare(expr left, cmpop* ops, expr* comparators)
	     | Call(expr func, expr* args, keyword* keywords,
			 expr? starargs, expr? kwargs)
	     | Repr(expr value)
	     | Num(object n) -- a number as a PyObject.
	     | Str(string s) -- need to specify raw, unicode, etc?
	     -- other literals? bools?

	     -- the following expression can appear in assignment context
	     | Attribute(expr value, identifier attr, expr_context ctx)
	     | Subscript(expr value, slice slice, expr_context ctx)
	     | Name(identifier id, expr_context ctx)
	     | List(expr* elts, expr_context ctx)
	     | Tuple(expr* elts, expr_context ctx)

	      -- col_offset is the byte offset in the utf8 string the parser uses
	      attributes (int lineno, int col_offset)

	expr_context = Load | Store | Del | AugLoad | AugStore | Param

	slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step)
	      | ExtSlice(slice* dims)
	      | Index(expr value)

	boolop = And | Or

	operator = Add | Sub | Mult | Div | Mod | Pow | LShift
                 | RShift | BitOr | BitXor | BitAnd | FloorDiv

	unaryop = Invert | Not | UAdd | USub

	cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn

	comprehension = (expr target, expr iter, expr* ifs)

	-- not sure what to call the first argument for raise and except
	excepthandler = ExceptHandler(expr? type, expr? name, stmt* body)
	                attributes (int lineno, int col_offset)

	arguments = (expr* args, identifier? vararg,
		     identifier? kwarg, expr* defaults)

        -- keyword arguments supplied to call
        keyword = (identifier arg, expr value)

        -- import name with optional 'as' alias.
        alias = (identifier name, identifier? asname)
}

31.2.3. ast ヘルパー

バージョン 2.6 で追加.

ノード・クラスの他に、 ast モジュールは以下のような抽象構文木をトラバースするためのユーティリティ関数やクラスも定義しています。

ast.parse(source, filename='<unknown>', mode='exec')

source を解析して AST ノードにします。 compile(source, filename, mode, ast.PyCF_ONLY_AST) と等価です。

ast.literal_eval(node_or_string)

式ノードまたは Python の式を表す文字列を安全に評価します。与えられる文字列またはノードは次のリテラルのみからなるものに限られます: 文字列, 数, タプル, リスト, 辞書, ブール値, None 。

この関数は Python の式を含んだ必ずしも信用できない出どころからの文字列を、自身での値の解析を要さずに、安全に評価するのに使えます。

ast.get_docstring(node, clean=True)

与えられた node (これは FunctionDef, ClassDef, Module のいずれかのノードでなければなりません) のドキュメント文字列を返します。もしドキュメント文字列が無ければ None を返します。 clean が真ならば、ドキュメント文字列のインデントを inspect.cleandoc() を用いて一掃します。

ast.fix_missing_locations(node)

compile() はノード・ツリーをコンパイルする際、 lineno と col_offset 両属性をサポートする全てのノードに対しそれが存在するものと想定します。生成されたノードに対しこれらを埋めて回るのはどちらかというと退屈な作業なので、このヘルパーが再帰的に二つの属性がセットされていないものに親ノードと同じ値をセットしていきます。再帰の出発点が node です。

ast.increment_lineno(node, n=1)

node から始まるツリーの全てのノードの行番号を n ずつ増やします。これはファイルの中で別の場所に「コードを動かす」ときに便利です。

ast.copy_location(new_node, old_node)

ソースの場所 (lineno と col_offset) を old_node から new_node に可能ならばコピーし、 new_node を返します。

ast.iter_fields(node)

node にある node._fields のそれぞれのフィールドを (フィールド名, 値) のタプルとして yield します。

ast.iter_child_nodes(node)

node の直接の子ノード全てを yield します。すなわち、 yield されるのは、ノードであるような全てのフィールドおよびノードのリストであるようなフィールドの全てのアイテムです。

ast.walk(node)

node の全ての子孫ノード(node 自体を含む)を再帰的に yield します。順番は決められていません。この関数はノードをその場で変更するだけで文脈を気にしないような場合に便利です。

class ast.NodeVisitor

抽象構文木を渡り歩いてビジター関数を見つけたノードごとに呼び出すノード・ビジターの基底クラスです。この関数は visit() メソッドに送られる値を返してもかまいません。

このクラスはビジター・メソッドを付け加えたサブクラスを派生させることを意図しています。

visit(node)

ノードを訪れます。デフォルトの実装では self.visit_classname というメソッド (ここで classname はノードのクラス名です) を呼び出すか、そのメソッドがなければ generic_visit() を呼び出します。

generic_visit(node)

このビジターはノードの全ての子について visit() を呼び出します。

注意して欲しいのは、専用のビジター・メソッドを具えたノードの子ノードは、このビジターが generic_visit() を呼び出すかそれ自身で子ノードを訪れない限り訪れられないということです。

トラバースの途中でノードを変化させたいならば NodeVisitor を使ってはいけません。そうした目的のために変更を許す特別なビジター (NodeTransformer) があります。

class ast.NodeTransformer

NodeVisitor のサブクラスで抽象構文木を渡り歩きながらノードを変更することを許すものです。

NodeTransformer は抽象構文木(AST)を渡り歩き、ビジター・メソッドの戻り値を使って古いノードを置き換えたり削除したりします。ビジター・メソッドの戻り値が None ならば、ノードはその場から取り去られ、そうでなければ戻り値で置き換えられます。置き換えない場合は戻り値が元のノードそのものであってもかまいません。

それでは例を示しましょう。 Name (たとえば foo) を見つけるたび全て data['foo'] に書き換える変換器 (transformer) です:

class RewriteName(NodeTransformer):

    def visit_Name(self, node):
        return copy_location(Subscript(
            value=Name(id='data', ctx=Load()),
            slice=Index(value=Str(s=node.id)),
            ctx=node.ctx
        ), node)

操作しようとしているノードが子ノードを持つならば、その子ノードの変形も自分で行うか、またはそのノードに対し最初に generic_visit() メソッドを呼び出すか、それを行うのはあなたの責任だということを肝に銘じましょう。

文のコレクションであるようなノード (全ての文のノードが当てはまります) に対して、このビジターは単独のノードではなくノードのリストを返すかもしれません。

たいてい、変換器の使い方は次のようになります:

node = YourTransformer().visit(node)

ast.dump(node, annotate_fields=True, include_attributes=False)

node 中のツリーのフォーマットされたダンプを返します。主な使い道はデバッグです。返される文字列は名前とフィールドの値を表示します。これを使うとコードは評価できなくなりますので、評価が必要ならば annotated_fields に False をセットしなければなりません。行番号や列オフセットのような属性はデフォルトではダンプされません。これが欲しければ、 include_attributes を True にセットすることができます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.3. symtable — コンパイラの記号表へのアクセス

記号表(symbol table)は、コンパイラが AST からバイトコードを生成する直前に作られます。記号表はコード中の全ての識別子のスコープの算出に責任を持ちます。 symtable はこうした記号表を調べるインターフェイスを提供します。

31.3.1. 記号表の生成

symtable.symtable(code, filename, compile_type)

Python ソース code に対するトップレベルの SymbolTable を返します。 filename はコードを収めてあるファイルの名前です。 compile_type は compile() の mode 引数のようなものです。

31.3.2. 記号表の検査

class symtable.SymbolTable

ブロックに対する名前空間の記号表。コンストラクタはパブリックではありません。

get_type()

記号表の型を返します。有り得る値は 'class', 'module', 'function' です。

get_id()

記号表の識別子を返します。

get_name()

記号表の名前を返します。この名前は記号表がクラスに対するものであればクラス名であり、関数に対するものであれば関数名であり、グローバルな (get_type() が 'module' を返す) 記号表であれば 'top' です。

get_lineno()

この記号表に対応するブロックの一行目の行番号を返します。

is_optimized()

この記号表に含まれるローカル変数が最適化できるならば True を返します。

is_nested()

ブロックが入れ子のクラスまたは関数のとき True を返します。

has_children()

ブロックが入れ子の名前空間を含んでいるならば True を返します。入れ子の名前空間は get_children() で得られます。

has_exec()

ブロックの中で exec が使われているならば True を返します。

has_import_star()

ブロックの中で * を使った from-import が使われているならば True を返します。

get_identifiers()

この記号表にある記号の名前のリストを返します。

lookup(name)

記号表から名前 name を見つけ出して Symbol インスタンスとして返します。

get_symbols()

記号表中の名前を表す Symbol インスタンスのリストを返します。

get_children()

入れ子になった記号表のリストを返します。

class symtable.Function

関数またはメソッドの名前空間。このクラスは SymbolTable を継承しています。

get_parameters()

この関数の引数名からなるタプルを返します。

get_locals()

この関数のローカル変数の名前からなるタプルを返します。

get_globals()

この関数のグローバル変数の名前からなるタプルを返します。

get_frees()

この関数の自由変数の名前からなるタプルを返します。

class symtable.Class

クラスの名前空間。このクラスは SymbolTable を継承しています。

get_methods()

このクラスで宣言されているメソッド名からなるタプルを返します。

class symtable.Symbol

SymbolTable のエントリーでソースの識別子に対応するものです。コンストラクタはパブリックではありません。

get_name()

記号の名前を返します。

is_referenced()

記号がそのブロックの中で使われていれば True を返します。

is_imported()

記号が import 文で作られたものならば True を返します。

is_parameter()

記号がパラメータならば True を返します。

is_global()

記号がグローバルならば True を返します。

is_declared_global()

記号が global 文によってグローバルであると宣言されているなら True を返します。

is_local()

記号がそのブロックに対してローカルならば True を返します。

is_free()

記号がそのブロックの中で参照されていて、しかし代入は行われないならば True を返します。

is_assigned()

記号がそのブロックの中で代入されているならば True を返します。

is_namespace()

名前の束縛が新たな名前空間を導入するならば True を返します。

名前が関数または class 文のターゲットとして使われるならば、真です。

例えば:

>>> table = symtable.symtable("def some_func(): pass", "string", "exec")
>>> table.lookup("some_func").is_namespace()
True

一つの名前が複数のオブジェクトに束縛されうることに注意しましょう。結果が True であったとしても、その名前は他のオブジェクトにも束縛されるかもしれず、それがたとえば整数やリストであれば、そこでは新たな名前空間は導入されません。

get_namespaces()

この名前に束縛された名前空間のリストを返します。

get_namespace()

この名前に束縛されたただ一つの名前空間を返します。束縛された名前空間が一つより多くあれば ValueError が送出されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.4. symbol — Python 解析木と共に使われる定数

このモジュールは解析木の内部ノードの数値を表す定数を提供します。ほとんどの Python 定数とは違い、これらは小文字の名前を使います。言語の文法のコンテキストにおける名前の定義については、 Python ディストリビューションのファイル Grammar/Grammar を参照してください。名前がマップする特定の数値は Python のバージョン間で変わります。

このモジュールには、データオブジェクトも一つ付け加えられています:

symbol.sym_name

ディクショナリはこのモジュールで定義されている定数の数値を名前の文字列へマップし、より人が読みやすいように解析木を表現します。

参考

parser モジュール

parser モジュールの二番目の例で、 symbol モジュールの使い方を示しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.5. token — Python 解析木と共に使われる定数

このモジュールは解析木の葉ノード(終端記号)の数値を表す定数を提供します。言語の文法のコンテキストにおける名前の定義については、 Python ディストリビューションのファイル Grammar/Grammar を参照してください。名前がマップする特定の数値は Python のバージョン間で変わります。

このモジュールは、数値コードから名前へのマッピングと、いくつかの関数も提供しています。関数は Python の C ヘッダファイルの定義を反映します。

token.tok_name

辞書はこのモジュールで定義されている定数の数値を名前の文字列へマップし、より人が読みやすいように解析木を表現します。

token.ISTERMINAL(x)

終端トークンの値に対して真を返します。

token.ISNONTERMINAL(x)

非終端トークンの値に対して真を返します。

token.ISEOF(x)

x が入力の終わりを示すマーカーならば、真を返します。

token の定数一覧:

token.ENDMARKER

token.NAME

token.NUMBER

token.STRING

token.NEWLINE

token.INDENT

token.DEDENT

token.LPAR

token.RPAR

token.LSQB

token.RSQB

token.COLON

token.COMMA

token.SEMI

token.PLUS

token.MINUS

token.STAR

token.SLASH

token.VBAR

token.AMPER

token.LESS

token.GREATER

token.EQUAL

token.DOT

token.PERCENT

token.BACKQUOTE

token.LBRACE

token.RBRACE

token.EQEQUAL

token.NOTEQUAL

token.LESSEQUAL

token.GREATEREQUAL

token.TILDE

token.CIRCUMFLEX

token.LEFTSHIFT

token.RIGHTSHIFT

token.DOUBLESTAR

token.PLUSEQUAL

token.MINEQUAL

token.STAREQUAL

token.SLASHEQUAL

token.PERCENTEQUAL

token.AMPEREQUAL

token.VBAREQUAL

token.CIRCUMFLEXEQUAL

token.LEFTSHIFTEQUAL

token.RIGHTSHIFTEQUAL

token.DOUBLESTAREQUAL

token.DOUBLESLASH

token.DOUBLESLASHEQUAL

token.AT

token.OP

token.ERRORTOKEN

token.N_TOKENS

token.NT_OFFSET

参考

parser モジュール

parser モジュールの二番目の例で、 symbol モジュールの使い方を示しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.6. keyword — Python キーワードチェック

このモジュールでは、 Python プログラムで文字列がキーワードか否かをチェックする機能を提供します。

keyword.iskeyword(s)

s が Python のキーワードであれば真を返します。

keyword.kwlist

インタープリタで定義している全てのキーワードのシーケンス。特定の __future__ 宣言がなければ有効ではないキーワードでもこのリストには含まれます。

参考

最新のバージョンの keyword モジュールの Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/keyword.py?view=markup]

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.7. tokenize — Pythonソースのためのトークナイザ

tokenize モジュールでは、Python で実装された Python ソースコードの字句解析器を提供します。さらに、このモジュールの字句解析器はコメントもトークンとして返します。このため、このモジュールはスクリーン上で表示する際の色付け機能 (colorizers) を含む “清書出力器 (pretty-printer)” を実装する上で便利です。

参考

最新バージョンの tokenize module Python ソースコード [http://svn.python.org/view/python/branches/release27-maint/Lib/tokenize.py?view=markup]

第一のエントリポイントはジェネレータ(generator)です:

tokenize.generate_tokens(readline)

generate_tokens() ジェネレータは一つの引数 readline を必要とします。この引数は呼び出し可能オブジェクトで、組み込みファイルオブジェクトにおける readline() メソッドと同じインタフェースを提供していなければなりません ( ファイルオブジェクト 節を参照してください)。この関数は呼び出しのたびに入力内の一行を文字列で返さなければなりません。

ジェネレータは 5 要素のタプルを返し、タプルは以下のメンバ: トークン型; トークン文字列; ソースコード中でトークンが始まる行と列を示す整数の2要素のタプル (srow, scol) ; ソースコード中でトークンが終わる行と列を示す整数の2要素のタプル (srow, scol) ; そして、トークンが見つかった行、からなります。渡される行は 論理 行です; 連続する行は一行に含められます。

バージョン 2.2 で追加.

後方互換性のために古いエントリポイントが残されています:

tokenize.tokenize(readline[, tokeneater])

tokenize() 関数は二つのパラメータを取ります: 一つは入力ストリームを表し、もう一つは tokenize() のための出力メカニズムを与えます。

最初のパラメータ、 readline は、組み込みファイルオブジェクトの readline() メソッドと同じインタフェイスを提供する呼び出し可能オブジェクトでなければなりません ( ファイルオブジェクト 節を参照)。この関数は呼び出しのたびに入力内の一行を文字列で返さなければなりません。もしくは、 readline を呼び出し可能オブジェクトで StopIteration を送出することで補完を知らせるものとすることもできます。

バージョン 2.5 で変更: StopIteration サポートの追加.

二番目のパラメータ tokeneater も呼び出し可能オブジェクトでなければなりません。この関数は各トークンに対して一度だけ呼び出され、 generate_tokens() が生成するタプルに対応する 5 つの引数をとります。

token モジュールの全ての定数は tokenize でも公開されており、これに加え、以下の二つのトークン値が tokenize() の tokeneater 関数に渡される可能性があります:

tokenize.COMMENT

コメントであることを表すために使われるトークン値です。

tokenize.NL

終わりではない改行を表すために使われるトークン値。 NEWLINE トークンは Pythonコードの論理行の終わりを表します。 NLトークンはコードの論理行が複数の物理行にわたって続いているときに作られます。

もう一つの関数がトークン化プロセスを逆転するために提供されています。これは、スクリプトを字句解析し、トークンのストリームに変更を加え、変更されたスクリプトを書き戻すようなツールを作成する際に便利です。

tokenize.untokenize(iterable)

トークンの列を Python ソースコードに変換します。 iterable は少なくとも二つの要素、トークン型およびトークン文字列、からなるシーケンスを返します。その他のシーケンスの要素は無視されます。

再構築されたスクリプトは一つの文字列として返されます。得られる結果はもう一度字句解析すると入力と一致することが保証されるので、変換がロスレスでありラウンドトリップできることは間違いありません。この保証はトークン型およびトークン文字列に対してのものでトークン間のスペース (コラム位置)のようなものは変わることがあり得ます。

バージョン 2.5 で追加.

スクリプト書き換えの例で、浮動小数点数リテラルを Decimal オブジェクトに変換します:

def decistmt(s):
    """Substitute Decimals for floats in a string of statements.

    >>> from decimal import Decimal
    >>> s = 'print +21.3e-5*-.1234/81.7'
    >>> decistmt(s)
    "print +Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7')"

    >>> exec(s)
    -3.21716034272e-007
    >>> exec(decistmt(s))
    -3.217160342717258261933904529E-7

    """
    result = []
    g = generate_tokens(StringIO(s).readline)   # tokenize the string
    for toknum, tokval, _, _, _  in g:
        if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens
            result.extend([
                (NAME, 'Decimal'),
                (OP, '('),
                (STRING, repr(tokval)),
                (OP, ')')
            ])
        else:
            result.append((toknum, tokval))
    return untokenize(result)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.8. tabnanny — あいまいなインデントの検出

差し当たり、このモジュールはスクリプトとして呼び出すことを意図しています。しかし、IDE 上にインポートして下で説明する関数 check() を使うことができます。

ノート

このモジュールが提供する API を将来のリリースで変更する確率が高いです。このような変更は後方互換性がないかもしれません。

tabnanny.check(file_or_dir)

file_or_dir がディレクトリであってシンボリックリンクでないときに、 file_or_dir という名前のディレクトリツリーを再帰的に下って行き、この通り道に沿ってすべての .py ファイルを変更します。 file_or_dir が通常の Python ソースファイルの場合には、問題のある空白をチェックします。診断メッセージは print 文を使って標準出力に書き込まれます。

tabnanny.verbose

冗長なメッセージをプリントするかどうかを示すフラグ。スクリプトとして呼び出された場合は、 -v オプションによって増加します。

tabnanny.filename_only

問題のある空白を含むファイルのファイル名のみをプリントするかどうかを示すフラグ。スクリプトとして呼び出された場合は、 -q オプションによって真に設定されます。

exception tabnanny.NannyNag

あいまいなインデントを検出した場合に tokeneater() によって発生させられます。 check() で捕捉され処理されます。

tabnanny.tokeneater(type, token, start, end, line)

この関数は関数 tokenize.tokenize() へのコールバックパラメータとして check() によって使われます。

参考

tokenize モジュール

Pythonソースコードの字句解析器。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.9. pyclbr — Python クラスブラウザサポート

この pyclbr モジュールはモジュールで定義されたクラス、メソッド、およびトップレベルの関数について、限られた量の情報を取得するのに使われます。伝統的な 3 ペイン形式のクラスブラウザを実装するのに十分な情報を提供します。情報は、モジュールのインポートによらず、ソースコードから抽出します。このため、このモジュールは信用できないソースコードに対して利用しても安全です。この制限から、多くの標準モジュールやオプションの拡張モジュールを含む、 Python で実装されていないモジュールに対して利用することはできません。

pyclbr.readmodule(module[, path=None])

モジュールを読み込み、クラス名からクラス記述オブジェクトにマップする辞書を返します。パラメタ module はモジュール名を表す文字列でなくてはなりません; パッケージ内のモジュール名でもかまいません。 path パラメタはシーケンス型でなくてはならず、モジュールのソースコードがある場所を特定する際に sys.path の値に加えて使われます。

pyclbr.readmodule_ex(module[, path=None])

readmodule() に似ていますが、返される辞書は、クラス名からクラス記述オブジェクトへの対応付けに加えて、トップレベル関数から関数記述オブジェクトへの対応付けも行っています。さらに、読み出し対象のモジュールがパッケージである場合、返される辞書はキー '__path__' を持ち、その値はパッケージの検索パスが入ったリストになります。

31.9.1. Class オブジェクト

Class オブジェクトは、 readmodule() や readmodule_ex() が返す辞書の値として使われており、以下のデータメンバを提供しています:

Class.module

クラス記述オブジェクトが記述している対象のクラスを定義しているモジュールの名前です。

Class.name

クラスの名前です。

Class.super

記述しようとしている対象クラスの、直接の基底クラス群について記述している Class オブジェクトのリストです。スーパクラスとして挙げられているが readmodule() が見つけられなかったクラスは、 Class オブジェクトではなくクラス名の文字列としてリストに挙げられます。

Class.methods

メソッド名を行番号に対応付ける辞書です。

Class.file

クラスを定義している class 文が入っているファイルの名前です。

Class.lineno

file で指定されたファイルにおける class 文の行番号です。

31.9.2. Function オブジェクト

Function オブジェクトは、 readmodule_ex() が返す辞書内でキーに対応する値として使われており、以下のデータメンバを提供しています:

Function.module

関数記述オブジェクトが記述している対象の関数を定義しているモジュールの名前です。

Function.name

関数の名前です。

Function.file

関数を定義してる def 文が入っているファイルの名前です。

Function.lineno

file で指定されたファイルにおける def 文の行番号です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.10. py_compile — Python ソースファイルのコンパイル

py_compile モジュールには、ソースファイルからバイトコードファイルを作る関数と、モジュールのソースファイルがスクリプトとして呼び出される時に使用される関数が定義されています。

頻繁に必要となるわけではありませんが、共有ライブラリとしてモジュールをインストールする場合や、特にソースコードのあるディレクトリにバイトコードのキャッシュファイルを書き込む権限がないユーザがいるときには、この関数は役に立ちます。

exception py_compile.PyCompileError

ファイルをコンパイル中にエラーが発生すると送出される例外。

py_compile.compile(file[, cfile[, dfile[, doraise]]])

ソースファイルをバイトコードにコンパイルして、バイトコードのキャッシュファイルに書き出します。ソースコードはファイル名 file で渡します。バイトコードはファイル cfile に書き込まれ、デフォルトでは file + 'c' (使用しているインタープリタで最適化が可能なら 'o') です。もし dfile が指定されたら、 file の代わりにソースファイルの名前としてエラーメッセージの中で使われます。 doraise が真の場合、コンパイル中にエラーが発生すると PyCompileError を送出します。 doraise が偽の場合(デフォルト)はエラーメッセージは sys.stderr に出力されますが、例外は送出しません。

py_compile.main([args])

いくつか複数のソースファイルをコンパイルします。 args で (あるいは args で指定されなかったらコマンドラインで) 指定されたファイルをコンパイルし、できたバイトコードを通常の方法で保存します。この関数はソースファイルの存在するディレクトリを検索しません。指定されたファイルをコンパイルするだけです。 args が '-' 1つだけだった場合、ファイルのリストは標準入力から取られます。

バージョン 2.7 で変更: '-' のサポートが追加されました。

このモジュールがスクリプトとして実行されると、 main() がコマンドラインで指定されたファイルを全てコンパイルします。一つでもコンパイルできないファイルがあると終了ステータスが 0 でない値になります。

バージョン 2.6 で変更: モジュールがスクリプトとして実行された場合の 0 でない終了ステータスが追加された。

参考

compileall モジュール

ディレクトリツリー内の Python ソースファイルを全てコンパイルするライブラリ。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.11. compileall — Python ライブラリをバイトコンパイル

このモジュールは、Python ライブラリのインストールを助けるユーティリティ関数群を提供します。この関数群は、ディレクトリツリー内の Python ソースファイルをコンパイルします。このモジュールを使って、キャッシュされたバイトコードファイルをライブラリのインストール時に生成することで、ライブラリディレクトリに書き込み権限をもたないユーザでも、これらを利用できるようになります。

31.11.1. コマンドラインでの使用

このモジュールは、 (python -m compileall を使って) Python ソースをコンパイルするスクリプトとして機能します。

[directory|file]...

位置引数は、コンパイルするファイル群か、再帰的に横断されるディレクトリでソースファイル群を含むものです。引数が与えられなければ、 -l <directories from sys.path> を渡したのと同じように動作します。

-l

サブディレクトリを再帰処理せず、指名または暗示されたディレクトリ群に含まれるソースコードファイル群だけをコンパイルします。

-f

タイムスタンプが最新であってもリビルドを強制します。

-q

コンパイルされたファイルを一覧表示せず、エラーメッセージのみ表示します。

-d destdir

コンパイルされるそれぞれのファイルへのパスの先頭に、ディレクトリを追加します。これはコンパイル時トレースバックに使われ、バイトコードファイルが実行される時点でソースファイルが存在しない場合に、トレースバックやその他のメッセージに使われるバイトコードファイルにもコンパイルされます。

-x regex

regex を使って、コンパイル候補のそれぞれのファイルのフルパスを検索し、 regex がマッチしたファイルを除外します。

-i list

ファイル list を読み込み、そのファイルのそれぞれの行を、コンパイルするファイルとディレクトリのリストに加えます。 list が - なら、 stdin の行を読み込みます。

バージョン 2.7 で変更: -i オプションを追加しました。

31.11.2. パブリックな関数

compileall.compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]])

dir で指定されたディレクトリを再帰的に下降し、見つかった .py を全てコンパイルします。

maxlevels パラメタは、再帰する深さの限度に使われ、デフォルトは 10 です。

ddir が与えられれば、コンパイルされるそれぞれのファイルへのパスの先頭に、そのディレクトリを追加します。これはコンパイル時トレースバックに使われ、バイトコードファイルが実行される時点でソースファイルが存在しない場合に、トレースバックやその他のメッセージに使われるバイトコードファイルにもコンパイルされます。

force が真の場合、モジュールはファイルの更新日付に関わりなく再コンパイルされます。

rx が与えられれば、コンパイル候補のそれぞれのファイルのフルパスに対して検索メソッドが呼び出され、それが真値を返したら、そのファイルは除外されます。

quiet が真の場合、エラーが起こらない限り標準出力に何も表示しません。

compileall.compile_file(fullname[, ddir[, force[, rx[, quiet]]]])

パス fullname のファイルをコンパイルします。

ddir が与えられれば、コンパイルされるファイルへのパスの先頭に、そのディレクトリを追加します。これはコンパイル時トレースバックに使われ、バイトコードファイルが実行される時点でソースファイルが存在しない場合に、トレースバックやその他のメッセージに使われるバイトコードファイルにもコンパイルされます。

rx が与えられれば、コンパイル候補のファイルのフルパスに対して検索メソッドが呼び出され、それが真値を返したら、ファイルはコンパイルされず、 True が返されます。

quiet が真の場合、エラーが起こらない限り標準出力に何も表示しません。

バージョン 2.7 で追加.

compileall.compile_path([skip_curdir[, maxlevels[, force]]])

sys.path に含まれる、全ての .py ファイルをバイトコンパイルします。 skip_curdir が真（デフォルト）の時、カレントディレクトリは検索されません。その他のパラメタはすべて compile_dir() 関数に渡されます。なお、他のコンパイル関数とは違い、 maxlevels のデフォルトは 0 です。

Lib/ ディレクトリ以下にある全ての .py ファイルを強制的に再コンパイルするには、以下のようにします:

import compileall

compileall.compile_dir('Lib/', force=True)

# .svn ディレクトリにあるファイルを除いて同じことをするにはこのようにします。
import re
compileall.compile_dir('Lib/', rx=re.compile('/[.]svn'), force=True)

参考

py_compile モジュール

一つのソースファイルをバイトコンパイルします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.12. dis — Python バイトコードの逆アセンブラ

dis モジュールは CPython バイトコード (bytecode) を逆アセンブルすることでバイトコードの解析をサポートします。このモジュールが入力として受け取る CPython バイトコードはファイル Include/opcode.h に定義されており、コンパイラとインタプリタが使用しています。

参考

Latest version of the dis module Python source code [http://svn.python.org/view/python/branches/release27-maint/Lib/dis.py?view=markup]

CPython implementation detail: バイトコードは CPython インタプリタの実装詳細です! Python のバージョン間でバイトコードの追加や、削除、変更がないという保証はありません。このモジュールを使用することによって Python の異なる VM または異なるリリースの間で動作すると考えるべきではありません。

例: 以下の関数 myfunc() を考えると

def myfunc(alist):
    return len(alist)

myfunc() の逆アセンブル結果を得るために次のコマンドを使うことができます

>>> dis.dis(myfunc)
  2           0 LOAD_GLOBAL              0 (len)
              3 LOAD_FAST                0 (alist)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE

(“2”は行番号です)。

dis モジュールは次の関数と定数を定義します:

dis.dis([bytesource])

bytesource オブジェクトを逆アセンブルします。 bytesource はモジュール、クラス、関数、あるいはコードオブジェクトのいずれかを示します。モジュールに対しては、すべての関数を逆アセンブルします。クラスに対しては、すべてのメソッドを逆アセンブルします。単一のコード列に対しては、バイトコード命令ごとに 1 行を出力します。オブジェクトが与えられない場合は、最後のトレースバックを逆アセンブルします。

dis.distb([tb])

トレースバックのスタックの先頭の関数を逆アセンブルします。 Noneが渡された場合は最後のトレースバックを使います。例外を引き起こした命令が表示されます。

dis.disassemble(code[, lasti])

コードオブジェクトを逆アセンブルします。 lasti が与えられた場合は、最後の命令を示します。出力は次のようなカラムに分割されます:

各行の最初の命令に対する行番号。

現在の命令。 --> として示されます。

ラベル付けされた命令。 >> とともに表示されます。

命令のアドレス。

命令コード名。

命令パラメタ。

パラメタの解釈を括弧で囲んだもの。

パラメタの解釈は、ローカル変数とグローバル変数の名前、定数の値、分岐先、比較命令を認識します。

dis.disco(code[, lasti])

disassemble() の別名。よりタイプしやすく、以前の Python リリースと互換性があります。

dis.findlinestarts(code)

このジェネレータ関数は、コードオブジェクト code の co_firstlineno と co_lnotab 属性を使い、ソースコード内の行が始まる場所であるオフセットを求めます。これらは (offset, lineno) の対として生成されます。

dis.findlabels(code)

ジャンプ先であるコードオブジェクト code のすべてのオフセットを求め、これらのオフセットのリストを返します。

dis.opname

命令コード名のリスト。バイトコードをインデクスに使って参照できます。

dis.opmap

命令コード名をバイトコードに対応づける辞書。

dis.cmp_op

すべての比較命令の名前のリスト。

dis.hasconst

定数パラメタを持つバイトコードのリスト。

dis.hasfree

自由変数にアクセスするバイトコードのリスト。

dis.hasname

名前によって属性にアクセスするバイトコードのリスト。

dis.hasjrel

相対ジャンプ先を持つバイトコードのリスト。

dis.hasjabs

絶対ジャンプ先を持つバイトコードのリスト。

dis.haslocal

ローカル変数にアクセスするバイトコードのリスト。

dis.hascompare

ブール命令のバイトコードのリスト。

31.12.1. Python バイトコード命令

現在 Python コンパイラは次のバイトコード命令を生成します。

STOP_CODE()

コンパイラにコードの終わりを知らせます。インタプリタでは使われません。

NOP()

なにもしないコード。バイトコードオプティマイザでプレースホルダとして使われます。

POP_TOP()

スタックの先頭 (TOS) の要素を取り除きます。

ROT_TWO()

スタックの先頭の 2 つの要素を入れ替えます。

ROT_THREE()

スタックの二番目と三番目の要素の位置を 1 つ上げ、先頭を三番目へ下げます。

ROT_FOUR()

スタックの二番目、三番目および四番目の位置を 1 つ上げ、先頭を四番目に下げます。

DUP_TOP()

スタックの先頭にある参照の複製を作ります。

単項命令はスタックの先頭を取り出して操作を適用し、結果をスタックへプッシュし戻します。

UNARY_POSITIVE()

TOS = +TOS に対応します。

UNARY_NEGATIVE()

TOS = -TOS に対応します。

UNARY_NOT()

TOS = not TOS に対応します。

UNARY_CONVERT()

TOS = `TOS` に対応します。

UNARY_INVERT()

TOS = ~TOS に対応します。

GET_ITER()

TOS = iter(TOS) に対応します。

二項命令はスタックの先頭 (TOS) と先頭から二番目の要素をスタックから取り除きます。命令を実行し、スタックへ結果をプッシュし戻します。

BINARY_POWER()

TOS = TOS1 ** TOS に対応します。

BINARY_MULTIPLY()

TOS = TOS1 * TOS に対応します。

BINARY_DIVIDE()

from __future__ import division が有効でないときの TOS = TOS1 / TOS に対応します。

BINARY_FLOOR_DIVIDE()

TOS = TOS1 // TOS に対応します。

BINARY_TRUE_DIVIDE()

from __future__ import division が有効なときの TOS = TOS1 / TOS に対応します。

BINARY_MODULO()

TOS = TOS1 % TOS に対応します。

BINARY_ADD()

TOS = TOS1 + TOS に対応します。

BINARY_SUBTRACT()

TOS = TOS1 - TOS に対応します。

BINARY_SUBSCR()

TOS = TOS1[TOS] に対応します。

BINARY_LSHIFT()

TOS = TOS1 << TOS に対応します。

BINARY_RSHIFT()

TOS = TOS1 >> TOS に対応します。

BINARY_AND()

TOS = TOS1 & TOS に対応します。

BINARY_XOR()

TOS = TOS1 ^ TOS に対応します。

BINARY_OR()

TOS = TOS1 | TOS に対応します。

インプレース命令は TOS と TOS1 を取り除いて結果をスタックへプッシュするという点で二項命令と似ています。しかし、TOS1 がインプレース命令をサポートしている場合には操作が直接 TOS1 に行われます。また、操作結果の TOS は (常に同じというわけではありませんが) 元の TOS1 と同じオブジェクトになることが多いです。

INPLACE_POWER()

インプレースの TOS = TOS1 ** TOS に対応します。

INPLACE_MULTIPLY()

インプレースの TOS = TOS1 * TOS に対応します。

INPLACE_DIVIDE()

from __future__ import division が有効でないときのインプレースの TOS = TOS1 / TOS に対応します。

INPLACE_FLOOR_DIVIDE()

インプレースの TOS = TOS1 // TOS に対応します。

INPLACE_TRUE_DIVIDE()

from __future__ import division が有効なときのインプレースの TOS = TOS1 / TOS に対応します。

INPLACE_MODULO()

インプレースの TOS = TOS1 % TOS に対応します。

INPLACE_ADD()

インプレースの TOS = TOS1 + TOS に対応します。

INPLACE_SUBTRACT()

インプレースの TOS = TOS1 - TOS に対応します。

INPLACE_LSHIFT()

インプレースの TOS = TOS1 << TOS に対応します。

INPLACE_RSHIFT()

インプレースの TOS = TOS1 >> TOS に対応します。

INPLACE_AND()

インプレースの TOS = TOS1 & TOS に対応します。

INPLACE_XOR()

インプレースの TOS = TOS1 ^ TOS に対応します。

INPLACE_OR()

インプレースの TOS = TOS1 | TOS に対応します。

スライス命令コードは最大 3 つのパラメタを取ります。

SLICE+0()

TOS = TOS[:] に対応します。

SLICE+1()

TOS = TOS1[TOS:] に対応します。

SLICE+2()

TOS = TOS1[:TOS] に対応します。

SLICE+3()

TOS = TOS2[TOS1:TOS] に対応します。

スライス代入はさらにもう 1 つのパラメタを必要とします。他の文と同じく、これらはスタックに何もプッシュしません。

STORE_SLICE+0()

TOS[:] = TOS1 に対応します。

STORE_SLICE+1()

TOS1[TOS:] = TOS2 に対応します。

STORE_SLICE+2()

TOS1[:TOS] = TOS2 に対応します。

STORE_SLICE+3()

TOS2[TOS1:TOS] = TOS3 に対応します。

DELETE_SLICE+0()

del TOS[:] に対応します。

DELETE_SLICE+1()

del TOS1[TOS:] に対応します。

DELETE_SLICE+2()

del TOS1[:TOS] に対応します。

DELETE_SLICE+3()

del TOS2[TOS1:TOS] に対応します。

STORE_SUBSCR()

TOS1[TOS] = TOS2 に対応します。

DELETE_SUBSCR()

del TOS1[TOS] に対応します。

その他の命令コード。

PRINT_EXPR()

対話モードのための式文に対応します。TOS はスタックから取り除かれ表示されます。非対話モードにおいては、式文は POP_STACK で終了しています。

PRINT_ITEM()

sys.stdout に束縛されたファイル互換オブジェクトに対して TOS を出力します。 print 文の各要素に対してこのような命令が一つずつあります。

PRINT_ITEM_TO()

PRINT_ITEM と似ていますが、TOS から二番目の要素を TOS にあるファイル互換オブジェクトへ出力します。これは拡張 print 文で使われます。

PRINT_NEWLINE()

sys.stdout へ改行を表示します。これは print 文がコンマで終わっていない場合に print 文の最後の命令として生成されます。

PRINT_NEWLINE_TO()

PRINT_NEWLINE と似ていますが、TOSのファイル互換オブジェクトに改行を表示します。これは拡張 print 文で使われます。

BREAK_LOOP()

break 文によってループを終了します。

CONTINUE_LOOP(target)

continue 文によってループを継続します。 target はジャンプするアドレスです (アドレスは FOR_ITER 命令でなければなりません)。

LIST_APPEND(i)

list.append(TOS[-i], TOS) を呼びます。リスト内包表記を実装するために使われます。要素が取り除かれる間、リストオブジェクトはスタックに残るので、ループの反復をさらに行えます。

LOAD_LOCALS()

現在のスコープのローカルな名前空間 (locals) への参照をスタックにプッシュします。これはクラス定義のためのコードで使われます: クラス本体が評価された後、locals はクラス定義へ渡されます。

RETURN_VALUE()

関数の呼び出し元へ TOS を返します。

YIELD_VALUE()

TOS をポップし、それをジェネレータ (generator) から yield します。

IMPORT_STAR()

'_' で始まっていないすべてのシンボルをモジュール TOS から直接ローカル名前空間へロードします。モジュールはすべての名前をロードした後にポップされます。この命令コードは from module import * に対応します。

EXEC_STMT()

exec TOS2,TOS1,TOS に対応します。コンパイラは指定されなかったオプションのパラメタを None で埋めます。

POP_BLOCK()

ブロックスタックからブロックを一つ取り除きます。フレームごとにブロックのスタックがあり、ネストしたループや try 文などを表しています。

END_FINALLY()

finally 節を終了します。インタプリタは例外を再送出しなければならないかどうか、あるいは、関数から return して外側の次のブロックに続くかどうかを再度判断します。

BUILD_CLASS()

新しいクラスオブジェクトを作成します。TOSはメソッド辞書、TOS1は基底クラスの名前のタプル、TOS2はクラス名です。

SETUP_WITH(delta)

この命令コードは、with ブロックが開始する前にいくつかの命令を行います。まず、コンテキストマネージャから __exit__() をロードし、後から WITH_CLEANUP で使うためにスタックにプッシュします。そして、 __enter__() が呼び出され、 delta を指す finally ブロックがプッシュされます。最後に、enter メソッドを呼び出した結果がスタックにプッシュされます。次の命令コードはこれを無視 (POP_TOP) するか、変数に保存 (STORE_FAST, STORE_NAME, または UNPACK_SEQUENCE) します。

WITH_CLEANUP()

with 式ブロックを抜けるときに、スタックをクリーンアップします。スタックの先頭は 1–3 個の値で、それらはなぜ/どのように finally 節に到達したかを表しています:

TOP = None

(TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval

TOP = WHY_*; no retval below it

(TOP, SECOND, THIRD) = exc_info()

これらの値の下には、コンテキストマネージャーの __exit__() 結合メソッド (bound method) である EXIT があります。

最後のケースでは、 EXIT(TOP, SECOND, THIRD) が呼ばれ、それ以外では EXIT(None, None, None) が呼ばれます。

EXIT はスタックから取り除かれ、その上の値は順序を維持したまま残されます。加えて、スタックが例外処理中であることを示し、 かつ 関数呼び出しが true 値を返した場合、 END_FINALLY が例外を再送出することを防ぐため、この情報は削除されます (“zapped”)。 (しかし、 non-local goto は再開されます)

以下の命令コードはすべて引数を必要とします。引数は 2 バイトで、最上位バイトが後になります。

name = TOS に対応します。 namei はコードオブジェクトの属性 co_names における name のインデクスです。コンパイラは可能ならば STORE_FAST または STORE_GLOBAL を使おうとします。

DELETE_NAME(namei)

del name に対応します。 namei はコードオブジェクトの co_names 属性へのインデクスです。

UNPACK_SEQUENCE(count)

TOS を count 個の個別の値にアンパックして、右から左の順にスタックに置きます。

DUP_TOPX(count)

count 個の要素を順番を保ちながら複製します。実装上の制限から、 count は 1以上 から 5 以下でなければなりません。

STORE_ATTR(namei)

TOS.name = TOS1 に対応します。 namei は co_names における名前のインデクスです。

DELETE_ATTR(namei)

del TOS.name に対応します。 co_names へのインデクスとして namei を使います。

STORE_GLOBAL(namei)

STORE_NAME と同じように動作しますが、 name をグローバルとして保存します。

DELETE_GLOBAL(namei)

DELETE_NAME と同じように動作しますが、グローバルの name を削除します。

LOAD_CONST(consti)

co_consts[consti] をスタックにプッシュします。

LOAD_NAME(namei)

co_names[namei] に関連付けられた値をスタックにプッシュします。

BUILD_TUPLE(count)

スタックから count 個の要素を消費してタプルを作り出し、できたタプルをスタックにプッシュします。

BUILD_LIST(count)

BUILD_TUPLE と同じように動作しますが、リストを作り出します。

BUILD_MAP(count)

スタックに新しい辞書オブジェクトをプッシュします。辞書は count 個のエントリを持つサイズに設定されます。

LOAD_ATTR(namei)

TOS を getattr(TOS, co_names[namei]) と入れ替えます。

COMPARE_OP(opname)

ブール命令を実行します。命令名は cmp_op[opname] にあります。

IMPORT_NAME(namei)

モジュール co_names[namei] をインポートします。 TOS と TOS1 がポップされ、 __import__() の fromlist と level 引数になります。モジュールオブジェクトはスタックへプッシュされます。現在の名前空間は影響されません: 適切な import 文のためには、後続の STORE_FAST 命令が名前空間を変更します。

IMPORT_FROM(namei)

TOS にあるモジュールから属性 co_names[namei] をロードします。作成されたオブジェクトはスタックにプッシュされ、後続の STORE_FAST 命令によって保存されます。

JUMP_FORWARD(delta)

バイトコードカウンタを delta だけ増加させます。

POP_JUMP_IF_TRUE(target)

TOS が真ならば、バイトコードカウンタを target に設定します。 TOS はポップされます。

POP_JUMP_IF_FALSE(target)

TOS が偽ならば、バイトコードカウンタを target に設定します。 TOS はポップされます。

JUMP_IF_TRUE_OR_POP(target)

TOS が真ならば、バイトコードカウンタを target に設定し、TOS はスタックに残されます。そうでない (TOS が偽) なら、TOS はポップされます。

JUMP_IF_FALSE_OR_POP(target)

TOS が偽ならば、バイトコードカウンタを target に設定し、TOS はスタックに残されます。そうでない (TOS が真) なら、TOS はポップされます。

JUMP_ABSOLUTE(target)

バイトコードカウンタを target に設定します。

FOR_ITER(delta)

TOS はイテレータです。その next() メソッドを呼び出します。新しい値が yield された場合は、それをスタックにプッシュします (イテレータはその下に残されます)。イテレータの呼び出しで要素が尽きたことが示された場合は、 TOS がポップされます。そして、バイトコードカウンタが delta だけ増やされます。

LOAD_GLOBAL(namei)

co_names[namei] という名前のグローバルをスタック上にロードします。

SETUP_LOOP(delta)

ループのためのブロックをブロックスタックにプッシュします。ブロックは現在の命令から delta バイトの大きさを占めます。

SETUP_EXCEPT(delta)

try-except 節から try ブロックをブロックスタックにプッシュします。 delta は最初の except ブロックを指します。

SETUP_FINALLY(delta)

try-except 節から try ブロックをブロックスタックにプッシュします。 delta は finally ブロックを指します。

STORE_MAP()

key, value のペアを辞書に格納します。 key と value をポップする一方、辞書はスタックに残されます。

LOAD_FAST(var_num)

ローカルな co_varnames[var_num] への参照をスタックにプッシュします。

STORE_FAST(var_num)

TOS をローカルな co_varnames[var_num] の中に保存します。

DELETE_FAST(var_num)

ローカルな co_varnames[var_num] を削除します。

LOAD_CLOSURE(i)

セルと自由変数の記憶領域のスロット i に含まれるセルへの参照をプッシュします。 i が co_cellvars の長さより小さければ、変数の名前は co_cellvars[i] です。そうでなければ co_freevars[i - len(co_cellvars)] です。

LOAD_DEREF(i)

セルと自由変数の記憶領域のスロット i に含まれるセルをロードします。セルが持つオブジェクトへの参照をスタックにプッシュします。

STORE_DEREF(i)

セルと自由変数の記憶領域のスロット i に含まれるセルへTOSを保存します。

SET_LINENO(lineno)

この命令コードは廃止されました。

RAISE_VARARGS(argc)

例外を発生させます。 argc は raise 文へ与えるパラメタの数を 0 から 3 の範囲で示します。ハンドラは TOS2 をトレースバック、TOS1 をパラメタ、TOS を例外として探します。

CALL_FUNCTION(argc)

関数を呼び出します。 argc の下位バイトは位置パラメタの数を、上位バイトはキーワードパラメタの数を示します。スタック上では、最初にキーワードパラメタが見つかります。それぞれのキーワード引数に対しては、値がキーより上に来ます。スタック上のキーワードパラメタの下に位置パラメタがあり、最も右のパラメタが先頭になります。スタック上のパラメタの下には、呼び出される関数オブジェクトが置かれます。すべての関数引数をポップし、関数自体もスタックから取り除き、戻り値をプッシュします。

MAKE_FUNCTION(argc)

新しい関数オブジェクトをスタックにプッシュします。 TOS は関数に関連付けられたコードです。関数オブジェクトは TOS の下にある argc デフォルトパラメタをもつように定義されます。

MAKE_CLOSURE(argc)

新しい関数オブジェクトを作り出し、その func_closure スロットを設定し、スタックにプッシュします。 TOS は関数に関連付けられたコードで、TOS1 はクロージャの自由変数に対するセルを格納したタプルです。関数はセルの前にある argc デフォルトパラメタも持っています。

BUILD_SLICE(argc)

スライスオブジェクトをスタックにプッシュします。 argc は2あるいは3でなければなりません。 2 ならば slice(TOS1, TOS) がプッシュされます。 3 ならば slice(TOS2, TOS1, TOS) がプッシュされます。これ以上の情報については、 slice() 組み込み関数を参照してください。

EXTENDED_ARG(ext)

デフォルトの 2 バイトに収まりきらない大きな引数を持つあらゆる命令コードの前に置かれます。 ext は追加の 2 バイトを保持し、後続の命令コードの引数と組み合わされます。それらは 4 バイト引数を構成し、 ext はその最上位バイトです。

CALL_FUNCTION_VAR(argc)

関数を呼び出します。 argc は CALL_FUNCTION と同じように解釈されます。スタックの先頭の要素は可変引数リストを含んでおり、その後にキーワード引数と位置引数が続きます。

CALL_FUNCTION_KW(argc)

関数を呼び出します。 argc は CALL_FUNCTION と同じように解釈されます。スタックの先頭の要素はキーワード引数辞書を含んでおり、その後に明示的なキーワード引数と位置引数が続きます。

CALL_FUNCTION_VAR_KW(argc)

関数を呼び出します。 argc は CALL_FUNCTION と同じように解釈されます。スタックの先頭の要素はキーワード引数辞書を含んでおり、その後に変数引数のタプルが続き、さらに明示的なキーワード引数と位置引数が続きます。

HAVE_ARGUMENT()

これは実際の命令コードではありません。引数を取らない命令コード < HAVE_ARGUMENT と、引数を取る命令コード >= HAVE_ARGUMENT の分割行を表します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

31. Python言語サービス »

31.13. pickletools — pickle 開発者のためのツール群

バージョン 2.3 で追加.

このモジュールには、 pickle モジュールの詳細に関わる様々な定数や実装に関する長大なコメント、そして pickle 化されたデータを解析する上で有用な関数をいくつか定義しています。このモジュールの内容は pickle および cPickle の実装に関わっている Python コア開発者にとって有用なものです; 普通の pickle 利用者にとっては、 pickletools モジュールはおそらく関係ないものでしょう。

pickletools.dis(pickle[, out=None, memo=None, indentlevel=4])

pickle をシンボル分解 (symbolic disassembly) した内容をファイル類似オブジェクト out (デフォルトでは sys.stdout) に出力します。 pickle は文字列にもファイル類似オブジェクトにもできます。 memo は Python 辞書型で、 pickle のメモに使われます。同じ pickler の生成した複数の pickle 間にわたってシンボル分解を行う場合に使われます。ストリーム中で MARK opcode で表される継続レベル (successive level) は indentlevel に指定したスペース分インデントされます。

pickletools.genops(pickle)

pickle 内の全ての opcode を取り出すイテレータ(iterator)を返します。このイテレータは (opcode, arg, pos) の三つ組みからなる配列を返します。 opcode は OpcodeInfo クラスのインスタンスのクラスです。 arg は opcode の引数としてデコードされた Python オブジェクトの値です。 pos は opcode の場所を表す値です。 pickle は文字列でもファイル類似オブジェクトでもかまいません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

32. Python コンパイラパッケージ

バージョン 2.6 で撤廃: compiler パッケージは Python 3.0 で削除されました。

Python compiler パッケージは Python のソースコードを分析したり Python バイトコードを生成するためのツールです。compiler は Python のソースコードから抽象的な構文木を生成し、その構文木から Python バイトコード (bytecode) を生成するライブラリをそなえています。

compiler パッケージは、Python で書かれた Python ソースコードからバイトコードへの変換プログラムです。これは組み込みの構文解析器と標準ライブラリの parser を使って、構文木を生成します。この構文木から抽象構文木 AST (Abstract Syntax Tree) が生成され、その後 Python バイトコードが得られます。

このパッケージの機能は、Python インタプリタに内蔵されている組み込みのコンパイラがすべて含んでいるものです。これはその機能と正確に同じものになるよう意図してつくられています。なぜ同じことをするコンパイラをもうひとつ作る必要があるのでしょうか? このパッケージはいろいろな目的に使うことができるからです。これは組み込みのコンパイラよりも簡単に変更できますし、これが生成する AST は Python ソースコードを解析するのに有用です。

この章では compiler パッケージのいろいろなコンポーネントがどのように動作するのかを説明します。そのため説明はリファレンスマニュアル的なものと、チュートリアル的な要素がまざったものになっています。

32.1. 基本的なインターフェイス

このパッケージのトップレベルでは4つの関数が定義されています。 compiler モジュールを import すると、これらの関数およびこのパッケージに含まれている一連のモジュールが使用可能になります。

compiler.parse(buf)

buf 中の Python ソースコードから得られた抽象構文木 AST を返します。ソースコード中にエラーがある場合、この関数は SyntaxError を発生させます。返り値は compiler.ast.Module インスタンスであり、この中に構文木が格納されています。

compiler.parseFile(path)

path で指定されたファイル中の Python ソースコードから得られた抽象構文木 AST を返します。これは parse(open(path).read()) と等価な働きをします。

compiler.walk(ast, visitor[, verbose])

ast に格納された抽象構文木の各ノードを先行順序 (pre-order) でたどっていきます。各ノードごとに visitor インスタンスの該当するメソッドが呼ばれます。

compiler.compile(source, filename, mode, flags=None, dont_inherit=None)

文字列 source 、Python モジュール、文あるいは式を exec 文あるいは eval() 関数で実行可能なバイトコードオブジェクトにコンパイルします。この関数は組み込みの compile() 関数を置き換えるものです。

filename は実行時のエラーメッセージに使用されます。

mode は、モジュールをコンパイルする場合は ‘exec’、 (対話的に実行される)単一の文をコンパイルする場合は ‘single’、式をコンパイルする場合には ‘eval’ を渡します。

引数 flags および dont_inherit は将来的に使用される文に影響しますが、いまのところはサポートされていません。

compiler.compileFile(source)

ファイル source をコンパイルし、.pyc ファイルを生成します。

compiler パッケージは以下のモジュールを含んでいます: ast, consts, future, misc, pyassem, pycodegen, symbols, transformer, そして visitor 。

32.2. 制限

compiler パッケージにはエラーチェックにいくつか問題が存在します。構文エラーはインタープリタの2つの別々のフェーズによって認識されます。ひとつはインタープリタのパーザによって認識されるもので、もうひとつはコンパイラによって認識されるものです。 compiler パッケージはインタープリタのパーザに依存しているので、最初の段階のエラーチェックは労せずして実現できています。しかしその次の段階は、実装されてはいますが、その実装は不完全です。たとえば compiler パッケージは引数に同じ名前が 2度以上出てきていてもエラーを出しません: def f(x, x): ...

compiler の将来のバージョンでは、これらの問題は修正される予定です。

32.3. Python 抽象構文

compiler.ast モジュールは Python の抽象構文木 AST を定義します。 AST では各ノードがそれぞれの構文要素をあらわします。木の根は Module オブジェクトです。

抽象構文木 AST は、パーズされた Python ソースコードに対する高水準のインターフェイスを提供します。 Python インタプリタにおける parser モジュールとコンパイラは C で書かれおり、具体的な構文木を使っています。具体的な構文木は Python のパーザ中で使われている構文と密接に関連しています。ひとつの要素に単一のノードを割り当てる代わりに、ここでは Python の優先順位に従って、何層にもわたるネストしたノードがしばしば使われています。

抽象構文木 AST は、 compiler.transformer (変換器) モジュールによって生成されます。 transformer は組み込みの Python パーザに依存しており、これを使って具体的な構文木をまず生成します。つぎにそこから抽象構文木 AST を生成します。

transformer モジュールは、実験的な Python-to-C コンパイラ用に Greg Stein と Bill Tutt によって作られました。現行のバージョンではいくつもの修正と改良がなされていますが、抽象構文木 AST と transformer の基本的な構造は Stein と Tutt によるものです。

32.3.1. AST ノード

compiler.ast モジュールは、各ノードのタイプとその要素を記述したテキストファイルからつくられます。各ノードのタイプはクラスとして表現され、そのクラスは抽象基底クラス compiler.ast.Node を継承し子ノードの名前属性を定義しています。

class compiler.ast.Node

Node インスタンスはパーザジェネレータによって自動的に作成されます。ある特定の Node インスタンスに対する推奨されるインターフェイスとは、子ノードにアクセスするために public な (訳注: 公開された) 属性を使うことです。 public な属性は単一のノード、あるいは一連のノードのシーケンスに束縛されている (訳注: バインドされている) かもしれませんが、これは Node のタイプによって違います。たとえば Class ノードの bases 属性は基底クラスのノードのリストに束縛されており、 doc 属性は単一のノードのみに束縛されている、といった具合です。

各 Node インスタンスは lineno 属性をもっており、これは None かもしれません。 XXX どういったノードが使用可能な lineno をもっているかの規則は定かではない。

Node オブジェクトはすべて以下のメソッドをもっています:

getChildren()

子ノードと子オブジェクトを、これらが出てきた順で、平らなリスト形式にして返します。とくにノードの順序は、 Python 文法中に現れるものと同じになっています。すべての子が Node インスタンスなわけではありません。たとえば関数名やクラス名といったものは、ただの文字列として表されます。

getChildNodes()

子ノードをこれらが出てきた順で平らなリスト形式にして返します。このメソッドは getChildren() に似ていますが、 Node インスタンスしか返さないという点で異なっています。

Node クラスの一般的な構造を説明するため、以下に 2つの例を示します。 while 文は以下のような文法規則により定義されています:

while_stmt:     "while" expression ":" suite
               ["else" ":" suite]

While ノードは 3つの属性をもっています: test, body および else_ です。 (ある属性にふさわしい名前が Python の予約語としてすでに使われているとき、その名前を属性名にすることはできません。そのため、ここでは名前が正規のものとして受けつけられるようにアンダースコアを後につけてあります、そのため else_ は else のかわりです。)

if 文はもっとこみ入っています。なぜならこれはいくつもの条件判定を含む可能性があるからです。

if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]

If ノードでは、 tests および else_ の 2つだけの属性が定義されています。 tests 属性には条件式とその後の動作のタプルがリスト形式で入っています。おのおのの if / elif 節ごとに 1タプルです。各タプルの最初の要素は条件式で、2番目の要素はもしその式が真ならば実行されるコードをふくんだ Stmt ノードになっています。

If の getChildren() メソッドは、子ノードの平らなリストを返します。 if / elif 節が 3つあって else 節がない場合なら、 getChildren() は 6要素のリストを返すでしょう: 最初の条件式、最初の Stmt 、2番目の条件式…といった具合です。

以下の表は compiler.ast で定義されている Node サブクラスと、それらのインスタンスに対して使用可能なパブリックな属性です。ほとんどの属性の値じたいは Node インスタンスか、インスタンスのリストです。この値がインスタンス型以外の場合、その型は備考の中で記されています。これら属性の順序は、 getChildren() および getChildNodes() が返す順です。

ノード型 | 属性 | 値
Add | left | 左オペランド
| right | 右オペランド
And | nodes | オペランドのリスト
AssAttr |  | 代入のターゲットとなる属性
| expr | ドットの左側の式
| attrname | 属性名, 文字列
| flags | XXX
AssList | nodes | 代入先のリスト要素のリスト
AssName | name | 代入先の名前
| flags | XXX
AssTuple | nodes | 代入先のタプル要素のリスト
Assert | test | テストされる式
| fail | AssertionError の値
Assign | nodes | 代入ターゲットのリスト、等号ごとに一つ
| expr | 代入される値
AugAssign | node |
| op |
| expr |
Backquote | expr |
Bitand | nodes |
Bitor | nodes |
Bitxor | nodes |
Break |  |
CallFunc | node | 呼び出される式
| args | 引数のリスト
| star_args | 拡張された *-引数の値
| dstar_args | 拡張された **-引数の値
Class | name | クラス名, 文字列
| bases | 基底クラスのリスト
| doc | ドキュメント文字列, 文字列または None
| code | クラス文の本体
Compare | expr |
| ops |
Const | value |
Continue |  |
Decorators | nodes | 関数デコレータ式のリスト
Dict | items |
Discard | expr |
Div | left |
| right |
Ellipsis |  |
Expression | node |
Exec | expr |
| locals |
| globals |
FloorDiv | left |
| right |
For | assign |
| list |
| body |
| else_ |
From | modname |
| names |
Function | decorators | Decorators か None
| name | def に使われた名前, 文字列
| argnames | 引数名の文字列としてのリスト
| defaults | デフォルト値のリスト
| flags | xxx
| doc | ドキュメント文字列, 文字列または None
| code | 関数の本体
GenExpr | code |
GenExprFor | assign |
| iter |
| ifs |
GenExprIf | test |
GenExprInner | expr |
| quals |
Getattr | expr |
| attrname |
Global | names |
If | tests |
| else_ |
Import | names |
Invert | expr |
Keyword | name |
| expr |
Lambda | argnames |
| defaults |
| flags |
| code |
LeftShift | left |
| right |
List | nodes |
ListComp | expr |
| quals |
ListCompFor | assign |
| list |
| ifs |
ListCompIf | test |
Mod | left |
| right |
Module | doc | ドキュメント文字列, 文字列または None
| node | モジュールの本体, Stmt
Mul | left |
| right |
Name | name |
Not | expr |
Or | nodes |
Pass |  |
Power | left |
| right |
Print | nodes |
| dest |
Printnl | nodes |
| dest |
Raise | expr1 |
| expr2 |
| expr3 |
Return | value |
RightShift | left |
| right |
Slice | expr |
| flags |
| lower |
| upper |
Sliceobj | nodes | 文のリスト
Stmt | nodes |
Sub | left |
| right |
Subscript | expr |
| flags |
| subs |
TryExcept | body |
| handlers |
| else_ |
TryFinally | body |
| final |
Tuple | nodes |
UnaryAdd | expr |
UnarySub | expr |
While | test |
| body |
| else_ |
With | expr |
| vars |
| body |
Yield | value |

32.3.2. 代入ノード

代入をあらわすのに使われる一群のノードが存在します。ソースコードにおけるそれぞれの代入文は、抽象構文木 AST では単一のノード Assign になっています。 nodes 属性は各代入の対象にたいするノードのリストです。これが必要なのは、たとえば a = b = 2 のように代入が連鎖的に起こるためです。このリスト中における各 Node は、次のうちどれかのクラスになります: AssAttr, AssList, AssName または AssTuple 。

代入対象の各ノードには代入されるオブジェクトの種類が記録されています。 AssName は a = 1 などの単純な変数名、 AssAttr は a.x = 1 などの属性に対する代入、 AssList および AssTuple はそれぞれ、 a, b, c = a_tuple などのようなリストとタプルの展開をあらわします。

代入対象ノードはまた、そのノードが代入で使われるのか、それとも del 文で使われるのかをあらわす属性 flags も持っています。 AssName は del x などのような del 文をあらわすのにも使われます。

ある式がいくつかの属性への参照をふくんでいるときは、代入あるいは del 文はただひとつだけの AssAttr ノードをもちます – 最終的な属性への参照としてです。それ以外の属性への参照は AssAttr インスタンスの expr 属性にある Getattr ノードによってあらわされます。

32.3.3. サンプル

この節では、Python ソースコードに対する抽象構文木 AST のかんたんな例をいくつかご紹介します。これらの例では parse() 関数をどうやって使うか、AST の repr 表現はどんなふうになっているか、そしてある AST ノードの属性にアクセスするにはどうするかを説明します。

最初のモジュールでは単一の関数を定義しています。かりにこれは /tmp/doublelib.py に格納されていると仮定しましょう。

"""This is an example module.

This is the docstring.
"""

def double(x):
    "Return twice the argument"
    return x * 2

以下の対話的インタプリタのセッションでは、見やすさのため長い AST の repr を整形しなおしてあります。 AST の repr では qualify されていないクラス名が使われています。 repr 表現からインスタンスを作成したい場合は、 compiler.ast モジュールからそれらのクラス名を import しなければなりません。

>>> import compiler
>>> mod = compiler.parseFile("/tmp/doublelib.py")
>>> mod
Module('This is an example module.\n\nThis is the docstring.\n',
       Stmt([Function(None, 'double', ['x'], [], 0,
                      'Return twice the argument',
                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
>>> from compiler.ast import *
>>> Module('This is an example module.\n\nThis is the docstring.\n',
...    Stmt([Function(None, 'double', ['x'], [], 0,
...                   'Return twice the argument',
...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))
Module('This is an example module.\n\nThis is the docstring.\n',
       Stmt([Function(None, 'double', ['x'], [], 0,
                      'Return twice the argument',
                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
>>> mod.doc
'This is an example module.\n\nThis is the docstring.\n'
>>> for node in mod.node.nodes:
...     print node
...
Function(None, 'double', ['x'], [], 0, 'Return twice the argument',
         Stmt([Return(Mul((Name('x'), Const(2))))]))
>>> func = mod.node.nodes[0]
>>> func.code
Stmt([Return(Mul((Name('x'), Const(2))))])

32.4. Visitor を使って AST をわたり歩く

visitor パターンは… compiler パッケージは、Python のイントロスペクション機能を利用して visitor のために必要な大部分のインフラを省略した、visitor パターンの変種を使っています。

visit されるクラスは、visitor を受け入れるようにプログラムされている必要はありません。 visitor が必要なのはただそれがとくに興味あるクラスに対して visit メソッドを定義することだけです。それ以外はデフォルトの visit メソッドが処理します。

XXX visitor 用の魔法の visit() メソッド。

compiler.visitor.walk(tree, visitor[, verbose])

class compiler.visitor.ASTVisitor

ASTVisitor は構文木を正しい順序でわたり歩くようにします。それぞれのノードはまず preorder() の呼び出しではじまります。各ノードに対して、これは ‘visitNodeType’ という名前のメソッドに対する preorder() 関数への visitor 引数をチェックします。ここで NodeType の部分はそのノードのクラス名です。たとえば While ノードなら、 visitWhile() が呼ばれるわけです。もしそのメソッドが存在している場合、それはそのノードを第一引数として呼び出されます。

ある特定のノード型に対する visitor メソッドでは、その子ノードをどのようにわたり歩くかが制御できます。 ASTVisitor は visitor に visit メソッドを追加することで、その visitor 引数を修正します。特定のノード型に対する visitor が存在しない場合、 default() メソッドが呼び出されます。

ASTVisitor オブジェクトには以下のようなメソッドがあります:

XXX 追加の引数を記述

default(node[, ...])

dispatch(node[, ...])

preorder(tree, visitor)

32.5. バイトコード生成

バイトコード生成器はバイトコードを出力する visitor です。 visit メソッドが呼ばれるたびにこれは emit() メソッドを呼び出し、バイトコードを出力します。基本的なバイトコード生成器はモジュール、クラス、および関数によって拡張できます。アセンブラがこれらの出力された命令を低レベルのバイトコードに変換します。これはコードオブジェクトからなる定数のリスト生成や、分岐のオフセット計算といった処理をおこないます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

33. 各種サービス

この章では、Pythonのすべてのバージョンで利用可能な各種サービスについて説明します。以下に概要を示します。

33.1. formatter — 汎用の出力書式化機構

33.1.1. formatter インタフェース

33.1.2. formatter 実装

33.1.3. writer インタフェース

33.1.4. writer 実装

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

33. 各種サービス »

33.1. formatter — 汎用の出力書式化機構

このモジュールでは、二つのインタフェース定義を提供しており、それらの各インタフェースについて複数の実装を提供しています。 formatter インタフェースは htmllib モジュールの HTMLParser クラスで使われており、 writer インタフェースは formatter インタフェースを使う上で必要です。

formatter オブジェクトはある抽象化された書式イベントの流れを writer オブジェクト上の特定の出力イベントに変換します。 formatter はいくつかのスタック構造を管理することで、writer オブジェクトの様々な属性を変更したり復元したりできるようにしています; このため、writer は相対的な変更や “元に戻す” 操作を処理できなくてもかまいません。writer の特定のプロパティのうち、 formatter オブジェクトを介して制御できるのは、水平方向の字揃え、フォント、そして左マージンの字下げです。任意の、非排他的なスタイル設定を writer に提供するためのメカニズムも提供されています。さらに、段落分割のように、可逆でない書式化イベントの機能を提供するインタフェースもあります。

writer オブジェクトはデバイスインタフェースをカプセル化します。ファイル形式のような抽象デバイスも物理デバイス同様にサポートされています。ここで提供されている実装内容はすべて抽象デバイス上で動作します。デバイスインタフェースは formatter オブジェクトが管理しているプロパティを設定し、データを出力端に書き込めるようにします。

33.1.1. formatter インタフェース

formatter を作成するためのインタフェースは、インスタンス化しようとする個々の formatter クラスに依存します。以下で解説するのは、インスタンス化された全ての formatter がサポートしなければならないインタフェースです。

モジュールレベルではデータ要素を一つ定義しています:

formatter.AS_IS

後に述べる push_font() メソッドでフォント指定をする時に使える値です。また、その他の push_property() メソッドの新しい値として使うことができます。

AS_IS の値をスタックに置くと、どのプロパティが変更されたかの追跡を行わずに、対応する pop_property() メソッドが呼び出されるようになります。

formatter インスタンスオブジェクトには以下の属性が定義されています:

formatter.writer

formatter とやり取りを行う writer インスタンスです。

formatter.end_paragraph(blanklines)

開かれている段落があれば閉じ、次の段落との間に少なくとも blanklines が挿入されるようにします。

formatter.add_line_break()

強制改行挿入します。既に強制改行がある場合は挿入しません。論理的な段落は中断しません。

formatter.add_hor_rule(*args, **kw)

出力に水平罫線を挿入します。現在の段落に何らかのデータがある場合、強制改行が挿入されますが、論理的な段落は中断しません。引数とキーワードは writer の send_line_break() メソッドに渡されます。

formatter.add_flowing_data(data)

空白を折りたたんで書式化しなければならないデータを提供します。空白の折りたたみでは、直前や直後の add_flowing_data() 呼び出しに入っている空白も考慮されます。このメソッドに渡されたデータは出力デバイスで行末の折り返し (word-wrap) されるものと想定されています。出力デバイスでの要求やフォント情報に応じて、writer オブジェクトでも何らかの行末折り返しが行われなければならないので注意してください。

formatter.add_literal_data(data)

変更を加えずに writer に渡さなければならないデータを提供します。改行およびタブを含む空白を data の値にしても問題ありません。

formatter.add_label_data(format, counter)

現在の左マージン位置の左側に配置されるラベルを挿入します。このラベルは箇条書き、数字つき箇条書きの書式を構築する際に使われます。 format の値が文字列の場合、整数の値 counter の書式指定として解釈されます。

format の値が文字列の場合、整数の値をとる counter の書式化指定として解釈されます。書式化された文字列はラベルの値になります; format が文字列でない場合、ラベルの値として直接使われます。ラベルの値は writer の send_label_data() メソッドの唯一の引数として渡されます。非文字列のラベル値をどう解釈するかは関連付けられた writer に依存します。

書式化指定は文字列からなり、 counter の値と合わせてラベルの値を算出するために使われます。書式文字列の各文字はラベル値にコピーされます。このときいくつかの文字は counter 値を変換を指すものとして認識されます。特に、文字 '1' はアラビア数字の counter 値を表し、 'A' と 'a' はそれぞれ大文字および小文字のアルファベットによる counter 値を表し、 'I' と 'i' はそれぞれ大文字および小文字のローマ数字による counter 値を表します。アルファベットおよびローマ字数字への変換の際には、counter の値はゼロ以上である必要があるので注意してください。

formatter.flush_softspace()

以前の add_flowing_data() 呼び出しでバッファされている出力待ちの空白を、関連付けられている writer オブジェクトに送信します。このメソッドは writer オブジェクトに対するあらゆる直接操作の前に呼び出さなければなりません。

formatter.push_alignment(align)

新たな字揃え (alignment) 設定を字揃えスタックの上にプッシュします。変更を行いたくない場合には AS_IS にすることができます。字揃え設定値が以前の設定から変更された場合、writer の new_alignment() メソッドが align の値と共に呼び出されます。

formatter.pop_alignment()

以前の字揃え設定を復元します。

formatter.push_font((size, italic, bold, teletype))

writer オブジェクトのフォントプロパティのうち、一部または全てを変更します。 AS_IS に設定されていないプロパティは引数で渡された値に設定され、その他の値は現在の設定を維持します。writer の new_font() メソッドは完全に設定解決されたフォント指定で呼び出されます。

formatter.pop_font()

以前のフォント設定を復元します。

formatter.push_margin(margin)

左マージンのインデント数を一つ増やし、論理タグ margin を新たなインデントに関連付けます。マージンレベルの初期値は 0 です。変更された論理タグの値は真値とならなければなりません; AS_IS 以外の偽の値はマージンの変更としては不適切です。

formatter.pop_margin()

以前のマージン設定を復元します。

formatter.push_style(*styles)

任意のスタイル指定をスタックにプッシュします。全てのスタイルはスタイルスタックに順番にプッシュされます。 AS_IS 値を含み、スタック全体を表すタプルは writer の new_styles() メソッドに渡されます。

formatter.pop_style([n=1])

push_style() に渡された最新 n 個のスタイル指定をポップします。 AS_IS 値を含み、変更されたスタックを表すタプルは writer の new_styles() メソッドに渡されます。

formatter.set_spacing(spacing)

writer の割り付けスタイル (spacing style) を設定します。

formatter.assert_line_data([flag=1])

現在の段落にデータが予期せず追加されたことを formatter に知らせます。このメソッドは writer を直接操作した際に使わなければなりません。 writer 操作の結果、出力の末尾が強制改行となった場合、オプションの flag 引数を偽に設定することができます。

33.1.2. formatter 実装

このモジュールでは、formatter オブジェクトに関して二つの実装を提供しています。ほとんどのアプリケーションではこれらのクラスを変更したりサブクラス化することなく使うことができます。

class formatter.NullFormatter([writer])

何も行わない formatter です。 writer を省略すると、 NullWriter インスタンスが生成されます。 NullFormatter インスタンスは、writer のメソッドを全く呼び出しません。writer へのインタフェースを実装する場合にはこのクラスのインタフェースを継承する必要がありますが、実装を継承する必要は全くありません。

class formatter.AbstractFormatter(writer)

標準の formatter です。この formatter 実装は広範な writer で適用できることが実証されており、ほとんどの状況で直接使うことができます。高機能の WWW ブラウザを実装するために使われたこともあります。

33.1.3. writer インタフェース

writer を作成するためのインタフェースは、インスタンス化しようとする個々の writer クラスに依存します。以下で解説するのは、インスタンス化された全ての writer がサポートしなければならないインタフェースです。ほとんどのアプリケーションでは AbstractFormatter クラスを formatter として使うことができますが、通常 writer はアプリケーション側で与えなければならないので注意してください。

writer.flush()

バッファに蓄積されている出力データやデバイス制御イベントをフラッシュします。

writer.new_alignment(align)

字揃えのスタイルを設定します。 align の値は任意のオブジェクトを取りえますが、慣習的な値は文字列または None で、 None は writer の “好む” 字揃えを使うことを表します。慣習的な align の値は 'left' 、 'center' 、 'right' 、および 'justify' です。

writer.new_font(font)

フォントスタイルを設定します。 font は、デバイスの標準のフォントが使われることを示す None か、 (size, italic, bold, teletype) の形式をとるタプルになります。size はフォントサイズを示す文字列になります; 特定の文字列やその解釈はアプリケーション側で定義します。 italic 、 bold 、および teletype といった値はブール値で、それらの属性を使うかどうかを指定します。

writer.new_margin(margin, level)

マージンレベルを整数値 level に設定し、論理タグ (logical tag) を margin に設定します。論理タグの解釈は writer の判断に任されます; 論理タグの値に対する唯一の制限は level が非ゼロの値の際に偽であってはならないということです。

writer.new_spacing(spacing)

割り付けスタイル (spacing style) を spacing に設定します。

writer.new_styles(styles)

追加のスタイルを設定します。 styles の値は任意の値からなるタプルです; AS_IS 値は無視されます。 styles タプルはアプリケーションや writer の実装上の都合により、集合としても、スタックとしても解釈され得ます。

writer.send_line_break()

現在の行を改行します。

writer.send_paragraph(blankline)

少なくとも blankline 空行分の間隔か、空行そのもので段落を分割します。 blankline の値は整数になります。 writer の実装では、改行を行う必要がある場合、このメソッドの呼び出しに先立って send_line_break() の呼び出しを受ける必要あります; このメソッドには段落の最後の行を閉じる機能は含まれておらず、段落間に垂直スペースを空ける役割しかありません。

writer.send_hor_rule(*args, **kw)

水平罫線を出力デバイスに表示します。このメソッドへの引数は全てアプリケーションおよび writer 特有のものなので、注意して解釈する必要があります。このメソッドの実装では、すでに改行が send_line_break() によってなされているものと仮定しています。

writer.send_flowing_data(data)

行端が折り返され、必要に応じて再割り付け解析を行った (re-flowed) 文字データを出力します。このメソッドを連続して呼び出す上では、 writer は複数の空白文字は単一のスペース文字に縮約されていると仮定することがあります。

writer.send_literal_data(data)

すでに表示用に書式化された文字データを出力します。これは通常、改行文字で表された改行を保存し、新たに改行を持ち込まないことを意味します。 send_formatted_data() インタフェースと違って、データには改行やタブ文字が埋め込まれていてもかまいません。

writer.send_label_data(data)

可能ならば、 data を現在の左マージンの左側に設定します。 data の値には制限がありません; 文字列でない値の扱い方はアプリケーションや writer に完全に依存します。このメソッドは行の先頭でのみ呼び出されます。

33.1.4. writer 実装

このモジュールでは、3 種類の writer オブジェクトインタフェース実装を提供しています。ほとんどのアプリケーションでは、 NullWriter から新しい writer クラスを派生する必要があるでしょう。

class formatter.NullWriter

インタフェース定義だけを提供する writer クラスです; どのメソッドも何ら処理を行いません。このクラスは、メソッド実装をまったく継承する必要のない writer 全ての基底クラスになります。

class formatter.AbstractWriter

この writer は formatter をデバッグするのに利用できますが、それ以外に利用できるほどのものではありません。各メソッドを呼び出すと、メソッド名と引数を標準出力に印字して呼び出されたことを示します。

class formatter.DumbWriter([file[, maxcol=72]])

単純な writer クラスで file に渡されたファイルオブジェクトか file が省略された場合には標準出力に出力を書き込みます。出力は maxcol で指定されたカラム数で単純な行端折り返しが行われます。このクラスは連続した段落を再割り付けするのに適しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

34. MS Windows 固有のサービス

この章では、MS Windows プラットフォーム上でのみ利用可能なモジュール群について記述します。

34.1. msilib — Microsoft インストーラーファイルの読み書き

34.1.1. データベースオブジェクト

34.1.2. ビューオブジェクト

34.1.3. サマリー情報オブジェクト

34.1.4. レコードオブジェクト

34.1.5. エラー

34.1.6. CAB オブジェクト

34.1.7. ディレクトリオブジェクト

34.1.8. フィーチャー

34.1.9. GUI クラス

34.1.10. 事前に計算されたテーブル

34.2. msvcrt – MS VC++実行時システムの有用なルーチン群

34.2.1. ファイル操作関連

34.2.2. コンソール I/O 関連

34.2.3. その多の関数

34.3. _winreg – Windows レジストリへのアクセス

34.3.1. 定数

34.3.1.1. HKEY_* 定数

34.3.1.2. アクセス権限

34.3.1.2.1. 64-bit 特有のアクセス権

34.3.1.3. 値の型

34.3.2. レジストリハンドルオブジェクト

34.4. winsound — Windows 用の音声再生インタフェース

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

34. MS Windows 固有のサービス »

34.1. msilib — Microsoft インストーラーファイルの読み書き

バージョン 2.5 で追加.

msilib モジュールは Microdoft インストーラー(.msi)の作成を支援します。このファイルはしばしば埋め込まれた「キャビネット」ファイル (.cab) を含むので、CAB ファイル作成用の API も暴露します。現在のところ .cab ファイルの読み出しはサポートしていませんが、 .msi データベースの読み出しサポートは可能です。

このパッケージの目的は .msi ファイルにある全てのテーブルへの完全なアクセスの提供なので、提供されているものは正直に言って低レベルな API です。このパッケージの二つの主要な応用は distutils の bdist_msi コマンドと、Python インストーラーパッケージそれ自体(と言いつつ現在は別バージョンの msilib を使っているのですが)です。

パッケージの内容は大きく四つのパートに分けられます。低レベル CAB ルーチン、低レベル MSI ルーチン、少し高レベルの MSI ルーチン、標準的なテーブル構造、の四つです。

msilib.FCICreate(cabname, files)

新しい CAB ファイルを cabname という名前で作ります。 files はタプルのリストで、それぞれのタプルがディスク上のファイル名と CAB ファイルで付けられるファイル名とからなるものでなければなりません。

ファイルはリストに現れた順番で CAB ファイルに追加されます。全てのファイルは MSZIP 圧縮アルゴリズムを使って一つの CAB ファイルに追加されます。

MSI 作成の様々なステップに対する Python コールバックは現在暴露されていません。

msilib.UuidCreate()

新しい一意識別子の文字列表現を返します。この関数は Windows API の関数 UuidCreate() と UuidToString() をラップしたものです。

msilib.OpenDatabase(path, persist)

MsiOpenDatabase を呼び出して新しいデータベースオブジェクトを返します。 path は MSI ファイルのファイル名です。 persist は五つの定数 MSIDBOPEN_CREATEDIRECT, MSIDBOPEN_CREATE, MSIDBOPEN_DIRECT, MSIDBOPEN_READONLY, MSIDBOPEN_TRANSACT のどれか一つで、フラグ MSIDBOPEN_PATCHFILE を含めても構いません。これらのフラグの意味は Microsoft のドキュメントを参照してください。フラグに依って既存のデータベースを開いたり新しいのを作ったりします。

msilib.CreateRecord(count)

MSICreateRecord() を呼び出して新しいレコードオブジェクトを返します。 count はレコードのフィールドの数です。

msilib.init_database(name, schema, ProductName, ProductCode, ProductVersion, Manufacturer)

name という名前の新しいデータベースを作り、 schema で初期化し、プロパティ ProductName, ProductCode, ProductVersion, Manufacturer をセットして、返します

schema は tables と _Validation_records という属性をもったモジュールオブジェクトでなければなりません。典型的には、 msilib.schema を使うべきです。

データベースはこの関数から返された時点でスキーマとバリデーションレコードだけが収められています。

msilib.add_data(database, table, records)

全ての records を database の table テーブルに追加します。

table 引数は MSI スキーマで事前に定義されたテーブルでなければなりません。例えば、 'Feature', 'File', 'Component', 'Dialog', 'Control', などです。

records はタプルのリストで、それぞれのタプルにはテーブルのスキーマに従ったレコードの全てのフィールドを含んでいるものでなければなりません。オプションのフィールドには None を渡すことができます。

フィールドの値には、整数・長整数・文字列・Binary クラスのインスタンスが使えます。

class msilib.Binary(filename)

Binary テーブル中のエントリーを表わします。 add_data() を使ってこのクラスのオブジェクトを挿入するときには filename という名前のファイルをテーブルに読み込みます。

msilib.add_tables(database, module)

module の全てのテーブルの内容を database に追加します。 module は tables という内容が追加されるべき全てのテーブルのリストと、テーブルごとに一つある実際の内容を持っている属性とを含んでいなければなりません。

この関数は典型的にシーケンステーブルをインストールするのに使われます。

msilib.add_stream(database, name, path)

database の _Stream テーブルに、ファイル path を name というストリーム名で追加します。

msilib.gen_uuid()

新しい UUID を、 MSI が通常要求する形式(すなわち、中括弧に入れ、16進数は大文字)で返します。

参考

FCICreateFile [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/fcicreate.asp] UuidCreate [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreate.asp] UuidToString [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidtostring.asp]

34.1.1. データベースオブジェクト

Database.OpenView(sql)

MSIDatabaseOpenView() を呼び出してビューオブジェクトを返します。 sql は実行される SQL 命令です。

Database.Commit()

MSIDatabaseCommit() を呼び出して現在のトランザクションで保留されている変更をコミットします。

Database.GetSummaryInformation(count)

MsiGetSummaryInformation() を呼び出して新しいサマリー情報オブジェクトを返します。 count は更新された値の最大数です。

参考

MSIDatabaseOpenView [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabaseopenview.asp] MSIDatabaseCommit [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabasecommit.asp] MSIGetSummaryInformation [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msigetsummaryinformation.asp]

34.1.2. ビューオブジェクト

View.Execute(params)

MSIViewExecute() を通してビューに対する SQL 問い合わせを実行します。 params が None でない場合、クエリ中のパラメータトークンの実際の値を与えるものです。

View.GetColumnInfo(kind)

MsiViewGetColumnInfo() の呼び出しを通してビューのカラムを説明するレコードを返します。 kind は MSICOLINFO_NAMES または MSICOLINFO_TYPES です。

View.Fetch()

MsiViewFetch() の呼び出しを通してクエリの結果レコードを返します。

View.Modify(kind, data)

MsiViewModify() を呼び出してビューを変更します。 kind は MSIMODIFY_SEEK, MSIMODIFY_REFRESH, MSIMODIFY_INSERT, MSIMODIFY_UPDATE, MSIMODIFY_ASSIGN, MSIMODIFY_REPLACE, MSIMODIFY_MERGE, MSIMODIFY_DELETE, MSIMODIFY_INSERT_TEMPORARY, MSIMODIFY_VALIDATE, MSIMODIFY_VALIDATE_NEW, MSIMODIFY_VALIDATE_FIELD, MSIMODIFY_VALIDATE_DELETE のいずれかです。

data は新しいデータを表わすレコードでなければなりません。

View.Close()

MsiViewClose() を通してビューを閉じます。

参考

MsiViewExecute [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewexecute.asp] MSIViewGetColumnInfo [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp] MsiViewFetch [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewfetch.asp] MsiViewModify [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewmodify.asp] MsiViewClose [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewclose.asp]

34.1.3. サマリー情報オブジェクト

SummaryInformation.GetProperty(field)

MsiSummaryInfoGetProperty() を通してサマリーのプロパティを返します。 field はプロパティ名で、定数 PID_CODEPAGE, PID_TITLE, PID_SUBJECT, PID_AUTHOR, PID_KEYWORDS, PID_COMMENTS, PID_TEMPLATE, PID_LASTAUTHOR, PID_REVNUMBER, PID_LASTPRINTED, PID_CREATE_DTM, PID_LASTSAVE_DTM, PID_PAGECOUNT, PID_WORDCOUNT, PID_CHARCOUNT, PID_APPNAME, PID_SECURITY のいずれかです。

SummaryInformation.GetPropertyCount()

MsiSummaryInfoGetPropertyCount() を通してサマリープロパティの個数を返します。

SummaryInformation.SetProperty(field, value)

MsiSummaryInfoSetProperty() を通してプロパティをセットします。 field は GetProperty() におけるものと同じ値をとります。 value はプロパティの新しい値です。許される値の型は整数と文字列です。

SummaryInformation.Persist()

MsiSummaryInfoPersist() を使って変更されたプロパティをサマリー情報ストリームに書き込みます。

参考

MsiSummaryInfoGetProperty [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp] MsiSummaryInfoGetPropertyCount [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp] MsiSummaryInfoSetProperty [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp] MsiSummaryInfoPersist [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfopersist.asp]

34.1.4. レコードオブジェクト

Record.GetFieldCount()

MsiRecordGetFieldCount() を通してレコードのフィールド数を返します。

Record.GetInteger(field)

field の値を可能なら整数として返します。 field は整数でなければなりません。

Record.GetString(field)

field の値を可能なら文字列として返します。 field は整数でなければなりません。

Record.SetString(field, value)

MsiRecordSetString() を通して field を value にセットします。 field は整数、 value は文字列でなければなりません。

Record.SetStream(field, value)

MsiRecordSetStream() を通して field を value という名のファイルの内容にセットします。 field は整数、 value は文字列でなければなりません。

Record.SetInteger(field, value)

MsiRecordSetInteger() を通して field を value にセットします。 field も value も整数でなければなりません。

Record.ClearData()

MsiRecordClearData() を通してレコードの全てのフィールドを 0 にセットします。

参考

MsiRecordGetFieldCount [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp] MsiRecordSetString [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstring.asp] MsiRecordSetStream [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstream.asp] MsiRecordSetInteger [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetinteger.asp] MsiRecordClear [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordclear.asp]

34.1.5. エラー

全ての MSI 関数のラッパーは MsiError を送出します。例外の内部の文字列がより詳細な情報を含んでいます。

34.1.6. CAB オブジェクト

class msilib.CAB(name)

CAB クラスは CAB ファイルを表わすものです。MSI 構築中、ファイルは Files テーブルと CAB ファイルとに同時に追加されます。そして、全てのファイルを追加し終えたら、CAB ファイルは書き込まれることが可能になり、MSI ファイルに追加されます。

name は MSI ファイル中の CAB ファイルの名前です。

append(full, logical)

パス名 full のファイルを CAB ファイルに logical という名で追加します。 logical という名が既に存在したならば、新しいファイル名が作られます。

ファイルの CAB ファイル中のインデクスと新しいファイル名を返します。

commit(database)

CAB ファイルを作り、MSI ファイルにストリームとして追加し、 Media テーブルに送り込み、作ったファイルはディスクから削除します。

34.1.7. ディレクトリオブジェクト

class msilib.Directory(database, cab, basedir, physical, logical, default[, componentflags])

新しいディレクトリを Directory テーブルに作成します。ディレクトリには各時点で現在のコンポーネントがあり、それは start_component() を使って明ら様に作成されたかまたは最初にファイルが追加された際に暗黙裡に作成されたものです。ファイルは現在のコンポーネントと cab ファイルに追加されます。ディレクトリを作成するには親ディレクトリオブジェクト(None でも可)、物理的ディレクトリへのパス、論理的ディレクトリ名を指定する必要があります。 default はディレクトリテーブルの DefaultDir スロットを指定します。 componentflags は新しいコンポーネントが得るデフォルトのフラグを指定します。

start_component([component[, feature[, flags[, keyfile[, uuid]]]]])

エントリを Component テーブルに追加し、このコンポーネントをこのディレクトリの現在のコンポーネントにします。もしコンポーネント名が与えられなければディレクトリ名が使われます。 feature が与えられなければ、ディレクトリのデフォルトフラグが使われます。 keyfile が与えられなければ、Component テーブルの KeyPath は null のままになります。

add_file(file[, src[, version[, language]]])

ファイルをディレクトリの現在のコンポーネントに追加します。このとき現在のコンポーネントがなければ新しいものを開始します。デフォルトではソースとファイルテーブルのファイル名は同じになります。 src ファイルが与えられたならば、それば現在のディレクトリから相対的に解釈されます。オプションで version と language を File テーブルのエントリ用に指定することができます。

glob(pattern[, exclude])

現在のコンポーネントに glob パターンで指定されたファイルのリストを追加します。個々のファイルを exclude リストで除外することができます。

remove_pyc()

アンインストールの際に .pyc / .pyo を削除します。

参考

Directory Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/directory_table.asp] File Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/file_table.asp] Component Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/component_table.asp] FeatureComponents Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/featurecomponents_table.asp]

34.1.8. フィーチャー

class msilib.Feature(database, id, title, desc, display[, level=1[, parent[, directory[, attributes=0]]]])

id, parent.id, title, desc, display, level, directory, attributes の値を使って、新しいレコードを Feature テーブルに追加します。出来上がったフィーチャーオブジェクトは Directory の start_component() メソッドに渡すことができます。

set_current()

このフィーチャーを msilib の現在のフィーチャーにします。フィーチャーが明ら様に指定されない限り、新しいコンポーネントが自動的にデフォルトのフィーチャーに追加されます。

参考

Feature Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/feature_table.asp]

34.1.9. GUI クラス

msilib モジュールは MSI データベースの中の GUI テーブルをラップする幾つかのクラスを提供しています。しかしながら、標準で提供されるユーザーインタフェースはありません。インストールする Python パッケージに対するユーザーインタフェース付きの MSI ファイルを作成するには bdist_msi を使ってください。

class msilib.Control(dlg, name)

ダイアログコントロールの基底クラス。 dlg はコントロールの属するダイアログオブジェクト、 name はコントロールの名前です。

event(event, argument[, condition=1[, ordering]])

このコントロールの ControlEvent テーブルにエントリを作ります。

mapping(event, attribute)

このコントロールの EventMapping テーブルにエントリを作ります。

condition(action, condition)

このコントロールの ControlCondition テーブルにエントリを作ります。

class msilib.RadioButtonGroup(dlg, name, property)

name という名前のラジオボタンコントロールを作成します。 property はラジオボタンが選ばれたときにセットされるインストーラープロパティです。

add(name, x, y, width, height, text[, value])

グループに name という名前で、座標 x, y に大きさが width, height で text というラベルの付いたラジオボタンを追加します。 value が省略された場合、デフォルトは name になります。

class msilib.Dialog(db, name, x, y, w, h, attr, title, first, default, cancel)

新しい Dialog オブジェクトを返します。 Dialog テーブルの中に指定された座標、ダイアログ属性、タイトル、最初とデフォルトとキャンセルコントロールの名前を持ったエントリが作られます。

control(name, type, x, y, width, height, attributes, property, text, control_next, help)

新しい Control オブジェクトを返します。 Control テーブルに指定されたパラメータのエントリが作られます。

これは汎用のメソッドで、特定の型に対しては特化したメソッドが提供されています。

text(name, x, y, width, height, attributes, text)

Text コントロールを追加して返します。

bitmap(name, x, y, width, height, text)

Bitmap コントロールを追加して返します。

line(name, x, y, width, height)

Line コントロールを追加して返します。

pushbutton(name, x, y, width, height, attributes, text, next_control)

PushButton コントロールを追加して返します。

radiogroup(name, x, y, width, height, attributes, property, text, next_control)

RadioButtonGroup コントロールを追加して返します。

checkbox(name, x, y, width, height, attributes, property, text, next_control)

CheckBox コントロールを追加して返します。

参考

Dialog Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/dialog_table.asp] Control Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/control_table.asp] Control Types [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controls.asp] ControlCondition Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlcondition_table.asp] ControlEvent Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlevent_table.asp] EventMapping Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/eventmapping_table.asp] RadioButton Table [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/radiobutton_table.asp]

34.1.10. 事前に計算されたテーブル

msilib はスキーマとテーブル定義だけから成るサブパッケージをいくつか提供しています。現在のところ、これらの定義は MSI バージョン 2.0 に基づいています。

msilib.schema

これは MSI 2.0 用の標準 MSI スキーマで、テーブル定義のリストを提供する tables 変数と、MSI バリデーション用のデータを提供する _Validation_records 変数があります。

msilib.sequence

このモジュールは標準シーケンステーブルのテーブル内容を含んでいます。 AdminExecuteSequence, AdminUISequence, AdvtExecuteSequence, InstallExecuteSequence, InstallUISequence が含まれています。

msilib.text

このモジュールは標準的なインストーラーのアクションのための UIText および ActionText テーブルの定義を含んでいます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

34. MS Windows 固有のサービス »

34.2. msvcrt – MS VC++実行時システムの有用なルーチン群

このモジュールの関数は、 Windows プラットフォームの便利な機能のいくつかに対するアクセス機構を提供しています。高レベルモジュールのいくつかは、提供するサービスを Windows で実装するために、これらの関数を使っています。例えば、 getpass モジュールは関数 getpass() を実装するためにこのモジュールの関数を使います。

ここに挙げた関数の詳細なドキュメントについては、プラットフォーム API ドキュメントで見つけることができます。

このモジュールは、通常版とワイド文字列版の両方のコンソールI/O APIを実装しています。通常版のAPIはASCII文字列のためのもので、国際化アプリケーションでは利用が制限されます。可能な限りワイド文字列版APIを利用するべきです。

34.2.1. ファイル操作関連

msvcrt.locking(fd, mode, nbytes)

C 言語による実行時システムにおけるファイル記述子 fd に基づいて、ファイルの一部にロックをかけます。ロックされるファイルの領域は、現在のファイル位置から nbytes バイトで、ファイルの末端まで延長することができます。 mode は以下に列挙する LK_* のいずれか一つでなければなりません。一つのファイルの複数の領域を同時にロックすることは可能ですが、領域が重複してはなりません。連接する領域をまとめて指定することはできません; それらの領域は個別にロック解除しなければなりません。

msvcrt.LK_LOCK

msvcrt.LK_RLCK

指定されたバイト列にロックをかけます。指定領域がロックできなかった場合、プログラムは 1 秒後に再度ロックを試みます。10 回再試行した後でもロックをかけられない場合、 IOError が送出されます。

msvcrt.LK_NBLCK

msvcrt.LK_NBRLCK

指定されたバイト列にロックをかけます。指定領域がロックできなかった場合、 IOError が送出されます。

msvcrt.LK_UNLCK

指定されたバイト列のロックを解除します。指定領域はあらかじめロックされていなければなりません。

msvcrt.setmode(fd, flags)

ファイル記述子 fd に対して、行末文字の変換モードを設定します。テキストモードに設定するには、 flags を os.O_TEXT にします; バイナリモードにするには os.O_BINARY にします。

msvcrt.open_osfhandle(handle, flags)

C 言語による実行時システムにおけるファイル記述子をファイルハンドル handle から生成します。 flags パラメタは os.O_APPEND 、 os.O_RDONLY 、および os.O_TEXT をビット単位で OR したものになります。返されるファイル記述子は os.fdopen() でファイルオブジェクトを生成するために使うことができます。

msvcrt.get_osfhandle(fd)

ファイル記述子 fd のファイルハンドルを返します。 fd が認識できない場合、 IOError を送出します。

34.2.2. コンソール I/O 関連

msvcrt.kbhit()

読み出し待ちの打鍵イベントが存在する場合に真を返します。

msvcrt.getch()

打鍵を読み取り、読み出された文字を返します。コンソールには何もエコーバックされません。この関数呼び出しは読み出し可能な打鍵がない場合にはブロックしますが、文字を読み出せるようにするために Enter の打鍵を待つ必要はありません。打鍵されたキーが特殊機能キー (function key) である場合、この関数は '\000' または '\xe0' を返します; キーコードは次に関数を呼び出した際に返されます。この関数で Control-C の打鍵を読み出すことはできません。

msvcrt.getwch()

getch() のワイド文字列版。Unicodeの値を返します。

バージョン 2.6 で追加.

msvcrt.getche()

getch() に似ていますが、打鍵した字が印字可能な文字の場合エコーバックされます。

msvcrt.getwche()

getche() のワイド文字列版。Unicodeの値を返します。

バージョン 2.6 で追加.

msvcrt.putch(char)

キャラクタ char をバッファリングを行わないでコンソールに出力します。

msvcrt.putwch(unicode_char)

putch() のワイド文字列版。Unicodeの値を引数に取ります。

バージョン 2.6 で追加.

msvcrt.ungetch(char)

キャラクタ char をコンソールバッファに “押し戻し (push back)” ます; これにより、押し戻された文字は getch() や getche() で次に読み出される文字になります。

msvcrt.ungetwch(unicode_char)

ungetch() のワイド文字列版。Unicodeの値を引数に取ります。

バージョン 2.6 で追加.

34.2.3. その多の関数

msvcrt.heapmin()

malloc() されたヒープ領域を強制的に消去させて、未使用のメモリブロックをオペレーティングシステムに返します。失敗した場合、 IOError を送出します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

34. MS Windows 固有のサービス »

34.3. _winreg – Windows レジストリへのアクセス

ノート

_winreg モジュールは Python 3.0 では winreg にリネームされました。ソースコードを3.0用に変換するときは、 2to3 ツールが自動的に import を修正します。

バージョン 2.0 で追加.

これらの関数は Windows レジストリ API を Python から使えるようにします。プログラマがレジストリハンドルのクローズを失念した場合でも、確実にハンドルがクローズされるようにするために、整数値をレジストリハンドルとして使う代わりにハンドルオブジェクト が使われます。

このモジュールでは以下の関数を提供します:

_winreg.CloseKey(hkey)

以前開かれたレジストリキーを閉じます。 hkey 引数には以前開かれたレジストリキーを特定します。

ノート

このメソッドを使って (または handle.Close() によって) hkey が閉じられなかった場合、Python が hkey オブジェクトを破壊する際に閉じられます。

_winreg.ConnectRegistry(computer_name, key)

他の計算機上にある既定のレジストリハンドル接続を確立し、ハンドルオブジェクト を返します。

computer_name はリモートコンピュータの名前で、 r"\\computername" の形式をとります。 None の場合、ローカルの計算機が使われます。

key は接続したい既定のハンドルです。

戻り値は開かれたキーのハンドルです。関数が失敗した場合、 WindowsError 例外が送出されます。

_winreg.CreateKey(key, sub_key)

特定のキーを生成するか開き、 ハンドルオブジェクトを返します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

sub_key はこのメソッドが開く、または新規作成するキーの名前です。

key が既定のキーの一つなら、 sub_key は None でかまいません。この場合、返されるハンドルは関数に渡されたのと同じキーハンドルです。

キーがすでに存在する場合、この関数は既に存在するキーを開きます。

戻り値は開かれたキーのハンドルです。この関数が失敗した場合、 WindowsError 例外が送出されます。

_winreg.CreateKeyEx(key, sub_key[, res[, sam]])

指定された key を作成するか開いて、 ハンドルオブジェクトを返します。

key はすでに開かれた key か、定義済みの HKEY_* 定数 です。

sub_key はこのメソッドが開くまたは作成するキーの名前を表す文字列です。

res は予約された整数で、 0 でなくてはなりません。デフォルト値は 0 です。

sam は、 key に対して想定するセキュリティアクセスを示すアクセスマスクを指定します。デフォルトは KEY_ALL_ACCESS です。利用可能な値については アクセス権 を参照してください。

key が定義済みのキーのどれかの場合、 sub_key には None も指定できます。この場合、戻り値のハンドルはこの関数に渡されたキーのハンドルと同じです。

key がすでに存在する場合は、この関数はそのキーを開きます。

戻り値は開いた key のハンドルです。失敗した場合、 WindowsError 例外を発生させます。

バージョン 2.7 で追加.

_winreg.DeleteKey(key, sub_key)

特定のキーを削除します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

sub_key は文字列で、 key パラメタによって特定されたキーのサブキーでなければなりません。この値は None であってはならず、キーはサブキーを持っていてはなりません。

このメソッドはサブキーをもつキーを削除することはできません。

このメソッドの実行が成功すると、キー全体が、その値すべてを含めて削除されます。このメソッドが失敗した場合、 WindowsError 例外が送出されます。

_winreg.DeleteKeyEx(key, sub_key[, sam[, res]])

指定された key を削除します。

ノート

DeleteKeyEx() 関数は RegDeleteKeyEx Windows API 関数を使って実装されています。このAPIは 64bit 版Windowsにしかありません。 RegDeleteKeyEx のドキュメント [http://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx] を参照してください。

key は開いたキーか、定義済みの HKEY_* 定数 のどれかです。

sub_key は key 引数によって指定された key の subkey でなければなりません。この値は None であってはなりません。また、 key は subkey を持たないかもしれません。

res は予約済みの整数で、 0 でなければなりません。デフォルトは 0 です。

sam は、 key に対して想定するセキュリティアクセスを示すアクセスマスクを指定します。デフォルトは KEY_WOW64_64KEY です。利用可能な値については アクセス権 を参照してください。

このメソッドはサブキーをもつキーを削除することはできません。

このメソッドの実行が成功すると、キー全体が、その値すべてを含めて削除されます。このメソッドが失敗した場合、 WindowsError 例外を発生させます。

サポートされていない Windows バージョンでは、 NotImplementedError 例外を発生させます。

バージョン 2.7 で追加.

_winreg.DeleteValue(key, value)

レジストリキーから指定された名前つきの値を削除します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

value は削除したい値を指定するための文字列です。

_winreg.EnumKey(key, index)

開かれているレジストリキーのサブキーを列挙し、文字列で返します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

index は整数値で、取得するキーのインデクスを特定します。

この関数は呼び出されるたびに一つのサブキーの名前を取得します。この関数は通常、これ以上サブキーがないことを示す WindowsError 例外が送出されるまで繰り返し呼び出されます。

_winreg.EnumValue(key, index)

開かれているレジストリキーの値を列挙し、タプルで返します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

index は整数値で、取得する値のインデクスを特定します。

この関数は呼び出されるたびに一つの値の名前を取得します。この関数は通常、これ以上値がないことを示す WindowsError 例外が送出されるまで繰り返し呼び出されます。

結果は 3 要素のタプルになります:

Index | Meaning
0 | 値の名前を特定する文字列
1 | 値のデータを保持するためのオブジェクトで、その型は背後のレジストリ型に依存します
2 | 値のデータ型を特定する整数です (SetValueEx() のドキュメント内のテーブルを参照してください。

_winreg.ExpandEnvironmentStrings(unicode)

REG_EXPAND_SZ のように、環境変数プレースホルダ %NAME% を Unicode 文字列で展開します。

>>> ExpandEnvironmentStrings(u"%windir%")
u"C:\\Windows"

バージョン 2.6 で追加.

_winreg.FlushKey(key)

キーのすべての属性をレジストリに書き込みます。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

キーを変更するために RegFlushKey() を呼ぶ必要はありません。レジストリの変更は怠惰なフラッシュ機構 (lazy flusher) を使ってフラッシュされます。また、システムの遮断時にもディスクにフラッシュされます。 CloseKey() と違って、 FlushKey() メソッドはレジストリに全てのデータを書き終えたときにのみ返ります。アプリケーションは、レジストリへの変更を絶対に確実にディスク上に反映させる必要がある場合にのみ、 FlushKey() を呼ぶべきです。

ノート

FlushKey() を呼び出す必要があるかどうか分からない場合、おそらくその必要はありません。

_winreg.LoadKey(key, sub_key, file_name)

指定されたキーの下にサブキーを生成し、サブキーに指定されたファイルのレジストリ情報を記録します。

key は ConnectRegistry() が返したハンドルか、定数 HKEY_USERS と HKEY_LOCAL_MACHINE のどちらかです。

sub_key は記録先のサブキーを指定する文字列です。

file_name はレジストリデータを読み出すためのファイル名です。このファイルは SaveKey() 関数で生成されたファイルでなくてはなりません。ファイル割り当てテーブル (FAT) ファイルシステム下では、ファイル名は拡張子を持っていてはなりません。

この関数を呼び出しているプロセスが SE_RESTORE_PRIVILEGE 特権を持たない場合には LoadKey() は失敗します。この特権はファイル許可とは違うので注意してください - 詳細は RegLoadKey documentation [http://msdn.microsoft.com/en-us/library/ms724889%28v=VS.85%29.aspx] を参照してください。

key が ConnectRegistry() によって返されたハンドルの場合、 fileName に指定されたパスは遠隔計算機に対する相対パス名になります。

_winreg.OpenKey(key, sub_key[, res[, sam]])

指定されたキーを開き、 ハンドルオブジェクト を返します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

sub_key は開きたいサブキーを特定する文字列です。

res 予約されている整数値で、ゼロでなくてはなりません。標準の値はゼロです。

sam は必要なキーへのセキュリティアクセスを記述する、アクセスマスクを指定する整数です。標準の値は KEY_READ です。その他の利用できる値については アクセス権限を参照してください。

指定されたキーへの新しいハンドルが返されます。

この関数が失敗すると、 WindowsError が送出されます。

_winreg.OpenKeyEx()

OpenKeyEx() の機能は OpenKey() を標準の引数で使うことで提供されています。

_winreg.QueryInfoKey(key)

キーに関数情報をタプルとして返します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

結果は以下の 3 要素からなるタプルです:

インデクス | 意味
0 | このキーが持つサブキーの数を表す整数。
1 | このキーが持つ値の数を表す整数。
2 | 最後のキーの変更が (あれば) いつだったかを表す長整数で、 1600 年 1 月 1 日からの 100 ナノ秒単位で数えたもの。

_winreg.QueryValue(key, sub_key)

キーに対する、名前付けられていない値を文字列で取得します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

sub_key は値が関連付けられているサブキーの名前を保持する文字列です。この引数が None または空文字列の場合、この関数は key で特定されるキーに対して SetValue() メソッドで設定された値を取得します。

レジストリ中の値は名前、型、およびデータから構成されています。このメソッドはあるキーのデータ中で、名前 NULL をもつ最初の値を取得します。しかし背後のAPI 呼び出しは型情報を返しません。なので、可能ならいつでも QueryValueEx() を使うべきです。

_winreg.QueryValueEx(key, value_name)

開かれたレジストリキーに関連付けられている、指定した名前の値に対して、型およびデータを取得します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

value_name は要求する値を指定する文字列です。

結果は 2 つの要素からなるタプルです:

インデクス | 意味
0 | レジストリ要素の名前。
1 | この値のレジストリ型を表す整数。 (SetValueEx() のドキュメント内のテーブルを参照してください。)

_winreg.SaveKey(key, file_name)

指定されたキーと、そのサブキー全てを指定したファイルに保存します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

file_name はレジストリデータを保存するファイルの名前です、このファイルはすでに存在していてはいけません。このファイル名が拡張子を含んでいる場合、 LoadKey() メソッドは、FAT ファイルシステムを使うことができません。

key が遠隔の計算機上にあるキーを表す場合、 file_name で記述されているパスは遠隔の計算機に対して相対的なパスになります。このメソッドの呼び出し側は SeBackupPrivilege セキュリティ特権を保有していなければなりません。この特権はファイルパーミッションとは異なります - 詳細は Conflicts Between User Rights and Permissions documentation [http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx] を参照してください。

この関数は security_attributes を NULL にして API に渡します。

_winreg.SetValue(key, sub_key, type, value)

値を指定したキーに関連付けます。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

sub_key は値が関連付けられているサブキーの名前を表す文字列です。

type はデータの型を指定する整数です。現状では、この値は REG_SZ でなければならず、これは文字列だけがサポートされていることを示します。他のデータ型をサポートするには SetValueEx() を使ってください。

value は新たな値を指定する文字列です。

sub_key 引数で指定されたキーが存在しなければ、 SetValue 関数で生成されます。

値の長さは利用可能なメモリによって制限されます。(2048 バイト以上の) 長い値はファイルに保存して、そのファイル名を設定レジストリに保存するべきです。そうすればレジストリを効率的に動作させる役に立ちます。

key 引数に指定されたキーは KEY_SET_VALUE アクセスで開かれていなければなりません。

_winreg.SetValueEx(key, value_name, reserved, type, value)

開かれたレジストリキーの値フィールドにデータを記録します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

value_name は値が関連付けられているサブキーの名前を表す文字列です。

type はデータの型を指定する整数です。 利用できる型については値の型 を参照してください。

reserved は何もしません - API には常にゼロが渡されます。

value は新たな値を指定する文字列です。

このメソッドではまた、指定されたキーに対して、さらに別の値や型情報を設定することができます。 key 引数で指定されたキーは KEY_SET_VALUE アクセスで開かれていなければなりません。

キーを開くには、 CreateKey() または OpenKey() メソッドを使ってください。

値の長さは利用可能なメモリによって制限されます。(2048 バイト以上の) 長い値はファイルに保存して、そのファイル名を設定レジストリに保存するべきです。そうすればレジストリを効率的に動作させる役に立ちます。

_winreg.DisableReflectionKey(key)

64ビット OS上で動作している 32bit プロセスに対するレジストリリフレクションを無効にします。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

32bit OS上では一般的に NotImplemented 例外を発生させます。

key がリフレクションリストに無い場合は、この関数は成功しますが効果はありません。あるキーのリフレクションを無効にしても、その全てのサブキーのリフレクションには影響しません。

_winreg.EnableReflectionKey(key)

指定された、リフレクションが無効にされたキーのリフレクションを再び有効にします。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

32bit OS上では一般的に NotImplemented 例外を発生させます。

あるキーのリフレクションを再開しても、その全てのサブキーには影響しません。

_winreg.QueryReflectionKey(key)

指定されたキーのリフレクション状態を確認します。

key はすでに開かれたキーか、既定の HKEY_* 定数のうちの一つです。

リフレクションが無効になっている場合、 True を返します。

32bit OS上では一般的に NotImplemented 例外を発生させます。

34.3.1. 定数

_winreg の多くの関数で利用するために以下の定数が定義されています。

34.3.1.1. HKEY_* 定数

_winreg.HKEY_CLASSES_ROOT

このキー以下のレジストリエントリは、ドキュメントのタイプ（またはクラス）や、それに関連付けられたプロパティを定義しています。シェルと COM アプリケーションがこの情報を利用します。

_winreg.HKEY_CURRENT_USER

このキー以下のレジストリエントリは、現在のユーザーの設定を定義します。この設定には、環境変数、プログラムグループに関するデータ、カラー、プリンター、ネットワーク接続、アプリケーション設定などが含まれます。

_winreg.HKEY_LOCAL_MACHINE

このキー以下のレジストリエントリは、コンピュータの物理的な状態を定義します。これには、バスタイプ、システムメモリ、インストールされているソフトウェアやハードウェアが含まれます。

_winreg.HKEY_USERS

このキー以下のレジストリエントリは、ローカルコンピュータの新規ユーザーのためのデフォルト設定や、現在のユーザーの設定を定義しています。

_winreg.HKEY_PERFORMANCE_DATA

このキー以下のレジストリエントリは、パフォーマンスデータへのアクセスを可能にしています。実際にはデータはレジストリには格納されていません。レジストリ関数がシステムにソースからデータを集めさせます。

_winreg.HKEY_CURRENT_CONFIG

ローカルコンピュータシステムの現在のハードウェアプロファイルに関する情報を含みます。

_winreg.HKEY_DYN_DATA

..This key is not used in versions of Windows after 98.

このキーは Windows の 98 以降のバージョンでは利用されていません。

34.3.1.2. アクセス権限

より詳しい情報については、 Registry Key Security and Access [http://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx] を参照してください。

_winreg.KEY_ALL_ACCESS

STANDARD_RIGHTS_REQUIRED (KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_LINK) アクセス権限の組み合わせ。

_winreg.KEY_WRITE

STANDARD_RIGHTS_WRITE (KEY_SET_VALUE, KEY_CREATE_SUB_KEY) アクセス権限の組み合わせ。

_winreg.KEY_READ

STANDARD_RIGHTS_READ (KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY) アクセス権限の組み合わせ。

_winreg.KEY_EXECUTE

KEY_READ と同じ

_winreg.KEY_QUERY_VALUE

レジストリキーの値を問い合わせるのに必要

_winreg.KEY_SET_VALUE

レジストリの値を作成、削除、設定するのに必要

_winreg.KEY_CREATE_SUB_KEY

レジストリキーのサブキーを作るのに必要

_winreg.KEY_ENUMERATE_SUB_KEYS

レジストリキーのサブキーを列挙するのに必要

_winreg.KEY_NOTIFY

レジストリキーやそのサブキーに対する変更通知を要求するのに必要

_winreg.KEY_CREATE_LINK

システムでの利用のために予約されている

34.3.1.2.1. 64-bit 特有のアクセス権

より詳しい情報については、 Accesing an Alternate Registry View [http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx] を参照してください。

_winreg.KEY_WOW64_64KEY

64 bit Windows 上のアプリケーションが、 64 bit のレジストリビュー上で操作する事を示します。

_winreg.KEY_WOW64_32KEY

64 bit Windows 上のアプリケーションが、 32 bit のレジストリビュー上で操作する事を示します。

34.3.1.3. 値の型

For more information, see Registry Value Types [http://msdn.microsoft.com/en-us/library/ms724884%28v=VS.85%29.aspx].

_winreg.REG_BINARY

何らかの形式のバイナリデータ

_winreg.REG_DWORD

32 ビットの数

_winreg.REG_DWORD_LITTLE_ENDIAN

32 ビットのリトルエンディアン形式の数。

_winreg.REG_DWORD_BIG_ENDIAN

32 ビットのビッグエンディアン形式の数。

_winreg.REG_EXPAND_SZ

環境変数を参照している、ヌル文字で終端された文字列。 (%PATH%)。

_winreg.REG_LINK

Unicode のシンボリックリンク。

_winreg.REG_MULTI_SZ

ヌル文字で終端された文字列からなり、二つのヌル文字で終端されている配列 (Python はこの終端の処理を自動的に行います)。

_winreg.REG_NONE

定義されていない値の形式。

_winreg.REG_RESOURCE_LIST

デバイスドライバリソースのリスト。

_winreg.REG_FULL_RESOURCE_DESCRIPTOR

ハードウェアセッティング

_winreg.REG_RESOURCE_REQUIREMENTS_LIST

ハードウェアリソースリスト

_winreg.REG_SZ

ヌル文字で終端された文字列。

34.3.2. レジストリハンドルオブジェクト

このオブジェクトは Windows の HKEY オブジェクトをラップし、オブジェクトが破壊されたときに自動的にハンドルを閉じます。オブジェクトの Close() メソッドと CloseKey() 関数のどちらも、後始末がきちんと行われることを保証するために呼び出すことができます。

このモジュールのレジストリ関数は全て、これらのハンドルオブジェクトの一つを返します。

このモジュールのレジストリ関数でハンドルオブジェクトを受理するものは全て整数も受理しますが、ハンドルオブジェクトを利用することを推奨します。

ハンドルオブジェクトは __nonzero__() の意味構成を持ちます - すなわち、

if handle:
    print "Yes"

は、ハンドルが現在有効な (閉じられたり切り離されたりしていない) 場合には Yes となります。

ハンドルオブジェクトはまた、比較の意味構成もサポートしています。このため、背後の Windows ハンドル値が同じものを複数のハンドルオブジェクトが参照している場合、それらの比較は真になります。

ハンドルオブジェクトは (例えば組み込みの int() 関数を使って) 整数に変換することができます。この場合、背後の Windows ハンドル値が返されます、また、 Detach() メソッドを使って整数のハンドル値を返させると同時に、ハンドルオブジェクトから Windows ハンドルを切り離すこともできます。

PyHKEY.Close()

背後の Windows ハンドルを閉じます。

ハンドルがすでに閉じられていてもエラーは送出されません。

PyHKEY.Detach()

ハンドルオブジェクトから Windows ハンドルを切り離します。

切り離される以前にそのハンドルを保持していた整数 (または 64 ビット Windows の場合には長整数) オブジェクトが返されます。ハンドルがすでに切り離されていたり閉じられていたりした場合、ゼロが返されます。

この関数を呼び出した後、ハンドルは確実に無効化されますが、閉じられるわけではありません。背後の Win32 ハンドルがハンドルオブジェクトよりも長く維持される必要がある場合にはこの関数を呼び出すとよいでしょう。

PyHKEY.__enter__()

PyHKEY.__exit__(*exc_info)

HKEY オブジェクトは __enter__(), __exit__() メソッドを実装していて、 with 文のためのコンテキストプロトコルをサポートしています。

with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key:
    # ... key を使った処理 ...

このコードは、 with ブロックから抜けるときに自動的に key を閉じます。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

34. MS Windows 固有のサービス »

34.4. winsound — Windows 用の音声再生インタフェース

バージョン 1.5.2 で追加.

winsound モジュールは Windows プラットフォーム上で提供されている基本的な音声再生機構へのアクセス手段を提供します。このモジュールではいくつかの関数と定数が定義されています。

winsound.Beep(frequency, duration)

PC のスピーカを鳴らします。引数 frequency は鳴らす音の周波数の指定で、単位は Hz です。値は 37 から 32.767 でなくてはなりません。引数 duration は音を何ミリ秒鳴らすかの指定です。システムがスピーカを鳴らすことができない場合、例外 RuntimeError が送出されます。

バージョン 1.6 で追加.

winsound.PlaySound(sound, flags)

プラットフォームの API から関数 PlaySound() を呼び出します。引数 sound はファイル名、音声データの文字列、または None をとり得ます。 sound の解釈は flags の値に依存します。この値は以下に述べる定数をビット単位OR して組み合わせたものになります。 sound 引数が None だった場合、現在再生中のWave形式サウンドの再生を停止します。システムのエラーが発生した場合、例外 RuntimeError が送出されます。

winsound.MessageBeep([type=MB_OK])

根底にある MessageBeep() 関数をプラットフォームの API から呼び出します。この関数は音声をレジストリの指定に従って再生します。 type 引数はどの音声を再生するかを指定します; とり得る値は -1, MB_ICONASTERISK, MB_ICONEXCLAMATION, MB_ICONHAND, MB_ICONQUESTION,および MB_OK で、全て以下に記述されています。値 -1 は “単純なビープ音” を再生します; この値は他の場合で音声を再生することができなかった際の最終的な代替音です。

バージョン 2.3 で追加.

winsound.SND_FILENAME

sound パラメタが WAV ファイル名であることを示します。 SND_ALIAS と同時に使ってはいけません。

winsound.SND_ALIAS

引数 sound はレジストリにある音声データに関連付けられた名前であることを示します。指定した名前がレジストリ上にない場合、定数 SND_NODEFAULT が同時に指定されていない限り、システム標準の音声データが再生されます。標準の音声データが登録されていない場合、例外 RuntimeError が送出されます。 SND_FILENAME と同時に使ってはいけません。

全ての Win32 システムは少なくとも以下の名前をサポートします; ほとんどのシステムでは他に多数あります:

PlaySound() name | 対応するコントロールパネルでの音声名
'SystemAsterisk' | Asterisk
'SystemExclamation' | Exclamation
'SystemExit' | Exit Windows
'SystemHand' | Critical Stop
'SystemQuestion' | Question

例えば以下のように使います:

import winsound
# Play Windows exit sound.
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)

# Probably play Windows default sound, if any is registered (because
# "*" probably isn't the registered name of any sound).
winsound.PlaySound("*", winsound.SND_ALIAS)

winsound.SND_LOOP

音声データを繰り返し再生します。システムがブロックしないようにするため、 SND_ASYNC フラグを同時に使わなくてはなりません。 SND_MEMORY と同時に使うことはできません。

winsound.SND_MEMORY

PlaySound() の引数 sound が文字列の形式をとった WAV ファイルのメモリ上のイメージであることを示します。

ノート

このモジュールはメモリ上のイメージを非同期に再生する機能をサポートしていません。従って、このフラグと SND_ASYNC を組み合わせると例外 RuntimeError が送出されます。

winsound.SND_PURGE

指定した音声の全てのインスタンスについて再生処理を停止します。

ノート

このフラグは現代のWindowsプラットフォームではサポートされていません。

winsound.SND_ASYNC

音声を非同期に再生するようにして、関数呼び出しを即座に返します。

winsound.SND_NODEFAULT

指定した音声が見つからなかった場合にシステム標準の音声を鳴らさないようにします。

winsound.SND_NOSTOP

現在鳴っている音声を中断させないようにします。

winsound.SND_NOWAIT

サウンドドライバがビジー状態にある場合、関数がすぐ返るようにします。

winsound.MB_ICONASTERISK

音声 SystemDefault を再生します。

winsound.MB_ICONEXCLAMATION

音声 SystemExclamation を再生します。

winsound.MB_ICONHAND

音声 SystemHand を再生します。

winsound.MB_ICONQUESTION

音声 SystemQuestion を再生します。

winsound.MB_OK

音声 SystemDefault を再生します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス

本章に記述されたモジュールは、Unix オペレーティングシステム、あるいはそれから派生した多くのものに固有の機能のためのインタフェースを提供します。その概要を以下に述べます。

35.1. posix — 最も一般的な POSIX システムコール群

35.1.1. ラージファイルのサポート

35.1.2. 注目すべきモジュールの内容

35.2. pwd — パスワードデータベースへのアクセスを提供する

35.3. spwd — シャドウパスワードデータベース

35.4. grp — グループデータベースへのアクセス

35.5. crypt — Unix パスワードをチェックするための関数

35.6. dl — 共有オブジェクトのC関数の呼び出し

35.6.1. Dlオブジェクト

35.7. termios — POSIX スタイルの端末制御

35.7.1. 使用例

35.8. tty — 端末制御のための関数群

35.9. pty — 擬似端末ユーティリティ

35.10. fcntl — fcntl() および ioctl() システムコール

35.11. pipes — シェルパイプラインへのインタフェース

35.11.1. テンプレートオブジェクト

35.12. posixfile — ロック機構をサポートするファイル類似オブジェクト

35.13. resource — リソース使用状態の情報

35.13.1. リソースの制限

35.13.2. リソースの使用状態

35.14. nis — Sun の NIS (Yellow Pages) へのインタフェース

35.15. syslog — Unix syslog ライブラリルーチン群

35.15.1. 例

35.15.1.1. シンプルな例

35.16. commands — コマンド実行ユーティリティ

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.1. posix — 最も一般的な POSIX システムコール群

このモジュールはオペレーティングシステムの機能のうち、C 言語標準および POSIX 標準 (Unix インタフェースをほんの少し隠蔽した) で標準化されている機能に対するアクセス機構を提供します。

このモジュールを直接 import しないで下さい。その代わりに、移植性のあるインタフェースを提供している os をインポートしてください。 Unixでは、 os モジュールが提供するインタフェースは posix の内容を内包しています。非 Unix オペレーティングシステムでは posix モジュールを使うことはできませんが、その部分的な機能セットは、たいてい os インタフェースを介して利用することができます。 os は、一度 import してしまえば posix の代わりであることによるパフォーマンス上のペナルティは 全くありません 。その上、 os は os.environ の内容が変更された際に自動的に putenv() を呼ぶなど、いくつかの追加機能を提供しています。

エラーは例外として報告されます; よくある例外は型エラーです。一方、システムコールから報告されたエラーは以下に述べるように OSError を送出します。

35.1.1. ラージファイルのサポート

いくつかのオペレーティングシステム (AIX, HP-UX, Irix および Solaris が含まれます) は、 int および long を 32 ビット値とするC プログラムモデルで 2GB を超えるサイズのファイルのサポートを提供しています。このサポートは典型的には 64 ビット値のオフセット値と、そこからの相対サイズを定義することで実現しています。このようなファイルは時にラージファイル (large files) と呼ばれます。

Python では、 off_t のサイズが long より大きく、かつ long long 型を利用することができて、少なくとも off_t 型と同じくらい大きなサイズである場合、ラージファイルのサポートが有効になります。この場合、ファイルのサイズ、オフセットおよび Python の通常整数型の範囲を超えるような値の表現には Python の長整数型が使われます。例えば、ラージファイルのサポートは Irix の最近のバージョンでは標準で有効ですが、Solaris 2.6 および 2.7 では、以下のようにする必要があります:

CFLAGS="`getconf LFS_CFLAGS`" OPT="-g -O2 $CFLAGS" \
        ./configure

ラージファイル対応の Linux システムでは、以下のようにすれば良いでしょう:

CFLAGS='-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' OPT="-g -O2 $CFLAGS" \
        ./configure

35.1.2. 注目すべきモジュールの内容

os モジュールのドキュメントで説明されている多数の関数に加え、 posix では以下のデータ項目を定義しています:

posix.environ

インタプリタが起動した時点の環境変数文字列を表現する辞書です。例えば、 environ['HOME'] はホームディレクトリのパス名で、C 言語の getenv("HOME") と等価です。

この辞書を変更しても、 execv() 、 popen() または system() などに渡される環境変数文字列には影響しません; そうした環境を変更するする必要がある場合、 environ を execve() に渡すか、 system() または popen() の命令文字列に変数の代入や export 文を追加してください。

ノート

os モジュールでは、もう一つの environ 実装を提供しており、環境変数が変更された場合、その内容を更新するようになっています。 os.environ を更新した場合、この辞書は古い内容を表していることになってしまうので、このことにも注意してください。 posix モジュール版を直接アクセスするよりも、 os モジュール版を使う方が推奨されています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.2. pwd — パスワードデータベースへのアクセスを提供する

このモジュールは Unix のユーザアカウントとパスワードのデータベースへのアクセスを提供します。全ての Unix 系 OS で利用できます。

パスワードデータベースの各エントリはタプルのようなオブジェクトで提供され、それぞれの属性は passwd 構造体のメンバに対応しています(下の属性欄については、 <pwd.h> を見てください)。

インデックス | 属性 | 意味
0 | pw_name | ログイン名
1 | pw_passwd | 暗号化されたパスワード(optional))
2 | pw_uid | ユーザID(UID)
3 | pw_gid | グループID(GID)
4 | pw_gecos | 実名またはコメント
5 | pw_dir | ホームディレクトリ
6 | pw_shell | シェル

UIDとGIDは整数で、それ以外は全て文字列です。検索したエントリが見つからないと KeyError が発生します。

ノート

伝統的なUnixでは、 pw_passwd フィールドはDES由来のアルゴリズムで暗号化されたパスワード(crypt モジュールをごらんください)が含まれています。しかし、近代的なUNIX系OSでは シャドウパスワード とよばれる仕組みを利用しています。この場合には pw_passwd フィールドにはアスタリスク('*')か、 'x' という一文字だけが含まれており、暗号化されたパスワードは、一般には見えない /etc/shadow というファイルに入っています。 pw_passwd フィールドに有用な値が入っているかはシステムに依存します。利用可能なら、暗号化されたパスワードへのアクセスが必要なときには spwd モジュールを利用してください。

このモジュールでは以下のものが定義されています:

pwd.getpwuid(uid)

与えられたUIDに対応するパスワードデータベースのエントリを返します。

pwd.getpwnam(name)

与えられたユーザ名に対応するパスワードデータベースのエントリを返します。

pwd.getpwall()

パスワードデータベースの全てのエントリを、任意の順番で並べたリストを返します。

参考

grp モジュール

このモジュールに似た、グループデータベースへのアクセスを提供するモジュール。

spwd モジュール

このモジュールに似た、シャドウパスワードデータベースへのアクセスを提供するモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.3. spwd — シャドウパスワードデータベース

バージョン 2.5 で追加.

このモジュールは Unix のシャドウパスワードデータベースへのアクセスを提供します。様々な Unix 環境で利用できます。

シャドウパスワードデータベースへアクセスできる権限が必要(大抵の場合 root である必要があります)です。

シャドウパスワードデータベースのエントリはタプル状のオプジェクトで提供され、その属性は spwd 構造のメンバーに対応しています（以下を参照してください。 <shadow.h>を参照):

Index | Attribute | Meaning
0 | sp_nam | ログイン名
1 | sp_pwd | 暗号化されたパスワード
2 | sp_lstchg | 最終更新日
3 | sp_min | パスワード変更が出来るようになるまでの最小日数
4 | sp_max | パスワードを変更しなくても良い最大日数
5 | sp_warn | パスワードが期限切れになる前に、期限切れが近づいている旨の警告をユーザに出しはじめる日数
6 | sp_inact | パスワードが期限切れになってから、アカウントがinactiveとなり使用できなくなるまでの日数
7 | sp_expire | 1970-01-01からアカウントが使用できなくなるまでの日数
8 | sp_flag | 将来のために予約

sp_nam と sp_pwd は文字列で、他は全て整数です。

エントリが見つからなかった時は KeyError が起きます。

このモジュールでは以下を定義しています:

spwd.getspnam(name)

与えられたユーザ名に対応するシャドウパスワードデータベースのエントリを返します。

spwd.getspall()

利用可能なシャドウパスワードデータベースの全エントリを任意の順番で返します。

参考

grp モジュール

このモジュールに似たグループデータベースへのインタフェース

pwd モジュール

このモジュールに似た通常のパスワードデータベースへのインタフェース

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.4. grp — グループデータベースへのアクセス

このモジュールでは Unix グループ (group) データベースへのアクセス機構を提供します。全ての Unix バージョンで利用可能です。

このモジュールはグループデータベースのエントリをタプルに似たオブジェクトとして報告されます。このオブジェクトの属性は group 構造体の各メンバ (以下の属性フィールド、 <pwd.h> を参照) に対応します:

インデクス | 属性 | 意味
0 | gr_name | グループ名
1 | gr_passwd | (暗号化された) グループパスワード; しばしば空文字列になります
2 | gr_gid | 数字のグループ ID
3 | gr_mem | グループメンバの全てのユーザ名

gid は整数、名前およびパスワードは文字列、そしてメンバリストは文字列からなるリストです。 (ほとんどのユーザは、パスワードデータベースで自分が入れられているグループのメンバとしてグループデータベース内では明示的に列挙されていないので注意してください。完全なメンバ情報を取得するには両方のデータベースを調べてください。また、 + や - で始まる gr_name は YP/NIS 参照である可能性があり、 getgrnam() や getgrgid() でアクセスできないかもしれないことにも注意してください。 )

このモジュールでは以下の内容を定義しています:

grp.getgrgid(gid)

与えられたグループ ID に対するグループデータベースエントリを返します。要求したエントリが見つからなかった場合、 KeyError が送出されます。

grp.getgrnam(name)

与えられたグループ名に対するグループデータベースエントリを返します。要求したエントリが見つからなかった場合、 KeyError が送出されます。

grp.getgrall()

全ての入手可能なグループエントリを返します。順番は決まっていません。

参考

pwd モジュール

このモジュールと類似の、ユーザデータベースへのインタフェース。

spwd モジュール

このモジュールと類似の、シャドウパスワードデータベースへのインタフェース。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.5. crypt — Unix パスワードをチェックするための関数

このモジュールは DES アルゴリズムに基づいた一方向ハッシュ関数である crypt(3) ルーチンを実装しています。詳細については Unix マニュアルページを参照してください。このモジュールは、Python スクリプトがユーザから入力されたパスワードを受理できるようにしたり、 Unix パスワードに (脆弱性検査のための) 辞書攻撃を試みるのに使えます。

このモジュールは実行環境の crypt(3) の実装に依存しています。そのため、現在の実装で利用可能な拡張を、このモジュールでもそのまま利用できます。

crypt.crypt(word, salt)

word は通常はユーザのパスワードで、プロンプトやグラフィカルインタフェースからタイプ入力されます。 salt は通常ランダムな 2 文字からなる文字列で、DES アルゴリズムに 4096 通りのうち 1 つの方法で外乱を与えるために使われます。 salt に使う文字は集合 [./a-zA-Z0-9] の要素でなければなりません。ハッシュされたパスワードを文字列として返します。パスワード文字列は salt と同じ文字集合に含まれる文字からなります (最初の 2 文字は salt 自体です).

いくつかの拡張された crypt(3) は異なる値と salt の長さを許しているので、パスワードをチェックする際には crypt されたパスワード文字列全体を salt として渡すよう勧めます。

典型的な使用例のサンプルコード:

import crypt, getpass, pwd

def login():
    username = raw_input('Python login:')
    cryptedpasswd = pwd.getpwnam(username)[1]
    if cryptedpasswd:
        if cryptedpasswd == 'x' or cryptedpasswd == '*':
            raise NotImplementedError(
                "Sorry, currently no support for shadow passwords")
        cleartext = getpass.getpass()
        return crypt.crypt(cleartext, cryptedpasswd) == cryptedpasswd
    else:
        return 1

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.6. dl — 共有オブジェクトのC関数の呼び出し

バージョン 2.6 で撤廃: dl モジュールは Python 3.0 で削除されました。代わりに ctypes モジュールを使ってください。

dl モジュールは dlopen() 関数へのインタフェースを定義します。これはダイナミックライブラリにハンドルするための Unix プラットフォーム上の最も一般的なインタフェースです。そのライブラリの任意の関数を呼ぶプログラムを与えます。

警告

dl モジュールは Python の型システムとエラー処理をバイパスしています。もし間違って使用すれば、セグメンテーションフォルト、クラッシュ、その他の不正な動作を起こします。

ノート

このモジュールは sizeof(int) == sizeof(long) == sizeof(char *) でなければ働きません。そうでなければimportするときに SystemError が送出されるでしょう。

dl モジュールは次の関数を定義します:

dl.open(name[, mode=RTLD_LAZY])

共有オブジェクトファイルを開いて、ハンドルを返します。モードは遅延結合(RTLD_LAZY)または即時結合(RTLD_NOW) を表します。デフォルトは RTLD_LAZY です。いくつかのシステムは RTLD_NOW をサポートしていないことに注意してください。

返り値は dlobject です。

dl モジュールは次の定数を定義します:

dl.RTLD_LAZY

open() の引数として使います。

dl.RTLD_NOW

open() の引数として使います。即時結合をサポートしないシステムでは、この定数がモジュールに現われないことに注意してください。最大のポータビリティを求めるならば、システムが即時結合をサポートするかどうかを決定するために hasattr() を使用してください。

dl モジュールは次の例外を定義します:

exception dl.error

動的なロードやリンクルーチンの内部でエラーが生じたときに送出される例外です。

例:

>>> import dl, time
>>> a=dl.open('/lib/libc.so.6')
>>> a.call('time'), time.time()
(929723914, 929723914.498)

この例はDebian GNU/Linuxシステム上で行なったもので、このモジュールの使用はたいてい悪い選択肢であるという事実のよい例です。

35.6.1. Dlオブジェクト

open() によって返されたDlオブジェクトは次のメソッドを持っています:

dl.close()

メモリーを除く全てのリソースを解放します。

dl.sym(name)

name という名前の関数が参照された共有オブジェクトに存在する場合、そのポインター(整数値)を返します。存在しない場合 None を返します。これは次のように使えます:

>>> if a.sym('time'):
...     a.call('time')
... else:
...     time.time()

(0は NULL ポインターであるので、この関数は0でない数を返すだろうということに注意してください)

dl.call(name[, arg1[, arg2...]])

参照された共有オブジェクトの name という名前の関数を呼出します。引数は、Python整数(そのまま渡される)、Python文字列(ポインターが渡される)、 None (NULL として渡される) のどれかでなければいけません。 Pythonはその文字列が変化させられるのを好まないので、文字列は const char* として関数に渡されるべきであることに注意してください。

最大で10個の引数が渡すことができ、与えられない引数は None として扱われます。関数の返り値は C long (Python整数である)です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.7. termios — POSIX スタイルの端末制御

このモジュールでは端末 I/O 制御のための POSIX 準拠の関数呼び出しインタフェースを提供します。これら呼び出しのための完全な記述については、 POSIX または Unix マニュアルページを参照してください。 POSIX termios 形式の端末制御をサポートする Unix のバージョンで (かつインストール時に指定した場合に) のみ利用可能です。

このモジュールの関数は全て、ファイル記述子 fd を最初の引数としてとります。この値は、 sys.stdin.fileno() が返すような整数のファイル記述子でも、 sys.stdin 自体のようなファイルオブジェクトでもかまいません。

このモジュールではまた、モジュールで提供されている関数を使う上で必要となる全ての定数を定義しています; これらの定数は C の対応する関数と同じ名前を持っています。これらの端末制御インタフェースを利用する上でのさらなる情報については、あなたのシステムのドキュメンテーションを参考にしてください。

このモジュールでは以下の関数を定義しています:

termios.tcgetattr(fd)

ファイル記述子 fd の端末属性を含むリストを返します。その形式は: [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] です。 cc は端末特殊文字のリストです (それぞれ長さ 1 の文字列です。ただしインデクス VMIN および VTIME の内容は、それらのフィールドが定義されていた場合整数の値となります)。端末設定フラグおよび端末速度の解釈、および配列 cc のインデクス検索は、 termios で定義されているシンボル定数を使って行わなければなりません。

termios.tcsetattr(fd, when, attributes)

ファイル記述子 fd の端末属性を attributes から取り出して設定します。 attributes は tcgetattr() が返すようなリストです。引数 when は属性がいつ変更されるかを決定します: TCSANOW は即時変更を行い、 TCSAFLUSH は現在キューされている出力を全て転送し、全てのキューされている入力を無視した後に変更を行います。

termios.tcsendbreak(fd, duration)

ファイル記述子 fd にブレークを送信します。 duration をゼロにすると、 0.25–0.5 秒間のブレークを送信します; duration の値がゼロでない場合、その意味はシステム依存です。

termios.tcdrain(fd)

ファイル記述子 fd に書き込まれた全ての出力が転送されるまで待ちます。

termios.tcflush(fd, queue)

ファイル記述子 fd にキューされたデータを無視します。どのキューかは queue セレクタで指定します: TCIFLUSH は入力キュー、 TCOFLUSH は出力キュー、 TCIOFLUSH は両方のキューです。

termios.tcflow(fd, action)

ファイル記述子 fd の入力または出力をサスペンドしたりレジュームしたりします。引数 action は出力をサスペンドする TCOOFF 、出力をレジュームする TCOON 、入力をサスペンドする TCIOFF 、入力をレジュームする TCION をとることができます。

参考

tty モジュール

一般的な端末制御操作のための便利な関数。

35.7.1. 使用例

以下はエコーバックを切った状態でパスワード入力を促す関数です。ユーザの入力に関わらず以前の端末属性を正確に回復するために、二つの tcgetattr() と try ... finally 文によるテクニックが使われています:

def getpass(prompt="Password: "):
    import termios, sys
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ECHO          # lflags
    try:
        termios.tcsetattr(fd, termios.TCSADRAIN, new)
        passwd = raw_input(prompt)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old)
    return passwd

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.8. tty — 端末制御のための関数群

tty モジュールは端末を cbreak および raw モードにするための関数を定義しています。

このモジュールは termios モジュールを必要とするため、 Unix でしか動作しません。

tty モジュールでは、以下の関数を定義しています:

tty.setraw(fd[, when])

ファイル記述子 fd のモードを raw モードに変えます。 when を省略すると標準の値は termios.TCSAFLUSH になり、 termios.tcsetattr() に渡されます。

tty.setcbreak(fd[, when])

ファイル記述子 fd のモードを cbreakモードに変えます。 when を省略すると標準の値は termios.TCSAFLUSH になり、 termios.tcsetattr() に渡されます。

参考

termios モジュール

低レベル端末制御インタフェース。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.9. pty — 擬似端末ユーティリティ

pty モジュールは擬似端末(他のプロセスを実行してその制御をしている端末をプログラムで読み書きする)を制御する操作を定義しています。

擬似端末の制御はプラットフォームに強く依存するので、Linux用のコードしか存在していません。(Linux用のコードは他のプラットフォームでも動作するように作られていますがテストされていません。)

pty モジュールでは以下の関数を定義しています:

pty.fork()

forkします。子プロセスの制御端末を擬似端末に接続します。返り値は (pid, fd) です。子プロセスは pid として0、 fd として invalid をそれぞれ受けとります。親プロセスは pid として子プロセスのPID、 fd として子プロセスの制御端末 (子プロセスの標準入出力に接続されている)のファイルディスクリプタを受けとります。

pty.openpty()

新しい擬似端末のペアを開きます。利用できるなら os.openpty() を使い、利用できなければ一般的なUnixシステム用のエミュレーションコードを使います。マスター、スレーブそれぞれのためのファイルディスクリプタ、 (master, slave) のタプルを返します。

pty.spawn(argv[, master_read[, stdin_read]])

プロセスを生成して制御端末を現在のプロセスの標準入出力に接続します。これは制御端末を読もうとするプログラムをごまかすために利用されます。

master_read と stdin_read にはファイルディスクリプタから読み込む関数を指定してください。デフォルトでは呼ばれるたびに1024バイトずつ読み込もうとします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.10. fcntl — fcntl() および ioctl() システムコール

このモジュールでは、ファイル記述子 (file descriptor) に基づいたファイル制御および I/O 制御を実現します。このモジュールは、 Unix のルーチンである fcntl() および ioctl() へのインタフェースです。

このモジュール内の全ての関数はファイル記述子 fd を最初の引数に取ります。この値は sys.stdin.fileno() が返すような整数のファイル記述子でも、 sys.stdin 自体のような、純粋にファイル記述子だけを返す fileno() メソッドを提供しているファイルオブジェクトでもかまいません。

このモジュールでは以下の関数を定義しています:

fcntl.fcntl(fd, op[, arg])

要求された操作をファイル記述子 fd (または fileno() メソッドを提供しているファイルオブジェクト) に対して実行します。操作は op で定義され、オペレーティングシステム依存です。これらの操作コードは fcntl モジュール内にもあります。引数 arg はオプションで、標準では整数値 0 です。この引数を与える場合、整数か文字列の値をとります。引数が無いか整数値の場合、この関数の戻り値は C 言語の fcntl() を呼び出した際の整数の戻り値になります。引数が文字列の場合には、 struct.pack() で作られるようなバイナリの構造体を表します。バイナリデータはバッファにコピーされ、そのアドレスが C 言語の fcntl() 呼び出しに渡されます。呼び出しが成功した後に戻される値はバッファの内容で、文字列オブジェクトに変換されています。返される文字列は arg 引数と同じ長さになます。この値は 1024 バイトに制限されています。オペレーティングシステムからバッファに返される情報の長さが 1024 バイトよりも大きい場合、大抵はセグメンテーション違反となるか、より不可思議なデータの破損を引き起こします。

fcntl() が失敗した場合、 IOError が送出されます。

fcntl.ioctl(fd, op, arg)

この関数は fcntl() 関数と同じですが、操作が通常ライブラリモジュール termios で定義されており、引数の扱いがより複雑であるところが異なります。

パラメタ op は32ビットに収まる値に制限されます。

パラメタ arg は整数か、存在しない (整数 0 と等価なものとして扱われます) か、(通常の Python 文字列のような) 読み出し専用のバッファインタフェースをサポートするオブジェクトか、読み書きバッファインタフェースをサポートするオブジェクトです。

最後の型のオブジェクトを除き、動作は fcntl() 関数と同じです。

可変なバッファが渡された場合、動作は mutate_flag 引数の値で決定されます。

この値が偽の場合、バッファの可変性は無視され、動作は読み出しバッファの場合と同じになりますが、上で述べた 1024 バイトの制限は回避されます – 従って、オペレーティングシステムが希望するバッファ長までであれば正しく動作します。

mutate_flag が真の場合、バッファは (実際には) 根底にある ioctl() システムコールに渡され、後者の戻り値が呼び出し側の Python に引き渡され、バッファの新たな内容は ioctl() の動作を反映します。この説明はやや単純化されています。というのは、与えられたバッファが 1024 バイト長よりも短い場合、バッファはまず 1024 バイト長の静的なバッファにコピーされてから ioctl() に渡され、その後引数で与えたバッファに戻しコピーされるからです。

mutate_flag が与えられなかった場合、2.3 ではこの値は偽となります。この仕様は今後のいくつかのバージョンを経た Python で変更される予定です: 2.4 では、 mutate_flag を提供し忘れると警告が出されますが同じ動作を行い、2.5 ではデフォルトの値が真となるはずです。

以下に例を示します:

>>> import array, fcntl, struct, termios, os
>>> os.getpgrp()
13341
>>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, "  "))[0]
13341
>>> buf = array.array('h', [0])
>>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)
0
>>> buf
array('h', [13341])

fcntl.flock(fd, op)

ファイル記述子 fd (fileno() メソッドを提供しているファイルオブジェクトも含む) に対してロック操作 op を実行します。詳細は Unix マニュアルの flock(2) を参照してください (システムによっては、この関数は fcntl() を使ってエミュレーションされています)。

fcntl.lockf(fd, operation[, length[, start[, whence]]])

本質的に fcntl() によるロッキングの呼び出しをラップしたものです。 fd はロックまたはアンロックするファイルのファイル記述子で、 operation は以下の値のうちいずれかになります:

LOCK_UN – アンロック

LOCK_SH – 共有ロックを取得

LOCK_EX – 排他的ロックを取得

operation が LOCK_SH または LOCK_EX の場合、 LOCK_NB とビット OR にすることでロック取得時にブロックしないようにすることができます。 LOCK_NB が使われ、ロックが取得できなかった場合、 IOError が送出され、例外は errno 属性を持ち、その値は EACCESS または EAGAIN になります (オペレーティングシステムに依存します; 可搬性のため、両方の値をチェックしてください)。少なくともいくつかのシステムでは、ファイル記述子が参照しているファイルが書き込みのために開かれている場合、 LOCK_EX だけしか使うことができません。

length はロックを行いたいバイト数、 start はロック領域先頭の whence からの相対的なバイトオフセット、 whence は fileobj.seek() と同じで、具体的には:

0 – ファイル先頭からの相対位置 (SEEK_SET)

1 – 現在のバッファ位置からの相対位置 (SEEK_CUR)

2 – ファイルの末尾からの相対位置 (SEEK_END)

start の標準の値は 0 で、ファイルの先頭から開始することを意味します。 whence の標準の値も 0 です。

以下に (全ての SVR4 互換システムでの) 例を示します:

import struct, fcntl, os

f = open(...)
rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)

lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)

最初の例では、戻り値 rv は整数値を保持しています; 二つ目の例では文字列値を保持しています。 lockdata 変数の構造体レイアウトはシステム依存です — 従って flock() を呼ぶ方がベターです。

参考

os モジュール

もし os モジュールに O_SHLOCK と O_EXLOCK が 存在する場合 (BSD のみ)、 os.open() 関数は lockf() や flock() 関数を代替できます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.11. pipes — シェルパイプラインへのインタフェース

pipes モジュールでは、 ‘pipeline’ の概念 — あるファイルを別のファイルに変換する機構の直列接続 — を抽象化するためのクラスを定義しています。

このモジュールは /bin/sh コマンドラインを利用するため、 os.system() および os.popen() のための POSIX 準拠のシェル、または互換のシェルが必要です。

pipes モジュールでは、以下のクラスを定義しています:

class pipes.Template

パイプラインを抽象化したクラス。

使用例:

>>> import pipes
>>> t=pipes.Template()
>>> t.append('tr a-z A-Z', '--')
>>> f=t.open('/tmp/1', 'w')
>>> f.write('hello world')
>>> f.close()
>>> open('/tmp/1').read()
'HELLO WORLD'

35.11.1. テンプレートオブジェクト

テンプレートオブジェクトは以下のメソッドを持っています:

Template.reset()

パイプラインテンプレートを初期状態に戻します。

Template.clone()

元のパイプラインテンプレートと等価の新しいオブジェクトを返します。

Template.debug(flag)

flag が真の場合、デバッグをオンにします。そうでない場合、デバッグをオフにします。デバッグがオンの時には、実行されるコマンドが印字され、より多くのメッセージを出力するようにするために、シェルに set -x 命令を与えます。

Template.append(cmd, kind)

新たなアクションをパイプラインの末尾に追加します。 cmd 変数は有効な bourne shell 命令でなければなりません。 kind 変数は二つの文字からなります。

最初の文字は '-' (コマンドが標準入力からデータを読み出すことを意味します)、'f' (コマンドがコマンドライン上で与えたファイルからデータを読み出すことを意味します)、あるいは '.' (コマンドは入力を読まないことを意味します、従ってパイプラインの先頭になります)、のいずれかになります。

同様に、二つ目の文字は '-' (コマンドが標準出力に結果を書き込むことを意味します)、 'f' (コマンドがコマンドライン上で指定したファイルに結果を書き込むことを意味します)、あるいは '.' (コマンドはファイルを書き込まないことを意味し、パイプラインの末尾になります)、のいずれかになります。

Template.prepend(cmd, kind)

パイプラインの先頭に新しいアクションを追加します。引数の説明については append() を参照してください。

Template.open(file, mode)

ファイル類似のオブジェクトを返します。このオブジェクトは file を開いていますが、パイプラインを通して読み書きするようになっています。 mode には 'r' または 'w' のいずれか一つしか与えることができないので注意してください。

Template.copy(infile, outfile)

パイプを通して infile を outfile にコピーします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.12. posixfile — ロック機構をサポートするファイル類似オブジェクト

バージョン 1.5 で撤廃: このモジュールが提供しているよりもうまく処理ができ、可搬性も高いロック操作が fcntl.lockf() で提供されています。

このモジュールでは、組み込みのファイルオブジェクトの上にいくつかの追加機能を実装しています。特に、このオブジェクトはファイルのロック機構、ファイルフラグへの操作、およびファイルオブジェクトを複製するための簡単なインタフェースを実装しています。オブジェクトは全ての標準ファイルオブジェクトのメソッドに加え、以下に述べるメソッドを持っています。このモジュールはファイルのロック機構に fcntl.fcntl() を用いるため、ある種の Unix でしか動作しません。

posixfile オブジェクトをインスタンス化するには、 posixfile.open() 関数を使います。生成されるオブジェクトは標準ファイルオブジェクトとだいたい同じルック&フィールです。

posixfile モジュールでは、以下の定数を定義しています:

posixfile.SEEK_SET

オフセットをファイルの先頭から計算します。

posixfile.SEEK_CUR

オフセットを現在のファイル位置から計算します。

posixfile.SEEK_END

オフセットをファイルの末尾から計算します。

posixfile モジュールでは以下の関数を定義しています:

posixfile.open(filename[, mode[, bufsize]])

指定したファイル名とモードで新しい posixfile オブジェクトを作成します。 filename 、 mode および bufsize 引数は組み込みの open() 関数と同じように解釈されます。

posixfile.fileopen(fileobject)

指定した標準ファイルオブジェクトで新しい posixfile オブジェクトを作成します。作成されるオブジェクトは元のファイルオブジェクトと同じファイル名およびモードを持っています。

posixfile オブジェクトでは以下の追加メソッドを定義しています:

posixfile.lock(fmt[, len[, start[, whence]]])

ファイルオブジェクトが参照しているファイルの指定部分にロックをかけます。指定の書式は下のテーブルで説明されています。 len 引数にはロックする部分の長さを指定します。標準の値は 0 です。 start にはロックする部分の先頭オフセットを指定し、その標準値は 0 です。 whence 引数はオフセットをどこからの相対位置にするかを指定します。この値は定数 SEEK_SET 、 SEEK_CUR 、または SEEK_END のいずれかになります。標準の値は SEEK_SET です。引数についてのより詳しい情報はシステムの fcntl(2) マニュアルページを参照してください。

posixfile.flags([flags])

ファイルオブジェクトが参照しているファイルに指定したフラグを設定します。新しいフラグは特に指定しない限り以前のフラグと OR されます。指定書式は下のテーブルで説明されています。 flags 引数なしの場合、現在のフラグを示す文字列が返されます(? 修飾子と同じです) 。フラグについてのより詳しい情報はシステムの fcntl(2) マニュアルページを参照してください。

posixfile.dup()

ファイルオブジェクトと、背後のファイルポインタおよびファイル記述子を複製します。返されるオブジェクトは新たに開かれたファイルのように振舞います。

posixfile.dup2(fd)

ファイルオブジェクトと、背後のファイルポインタおよびファイル記述子を複製します。新たなオブジェクトは指定したファイル記述子を持ちます。それ以外の点では、返されるオブジェクトは新たに開かれたファイルのように振舞います。

posixfile.file()

posixfile オブジェクトが参照している標準ファイルオブジェクトを返します。この関数は標準ファイルオブジェクトを使うよう強制している関数を使う場合に便利です。

全てのメソッドで、要求された操作が失敗した場合には IOError が送出されます。

lock() の書式指定文字には以下のような意味があります:

書式指定 | 意味
u | 指定領域のロックを解除します
r | 指定領域の読み出しロックを要求します
w | 指定領域の書き込みロックを要求します

これに加え、以下の修飾子を書式に追加できます:

修飾子 | 意味 | 注釈
| | ロック操作が処理されるまで待ちます |
? | 要求されたロックと衝突している第一のロックを返すか、衝突がない場合には None を返します。 | (1)

注釈:

返されるロックは (mode, len, start, whence, pid) の形式で、 mode はロックの形式を表す文字 (‘r’ または ‘w’) です。この修飾子はロック要求の許可を行わせません; すなわち、問い合わせの目的にしか使えません。

flags() の書式指定文字には以下のような意味があります:

書式 | 意味
a | 追記のみ (append only) フラグ
c | 実行時クローズ (close on exec) フラグ
n | 無遅延 (no delay) フラグ (非ブロック (non-blocking) フラグとも呼ばれます)
s | 同期 (synchronization) フラグ

これに加え、以下の修飾子を書式に追加できます:

修飾子 | 意味 | 注釈
! | 指定したフラグを通常の ‘オン’ にせず ‘オフ’ にします | (1)
= | フラグを標準の ‘OR’ 操作ではなく置換します。 | (1)
? | 設定されているフラグを表現する文字からなる文字列を返します。 | (2)

注釈:

! および = 修飾子は互いに排他の関係にあります。

この文字列が表すフラグは同じ呼び出しによってフラグが置き換えられた後のものです。

以下に例を示します:

import posixfile

file = posixfile.open('/tmp/test', 'w')
file.lock('w|')
...
file.lock('u')
file.close()

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.13. resource — リソース使用状態の情報

このモジュールでは、プログラムによって使用されているシステムリソースを計測したり制御するための基本的なメカニズムを提供します。

特定のシステムリソースを指定したり、現在のプロセスやその子プロセスのリソース使用情報を要求するためにはシンボル定数が使われます。

エラーを表すための例外が一つ定義されています:

exception resource.error

下に述べる関数は、背後にあるシステムコールが予期せず失敗した場合、このエラーを送出するかもしれません。

35.13.1. リソースの制限

リソースの使用は下に述べる setrlimit() 関数を使って制限することができます。各リソースは二つ組の制限値: ソフトリミット (soft limit) 、およびハードリミット (hard limit) 、で制御されます。ソフトリミットは現在の制限値で、時間とともにプロセスによって下げたり上げたりできます。ソフトリミットはハードリミットを超えることはできません。ハードリミットはソフトリミットよりも高い任意の値まで下げることができますが、上げることはできません。 (スーパユーザの有効な UID を持つプロセスのみがハードリミットを上げることができます。)

制限をかけるべく指定できるリソースはシステムに依存します。指定できるリソースは getrlimit(2) マニュアルページで解説されています。以下に列挙するリソースは背後のオペレーティングシステムがサポートする場合にサポートされています; オペレーティングシステム側で値を調べたり制御したりできないリソースは、そのプラットフォーム向けのこのモジュール内では定義されていません。

resource.getrlimit(resource)

resource の現在のソフトおよびハードリミットを表すタプル (soft, hard) を返します。無効なリソースが指定された場合には ValueError が、背後のシステムコールが予期せず失敗した場合には error が送出されます。

resource.setrlimit(resource, limits)

resouce の新たな消費制限を設定します。 limits 引数には、タプル (soft, hard) による二つの整数で、新たな制限を記述しなければなりません。現在指定可能な最大の制限を指定するために -1 を使うことができます。

無効なリソースが指定された場合、ソフトリミットの値がハードリミットの値を超えている場合、プロセスが (スーパユーザの有効な UID を持っていない状態で) ハードリミットを引き上げようとした場合には ValueError が送出されます。背後のシステムコールが予期せず失敗した場合には error が送出される可能性もあります。

以下のシンボルは、後に述べる関数 setrlimit() および getrlimit() を使って消費量を制御することができるリソースを定義しています。これらのシンボルの値は、C プログラムで使われているシンボルと全く同じです。

getrlimit(2) の Unix マニュアルページには、指定可能なリソースが列挙されています。全てのシステムで同じシンボルが使われているわけではなく、また同じリソースを表すために同じ値が使われているとも限らないので注意してください。このモジュールはプラットフォーム間の相違を隠蔽しようとはしていません — あるプラットフォームで定義されていないシンボルは、そのプラットフォーム向けの本モジュールでは利用することができません。

resource.RLIMIT_CORE

現在のプロセスが生成できるコアファイルの最大 (バイト) サイズです。プロセスの全体イメージを入れるためにこの値より大きなサイズのコアファイルが要求された結果、部分的なコアファイルが生成される可能性があります。

resource.RLIMIT_CPU

プロセッサが利用することができる最大プロセッサ時間 (秒) です。この制限を超えた場合、 SIGXCPU シグナルがプロセスに送られます。 (どのようにしてシグナルを捕捉したり、例えば開かれているファイルをディスクにフラッシュするといった有用な処理を行うかについての情報は、 signal モジュールのドキュメントを参照してください)

resource.RLIMIT_FSIZE

プロセスが生成できるファイルの最大サイズです。マルチスレッドプロセスの場合、この値は主スレッドのスタックにのみ影響します。

resource.RLIMIT_DATA

プロセスのヒープの最大 (バイト) サイズです。

resource.RLIMIT_STACK

現在のプロセスのコールスタックの最大 (バイト) サイズです。

resource.RLIMIT_RSS

プロセスが取りうる最大 RAM 常駐ページサイズ (resident set size) です。

resource.RLIMIT_NPROC

現在のプロセスが生成できるプロセスの上限です。

resource.RLIMIT_NOFILE

現在のプロセスが開けるファイル記述子の上限です。

resource.RLIMIT_OFILE

RLIMIT_NOFILE の BSD での名称です。

resource.RLIMIT_MEMLOCK

メモリ中でロックできる最大アドレス空間です。

resource.RLIMIT_VMEM

プロセスが占有できるマップメモリの最大領域です。

resource.RLIMIT_AS

アドレス空間でプロセスが占有できる最大領域 (バイト) です。

35.13.2. リソースの使用状態

以下の関数はリソース使用情報を取得するために使われます:

resource.getrusage(who)

この関数は、 who 引数で指定される、現プロセスおよびその子プロセスによって消費されているリソースを記述するオブジェクトを返します。 who 引数は以下に記述される RUSAGE_* 定数のいずれかを使って指定します。

返される値の各フィールドはそれぞれ、個々のシステムリソースがどれくらい使用されているか、例えばユーザモードでの実行に費やされた時間やプロセスが主記憶からスワップアウトされた回数、を示しています。幾つかの値、例えばプロセスが使用しているメモリ量は、内部時計の最小単位に依存します。

以前のバージョンとの互換性のため、返される値は 16 要素からなるタプルとしてアクセスすることもできます。

戻り値のフィールド ru_utime および ru_stime は浮動小数点数で、それぞれユーザモードでの実行に費やされた時間、およびシステムモードでの実行に費やされた時間を表します。それ以外の値は整数です。これらの値に関する詳しい情報は getrusage(2) を調べてください。以下に簡単な概要を示します:

インデクス | フィールド名 | リソース
0 | ru_utime | ユーザモード実行時間 (float)
1 | ru_stime | システムモード実行時間 (float)
2 | ru_maxrss | 最大常駐ページサイズ
3 | ru_ixrss | 共有メモリサイズ
4 | ru_idrss | 非共有メモリサイズ
5 | ru_isrss | 非共有スタックサイズ
6 | ru_minflt | I/O を必要としないページフォールト数
7 | ru_majflt | I/O を必要とするページフォールト数
8 | ru_nswap | スワップアウト回数
9 | ru_inblock | ブロック入力操作数
10 | ru_oublock | ブロック出力操作数
11 | ru_msgsnd | 送信メッセージ数
12 | ru_msgrcv | 受信メッセージ数
13 | ru_nsignals | 受信シグナル数
14 | ru_nvcsw | 自発的な実行コンテキスト切り替え数
15 | ru_nivcsw | 非自発的な実行コンテキスト切り替え数

この関数は無効な who 引数を指定した場合には ValueError を送出します。また、異常が発生した場合には error 例外が送出される可能性があります。

バージョン 2.3 で変更: 各値を返されたオブジェクトの属性としてアクセスできるようにしました.

resource.getpagesize()

システムページ内のバイト数を返します。(ハードウェアページサイズと同じとは限りません。) この関数はプロセスが使用しているメモリのバイト数を決定する上で有効です。 getrusage() が返すタプルの 3 つ目の要素はページ数で数えたメモリ使用量です; ページサイズを掛けるとバイト数になります。

以下の RUSAGE_* シンボルはどのプロセスの情報を提供させるかを指定するために関数 getrusage() に渡されます。

resource.RUSAGE_SELF

RUSAGE_SELF はプロセス自体に属する情報を要求するために使われます。

resource.RUSAGE_CHILDREN

getrusage() に渡すと呼び出し側プロセスの子プロセスのリソース情報を要求します。

resource.RUSAGE_BOTH

getrusage() に渡すと現在のプロセスおよび子プロセスの両方が消費しているリソースを要求します。全てのシステムで利用可能なわけではありません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.14. nis — Sun の NIS (Yellow Pages) へのインタフェース

nis モジュールは複数のホストを集中管理する上で便利な NIS ライブラリを薄くラップします。

NIS は Unix システム上にしかないので、このモジュールは Unix でしか利用できません。

nis モジュールでは以下の関数を定義しています:

nis.match(key, mapname[, domain=default_domain])

mapname 中で key に一致するものを返すか、見つからない場合にはエラー (nis.error) を送出します。両方の引数とも文字列で、 key は 8 ビットクリーンです。返される値は (NULL その他を含む可能性のある) 任意のバイト列です。

mapname は他の名前の別名になっていないか最初にチェックされます。

バージョン 2.5 で変更: domain 引数で参照するNISドメインをオーバーライドできます。設定されない場合にはデフォルトのNISドメインを参照します。

nis.cat(mapname[, domain=default_domain])

match(key, mapname)==value となる key を value に対応付ける辞書を返します。辞書内のキーと値は共に任意のバイト列なので注意してください。

mapname は他の名前の別名になっていないか最初にチェックされます。

バージョン 2.5 で変更: domain 引数で参照するNISドメインをオーバーライドできます。設定されない場合にはデフォルトのNISドメインを参照します。

nis.maps()

有効なマップのリストを返します。

nis.get_default_domain()

システムのデフォルトNISドメインを返します。

バージョン 2.5 で追加.

nis モジュールは以下の例外を定義しています:

exception nis.error

NIS 関数がエラーコードを返した場合に送出されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.15. syslog — Unix syslog ライブラリルーチン群

このモジュールでは Unix syslog ライブラリルーチン群へのインタフェースを提供します。 syslog の便宜レベルに関する詳細な記述は Unix マニュアルページを参照してください。

このモジュールはシステムの syslog ファミリのルーチンをラップしています。 syslog サーバーと通信できる pure Python のライブラリが、 logging.handlers モジュールの SysLogHandler にあります。

このモジュールでは以下の関数を定義しています:

syslog.syslog([priority], message)

文字列 message をシステムログ機構に送信します。末尾の改行文字は必要に応じて追加されます。各メッセージは facility および level からなる優先度でタグ付けされます。オプションの priority 引数はメッセージの優先度を定義します。標準の値は LOG_INFO です。 priority 中に、便宜レベルが (LOG_INFO | LOG_USER のように) 論理和を使ってコード化されていない場合、 openlog() を呼び出した際の値が使われます。

syslog() が呼び出される前に openlog() が呼び出されなかった場合、 openlog() が引数なしで呼び出されます。

syslog.openlog([ident[, logopt[, facility]]])

openlog() 関数を呼び出すことで以降の syslog() の呼び出しに対するログオプションを設定することができます。ログがまだ開かれていない状態で syslog() を呼び出すと openlog() が引数なしで呼び出されます。

オプションの ident キーワード引数は全てのメッセージの先頭に付く文字列で、デフォルトでは sys.argv[0] から前方のパス部分を取り除いたものです。

オプションの logopt キーワード引数 (デフォルトは 0) はビットフィールドです。組み合わせられる値については下記を参照してください。

オプションの facility キーワード引数 (デフォルトは LOG_USER) は明示的に facility が encode されていないメッセージに設定される facility です。

syslog.closelog()

syslog モジュールの値をリセットし、システムライブラリの closelog() を呼び出します。

この関数を呼ぶと、モジュールが最初に import されたときと同じようにふるまいます。例えば、(openlog() を呼び出さないで) syslog() を最初に呼び出したときに、 openlog() が呼び出され、 ident やその他の openlog() の引数はデフォルト値にリセットされます。

syslog.setlogmask(maskpri)

優先度マスクを maskpri に設定し、以前のマスク値を返します。 maskpri に設定されていない優先度レベルを持った syslog() の呼び出しは無視されます。標準では全ての優先度をログ出力します。関数 LOG_MASK(pri) は個々の優先度 pri に対する優先度マスクを計算します。関数 LOG_UPTO(pri) は優先度 pri までの全ての優先度を含むようなマスクを計算します。

このモジュールでは以下の定数を定義しています:

優先度 (高い優先度順):

LOG_EMERG 、 LOG_ALERT 、 LOG_CRIT 、 LOG_ERR 、 LOG_WARNING 、 LOG_NOTICE 、 LOG_INFO 、 LOG_DEBUG 。

便宜レベル:

LOG_KERN 、 LOG_USER 、 LOG_MAIL 、 LOG_DAEMON 、 LOG_AUTH 、 LOG_LPR 、 LOG_NEWS 、 LOG_UUCP 、 LOG_CRON 、および LOG_LOCAL0 から LOG_LOCAL7 。

ログオプション:

<syslog.h> で定義されている場合、 LOG_PID 、 LOG_CONS 、 LOG_NDELAY 、 LOG_NOWAIT 、および LOG_PERROR 。

35.15.1. 例

35.15.1.1. シンプルな例

1つ目のシンプルな例:

import syslog

syslog.syslog('Processing started')
if error:
    syslog.syslog(syslog.LOG_ERR, 'Processing started')

いくつかのログオプションを設定する例。ログメッセージにプロセスIDを含み、メッセージをメールのログ用の facility にメッセージを書きます。

syslog.openlog(logopt=syslog.LOG_PID, facility=syslog.LOG_MAIL)
syslog.syslog('E-mail processing initiated...')

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

35. Unix 固有のサービス »

35.16. commands — コマンド実行ユーティリティ

バージョン 2.6 で撤廃: commands モジュールは Python 3.0 で削除されました。代わりに subprocess モジュールを使ってください。

commands は、システムへコマンド文字列を渡して実行する os.popen() のラッパー関数を含んでいるモジュールです。外部で実行したコマンドの結果や、その終了ステータスを扱います。

subprocess がプロセスを生成してその結果を取得するためのより強力な手段を提供しています。 subprocess モジュールを使う方が commands モジュールを使うより好ましいです。

ノート

Python 3.x において、 getstatus() および二つの隠し関数(mk2arg() と mkarg()) は削除されました。また、 getstatusoutput() と getoutput() は subprocess モジュールに移動されました。

commands モジュールは以下の関数を定義しています。

commands.getstatusoutput(cmd)

文字列 cmd を os.popen() を使いシェル上で実行し、タプル (status, output) を返します。実際には { cmd; } 2>&1 と実行されるため、標準出力とエラー出力が混合されます。また、出力の最後の改行文字は取り除かれます。コマンドの終了ステータスはC言語関数の wait() の規則に従って解釈することができます。

commands.getoutput(cmd)

getstatusoutput() に似ていますが、終了ステータスは無視され、コマンドの出力のみを返します。

commands.getstatus(file)

ls -ld file の出力を文字列で返します。この関数は getoutput() を使い、引数内のバックスラッシュ記号「\」とドル記号「$」を適切にエスケープします。

バージョン 2.6 で撤廃: この関数は明らかでないですし役立たずです。名前も getstatusoutput() の前では誤解を招くものです。

例:

>>> import commands
>>> commands.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> commands.getstatusoutput('cat /bin/junk')
(256, 'cat: /bin/junk: No such file or directory')
>>> commands.getstatusoutput('/bin/junk')
(256, 'sh: /bin/junk: not found')
>>> commands.getoutput('ls /bin/ls')
'/bin/ls'
>>> commands.getstatus('/bin/ls')
'-rwxr-xr-x  1 root        13352 Oct 14  1994 /bin/ls'

参考

subprocess モジュール

サブプロセスの生成と管理のためのモジュール。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス

この章では Mac OS X プラットフォームでのみ利用可能なモジュールについて説明します。

さらに多くのモジュールについて MacPython OSA モジュール や 文書化されていない Mac OS モジュールも参照してください。また HOWTO の Macintosh で Python を使う は Mac 固有の Python プログラミングについての一般的な入門編になっています。

ノート

これらのモジュールは廃止され Python 3.x では削除されました。

36.1. ic — Mac OS X インターネット設定へのアクセス

36.1.1. IC オブジェクト

36.2. MacOS — Mac OS インタプリタ機能へのアクセス

36.3. macostools — ファイル操作を便利にするルーチン集

36.4. findertools — finder のApple Eventsインターフェース

36.5. EasyDialogs — 基本的な Macintosh ダイアログ

36.5.1. プログレスバーオブジェクト

36.6. FrameWork — 対話型アプリケーション・フレームワーク

36.6.1. アプリケーションオブジェクト

36.6.2. ウィンドウオブジェクト

36.6.3. コントロールウィンドウオブジェクト

36.6.4. スクロールウィンドウオブジェクト

36.6.5. ダイアログウィンドウオブジェクト

36.7. autoGIL — イベントループ中のグローバルインタープリタの取り扱い

36.8. Mac OS ツールボックスモジュール

36.8.1. Carbon.AE — Apple Events

36.8.2. Carbon.AH — Apple ヘルプ

36.8.3. Carbon.App — アピアランスマネージャ

36.8.4. Carbon.Appearance — Appearance Manager 定数

36.8.5. Carbon.CF — Core Foundation

36.8.6. Carbon.CG — Core Graphics

36.8.7. Carbon.CarbonEvt — Carbon Event Manager

36.8.8. Carbon.CarbonEvents — Carbon Event Manager 定数

36.8.9. Carbon.Cm — Component Manager

36.8.10. Carbon.Components — Component Manager constants

36.8.11. Carbon.ControlAccessor — Control Manager accssors

36.8.12. Carbon.Controls — Control Manager constants

36.8.13. Carbon.CoreFounation — CoreFounation constants

36.8.14. Carbon.CoreGraphics — CoreGraphics constants

36.8.15. Carbon.Ctl — Control Manager

36.8.16. Carbon.Dialogs — Dialog Manager constants

36.8.17. Carbon.Dlg — Dialog Manager

36.8.18. Carbon.Drag — Drag and Drop Manager

36.8.19. Carbon.Dragconst — Drag and Drop Manager constants

36.8.20. Carbon.Events — Event Manager constants

36.8.21. Carbon.Evt — Event Manager

36.8.22. Carbon.File — File Manager

36.8.23. Carbon.Files — File Manager constants

36.8.24. Carbon.Fm — Font Manager

36.8.25. Carbon.Folder — Folder Manager

36.8.26. Carbon.Folders — Folder Manager constants

36.8.27. Carbon.Fonts — Font Manager constants

36.8.28. Carbon.Help — Help Manager

36.8.29. Carbon.IBCarbon — Carbon InterfaceBuilder

36.8.30. Carbon.IBCarbonRuntime — Carbon InterfaceBuilder constants

36.8.31. Carbon.Icn — Carbon Icon Manager

36.8.32. Carbon.Icons — Carbon Icon Manager constants

36.8.33. Carbon.Launch — Carbon Launch Services

36.8.34. Carbon.LaunchServices — Carbon Launch Services constants

36.8.35. Carbon.List — List Manager

36.8.36. Carbon.Lists — List Manager constants

36.8.37. Carbon.MacHelp — Help Manager constants

36.8.38. Carbon.MediaDescr — Parsers and generators for Quicktime Media descriptors

36.8.39. Carbon.Menu — Menu Manager

36.8.40. Carbon.Menus — Menu Manager constants

36.8.41. Carbon.Mlte — MultiLingual Text Editor

36.8.42. Carbon.OSA — Carbon OSA Interface

36.8.43. Carbon.OSAconst — Carbon OSA Interface constants

36.8.44. Carbon.QDOffscreen — QuickDraw Offscreen constants

36.8.45. Carbon.Qd — QuickDraw

36.8.46. Carbon.Qdoffs — QuickDraw Offscreen

36.8.47. Carbon.Qt — QuickTime

36.8.48. Carbon.QuickDraw — QuickDraw constants

36.8.49. Carbon.QuickTime — QuickTime constants

36.8.50. Carbon.Res — Resource Manager and Handles

36.8.51. Carbon.Resources — Resource Manager and Handles constants

36.8.52. Carbon.Scrap — スクラップマネージャ

36.8.53. Carbon.Snd — Sound Manager

36.8.54. Carbon.Sound — Sound Manager constants

36.8.55. Carbon.TE — TextEdit

36.8.56. Carbon.TextEdit — TextEdit constants

36.8.57. Carbon.Win — Window Manager

36.8.58. Carbon.Windows — Window Manager constants

36.9. ColorPicker — 色選択ダイアログ

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.1. ic — Mac OS X インターネット設定へのアクセス

このモジュールでは、 システム設定 や Finder で設定したインターネット関連の設定へのアクセス機能を提供しています。

ノート

このモジュールは Python 3.x で削除されました。

このモジュールには、 icglue という低水準の関連モジュールがあり、インターネット設定への基本的なアクセス機能を提供しています。この低水準のモジュールはドキュメント化されていませんが、各ルーチンの docstring にはパラメタの説明があり、ルーチン名には Internet Config に対する Pascal や C のインタフェースと同じ名前を使っているので、このモジュールが必要な場合には標準の IC プログラマドキュメントを利用できます。

ic モジュールでは、例外 error と、インターネット設定から生じる全てのエラーコードに対するシンボル名を定義しています。詳しくはソースコードを参照してください。

exception ic.error

ic モジュール内部でエラーが生じたときに送出される例外です。

ic モジュールは以下のクラスと関数を定義しています：

class ic.IC([signature[, ic]])

インターネット設定オブジェクトを作成します。 signature は、IC の設定に影響を及ぼす可能性のある現在のアプリケーションを表す 4 文字のクリエータコード (デフォルトは 'Pyth') です。オプションの引数 ic は低水準モジュールであらかじめ作成しておいた icglue.icinstance で、別の設定ファイルなどから設定を得る場合に便利です。

ic.launchurl(url[, hint])

ic.parseurl(data[, start[, end[, hint]]])

ic.mapfile(file)

ic.maptypecreator(type, creator[, filename])

ic.settypecreator(file)

これらの関数は、後述する同名のメソッドへの「ショートカット」です。

36.1.1. IC オブジェクト

IC オブジェクトはマップ型のインターフェースを持っているので、メールアドレスの取得は単に ic['MailAddress'] でできます。値の代入もでき、設定ファイルのオプションを変更できます。

このモジュールは各種のデータ型を知っていて、IC内部の表現を「論理的な」 Python データ構造に変換します。 ic モジュールを単体で実行すると、テストプログラムが実行されて IC データベースにある全てのキーと値のペアをリスト表示するので、文書代わりになります。

モジュールがデータの表現方法を推測できなかった場合、 data 属性に生のデータが入った ICOpaqueData 型のインスタンスを返します。この型のオブジェクトも代入に利用できます。

IC には辞書型のインターフェースの他にも以下のようなメソッドがあります。

IC.launchurl(url[, hint])

与えられたURLを解析し、適切なアプリケーションを起動してURLを渡します。省略可能な hint は、 'mailto:' などのスキーム名で、不完全なURLはこのスキームにあわせて補完します。 hint を指定していない場合、不完全なURLは無効になります。

IC.parseurl(data[, start[, end[, hint]]])

data の中からURLを検索し、URLの開始位置、終了位置、URLそのものを返します。オプションの引数 start と end を使うと検索範囲を制限できます。例えば、ユーザーが長いテキストフィールドをクリックした場合に、このルーチンにテキストフィールド全体とクリック位置 start を渡すことで、ユーザーがクリックした場所にある URL 全体を返させられます。先に述べたように、 hint はオプションで、不完全なURLを補完するためのスキームです。

IC.mapfile(file)

file に対するマッピングエントリを返します。 file にはファイル名か FSSpec() の戻り値を渡せます。実在しないファイルであってもかまいません。

マッピングエントリは (version, type, creator, postcreator, flags, extension, appname, postappname, mimetype, entryname) からなるタプルで返されます。 version はエントリーのバージョン番号、 type は4文字のファイルタイプ、 creator は 4 文字のクリエータタイプ、 postcreator はファイルのダウンロード後にオプションとして起動され、後処理を行うアプリケーションの 4 文字のクリエータコードです。 flags は、転送をバイナリで行うかアスキーで行うか、などの様々なフラグビットからなる値です。 extension はこのファイルタイプに対するファイル名の拡張子、 appname はファイルが属するアプリケーションの印字可能な名前、 postappname は後処理用アプリケーション、 mimetype はこのファイルのMIMEタイプ、最後の entryname はこのエントリの名前です。

IC.maptypecreator(type, creator[, filename])

4文字の type と creator コードを持つファイルに対するマッピングエントリを返します。(クリエータが '????' であるような場合に) 正しいエントリが見つかりやすいようにオプションの filename を指定できます。

マッピングエントリーは mapfile と同じフォーマットで返されます。

IC.settypecreator(file)

実在のファイル file に対して、拡張子に基づいて適切なクリエータとタイプを設定します。 file の指定は、ファイル名でも FSSpec() の戻り値でもかまいません。変更は Finder に通知されるので、Finder 上のアイコンは即座に更新されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.2. MacOS — Mac OS インタプリタ機能へのアクセス

このモジュールは、Python インタプリタ内の MacOS 固有の機能に対するアクセスを提供します。例えば、インタプリタのイベントループ関数などです。十分注意して利用してください。

ノート

このモジュールは Python 3.x で削除されました。

モジュール名が大文字で始まることに注意してください。これは昔からの約束です。

MacOS.runtimemodel

Python 2.4 以降は常に 'macho' です。それより前のバージョンの Python では、古い Mac OS 8 ランタイムモデルの場合は 'ppc' 、 Mac OS 9 ランタイムモデルの場合は 'carbon' となります。

MacOS.linkmodel

インタープリタがどのような方法でリンクされているかを返します。拡張モジュールがリンクモデル間で非互換性かもしれない場合、パッケージはより多くの適切なエラーメッセージを伝えるためにこの情報を使用することができます。値は静的リンクした Python は 'static' 、Mac OS X framework で構築した Python は 'framework' 、標準の Unix 共有ライブラリ (shared library)で構築された Python は 'shared' となります。古いバージョンの Python の場合、Mac OS 9 互換の Python では 'cfm' となります。

exception MacOS.Error

MacOS でエラーがあると、このモジュールの関数か、Mac 固有なツールボックスインターフェースモジュールから、この例外が生成されます。引数は、整数エラーコード(OSErr 値)とテキストで記述されたエラーコードです。分かっている全てのエラーコードのシンボル名は、標準モジュール macerrors で定義されています。

MacOS.GetErrorString(errno)

MacOSのエラーコード errno のテキスト表現を返します。

MacOS.DebugStr(message[, object])

Mac OS X上では、文字列を単純に標準出力に送ります (古いバージョンの Mac OSでは、より複雑な機能が使用できました)。しかし、低水準のデバッガ (gdb など) 用にブレークポイントを設定する場所も適切に用意しています。

ノート

64ビットモードでは使用できません。

MacOS.SysBeep()

ベルを鳴らします。

ノート

64ビットモードでは使用できません。

MacOS.GetTicks()

システム起動時からのチック数(clock ticks、1/60秒)を得ます。

MacOS.GetCreatorAndType(file)

2つの4文字の文字列としてファイルクリエータおよびファイルタイプを返します。 file 引数はパスもしくは、 FSSpec 、 FSRef オブジェクトを与える事ができます。

ノート

FSSpec は64ビットモードでは使うことができません。

MacOS.SetCreatorAndType(file, creator, type)

ファイルクリエータおよびファイルタイプを設定します。 file 引数はパスもしくは、 FSSpec 、 FSRef オブジェクトを与える事ができます。 creator と type は4文字の文字列が必要です。

ノート

FSSpec は64ビットモードでは使うことができません。

MacOS.openrf(name[, mode])

ファイルのリソースフォークを開きます。引数は組み込み関数 open() と同じです。返されたオブジェクトはファイルのように見えるかもしれませんが、これは Python のファイルオブジェクトではありませんので扱いに微妙な違いがあります。

MacOS.WMAvailable()

現在のプロセスが動作しているウィンドウマネージャにアクセスします。例えば、Mac OS X サーバー上、あるいは SSH でログインしている、もしくは現在のインタープリタがフルブローンアプリケーションバンドル(fullblown application bundle)から起動されていない場合などのような、ウィンドウマネージャが存在しない場合は False を返します。

MacOS.splash([resourceid])

リソース id でスプラッシュスクリーンを開きます。スプラッシュスクリーンを閉じるには resourceid 0 を使います。

ノート

64ビットモードでは使用できません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.3. macostools — ファイル操作を便利にするルーチン集

このモジュールには、Macintosh 上でのファイル操作を便利にするためのルーチンがいくつか入っています。全てファイルパラメタは、パス名か FSRef または FSSpec オブジェクトで指定できます。このモジュールは、リソースフォークつきファイル (forked file) をサポートするファイルシステムを想定しているので、UFS パーティションに使ってはなりません。

ノート

このモジュールは Python 3.0 で削除されました。

macostools モジュールでは以下の関数を定義しています。

macostools.copy(src, dst[, createpath[, copytimes]])

ファイル src を dst へコピーします。 createpath が真なら、必要に応じて dst に至るまでのフォルダを作成します。このメソッドはデータとリソースフォーク、そしていくつかのファインダ情報 (クリエータ、タイプ、フラグ) をコピーします。オプションの copytypes を指定すると、作成日、修正日、バックアップ日の情報のコピー (デフォルトではコピーします) を制御できます。カスタムアイコン、コメント、アイコン位置はコピーされません。

ノート

この関数は 64 bit モードで利用できない API を使用するので、 64 bit のコードでは動きません。

macostools.copytree(src, dst)

src から dst へ再帰的にファイルのツリーをコピーします。必要に応じてフォルダを作成してゆきます。 src と dst はパス名で指定しなければなりません。

ノート

この関数は 64 bit モードで利用できない API を使用するので、 64 bit のコードでは動きません。

macostools.mkalias(src, dst)

src を示すファインダエイリアス dst を作成します。

ノート

この関数は 64 bit モードで利用できない API を使用するので、 64 bit のコードでは動きません。

macostools.touched(dst)

ファイル dst のクリエータやタイプなどのファインダ情報が変わったことをファインダに知らせます。ファイルはパス名か FSSpec で指定できます。この呼び出しは、ファインダにアイコンを再描画させるよう命令します。

バージョン 2.6 で撤廃: この関数は OS X では no-op です。

macostools.BUFSIZ

copy に用いるバッファサイズで、デフォルトは 1 メガバイトです。

Apple のドキュメントでは、ファインダエイリアスの作成プロセスを規定していません。そのため、 mkalias() で作成したエイリアスが互換性のない振る舞いをする可能性があるので注意してください。

36.4. findertools — finder のApple Eventsインターフェース

このモジュールのルーチンを使うと、Python プログラムからファインダが持ついくつかの機能へアクセスできます。これらの機能はファインダへの AppleEvent インタフェースのラッパとして実装されています。全てのファイルとフォルダのパラメータは、フルパス名、あるいは FSRef か FSSpec オブジェクトで指定できます。

findertools モジュールは以下の関数を定義しています。

findertools.launch(file)

ファインダに file を起動するように命令します。起動が意味するものは file に依存します。アプリケーションなら起動しますし、フォルダなら開かれ、文書なら適切なアプリケーションで開かれます。

findertools.Print(file)

ファインダにファイルを印刷するよう命令します。実際の動作はファイルを選択し、ファインダのファイルメニューから印刷コマンドを使うのと同じです。

findertools.copy(file, destdir)

ファインダにファイルかフォルダである file をフォルダ destdir にコピーするよう命令します。この関数は新しいファイルを示す Alias オブジェクトを返します。

findertools.move(file, destdir)

ファインダにファイルかフォルダである file をフォルダ destdir に移動するように命令します。この関数は新しいファイルを示す Alias オブジェクトを返します。

findertools.sleep()

マシンがサポートしていれば、ファインダに Macintosh をスリープさせるよう命令します。

findertools.restart()

ファインダに、マシンを適切に再起動するよう命令します。

findertools.shutdown()

ファインダに、マシンを適切にシャットダウンするよう命令します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.5. EasyDialogs — 基本的な Macintosh ダイアログ

EasyDialogs モジュールには、Macintosh で単純なダイアログ操作を行うためのルーチンが入っています。ダイアログはドックに現れる別のアプリケーションとして起動され、ダイアログが表示されるにはクリックされなければなりません。全てのルーチンは、オプションとしてリソース ID パラメタ id をとります。デフォルトの DLOG のリソース (タイプとアイテムナンバの両方) が一致するようなダイアログがあれば、 id を使ってダイアログ操作に使われるダイアログオブジェクト情報を上書きできます。詳細はソースコードを参照してください。

EasyDialogs モジュールでは以下の関数を定義しています。

ノート

このモジュールは Python 3.x では削除されます。

EasyDialogs.Message(str[, id[, ok]])

メッセージテキスト str 付きのモーダルダイアログを表示します。テキストの長さは最大255文字です。ボタンのテキストはデフォルトでは”OK”ですが、文字列の引数 ok を指定して変更できます。ユーザが”OK”ボタンをクリックすると処理を戻します。

EasyDialogs.AskString(prompt[, default[, id[, ok[, cancel]]]])

ユーザに文字列値の入力を促すモーダルダイアログを表示します。 prompt はプロンプトメッセージで、オプションの default 引数は入力文字列の初期値です（指定しなければ "" を使います)。 “OK”と”Cancel”ボタンの文字列は ok と cancel の引数で変更できます。文字列の長さは全て最大255文字です。入力された文字列か、ユーザがキャンセルした場合には None を返します。

EasyDialogs.AskPassword(prompt[, default[, id[, ok[, cancel]]]])

ユーザに文字列値の入力を促すモーダルダイアログを表示します。 AskString() に似ていますが、ユーザの入力したテキストは点で表示されます。引数は AskString() のものと同じ意味です。

EasyDialogs.AskYesNoCancel(question[, default[, yes[, no[, cancel[, id]]]]])

プロンプト question と”Yes”、”No”、”Cancel”というラベルの3つボタンが付いたダイアログを表示します。ユーザが”Yes”を押した場合には 1 を、”No” ならば 0 を、 “Cancel” ならば -1 を返します。 RETURN キーを押した場合は default の値 (default を指定しない場合は 0)を返します。ボタンのテキストはそれぞれ引数 yes 、 no 、 cancel で変更できます。ボタンを表示したくなければ引数に "" を指定します。

EasyDialogs.ProgressBar([title[, maxval[, label[, id]]]])

プログレスバー付きのモードレスダイアログを表示します。これは後で述べる ProgressBar クラスのコンストラクタです。 title はダイアログに表示するテキスト文字列 (デフォルトの値は “Working...”) で、 maxval は処理が完了するときの値です (デフォルトは 0 で、残りの作業量が不確定であることを示します)。 label はプログレスバー自体の上に表示するテキストです。

EasyDialogs.GetArgv([optionlist[ commandlist[, addoldfile[, addnewfile[, addfolder[, id]]]]]])

コマンドライン引数リストの作成を補助するためのダイアログを表示します。得られた引数リストを sys.argv の形式にします。これは getopt.getopt() の引数として渡すのに適した形式です。 addoldfile 、 addnewfile 、 addfolder はブール型の引数です。これらの引数が真の場合、それぞれ実在のファイル、まだ (おそらく) 存在しないファイル、フォルダへのパスをコマンドラインのパスとして設定できます。 (注意: getopt.getopt() がファイルやフォルダ引数を認識できるようにするためには、オブションの引数がそれらより前に現れるようにしなければなりません。) 空白を含む引数は、空白をシングルクォートあるいはダブルクォートで囲んで指定できます。

ユーザが”Cancel”ボタンを押した場合、 SystemExit 例外を送出します。

optionlist には、ポップアップメニューで選べる選択肢を定義したリストを指定します。ポップアップメニューの要素には、次の2つの形式、 optstr または (optstr, descr) があります。 descr に短い説明文字列を指定すると、該当の選択肢をポップアップメニューで選択しいる間その文字列をダイアログに表示します。 optstr とコマンドライン引数の対応を以下に示します:

optstr format | Command-line format
x | -x (短いオプション)
x: あるいは x= | -x (値を持つ短いオプション)
xyz | --xyz (長いオプション)
xyz: あるいは xyz= | --xyz (値を持つ長いオプション)

commandlist は cmdstr あるいは (cmdstr, descr) の形のアイテムからなるリストです。 descr は上と同じです。 cmdstr はポップアップメニューに表示されます。メニューを選択すると cmdstr はコマンドラインに追加されますが、それに続く ':' や '=' は (存在していれば) 取り除かれます。

バージョン 2.0 で追加.

EasyDialogs.AskFileForOpen( [message] [, typeList] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, eventProc] [, previewProc] [, filterProc] [, wanted] )

どのファイルを開くかをユーザに尋ねるダイアログを表示し、ユーザが選択したファイルを返します。ユーザがダイアログをキャンセルした場合には None を返します。 message はダイアログに表示するテキストメッセージです。 typeList は選択できるファイルタイプを表す 4 文字の文字列からなるリスト、 defaultLocation は最初に表示すルフォルダで、パス名、 FSSpec あるいは FSRef で指定します。 location はダイアログを表示するスクリーン上の位置 (x, y) です。 actionButtonLabel はOKボタンの位置に”Open”の代わりに表示する文字列、 cancelButtonLabel は”Cancel”ボタンの位置に”Cancel”の代わりに表示する文字列です。 wanted は返したい値のタイプで、 str 、 unicode 、 FSSpec 、 FSRef およびそれらのサブタイプを指定できます。

その他の引数の説明についてはApple Navigation Servicesのドキュメントと EasyDialogs のソースコードを参照してください。

EasyDialogs.AskFileForSave( [message] [, savedFileName] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, fileType] [, fileCreator] [, eventProc] [, wanted] )

保存先のファイルをユーザに尋ねるダイアログを表示して、ユーザが選択したファイルを返します。ユーザがダイアログをキャンセルした場合には None を返します。 savedFileName は保存先のファイル名 (戻り値) のデフォルト値です。その他の引数の説明については AskFileForOpen() を参照してください。

EasyDialogs.AskFolder( [message] [, defaultLocation] [, defaultOptionFlags] [, location] [, clientName] [, windowTitle] [, actionButtonLabel] [, cancelButtonLabel] [, preferenceKey] [, popupExtension] [, eventProc] [, filterProc] [, wanted] )

フォルダの選択をユーザに促すダイアログを表示して、ユーザが選択したフォルダを返します。ユーザがダイアログをキャンセルした場合には None を返します。引数についての説明は AskFileForOpen() を参照してください。

参考

Navigation Services Reference [http://developer.apple.com/documentation/Carbon/Reference/Navigation_Services_Ref/]

Programmer’s reference documentation の Carbon framework の Navigation Services の項。

36.5.1. プログレスバーオブジェクト

ProgressBar オブジェクトでは、モードレスなプログレスバーダイアログのサポートを提供しています。定量プログレスバー (温度計スタイル) と不定量プログレスバー (床屋の螺旋看板スタイル) がサポートされています。プログレスバーの最大値がゼロ以上の場合には定量インジケータに、そうでない場合は不定量インジケータになります。

バージョン 2.2 で変更: 不定量プログレスバーのサポートを追加しました。

ダイアログは作られるとすぐに表示されます。ダイアログの”Cancel”ボタンを押すか、 Cmd-. (コマンドキーを押しながらピリオド('.')を押す) か、あるいは ESC をタイプすると、ダイアログウィンドウを非表示にして KeyboardInterrupt を送出します (ただし、この応答は次にプログレスバーを更新するときまで、すなわち次に inc() または set() を呼び出してダイアログを更新するまで発生しません) 。それ以外の場合、プログレスバーは ProgressBar オブジェクトを廃棄するまで表示されたままになります。

ProgressBar オブジェクトには以下の属性とメソッドがあります。

ProgressBar.curval

プログレスバーの現在の値 (整数型あるいは長整数型) です。プログレスバーの通常のアクセスのメソッドによって curval を 0 と maxval の間にします。この属性を直接変更してはなりません。

ProgressBar.maxval

プログレスバーの最大値　(整数型あるいは長整数型) です; プログレスバー (温度計, thermometer) では、 curval が maxval に等しい時に全量に到達します。 maxval が 0 の場合、不定量プログレスバー (床屋の螺旋看板, barbar pole) になります。この属性を直接変更してはなりません。

ProgressBar.title([newstr])

プログレスダイアログのタイトルバーのテキストを newstr に設定します。

ProgressBar.label([newstr])

プログレスダイアログ中のプログレスボックスのテキストを newstr に設定します。

ProgressBar.set(value[, max])

プログレスバーの現在値 curval を value に設定します。 max も指定した場合、 maxval を max にします。 value は前もって 0 と maxval の間になるよう強制的に設定されます。温度計バーの場合、変更内容を反映するよう表示を更新します。変更によって定量プログレスバーから不定量プログレスバーへ、あるいはその逆への推移が起こります。

ProgressBar.inc([n])

プログレスバーの curval を n だけ増やします。 n を指定しなければ 1 だけ増やします。 (n は負にもでき、その場合は curval を減少させます。) 変更内容を反映するようプログレスバーの表示を更新します。プログレスバーが不定量プログレスバーの場合、床屋の螺旋看板 (barbar pole) 模様を 1 度「回転」させます。増減によって curval が 0 から maxval までの範囲を越えた場合、 0 と maxval の範囲に収まるよう強制的に値を設定します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.6. FrameWork — 対話型アプリケーション・フレームワーク

FrameWork モジュールは、対話型 Macintosh アプリケーションのクラスで、同時にフレームワークを提供します。プログラマは、サブクラスを作って基底クラスの様々なメソッドをオーバーライドし、必要な機能を実装することでアプリケーションを組み立てられます。機能のオーバーライドは、時によって様々な異なるレベルで行われます。つまり、ある一つのダイアログウィンドウでクリックの処理を普段と違う方法で行うには、完全なイベント処理をオーバーライドする必要はありません。

ノート

このモジュールは Python 3.x では削除されました。

FrameWork の開発は事実上停止しています。現在では PyObjC を使用すれば Python から Cocoa の全機能を使用することができます。このドキュメントでは最も重要な機能だけしか記述していませんし、それさえも論理的な形で書かれてもいません。ソースか例題を詳しく見てください。次にあげるのは、MacPython ニュースグループにポストされたコメントで、 FrameWork の強力さと限界について述べています。

FrameWork の最大の強みは、制御の流れをたくさんの異なる部分に分割できることです。例えば W を使って、いろいろな方法でメニューをオン/オフしたり、残りをいじらずにうまくプラグインさせることができます。 FrameWork の弱点は、コマンドインタフェースが抽象化されていないこと(といっても難しいわけではないですが)、ダイアログサポートが最低限しかないこと、それからコントロール/ツールバーサポートが全くないことです。

FrameWork モジュールは次の関数を定義しています。

FrameWork.Application()

アプリケーション全体を表現しているオブジェクト。メソッドについての詳細は以下の記述を参照してください。デフォルト __init__() ルーチンは、空のウィンドウ辞書とアップルメニューつきのメニューバーを作成します。

FrameWork.MenuBar()

メニューバーを表現するオブジェクト。このオブジェクトは普通はユーザは作成しません。

FrameWork.Menu(bar, title[, after])

メニューを表現するオブジェクト。生成時には、メニューが現われる MenuBar と、 title 文字列、メニューが表示されるべき(1から始まる)位置 after (デフォルトは末尾)を渡します。

FrameWork.MenuItem(menu, title[, shortcut, callback])

メニューアイテムオブジェクトを作成します。引数は作成するメニューと、アイテムのタイトル文字列、オプションのキーボードショートカット、コールバックルーチンです。コールバックは、メニューID、メニュー内のアイテム番号(1から数える)、現在のフロントウィンドウ、イベントレコードを引数に呼ばれます。

呼び出し可能なオブジェクトのかわりに、コールバックは文字列でも良いです。この場合、メニューの選択は、最前面のウィンドウとアプリケーションの中でメソッド探索を引き起こします。メソッド名は、コールバック文字列の前に 'domenu_' を付けたものです。

MenuBar の fixmenudimstate() メソッドを呼びだすと、現在のフロントウィンドウにもとづいて、適切なディム化を全てのメニューアイテムに対してほどこします。

FrameWork.Separator(menu)

メニューの最後にセパレータを追加します。

FrameWork.SubMenu(menu, label)

label の名前のサブメニューを、メニュー menu の下に作成します。メニューオブジェクトが返されます。

FrameWork.Window(parent)

(モードレス)ウィンドウを作成します。 Parent は、ウィンドウが属するアプリケーションオブジェクトです。作成されたウィンドウはまだ表示されません。

FrameWork.DialogWindow(parent)

モードレスダイアログウィンドウを作成します。

FrameWork.windowbounds(width, height)

与えた幅と高さのウィンドウを作成するのに必要な、 (left, top, right, bottom) からなるタプルを返します。ウィンドウは以前のウィンドウに対して位置をずらして作成され、全体のウィンドウが画面からなるべく外れないようにします。しかし、ウィンドウはいつでも全く同じサイズで、そのため一部は画面から隠れる場合もあります。

FrameWork.setwatchcursor()

マウスカーソルを時計型に設定します。

FrameWork.setarrowcursor()

マウスカーソルを矢印型に設定します。

36.6.1. アプリケーションオブジェクト

アプリケーションオブジェクトのメソッドは各種ありますが、次のメソッドをあげておきます。

Application.makeusermenus()

アプリケーションでメニューを使う必要がある場合、このメソッドをオーバーライドします。属性 menubar にメニューを追加します。

Application.getabouttext()

このメソッドをオーバーライドすることで、アプリケーションの説明を記述するテキスト文字列を返します。代わりに、 do_about() メソッドをオーバーライドすれば、もっと凝った”アバウト”メッセージを出す事ができます。

Application.mainloop([mask[, wait]])

このルーチンがメインイベントループで、作成したアプリケーションが動き出すためにはこれを呼ぶことになります。 Mask は操作したいイベントを選択するマスクです。 wait は並行に動作しているアプリケーションに割り当てたいチック数(1/60秒)です(デフォルトで 0 ですが、あまり良い値ではありません)。 self フラグを立ててメインループを抜ける方法はまだサポートされていますが、これはお勧めできません。代わりに self._quit() を呼んでください。

イベントループは小さなパーツに分割されていて、各々をオーバーライドできるようになっています。これらのメソッドは、デフォルトでウィンドウとダイアログや、ドラッグとリサイズの操作、 AppleEvent、非FrameWorkのウィンドウに関するウィンドウの操作などに関するイベントを分岐することなどまで面倒をみてくれます。

原則として、全てのイベントハンドラは、イベントが完全に取り扱われた場合は 1 を返さなくてはいけませんし、それ以外では 0 を返さなくてはいけません(例えば、前面のウィンドウは FrameWork ウィンドウではない場合を考えてください)。こうしなくてはいけない理由は、アップデートイベントなどが Sioux コンソールウィンドウなどの他のウィンドウにきちんと渡されるようにするためです。 our_dispatch やその呼び出し元の内部から MacOS.HandleEvent() を呼んではいけません。そうしたコードが Python の内部ループのイベントハンドラを経由して呼ばれると、無限ループになりかねないからです。

Application.asyncevents(onoff)

非同期でイベント操作をしたい場合は、非ゼロの引数でこのメソッドを呼んでください。こうすることで、イベントが生じた時に、内部のインタプリタのループで、アプリケーションイベントハンドラ async_dispatch が呼ばれることになります。すると、長時間の計算を行っている場合でも、FrameWorkウィンドウがアップデートされ、ユーザーインターフェースが動き続けるようになります。ただし、インタプリタの動作が減速し、非リエントラントのコード (例えばFrameWork自身など)に奇妙な動作が見られるかもしれません。デフォルトでは async_dispatch はすぐに our_dispatch を呼びますが、このメソッドをオーバーライドすると、特定のイベントを非同期で操作しても良くなります。処理しないイベントは Sioux などに渡されることになります。

onあるいはoff値が返されます。

Application._quit()

実行中の mainloop() 呼び出しを、次の適当なタイミングで終了させます。

Application.do_char(c, event)

ユーザーが文字 c をタイプした時に呼ばれます。イベントの全詳細は event 構造体の中にあります。このメソッドはウィンドウオブジェクト内で使うためにも提供されています。このオブジェクトのウィンドウが最前面にある場合は、アプリケーション全般について本ハンドラをオーバーライドします。

Application.do_dialogevent(event)

イベントループ内部で最初に呼ばれて、モードレスダイアログイベントを処理します。デフォルトではメソッドは単にイベントを適切なダイアログに分岐するだけです(関連したダイアログウィンドウオブジェクトを経由してではありません)。特別にダイアログイベント(キーボードショートカットなど)を処理する必要がある場合にオーバーライドしてください。

Application.idle(event)

イベントが無い場合にメインイベントループから呼ばれます。 null イベントも渡されます(つまりマウス位置などを監視することができます)。

36.6.2. ウィンドウオブジェクト

ウィンドウオブジェクトは特に次のメソッドを持ちます。

Window.open()

ウィンドウを開く時はこのメソッドをオーバーライドします。Mac OS ウィンドウ ID を self.wid に入れて do_postopen() メソッドを呼ぶと、親アプリケーションにウィンドウを登録します。

Window.close()

ウィンドウを閉じるときに特別な処理をする場合はこのメソッドをオーバーライドします。親アプリケーションからウィンドウの登録を削除するには、 do_postclose() を呼びます。

Window.do_postresize(width, height, macoswindowid)

ウィンドウがリサイズされた後に呼ばれます。 InvalRect を呼び出す以外にもすることがある場合はこれをオーバーライドします。

Window.do_contentclick(local, modifiers, event)

ウィンドウのコンテント部分をユーザーがクリックすると呼ばれます。引数は位置座標(ウィンドウを基準)、キーモディファイア、生のイベントです。

Window.do_update(macoswindowid, event)

ウィンドウのアップデートイベントが受信された時に呼ばれます。ウィンドウを再描画します。

Window.do_activate(activate, event)

ウィンドウがアクティブ化(activate == 1)、非アクティブ化(activate == 0)する際に呼ばれます。フォーカスのハイライトなどを処理します。

36.6.3. コントロールウィンドウオブジェクト

コントロールウィンドウオブジェクトには Window オブジェクトのメソッドの他に次のメソッドがあります。

ControlsWindow.do_controlhit(window, control, pcode, event)

コントロール control のパートコード pcode がユーザにヒットされた場合に呼ばれます。トラッキングなどは任せておいてかまいません。

36.6.4. スクロールウィンドウオブジェクト

スクロールウィンドウオブジェクトは、次のメソッドを追加したコントロールウィンドウオブジェクトです。

ScrolledWindow.scrollbars([wantx[, wanty]])

水平スクロールバーと垂直スクロールバーを作成します(あるいは破棄します)。引数はどちらが欲しいか指定します(デフォルトは両方)。スクロールバーは常に最小値 0 、最大値 32767 です。

ScrolledWindow.getscrollbarvalues()

このメソッドは必ず作っておかなくてはいけません。現在のスクロールバーの位置を与えるタプル (x, y) を(0 の 32767 間で)返してください。バーの方向について全文書が可視状態であること知らせるため None を返す事もできます。

ScrolledWindow.updatescrollbars()

文書に変更があった場合はこのメソッドを呼びます。このメソッドは getscrollbarvalues() を呼んでスクロールバーを更新します。

ScrolledWindow.scrollbar_callback(which, what, value)

あらかじめ与えておくメソッドで、ユーザーとの対話により呼ばれます。 which は 'x' か 'y' 、 what は '-', '--', 'set', '++', '+' のどれかです。 'set' の場合は、 value に新しいスクロールバー位置を入れておきます。

ScrolledWindow.scalebarvalues(absmin, absmax, curmin, curmax)

getscrollbarvalues() の結果から値を計算するのを助ける補助的なメソッドです。文書の最小値と最大値、可視部分に関する最先頭値(最左値)と最底値(最右値)を渡すと、正しい数か None を返します。

ScrolledWindow.do_activate(onoff, event)

ウィンドウが最前面になった時、スクロールバーのディム(dimming)/ハイライトの面倒をみます。このメソッドをオーバーライドするなら、オーバーライドしたメソッドの最後でオリジナルのメソッドを呼んでください。

ScrolledWindow.do_postresize(width, height, window)

スクロールバーを正しい位置に移動させます。オーバーライドする時は、オーバーライドしたメソッドの一番最初でオリジナルのメソッドを呼んでください。

ScrolledWindow.do_controlhit(window, control, pcode, event)

スクロールバーのインタラクションを処理します。これをオーバーライドする時は、オリジナルのメソッドを最初に呼び出してください。非ゼロの返り値はスクロールバー内がヒットされたことを意味し、実際に処理が進むことになります。

36.6.5. ダイアログウィンドウオブジェクト

ダイアログウィンドウオブジェクトには、 Window オブジェクトのメソッドの他に次のメソッドがあります。

DialogWindow.open(resid)

ID resid の DLOG リソースからダイアログウィンドウを作成します。ダイアログオブジェクトは self.wid に保存されます。

DialogWindow.do_itemhit(item, event)

アイテム番号 item がヒットされた時に呼ばれます。トグルボタンなどの再描画は自分で処理してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.7. autoGIL — イベントループ中のグローバルインタープリタの取り扱い

autoGIL モジュールは、自動的にイベントループを実行する場合、 Python のグローバルインタープリタロック(Global Interpreter Lock) をロックしたり、ロックの解除をしたりするための関数 installAutoGIL() を提供します。

ノート

このモジュールは Python 3.x で削除されました。

exception autoGIL.AutoGILError

例えば現在のスレッドがループしていないなど、オブザーバにコールバックができない場合に発生します。

autoGIL.installAutoGIL()

現在のスレッドのイベントループ(CFRunLoop)中のオブザーバにコールバックを行ない、適切な時にグローバルインタープリタロック(GIL)を、イベントループが使用されていない間、他の Python スレッドの起動ができるようにロックしたり、ロックの解除をしたりします。

有効性：OS X 10.1 以降

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.8. Mac OS ツールボックスモジュール

各種の Mac OS ツールボックスへのインターフェースを与えるモジュール群があります。対応するモジュールがあるなら、そのモジュールではツールボックスで宣言された各種の構造体の Python オブジェクトが定義され、操作は定義されたオブジェクトのメソッドとして実装されています。その他の操作はモジュールの関数として実装されています。 C で可能な操作がすべて Python で可能なわけではありませんし(コールバックはよく問題になります)、パラメータがPython だと違ってしまうことはよくあります(特に入力バッファや出力バッファ)。全てのメソッドと関数は __doc__ 文字列があるので、引数と返り値の説明を得る事ができます。他の情報源としては、 Inside Macintosh [http://developer.apple.com/documentation/macos8/mac8.html] などを参照してください。

これらのモジュールは全て Carbon パッケージに含まれています。この名前にもかかわらずそれら全てが Carbon フレームワークの一部なわけではありません。CF は、CoreFoundation フレームワークの中に実際はありますし、Qt は QuickTime フレームワークにあります。ツールボックスモジュールは普通以下のようにして利用します。

from Carbon import AE

ノート

Carbon モジュール群は Python 3.0 で削除されました。

36.8.1. Carbon.AE — Apple Events

36.8.2. Carbon.AH — Apple ヘルプ

36.8.3. Carbon.App — アピアランスマネージャ

36.8.4. Carbon.Appearance — Appearance Manager 定数

36.8.5. Carbon.CF — Core Foundation

CFBase, CFArray, CFData, CFDictionary, CFString と CFURL オブジェクトがいくらか部分的にサポートされています。

36.8.6. Carbon.CG — Core Graphics

36.8.7. Carbon.CarbonEvt — Carbon Event Manager

36.8.8. Carbon.CarbonEvents — Carbon Event Manager 定数

36.8.9. Carbon.Cm — Component Manager

36.8.10. Carbon.Components — Component Manager constants

36.8.11. Carbon.ControlAccessor — Control Manager accssors

36.8.12. Carbon.Controls — Control Manager constants

36.8.13. Carbon.CoreFounation — CoreFounation constants

36.8.14. Carbon.CoreGraphics — CoreGraphics constants

36.8.15. Carbon.Ctl — Control Manager

36.8.16. Carbon.Dialogs — Dialog Manager constants

36.8.17. Carbon.Dlg — Dialog Manager

36.8.18. Carbon.Drag — Drag and Drop Manager

36.8.19. Carbon.Dragconst — Drag and Drop Manager constants

36.8.20. Carbon.Events — Event Manager constants

36.8.21. Carbon.Evt — Event Manager

36.8.22. Carbon.File — File Manager

36.8.23. Carbon.Files — File Manager constants

36.8.24. Carbon.Fm — Font Manager

36.8.25. Carbon.Folder — Folder Manager

36.8.26. Carbon.Folders — Folder Manager constants

36.8.27. Carbon.Fonts — Font Manager constants

36.8.28. Carbon.Help — Help Manager

36.8.29. Carbon.IBCarbon — Carbon InterfaceBuilder

36.8.30. Carbon.IBCarbonRuntime — Carbon InterfaceBuilder constants

36.8.31. Carbon.Icn — Carbon Icon Manager

36.8.32. Carbon.Icons — Carbon Icon Manager constants

36.8.33. Carbon.Launch — Carbon Launch Services

36.8.34. Carbon.LaunchServices — Carbon Launch Services constants

36.8.35. Carbon.List — List Manager

36.8.36. Carbon.Lists — List Manager constants

36.8.37. Carbon.MacHelp — Help Manager constants

36.8.38. Carbon.MediaDescr — Parsers and generators for Quicktime Media descriptors

36.8.39. Carbon.Menu — Menu Manager

36.8.40. Carbon.Menus — Menu Manager constants

36.8.41. Carbon.Mlte — MultiLingual Text Editor

36.8.42. Carbon.OSA — Carbon OSA Interface

36.8.43. Carbon.OSAconst — Carbon OSA Interface constants

36.8.44. Carbon.QDOffscreen — QuickDraw Offscreen constants

36.8.45. Carbon.Qd — QuickDraw

36.8.46. Carbon.Qdoffs — QuickDraw Offscreen

36.8.47. Carbon.Qt — QuickTime

36.8.48. Carbon.QuickDraw — QuickDraw constants

36.8.49. Carbon.QuickTime — QuickTime constants

36.8.50. Carbon.Res — Resource Manager and Handles

36.8.51. Carbon.Resources — Resource Manager and Handles constants

36.8.52. Carbon.Scrap — スクラップマネージャ

このモジュールは Mac OS 9 とそれ以前の OS 上の Classic PPC MacPython で完全に利用可能です。 Carbon 版の MacPython ではほんの限られた機能だけが利用可能です。

スクラップマネージャは Macintosh 上でのカット & ペースト操作の最もシンプルな形式をサポートします。アプリケーション間とアプリケーション内での両方のクリップボード操作が可能です。

Scrap モジュールはスクラップマネージャの関数へのローレベルでのアクセスを提供します。以下の関数が定義されています：

Carbon.Scrap.InfoScrap()

スクラップについて現在の情報を返します。この情報は (size, handle, count, state, path) を含むタプルでエンコードされます。

Field | Meaning
size | スクラップのサイズをバイト数で示したもの。
handle | スクラップを表現するリソースオブジェクト。
count | スクラップの内容のシリアルナンバー。
state | 整数。メモリー内にあるなら正、ディスク上にあるなら 0 、初期化されていないなら負。
path | ディスク上に保存されているなら、そのスクラップのファイルネーム。

参考

Scrap Manager [http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-109.html]

Appleのスクラップマネージャに関する文書には、アプリケーションでスクラップマネージャを使用する上での便利な情報がたくさんあります。

36.8.53. Carbon.Snd — Sound Manager

36.8.54. Carbon.Sound — Sound Manager constants

36.8.55. Carbon.TE — TextEdit

36.8.56. Carbon.TextEdit — TextEdit constants

36.8.57. Carbon.Win — Window Manager

36.8.58. Carbon.Windows — Window Manager constants

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

36. Mac OS X 固有のサービス »

36.9. ColorPicker — 色選択ダイアログ

ColorPicker モジュールは標準色選択ダイアログへのアクセスを提供します。

ノート

このモジュールは Python 3.x で削除されました。

ColorPicker.GetColor(prompt, rgb)

標準色選択ダイアログを表示し、ユーザが色を選択することを可能にします。 prompt の文字列によりユーザに指示を与えられ、デフォルトの選択色を rgb で設定する事ができます。 rgb は赤、緑、青の色要素のタプルで与えてください。 GetColor() はユーザが選択した色のタプルと色が選択されたか、取り消されたかを示すフラグを返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール

この章では、オープンスクリプティングアーキテクチャ (Open Scripting Architecture、OSA、一般的には AppleScript として知られている) の現在の Python 用実装について説明します。これを使うとスクリプト可能なアプリケーションを Python プログラムから実に python らしいインタフェースとともに制御することができます。このモジュール群の開発は停止しました。もっと新しい AppleScript サポートの実装については、サードパーティのライブラリである py-appscript プロジェクトを参照してください: <http://pypi.python.org/pypi/appscript/>

AppleScript や OSA の様々なコンポーネントの説明、およびそのアーキテクチャや用語の理解のために、 Apple のドキュメントを読んでおく方がよいでしょう。 “Applescript Language Guide” は概念モデルと用語を説明し、標準スイートについて文書にまとめてあります。 “Open Scripting Architecture” はアプリケーションプログラマの視点から、 OSA を使用する方法について説明しています。 Apple ヘルプビューワにおいてこれらは Developer Documentation, Core Technologies セクションで見つかります。

アプリケーションでスクリプト制御する例として、以下の AppleScript コードは、もっとも手前にある Finder のウィンドウの名前を取得して表示させます:

tell application "Finder"
    get name of window 1
end tell

Python では、以下のコードで同じ事ができます:

import Finder

f = Finder.Finder()
print f.get(f.window(1).name)

配布されている Python ライブラリには、標準スイートを実装したパッケージに加えて、いくつかのよくあるアプリケーションへのインタフェースを実装したパッケージが含まれています。

AppleEvent をアプリケーションに送るためには、最初にアプリケーションの用語 (Script Editor が「辞書」と呼んでいるもの) を話せる Python パッケージを作らなければなりません。この作業は PythonIDE の中から行うこともできますし、コマンドラインから gensuitemodule.py モジュールをスタンドアロンのプログラムとして実行することでもできます。

作成されるのはいくつものモジュールからなるパッケージで、それぞれのモジュールはプログラムで使われるスイートであり __init__ モジュールがそれらを取りまとめています。 Python の継承グラフは AppleScript の継承グラフに従っていますので、プログラムの辞書が標準スイートのサポートを含みつつ、一つ二つ動詞を追加の引数で拡張するように指定しているならば、出力されるスイートは Standard_Suite という StdSuites.Standard_Suite からすべてをインポートしてエクスポートし直しつつ追加された機能を持つようにメソッドをオーバーライドしたモジュールを含みます。 gensuitemodule の出力は非常に読み易く、また元々の AppleScript 辞書にあったドキュメントを Python 文書化文字列 (docstring) 中に含みますので、それを読むことは有用な情報源となります。

出力されたパッケージはパッケージと同じ名前のメインクラスを実装しており、これは全ての AppleScript 動詞を直接のオブジェクトは第1引数で、オプションのパラメータはキーワード引数で受けるメソッドとして含みます。 AppleScript クラスも Python クラスとして実装されたり、その他諸々も同様です。

動詞を実装しているメインの Python クラスはまた AppleScript の “application” クラスで宣言されたプロパティおよび要素へのアクセスも許します。現在のリリースではこれはオブジェクト指向的というには程遠く、上の例で見たように f.get(f.window(1).name) と書かねばならず、より Python らしい f.window(1).name.get() という書き方はできません。

AppleScript の識別子が Python の識別子として扱えない場合以下の少数のルールで変換します:

空白はアンダースコアに置き換えられます

その他の英数字以外の文字は _xx_ に置き換えられます。ここで xx はその文字の16進値です。

Python の予約語にはアンダースコアが後ろに付けられます

Python はスクリプト可能なアプリケーションを Python で作成することもサポートしていますが、以下のモジュールは MacPython の AppleScript サポートに関係するモジュールのみです:

37.1. gensuitemodule — OSA スタブ作成パッケージ

37.2. aetools — OSA クライアントのサポート

37.3. aepack — Python変数とAppleEventデータコンテナ間の変換

37.4. aetypes — AppleEvent オブジェクト

37.5. MiniAEFrame — オープンスクリプティングアーキテクチャサーバのサポート

37.5.1. AEServer オブジェクト

他に、以下のサポートモジュールが事前に生成されています: Finder, Terminal, Explorer, Netscape, CodeWarrior, SystemEvents, StdSuites 。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール »

37.1. gensuitemodule — OSA スタブ作成パッケージ

gensuitemodule モジュールは AppleScript 辞書によって特定のアプリケーションに実装されている AppleScript 群のためのスタブコードを実装した Python パッケージを作成します。

このモジュールは、通常は PythonIDE からユーザによって起動されますが、コマンドラインからスクリプトとして実行する(オプションとしてヘルプに --help を与えてみてください)こともできますし、Pythonコードでインポートして利用する事もできます。使用例として、どのようにして標準ライブラリに含まれているスタブパッケージを生成するか、 Mac/scripts/genallsuites.py にあるソースを見てください。

このモジュールは次の関数を定義しています。

gensuitemodule.is_scriptable(application)

application としてパス名を与えたアプリケーションがスクリプト可能でありそうな場合、真を返します。返り値はやや不確実な場合があります。 Internet Explorer はスクリプト不可能なように見えてしまいますが、実際はスクリプト可能です。

gensuitemodule.processfile(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose])

パス名として渡された application のためのスタブパッケージを作成します。 .app として一つのパッケージにまとめてあるプログラム群のために内部の実行プログラムそのものではなくパッケージへのパス名を渡すだけでよくなっています。パッケージ化されていないCFM アプリケーションではアプリケーションバイナリのファイル名を渡す事もできます。

この関数は、アプリケーションの OSA 用語リソースを捜し、これらのリソースを読み取り、その結果データをクライアントスタブを実装したPython コードパッケージを作成するために使用します。

output は作成結果のパッケージを保存するパス名で、指定しない場合は標準の「別名で保存(save file as)」ダイアログが表示されます。 basepkgname はこのパッケージの基盤となるパッケージを指定します。デフォルトは StdSuites になります。 StdSuites 自体を生成する場合だけ、このオプションを指定する必要があります。 edit_modnames は自動生成によって作成されてあまり綺麗ではないモジュール名を変更するために使用することができる辞書です。 creator_signature はパッケージ中の PkgInfo ファイル、あるいは CFM ファイルクリエータ署名から通常得られる4文字クリエータコードを無視するために使用することができます。 dump にはファイルオブジェクトを与えます、これを指定するとリソースを読取った後に停止して processfile がコード化した用語リソースの Python 表現をダンプします。 verbose にもまたファイルオブジェクトを与え、これを指定すると processfile の行なっている処理の詳細を出力します。

gensuitemodule.processfile_fromresource(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose])

この関数は、用語リソースを得るのに異なる方法を使用する以外は、 processfile と同じです。この関数では、リソースファイルとして application を開き、このファイルから "aete" および "aeut" リソースをすべて読み込む事で、AppleScript 用語リソース読み込みを行ないます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール »

37.2. aetools — OSA クライアントのサポート

aetools モジュールは Python で AppleScript クライアントとしての機能をサポートするアプリケーションを構築するための基本的な機能を含んでいます。さらに、このモジュールは、 aetypes および aepack モジュールの中核機能をインポートし再エクスポートします。 gensuitemodule によって生成されたスタブパッケージは aetools のかなり適切な部分をインポートするので、通常はそれを明示的にインポートする必要はありません。生成されたパッケージ群を使用することができない場合と、スクリプト対応のためにより低いレベルのアクセスを必要としている場合、例外が発生します。

aetools モジュールはそれ自身、 Carbon.AE モジュールによって提供される AppleEvent サポートを利用します。このモジュールにはウィンドウマネージャへのアクセスを必要とするという1つの欠点があります。詳細は GUI でスクリプトを実行 を見てください。この制限は将来のリリースで撤廃されるかもしれません。

ノート

このモジュールは Python 3.x で削除されました。

aetools モジュールは下記の関数を定義しています。

aetools.packevent(ae, parameters, attributes)

あらかじめ作成された Carbon.AE.AEDesc オブジェクト中のパラメーターおよび属性を保存します。 parameters と attributes は Python オブジェクトの4文字の OSA パラメータのキーを写像した辞書です。このオブジェクトをパックするには aepack.pack() を使います。

aetools.unpackevent(ae[, formodulename])

再帰的に、 Carbon.AE.AEDesc イベントを Python オブジェクトへアンパックします。関数は引数の辞書および属性の辞書を返します。 formodulename 引数は AppleScript クラスをどこに捜しに行くか制御するために、生成されたスタブパッケージにより使用されます。

aetools.keysubst(arguments, keydict)

Python キーワード引数辞書 arguments を、写像による4文字の OSA キーとして keydict の中で指定された Python 識別子であるキーの交換により packevent によって要求されるフォーマットへ変換します。生成されたパッケージ群によって使用されます。

aetools.enumsubst(arguments, key, edict)

arguments 辞書が key へのエントリーを含んでいる場合、辞書 edict のエントリーに見合う値に変換します。これは人間に判読可能なように Python 列挙名を OSA 4文字のコードに変換します。生成されたパッケージ群によって使用されます。

aetools モジュールは次のクラスを定義しています。

class aetools.TalkTo([signature=None, start=0, timeout=0])

アプリケーションとの対話に利用する代理の基底クラスです。 signature はクラス属性 _signature (サブクラスによって通常設定される)を上書きした、対話するアプリケーションを定義する4文字クリエートコードです。 start にはクラスインスタンス上でアプリケーションを実行することを可能にするために、真を設定する事ができます。 timeout を明示的に設定する事で、 AppleEvent の返答を待つデフォルトのタイムアウト時間を変更する事ができます。

TalkTo._start()

アプリケーションが起動していてるか確認し、起動していなければ起動しようとします。

TalkTo.send(code, subcode[, parameters, attributes])

OSA指示子 code, subcode (いずれも通常4文字の文字列です)を持った変数のために、 parameters をパックし、 attributes に戻し、目標アプリケーションにそれを送って、返答を待ち、 unpackevent を含んだ返答をアンパックし、AppleEvent の返答を返し、辞書としてアンパックした値と属性を返して、AppleEvent Carbon.AE.AEDesc を作成します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール »

37.3. aepack — Python変数とAppleEventデータコンテナ間の変換

aepack モジュールは、Python 変数から AppleEvent ディスクリプタへの変換(パック)と、その逆に変換(アンパック)する関数を定義しています。 Python 内では AppleEvent ディスクリプタは、組み込み型である AEDesc の Python オブジェクトとして扱われます。 AEDesc は Carbon.AE モジュールで定義されています。

ノート

このモジュールは Python 3.x で削除されました。

aepack モジュールは次の関数を定義しています。

aepack.pack(x[, forcetype])

Python 値 x を変換した値を保持する AEDesc オブジェクトを返します。 forcetype を与えることで、結果のディスクリプタ型を指定できます。それ以外では、Python 型から Apple Eventディスクリプタ型へのデフォルトのマッピングが使われます。マッピングは次の通りとなります。

Python type | descriptor type
FSSpec | typeFSS
FSRef | typeFSRef
Alias | typeAlias
integer | typeLong (32 bit integer)
float | typeFloat (64 bit floating point)
string | typeText
unicode | typeUnicodeText
list | typeAEList
dictionary | typeAERecord
instance | see below

x がPythonインスタンスなら、この関数は __aepack__() メソッドを呼びだそうとします。このメソッドは AEDesc オブジェクトを返します。

x の変換が上で定義されていない場合は、この関数は、テキストディスクリプタとしてエンコードされた、値の(repr()関数による)Python文字列表現が返されます。

aepack.unpack(x[, formodulename])

x は AEDesc タイプのオブジェクトでなければいけません。この関数は、Apple Eventディスクリプタ x のデータの Python オブジェクト表現を返します。単純な AppleEvent データ型(整数、テキスト、浮動小数点数)の、対応する Python 型が返されます。Apple Event リストは Python リストとして返され、リストの要素は再帰的にアンパックされます。 formodulename の指定がない場合、オブジェクト参照 (例： line 3 of document 1)が、 aetypes.ObjectSpecifier のインスタンスとして返されます。ディスクリプタ型が typeFSS である AppleEvent ディスクリプタが、 FSSpec オブジェクトとして返されます。 AppleEventレコードディスクリプタが、再帰的にアンパックされた、型の4 文字キーと要素を持つPython辞書として返されます。

オプションの formodulename 引数は gensuitemodule より作成されるスタブパッケージにより利用され、オブジェクト指定子のための OSA クラスをモジュールの中で見つけられることを保証します。これは、例えば、ファインダがウィンドウに対してオブジェクト指定子を返す場合、 Finder.Window のインスタンスが得られ、 aetypes.Window が得られないことを保証します。前者は、ファインダ上のウィンドウが持っている、すべての特性および要素のことを知っています。一方、後者のものはそれらのことを知りません。

参考

Module Carbon.AE

Apple Eventマネージャルーチンへの組み込みアクセス

Module aetypes

Apple Eventディスクリプタ型としてコードされたPython定義

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール »

37.4. aetypes — AppleEvent オブジェクト

aetypes では、 Apple Event データデスクリプタ (data descriptor) や Apple Eventオブジェクト指定子 (object specifier) を表現するクラスを定義しています。

Apple Event データはデスクリプタに含まれていて、これらのデスクリプタは型付けされています。多くのデスクリプタは、単に対応するPython の型で表現されています。例えば、OSA 中の typeText は Python 文字列型で、 typeFloat は浮動小数点型になる、といった具合です。このモジュールでは、OSA の型のうち、直接的に対応する Python の型がないもののためにクラスを定義しています。そのようなクラスのインスタンスに対するパックやアンパック操作は、 aepack モジュール自動的に処理します。

オブジェクト指定子は、本質的には Apple Event サーバ中に実装されているオブジェクトへのアドレスです。Apple Event 指定子は、Apple Event のオブジェクトそのものとして、あるいはオプションパラメタの引数として使われます。 aetypes モジュールには OSA クラスやプロパティを表現するための基底クラスが入っています。これらのクラスは、 gensuitemodule が生成するパッケージ内で、目的に応じてクラスやプロパティを増やす際に使われます。

以前のバージョンとの互換性や、スタブパッケージを生成していないようなアプリケーションをスクリプトで書く必要がある場合のために、このモジュールには Document 、 Window 、 Character 、といったよく使われる OSA クラスのいくつかを指定できるオブジェクト指定子も入っています。

ノート

このモジュールは Python 3.x で削除されました。

AEObjects モジュールでは、以下のようなクラスを定義して、 Apple Event デスクリプタデータを表現しています:

class aetypes.Unknown(type, data)

aepack や aetypes がサポートしていない OSA のデスクリプタデータ、すなわち、このモジュールで扱っている他のクラスや、 Python の組み込み型の値で表現されていないようなデータを表現するクラスです。

class aetypes.Enum(enum)

列挙値 (enumeration value) を表すクラスです。値は 4 文字の文字列型になります。

class aetypes.InsertionLoc(of, pos)

オブジェクト of の中の pos の位置を表すクラスです。

class aetypes.Boolean(bool)

ブール値 (真偽値) を表すクラスです。

class aetypes.StyledText(style, text)

スタイル情報 (フォント、タイプフェイスなど) つきのテキストを表すクラスです。

class aetypes.AEText(script, style, text)

スクリプトシステム (script system) およびスタイル情報の入ったテキストを表すクラスです。

class aetypes.IntlText(script, language, text)

スクリプトシステムと言語情報 (language information) の入ったテキストを表すクラスです。

class aetypes.IntlWritingCode(script, language)

スクリプトシステムと言語情報を表すクラスです。

class aetypes.QDPoint(v, h)

QuickDrawの点を表すクラスです。

class aetypes.QDRectangle(v0, h0, v1, h1)

QuickDrawの矩形を表すクラスです。

class aetypes.RGBColor(r, g, b)

色を表すクラスです。

class aetypes.Type(type)

OSA の型 (type value) を表すクラスです。 4 文字からなる名前を値に持ちます。

class aetypes.Keyword(name)

OSA のキーワードです。 4 文字からなる名前を値に持ちます。

class aetypes.Range(start, stop)

範囲を表すクラスです。

class aetypes.Ordinal(abso)

先頭を表す "firs" や中央を表す "midd" のように、数値でない絶対位置指定子を表すクラスです。

class aetypes.Logical(logc, term)

演算子 logc を term に適用したときの論理式を表すクラスです。

class aetypes.Comparison(obj1, relo, obj2)

obj1 と obj2 の relo による比較を表すクラスです。

以下のクラスは、生成されたスタブパッケージが、 AppleScript のクラスやプロパティを Python で表現する上で基底クラスとして利用します。

class aetypes.ComponentItem(which[, fr])

OSA クラス用の抽象基底クラスです。サブクラスでは、クラス属性 want を 4 文字の OSA クラスコードに設定せねばなりません。このクラスのサブクラスのインスタンスは AppleScript オブジェクト指定子と同じになります。インスタンス化を行う最には、 which にセレクタを渡さねばなりません。また、任意で親オブジェクトを fr に渡せます。

class aetypes.NProperty(fr)

OSA プロパティ用の抽象基底クラスです。サブクラスでは、クラス属性 want と which を設定して、どのプロパティを表しているかを指定せねばなりません。このクラスのサブクラスのインスタンスはオブジェクト指定子と同じになります。

class aetypes.ObjectSpecifier(want, form, seld[, fr])

ComponentItem と NProperty の基底クラスで、汎用の OSA オブジェクト指定子を表します。パラメタの説明は Apple Open Scripting Architecture のドキュメントを参照してください。このクラスは抽象クラスではないので注意してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

37. MacPython OSA モジュール »

37.5. MiniAEFrame — オープンスクリプティングアーキテクチャサーバのサポート

MiniAEFrame モジュールは、アプリケーションにオープンスクリプティングアーキテクチャ(OSA)サーバ機能を持たせるためのフレームワークを提供します。つまり、AppleEvents の受信と処理を行わせます。 FrameWork と連携させても良いし、単独でも使えます。実例として、このモジュールは PythonCGISlave の中で使われています。

MiniAEFrame には以下のクラスが定義されています。

class MiniAEFrame.AEServer

AppleEvent の分岐を処理するクラス。作成するアプリケーションはこのクラスと、 MiniApplication あるいは FrameWork.Application のサブクラスでなければなりません。サブクラス化したクラスでは __init__() メソッドで、継承した両方のクラスの __init__() メソッドを呼びださなければなりません。

class MiniAEFrame.MiniApplication

FrameWork.Application とある程度互換なクラスですが、機能は少ないです。このクラスのイベントループはアップルメニュー、 Cmd-.(コマンドキーを押しながらピリオド.を押す)、 AppleEvent をサポートします。他のイベントは Python インタープリタか Sioux（CodeWarrior のコンソールシステム）に渡されます。作成するアプリケーションで AEServer を使いたいが、独自のウィンドウなどを持たない場合に便利です。

37.5.1. AEServer オブジェクト

AEServer.installaehandler(classe, type, callback)

AppleEvent ハンドラをインストールします。 classe と type は4文字の OSA クラスとタイプの指定子で、ワイルドカード '****' も使えます。対応する AppleEvent を受けるとパラメータがデコードされ、与えたコールバックが呼び出されます。

AEServer.callback(_object, **kwargs)

与えたコールバックは、OSAダイレクトオブジェクトを1番目のパラメータとして呼び出されます。他のパラメータは4文字の指定子を名前にしたキーワード引数として渡されます。他に3つのキーワード・パラメータが渡されます。つまり、 _class と _type はクラスとタイプ指定子で、 _attributes は AppleEvent 属性を持つ辞書です。

与えたメソッドの返り値は aetools.packevent() でパックされ、リプライとして送られます。

現在のクラス設計にはいくつか重大な問題があることに注意してください。引数に名前ではない4文字の指定子を持つ AppleEvent はまだ実装されていないし、イベントの送信側にエラーを返すこともできません。この問題は将来のリリースまで先送りにされています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス

この章で記述されているモジュールは、SGI の IRIX オペレーティングシステム (バージョン4と5) 固有の機能へのインターフェイスを提供します。

38.1. al — SGIのオーディオ機能

38.1.1. コンフィギュレーションオブジェクト

38.1.2. ポートオブジェクト

38.2. AL — al モジュールで使われる定数

38.3. cd — SGI システムの CD-ROM へのアクセス

38.3.1. プレーヤーオブジェクト

38.3.2. パーザオブジェクト

38.4. fl — グラフィカルユーザーインターフェースのための FORMS ライブラリ

38.4.1. fl モジュールに定義されている関数

38.4.2. フォームオブジェクト

38.4.3. FORMSオブジェクト

38.5. FL — fl モジュールで使用される定数

38.6. flp — 保存されたFORMSデザインをロードする関数

38.7. fm — Font Manager インターフェース

38.8. gl — Graphics Library インターフェース

38.9. DEVICE — gl モジュールで使われる定数

38.10. GL — gl モジュールで使われる定数

38.11. imgfile — SGI imglib ファイルのサポート

38.12. jpeg — JPEGファイルの読み書きを行う

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.1. al — SGIのオーディオ機能

バージョン 2.6 で撤廃: al モジュールは Python 3.0 での削除に向け非推奨になりました。

このモジュールを使うと、SGI Indy と Indigo ワークステーションのオーディオ装置にアクセスできます。詳しくは IRIX の man ページのセクション 3A を参照してください。ここに書かれた関数が何をするかを理解するには、man ページを読む必要があります！ IRIX のリリース 4.0.5 より前のものでは使えない関数もあります。お使いのプラットフォームで特定の関数が使えるかどうか、マニュアルで確認してください。

このモジュールで定義された関数とメソッドは全て、名前に AL の接頭辞を付けた C の関数と同義です。

C のヘッダーファイル <audio.h> のシンボル定数は標準モジュール AL に定義されています。下記を参照してください。

警告

オーディオライブラリの現在のバージョンは、不正な引数が渡されるとエラーステイタスが返るのではなく、coreを吐き出すことがあります。残念ながら、この現象が確実に起こる環境は述べられていないし、確認することは難しいので、 Python インターフェースでこの種の問題に対して防御することはできません。（一つの例は過大なキューサイズを特定することです — 上限については記載されていません。）

このモジュールには、以下の関数が定義されています：

al.openport(name, direction[, config])

引数 name と direction は文字列です。省略可能な引数 config は、 newconfig() で返されるコンフィギュレーションオブジェクトです。返り値は audio port object です；オーディオポートオブジェクトのメソッドは下に書かれています。

al.newconfig()

返り値は新しい audio configuration object です；オーディオコンフィギュレーションオブジェクトのメソッドは下に書かれています。

al.queryparams(device)

引数 device は整数です。返り値は ALqueryparams() で返されるデータを含む整数のリストです。

al.getparams(device, list)

引数 device は整数です。引数 list は queryparams() で返されるようなリストです； queryparams() を適切に（！）修正して使うことができます。

al.setparams(device, list)

引数 device は整数です。引数 list は queryparams() で返されるようなリストです。

38.1.1. コンフィギュレーションオブジェクト

newconfig() で返されるコンフィギュレーションオブジェクトには以下のメソッドがあります：

audio configuration.getqueuesize()

キューサイズを返します。

audio configuration.setqueuesize(size)

キューサイズを設定します。

audio configuration.getwidth()

サンプルサイズを返します。

audio configuration.setwidth(width)

サンプルサイズを設定します。

audio configuration.getchannels()

チャンネル数を返します。

audio configuration.setchannels(nchannels)

チャンネル数を設定します。

audio configuration.getsampfmt()

サンプルのフォーマットを返します。

audio configuration.setsampfmt(sampfmt)

サンプルのフォーマットを設定します。

audio configuration.getfloatmax()

浮動小数点数でサンプルデータの最大値を返します。

audio configuration.setfloatmax(floatmax)

浮動小数点数でサンプルデータの最大値を設定します。

38.1.2. ポートオブジェクト

openport() で返されるポートオブジェクトには以下のメソッドがあります：

audio port.closeport()

ポートを閉じます。

audio port.getfd()

ファイルディスクリプタを整数で返します。

audio port.getfilled()

バッファに存在するサンプルの数を返します。

audio port.getfillable()

バッファの空きに入れることのできるサンプルの数を返します。

audio port.readsamps(nsamples)

必要ならブロックして、キューから指定のサンプル数を読み込みます。生データを文字列として（例えば、サンプルサイズが 2 バイトならサンプル当たり 2 バイトが big-endian (high byte、low byte) で）返します。

audio port.writesamps(samples)

必要ならブロックして、キューにサンプルを書き込みます。サンプルは readsamps() で返される値のようにエンコードされていなければなりません。

audio port.getfillpoint()

‘fill point’ を返します。

audio port.setfillpoint(fillpoint)

‘fill point’ を設定します。

audio port.getconfig()

現在のポートのコンフィギュレーションを含んだコンフィギュレーションオブジェクトを返します。

audio port.setconfig(config)

コンフィギュレーションを引数に取り、そのコンフィギュレーションに設定します。

audio port.getstatus(list)

最後のエラーについてのステイタスの情報を返します。

38.2. AL — al モジュールで使われる定数

バージョン 2.6 で撤廃: AL モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールには、組み込みモジュール al (上記参照) を使用するのに必要とされるシンボリック定数が定義されています。定数の名前は C の include ファイル <audioio.h> で接頭辞 AL_ を除いたものと同じです。

定義されている名前の完全なリストについてはモジュールのソースを参照してください。お勧めの使い方は以下の通りです：

import al
from AL import *

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.3. cd — SGI システムの CD-ROM へのアクセス

バージョン 2.6 で撤廃: cd モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールは Silicon Graphics CD ライブラリへのインターフェースを提供します。 Silicon Graphics システムだけで利用可能です。

ライブラリは以下のように使われます。

CD-ROM デバイスを open() で開き、 createparser() で CD からデータをパースするためのパーザを作ります。 open() で返されるオブジェクトは CD からデータを読み込むのに使われますが、 CD-ROM デバイスのステータス情報や、CD の情報、たとえば目次などを得るのにも使われます。 CD から得たデータはパーザに渡され、パーザはフレームをパースし、あらかじめ加えられたコールバック関数を呼び出します。

オーディオCDはトラック tracks あるいはプログラム programs (同じ意味で、どちらかの用語が使われます) に分けられます。トラックはさらにインデックス indices に分けられます。オーディオ CD は、CD 上の各トラックのスタート位置を示す目次 table of contents を持っています。インデックス0は普通、トラックの始まりの前のポーズです。目次から得られるトラックのスタート位置は通常、インデックス1のスタート位置です。

CD 上の位置は2通りの方法で得ることができます。それはフレームナンバーと、分、秒、フレームの3つの値からなるタプルの2つです。ほとんどの関数は後者を使います。位置はCDの開始位置とトラックの開始位置の両方に相対的になります。

モジュール cd は、以下の関数と定数を定義しています：

cd.createparser()

不透明なパーザオブジェクトを作って返します。パーザオブジェクトのメソッドは下に記載されています。

cd.msftoframe(minutes, seconds, frames)

絶対的なタイムコードである (minutes, seconds, frames) の3つ組の表現を、相当するCDのフレームナンバーに変換します。

cd.open([device[, mode]])

CD-ROM デバイスを開きます。不透明なプレーヤーオブジェクトを返します；プレーヤーオブジェクトのメソッドは下に記載されています。デバイス device は SCSI デバイスファイルの名前で、例えば '/dev/scsi/sc0d4l0' あるいは None です。もし省略したり、 None なら、ハードウエアが検索されて CD-ROM デバイスを割り当てます。 mode は、省略しないなら 'r' にすべきです。

このモジュールでは以下の変数を定義しています：

exception cd.error

様々なエラーについて発生する例外です。

cd.DATASIZE

オーディオデータの1フレームのサイズです。これは audio タイプのコールバックへ渡されるオーディオデータのサイズです。

cd.BLOCKSIZE

オーディオデータが読み取られていないフレーム1つのサイズです。

以下の変数は getstatus() で返されるステータス情報です：

cd.READY

オーディオ CD がロードされて、ドライブが操作可能であることを示します。

cd.NODISC

ドライブに CD がロードされていないことを示します。

cd.CDROM

ドライブに CD-ROM がロードされていることを示します。続いて play あるいは read の操作をすると、I/O エラーを返します。

cd.ERROR

ディスクや目次を読み込もうとしているときに起こるエラー。

cd.PLAYING

ドライブがオーディオ CD を CD プレーヤーモードでオーディオ端子から再生していることを示します。

cd.PAUSED

ドライブが CD プレーヤーモードで、再生を一時停止していることを示します。

cd.STILL

PAUSED と同じですが、古いモデル（non 3301）である Toshiba CD-ROM ドライブのものです。このドライブはもうSGIから出荷されていません。

cd.audio

cd.pnum

cd.index

cd.ptime

cd.atime

cd.catalog

cd.ident

cd.control

これらは整数の定数で、パーザのいろいろなタイプのコールバックを示しています。コールバックは CD パーザオブジェクトの addcallback() で設定できます（下記参照）。

38.3.1. プレーヤーオブジェクト

プレーヤーオブジェクト (open() で返されます) には以下のメソッドがあります：

CD player.allowremoval()

CD-ROM ドライブのイジェクトボタンのロックを解除して、ユーザが CD キャディを排出するのを許可します。

CD player.bestreadsize()

メソッド readda() のパラメータ num_frames として最適の値を返します。最適値は CD-ROM ドライブからの連続したデータフローが許可される値が定義されます。

CD player.close()

プレーヤーオブジェクトと関連付けられたリソースを解放します。 close() を呼び出したあとでは、そのオブジェクトに対するメソッドは使用できません。

CD player.eject()

CD-ROMドライブからキャディを排出します。

CD player.getstatus()

CD-ROMドライブの現在の状態に関する情報を返します。返される情報は以下の値からなるタプルです： state 、 track 、 rtime 、 atime 、 ttime 、 first 、 last 、 scsi_audio 、 cur_block 。 rtime は現在のトラックの初めからの相対的な時間； atime はディスクの初めからの相対的な時間； ttime はディスクの全時間です。それぞれの値の詳細については、マニュアルページ CDgetstatus(3dm) を参照してください。 state の値は以下のうちのどれか一つです： ERROR 、 NODISC 、 READY 、 PLAYING 、 PAUSED 、 STILL 、 CDROM 。

CD player.gettrackinfo(track)

特定のトラックについての情報を返します。返される情報は、トラックの開始時刻とトラックの時間の長さの二つの要素からなるタプルです。

CD player.msftoblock(min, sec, frame)

分、秒、フレームの3つからなる絶対的なタイムコードを、与えられた CD-ROM ドライブの相当する論理ブロック番号に変換します。時刻を比較するには msftoblock() よりも msftoframe() を使うべきです。論理ブロック番号は、CD-ROM ドライブによって必要とされるオフセット値が違うため、フレームナンバーと異なります。

CD player.play(start, play)

CD-ROM ドライブのオーディオ CD の特定のトラックから再生を開始します。 CD-ROM ドライブのヘッドフォン端子と（備えているなら）オーディオ端子から出力されます。ディスクの最後で再生は停止します。 start は再生を開始する CD のトラックナンバーです； play が0なら、CD は最初の一時停止状態になります。その状態からメソッド togglepause() で再生を開始できます。

CD player.playabs(minutes, seconds, frames, play)

play() と似ていますが、開始位置をトラックナンバーの代わりに分、秒、フレームで与えます。

CD player.playtrack(start, play)

play() と似ていますが、トラックの終わりで再生を停止します。

CD player.playtrackabs(track, minutes, seconds, frames, play)

play() と似ていますが、指定した絶対的な時刻から再生を開始して、指定したトラックで終了します。

CD player.preventremoval()

CD-ROM ドライブのイジェクトボタンをロックして、ユーザが CD キャディを排出できないようにします。

CD player.readda(num_frames)

CD-ROM ドライブにマウントされたオーディオ CD から、指定したフレーム数を読み込みます。オーディオフレームのデータを示す文字列を返します。この文字列はそのままパーザオブジェクトのメソッド parseframe() へ渡すことができます。

CD player.seek(minutes, seconds, frames)

CD-ROM から次にデジタルオーディオデータを読み込む開始位置のポインタを設定します。ポインタは minutes 、 seconds 、 frames で指定した絶対的なタイムコードの位置に設定されます。返される値はポインタが設定された論理ブロック番号です。

CD player.seekblock(block)

CD-ROM から次にデジタルオーディオデータを読み込む開始位置のポインタを設定します。ポインタは指定した論理ブロック番号に設定されます。返される値はポインタが設定された論理ブロック番号です。

CD player.seektrack(track)

CD-ROM から次にデジタルオーディオデータを読み込む開始位置のポインタを設定します。ポインタは指定したトラックに設定されます。返される値はポインタが設定された論理ブロック番号です。

CD player.stop()

現在実行中の再生を停止します。

CD player.togglepause()

再生中なら CD を一時停止し、一時停止中なら再生します。

38.3.2. パーザオブジェクト

パーザオブジェクト (createparser() で返されます) には以下のメソッドがあります：

CD parser.addcallback(type, func, arg)

パーザにコールバックを加えます。デジタルオーディオストリームの8つの異なるデータタイプのためのコールバックをパーザは持っています。これらのタイプのための定数は cd モジュールのレベルで定義されています (上記参照)。コールバックは以下のように呼び出されます： func(arg, type, data) 、ここで arg はユーザが与えた引数、 type はコールバックの特定のタイプ、 data はこの type のコールバックに渡されるデータです。データのタイプは以下のようにコールバックのタイプによって決まります：

Type | Value
audio | al.writesamps() へそのまま渡すことのできる文字列。
pnum | プログラム（トラック）ナンバーを示す整数。
index | インデックスナンバーを示す整数。
ptime | プログラムの時間を示す分、秒、フレームからなるタプル。
atime | 絶対的な時刻を示す分、秒、フレームからなるタプル。
catalog | CDのカタログナンバーを示す13文字の文字列。
ident | 録音のISRC識別番号を示す12文字の文字列。文字列は2文字の国別コード、3文字の所有者コード、2文字の年号、5文字のシリアルナンバーからなります。
control | CDのサブコードデータのコントロールビットを示す整数。

CD parser.deleteparser()

パーザを消去して、使用していたメモリを解放します。この呼び出しのあと、オブジェクトは使用できません。オブジェクトへの最後の参照が削除されると、自動的にこのメソッドが呼び出されます。

CD parser.parseframe(frame)

readda() などから返されたデジタルオーディオ CD のデータの1つあるいはそれ以上のフレームをパースします。データ内にどういうサブコードがあるかを決定します。その前のフレームからサブコードが変化していたら、 parseframe() は対応するタイプのコールバックを起動して、フレーム内のサブコードデータをコールバックに渡します。 C の関数とは違って、1つ以上のデジタルオーディオデータのフレームをこのメソッドに渡すことができます。

CD parser.removecallback(type)

指定した type のコールバックを削除します。

CD parser.resetparser()

サブコードを追跡しているパーザのフィールドをリセットして、初期状態にします。ディスクを交換したあと、 resetparser() を呼び出さなければなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.4. fl — グラフィカルユーザーインターフェースのための FORMS ライブラリ

バージョン 2.6 で撤廃: fl モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールは、Mark Overmars による FORMS ライブラリへのインターフェースを提供します。 FORMS ライブラリのソースは anonymous ftp ftp.cs.ruu.nl の SGI/FORMS ディレクトリから入手できます。最新のテストはバージョン2.0bで行いました。

ほとんどの関数は接頭辞の fl_ を取ると、対応する C の関数名になります。ライブラリで使われる定数は後述の FL モジュールで定義されています。

Python でこのオブジェクトを作る方法は C とは少し違っています：ライブラリに保持された’現在のフォーム’に新しい FORMS オブジェクトを加えるのではなく、フォームに FORMS オブジェクトを加えるには、フォームを示す Python オブジェクトのメソッドで全て行います。したがって、C の関数の fl_addto_form() と fl_end_form() に相当するものは Python にはありませんし、 fl_bgn_form() に相当するものとしては fl.make_form() を呼び出します。

用語のちょっとした混乱に注意してください： FORMS ではフォームの中に置くことができるボタン、スライダーなどに object の用語を使います。 Python では全ての値が’オブジェクト’です。 FORMS への Python のインターフェースによって、2つの新しいタイプの Python オブジェクト：フォームオブジェクト（フォーム全体を示します）と FORMS オブジェクト（ボタン、スライダーなどの一つひとつを示します）を作ります。おそらく、混乱するほどのことではありません。

FORMS への Python インターフェースに’フリーオブジェクト’はありませんし、 Python でオブジェクトクラスを書いて加える簡単な方法もありません。しかし、GL イベントハンドルへの FORMS インターフェースが利用可能で、純粋な GL ウィンドウに FORMS を組み合わせることができます。

注意： fl をインポートすると、GL の関数 foreground() と FORMS のルーチン fl_init() を呼び出します。

38.4.1. fl モジュールに定義されている関数

fl モジュールには以下の関数が定義されています。これらの関数の働きに関する詳しい情報については、FORMS ドキュメントで対応する C の関数の説明を参照してください。

fl.make_form(type, width, height)

与えられたタイプ、幅、高さでフォームを作ります。これは form オブジェクトを返します。このオブジェクトは後述のメソッドを持ちます。

fl.do_forms()

標準の FORMS のメインループです。ユーザからの応答が必要な FORMS オブジェクトを示す Python オブジェクト、あるいは特別な値 FL.EVENT を返します。

fl.check_forms()

FORMS イベントを確認します。 do_forms() が返すもの、あるいはユーザからの応答をすぐに必要とするイベントがないなら None を返します。

fl.set_event_call_back(function)

イベントのコールバック関数を設定します。

fl.set_graphics_mode(rgbmode, doublebuffering)

グラフィックモードを設定します。

fl.get_rgbmode()

現在の RGB モードを返します。これは C のグローバル変数 fl_rgbmode の値です。

fl.show_message(str1, str2, str3)

3行のメッセージと OK ボタンのあるダイアログボックスを表示します。

fl.show_question(str1, str2, str3)

3行のメッセージと YES、NO のボタンのあるダイアログボックスを表示します。ユーザによって YES が押されたら 1 、NO が押されたら 0 を返します。

fl.show_choice(str1, str2, str3, but1[, but2[, but3]])

3行のメッセージと最大3つまでのボタンのあるダイアログボックスを表示します。ユーザによって押されたボタンの数値を返します (それぞれ 1 、 2 、 3)。

fl.show_input(prompt, default)

1行のプロンプトメッセージと、ユーザが入力できるテキストフィールドを持つダイアログボックスを表示します。 2番目の引数はデフォルトで表示される入力文字列です。ユーザが入力した文字列が返されます。

fl.show_file_selector(message, directory, pattern, default)

ファイル選択ダイアログを表示します。ユーザによって選択されたファイルの絶対パス、あるいはユーザが Cancel ボタンを押した場合は None を返します。

fl.get_directory()

fl.get_pattern()

fl.get_filename()

これらの関数は最後にユーザが show_file_selector() で選択したディレクトリ、パターン、ファイル名（パスの末尾のみ）を返します。

fl.qdevice(dev)

fl.unqdevice(dev)

fl.isqueued(dev)

fl.qtest()

fl.qread()

fl.qreset()

fl.qenter(dev, val)

fl.get_mouse()

fl.tie(button, valuator1, valuator2)

これらの関数は対応する GL 関数への FORMS のインターフェースです。 fl.do_events() を使っていて、自分で何か GL イベントを操作したいときにこれらを使います。FORMS が扱うことのできない GL イベントが検出されたら fl.do_forms() が特別の値 FL.EVENT を返すので、 fl.qread() を呼び出して、キューからイベントを読み込むべきです。対応する GL の関数は使わないでください！

fl.color()

fl.mapcolor()

fl.getmcolor()

FORMS ドキュメントにある fl_color() 、 fl_mapcolor() 、 fl_getmcolor() の記述を参照してください。

38.4.2. フォームオブジェクト

フォームオブジェクト（上で述べた make_form() で返されます）には下記のメソッドがあります。各メソッドは名前の接頭辞に fl_ を付けた C の関数に対応します；また、最初の引数はフォームのポインタです；説明はFORMSの公式文書を参照してください。

全ての add_*() メソッドは、 FORMS オブジェクトを示す Python オブジェクトを返します。 FORMS オブジェクトのメソッドを以下に記載します。ほとんどの FORMS オブジェクトは、そのオブジェクトの種類ごとに特有のメソッドもいくつか持っています。

form.show_form(placement, bordertype, name)

フォームを表示します。

form.hide_form()

フォームを隠します。

form.redraw_form()

フォームを再描画します。

form.set_form_position(x, y)

フォームの位置を設定します。

form.freeze_form()

フォームを固定します。

form.unfreeze_form()

固定したフォームの固定を解除します。

form.activate_form()

フォームをアクティベートします。

form.deactivate_form()

フォームをディアクティベートします。

form.bgn_group()

新しいオブジェクトのグループを作ります；グループオブジェクトを返します。

form.end_group()

現在のオブジェクトのグループを終了します。

form.find_first()

フォームの中の最初のオブジェクトを見つけます。

form.find_last()

フォームの中の最後のオブジェクトを見つけます。

form.add_box(type, x, y, w, h, name)

フォームにボックスオブジェクトを加えます。特別な追加のメソッドはありません。

form.add_text(type, x, y, w, h, name)

フォームにテキストオブジェクトを加えます。特別な追加のメソッドはありません。

form.add_clock(type, x, y, w, h, name)

フォームにクロックオブジェクトを加えます。 — メソッド： get_clock() 。

form.add_button(type, x, y, w, h, name)

フォームにボタンオブジェクトを加えます。 — メソッド： get_button() 、 set_button() 。

form.add_lightbutton(type, x, y, w, h, name)

フォームにライトボタンオブジェクトを加えます。 — メソッド： get_button() 、 set_button() 。

form.add_roundbutton(type, x, y, w, h, name)

フォームにラウンドボタンオブジェクトを加えます。 — メソッド： get_button() 、 set_button() 。

form.add_slider(type, x, y, w, h, name)

フォームにスライダーオブジェクトを加えます。 — メソッド： set_slider_value() 、 get_slider_value() 、 set_slider_bounds() 、 get_slider_bounds() 、 set_slider_return() 、 set_slider_size() 、 set_slider_precision() 、 set_slider_step() 。

form.add_valslider(type, x, y, w, h, name)

フォームにバリュースライダーオブジェクトを加えます。 — メソッド： set_slider_value() 、 get_slider_value() 、 set_slider_bounds() 、 get_slider_bounds() 、 set_slider_return() 、 set_slider_size() 、 set_slider_precision() 、 set_slider_step() 。

form.add_dial(type, x, y, w, h, name)

フォームにダイアルオブジェクトを加えます。 — メソッド： set_dial_value() 、 get_dial_value() 、 set_dial_bounds() 、 get_dial_bounds() 。

form.add_positioner(type, x, y, w, h, name)

フォームに2次元ポジショナーオブジェクトを加えます。 — メソッド： set_positioner_xvalue() 、 set_positioner_yvalue() 、 set_positioner_xbounds() 、 set_positioner_ybounds() 、 get_positioner_xvalue() 、 get_positioner_yvalue() 、 get_positioner_xbounds() 、 get_positioner_ybounds() 。

form.add_counter(type, x, y, w, h, name)

フォームにカウンタオブジェクトを加えます。 — メソッド： set_counter_value() 、 get_counter_value() 、 set_counter_bounds() 、 set_counter_step() 、 set_counter_precision() 、 set_counter_return() 。

form.add_input(type, x, y, w, h, name)

フォームにインプットオブジェクトを加えます。 — メソッド： set_input() 、 get_input() 、 set_input_color() 、 set_input_return() 。

form.add_menu(type, x, y, w, h, name)

フォームにメニューオブジェクトを加えます。 — メソッド： set_menu() 、 get_menu() 、 addto_menu() 。

form.add_choice(type, x, y, w, h, name)

フォームにチョイスオブジェクトを加えます。 — メソッド： set_choice() 、 get_choice() 、 clear_choice() 、 addto_choice() 、 replace_choice() 、 delete_choice() 、 get_choice_text() 、 set_choice_fontsize() 、 set_choice_fontstyle() 。

form.add_browser(type, x, y, w, h, name)

フォームにブラウザオブジェクトを加えます。 — メソッド： set_browser_topline() 、 clear_browser() 、 add_browser_line() 、 addto_browser() 、 insert_browser_line() 、 delete_browser_line() 、 replace_browser_line() 、 get_browser_line() 、 load_browser() 、 get_browser_maxline() 、 select_browser_line() 、 deselect_browser_line() 、 deselect_browser() 、 isselected_browser_line() 、 get_browser() 、 set_browser_fontsize() 、 set_browser_fontstyle() 、 set_browser_specialkey() 。

form.add_timer(type, x, y, w, h, name)

フォームにタイマーオブジェクトを加えます。 — メソッド： set_timer() 、 get_timer() 。

フォームオブジェクトには以下のデータ属性があります；FORMS ドキュメントを参照してください：

名称 | Cの型 | 意味
window | int (read-only) | GLウィンドウのid
w | float | フォームの幅
h | float | フォームの高さ
x | float | フォーム左肩のx座標
y | float | フォーム左肩のy座標
deactivated | int | フォームがディアクティベートされているなら非ゼロ
visible | int | フォームが可視なら非ゼロ
frozen | int | フォームが固定されているなら非ゼロ
doublebuf | int | ダブルバッファリングがオンなら非ゼロ

38.4.3. FORMSオブジェクト

FORMS オブジェクトの種類ごとに特有のメソッドの他に、全てのFORMSオブジェクトは以下のメソッドも持っています：

FORMS object.set_call_back(function, argument)

オブジェクトのコールバック関数と引数を設定します。オブジェクトがユーザからの応答を必要とするときには、コールバック関数は2 つの引数、オブジェクトとコールバックの引数とともに呼び出されます。（コールバック関数のない FORMS オブジェクトは、ユーザからの応答を必要とするときには fl.do_forms() あるいは fl.check_forms() によって返されます。）引数なしにこのメソッドを呼び出すと、コールバック関数を削除します。

FORMS object.delete_object()

オブジェクトを削除します。

FORMS object.show_object()

オブジェクトを表示します。

FORMS object.hide_object()

オブジェクトを隠します。

FORMS object.redraw_object()

オブジェクトを再描画します。

FORMS object.freeze_object()

オブジェクトを固定します。

FORMS object.unfreeze_object()

固定したオブジェクトの固定を解除します。

FORMS オブジェクトには以下のデータ属性があります； FORMS ドキュメントを参照してください。

名称 | Cの型 | 意味
objclass | int (read-only) | オブジェクトクラス
type | int (read-only) | オブジェクトタイプ
boxtype | int | ボックスタイプ
x | float | 左肩のx座標
y | float | 左肩のy座標
w | float | 幅
h | float | 高さ
col1 | int | 第1の色
col2 | int | 第2の色
align | int | 配置
lcol | int | ラベルの色
lsize | float | ラベルのフォントサイズ
label | string | ラベルの文字列
lstyle | int | ラベルのスタイル
pushed | int (read-only) | （FORMSドキュメント参照）
focus | int (read-only) | （FORMSドキュメント参照）
belowmouse | int (read-only) | （FORMSドキュメント参照）
frozen | int (read-only) | （FORMSドキュメント参照）
active | int (read-only) | （FORMSドキュメント参照）
input | int (read-only) | （FORMSドキュメント参照）
visible | int (read-only) | （FORMSドキュメント参照）
radio | int (read-only) | （FORMSドキュメント参照）
automatic | int (read-only) | （FORMSドキュメント参照）

38.5. FL — fl モジュールで使用される定数

バージョン 2.6 で撤廃: FL モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールには、組み込みモジュール fl を使うのに必要なシンボル定数が定義されています (上記参照) ；これらは名前の接頭辞 FL_ が省かれていることを除いて、C のヘッダファイル <forms.h> に定義されているものと同じです。定義されている名称の完全なリストについては、モジュールのソースをご覧ください。お勧めする使い方は以下の通りです：

import fl
from FL import *

38.6. flp — 保存されたFORMSデザインをロードする関数

バージョン 2.6 で撤廃: flp モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールには、FORMSライブラリ (上記の fl モジュールを参照してください) とともに配布される ‘フォームデザイナー’ (fdesign) プログラムで作られたフォームの定義を読み込む関数が定義されています。

詳しくはPythonライブラリソースのディレクトリの中の flp.doc を参照してください。

XXX　完全な説明をここに書いて！

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.7. fm — Font Manager インターフェース

バージョン 2.6 で撤廃: fm モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールはIRIS Font Manager ライブラリへのアクセスを提供します。 Silicon Graphics マシン上だけで利用可能です。次も参照してください： 4Sight User’s Guide, section 1, chapter 5: “Using the IRIS Font Manager”。このモジュールは、まだ IRIS Font Manager への完全なインタフェースではありません。サポートされていない機能は次のものです： matrix operations; cache operations; character operations（代わりに string operations を使ってください）; font info のうちのいくつか; individual glyph metrics; printer matching。

以下の操作をサポートしています：

fm.init()

関数を初期化します。 fminit() を呼び出します。この関数は fm モジュールを最初にインポートすると自動的に呼び出されるので、普通、呼び出す必要はありません。

fm.findfont(fontname)

フォントハンドルオブジェクトを返します。 fmfindfont(fontname) を呼び出します。

fm.enumerate()

利用可能なフォント名のリストを返します。この関数は fmenumerate() へのインタフェースです。

fm.prstr(string)

現在のフォントを使って文字列をレンダリングします（下のフォントハンドルメソッド setfont() を参照）。 fmprstr(string) を呼び出します。

fm.setpath(string)

フォントの検索パスを設定します。 fmsetpath(string) を呼び出します。（XXX 機能しない！？！）

fm.fontpath()

現在のフォント検索パスを返します。

フォントハンドルオブジェクトは以下の操作をサポートします：

font handle.scalefont(factor)

このフォントを拡大／縮小したハンドルを返します。 fmscalefont(fh, factor) を呼び出します。

font handle.setfont()

このフォントを現在のフォントに設定します。注意：フォントハンドルオブジェクトが削除されると、設定は告知なしに元に戻ります。 fmsetfont(fh) を呼び出します。

font handle.getfontname()

このフォントの名前を返します。 fmgetfontname(fh) を呼び出します。

font handle.getcomment()

このフォントに関連付けられたコメント文字列を返します。コメント文字列が何もなければ例外を返します。 fmgetcomment(fh) を呼び出します。

font handle.getfontinfo()

このフォントに関連したデータを含むタプルを返します。これは fmgetfontinfo() へのインタフェースです。以下の数値を含むタプルを返します： (printermatched, fixed_width, xorig, yorig, xsize, ysize, height, nglyphs) 。

font handle.getstrwidth(string)

このフォントで string を描いたときの幅をピクセル数で返します。 fmgetstrwidth(fh, string) を呼び出します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.8. gl — Graphics Library インターフェース

バージョン 2.6 で撤廃: gl モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールは Silicon Graphics の Graphics Library へのアクセスを提供します。 Silicon Graphics マシン上だけで利用可能です。

警告

GL ライブラリの不適切な呼び出しによっては、Python インタープリタがコアを吐き出すことがあります。特に、GL のほとんどの関数では最初のウィンドウを開く前に呼び出すのは安全ではありません。

このモジュールはとても大きいので、ここに全てを記述することはできませんが、以下の説明で出発点としては十分でしょう。 C の関数のパラメータは、以下のような決まりに従って Python に翻訳されます：

全て（short、long、unsigned）の整数値（int）は Python の整数に相当します。

全ての浮動小数点数と倍精度浮動小数点数は Python の浮動小数点数に相当します。たいていの場合、Python の整数も使えます。

全ての配列は Python の一次元のリストに相当します。たいていの場合、タプルも使えます。

全ての文字列と文字の引数は、Python の文字列に相当します。例えば、 winopen('Hi There!') と rotate(900, 'z') 。

配列である引数の長さを特定するためだけに使われる全て（short、long、unsigned）の整数値の引数あるいは返り値は、無視されます。例えば、Cの呼び出しで、

lmdef(deftype, index, np, props)

これは Python では、こうなります。

lmdef(deftype, index, props)

出力のための引数は、引数のリストから省略されています；代わりにこれらは関数の返り値として渡されます。もし１つ以上の値が返されるのなら、返り値はタプルです。もし C の関数が通常の返り値（先のルールによって省略されません）と、出力のための引数の両方を取るなら、返り値はタプルの最初に来ます。例：Cの呼び出しで、

getmcolor(i, &red, &green, &blue)

これは Python ではこうなります。

red, green, blue = getmcolor(i)

以下の関数は一般的でないか、引数に特別な決まりを持っています：

gl.varray(argument)

v3d() の呼び出しに相当しますが、それよりも速いです。 argument は座標のリスト（あるいはタプル）です。各座標は (x, y, z) あるいは (x, y) のタプルでなければなりません。座標は２次元あるいは３次元が可能ですが、全て同次元でなければなりません。ですが、浮動小数点数と整数を混合して使えます。座標は（マニュアルページにあるように）必要であれば z = 0.0 と仮定して、常に３次元の精密な座標に変換され、各座標について v3d() が呼び出されます。

gl.nvarray()

n3f と v3f の呼び出しに相当しますが、それらよりも速いです。引数は法線と座標とのペアからなるシーケンス（リストあるいはタプル）です。各ペアは座標と、その座標からの法線とのタプルです。各座標と各法線は (x, y, z) からなるタプルでなければなりません。３つの座標が渡されなければなりません。浮動小数点数と整数を混合して使えます。各ペアについて、法線に対して n3f() が呼び出され、座標に対して v3f() が呼び出されます。

gl.vnarray()

nvarray() と似ていますが、各ペアは始めに座標を、２番目に法線を持っています。

gl.nurbssurface(s_k, t_k, ctl, s_ord, t_ord, type)

nurbs（非均一有理Bスプライン）曲面を定義します。 ctl[][] の次元は以下のように計算されます： [len(s_k) - s_ord] 、 [len(t_k) - t_ord] 。

gl.nurbscurve(knots, ctlpoints, order, type)

nurbs（非均一有理Bスプライン）曲線を定義します。 ctlpointsの長さは、 len(knots) - order です。

gl.pwlcurve(points, type)

区分線形曲線（piecewise-linear curve）を定義します。 points は座標のリストです。 type は N_ST でなければなりません。

gl.pick(n)

gl.select(n)

これらの関数はただ一つの引数を取り、pick/select に使うバッファのサイズを設定します。

gl.endpick()

gl.endselect()

これらの関数は引数を取りません。 pick/select に使われているバッファの大きさを示す整数のリストを返します。バッファがあふれているのを検出するメソッドはありません。

小さいですが完全なPythonのGLプログラムの例をここに挙げます：

import gl, GL, time

def main():
    gl.foreground()
    gl.prefposition(500, 900, 500, 900)
    w = gl.winopen('CrissCross')
    gl.ortho2(0.0, 400.0, 0.0, 400.0)
    gl.color(GL.WHITE)
    gl.clear()
    gl.color(GL.RED)
    gl.bgnline()
    gl.v2f(0.0, 0.0)
    gl.v2f(400.0, 400.0)
    gl.endline()
    gl.bgnline()
    gl.v2f(400.0, 0.0)
    gl.v2f(0.0, 400.0)
    gl.endline()
    time.sleep(5)

main()

参考

PyOpenGL: PythonのOpenGLとの結合 [http://pyopengl.sourceforge.net/]

OpenGL へのインタフェースが利用できます；詳しくは PyOpenGL プロジェクト http://pyopengl.sourceforge.net/ から情報を入手できます。これは、SGI のハードウェアが1996年頃より前である必要がないので、 OpenGL の方が良い選択かもしれません。

38.9. DEVICE — gl モジュールで使われる定数

バージョン 2.6 で撤廃: DEVICE モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールには、Silicon Graphics の Graphics Library で使われる定数が定義されています。これらはCのプログラマーがヘッダーファイル <gl/device.h> の中から使っているものです。詳しくはモジュールのソースファイルをご覧ください。

38.10. GL — gl モジュールで使われる定数

バージョン 2.6 で撤廃: GL モジュールは Python 3.0 での削除に向けて非推奨になりました。

このモジュールには Silicon Graphics の Graphics Library で使われる C のヘッダーファイル <gl/gl.h> の定数が定義されています。詳しくはモジュールのソースファイルをご覧ください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.11. imgfile — SGI imglib ファイルのサポート

バージョン 2.6 で撤廃: imagefile モジュールは Python 3.0 での削除に向けて非推奨になりました。

imgfile モジュールは、Python プログラムが SGI imglib 画像ファイル (.rgb ファイルとしても知られています) にアクセスできるようにします。このモジュールは完全なものにはほど遠いですが、その機能はある状況で十分役に立つものなので、ライブラリで提供されています。現在、カラーマップ形式のファイルはサポートされていません。

このモジュールでは以下の変数および関数が定義されています:

exception imgfile.error

この例外は、サポートされていないファイル形式の場合のような全てのエラーで送出されます。

imgfile.getsizes(file)

この関数はタプル (x, y, z) を返します。 x および y は画像のサイズをピクセルで表したもので、 z はピクセルあたりのバイト長です。3 バイトの RGB ピクセルと 1 バイトのグレイスケールピクセルのみが現在サポートされています。

imgfile.read(file)

この関数は指定されたファイル上の画像を読み出して復号化し、 Python 文字列として返します。この文字列は 1 バイトのグレイスケールピクセルか、4 バイトの RGBA ピクセルによるものです。左下のピクセルが文字列中の最初のピクセルになります。これは gl.lrectwrite() に渡すのに適した形式です。

imgfile.readscaled(file, x, y, filter[, blur])

この関数は read と同じですが、 x および y のサイズにスケールされた画像を返します。 filter および blur パラメタが省略された場合、単にピクセルデータを捨てたり複製したりすることによってスケール操作が行われるので、処理結果は、特に計算機上で合成した画像の場合にはおよそ完璧とはいえないものになります。

そうする代わりに、スケール操作後に画像を平滑化するために用いるフィルタを指定することができます。サポートされているフィルタの形式は'impulse' 、 'box' 、 'triangle' 、 'quadratic' 、および 'gaussian' です。フィルタを指定する場合、 blur はオプションのパラメタで、フィルタの不明瞭化度を指定します。標準の値は 1.0 です。

readscaled() は正しいアスペクト比をまったく維持しようとしないので、それはユーザの責任になります。

imgfile.ttob(flag)

この関数は画像のスキャンラインの読み書きを下から上に向かって行う (フラグがゼロの場合で、SGI GL 互換です) か、上から下に向かって行う (フラグが 1 の場合で、X 互換です) かを決定する大域的なフラグを設定します。標準の値はゼロです。

imgfile.write(file, data, x, y, z)

この関数は data 中の RGB またはグレイスケールのデータを画像ファイル file に書き込みます。 x および y には画像のサイズを与え、 z は 1 バイトグレイスケール画像の場合には 1 で、RGB 画像の場合には 3 (4 バイトの値として記憶され、下位 3 バイトが使われます) です。これらは gl.lrectread() が返すデータの形式です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

38. SGI IRIX 固有のサービス »

38.12. jpeg — JPEGファイルの読み書きを行う

バージョン 2.6 で撤廃: jpeg モジュールは Python 3.0 での削除に向けて非推奨になりました。

この jpeg モジュールは Independent JPEG Group (IJG) によって書かれた JEPG 圧縮及び展開アルゴリズムを提供します。 JPEG 形式は写真等の画像圧縮で標準的に利用され、ISO 10918で定義されてます。 JPEG、あるいは Independent JPEG Group ソフトウェアの詳細は、標準JPEG、若しくは提供されるソフトウェアのドキュメントを参照してください。

JPEGファイルを扱うポータブルなインタフェースは Fredrik Lundh による Python Imaging Library (PIL)があります。また、PILの情報は http://www.pythonware.com/products/pil/ で見つけることができます。

モジュール jpeg では、一つの例外といくつかの関数を定義しています。

exception jpeg.error

関数 compress() または decompress() のエラーで上げられる例外です。

jpeg.compress(data, w, h, b)

イメージファイルの幅 w 、高さ h 、1ピクセルあたりのバイト数 b を引数として扱います。データは SGI GL 順になっていて、最初のピクセルは左下端になります。また、これは gl.lrectread() が返す値をすぐに compress() にかけるためです。現在は、1 バイト若しくは 4 バイトのピクセルを取り扱うことができます。前者はグレースケール、後者はRGBカラーを扱います。 compress() は、圧縮された JFIF 形式のイメージが含まれた文字列を返します。

jpeg.decompress(data)

データは圧縮された JFIF 形式のイメージが含まれた文字列で、この関数はタプル (data, width, height, bytesperpixel) を返します。また、そのデータは gl.lrectwrite() を通過します。

jpeg.setoption(name, value)

compress() と decompress() を呼ぶための様々なオプションをセットします。次のオプションが利用できます:

オプション | 効果
'forcegray' | 入力がRGBでも強制的にグレースケールを出力します。
'quality' | 圧縮後イメージの品質を 0 から 100 の間の値で指定します (デフォルトは 75 です)。これは圧縮にのみ影響します。
'optimize' | ハフマンテーブルを最適化します。時間がかかりますが、高圧縮になります。これは圧縮にのみ影響します。
'smooth' | 圧縮されていないイメージ上でインターブロックスムーシングを行います。低品質イメージに役立ちます。これは展開にのみ影響します。

参考

JPEG Still Image Data Compression Standard

The canonical reference for the JPEG image format, by Pennebaker and Mitchell.

Information Technology - Digital Compression and Coding of Continuous-tone Still Images - Requirements and Guidelines [http://www.w3.org/Graphics/JPEG/itu-t81.pdf]

The ISO standard for JPEG is also published as ITU T.81. This is available online in PDF form.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

39. SunOS 固有のサービス

この章では、SunOSオペレーティングシステムバージョン5(Solarisバージョン2)に固有の機能を解説します。

39.1. sunaudiodev — Sun オーディオハードウェアへのアクセス

39.1.1. オーディオデバイスオブジェクト

39.2. SUNAUDIODEV — sunaudiodev で使われる定数

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

39. SunOS 固有のサービス »

39.1. sunaudiodev — Sun オーディオハードウェアへのアクセス

バージョン 2.6 で撤廃: sunaudiodev モジュールは Python 3.0 での削除に向け非推奨になりました。

このモジュールを使うと、Sun のオーディオインターフェースにアクセスできます。 Sun オーディオハードウェアは、1秒あたり8kのサンプリングレート、u-LAW フォーマットでオーディオデータを録音、再生できます。完全な説明文書はマニュアルページ audio(7I) にあります。

モジュール SUNAUDIODEV には、このモジュールで使われる定数が定義されています。

このモジュールには、以下の変数と関数が定義されています：

exception sunaudiodev.error

この例外は、全てのエラーについて発生します。引数は誤りを説明する文字列です。

sunaudiodev.open(mode)

この関数はオーディオデバイスを開き、Sun オーディオデバイスのオブジェクトを返します。こうすることで、オブジェクトが I/O に使用できるようになります。パラメータ mode は次のうちのいずれか一つで、録音のみには 'r' 、再生のみには 'w' 、録音と再生両方には 'rw' 、コントロールデバイスへのアクセスには 'control' です。レコーダーやプレーヤーには同時に１つのプロセスしかアクセスが許されていないので、必要な動作についてだけデバイスをオープンするのがいい考えです。詳しくは audio(7I) を参照してください。マニュアルページにあるように、このモジュールは環境変数 AUDIODEV の中のベースオーディオデバイスファイルネームを初めに参照します。見つからない場合は /dev/audio を参照します。コントロールデバイスについては、ベースオーディオデバイスに”ctl”を加えて扱われます。

39.1.1. オーディオデバイスオブジェクト

オーディオデバイスオブジェクトは open() で返され、このオブジェクトには以下のメソッドが定義されています (control オブジェクトは除きます。これには getinfo() 、 setinfo() 、 fileno() 、 drain() だけが定義されています）：

audio device.close()

このメソッドはデバイスを明示的に閉じます。オブジェクトを削除しても、それを参照しているものがあって、すぐに閉じてくれない場合に便利です。閉じられたデバイスを使うことはできません。

audio device.fileno()

デバイスに関連づけられたファイルディスクリプタを返します。これは、後述の SIGPOLL の通知を組み立てるのに使われます。

audio device.drain()

このメソッドは全ての出力中のプロセスが終了するまで待って、それから制御が戻ります。このメソッドの呼び出しはそう必要ではありません：オブジェクトを削除すると自動的にオーディオデバイスを閉じて、暗黙のうちに吐き出します。

audio device.flush()

このメソッドは全ての出力中のものを捨て去ります。ユーザの停止命令に対する反応の遅れ（1秒までの音声のバッファリングによって起こります）を避けるのに使われます。

audio device.getinfo()

このメソッドは入出力のボリューム値などの情報を引き出して、オーディオステータスのオブジェクト形式で返します。このオブジェクトには何もメソッドはありませんが、現在のデバイスの状態を示す多くの属性が含まれます。属性の名称と意味は <sun/audioio.h> と audio(7I) に記載があります。メンバー名は相当する C のものとは少し違っています：ステータスオブジェクトは１つの構造体です。その中の構造体である play のメンバーには名前の初めに o_ がついていて、 record には i_ がついています。そのため、C のメンバーである play.sample_rate は o_sample_rate として、 record.gain は i_gain として参照され、 monitor_gain はそのまま monitor_gain で参照されます。

audio device.ibufcount()

このメソッドは録音側でバッファリングされるサンプル数を返します。つまり、プログラムは同じ大きさのサンプルに対する read() の呼び出しをブロックしません。

audio device.obufcount()

このメソッドは再生側でバッファリングされるサンプル数を返します。残念ながら、この数値はブロックなしに書き込めるサンプル数を調べるのには使えません。というのは、カーネルの出力キューの長さは可変だからです。

audio device.read(size)

このメソッドはオーディオ入力から size のサイズのサンプルを読み込んで、Pythonの文字列として返します。この関数は必要なデータが得られるまで他の操作をブロックします。

audio device.setinfo(status)

このメソッドはオーディオデバイスのステータスパラメータを設定します。パラメータ status は getinfo() で返されたり、プログラムで変更されたオーディオステータスオブジェクトです。

audio device.write(samples)

パラメータとしてオーディオサンプルをPython文字列を受け取り、再生します。もし十分なバッファの空きがあればすぐに制御が戻り、そうでないならブロックされます。

オーディオデバイスは SIGPOLL を介して様々なイベントの非同期通知に対応しています。 Python でこれをどのようにしたらできるか、例を挙げます：

def handle_sigpoll(signum, frame):
    print 'I got a SIGPOLL update'

import fcntl, signal, STROPTS

signal.signal(signal.SIGPOLL, handle_sigpoll)
fcntl.ioctl(audio_obj.fileno(), STROPTS.I_SETSIG, STROPTS.S_MSG)

39.2. SUNAUDIODEV — sunaudiodev で使われる定数

バージョン 2.6 で撤廃: SUNAUDIODEV モジュールは Python 3.0 での削除に向け非推奨になりました。

これは sunaudiodev に付随するモジュールで、 MIN_GAIN 、 MAX_GAIN 、 SPEAKER などの便利なシンボル定数を定義しています。定数の名前は C の include ファイル <sun/audioio.h> のものと同じで、初めの文字列 AUDIO_ を除いたものです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

40. ドキュメント化されていないモジュール

現在ドキュメント化されていないが、ドキュメント化すべきモジュールを以下にざっと列挙します。どうぞこれらのドキュメントを寄稿してください！ (電子メールで docs@python.org に送ってください)。

この章のアイデアと元の文章内容は Fredrik Lundh のポストによるものです; この章の特定の内容は実際には改訂されてきています。

40.1. 雑多な有用ユーティリティ

以下のいくつかは非常に古く、かつ／またはあまり頑健ではありません。 “hmm.” マーク付きです。

ihooks

— import フックのサポートです (rexec のためのものです; 撤廃されるかもしれません)。 Python 3.0 で削除されました。

40.2. プラットフォーム固有のモジュール

これらのモジュールは os.path モジュールを実装するために用いられていますが、ここで触れる内容を超えてドキュメントされていません。これらはもう少しドキュメント化する必要があります。

ntpath

— Win32、 Win64、 WinCE、および OS/2 プラットフォームにおける os.path 実装です。

posixpath

— POSIXにおける os.path 実装です。

bsddb185

— まだBerkeleyDB 1.85を使用しているシステムで後方互換性を保つためのモジュール。通常、特定のBSD Unixベースのシステムでのみ利用可能。直接使用しないで下さい。

40.3. マルチメディア関連

audiodev

— 音声データを再生するためのプラットフォーム非依存の API です。 Python 3.0 で削除されました。

linuxaudiodev

— Linux 音声デバイスで音声データを再生します。Python 2.3 では ossaudiodev モジュールと置き換えられました。 Python 3.0 で削除されました。

sunaudio

— Sun 音声データヘッダを解釈します (撤廃されるか、ツール/デモになるかもしれません)。 Python 3.0 で削除されました。

toaiff

— “任意の” 音声ファイルを AIFF ファイルに変換します; おそらくツールかデモになるはずです。外部プログラム sox が必要です。 Python 3.0 で削除されました。

40.4. 文書化されていない Mac OS モジュール

40.4.1. applesingle — AppleSingle デコーダー

バージョン 2.6 で撤廃.

40.4.2. buildtools — BuildAppletとその仲間のヘルパーモジュール

バージョン 2.4 で撤廃.

40.4.3. cfmfile — コードフラグメントリソースを扱うモジュール

cfmfile は、コードフラグメントと関連する”cfrg”リソースを処理するモジュールです。このモジュールでコードフラグメントを分解やマージできて、全てのプラグインモジュールをまとめて、一つの実行可能ファイルにするため、BuildApplicationによって利用されます。

バージョン 2.4 で撤廃.

40.4.4. icopen — open() と Internet Config の置き換え

icopen をインポートすると、組込み open() を新しいファイル用にファイルタイプおよびクリエーターを設定するために Internet Configを使用するバージョンに置き換えます。

バージョン 2.6 で撤廃.

40.4.5. macerrors — MacOSのエラー

macerrors は、MacOS エラーコードを意味する定数定義を含みます。

バージョン 2.6 で撤廃.

40.4.6. macresource — スクリプトのリソースを見つける

macresource はスクリプトが MacPython 上や MacPython アプレットおよび OSX Python 上で起動されている時、特別な処理をせずにダイアログやメニューなどのようなリソースを見つけるためのヘルパースクリプトです。

バージョン 2.6 で撤廃.

40.4.7. Nav — NavServices の呼出し

Navigation Servicesの低レベルインターフェース。

バージョン 2.6 で撤廃.

40.4.8. PixMapWrapper — PixMapオブジェクトのラッパー

PixMapWrapper はPixMap オブジェクトを Python オブジェクトでラップしたもので、各フィールドに対し名前でアクセスできるようになります。 PIL 画像との相互の変換をするメソッドも用意されています。

バージョン 2.6 で撤廃.

40.4.9. videoreader — QuickTime ムービーの読み込み

videoreader は QuickTime ムービーを読み込み、デコードし、プログラムへ渡せます。このモジュールはさらにオーディオトラックをサポートしています。

バージョン 2.6 で撤廃.

40.4.10. W — FrameWork 上に作られたウイジェット

W ウィジェットは、 IDE で頻繁に使われています。

バージョン 2.6 で撤廃.

40.5. 撤廃されたもの

これらのモジュールは通常 import して利用できません; 利用できるようにするには作業を行わなければなりません。

これらの拡張モジュールのうち C で書かれたものは、標準の設定ではビルドされません。Unixでこれらのモジュールを有効にするには、ビルドツリー内の Modules/Setup の適切な行のコメントアウトを外して、モジュールを静的リンクするなら Python をビルドしなおし、動的にロードされる拡張を使うなら共有オブジェクトをビルドしてインストールする必要があります。

timing

— 高い精度で経過時間を計測します (time.clock() を使ってください)。 Python 3.0 で削除されました。

40.6. SGI 固有の拡張モジュール

以下は SGI 固有のモジュールで、現在のバージョンの SGI の実情が反映されていないかもしれません。

cl

— SGI 圧縮ライブラリへのインタフェースです。

sv

— SGI Indigo 上の “simple video” ボード(旧式のハードウェアです) へのインタフェースです。 Python 3.0 で削除されました。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python 標準ライブラリ »

41. 日本語訳について

この文書は、Pythonドキュメント翻訳プロジェクトによる Python Library Reference Release の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

41.1. 翻訳者一覧 (敬称略)

Akihiro Takizawa

Aoki Nobuaki

Atsuo Ishimoto

G.Yoshida

Hiroyuki Yoshimura

Minami Masanori

Shinsei Nakano

Sumiya Sakoda

YASOZUMI Daisuke

Yasushi Iwata

Yasushi MASUDA

Hiroshi Ayukawa

ippei-at-mbd.nifty.com

sakito

umi-at-venus.dti.ne.jp

ふるかわとおる

浦郷圭介

梶山大輔

根岸史郎

山中裕史

山本昇

新山祐介

森若和雄

TAKAGI Masahiro

MATSUI Tetsushi

Hiroshi

Okagawa

hkurosawa

INADA Naoki

Keisuke Urago

Shinya Okano

Toshiyuki Kawanishi

松江

森本哲也

osawa <osawa at sm.rim.or.jp> (2.0)

打田旭宏

cocoatomo

Arihiro TAKASE <hinaclegear at gmail.com>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み

Release: | 2.7
Date: | 2011年 12月 26日

このドキュメントでは、Python インタプリタを拡張するために C/C++ でモジュールを書く方法について述べます。拡張モジュールでは、新たな関数を定義できるだけでなく、新たなオブジェクト型とそのメソッドも定義できます。このドキュメントではまた、Python インタプリタを別のアプリケーションに埋め込み (embedding)、拡張言語として使う方法についても述べます。また、動的に(実行時に)拡張モジュールをロードする機能をOSがサポートしている場合に、動的ロード可能な拡張モジュールをコンパイルしてリンクする方法を示します。

このドキュメントでは、読者は Python について基礎的な知識を持ち合わせているものと仮定しています。形式ばらない Python 言語の入門には、 Python チュートリアル を読んでください。 Python 言語リファレンス を読めば、 Python 言語についてより形式的な定義を得られます。また、 Python 標準ライブラリ では、Python に広い適用範囲をもたらしている既存のオブジェクト型、関数、および (組み込み、および Python で書かれたものの両方の) モジュールについて解説しています。

Python/C API 全体の詳しい説明は、別のドキュメントである、 Python/C API リファレンスマニュアル を参照してください。

1. C や C++ による Python の拡張

1.1. 簡単な例

1.2. 幕間小話: エラーと例外

1.3. 例に戻る

1.4. モジュールのメソッドテーブルと初期化関数

1.5. コンパイルとリンク

1.6. C から Python 関数を呼び出す

1.7. 拡張モジュール関数でのパラメタ展開

1.8. 拡張モジュール関数のキーワードパラメタ

1.9. 任意の値を構築する

1.10. 参照カウント法

1.11. C++での拡張モジュール作成

1.12. 拡張モジュールに C API を提供する

2. 新しい型を定義する

2.1. 基本的なこと

2.2. タイプメソッド

3. distutils による C および C++ 拡張モジュールのビルド

3.1. 拡張モジュールの配布

4. Windows 上での C および C++ 拡張モジュールのビルド

4.1. 型どおりのアプローチ

4.2. Unix と Windows の相違点

4.3. DLL 使用の実際

5. 他のアプリケーションへの Python の埋め込み

5.1. 高水準の埋め込み

5.2. 超高水準の埋め込みから踏み出す: 概要

5.3. 純粋な埋め込み

5.4. 埋め込まれた Python の拡張

5.5. C++による Python の埋め込み

5.6. リンクに関する要件

6. このドキュメントについて

6.1. 翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

1. C や C++ による Python の拡張

C プログラムの書き方を知っているなら、Python に新たな組み込みモジュールを追加するのはきわめて簡単です。この新たなモジュール、拡張モジュール (extention module) を使うと、Python が直接行えない二つのこと: 新しい組み込みオブジェクトの実装、そして全ての C ライブラリ関数とシステムコールに対する呼び出し、ができるようになります。

拡張モジュールをサポートするため、Python API (Application Programmer’s Interface) では一連の関数、マクロおよび変数を提供していて、Python ランタイムシステムのほとんどの側面へのアクセス手段を提供しています。 Python API は、ヘッダ "Python.h" をインクルードして C ソースに取り込みます。

拡張モジュールのコンパイル方法は、モジュールの用途やシステムの設定方法に依存します; 詳細は後の章で説明します。

もし C ライブラリ関数やシステムコールを呼び出すような使い方を考えているなら、 C のコードをいちいち書く前に ctypes モジュールの使用を検討してください。 ctypes モジュールを使うと C のコードを扱う Python のコードが書けるようになるだけでなく、拡張モジュールを書きコンパイルして CPython に縛られてしまうよりも Python の実装間での互換性を高めることができます。

1.1. 簡単な例

spam (Monty Python ファンの好物ですね) という名の拡張モジュールを作成することにして、C ライブラリ関数 system() に対する Python インタフェースを作成したいとします。 [1] この関数は null で終端されたキャラクタ文字列を引数にとり、整数を返します。この関数を以下のようにして Python から呼び出せるようにしたいとします:

>>> import spam
>>> status = spam.system("ls -l")

まずは spammodule.c を作成するところから始めます。 (伝統として、 spam という名前のモジュールを作成する場合、モジュールの実装が入った C ファイルを spammodule.c と呼ぶことになっています; spammify のように長すぎるモジュール名の場合には、単に spammify.c にもできます。)

このファイルの最初の行は以下のようにします:

#include <Python.h>

これで、Python API を取り込みます (必要なら、モジュールの用途に関する説明や、著作権表示を追加します)。

ノート

Python は、システムによっては標準ヘッダの定義に影響するようなプリプロセッサ定義を行っているので、 Python.h をいずれの標準ヘッダよりも前にインクルード せねばなりません 。

Python.h で定義されているユーザから可視のシンボルは、全て接頭辞 Py または PY が付いています。ただし、標準ヘッダファイル内の定義は除きます。簡単のためと、Python 内で広範に使うことになるという理由から、 "Python.h" はいくつかの標準ヘッダファイル: <stdio.h> 、 <string.h> 、 <errno.h> 、および <stdlib.h> をインクルードしています。後者のヘッダファイルがシステム上になければ、 "Python.h" が関数 malloc() 、 free() および realloc() を直接定義します。

次にファイルに追加する内容は、Python 式 spam.system(string) を評価する際に呼び出されることになる C 関数です (この関数を最終的にどのように呼び出すかは、後ですぐわかります):

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

ここでは、Python の引数リスト (例えば、単一の式 "ls -l") から C 関数に渡す引数にそのまま変換しています。 C 関数は常に二つの引数を持ち、便宜的に self および args と呼ばれます。

self 引数には、モジュールレベルの関数であればモジュールが、メソッドにはオブジェクトインスタンスが渡されます。

args 引数は、引数の入った Python タプルオブジェクトへのポインタになります。タプル内の各要素は、呼び出しの際の引数リストにおける各引数に対応します。引数は Python オブジェクトです — C 関数で引数を使って何かを行うには、オブジェクトから C の値に変換せねばなりません。Python API の関数 PyArg_ParseTuple() は引数の型をチェックし、C の値に変換します。 PyArg_ParseTuple() はテンプレート文字列を使って、引数オブジェクトの型と、変換された値を入れる C 変数の型を判別します。これについては後で詳しく説明します。

PyArg_ParseTuple() は、全ての引数が正しい型を持っていて、アドレス渡しされた各変数に各引数要素を保存したときに真 (非ゼロ) を返します。この関数は不正な引数リストを渡すと偽 (ゼロ) を返します。後者の場合、関数は適切な例外を送出するので、呼び出し側は (例にもあるように) すぐに NULL を返すようにしてください。

1.2. 幕間小話: エラーと例外

Python インタプリタ全体を通して、一つの重要な取り決めがあります: それは、関数が処理に失敗した場合、例外状態をセットして、エラーを示す値 (通常は NULL ポインタ) を返さねばならない、ということです。例外はインタプリタ内の静的なグローバル変数に保存されます; この値が NULL の場合、例外は何も起きていないことになります。第二のグローバル変数には、例外の “付属値 (associated value)” (raise 文の第二引数) が入ります。第三の値には、エラーの発生源が Python コード内だった場合にスタックトレースバック (stack traceback) が入ります。これらの三つの変数は、それぞれ Python の変数 sys.exc_type 、 sys.exc_value および sys.exc_traceback と等価な C の変数です (Python ライブラリリファレンスの sys モジュールに関する節を参照してください。) エラーがどのように受け渡されるかを理解するには、これらの変数についてよく知っておくことが重要です。

Python API では、様々な型の例外をセットするための関数をいくつか定義しています。

もっともよく用いられるのは PyErr_SetString() です。引数は例外オブジェクトと C 文字列です。例外オブジェクトは通常、 PyExc_ZeroDivisionError のような定義済みのオブジェクトです。 C 文字列はエラーの原因を示し、Python 文字列オブジェクトに変換されて例外の “付属値” に保存されます。

もう一つ有用な関数として PyErr_SetFromErrno() があります。この関数は引数に例外だけをとり、付属値はグローバル変数 errno から構築します。もっとも汎用的な関数は PyErr_SetObject() で、二つのオブジェクト、例外と付属値を引数にとります。これら関数に渡すオブジェクトには Py_INCREF() を使う必要はありません。

例外がセットされているかどうかは、 PyErr_Occurred() を使って非破壊的に調べられます。この関数は現在の例外オブジェクトを返します。例外が発生していない場合には NULL を返します。通常は、関数の戻り値からエラーが発生したかを判別できるはずなので、 PyErr_Occurred() を呼び出す必要はありません。

関数 g を呼び出す f が、前者の関数の呼び出しに失敗したことを検出すると、 f 自体はエラー値 (大抵は NULL や -1) を返さねばなりません。しかし、 PyErr_*() 関数群のいずれかを呼び出す必要は ありません — なぜなら、 g がすでに呼び出しているからです。次いで f を呼び出したコードもエラーを示す値を 自らを呼び出したコード に返すことになりますが、同様に PyErr_*() は 呼び出しません 。以下同様に続きます — エラーの最も詳しい原因は、最初にエラーを検出した関数がすでに報告しているからです。エラーが Python インタプリタのメインループに到達すると、現在実行中の Python コードは一時停止し、 Python プログラマが指定した例外ハンドラを探し出そうとします。

(モジュールが PyErr_*() 関数をもう一度呼び出して、より詳細なエラーメッセージを提供するような状況があります。このような状況ではそうすべきです。とはいえ、一般的な規則としては、 PyErr_*() を何度も呼び出す必要はなく、ともすればエラーの原因に関する情報を失う結果になりがちです: これにより、ほとんどの操作が様々な理由から失敗するかもしれません)

ある関数呼び出しでの処理の失敗によってセットされた例外を無視するには、 PyErr_Clear() を呼び出して例外状態を明示的に消去しなくてはなりません。エラーをインタプリタには渡したくなく、自前で (何か他の作業を行ったり、何も起こらなかったかのように見せかけるような) エラー処理を完全に行う場合にのみ、 PyErr_Clear() を呼び出すようにすべきです。

malloc() の呼び出し失敗は、常に例外にしなくてはなりません — malloc() (または realloc()) を直接呼び出しているコードは、 PyErr_NoMemory() を呼び出して、失敗を示す値を返さねばなりません。オブジェクトを生成する全ての関数 (例えば PyInt_FromLong()) は PyErr_NoMemory() の呼び出しを済ませてしまうので、この規則が関係するのは直接 malloc() を呼び出すコードだけです。

また、 PyArg_ParseTuple() という重要な例外を除いて、整数の状態コードを返す関数はたいてい、Unix のシステムコールと同じく、処理が成功した際にはゼロまたは正の値を返し、失敗した場合には -1 を返します。

最後に、エラー標示値を返す際に、(エラーが発生するまでに既に生成してしまったオブジェクトに対して Py_XDECREF() や Py_DECREF() を呼び出して) ごみ処理を注意深く行ってください!

どの例外を返すかの選択は、ユーザに完全にゆだねられます。 PyExc_ZeroDivisionError のように、全ての組み込みの Python 例外には対応する宣言済みの C オブジェクトがあり、直接利用できます。もちろん、例外の選択は賢く行わねばなりません — ファイルが開けなかったことを表すのに PyExc_TypeError を使ったりはしないでください (この場合はおそらく PyExc_IOError の方にすべきでしょう)。引数リストに問題がある場合には、 PyArg_ParseTuple() はたいてい PyExc_TypeError を送出します。引数の値が特定の範囲を超えていたり、その他の満たすべき条件を満たさなかった場合には、 PyExc_ValueError が適切です。

モジュール固有の新たな例外も定義できます。定義するには、通常はファイルの先頭部分に静的なオブジェクト変数の宣言を行います:

static PyObject *SpamError;

そして、モジュールの初期化関数 (initspam()) の中で、例外オブジェクトを使って初期化します (ここではエラーチェックを省略しています):

PyMODINIT_FUNC
initspam(void)
{
    PyObject *m;

    m = Py_InitModule("spam", SpamMethods);
    if (m == NULL)
        return;

    SpamError = PyErr_NewException("spam.error", NULL, NULL);
    Py_INCREF(SpamError);
    PyModule_AddObject(m, "error", SpamError);
}

Python レベルでの例外オブジェクトの名前は spam.error になることに注意してください。 PyErr_NewException() 関数は、 組み込み例外 で述べられている Exception クラスを基底クラスに持つ例外クラスも作成できます (NULL の代わりに他のクラスを渡した場合は別です)。

SpamError 変数は、新たに生成された例外クラスへの参照を維持することにも注意してください; これは意図的な仕様です! 外部のコードが例外オブジェクトをモジュールから除去できるため、モジュールから新たに作成した例外クラスが見えなくなり、 SpamError がぶら下がりポインタ (dangling pointer) になってしまわないようにするために、クラスに対する参照を所有しておかねばなりません。もし SpamError がぶら下がりポインタになってしまうと、 C コードが例外を送出しようとしたときにコアダンプや意図しない副作用を引き起こすことがあります。

この例にある、関数の戻り値型に PyMODINIT_FUNC を使う方法については後で議論します。

PyErr_SetString() を次のように呼び出すと、拡張モジュールで例外 spam.error を送出することができます:

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    if (sts < 0) {
        PyErr_SetString(SpamError, "System command failed");
        return NULL;
    }
    return PyLong_FromLong(sts);
}

1.3. 例に戻る

先ほどの関数の例に戻ると、今度は以下の実行文を理解できるはずです:

if (!PyArg_ParseTuple(args, "s", &command))
    return NULL;

この実行文は、 PyArg_ParseTuple() がセットする例外によって、引数リストに何らかのエラーが生じたときに NULL (オブジェクトへのポインタを返すタイプの関数におけるエラー標示値) を返します。エラーでなければ、引数として与えた文字列値はローカルな変数 command にコピーされています。この操作はポインタ代入であり、ポインタが指している文字列に対して変更が行われるとは想定されていません (従って、標準 C では、変数 command は const char* command として適切に定義せねばなりません)。

次の文では、 PyArg_ParseTuple() で得た文字列を渡して Unix 関数 system() を呼び出しています:

sts = system(command);

spam.system() は sts を Python オブジェクトとして返さねばなりません。これには、 PyArg_ParseTuple() の逆ともいうべき関数 Py_BuildValue() を使います: Py_BuildValue() は書式化文字列と任意の数の C の値を引数にとり、新たな Python オブジェクトを返します。 Py_BuildValue() に関する詳しい情報は後で示します。

return Py_BuildValue("i", sts);

上の場合では、 Py_BuildValue() は整数オブジェクトを返します。(そう、整数ですら、 Python においてはヒープ上のオブジェクトなのです! )

何ら有用な値を返さない関数 (void を返す関数) に対応する Python の関数は None を返さねばなりません。関数に None を返させるには、以下のような慣用句を使います (この慣用句は Py_RETURN_NONE マクロに実装されています):

Py_INCREF(Py_None);
return Py_None;

Py_None は特殊な Pyhton オブジェクトである None に対応する C での名前です。これまで見てきたようにほとんどのコンテキストで “エラー” を意味する NULL ポインタとは違い、 None は純粋な Python のオブジェクトです。

1.4. モジュールのメソッドテーブルと初期化関数

さて、前に約束したように、 spam_system() を Python プログラムからどうやって呼び出すかをこれから示します。まずは、関数名とアドレスを “メソッドテーブル (method table)” に列挙する必要があります:

static PyMethodDef SpamMethods[] = {
    ...
    {"system",  spam_system, METH_VARARGS,
     "Execute a shell command."},
    ...
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

リスト要素の三つ目のエントリ (METH_VARARGS) に注意してください。このエントリは、C 関数が使う呼び出し規約をインタプリタに教えるためのフラグです。通常この値は METH_VARARGS か METH_VARARGS | METH_KEYWORDS のはずです; 0 は旧式の PyArg_ParseTuple() の変化形が使われることを意味します。

METH_VARARGS だけを使う場合、C 関数は、Python レベルでの引数が PyArg_ParseTuple() が受理できるタプルの形式で渡されるものと想定しなければなりません; この関数についての詳細は下で説明します。

関数にキーワード引数が渡されることになっているのなら、第三フィールドに METH_KEYWORDS ビットをセットできます。この場合、C 関数は第三引数に PyObject * を受理するようにせねばなりません。このオブジェクトは、キーワード引数の辞書になります。こうした関数で引数を解釈するには、 PyArg_ParseTupleAndKeywords() を使ってください。

メソッドテーブルは、モジュールの初期化関数内でインタプリタに渡さねばなりません。初期化関数はモジュールの名前を name としたときに initname() という名前でなければならず、モジュールファイル内で定義されているもののうち、唯一の非 static 要素でなければなりません:

PyMODINIT_FUNC
initspam(void)
{
    (void) Py_InitModule("spam", SpamMethods);
}

PyMODINIT_FUNC は関数の戻り値を void になるように宣言し、プラットフォーム毎に必要とされる、特有のリンク宣言 (linkage declaration) を定義すること、さらに C++ の場合には関数を extern "C" に宣言することに注意してください。

Python プログラムがモジュール spam を初めて import するとき、 initspam() が呼び出されます。 (Python の埋め込みに関するコメントは下記を参照してください。) initspam() は Py_InitModule() を呼び出して “モジュールオブジェクト” を生成し (オブジェクトは "spam" をキーとして辞書 sys.modules に挿入されます)、第二引数として与えたメソッドテーブル (PyMethodDef 構造体の配列) の情報に基づいて、組み込み関数オブジェクトを新たなモジュールに挿入していきます。 Py_InitModule() は、自らが生成した (この段階ではまだ未使用の) モジュールオブジェクトへのポインタを返します。 Py_InitModule() は、幾つかのエラーでは致命的エラーで abort し、それ以外のモジュールが満足に初期化できなかった場合は NULL を返します。

Python を埋め込む場合には、 _PyImport_Inittab テーブルのエントリ内に initspam() がない限り、 initspam() は自動的には呼び出されません。この問題を解決する最も簡単な方法は、 Py_Initialize() や PyMac_Initialize() を呼び出した後に initspam() を直接呼び出し、静的にリンクしておいたモジュールを静的に初期化してしまうというものです:

int
main(int argc, char *argv[])
{
    /* Python インタプリタに argv[0] を渡す */
    Py_SetProgramName(argv[0]);

    /* Python インタプリタを初期化する。必ず必要。 */
    Py_Initialize();

    /* 静的モジュールを追加する */
    initspam();

Python ソース配布物中の Demo/embed/demo.c ファイル内に例があります。

ノート

単一のプロセス内 (または fork() 後の exec() が介入していない状態) における複数のインタプリタにおいて、 sys.module からエントリを除去したり新たなコンパイル済みモジュールを import したりすると、拡張モジュールによっては問題を生じることがあります。拡張モジュールの作者は、内部データ構造を初期化する際にはよくよく用心すべきです。また、 reload() 関数を拡張モジュールに対して利用でき、この場合はモジュール初期化関数 (initspam()) は呼び出されますが、モジュールが動的にロード可能なオブジェクトファイル (Unixでは .so 、Windows では .dll) から読み出された場合にはモジュールファイルを再読み込みしないので注意してください。

より実質的なモジュール例は、Python ソース配布物に Modules/xxmodule.c という名前で入っています。このファイルはテンプレートとしても利用できますし、単に例としても読めます。

1.5. コンパイルとリンク

新しい拡張モジュールを使えるようになるまで、まだ二つの作業: コンパイルと、Python システムへのリンク、が残っています。動的読み込み (dynamic loading) を使っているのなら、作業の詳細は自分のシステムが使っている動的読み込みの形式によって変わるかもしれません; 詳しくは、拡張モジュールのビルドに関する章 (distutils による C および C++ 拡張モジュールのビルド 章) や、Windows におけるビルドに関係する追加情報の章 (Windows 上での C および C++ 拡張モジュールのビルド 章) を参照してください。

動的読み込みを使えなかったり、モジュールを常時 Python インタプリタの一部にしておきたい場合には、インタプリタのビルド設定を変更して再ビルドしなければならなくなるでしょう。Unixでは、幸運なことにこの作業はとても単純です: 単に自作のモジュールファイル (例えば spammodule.c ) を展開したソース配布物の Modules/ ディレクトリに置き、 Modules/Setup.local に自分のファイルを説明する以下の一行:

spam spammodule.o

を追加して、トップレベルのディレクトリで make を実行して、インタプリタを再ビルドするだけです。 Modules/ サブディレクトリでも make を実行できますが、前もって ‘make Makefile’ を実行して Makefile を再ビルドしておかなければならりません。(この作業は Setup ファイルを変更するたびに必要です。)

モジュールが別のライブラリとリンクされている必要がある場合、ライブラリも設定ファイルに列挙できます。例えば以下のようにします:

spam spammodule.o -lX11

1.6. C から Python 関数を呼び出す

これまでは、Python からの C 関数の呼び出しに重点を置いて述べてきました。ところでこの逆: C からの Python 関数の呼び出しもまた有用です。とりわけ、いわゆる “コールバック” 関数をサポートするようなライブラリを作成する際にはこの機能が便利です。ある C インタフェースがコールバックを利用している場合、同等の機能を提供する Python コードでは、しばしば Python プログラマにコールバック機構を提供する必要があります; このとき実装では、 C で書かれたコールバック関数から Python で書かれたコールパック関数を呼び出すようにする必要があるでしょう。もちろん、他の用途も考えられます。

幸運なことに、Python インタプリタは簡単に再帰呼び出しでき、 Python 関数を呼び出すための標準インタフェースもあります。 (Python パーザを特定の入力文字を使って呼び出す方法について詳説するつもりはありません — この方法に興味があるなら、 Python ソースコードの Modules/main.c にある、コマンドラインオプション -c の実装を見てください)

Python 関数の呼び出しは簡単です。まず、C のコードに対してコールバックを登録しようとする Python プログラムは、何らかの方法で Python の関数オブジェクトを渡さねばなりません。このために、コールバック登録関数 (またはその他のインタフェース) を提供せねばなりません。このコールバック登録関数が呼び出された際に、引き渡された Python 関数オブジェクトへのポインタをグローバル変数に — あるいは、どこか適切な場所に — 保存します (関数オブジェクトを Py_INCREF() するようよく注意してください!)。例えば、以下のような関数がモジュールの一部になっていることでしょう:

static PyObject *my_callback = NULL;

static PyObject *
my_set_callback(PyObject *dummy, PyObject *args)
{
    PyObject *result = NULL;
    PyObject *temp;

    if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
        if (!PyCallable_Check(temp)) {
            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
            return NULL;
        }
        Py_XINCREF(temp);         /* 新たなコールバックへの参照を追加 */
        Py_XDECREF(my_callback);  /* 以前のコールバックを捨てる */
        my_callback = temp;       /* 新たなコールバックを記憶 */
        /* "None" を返す際の定型句 */
        Py_INCREF(Py_None);
        result = Py_None;
    }
    return result;
}

この関数は METH_VARARGS フラグを使ってインタプリタに登録せねばなりません; METH_VARARGS フラグについては、 モジュールのメソッドテーブルと初期化関数 で説明しています。 PyArg_ParseTuple() 関数とその引数については、 拡張モジュール関数でのパラメタ展開 に記述しています。

Py_XINCREF() および Py_XDECREF() は、オブジェクトに対する参照カウントをインクリメント/デクリメントするためのマクロで、 NULL ポインタが渡されても安全に操作できる形式です (とはいえ、上の流れでは temp が NULL になることはありません)。これらのマクロと参照カウントについては、 参照カウント法 で説明しています。

その後、コールバック関数を呼び出す時が来たら、C 関数 PyObject_CallObject() を呼び出します。この関数には二つの引数: Python 関数と Python 関数の引数リストがあり、いずれも任意の Python オブジェクトを表すポインタ型です。引数リストは常にタプルオブジェクトでなければならず、その長さは引数の数になります。Python 関数を引数なしで呼び出すのなら、 NULL か空のタプルを渡します; 単一の引数で関数を呼び出すのなら、単要素 (singleton) のタプルを渡します。 Py_BuildValue() の書式化文字列中に、ゼロ個または一個以上の書式化コードが入った丸括弧がある場合、この関数はタプルを返します。以下に例を示します:

int arg;
PyObject *arglist;
PyObject *result;
...
arg = 123;
...
/* ここでコールバックを呼ぶ */
arglist = Py_BuildValue("(i)", arg);
result = PyObject_CallObject(my_callback, arglist);
Py_DECREF(arglist);

PyObject_CallObject() は Python オブジェクトへのポインタを返します; これは Python 関数からの戻り値になります。 PyObject_CallObject() は、引数に対して “参照カウント中立 (reference-count- neutral)” です。上の例ではタプルを生成して引数リストとして提供しており、このタプルは呼び出し直後に Py_DECREF() しています。

PyObject_CallObject() は戻り値として “新しい” オブジェクト: 新規に作成されたオブジェクトか、既存のオブジェクトの参照カウントをインクリメントしたものを返します。従って、このオブジェクトをグローバル変数に保存したいのでないかぎり、たとえこの戻り値に興味がなくても (むしろ、そうであればなおさら!) 何がしかの方法で戻り値オブジェクトを Py_DECREF() しなければなりません。

とはいえ、戻り値を Py_DECREF() する前には、値が NULL でないかチェックしておくことが重要です。もし NULL なら、呼び出した Python 関数は例外を送出して終了させられています。 PyObject_CallObject() を呼び出しているコード自体もまた Python から呼び出されているのであれば、今度は C コードが自分を呼び出している Python コードにエラー標示値を返さねばなりません。それにより、インタプリタはスタックトレースを出力したり、例外を処理するための Python コードを呼び出したりできます。例外の送出が不可能だったり、したくないのなら、 PyErr_Clear() を呼んで例外を消去しておかねばなりません。例えば以下のようにします:

if (result == NULL)
    return NULL; /* エラーを返す */
...use result...
Py_DECREF(result);

Python コールバック関数をどんなインタフェースにしたいかによっては、引数リストを PyObject_CallObject() に与えなければならない場合もあります。あるケースでは、コールバック関数を指定したのと同じインタフェースを介して、引数リストも渡されているかもしれません。また別のケースでは、新しいタプルを構築して引数リストを渡さねばならないかもしれません。この場合最も簡単なのは Py_BuildValue() を呼ぶやり方です。例えば、整数のイベントコードを渡したければ、以下のようなコードを使うことになるでしょう:

PyObject *arglist;
...
arglist = Py_BuildValue("(l)", eventcode);
result = PyObject_CallObject(my_callback, arglist);
Py_DECREF(arglist);
if (result == NULL)
    return NULL; /* エラーを返す */
/* 場合によってはここで結果を使うかもね */
Py_DECREF(result);

Py_DECREF(arglist) が呼び出しの直後、エラーチェックよりも前に置かれていることに注意してください! また、厳密に言えば、このコードは完全ではありません: Py_BuildValue() はメモリ不足におちいるかもしれず、チェックしておくべきです。

通常の引数とキーワード引数をサポートする PyObject_Call() を使って、キーワード引数を伴う関数呼び出しをすることができます。上の例と同じように、 Py_BuildValue() を作って辞書を作ります。

PyObject *dict;
...
dict = Py_BuildValue("{s:i}", "name", val);
result = PyObject_Call(my_callback, NULL, dict);
Py_DECREF(dict);
if (result == NULL)
    return NULL; /* エラーを返す */
/* 場合によってはここで結果を使うかもね */
Py_DECREF(result);

1.7. 拡張モジュール関数でのパラメタ展開

PyArg_ParseTuple() は、以下のように宣言されています:

int PyArg_ParseTuple(PyObject *arg, char *format, ...);

引数 arg は C 関数から Python に渡される引数リストが入ったタプルオブジェクトでなければなりません。 format 引数は書式化文字列で、 Python/C API リファレンスマニュアルの 引数の解釈と値の構築 で解説されている書法に従わねばなりません。残りの引数は、それぞれの変数のアドレスで、書式化文字列から決まる型になっていなければなりません。

PyArg_ParseTuple() は Python 側から与えられた引数が必要な型になっているか調べるのに対し、 PyArg_ParseTuple() は呼び出しの際に渡された C 変数のアドレスが有効な値を持つか調べられないことに注意してください: ここで間違いを犯すと、コードがクラッシュするかもしれませんし、少なくともでたらめなビットをメモリに上書きしてしまいます。慎重に!

呼び出し側に提供されるオブジェクトへの参照はすべて 借用 参照 (borrowed reference) になります; これらのオブジェクトの参照カウントをデクリメントしてはなりません!

以下にいくつかの呼び出し例を示します:

int ok;
int i, j;
long k, l;
const char *s;
int size;

ok = PyArg_ParseTuple(args, ""); /* 引数なし */
    /* Python での呼び出し: f() */

ok = PyArg_ParseTuple(args, "s", &s); /* 文字列 */
    /* Python での呼び出し例: f('whoops!') */

ok = PyArg_ParseTuple(args, "lls", &k, &l, &s);
    /* 二つの long と文字列 */
    /* Python での呼び出し例: f(1, 2, 'three') */

ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size);
    /* 二つの int と文字列、文字列のサイズも返す */
    /* Python での呼び出し例: f((1, 2), 'three') */

{
    const char *file;
    const char *mode = "r";
    int bufsize = 0;
    ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize);
    /* 文字列、オプションとして文字列がもう一つと整数が一つ */
    /* Python での呼び出し例:
       f('spam')
       f('spam', 'w')
       f('spam', 'wb', 100000) */
}

{
    int left, top, right, bottom, h, v;
    ok = PyArg_ParseTuple(args, "((ii)(ii))(ii)",
             &left, &top, &right, &bottom, &h, &v);
    /* 矩形と点を表現するデータ */
    /* Python での呼び出し例:
       f(((0, 0), (400, 300)), (10, 10)) */
}

{
    Py_complex c;
    ok = PyArg_ParseTuple(args, "D:myfunction", &c);
    /* 複素数。エラー発生時用に関数名も指定 */
    /* Python での呼び出し例: myfunction(1+2j) */
}

1.8. 拡張モジュール関数のキーワードパラメタ

PyArg_ParseTupleAndKeywords() は、以下のように宣言されています:

int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
                                char *format, char *kwlist[], ...);

arg と format パラメタは PyArg_ParseTuple() のものと同じです。 kwdict パラメタはキーワード引数の入った辞書で、 Python ランタイムシステムから第三パラメタとして受け取ります。 kwlist パラメタは各パラメタを識別するための文字列からなる、 NULL 終端されたリストです; 各パラメタ名は format 中の型情報に対して左から右の順に照合されます。

成功すると PyArg_ParseTupleAndKeywords() は真を返し、それ以外の場合には適切な例外を送出して偽を返します。

ノート

キーワード引数を使っている場合、タプルは入れ子にして使えません! kwlist 内に存在しないキーワードパラメタが渡された場合、 TypeError の送出を引き起こします。

以下にキーワードを使ったモジュール例を示します。これは Geoff Philbrick (philbrick@hks.com) によるプログラム例をもとにしています。

#include "Python.h"

static PyObject *
keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
{
    int voltage;
    char *state = "a stiff";
    char *action = "voom";
    char *type = "Norwegian Blue";

    static char *kwlist[] = {"voltage", "state", "action", "type", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
                                     &voltage, &state, &action, &type))
        return NULL;

    printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",
           action, voltage);
    printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);

    Py_INCREF(Py_None);

    return Py_None;
}

static PyMethodDef keywdarg_methods[] = {
    / * PyCFunction の値は PyObject* パラメタを二つだけしか引数に
     * 取らないが、 keywordarg_parrot() は三つとるので、キャストが
     * 必要。
     */
    {"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
     "Print a lovely skit to standard output."},
    {NULL, NULL, 0, NULL}   /* センティネル値 */
};

void
initkeywdarg(void)
{
  /* モジュールを作成して関数を追加する */
  Py_InitModule("keywdarg", keywdarg_methods);
}

1.9. 任意の値を構築する

Py_BuildValue() は PyArg_ParseTuple() の対極に位置するものです。この関数は以下のように定義されています:

PyObject *Py_BuildValue(char *format, ...);

Py_BuildValue() は、 PyArg_ParseTuple() の認識する一連の書式化単位に似た書式化単位を認識します。ただし (関数への出力ではなく、入力に使われる) 引数はポインタではなく、ただの値でなければなりません。 Python から呼び出された C 関数が返す値として適切な、新たな Python オブジェクトを返します。

PyArg_ParseTuple() とは一つ違う点があります: PyArg_ParseTuple() は第一引数をタプルにする必要があります (Python の引数リストは内部的には常にタプルとして表現されるからです) が、 Py_BuildValue() はタプルを生成するとは限りません。 Py_BuildValue() は書式化文字列中に書式化単位が二つかそれ以上入っている場合にのみタプルを構築します。書式化文字列が空なら、 None を返します。きっかり一つの書式化単位なら、その書式化単位が記述している何らかのオブジェクトになります。サイズが 0 や 1 のタプル返させたいのなら、書式化文字列を丸括弧で囲います。

以下に例を示します (左に呼び出し例を、右に構築される Python 値を示します):

Py_BuildValue("")                        None
Py_BuildValue("i", 123)                  123
Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)
Py_BuildValue("s", "hello")              'hello'
Py_BuildValue("ss", "hello", "world")    ('hello', 'world')
Py_BuildValue("s#", "hello", 4)          'hell'
Py_BuildValue("()")                      ()
Py_BuildValue("(i)", 123)                (123,)
Py_BuildValue("(ii)", 123, 456)          (123, 456)
Py_BuildValue("(i,i)", 123, 456)         (123, 456)
Py_BuildValue("[i,i]", 123, 456)         [123, 456]
Py_BuildValue("{s:i,s:i}",
              "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii)) (ii)",
              1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))

1.10. 参照カウント法

C や C++のような言語では、プログラマはヒープ上のメモリを動的に確保したり解放したりする責任があります。こうした作業は C では関数 malloc() や free() で行います。C++では本質的に同じ意味で演算子 new や delete が使われます。そこで、以下の議論は C の場合に限定して行います。

malloc() が確保する全てのメモリブロックは、最終的には free() を厳密に一度だけ呼び出して利用可能メモリのプールに戻さねばなりません。そこで、適切な時に free() を呼び出すことが重要になります。あるメモリブロックに対して、 free() を呼ばなかったにもかかわらずそのアドレスを忘却してしまうと、ブロックが占有しているメモリはプログラムが終了するまで再利用できなくなります。これはメモリリーク(memory leak) と呼ばれています。逆に、プログラムがあるメモリブロックに対して free() を呼んでおきながら、そのブロックを使い続けようとすると、別の malloc() 呼び出しによって行われるブロックの再利用と衝突を起こします。これは解放済みメモリの使用 (using freed memory) と呼ばれます。これは初期化されていないデータに対する参照と同様のよくない結果 — コアダンプ、誤った参照、不可解なクラッシュ — を引き起こします。

よくあるメモリリークの原因はコード中の普通でない処理経路です。例えば、ある関数があるメモリブロックを確保し、何らかの計算を行って、再度ブロックを解放するとします。さて、関数の要求仕様を変更して、計算に対するテストを追加すると、エラー条件を検出し、関数の途中で処理を戻すようになるかもしれません。この途中での終了が起きるとき、確保されたメモリブロックは解放し忘れやすいのです。コードが後で追加された場合には特にそうです。このようなメモリリークが一旦紛れ込んでしまうと、長い間検出されないままになることがよくあります: エラーによる関数の終了は、全ての関数呼び出しのに対してほんのわずかな割合しか起きず、その一方でほとんどの近代的な計算機は相当量の仮想記憶を持っているため、メモリリークが明らかになるのは、長い間動作していたプロセスがリークを起こす関数を何度も使った場合に限られるからです。従って、この種のエラーを最小限にとどめるようなコーディング規約や戦略を設けて、不慮のメモリリークを避けることが重要なのです。

Python は malloc() や free() を非常によく利用するため、メモリリークの防止に加え、解放されたメモリの使用を防止する戦略が必要です。このために選ばれたのが参照カウント法 (reference counting) と呼ばれる手法です。参照カウント法の原理は簡単です: 全てのオブジェクトにはカウンタがあり、オブジェクトに対する参照がどこかに保存されたらカウンタをインクリメントし、オブジェクトに対する参照が削除されたらデクリメントします。カウンタがゼロになったら、オブジェクトへの最後の参照が削除されたことになり、オブジェクトは解放されます。

もう一つの戦略は自動ガベージコレクション (automatic garbage collection) と呼ばれています。 (参照カウント法はガベージコレクション戦略の一つとして挙げられることもあるので、二つを区別するために筆者は “自動 (automatic)” を使っています。) 自動ガベージコレクションの大きな利点は、ユーザが free() を明示的によばなくてよいことにあります。 (速度やメモリの有効利用性も利点として主張されています — が、これは確たる事実ではありません。) C における自動ガベージコレクションの欠点は、真に可搬性のあるガベージコレクタが存在しないということです。それに対し、参照カウント法は可搬性のある実装ができます (malloc() や free() を利用できるのが前提です — C 標準はこれを保証しています)。いつの日か、十分可搬性のあるガベージコレクタが C で使えるようになるかもしれませんが、それまでは参照カウント法でやっていく以外にはないのです。

Python では、伝統的な参照カウント法の実装を行っている一方で、参照の循環を検出するために働く循環参照検出機構 (cycle detector) も提供しています。循環参照検出機構のおかげで、直接、間接にかかわらず循環参照の生成を気にせずにアプリケーションを構築できます; というのも、参照カウント法だけを使ったガベージコレクション実装にとって循環参照は弱点だからです。循環参照は、(間接参照の場合も含めて) 相互への参照が入ったオブジェクトから形成されるため、循環内のオブジェクトは各々非ゼロの参照カウントを持ちます。典型的な参照カウント法の実装では、たとえ循環参照を形成するオブジェクトに対して他に全く参照がないとしても、循環参照内のどのオブジェクトに属するメモリも再利用できません。

循環参照検出機構は、ごみとなった循環参照を検出し、Python で実装された後始末関数 (finalizer、 __del__() メソッド) が定義されていないかぎり、それらのメモリを再利用できます。後始末関数がある場合、検出機構は検出した循環参照を gc モジュールに (具体的にはこのモジュールの garbage 変数内) に公開します。 gc モジュールではまた、検出機構 (collect() 関数) を実行する方法や設定用のインタフェース、実行時に検出機構を無効化する機能も公開しています。循環参照検出機構はオプションの機構とみなされています; デフォルトで入ってはいますが、Unix プラットフォーム (Mac OS X も含みます) ではビルド時に configure スクリプトの --without-cycle-gc オプションを使って、他のプラットフォームでは pyconfig.h ヘッダの WITH_CYCLE_GC 定義をはずして無効にできます。こうして循環参照検出機構を無効化すると、 gc モジュールは利用できなくなります。

1.10.1. Python における参照カウント法

Python には、参照カウントのインクリメントやデクリメントを処理する二つのマクロ、 Py_INCREF(x) と Py_DECREF(x) があります。 Py_DECREF() は、参照カウントがゼロに到達した際に、オブジェクトのメモリ解放も行います。柔軟性を持たせるために、 free() を直接呼び出しません — その代わりにオブジェクトの型オブジェクト (type object) を介します。このために (他の目的もありますが)、全てのオブジェクトには自身の型オブジェクトに対するポインタが入っています。

さて、まだ重大な疑問が残っています: いつ Py_INCREF(x) や Py_DECREF(x) を使えばよいのでしょうか? まず、いくつかの用語説明から始めさせてください。まず、オブジェクトは “占有 (own)” されることはありません; しかし、あるオブジェクトに対する参照の所有 own a reference はできます。オブジェクトの参照カウントは、そのオブジェクトが参照の所有を受けている回数と定義されています。参照の所有者は、参照が必要なくなった際に Py_DECREF() を呼び出す役割を担います。参照の所有権は委譲 (transfer) できます。所有参照 (owned reference) の放棄には、渡す、保存する、 Py_DECREF() を呼び出す、という三つの方法があります。所有参照を処理し忘れると、メモリリークを引き起こします。

オブジェクトに対する参照は、借用 (borrow) も可能です。 [2] 参照の借用者は、 Py_DECREF() を呼んではなりません。借用者は、参照の所有者から借用した期間を超えて参照を保持し続けてはなりません。所有者が参照を放棄した後で借用参照を使うと、解放済みメモリを使用してしまう危険があるので、絶対に避けねばなりません。 [3]

参照の借用が参照の所有よりも優れている点は、コードがとりうるあらゆる処理経路で参照を廃棄しておくよう注意しなくて済むことです — 別の言い方をすれば、借用参照の場合には、処理の途中で関数を終了してもメモリリークの危険を冒すことがない、ということです。逆に、所有よりも不利な点は、ごくまともに見えるコードが、実際には参照の借用元で放棄されてしまった後にその参照を使うかもしれないような微妙な状況があるということです。

Py_INCREF() を呼び出すと、借用参照を所有参照 に変更できます。この操作は参照の借用元の状態には影響しません — Py_INCREF() は新たな所有参照を生成し、参照の所有者が担うべき全ての責任を課します (つまり、新たな参照の所有者は、以前の所有者と同様、参照の放棄を適切に行わねばなりません)。

1.10.2. 所有権にまつわる規則

オブジェクトへの参照を関数の内外に渡す場合には、オブジェクトの所有権が参照と共に渡されるか否かが常に関数インタフェース仕様の一部となります。

オブジェクトへの参照を返すほとんどの関数は、参照とともに所有権も渡します。特に、 PyInt_FromLong() や Py_BuildValue() のように、新しいオブジェクトを生成する関数は全て所有権を相手に渡します。オブジェクトが実際には新たなオブジェクトでなくても、そのオブジェクトに対する新たな参照の所有権を得ます。例えば、 PyInt_FromLong() はよく使う値をキャッシュしており、キャッシュされた値への参照を返すことがあります。

PyObject_GetAttrString() のように、あるオブジェクトから別のオブジェクトを抽出するような関数もまた、参照とともに所有権を委譲します。こちらの方はやや理解しにくいかもしれません。というのはよく使われるルーチンのいくつかが例外となっているからです: PyTuple_GetItem() 、 PyList_GetItem() 、 PyDict_GetItem() 、および PyDict_GetItemString() は全て、タプル、リスト、または辞書から借用参照を返します。

PyImport_AddModule() は、実際にはオブジェクトを生成して返すことがあるにもかかわらず、借用参照を返します: これが可能なのは、生成されたオブジェクトに対する所有参照は sys.modules に保持されるからです。

オブジェクトへの参照を別の関数に渡す場合、一般的には、関数側は呼び出し手から参照を借用します — 参照を保存する必要があるなら、関数側は Py_INCREF() を呼び出して独立した所有者になります。とはいえ、この規則には二つの重要な例外: PyTuple_SetItem() と PyList_SetItem() があります。これらの関数は、渡された引数要素に対して所有権を乗っ取り (take over) ます — たとえ失敗してもです! (PyDict_SetItem() とその仲間は所有権を乗っ取りません — これらはいわば “普通の” 関数です。)

Python から C 関数が呼び出される際には、C 関数は呼び出し側から引数への参照を借用します。C 関数の呼び出し側はオブジェクトへの参照を所有しているので、借用参照の生存期間が保証されるのは関数が処理を返すまでです。このようにして借用参照を保存したり他に渡したりしたい場合にのみ、 Py_INCREF() を使って所有参照にする必要があります。

Python から呼び出された C 関数が返す参照は所有参照でなければなりません — 所有権は関数から呼び出し側へと委譲されます。

1.10.3. 薄氷

数少ない状況において、一見無害に見える借用参照の利用が問題をひきおこすことがあります。この問題はすべて、インタプリタが非明示的に呼び出され、インタプリタが参照の所有者に参照を放棄させてしまう状況と関係しています。

知っておくべきケースのうち最初の、そして最も重要なものは、リスト要素に対する参照を借りている際に起きる、関係ないオブジェクトに対する Py_DECREF() の使用です。例えば:

void
bug(PyObject *list)
{
    PyObject *item = PyList_GetItem(list, 0);

    PyList_SetItem(list, 1, PyInt_FromLong(0L));
    PyObject_Print(item, stdout, 0); /* BUG! */
}

上の関数はまず、 list[0] への参照を借用し、次に list[1] を値 0 で置き換え、最後にさきほど借用した参照を出力しています。何も問題ないように見えますね? でもそうではないのです!

PyList_SetItem() の処理の流れを追跡してみましょう。リストは全ての要素に対して参照を所有しているので、要素 1 を置き換えると、以前の要素 1 を放棄します。ここで、以前の要素 1 がユーザ定義クラスのインスタンスであり、さらにこのクラスが __del__() メソッドを定義していると仮定しましょう。このクラスインスタンスの参照カウントが 1 だった場合、リストが参照を放棄すると、インスタンスの __del__() メソッドが呼び出されます。

クラスは Python で書かれているので、 __del__() は任意の Python コードを実行できます。この __del__() が bug() における item に何か不正なことをしているのでしょうか? その通り! buf() に渡したリストが __del__() メソッドから操作できるとすると、 del list[0] の効果を持つような文を実行できてしまいます。もしこの操作で list[0] に対する最後の参照が放棄されてしまうと、 list[0] に関連付けられていたメモリは解放され、結果的に item は無効な値になってしまいます。

問題の原因が分かれば、解決は簡単です。一時的に参照回数を増やせばよいのです。正しく動作するバージョンは以下のようになります:

void
no_bug(PyObject *list)
{
    PyObject *item = PyList_GetItem(list, 0);

    Py_INCREF(item);
    PyList_SetItem(list, 1, PyInt_FromLong(0L));
    PyObject_Print(item, stdout, 0);
    Py_DECREF(item);
}

これは実際にあった話です。以前のバージョンの Python には、このバグの一種が潜んでいて、 __del__() メソッドがどうしてうまく動かないのかを調べるために C デバッガで相当時間を費やした人がいました...

二つ目は、借用参照がスレッドに関係しているケースです。通常は、 Python インタプリタにおける複数のスレッドは、グローバルインタプリタロックがオブジェクト空間全体を保護しているため、互いに邪魔し合うことはありません。とはいえ、ロックは Py_BEGIN_ALLOW_THREADS マクロで一時的に解除したり、 Py_END_ALLOW_THREADS で再獲得したりできます。これらのマクロはブロックの起こる I/O 呼び出しの周囲によく置かれ、 I/O が完了するまでの間に他のスレッドがプロセッサを利用できるようにします。明らかに、以下の関数は上の例と似た問題をはらんでいます:

void
bug(PyObject *list)
{
    PyObject *item = PyList_GetItem(list, 0);
    Py_BEGIN_ALLOW_THREADS
    ...ブロックが起こる何らかの I/O 呼び出し...
    Py_END_ALLOW_THREADS
    PyObject_Print(item, stdout, 0); /* BUG! */
}

1.10.4. NULL ポインタ

一般論として、オブジェクトへの参照を引数にとる関数はユーザが NULL ポインタを渡すとは予想しておらず、渡そうとするとコアダンプになる (か、あとでコアダンプを引き起こす) ことでしょう。一方、オブジェクトへの参照を返すような関数は一般に、例外の発生を示す場合にのみ NULL を返します。引数に対して NULL テストを行わない理由は、こうした関数群はしばしば受け取った関数を他の関数へと引き渡すからです — 各々の関数が NULL テストを行えば、冗長なテストが大量に行われ、コードはより低速に動くことになります。

従って、 NULL のテストはオブジェクトの “発生源”、すなわち値が NULL になるかもしれないポインタを受け取ったときだけにしましょう。 malloc() や、例外を送出する可能性のある関数がその例です。

マクロ Py_INCREF() および Py_DECREF() は NULL ポインタのチェックを行いません — しかし、これらのマクロの変化形である Py_XINCREF() および Py_XDECREF() はチェックを行います。

特定のオブジェクト型について調べるマクロ (Pytype_Check()) は NULL ポインタのチェックを行いません — 繰り返しますが、様々な異なる型を想定してオブジェクトの型を調べる際には、こうしたマクロを続けて呼び出す必要があるので、個別に NULL ポインタのチェックをすると冗長なテストになってしまうのです。型を調べるマクロには、 NULL チェックを行う変化形はありません。

Python から C 関数を呼び出す機構は、 C 関数に渡される引数リスト (例でいうところの args) が決して NULL にならないよう保証しています — 実際には、常にタプル型になるよう保証しています。 [4]

NULL ポインタを Python ユーザレベルに “逃がし” てしまうと、深刻なエラーを引き起こします。

1.11. C++での拡張モジュール作成

C++でも拡張モジュールは作成できます。ただしいくつか制限があります。メインプログラム (Python インタプリタ) は C コンパイラでコンパイルされリンクされているので、グローバル変数や静的オブジェクトをコンストラクタで作成できません。メインプログラムが C++ コンパイラでリンクされているならこれは問題ではありません。 Python インタプリタから呼び出される関数 (特にモジュール初期化関数) は、 extern "C" を使って宣言しなければなりません。また、Python ヘッダファイルを extern "C" {...} に入れる必要はありません— シンボル __cplusplus (最近の C++ コンパイラは全てこのシンボルを定義しています) が定義されているときに extern "C" {...} が行われるように、ヘッダファイル内にすでに書かれているからです。

1.12. 拡張モジュールに C API を提供する

多くの拡張モジュールは単に Python から使える新たな関数や型を提供するだけですが、時に拡張モジュール内のコードが他の拡張モジュールでも便利なことがあります。例えば、あるモジュールでは順序概念のないリストのように動作する “コレクション (collection)” クラスを実装しているかもしれません。ちょうどリストを生成したり操作したりできる C API を備えた標準の Python リスト型のように、この新たなコレクション型も他の拡張モジュールから直接操作できるようにするには一連の C 関数を持っていなければなりません。

一見するとこれは簡単なこと: 単に関数を (もちろん static などとは宣言せずに) 書いて、適切なヘッダファイルを提供し、C API を書けばよいだけ、に思えます。そして実際のところ、全ての拡張モジュールが Python インタプリタに常に静的にリンクされている場合にはうまく動作します。ところがモジュールが共有ライブラリの場合には、一つのモジュールで定義されているシンボルが他のモジュールから不可視なことがあります。可視性の詳細はオペレーティングシステムによります; あるシステムは Python インタプリタと全ての拡張モジュール用に単一のグローバルな名前空間を用意しています (例えば Windows)。別のシステムはモジュールのリンク時に取り込まれるシンボルを明示的に指定する必要があります (AIX がその一例です)、また別のシステム (ほとんどの Unix) では、違った戦略を選択肢として提供しています。そして、たとえシンボルがグローバル変数として可視であっても、呼び出したい関数の入ったモジュールがまだロードされていないことだってあります!

従って、可搬性の点からシンボルの可視性には何ら仮定をしてはならないことになります。つまり拡張モジュール中の全てのシンボルは static と宣言せねばなりません。例外はモジュールの初期化関数で、これは (モジュールのメソッドテーブルと初期化関数 で述べたように) 他の拡張モジュールとの間で名前が衝突するのを避けるためです。また、他の拡張モジュールからアクセスを 受けるべきではない シンボルは別のやり方で公開せねばなりません。

Python はある拡張モジュールの C レベルの情報 (ポインタ) を別のモジュールに渡すための特殊な機構: Capsule (カプセル)を提供しています。 Capsule はポインタ (void*) を記憶する Python のデータ型です。 Capsule は C API を介してのみ生成したりアクセスしたりできますが、他の Python オブジェクトと同じように受け渡しできます。とりわけ、Capsule は拡張モジュールの名前空間内にある名前に代入できます。他の拡張モジュールはこのモジュールを import でき、次に名前を取得し、最後にCapsule へのポインタを取得します。

拡張モジュールの C API を公開するために、様々な方法で Capsule が使われます。各関数を1つのオブジェクトに入れたり、全ての C API のポインタ配列を Capsule に入れることができます。そして、ポインタに対する保存や取得といった様々な作業は、コードを提供しているモジュールとクライアントモジュールとの間では異なる方法で分散できます。

どの方法を選ぶにしても、 Capsule の name を正しく設定することは重要です。 PyCapsule_New() は name 引数 (const char *) を取ります。 NULL を name に渡すことも許可されていますが、 name を設定することを強く推奨します。正しく名前を付けられた Capsule はある程度の実行時型安全性を持ちます。名前を付けられていない Capsule を他の Capsule と区別する現実的な方法はありません。

特に、 C API を公開するための Capsule には次のルールに従った名前を付けるべきです:

modulename.attributename

PyCapsule_Import() という便利関数は、 Capsule の名前がこのルールに一致しているときにのみ、簡単に Capsule 経由で公開されている C API をロードすることができます。この挙動により、 C API のユーザーが、確実に正しい C API を格納している Capsule をロードできたことを確かめることができます。

以下の例では、名前を公開するモジュールの作者にほとんどの負荷が掛かりますが、よく使われるライブラリを作る際に適切なアプローチを実演します。このアプローチでは、全ての C API ポインタ (例中では一つだけですが!) を、 Capsule の値となる void ポインタの配列に保存します。拡張モジュールに対応するヘッダファイルは、モジュールの import と C API ポインタを取得するよう手配するマクロを提供します; クライアントモジュールは、C API にアクセスする前にこのマクロを呼ぶだけです。

名前を公開する側のモジュールは、 簡単な例 節の spam モジュールを修正したものです。関数 spam.system() は C ライブラリ関数 system() を直接呼び出さず、 PySpam_System() を呼び出します。この関数はもちろん、実際には (全てのコマンドに “spam” を付けるといったような) より込み入った処理を行います。この関数 PySpam_System() はまた、他の拡張モジュールにも公開されます。

関数 PySpam_System() は、他の全ての関数と同様に static で宣言された通常の C 関数です。

static int
PySpam_System(const char *command)
{
    return system(command);
}

spam_system() には取るに足らない変更が施されています:

static PyObject *
spam_system(PyObject *self, PyObject *args)
{
    const char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = PySpam_System(command);
    return Py_BuildValue("i", sts);
}

モジュールの先頭にある以下の行

#include "Python.h"

の直後に、以下の二行:

#define SPAM_MODULE
#include "spammodule.h"

を必ず追加してください。

#define は、ファイル spammodule.h をインクルードしているのが名前を公開する側のモジュールであって、クライアントモジュールではないことをヘッダファイルに教えるために使われます。最後に、モジュールの初期化関数は C API のポインタ配列を初期化するよう手配しなければなりません:

PyMODINIT_FUNC
initspam(void)
{
    PyObject *m;
    static void *PySpam_API[PySpam_API_pointers];
    PyObject *c_api_object;

    m = Py_InitModule("spam", SpamMethods);
    if (m == NULL)
        return;

    /* C API ポインタ配列を初期化する */
    PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;

    /* API ポインタ配列のアドレスが入った Capsule を生成する */
    c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);

    if (c_api_object != NULL)
        PyModule_AddObject(m, "_C_API", c_api_object);
}

PySpam_API が static と宣言されていることに注意してください; そうしなければ、 initspam() が終了したときにポインタアレイは消滅してしまいます!

からくりの大部分はヘッダファイル spammodule.h 内にあり、以下のようになっています:

#ifndef Py_SPAMMODULE_H
#define Py_SPAMMODULE_H
#ifdef __cplusplus
extern "C" {
#endif

/* spammodule のヘッダファイル */

/* C API 関数 */
#define PySpam_System_NUM 0
#define PySpam_System_RETURN int
#define PySpam_System_PROTO (const char *command)

/* C API ポインタの総数 */
#define PySpam_API_pointers 1

#ifdef SPAM_MODULE
/* この部分は spammodule.c をコンパイルする際に使われる */

static PySpam_System_RETURN PySpam_System PySpam_System_PROTO;

#else
/* この部分は spammodule の API を使うモジュール側で使われる */

static void **PySpam_API;

#define PySpam_System \
 (*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM])

/* エラーによる例外の場合には -1 を、成功すると 0 を返す
 * エラーがあれば PyCapsule_Import が例外を設定する。
 */
static int
import_spam(void)
{
    PySpam_API = (void **)PyCapsule_Import("spam._C_API", 0);
    return (PySpam_API != NULL) ? 0 : -1;
}

#endif

#ifdef __cplusplus
}
#endif

#endif /* !defined(Py_SPAMMODULE_H) */

PySpam_System() へのアクセス手段を得るためにクライアントモジュール側がしなければならないことは、初期化関数内での import_spam() 関数 (またはマクロ) の呼び出しです:

PyMODINIT_FUNC
initclient(void)
{
    PyObject *m;

    m = Py_InitModule("client", ClientMethods);
    if (m == NULL)
        return;
    if (import_spam() < 0)
        return;
    /* さらなる初期化処理はここに置ける */
}

このアプローチの主要な欠点は、 spammodule.h がやや難解になるということです。とはいえ、各関数の基本的な構成は公開されるものと同じなので、書き方を一度だけ学べばすみます。

最後に、Capsule は、自身に保存されているポインタをメモリ確保したり解放したりする際に特に便利な、もう一つの機能を提供しているということに触れておかねばなりません。詳細は Python/C API リファレンスマニュアルのカプセル (Capsules), および Capsule の実装部分 (Python ソースコード配布物中のファイル Include/pycapsule.h および Objects/pycapsule.c に述べられています。

注記

[1]
この関数へのインタフェースはすでに標準モジュール os にあります — この関数を選んだのは、単純で直接的な例を示したいからです。

[2]
参照を “借用する” というメタファは厳密には正しくありません: なぜなら、参照の所有者は依然として参照のコピーを持っているからです。

[3]
参照カウントが 1 以上かどうか調べる方法は うまくいきません — 参照カウント自体も解放されたメモリ上にあるため、その領域が他のオブジェクトに使われている可能性があります!

[4]
“旧式の” 呼び出し規約を使っている場合には、この保証は適用されません — 既存のコードにはいまだに旧式の呼び出し規約が多々あります

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

2. 新しい型を定義する

前の章でふれたように、Python では拡張モジュールを書くプログラマが Python のコードから操作できる、新しい型を定義できるようになっています。ちょうど Python の中核にある文字列やリストをつくれるようなものです。

これはそんなにむずかしくはありません。拡張型のためのコードにはすべて、一定のパターンが存在しています。しかし始める前に、いくつか細かいことを理解しておく必要があるでしょう。

ノート

Python 2.2 から、新しい型を定義する方法がかなり変わって (良くなって) います。この文書は Python 2.2 およびそれ以降で新しい型をどうやって定義するかについて述べています。古いバージョンの Python をサポートする必要がある場合は、 この文書の古い版 [http://www.python.org/doc/versions/] を参照してください。

2.1. 基本的なこと

Python ランタイムでは、すべての Python オブジェクトは PyObject* 型の変数として扱います。 PyObject はさほど大仰なオブジェクトではなく、単にオブジェクトに対する参照回数と、そのオブジェクトの「タイプオブジェクト (type object)」へのポインタを格納しているだけです。重要な役割を果たしているのはこのタイプオブジェクトです。つまりタイプオブジェクトは、例えばあるオブジェクトのある属性が参照されるとか、あるいは別のオブジェクトとの間で乗算を行うといったときに、どの (C の) 関数を呼び出すかを決定しているのです。これらの C 関数は「タイプメソッド (type method)」と呼ばれ、 [].append のようなもの (いわゆる「オブジェクトメソッド (object method)」) とは区別しています。

なので、新しいオブジェクトの型を定義したいときは、新しいタイプオブジェクトを作成すればよいわけです。

この手のことは例を見たほうが早いでしょうから、ここに最小限の、しかし完全な、新しい型を定義するモジュールをあげておきます:

#include <Python.h>

typedef struct {
    PyObject_HEAD
    /* Type-specific fields go here. */
} noddy_NoddyObject;

static PyTypeObject noddy_NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "noddy.Noddy",             /*tp_name*/
    sizeof(noddy_NoddyObject), /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    0,                         /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
    "Noddy objects",           /* tp_doc */
};

static PyMethodDef noddy_methods[] = {
    {NULL}  /* Sentinel */
};

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy(void)
{
    PyObject* m;

    noddy_NoddyType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&noddy_NoddyType) < 0)
        return;

    m = Py_InitModule3("noddy", noddy_methods,
                       "Example module that creates an extension type.");

    Py_INCREF(&noddy_NoddyType);
    PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
}

さしあたって覚えておくことは以上ですが、これで前の章からすこしは説明がわかりやすくなっていることと思います。

最初に習うのは、つぎのようなものです:

typedef struct {
    PyObject_HEAD
} noddy_NoddyObject;

これが Noddy オブジェクトの内容です — このケースでは、ほかの Python オブジェクトが持っているものと何ら変わりはありません。つまり参照カウントと型オブジェクトへのポインタですね。これらは PyObject_HEAD マクロによって展開されるメンバです。マクロを使う理由は、レイアウトを標準化するためと、デバッグ用ビルド時に特別なデバッグ用のメンバを定義できるようにするためです。この PyObject_HEAD マクロの後にはセミコロンがないことに注意してください。セミコロンはすでにマクロ内に含まれています。うっかり後にセミコロンをつけてしまわないように気をつけて。これはお使いの機種では何の問題も起こらないかもしれませんが、機種によっては、おそらく問題になるのです! (Windows 上では、MS Visual C がこの手のエラーを出し、コンパイルできないことが知られています)

比較のため、以下に標準的な Python の整数型の定義を見てみましょう:

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

では次にいってみます。かなめの部分、タイプオブジェクトです。

static PyTypeObject noddy_NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "noddy.Noddy",             /*tp_name*/
    sizeof(noddy_NoddyObject), /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    0,                         /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
    "Noddy objects",           /* tp_doc */
};

object.h の中にある PyTypeObject の定義を見ると、実際にはここに挙げた以上の数のメンバがあるとわかるでしょう。これ以外のメンバは C コンパイラによってゼロに初期化されるので、必要な時を除いてふつうはそれらの値を明示的には指定せずにおきます。

次のものは非常に重要なので、とくに最初の最初に見ておきましょう:

PyObject_HEAD_INIT(NULL)

これはちょっとぶっきらぼうですね。実際に書きたかったのはこうです:

PyObject_HEAD_INIT(&PyType_Type)

この場合、タイプオブジェクトの型は「type」という名前になりますが、これは厳密には C の基準に従っておらず、コンパイラによっては文句を言われます。幸いにも、このメンバは PyType_Ready() が埋めてくれます。

0,                          /* ob_size */

ヘッダ中の ob_size メンバは使われていません。これは歴史的な遺物であり、構造体中にこれが存在しているのは古いバージョンの Python 用にコンパイルされた拡張モジュールとのバイナリ上の互換性を保つためです。ここにはつねにゼロを指定してください。

"noddy.Noddy",              /* tp_name */

これは型の名前です。この名前はオブジェクトのデフォルトの表現形式と、いくつかのエラーメッセージ中で使われます。たとえば:

>>> "" + noddy.new_noddy()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot add type "noddy.Noddy" to string

注意: この名前はドットで区切られた名前で、モジュール名と、そのモジュール内での型名を両方ふくんでいます。この場合のモジュールは noddy で、型の名前は Noddy ですから、ここでの型名としては noddy.Noddy を指定するわけです。

sizeof(noddy_NoddyObject),  /* tp_basicsize */

これによって Python は PyObject_New() が呼ばれたときにどれくらいの量のメモリを割り当てればよいのか知ることができます。

ノート

あなたのタイプを Python でサブクラス化可能にしたい場合、そのタイプが基底タイプと同じ tp_basicsize をもっていると多重継承のときに問題が生じることがあります。そのタイプを Python のサブクラスにしたとき、その __bases__ リストにはあなたのタイプが最初にくるようにしなければなりません。さもないとエラーの発生なしにあなたのタイプの __new__() メソッドを呼び出すことはできなくなります。この問題を回避するには、つねにあなたのタイプの tp_basicsize をその基底タイプよりも大きくしておくことです。ほとんどの場合、あなたのタイプは object か、そうでなければ基底タイプにデータ用のメンバを追加したものでしょうから、したがって大きさはつねに増加するためこの条件は満たされています。

0,                          /* tp_itemsize */

これはリストや文字列などの可変長オブジェクトのためのものです。今のところ無視しましょう。

このあとのいくつかのメソッドは使わないのでとばして、クラスのフラグ (flags) には Py_TPFLAGS_DEFAULT を入れます。

Py_TPFLAGS_DEFAULT,        /*tp_flags*/

すべての型はフラグにこの定数を含めておく必要があります。これは現在のバージョンの Python で定義されているすべてのメンバを許可します。

この型の docstring は tp_doc に入れます。

"Noddy objects",           /* tp_doc */

ここからタイプメソッドに入るわけですが。ここがあなたのオブジェクトが他と違うところです。でも今回のバージョンでは、これらはどれも実装しないでおき、あとでこの例をより面白いものに改造することにしましょう。

とりあえずやりたいのは、この Noddy オブジェクトを新しく作れるようにすることです。オブジェクトの作成を許可するには、 tp_new の実装を提供する必要があります。今回は、 API 関数によって提供されるデフォルトの実装 PyType_GenericNew() を使うだけにしましょう。これを単に tp_new スロットに代入すればよいのですが、これは互換上の理由からできません。プラットフォームやコンパイラによっては、構造体メンバの初期化に別の場所で定義されている C の関数を代入することはできないのです。なので、この tp_new の値はモジュール初期化用の関数で代入します。 PyType_Ready() を呼ぶ直前です:

noddy_NoddyType.tp_new = PyType_GenericNew;
if (PyType_Ready(&noddy_NoddyType) < 0)
    return;

これ以外のタイプメソッドはすべて NULL です。これらについては後ほどふれます。

このファイル中にある他のものは、どれもおなじみでしょう。 initnoddy() のこれを除いて:

if (PyType_Ready(&noddy_NoddyType) < 0)
    return;

この関数は、上で NULL に指定していた ob_type などのいくつものメンバを埋めて、 Noddy 型を初期化します。

PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);

これはこの型をモジュール中の辞書に埋め込みます。これで、 Noddy クラスを呼べば Noddy インスタンスを作れるようになりました:

>>> import noddy
>>> mynoddy = noddy.Noddy()

これだけです! 残るはこれをどうやってビルドするかということです。上のコードを noddy.c というファイルに入れて、以下のものを setup.py というファイルに入れましょう。

from distutils.core import setup, Extension
setup(name="noddy", version="1.0",
      ext_modules=[Extension("noddy", ["noddy.c"])])

そして、シェルから以下のように入力します。

$ python setup.py build

これでサブディレクトリの下にファイル noddy.so が作成されます。このディレクトリに移動して Python を起動しましょう。 import noddy して Noddy オブジェクトで遊べるようになっているはずです。

そんなにむずかしくありません、よね?

もちろん、現在の Noddy 型はまだおもしろみに欠けています。何もデータを持ってないし、何もしてはくれません。継承してサブクラスを作ることさえできないのです。

2.1.1. 基本のサンプルにデータとメソッドを追加する

この基本のサンプルにデータとメソッドを追加してみましょう。ついでに、この型を基底クラスとしても利用できるようにします。ここでは新しいモジュール noddy2 をつくり、以下の機能を追加します:

#include <Python.h>
#include "structmember.h"

typedef struct {
    PyObject_HEAD
    PyObject *first; /* first name */
    PyObject *last;  /* last name */
    int number;
} Noddy;

static void
Noddy_dealloc(Noddy* self)
{
    Py_XDECREF(self->first);
    Py_XDECREF(self->last);
    self->ob_type->tp_free((PyObject*)self);
}

static PyObject *
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Noddy *self;

    self = (Noddy *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->first = PyString_FromString("");
        if (self->first == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->last = PyString_FromString("");
        if (self->last == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->number = 0;
    }

    return (PyObject *)self;
}

static int
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
{
    PyObject *first=NULL, *last=NULL, *tmp;

    static char *kwlist[] = {"first", "last", "number", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
                                      &first, &last,
                                      &self->number))
        return -1;

    if (first) {
	tmp = self->first;
        Py_INCREF(first);
        self->first = first;
        Py_XDECREF(tmp);
    }

    if (last) {
        tmp = self->last;
        Py_INCREF(last);
        self->last = last;
        Py_XDECREF(tmp);
    }

    return 0;
}

static PyMemberDef Noddy_members[] = {
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
     "first name"},
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
     "last name"},
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

static PyObject *
Noddy_name(Noddy* self)
{
    static PyObject *format = NULL;
    PyObject *args, *result;

    if (format == NULL) {
        format = PyString_FromString("%s %s");
        if (format == NULL)
            return NULL;
    }

    if (self->first == NULL) {
        PyErr_SetString(PyExc_AttributeError, "first");
        return NULL;
    }

    if (self->last == NULL) {
        PyErr_SetString(PyExc_AttributeError, "last");
        return NULL;
    }

    args = Py_BuildValue("OO", self->first, self->last);
    if (args == NULL)
        return NULL;

    result = PyString_Format(format, args);
    Py_DECREF(args);

    return result;
}

static PyMethodDef Noddy_methods[] = {
    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
     "Return the name, combining the first and last name"
    },
    {NULL}  /* Sentinel */
};

static PyTypeObject NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "noddy.Noddy",             /*tp_name*/
    sizeof(Noddy),             /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    (destructor)Noddy_dealloc, /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
    "Noddy objects",           /* tp_doc */
    0,		               /* tp_traverse */
    0,		               /* tp_clear */
    0,		               /* tp_richcompare */
    0,		               /* tp_weaklistoffset */
    0,		               /* tp_iter */
    0,		               /* tp_iternext */
    Noddy_methods,             /* tp_methods */
    Noddy_members,             /* tp_members */
    0,                         /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc)Noddy_init,      /* tp_init */
    0,                         /* tp_alloc */
    Noddy_new,                 /* tp_new */
};

static PyMethodDef module_methods[] = {
    {NULL}  /* Sentinel */
};

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy2(void)
{
    PyObject* m;

    if (PyType_Ready(&NoddyType) < 0)
        return;

    m = Py_InitModule3("noddy2", module_methods,
                       "Example module that creates an extension type.");

    if (m == NULL)
      return;

    Py_INCREF(&NoddyType);
    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
}

このバージョンでは、いくつもの変更をおこないます。

以下の include を追加します:

#include <structmember.h>

すこしあとでふれますが、この include には属性を扱うための宣言が入っています。

Noddy オブジェクトの構造体の名前は Noddy に縮めることにします。タイプオブジェクト名は NoddyType に縮めます。

これから Noddy 型は 3つのデータ属性をもつようになります。 first 、 last 、および number です。 first と last 属性はファーストネームとラストネームを格納した Python 文字列で、 number 属性は整数の値です。

これにしたがうと、オブジェクトの構造体は次のようになります:

typedef struct {
    PyObject_HEAD
    PyObject *first;
    PyObject *last;
    int number;
} Noddy;

いまや管理すべきデータができたので、オブジェクトの割り当てと解放に際してはより慎重になる必要があります。最低限、オブジェクトの解放メソッドが必要です:

static void
Noddy_dealloc(Noddy* self)
{
    Py_XDECREF(self->first);
    Py_XDECREF(self->last);
    self->ob_type->tp_free((PyObject*)self);
}

この関数は tp_dealloc メンバに代入されます。

(destructor)Noddy_dealloc, / *tp_dealloc* /

このメソッドでやっているのは、ふたつの Python 属性の参照カウントを減らすことです。 first メンバと last メンバが NULL かもしれないため、ここでは Py_XDECREF() を使いました。このあとそのオブジェクトのタイプメソッドである tp_free メンバを呼び出しています。ここではオブジェクトの型が NoddyType とは限らないことに注意してください。なぜなら、このオブジェクトはサブクラス化したインスタンスかもしれないからです。

ファーストネームとラストネームを空文字列に初期化しておきたいので、新しいメソッドを追加することにしましょう:

static PyObject *
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Noddy *self;

    self = (Noddy *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->first = PyString_FromString("");
        if (self->first == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->last = PyString_FromString("");
        if (self->last == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->number = 0;
    }

    return (PyObject *)self;
}

そしてこれを tp_new メンバとしてインストールします:

Noddy_new,                 /* tp_new */

この新しいメンバはその型のオブジェクトを (初期化するのではなく) 作成する責任を負っています。Python ではこのメンバは __new__() メソッドとして見えています。 __new__() メソッドについての詳しい議論は “Unifying types and classes in Python” という題名の論文を見てください。 new メソッドを実装する理由のひとつは、インスタンス変数の初期値を保証するためです。この例でやりたいのは new メソッドが first メンバと last メンバの値を NULL でないようにするということです。もしこれらの初期値が NULL でもよいのであれば、先の例でやったように、new メソッドとして PyType_GenericNew() を使うこともできたでしょう。 PyType_GenericNew() はすべてのインスタンス変数のメンバを NULL にします。

この new メソッドは静的なメソッドで、インスタンスを生成するときにその型と、型が呼び出されたときの引数が渡され、新しいオブジェクトを作成して返します。new メソッドはつねに、あらかじめ固定引数 (positional argument) とキーワード引数を取りますが、これらのメソッドはしばしばそれらの引数は無視して初期化メソッドにそのまま渡します。new メソッドはメモリ割り当てのために tp_alloc メンバを呼び出します。 tp_alloc をこちらで初期化する必要はありません。これは PyType_Ready() が基底クラス (デフォルトでは object) をもとに埋めるものです。ほとんどの型ではデフォルトのメモリ割り当てを使っています。

ノート

もし協力的な tp_new (基底タイプの tp_new または __new__() を呼んでいるもの) を作りたいのならば、実行時のメソッド解決順序をつかってどのメソッドを呼びだすかを決定しようとしてはいけません 。つねに呼び出す型を静的に決めておき、直接その tp_new を呼び出すか、あるいは type->tp_base->tp_new を経由してください。こうしないと、あなたが作成したタイプの Python サブクラスが他の Python で定義されたクラスも継承している場合にうまく動かない場合があります。 (とりわけ、そのようなサブクラスのインスタンスを TypeError を出さずに作ることが不可能になります。)

つぎに初期化用の関数を見てみましょう:

static int
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
{
    PyObject *first=NULL, *last=NULL, *tmp;

    static char *kwlist[] = {"first", "last", "number", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
                                      &first, &last,
                                      &self->number))
        return -1;

    if (first) {
        tmp = self->first;
        Py_INCREF(first);
        self->first = first;
        Py_XDECREF(tmp);
    }

    if (last) {
        tmp = self->last;
        Py_INCREF(last);
        self->last = last;
        Py_XDECREF(tmp);
    }

    return 0;
}

これは tp_init メンバに代入されます。

(initproc)Noddy_init,         /* tp_init */

Python では、 tp_init メンバは __init__() メソッドとして見えています。このメソッドは、オブジェクトが作成されたあとに、それを初期化する目的で使われます。 new メソッドとはちがって、初期化用のメソッドは必ず呼ばれるとは限りません。初期化用のメソッドは、インスタンスの初期値を提供するのに必要な引数を受けとります。このメソッドはつねに固定引数とキーワード引数を受けとります。

初期化メソッドは複数回呼び出される可能性があります。あなたのオブジェクトの __init__() メソッドは、誰にでも呼び出すことができるからです。このため、新しい値を代入するさいには特別な注意を払う必要があります。たとえば、 first メンバには以下のように代入したくなるかもしれません:

if (first) {
    Py_XDECREF(self->first);
    Py_INCREF(first);
    self->first = first;
}

しかしこのやり方は危険です。このタイプでは first メンバに入るオブジェクトをなにも限定していないので、どんなオブジェクトでもとり得てしまうからです。それはこのコードが first メンバにアクセスしようとする前に、そのデストラクタが呼び出されてしまうかもしれないのです。このような可能性からパラノイア的に身をまもるため、ほとんどの場合メンバへの代入は,その参照カウントを減らす前におこなってください。こうする必要がないのはどんな場合でしょうか?

その参照カウントが 1 より大きいと確信できる場合。

そのオブジェクトの解放があなたのタイプのコードにコールバックするようなことが決してない場合 [1] 。

ガベージコレクションがサポートされていない場合に tp_dealloc ハンドラで参照カウントを減らすとき [2] 。

ここではインスタンス変数を属性として見えるようにしたいのですが、これにはいくつもの方法があります。もっとも簡単な方法は、メンバの定義を与えることです:

static PyMemberDef Noddy_members[] = {
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
     "first name"},
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
     "last name"},
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

そして、この定義を tp_members に入れましょう:

Noddy_members,             /* tp_members */

各メンバの定義はそれぞれ、メンバの名前、型、オフセット、アクセスフラグおよび docstring です。詳しくは後の “総称的な属性を管理する” (総称的な属性を管理する) の節をご覧ください。

この方法の欠点は、Python 属性に代入できるオブジェクトの型を制限する方法がないことです。ここではファーストネーム first とラストネーム last に、ともに文字列が入るよう期待していますが、今のやり方ではどんな Python オブジェクトも代入できてしまいます。加えてこの属性は削除 (del) できてしまい、その場合、 C のポインタには NULL が設定されます。たとえもしメンバが NULL 以外の値に初期化されるようにしてあったとしても、属性が削除されればメンバは NULL になってしまいます。

ここでは name() と呼ばれるメソッドを定義しましょう。これはファーストネーム first とラストネーム last を連結した文字列をそのオブジェクトの名前として返します。

static PyObject *
Noddy_name(Noddy* self)
{
    static PyObject *format = NULL;
    PyObject *args, *result;

    if (format == NULL) {
        format = PyString_FromString("%s %s");
        if (format == NULL)
            return NULL;
    }

    if (self->first == NULL) {
        PyErr_SetString(PyExc_AttributeError, "first");
        return NULL;
    }

    if (self->last == NULL) {
        PyErr_SetString(PyExc_AttributeError, "last");
        return NULL;
    }

    args = Py_BuildValue("OO", self->first, self->last);
    if (args == NULL)
        return NULL;

    result = PyString_Format(format, args);
    Py_DECREF(args);

    return result;
}

このメソッドは C 関数として実装され、 Noddy (あるいは Noddy のサブクラス) のインスタンスを第一引数として受けとります。メソッドはつねにそのインスタンスを最初の引数として受けとらなければなりません。しばしば固定引数とキーワード引数も受けとりますが、今回はなにも必要ないので、固定引数のタプルもキーワード引数の辞書も取らないことにします。このメソッドは Python の以下のメソッドと等価です:

def name(self):
   return "%s %s" % (self.first, self.last)

first メンバと last メンバがそれぞれ NULL かどうかチェックしなければならないことに注意してください。これらは削除される可能性があり、その場合値は NULL にセットされます。この属性の削除を禁止して、そこに入れられる値を文字列に限定できればなおいいでしょう。次の節ではこれについて扱います。

さて、メソッドを定義したので、ここでメソッド定義用の配列を作成する必要があります:

static PyMethodDef Noddy_methods[] = {
    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
     "Return the name, combining the first and last name"
    },
    {NULL}  /* Sentinel */
};

これを tp_methods スロットに入れましょう:

Noddy_methods,             /* tp_methods */

ここでの METH_NOARGS フラグは、そのメソッドが引数を取らないことを宣言するのに使われています。

最後に、この型を基底クラスとして利用可能にしましょう。上のメソッドは注意ぶかく書かれているので、これはそのオブジェクトの型が作成されたり利用される場合についてどんな仮定も置いていません。なので、ここですべきことは Py_TPFLAGS_BASETYPE をクラス定義のフラグに加えるだけです:

Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, / *tp_flags* /

initnoddy() の名前を initnoddy2() に変更し、 Py_InitModule3() に渡されるモジュール名を更新します。

さいごに setup.py ファイルを更新して新しいモジュールをビルドします。

from distutils.core import setup, Extension
setup(name="noddy", version="1.0",
      ext_modules=[
         Extension("noddy", ["noddy.c"]),
         Extension("noddy2", ["noddy2.c"]),
         ])

2.1.2. データ属性をこまかく制御する

この節では、 Noddy クラスの例にあった first と last の各属性にたいして、より精密な制御を提供します。以前のバージョンのモジュールでは、インスタンス変数の first と last には文字列以外のものも代入できてしまい、あまつさえ削除まで可能でした。ここではこれらの属性が必ず文字列を保持しているようにしましょう。

#include <Python.h>
#include "structmember.h"

typedef struct {
    PyObject_HEAD
    PyObject *first;
    PyObject *last;
    int number;
} Noddy;

static void
Noddy_dealloc(Noddy* self)
{
    Py_XDECREF(self->first);
    Py_XDECREF(self->last);
    self->ob_type->tp_free((PyObject*)self);
}

static PyObject *
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Noddy *self;

    self = (Noddy *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->first = PyString_FromString("");
        if (self->first == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->last = PyString_FromString("");
        if (self->last == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->number = 0;
    }

    return (PyObject *)self;
}

static int
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
{
    PyObject *first=NULL, *last=NULL, *tmp;

    static char *kwlist[] = {"first", "last", "number", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
                                      &first, &last,
                                      &self->number))
        return -1;

    if (first) {
        tmp = self->first;
        Py_INCREF(first);
        self->first = first;
        Py_DECREF(tmp);
    }

    if (last) {
        tmp = self->last;
        Py_INCREF(last);
        self->last = last;
        Py_DECREF(tmp);
    }

    return 0;
}

static PyMemberDef Noddy_members[] = {
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

static PyObject *
Noddy_getfirst(Noddy *self, void *closure)
{
    Py_INCREF(self->first);
    return self->first;
}

static int
Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
{
  if (value == NULL) {
    PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
    return -1;
  }

  if (! PyString_Check(value)) {
    PyErr_SetString(PyExc_TypeError,
                    "The first attribute value must be a string");
    return -1;
  }

  Py_DECREF(self->first);
  Py_INCREF(value);
  self->first = value;

  return 0;
}

static PyObject *
Noddy_getlast(Noddy *self, void *closure)
{
    Py_INCREF(self->last);
    return self->last;
}

static int
Noddy_setlast(Noddy *self, PyObject *value, void *closure)
{
  if (value == NULL) {
    PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
    return -1;
  }

  if (! PyString_Check(value)) {
    PyErr_SetString(PyExc_TypeError,
                    "The last attribute value must be a string");
    return -1;
  }

  Py_DECREF(self->last);
  Py_INCREF(value);
  self->last = value;

  return 0;
}

static PyGetSetDef Noddy_getseters[] = {
    {"first",
     (getter)Noddy_getfirst, (setter)Noddy_setfirst,
     "first name",
     NULL},
    {"last",
     (getter)Noddy_getlast, (setter)Noddy_setlast,
     "last name",
     NULL},
    {NULL}  /* Sentinel */
};

static PyObject *
Noddy_name(Noddy* self)
{
    static PyObject *format = NULL;
    PyObject *args, *result;

    if (format == NULL) {
        format = PyString_FromString("%s %s");
        if (format == NULL)
            return NULL;
    }

    args = Py_BuildValue("OO", self->first, self->last);
    if (args == NULL)
        return NULL;

    result = PyString_Format(format, args);
    Py_DECREF(args);

    return result;
}

static PyMethodDef Noddy_methods[] = {
    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
     "Return the name, combining the first and last name"
    },
    {NULL}  /* Sentinel */
};

static PyTypeObject NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "noddy.Noddy",             /*tp_name*/
    sizeof(Noddy),             /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    (destructor)Noddy_dealloc, /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
    "Noddy objects",           /* tp_doc */
    0,		               /* tp_traverse */
    0,		               /* tp_clear */
    0,		               /* tp_richcompare */
    0,		               /* tp_weaklistoffset */
    0,		               /* tp_iter */
    0,		               /* tp_iternext */
    Noddy_methods,             /* tp_methods */
    Noddy_members,             /* tp_members */
    Noddy_getseters,           /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc)Noddy_init,      /* tp_init */
    0,                         /* tp_alloc */
    Noddy_new,                 /* tp_new */
};

static PyMethodDef module_methods[] = {
    {NULL}  /* Sentinel */
};

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy3(void)
{
    PyObject* m;

    if (PyType_Ready(&NoddyType) < 0)
        return;

    m = Py_InitModule3("noddy3", module_methods,
                       "Example module that creates an extension type.");

    if (m == NULL)
      return;

    Py_INCREF(&NoddyType);
    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
}

first 属性と last 属性をよりこまかく制御するためには、カスタムメイドの getter 関数と setter 関数を使います。以下は first 属性から値を取得する関数 (getter) と、この属性に値を格納する関数 (setter) です:

Noddy_getfirst(Noddy *self, void *closure)
{
    Py_INCREF(self->first);
    return self->first;
}

static int
Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
{
  if (value == NULL) {
    PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
    return -1;
  }

  if (! PyString_Check(value)) {
    PyErr_SetString(PyExc_TypeError,
                    "The first attribute value must be a string");
    return -1;
  }

  Py_DECREF(self->first);
  Py_INCREF(value);
  self->first = value;

  return 0;
}

getter 関数には Noddy オブジェクトと「閉包 (closure)」 (これは void型のポインタです) が渡されます。今回のケースでは閉包は無視します。 (閉包とは定義データが渡される setter や getter の高度な利用をサポートするためのもので、これを使うとたとえば getter と setter をひとまとめにした関数に、閉包のデータにもとづいて属性を get するか set するか決めさせる、といったことができます。)

setter 関数には Noddy オブジェクトと新しい値、そして閉包が渡されます。新しい値は NULL かもしれず、その場合はこの属性が削除されます。ここでは属性が削除されたり、その値が文字列でないときにはエラーを発生させるようにします。

ここでは PyGetSetDef 構造体の配列をつくります:

static PyGetSetDef Noddy_getseters[] = {
    {"first",
     (getter)Noddy_getfirst, (setter)Noddy_setfirst,
     "first name",
     NULL},
    {"last",
     (getter)Noddy_getlast, (setter)Noddy_setlast,
     "last name",
     NULL},
    {NULL}  /* Sentinel */
};

そしてこれを tp_getset スロットに登録します:

Noddy_getseters,           /* tp_getset */

これで属性の getter と setter が登録できました。

PyGetSetDef 構造体の最後の要素が上で説明した閉包です。今回は閉包は使わないので NULL を渡しています。

また、メンバ定義からはこれらの属性を除いておきましょう:

static PyMemberDef Noddy_members[] = {
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

また、ここでは tp_init ハンドラも渡されるものとして文字列のみを許可するように修正する必要があります [3]:

static int
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
{
    PyObject *first=NULL, *last=NULL, *tmp;

    static char *kwlist[] = {"first", "last", "number", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist,
                                      &first, &last,
                                      &self->number))
        return -1;

    if (first) {
        tmp = self->first;
        Py_INCREF(first);
        self->first = first;
        Py_DECREF(tmp);
    }

    if (last) {
        tmp = self->last;
        Py_INCREF(last);
        self->last = last;
        Py_DECREF(tmp);
    }

    return 0;
}

これらの変更によって、 first メンバと last メンバが決して NULL にならないと保証できました。これでほとんどすべてのケースから NULL 値のチェックを除けます。これは Py_XDECREF() 呼び出しを Py_DECREF() 呼び出しに変えられることを意味します。唯一これを変えられないのはオブジェクト解放メソッド (deallocator) で、なぜならここではコンストラクタによるメンバ初期化が失敗している可能性があるからです。

さて、先ほどもしたように、このモジュール初期化関数と初期化関数内にあるモジュール名を変更しましょう。そして setup.py ファイルに追加の定義をくわえます。

2.1.3. 循環ガベージコレクションをサポートする

Python は循環ガベージコレクション機能をもっており、これは不要なオブジェクトを、たとえ参照カウントがゼロでなくても、発見することができます。これはオブジェクトの参照が循環しているときに起こりえます。たとえば以下の例を考えてください:

>>> l = []
>>> l.append(l)
>>> del l

この例では、自分自身をふくむリストをつくりました。たとえこのリストを del しても、それは自分自身への参照をまだ持ちつづけますから、参照カウントはゼロにはなりません。嬉しいことに Python には循環ガベージコレクション機能がありますから、最終的にはこのリストが不要であることを検出し、解放できます。

Noddy クラスの 2番目の例では、 first 属性と last 属性にどんなオブジェクトでも格納できるようになっていました。 [4] 。つまり、 Noddy オブジェクトの参照は循環しうるのです:

>>> import noddy2
>>> n = noddy2.Noddy()
>>> l = [n]
>>> n.first = l

これは実にばかげた例ですが、すくなくとも Noddy クラスに循環ガベージコレクション機能のサポートを加える口実を与えてくれます。循環ガベージコレクションをサポートするには 2つのタイプスロットを埋め、これらのスロットを許可するようにクラス定義のフラグを設定する必要があります:

#include <Python.h>
#include "structmember.h"

typedef struct {
    PyObject_HEAD
    PyObject *first;
    PyObject *last;
    int number;
} Noddy;

static int
Noddy_traverse(Noddy *self, visitproc visit, void *arg)
{
    int vret;

    if (self->first) {
        vret = visit(self->first, arg);
        if (vret != 0)
            return vret;
    }
    if (self->last) {
        vret = visit(self->last, arg);
        if (vret != 0)
            return vret;
    }

    return 0;
}

static int
Noddy_clear(Noddy *self)
{
    PyObject *tmp;

    tmp = self->first;
    self->first = NULL;
    Py_XDECREF(tmp);

    tmp = self->last;
    self->last = NULL;
    Py_XDECREF(tmp);

    return 0;
}

static void
Noddy_dealloc(Noddy* self)
{
    Noddy_clear(self);
    self->ob_type->tp_free((PyObject*)self);
}

static PyObject *
Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Noddy *self;

    self = (Noddy *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->first = PyString_FromString("");
        if (self->first == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->last = PyString_FromString("");
        if (self->last == NULL)
          {
            Py_DECREF(self);
            return NULL;
          }

        self->number = 0;
    }

    return (PyObject *)self;
}

static int
Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
{
    PyObject *first=NULL, *last=NULL, *tmp;

    static char *kwlist[] = {"first", "last", "number", NULL};

    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
                                      &first, &last,
                                      &self->number))
        return -1;

    if (first) {
        tmp = self->first;
        Py_INCREF(first);
        self->first = first;
        Py_XDECREF(tmp);
    }

    if (last) {
        tmp = self->last;
        Py_INCREF(last);
        self->last = last;
        Py_XDECREF(tmp);
    }

    return 0;
}

static PyMemberDef Noddy_members[] = {
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
     "first name"},
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
     "last name"},
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

static PyObject *
Noddy_name(Noddy* self)
{
    static PyObject *format = NULL;
    PyObject *args, *result;

    if (format == NULL) {
        format = PyString_FromString("%s %s");
        if (format == NULL)
            return NULL;
    }

    if (self->first == NULL) {
        PyErr_SetString(PyExc_AttributeError, "first");
        return NULL;
    }

    if (self->last == NULL) {
        PyErr_SetString(PyExc_AttributeError, "last");
        return NULL;
    }

    args = Py_BuildValue("OO", self->first, self->last);
    if (args == NULL)
        return NULL;

    result = PyString_Format(format, args);
    Py_DECREF(args);

    return result;
}

static PyMethodDef Noddy_methods[] = {
    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
     "Return the name, combining the first and last name"
    },
    {NULL}  /* Sentinel */
};

static PyTypeObject NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "noddy.Noddy",             /*tp_name*/
    sizeof(Noddy),             /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    (destructor)Noddy_dealloc, /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
    "Noddy objects",           /* tp_doc */
    (traverseproc)Noddy_traverse,   /* tp_traverse */
    (inquiry)Noddy_clear,           /* tp_clear */
    0,		               /* tp_richcompare */
    0,		               /* tp_weaklistoffset */
    0,		               /* tp_iter */
    0,		               /* tp_iternext */
    Noddy_methods,             /* tp_methods */
    Noddy_members,             /* tp_members */
    0,                         /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc)Noddy_init,      /* tp_init */
    0,                         /* tp_alloc */
    Noddy_new,                 /* tp_new */
};

static PyMethodDef module_methods[] = {
    {NULL}  /* Sentinel */
};

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initnoddy4(void)
{
    PyObject* m;

    if (PyType_Ready(&NoddyType) < 0)
        return;

    m = Py_InitModule3("noddy4", module_methods,
                       "Example module that creates an extension type.");

    if (m == NULL)
      return;

    Py_INCREF(&NoddyType);
    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
}

traversal メソッドは循環した参照に含まれる可能性のある内部オブジェクトへのアクセスを提供します:

static int
Noddy_traverse(Noddy *self, visitproc visit, void *arg)
{
    int vret;

    if (self->first) {
        vret = visit(self->first, arg);
        if (vret != 0)
            return vret;
    }
    if (self->last) {
        vret = visit(self->last, arg);
        if (vret != 0)
            return vret;
    }

    return 0;
}

循環した参照に含まれるかもしれない各内部オブジェクトに対して、 traversal メソッドに渡された visit() 関数を呼びます。 visit() 関数は内部オブジェクトと、traversal メソッドに渡された追加の引数 arg を引数としてとります。この関数はこの値が非負の場合に返される整数の値を返します。

Python 2.4 以降では、visit 関数の呼び出しを自動化する Py_VISIT() マクロが用意されています。 Py_VISIT() を使えば、 Noddy_traverse() は次のように簡略化できます:

static int
Noddy_traverse(Noddy *self, visitproc visit, void *arg)
{
    Py_VISIT(self->first);
    Py_VISIT(self->last);
    return 0;
}

ノート

注意: tp_traverse の実装で Py_VISIT() を使うには、その引数に正確に visit および arg という名前をつける必要があります。これは、この退屈な実装に統一性を導入することを促進します。

また、循環した参照に含まれた内部オブジェクトを消去するためのメソッドも提供する必要があります。オブジェクト解放用のメソッドを再実装して、このメソッドに使いましょう:

static int
Noddy_clear(Noddy *self)
{
    PyObject *tmp;

    tmp = self->first;
    self->first = NULL;
    Py_XDECREF(tmp);

    tmp = self->last;
    self->last = NULL;
    Py_XDECREF(tmp);

    return 0;
}

static void
Noddy_dealloc(Noddy* self)
{
    Noddy_clear(self);
    self->ob_type->tp_free((PyObject*)self);
}

Noddy_clear() 中での一時変数の使い方に注目してください。ここでは、一時変数をつかって各メンバの参照カウントを減らす前にそれらに NULL を代入しています。これは次のような理由によります。すでにお話ししたように、もし参照カウントがゼロになると、このオブジェクトがコールバックされるようになってしまいます。さらに、いまやガベージコレクションをサポートしているため、ガベージコレクション時に実行されるコードについても心配しなくてはなりません。もしガベージコレクションが走っていると、あなたの tp_traverse ハンドラが呼び出される可能性があります。メンバの参照カウントがゼロになった場合に、その値が NULL に設定されていないと Noddy_traverse() が呼ばれる機会はありません。

Python 2.4 以降では、注意ぶかく参照カウントを減らすためのマクロ Py_CLEAR() が用意されています。 Py_CLEAR() を使えば、 Noddy_clear() は次のように簡略化できます:

static int
Noddy_clear(Noddy *self)
{
    Py_CLEAR(self->first);
    Py_CLEAR(self->last);
    return 0;
}

最後に、 Py_TPFLAGS_HAVE_GC フラグをクラス定義のフラグに加えます:

Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, / *tp_flags* /

これで完了です。 tp_alloc スロットまたは tp_free スロットが書かれていれば、それらを循環ガベージコレクションに使えるよう修正すればよいのです。ほとんどの拡張機能は自動的に提供されるバージョンを使うでしょう。

2.1.4. 他の型のサブクラスを作る

既存の型を継承した新しい拡張型を作成することができます。組み込み型から継承するのは特に簡単です。必要な PyTypeObject を簡単に利用できるからです。それに比べて、 PyTypeObject 構造体を拡張モジュール間で共有するのは難しいです。

次の例では、ビルトインの list 型を継承した Shoddy 型を作成しています。新しい型は通常のリスト型と完全に互換性がありますが、追加で内部のカウンタを増やす increment() メソッドを持っています。

>>> import shoddy
>>> s = shoddy.Shoddy(range(3))
>>> s.extend(s)
>>> print len(s)
6
>>> print s.increment()
1
>>> print s.increment()
2

#include <Python.h>

typedef struct {
    PyListObject list;
    int state;
} Shoddy;

static PyObject *
Shoddy_increment(Shoddy *self, PyObject *unused)
{
    self->state++;
    return PyInt_FromLong(self->state);
}

static PyMethodDef Shoddy_methods[] = {
    {"increment", (PyCFunction)Shoddy_increment, METH_NOARGS,
     PyDoc_STR("increment state counter")},
    {NULL,	NULL},
};

static int
Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
{
    if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
        return -1;
    self->state = 0;
    return 0;
}

static PyTypeObject ShoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,                       /* ob_size */
    "shoddy.Shoddy",         /* tp_name */
    sizeof(Shoddy),          /* tp_basicsize */
    0,                       /* tp_itemsize */
    0,                       /* tp_dealloc */
    0,                       /* tp_print */
    0,                       /* tp_getattr */
    0,                       /* tp_setattr */
    0,                       /* tp_compare */
    0,                       /* tp_repr */
    0,                       /* tp_as_number */
    0,                       /* tp_as_sequence */
    0,                       /* tp_as_mapping */
    0,                       /* tp_hash */
    0,                       /* tp_call */
    0,                       /* tp_str */
    0,                       /* tp_getattro */
    0,                       /* tp_setattro */
    0,                       /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT |
      Py_TPFLAGS_BASETYPE,   /* tp_flags */
    0,                       /* tp_doc */
    0,                       /* tp_traverse */
    0,                       /* tp_clear */
    0,                       /* tp_richcompare */
    0,                       /* tp_weaklistoffset */
    0,                       /* tp_iter */
    0,                       /* tp_iternext */
    Shoddy_methods,          /* tp_methods */
    0,                       /* tp_members */
    0,                       /* tp_getset */
    0,                       /* tp_base */
    0,                       /* tp_dict */
    0,                       /* tp_descr_get */
    0,                       /* tp_descr_set */
    0,                       /* tp_dictoffset */
    (initproc)Shoddy_init,   /* tp_init */
    0,                       /* tp_alloc */
    0,                       /* tp_new */
};

PyMODINIT_FUNC
initshoddy(void)
{
    PyObject *m;

    ShoddyType.tp_base = &PyList_Type;
    if (PyType_Ready(&ShoddyType) < 0)
        return;

    m = Py_InitModule3("shoddy", NULL, "Shoddy module");
    if (m == NULL)
        return;

    Py_INCREF(&ShoddyType);
    PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
}

見てわかるように、ソースコードは前の節の Noddy の時と非常に似ています。違う部分をそれぞれを見ていきます。

typedef struct {
    PyListObject list;
    int state;
} Shoddy;

継承した型のオブジェクトの最初の違いは、親クラスのオブジェクト構造が最初に必要なことです。基底型が既に PyObject_HEAD() を構造体の先頭に持っています。

Python オブジェクトが Shoddy 型のインスタンスだった場合、その PyObject* ポインタは PyListObject* にも Shoddy* にも安全にキャストできます。

static int
Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds)
{
    if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
       return -1;
    self->state = 0;
    return 0;
}

この新しい型の __init__ メソッドで、基底型の __init__ メソッドを呼び出している様子を見ることができます。

このパターンは、カスタムの new と dealloc メソッドを実装するときには重要です。継承した型の new メソッドは、 tp_alloc を使ってメモリを割り当てるべきではありません。それは基底型の tp_new を呼出たときに処理されるからです。

Shoddy 型のために PyTypeObject() を埋めるとき、 tp_base() スロットを見つけることができます。クロスプラットフォームのコンパイラに対応するために、直接そのスロットを PyList_Type() で埋めてはいけません。代わりに、後でモジュールの init() 関数の中で行うことができます。

PyMODINIT_FUNC
initshoddy(void)
{
    PyObject *m;

    ShoddyType.tp_base = &PyList_Type;
    if (PyType_Ready(&ShoddyType) < 0)
        return;

    m = Py_InitModule3("shoddy", NULL, "Shoddy module");
    if (m == NULL)
        return;

    Py_INCREF(&ShoddyType);
    PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType);
}

PyType_Read() を呼ぶ前に、型の構造は tp_base スロットは埋められていなければなりません。継承している新しい型を作るとき、 tp_alloc スロットを PyType_GenericNew() で埋める必要はありません。 – 基底型のアロケート関数が継承されます。

その後、 PyType_Read() を呼んで、 Noddy の時と同じようにタイプオブジェクトをモジュールに追加します。

2.2. タイプメソッド

この節ではさまざまな実装可能なタイプメソッドと、それらが何をするものであるかについて、ざっと説明します。

以下は PyTypeObject の定義です。デバッグビルドでしか使われないいくつかのメンバは省いてあります:

typedef struct _typeobject {
    PyObject_VAR_HEAD
    char *tp_name; /* For printing, in format "<module>.<name>" */
    int tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    printfunc tp_print;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    cmpfunc tp_compare;
    reprfunc tp_repr;

    /* Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* More standard operations (here for binary compatibility) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Functions to access object as input/output buffer */
    PyBufferProcs *tp_as_buffer;

    /* Flags to define presence of optional/expanded features */
    long tp_flags;

    char *tp_doc; /* Documentation string */

    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    long tp_weaklistoffset;

    /* Added in release 2.2 */
    /* Iterators */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Attribute descriptor and subclassing stuff */
    struct PyMethodDef *tp_methods;
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset;
    struct _typeobject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    long tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Low-level free-memory routine */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* method resolution order */
    PyObject *tp_cache;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;

} PyTypeObject;

たくさんの メソッドがありますね。でもそんなに心配する必要はありません。定義したい型があるなら、実装するのはこのうちのごくわずかですむことがほとんどです。

すでに予想されているでしょうが、これらの多様なハンドラについて、これからより詳しい情報を提供します。しかしこれらのメンバが構造体中で定義されている順番は無視します。というのは、これらのメンバの現れる順序は歴史的な遺産によるものだからです。型を初期化するさいに、これらのメンバを正しい順序で並べるよう、くれぐれも注意してください。ふつういちばん簡単なのは、必要なメンバがすべて含まれている (たとえそれらが 0 に初期化されていても) 例をとってきて、自分の型に合わせるよう変更をくわえることです。

char *tp_name; /* 表示用 */

これは型の名前です。前節で説明したように、これはいろいろな場面で現れ、ほとんどは診断用の目的で使われるものです。なので、そのような場面で役に立つであろう名前を選んでください。

int tp_basicsize, tp_itemsize; /* 割り当て用 */

これらのメンバは、この型のオブジェクトが作成されるときにどれだけのメモリを割り当てればよいのかをランタイムに指示します。Python には可変長の構造体 (文字列やリストなどを想像してください) に対する組み込みのサポートがある程度あり、ここで tp_itemsize メンバが使われます。これらについてはあとでふれます。

char *tp_doc;

ここには Python スクリプトリファレンス obj.__doc__ が doc string を返すときの文字列 (あるいはそのアドレス) を入れます。

では次に、ほとんどの拡張型が実装するであろう基本的なタイプメソッドに入っていきます。

2.2.1. 最終化 (finalization) と解放

destructor tp_dealloc;

型のインスタンスの参照カウントがゼロになり、 Python インタプリタがそれを潰して再利用したくなると、この関数が呼ばれます。解放すべきメモリをその型が保持していたり、それ以外にも実行すべき後処理がある場合は、それらをここに入れます。オブジェクトそれ自体もここで解放される必要があります。この関数の例は、以下のようなものです:

static void
newdatatype_dealloc(newdatatypeobject * obj)
{
    free(obj->obj_UnderlyingDatatypePtr);
    obj->ob_type->tp_free(obj);
}

解放用関数でひとつ重要なのは、処理待ちの例外にいっさい手をつけないことです。なぜなら、解放用の関数は Python インタプリタがスタックを元の状態に戻すときに呼ばれることが多いからです。そして (通常の関数からの復帰でなく) 例外のためにスタックが巻き戻されるときは、すでに発生している例外から解放用関数を守るものはありません。解放用の関数がおこなう動作が追加の Python のコードを実行してしまうと、それらは例外が発生していることを検知するかもしれません。これはインタプリタが誤解させるエラーを発生させることにつながります。これを防ぐ正しい方法は、安全でない操作を実行する前に処理待ちの例外を保存しておき、終わったらそれを元に戻すことです。これは PyErr_Fetch() および PyErr_Restore() 関数を使うことによって可能になります:

static void
my_dealloc(PyObject *obj)
{
    MyObject *self = (MyObject *) obj;
    PyObject *cbresult;

    if (self->my_callback != NULL) {
        PyObject *err_type, *err_value, *err_traceback;
        int have_error = PyErr_Occurred() ? 1 : 0;

        if (have_error)
            PyErr_Fetch(&err_type, &err_value, &err_traceback);

        cbresult = PyObject_CallObject(self->my_callback, NULL);
        if (cbresult == NULL)
            PyErr_WriteUnraisable();
        else
            Py_DECREF(cbresult);

        if (have_error)
            PyErr_Restore(err_type, err_value, err_traceback);

        Py_DECREF(self->my_callback);
    }
    obj->ob_type->tp_free((PyObject*)self);
}

2.2.2. オブジェクト表現

Python では、オブジェクトの文字列表現を生成するのに 3つのやり方があります: repr() 関数 (あるいはそれと等価なバッククォートを用いた表現) を使う方法、 str() 関数を使う方法、そして print 文を使う方法です。ほとんどのオブジェクトで print 文は str() 関数と同じですが、必要な場合には特殊なケースとして FILE* にも表示できます。 FILE* への表示は、効率が問題となっている場合で、一時的な文字列オブジェクトを作成してファイルに書き込むのでは効率が悪すぎることがプロファイリングからも明らかな場合にのみ使うべきです。

これらのハンドラはどれも必須ではありません。ほとんどの型ではせいぜい tp_str ハンドラと tp_repr ハンドラを実装するだけですみます。

reprfunc tp_repr;
reprfunc tp_str;
printfunc tp_print;

tp_repr ハンドラは呼び出されたインスタンスの文字列表現を格納した文字列オブジェクトを返す必要があります。簡単な例は以下のようなものです:

static PyObject *
newdatatype_repr(newdatatypeobject * obj)
{
    return PyString_FromFormat("Repr-ified_newdatatype{{size:\%d}}",
                               obj->obj_UnderlyingDatatypePtr->size);
}

tp_repr ハンドラが指定されていなければ、インタプリタはその型の tp_name とそのオブジェクトの一意な識別値をもちいて文字列表現を作成します。

tp_str ハンドラと str() の関係は、上の tp_repr ハンドラと repr() の関係に相当します。つまり、これは Python のコードがオブジェクトのインスタンスに対して str() を呼び出したときに呼ばれます。この関数の実装は tp_repr ハンドラのそれと非常に似ていますが、得られる文字列表現は人間が読むことを意図されています。 tp_str が指定されていない場合、かわりに tp_repr ハンドラが使われます。

以下は簡単な例です:

static PyObject *
newdatatype_str(newdatatypeobject * obj)
{
    return PyString_FromFormat("Stringified_newdatatype{{size:\%d}}",
                               obj->obj_UnderlyingDatatypePtr->size);
}

print ハンドラは Python がその型のインスタンスを「print する」必要のあるときに毎回呼ばれます。たとえば ‘node’ が TreeNode 型のインスタンスだとすると、print ハンドラは Python が以下を実行したときに呼ばれます:

print node

flags 引数には Py_PRINT_RAW というフラグがあり、これはその文字列をクォートやおそらくはエスケープシーケンスの解釈もなしで表示することを指示します。

この print 関数は FILE* オブジェクトを引数としてとります。たぶん、ここに出力することになるでしょう。

print 関数の例は以下のようになります:

static int
newdatatype_print(newdatatypeobject *obj, FILE *fp, int flags)
{
    if (flags & Py_PRINT_RAW) {
        fprintf(fp, "<{newdatatype object--size: %d}>",
                obj->obj_UnderlyingDatatypePtr->size);
    }
    else {
        fprintf(fp, "\"<{newdatatype object--size: %d}>\"",
                obj->obj_UnderlyingDatatypePtr->size);
    }
    return 0;
}

2.2.3. 属性を管理する

属性をもつどのオブジェクトに対しても、その型は、それらオブジェクトの属性をどのように解決するか制御する関数を提供する必要があります。必要な関数としては、属性を (それが定義されていれば) 取り出すものと、もうひとつは属性に (それが許可されていれば) 値を設定するものです。属性を削除するのは特殊なケースで、この場合は新しい値としてハンドラに NULL が渡されます。

Python は 2つの属性ハンドラの組をサポートしています。属性をもつ型はどちらか一組を実装するだけでよく、それらの違いは一方の組が属性の名前を char* として受け取るのに対してもう一方の組は属性の名前を PyObject* として受け取る、というものです。それぞれの型はその実装にとって都合がよい方を使えます。

getattrfunc  tp_getattr;        /* char * バージョン */
setattrfunc  tp_setattr;
/* ... */
getattrofunc tp_getattrofunc;   /* PyObject * バージョン */
setattrofunc tp_setattrofunc;

オブジェクトの属性へのアクセスがつねに (すぐあとで説明する) 単純な操作だけならば、 PyObject* を使って属性を管理する関数として、総称的 (generic) な実装を使えます。特定の型に特化した属性ハンドラの必要性は Python 2.2 からほとんど完全になくなりました。しかし、多くの例はまだ、この新しく使えるようになった総称的なメカニズムを使うよう更新されてはいません。

2.2.3.1. 総称的な属性を管理する

バージョン 2.2 で追加.

ほとんどの型は 単純な 属性を使うだけです。では、どのような属性が単純だといえるのでしょうか? それが満たすべき条件はごくわずかです:

PyType_Ready() が呼ばれたとき、すでに属性の名前がわかっていること。

属性を参照したり設定したりするときに、特別な記録のための処理が必要でなく、また参照したり設定した値に対してどんな操作も実行する必要がないこと。

これらの条件は、属性の値や、値が計算されるタイミング、または格納されたデータがどの程度妥当なものであるかといったことになんら制約を課すものではないことに注意してください。

PyType_Ready() が呼ばれると、これはそのタイプオブジェクトに参照されている 3つのテーブルを使って、そのタイプオブジェクトの辞書中にデスクリプタ(descriptor) を作成します。各デスクリプタは、インスタンスオブジェクトの属性に対するアクセスを制御します。それぞれのテーブルはなくてもかまいません。もしこれら 3つがすべて NULL だと、その型のインスタンスはその基底型から継承した属性だけを持つことになります。また、 tp_getattro および tp_setattro が NULL のままだった場合も、基底型にこれらの属性の操作がまかせられます。

テーブルはタイプオブジェクト中の 3つのメンバとして宣言されています:

struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;

tp_methods が NULL でない場合、これは PyMethodDef 構造体への配列を指している必要があります。テーブル中の各エントリは、つぎのような構造体のインスタンスです:

typedef struct PyMethodDef {
    char        *ml_name;       /* メソッド名 */
    PyCFunction  ml_meth;       /* 実装する関数 */
    int          ml_flags;      /* flags */
    char        *ml_doc;        /* docstring */
} PyMethodDef;

その型が提供する各メソッドについてひとつのエントリを定義する必要があります。基底型から継承してきたメソッドについてはエントリは必要ありません。これの最後には、配列の終わりを示すための見張り番 (sentinel) として追加のエントリがひとつ必要です。この場合、 ml_name メンバが sentinel として使われ、その値は NULL でなければなりません。

2番目のテーブルは、インスタンス中に格納されるデータと直接対応づけられた属性を定義するのに使います。いくつもの C の原始的な型がサポートされており、アクセスを読み込み専用にも読み書き可能にもできます。このテーブルで使われる構造体は次のように定義されています:

typedef struct PyMemberDef {
    char *name;
    int   type;
    int   offset;
    int   flags;
    char *doc;
} PyMemberDef;

このテーブルの各エントリに対してデスクリプタ(descriptor)が作成され、値をインスタンスの構造体から抽出しうる型に対してそれらが追加されます。 type メンバは structmember.h ヘッダで定義された型のコードをひとつ含んでいる必要があります。この値は Python における値と C における値をどのように変換しあうかを定めるものです。 flags メンバはこの属性がどのようにアクセスされるかを制御するフラグを格納するのに使われます。

以下のフラグ用定数は structmember.h で定義されており、これらはビットごとの OR を取って組み合わせられます。

Constant | Meaning
READONLY | 絶対に変更できない。
RO | READONLY の短縮形。
READ_RESTRICTED | 制限モード (restricted mode) では参照できない。
WRITE_RESTRICTED | 制限モード (restricted mode) では変更できない。
RESTRICTED | 制限モード (restricted mode) では参照も変更もできない。

tp_members を使ったひとつの面白い利用法は、実行時に使われるデスクリプタを作成しておき、単にテーブル中にテキストを置いておくことによって、この方法で定義されたすべての属性に doc string を関連付けられるようにすることです。アプリケーションはこのイントロスペクション用 API を使って、クラスオブジェクトからデスクリプタを取り出し、その __doc__ 属性を使って doc string を得られます。

tp_methods テーブルと同じように、ここでも name メンバの値を NULL にした見張り用エントリが必要です。

2.2.3.2. 特定の型に特化した属性の管理

話を単純にするため、ここでは char* を使ったバージョンのみを示します。name パラメータの型はインターフェイスとして char* を使うか PyObject* を使うかの違いしかありません。この例では、上の総称的な例と同じことを効率的にやりますが、 Python 2.2 で追加された総称的な型のサポートを使わずにやります。これを紹介することは 2つの意味をもっています。ひとつはどうやって、古いバージョンの Python と互換性のあるやり方で、基本的な属性管理をおこなうか。そしてもうひとつはハンドラの関数がどのようにして呼ばれるのか。これで、たとえその機能を拡張する必要があるとき、何をどうすればいいかわかるでしょう。

tp_getattr ハンドラはオブジェクトが属性への参照を要求するときに呼ばれます。これは、そのクラスの __getattr__() メソッドが呼ばれるであろう状況と同じ状況下で呼び出されます。

これを処理するありがちな方法は、(1) 一連の関数 (下の例の newdatatype_getSize() や newdatatype_setSize()) を実装する、(2) これらの関数を記録したメソッドテーブルを提供する、そして (3) そのテーブルの参照結果を返す getattr 関数を提供することです。メソッドテーブルはタイプオブジェクトの tp_methods メンバと同じ構造を持っています。

以下に例を示します:

static PyMethodDef newdatatype_methods[] = {
    {"getSize", (PyCFunction)newdatatype_getSize, METH_VARARGS,
     "Return the current size."},
    {"setSize", (PyCFunction)newdatatype_setSize, METH_VARARGS,
     "Set the size."},
    {NULL, NULL, 0, NULL}           /* 見張り */
};

static PyObject *
newdatatype_getattr(newdatatypeobject *obj, char *name)
{
    return Py_FindMethod(newdatatype_methods, (PyObject *)obj, name);
}

tp_setattr ハンドラは、クラスのインスタンスの __setattr__() または __delattr__() メソッドが呼ばれるであろう状況で呼び出されます。ある属性が削除されるとき、3番目のパラメータは NULL になります。以下の例はたんに例外を発生させるものですが、もし本当にこれと同じことをしたいなら、 tp_setattr ハンドラを NULL に設定すべきです。

static int
newdatatype_setattr(newdatatypeobject *obj, char *name, PyObject *v)
{
    (void)PyErr_Format(PyExc_RuntimeError, "Read-only attribute: \%s", name);
    return -1;
}

2.2.4. オブジェクトの比較

cmpfunc tp_compare;

tp_compare ハンドラは、オブジェクトどうしの比較が必要で、そのオブジェクトに要求された比較をおこなうのに適した特定の拡張比較メソッドが実装されていないときに呼び出されます。(これが定義されているとき、 PyObject_Compare() または PyObject_Cmp() が使われるとこれはつねに呼び出されます、また Python で cmp() が使われたときにも呼び出されます。) これは __cmp__() メソッドに似ています。この関数はもし obj1 が obj2 より「小さい」場合は -1 を返し、それらが等しければ 0 、そしてもし obj1 が obj2 より「大きい」場合は 1 を返す必要があります。 (以前は大小比較の結果として、任意の大きさの負または正の整数を返せましたが、 Python 2.2 以降ではこれはもう許されていません。将来的には、上にあげた以外の返り値は別の意味をもつ可能性があります。)

tp_compare ハンドラは例外を発生させられます。この場合、この関数は負の値を返す必要があります。呼び出した側は PyErr_Occurred() を使って例外を検査しなければなりません。

以下はサンプル実装です:

static int
newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2)
{
    long result;

    if (obj1->obj_UnderlyingDatatypePtr->size <
        obj2->obj_UnderlyingDatatypePtr->size) {
        result = -1;
    }
    else if (obj1->obj_UnderlyingDatatypePtr->size >
             obj2->obj_UnderlyingDatatypePtr->size) {
        result = 1;
    }
    else {
        result = 0;
    }
    return result;
}

2.2.5. 抽象的なプロトコルのサポート

Python はいくつもの 抽象的な “プロトコル”をサポートしています。これらを使用する特定のインターフェイスについては 抽象オブジェクトレイヤ (abstract objects layer) で解説されています。

これら多数の抽象的なインターフェイスは、Python の実装が開発される初期の段階で定義されていました。とりわけ数値や辞書、そしてシーケンスなどのプロトコルは最初から Python の一部だったのです。それ以外のプロトコルはその後追加されました。型の実装にあるいくつかのハンドラルーチンに依存するようなプロトコルのために、古いプロトコルはハンドラの入ったオプションのブロックとして定義し、型オブジェクトから参照するようになりました。タイプオブジェクトの主部に追加のスロットをもつ新しいプロトコルについては、フラグ用のビットを立てることでそれらのスロットが存在しており、インタプリタがチェックすべきであることを指示できます。 (このフラグ用のビットは、そのスロットの値が非 NULL であることを示しているわけではありません。フラグはスロットの存在を示すのに使えますが、そのスロットはまだ埋まっていないかもしれないのです。)

PyNumberMethods   tp_as_number;
PySequenceMethods tp_as_sequence;
PyMappingMethods  tp_as_mapping;

お使いのオブジェクトを数値やシーケンス、あるいは辞書のようにふるまうようにしたいならば、それぞれに C の PyNumberMethods 構造体、 PySequenceMethods 構造体、または PyMappingMethods 構造体のアドレスを入れます。これらに適切な値を入れても入れなくてもかまいません。これらを使った例は Python の配布ソースにある Objects でみつけることができるでしょう。

hashfunc tp_hash;

この関数は、もし使うのならば、これはお使いの型のインスタンスのハッシュ番号を返すようにします。以下はやや的はずれな例ですが

static long
newdatatype_hash(newdatatypeobject *obj)
{
    long result;
    result = obj->obj_UnderlyingDatatypePtr->size;
    result = result * 3;
    return result;
}

ternaryfunc tp_call;

この関数は、その型のインスタンスが「関数として呼び出される」ときに呼ばれます。たとえばもし obj1 にそのインスタンスが入っていて、Python スクリプトで obj1('hello') を実行したとすると、 tp_call ハンドラが呼ばれます。

この関数は 3つの引数をとります:

arg1 にはその呼び出しの対象となる、そのデータ型のインスタンスが入ります。たとえば呼び出しが obj1('hello') の場合、 arg1 は obj1 になります。

arg2 は呼び出しの引数を格納しているタプルです。ここから引数を取り出すには PyArg_ParseTuple() を使います。

arg3 はキーワード引数のための辞書です。これが NULL 以外でキーワード引数をサポートしているなら、 PyArg_ParseTupleAndKeywords() をつかって引数を取り出せます。キーワード引数をサポートしていないのにこれが NULL 以外の場合は、キーワード引数はサポートしていない旨のメッセージとともに TypeError を発生させてください。

以下はこの call 関数をてきとうに使った例です。

/* call 関数の実装。
 *    obj1 : 呼び出しを受けるインスタンス。
 *    obj2 : 呼び出しのさいの引数を格納するタプル、この場合は 3つの文字列。
 */
static PyObject *
newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *other)
{
    PyObject *result;
    char *arg1;
    char *arg2;
    char *arg3;

    if (!PyArg_ParseTuple(args, "sss:call", &arg1, &arg2, &arg3)) {
        return NULL;
    }
    result = PyString_FromFormat(
        "Returning -- value: [\%d] arg1: [\%s] arg2: [\%s] arg3: [\%s]\n",
        obj->obj_UnderlyingDatatypePtr->size,
        arg1, arg2, arg3);
    printf("\%s", PyString_AS_STRING(result));
    return result;
}

/* バージョン 2.2 以降で追加 */
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;

これらの関数はイテレータ用プロトコルをサポートします。オブジェクトが、その (ループ中に順に生成されていくかもしれない) 内容を巡回 (訳注: イテレータでひとつずつ要素をたどっていくこと) するイテレータをサポートしたい場合は、 tp_iter ハンドラを実装する必要があります。 tp_iter ハンドラによって返されるオブジェクトは tp_iter と tp_iternext の両方を実装する必要があります。どちらのハンドラも、それが呼ばれたインスタンスをひとつだけ引数としてとり、新しい参照を返します。エラーが起きた場合には例外を設定してから NULL を返す必要があります。

巡回可能な要素を表現するオブジェクトに対しては、 tp_iter ハンドラがイテレータオブジェクトを返す必要があります。イテレータオブジェクトは巡回中の状態を保持する責任をもっています。お互いに干渉しない複数のイテレータの存在を許すようなオブジェクト (リストやタプルがそうです) の場合は、新しいイテレータを作成して返す必要があります。 (巡回の結果生じる副作用のために) 一回だけしか巡回できないオブジェクトの場合は、それ自身への参照を返すようなハンドラと、 tp_iternext ハンドラも実装する必要があります。ファイルオブジェクトはそのようなイテレータの例です。

イテレータオブジェクトは両方のハンドラを実装する必要があります。 tp_iter ハンドラはそのイテレータへの新しい参照を返します (これは破壊的にしか巡回できないオブジェクトに対する tp_iter ハンドラと同じです)。 tp_iternext ハンドラはその次のオブジェクトがある場合、それへの新しい参照を返します。巡回が終端に達したときは例外を出さずに NULL を返してもいいですし、 StopIteration を放出してもかまいません。例外を使わないほうがやや速度が上がるかもしれません。実際のエラーが起こったときには、例外を放出して NULL を返す必要があります。

2.2.6. 弱参照(Weak Reference)のサポート

Pythonの弱参照実装のひとつのゴールは、どのような（数値のような弱参照による利益を得ない）タイプでもオーバーヘッドなしで弱参照のメカニズムに組み込めるようにすることです。

弱参照可能なオブジェクトの拡張では、弱参照メカニズムのために PyObject* フィールドをインスタンス構造体に含む必要があります。これはオブジェクトのコンストラクタで NULL に初期化する必要があります。これは対応するタイプの tp_weaklistoffset フィールドをフィールドのオフセットに設定しなければいけません。たとえば、インスタンスタイプは以下の構造体で定義されます:

typedef struct {
    PyObject_HEAD
    PyClassObject *in_class;       /* The class object */
    PyObject      *in_dict;        /* A dictionary */
    PyObject      *in_weakreflist; /* List of weak references */
} PyInstanceObject;

インスタンス用に静的に宣言されたタイプオブジェクトはこのように定義されます:

PyTypeObject PyInstance_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,
    "module.instance",

    /* Lots of stuff omitted for brevity... */

    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    0,                                          /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
};

タイプのコンストラクタは弱参照を NULL に初期化する責任があります:

static PyObject *
instance_new() {
    /* Other initialization stuff omitted for brevity */

    self->in_weakreflist = NULL;

    return (PyObject *) self;
}

さらに、デストラクタは弱参照を消すために弱参照のマネージャを呼ぶ必要があります。これはデストラクタのどの処理よりも先に実施される必要がありますが、弱参照リストが NULL でない場合にだけ必要です:

static void
instance_dealloc(PyInstanceObject *inst)
{
    /* Allocate temporaries if needed, but do not begin
       destruction just yet.
     */

    if (inst->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) inst);

    /* Proceed with object destruction normally. */
}

2.2.7. その他いろいろ

上にあげたほとんどの関数は、その値として 0 を与えれば省略できることを忘れないでください。それぞれの関数で提供しなければならない型の定義があり、これらは Python の include 用ディレクトリの object.h というファイルにおさめられています。これは Python の配布ソースに含まれています。

新しいデータ型に何らかのメソッドを実装するやりかたを学ぶには、以下の方法がおすすめです: Python の配布されているソースをダウンロードして展開する。 Objects ディレクトリへ行き、C のソースファイルから「 tp_ 欲しい名前」の文字列で検索する (たとえば tp_print とか tp_compare のように)。こうすれば実装したい例がみつかるでしょう。

あるオブジェクトが、いま実装している型のインスタンスであるかどうかを確かめたい場合には、 PyObject_TypeCheck() 関数を使ってください。使用例は以下のようなかんじです:

if (! PyObject_TypeCheck(some_object, &MyType)) {
    PyErr_SetString(PyExc_TypeError, "arg #1 not a mything");
    return NULL;
}

注記

[1]
これはそのオブジェクトが文字列や実数などの基本タイプであるような時に成り立ちます。

[2]
We relied ここで出てきたタイプではガベージコレクションをサポートしていないので、この例では tp_dealloc ハンドラに依存しています。このハンドラはそのタイプがたとえガベージコレクションをサポートしている場合でも、そのオブジェクトの「追跡を解除する」ために呼ばれることがありますが、これは高度な話題でありここでは扱いません。

[3]
first および last メンバが文字列であるということはわかっているので、いまやそれらの参照カウントを減らすときにはそれほど注意する必要はないように思えるかもしれません。しかし文字列型のサブクラスは依然として受けつけられています。通常の文字列型ならば、解放時にあなたのオブジェクトがコールバックされることはありませんが、文字列型のサブクラスがそうしないという保証はありません。

[4]
3番目のバージョンでさえ、循環を回避できるという保証はされていません。たとえ通常の文字列型なら循環しない場合でも、文字列型のサブクラスをとることが許されていれば、そのタイプでは循環が発生しうるからです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

3. distutils による C および C++ 拡張モジュールのビルド

Python 1.4 になってから、動的にリンクされるような拡張モジュールをビルドするためのメイクファイルを作成するような、特殊なメイクファイルをUnix 向けに提供するようになりました。Python 2.0 からはこの機構 (いわゆる Makefile.pre.in および Setup ファイルの関係ファイル) はサポートされなくなりました。インタプリタ自体のカスタマイズはほとんど使われず、 distutils で拡張モジュールをビルドできるようになったからです。

distutils を使った拡張モジュールのビルドには、ビルドを行う計算機上に distutils をインストールしていることが必要です。 Python 2.x には distutils が入っており、 Python 1.5 用には個別のパッケージがあります。distutils はバイナリパッケージの作成もサポートしているので、ユーザが拡張モジュールをインストールする際に、必ずしもコンパイラが必要というわけではありません。

distutils ベースのパッケージには、駆動スクリプト (driver script) となる setup.py が入っています。 setup.py は普通の Python プログラムファイルで、ほとんどの場合以下のような見かけになっています:

from distutils.core import setup, Extension

module1 = Extension('demo',
                    sources = ['demo.c'])

setup (name = 'PackageName',
       version = '1.0',
       description = 'This is a demo package',
       ext_modules = [module1])

この setup.py とファイル demo.c があるとき、以下のコマンド

python setup.py build

を実行すると、 demo.c をコンパイルして、 demo という名前の拡張モジュールを build ディレクトリ内に生成します。システムによってはモジュールファイルは build/lib.system サブディレクトリに生成され、 demo.so や demo.pyd といった名前になることがあります。

setup.py 内では、コマンドの実行はすべて setup 関数を呼び出して行います。この関数は可変個のキーワード引数をとります。例ではその一部を使っているにすぎません。もっと具体的にいうと、例の中ではパッケージをビルドするためのメタ情報と、パッケージの内容を指定しています。通常、パッケージには Python ソースモジュールやドキュメント、サブパッケージ等といった別のファイルも入ります。 distutils の機能に関する詳細は、 Python モジュールの配布 に書かれている distutils のドキュメントを参照してください; この節では、拡張モジュールのビルドについてのみ説明します。

駆動スクリプトをよりよく構成するために、決め打ちの引数を setup() に入れておくことがよくあります。上の例では、 setup() の ext_modules は拡張モジュールのリストで、リストの各々の要素は Extension クラスのインスタンスになっています。上の例では、 demo という名の拡張モジュールを定義していて、単一のソースファイル demo.c をコンパイルしてビルドするよう定義しています。

多くの場合、拡張モジュールのビルドはもっと複雑になります。というのは、プリプロセッサ定義やライブラリの追加指定が必要になることがあるからです。例えば以下のファイルがその実例です。

from distutils.core import setup, Extension

module1 = Extension('demo',
                    define_macros = [('MAJOR_VERSION', '1'),
                                     ('MINOR_VERSION', '0')],
                    include_dirs = ['/usr/local/include'],
                    libraries = ['tcl83'],
                    library_dirs = ['/usr/local/lib'],
                    sources = ['demo.c'])

setup (name = 'PackageName',
       version = '1.0',
       description = 'This is a demo package',
       author = 'Martin v. Loewis',
       author_email = 'martin@v.loewis.de',
       url = 'http://docs.python.org/extending/building',
       long_description = '''
This is really just a demo package.
''',
       ext_modules = [module1])

この例では、 setup() は追加のメタ情報と共に呼び出されます。配布パッケージを構築する際には、メタ情報の追加が推奨されています。拡張モジュール自体については、プリプロセッサ定義、インクルードファイルのディレクトリ、ライブラリのディレクトリ、ライブラリといった指定があります。 distutils はこの情報をコンパイラに応じて異なるやり方で引渡します。例えば、Unix では、上の設定は以下のようなコンパイルコマンドになるかもしれません:

gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o

gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so

これらのコマンドラインは実演目的で書かれたものです; distutils のユーザは distutils が正しくコマンドを実行すると信用してください。

3.1. 拡張モジュールの配布

拡張モジュールをうまくビルドできたら、三通りの使い方があります。

エンドユーザは普通モジュールをインストールしようと考えます; これには

python setup.py install

を実行します。

モジュールメンテナはソースパッケージを作成します; これには

python setup.py sdist

を実行します。

場合によっては、ソース配布物に追加のファイルを含める必要があります; これには MANIFEST.in ファイルを使います; 詳しくは distutils のドキュメントを参照してください。

ソースコード配布物をうまく構築できたら、メンテナはバイナリ配布物も作成できます。プラットフォームに応じて、以下のコマンドのいずれかを使います。

python setup.py bdist_wininst
python setup.py bdist_rpm
python setup.py bdist_dumb

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

4. Windows 上での C および C++ 拡張モジュールのビルド

この章では Windows 向けの Python 拡張モジュールを Microsoft Visual C++ を使って作成する方法について簡単に述べ、その後に拡張モジュールのビルドがどのように動作するのかについて詳しい背景を述べます。この説明は、Python 拡張モジュールを作成する Windows プログラマと、 Unix と Windows の双方でうまくビルドできるようなソフトウェアの作成に興味がある Unix プログラマの双方にとって有用です。

モジュールの作者には、この節で説明している方法よりも、 distutils によるアプローチで拡張モジュールをビルドするよう勧めます。また、Python をビルドした際に使われた C コンパイラが必要です; 通常は Microsoft Visual C++です。

ノート

この章では、Python のバージョン番号が符号化されて入っているたくさんのファイル名について触れます。これらのファイル名は XY で表されるバージョン名付きで表現されます; 'X' は使っている Python リリースのメジャーバージョン番号、 'Y' はマイナーバージョン番号です。例えば、 Python 2.2.1 を使っているなら、 XY は実際には 22 になります。

4.1. 型どおりのアプローチ

Windows での拡張モジュールのビルドには、Unix と同じように、 distutils パッケージを使ったビルド作業の制御と手動の二通りのアプローチがあります。 distutils によるアプローチはほとんどの拡張モジュールでうまくいきます; distutils を使った拡張モジュールのビルドとパッケージ化については、 Python モジュールの配布 にあります。この節では、C や C++で書かれた Python 拡張モジュールを手動でビルドするアプローチについて述べます。

以下の説明に従って拡張モジュールをビルドするには、インストールされている Python と同じバージョンの Python のソースコードを持っていなければなりません。また、 Microsoft Visual C++ “Developer Studio” が必要になります; プロジェクトファイルは VC++ バージョン 7.1 向けのものが提供されていますが、以前のバージョンの VC++も使えます。Python自体をビルドしたものと同じバージョンの VC++を使わなければならないことに注意しましょう。ここで述べる例題のファイルは、Python ソースコードと共に配布されており、 PC\example_nt\ ディレクトリにあります。

例題ファイルをコピーする — example_nt ディレクトリは PC ディレクトリのサブディレクトリになっています。これは PC 関連の全てのファイルをソースコード配布物内の同じディレクトリに置くための措置です。とはいえ実際には、 example_nt ディレクトリは PC の下では利用できません。そこで、まずこのディレクトリを一階層上にコピーして、 example_nt が PC および Include と同じ階層のディレクトリになるようにします。以降の作業は、移動先の新しいディレクトリ内で行ってください。

プロジェクトを開く — VC++から、 ファイル ‣ ソリューションを開くダイアログメニューを選択します (ファイル ‣ 開くではありません!)。ディレクトリ階層を辿って、 example_nt をコピーしたディレクトリ 内の example.sln を選択し、「開く」をクリックします。

例題の DLL をビルドする — 設定が全て正しく行われているか調べるために、ビルドしてみます:

ビルド構成を選びます。このステップは省略できます。ビルド ‣ 設定マネージャー ‣ アクティブなソリューションの設定を選び、 リリース または デバッグ を選びます。このステップを飛ばすと、VC++ はデフォルトでデバッグ構成を使います。

DLL をビルドします。 ビルド ‣ ソリューションのビルド を選びます。全ての中間ファイルおよび最終ファイルが、上のビルド構成で選んだ構成に従って Debug または Release という名前のディレクトリに生成されます。

デバッグモードの DLL をテストする — デバッグビルドが成功したら、コマンドプロンプトを起動し、 example_nt\Debug ディレクトリに移動してください。以下のセッション通りにコマンドを実行できるはずです (C> は DOS コマンドのプロンプト、 >>> は Python のプロンプトです; ビルド情報や様々なデバッグ出力は、ここに示したスクリーン出力と一致しないこともあるので注意して下さい):

C>..\..\PCbuild\python_d
Adding parser accelerators ...
Done.
Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> import example
[4897 refs]
>>> example.foo()
Hello, world
[4903 refs]
>>>

おめでとうございます! とうとう初めての Python 拡張モジュールのビルドに成功しましたね。

自分用にプロジェクトを作成する — プロジェクト用のディレクトリを適当な名前で作成してください。自作の C ソースコードをディレクトリ内にコピーします。モジュールのソースコードファイル名は必ずしもモジュール名と一致している必要はありませんが、初期化関数の名前はモジュール名と一致していなければなりません — 初期化関数の名前が initspam() なら、モジュールは spam という名前でしか import できません。 initspam() は第一引数を "spam" にして、 Py_InitModule() を呼び出します (このディレクトリにある、最小限の内容が書かれている example.c を手がかりにするとよいでしょう)。ならわしとして、ファイルは spam.c または spammodule.c という名前にしておきます。出力ファイル名はリリースモードでは spam.pyd 、デバッグモードでは spam_d.pyd 、になるはずです。 .pyd という拡張子は、システムライブラリの spam.dll と作成した拡張モジュールの間での混乱を避けるために選ばれました。

バージョン 2.5 で変更.

さて、やり方は二通りあります:

example.sln と example.vcproj をコピーし、 spam.* に名前を変えて、手作業で編集する

新しくプロジェクトを作成する; 説明は下にあります。

どちらの場合も、 example_nt\example.def を spam\spam.def にコピーして、新たにできた spam.def を編集し、二行目に ‘initspam‘ が入るようにします。自分で新たなプロジェクトを作成したのなら、ここで spam.def をプロジェクトに追加しておいてください (このファイルはたった二行しかない目障りなファイルです。 .def ファイルを全く無視するという方法もあり、それには /exprt:initspam を「プロジェクトのプロパティ」ダイアログにあるリンク設定のどこかに手動で追加します)。

新しくプロジェクトを作成する — ファイル ‣ 新規作成 ‣ プロジェクト ダイアログを使って、新たなプロジェクト用ワークスペースを作成します。 Visual C++ プロジェクト/Win32/Win32 プロジェクトを選択し、名前(spam) を入れ、「場所」が先ほど作成した spam ディレクトリの親ディレクトリに (Python ビルドツリーの直下のサブディレクトリで、 Include および PC と同じディレクトリになるはずです) あることを確かめます。「作成」をクリックします。

前の節で述べた spam.def をここで作成しておかねばなりません。その後、追加 ‣ ファイルをプロジェクトに追加 ダイアログを選びます。「ファイルの種類」を *.* にして、 spam.c と spam.def を選び、 OK をクリックします (一つ一つファイルを追加してもかまいません)。

プロジェクト ‣ spam のプロパティ ダイアログを開きます。ほんのいくつかですが、設定の変更が必要です。 構成 ドロップダウンリストに すべての構成が設定されているか確かめてください。 C/C++ タブを選び、ポップアップメニューから「一般」カテゴリを選びます。以下のテキスト:

..\Include,..\PC

を、 追加のインクルードディレクトリ とラベルされたエントリボックスに入力します

次に、「リンカ」タブの「一般」カテゴリを選び、

..\PCbuild

を 追加のライブラリディレクトリ と書かれたテキストボックスに入力します。

さて、構成ごとに特有の設定をいくつか行う必要があります:

「構成」ドロップダウンリストから、 リリース を選んでください。「リンク」タブをクリックし、「入力」カテゴリを選んで、「追加の依存ファイル」ボックス内のリストに pythonXY.lib を追加します。

「構成」ドロップダウンリストから、 デバッグ に切り替え、「追加の依存ファイル」ボックス内のリストに pythonXY_d.lib を追加します。次に C/C++ タブをクリックして、コード生成 をカテゴリから選び、 ラインタイムライブラリ に対してマルチスレッドデバッグ DLL を選びます。

「構成」ドロップダウンリストから リリース に切り替えなおします。 ラインタイムライブラリ に対してマルチスレッド DLL を選びます。

作っているモジュールが新たな型を作成するのなら、以下の行:

PyObject_HEAD_INIT(&PyType_Type)

がうまくいかないはずです。拡張モジュール内での静的な型オブジェクトの初期化は “initializer not a constant” というようなエラーメッセージで失敗することがあります。これは DLL を MSVC でビルドするときに表示されます。そこで:

PyObject_HEAD_INIT(NULL)

に変更してください。また、以下の行をモジュール初期化関数に加えます:

if (PyType_Ready(&MyObject_Type) < 0)
     return NULL;

4.2. Unix と Windows の相違点

Unix と Windows では、コードの実行時読み込みに全く異なるパラダイムを用いています。動的ロードされるようなモジュールをビルドしようとする前に、自分のシステムがどのように動作するか知っておいてください。

Unix では、共有オブジェクト (.so) ファイルにプログラムが使うコード、そしてプログラム内で使う関数名やデータが入っています。ファイルがプログラムに結合されると、これらの関数やデータに対するファイルのコード内の全ての参照は、メモリ内で関数やデータが配置されている、プログラム中の実際の場所を指すように変更されます。これは基本的にはリンク操作にあたります。

Windows では、動的リンクライブラリ (.dll) ファイルにはぶら下がり参照 (dangling reference) はありません。その代わり、関数やデータへのアクセスはルックアップテーブルを介します。従って DLL コードの場合、実行時にポインタがプログラムメモリ上の正しい場所を指すように修正する必要はありません; その代わり、コードは常に DLL のルックアップテーブルを使い、ルックアップテーブル自体は実行時に実際の関数やデータを指すように修正されます。

Unix には、唯一のライブラリファイル形式 (.a) しかありません。 .a ファイルには複数のオブジェクトファイル (.o) 由来のコードが入っています。共有オブジェクトファイル (.so) を作成するリンク処理の段階中に、リンカは定義場所の不明な識別子に遭遇することがあります。このときリンカはライブラリ内のオブジェクトファイルを検索します; もし識別子が見つかると、リンカはそのオブジェクトファイルから全てのコードを取り込みます。

Windows では、二つの形式のライブラリ、静的ライブラリとインポートライブラリがあります (どちらも .lib と呼ばれています)。静的ライブラリは Unix における .a ファイルに似ています; このファイルには、必要に応じて取り込まれるようなコードが入っています。インポートライブラリは、基本的には特定の識別子が不正ではなく、 DLL がロードされた時点で存在することを保証するためにだけ使われます。リンカはインポートライブラリからの情報を使ってルックアップテーブルを作成し、DLL に入っていない識別子を使えるようにします。アプリケーションや DLL がリンクされるさい、インポートライブラリが生成されることがあります。このライブラリは、アプリケーションや DLL 内のシンボルに依存するような、将来作成される全ての DLL で使うために必要になります。

二つの動的ロードモジュール、B と C を作成し、別のコードブロック A を共有するとします。Unix では、 A.a を B.so や C.so をビルドするときのリンカに渡したりは しません ; そんなことをすれば、コードは二度取り込まれ、B と C のそれぞれが自分用のコピーを持ってしまいます。 Windows では、 A.dll をビルドすると A.lib もビルドされます。 B や C のリンクには A.lib を渡します。 A.lib にはコードは入っていません; 単に A のコードにアクセスするするために実行時に用いられる情報が入っているだけです。

Windows ではインポートライブラリの使用は import spam とするようなものです; この操作によって spam の名前にアクセスできますが、コードのコピーを個別に作成したりはしません。Unix では、ライブラリとのリンクはむしろ from spam import * に似ています; この操作では個別にコードのコピーを生成します。

4.3. DLL 使用の実際

Windows 版の Python は Microsoft Visual C++でビルドされています; 他のコンパイラを使うと、うまく動作したり、しなかったりします (Borland も一見うまく動作しません)。この節の残りの部分は MSVC++ 向けの説明です。

Windows で DLL を作成する際は、 pythonXY.lib をリンカに渡さねばなりません。例えば二つの DLL 、spam と ni (spam の中には C 関数が入っているとします) をビルドするには、以下のコマンドを実行します:

cl /LD /I/python/include spam.c ../libs/pythonXY.lib
cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib

最初のコマンドで、三つのファイル: spam.obj 、 spam.dll および spam.lib ができます。 Spam.dll には (PyArg_ParseTuple() のような) Python 関数は全く入っていませんが、 pythonXY.lib のおかげで Python コードを見つけることはできます。

二つ目のコマンドでは、 ni.dll (および .obj と .lib) ができ、このライブラリは spam と Python 実行形式中の必要な関数をどうやって見つければよいか知っています。

全ての識別子がルックアップテーブル上に公開されるわけではありません。他のモジュール (Python 自体を含みます) から、自作の識別子が見えるようにするには、 void _declspec(dllexport) initspam(void) や PyObject _declspec(dllexport) *NiGetSpamData(void) のように、 _declspec(dllexport) で宣言せねばなりません。

Developer Studio は必要もなく大量のインポートライブラリを DLL に突っ込んで、実行形式のサイズを 100K も大きくしてしまいます。不用なライブラリを追い出したければ、「プロジェクトのプロパティ」ダイアログを選び、「リンカ」タブに移動して、 インポートライブラリの無視を指定します。その後、適切な msvcrtxx.lib をライブラリのリストに追加してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

5. 他のアプリケーションへの Python の埋め込み

前章では、 Python を拡張する方法、すなわち C 関数のライブラリを Python に結びつけて機能を拡張する方法について述べました。同じようなことを別の方法でも実行できます: それは、自分の C/C++ アプリケーションに Python を埋め込んで機能を強化する、というものです。埋め込みを行うことで、アプリケーションの何らかの機能を C や C++ の代わりに Python で実装できるようになります。埋め込みは多くの用途で利用できます; ユーザが Python でスクリプトを書き、アプリケーションを自分好みに仕立てられるようにする、というのがその一例です。プログラマが、特定の機能を Python でより楽に書ける場合に自分自身のために埋め込みを行うこともできます。

Python の埋め込みは Python の拡張と似ていますが、全く同じというわけではありません。その違いは、Python を拡張した場合にはアプリケーションのメインプログラムは依然として Python インタプリタである一方、 Python を組み込みんだ場合には、メインプログラムには Python が関係しない — その代わりに、アプリケーションのある一部分が時折 Python インタプリタを呼び出して何らかの Python コードを実行させる — かもしれない、ということです。

従って、 Python の埋め込みを行う場合、自作のメインプログラムを提供しなければなりません。メインプログラムがやらなければならないことの一つに、 Python インタプリタの初期化があります。とにかく少なくとも関数 Py_Initialize() を呼び出さねばなりません。オプションとして、Python 側にコマンドライン引数を渡すために関数呼び出しを行います。その後、アプリケーションのどこでもインタプリタを呼び出せるようになります。

インタプリタを呼び出すには、異なるいくつかの方法があります: Python 文が入った文字列を PyRun_SimpleString() に渡す、 stdio ファイルポインタとファイル名 (これはエラーメッセージ内でコードを識別するためだけのものです) を PyRun_SimpleFile() に渡す、といった具合です。これまでの各章で説明した低水準の操作を呼び出して、Python オブジェクトを構築したり使用したりもできます。

Python の埋め込みを行っている簡単なデモは、ソース配布物の Demo/embed/ ディレクトリにあります。

参考

Python/C API リファレンスマニュアル

Python C インタフェースの詳細はこのマニュアルに書かれています。必要な情報の大部分はここにあるはずです。

5.1. 高水準の埋め込み

Python の埋め込みの最も簡単な形式は、超高水準インタフェースの利用です。このインタフェースは、アプリケーションとやり取りする必要がない Python スクリプトを実行するためのものです。例えばこれは、一つのファイル上で何らかの操作を実現するのに利用できます。

#include <Python.h>

int
main(int argc, char *argv[])
{
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}

上のコードでは、まず Python インタプリタを Py_Initialize() で起動し、続いてハードコードされた Python スクリプトで日付と時間の出力を実行します。その後、 Py_Finalize() の呼び出しでインタプリタを終了し, プログラムの終了に続きます。実際のプログラムでは、Python スクリプトを他のソース、おそらくテキストエディタルーチンやファイル、データベースから取り出したいと考えるかもしれません。Python コードをファイルから取り出すには、 PyRun_SimpleFile() 関数を使うのがよいでしょう。この関数はメモリを確保して、ファイルの内容をロードする手間を省いてくれます。

5.2. 超高水準の埋め込みから踏み出す: 概要

高水準インタフェースは、断片的な Python コードをアプリケーションから実行できるようにしてくれますが、アプリケーションと Python コードの間でのデータのやり取りは、控えめに言っても煩わしいものです。データのやり取りをしたいなら、より低水準のインタフェース呼び出しを利用しなくてはなりません。より多く C コードを書かねばならない代わりに、ほぼ何でもできるようになります。

Python の拡張と埋め込みは、趣旨こそ違え、同じ作業であるということに注意せねばなりません。これまでの章で議論してきたトピックのほとんどが埋め込みでもあてはまります。これを示すために、 Python から C への拡張を行うコードが実際には何をするか考えてみましょう:

データ値を Python から C に変換する。

変換された値を使って C ルーチンの関数呼び出しを行い、

呼び出しで得られたデータ値 C から Python に変換する。

Python を埋め込む場合には、インタフェースコードが行う作業は以下のようになります:

データ値を C から Python に変換する。

変換された値を使って Python インタフェースルーチンの関数呼び出しを行い、

呼び出しで得られたデータ値 Python から C に変換する。

一見して分かるように、データ変換のステップは、言語間でデータを転送する方向が変わったのに合わせて単に入れ替えただけです。唯一の相違点は、データ変換の間にあるルーチンです。拡張を行う際には C ルーチンを呼び出しますが、埋め込みの際には Python ルーチンを呼び出します。

この章では、Python から C へ、そしてその逆へとデータを変換する方法については議論しません。また、正しい参照の使い方やエラーの扱い方についてすでに理解しているものと仮定します。これらの側面についてはインタプリタの拡張と何ら変わるところがないので、必要な情報については以前の章を参照できます。

5.3. 純粋な埋め込み

最初に例示するプログラムは、Python スクリプト内の関数を実行するためのものです。超高水準インタフェースに関する節で挙げた例と同様に、Python インタプリタはアプリケーションと直接やりとりはしません (が、次の節でやりとりするよう変更します)。

Python スクリプト内で定義されている関数を実行するためのコードは以下のようになります:

#include <Python.h>

int
main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    if (argc < 3) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
        return 1;
    }

    Py_Initialize();
    pName = PyString_FromString(argv[1]);
    /* Error checking of pName left out */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
        /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyInt_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argument\n");
                    return 1;
                }
                /* pValue reference stolen here: */
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf("Result of call: %ld\n", PyInt_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
        return 1;
    }
    Py_Finalize();
    return 0;
}

このコードは argv[1] を使って Python スクリプトをロードし、 argv[2] 内に指定された名前の関数を呼び出します。関数の整数引数は argv 配列中の他の値になります。このプログラムをコンパイルしてリンクし (できた実行可能形式を call と呼びましょう)、以下のような Python スクリプトを実行することにします:

def multiply(a,b):
    print "Will compute", a, "times", b
    c = 0
    for i in range(0, a):
        c = c + b
    return c

実行結果は以下のようになるはずです:

$ call multiply multiply 3 2
Will compute 3 times 2
Result of call: 6

この程度の機能を実現するにはプログラムがいささか大きすぎますが、ほとんどは Python から C へのデータ変換やエラー報告のためのコードです。Python の埋め込みという観点から最も興味深い部分は以下のコード、

Py_Initialize();
pName = PyString_FromString(argv[1]);
/* pName のエラーチェックは省略している */
pModule = PyImport_Import(pName);

から始まる部分です。

インタプリタの初期化後、スクリプトは PyImport_Import() を使って読み込まれます。このルーチンは Python 文字列を引数に取る必要があり、データ変換ルーチン PyString_FromString() で構築します。

pFunc = PyObject_GetAttrString(pModule, argv[2]);
/* pFunc は新たな参照 */

if (pFunc && PyCallable_Check(pFunc)) {
    ...
}
Py_XDECREF(pFunc);

ひとたびスクリプトが読み込まれると、 PyObject_GetAttrString() を使って必要な名前を取得できます。名前がスクリプト中に存在し、取得したオブジェクトが呼び出し可能オブジェクトであれば、このオブジェクトが関数であると考えて差し支えないでしょう。そこでプログラムは定石どおりに引数のタプル構築に進みます。その後、Python 関数を以下のコードで呼び出します:

pValue = PyObject_CallObject(pFunc, pArgs);

関数が処理を戻す際、 pValue は NULL になるか、関数の戻り値への参照が入っています。値を調べた後には忘れずに参照を解放してください。

5.4. 埋め込まれた Python の拡張

ここまでは、埋め込み Python インタプリタはアプリケーション本体の機能にアクセスする手段がありませんでした。 Python API を使うと、埋め込みインタプリタを拡張することでアプリケーション本体へのアクセスを可能にします。つまり、アプリケーションで提供されているルーチンを使って、埋め込みインタプリタを拡張するのです。複雑なことのように思えますが、それほどひどいわけではありません。さしあたって、アプリケーションが Python インタプリタを起動したということをちょっと忘れてみてください。その代わり、アプリケーションがサブルーチンの集まりで、あたかも普通の Python 拡張モジュールを書くかのように、Python から各ルーチンにアクセスできるようにするグルー(glue, 糊) コードを書くと考えてください。例えば以下のようにです:

static int numargs=0;

/* アプリケーションのコマンドライン引数の個数を返す */
static PyObject*
emb_numargs(PyObject *self, PyObject *args)
{
    if(!PyArg_ParseTuple(args, ":numargs"))
        return NULL;
    return Py_BuildValue("i", numargs);
}

static PyMethodDef EmbMethods[] = {
    {"numargs", emb_numargs, METH_VARARGS,
     "Return the number of arguments received by the process."},
    {NULL, NULL, 0, NULL}
};

上のコードを main() 関数のすぐ上に挿入します。また、以下の二つの文を Py_Initialize() の直後に挿入します:

numargs = argc;
Py_InitModule("emb", EmbMethods);

これら二つの行は numargs 変数を初期化し、埋め込み Python インタプリタから emb.numargs() 関数にアクセスできるようにします。これらの拡張モジュール関数を使うと、 Python スクリプトは

import emb
print "Number of arguments", emb.numargs()

のようなことができます。

実際のアプリケーションでは、こうしたメソッドでアプリケーション内の API を Python に公開することになります。

5.5. C++による Python の埋め込み

C++ プログラム中にも Python を埋め込めます; 厳密に言うと、どうやって埋め込むかは使っているC++ 処理系の詳細に依存します; 一般的には、メインプログラムをC++で書き、C++ コンパイラを使ってプログラムをコンパイル・リンクする必要があるでしょう。 Python 自体を C++でコンパイルしなおす必要はありません。

5.6. リンクに関する要件

Python ソースと一緒についてくる configure スクリプトは動的にリンクされる拡張モジュールが必要とするシンボルを公開するようただしく Python をビルドしますが、この機能は Python ライブラリを静的に埋め込むようなアプリケーションには継承されません。少なくとも Unix ではそうです。これは、アプリケーションが静的な実行時ライブラリ (libpython.a) にリンクされていて、かつ (.so ファイルとして実装されている) 動的ロードされるような拡張モジュールをロードする必要がある場合に起きる問題です。

問題になるのは、拡張モジュールが使うあるエントリポイントが Python ランタイムだけで定義されているという状況です。埋め込みを行うアプリケーション側がこうしたエントリポイントを全く使わない場合、リンカによってはエントリポイントを最終的に生成される実行可能形式のシンボルテーブル内に含めません。こうした場合、リンカに追加のオプションを与えて、これらのシンボルを除去しないよう教える必要があります。

プラットフォームごとに正しいオプションを決めるのはかなり困難です、とはいえ、幸運なことに、オプションは Python のビルド設定内にすでにあります。インストール済みの Python インタプリタからオプションを取り出すには、対話インタプリタを起動して、以下のような短いセッションを実行します:

>>> import distutils.sysconfig
>>> distutils.sysconfig.get_config_var('LINKFORSHARED')
'-Xlinker -export-dynamic'

表示された文字列の内容が、ビルド時に使うべきオプションです。文字列が空であれば、特に追加すべきオプションはありません。 LINKFORSHARED の定義内容は、 Python のトップレベル Makefile 内の同名の変数に対応しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python インタプリタの拡張と埋め込み »

6. このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる Extending and Embedding the Python Interpreter の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

6.1. 翻訳者一覧 (敬称略)

Yasushi MASUDA

Yusuke SHINYAMA

Kazuo Moriwaka

TAKAGI Masahiro

INADA Naoki <inada-n at klab.jp>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル

Release: | 2.7
Date: | 2011年 12月 26日

このマニュアルでは、拡張モジュールを書いたり Python インタプリタをアプリケーションに埋め込んだりしたい C/C++ プログラマが利用できる API について述べています。 Python インタプリタの拡張と埋め込みは拡張モジュールを書く際の一般的な決まりごとについて記述していますが、 API の詳細までは記述していないので、このドキュメントが手引きになります。

はじめに

インクルードファイル

オブジェクト、型および参照カウント

例外

Python の埋め込み

デバッグ版ビルド (Debugging Builds)

超高レベルレイヤ

参照カウント

例外処理

Unicode 例外オブジェクト

再帰の管理

標準例外

文字列の例外

ユーティリティ関数

オペレーティングシステム関連のユーティリティ

システム関数

プロセス制御

モジュールの import

データ整列化 (data marshalling) のサポート

引数の解釈と値の構築

文字列の変換と書式化

リフレクション

codec レジストリとサポート関数

抽象オブジェクトレイヤ (abstract objects layer)

オブジェクトプロトコル (object protocol)

数値型プロトコル (number protocol)

シーケンス型プロトコル (sequence protocol)

マップ型プロトコル (mapping protocol)

イテレータプロトコル (iterator protocol)

古いバッファプロトコル

具象オブジェクト (concrete object) レイヤ

基本オブジェクト (fundamental object)

数値型オブジェクト (numeric object)

シーケンスオブジェクト (sequence object)

マップ型オブジェクト (mapping object)

その他のオブジェクト

初期化 (initialization)、終了処理 (finalization)、スレッド

インタプリタの初期化と終了処理

プロセスワイドのパラメータ

スレッド状態 (thread state) とグローバルインタプリタロック (global interpreter lock)

サブインタプリタサポート

非同期通知

プロファイルとトレース (profiling and tracing)

高度なデバッガサポート (advanced debugger support)

メモリ管理

概要

メモリインタフェース

例

オブジェクト実装サポート (object implementation support)

オブジェクトをヒープ上にメモリ確保する

共通のオブジェクト構造体 (common object structure)

型オブジェクト

数値オブジェクト構造体

マップ型オブジェクト構造体

シーケンスオブジェクト構造体

バッファオブジェクト構造体 (buffer object structure)

循環参照ガベージコレクションをサポートする

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

はじめに

Python のアプリケーションプログラマ用インタフェース (Application Programmer’s Interface, API) は、 Python インタプリタに対する様々なレベルでのアクセス手段を C や C++ のプログラマに提供しています。この API は通常 C++ からも全く同じように利用できるのですが、簡潔な呼び名にするために Python/C API と名づけられています。根本的に異なる二つの目的から、 Python/C API が用いられます。第一は、特定用途の 拡張モジュール (extention module) 、すなわち Python インタプリタを拡張する C で書かれたモジュールを記述する、という目的です。第二は、より大規模なアプリケーション内で Python を構成要素 (component) として利用するという目的です; このテクニックは、一般的にはアプリケーションへの Python の埋め込み (embedding) と呼びます。拡張モジュールの作成は比較的わかりやすいプロセスで、 “手引書 (cookbook)” 的なアプローチでうまく実現できます。作業をある程度まで自動化してくれるツールもいくつかあります。一方、他のアプリケーションへの Python の埋め込みは、Python ができてから早い時期から行われてきましたが、拡張モジュールの作成に比べるとやや難解です。

多くの API 関数は、Python の埋め込みであるか拡張であるかに関わらず役立ちます; とはいえ、 Python を埋め込んでいるほとんどのアプリケーションは、同時に自作の拡張モジュールも提供する必要が生じることになるでしょうから、Python を実際にアプリケーションに埋め込んでみる前に拡張モジュールの書き方に詳しくなっておくのはよい考えだと思います。

インクルードファイル

Python/C API を使うために必要な、関数、型およびマクロの全ての定義をインクルードするには、以下の行:

#include "Python.h"

をソースコードに記述します。この行を記述すると、標準ヘッダ: <stdio.h>, <string.h>, <errno.h>, <limits.h>, <assert.h>, <stdlib.h> を (利用できれば) インクルードします。

ノート

システムによっては、Python の定義しているプリプロセッサ定義が標準ヘッダに影響をおよぼす可能性があるので、 Python.h は他の標準ヘッダファイルよりも前にインクルードしてください。

Python.h で定義されている、ユーザから見える名前全て (Python.h がインクルードしている標準ヘッダの名前は除きます) には、接頭文字列 Py または _Py が付きます。 _Py で始まる名前は Python 実装で内部使用するための名前で、拡張モジュールの作者は使ってはなりません。構造体のメンバには予約済みの接頭文字列はありません。

重要: API のユーザは、 Py や _Py で始まる名前を定義するようなコードを絶対に書いてはなりません。後からコードを読む人を混乱させたり、将来の Python のバージョンで同じ名前が定義されて、ユーザの書いたコードの可搬性を危うくする可能性があります。

ヘッダファイル群は通常 Python と共にインストールされます。 Unixでは prefix/include/pythonversion/ および exec_prefix/include/pythonversion/ に置かれます。 prefix と exec_prefix は Python をビルドする際の configure スクリプトに与えたパラメタに対応し、 version は sys.version[:3] に対応します。 Windows では、ヘッダは prefix/include に置かれます。 prefix はインストーラに指定したインストールディレクトリです。

ヘッダをインクルードするには、各ヘッダの入ったディレクトリ (別々のディレクトリの場合は両方) を、コンパイラがインクルードファイルを検索するためのパスに入れます。親ディレクトリをサーチパスに入れて、 #include <pythonX.Y/Python.h> のようにしては なりません ; prefix 内のプラットフォームに依存しないヘッダは、 exec_prefix からプラットフォーム依存のヘッダをインクルードしているので、このような操作を行うと複数のプラットフォームでのビルドができなくなります。

API はすべて C 言語を使って定義していますが、ヘッダファイルはエントリポイントを extern "C" で適切に宣言しているので、 C++ ユーザは、なんの問題もなく C++から API を利用できることに気づくはずです。

オブジェクト、型および参照カウント

Python/C API 関数は、 PyObject* 型の一つ以上の引数と戻り値を持ちます。この型は、任意の Python オブジェクトを表現する不透明 (opaque) なデータ型へのポインタです。 Python 言語は、全ての Python オブジェクト型をほとんどの状況 (例えば代入、スコープ規則 (scope rule)、引数渡し) で同様に扱います。ほとんど全ての Python オブジェクトはヒープ (heap) 上に置かれます: このため、 PyObject 型のオブジェクトは、自動記憶 (automatic) としても静的記憶 (static) としても宣言できません。 PyObject* 型のポインタ変数のみ宣言できます。唯一の例外は、型オブジェクトです; 型オブジェクトはメモリ解放 (deallocate) してはならないので、通常は静的記憶の PyTypeObject オブジェクトにします。

全ての Python オブジェクトには (Python 整数型ですら) 型 (type) と参照カウント (reference count) があります。あるオブジェクトの型は、そのオブジェクトがどの種類のオブジェクトか (例えば整数、リスト、ユーザ定義関数、など; その他多数については 標準型の階層 で説明しています) を決定します。よく知られている型については、各々マクロが存在して、あるオブジェクトがその型かどうか調べられます; 例えば、 PyList_Check(a) は、 a で示されたオブジェクトが Python リスト型のとき (かつそのときに限り) 真値を返します。

参照カウント

今日の計算機は有限の (しばしば非常に限られた) メモリサイズしか持たないので、参照カウントは重要な概念です; 参照カウントは、あるオブジェクトに対して参照を行っている場所が何箇所あるかを数える値です。参照を行っている場所とは、別のオブジェクトであったり、グローバルな (あるいは静的な) C 変数であったり、何らかの C 関数内にあるローカルな変数だったりします。あるオブジェクトの参照カウントがゼロになると、そのオブジェクトは解放されます。そのオブジェクトに他のオブジェクトへの参照が入っていれば、他のオブジェクトの参照カウントはデクリメントされます。デクリメントの結果、他のオブジェクトの参照カウントがゼロになると、今度はそのオブジェクトが解放される、といった具合に以後続きます。(言うまでもなく、互いを参照しあうオブジェクトについて問題があります; 現状では、解決策は “何もしない” です。)

参照カウントは、常に明示的なやり方で操作されます。通常の方法では、 Py_INCREF() でオブジェクトの参照を 1 インクリメントし、 Py_DECREF() で 1 デクリメントします。 Py_DECREF() マクロは、incref よりもかなり複雑です。というのは、 Py_DECREF() マクロは参照カウントがゼロになったかどうかを調べて、なった場合にはオブジェクトのデアロケータ (deallocator) を呼び出さなければならないからです。デアロケータとは、オブジェクトの型を定義している構造体内にある関数へのポインタです。型固有のデアロケータは、その型が複合オブジェクト (compound object) 型である場合には、オブジェクト内の他のオブジェクトに対する参照カウントをデクリメントするよう気を配るとともに、その他の必要なファイナライズ (finalize) 処理を実行します。参照カウントがオーバフローすることはありません; というのも、仮想メモリ空間には、(sizeof(Py_ssize_t) >= sizeof(char*) と仮定した場合) 少なくとも参照カウントの記憶に使われるビット数と同じだけのメモリ上の位置があるからです。従って、参照カウントのインクリメントは単純な操作になります。

オブジェクトへのポインタが入っているローカルな変数全てについて、オブジェクトの参照カウントを必ずインクリメントしなければならないわけではありません。理論上は、オブジェクトの参照カウントは、オブジェクトを指し示す変数が生成されたときに 1 増やされ、その変数がスコープから出て行った際に 1 減らされます。しかしこの場合、二つの操作は互いに相殺するので、結果的に参照カウントは変化しません。参照カウントを使う真の意義とは、手持ちの何らかの変数がオブジェクトを指している間はオブジェクトがデアロケートされないようにすることにあります。オブジェクトに対して、一つでも別の参照が行われていて、その参照が手持ちの変数と同じ間維持されるのなら、参照カウントを一時的に増やす必要はありません。参照カウント操作の必要性が浮き彫りになる重要な局面とは、Python から呼び出された拡張モジュール内の C 関数にオブジェクトを引数として渡すときです; 呼び出しメカニズムは、呼び出しの間全ての引数に対する参照を保証します。

しかしながら、よく陥る過ちとして、あるオブジェクトをリストから得たときに、参照カウントをインクリメントせずにしばらく放っておくというのがあります。他の操作がオブジェクトをリストから除去してしまい、参照カウントがデクリメントされてデアロケートされてしまうことが考えられます。本当に危険なのは、まったく無害そうにみえる操作が、上記の動作を引き起こす何らかの Python コードを呼び出しかねないということです; Py_DECREF() からユーザへ制御を戻せるようなコードパスが存在するため、ほとんど全ての操作が潜在的に危険をはらむことになります。

安全に参照カウントを操作するアプローチは、汎用の操作 (関数名が PyObject_, PyNumber_, PySequence_, および PyMapping_ で始まる関数) の利用です。これらの操作は常に戻り値となるオブジェクトの参照カウントをインクリメントします。ユーザには戻り値が不要になったら Py_DECREF() を呼ぶ責任が残されています; とはいえ、すぐにその習慣は身に付くでしょう。

参照カウントの詳細

Python/C API の各関数における参照カウントの振る舞いは、説明するには、 参照の所有権 (ownership of references) という言葉でうまく説明できます。所有権は参照に対するもので、オブジェクトに対するものではありません (オブジェクトは誰にも所有されず、常に共有されています)。ある参照の “所有” は、その参照が必要なくなった時点で Py_DECREF() を呼び出す役割を担うことを意味します。所有権は委譲でき、あるコードが委譲によって所有権を得ると、今度はそのコードが参照が必要なくなった際に最終的に Py_DECREF() や Py_XDECREF() を呼び出して decref する役割を担います — あるいは、その役割を (通常はコードを呼び出した元に) 受け渡します。ある関数が、関数の呼び出し側に対して参照の所有権を渡すと、呼び出し側は 新たな 参照 (new reference) を得る、と言います。所有権が渡されない場合、呼び出し側は参照を 借りる (borrow) といいます。借りた参照に対しては、何もする必要はありません。

逆に、ある関数呼び出しで、あるオブジェクトへの参照を呼び出される関数に渡す際には、二つの可能性: 関数がオブジェクトへの参照を 盗み取る (steal) 場合と、そうでない場合があります。

参照を盗む とは、関数に参照を渡したときに、参照の所有者がその関数になったと仮定し、関数の呼び出し元には所有権がなくなるということです。

参照を盗み取る関数はほとんどありません; 例外としてよく知られているのは、 PyList_SetItem() と PyTuple_SetItem() で、これらはシーケンスに入れる要素に対する参照を盗み取ります (しかし、要素の入る先のタプルやリストの参照は盗み取りません!)。これらの関数は、リストやタプルの中に新たに作成されたオブジェクトを入れていく際の常套的な書き方をしやすくするために、参照を盗み取るように設計されています; 例えば、 (1, 2, "three") というタプルを生成するコードは以下のようになります (とりあえず例外処理のことは忘れておきます; もっとよい書き方を後で示します):

PyObject *t;

t = PyTuple_New(3);
PyTuple_SetItem(t, 0, PyInt_FromLong(1L));
PyTuple_SetItem(t, 1, PyInt_FromLong(2L));
PyTuple_SetItem(t, 2, PyString_FromString("three"));

ここで、 PyInt_FromLong() は新しい参照を返し、すぐに PyTuple_SetItem() に盗まれます。参照が盗まれた後もそのオブジェクトを利用したい場合は、参照盗む関数を呼び出す前に、 Py_INCREF() を利用してもう一つの参照を取得してください。

ちなみに、 PyTuple_SetItem() はタプルに値をセットするための 唯一の 方法です; タプルは変更不能なデータ型なので、 PySequence_SetItem() や PyObject_SetItem() を使うと上の操作は拒否されてしまいます。自分でタプルの値を入れていくつもりなら、 PyTuple_SetItem() だけしか使えません。

同じく、リストに値を入れていくコードは PyList_New() と PyList_SetItem() で書けます。

しかし実際には、タプルやリストを生成して値を入れる際には、上記のような方法はほとんど使いません。より汎用性のある関数、 Py_BuildValue() があり、ほとんどの主要なオブジェクトをフォーマット文字列 format string の指定に基づいて C の値から生成できます。例えば、上の二種類のコードブロックは、以下のように置き換えられます (エラーチェックにも配慮しています):

PyObject *tuple, *list;

tuple = Py_BuildValue("(iis)", 1, 2, "three");
list = Py_BuildValue("[iis]", 1, 2, "three");

自作の関数に渡す引数のように、単に参照を借りるだけの要素に対しては、 PyObject_SetItem() とその仲間を使うのがはるかに一般的です。その場合、参照カウントをインクリメントする必要がなく、参照を引き渡せる (“参照を盗み取らせられる”) ので、参照カウントに関する動作はより健全になります。例えば、以下の関数は与えられた要素をリスト中の全ての要素の値にセットします:

int
set_all(PyObject *target, PyObject *item)
{
    int i, n;

    n = PyObject_Length(target);
    if (n < 0)
        return -1;
    for (i = 0; i < n; i++) {
        PyObject *index = PyInt_FromLong(i);
        if (!index)
            return -1;
        if (PyObject_SetItem(target, index, item) < 0)
            return -1;
        Py_DECREF(index);
    }
    return 0;
}

関数の戻り値の場合には、状況は少し異なります。ほとんどの関数については、参照を渡してもその参照に対する所有権が変わることがない一方で、あるオブジェクトに対する参照を返すような多くの関数は、参照に対する所有権を呼び出し側に与えます。理由は簡単です: 多くの場合、関数が返すオブジェクトはその場で (on the fly) 生成されるため、呼び出し側が得る参照は生成されたオブジェクトに対する唯一の参照になるからです。従って、 PyObject_GetItem() や PySequence_GetItem() のように、オブジェクトに対する参照を返す汎用の関数は、常に新たな参照を返します (呼び出し側が参照の所有者になります)。

重要なのは、関数が返す参照の所有権を持てるかどうかは、どの関数を呼び出すかだけによる、と理解することです — 関数呼び出し時の お飾り (関数に引数として渡したオブジェクトの型) は この問題には関係ありません! 従って、 PyList_GetItem() を使ってリスト内の要素を得た場合には、参照の所有者にはなりません — が、同じ要素を同じリストから PySequence_GetItem() (図らずもこの関数は全く同じ引数をとります) を使って取り出すと、返されたオブジェクトに対する参照を得ます。

以下は、整数からなるリストに対して各要素の合計を計算する関数をどのようにして書けるかを示した例です; 一つは PyList_GetItem() を使っていて、もう一つは PySequence_GetItem() を使っています。

long
sum_list(PyObject *list)
{
    int i, n;
    long total = 0;
    PyObject *item;

    n = PyList_Size(list);
    if (n < 0)
        return -1; /* リストではない */
    for (i = 0; i < n; i++) {
        item = PyList_GetItem(list, i); /* 失敗しないはず */
        if (!PyInt_Check(item)) continue; /* 整数でなければ読み飛ばす */
        total += PyInt_AsLong(item);
    }
    return total;
}

long
sum_sequence(PyObject *sequence)
{
    int i, n;
    long total = 0;
    PyObject *item;
    n = PySequence_Length(sequence);
    if (n < 0)
        return -1; /* 長さの概念がない */
    for (i = 0; i < n; i++) {
        item = PySequence_GetItem(sequence, i);
        if (item == NULL)
            return -1; /* シーケンスでないか、その他の失敗 */
        if (PyInt_Check(item))
            total += PyInt_AsLong(item);
        Py_DECREF(item); /* GetItem で得た所有権を放棄する */
    }
    return total;
}

型

Python/C API において重要な役割を持つデータ型は、 PyObject 型の他にもいくつかあります; ほとんどは int, long, double, および char* といった、単なる C のデータ型です。また、モジュールで公開している関数を列挙する際に用いられる静的なテーブルや、新しいオブジェクト型におけるデータ属性を記述したり、複素数の値を記述したりするために構造体をいくつか使っています。これらの型については、その型を使う関数とともに説明してゆきます。

例外

Python プログラマは、特定のエラー処理が必要なときだけしか例外を扱う必要はありません; 処理しなかった例外は、処理の呼び出し側、そのまた呼び出し側、といった具合に、トップレベルのインタプリタ層まで自動的に伝播します。インタプリタ層は、スタックトレースバックと合わせて例外をユーザに報告します。

ところが、 C プログラマの場合、エラーチェックは常に明示的に行わねばなりません。 Python/C API の全ての関数は、関数のドキュメントで明確に説明がない限り例外を発行する可能性があります。一般的な話として、ある関数が何らかのエラーに遭遇すると、関数は例外を設定して、関数内における参照の所有権を全て放棄し、エラー値(error indicator)を返します。ドキュメントに書かれてない場合、このエラー値は関数の戻り値の型にによって、 NULL か -1 のどちらかになります。いくつかの関数ではブール型で真/偽を返し、偽はエラーを示します。きわめて少数の関数では明確なエラー指標を返さなかったり、あいまいな戻り値を返したりするので、 PyErr_Occurred() で明示的にエラーテストを行う必要があります。これらの例外は常に明示的にドキュメント化されます。

例外時の状態情報 (exception state)は、スレッド単位に用意された記憶領域 (per-thread storage) 内で管理されます (この記憶領域は、スレッドを使わないアプリケーションではグローバルな記憶領域と同じです)。一つのスレッドは二つの状態のどちらか: 例外が発生したか、まだ発生していないか、をとります。関数 PyErr_Occurred() を使うと、この状態を調べられます: この関数は例外が発生した際にはその例外型オブジェクトに対する借用参照 (borrowed reference) を返し、そうでないときには NULL を返します。例外状態を設定する関数は数多くあります: PyErr_SetString() はもっともよく知られている (が、もっとも汎用性のない) 例外を設定するための関数で、 PyErr_Clear() は例外状態情報を消し去る関数です。

完全な例外状態情報は、3 つのオブジェクト: 例外の型、例外の値、そしてトレースバック、からなります (どのオブジェクトも NULL を取り得ます)。これらの情報は、 Python オブジェクトの sys.exc_type, sys.exc_value, および sys.exc_traceback と同じ意味を持ちます; とはいえ、 C と Python の例外状態情報は全く同じではありません: Python における例外オブジェクトは、Python の try ... except 文で最近処理したオブジェクトを表す一方、 C レベルの例外状態情報が存続するのは、渡された例外情報を sys.exc_type その他に転送するよう取り計らう Python のバイトコードインタプリタのメインループに到達するまで、例外が関数の間で受け渡しされている間だけです。

Python 1.5 からは、Python で書かれたコードから例外状態情報にアクセスする方法として、推奨されていてスレッドセーフな方法は sys.exc_info() になっているので注意してください。この関数は Python コードの実行されているスレッドにおける例外状態情報を返します。また、これらの例外状態情報に対するアクセス手段は、両方とも意味づけ (semantics) が変更され、ある関数が例外を捕捉すると、その関数を実行しているスレッドの例外状態情報を保存して、呼び出し側の呼び出し側の例外状態情報を維持するようになりました。この変更によって、無害そうに見える関数が現在扱っている例外を上書きすることで引き起こされる、例外処理コードでよくおきていたバグを抑止しています; また、トレースバック内のスタックフレームで参照されているオブジェクトがしばしば不必要に寿命を永らえていたのをなくしています。

一般的な原理として、ある関数が別の関数を呼び出して何らかの作業をさせるとき、呼び出し先の関数が例外を送出していないか調べなくてはならず、もし送出していれば、その例外状態情報は呼び出し側に渡されなければなりません。呼び出し元の関数はオブジェクト参照の所有権をすべて放棄し、エラー指標を返さなくてはなりませんが、余計に例外を設定する必要は ありません — そんなことをすれば、たった今送出されたばかりの例外を上書きしてしまい、エラーの原因そのものに関する重要な情報を失うことになります。

例外を検出して渡す例は、上の sum_sequence() で示しています。偶然にも、この例ではエラーを検出した際に何ら参照を放棄する必要がありません。以下の関数の例では、エラーに対する後始末について示しています。まず、どうして Python で書くのが好きか思い出してもらうために、等価な Python コードを示します:

def incr_item(dict, key):
    try:
        item = dict[key]
    except KeyError:
        item = 0
    dict[key] = item + 1

以下は対応するコードを C で完璧に書いたものです:

int
incr_item(PyObject *dict, PyObject *key)
{
    /* Py_XDECREF 用に全てのオブジェクトを NULL で初期化 */
    PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
    int rv = -1; /* 戻り値の初期値を -1 (失敗) に設定しておく */

    item = PyObject_GetItem(dict, key);
    if (item == NULL) {
        /* KeyError だけを処理: */
        if (!PyErr_ExceptionMatches(PyExc_KeyError))
            goto error;

        /* エラーを無かったことに (clear) してゼロを使う: */
        PyErr_Clear();
        item = PyInt_FromLong(0L);
        if (item == NULL)
            goto error;
    }
    const_one = PyInt_FromLong(1L);
    if (const_one == NULL)
        goto error;

    incremented_item = PyNumber_Add(item, const_one);
    if (incremented_item == NULL)
        goto error;

    if (PyObject_SetItem(dict, key, incremented_item) < 0)
        goto error;
    rv = 0; /* うまくいった場合 */
    /* 後始末コードに続く */

 error:
    /* 成功しても失敗しても使われる後始末コード */

    /* NULL を参照している場合は無視するために Py_XDECREF() を使う */
    Py_XDECREF(item);
    Py_XDECREF(const_one);
    Py_XDECREF(incremented_item);

    return rv; /* エラーなら -1 、成功なら 0 */
}

なんとこの例は C で goto 文を使うお勧めの方法まで示していますね! この例では、特定の例外を処理するために PyErr_ExceptionMatches() および PyErr_Clear() をどう使うかを示しています。また、所有権を持っている参照で、値が NULL になるかもしれないものを捨てるために Py_XDECREF() をどう使うかも示しています (関数名に 'X' が付いていることに注意してください; Py_DECREF() は NULL 参照に出くわすとクラッシュします)。正しく動作させるためには、所有権を持つ参照を保持するための変数を NULL で初期化することが重要です; 同様に、あらかじめ戻り値を定義する際には値を -1 (失敗) で初期化しておいて、最後の関数呼び出しまでうまくいった場合にのみ 0 (成功) に設定します。

Python の埋め込み

Python インタプリタの埋め込みを行う人 (いわば拡張モジュールの書き手の対極) が気にかけなければならない重要なタスクは、 Python インタプリタの初期化処理 (initialization)、そしておそらくは終了処理 (finalization) です。インタプリタのほとんどの機能は、インタプリタの起動後しか使えません。

基本的な初期化処理を行う関数は Py_Initialize() です。この関数はロード済みのモジュールからなるテーブルを作成し、土台となるモジュール __builtin__, __main__, sys, および exceptions を作成します。また、モジュール検索パス (sys.path) の初期化も行います。

Py_Initialize() の中では、 “スクリプトへの引数リスト” (script argument list, sys.argv のこと) を設定しません。この変数が後に実行される Python コード中で必要なら、 Py_Initialize() の後で PySys_SetArgvEx(argc, argv, updatepath) を呼び出して明示的に設定しなければなりません。

ほとんどのシステムでは (特に Unix と Windows は、詳細がわずかに異なりはしますが)、 Py_Initialize() は標準の Python インタプリタ実行形式の場所に対する推定結果に基づいて、 Python のライブラリが Python インタプリタ実行形式からの相対パスで見つかるという仮定の下にモジュール検索パスを計算します。とりわけこの検索では、シェルコマンド検索パス (環境変数 PATH) 上に見つかった python という名前の実行ファイルの置かれているディレクトリの親ディレクトリからの相対で、 lib/pythonX.Y という名前のディレクトリを探します。

例えば、 Python 実行形式が /usr/local/bin/python で見つかったとすると、 Py_Initialize() はライブラリが /usr/local/lib/pythonX.Y にあるものと仮定します。 (実際には、このパスは “フォールバック (fallback)” のライブラリ位置でもあり、 python が PATH 上にない場合に使われます。) ユーザは PYTHONHOME を設定することでこの動作をオーバライドしたり、 PYTHONPATH を設定して追加のディレクトリを標準モジュール検索パスの前に挿入したりできます。

埋め込みを行うアプリケーションでは、 Py_Initialize() を呼び出す 前に Py_SetProgramName(file) を呼び出すことで、上記の検索を操作できます。この埋め込みアプリケーションでの設定は依然として PYTHONHOME でオーバライドでき、標準のモジュール検索パスの前には以前として PYTHONPATH が挿入されるので注意してください。アプリケーションでモジュール検索パスを完全に制御したいのなら、独自に Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), および Py_GetProgramFullPath() の実装を提供しなければなりません (これらは全て Modules/getpath.c で定義されています)。

たまに、 Python を “初期化しない” ようにしたいことがあります。例えば、あるアプリケーションでは実行を最初からやりなおし (start over) させる (Py_Initialize() をもう一度呼び出させる) ようにしたいかもしれません。あるいは、アプリケーションが Python を一旦使い終えて、Python が確保したメモリを解放できるようにしたいかもしれません。 Py_Finalize() を使うと、こうした処理を実現できます。また、関数 Py_IsInitialized() は、Python が現在初期化済みの状態にある場合に真を返します。これらの関数についてのさらなる情報は、後の章で説明します。 Py_Finalize() がPythonインタプリタに確保された全てのメモリを開放するわけではない ことに注意してください。例えば、拡張モジュールによって確保されたメモリは、現在のところ開放する事ができません。

デバッグ版ビルド (Debugging Builds)

インタプリタと拡張モジュールに対しての追加チェックをするためのいくつかのマクロを有効にしてPythonをビルドすることができます。これらのチェックは、実行時に大きなオーバーヘッドを生じる傾向があります。なので、デフォルトでは有効にされていません。

Pythonデバッグ版ビルドの全ての種類のリストが、Pythonソース配布(source distribution)の中の Misc/SpecialBuilds.txt にあります。参照カウントのトレース、メモリアロケータのデバッグ、インタプリタのメインループの低レベルプロファイリングが利用可能です。よく使われるビルドについてのみ、この節の残りの部分で説明します。

インタプリタを Py_DEBUG マクロを有効にしてコンパイルすると、一般的に「デバッグビルド」といわれるPythonができます。 Unix では、 configure コマンドに --with-pydebug を追加することで、 Py_DEBUG が有効になります。その場合、暗黙的にPython専用ではない _DEBUG も有効になります。 Unix ビルドでは、 Py_DEBUG が有効な場合、コンパイラの最適化が無効になります。

あとで説明する参照カウントデバッグの他に、以下の追加チェックも有効になります。

object allocator に対する追加チェック

パーサーとコンパイラに対する追加チェック

情報損失のために、大きい型から小さい型へのダウンキャストに対するチェック

辞書(dict)と集合(set)の実装に対する、いくつもの assertion の追加。加えて、集合オブジェクトに test_c_api() メソッドが追加されます。

フレームを作成する時の、引数の健全性チェック。

初期化されていない数に対する参照を検出するために、長整数のストレージが特定の妥当でないパターンで初期化されます。

低レベルトレースと追加例外チェックがVM runtimeに追加されます。

メモリアリーナ(memory arena)の実装に対する追加チェック

threadモジュールに対する追加デバッグ機能.

ここで言及されていない追加チェックもあるでしょう。

Py_TRACE_REFS を宣言すると、参照トレースが有効になります。全ての PyObject に二つのフィールドを追加することで、使用中のオブジェクトの循環二重連結リストが管理されます。全ての割り当て(allocation)がトレースされます。終了時に、全ての残っているオブジェクトが表示されます。 (インタラクティブモードでは、インタプリタによる文の実行のたびに表示されます) Py_TRACE_REFS は Py_DEBUG によって暗黙的に有効になります。

より詳しい情報については、Pythonのソース配布(source distribution)の中の Misc/SpecialBuilds.txt を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

超高レベルレイヤ

この章の関数を使うとファイルまたはバッファにあるPythonソースコードを実行できますが、より詳細なやり取りをインタプリタとすることはできないでしょう。

これらの関数のいくつかは引数として文法の開始記号を受け取ります。使用できる開始記号は Py_eval_input と Py_file_input 、 Py_single_input です。開始期号の説明はこれらを引数として取る関数の後にあります。

これらの関数のいくつかが FILE* 引数をとることにも注意してください。注意深く扱う必要がある特別な問題の1つは、異なるCライブラリの FILE 構造体は異なっていて互換性がない可能性があるということです。実際に(少なくとも)Windowsでは、動的リンクされる拡張が異なるライブラリを使うことが可能であり、したがって、 FILE* 引数がPythonランタイムが使っているライブラリと同じライブラリによって作成されたことが確かならば、単にこれらの関数へ渡すだけということに注意すべきです。

int Py_Main(int argc, char **argv)

標準インタプリタのためのメインプログラム。Pythonを組み込むプログラムのためにこれを利用できるようにしています。 argc と argv 引数をCプログラムの main() 関数へ渡されるものとまったく同じに作成すべきです。引数リストが変更される可能性があるという点に注意することは重要です。 (しかし、引数リストが指している文字列の内容は変更されません)。戻り値はインタプリタが(例外などではなく)普通に終了した時は 0 に、例外で終了したときには 1 に、引数リストが正しい Python コマンドラインが渡されなかったときは 2 になります。

Py_InspectFlag が設定されていない場合、未処理の SystemExit 例外が発生すると、この関数は 1 を返すのではなくプロセスを exit することに気をつけてください。

int PyRun_AnyFile(FILE *fp, const char *filename)

下記の PyRun_AnyFileExFlags() の closeit を 0 に、 flags を NULL にして単純化したインタフェースです。

int PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)

下記の PyRun_AnyFileExFlags() の closeit を 0 にして単純化したインタフェースです。

int PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit)

下記の PyRun_AnyFileExFlags() の flags を NULL にして単純化したインタフェースです。

int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)

fp が対話的デバイス(コンソールや端末入力あるいはUnix仮想端末)と関連づけられたファイルを参照しているならば、 PyRun_InteractiveLoop() の値を返します。それ以外の場合は、 PyRun_SimpleFile() の結果を返します。 filename が NULL ならば、この関数はファイル名として "???" を使います。

int PyRun_SimpleString(const char *command)

下記の PyRun_SimpleStringFlags() の PyCompilerFlags* を NULL にして単純化したインタフェースです。

int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)

__main__ モジュールの中で flags に従って command に含まれる Python ソースコードを実行します。 __main__ がまだ存在しない場合は作成されます。正常終了の場合は 0 を返し、また例外が発生した場合は -1 を返します。エラーがあっても、例外情報を得る方法はありません。 flags の意味については、後述します。

Py_InspectFlag が設定されていない場合、未処理の SystemExit 例外が発生すると、この関数は 1 を返すのではなくプロセスを exit することに気をつけてください。

int PyRun_SimpleFile(FILE *fp, const char *filename)

下記の PyRun_SimpleStringFileExFlags() の closeit を 0 に、 flags を NULL にして単純化したインタフェースです。

int PyRun_SimpleFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)

下記の PyRun_SimpleStringFileExFlags() の closeit を 0 にして単純化したインタフェースです。

int PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit)

下記の PyRun_SimpleStringFileExFlags() の flags を NULL にして単純化したインタフェースです。

int PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)

Similar to PyRun_SimpleStringFlags(), but the Python source PyRun_SimpleString() と似ていますが、Pythonソースコードをメモリ内の文字列ではなく fp から読み込みます。 filename はそのファイルの名前でなければなりません。 closeit が真ならば、PyRun_SimpleFileExFlags は処理を戻す前にファイルを閉じます。

int PyRun_InteractiveOne(FILE *fp, const char *filename)

下記の PyRun_InteractiveOneFlags() の flags を NULL にして単純化したインタフェースです。

int PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)

対話的デバイスに関連付けられたファイルから文を一つ読み込み、 flags に従って実行します。 sys.ps1 と sys.ps2 を使って、ユーザにプロンプトを表示します。入力が正常に実行されたときは 0 を返します。例外が発生した場合は -1 を返します。パースエラーの場合はPythonの一部として配布されている errcode.h インクルードファイルにあるエラーコードを返します。 (Python.h は errcode.h をインクルードしません。したがって、必要ならば特別にインクルードしなければならないことに注意してください。)

int PyRun_InteractiveLoop(FILE *fp, const char *filename)

下記の PyRun_InteractiveLoopFlags() の flags を 0 にして単純化したインタフェースです。

int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)

対話的デバイスに関連付けられたファイルからEOF に達するまで複数の文を読み込み実行します。使われます。 sys.ps1 と sys.ps2 を使って、ユーザにプロンプトを表示します。 EOFに達すると 0 を返します。

struct _node* PyParser_SimpleParseString(const char *str, int start)

下記の PyRun_SimpleParseStringFlagsFilename() の filename を NULL に、 flags を 0 にして単純化したインタフェースです。

struct _node* PyParser_SimpleParseStringFlags(const char *str, int start, int flags)

下記の PyRun_SimpleParseStringFlagsFilename() の filename を NULL にして単純化したインタフェースです。

struct _node* PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, int start, int flags)

開始トークン start を使って str に含まれる Python ソースコードを flags 引数に従ってパースします。効率的に評価可能なコードオブジェクトを作成するためにその結果を使うことができます。コード断片を何度も評価しなければならない場合に役に立ちます。

struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)

下記の PyRun_SimpleParseFileFlags() の flags を 0 にして単純化したインタフェースです。

struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)

PyParser_SimpleParseStringFlagsFilename() に似ていますが、 Pythonソースコードをメモリ内の文字列ではなく fp から読み込みます。 filename はそのファイルの名前でなけれななりません。

PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)

Return value: New reference.

下記の PyRun_StringFlags() の flags を NULL にして単純化したインタフェースです。

PyObject* PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)

Return value: New reference.

辞書 globals と locals で指定されるコンテキストにおいて、 str に含まれるPythonソースコードをコンパイラフラグ flags のもとで実行します。パラメータ start はソースコードをパースするために使われるべき開始トークンを指定します。

コードを実行した結果をPythonオブジェクトとして返します。または、例外が発生したならば NULL を返します。

PyObject* PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals)

Return value: New reference.

下記の PyRun_FileExFlags() の closeit を 0 にし、 flags を NULL にして単純化したインタフェースです。

PyObject* PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit)

Return value: New reference.

下記の PyRun_FileExFlags() の flags を NULL にして単純化したインタフェースです。

PyObject* PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)

Return value: New reference.

下記の PyRun_FileExFlags() の closeit を 0 にして単純化したインタフェースです。

PyObject* PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags)

Return value: New reference.

PyRun_String() と似ていますが、Pythonソースコードをメモリ内の文字列ではなく fp から読み込みます。 closeit を真にすると、 PyRun_FileExFlags() から処理を戻す前にファイルを閉じます。 filename はそのファイルの名前でなければなりません。

PyObject* Py_CompileString(const char *str, const char *filename, int start)

Return value: New reference.

下記の Py_CompileStringFlags() の flags を NULL にして単純化したインタフェースです。

PyObject* Py_CompileStringFlags(const char *str, const char *filename, int start, PyCompilerFlags *flags)

Return value: New reference.

str 内のPythonソースコードをパースしてコンパイルし、作られたコードオブジェクトを返します。開始トークンは start によって与えられます。これはコンパイル可能なコードを制限するために使うことができ、 Py_eval_input 、 Py_file_input もしくは Py_single_input であるべきです。 filename で指定されるファイル名はコードオブジェクトを構築するために使われ、トレースバックあるいは SyntaxError 例外メッセージに出てくる可能性があります。コードがパースできなかったりコンパイルできなかったりした場合に、これは NULL を返します。

PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)

Return value: New reference.

PyEval_EvalCodeEx() に対するシンプルなインタフェースで、コードオブジェクトと、グローバル・ローカル変数辞書だけを受け取ります。他の引数には NULL が渡されます。

PyObject* PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure)

与えられた特定の環境で、コンパイル済みのコードオブジェクトを評価します。環境はグローバルとローカルの辞書、引き数の配列、キーワードとデフォルト値、クロージャーのためのセルのタプルで構成されています。

PyObject* PyEval_EvalFrame(PyFrameObject *f)

実行フレームを評価します。これは PyEval_EvalFrameEx に対するシンプルなインタフェースで、後方互換性のためのものです。

PyObject* PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)

Python のインタープリタの主要な、直接的な関数です。この関数には 2000 行ほどあります。実行フレーム f に関連付けられたコードオブジェクトを実行します。バイトコードを解釈して、必要に応じて呼び出しを実行します。追加の throwflag 引数はほとんど無視できます。 - もし true なら、すぐに例外を発生させます。これはジェネレータオブジェクトの throw() メソッドで利用されます。

int PyEval_MergeCompilerFlags(PyCompilerFlags *cf)

現在の評価フレームのフラグを変更します。成功したら true を、失敗したら false を返します。

int Py_eval_input

単独の式に対するPython文法の開始記号で、 Py_CompileString() と一緒に使います。

int Py_file_input

ファイルあるいは他のソースから読み込まれた文の並びに対するPython文法の開始記号で、 Py_CompileString() と一緒に使います。これは任意の長さのPythonソースコードをコンパイルするときに使う記号です。

int Py_single_input

単一の文に対するPython文法の開始記号で、 Py_CompileString() と一緒に使います。これは対話式のインタプリタループのための記号です。

struct PyCompilerFlags

コンパイラフラグを収めておくための構造体です。コードをコンパイルするだけの場合、この構造体が int flags として渡されます。コードを実行する場合には PyCompilerFlags *flags として渡されます。この場合、 from __future__  import は flags の内容を変更できます。

PyCompilerFlags *flags が NULL の場合、 cf_flags は 0 として扱われ、 from __future__ import による変更は無視されます。

struct PyCompilerFlags {
    int cf_flags;
}

int CO_FUTURE_DIVISION

このビットを flags にセットすると、除算演算子 / は PEP 238 [http://www.python.org/dev/peps/pep-0238] による「真の除算 (true division)」として扱われます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

参照カウント

この節のマクロはPythonオブジェクトの参照カウントを管理するために使われます。

void Py_INCREF(PyObject *o)

オブジェクト o に対する参照カウントを一つ増やします。オブジェクトが NULL であってはいけません。それが NULL ではないと確信が持てないならば、 Py_XINCREF() を使ってください。

void Py_XINCREF(PyObject *o)

オブジェクト o に対する参照カウントを一つ増やします。オブジェクトが NULL であってもよく、その場合マクロは何の影響も与えません。

void Py_DECREF(PyObject *o)

オブジェクト o に対する参照カウントを一つ減らします。オブジェクトが NULL であってはいけません。それが NULL ではないと確信が持てないならば、 Py_XDECREF() を使ってください。参照カウントがゼロになったら、オブジェクトの型のメモリ解放関数(NULL であってはならない)が呼ばれます。

警告

(例えば __del__() メソッドをもつクラスインスタンスがメモリ解放されたときに)メモリ解放関数は任意のPythonコードを呼び出すことができます。このようなコードでは例外は伝播しませんが、実行されたコードはすべてのPythonグローバル変数に自由にアクセスできます。これが意味するのは、 Py_DECREF() が呼び出されるより前では、グローバル変数から到達可能などんなオブジェクトも一貫した状態にあるべきであるということです。例えば、リストからオブジェクトを削除するコードは削除するオブジェクトへの参照を一時変数にコピーし、リストデータ構造を更新し、それから一時変数に対して Py_DECREF() を呼び出すべきです。

void Py_XDECREF(PyObject *o)

オブジェクト o への参照カウントを一つ減らします。オブジェクトは NULL でもかまいませんが、その場合マクロは何の影響も与えません。それ以外の場合、結果は Py_DECREF() と同じです。また、注意すべきことも同じです。

void Py_CLEAR(PyObject *o)

o の参照カウントを減らします．オブジェクトは NULL でもよく，その場合このマクロは何も行いません．オブジェクトが NULL でなければ，引数を NULL にした Py_DECREF() と同じ効果をもたらします．このマクロは一時変数を使って，参照カウントをデクリメントする前に引数を NULL にセットしてくれるので， Py_DECREF() に使うときの警告を気にしなくてすみます．

ガベージコレクション中に追跡される可能性のある変数の参照デクリメントを行うには，このマクロを使うのがよいでしょう．

バージョン 2.4 で追加.

以下の関数: Py_IncRef(PyObject *o), Py_DecRef(PyObject *o), は，実行時の動的な Python 埋め込みで使われる関数です．これらの関数はそれぞれ Py_XINCREF() および Py_XDECREF() をエクスポートしただけです．

以下の関数やマクロ: _Py_Dealloc(), _Py_ForgetReference(), _Py_NewReference() は，インタプリタのコアの内部においてのみ使用するためのものです。また、グローバル変数 _Py_RefTotal も同様です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

例外処理

この章で説明する関数を使うと、 Python の例外の処理や送出ができるようになります。 Python の例外処理の基本をいくらか理解することが大切です。例外は Unix errno 変数にやや似た機能を果たします: 発生した中で最も新しいエラーの (スレッド毎の) グローバルなインジケータがあります。実行に成功した場合にはほとんどの関数がこれをクリアしませんが、失敗したときにはエラーの原因を示すために設定します。ほとんどの関数はエラーインジケータも返し、通常は関数がポインタを返すことになっている場合は NULL であり、関数が整数を返す場合は -1 です。(例外: PyArg_*() 関数は実行に成功したときに 1 を返し、失敗したときに 0 を返します).

ある関数が呼び出した関数がいくつか失敗したために、その関数が失敗しなければならないとき、一般的にエラーインジケータを設定しません。呼び出した関数がすでに設定しています。エラーを処理して例外をクリアするか、あるいは (オブジェクト参照またはメモリ割り当てのような)それが持つどんなリソースも取り除いた後に戻るかのどちらか一方を行う責任があります。エラーを処理する準備をしていなければ、普通に続けるべきでは ありません 。エラーのために戻る場合は、エラーが設定されていると呼び出し元に知らせることが大切です。エラーが処理されていない場合または丁寧に伝えられている場合には、 Python/C APIのさらなる呼び出しは意図した通りには動かない可能性があり、不可解な形で失敗するかもしれません。

エラーインジケータは Python変数 sys.exc_type, sys.exc_value および sys.exc_traceback に対応する三つのPythonオブジェクトからからなります。いろいろな方法でエラーインジケータとやりとりするためにAPI関数が存在します。各スレッドに別々のエラーインジケータがあります。

void PyErr_PrintEx(int set_sys_last_vars)

sys.stderr へ標準トレースバックをプリントし、エラーインジケータをクリアします。エラーインジケータが設定されているときにだけ、この関数を呼び出してください。(それ以外の場合、致命的なエラーを引き起こすでしょう!)

set_sys_last_vars が非ゼロであれば、 sys.last_type, sys.last_value, sys.last_traceback 変数が、表示される例外のタイプ、値、トレースバックそれぞれに反映されます。

void PyErr_Print()

PyErr_PrintEx(1) のエイリアス.

PyObject* PyErr_Occurred()

Return value: Borrowed reference.

エラーインジケータが設定されているかテストします。設定されている場合は、例外の 型 (PyErr_Set*() 関数の一つあるいは PyErr_Restore() への最も新しい呼び出しに対する第一引数)を返します。設定されていない場合は NULL を返します。あなたは戻り値への参照を持っていませんので、それに Py_DECREF() する必要はありません。

ノート

戻り値を特定の例外と比較しないでください。その代わり、下に示す PyErr_ExceptionMatches() を使ってください。(比較は簡単に失敗するでしょう。なぜなら、例外はクラスではなくインスタンスかもしれないし、あるいは、クラス例外の場合は期待される例外のサブクラスかもしれないからです。)

int PyErr_ExceptionMatches(PyObject *exc)

PyErr_GivenExceptionMatches(PyErr_Occurred(), exc) と同じ。例外が実際に設定されたときにだけ、これを呼び出だすべきです。例外が発生していないならば、メモリアクセス違反が起きるでしょう。

int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)

given 例外が exc の例外と一致するなら真を返します。これは exc がクラスオブジェクトである場合も真を返します。これは given がサブクラスのインスタンスであるときも真を返します。 exc がタプルならば、タプル内(と再帰的にサブタプル内)のすべての例外が一致するか調べられます。

void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)

ある状況では、以下の PyErr_Fetch() が返す値は “正規化されていない” 可能性があります。つまり、 *exc はクラスオブジェクトだが *val は同じクラスのインスタンスではないという意味です。この関数はそのような場合にそのクラスをインスタンス化するために使われます。その値がすでに正規化されている場合は何も起きません。遅延正規化はパフォーマンスを改善するために実装されています。

void PyErr_Clear()

エラーインジケータをクリアします。エラーインジケータが設定されていないならば、効果はありません。

void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

エラーインジケータをアドレスを渡す三つの変数の中へ取り出します。エラーインジケータが設定されていない場合は、三つすべての変数を NULL に設定します。エラーインジケータが設定されている場合はクリアされ、あなたは取り出されたそれぞれのオブジェクトへの参照を持つことになります。型オブジェクトが NULL でないときでさえ、その値とトレースバックオブジェクトは NULL かもしれません。

ノート

通常、この関数は例外を扱う必要のあるコードあるいはエラーインジケータを一時的に保存して元に戻す必要のあるコードによってのみ使用されます。

void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)

三つのオブジェクトからエラーインジケータを設定します。エラーインジケータがすでに設定されている場合は、最初にクリアされます。オブジェクトが NULL ならば、エラーインジケータがクリアされます。 NULL のtypeと非 NULL のvalueあるいは tracebackを渡してはいけません。例外の型(type)はクラスであるべきです。無効な例外の型(type)あるいは値(value)を渡してはいけません。 (これらの規則を破ると後で気付きにくい問題の原因となるでしょう。) この呼び出しはそれぞれのオブジェクトへの参照を取り除きます: あなたは呼び出しの前にそれぞれのオブジェクトへの参照を持たなければならないのであり、また呼び出しの後にはもはやこれらの参照を持っていません。 (これを理解していない場合は、この関数を使ってはいけません。注意しておきます。)

ノート

通常この関数はエラーインジケータを一時的に保存し元に戻す必要のあるコードによってのみに使われます。現在の例外状態を保存するためには PyErr_Fetch() を使ってください。

void PyErr_SetString(PyObject *type, const char *message)

これはエラーインジケータを設定するための最も一般的な方法です。第一引数は例外の型を指定します。通常は標準例外の一つ、例えば PyExc_RuntimeError です。その参照カウントを増加させる必要はありません。第二引数はエラーメッセージで、文字列オブジェクトへ変換されます。

void PyErr_SetObject(PyObject *type, PyObject *value)

この関数は PyErr_SetString() に似ていますが、例外の”値(value)”として任意のPythonオブジェクトを指定することができます。

PyObject* PyErr_Format(PyObject *exception, const char *format, ...)

Return value: Always NULL.

この関数はエラーインジケータを設定し NULL を返します。 exception はPython例外クラスであるべきです。 format と以降の引数はエラーメッセージを作るためのもので, PyString_FromFormat() の引数と同じ意味を持っています。

void PyErr_SetNone(PyObject *type)

これは PyErr_SetObject(type, Py_None) を省略したものです。

int PyErr_BadArgument()

これは PyErr_SetString(PyExc_TypeError, message) を省略したもので、ここで message は組み込み操作が不正な引数で呼び出されたということを表しています。主に内部で使用するためのものです。

PyObject* PyErr_NoMemory()

Return value: Always NULL.

これは PyErr_SetNone(PyExc_MemoryError) を省略したもので、 NULL を返します。したがって、メモリ不足になったとき、オブジェクト割り当て関数は return PyErr_NoMemory(); と書くことができます。

PyObject* PyErr_SetFromErrno(PyObject *type)

Return value: Always NULL.

Cライブラリ関数がエラーを返してC変数 errno を設定したときに、これは例外を発生させるために便利な関数です。第一要素が整数 errno 値で、第二要素が (strerror() から得られる)対応するエラーメッセージであるタプルオブジェクトを構成します。それから、 PyErr_SetObject(type, object) を呼び出します。 Unixでは、 errno 値が EINTR であるとき、すなわち割り込まれたシステムコールを表しているとき、これは PyErr_CheckSignals() を呼び出し、それがエラーインジケータを設定した場合は設定されたままにしておきます。関数は常に NULL を返します。したがって、システムコールがエラーを返したとき、システムコールのラッパー関数は return PyErr_SetFromErrno(type); と書くことができます。

PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename)

Return value: Always NULL.

PyErr_SetFromErrno() に似ていて、 filename が NULL でない場合に、それが type のコンストラクタに第三引数として渡されるというふるまいが追加されています。 IOError と OSError のような例外の場合では、これが例外インスタンスの filename 属性を定義するために使われます。

PyObject* PyErr_SetFromWindowsErr(int ierr)

Return value: Always NULL.

これは WindowsError を発生させるために便利な関数です。 0 の ierr とともに呼び出された場合、 GetLastError() が返すエラーコードが代りに使われます。 ierr あるいは GetLastError() によって与えられるエラーコードのWindows用の説明を取り出すために、Win32関数 FormatMessage() を呼び出します。それから、第一要素が ierr 値で第二要素が(FormatMessage() から得られる) 対応するエラーメッセージであるタプルオブジェクトを構成します。そして、 PyErr_SetObject(PyExc_WindowsError, object) を呼び出します。この関数は常に NULL を返します。利用可能範囲: Windows。

PyObject* PyErr_SetExcFromWindowsErr(PyObject *type, int ierr)

Return value: Always NULL.

PyErr_SetFromWindowsErr() に似ていて、送出する例外の型を指定する引数が追加されています。利用可能範囲: Windows。

バージョン 2.3 で追加.

PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename)

Return value: Always NULL.

PyErr_SetFromWindowsErr() に似ていて、 filename が NULL でない場合には WindowsError のコンストラクタへ第三引数として渡されるという振る舞いが追加されています。利用可能範囲: Windows。

PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, char *filename)

Return value: Always NULL.

PyErr_SetFromWindowsErrWithFilename() に似ていて、発生させる例外の型を指定する引数が追加されています。利用可能範囲: Windows。

バージョン 2.3 で追加.

void PyErr_BadInternalCall()

PyErr_SetString(PyExc_SystemError, message) を省略したものです。ここで message は内部操作(例えば、Python/C API関数)が不正な引数とともに呼び出されたということを示しています。主に内部で使用するためのものです。

int PyErr_WarnEx(PyObject *category, char *message, int stacklevel)

警告メッセージを出します。 category 引数は警告カテゴリ(以下を参照) かまたは NULL で、 message 引数はメッセージ文字列です。 stacklevel はフレームの数を示す正の整数です; 警告はそのスタックフレームの中の実行している行から発行されます。 stacklevel が1だと、 PyErr_WarnEx() が、2だとその上の関数が、Warningの発行元になります。

この関数は通常警告メッセージを sys.stderr へプリントします。けれども、ユーザが警告をエラーへ変更するように指定することも可能です。そのような場合には、これは例外を発生させます。警告機構がもつ問題のためにその関数が例外を発生させるということも可能です。(実装ではその厄介な仕事を行うために warnings モジュールをインポートします)。例外が発生させられなければ、戻り値は 0 です。あるいは、例外が発生させられると -1 です。(警告メッセージが実際にプリントされるかどうかを決定することはできず、また何がその例外の原因なのかを決定することもできない。これは意図的なものです。)例外が発生した場合、呼び出し元は通常の例外処理を行います(例えば、 Py_DECREF() は参照を持っており、エラー値を返します)。

警告カテゴリは Warning のサブクラスでなければならない。デフォルト警告カテゴリは RuntimeWarning です。標準Python警告カテゴリは PyExc_ にPython例外名が続く名前のグローバル変数を用いて変更できます。これらは型 PyObject* を持ち、すべてクラスオブジェクトです。それらの名前は PyExc_Warning, PyExc_UserWarning, PyExc_UnicodeWarning, PyExc_DeprecationWarning, PyExc_SyntaxWarning, PyExc_RuntimeWarning, PyExc_FutureWarning です。 PyExc_Warning は PyExc_Exception のサブクラスです。その他の警告カテゴリは PyExc_Warning のサブクラスです。

警告をコントロールするための情報については、 warnings モジュールのドキュメンテーションとコマンドライン・ドキュメンテーションの -W オプションを参照してください。警告コントロールのためのC APIはありません。

int PyErr_Warn(PyObject *category, char *message)

警告メッセージを出します。 category 引数は警告カテゴリ(以下を参照) かまたは NULL で、 message 引数はメッセージ文字列です。警告は、 PyErr_WarnEx() を stacklevel に 1 を指定した時と同じく、 PyErr_Warn() を呼び出した関数から発行されます。

非推奨; PyErr_WarnEx() を使って下さい。

int PyErr_WarnExplicit(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)

すべての警告の属性を明示的に制御した警告メッセージを出します。これはPython関数 warnings.warn_explicit() の直接的なラッパで、さらに情報を得るにはそちらを参照してください。そこに説明されているデフォルトの効果を得るために、 module と registry 引数は NULL に設定することができます。

int PyErr_WarnPy3k(char *message, int stacklevel)

Issue a DeprecationWarning with the given message and stacklevel if the Py_Py3kWarningFlag flag is enabled. Py_Py3kWarningFlag フラグが有効な場合、与えられた message と stacklevel に応じて DeprecationWarning を発生させます。

バージョン 2.6 で追加.

int PyErr_CheckSignals()

この関数はPythonのシグナル処理とやりとりすることができます。シグナルがそのプロセスへ送られたかどうかチェックし、そうならば対応するシグナルハンドラを呼び出します。 signal モジュールがサポートされている場合は、これはPythonで書かれたシグナルハンドラを呼び出せます。すべての場合で、 SIGINT のデフォルトの効果は KeyboardInterrupt 例外を発生させることです。例外が発生した場合、エラーインジケータが設定され、関数は -1 を返します。そうでなければ、関数は 0 を返します。エラーインジケータが以前に設定されている場合は、それがクリアされるかどうかわからない。

void PyErr_SetInterrupt()

この関数は廃止されています。 SIGINT シグナルが到達した影響をシミュレートします — 次に PyErr_CheckSignals() が呼ばれるとき、 KeyboardInterrupt は送出されるでしょう。インタプリタロックを保持することなく呼び出すことができます。

int PySignal_SetWakeupFd(int fd)

このユーティリティ関数は、シグナルを受信したときに '\0' バイトを書き込むファイルディスクリプタを指定します。戻り値は、それまで設定されていたファイルディスクリプタです。 -1 はこの機能を無効にします。これは初期状態です。これは Python の signal.set_wakeup_fd() と同じものですが、エラーチェックを行ないません。 fd は有効なファイルディスクリプタであるべきです。この関数の呼び出しはメインスレッドのみから行われるべきです。

バージョン 2.6 で追加.

PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict)

Return value: New reference.

このユーティリティ関数は新しい例外オブジェクトを作成して返します。 name 引数は新しい例外の名前、 module.class 形式の C文字列でなければならない。 base と dict 引数は通常 NULL です。これはすべての例外のためのルート、組み込み名 Exception (Cでは PyExc_Exception としてアクセス可能)をルートとして派生したクラスオブジェクトを作成します。

新しいクラスの __module__ 属性は name 引数の前半部分(最後のドットまで)に設定され、クラス名は後半部分(最後のドットの後)に設定されます。 base 引数は代わりのベースクラスを指定するために使えます; 一つのクラスでも、クラスのタプルでも構いません。 dict 引数はクラス変数とメソッドの辞書を指定するために使えます。

PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict)

PyErr_NewException() とほぼ同じですが、新しい例外クラスに簡単に docstring を設定できます。 doc が NULL で無い場合、それが例外クラスの docstring になります。

バージョン 2.7 で追加.

void PyErr_WriteUnraisable(PyObject *obj)

例外が設定されているがインタプリタが実際に例外を発生させることができないときに、このユーティリティ関数は警告メッセージを sys.stderr へプリントします。例えば、例外が __del__() メソッドで発生したときに使われます。

発生させられない例外が生じたコンテキストを特定するための一つの引数 obj とともに関数が呼び出されます。 obj のreprが警告メッセージにプリントされるでしょう。

Unicode 例外オブジェクト

以下の関数は C言語から Unicode 例外を作ったり修正したりするために利用します。

PyObject* PyUnicodeDecodeError_Create(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

encoding, object, length, start, end, reason 属性をもった UnicodeDecodeError オブジェクトを作成します。

PyObject* PyUnicodeEncodeError_Create(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

encoding, object, length, start, end, reason 属性を持った UnicodeEncodeError オブジェクトを作成します。

PyObject* PyUnicodeTranslateError_Create(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)

object, length, start, end, reason 属性を持った UnicodeTranslateError オブジェクトを作成します。

PyObject* PyUnicodeDecodeError_GetEncoding(PyObject *exc)

PyObject* PyUnicodeEncodeError_GetEncoding(PyObject *exc)

与えられた例外オブジェクトの encoding 属性を返します。

PyObject* PyUnicodeDecodeError_GetObject(PyObject *exc)

PyObject* PyUnicodeEncodeError_GetObject(PyObject *exc)

PyObject* PyUnicodeTranslateError_GetObject(PyObject *exc)

与えられた例外オブジェクトの object 属性を返します。

int PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)

int PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)

int PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)

渡された例外オブジェクトから start 属性を取得して *start に格納します。 start は NULL であってはなりません。成功したら 0 を、失敗したら -1 を返します。

int PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)

int PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)

int PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)

渡された例外オブジェクトの start 属性を start に設定します。成功したら 0 を、失敗したら -1 を返します。

int PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)

int PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)

int PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *end)

渡された例外オブジェクトから end 属性を取得して *end に格納します。 end は NULL であってはなりません。成功したら 0 を、失敗したら -1 を返します。

int PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)

int PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)

int PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)

渡された例外オブジェクトの end 属性を end に設定します。成功したら 0 を、失敗したら -1 を返します。

PyObject* PyUnicodeDecodeError_GetReason(PyObject *exc)

PyObject* PyUnicodeEncodeError_GetReason(PyObject *exc)

PyObject* PyUnicodeTranslateError_GetReason(PyObject *exc)

渡された例外オブジェクトの reason 属性を返します。

int PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)

int PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)

int PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)

渡された例外オブジェクトの reason 属性を reason に設定します。成功したら 0 を、失敗したら -1 を返します。

再帰の管理

これら2つの関数は C レベルの再帰呼び出しを安全に実行する方法を、コアモジュールにも拡張モジュールにも提供します。再帰を使ったコードが必ずしも Python コードを実行するわけではない場合 (Python コードは再帰の深さを自動的に追跡します)、これらの関数が必要となります。

int Py_EnterRecursiveCall(char *where)

C レベルの再帰呼び出しをしようとしているところに印を付けます。

USE_STACKCHECK が定義されている場合、 OS のスタックがオーバーフローがしたかどうかを PyOS_CheckStack() を使ってチェックします。もしオーバーフローしているなら、 MemoryError をセットしゼロでない値を返します。

次にこの関数は再帰の上限に達していないかをチェックします。上限に達している場合、 RuntimeError をセットしゼロでない値を返します。そうでない場合はゼロを返します。

再帰の深さの上限に達して送出される RuntimeError のメッセージに連結できるよう where は " in instance check" のような文字列にしてください。

void Py_LeaveRecursiveCall()

Py_EnterRecursiveCall() を終了させます。 Py_EnterRecursiveCall() の 成功した 呼び出しに対して必ず 1 回呼び出さなければなりません。

標準例外

PyExc_ の後ろにPythonの例外名が続く名前をもつグローバル変数として、すべての標準Python例外が利用可能です。これらは型 PyObject* を持ち、すべてクラスオブジェクトです。完璧を期するために、すべての変数を以下に列挙します:

C名 | Python名 | 注記
PyExc_BaseException | BaseException | (1), (4)
PyExc_Exception | Exception | (1)
PyExc_StandardError | StandardError | (1)
PyExc_ArithmeticError | ArithmeticError | (1)
PyExc_LookupError | LookupError | (1)
PyExc_AssertionError | AssertionError |
PyExc_AttributeError | AttributeError |
PyExc_EOFError | EOFError |
PyExc_EnvironmentError | EnvironmentError | (1)
PyExc_FloatingPointError | FloatingPointError |
PyExc_IOError | IOError |
PyExc_ImportError | ImportError |
PyExc_IndexError | IndexError |
PyExc_KeyError | KeyError |
PyExc_KeyboardInterrupt | KeyboardInterrupt |
PyExc_MemoryError | MemoryError |
PyExc_NameError | NameError |
PyExc_NotImplementedError | NotImplementedError |
PyExc_OSError | OSError |
PyExc_OverflowError | OverflowError |
PyExc_ReferenceError | ReferenceError | (2)
PyExc_RuntimeError | RuntimeError |
PyExc_SyntaxError | SyntaxError |
PyExc_SystemError | SystemError |
PyExc_SystemExit | SystemExit |
PyExc_TypeError | TypeError |
PyExc_ValueError | ValueError |
PyExc_WindowsError | WindowsError | (3)
PyExc_ZeroDivisionError | ZeroDivisionError |

注記:

これは別の標準例外のためのベースクラスです。

これは weakref.ReferenceError と同じです。

Windowsでのみ定義されています。プリプロセッサマクロ MS_WINDOWS が定義されているかテストすることで、これを使うコードを保護してください。

バージョン 2.5 で追加.

文字列の例外

バージョン 2.6 で変更: All exceptions to be raised or caught must be derived from BaseException. Trying to raise a string exception now raises TypeError. 発生したりキャッチされる全ての例外は BaseException を継承しなければなりません。文字列例外を発生させようとすると TypeError が発生されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数

この章の関数は、 C で書かれたコードをプラットフォーム間で可搬性のあるものにする上で役立つものから、C から Python モジュールを使うもの、そして関数の引数を解釈したり、 C の値から Python の値を構築するものまで、様々なユーティリティ的タスクを行います。

オペレーティングシステム関連のユーティリティ

システム関数

プロセス制御

モジュールの import

データ整列化 (data marshalling) のサポート

引数の解釈と値の構築

文字列の変換と書式化

リフレクション

codec レジストリとサポート関数

コーデック検索API

Unicode エラーハンドラ用レジストリ API

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

オペレーティングシステム関連のユーティリティ

int Py_FdIsInteractive(FILE *fp, const char *filename)

filename という名前の標準 I/O ファイル fp が対話的 (interactive) であると考えられる場合に真 (非ゼロ) を返します。これは isatty(fileno(fp)) が真になるファイルの場合です。グローバルなフラグ Py_InteractiveFlag が真の場合には、 filename ポインタが NULL か、名前が '<stdin>' または '???' のいずれかに等しい場合にも真を返します。

void PyOS_AfterFork()

プロセスが fork した後の内部状態を更新するための関数です; fork 後 Python インタプリタを使い続ける場合、新たなプロセス内でこの関数を呼び出さねばなりません。新たなプロセスに新たな実行可能物をロードする場合、この関数を呼び出す必要はありません。

int PyOS_CheckStack()

インタプリタがスタック空間を使い尽くしたときに真を返します。このチェック関数には信頼性がありますが、 USE_STACKCHECK が定義されている場合 (現状では Microsoft Visual C++ コンパイラでビルドした Windows 版) にしか利用できません . USE_CHECKSTACK は自動的に定義されます; 自前のコードでこの定義を変更してはなりません。

PyOS_sighandler_t PyOS_getsig(int i)

シグナル i に対する現在のシグナルハンドラを返します。この関数は sigaction() または signal() のいずれかに対する薄いラッパです。 sigaction() や signal() を直接呼び出してはなりません! PyOS_sighandler_t は void (*)(int) の typedef による別名です。

PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h)

シグナル i に対する現在のシグナルハンドラを h に設定します; 以前のシグナルハンドラを返します。この関数は sigaction() または signal() のいずれかに対する薄いラッパです。 sigaction() や signal() を直接呼び出してはなりません! PyOS_sighandler_t は void (*)(int) の typedef による別名です。

システム関数

sys モジュールが提供している機能にCのコードからアクセスする関数です。すべての関数は現在のインタプリタスレッドの sys モジュールの辞書に対して動作します。この辞書は内部のスレッド状態構造体に格納されています。

PyObject *PySys_GetObject(char *name)

sys モジュールの name オブジェクトを返すか、存在しなければ例外を設定せずに NULL を返します。

FILE *PySys_GetFile(char *name, FILE *def)

sys モジュールの name に関連付けられた FILE* を返します。 name がなかった場合や FILE* に関連付けられていなかった場合は def を返します。

int PySys_SetObject(char *name, PyObject *v)

v が NULL で無い場合、 sys モジュールの name に v を設定します。 v が NULL なら、 sys モジュールから name を削除します。成功したら 0 を、エラー時は -1 を返します。

void PySys_ResetWarnOptions()

sys.warnoptions を、空リストにリセットします。

void PySys_AddWarnOption(char *s)

sys.warnoptions に s を追加します。

void PySys_SetPath(char *path)

sys.path を path に含まれるパスの、リストオブジェクトに設定します。 path はプラットフォームの検索パスデリミタ(Unixでは :, Windows では ;) で区切られたパスのリストでなければなりません。

void PySys_WriteStdout(const char *format, ...)

format で指定された出力文字列を sys.stdout に出力します。切り詰めが起こった場合を含め、例外は一切発生しません。(後述)

format は、フォーマット後の出力文字列のトータルの大きさを1000バイト以下に抑えるべきです。 – 1000 バイト以降の出力文字列は切り詰められます。特に、制限のない “%s” フォーマットを使うべきではありません。 “%.<N>s” のようにして N に10進数の値を指定し、<N> + その他のフォーマット後の最大サイズが1000を超えないように設定するべきです。同じように “%f” にも気を付ける必要があります。非常に大きい数値に対して、数百の数字を出力する可能性があります。

問題が発生したり、 sys.stdout が設定されていなかった場合、フォーマット後のメッセージは本物の(Cレベルの) stdout に出力されます。

void PySys_WriteStderr(const char *format, ...)

上と同じですが、 sys.stderr か stderr に出力します。

プロセス制御

void Py_FatalError(const char *message)

致命的エラーメッセージ (fatal error message) を出力してプロセスを強制終了 (kill) します。後始末処理は行われません。この関数は、Python インタプリタを使い続けるのが危険であるような状況が検出されたとき; 例えば、オブジェクト管理が崩壊していると思われるときにのみ、呼び出されるようにしなければなりません。Unixでは、標準 C ライブラリ関数 abort() を呼び出して core を生成しようと試みます。

void Py_Exit(int status)

現在のプロセスを終了 (exit) します。この関数は Py_Finalize() を呼び出し、次いで標準 C ライブラリ関数 exit(status) を呼び出します。

int Py_AtExit(void (*func) ())

Py_Finalize() から呼び出される後始末処理を行う関数 (cleanup function) を登録します。後始末関数は引数無しで呼び出され、値を返しません。最大で 32 の後始末処理関数を登録できます。登録に成功すると、 Py_AtExit() は 0 を返します; 失敗すると -1 を返します。最後に登録した後始末処理関数から先に呼び出されます。各関数は高々一度しか呼び出されません。 Python の内部的な終了処理は後始末処理関数より以前に完了しているので、 func からはいかなる Python API も呼び出してはなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

モジュールの import

PyObject* PyImport_ImportModule(const char *name)

Return value: New reference.

この関数は下で述べる PyImport_ImportModuleEx() を単純化したインタフェースで、 globals および locals 引数を NULL のままにし、 level を 0 にしたものです。 name 引数にドットが含まれる場合 (あるパッケージのサブモジュールを指定している場合)、 fromlist 引数がリスト ['*'] に追加され、戻り値がモジュールを含むトップレベルパッケージではなく名前つきモジュール (named module) になるようにします。 (残念ながらこのやり方には、 name が実際にはサブモジュールでなくサブパッケージを指定している場合、パッケージの __all__ 変数に指定されているサブモジュールがロードされてしまうという副作用があります。) import されたモジュールへの新たな参照を返します。失敗した場合には例外をセットし、 NULL を返します。 Python 2.4 より前のバージョンでは、失敗した場合でもモジュールは生成されていることがあります — sys.modules を使って調べてください。 Python 2.4 以降では、 import に失敗したモジュールは sys.modules に残りません。

バージョン 2.4 で変更: import に失敗した場合、不完全なモジュールを除去するようになりました。

バージョン 2.6 で変更: 常に、絶対 import を使うようになりました。

PyObject* PyImport_ImportModuleNoBlock(const char *name)

このバージョンの PyImport_ImportModule() はブロックしません。関数を実行するために他のモジュールをインポートするC関数から使われることを意図しています。インポート処理は他のスレッドがインポートロックを持っている場合はブロックします。この関数はブロックしません。まず sys.modules からモジュールのフェッチを試み、失敗したら、ロックが取られていなければ PyImport_ImportModule() を実行します。ロックが取られていた場合は ImportError を発生させます。

バージョン 2.6 で追加.

PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)

Return value: New reference.

モジュールを import します。モジュールの import については組み込みの Python 関数 __import__() を読むとよく分かります。というのも、標準の __import__() はこの関数を直接呼び出しているからです。

戻り値は import されたモジュールかトップレベルパッケージへの新たな参照になります。失敗した場合には例外をセットし、 NULL を返します (Python 2.4 よりも前のバージョンでは、モジュールは生成されている場合があります) __import__() と同じく、パッケージに対してサブモジュールを要求した場合の戻り値は通常、空でない fromlist を指定しない限りトップレベルパッケージになります。

バージョン 2.4 で変更: import に失敗した場合、不完全なモジュールを除去するようになりました。

バージョン 2.6 で変更: この関数は PyImport_ImportModuleLevel() のエイリアスです。 level には相対インポートを意味する -1 が渡されます。

PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)

モジュールをインポートします。このモジュールの動作については、Python ビルトイン関数の __import__() でよく説明されています。 __import__() は直接この関数を実行します。

戻り値は、インポートされたモジュールかトップレベルパッケージへの新しい参照か、失敗した場合は例外を設定して NULL を返します。 __import__() と同じように、パッケージのサブモジュールが要求されたときは、空でない fromlist を渡された時以外は、トップレベルのパッケージを返します。

バージョン 2.5 で追加.

PyObject* PyImport_Import(PyObject *name)

Return value: New reference.

現在の “import フック関数” を呼び出すための高水準のインタフェースです。この関数は現在のグローバル変数辞書内の __builtins__ から __import__() 関数を呼び出します。すなわち、現在の環境にインストールされている import フック、例えば rexec や ihooks を使って import を行います。

バージョン 2.6 で変更: 常に、絶対importを使うようになりました。

PyObject* PyImport_ReloadModule(PyObject *m)

Return value: New reference.

モジュールを再ロード (reload) します。モジュールの再ロードについては組み込みの Python 関数 reload() を読むとよく分かります。というのも、標準の reload() はこの関数を直接呼び出しているからです。戻り値は再ロードしたモジュールかトップレベルパッケージへの新たな参照になります。失敗した場合には例外をセットし、 NULL を返します (その場合でも、モジュールは生成されている場合があります)

PyObject* PyImport_AddModule(const char *name)

Return value: Borrowed reference.

モジュール名に対応するモジュールオブジェクトを返します。 name 引数は package.module の形式でもかまいません。まずモジュール辞書に該当するモジュールがあるかどうか調べ、なければ新たなモジュールを生成してモジュール辞書に挿入します。失敗した場合には例外をセットして NULL を返します。

ノート

この関数はモジュールの import やロードを行いません; モジュールがまだロードされていなければ、空のモジュールオブジェクトを得ることになります。 PyImport_ImportModule() やその別形式を使ってモジュールを import してください。ドット名表記で指定した name が存在しない場合、パッケージ構造は作成されません。

PyObject* PyImport_ExecCodeModule(char *name, PyObject *co)

Return value: New reference.

モジュール名 (package.module 形式でもかまいません) および Python のバイトコードファイルや組み込み関数 compile() で得られたコードオブジェクトを元にモジュールをロードします。モジュールオブジェクトへの新たな参照を返します。失敗した場合には例外をセットし、 NULL を返します。Python 2.4 以前では、失敗した場合でもモジュールは生成されていることがありました。 Python 2.4 以降では、たとえ PyImport_ExecCodeModule() の処理に入った時に name が sys.modules に入っていたとしても、 import に失敗したモジュールは sys.modules に残りません。初期化の不完全なモジュールを sys.modules に残すのは危険であり、そのようなモジュールを import するコードにとっては、モジュールの状態がわからない (モジュール作者の意図から外れた壊れた状態かもしれない) からです。

モジュールの __file__ 属性が、コードオブジェクトの co_filename に設定されます。

この関数は、すでに import されているモジュールの場合には再ロードを行います。意図的にモジュールの再ロードを行う方法は PyImport_ReloadModule() を参照してください。

name が package.module 形式のドット名表記であった場合、まだ作成されていないパッケージ構造はその作成されないままになります。

バージョン 2.4 で変更: エラーが発生した場合に name を sys.modules から除去するようになりました。

PyObject* PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)

PyImport_ExecCodeModule() に似ていますが、 pathname が NULL で無い場合、モジュールオブジェクトの __file__ 属性に設定します。

long PyImport_GetMagicNumber()

Python バイトコードファイル (いわゆる .pyc および .pyo ファイル) のマジックナンバを返します。マジックナンバはバイトコードファイルの先頭 4 バイトにリトルエンディアン整列で配置されています。

PyObject* PyImport_GetModuleDict()

Return value: Borrowed reference.

モジュール管理のための辞書 (いわゆる sys.modules )を返します。この辞書はインタプリタごとに一つだけある変数なので注意してください。

PyObject* PyImport_GetImporter(PyObject *path)

sys.path/pkg.__path__ の要素 path の、 importer オブジェクトを返します。可能なら、 sys.path_importer_cache からフェッチします。まだキャッシュされていない場合、そのパスを扱える hook が見つかるまで sys.path_hooks を巡回します。 hook が見つからない場合、 None を返します。この場合、呼び出し元はビルトインの import 機構にフォールバックします。結果は sys.path_importer_cache にキャッシュされます。 importer オブジェクトへの新しい参照を返します。

バージョン 2.6 で追加.

void _PyImport_Init()

import 機構を初期化します。内部使用だけのための関数です。

void PyImport_Cleanup()

モジュールテーブルを空にします。内部使用だけのための関数です。

void _PyImport_Fini()

import 機構を終了処理します。内部使用だけのための関数です。

PyObject* _PyImport_FindExtension(char *, char *)

内部使用だけのための関数です。

PyObject* _PyImport_FixupExtension(char *, char *)

内部使用だけのための関数です。

int PyImport_ImportFrozenModule(char *name)

name という名前のフリーズ (freeze) されたモジュールをロードします。成功すると 1 を、モジュールが見つからなかった場合には 0 を、初期化が失敗した場合には例外をセットして -1 を返します。ロードに成功したモジュールにアクセスするには PyImport_ImportModule() を使ってください。 (Note この関数名はいささか誤称めいています — この関数はすでに import 済みのモジュールをリロードしてしまいます。)

struct _frozen

freeze ユーティリティが生成するようなフリーズ化モジュールデスクリプタの構造体型定義です。 (Python ソース配布物の Tools/freeze/ を参照してください) この構造体の定義は Include/import.h にあり、以下のようになっています:

struct _frozen {
    char *name;
    unsigned char *code;
    int size;
};

struct _frozen* PyImport_FrozenModules

このポインタは struct _frozen のレコードからなり、終端の要素のメンバが NULL かゼロになっているような配列を指すよう初期化されます。フリーズされたモジュールを import するとき、このテーブルを検索します。サードパーティ製のコードからこのポインタに仕掛けを講じて、動的に生成されたフリーズ化モジュールの集合を提供するようにできます。

int PyImport_AppendInittab(const char *name, void (*initfunc)(void))

既存の組み込みモジュールテーブルに単一のモジュールを追加します。この関数は利便性を目的とした PyImport_ExtendInittab() のラッパ関数で、テーブルが拡張できないときには -1 を返します。新たなモジュールは name で import でき、最初に import を試みた際に呼び出される関数として initfunc を使います。 Py_Initialize() よりも前に呼び出さねばなりません。

struct _inittab

組み込みモジュールリスト内の一つのエントリを記述している構造体です。リスト内の各構造体には、インタプリタ内に組み込まれているモジュールの名前と初期化関数が指定されています。 Python を埋め込むようなプログラムは、この構造体の配列と PyImport_ExtendInittab() を組み合わせて、追加の組み込みモジュールを提供できます。構造体は Include/import.h で以下のように定義されています:

struct _inittab {
    char *name;
    void (*initfunc)(void);
};

int PyImport_ExtendInittab(struct _inittab *newtab)

組み込みモジュールのテーブルに一群のモジュールを追加します。配列 newtab は name フィールドが NULL になっているセンチネル (sentinel) エントリで終端されていなければなりません; センチネル値を与えられなかった場合にはメモリ違反になるかもしれません。成功すると 0 を、内部テーブルを拡張するのに十分なメモリを確保できなかった場合には -1 を返します。操作が失敗した場合、モジュールは一切内部テーブルに追加されません。 Py_Initialize() よりも前に呼び出さねばなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

データ整列化 (data marshalling) のサポート

以下のルーチン群は、 marshal モジュールと同じ形式を使った整列化オブジェクトを C コードから使えるようにします。整列化形式でデータを書き出す関数に加えて、データを読み戻す関数もあります。整列化されたデータを記録するファイルはバイナリモードで開かれていなければなりません。

数値は最小桁が先にくるように記録されます。

このモジュールでは、3つのバージョンのデータ形式をサポートしています。バージョン 0 は従来のもので、(Python 2.4 で新たに追加された) バージョン 1 は intern 化された文字列をファイル内で共有し、逆マーシャル化の時にも共有されるようにします。 (Python 2.5 で新たに追加された) バージョン2は、浮動小数点数に対してバイナリフォーマットを利用します。 PY_MARSHAL_VERSION は現在のバージョン (バージョン 2) を示します。

void PyMarshal_WriteLongToFile(long value, FILE *file, int version)

long 型の整数値 value を file へ整列化します。この関数は value の下桁 32 ビットを書き込むだけです; ネイティブの long 型サイズには関知しません。

バージョン 2.4 で変更: ファイル形式を示す version が追加されました.

void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version)

Python オブジェクト value を file へ整列化します。

バージョン 2.4 で変更: ファイル形式を示す version が追加されました.

PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version)

Return value: New reference.

value の整列化表現が入った文字列オブジェクトを返します。

バージョン 2.4 で変更: ファイル形式を示す version が追加されました.

以下の関数を使うと、整列化された値を読み戻せます。

long PyMarshal_ReadLongFromFile(FILE *file)

読み出し用に開かれた FILE* 内のデータストリームから、 C の long 型データを読み出して返します。この関数は、ネイティブの long のサイズに関係なく、 32 ビットの値だけを読み出せます。

int PyMarshal_ReadShortFromFile(FILE *file)

読み出し用に開かれた FILE* 内のデータストリームから、 C の short 型データを読み出して返します。この関数は、ネイティブの short のサイズに関係なく、 16 ビットの値だけを読み出せます。

PyObject* PyMarshal_ReadObjectFromFile(FILE *file)

Return value: New reference.

読み出し用に開かれた FILE* 内のデータストリームから、 Python オブジェクトを読み出して返します。エラーが生じた場合、適切な例外 (EOFError または TypeError) を送出して NULL を返します。

PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file)

Return value: New reference.

読み出し用に開かれた FILE* 内のデータストリームから、 Python オブジェクトを読み出して返します。 PyMarshal_ReadObjectFromFile() と違い、この関数はファイル中に後続のオブジェクトが存在しないと仮定し、ファイルからメモリ上にファイルデータを一気にメモリにロードして、逆整列化機構がファイルから一バイトづつ読み出す代わりにメモリ上のデータを操作できるようにします。対象のファイルから他に何も読み出さないと分かっている場合にのみ、この関数を使ってください。エラーが生じた場合、適切な例外 (EOFError または TypeError) を送出して NULL を返します。

PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len)

Return value: New reference.

string が指している len バイトの文字列バッファに納められたデータストリームから Python オブジェクトを読み出して返します。エラーが生じた場合、適切な例外 (EOFError または TypeError) を送出して NULL を返します。

バージョン 2.5 で変更: この関数は以前は len の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

引数の解釈と値の構築

これらの関数は独自の拡張モジュール用の関数やメソッドを作成する際に便利です。詳しい情報や用例は Python インタプリタの拡張と埋め込み にあります。

最初に説明する 3 つの関数、 PyArg_ParseTuple(), PyArg_ParseTupleAndKeywords(),および PyArg_Parse() はいずれも書式化文字列 (format string) を使います。書式化文字列は、関数が受け取るはずの引数に関する情報を伝えるのに用いられます。いずれの関数における書式化文字列も、同じ書式を使っています。

書式化文字列は、ゼロ個またはそれ以上の “書式化単位 (format unit)” から成り立ちます。 1つの書式化単位は1つの Python オブジェクトを表します; 通常は単一の文字か、書式化単位からなる文字列を括弧で囲ったものになります。例外として、括弧で囲われていない書式化単位文字列が単一のアドレス引数に対応する場合がいくつかあります。以下の説明では、引用符のついた形式は書式化単位です; (丸)括弧で囲った部分は書式化単位に対応する Python のオブジェクト型です; [角] 括弧は値をアドレス渡しする際に使う C の変数型です。

s (文字列型または Unicode 型) [const char *]

Python の文字列または Unicode オブジェクトを、キャラクタ文字列を指す C のポインタに変換します。変換先の文字列自体の記憶領域を提供する必要はありません; キャラクタ型ポインタ変数のアドレスを渡すと、すでに存在している文字列へのポインタをその変数に記録します。C 文字列は NUL で終端されています。Python の文字列型は、NUL バイトが途中に埋め込まれていてはなりません; もし埋め込まれていれば TypeError 例外を送出します。Unicode オブジェクトはデフォルトエンコーディングを使って C 文字列に変換されます。変換に失敗すると UnicodeError を送出します。

s# (文字列型、Unicode 型または任意の読み出しバッファ互換型) [const char *, int (または Py_ssize_t, 下記参照)]

これは s の変化形で、値を二つの変数に記録します。一つ目の変数はキャラクタ文字列へのポインタで、二つ目はその長さです。この書式化単位の場合には、Python 文字列に null バイトが埋め込まれていてもかまいません。 Unicode オブジェクトの場合、デフォルトエンコーディングでの変換が可能ならば、変換したオブジェクトから文字列へのポインタを返します。その他の読み出しバッファ互換オブジェクトは生の内部データ表現への参照を返します。

Python 2.5 から、長さの引数の型を、 Python.h を include する前に PY_SSIZE_T_CLEAN マクロ を定義することで制御できるようになりました。もしこのマクロが定義されていた場合、長さは int ではなく Py_ssize_t になります。

s* (文字列型、Unicode 型、または任意のバッファー互換オブジェクト) [Py_buffer]

s# と似ていますが、呼び出し元から渡された Py_buffer 構造体に書き込みます。バッファーはロックされるので、呼び出し元はそのバッファーを Py_BEGIN_ALLOW_THREADS したブロック内でさえも利用することができます。その代わり、呼び出し元には、データを処理した後にその構造体に対して PyBuffer_Release する責任があります。

バージョン 2.6 で追加.

z (文字列型、Unicode 型 または None) [const char *]

s に似ていますが、Python オブジェクトは None でもよく、その場合には C のポインタは NULL にセットされます。

z# (文字列型、 None 、または任意の読み出しバッファ互換型) [const char *, int]

s# の s を z にしたような意味です。

z* (文字列型、Unicode型、 None または任意のバッファー互換型) [Py_buffer]

s* の s を z にしたような意味です。

バージョン 2.6 で追加.

u (Unicode 型) [Py_UNICODE *]

Python の Unicode オブジェクトを、NUL で終端された 16 ビットの Unicode (UTF-16) データに変換します。 s と同様に、 Unicode データバッファ用に記憶領域を提供する必要はありません; Py_UNICODE 型ポインタ変数のアドレスを渡すと、すでに存在している Unicode データへのポインタをその変数に記録します。

u# (Unicode 型) [Py_UNICODE *, int]

これは u の変化形で、値を二つの変数に記録します。一つ目の変数は Unicode データバッファへのポインタで、二つ目はその長さです。非 Unicode のオブジェクトの場合、読み出しバッファのポインタを Py_UNICODE 型シーケンスへのポインタと解釈して扱います。

es (文字列型、Unicode 型または任意の読み出しバッファ互換型)[const char *encoding, char **buffer]

これは s の変化形で、Unicode オブジェクトや Unicode に変換可能なオブジェクトをキャラクタ型バッファにエンコードするために用いられます。NUL バイトが埋め込まれていない文字列でのみ動作します。

この書式化単位には二つの引数が必要です。一つ目は入力にのみ用いられ、 NUL で終端されたエンコード名文字列を指す const char* 型でなければなりません。指定したエンコード名を Python が理解できない場合には例外を送出します。第二の引数は char** でなければなりません; この引数が参照しているポインタの値は、引数に指定したテキストの内容が入ったバッファへのポインタになります。テキストは最初の引数に指定したエンコード方式でエンコードされます。

PyArg_ParseTuple() を使うと、必要なサイズのバッファを確保し、そのバッファにエンコード後のデータをコピーして、 *buffer がこの新たに確保された記憶領域を指すように変更します。呼び出し側には、確保されたバッファを使い終わった後に PyMem_Free() で解放する責任があります。

et (文字列型、Unicode 型または文字列バッファ互換型) [const char *encoding, char **buffer]

es と同じです。ただし、8 ビット幅の文字列オブジェクトをエンコードし直さずに渡します。その代わり、実装では文字列オブジェクトがパラメタに渡したエンコードを使っているものと仮定します。

es# (文字列型、Unicode 型または文字列バッファ互換型) [const char *encoding, char **buffer, int *buffer_length]

s# の変化形で、Unicode オブジェクトや Unicode に変換可能なオブジェクトをキャラクタ型バッファにエンコードするために用いられます。 es 書式化単位と違って、この変化形はバイトが埋め込まれていてもかまいません。

この書式化単位には三つの引数が必要です。一つ目は入力にのみ用いられ、 NUL で終端されたエンコード名文字列を指す const char* 型か NULL でなければなりません。 NULL の場合にはデフォルトエンコーディングを使います。指定したエンコード名を Python が理解できない場合には例外を送出します。第二の引数は char** でなければなりません; この引数が参照しているポインタの値は、引数に指定したテキストの内容が入ったバッファへのポインタになります。テキストは最初の引数に指定したエンコード方式でエンコードされます。第三の引数は整数へのポインタでなければなりません; ポインタが参照している整数の値は出力バッファ内のバイト数にセットされます。

この書式化単位の処理には二つのモードがあります:

*buffer が NULL ポインタを指している場合、関数は必要なサイズのバッファを確保し、そのバッファにエンコード後のデータをコピーして、 *buffer がこの新たに確保された記憶領域を指すように変更します。呼び出し側には、確保されたバッファを使い終わった後に PyMem_Free() で解放する責任があります。

*buffer が非 NULL のポインタ (すでにメモリ確保済みのバッファ) を指している場合、 PyArg_ParseTuple() はこのメモリ位置をバッファとして用い、 *buffer_length の初期値をバッファサイズとして用います。 PyArg_ParseTuple() は次にエンコード済みのデータをバッファにコピーして、NUL で終端します。バッファの大きさが足りなければ ValueError がセットされます。

どちらの場合も、 *buffer_length は終端の NUL バイトを含まないエンコード済みデータの長さにセットされます。

et# (文字列型、Unicode 型または文字列バッファ互換型) [const char *encoding, char **buffer, int *buffer_length]

es# と同じです。ただし、文字列オブジェクトをエンコードし直さずに渡します。その代わり、実装では文字列オブジェクトがパラメタに渡したエンコードを使っているものと仮定します。

b (整数型) [unsigned char]

Python の非負の整数を、 C の unsigned char 型の小さな符号無し整数に変換します。

B (整数型) [unsigned char]

Python の整数を、オーバフローチェックを行わずに、 C の unsigned char 型の小さな整数に変換します。

バージョン 2.3 で追加.

h (整数型) [short int]

Python の整数を、 C の short int 型に変換します。

H (整数型) [unsigned short int]

Python の整数を、オーバフローチェックを行わずに、 C の unsigned short int 型に変換します。

バージョン 2.3 で追加.

i (整数型) [int]

Python の整数を、 C の int 型に変換します。

I (整数型) [unsigned int]

Python の整数を、オーバフローチェックを行わずに、 C の unsigned int 型に変換します。

バージョン 2.3 で追加.

l (整数型) [long int]

Python の整数を、 C の long int 型に変換します。

k (整数型) [unsigned long]

Python の整数もしくは長整数を、オーバフローチェックを行わずに、 C の unsigned long int 型に変換します。

バージョン 2.3 で追加.

L (整数型) [PY_LONG_LONG]

Python の整数を、 C の long long 型に変換します。この書式化単位は、 long long 型 (または Windows の _int64 型) がサポートされているプラットフォームでのみ利用できます。

K (整数型) [unsigned PY_LONG_LONG]

Python の整数もしくは長整数を、オーバフローチェックを行わずに、 C の unsigned long long 型に変換します。この書式化単位は、 unsigned long long 型 (または Windows の unsigned _int64 型) がサポートされているプラットフォームでのみ利用できます。

バージョン 2.3 で追加.

n (整数型) [Py_ssize_t]

Python の整数もしくは長整数をCの Py_ssize_t 型に変換します。

バージョン 2.5 で追加.

c (長さ 1 の文字列型) [char]

長さ 1 の文字列として表現されている Python キャラクタを C の char 型に変換します。

f (浮動小数点型) [float]

Python の浮動小数点型を、 C の float 型に変換します。

d (浮動小数点型) [double]

Python の浮動小数点型を、 C の double 型に変換します。

D (複素数型) [Py_complex]

Python の複素数型を、 C の Py_complex 構造体に変換します。

O (オブジェクト) [PyObject *]

Python オブジェクトを (一切変換を行わずに) C の Python オブジェクト型ポインタに保存します。これにより、C プログラムは実際のオブジェクトを受け渡しされます。オブジェクトの参照カウントは増加しません。保存されるポインタが NULL になることはありません。

O! (オブジェクト) [typeobject, PyObject *]

Python オブジェクトを C の Python オブジェクト型ポインタに保存します。 O に似ていますが、二つの C の引数をとります: 一つ目の引数は Python の型オブジェクトへのアドレスで、二つ目の引数はオブジェクトへのポインタが保存されている (PyObject* の) C の変数へのアドレスです。Python オブジェクトが指定した型ではない場合、 TypeError を送出します。

O& (オブジェクト) [converter, anything]

Python オブジェクトを converter 関数を介して C の変数に変換します。二つの引数をとります: 一つ目は関数で、二つ目は (任意の型の) C 変数へのアドレスを void * 型に変換したものです。 converter は以下のようにして呼び出されます:

status = converter(object, address);

ここで object は変換対象の Python オブジェクトで、 address は PyArg_Parse*() に渡した void* 型の引数です。戻り値 status は変換に成功した際に 1,失敗した場合には 0 になります。変換に失敗した場合、 converter 関数は address の内容を変更せずに例外を送出しなくてはなりません。

S (文字列型) [PyStringObject *]

O に似ていますが、Python オブジェクトは文字列オブジェクトでなければなりません。オブジェクトが文字列オブジェクトでない場合には TypeError を送出します。 C 変数は PyObject* で宣言しておいてもかまいません。

U (Unicode 型) [PyUnicodeObject *]

O に似ていますが、Python オブジェクトは Unicode オブジェクトでなければなりません。オブジェクトが Unicode オブジェクトでない場合には TypeError を送出します。 C 変数は PyObject* で宣言しておいてもかまいません。

t# (読み出し専用キャラクタバッファ) [char *, int]

s# に似ていますが、読み出し専用バッファインタフェースを実装している任意のオブジェクトを受理します。 char* 変数はバッファの最初のバイトを指すようにセットされ、 int はバッファの長さにセットされます。単一セグメントからなるバッファオブジェクトだけを受理します; それ以外の場合には TypeError を送出します。

w (読み書き可能なキャラクタバッファ) [char *]

s と同様ですが、読み書き可能なバッファインタフェースを実装している任意のオブジェクトを受理します。呼び出し側は何らかの別の手段でバッファの長さを決定するか、あるいは w# を使わねばなりません。単一セグメントからなるバッファオブジェクトだけを受理します; それ以外の場合には TypeError を送出します。

w# (読み書き可能なキャラクタバッファ) [char *, Py_ssize_t]

s# に似ていますが、読み書き可能なバッファインタフェースを実装している任意のオブジェクトを受理します。 char* 変数はバッファの最初のバイトを指すようにセットされ、 Py_ssize_t はバッファの長さにセットされます。単一セグメントからなるバッファオブジェクトだけを受理します; それ以外の場合には TypeError を送出します。

w* (読み書きできるバイト列バッファ) [Py_buffer]

s に対する s* と同じ、 w のバージョンです。

バージョン 2.6 で追加.

(items) (タプル) [matching-items]

オブジェクトは items に入っている書式化単位の数だけの長さを持つ Python のシーケンス型でなくてはなりません。各 C 引数は items 内の個々の書式化単位に対応づけできねばなりません。シーケンスの書式化単位は入れ子構造にできます。

ノート

Python のバージョン 1.5.2 より以前は、この書式化指定文字列はパラメタ列ではなく、個別のパラメタが入ったタプルでなければなりませんでした。このため、以前は TypeError を引き起こしていたようなコードが現在は例外を出さずに処理されるかもしれません。とはいえ、既存のコードにとってこれは問題ないと思われます。

Python 整数型を要求している場所に Python 長整数型を渡すのは可能です; しかしながら、適切な値域チェックはまったく行われません — 値を受け取るためのフィールドが、値全てを受け取るには小さすぎる場合、上桁のビット群は暗黙のうちに切り詰められます (実際のところ、このセマンティクスは C のダウンキャスト (downcast) から継承しています — その恩恵は人それぞれかもしれませんが)。

その他、書式化文字列において意味を持つ文字がいくつかあります。それらの文字は括弧による入れ子内には使えません。以下に文字を示します:

|

Python 引数リスト中で、この文字以降の引数がオプションであることを示します。オプションの引数に対応する C の変数はデフォルトの値で初期化しておかねばなりません — オプションの引数が省略された場合、 PyArg_ParseTuple() は対応する C 変数の内容に手を加えません。

:

この文字があると、書式化単位の記述はそこで終わります; コロン以降の文字列は、エラーメッセージにおける関数名 (PyArg_ParseTuple() が送出する例外の “付属値 (associated value)”) として使われます。

;

この文字があると、書式化単位の記述はそこで終わります; セミコロン以降の文字列は、デフォルトエラーメッセージを 置き換えるエラーメッセージとして使われます。 : と ; は相互に排他の文字です。

呼び出し側に提供される Python オブジェクトの参照は全て 借りた (borrowed) ものです; オブジェクトの参照カウントをデクリメントしてはなりません!

以下の関数に渡す補助引数 (additional argument) は、書式化文字列から決定される型へのアドレスでなければなりません; 補助引数に指定したアドレスは、タプルから入力された値を保存するために使います。上の書式化単位のリストで説明したように、補助引数を入力値として使う場合がいくつかあります; その場合、対応する書式化単位の指定する形式に従うようにせねばなりません。

変換を正しく行うためには、 arg オブジェクトは書式化文字に一致しなければならず、かつ書式化文字列内の書式化単位に全て値が入るようにせねばなりません。成功すると、 PyArg_Parse*() 関数は真を返します。それ以外の場合には偽を返し、適切な例外を送出します。書式化単位のどれかの変換失敗により PyArg_Parse*() が失敗した場合、失敗した書式化単位に対応するアドレスとそれ以降のアドレスの内容は変更されません。

int PyArg_ParseTuple(PyObject *args, const char *format, ...)

固定引数のみを引数にとる関数のパラメタを解釈して、ローカルな変数に変換します。成功すると真を返します;失敗すると偽を返し、適切な例外を送出します。

int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)

PyArg_ParseTuple() と同じですが、可変長の引数ではなく va_list を引数にとります。

int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)

固定引数およびキーワード引数をとる関数のパラメタを解釈して、ローカルな変数に変換します。成功すると真を返します;失敗すると偽を返し、適切な例外を送出します。

int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)

PyArg_ParseTupleAndKeywords() と同じですが、可変長の引数ではなく va_list を引数にとります。

int PyArg_Parse(PyObject *args, const char *format, ...)

“旧スタイル” の関数における引数リストを分析するために使われる関数です — 旧スタイルの関数は、引数解釈手法に METH_OLDARGS を使います。新たに書かれるコードでのパラメタ解釈にはこの関数の使用は奨められず、標準のインタプリタにおけるほとんどのコードがもはや引数解釈のためにこの関数を使わないように変更済みです。この関数を残しているのは、この関数が依然として引数以外のタプルを分析する上で便利だからですが、この目的においては将来も使われつづけるかもしれません。

int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)

パラメータ取得を簡単にした形式で、引数の型を指定する書式化文字列を使いません。パラメタの取得にこの手法を使う関数は、関数宣言テーブル、またはメソッド宣言テーブル内で METH_VARARGS として宣言しなくてはなりません。実引数の入ったタプルは args に渡します; このタプルは本当のタプルでなくてはなりません。タプルの長さは少なくとも min で、 max を超えてはなりません; min と max が等しくてもかまいません。補助引数を関数に渡さなくてはならず、各補助引数は PyObject* 変数へのポインタでなくてはなりません; これらの補助引数には、 args の値が入ります; 値の参照は借りた参照です。オプションのパラメタに対応する変数のうち、 args に指定していないものには値が入りません; 呼び出し側はそれらの値を初期化しておかねばなりません。この関数は成功すると真を返し、 args がタプルでない場合や間違った数の要素が入っている場合に偽を返します; 何らかの失敗が起きた場合には例外をセットします。

この関数の使用例を以下に示します。この例は、弱参照のための _weakref 補助モジュールのソースコードからとったものです:

static PyObject *
weakref_ref(PyObject *self, PyObject *args)
{
    PyObject *object;
    PyObject *callback = NULL;
    PyObject *result = NULL;

    if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) {
        result = PyWeakref_NewRef(object, callback);
    }
    return result;
}

この例における PyArg_UnpackTuple() 呼び出しは、 PyArg_ParseTuple() を使った以下の呼び出し:

PyArg_ParseTuple(args, "O|O:ref", &object, &callback)

と全く等価です。

バージョン 2.2 で追加.

バージョン 2.5 で変更: この関数は min と max に int を利用していました。この変更により、64 bitシステムを正しくサポートするためには修正が必要になるでしょう。

PyObject* Py_BuildValue(const char *format, ...)

Return value: New reference.

PyArg_Parse*() ファミリの関数が受け取るのと似た形式の書式化文字列および値列に基づいて、新たな値を生成します。生成した値を返します。エラーの場合には NULL を返します; NULL を返す場合、例外を送出するでしょう。

Py_BuildValue() は常にタプルを生成するとは限りません。この関数がタプルを生成するのは、書式化文字列に二つ以上の書式化単位が入っているときだけです。書式化文字列が空の場合、 None を返します; 書式化単位が厳密に一つだけ入っている場合、書式化単位で指定されている何らかのオブジェクト単体を返します。サイズがゼロや 1 のタプルを返すように強制するには、丸括弧で囲われた書式化文字列を使います。

書式化単位 s や s# の場合のように、オブジェクトを構築する際にデータを供給するためにメモリバッファをパラメタとして渡す場合には、指定したデータはコピーされます。 Py_BuildValue() が生成したオブジェクトは、呼び出し側が提供したバッファを決して参照しません。別の言い方をすれば、 malloc() を呼び出してメモリを確保し、それを Py_BuildValue() に渡した場合、コード内で Py_BuildValue() が返った後で free() を呼び出す責任があるということです。

以下の説明では、引用符のついた形式は書式化単位です; (丸)括弧で囲った部分は書式化単位が返す Python のオブジェクト型です; [角] 括弧は関数に渡す値の C 変数型です。

書式化文字列内では、(s# のような書式化単位を除いて) スペース、タブ、コロンおよびコンマは無視されます。これらの文字を使うと、長い書式化文字列をちょっとだけ読みやすくできます。

s (文字列型) [char *]

null 終端された C 文字列から Python オブジェクトに変換します。 C 文字列ポインタが NULL の場合、 None になります。

s# (文字列型) [char *, int]

C 文字列とその長さから Python オブジェクトに変換します。 C 文字列ポインタが NULL の場合、長さは無視され None になります。

z (文字列型または None) [char *]

s と同じです。

z# (文字列型または None) [char *, int]

s# と同じです。

u (Unicode 型) [Py_UNICODE *]

null 終端された Unicode (UCS-2 または UCS-4) データのバッファから Python オブジェクトに変換します。 Unicode バッファポインタが NULL の場合、 None になります。

u# (Unicode 型) [Py_UNICODE *, int]

null 終端された Unicode (UCS-2 または UCS-4) データのバッファとその長さから Python オブジェクトに変換します。 Unicode バッファポインタが NULL の場合、長さは無視され None になります。

i (整数型) [int]

通常の C の int を Python の整数オブジェクトに変換します。

b (整数型) [char]

i と同じです。通常のC の char を Python の整数オブジェクトに変換します。

h (整数型) [short int]

通常のC の short int を Python の整数オブジェクトに変換します。

l (整数型) [long int]

C の long int を Python の整数オブジェクトに変換します。

B (整数型) [unsigned char]

C の unsigned char を Python の整数オブジェクトに変換します。

H (整数型) [unsigned short int]

C の unsigned short int を Python の整数オブジェクトに変換します。

I (整数型/長整数型) [unsigned int]

C の unsigned int を Python の整数オブジェクト、あるいは、値が sys.maxint より大きければ長整数オブジェクトに変換します。

k (整数型/長整数型) [unsigned long]

C の unsigned long を Python の整数オブジェクト、あるいは、値が sys.maxint より大きければ長整数オブジェクトに変換します。

L (長整数型) [PY_LONG_LONG]

C の long long を Python の長整数オブジェクトに変換します。 long long をサポートしているプラットフォームでのみ利用可能です。

K (長整数型) [unsigned PY_LONG_LONG]

C の unsigned long long を Python の長整数オブジェクトに変換します。 long long をサポートしているプラットフォームでのみ利用可能です。

n (長整数型) [Py_ssize_t]

C の unsigned long を Python の整数オブジェクト、あるいは長整数オブジェクトに変換します。

バージョン 2.5 で追加.

c (長さ 1 の文字列型) [char]

文字を表す通常の C の int を、長さ 1 の Python の文字列オブジェクトに変換します。

d (浮動小数点型) [double]

C の double を Python の浮動小数点数に変換します。

f (浮動小数点型) [float]

d と同じです。

D (複素数型) [Py_complex *]

C の Py_complex 構造体を Python の複素数に変換します。

O (オブジェクト) [PyObject *]

Python オブジェクトを手を加えずに渡します (ただし、参照カウントは 1 インクリメントします)。渡したオブジェクトが NULL ポインタの場合、この引数を生成するのに使った何らかの呼び出しがエラーになったのが原因であると仮定して、例外をセットします。従ってこのとき Py_BuildValue() は NULL を返しますが Py_BuildValue() 自体は例外を送出しません。例外をまだ送出していなければ SystemError をセットします。

S (オブジェクト) [PyObject *]

O と同じです。

N (オブジェクト) [PyObject *]

O と同じです。ただし、オブジェクトの参照カウントをインクリメントしません。オブジェクトが引数リスト内のオブジェクトコンストラクタ呼び出しによって生成されている場合に便利です。

O& (オブジェクト) [converter, anything]

anything を converter 関数を介して Python オブジェクトに変換します。この関数は anything (void * と互換の型でなければなりません) を引数にして呼び出され、”新たな” オブジェクトを返すか、失敗した場合には NULL を返すようにしなければなりません。

(items) (タプル型) [matching-items]

C の値からなる配列を、同じ要素数を持つ Python のタプルに変換します。

[items] (リスト型) [matching-items]

C の値からなる配列を、同じ要素数を持つ Python のリストに変換します。

{items} (辞書型) [matching-items]

C の値からなる配列を Python の辞書に変換します。一連のペアからなる C の値が、それぞれキーおよび値となって辞書に追加されます。

書式化文字列に関するエラーが生じると、 SystemError 例外をセットして NULL を返します。

PyObject* Py_VaBuildValue(const char *format, va_list vargs)

Py_BuildValue() と同じですが、可変長引数の代わりに va_list を受け取ります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

文字列の変換と書式化

数値変換と、書式化文字列出力のための関数群

int PyOS_snprintf(char *str, size_t size, const char *format, ...)

書式化文字列 format と追加の引数から、 size バイトを超えない文字列を str に出力します。 Unix man page の snprintf(2) を参照してください。

int PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)

書式化文字列 format と可変長引数リスト va から、 size バイトを超えない文字列を str に出力します。 Unix man page の vsnprintf(2) を参照してください。

PyOS_snprintf() と PyOS_vsnprintf() は標準Cライブラリの snprintf() と vsnprintf() 関数をラップします。これらの関数の目的は、C標準ライブラリが保証していないコーナーケースでの動作を保証することです。

これらのラッパ関数は、戻るときに str*[*size-1] が常に '\0' であることを保証します。 (str の末尾の '\0' を含めて) size バイト以上を書き込みません。 str != NULL, size > 0, format != NULL を要求します。

もし vsnprintf() のないプラットフォームで、切り捨てを避けるために必要なバッファサイズが size を512バイトより大きく超過していれば、 Python は Py_FatalError で abort します。

The return value (rv) for these functions should be interpreted as follows: これらの関数の戻り値 (rv) は次のように解釈されなければなりません:

0 <= rv < size のとき、変換出力は成功して、 (最後の str*[*rv] にある '\0' を除いて) rv 文字が str に出力された。

rv >= size のとき、変換出力は切り詰められており、成功するためには rv + 1 バイトが必要だったことを示します。 str*[*size-1] は '\0' です。

rv < 0 のときは、何か悪いことが起こった時です。この場合でも str*[*size-1] は '\0' ですが、 str のそれ以外の部分は未定義です。エラーの正確な原因はプラットフォーム依存です。

以下の関数は locale 非依存な文字列から数値への変換を行ないます。

double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception)

文字列 s を double に変換します。失敗したときは Python の例外を発生させます。受け入れられる文字列は、 Python の float() コンストラクタが受け付ける文字列に準拠しますが、 s の先頭と末尾に空白文字があってはならないという部分が異なります。この変換は現在のロケールに依存しません。

endptr が NULL の場合、変換は文字列全体に対して行われます。文字列が正しい浮動小数点数の表現になっていない場合は -1.0 を返して ValueError を発生させます。

endptr が NULL で無い場合、文字列を可能な範囲で変換して、 *endptr に最初の変換されなかった文字へのポインタを格納します。文字列の先頭に正しい浮動小数点数の表現が無かった場合、 *endptr を文字列の先頭に設定して、 ValueError を発生させ、 -1.0 を返します。

s が float に格納し切れないほど大きい値を表現していた場合、 (例えば、 "1e500" は多くのプラットフォームで表現できません) overflow_exception が NULL なら Py_HUGE_VAL に適切な符号を付けて返します。他の場合は overflow_exception は Python の例外オブジェクトへのポインタでなければならず、その例外を発生させて -1.0 を返します。どちらの場合でも、 *endptr には変換された値の直後の最初の文字へのポインタが設定されます。

それ以外のエラーが変換中に発生した場合(例えば out-of-memory エラー)、適切な Python の例外を設定して -1.0 を返します。

バージョン 2.7 で追加.

double PyOS_ascii_strtod(const char *nptr, char **endptr)

文字列を double へ変換します。この関数は、C locale におけるC標準の strtod() と同じように動作します。スレッドセーフのために、この関数は現在の locale を変更せずに実装されています。

PyOS_ascii_strtod() は通常、設定ファイルを読み込むときや、ロケール独立な非ユーザーからの入力を読み込むときに使われるべきです。

詳細は Unix man page の strtod(2) を参照してください。

バージョン 2.4 で追加.

バージョン 2.7 で撤廃: 代わりに PyOS_string_to_double() を使ってください。

char* PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d)

double を '.' を小数点記号に利用して文字列に変換します。 format は数値のフォーマットを指定する printf() スタイルの文字列です。利用できる変換文字は 'e', 'E', 'f', 'F', 'g', 'G' です。

戻り値は、変換された文字列が格納された buffer へのポインタか、失敗した場合は NULL です。

バージョン 2.4 で追加.

バージョン 2.7 で撤廃: この関数は Python 2.7 と 3.1 では削除されました。代わりに PyOS_double_to_string() を使ってください。

char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype)

double val を指定された format_code, precision, flags に基づいて文字列に変換します。

format_code は 'e', 'E', 'f', 'F', 'g', 'G', 'r' のどれかでなければなりません。 'r' の場合、 precision は 0 でなければならず、無視されます。 'r' フォーマットコードは標準の repr() フォーマットを指定しています。

flags は 0 か、 Py_DTSF_SIGN, Py_DTSF_ADD_DOT_0, Py_DTSF_ALT かこれらの or を取ったものです。

Py_DTSF_SIGN は、 val が負で無いときも常に符号文字を先頭につけることを意味します。

Py_DTSF_ADD_DOT_0 は文字列が整数のように見えないことを保証します。

Py_DTSF_ALT は “alternate” フォーマットルールを適用することを意味します。詳細は PyOS_snprintf() の '#' 指定を参照してください。

ptype が NULL で無い場合、 val が有限数、無限数、NaNのどれかに合わせて、 Py_DTST_FINITE, Py_DTST_INFINITE, Py_DTST_NAN のいずれかに設定されます。

戻り値は変換後の文字列が格納された buffer へのポインタか、変換が失敗した場合は NULL です。呼び出し側は、返された文字列を PyMem_Free() を使って解放する責任があります。

バージョン 2.7 で追加.

double PyOS_ascii_atof(const char *nptr)

文字列を、 locale 非依存な方法で double へ変換します。

詳細は Unix man page の atof(2) を参照してください。

バージョン 2.4 で追加.

バージョン 3.1 で撤廃: 代わりに PyOS_string_to_double() を使ってください。

char* PyOS_stricmp(char *s1, char *s2)

大文字/小文字を区別しない文字列比較。大文字/小文字を無視する以外は、 strcmp() と同じ動作をします。

バージョン 2.6 で追加.

char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t  size)

大文字/小文字を区別しない文字列比較。大文字/小文字を無視する以外は、 strncmp() と同じ動作をします。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

リフレクション

PyObject* PyEval_GetBuiltins()

現在の実行フレーム内のビルトインの辞書か、もし実行中のフレームがなければスレッド状態のインタプリタのビルトイン辞書を返します。

PyObject* PyEval_GetLocals()

現在の実行フレーム内のローカル変数の辞書か、実行中のフレームがなければ NULL を返します。

PyObject* PyEval_GetGlobals()

現在の実行フレームのグローバル変数の辞書か、実行中のフレームがなければ NULL を返します。

PyFrameObject* PyEval_GetFrame()

現在のスレッド状態のフレームを返します。現在実行中のフレームがなければ NULL を返します。

int PyFrame_GetLineNumber(PyFrameObject *frame)

frame が現在実行している行番号を返します。

int PyEval_GetRestricted()

現在のフレームがありそれが制限モードで実行していた場合、真を返します。それ以外の場合は僞を返します。

const char* PyEval_GetFuncName(PyObject *func)

func が 関数、クラス、インスタンスオブジェクトであればその名前を、そうでなければ func の型を返します。

const char* PyEval_GetFuncDesc(PyObject *func)

func の型に依存する、解説文字列(description string)を返します。戻り値は、関数とメソッドに対しては “()”, ” constructor”, ” instance”, ” object” です。 PyEval_GetFuncName() と連結された結果、 func の解説になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

ユーティリティ関数 »

codec レジストリとサポート関数

int PyCodec_Register(PyObject *search_function)

新しい codec 検索関数を登録します。

副作用として、この関数は encodings パッケージが常に検索関数の先頭に来るように、まだロードされていない場合はロードします。

int PyCodec_KnownEncoding(const char *encoding)

encoding のための登録された codec が存在するかどうかに応じて 1 か 0 を返します。

PyObject* PyCodec_Encode(PyObject *object, const char *encoding, const char *errors)

汎用の codec ベースの encode API.

encoding に応じて見つかったエンコーダ関数に対して object を渡します。エラーハンドリングメソッドは errors で指定します。 errors は NULL でもよく、その場合はその codec のデフォルトのメソッドが利用されます。エンコーダが見つからなかった場合は LookupError を発生させます。

PyObject* PyCodec_Decode(PyObject *object, const char *encoding, const char *errors)

汎用の codec ベースの dencode API.

encoding に応じて見つかったデコーダ関数に対して object を渡します。エラーハンドリングメソッドは errors で指定します。 errors は NULL でもよく、その場合はその codec のデフォルトのメソッドが利用されます。デコーダが見つからなかった場合は LookupError を発生させます。

コーデック検索API

以下の関数では、文字列 encoding は全て小文字に変換することで、効率的に、大文字小文字を無視した検索をします。コーデックが見つからない場合、 KeyError を設定して NULL を返します。

PyObject* PyCodec_Encoder(const char *encoding)

encoding のエンコーダ関数を返します。

PyObject* PyCodec_Decoder(const char *encoding)

encoding のデコーダ関数を返します。

PyObject* PyCodec_IncrementalEncoder(const char *encoding, const char *errors)

encoding の IncrementalEncoder オブジェクトを返します。

PyObject* PyCodec_IncrementalDecoder(const char *encoding, const char *errors)

encoding の IncrementalDecoder オブジェクトを返します。

PyObject* PyCodec_StreamReader(const char *encoding, PyObject *stream, const char *errors)

encoding の StreamReader ファクトリ関数を返します。

PyObject* PyCodec_StreamWriter(const char *encoding, PyObject *stream, const char *errors)

encoding の StreamWriter ファクトリ関数を返します。

Unicode エラーハンドラ用レジストリ API

int PyCodec_RegisterError(const char *name, PyObject *error)

エラーハンドルのためのコールバック関数 error を name で登録します。このコールバック関数は、コーデックがエンコードできない文字/デコードできないバイトに遭遇した時に、そのエンコード/デコード関数の呼び出しで name が指定されていたら呼び出されます。

コールバックは1つの引数として、 UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError のどれかのインスタンスを受け取ります。このインスタンスは問題のある文字列やバイト列に関する情報と、その元の文字列中のオフセットを持っています。(その情報を取得するための関数については Unicode 例外オブジェクト を参照してください。) コールバックは渡された例外を発生させるか、2要素のタプルに問題のシーケンスの代替と、 encode/decode を再開する元の文字列中のオフセットとなる整数を格納して返します。

成功したら 0 を、エラー時は -1 を返します。

PyObject* PyCodec_LookupError(const char *name)

name で登録されたエラーハンドリングコールバック関数を検索します。特別な場合として、 NULL が渡された場合、 “strict” のエラーハンドリングコールバック関数を返します。

PyObject* PyCodec_StrictErrors(PyObject *exc)

exc を例外として発生させます。

PyObject* PyCodec_IgnoreErrors(PyObject *exc)

unicode エラーを無視し、問題の入力をスキップします。

PyObject* PyCodec_ReplaceErrors(PyObject *exc)

unicode エラーを ? か U+FFFD で置き換えます。

PyObject* PyCodec_XMLCharRefReplaceErrors(PyObject *exc)

unicode encode エラーを XML文字参照で置き換えます。

PyObject* PyCodec_BackslashReplaceErrors(PyObject *exc)

unicode encode エラーをバックスラッシュエスケープ (\x, \u, \U) で置き換えます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer)

この章で説明する関数は、オブジェクトの型に依存しないような Python オブジェクトの操作や、(数値型全て、シーケンス型全てといった)大まかな型のオブジェクトに対する操作を行ないます。関数を適用対象でないオブジェクトに対して使った場合、 Python の例外が送出されることになります。

これらの関数は、 PyList_New() で作成された後に NULL 以外の値を設定されていないリストのような、適切に初期化されていないオブジェクトに対して使うことはできません。

オブジェクトプロトコル (object protocol)

数値型プロトコル (number protocol)

シーケンス型プロトコル (sequence protocol)

マップ型プロトコル (mapping protocol)

イテレータプロトコル (iterator protocol)

古いバッファプロトコル

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

オブジェクトプロトコル (object protocol)

int PyObject_Print(PyObject *o, FILE *fp, int flags)

オブジェクト o をファイル fp に出力します。失敗すると -1 を返します。 flags 引数は何らかの出力オプションを有効にする際に使います。現在サポートされている唯一のオプションは Py_PRINT_RAW です; このオプションを指定すると、 repr() の代わりに str() を使ってオブジェクトを書き込みます。

int PyObject_HasAttr(PyObject *o, PyObject *attr_name)

o が属性 attr_name を持つときに 1 を、それ以外のときに 0 を返します。この関数は Python の式 hasattr(o, attr_name) と同じです。この関数は常に成功します。

int PyObject_HasAttrString(PyObject *o, const char *attr_name)

o が属性 attr_name を持つときに 1 を、それ以外のときに 0 を返します。この関数は Python の式 hasattr(o, attr_name) と同じです。この関数は常に成功します。

PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name)

Return value: New reference.

オブジェクト o から、名前 attr_name の属性を取得します。成功すると属性値を返し失敗すると NULL を返します。この関数は Python の式 o.attr_name と同じです。

PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name)

Return value: New reference.

オブジェクト o から、名前 attr_name の属性を取得します。成功すると属性値を返し失敗すると NULL を返します。この関数は Python の式 o.attr_name と同じです。

PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name)

汎用の属性取得関数で、 type オブジェクトの tp_getattro スロットに置かれることを意図されています。この関数は、オブジェクトのMRO中のクラスの辞書にあるディスクリプタと、オブジェクトの __dict__ (があれば)に格納されている属性を検索します。デスクリプタ (descriptor) の実装 で説明されているように、データディスクリプタはインスタンス属性より優先され、非データディスクリプタは後回しにされます。見つからなかった場合は AttributeError を発生させます。

int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v)

オブジェクト o の attr_name という名の属性に、値 v を設定します。失敗すると -1 を返します。この関数は Python の式 o.attr_name = v と同じです。

int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v)

オブジェクト o の attr_name という名の属性に、値 v を設定します。失敗すると -1 を返します。この関数は Python の式 o.attr_name = v と同じです。

int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value)

汎用の属性設定関数で、typeオブジェクトの tp_setattro スロットに置かれることを意図しています。オブジェクトのMROにあるクラス列の辞書からデータディスクリプタを探し、見つかればインスタンス辞書への格納よりもデータディスクリプタを優先します。見つからなければ、オブジェクトの __dict__ (があれば) に属性を設定します。失敗した場合、 AttributeError を発生させて -1 を返します。

int PyObject_DelAttr(PyObject *o, PyObject *attr_name)

オブジェクト o の attr_name という名の属性を削除します。失敗すると -1 を返します。この関数は Python の文 del o.attr_name と同じです。

int PyObject_DelAttrString(PyObject *o, const char *attr_name)

オブジェクト o の attr_name という名の属性を削除します。失敗すると -1 を返します。この関数は Python の文 del o.attr_name と同じです。

PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid)

Return value: New reference.

o1 と o2 を opid に指定した演算によって比較します。 opid は Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, または Py_GE, のいずれかでなければならず、それぞれ <, <=, ==, !=, >, および >= に対応します。この関数は Python の式 o1 op o2 と同じで、 op が opid に対応する演算子です。成功すると比較結果の値を返し失敗すると NULL を返します。

int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)

o1 と o2 を opid に指定した演算によって比較します。 opid は Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, または Py_GE, のいずれかでなければならず、それぞれ <, <=, ==, !=, >, および >= に対応します。比較結果が真ならば 1 を、偽ならば 0 を、エラーが発生すると -1 を返します。この関数は Python の式 o1 op o2 と同じで、 op が opid に対応する演算子です。

ノート

o1 と o2 が同一のオブジェクトである場合、 PyObject_RichCompareBool() は Py_EQ に対して常に 1 を返し、 Py_NE に対して常に 0 を返します。

int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)

o1 と o2 の値を比較します。このとき o1 が比較ルーチンを持っていればそれを使い、なければ o2 のルーチンを使います。比較結果は result に返されます。失敗すると -1 を返します。 Python 文 result = cmp(o1, o2) と同じです。

int PyObject_Compare(PyObject *o1, PyObject *o2)

o1 と o2 の値を比較します。このとき o1 が比較ルーチンを持っていればそれを使い、なければ o2 のルーチンを使います。比較結果は result に返されます。失敗すると -1 を返します。 Python 文 result = cmp(o1, o2) と同じです。成功すると比較結果を返します。エラーが生じた場合の戻り値は未定義です; PyErr_Occurred() を使ってエラー検出を行って下さい。Python 式 cmp(o1,  o2) と同じです。

PyObject* PyObject_Repr(PyObject *o)

Return value: New reference.

o の文字列表現を計算します。成功すると文字列表現を返し、失敗すると NULL を返します。Python 式 repr(o) と同じです。この関数は組み込み関数 repr() や逆クオート表記の処理で呼び出されます。

PyObject* PyObject_Str(PyObject *o)

Return value: New reference.

o の文字列表現を計算します。成功すると文字列表現を返し、失敗すると NULL を返します。Python 式 str(o) と同じです。この関数は組み込み関数 str() や print 文の処理で呼び出されます。

PyObject* PyObject_Bytes(PyObject *o)

o オブジェクトの bytes 表現を計算します。 2.x では、単に PyObject_Str() のエイリアスです。

PyObject* PyObject_Unicode(PyObject *o)

Return value: New reference.

o の Unicode 文字列表現を計算します。成功すると Unicode 文字列表現を返し失敗すると NULL を返します。 Python 式 unicode(o) と同じです。この関数は組み込み関数 unicode() の処理で呼び出されます。

int PyObject_IsInstance(PyObject *inst, PyObject *cls)

inst が cls のインスタンスか、 cls のサブクラスのインスタンスの場合に -1 を返し、そうでなければ 0 を返します。エラーの時には -1 を返し、例外をセットします。 cls がクラスオブジェクトではなく型オブジェクトの場合、 PyObject_IsInstance() は inst が cls であるときに 1 を返します。 cls をタプルで指定した場合、 cls に指定した全てのエントリについてチェックを行います。少なくとも一つのエントリに対するチェックが 1 を返せば結果は 1 になり、そうでなければ 0 になります。 inst がクラスインスタンスでなく、かつ cls が型オブジェクトでもクラスオブジェクトでもタプルでもない場合、 inst には __class__ 属性がなくてはなりません — この場合、 __class__ 属性の値と、 cls の値の間のクラス関係を、関数の戻り値を決定するのに使います。

バージョン 2.1 で追加.

バージョン 2.2 で変更: 二つ目の引数にタプルのサポートを追加しました。.

サブクラスの決定はかなり正攻法で行いますが、クラスシステムの拡張を実装する人たちに知っておいて欲しいちょっとした問題点があります。 A と B がクラスオブジェクトの場合、 B が A のサブクラスとなるのは、 B が A を直接的あるいは間接的に継承 (inherit) している場合です。両方がクラスオブジェクトでない場合、二つのオブジェクト間のクラス関係を決めるには、より汎用の機構を使います。 B が A のサブクラスであるか調べたとき、 A が B と等しければ、 PyObject_IsSubclass() は真を返します。 A および B が異なるオブジェクトなら、 B の __bases__ 属性から深さ優先探索 (depth-first search)で A を探索します — オブジェクトに __bases__ があるだけで、この決定法を適用する条件を満たしているとみなされます。

int PyObject_IsSubclass(PyObject *derived, PyObject *cls)

クラス derived が cls と同じクラスか、 cls の派生クラスの場合に 1 を返し、それ以外の場合には 0 を返します。エラーが生じると -1 を返します。 cls をタプルで指定した場合、 cls に指定した全てのエントリについてチェックを行います。少なくとも一つのエントリに対するチェックが 1 を返せば結果は 1 になり、そうでなければ 0 になります。 derived または cls のいずれかが実際のクラスオブジェクト (あるいはタプル) でない場合、上で述べた汎用アルゴリズムを使います。

バージョン 2.1 で追加.

バージョン 2.3 で変更: 以前の Python のバージョンは、二つ目の引数にタプルをサポートしていませんでした.

int PyCallable_Check(PyObject *o)

オブジェクト o が呼び出し可能オブジェクトかどうか調べます。オブジェクトが呼び出し可能であるときに 1 を返し、そうでないときには 0 を返します。この関数呼び出しは常に成功します。

PyObject* PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw)

Return value: New reference.

呼び出し可能な Python オブジェクト callable_object をタプルで指定された引数 args および辞書で指定された名前つき引数 (named argument) kw とともに呼び出します。名前つき引数を必要としない場合、 kw を NULL にしてもかまいません。 args は NULL であってはなりません。引数が全く必要ない場合には空のタプルを使ってください。成功すると呼び出し結果として得られたオブジェクトを返し、失敗すると NULL を返します。 Python の式 apply(callable_object, args, kw) あるいは callable_object(*args, **kw) と同じです。

バージョン 2.2 で追加.

PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args)

Return value: New reference.

呼び出し可能な Python オブジェクト callable_object をタプルで指定された引数 args とともに呼び出します。 引数を必要としない場合、 args を NULL にしてもかまいません。成功すると呼び出し結果として得られたオブジェクトを返し、失敗すると NULL を返します。 Python の式 apply(callable_object, args) あるいは callable_object(*args) と同じです。

PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...)

Return value: New reference.

呼び出し可能な Python オブジェクト callable_object を可変数個の C 引数とともに呼び出します。C 引数は Py_BuildValue() 形式のフォーマット文字列を使って記述します。 format は NULL にしてもよく、与える引数がないことを表します。成功すると呼び出し結果として得られたオブジェクトを返し、失敗すると NULL を返します。 Python の式 apply(callable, args) あるいは callable(*args) と同じです。もしも、 PyObject * args だけを引数に渡す場合は、 PyObject_CallFunctionObjArgs() がより速い方法であることを覚えておいてください。

PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...)

Return value: New reference.

オブジェクト o の method という名前のメソッドを、可変数個の C 引数とともに呼び出します。C 引数はタプルを生成するような Py_BuildValue() 形式のフォーマット文字列を使って記述します。 format は NULL にしてもよく、与える引数がないことを表します。成功すると呼び出し結果として得られたオブジェクトを返し、失敗すると NULL を返します。 Python の式 o.method(args) と同じです。もしも、 PyObject * args だけを引数に渡す場合は、 PyObject_CallMethodObjArgs() がより速い方法であることを覚えておいてください。

PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL)

Return value: New reference.

呼び出し可能な Python オブジェクト callable_object を可変数個の PyObject* 引数とともに呼び出します。引数列は末尾に NULL がついた可変数個のパラメタとして与えます。成功すると呼び出し結果として得られたオブジェクトを返し失敗すると NULL を返します。

バージョン 2.2 で追加.

PyObject* PyObject_CallMethodObjArgs(PyObject *o, PyObject *name, ..., NULL)

Return value: New reference.

オブジェクト o のメソッドを呼び出します、メソッド名は Python 文字列オブジェクト name で与えます。可変数個の PyObject* 引数と共に呼び出されます. 引数列は末尾に NULL がついた可変数個のパラメタとして与えます。成功すると呼び出し結果として得られたオブジェクトを返し失敗すると NULL を返します。

バージョン 2.2 で追加.

long PyObject_Hash(PyObject *o)

オブジェクト o のハッシュ値を計算して返します。失敗すると -1 を返します。 Python の式 hash(o) と同じです。

long PyObject_HashNotImplemented(PyObject *o)

type(o) がハッシュ不可能であることを示す TypeError を設定し、 -1 を返します。この関数は tp_hash スロットに格納されたときには特別な扱いを受け、その type がハッシュ不可能であることをインタプリタに明示的に示します。

バージョン 2.6 で追加.

int PyObject_IsTrue(PyObject *o)

o が真を表すとみなせる場合には 1 を、そうでないときには 0 を返します。 Python の式 not not o と同じです。失敗すると -1 を返します。

int PyObject_Not(PyObject *o)

o が真を表すとみなせる場合には 0 を、そうでないときには 1 を返します。 Python の式 not o と同じです。失敗すると -1 を返します。

PyObject* PyObject_Type(PyObject *o)

Return value: New reference.

o が NULL でない場合、オブジェクト o のオブジェクト型に相当する型オブジェクトを返します。失敗すると SystemError を送出して NULL を返します。 Python の式 type(o) と同じです。 この関数は戻り値の参照カウントをインクリメントします。参照カウントのインクリメントが必要でない限り、広く使われていて PyTypeObject* 型のポインタを返す表記法 o->ob_type の代わりに使う理由は全くありません。

int PyObject_TypeCheck(PyObject *o, PyTypeObject *type)

オブジェクト o が、 type か type のサブタイプであるときに真を返します。どちらのパラメタも NULL であってはなりません。

バージョン 2.2 で追加.

Py_ssize_t PyObject_Length(PyObject *o)

Py_ssize_t PyObject_Size(PyObject *o)

o の長さを返します。オブジェクト o がシーケンス型プロトコルとマップ型プロトコルの両方を提供している場合、シーケンスとしての長さを返します。エラーが生じると -1 を返します。 Python の式 len(o) と同じです。

バージョン 2.5 で変更: これらの関数は以前は int 型を返していました。この変更により、 64bit システムを適切にサポートするためにはコードの修正が必要になります。

PyObject* PyObject_GetItem(PyObject *o, PyObject *key)

Return value: New reference.

成功するとオブジェクト key に対応する o の要素を返し、失敗すると NULL を返します。 Python の式 o[key] と同じです。

int PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v)

オブジェクト key を値 v に対応付けます。失敗すると -1 を返します。 Python の文 o[key] = v と同じです。

int PyObject_DelItem(PyObject *o, PyObject *key)

オブジェクト o から key に対する対応付けを削除します。失敗すると -1 を返します。 Python の文 del o[key] と同じです。

int PyObject_AsFileDescriptor(PyObject *o)

Python オブジェクトからファイル記述子を取り出します。オブジェクトが整数か長整数なら、その値を返します。 (長)整数でない場合、オブジェクトに fileno() メソッドがあれば呼び出します; この場合、 fileno() メソッドは整数または長整数をファイル記述子の値として返さなければなりません。失敗すると -1 を返します。

PyObject* PyObject_Dir(PyObject *o)

Return value: New reference.

この関数は Python の式 dir(o) と同じで、オブジェクトの変数名に割り当てている文字列からなるリスト (空の場合もあります) を返します。エラーの場合には NULL を返します。引数を NULL にすると、Python における dir() と同様に、現在のローカルな名前を返します; この場合、アクティブな実行フレームがなければ NULL を返しますが、 PyErr_Occurred() は偽を返します。

PyObject* PyObject_GetIter(PyObject *o)

Return value: New reference.

Python の式 iter(o) と同じです。引数にとったオブジェクトに対する新たなイテレータか、オブジェクトがすでにイテレータの場合にはオブジェクト自身を返します。オブジェクトが反復処理不可能であった場合には TypeError を送出して NULL を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

数値型プロトコル (number protocol)

int PyNumber_Check(PyObject *o)

オブジェクト o が数値型プロトコルを提供している場合に 1 を返し、そうでないときには偽を返します。この関数呼び出しは常に成功します。

PyObject* PyNumber_Add(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 を加算した結果を返し、失敗すると NULL を返します。 Python の式 o1 + o2 と同じです。

PyObject* PyNumber_Subtract(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 から o2 を減算した結果を返し、失敗すると NULL を返します。 Python の式 o1 - o2 と同じです。

PyObject* PyNumber_Multiply(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 を乗算した結果を返し、失敗すると NULL を返します。 Python の式 o1 * o2 と同じです。

PyObject* PyNumber_Divide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した結果を返し, 失敗すると NULL を返します。 Python の式 o1 / o2 と同じです。

PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した切捨て値を返し、失敗すると NULL を返します。 “旧仕様の” 整数間での除算と同じです。

バージョン 2.2 で追加.

PyObject* PyNumber_TrueDivide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると、数学的な o1 の o2 による除算値に対する妥当な近似 (reasonable approximation) を返し、失敗すると NULL を返します。全ての実数を 2 を基数として表現するのは不可能なため、二進の浮動小数点数は “近似値” しか表現できません。このため、戻り値も近似になります。この関数に二つの整数を渡した際、浮動小数点の値を返すことがあります。

バージョン 2.2 で追加.

PyObject* PyNumber_Remainder(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した剰余を返し、失敗すると NULL を返します。 Python の式 o1 % o2 と同じです。

PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2)

Return value: New reference.

組み込み関数 divmod() を参照してください。失敗すると NULL を返します。 Python の式 divmod(o1, o2) と同じです。

PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3)

Return value: New reference.

組み込み関数 pow() を参照してください。失敗すると NULL を返します。 Python の式 pow(o1, o2, o3) と同じです。 o3 はオプションです。 o3 を無視させたいなら、 Py_None を入れてください (o3 に NULL を渡すと、不正なメモリアクセスを引き起こすことがあります)。

PyObject* PyNumber_Negative(PyObject *o)

Return value: New reference.

成功すると o の符号反転を返し、失敗すると NULL を返します。 Python の式 -o と同じです。

PyObject* PyNumber_Positive(PyObject *o)

Return value: New reference.

成功すると o を返し、失敗すると NULL を返します。 Python の式 +o と同じです。

PyObject* PyNumber_Absolute(PyObject *o)

Return value: New reference.

成功すると o の絶対値を返し、失敗すると NULL を返します。 Python の式 abs(o) と同じです。

PyObject* PyNumber_Invert(PyObject *o)

Return value: New reference.

成功すると o のビット単位反転 (bitwise negation) を返し、失敗すると NULL を返します。Python の式 ~o と同じです。

PyObject* PyNumber_Lshift(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 だけ左シフトした結果を返し、失敗すると NULL を返します。 Python の式 o1 << o2 と同じです。

PyObject* PyNumber_Rshift(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 だけ右シフトした結果を返し、失敗すると NULL を返します。 Python の式 o1 >> o2 と同じです。

PyObject* PyNumber_And(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位論理積 (bitwise and)” を返し、失敗すると NULL を返します。 Python の式 o1 & o2 と同じです。

PyObject* PyNumber_Xor(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位排他的論理和 (bitwise exclusive or)” を返し、失敗すると NULL を返します。 Python の式 o1 ^ o2 と同じです。

PyObject* PyNumber_Or(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位論理和 (bitwise or)” を返し失敗すると NULL を返します。 Python の式 o1 | o2 と同じです。

PyObject* PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 を加算した結果を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 += o2 と同じです。

PyObject* PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 から o2 を減算した結果を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 -= o2 と同じです。

PyObject* PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 を乗算した結果を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 *= o2 と同じです。

PyObject* PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した結果を返し, 失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 /= o2 と同じです。

PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した切捨て値を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 //= o2 と同じです。

バージョン 2.2 で追加.

PyObject* PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると、数学的な o1 の o2 による除算値に対する妥当な近似 (reasonable approximation) を返し、失敗すると NULL を返します。全ての実数を 2 を基数として表現するのは不可能なため、二進の浮動小数点数は “近似値” しか表現できません。このため、戻り値も近似になります。この関数に二つの整数を渡した際、浮動小数点の値を返すことがあります。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。

バージョン 2.2 で追加.

PyObject* PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 で除算した剰余を返し、 , 失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 %= o2 と同じです。

PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3)

Return value: New reference.

組み込み関数 pow() を参照してください。失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。この関数は o3 が Py_None の場合は Python 文 o1 **= o2 と同じで、それ以外の場合は pow(o1, o2, o3) の in-place 版です。 o3 を無視させたいなら、 Py_None を入れてください (o3 に NULL を渡すと、不正なメモリアクセスを引き起こすことがあります)。

PyObject* PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 だけ左シフトした結果を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 <<= o2 と同じです。

PyObject* PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 を o2 だけ右シフトした結果を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 >>= o2 と同じです。

PyObject* PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位論理積 (bitwise and)” を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 &= o2 と同じです。

PyObject* PyNumber_InPlaceXor(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位排他的論理和 (bitwise exclusive or)” を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 ^= o2 と同じです。

PyObject* PyNumber_InPlaceOr(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の “ビット単位論理和 (bitwise or)” を返し失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の文 o1 |= o2 と同じです。

int PyNumber_Coerce(PyObject **p1, PyObject **p2)

この関数は PyObject* 型の二つの変数のアドレスを引数にとります。 *p1 と *p2 が指すオブジェクトが同じ型の場合、それぞれの参照カウントをインクリメントして 0 (成功) を返します。オブジェクトを変換して共通の数値型にできる場合、 *p1 と *p2 を変換後の値に置き換えて (参照カウントを ‘新しく’ して) 、 0 を返します。変換が不可能な場合や、その他何らかのエラーが生じた場合、 -1 (失敗) を返し、参照カウントをインクリメントしません。 PyNumber_Coerce(&o1, &o2) の呼び出しは Python 文 o1, o2 = coerce(o1, o2) と同じです。

int PyNumber_CoerceEx(PyObject **p1, PyObject **p2)

This function is similar to PyNumber_Coerce(), except that it returns 1 when the conversion is not possible and when no error is raised. Reference counts are still not increased in this case. この関数は PyNumber_Coerce() と似ていますが、変換が失敗た場合にはエラーを発生させず、 -1 を返します。この場合、参照カウントはインクリメントされません。

PyObject* PyNumber_Int(PyObject *o)

Return value: New reference.

成功すると o を整数に変換したものを返し、失敗すると NULL を返します。引数の値が整数の範囲外の場合、長整数を代わりに返します。 Python の式 int(o) と同じです。

PyObject* PyNumber_Long(PyObject *o)

Return value: New reference.

成功すると o を長整数に変換したものを返し、失敗すると NULL を返します。 Python の式 long(o) と同じです。

PyObject* PyNumber_Float(PyObject *o)

Return value: New reference.

成功すると o を浮動小数点数に変換したものを返し、失敗すると NULL を返します。 Python の式 float(o) と同じです。

PyObject* PyNumber_Index(PyObject *o)

o をPythonのintもしくはlong型に変換し、成功したらその値を返します。失敗したら NULL が返され、 TypeError 例外が送出されます。

バージョン 2.5 で追加.

PyObject* PyNumber_ToBase(PyObject *n, int base)

整数 n を、 base 進数の文字列に変換し、適切であれば '0b', '0o', '0x' の基数マーカーをつけます。 base が 2, 8, 10, 16 のいずれでも無い場合、フォーマットは x を基数として 'x#num' となります。もし n が整数オブジェクトでない場合、まず PyNumber_Index() を使って変換されます。

バージョン 2.6 で追加.

Py_ssize_t PyNumber_AsSsize_t(PyObject *o, PyObject *exc)

o を整数として解釈可能だった場合、Py_ssize_t型の値に変換して返します。もし o がPythonのintもしくはlongに変換できたのに、Py_ssize_tへの変換が OverflowError になる場合は、 exc 引数で渡された型 (普通は IndexError か OverflowError) の例外を送出します。もし、 exc が NULL なら、例外はクリアされて、値が負の場合は PY_SSIZE_T_MIN へ、正の場合は PY_SSIZE_T_MAX へと制限されます。

バージョン 2.5 で追加.

int PyIndex_Check(PyObject *o)

o がインデックス整数であるときにTrueを返します。 (tp_as_number構造体のnb_indexスロットが埋まっている場合)

バージョン 2.5 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

シーケンス型プロトコル (sequence protocol)

int PySequence_Check(PyObject *o)

オブジェクトがシーケンス型プロトコルを提供している場合に 1 を返し、そうでないときには 0 を返します。この関数呼び出しは常に成功します。

Py_ssize_t PySequence_Size(PyObject *o)

Py_ssize_t PySequence_Length(PyObject *o)

成功するとシーケンス o 中のオブジェクトの数を返し、失敗すると -1 を返します。シーケンス型プロトコルをサポートしないオブジェクトに対しては、 Python の式 len(o) と同じになります。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PySequence_Concat(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の連結 (concatenation) を返し、失敗すると NULL を返します。 Python の式 o1 + o2 と同じです。

PyObject* PySequence_Repeat(PyObject *o, Py_ssize_t count)

Return value: New reference.

成功するとオブジェクト o の count 回繰り返しを返し、失敗すると NULL を返します。 Python の式 o * count と同じです。

バージョン 2.5 で変更: この関数は以前は count の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2)

Return value: New reference.

成功すると o1 と o2 の連結 (concatenation) を返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の式 o1 += o2 と同じです。

PyObject* PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)

Return value: New reference.

成功するとオブジェクト o の count 回繰り返しを返し、失敗すると NULL を返します。 o1 が in-place 演算をサポートする場合、in-place 演算を行います。 Python の式 o *= count と同じです。

バージョン 2.5 で変更: この関数は以前は count の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i)

Return value: New reference.

成功すると o の i 番目の要素を返し、失敗すると NULL を返します。 Python の式 o[i] と同じです。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)

Return value: New reference.

成功すると o の i1 から i2 までの間のスライスを返し、失敗すると NULL を返します。 Python の式 o[i1:i2] と同じです。

バージョン 2.5 で変更: この関数は以前は i1, i2 の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_SetItem(PyObject *o, int Py_ssize_t i, PyObject *v)

o の i 番目の要素に v を代入します。失敗すると -1 を返します。 Python の文 o[i] = v と同じです。この関数は v への参照を盗み取り ません 。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_DelItem(PyObject *o, Py_ssize_t i)

o の i 番目の要素を削除します。失敗すると -1 を返します。 Python の文 del o[i] と同じです。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v)

o の i1 から i2 までの間のスライスに v を代入します。 Python の文 o[i1:i2] = v と同じです。

バージョン 2.5 で変更: この関数は以前は i1, i2 の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2)

シーケンスオブジェクト o の i1 から i2 までの間のスライスを削除します。失敗すると -1 を返します。 Python の文 del o[i1:i2] と同じです。

バージョン 2.5 で変更: この関数は以前は i1, i2 の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_Count(PyObject *o, PyObject *value)

o における value の出現回数、すなわち o[key] == value となる key の個数を返します。失敗すると -1 を返します。 Python の式 o.count(value) と同じです。

バージョン 2.5 で変更: この関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_Contains(PyObject *o, PyObject *value)

o に value が入っているか判定します。 o のある要素が value と等価 (equal) ならば 1 を返し、それ以外の場合には 0 を返します。エラーが発生すると -1 を返します。 Python の式 value in o と同じです。

int PySequence_Index(PyObject *o, PyObject *value)

o[i] == value となる最初に見つかったインデクス i を返します。エラーが発生すると -1 を返します。 Python の式 o.index(value) と同じです。

バージョン 2.5 で変更: この関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PySequence_List(PyObject *o)

Return value: New reference.

任意のシーケンス o と同じ内容を持つリストオブジェクトを返します。返されるリストは必ず新しいリストオブジェクトになります。

PyObject* PySequence_Tuple(PyObject *o)

Return value: New reference.

任意のシーケンス o と同じ内容を持つタプルオブジェクトを返します。失敗したら NULL を返します。 o がタプルの場合、新たな参照を返します。それ以外の場合、適切な内容が入ったタプルを構築して返します。 Pythonの式 tuple(o) と同じです。

PyObject* PySequence_Fast(PyObject *o, const char *m)

Return value: New reference.

シーケンス o がすでにタプルやリストであれば o を返し、そうでなければ o をタプルで返します。返されるタプルのメンバにアクセスするには PySequence_Fast_GET_ITEM() を使ってください。失敗すると NULL を返します。オブジェクトがシーケンスでなければ、 m がメッセージテキストになっている TypeError を送出します。

PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)

Return value: Borrowed reference.

o が NULL でなく、 PySequence_Fast() が返したオブジェクトであり、かつ i がインデクスの範囲内にあると仮定して、 o の i 番目の要素を返します。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject** PySequence_Fast_ITEMS(PyObject *o)

PyObject ポインタの背後にあるアレイを返します．この関数では， o は PySequence_Fast() の返したオブジェクトであり， NULL でないものと仮定しています．

リストのサイズが変更されるとき、メモリ再確保が要素の配列を再配置するかもしれないことに注意してください。そのため、シーケンスの変更が発生しないコンテキストでのみ背後にあるポインタを使ってください。

バージョン 2.4 で追加.

PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)

Return value: New reference.

成功すると o の i 番目の要素を返し、失敗すると NULL を返します。 PySequence_GetItem() ですが、 PySequence_Check(o)() が真になるかチェックせず、負のインデクスに対する調整を行いません。

バージョン 2.3 で追加.

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySequence_Fast_GET_SIZE(PyObject *o)

o が NULL でなく、 PySequence_Fast() が返したオブジェクトであると仮定して、 o の長さを返します。 o のサイズは PySequence_Size() を呼び出しても得られますが、 PySequence_Fast_GET_SIZE() の方が o をリストかタプルであると仮定して処理するため、より高速です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

マップ型プロトコル (mapping protocol)

int PyMapping_Check(PyObject *o)

オブジェクトがマップ型プロトコルを提供している場合に 1 を返し、そうでないときには 0 を返します。この関数呼び出しは常に成功します。

Py_ssize_t PyMapping_Size(PyObject *o)

Py_ssize_t PyMapping_Length(PyObject *o)

成功するとオブジェクト o 中のキーの数を返し、失敗すると -1 を返します。マップ型プロトコルを提供していないオブジェクトに対しては、 Python の式 len(o) と同じになります。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyMapping_DelItemString(PyObject *o, char *key)

オブジェクト o から key に関する対応付けを削除します。失敗すると -1 を返します。 Python の文 del o[key] と同じです。

int PyMapping_DelItem(PyObject *o, PyObject *key)

オブジェクト o から key に対する対応付けを削除します。失敗すると -1 を返します。 Python の文 del o[key] と同じです。

int PyMapping_HasKeyString(PyObject *o, char *key)

成功すると、マップ型オブジェクトがキー key を持つ場合に 1 を返し、そうでないときには 0 を返します。これは、 o[key] が成功したときに True を、例外が発生したときに False を返すのと等価です。この関数呼び出しは常に成功します。

int PyMapping_HasKey(PyObject *o, PyObject *key)

マップ型オブジェクトがキー key を持つ場合に 1 を返し、そうでないときには 0 を返します。これは、 o[key] が成功したときに True を、例外が発生したときに False を返すのと等価です。この関数呼び出しは常に成功します。

PyObject* PyMapping_Keys(PyObject *o)

Return value: New reference.

成功するとオブジェクト o のキーからなるリストを返します。失敗すると NULL を返します。 Python の式 o.keys() と同じです。

PyObject* PyMapping_Values(PyObject *o)

Return value: New reference.

成功するとオブジェクト o のキーに対応する値からなるリストを返します。失敗すると NULL を返します。 Python の式 o.values() と同じです。

PyObject* PyMapping_Items(PyObject *o)

Return value: New reference.

成功するとオブジェクト o の要素対、すなわちキーと値のペアが入ったタプルからなるリストを返します。失敗すると NULL を返します。 Python の式 o.items() と同じです。

PyObject* PyMapping_GetItemString(PyObject *o, char *key)

Return value: New reference.

オブジェクト key に対応する o の要素を返します。失敗すると NULL を返します。 Python の式 o[key] と同じです。

int PyMapping_SetItemString(PyObject *o, char *key, PyObject *v)

オブジェクト o で key を値 v に対応付けます。失敗すると -1 を返します。 Python の文 o[key] = v と同じです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

イテレータプロトコル (iterator protocol)

バージョン 2.2 で追加.

イテレータを扱うための固有の関数は二つしかありません。

int PyIter_Check(PyObject *o)

o がイテレータプロトコルをサポートする場合に真を返します。

PyObject* PyIter_Next(PyObject *o)

Return value: New reference.

反復処理 o における次の値を返します。オブジェクトがイテレータの場合、この関数は反復処理における次の値を取り出します。要素が何も残っていない場合には例外がセットされていない状態で NULL を返します。オブジェクトがイテレータでない場合には TypeError を送出します。要素を取り出す際にエラーが生じると NULL を返し、発生した例外を送出します。

イテレータの返す要素にわたって反復処理を行うループを書くと、 C のコードは以下のようになるはずです:

PyObject *iterator = PyObject_GetIter(obj);
PyObject *item;

if (iterator == NULL) {
    /* エラーの伝播処理をここに書く */
}

while (item = PyIter_Next(iterator)) {
    /* 取り出した要素で何らかの処理を行う */
    ...
    /* 終わったら参照を放棄する */
    Py_DECREF(item);
}

Py_DECREF(iterator);

if (PyErr_Occurred()) {
    /* エラーの伝播処理をここに書く */
}
else {
    /* 別の処理を続ける */
}

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

抽象オブジェクトレイヤ (abstract objects layer) »

古いバッファプロトコル

このセクションは Python 1.6 で導入された古いバッファプロトコルについて解説します。このプロトコルは、 Python 2.x 系ではサポートされていますが廃止予定扱いです。 Python 3.0 から、このプロトコルの弱点や欠点を克服した新しいバッファプロトコルが導入され、 Python 2.6 へと逆移植されました。詳細は buffer オブジェクトと memoryview オブジェクト を参照してください。

int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)

文字ベースの入力として使える読み出し専用メモリ上の位置へのポインタを返します。 obj 引数は単一セグメントからなる文字バッファインタフェースをサポートしていなければなりません。成功すると 0 を返し、 buffer をメモリの位置に、 buffer_len をバッファの長さに設定します。エラーの際には -1 を返し、 TypeError をセットします。

バージョン 1.6 で追加.

バージョン 2.5 で変更: この関数は以前は buffer_len の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)

任意のデータを収めた読み出し専用のメモリ上の位置へのポインタを返します。 obj 引数は単一セグメントからなる読み出し可能バッファインタフェースをサポートしていなければなりません。成功すると 0 を返し、 buffer をメモリの位置に、 buffer_len をバッファの長さに設定します。エラーの際には -1 を返し、 TypeError をセットします。

バージョン 1.6 で追加.

バージョン 2.5 で変更: この関数は以前は buffer_len の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyObject_CheckReadBuffer(PyObject *o)

o が単一セグメントからなる読み出し可能バッファインタフェースをサポートしている場合に 1 を返します。それ以外の場合には 0 を返します。

バージョン 2.2 で追加.

int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len)

書き込み可能なメモリ上の位置へのポインタを返します。 obj 引数は単一セグメントからなる文字バッファインタフェースをサポートしていなければなりません。成功すると 0 を返し、 buffer をメモリの位置に、 buffer_len をバッファの長さに設定します。エラーの際には -1 を返し、 TypeError をセットします。

バージョン 1.6 で追加.

バージョン 2.5 で変更: この関数は以前は buffer_len の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ

この章ではは、特定の Python オブジェクト型固有の関数について述べています。これらの関数に間違った型のオブジェクトを渡すのは良い考えではありません; Python プログラムから何らかのオブジェクトを受け取ったとき、そのオブジェクトが正しい型になっているか確信をもてないのなら、まず型チェックを行わなければなりません; 例えば、あるオブジェクトが辞書型か調べるには、 PyDict_Check() を使います。この章は Python のオブジェクト型における “家計図” に従って構成されています。

警告

この章で述べている関数は、渡されたオブジェクトの型を注意深くチェックしはするものの、多くの関数は渡されたオブジェクトが有効な NULL なのか有効なオブジェクトなのかをチェックしません。これらの関数に NULL を渡させてしまうと、関数はメモリアクセス違反を起こして、インタプリタを即座に終了させてしまうはずです。

基本オブジェクト (fundamental object)

この節では、Python の型オブジェクトとシングルトン(singleton)オブジェクト None について述べます。

型オブジェクト (type object)

None オブジェクト

数値型オブジェクト (numeric object)

(通常)整数型オブジェクト (plain integer object)

Bool 型オブジェクト

長整数型オブジェクト (long integer object)

浮動小数点型オブジェクト (floating point object)

浮動小数点オブジェクト (complex number object)

C 構造体としての複素数

Python オブジェクトとしての複素数型

シーケンスオブジェクト (sequence object)

シーケンスオブジェクトに対する一般的な操作については前の章ですでに述べました; この節では、Python 言語にもともと備わっている特定のシーケンスオブジェクトについて扱います。

bytearray オブジェクト

型チェックマクロ

ダイレクト API 関数

マクロ

文字列/バイトオブジェクト

Unicode オブジェクトと codec

Unicode オブジェクト

Unicode 型

Unicode 文字プロパティ

Plain Py_UNICODE

wchar_t サポート

組み込み codec (built-in codec)

汎用 codec

UTF-8 Codecs

UTF-32 Codecs

UTF-16 Codecs

UTF-7 Codecs

Unicode-Escape Codecs

Raw-Unicode-Escape Codecs

Latin-1 Codecs

ASCII Codecs

Character Map Codecs

Windows 用の MBCS codec

Methods & Slots

メソッドおよびスロット関数 (slot function)

buffer オブジェクトと memoryview オブジェクト

新スタイル Py_buffer 構造体

バッファ関連関数

memoryview オブジェクト

旧スタイルバッファオブジェクト

タプルオブジェクト (tuple object)

List Objects

マップ型オブジェクト (mapping object)

辞書オブジェクト (dictionary object)

その他のオブジェクト

クラスとインスタンスオブジェクト

関数オブジェクト (Function Objects)

メソッドオブジェクト (method object)

ファイルオブジェクト

モジュールオブジェクト (module object)

イテレータオブジェクト (iterator object)

デスクリプタオブジェクト (descriptor object)

スライスオブジェクト (slice object)

弱参照オブジェクト (weak reference object)

カプセル (Capsules)

Cオブジェクト (CObject)

セルオブジェクト (cell object)

ジェネレータオブジェクト

DateTime オブジェクト

集合オブジェクト (Set Objects)

コードオブジェクト

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

型オブジェクト (type object)

PyTypeObject

組み込み型を記述する際に用いられる、オブジェクトを表す C 構造体です。

PyObject* PyType_Type

型オブジェクト自身の型オブジェクトです; Python レイヤにおける type や types.TypeType と同じオブジェクトです。

int PyType_Check(PyObject *o)

オブジェクト o が型オブジェクトの場合に真を返します。標準型オブジェクトから派生したサブタイプ (subtype) のインスタンスも含みます。その他の場合には偽を返します。

int PyType_CheckExact(PyObject *o)

オブジェクト o が型オブジェクトの場合に真を返します。標準型のサブタイプの場合は含みません。その他の場合には偽を返します。

バージョン 2.2 で追加.

unsigned int PyType_ClearCache()

内部の検索キャッシュをクリアします。現在のバージョンタグを返します。

バージョン 2.6 で追加.

void PyType_Modified(PyTypeObject *type)

内部の検索キャッシュを、その type とすべてのサブタイプに対して無効にします。この関数は type の属性や基底クラス列を変更したあとに手動で呼び出さなければなりません。

バージョン 2.6 で追加.

int PyType_HasFeature(PyObject *o, int feature)

型オブジェクト o に、型機能 feature が設定されている場合に真を返します。型機能は各々単一ビットのフラグで表されます。

int PyType_IS_GC(PyObject *o)

型オブジェクトが o が循環参照検出をサポートしている場合に真を返します; この関数は型機能フラグ Py_TPFLAGS_HAVE_GC の設定状態をチェックします。

バージョン 2.0 で追加.

int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)

a が b のサブタイプの場合に真を返します。

バージョン 2.2 で追加.

PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)

Return value: New reference.

バージョン 2.2 で追加.

バージョン 2.5 で変更: この関数は以前は nitems の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)

Return value: New reference.

バージョン 2.2 で追加.

int PyType_Ready(PyTypeObject *type)

型オブジェクトの後始末処理 (finalize) を行います。この関数は全てのオブジェクトで初期化を完了するために呼び出されなくてはなりません。この関数は、基底クラス型から継承したスロットを型オブジェクトに追加する役割があります。成功した場合には 0 を返し、エラーの場合には -1 を返して例外情報を設定します。

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

None オブジェクト

None に対する PyTypeObject は、 Python/C API では直接公開されていないので注意してください。 None は単量子 (singleton) なので、オブジェクトのアイデンティティテスト (C では ==) を使うだけで十分だからです。同じ理由から、 PyNone_Check() 関数はありません。

PyObject* Py_None

Python における None オブジェクトで、値がないことを表します。このオブジェクトにはメソッドがありません。リファレンスカウントについては、このオブジェクトも他のオブジェクトと同様に扱う必要があります。

Py_RETURN_NONE

C 関数から Py_None を戻す操作を適切に行うためのマクロです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

(通常)整数型オブジェクト (plain integer object)

PyIntObject

この PyObject のサブタイプは Python の整数型オブジェクトを表現します。

PyTypeObject PyInt_Type

この PyTypeObject のインスタンスは Python の (長整数でない)整数型を表現します。これは int や types.IntType と同じオブジェクトです。

int PyInt_Check(PyObject *o)

o が PyInt_Type 型か PyInt_Type 型のサブタイプであるときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyInt_CheckExact(PyObject *o)

o が PyInt_Type 型で、かつ PyInt_Type 型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyInt_FromString(char *str, char **pend, int base)

Return value: New reference.

str の文字列値に基づいて、新たな PyIntObject または PyLongObject を返します。このとき base を基数として文字列を解釈します。 pend が NULL でなければ、 *pend は str 中で数が表現されている部分以後の先頭の文字のアドレスを指しています。 base が 0 ならば、 str の先頭の文字列に基づいて基数を決定します: もし str が '0x' または '0X' で始まっていれば、基数に 16 を使います; str が '0' で始まっていれば、基数に 8 を使います; その他の場合には基数に 10 を使います。 base が 0 でなければ、 base は 2 以上 36 以下の数でなければなりません。先頭に空白がある場合は無視されます。数字が全くない場合、 ValueError が送出されます。使用しているマシンの long int 型で表現し切れないくらい大きな数が文字列に入っており、オーバフロー警告が抑制されていれば、 PyLongObject を返します。オーバフロー警告が抑制されていなければ、 NULL を返します。

PyObject* PyInt_FromLong(long ival)

Return value: New reference.

ival の値を使って新たな整数オブジェクトを生成します。

現在の実装では、 -5 から 256 までの全ての整数に対する整数オブジェクトの配列を保持するようにしており、この範囲の数を生成すると、実際には既存のオブジェクトに対する参照が返るようになっています。従って、 1 の値を変えることすら可能です。変えてしまった場合の Python の挙動は未定義です :-)

PyObject* PyInt_FromSsize_t(Py_ssize_t ival)

Return value: New reference.

ival の値を使って新たな整数オブジェクトを生成します。値が LONG_MAX を超えている場合、長整数オブジェクトを返します。

バージョン 2.5 で追加.

PyObject* PyInt_FromSize_t(size_t ival)

ival の値を使って新たな整数オブジェクトを生成します。値が LONG_MAX を超えている場合、長整数オブジェクトを返します。

バージョン 2.5 で追加.

long PyInt_AsLong(PyObject *io)

オブジェクトがまだ PyIntObject でなければまず型キャストを試み、次にその値を返します。エラーが発生した場合、 -1 が返されます。その時呼び出し側は、 PyErr_Occurred() を使って、エラーが発生したのか、単に値が-1だったのかを判断するべきです。

long PyInt_AS_LONG(PyObject *io)

オブジェクト io の値を返します。エラーチェックを行いません。

unsigned long PyInt_AsUnsignedLongMask(PyObject *io)

オブジェクトがまだ PyIntObject または PyLongObject でなければまず型キャストを試み、次にその値を unsigned long 型で返します。この関数はオーバフローをチェックしません。

バージョン 2.3 で追加.

unsigned PY_LONG_LONG PyInt_AsUnsignedLongLongMask(PyObject *io)

オブジェクトがまだ PyIntObject または PyLongObject でなければまず型キャストを試み、次にその値を unsigned long long 型で返します。オーバフローをチェックしません。

バージョン 2.3 で追加.

Py_ssize_t PyInt_AsSsize_t(PyObject *io)

オブジェクトがまだ PyIntObject でなければまず型キャストを試み、次にその値を Py_ssize_t 型で返します。

バージョン 2.5 で追加.

long PyInt_GetMax()

システムの知識に基づく、扱える最大の整数値 (システムのヘッダファイルに定義されている LONG_MAX) を返します。

int PyInt_ClearFreeList()

整数の free list をクリアします。開放できなかった要素の数を返します。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

Bool 型オブジェクト

Python の Bool 型は整数のサブクラスとして実装されています。ブール型の値は、 Py_False と Py_True の 2 つしかありません。従って、通常の生成／削除関数はブール型にはあてはまりません。とはいえ、以下のマクロが利用できます。

int PyBool_Check(PyObject *o)

o が PyBool_Type の場合に真を返します。

バージョン 2.3 で追加.

PyObject* Py_False

Python における False オブジェクトです。このオブジェクトはメソッドを持ちません。参照カウントの点では、他のオブジェクトと同様に扱う必要があります。

PyObject* Py_True

Python における True オブジェクトです。このオブジェクトはメソッドを持ちません。参照カウントの点では、他のオブジェクトと同様に扱う必要があります。

Py_RETURN_FALSE

Py_False に適切な参照カウントのインクリメントを行って、関数から返すためのマクロです。

バージョン 2.4 で追加.

Py_RETURN_TRUE

Py_True に適切な参照カウントのインクリメントを行って、関数から返すためのマクロです。

バージョン 2.4 で追加.

int PyBool_FromLong(long v)

Return value: New reference.

v の値に応じて Py_True または Py_False への新しい参照を返します。

バージョン 2.3 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

長整数型オブジェクト (long integer object)

PyLongObject

この PyObject のサブタイプは長整数型を表現します。

PyTypeObject PyLong_Type

この PyTypeObject のインスタンスは Python 長整数型を表現します。これは long や types.LongType と同じオブジェクトです。

int PyLong_Check(PyObject *p)

引数が PyLongObject か PyLongObject のサブタイプのときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyLong_CheckExact(PyObject *p)

引数が PyLongObject 型で、かつ PyLongObject 型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyLong_FromLong(long v)

Return value: New reference.

v から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

PyObject* PyLong_FromUnsignedLong(unsigned long v)

Return value: New reference.

C の unsigned long 型から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

PyObject* PyLong_FromSsize_t(Py_ssize_t v)

C の Py_ssize_t 型から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

バージョン 2.6 で追加.

PyObject* PyLong_FromSize_t(size_t v)

C の size_t 型から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

バージョン 2.6 で追加.

PyObject* PyLong_FromSsize_t(Py_ssize_t v)

v から新しい PyLongObject オブジェクトを返します。失敗したら NULL を返します。

バージョン 2.6 で追加.

PyObject* PyLong_FromSize_t(size_t v)

v から新しい PyLongObject オブジェクトを返します。失敗したら NULL を返します。

バージョン 2.6 で追加.

PyObject* PyLong_FromLongLong(PY_LONG_LONG v)

Return value: New reference.

C の long long 型から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v)

Return value: New reference.

C の unsigned long long 型から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

PyObject* PyLong_FromDouble(double v)

Return value: New reference.

v の整数部から新たな PyLongObject オブジェクトを生成して返します。失敗のときには NULL を返します。

PyObject* PyLong_FromString(char *str, char **pend, int base)

Return value: New reference.

str の文字列値に基づいて、新たな PyLongObject を返します。このとき base を基数として文字列を解釈します。 pend が NULL でなければ、 *pend は str 中で数が表現されている部分以後の先頭の文字のアドレスを指しています。 base が 0 ならば、 str の先頭の文字列に基づいて基数を決定します: もし str が '0x' または '0X' で始まっていれば、基数に 16 を使います; str が '0' で始まっていれば、基数に 8 を使います; その他の場合には基数に 10 を使います。 base が 0 でなければ、 base は 2 以上 36 以下の数でなければなりません。先頭に空白がある場合は無視されます。数字が全くない場合、 ValueError が送出されます。

PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)

Return value: New reference.

Unicode の数字配列を Python の長整数型に変換します。最初のパラメタ u は、 Unicode 文字列の最初の文字を指し、 length には文字数を指定し、 base には変換時の基数を指定します。基数は範囲 [2, 36] になければなりません; 範囲外の基数を指定すると、 ValueError を送出します。

バージョン 1.6 で追加.

バージョン 2.5 で変更: この関数は以前は length の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyLong_FromVoidPtr(void *p)

Return value: New reference.

Python 整数型または長整数型をポインタ p から生成します。ポインタに入れる値は PyLong_AsVoidPtr() を使って得られるような値です。

バージョン 1.5.2 で追加.

バージョン 2.5 で変更: 整数値がLONG_MAXより大きい場合は、正の長整数を返します.

long PyLong_AsLong(PyObject *pylong)

pylong の指す長整数値を、 C の long 型表現で返します。 pylong が LONG_MAX よりも大きい場合、 OverflowError を送出し、 -1 を返します。

long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)

pylong の値を long で返す。 pylong が LONG_MAX より大きかったり LONG_MIN より小さい場合、 *overflow に 1 か -1 を設定して -1 を返します。それ以外の場合は *overflow に 0 を設定します。なにか例外が発生した場合は(TypeError や MemoryErrorなど)、 *overflow は 0 で戻り値が -1 になります。

バージョン 2.7 で追加.

PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject *pylong, int *overflow)

pylong の値を long long で返す。 pylong が PY_LLONG_MAX より大きかったり PY_LLONG_MIN より小さい場合、 *overflow に 1 か -1 を設定して -1 を返します。それ以外の場合は *overflow に 0 を設定します。なにか例外が発生した場合は(TypeError や MemoryErrorなど)、 *overflow は 0 で戻り値が -1 になります。

バージョン 2.7 で追加.

Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)

pylong の指す長整数値を、 C の Py_ssize_t 型表現で返します。 pylong が PY_SSIZE_T_MAX よりも大きい場合、 OverflowError を送出し、 -1 を返します。

バージョン 2.6 で追加.

unsigned long PyLong_AsUnsignedLong(PyObject *pylong)

pylong の指す長整数値を、 C の unsigned long 型表現で返します。 pylong が ULONG_MAX よりも大きい場合、 OverflowError を送出します。

Py_ssize_t PyLong_AsSsize_t(PyObject *pylong)

pylong の指す長整数値を、 C の Py_ssize_t 型表現で返します。 pylong が PY_SSIZE_T_MAX より大きい場合、 OverflowError を発生させます。

バージョン 2.6 で追加.

PY_LONG_LONG PyLong_AsLongLong(PyObject *pylong)

pylong の指す長整数値を、 C の long long 型表現で返します。 pylong が long long で表せない場合、 OverflowError を送出し -1 を返します。

バージョン 2.2 で追加.

unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *pylong)

pylong の指す値を、 C の unsigned long long 型表現で返します。 pylong が unsigned long long で表せない場合、 OverflowError を発生させて、 (unsigned long long)-1 を返します。

バージョン 2.2 で追加.

バージョン 2.7 で変更: 負の pylong が TypeError ではなく OverflowError を発生させるようになりました。

unsigned long PyLong_AsUnsignedLongMask(PyObject *io)

Python 長整数値を、オーバフローチェックを行わずに C の unsigned long 型表現で返します。

バージョン 2.3 で追加.

unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *io)

Python 長整数値を、オーバフローチェックを行わずに C の unsigned long long 型表現で返します。

バージョン 2.3 で追加.

double PyLong_AsDouble(PyObject *pylong)

pylong の指す値を、 C の double 型表現で返します。 pylong が double を使って近似表現できない場合、 OverflowError 例外を送出して -1.0 を返します。

void* PyLong_AsVoidPtr(PyObject *pylong)

Python の整数型か長整数型を指す pylong を、 C の void ポインタに変換します。 pylong を変換できなければ、 OverflowError を送出します。この関数は PyLong_FromVoidPtr() で値を生成するときに使うような void ポインタ型を生成できるだけです。

バージョン 1.5.2 で追加.

バージョン 2.5 で変更: 値が0..LONG_MAXの範囲の外だった場合、符号付き整数と符号無し整数の両方とも利用可能です.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

浮動小数点型オブジェクト (floating point object)

PyFloatObject

この PyObject のサブタイプは Python 浮動小数点型オブジェクトを表現します。

PyTypeObject PyFloat_Type

この PyTypeObject のインスタンスは Python 浮動小数点型を表現します。これは float や types.FloatType と同じオブジェクトです。

int PyFloat_Check(PyObject *p)

引数が PyFloatObject か PyFloatObject のサブタイプのときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyFloat_CheckExact(PyObject *p)

引数が PyFloatObject 型で、かつ PyFloatObject 型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyFloat_FromString(PyObject *str, char **pend)

Return value: New reference.

str の文字列値をもとに PyFloatObject オブジェクトを生成します。失敗すると NULL を返します。引数 pend は無視されます。この引数は後方互換性のためだけに残されています。

PyObject* PyFloat_FromDouble(double v)

Return value: New reference.

v から PyFloatObject オブジェクトを生成して返します。失敗すると NULL を返します。

double PyFloat_AsDouble(PyObject *pyfloat)

pyfloat の指す値を、 C の double 型表現で返します。

double PyFloat_AS_DOUBLE(PyObject *pyfloat)

pyfloat の指す値を、 C の double 型表現で返しますが、エラーチェックを行いません。

PyObject* PyFloat_GetInfo(void)

float の精度、最小値、最大値に関する情報を含む structseq インスタンスを返します。これは、 float.h ファイルの薄いラッパーです。

バージョン 2.6 で追加.

double PyFloat_GetMax()

float の表現できる最大限解値 DBL_MAX を C の double 型で返します。

バージョン 2.6 で追加.

double PyFloat_GetMin()

float の正規化された最小の正の値 DBL_MIN を C の double 型で返します。

バージョン 2.6 で追加.

int PyFloat_ClearFreeList()

float の free list をクリアします。開放できなかったアイテム数を返します。

バージョン 2.6 で追加.

void PyFloat_AsString(char *buf, PyFloatObject *v)

str() と同じルールで v を文字列に変換します。 buf の長さは 100 以上でなければなりません。

この関数は長さを知らないバッファに書きこむので安全ではありません。

バージョン 2.7 で撤廃: 代わりに func:PyObject_Str か PyOS_double_to_string() を利用してください。

void PyFloat_AsReprString(char *buf, PyFloatObject *v)

PyFloat_AsString とほとんど同じですが、 repr() とおなじルールを使います。 buf の長さは 100 以上でなければなりません。

この関数は長さを知らないバッファに書きこむので安全ではありません。

バージョン 2.7 で撤廃: 代わりに PyObject_Repr() か PyOS_double_to_string() を利用してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

浮動小数点オブジェクト (complex number object)

Python の複素数オブジェクトは、 C API 側から見ると二つの別個の型として実装されています: 一方は Python プログラムに対して公開されている Python のオブジェクトで、他方は実際の複素数値を表現する C の構造体です。 API では、これら双方を扱う関数を提供しています。

C 構造体としての複素数

複素数の C 構造体を引数として受理したり、戻り値として返したりする関数は、ポインタ渡しを行うのではなく 値渡し を行うので注意してください。これは API 全体を通して一貫しています。

Py_complex

Python 複素数オブジェクトの値の部分に対応する C の構造体です。複素数オブジェクトを扱うほとんどの関数は、この型の構造体を場合に応じて入力や出力として使います。構造体は以下のように定義されています:

typedef struct {
   double real;
   double imag;
} Py_complex;

Py_complex _Py_c_sum(Py_complex left, Py_complex right)

二つの複素数の和を C の Py_complex 型で返します。

Py_complex _Py_c_diff(Py_complex left, Py_complex right)

二つの複素数の差を C の Py_complex 型で返します。

Py_complex _Py_c_neg(Py_complex complex)

複素数 complex の符号反転 C の Py_complex 型で返します。

Py_complex _Py_c_prod(Py_complex left, Py_complex right)

二つの複素数の積を C の Py_complex 型で返します。

Py_complex _Py_c_quot(Py_complex dividend, Py_complex divisor)

二つの複素数の商を C の Py_complex 型で返します。

Py_complex _Py_c_pow(Py_complex num, Py_complex exp)

指数 exp の num 乗を C の Py_complex 型で返します。

Python オブジェクトとしての複素数型

PyComplexObject

この PyObject のサブタイプは Python の複素数オブジェクトを表現します。

PyTypeObject PyComplex_Type

この PyTypeObject のインスタンスは Python の複素数型を表現します。 Pythonの complex や types.ComplexType と同じオブジェクトです。

int PyComplex_Check(PyObject *p)

引数が PyComplexObject 型か PyComplexObject 型のサブタイプのときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyComplex_CheckExact(PyObject *p)

引数が PyComplexObject 型で、かつ PyComplexObject 型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyComplex_FromCComplex(Py_complex v)

Return value: New reference.

C の Py_complex 型から Python の複素数値を生成します。

PyObject* PyComplex_FromDoubles(double real, double imag)

Return value: New reference.

新たな PyComplexObject オブジェクトを real と imag から生成します。

double PyComplex_RealAsDouble(PyObject *op)

op の実数部分を C の double 型で返します。

double PyComplex_ImagAsDouble(PyObject *op)

op の虚数部分を C の double 型で返します。

Py_complex PyComplex_AsCComplex(PyObject *op)

複素数値 op から Py_complex 型を生成します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

bytearray オブジェクト

バージョン 2.6 で追加.

PyByteArrayObject

Python の bytearray オブジェクトを示す PyObject のサブタイプ

PyTypeObject PyByteArray_Type

この PyTypeObject のインスタンスは、 Python bytearray 型を示します。 Python レイヤでの bytearray と同じオブジェクトです。

型チェックマクロ

int PyByteArray_Check(PyObject *o)

o が bytearray かそのサブタイプのインスタンスだった場合に真を返します。

int PyByteArray_CheckExact(PyObject *o)

o が bytearray オブジェクトで、そのサブタイプのインスタンスでは無いときに、真を返します。

ダイレクト API 関数

PyObject* PyByteArray_FromObject(PyObject *o)

バッファプロトコルを実装している任意のオブジェクト o から、新しい bytearray オブジェクトを作成し返します。

PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)

string とその長さ len から新しい bytearray オブジェクトを返します。失敗した場合は NULL を返します。

PyObject* PyByteArray_Concat(PyObject *a, PyObject *b)

bytearray a と b を連結した結果を新しい bytearray として返します。

Py_ssize_t PyByteArray_Size(PyObject *bytearray)

NULL ポインタチェックの後に bytearray のサイズを返します。

char* PyByteArray_AsString(PyObject *bytearray)

NULL ポインタチェックの後に bytearray の内容を char 配列として返します。

int PyByteArray_Resize(PyObject *bytearray, Py_ssize_t len)

bytearray の内部バッファを len へリサイズします。

マクロ

以下のマクロは、ポインタのチェックをしないことにより安全性を犠牲にしてスピードを優先しています。

char* PyByteArray_AS_STRING(PyObject *bytearray)

PyByteArray_AsString() のマクロバージョン。

Py_ssize_t PyByteArray_GET_SIZE(PyObject *bytearray)

PyByteArray_Size() のマクロバージョン。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

文字列/バイトオブジェクト

以下の関数では、文字列が渡されるはずのパラメタに非文字列が渡された場合に TypeError を送出します。

ノート

これらの関数群は Python 3.x では PyBytes_* へリネームされます。移植を容易にするために、特に注釈されていない限り、 3.x で利用できる PyBytes 関数群は同等の PyString_* 関数へのエイリアスにされています。

PyStringObject

この PyObject のサブタイプは Python の文字列オブジェクトを表現します。

PyTypeObject PyString_Type

この PyTypeObject のインスタンスは Python の文字列型を表現します; このオブジェクトは Python レイヤにおける str や types.StringType と同じです。 .

int PyString_Check(PyObject *o)

o が文字列型か文字列型のサブタイプであるときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyString_CheckExact(PyObject *o)

o が文字列型で、かつ文字列型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyString_FromString(const char *v)

Return value: New reference.

v を値に持つ文字列オブジェクトを返します。失敗すると NULL を返します。パラメタ v は NULL であってはなりません; NULL かどうかはチェックしません。

PyObject* PyString_FromStringAndSize(const char *v, Py_ssize_t len)

Return value: New reference.

値が v で長さが len の新たな文字列オブジェクトを返します。失敗すると NULL を返します。 v が NULL の場合、文字列の中身は未初期化の状態になります。

バージョン 2.5 で変更: この関数は以前は len の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyString_FromFormat(const char *format, ...)

Return value: New reference.

C 関数 printf() 形式の format 文字列と可変個の引数をとり、書式化済みの文字列長を計算した上で、書式化を行った結果を値とする Python 文字列にして返します。可変個の引数部は C のデータ型でなくてはならず、かつ format 文字列内の書式指定文字 (format character) に一致する型でなくてはなりません。利用できる書式化文字は以下の通りです:

書式指定文字 | 型 | コメント
%% | n/a | 文字 % のリテラル。
%c | int | C の整数型で表現される単一の文字。
%d | int | C の printf("%d") と全く同じ。
%u | unsigned int | C の printf("%u") と全く同じ。
%ld | long | C の printf("%ld") と全く同じ。
%lu | unsigned long | C の printf("%lu") と全く同じ。
%lld | long long | C の printf("%lld") と全く同じ。
%llu | unsigned long long | C の printf("%llu") と全く同じ。
%zd | Py_ssize_t | C の printf("%zd") と全く同じ。
%zu | size_t | C の printf("%zu") と全く同じ。
%i | int | C の printf("%i") と全く同じ。
%x | int | C の printf("%x") と全く同じ。
%s | char* | null で終端された C の文字列。
%p | void* | C ポインタの 16 進表記。 printf("%p") とほとんど同じだが、プラットフォームにおける printf の定義に関わりなく先頭にリテラル 0x が付きます。

識別できない書式指定文字があった場合、残りの書式文字列はそのまま出力文字列にコピーされ、残りの引数は無視されます。

ノート

“%lld” と “%llu” 書式指定文字は HAVE_LONG_LONG が定義されている時だけ利用できます。

バージョン 2.7 で変更: “%lld” と “%llu” のサポートが追加されました。

PyObject* PyString_FromFormatV(const char *format, va_list vargs)

Return value: New reference.

PyString_FromFormat() と同じです。ただし、こちらの関数は二つしか引数をとりません。

Py_ssize_t PyString_Size(PyObject *string)

文字列オブジェクト string 内の文字列値の長さを返します。

バージョン 2.5 で変更: この関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyString_GET_SIZE(PyObject *string)

PyString_Size() をマクロで実装したもので、エラーチェックを行いません。

バージョン 2.5 で変更: この関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

char* PyString_AsString(PyObject *string)

string の中身を NUL 文字終端された表現で返します。ポインタは string オブジェクトの内部バッファを指し、バッファのコピーを指すわけではありません。 PyString_FromStringAndSize(NULL, size) を使って生成した文字列でない限り、バッファ内のデータはいかなる変更もしてはなりません。この文字列をデアロケートしてはなりません。 string が Unicode オブジェクトの場合、この関数は string のデフォルトエンコーディング版を計算し、デフォルトエンコーディング版に対して操作を行います。 string が文字列オブジェクトですらない場合、 PyString_AsString() は NULL を返して TypeError を送出します。

char* PyString_AS_STRING(PyObject *string)

PyString_AsString() をマクロで実装したもので、エラーチェックを行いません。文字列オブジェクトだけをサポートします; Unicode オブジェクトを渡してはなりません。

int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length)

obj の中身を NUL 文字終端された表現にして、出力用の変数 buffer と length を使って返します。

この関数は文字列オブジェクトと Unicode オブジェクトのどちらも入力として受理します。 Unicode オブジェクトの場合、オブジェクトをデフォルトエンコーディングでエンコードしたバージョン (default encoded version) を返します。 length が NULL の場合、値を返させるバッファには NUL 文字を入れてはなりません; NUL 文字が入っている場合、関数は -1 を返し、 TypeError を送出します。

buffer は obj の内部文字列バッファを参照し、バッファのコピーを参照するわけではありません。 PyString_FromStringAndSize(NULL, size) を使って生成した文字列でない限り、バッファ内のデータはいかなる変更もしてはなりません。この文字列をデアロケートしてはなりません。

string が Unicode オブジェクトの場合、この関数は string のデフォルトエンコーディング版を計算し、デフォルトエンコーディング版に対して操作を行います。 string が文字列オブジェクトですらない場合、 PyString_AsStringAndSize() は -1 を返して TypeError を送出します。

バージョン 2.5 で変更: この関数は以前は length の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void PyString_Concat(PyObject **string, PyObject *newpart)

新しい文字列オブジェクトを *string に作成し、 newpart の内容を string に追加します; 呼び出し側は新たな参照を所有することになります。 string の以前の値に対する参照は盗み取られます。新たな文字列を生成できなければ、 string に対する古い参照は無視され、 *string の値は NULL に設定されます; その際、適切な例外情報が設定されます。

void PyString_ConcatAndDel(PyObject **string, PyObject *newpart)

新しい文字列オブジェクトを *string に作成し、 newpart の内容を string に追加します。こちらのバージョンの関数は newpart への参照をデクリメントします。

int _PyString_Resize(PyObject **string, Py_ssize_t newsize)

“変更不能” である文字列オブジェクトをサイズ変更する手段です。新たな文字列オブジェクトを作成するときにのみ使用してください; 文字列がすでにコードの他の部分で使われているかもしれない場合には、この関数を使ってはなりません。入力する文字列オブジェクトの参照カウントが 1 でない場合、この関数を呼び出すとエラーになります。左側値には、既存の文字列オブジェクトのアドレスを渡し (このアドレスには書き込み操作が起きるかもしれません)、新たなサイズを指定します。成功した場合、 *string はサイズ変更された文字列オブジェクトを保持し、 0 が返されます; *string の値は、入力したときの値と異なっているかもしれません。文字列の再アロケーションに失敗した場合、 *string に入っていた元の文字列オブジェクトを解放し、 *string を NULL にセットし、メモリ例外をセットし、 -1 を返します。

バージョン 2.5 で変更: この関数は以前は newsize の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyString_Format(PyObject *format, PyObject *args)

Return value: New reference.

新たな文字列オブジェクトを format と args から生成します。 format % args と似た働きです。引数 args はタプルでなければなりません。

void PyString_InternInPlace(PyObject **string)

引数 *string をインプレースで隔離 (intern) します。引数は Python 文字列オブジェクトを指すポインタへのアドレスでなくてはなりません。 *string と等しい、すでに隔離済みの文字列が存在する場合、そのオブジェクトを *string に設定します (かつ、元の文字列オブジェクトの参照カウントをデクリメントし、すでに隔離済みの文字列オブジェクトの参照カウントをインクリメントします)。 (補足: 参照カウントについては沢山説明して来ましtが、この関数は参照カウント中立 (reference-count-neutral) と考えてください; この関数では、関数の呼び出し後にオブジェクトに対して参照の所有権を持てるのは、関数を呼び出す前にすでに所有権を持っていた場合に限ります。)

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

PyObject* PyString_InternFromString(const char *v)

Return value: New reference.

PyString_FromString() と PyString_InternInPlace() を組み合わせたもので、隔離済みの新たな文字列オブジェクトを返すか、同じ値を持つすでに隔離済みの文字列オブジェクトに対する新たな (“所有権を得た”) 参照を返します。

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

PyObject* PyString_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)

Return value: New reference.

size からなるエンコード済みのバッファ s を encoding の名前で登録されている codec に渡してデコードし、オブジェクトを生成します。 encoding および errors は組み込み関数 unicode() に与える同名のパラメタと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors)

Return value: New reference.

文字列オブジェクトを encoding の名前で登録されている codec に渡してデコードし、Python オブジェクトを返します。 encoding および errors は文字列型の encode() メソッドに与える同名のパラメタと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

PyObject* PyString_Encode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)

Return value: New reference.

size で指定されたサイズの char バッファを encoding の名前で登録されている codec に渡してエンコードし、 Python オブジェクトを返します。 encoding および errors は文字列型の encode() メソッドに与える同名のパラメタと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors)

Return value: New reference.

エンコード名 encoding で登録された codec を使って文字列オブジェクトをエンコードし、その結果を Python オブジェクトとして返します。 encoding および errors は文字列型の encode() メソッドに与える同名のパラメタと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

ノート

この関数は 3.x では利用できず、 PyBytes エイリアスもありません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

Unicode オブジェクトと codec

Unicode オブジェクト

Unicode 型

以下は Python の Unicode 実装に用いられている基本 Unicode オブジェクト型です:

Py_UNICODE

この型は Unicode 序数 (Unicode ordinal) を保持するための基礎単位として、 Python が内部的に使います。 Python のデフォルトのビルドでは、 Py_UNICODE として 16-bit 型を利用し、 Unicode の値を内部では UCS-2 で保持します。 UCS4 版の Python をビルドすることもできます。(最近の多くの Linux ディストリビューションでは UCS4 版の Python がついてきます) UCS4 版ビルドでは Py_UNICODE に 32-bit 型を利用し、内部では Unicode データを UCS4 で保持します。 wchar_t が利用できて、 Python の Unicode に関するビルドオプションと一致するときは、 Py_UNICODE は wchar_t を typedef でエイリアスされ、ネイティブプラットフォームに対する互換性を高めます。それ以外のすべてのプラットフォームでは、 Py_UNICODE は unsigned short (UCS2) か unsigned long (UCS4) の typedef によるエイリアスになります。

UCS2 と UCS4 の Python ビルドの間にはバイナリ互換性がないことに注意してください。拡張やインタフェースを書くときには、このことを覚えておいてください。

PyUnicodeObject

この PyObject のサブタイプは Unicode オブジェクトを表します。

PyTypeObject PyUnicode_Type

この PyTypeObject のインスタンスは Python の Unicode 型を表します。 Python レイヤにおける unicode や types.UnicodeType と同じオブジェクトです。

以下の API は実際には C マクロで、Unicode オブジェクト内部の読み出し専用データに対するチェックやアクセスを高速に行います:

int PyUnicode_Check(PyObject *o)

o が Unicode 文字列型か Unicode 文字列型のサブタイプであるときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyUnicode_CheckExact(PyObject *o)

o が Unicode 文字列型で、かつ Unicode 文字列型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

Py_ssize_t PyUnicode_GET_SIZE(PyObject *o)

オブジェクトのサイズを返します。 o は PyUnicodeObject でなければなりません (チェックはしません)。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o)

オブジェクトの内部バッファのサイズをバイト数で返します。 o は PyUnicodeObject でなければなりません (チェックはしません)。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o)

オブジェクト内部の Py_UNICODE バッファへのポインタを返します。 o は PyUnicodeObject でなければなりません (チェックはしません)。

const char* PyUnicode_AS_DATA(PyObject *o)

オブジェクト内部バッファへのポインタを返します。 o は PyUnicodeObject でなければなりません (チェックはしません)。

int PyUnicode_ClearFreeList()

free list をクリアします。開放できなかった要素数を返します。

バージョン 2.6 で追加.

Unicode 文字プロパティ

Unicode は数多くの異なる文字プロパティ (character property) を提供しています。よく使われる文字プロパティは、以下のマクロで利用できます。これらのマクロは Python の設定に応じて、各々 C の関数に対応付けられています。

int Py_UNICODE_ISSPACE(Py_UNICODE ch)

ch が空白文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISLOWER(Py_UNICODE ch)

ch が小文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISUPPER(Py_UNICODE ch)

ch が大文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISTITLE(Py_UNICODE ch)

ch がタイトルケース文字 (titlecase character) かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch)

ch が改行文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISDECIMAL(Py_UNICODE ch)

ch が 10 進の数字文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISDIGIT(Py_UNICODE ch)

ch が 2 進の数字文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISNUMERIC(Py_UNICODE ch)

ch が数字文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISALPHA(Py_UNICODE ch)

ch がアルファベット文字かどうかに応じて 1 または 0 を返します。

int Py_UNICODE_ISALNUM(Py_UNICODE ch)

ch が英数文字かどうかに応じて 1 または 0 を返します。

以下の API は、高速に直接文字変換を行うために使われます:

Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch)

ch を小文字に変換したものを返します。

Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch)

ch を大文字に変換したものを返します。

Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch)

ch をタイトルケース文字に変換したものを返します。

int Py_UNICODE_TODECIMAL(Py_UNICODE ch)

ch を 10 進の正の整数に変換したものを返します。不可能ならば -1 を返します。このマクロは例外を送出しません。

int Py_UNICODE_TODIGIT(Py_UNICODE ch)

ch を一桁の 2 進整数に変換したものを返します。不可能ならば -1 を返します。このマクロは例外を送出しません。

double Py_UNICODE_TONUMERIC(Py_UNICODE ch)

ch を double に変換したものを返します。不可能ならば -1.0 を返します。このマクロは例外を送出しません。

Plain Py_UNICODE

Unicode オブジェクトを生成したり、Unicode のシーケンスとしての基本的なプロパティにアクセスしたりするには、以下の API を使ってください:

PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファ u から Unicode オブジェクトを生成します。 u を NULL にしてもよく、その場合オブジェクトの内容は未定義です。バッファに必要な情報を埋めるのはユーザの責任です。バッファの内容は新たなオブジェクトにコピーされます。バッファが NULL でない場合、戻り値は共有されたオブジェクトになることがあります。従って、この関数が返す Unicode オブジェクトを変更してよいのは u が NULL のときだけです。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode)

Unicode オブジェクトの内部バッファ Py_UNICODE に対する読み出し専用のポインタを返します。 unicode が Unicode オブジェクトでなければ NULL を返します。

PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)

char 型バッファ u から Unicode オブジェクトを生成します。 u の内容は UTF-8 エンコードされているものとします。 u を NULL にしてもよく、その場合オブジェクトの内容は未定義で、バッファに必要な情報を埋めるのはユーザの責任です。バッファの内容は新たなオブジェクトにコピーされます。バッファが NULL でない場合、戻り値は共有されたオブジェクトになることがあります。従って、この関数が返す Unicode オブジェクトを変更してよいのは u が NULL のときだけです。

バージョン 2.6 で追加.

PyObject *PyUnicode_FromString(const char *u)

UTF-8 エンコードされたNUL文字終端のchar 型バッファ u から Unicode オブジェクトを生成します。

バージョン 2.6 で追加.

PyObject* PyUnicode_FromFormat(const char *format, ...)

printf() スタイルの format 文字列と可変長引数を受け取り、結果の unicode 文字の長さを計算し、フォーマットされた文字列を含む unicode オブジェクトを返します。可変長引数は C の型を持っていて、 format 文字列で指定された書式指定文字に完全に従う必要があります。以下の書式指定文字が利用できます:

書式指定文字 | 型 | 備考
%% | n/a | リテラルの % 文字
%c | int | C言語のintで表現される1文字
%d | int | printf("%d") と全く同じ
%u | unsigned int | printf("%u") と全く同じ
%ld | long | printf("%ld") と全く同じ
%lu | unsigned long | printf("%lu") と全く同じ
%zd | Py_ssize_t | printf("%zd") と全く同じ
%zu | size_t | printf("%zu") と全く同じ
%i | int | printf("%i") と全く同じ
%x | int | printf("%x") と全く同じ
%s | char* | NUL 文字で終わる文字列
%p | void* | C ポインタの16進数表現。 printf("%p") とほぼ同じですが、プラットフォームの printf に依存せず 0x リテラルで始まることが保証されます
%U | PyObject* | unicode オブジェクト
%V | PyObject*, char * | unicode オブジェクト(NULL でも良い)と、 2つめの引数として NUL 終端の C 文字列 (2つめの引数は1つめの引数が NULL だった時にのみ利用されます)
%S | PyObject* | PyObject_Unicode() の戻り値
%R | PyObject* | PyObject_Repr() の戻り値

解釈されない書式指定文字があると、それ以降のフォーマット文字列はそのまま出力の文字列にコピーされ、以降の引数は無視されます。

バージョン 2.6 で追加.

PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs)

2引数であることを除いて PyUnicode_FromFormat() と同じです。

バージョン 2.6 で追加.

Py_ssize_t PyUnicode_GetSize(PyObject *unicode)

Unicode オブジェクトの長さを返します。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors)

Return value: New reference.

あるエンコード方式でエンコードされたオブジェクト obj を Unicode オブジェクトに型強制して、参照カウントをインクリメントして返します。

型強制は以下のようにして行われます:

文字列やその他の char バッファ互換オブジェクトの場合、オブジェクトは encoding に従ってデコードされます。このとき error で定義されたエラー処理を用います。これら二つの引数は NULL にでき、その場合デフォルト値が使われます (詳細は次の節を参照してください)

その他のUnicodeオブジェクトを含むオブジェクトは TypeError 例外を引き起こします。

この API は、エラーが生じたときには NULL を返します。呼び出し側は返されたオブジェクトに対し参照カウンタを 1 つ減らす (decref) する責任があります。

PyObject* PyUnicode_FromObject(PyObject *obj)

Return value: New reference.

PyUnicode_FromEncodedObject(obj, NULL, "strict") を行うショートカットで、インタプリタは Unicode への型強制が必要な際に常にこの関数を使います。

プラットフォームで wchar_t がサポートされていて、かつ wchar.h が提供されている場合、Python は以下の関数を使って wchar_t に対して直接アクセスすることができます。このアクセスは、Python 自体の Py_UNICODE 型がシステムの wchar_t と同一の場合に最適化されます。

wchar_t サポート

wchar_t をサポートするプラットフォームでの wchar_t サポート:

PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)

Return value: New reference.

size の wchar_t バッファ w から Unicode オブジェクトを生成します。失敗すると NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size)

Unicode オブジェクトの内容を wchar_t バッファ w にコピーします。最大で size 個の wchar_t 文字を (末尾の 0-終端文字を除いて) コピーします。コピーした wchar_t 文字の個数を返します。エラーの時には -1 を返します。 wchar_t 文字列は 0-終端されている場合も、されていない場合もあります。関数の呼び出し側の責任で、アプリケーションの必要に応じて wchar_t 文字列を 0-終端してください。

バージョン 2.5 で変更: この関数は以前は int を返し、 size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

組み込み codec (built-in codec)

Python には、処理速度を高めるために C で書かれた codec が揃えてあります。これら全ての codec は以下の関数を介して直接利用できます。

以下の API の多くが、 encoding と errors という二つの引数をとります。これらのパラメータは、組み込みの Unicode オブジェクトコンストラクタである unicode() における同名のパラメータと同じ意味を持ちます。

encoding を NULL にすると、デフォルトエンコーディングである ASCII を使います。ファイルシステムに関する関数の呼び出しでは、ファイル名に対するエンコーディングとして Py_FileSystemDefaultEncoding を使わねばなりません。この変数は読み出し専用の変数として扱わねばなりません: この変数は、あるシステムによっては静的な文字列に対するポインタであったり、また別のシステムでは、(アプリケーションが setlocale を読んだときなどに) 変わったりもします。

errors で指定するエラー処理もまた、 NULL を指定できます。 NULL を指定すると、codec で定義されているデフォルト処理の使用を意味します。全ての組み込み codec で、デフォルトのエラー処理は “strict” (ValueError を送出する) になっています。

個々の codec は全て同様のインタフェースを使っています。個別の codec の説明では、説明を簡単にするために以下の汎用のインタフェースとの違いだけを説明しています。

汎用 codec

以下は汎用 codec の API です:

PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, const char *encoding, const char *errors)

Return value: New reference.

何らかのエンコード方式でエンコードされた、 size バイトの文字列 s をデコードして Unicode オブジェクトを生成します。 encoding と errors は、組み込み関数 unicode() の同名のパラメータと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors)

Return value: New reference.

size で指定されたサイズの Py_UNICODE バッファ s をエンコードした Python 文字列オブジェクトを返します。 encoding および errors は Unicode 型の encode() メソッドに与える同名のパラメータと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors)

Return value: New reference.

Unicode オブジェクトをエンコードし、その結果を Python 文字列オブジェクトとして返します。 encoding および errors は Unicode 型の encode() メソッドに与える同名のパラメータと同じ意味を持ちます。使用する codec の検索は、 Python の codec レジストリを使って行います。codec が例外を送出した場合には NULL を返します。

UTF-8 Codecs

以下は UTF-8 codec の APIです:

PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

UTF-8 でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)

Return value: New reference.

consumed が NULL の場合、 PyUnicode_DecodeUTF8() と同じように動作します。 consumed が NULL でない場合、 PyUnicode_DecodeUTF8Stateful() は末尾の不完全な UTF-8 バイト列をエラーとみなしません。これらのバイト列はデコードされず、デコードされたバイト数を consumed に返します。

バージョン 2.4 で追加.

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファ s を UTF-8 でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsUTF8String(PyObject *unicode)

Return value: New reference.

UTF-8 で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

UTF-32 Codecs

以下は UTF-32 codec API です。

PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, const char *errors, int *byteorder)

UTF-32 でエンコードされたバッファ文字列から size バイトをデコードし、 Unicodeオブジェクトとして返します。 errors は (NULL でないなら) エラーハンドラを指定します。デフォルトは “strict” です。

byteorder が NULL でない時、デコーダは与えられたバイトオーダーでデコードを開始します。

*byteorder == -1: little endian
*byteorder == 0:  native order
*byteorder == 1:  big endian

*byteorder が 0 で入力データの最初の 4 バイトがバイトオーダーマーク (BOM) だった場合、デコーダーは BOM のバイトオーダーに切り替え、 BOM は結果の unicode 文字列には含まれません。 *byteorder が -1 か 1 だった場合、すべての BOM は出力へコピーされます。

デコードが完了した後、入力データの終端に来た時点でのバイトオーダーを *byteorder にセットします。

narrow build の場合、BMP 外のコードポイントはサロゲートペアとしてデコードされます。

byteorder が NULL のとき、 codec は native order モードで開始します。

codec が例外を発生させたときは NULL を返します。

バージョン 2.6 で追加.

PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)

consumed が NULL のとき、 PyUnicode_DecodeUTF32() と同じように振る舞います。 consumed が NULL でないとき、 PyUnicode_DecodeUTF32Stateful() は末尾の不完全な (4 で割り切れない長さのバイト列などの) UTF-32 バイト列をエラーとして扱いません。末尾の不完全なバイト列はデコードされず、デコードされたバイト数が consumed に格納されます。

バージョン 2.6 で追加.

PyObject* PyUnicode_EncodeUTF32(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)

s の Unicode データを UTF-32 にエンコードし、その値を Python の bytes オブジェクトに格納して返します。出力は以下のバイトオーダーで従って書かれます。

byteorder == -1: little endian
byteorder == 0:  native byte order (BOM マークあり)
byteorder == 1:  big endian

byteorder が 0 のとき、出力文字列は常に Unicode BOM マーク (U+FEFF) で始まります。それ以外の2つのモードでは、先頭に BOM マークは出力されません。

Py_UNICODE_WIDE が定義されていない場合は、サロゲートペアを 1 つのコードポイントとして出力します。

codec が例外を発生させた場合、 NULL を返します。

バージョン 2.6 で追加.

PyObject* PyUnicode_AsUTF32String(PyObject *unicode)

ネイティブバイトオーダーで UTF-32 エンコーディングされた Python 文字列を返します。文字列は常に BOM マークで始まります。エラーハンドラは “strict” です。 codec が例外を発生させたときは NULL を返します。

バージョン 2.6 で追加.

UTF-16 Codecs

以下は UTF-16 codec の APIです:

PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors, int *byteorder)

Return value: New reference.

UTF-16 でエンコードされたバッファ s から size バイトだけデコードして、結果を Unicode オブジェクトで返します。 errors は (NULL でない場合) エラー処理方法を定義します。デフォルト値は “strict” です。

byteorder が NULL でない場合、デコード機構は以下のように指定されたバイト整列 (byte order) に従ってデコードを開始します:

*byteorder == -1: little endian
*byteorder == 0:  native order
*byteorder == 1:  bit endian

*byteorder が 0 で、入力データの先頭2バイトがバイトオーダーマーク (BOM) だった場合、デコーダは BOM が示すバイトオーダーに切り替え、そのBOMを結果の Unicode 文字列にコピーしません。 *byteorder が -1 か 1 だった場合、すべてのBOMは出力へコピーされます。 (出力では \ufeff か \ufffe のどちらかになるでしょう)

デコードを完了した後、入力データの終端に来た時点でのバイトオーダーを *byteorder にセットします。

byteorder が NULL の場合、 codec はネイティブバイト整列のモードで開始します。

codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed)

Return value: New reference.

consumed が NULL の場合、 PyUnicode_DecodeUTF16() と同じように動作します。 consumed が NULL でない場合、 PyUnicode_DecodeUTF16Stateful() は末尾の不完全な UTF-16 バイト列 (奇数長のバイト列や分割されたサロゲートペア) をエラーとみなしません。これらのバイト列はデコードされず、デコードされたバイト数を consumed に返します。

バージョン 2.4 で追加.

バージョン 2.5 で変更: この関数は以前は size の型に int を利用し、 consumed の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder)

Return value: New reference.

s 中の Unicode データを UTF-16 でエンコードした結果が入っている Python 文字列オブジェクトを返します。出力は以下のバイトオーダーに従って書き出されます:

byteorder == -1: little endian
byteorder == 0:  native byte order (BOM マークあり)
byteorder == 1:  big endian

byteorder が 0 の場合、出力結果となる文字列は常に Unicode BOM マーク (U+FEFF) で始まります。それ以外のモードでは、 BOM マークを頭につけません。

Py_UNICODE_WIDE が定義されている場合、単一の Py_UNICODE 値はサロゲートペアとして表現されることがあります。 Py_UNICODE_WIDE が定義されていなければ、各 Py_UNICODE 値は UCS-2 文字として表現されます。

codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsUTF16String(PyObject *unicode)

Return value: New reference.

ネイティブバイトオーダの UTF-16 でエンコードされた Python 文字列を返します。文字列は常に BOM マークから始まります。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

UTF-7 Codecs

以下は UTF-7 codec の API です。

PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors)

UTF-7 でエンコードされた size バイトの文字列 s をデコードして Unicode オブジェクトを作成します。 codec が例外を発生させたときは NULL を返します。

PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed)

consumed が NULL のとき、 PyUnicode_DecodeUTF7() と同じように動作します。 consumed が NULL でないとき、末尾の不完全な UTF-7 base-64 部分をエラーとしません。不完全な部分のバイト列はデコードせずに、デコードしたバイト数を consumed に格納します。

PyObject* PyUnicode_EncodeUTF7(const Py_UNICODE *s, Py_ssize_t size, int base64SetO, int base64WhiteSpace, const char *errors)

与えられたサイズの Py_UNICODE バッファを UTF-7 でエンコードして、 Python の bytes オブジェクトとして返します。 codec が例外を発生させたときは NULL を返します。

base64SetO がゼロでないとき、 “Set O” 文字 (他の場合には何も特別な意味を持たない句読点) を base-64 エンコードします。 base64WhiteSpace がゼロでないとき、空白文字を base-64 エンコードします。 Python の “utf-7” codec では、両方ともゼロに設定されています。

Unicode-Escape Codecs

以下は “Unicode Escape” codec の API です:

PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

Unicode-Escape でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを Unicode-Escape でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode)

Return value: New reference.

Unicode-Escape で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

Raw-Unicode-Escape Codecs

以下は “Raw Unicode Escape” codec の APIです:

PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

Raw-Unicode-Escape でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを Raw-Unicode-Escape でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)

Return value: New reference.

Raw-Unicode-Escape で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

Latin-1 Codecs

以下は Latin-1 codec の APIです: Latin-1 は、 Unicode 序数の最初の 256 個に対応し、エンコード時にはこの 256 個だけを受理します。

PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

Latin-1 でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを Latin-1 でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsLatin1String(PyObject *unicode)

Return value: New reference.

Latin-1 で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

ASCII Codecs

以下は ASCII codec の APIです。 7 ビットの ASCII データだけを受理します。その他のコードはエラーになります。

PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

ASCII でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを ASCII でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsASCIIString(PyObject *unicode)

Return value: New reference.

ASCII で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

Character Map Codecs

この codec は、多くの様々な codec を実装する際に使われるという点で特殊な codec です (実際、 encodings パッケージに入っている標準 codecs のほとんどは、この codec を使っています)。この codec は、文字のエンコードやデコードにマップ型 (mapping) を使います。

デコード用のマップ型は、文字列型の字列一組みを、 Unicode 型の字列一組、整数 (Unicode 序数として解釈されます) または None (“定義されていない対応付け (undefined mapping)” を意味し、エラーを引き起こします) のいずれかに対応付けなければなりません。

エンコード用のマップ型は、Unicode 型の字列一組みを、 string 型の字列一組、整数 (Latin-1 序数として解釈されます) または None (“定義されていない対応付け (undefined mapping)” を意味し、エラーを引き起こします) のいずれかに対応付けなければなりません。

マップ型オブジェクトは、 __getitem__() マップ型インタフェースをサポートしなければなりません。

ある文字の検索が LookupError によって失敗すると、その文字はそのままコピーされます。すなわち、その文字の序数値がそれぞれ Unicode または Latin-1 として解釈されます。このため、codec を実現するマップ型に入れる必要がある対応付け関係は、ある文字を別のコード点に対応付けるものだけです。

以下は mapping codec の APIです:

PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors)

Return value: New reference.

エンコードされた size バイトの文字列 s から mapping に指定されたオブジェクトを使って Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。もし、 mapping が NULL だった場合、latin-1 でデコードされます。それ以外の場合では、 mapping は byte に対する辞書マップ (訳注: s に含まれる文字の unsigned な値を int 型でキーとして、値として変換対象の Unicode 文字を表す Unicode 文字列になっているような辞書) か、ルックアップテーブルとして扱われる Unicode 文字列です。

文字列 (訳注: mapping が Unicode 文字列として渡された場合) の長さより大きい byte 値や、(訳注: mappingにしたがって変換した結果が) U+FFFE “characters” になる Byte値は、”定義されていない対応付け (undefined mapping)” として扱われます。

バージョン 2.4 で変更: mapping引数としてunicodeが使えるようになりました.

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを mapping に指定されたオブジェクトを使ってエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping)

Return value: New reference.

Unicode オブジェクトを mapping に指定されたオブジェクトを使ってエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

以下の codec API は Unicode から Unicode への対応付けを行う特殊なものです。

PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *table, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE バッファを、文字変換マップ table を適用して変換し、変換結果を Unicode オブジェクトで返します。 codec が例外を発行した場合には NULL を返します。

対応付けを行う table は、 Unicode 序数を表す整数を Unicode 序数を表す整数または None に対応付けます。 (None の場合にはその文字を削除します)

対応付けテーブルが提供する必要があるメソッドは __getitem__() インタフェースだけです; 従って、辞書やシーケンス型を使ってもうまく動作します。対応付けを行っていない (LookupError を起こすような) 文字序数に対しては、変換は行わず、そのままコピーします。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Windows 用の MBCS codec

以下は MBCS codec の API です。この codec は現在のところ、 Windows 上だけで利用でき、変換の実装には Win32 MBCS 変換機構 (Win32 MBCS converter) を使っています。 MBCS (または DBCS) はエンコード方式の種類 (class) を表す言葉で、単一のエンコード方式を表すわけでなないので注意してください。利用されるエンコード方式 (target encoding) は、 codec を動作させているマシン上のユーザ設定で定義されています。

PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors)

Return value: New reference.

MBCS でエンコードされた size バイトの文字列 s から Unicode オブジェクトを生成します。codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed)

consumed が NULL のとき、 PyUnicode_DecodeMBCS() と同じ動作をします。 consumed が NULL でないとき、 PyUnicode_DecodeMBCSStateful() は文字列の最後にあるマルチバイト文字の前半バイトをデコードせず、 consumed にデコードしたバイト数を格納します。

バージョン 2.5 で追加.

PyObject* PyUnicode_EncodeMBCS(const Py_UNICODE *s, Py_ssize_t size, const char *errors)

Return value: New reference.

size で指定された長さを持つ Py_UNICODE 型バッファを MBCS でエンコードし、 Python 文字列オブジェクトにして返します。 codec が例外を送出した場合には NULL を返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_AsMBCSString(PyObject *unicode)

Return value: New reference.

MBCS で Unicode オブジェクトをエンコードし、結果を Python 文字列オブジェクトとして返します。エラー処理は “strict” です。 codec が例外を送出した場合には NULL を返します。

Methods & Slots

メソッドおよびスロット関数 (slot function)

以下の API は Unicode オブジェクトおよび文字列を入力に取り (説明では、どちらも文字列と表記しています)、場合に応じて Unicode オブジェクトか整数を返す機能を持っています。

これらの関数は全て、例外が発生した場合には NULL または -1 を返します。

PyObject* PyUnicode_Concat(PyObject *left, PyObject *right)

Return value: New reference.

二つの文字列を結合して、新たな Unicode 文字列を生成します。

PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)

Return value: New reference.

Unicode 文字列のリストを分割して、 Unicode 文字列からなるリストを返します。 sep が NULL の場合、全ての空白文字を使って分割を行います。それ以外の場合、指定された文字を使って分割を行います。最大で maxsplit 個までの分割を行います。 maxsplit が負ならば分割数に制限を設けません。分割結果のリスト内には分割文字は含みません。

バージョン 2.5 で変更: この関数は以前は maxsplit の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_Splitlines(PyObject *s, int keepend)

Return value: New reference.

Unicode 文字列を改行文字で区切り、Unicode 文字列からなるリストを返します。CRLF は一個の改行文字とみなします。 keepend が 0 の場合、分割結果のリスト内に改行文字を含めません。

PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors)

Return value: New reference.

文字列に文字変換マップ table を適用して変換し、変換結果を Unicode オブジェクトで返します。

対応付けを行う table は、 Unicode 序数を表す整数を Unicode 序数を表す整数または None に対応付けます。 (None の場合にはその文字を削除します)

対応付けテーブルが提供する必要があるメソッドは __getitem__() インタフェースだけです; 従って、辞書やシーケンス型を使ってもうまく動作します。対応付けを行っていない (LookupError を起こすような) 文字序数に対しては、変換は行わず、そのままコピーします。

errors は codecs で通常使われるのと同じ意味を持ちます。 errors は NULL にしてもよく、デフォルトエラー処理の使用を意味します。

PyObject* PyUnicode_Join(PyObject *separator, PyObject *seq)

Return value: New reference.

指定した separator で文字列からなるシーケンスを連結 (join) し、連結結果を Unicode 文字列で返します。

int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)

Return value: New reference.

substr が str[start:end] の末端 (direction == -1 は先頭一致、 direction == 1 は末尾一致) でとマッチする場合に 1 を返し、それ以外の場合には 0 を返します。エラーが発生した時は -1 を返します。

バージョン 2.5 で変更: この関数は以前は start, end の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction)

str[start:end] 中に substr が最初に出現する場所を返します。このとき指定された検索方向 direction (direction == 1 は順方向検索、 direction == -1 は逆方向検索) で検索します。戻り値は最初にマッチが見つかった場所のインデクスです; 戻り値 -1 はマッチが見つからなかったことを表し、 -2 はエラーが発生して例外情報が設定されていることを表します。

バージョン 2.5 で変更: この関数は以前は start, end の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end)

str[start:end] に substr が重複することなく出現する回数を返します。エラーが発生した場合には -1 を返します。

バージョン 2.5 で変更: この関数は以前は start, end と戻り値の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount)

Return value: New reference.

str 中に出現する substr を最大で maxcount 個 replstr に置換し、置換結果を Unicode オブジェクトにして返します。 maxcount == -1 にすると、全ての substr を置換します。

バージョン 2.5 で変更: この関数は以前は maxcount の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyUnicode_Compare(PyObject *left, PyObject *right)

二つの文字列を比較して、左引数が右引数より小さい場合、左右引数が等価の場合、左引数が右引数より大きい場合に対して、それぞれ -1, 0, 1 を返します。

int PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)

二つのunicode文字列を比較して、下のうちの一つを返します:

NULL を、例外が発生したときに返します。

Py_True もしくは Py_False を、正しく比較できた時に返します。

Py_NotImplemented を、 left と right のどちらかに対する PyUnicode_FromObject() が失敗したときに返します。(原文: in case the type combination is unknown)

Py_EQ と Py_NE の比較は、引数からUnicodeへの変換が UnicodeDecodeError で失敗した時に、 UnicodeWarning を発生する可能性があることに注意してください。

op に入れられる値は、 Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, and Py_LE のどれかです。

PyObject* PyUnicode_Format(PyObject *format, PyObject *args)

Return value: New reference.

新たな文字列オブジェクトを format および args から生成して返します; このメソッドは format % args のようなものです。引数 args はタプルでなくてはなりません。

int PyUnicode_Contains(PyObject *container, PyObject *element)

element が container 内にあるか調べ、その結果に応じて真または偽を返します。

element は単要素の Unicode 文字に型強制できなければなりません。エラーが生じた場合には -1 を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

buffer オブジェクトと memoryview オブジェクト

C で実装された Python オブジェクトは、”バッファインタフェース (buffer interface)” と呼ばれる一連の関数を公開していることがあります。これらの関数は、あるオブジェクトのデータを生 (raw) のバイト列形式で公開するために使います。このオブジェクトの使い手は、バッファインタフェースを使うことで、オブジェクトをあらかじめコピーしておく必要なしに、オブジェクトのデータに直接アクセスできます。

バッファインタフェースをサポートするオブジェクトの例として、文字列型とアレイ (array) 型の二つがあります。文字列オブジェクトは、その内容をバッファインタフェースのバイト単位形式で公開しています。アレイもその内容を公開していますが、注意する必要があるのはアレイの要素は複数バイトの値になりうる、ということです。

バッファインタフェースの使い手の一例として、ファイルオブジェクトの write() メソッドがあります。バッファインタフェースを介してバイト列を公開しているオブジェクトは全て、ファイルへの書き出しができます。オブジェクトのバッファインタフェースを操作し、対象となるオブジェクトからデータを返させる PyArg_ParseTuple() には数多くのデータ書式化コードがあります。

バージョン 1.6 から、Python は Python レベルのバッファオブジェクトと、 C 言語レベルのバッファ API を提供しており、任意のビルトイン型やユーザー定義型はその文字列表現を公開することができます。しかし、両方共、幾つかの欠点のために廃止予定扱いされていて、 Python 3.0 では公式に削除され、新しい C 言語レベルのバッファ API と新しい Python レベルの memoryview という名前のオブジェクトに置き換えられています。

新しいバッファ API は Python 2.6 に逆移植されており、 memoryviews オブジェクトは Python 2.7 に逆移植されています。古いバージョンとの互換性が必要なければ、古いAPIの代わりにこれらを使うことをおすすめします。

新スタイル Py_buffer 構造体

Py_buffer

void *buf

オブジェクトのメモリの開始位置へのポインタ

Py_ssize_t len

メモリのトータルサイズ [byte]

int readonly

バッファが読み込み専用かどうかを示す

const char *format

バッファを通してアクセスできる要素の形式を指定する、 struct モジュールスタイル文法の、 NULL 終端文字列。このポインタの値が NULL なら、 "B" (符号無しバイト) として扱われます。

int ndim

メモリが多次元配列を表している時の次元数。 0 の場合、 strides と suboffsets は NULL でなければなりません。

Py_ssize_t *shape

メモリが多次元配列を表しているとき、その形を示す長さ ndim の Py_ssize_t の配列。 ((*shape)[0] * ... * (*shape)[ndims-1])*itemsize は len と等しくなければならないことに気をつけてください。

Py_ssize_t *strides

各次元で次の要素を得るためにスキップするバイト数を示す、長さ ndim の Py_ssize_t の配列。

Py_ssize_t *suboffsets

長さ ndim の Py_ssize_t の配列。 suboffset の各数値が 0 以上であるとき、その次元に格納されているのはポインタで、 suboffset の値はそのポインタの参照を解決するときに何バイトのオフセットを足すかを示しています。 suboffset に負の数が格納されているときは、参照解決が不要であること (連続したメモリブロック内に直接配置されていること)を意味しています。

次の例は、 strides も suboffsets も非NULL の時に、N次元配列からN次元インデックスで示される要素のポインタを返す関数です。

void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
    Py_ssize_t *suboffsets, Py_ssize_t *indices) {
    char *pointer = (char*)buf;
    int i;
    for (i = 0; i < ndim; i++) {
        pointer += strides[i] * indices[i];
        if (suboffsets[i] >=0 ) {
            pointer = *((char**)pointer) + suboffsets[i];
        }
    }
    return (void*)pointer;
 }

Py_ssize_t itemsize

これは共有メモリ上の各要素のbyte単位のサイズを格納する変数です。これは PyBuffer_SizeFromFormat() を使って計算できる値なので技術的には不要なのですが、バッファを提供する側はフォーマット文字列を解析しなくてもこの情報を知っているでしょうし、バッファを受け取る側にとっては正しく解釈するのに必要な情報です。なので、要素サイズを格納するほうが便利ですし高速です。

void *internal

バッファを提供する側のオブジェクトが内部的に利用するための変数です。例えば、提供側はこの変数に整数型をキャストして、 shape, strides, suboffsets といった配列をバッファを開放するときに同時に開放するべきかどうかを管理するフラグに使うことができるでしょう。バッファを受け取る側は、この値を変更してはなりません。

バッファ関連関数

int PyObject_CheckBuffer(PyObject *obj)

obj がバッファインタフェースをサポートしている場合に 1 を、それ以外の場合に 0 を返します。

int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)

obj を Py_buffer view へエクスポートします。これらの引数は NULL であってはなりません。 flag 引数は呼び出し側がどんなバッファを扱おうとしているのか、バッファ提供側がどんなバッファを返すことが許されているのかを示す、ビットフィールドです。バッファインタフェースは複雑なメモリ共有を可能にしていますが、呼び出し元はすべての複雑なバッファを扱えるとは限らず、バッファ提供側がシンプルなビューを提供できるならそれを利用したいとかもしれません。

バッファ提供側はすべての方法でメモリを共有できるとは限らず、呼び出し側に何かが不可能であることを伝えるためにエラーを発生させる必要があるかもしれません。その場合のエラーは、もしその問題を実際に引き起こしているのが別のエラーだったとしても、 BufferError でなければなりません。バッファ提供側は flag の情報を使って Py_buffer 構造体のどのフィールドへの非デフォルト値の設定を省略したり、要求されたシンプルな view を提供できない場合はエラーを発生させたりすることができます。

成功したら 0 が、エラー時には -1 が返されます。

次のテーブルは、 flags 引数が取りうる値です。

Flag | 説明
PyBUF_SIMPLE | これはデフォルトの flag の状態です。結果のバッファは書き込み可能かもしれませんし、不可能かもしれません。データのフォーマットは unsigned byte とします。これは “スタンドアロン” のフラグ定数です。他の定数と ‘|’ を取る必要はありません。提供側はこのような連続したバイト列のバッファを提供できない場合に、エラーを発生させるかもしれません。
PyBUF_WRITABLE | 結果のバッファは書込み可能でなければなりません。書き込み不可能な場合はエラーを発生させます。
PyBUF_STRIDES | この値は PyBUF_ND を含みます。バッファは strides 情報を提供しなければなりません。 (言い換えると、 strides は NULL であってはいけません。) このフラグは、呼び出し元が、要素間に隙間のある不連続な配列を扱えるときに使われます。 strides を扱うことは、自動的に shape も扱えることを要求されます。提供側は stride 形式のバッファを提供できないとき(例えば、 suboffset が必要な場合)はエラーを発生させます。
PyBUF_ND | バッファは shape 情報を提供しなければなりません。メモリは C スタイルの並び (最後の次元が一番高速) だと仮定されます。提供側はこの種類の連続バッファを提供できない場合はエラーを発生させます。このフラグが指定されていな場合は shape は NULL になります。
PyBUF_C_CONTIGUOUS PyBUF_F_CONTIGUOUS PyBUF_ANY_CONTIGUOUS | これらのフラグは、返されるバッファの並びを指定します。それぞれ、C並び(最後の次元が一番高速)、Fortran並び(最初の次元が一番高速), そのどちらでも、を意味します。これらのフラグは PyBUF_STRIDES を含んでおり、 strides 情報が正しく格納されていることを保証します。
PyBUF_INDIRECT | このフラグは、返されるバッファが suboffsets 情報を含んでいることを示します。(suboffsets が必要無いときは NULL でもかまいません。) このフラグは、バッファ利用側が suboffsets を使って参照されている間接配列を扱えるときに利用されます。このフラグは PyBUF_STRIDES を含みます。
PyBUF_FORMAT | 返されるバッファは正しい format 情報を持っていなければなりません。このフラグは、バッファ利用側が実際に格納されているデータの ‘種類’ をチェックするときに利用します。バッファ提供側は、要求された場合は常にこの情報を提供できるべきです。 format が明示的に要求されていない場合は format は NULL ('B', unsigned byte を意味する)であるべきです。
PyBUF_STRIDED | (PyBUF_STRIDES | PyBUF_WRITABLE) と同じ
PyBUF_STRIDED_RO | (PyBUF_STRIDES) と同じ
PyBUF_RECORDS | (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE) と同じ
PyBUF_RECORDS_RO | (PyBUF_STRIDES | PyBUF_FORMAT) と同じ
PyBUF_FULL | (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE) と同じ
PyBUF_FULL_RO | (PyBUF_INDIRECT | PyBUF_FORMAT) と同じ
PyBUF_CONTIG | (PyBUF_ND | PyBUF_WRITABLE) と同じ
PyBUF_CONTIG_RO | (PyBUF_ND) と同じ

void PyBuffer_Release(Py_buffer *view)

view バッファを開放します。バッファが利用されなくなったときに、そのメモリを開放できるようにこの関数を呼び出すべきです。

Py_ssize_t PyBuffer_SizeFromFormat(const char *)

itemsize の値を format から計算して返します。

int PyBuffer_IsContiguous(Py_buffer *view, char fortran)

view で定義されているメモリが、 C スタイル (fortran == 'C') のときか、 Fortran スタイル (fortran == 'F') のときか、そのいずれか (fortran == 'A') であれば 1 を返します。それ以外の場合は 0 を返します。

void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran)

strides 配列を、 itemsize の大きさの要素がバイト単位で連続した、 shape の形をした (fortran が 'C' なら C-style, 'F' なら Fortran-style の) 多次元配列として埋める。

int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags)

バッファ提供側が与えられた長さの “unsigned bytes” の連続した1つのメモリブロックしか提供できないものとして、 view バッファ情報構造体を正しく埋める。成功したら 0 を、エラー時には (例外を発生させつつ) -1 を返す。

memoryview オブジェクト

バージョン 2.7 で追加.

memoryview オブジェクトは、新しい、他のオブジェクトと同じように扱える Python オブジェクトの形をした C言語レベルのバッファへのインタフェースです。

PyObject *PyMemoryView_FromObject(PyObject *obj)

新しいバッファインタフェースを定義しているオブジェクトから memoryview オブジェクトを作ります。

PyObject *PyMemoryView_FromBuffer(Py_buffer *view)

buffer-info 構造体 view をラップする memoryview オブジェクトを作ります。作られた memoryview オブジェクトはバッファを所有することになるので、 view を開放してはいけません。このバッファは memoryview オブジェクトが削除されるときに解放されます。

PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)

buffer インタフェースを定義しているオブジェクトから (‘C’ か ‘F’ortran の order で) 連続したメモリチャンクへの memoryview オブジェクトを作ります。メモリが連続している場合、 memoryview オブジェクトは元のメモリを参照します。それ以外の場合、メモリはコピーされて、 memoryview オブジェクトは新しい bytes オブジェクトを参照します。

int PyMemoryView_Check(PyObject *obj)

obj が memoryview オブジェクトの場合に真を返します。現在のところ、 memoryview のサブクラスの作成は許可されていません。

Py_buffer *PyMemoryView_GET_BUFFER(PyObject *obj)

与えられたオブジェクトにラップされた buffer-info 構造体へのポインタを返します。オブジェクトは memoryview インスタンスで なければなりません 。このマクロはオブジェクトの型をチェックしないので、呼び出し側で保証しなければクラッシュする可能性があります。

旧スタイルバッファオブジェクト

古いバッファインタフェースに関するより詳しい情報は、 “バッファオブジェクト構造体” 節 ( バッファオブジェクト構造体 (buffer object structure) 節) の、 PyBufferProcs の説明のところにあります。

“バッファオブジェクト” はヘッダファイル bufferobject.h の中で定義されています (このファイルは Python.h がインクルードしています)。バッファオブジェクトは、 Python プログラミングのレベルからは文字列オブジェクトと非常によく似ているように見えます: スライス、インデックス指定、結合、その他標準の文字列操作をサポートしています。しかし、バッファオブジェクトのデータは二つのデータソース: 何らかのメモリブロックか、バッファインタフェースを公開している別のオブジェクト、のいずれかに由来しています。

バッファオブジェクトは、他のオブジェクトのバッファインタフェースから Python プログラマにデータを公開する方法として便利です。バッファオブジェクトはゼロコピーなスライス機構 (zero-copy slicing mechanism) としても使われます。ブロックメモリを参照するというバッファオブジェクトの機能を使うことで、任意のデータをきわめて簡単に Python プログラマに公開できます。メモリブロックは巨大でもかまいませんし、C 拡張モジュール内の定数配列でもかまいません。また、オペレーティングシステムライブラリ側に渡す前の、操作用の生のブロックメモリでもかまいませんし、構造化されたデータをネイティブのメモリ配置形式でやりとりするためにも使えます。

PyBufferObject

この PyObject のサブタイプはバッファオブジェクトを表現します。

PyTypeObject PyBuffer_Type

Python バッファ型 (buffer type) を表現する PyTypeObject です; Python レイヤにおける buffer や types.BufferType と同じオブジェクトです。

int Py_END_OF_BUFFER

この定数は、 PyBuffer_FromObject() や PyBuffer_FromReadWriteObject() に size パラメタとして渡します。このパラメタを渡すと、 PyBufferObject は指定された offset からバッファの終わりまでを base オブジェクトとして参照します。このパラメタを使うことで、関数の呼び出し側が base オブジェクトのサイズを調べる必要がなくなります。

int PyBuffer_Check(PyObject *p)

引数が PyBuffer_Type 型のときに真を返します。

PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)

Return value: New reference.

新たな読み出し専用バッファオブジェクトを返します。 base が読み出し専用バッファに必要なバッファプロトコルをサポートしていない場合や、厳密に一つのバッファセグメントを提供していない場合には TypeError を送出し、 offset がゼロ以下の場合には ValueError を送出します。バッファオブジェクトは base オブジェクトに対する参照を保持し、バッファオブジェクトの内容は base オブジェクトの offset から size バイトのバッファインタフェースへの参照になります。 size が Py_END_OF_BUFFER の場合、新たに作成するバッファオブジェクトの内容は base から公開されているバッファの末尾までにわたります。

バージョン 2.5 で変更: この関数は以前は offset, size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)

Return value: New reference.

新たな書き込み可能バッファオブジェクトを返します。パラメタおよび例外は PyBuffer_FromObject() と同じです。 base オブジェクトが書き込み可能バッファに必要なバッファプロトコルを公開していない場合、 TypeError を送出します。

バージョン 2.5 で変更: この関数は以前は offset, size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)

Return value: New reference.

メモリ上の指定された場所から指定されたサイズのデータを読み出せる、新たな読み出し専用バッファオブジェクトを返します。この関数が返すバッファオブジェクトが存続する間、 ptr で与えられたメモリバッファがデアロケートされないようにするのは呼び出し側の責任です。 size がゼロ以下の場合には ValueError を送出します。 size には Py_END_OF_BUFFER を指定してはいけません ; 指定すると、 ValueError を送出します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)

Return value: New reference.

PyBuffer_FromMemory() に似ていますが、書き込み可能なバッファを返します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyBuffer_New(Py_ssize_t size)

Return value: New reference.

size バイトのメモリバッファを独自に維持する新たな書き込み可能バッファオブジェクトを返します。 size がゼロまたは正の値でない場合、 ValueError を送出します。( PyObject_AsWriteBuffer() が返すような) メモリバッファは特に整列されていないので注意して下さい。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

タプルオブジェクト (tuple object)

PyTupleObject

この PyObject のサブタイプは Python のタプルオブジェクトを表現します。

PyTypeObject PyTuple_Type

この PyTypeObject のインスタンスは Python のタプル型を表現します; Python レイヤにおける tuple や types.TupleType と同じオブジェクトです。

int PyTuple_Check(PyObject *p)

p がタプルオブジェクトか、タプル型のサブタイプのインスタンスである場合に真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyTuple_CheckExact(PyObject *p)

p がタプルオブジェクトで、かつタプル型のサブタイプのインスタンスでない場合に真を返します。

バージョン 2.2 で追加.

PyObject* PyTuple_New(Py_ssize_t len)

Return value: New reference.

サイズが len の新たなタプルオブジェクトを返します。失敗すると NULL を返します。

バージョン 2.5 で変更: この関数は以前は len の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyTuple_Pack(Py_ssize_t n, ...)

Return value: New reference.

サイズが n の新たなタプルオブジェクトを返します。失敗すると NULL を返します。タプルの値は後続の n 個の Python オブジェクトを指す C 引数になります。 PyTuple_Pack(2, a, b) は Py_BuildValue("(OO)", a, b) と同じです。

バージョン 2.4 で追加.

バージョン 2.5 で変更: この関数は以前は n の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyTuple_Size(PyObject *p)

タプルオブジェクトへのポインタを引数にとり、そのタプルのサイズを返します。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyTuple_GET_SIZE(PyObject *p)

タプル p のサイズを返しますが、 p は非 NULL でなくてはならず、タプルオブジェクトを指していなければなりません; この関数はエラーチェックを行いません。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)

Return value: Borrowed reference.

p の指すタプルオブジェクト内の、位置 pos にあるオブジェクトを返します。 pos が範囲を超えている場合、 NULL を返して IndexError 例外をセットします。

バージョン 2.5 で変更: この関数は以前は pos の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos)

Return value: Borrowed reference.

PyTuple_GetItem() に似ていますが、引数に対するエラーチェックを行いません。

バージョン 2.5 で変更: この関数は以前は pos の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)

Return value: New reference.

p の指すタプルオブジェクト内の、位置 low から high までのスライスを取り出して、タプルオブジェクトとして返します。

バージョン 2.5 で変更: この関数は以前は low, high の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)

p の指すタプルオブジェクト内の位置 pos に、オブジェクト o への参照を挿入します。成功した場合には 0 を返します。

ノート

この関数は o への参照を “盗み取り” ます。

バージョン 2.5 で変更: この関数は以前は pos の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)

PyTuple_SetItem() に似ていますが、エラーチェックを行わず、新たなタプルに値を入れるとき 以外には使ってはなりません 。

ノート

この関数は o への参照を “盗み取り” ます。

バージョン 2.5 で変更: この関数は以前は pos の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize)

タプルをリサイズする際に使えます。 newsize はタプルの新たな長さです。タプルは変更不能なオブジェクト ということになっているので、この関数はこのオブジェクトに対してただ一つしか参照がない時以外には使ってはなりません。タプルがコード中の他の部分ですでに参照されている場合には、この関数を 使ってはなりません 。タプルは常に指定サイズの末尾まで伸縮します。成功した場合には 0 を返します。クライアントコードは、 *p の値が呼び出し前と同じになると期待してはなりません。 *p が置き換えられた場合、オリジナルの *p は破壊されます。失敗すると -1 を返し、 *p を NULL に設定して、 MemoryError または SystemError を送出します。

バージョン 2.2 で変更: 使われていなかった三つ目のパラメタ、 last_is_sticky を削除しました.

バージョン 2.5 で変更: この関数は以前は newsize の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyTuple_ClearFreeList()

free list をクリアします。開放したアイテム数を返します。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

List Objects

PyListObject

この PyObject のサブタイプは Python のリストオブジェクトを表現します。

PyTypeObject PyList_Type

この PyTypeObject のインスタンスは Python のタプル型を表現します。これは Python レイヤにおける list と同じオブジェクトです。

int PyList_Check(PyObject *p)

引数が PyListObject である場合に真を返します。

PyObject* PyList_New(Py_ssize_t len)

Return value: New reference.

サイズが len 新たなリストオブジェクトを返します。失敗すると NULL を返します。

ノート

len が0より大きいとき、返されるリストオブジェクトの要素には NULL がセットされています。なので、 PyList_SetItem() で本当にオブジェクトをセットするまでは、Pythonコードにこのオブジェクトを渡したり、 PySequence_SetItem() のような抽象APIを利用してはいけません。

バージョン 2.5 で変更: この関数は以前は len の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyList_Size(PyObject *list)

リストオブジェクト list の長さを返します; リストオブジェクトにおける len(list) と同じです。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PyList_GET_SIZE(PyObject *list)

マクロ形式でできた PyList_Size() で、エラーチェックをしません。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)

Return value: Borrowed reference.

list の指すリストオブジェクト内の、位置 index にあるオブジェクトを返します。位置は正である必要があり、リスト終端からのインデックスはサポートされていません。 index が範囲を超えている場合、 NULL を返して IndexError 例外をセットします。

バージョン 2.5 で変更: この関数は以前は index の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)

Return value: Borrowed reference.

マクロ形式でできた PyList_GetItem() で、エラーチェックをしません。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)

リストオブジェクト内の位置 index に、オブジェクト item を挿入します。成功した場合には 0 を返し、失敗すると -1 を返します。

ノート

この関数は item への参照を “盗み取り” ます。また、変更先のインデクスにすでに別の要素が入っている場合、その要素に対する参照を放棄します。

バージョン 2.5 で変更: この関数は以前は index の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o)

PyList_SetItem() をマクロによる実装で、エラーチェックを行いません。このマクロは、新たなリストのまだ要素を入れたことのない位置に要素を入れるときにのみ使います。

ノート

このマクロは item への参照を “盗み取り” ます。また、 PyList_SetItem() と違って、要素の置き換えが生じても置き換えられるオブジェクトへの参照を放棄 しません ; その結果、 list 中の位置 i で参照されていたオブジェクトがメモリリークを引き起こします。

バージョン 2.5 で変更: この関数は以前は i の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item)

要素 item をインデックス index の前に挿入します。成功すると 0 を返します。失敗すると -1 を返し、例外をセットします。 list.insert(index, item) に類似した機能です。

バージョン 2.5 で変更: この関数は以前は index の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyList_Append(PyObject *list, PyObject *item)

オブジェクト item を list の末尾に追加します。成功すると 0 を返します; 失敗すると -1 を返し、例外をセットします。 list.append(item) に類似した機能です。

PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high)

Return value: New reference.

list 内の、 low から high の 間の オブジェクトからなるリストを返します。失敗すると NULL を返し、例外をセットします。 list[low:high] に類似した機能です。ただし、 Python のスライスにある負のインデックスはサポートされていません。

バージョン 2.5 で変更: この関数は以前は low, high の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist)

list 内の、 low から high の間のオブジェクトを、 itemlist の内容にします。 list[low:high] = itemlist と類似の機能です。 itemlist は NULL でもよく、空リストの代入 (指定スライスの削除) になります。成功した場合には 0 を、失敗した場合には -1 を返します。 Python のスライスにある負のインデックスはサポートされていません。

バージョン 2.5 で変更: この関数は以前は low, high の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyList_Sort(PyObject *list)

list の内容をインプレースでソートします。成功した場合には 0 を、失敗した場合には -1 を返します。 list.sort() と同じです。

int PyList_Reverse(PyObject *list)

list の要素をインプレースで反転します。成功した場合には 0 を、失敗した場合には -1 を返します。 list.reverse() と同じです。

PyObject* PyList_AsTuple(PyObject *list)

Return value: New reference.

list の内容が入った新たなタプルオブジェクトを返します; tuple(list) と同じです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

辞書オブジェクト (dictionary object)

PyDictObject

この PyObject のサブタイプは Python の辞書オブジェクトを表現します。

PyTypeObject PyDict_Type

この PyTypeObject のインスタンスは Python の辞書を表現します。このオブジェクトは、Python プログラムには dict および types.DictType として公開されています。

int PyDict_Check(PyObject *p)

引数が PyDictObject のときに真を返します。

int PyDict_CheckExact(PyObject *p)

p が辞書型オブジェクトであり、かつ辞書型のサブクラスのインスタンスでない場合に真を返します。

バージョン 2.4 で追加.

PyObject* PyDict_New()

Return value: New reference.

p が辞書型オブジェクトで、かつ辞書型のサブタイプのインスタンスでない場合に真を返します。

PyObject* PyDictProxy_New(PyObject *dict)

Return value: New reference.

あるマップ型オブジェクトに対して、読み出し専用に制限されたプロキシオブジェクト (proxy object) を返します。通常、この関数は動的でないクラス型 (non-dynamic class type) のクラス辞書を変更させないためにプロキシを作成するために使われます。

バージョン 2.2 で追加.

void PyDict_Clear(PyObject *p)

現在辞書に入っている全てのキーと値のペアを除去して空にします。

int PyDict_Contains(PyObject *p, PyObject *key)

辞書 p に key が入っているか判定します。 p の要素が key に一致した場合は 1 を返し、それ以外の場合には 0 を返します。エラーの場合 -1 を返します。この関数は Python の式 key in p と等価です。

バージョン 2.4 で追加.

PyObject* PyDict_Copy(PyObject *p)

Return value: New reference.

p と同じキーと値のペアが入った新たな辞書を返します。

バージョン 1.6 で追加.

int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val)

辞書 p に、 key をキーとして値 value を挿入します。 key はハッシュ可能(hashable)でなければなりません; ハッシュ可能でない場合、 TypeError を送出します。成功した場合には 0 を、失敗した場合には -1 を返します。

int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val)

辞書 p に、 key をキーとして値 value を挿入します。 key は char* 型でなければなりません。キーオブジェクトは PyString_FromString(key) で生成されます。成功した場合には 0 を、失敗した場合には -1 を返します。

int PyDict_DelItem(PyObject *p, PyObject *key)

辞書 p から key をキーとするエントリを除去します。 key はハッシュ可能でなければなりません; ハッシュ可能でない場合、 TypeError を送出します。成功した場合には 0 を、失敗した場合には -1 を返します。

int PyDict_DelItemString(PyObject *p, char *key)

辞書 p から文字列 key をキーとするエントリを除去します。成功した場合には 0 を、失敗した場合には -1 を返します。

PyObject* PyDict_GetItem(PyObject *p, PyObject *key)

Return value: Borrowed reference.

辞書 p 内で key をキーとするオブジェクトを返します。キー key が存在しない場合には NULL を返しますが、例外をセットしません 。

PyObject* PyDict_GetItemString(PyObject *p, const char *key)

Return value: Borrowed reference.

PyDict_GetItem() と同じですが、 key は PyObject* ではなく char* で指定します。

PyObject* PyDict_Items(PyObject *p)

Return value: New reference.

辞書オブジェクトのメソッド item() のように、辞書内の全ての要素対が入った PyListObject を返します。 (items() については Python ライブラリリファレンス (XXX reference: ../lib/lib.html) を参照してください。)

PyObject* PyDict_Keys(PyObject *p)

Return value: New reference.

辞書オブジェクトのメソッド keys() のように、辞書内の全てのキーが入った PyListObject を返します。 (keys() については Python ライブラリリファレンス (XXX reference: ../lib/lib.html) を参照してください。)

PyObject* PyDict_Values(PyObject *p)

Return value: New reference.

辞書オブジェクトのメソッド values() のように、辞書内の全ての値が入った PyListObject を返します。 (values() については Python ライブラリリファレンス (XXX reference: ../lib/lib.html) を参照してください。)

Py_ssize_t PyDict_Size(PyObject *p)

辞書内の要素の数を返します。辞書に対して len(p) を実行するのと同じです。

バージョン 2.5 で変更: この関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)

辞書 p 内の全てのキー/値のペアにわたる反復処理を行います。 ppos が参照している Py_ssize_t 型は、この関数で反復処理を開始する際に、最初に関数を呼び出すよりも前に 0 に初期化しておかなければなりません; この関数は辞書内の各ペアを取り上げるごとに真を返し、全てのペアを取り上げたことが分かると偽を返します。パラメタ pkey および pvalue には、それぞれ辞書の各々のキーと値を指すポインタか、または NULL が入ります。この関数から返される参照はすべて借りた参照になります。反復処理中に ppos を変更してはなりません。この値は内部的な辞書構造体のオフセットを表現しており、構造体はスパースなので、オフセットの値に一貫性がないためです。

以下に例を示します:

PyObject *key, *value;
Py_ssize_t pos = 0;

while (PyDict_Next(self->dict, &pos, &key, &value)) {
    /* 取り出した値で何らかの処理を行う... */
    ...
}

反復処理中に辞書 p を変更してはなりません。 (Python 2.1 からは) 辞書を反復処理する際に、キーに対応する値を変更しても大丈夫になりましたが、キーの集合を変更しないことが前提です。以下に例を示します:

PyObject *key, *value;
Py_ssize_t pos = 0;

while (PyDict_Next(self->dict, &pos, &key, &value)) {
    int i = PyInt_AS_LONG(value) + 1;
    PyObject *o = PyInt_FromLong(i);
    if (o == NULL)
        return -1;
    if (PyDict_SetItem(self->dict, key, o) < 0) {
        Py_DECREF(o);
        return -1;
    }
    Py_DECREF(o);
}

バージョン 2.5 で変更: この関数は以前は ppos の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PyDict_Merge(PyObject *a, PyObject *b, int override)

マップ型オブジェクト b の全ての要素にわたって、反復的にキー/値のペアを辞書 a に追加します。 b は辞書か、 PyMapping_Keys() または PyObject_GetItem() をサポートする何らかのオブジェクトにできます。 override が真ならば、 a のキーと一致するキーが b にある際に、既存のペアを置き換えます。それ以外の場合は、 b のキーに一致するキーが a にないときのみ追加を行います。成功した場合には 0 を返し、例外が送出された場合には -1 を返します。

バージョン 2.2 で追加.

int PyDict_Update(PyObject *a, PyObject *b)

C で表せば PyDict_Merge(a, b, 1) と同じ、 Python で表せば a.update(b) と同じです。成功した場合には 0 を返し、例外が送出された場合には -1 を返します。

バージョン 2.2 で追加.

int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override)

seq2 内のキー/値ペアを使って、辞書 a の内容を更新したり統合したりします。 seq2 は、キー/値のペアとみなせる長さ 2 の反復可能オブジェクト(iterable object) を生成する反復可能オブジェクトでなければなりません。重複するキーが存在する場合、 override が真ならば先に出現したキーを使い、そうでない場合は後に出現したキーを使います。成功した場合には 0 を返し、例外が送出された場合には -1 を返します。

(戻り値以外は) 等価な Python コードを書くと、以下のようになります:

def PyDict_MergeFromSeq2(a, seq2, override):
    for key, value in seq2:
        if override or key not in a:
            a[key] = value

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

クラスとインスタンスオブジェクト

ここで説明されているクラスオブジェクトは旧スタイルクラスのもので、 Python 3 では削除されることに注意してください。新スタイルクラス(type)を拡張モジュールで作成する場合は、 type オブジェクトを扱うべきです。 (型オブジェクト (type object) を参照)

PyClassObject

ビルトインクラスを表すためのオブジェクトの構造体

PyObject* PyClass_Type

クラスオブジェクトのための type オブジェクト。 Python レイヤーの、 types.ClassType と同じオブジェクト。

int PyClass_Check(PyObject *o)

o が、標準のクラスオブジェクトから派生した type のインスタンスだった場合を含めて、クラスオブジェクトだった場合に真を返します。それ以外の場合は偽を返します。

int PyClass_IsSubclass(PyObject *klass, PyObject *base)

klass が base のサブクラスだった場合に真を返します。それ以外の場合は偽を返します。

インスタンスオブジェクト固有の関数はきわめてわずかです。

PyTypeObject PyInstance_Type

クラスインスタンスの型オブジェクトです。

int PyInstance_Check(PyObject *obj)

obj がインスタンスの場合に真を返します。

PyObject* PyInstance_New(PyObject *class, PyObject *arg, PyObject *kw)

Return value: New reference.

特定クラスの新たなインスタンスを生成します。パラメタ arg および kw はそれぞれオブジェクトのコンストラクタに渡す実引数およびキーワードパラメタとして使われます。

PyObject* PyInstance_NewRaw(PyObject *class, PyObject *dict)

Return value: New reference.

特定クラスの新たなインスタンスを、コンストラクタを呼ばずに生成します。 class は新たに作成するオブジェクトのクラスです。 dict パラメタはオブジェクトの __dict__ に使われます; dict が NULL なら、インスタンス用に新たな辞書が作成されます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

関数オブジェクト (Function Objects)

Pythonの関数にはいくつかの種類があります。

PyFunctionObject

関数に使われるCの構造体

PyTypeObject PyFunction_Type

PyTypeObject 型のインスタンスで、 Python の関数型を表します。これは Python プログラムに types.FunctionType として公開されます。

int PyFunction_Check(PyObject *o)

o が関数オブジェクト (PyFunction_Type を持っている) なら true を返します。引数は NULL であってはいけません。

PyObject* PyFunction_New(PyObject *code, PyObject *globals)

Return value: New reference.

コードオブジェクト code に関連付けられた新しい関数オブジェクトを返します。 globals はこの関数からアクセスできるグローバル変数の辞書でなければなりません。

関数のドキュメント文字列、名前および __module__ はコードオブジェクトから取得されます。引数のデフォルト値やクロージャは NULL にセットされます。

PyObject* PyFunction_GetCode(PyObject *op)

Return value: Borrowed reference.

関数オブジェクト op に関連付けられたコードオブジェクトを返します。

PyObject* PyFunction_GetGlobals(PyObject *op)

Return value: Borrowed reference.

関数オブジェクト op に関連付けられたglobals辞書を返します。

PyObject* PyFunction_GetModule(PyObject *op)

Return value: Borrowed reference.

関数オブジェクト op の __module__ 属性を返します。　これは普通はモジュール名の文字列が入っていますが、Python コードから他のオブジェクトをセットされることもあります。

PyObject* PyFunction_GetDefaults(PyObject *op)

Return value: Borrowed reference.

関数オブジェクト op の引数のデフォルト値を返します。引数のタプルか NULL になります。

int PyFunction_SetDefaults(PyObject *op, PyObject *defaults)

関数オブジェクト op の引数のデフォルト値を設定します。 defaults は Py_None かタプルでなければいけません。

失敗した時は、 SystemError を発生し、 -1 を返します。

PyObject* PyFunction_GetClosure(PyObject *op)

Return value: Borrowed reference.

関数オブジェクト op に設定されたクロージャを返します。 NULL か cell オブジェクトのタプルです。

int PyFunction_SetClosure(PyObject *op, PyObject *closure)

関数オブジェクト op にクロージャを設定します。 closure は、 Py_None もしくは cell オブジェクトのタプルでなければなりません。

失敗した時は、 SystemError を送出し、 -1 を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

メソッドオブジェクト (method object)

C API にはメソッドオブジェクトを扱うのに便利な関数があります。

PyTypeObject PyMethod_Type

この PyTypeObject のインスタンスは Python のメソッド型を表現します。このオブジェクトは、 types.MethodType として Python プログラムに公開されています。

int PyMethod_Check(PyObject *o)

o がメソッドオブジェクト (PyMethod_Type 型である) 場合に真を返します。パラメータは NULL にできません。

PyObject* PyMethod_New(PyObject *func, PyObject *self, PyObject *class)

Return value: New reference.

任意の呼び出し可能オブジェクト func を使った新たなメソッドオブジェクトを返します; 関数 func は、メソッドが呼び出された時に呼び出されるオブジェクトです。このメソッドをインスタンスに束縛 (bind) したい場合、 self をインスタンス自体にして、 class を self のクラスにしなければなりません。それ以外の場合は self を NULL に、 class を非束縛メソッドを提供しているクラスにしなければなりません。

PyObject* PyMethod_Class(PyObject *meth)

Return value: Borrowed reference.

メソッドオブジェクト meth を生成したクラスオブジェクトを返します; インスタンスがメソッドオブジェクトを生成した場合、戻り値はインスタンスのクラスになります。

PyObject* PyMethod_GET_CLASS(PyObject *meth)

Return value: Borrowed reference.

PyMethod_Class() をマクロで実装したバージョンで、エラーチェックを行いません。

PyObject* PyMethod_Function(PyObject *meth)

Return value: Borrowed reference.

メソッド meth に関連付けられている関数オブジェクトを返します。

PyObject* PyMethod_GET_FUNCTION(PyObject *meth)

Return value: Borrowed reference.

PyMethod_Function() のマクロ版で、エラーチェックを行いません。

PyObject* PyMethod_Self(PyObject *meth)

Return value: Borrowed reference.

meth が束縛メソッドの場合には、メソッドに関連付けられているインスタンスを返します。それ以外の場合には NULL を返します。

PyObject* PyMethod_GET_SELF(PyObject *meth)

Return value: Borrowed reference.

PyMethod_Self() のマクロ版で、エラーチェックを行いません。

int PyMethod_ClearFreeList()

free list をクリアします。解放された要素数を返します。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

ファイルオブジェクト

Python の組み込みファイルオブジェクトは、全て標準 C ライブラリの FILE* サポートの上に実装されています。以下の詳細説明は一実装に関するもので、将来の Python のリリースで変更されるかもしれません。

PyFileObject

この PyObject のサブタイプは Python のファイル型オブジェクトを表現します。

PyTypeObject PyFile_Type

この PyTypeObject のインスタンスは Python のファイル型を表現します。このオブジェクトは file および types.FileType として Python プログラムで公開されています。

int PyFile_Check(PyObject *p)

引数が PyFileObject か PyFileObject のサブタイプのときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyFile_CheckExact(PyObject *p)

引数が PyFileObject 型で、かつ PyFileObject 型のサブタイプでないときに真を返します。

バージョン 2.2 で追加.

PyObject* PyFile_FromString(char *filename, char *mode)

Return value: New reference.

成功すると、 filename に指定した名前のファイルを mode に指定したファイルモードで開いて得た新たなファイルオブジェクトを返します。 mode のセマンティクスは標準 C ルーチン fopen() と同じです。失敗すると NULL を返します。

PyObject* PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE*))

Return value: New reference.

すでに開かれている標準 C ファイルポインタ fp から新たな PyFileObject を生成します。この関数で生成したファイルオブジェクトは、閉じる際に close に指定した関数を呼び出します。失敗すると NULL を返します。

FILE* PyFile_AsFile(PyObject *p)

p に関連付けられたファイルオブジェクトを FILE* で返します。

呼び出し側が GIL を開放している間もこの関数が返した FILE* オブジェクトを使うのであれば、以下に解説されている PyFile_IncUseCount() と PyFile_DecUseCount() 関数を適切に呼び出さなければなりません。

void PyFile_IncUseCount(PyFileObject *p)

PyFileObject 内部の、 FILE* が使用中であることを示す使用数カウントをインクリメントします。これは、別のスレッドで使用中の FILE* に対して Python が fclose() を呼び出すことを防ぎます。この関数の呼び出し側は、 FILE* を使い終わったときに必ず PyFile_DecUseCount() を呼び出さなければなりません。そうしなければ、 Python はそのファイルオブジェクトを永遠に閉じません。

この関数を呼び出すときは、 GIL を取得していなければなりません。

例えば、 PyFile_AsFile() を呼び出した後、GILを開放する前にこの関数を呼び出します。

FILE *fp = PyFile_AsFile(p);
PyFile_IncUseCount(p);
/* ... */
Py_BEGIN_ALLOW_THREADS
do_something(fp);
Py_END_ALLOW_THREADS
/* ... */
PyFile_DecUseCount(p);

バージョン 2.6 で追加.

void PyFile_DecUseCount(PyFileObject *p)

PyFileObject 内部の、 FILE* が使用中であることを示す unlocked_count メンバーをデクリメントして、呼び出し元が FILE* を使い終わったことを示します。これは、先に行った PyFile_IncUseCount() の呼び出しを取り消すためだけに呼び出されるでしょう。

この関数を呼び出すときは、 GIL を取得していなければなりません。 (上の例を参照してください)

バージョン 2.6 で追加.

PyObject* PyFile_GetLine(PyObject *p, int n)

Return value: New reference.

p.readline([*n*]) と同じで、この関数はオブジェクト p の各行を読み出します。 p はファイルオブジェクトか、 readline() メソッドを持つ何らかのオブジェクトでかまいません。 n が 0 の場合、行の長さに関係なく正確に 1 行だけ読み出します。 n が 0 より大きければ、 n バイト以上のデータは読み出しません; 従って、行の一部だけが返される場合があります。どちらの場合でも、読み出し後すぐにファイルの終端に到達した場合には空文字列を返します。 n が 0 より小さければ、長さに関わらず 1 行だけを読み出しますが、すぐにファイルの終端に到達した場合には EOFError を送出します。

PyObject* PyFile_Name(PyObject *p)

Return value: Borrowed reference.

p に指定したファイルの名前を文字列オブジェクトで返します。

void PyFile_SetBufSize(PyFileObject *p, int n)

setvbuf() があるシステムでのみ利用できます。この関数を呼び出してよいのはファイルオブジェクトの生成直後のみです。

int PyFile_SetEncoding(PyFileObject *p, const char *enc)

Unicode オブジェクトをファイルに出力するときにのエンコーディングを enc にします。成功すると 1 を、失敗すると 0 を返します。

バージョン 2.3 で追加.

int PyFile_SetEncodingAndErrors(PyFileObject *p, const char *enc, *errors)

Unicode オブジェクトをファイルに出力するときにのエンコーディングを enc に設定し、そのエラーモードを err に設定します。

バージョン 2.6 で追加.

int PyFile_SoftSpace(PyObject *p, int newflag)

この関数はインタプリタの内部的な利用のために存在します。この関数は p の softspace 属性を newflag に設定し、以前の設定値を返します。この関数を正しく動作させるために、 p がファイルオブジェクトである必然性はありません; 任意のオブジェクトをサポートします (softspace 属性が設定されているかどうかのみが問題だと思ってください)。この関数は全てのエラーを解消し、属性値が存在しない場合や属性値を取得する際にエラーが生じると、 0 を以前の値として返します。この関数からはエラーを検出できませんが、そもそもそういう必要はありません。

int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags)

オブジェクト obj をファイルオブジェクト p に書き込みます。 flag がサポートするフラグは Py_PRINT_RAW だけです; このフラグを指定すると、オブジェクトに repr() ではなく str() を適用した結果をファイルに書き出します。成功した場合には 0 を返し、失敗すると -1 を返して適切な例外をセットします。

int PyFile_WriteString(const char *s, PyObject *p)

文字列 s をファイルオブジェクト p に書き出します。成功した場合には 0 を返し、失敗すると -1 を返して適切な例外をセットします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

モジュールオブジェクト (module object)

モジュールオブジェクト固有の関数は数個しかありません。

PyTypeObject PyModule_Type

この PyTypeObject のインスタンスは Python のモジュールオブジェクト型を表現します。このオブジェクトは、Python プログラムには types.ModuleType として公開されています。

int PyModule_Check(PyObject *p)

o がモジュールオブジェクトかモジュールオブジェクトのサブタイプであるときに真を返します。

バージョン 2.2 で変更: サブタイプを引数にとれるようになりました.

int PyModule_CheckExact(PyObject *p)

o がモジュールオブジェクトで、かつモジュールオブジェクトのサブタイプでないときに真を返します。 PyModule_Type.

バージョン 2.2 で追加.

PyObject* PyModule_New(const char *name)

Return value: New reference.

__name__ 属性が name に設定された新たなモジュールオブジェクトを返します。モジュールの __doc__ および __name__ 属性だけに値が入っています; __file__ 属性に値を入れるのは呼び出し側の責任です。

PyObject* PyModule_GetDict(PyObject *module)

Return value: Borrowed reference.

module の名前空間を実現する辞書オブジェクトを返します; このオブジェクトはモジュールオブジェクトの __dict__ と同じです。この関数が失敗することはありません。 拡張モジュールでは、この関数で得たモジュールの __dict__ を直接いじるより、他の PyModule_*() および PyObject_*() 関数を使うよう勧めます。

char* PyModule_GetName(PyObject *module)

module の __name__ の値を返します。モジュールがこの属性を提供していない場合や文字列型でない場合、 SystemError を送出して NULL を返します。

char* PyModule_GetFilename(PyObject *module)

module をロードするために使ったファイルの名前を、 module の __file__ 属性から調べて返します。 __file__ が定義されていない場合や文字列型でない場合、 SystemError を送出して NULL を返します。

int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)

module にオブジェクトを name として追加します。この関数はモジュールの初期化関数から利用される便宜関数です。エラーのときには -1 を、成功したときには 0 を返します。

バージョン 2.0 で追加.

int PyModule_AddIntConstant(PyObject *module, const char *name, long value)

module に整数定数を name として追加します。この便宜関数はモジュールの初期化関数から利用されています。エラーのときには -1 を、成功したときには 0 を返します。

バージョン 2.0 で追加.

int PyModule_AddStringConstant(PyObject *module, const char *name, char *value)

module に文字列定数を name として追加します。この便宜関数はモジュールの初期化関数から利用されています。文字列 value は null 終端されていなければなりません。エラーのときには -1 を、成功したときには 0 を返します。

バージョン 2.0 で追加.

int PyModule_AddIntMacro(PyObject *module, macro)

module に int 定数を追加します。名前と値は macro から取得されます。例えば、 PyModule_AddIntMacro(module, AF_INTE) とすると、 AF_INET という名前の int 型定数を AF_INET の値で module に追加します。エラー時には -1 を、成功時には 0 を返します。

バージョン 2.6 で追加.

int PyModule_AddStringMacro(PyObject *module, macro)

文字列定数を module に追加します。

バージョン 2.6 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

イテレータオブジェクト (iterator object)

Python では二種類のイテレータオブジェクトを提供しています。一つ目はシーケンスイテレータで、 __getitem__() メソッドをサポートする任意のシーケンスを取り扱います。二つ目は呼び出し可能オブジェクトとセンチネル値 (sentinel value) を扱い、シーケンス内の要素ごとに呼び出し可能オブジェクトを呼び出して、センチネル値が返されたときに反復処理を終了します。

PyTypeObject PySeqIter_Type

PySeqIter_New() や、組み込みシーケンス型に対して 1 引数形式の組み込み関数 iter() を呼び出したときに返される、イテレータオブジェクトの型オブジェクトです。

バージョン 2.2 で追加.

int PySeqIter_Check(op)

PySeqIter_Type の型が op のときに真を返します。

バージョン 2.2 で追加.

PyObject* PySeqIter_New(PyObject *seq)

Return value: New reference.

一般的なシーケンスオブジェクト seq を扱うイテレータを返します。反復処理は、シーケンスが添字指定操作の際に IndexError を返したときに終了します。

バージョン 2.2 で追加.

PyTypeObject PyCallIter_Type

PyCallIter_New() や、組み込み関数 iter() の 2 引数形式が返すイテレータオブジェクトの型オブジェクトです。 iter() built-in function.

バージョン 2.2 で追加.

int PyCallIter_Check(op)

PyCallIter_Type の型が op のときに真を返します。

バージョン 2.2 で追加.

PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)

Return value: New reference.

新たなイテレータを返します。最初のパラメタ callable は引数なしで呼び出せる Python の呼び出し可能オブジェクトならなんでもかまいません; callable は、呼び出されるたびに次の反復処理対象オブジェクトを返さなければなりません。生成されたイテレータは、 callable が sentinel に等しい値を返すと反復処理を終了します。

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

デスクリプタオブジェクト (descriptor object)

“デスクリプタ (descriptor)” は、あるオブジェクトのいくつかの属性について記述したオブジェクトです。デスクリプタオブジェクトは型オブジェクトの辞書内にあります。

PyTypeObject PyProperty_Type

組み込みデスクリプタ型の型オブジェクトです。

バージョン 2.2 で追加.

PyObject* PyDescr_NewGetSet(PyTypeObject *type, struct PyGetSetDef *getset)

Return value: New reference.

バージョン 2.2 で追加.

PyObject* PyDescr_NewMember(PyTypeObject *type, struct PyMemberDef *meth)

Return value: New reference.

バージョン 2.2 で追加.

PyObject* PyDescr_NewMethod(PyTypeObject *type, struct PyMethodDef *meth)

Return value: New reference.

バージョン 2.2 で追加.

PyObject* PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *wrapper, void *wrapped)

Return value: New reference.

バージョン 2.2 で追加.

int PyDescr_IsData(PyObject *descr)

デスクリプタオブジェクト descr がデータ属性のデスクリプタの場合には真を、メソッドデスクリプタの場合には偽を返します。 descr はデスクリプタオブジェクトでなければなりません; エラーチェックは行いません。

バージョン 2.2 で追加.

PyObject* PyWrapper_New(PyObject *, PyObject *)

Return value: New reference.

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

スライスオブジェクト (slice object)

PyTypeObject PySlice_Type

スライスオブジェクトの型オブジェクトです。 slice や types.SliceType と同じです。

int PySlice_Check(PyObject *ob)

ob がスライスオブジェクトの場合に真を返します; ob は NULL であってはなりません。

PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step)

Return value: New reference.

指定した値から新たなスライスオブジェクトを返します。パラメタ start, stop, および step はスライスオブジェクトにおける同名の属性として用いられます。これらの値はいずれも NULL にでき、対応する値には None が使われます。新たなオブジェクトをアロケーションできない場合には NULL を返します。

int PySlice_GetIndices(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)

スライスオブジェクト slice における start, stop, および step のインデクス値を取得します。このときシーケンスの長さを length と仮定します。 length よりも大きなインデクスになるとエラーとして扱います。

成功のときには 0 を、エラーのときには例外をセットせずに -1 を返します (ただし、指定インデクスのいずれか一つが None ではなく、かつ整数に変換できなかった場合を除きます。この場合、 -1 を返して例外をセットします)。

おそらくこの関数を使う気にはならないでしょう。バージョン 2.3 以前の Python でスライスオブジェクトを使いたいのなら、 PySlice_GetIndicesEx() のソースを適切に名前変更して自分の拡張モジュールのソースコード内に組み込むとよいでしょう。

バージョン 2.5 で変更: この関数は以前は length の型に int を、 start, stop, step の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

int PySlice_GetIndicesEx(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)

PySlice_GetIndices() の置き換えとして使える関数です。

スライスオブジェクト slice における start, stop, および step のインデクス値を取得します。このときシーケンスの長さを length と仮定します。スライスの長さを slicelength に記憶します。境界をはみだしたインデクスは、通常のスライスを扱うのと同じ一貫したやり方でクリップされます。

成功のときには 0 を、エラーのときには例外をセットして -1 を返します。

バージョン 2.3 で追加.

バージョン 2.5 で変更: この関数は以前は length の型に int を、 start, stop, step, slicelength の型に int * を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

弱参照オブジェクト (weak reference object)

Python は 弱参照 を第一級オブジェクト (first-class object) としてサポートします。弱参照を直接実装する二種類の固有のオブジェクト型があります。第一は単純な参照オブジェクトで、第二はオリジナルのオブジェクトに対して可能な限りプロキシとして振舞うオブジェクトです。

int PyWeakref_Check(ob)

ob が参照オブジェクトかプロキシオブジェクトの場合に真を返します。

バージョン 2.2 で追加.

int PyWeakref_CheckRef(ob)

ob が参照オブジェクトの場合に真を返します。

バージョン 2.2 で追加.

int PyWeakref_CheckProxy(ob)

ob がプロキシオブジェクトの場合に真を返します。

バージョン 2.2 で追加.

PyObject* PyWeakref_NewRef(PyObject *ob, PyObject *callback)

Return value: New reference.

ob に対する弱参照オブジェクトを返します。この関数は常に新たな参照を返しますが、必ずしも新たなオブジェクトを作る保証はありません; 既存の参照オブジェクトが返されることもあります。第二のパラメタ callback は呼び出し可能オブジェクトで、 ob がガーベジコレクションされた際に通知を受け取ります; callback は弱参照オブジェクト自体を単一のパラメタとして受け取ります。 callback は None や NULL にしてもかまいません。 ob が弱参照できないオブジェクトの場合や、 callback が呼び出し可能オブジェクト、 None 、 NULL のいずれでもない場合は、 NULL を返して TypeError を送出します。

バージョン 2.2 で追加.

PyObject* PyWeakref_NewProxy(PyObject *ob, PyObject *callback)

Return value: New reference.

ob に対する弱参照プロキシオブジェクトを返します。この関数は常に新たな参照を返しますが、必ずしも新たなオブジェクトを作る保証はありません; 既存の参照オブジェクトが返されることもあります。第二のパラメタ callback は呼び出し可能オブジェクトで、 ob がガーベジコレクションされた際に通知を受け取ります; callback は弱参照オブジェクト自体を単一のパラメタとして受け取ります。 callback は None や NULL にしてもかまいません。 ob が弱参照できないオブジェクトの場合や、 callback が呼び出し可能オブジェクト、 None 、 NULL のいずれでもない場合は、 NULL を返して TypeError を送出します。

バージョン 2.2 で追加.

PyObject* PyWeakref_GetObject(PyObject *ref)

Return value: Borrowed reference.

弱参照 ref が参照しているオブジェクトを返します。被参照オブジェクトがすでに存続していない場合、 Py_None を返します。

バージョン 2.2 で追加.

警告

この関数は参照先オブジェクトの 借り物の参照 を返します。そのため、そのオブジェクトを利用している間そのオブジェクトが破棄されないことが判っている場合を除き、常に Py_INCREF() を呼び出すべきです。

PyObject* PyWeakref_GET_OBJECT(PyObject *ref)

Return value: Borrowed reference.

PyWeakref_GetObject() に似ていますが、マクロで実装されていて、エラーチェックを行いません。

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

カプセル (Capsules)

using-capsules 以下のオブジェクトを使う方法については 拡張モジュールに C API を提供するを参照してください。

PyCapsule

この PyObject のサブタイプは、任意の値を表し、C拡張モジュールから Pythonコードを経由して他のC言語のコードに任意の値を(void* ポインタの形で)渡す必要があるときに有用です。あるモジュール内で定義されているC言語関数のポインタを、他のモジュールに渡してそこから呼び出せるようにするためによく使われます。これにより、動的にロードされるモジュールの中の C API に通常の import 機構を通してアクセスすることができます。

PyCapsule_Destructor

カプセルに対するデストラクタコールバック型. 次のように定義されます:

typedef void (*PyCapsule_Destructor)(PyObject *);

PyCapsule_Destructor コールバックの動作については PyCapsule_New() を参照してください。

int PyCapsule_CheckExact(PyObject *p)

引数が PyCapsule だったときに true を返します。

PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)

pointer を格納する PyCapsule を作成します。 pointer 引数は NULL であってはなりません。

失敗した場合、例外を設定して NULL を返します。

name 文字列は NULL か、有効なC文字列へのポインタです。 NULL で無い場合、この文字列は少なくともカプセルより長く生存する必要があります。 (destructor の中で解放することは許可されています)

destructor が NULL で無い場合、カプセルが削除されるときにそのカプセルを引数として呼び出されます。

このカプセルがモジュールの属性として保存される場合、 name は modulename.attributename と指定されるべきです。こうすると、他のモジュールがそのカプセルを PyCapsule_Import() でインポートすることができます。

void* PyCapsule_GetPointer(PyObject *capsule, const char *name)

カプセルに保存されている pointer を取り出します。失敗した場合は例外を設定して NULL を返します。

name 引数はカプセルに保存されている名前と正確に一致しなければなりません。もしカプセルに格納されている name が NULL なら、この関数の name 引数も同じく NULL でなければなりません。 Python は C言語の strcmp() を使ってこの name を比較します。

PyCapsule_Destructor PyCapsule_GetDestructor(PyObject *capsule)

カプセルに保存されている現在のデストラクタを返します。失敗した場合、例外を設定して NULL を返します。

カプセルは NULL をデストラクタとして持つことができます。従って、戻り値の NULL がエラーを指してない可能性があります。 PyCapsule_IsValid() か PyErr_Occurred を利用して確認してください。

void* PyCapsule_GetContext(PyObject *capsule)

カプセルに保存されている現在のコンテキスト(context)を返します。失敗した場合、例外を設定して NULL を返します。

カプセルは NULL をコンテキストとして持つことができます。従って、戻り値の NULL がエラーを指してない可能性があります。 PyCapsule_IsValid() か PyErr_Occurred を利用して確認してください。

const char* PyCapsule_GetName(PyObject *capsule)

カプセルに保存されている現在の name を返します。失敗した場合、例外を設定して NULL を返します。

カプセルは NULL を name として持つことができます。従って、戻り値の NULL がエラーを指してない可能性があります。 PyCapsule_IsValid() か PyErr_Occurred を利用して確認してください。

void* PyCapsule_Import(const char *name, int no_block)

モジュールのカプセル属性から Cオブジェクトへのポインタをインポートします。 name 引数はその属性の完全名を module.attribute のように指定しなければなりません。カプセルに格納されている name はこの文字列に正確に一致しなければなりません。 no_block が真の時、モジュールを(PyImport_InportModuleNoBlock() を使って) ブロックせずにインポートします。 no_block が偽の時、モジュールは (PyImport_ImportModule() を使って) 通常の方法でインポートされます。

成功した場合、カプセル内部の pointer を返します。失敗した場合、例外を設定して NULL を返します。ただし、 no_block が真だった場合は、 PyCapsule_Import() はモジュールのインポートに失敗しても例外を設定しません。

int PyCapsule_IsValid(PyObject *capsule, const char *name)

capsule が有効なカプセルであるかどうかをチェックします。有効な capsule は、非 NULL で、 PyCapsule_CheckExact() をパスし、非 NULL なポインタを格納していて、内部の name が引数 name とマッチします。 (name の比較方法については PyCapsule_GetPointer() を参照)

言い換えると、 PyCapsule_IsValid() が真を返す場合、全てのアクセッサ (PyCapsule_Get() で始まる全ての関数) が成功することが保証されます。

オブジェクトが有効で name がマッチした場合に非0を、それ以外の場合に 0 を返します。この関数は絶対に失敗しません。

int PyCapsule_SetContext(PyObject *capsule, void *context)

capsule 内部のコンテキストポインタを context に設定します。

成功したら 0 を、失敗したら例外を設定して 非0 を返します。

int PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor)

capsule 内部のデストラクタを destructor に設定します。

成功したら 0 を、失敗したら例外を設定して 非0 を返します。

int PyCapsule_SetName(PyObject *capsule, const char *name)

capsule 内部の name を name に設定します。 name が非 NULL のとき、それは capsule よりも長い寿命を持つ必要があります。もしすでに capsule に非 NULL の name が保存されていた場合、それに対する開放は行われません。

成功したら 0 を、失敗したら例外を設定して 非0 を返します。

int PyCapsule_SetPointer(PyObject *capsule, void *pointer)

capsule 内部のポインタを pointer に設定します。 pointer は NULL であってはなりません。

成功したら 0 を、失敗したら例外を設定して 非0 を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

Cオブジェクト (CObject)

警告

CObject API は Python 2.7 から非推奨になりました。新しい カプセル (Capsules) APIへ移行してください。

PyCObject

この PyObject のサブタイプは不透明型値 (opaque value) を表現します。C 拡張モジュールが Python コードから不透明型値を (void* ポインタで) 他の C コードに渡す必要があるときに便利です。正規の import 機構を使って動的にロードされるモジュール内で定義されている C API にアクセスするために、あるモジュール内で定義されている C 関数ポインタを別のモジュールでも利用できるようにするためによく使われます。

int PyCObject_Check(PyObject *p)

引数が PyCObject の場合に真を返します。

PyObject* PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))

Return value: New reference.

void* cobj から PyCObject を生成します。関数 destr が NULL でない場合、オブジェクトを再利用する際に呼び出します。

PyObject* PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *))

Return value: New reference.

void* cobj から PyCObject を生成します。関数 destr が NULL でない場合、オブジェクトを再利用する際に呼び出します。引数 desc を使って、デストラクタ関数に追加のコールバックデータを渡せます。

void* PyCObject_AsVoidPtr(PyObject* self)

PyCObject オブジェクト self を生成するのに用いたオブジェクト void * を返します。

void* PyCObject_GetDesc(PyObject* self)

PyCObject オブジェクト self を生成するのに用いたコールバックデータ void * を返します。

int PyCObject_SetVoidPtr(PyObject* self, void* cobj)

self 内の void ポインタ cobj に設定します。 PyCObject にデストラクタが関連づけられていてはなりません。成功すると真値を返し、失敗すると偽値を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

セルオブジェクト (cell object)

“セル (cell)” オブジェクトは、複数のスコープから参照される変数群を実装するために使われます。セルは各変数について作成され、各々の値を記憶します; この値を参照する各スタックフレームにおけるローカル変数には、そのスタックフレームの外側で同じ値を参照しているセルに対する参照が入ります。セルで表現された値にアクセスすると、セルオブジェクト自体の代わりにセル内の値が使われます。このセルオブジェクトを使った間接参照 (dereference) は、インタプリタによって生成されたバイトコード内でサポートされている必要があります; セルオブジェクトにアクセスした際に、自動的に間接参照は起こりません。上記以外の状況では、セルオブジェクトは役に立たないはずです。

PyCellObject

セルオブジェクトに使われる C 構造体です。

PyTypeObject PyCell_Type

セルオブジェクトに対応する型オブジェクトです。

int PyCell_Check(ob)

ob がセルオブジェクトの場合に真を返します; ob は NULL であってはなりません。

PyObject* PyCell_New(PyObject *ob)

Return value: New reference.

値 ob の入った新たなセルオブジェクトを生成して返します。引数を NULL にしてもかまいません。

PyObject* PyCell_Get(PyObject *cell)

Return value: New reference.

cell の内容を返します。

PyObject* PyCell_GET(PyObject *cell)

Return value: Borrowed reference.

cell の内容を返しますが、 cell が非 NULL でかつセルオブジェクトであるかどうかチェックしません。

int PyCell_Set(PyObject *cell, PyObject *value)

セルオブジェクト cell の内容を value に設定します。この関数は現在のセルの全ての内容に対する参照を解放します。 value は NULL でもかまいません。 cell は非 NULL でなければなりません; もし cell がセルオブジェクトでない場合、 -1 を返します。成功すると 0 を返します。

void PyCell_SET(PyObject *cell, PyObject *value)

セルオブジェクト cell の値を value に設定します。参照カウントに対する変更はなく、安全のためのチェックは何も行いません; cell は非 NULL でなければならず、かつセルオブジェクトでなければなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

ジェネレータオブジェクト

ジェネレータ (generator) オブジェクトは、 Python がジェネレータ型イテレータを実装するために使っているオブジェクトです。ジェネレータオブジェクトは、通常、 PyGen_New() で明示的に生成されることはなく、値を逐次生成するような関数に対してイテレーションを行うときに生成されます。

PyGenObject

ジェネレータオブジェクトに使われている C 構造体です。

PyTypeObject PyGen_Type

ジェネレータオブジェクトに対応する型オブジェクトです。

int PyGen_Check(ob)

ob がジェネレータオブジェクトの場合に真を返します。 ob が NULL であってはなりません。

int PyGen_CheckExact(ob)

ob の型が PyGen_Type の場合に真を返します。 ob が NULL であってはなりません。

PyObject* PyGen_New(PyFrameObject *frame)

Return value: New reference.

frame オブジェクトに基づいて新たなジェネレータオブジェクトを生成して返します。この関数は frame への参照を盗みます。パラメタが NULL であってはなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

DateTime オブジェクト

datetime モジュールでは、様々な日付オブジェクトや時刻オブジェクトを提供しています。以下に示す関数を使う場合には、あらかじめヘッダファイル datetime.h をソースに include し (Python.h はこのファイルを include しません)、 PyDateTime_IMPORT マクロを、通常はモジュール初期化関数から、起動しておく必要があります。このマクロは以下のマクロで使われる静的変数 PyDateTimeAPI に C 構造体へのポインタを入れます。

以下は型チェックマクロです:

int PyDate_Check(PyObject *ob)

ob が PyDateTime_DateType 型か PyDateTime_DateType 型のサブタイプのオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyDate_CheckExact(PyObject *ob)

ob が PyDateTime_DateType 型のオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyDateTime_Check(PyObject *ob)

ob が PyDateTime_DateTimeType 型か PyDateTime_DateTimeType 型のサブタイプのオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyDateTime_CheckExact(PyObject *ob)

ob が PyDateTime_DateTimeType 型のオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyTime_Check(PyObject *ob)

ob が PyDateTime_TimeType 型か PyDateTime_TimeType 型のサブタイプのオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyTime_CheckExact(PyObject *ob)

ob が PyDateTime_TimeType 型のオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyDelta_Check(PyObject *ob)

ob が PyDateTime_DeltaType 型か PyDateTime_DeltaType 型のサブタイプのオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyDelta_CheckExact(PyObject *ob)

ob が PyDateTime_DeltaType 型のオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyTZInfo_Check(PyObject *ob)

ob が PyDateTime_TZInfoType 型か PyDateTime_TZInfoType 型のサブタイプのオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

int PyTZInfo_CheckExact(PyObject *ob)

ob が PyDateTime_TZInfoType 型のオブジェクトの場合に真を返します; ob は NULL であってはなりません。

バージョン 2.4 で追加.

以下はオブジェクトを作成するためのマクロです:

PyObject* PyDate_FromDate(int year, int month, int day)

Return value: New reference.

指定された年、月、日の datetime.date オブジェクトを返します。

バージョン 2.4 で追加.

PyObject* PyDateTime_FromDateAndTime(int year, int month, int day, int hour, int minute, int second, int usecond)

Return value: New reference.

指定された年、月、日、時、分、秒、マイクロ秒の datetime.datetime オブジェクトを返します。

バージョン 2.4 で追加.

PyObject* PyTime_FromTime(int hour, int minute, int second, int usecond)

Return value: New reference.

指定された時、分、秒、マイクロ秒の datetime.time オブジェクトを返します。

バージョン 2.4 で追加.

PyObject* PyDelta_FromDSU(int days, int seconds, int useconds)

Return value: New reference.

指定された日、秒、マイクロ秒の datetime.timedelta オブジェクトを返します。マイクロ秒と秒が datetime.timedelta オブジェクトで定義されている範囲に入るように正規化を行います。

バージョン 2.4 で追加.

以下のマクロは date オブジェクトからフィールド値を取り出すためのものです。引数は PyDateTime_Date またはそのサブクラス (例えば PyDateTime_DateTime)の インスタンスでなければなりません。引数を NULL にしてはならず、型チェックは行いません:

int PyDateTime_GET_YEAR(PyDateTime_Date *o)

年を正の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_GET_MONTH(PyDateTime_Date *o)

月を 1 から 12 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_GET_DAY(PyDateTime_Date *o)

日を 1 から 31 の間の整数で返します。

バージョン 2.4 で追加.

以下のマクロは datetime オブジェクトからフィールド値を取り出すためのものです。引数は PyDateTime_DateTime またはそのサブクラスのインスタンスでなければなりません。引数を NULL にしてはならず、型チェックは行いません:

int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o)

時を 0 から 23 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_DATE_GET_MINUTE(PyDateTime_DateTime *o)

分を 0 から 59 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_DATE_GET_SECOND(PyDateTime_DateTime *o)

秒を 0 から 59 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_DATE_GET_MICROSECOND(PyDateTime_DateTime *o)

マイクロ秒を 0 から 999999 の間の整数で返します。

バージョン 2.4 で追加.

以下のマクロは time オブジェクトからフィールド値を取り出すためのものです。引数は PyDateTime_Time またはそのサブクラスのインスタンスでなければなりません。引数を NULL にしてはならず、型チェックは行いません:

int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o)

時を 0 から 23 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_TIME_GET_MINUTE(PyDateTime_Time *o)

分を 0 から 59 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_TIME_GET_SECOND(PyDateTime_Time *o)

秒を 0 から 59 の間の整数で返します。

バージョン 2.4 で追加.

int PyDateTime_TIME_GET_MICROSECOND(PyDateTime_Time *o)

マイクロ秒を 0 から 999999 の間の整数で返します。

バージョン 2.4 で追加.

以下のマクロは DB API を実装する上での便宜用です:

PyObject* PyDateTime_FromTimestamp(PyObject *args)

Return value: New reference.

dateitme.datetime.fromtimestamp() に渡すのに適した引数タプルから新たな datetime.datetime オブジェクトを生成して返します。

バージョン 2.4 で追加.

PyObject* PyDate_FromTimestamp(PyObject *args)

Return value: New reference.

dateitme.date.fromtimestamp() に渡すのに適した引数タプルから新たな datetime.date オブジェクトを生成して返します。

バージョン 2.4 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

集合オブジェクト (Set Objects)

バージョン 2.5 で追加.

このセクションでは set と frozenset の公開 API について詳しく述べます。以降で説明していない機能は、抽象オブジェクトプロトコル ( PyObject_CallMethod(), PyObject_RichCompareBool(), PyObject_Hash(), PyObject_Repr(), PyObject_IsTrue(), PyObject_Print(), PyObject_GetIter() を含む) か抽象数値プロトコル ( PyNumber_Add(), PyNumber_Subtract(), PyNumber_Or(), PyNumber_Xor(), PyNumber_InPlaceAdd(), PyNumber_InPlaceSubtract(), PyNumber_InPlaceOr(), PyNumber_InPlaceXor() を含む) を使って利用できます。

PySetObject

この PyObject を継承した型は、 set と frozenset 両方の内部データを保存するのに用いられます。 PyDictObject と同じように、小さい集合(set)に対しては(タプルのように)固定サイズであり、そうでない集合に対しては(リストと同じように)可変長のメモリブロックを用います。この構造体のどのフィールドも、非公開で変更される可能性があると考えて下さい。すべてのアクセスは、構造体の中の値を直接操作するのではなく、ドキュメントされた API を用いて行うべきです。

PyTypeObject PySet_Type

この PyTypeObject のインスタンスは、Python の set 型を表します。

PyTypeObject PyFrozenSet_Type

この PyTypeObject のインスタンスは、Python の frozenset 型を表します。

以降の型チェックマクロはすべての Python オブジェクトに対するポインタに対して動作します。同様に、コンストラクタはすべてのイテレート可能な Python オブジェクトに対して動作します。

int PySet_Check(PyObject *p)

p が set かそのサブタイプのオブジェクトであるときに真を返します。

バージョン 2.6 で追加.

int PyFrozenSet_Check(PyObject *p)

p が frozenset かそのサブタイプのオブジェクトであるときに真を返します。

バージョン 2.6 で追加.

int PyAnySet_Check(PyObject *p)

p が set か frozenset 、あるいはそのサブタイプのオブジェクトであれば、true を返します。

int PyAnySet_CheckExact(PyObject *p)

p が set か frozenset のどちらかのオブジェクトであるときに true を返します。サブタイプのオブジェクトは含みません。

int PyFrozenSet_CheckExact(PyObject *p)

p が frozenset のオブジェクトであるときに true を返します。サブタイプのオブジェクトは含みません。

PyObject* PySet_New(PyObject *iterable)

Return value: New reference.

iterable が返すオブジェクトを含む新しい set を返します。 iterable が NULL のときは、空の set を返します。成功したら新しい set を、失敗したら NULL を返します。 iterable がイテレート可能で無い場合は、 TypeError を送出します。このコンストラクタは set をコピーするときにも使えます。 (c=set(s))

PyObject* PyFrozenSet_New(PyObject *iterable)

Return value: New reference.

iterable が返すオブジェクトを含む新しい frozenset を返します。 iterable が NULL のときは、空の frozenset を返します。 iterable がイテレート可能で無い場合は、 TypeError を送出します。

バージョン 2.6 で変更: 完全に新しい frozenset オブジェクトを返すことが保証されるようになりました。以前は、大きさがゼロの frozenset はシングルトンでした。これは新しい frozenset を PySet_Add() を使って作成するためです。

以降の関数やマクロは、 set と frozenset とそのサブタイプのインスタンスに対して利用できます。

Py_ssize_t PySet_Size(PyObject *anyset)

set や frozenset のオブジェクトの長さを返します。 len(anyset) と同じです。 anyset が set 、 frozenset 及びそのサブタイプのオブジェクトで無い場合は、 PyExc_SystemError を送出します。

バージョン 2.5 で変更: これらの関数は以前は int を返していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

Py_ssize_t PySet_GET_SIZE(PyObject *anyset)

エラーチェックを行わない、 PySet_Size() のマクロ形式。

int PySet_Contains(PyObject *anyset, PyObject *key)

見つかったら 1 を、見つからなかったら 0 を、エラーが発生したときは -1 を返します。 Python の __contains__() メソッドと違って、この関数は非ハッシュ set を一時 frozenset に自動で変換しません。 key がハッシュ可能で無い場合、 TypeError を送出します。 anyset が set, frozenset 及びそのサブタイプのオブジェクトで無い場合は PyExc_SystemError を送出します。

int PySet_Add(PyObject *set, PyObject *key)

set のインスタンスに key を追加します。 frozenset のインスタンスに使わないで下さい。成功したら 0 を、失敗したら -1 を返します。 key がハッシュ可能でないなら、 TypeError を送出します。 set を大きくする余裕が無い場合は、 MemoryError を送出します。 set が set とそのサブタイプのインスタンスで無い場合は、 SystemError を送出します。

バージョン 2.6 で変更: frozenset やそのサブタイプのインスタンスに対して利用できるようになりました。 PyTuple_SetItem() のように、新しい frozenset を他のコードに渡すまえに内容を追加するためのに使うことができます。

以降の関数は、 set とそのサブタイプに対して利用可能です。 frozenset とそのサブタイプには利用できません。

int PySet_Discard(PyObject *set, PyObject *key)

見つかって削除したら 1 を返します。見つからなかったら何もせずに 0 を返します。エラーが発生したら -1 を返します。 key が無くても KeyError を送出しません。 key がハッシュ不可能であれば TypeError を送出します。 Python の discard() メソッドと違って、この関数は非ハッシュ set を一時 frozenset に変換しません。 set が set とそのサブタイプのインスタンスで無いときは、 PyExc_SystemError を送出します。

PyObject* PySet_Pop(PyObject *set)

Return value: New reference.

set の中の要素のどれかに対する新しい参照を返し、そのオブジェクトを set から削除します。失敗したら NULL を返します。 set が空の場合には KeyError を送出します。 set が set とそのサブタイプのインスタンスで無い場合は、 SystemError を送出します。

int PySet_Clear(PyObject *set)

set を空にします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

具象オブジェクト (concrete object) レイヤ »

コードオブジェクト

コードオブジェクト(Code objects)は CPython 実装の低レベルな詳細部分です。各オブジェクトは関数に束縛されていない実行可能コードの塊を表現しています。

PyCodeObject

コードオブジェクトを表現するために利用されるC構造体。この型のフィールドは何時でも変更され得ます。

PyTypeObject PyCode_Type

Python の code 型を表現する PyTypeObject のインスタンス

int PyCode_Check(PyObject *co)

co が code オブジェクトのときに真を返します。

int PyCode_GetNumFree(PyObject *co)

co 内の自由変数(free variables)の数を返します。

PyCodeObject *PyCode_New(int argcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)

新しいコードオブジェクトを返します。フレームを作成するためにダミーのコードオブジェクトが必要な場合は、代わりに PyCode_NewEmpty() を利用してください。バイトコードは頻繁に変更されるため、 PyCode_New() を直接呼び出すと、 Python の詳細バージョンに依存してしまうことがあります。

int PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)

新しい空のコードオブジェクトを、指定されたファイル名、関数名、開始行番号で作成します。返されたコードオブジェクトに対しての exec や eval() は許されていません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

初期化 (initialization)、終了処理 (finalization)、スレッド

インタプリタの初期化と終了処理

void Py_Initialize()

Python インタプリタを初期化します。 Python の埋め込みを行うアプリケーションでは、他のあらゆる Python/C API を使用するよりも前にこの関数を呼び出さねばなりません。ただし、 Py_SetProgramName(), PyEval_InitThreads(), PyEval_ReleaseLock(), および PyEval_AcquireLock() は例外です。この関数はロード済みモジュールのテーブル (sys.modules) を初期化し、基盤となるモジュール群、 __builtin__, __main__, sys を生成します。また、モジュール検索パス (sys.path) も初期化します。 sys.argv の設定は行いません。設定するには、 PySys_SetArgvEx() を使ってください。この関数を (Py_Finalize() を呼ばずに) 再度呼び出しても何も行いません。戻り値はありません。初期化が失敗すれば、それは致命的なエラーです。

void Py_InitializeEx(int initsigs)

initsigs に1を指定すれば Py_Initialize() と同じ処理を実行しますが、 Python埋め込みアプリケーションでは initsigs を0として初期化時にシグナルハンドラの登録をスキップすることができます。

バージョン 2.4 で追加.

int Py_IsInitialized()

Python インタプリタがすでに初期化済みの場合に真 (非ゼロ) を返し、そうでない場合には偽 (ゼロ) を返します。 Py_Finalize() を呼び出すと、次に Py_Initialize() を呼び出すまでこの関数は偽を返します。

void Py_Finalize()

Py_Initialize() とそれ以後の Python/C API 関数で行った全ての初期化処理を取り消し、最後の Py_Initialize() 呼び出し以後に Python インタプリタが生成した全てのサブインタプリタ (sub-interpreter, 下記の Py_NewInterpreter() を参照) を消去します。理想的な状況では、この関数によって Python インタプリタが確保したメモリは全て解放されます。この関数を (Py_Initialize() を呼ばずに) 再度呼び出しても何も行いません。戻り値はありません。 終了処理中のエラーは無視されます。

この関数が提供されている理由はいくつかあります。 Python の埋め込みを行っているアプリケーションでは、アプリケーションを再起動することなく Python を再起動したいことがあります。また、動的ロード可能イブラリ (あるいは DLL) から Python インタプリタをロードするアプリケーションでは、DLL をアンロードする前に Python が確保したメモリを全て解放したいと考えるかもしれません。アプリケーション内で起きているメモリリークを追跡する際に、開発者は Python が確保したメモリをアプリケーションの終了前に解放させたいと思う場合もあります。

バグおよび注意事項: モジュールやモジュール内のオブジェクトはランダムな順番で削除されます。このため、他のオブジェクト(関数オブジェクトも含みます) やモジュールに依存するデストラクタ (__del__() メソッド) が失敗してしまうことがあります。動的にロードされるようになっている拡張モジュールが Python によってロードされていた場合、アンロードされません。 Python が確保したメモリがわずかながら解放されないかもしれません (メモリリークを発見したら、どうか報告してください)。オブジェクト間の循環参照に捕捉されているメモリは解放されないことがあります。拡張モジュールが確保したメモリは解放されないことがあります。拡張モジュールによっては、初期化ルーチンを 2 度以上呼び出すと正しく動作しないことがあります。 こうした状況は、 Py_Initialize() や Py_Finalize() を 2 度以上呼び出すと起こり得ます。

プロセスワイドのパラメータ

void Py_SetProgramName(char *name)

この関数を呼び出すなら、最初に Py_Initialize() を呼び出すよりも前に呼び出さねばなりません。この関数はインタプリタにプログラムの main() 関数に指定した argv[0] 引数の値を教えます。この引数値は、 Py_GetPath() や、以下に示すその他の関数が、インタプリタの実行可能形式から Python ランタイムライブラリへの相対パスを取得するために使われます。デフォルトの値は 'python' です。引数はゼロ終端されたキャラクタ文字列で、静的な記憶領域に入っていなければならず、その内容はプログラムの実行中に変更してはなりません。 Python インタプリタ内のコードで、この記憶領域の内容を変更するものは一切ありません。

char* Py_GetProgramName()

Py_SetProgramName() で設定されたプログラム名か、デフォルトのプログラム名を返します。関数が返す文字列ポインタは静的な記憶領域を返します。関数の呼び出し側はこの値を変更できません。

char* Py_GetPrefix()

プラットフォーム非依存のファイル群がインストールされている場所である prefix を返します。この値は Py_SetProgramName() でセットされたプログラム名やいくつかの環境変数をもとに、数々の複雑な規則から導出されます。例えば、プログラム名が '/usr/local/bin/python' の場合、prefix は '/usr/local' になります。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値はトップレベルの Makefile に指定されている変数 prefix や、ビルド値に configure スクリプトに指定した --prefix 引数に対応しています。この値は Python コードからは sys.prefix として利用できます。これはUnixでのみ有用です。次に説明する関数も参照してください。

char* Py_GetExecPrefix()

プラットフォーム 依存 のファイルがインストールされている場所である exec-prefix を返します。この値は Py_SetProgramName() でセットされたプログラム名やいくつかの環境変数をもとに、数々の複雑な規則から導出されます。例えば、プログラム名が '/usr/local/bin/python' の場合、exec-prefix は '/usr/local' になります。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値はトップレベルの Makefile に指定されている変数 exec_prefix や、ビルド値に configure スクリプトに指定した --exec-prefix 引数に対応しています。この値は Python コードからは sys.exec_prefix として利用できます。 Unixのみで有用です。

背景: プラットフォーム依存のファイル (実行形式や共有ライブラリ) が別のディレクトリツリー内にインストールされている場合、 exec-prefix は prefix と異なります。典型的なインストール形態では、プラットフォーム非依存のファイルが /usr/local に収められる一方、プラットフォーム依存のファイルは /usr/local/plat サブツリーに収められます。

一般的に、プラットフォームとは、ハードウェアとソフトウェアファミリの組み合わせを指します。例えば、 Solaris 2.x を動作させている Sparc マシンは全て同じプラットフォームであるとみなしますが、Solaris 2.x を動作させている Intel マシンは違うプラットフォームになりますし、同じ Intel マシンでも Linux を動作させているならまた別のプラットフォームです。一般的には、同じオペレーティングシステムでも、メジャーリビジョンの違うものは異なるプラットフォームです。非 Unix のオペレーティングシステムの場合は話はまた別です; 非 Unix のシステムでは、インストール方法はとても異なっていて、 prefix や exec-prefix には意味がなく、空文字列が設定されています。コンパイル済みの Python バイトコードはプラットフォームに依存しないので注意してください (ただし、どのバージョンの Python でコンパイルされたかには依存します!)。

システム管理者は、 mount や automount プログラムを使って、各プラットフォーム用の /usr/local/plat を異なったファイルシステムに置き、プラットフォーム間で /usr/local を共有するための設定方法を知っているでしょう。

char* Py_GetProgramFullPath()

Python 実行可能形式の完全なプログラム名を返します; この値はデフォルトのモジュール検索パスを (前述の Py_SetProgramName() で設定された) プログラム名から導出する際に副作用的に計算されます。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.executable として利用できます。

char* Py_GetPath()

デフォルトのモジュール検索パスを返します; パスは (上の Py_SetProgramName() で設定された) プログラム名と、いくつかの環境変数から計算されます。戻り値となる文字列は、プラットフォーム依存のパス区切り文字で分割された一連のディレクトリ名からなります。区切り文字は Unix と Mac OS X では ':', Windows では ';' です。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。 sys.path はインタプリタによってこの値で初期化され、その後にモジュールをロードする際の検索パスを変更するために修正することが可能で、たいていそうされます。

const char* Py_GetVersion()

Python インタプリタのバージョンを返します。バージョンは、次のような形式の文字列です。

"1.5 (#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"

第一ワード (最初のスペース文字まで) は、現在の Python のバージョンです; 最初の三文字は、ピリオドで区切られたメジャーバージョンとマイナーバージョンです。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.version として利用できます。

const char* Py_GetPlatform()

現在のプラットフォームのプラットフォーム識別文字列を返します。 Unixでは、オペレーティングシステムの “公式の” 名前を小文字に変換し、後ろにメジャーリビジョン番号を付けた構成になっています。例えば Solaris 2.x は、SunOS 5.x, としても知られていますが、 'sunos5' になります。Mac OS X では 'darwin' です。 Windows では 'win' です。関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.platform として利用できます。

const char* Py_GetCopyright()

現在の Python バージョンに対する公式の著作権表示文字列、例えば 'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam' を返します。

関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.copyright として利用できます。

const char* Py_GetCompiler()

現在使っているバージョンの Python をビルドする際に用いたコンパイラを示す文字列を、角括弧で囲った文字列を返します。例えば:

"[GCC 2.7.2.2]"

になります。

関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.version の一部として取り出せます。

const char* Py_GetBuildInfo()

現在使っている Python インタプリタインスタンスの、シーケンス番号とビルド日時に関する情報を返します。例えば

"#67, Aug  1 1997, 22:34:28"

になります。

関数が返す文字列ポインタは静的な記憶領域を返します; 関数の呼び出し側はこの値を変更できません。この値は Python コードからは sys.version の一部として取り出せます。

void PySys_SetArgvEx(int argc, char **argv, int updatepath)

argc および argv に基づいて sys.argv を設定します。これらの引数はプログラムの main() に渡した引数に似ていますが、最初の要素が Python インタプリタの宿主となっている実行形式の名前ではなく、実行されるスクリプト名を参照しなければならない点が違います。実行するスクリプトがない場合、 argv の最初の要素は空文字列にしてもかまいません。この関数が sys.argv の初期化に失敗した場合、致命的エラーを Py_FatalError() で知らせます。

updatepath が 0 の場合、ここまでの動作がこの関数がすることの全てです。 updatepath が 0 でない場合、この関数は sys.path を以下のアルゴリズムに基づいて修正します:

存在するスクリプトの名前が argv[0] に渡された場合、そのスクリプトがある場所の絶対パスを sys.path の先頭に追加します。

それ以外の場合(argc が 0 だったり、 argv[0] が存在するファイル名をさしていない場合)、 sys.path の先頭に空の文字列を追加します。これは現在の作業ディレクトリ (".") を先頭に追加するのと同じです。

ノート

Python インタプリタを、単一のスクリプトを実行する以外の目的で埋め込むアプリケーションは、 updatepath に 0 を渡して必要なら自分で sys.path を更新することをおすすめします。 CVE-2008-5983 [http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983] を参照してください。

2.6.6 より前のバージョンでは、 PySys_SetArgv() を呼出たあとに同じ事を手動で sys.path の先頭の要素を取り除くことで実現できます。例えば、次のようにします。

PyRun_SimpleString("import sys; sys.path.pop(0)\n");

バージョン 2.6.6 で追加.

void PySys_SetArgv(int argc, char **argv)

PySys_SetArgvEx() の updatepath に 1 を設定したのと同じように動作します。

void Py_SetPythonHome(char *home)

Python の標準ライブラリがある、デフォルトの “home” ディレクトリを設定します。引数の文字列の意味については PYTHONHOME を参照してください。

引数は静的なストレージに置かれてプログラム実行中に書き換えられないようなゼロ終端の文字列であるべきです。 Python インタプリタはこのストレージの内容を変更しません。

char* Py_GetPythonHome()

前回の Py_SetPythonHome() 呼び出しで設定されたデフォルトの “home” か、 PYTHONHOME 環境変数が設定されていればその値を返します。

スレッド状態 (thread state) とグローバルインタプリタロック (global interpreter lock)

Python インタプリタは完全にはスレッドセーフではありません。マルチスレッドの Python プログラムをサポートするために、グローバルインタプリタロック(global interpreter lock, GIL) と呼ばれるグローバルなロックが存在していて、現在のスレッドが Python オブジェクトに安全にアクセスする前に必ずロックを獲得しなければならなくなっています。ロック機構がなければ、単純な操作でさえ、マルチスレッドプログラムの実行に問題を引き起こす可能性があります。たとえば、二つのスレッドが同じオブジェクトの参照カウントを同時にインクリメントすると、結果的に参照カウントは二回でなく一回だけしかインクリメントされないかもしれません。

このため、 GIL を獲得したスレッドだけが Python オブジェクトを操作したり、 Python/C API 関数を呼び出したりできるというルールがあります。並行処理をエミュレートするために、インタプリタは定期的にロックを解放したり獲得したりします。 (sys.setcheckinterval() を参照) このロックはブロックが起こりうる I/O 操作の付近でも解放・獲得され、 I/O を要求するスレッドが I/O 操作の完了を待つ間、他のスレッドが動作できるようにしています。

Python インタプリタはスレッドごとに必要な情報を PyThreadState と呼ばれるデータ構造の中に保存します。そしてグローバル変数として現在の PyThreadState を指すポインタを1つ持ちます。このグローバル変数は PyThreadState_Get() を使って取得できます。

拡張コード内で GIL を解放する

GIL を操作するほとんどのコードは、次のような単純な構造になります。

スレッド状態をローカル変数に保存する。
GILを解放する。
...ブロックが起きるような何らかの I/O 操作...
GILを獲得する。
ローカル変数からスレッド状態を回復する。

この構造は非常に一般的なので、作業を単純にするために2つのマクロが用意されています:

Py_BEGIN_ALLOW_THREADS
...ブロックが起きるような何らかの I/O 操作...
Py_END_ALLOW_THREADS

Py_BEGIN_ALLOW_THREADS マクロは新たなブロックを開始し、隠しローカル変数を宣言します; Py_END_ALLOW_THREADS はブロックを閉じます。 Python をスレッドサポートなしでコンパイルしたときでもこの2つのマクロは利用可能です。 (単に、空行に展開されます)

スレッドサポートが有効になっている場合、上記のブロックは以下のようなコードに展開されます:

PyThreadState *_save;

_save = PyEval_SaveThread();
...ブロックが起きるような何らかの I/O 操作...
PyEval_RestoreThread(_save);

これらの関数の動作を説明します。 GIL は現在のスレッド状態を指すポインタを保護するために使われます。ロックを解放してスレッド状態を退避する際、ロックを解放する前に現在のスレッド状態ポインタを取得しておかなければなりません (他のスレッドがすぐさまロックを獲得して、自らのスレッド状態をグローバル変数に保存してしまうかもしれないからです)。逆に、ロックを獲得してスレッド状態を復帰する際には、グローバル変数にスレッド状態ポインタを保存する前にロックを獲得しておかなければなりません。

ノート

GIL を解放するのはほとんどがシステムのI/O関数を呼び出す時ですが、メモリバッファに対する圧縮や暗号化のように、 Python のオブジェクトにアクセスしない長時間かかる計算処理を呼び出すときも GIL を解放することは有益です。例えば、 zlib や hashlib モジュールは圧縮やハッシュ計算の前に GIL を開放します。

Python 以外で作られたスレッド

Python API を通して作られたスレッド (threading モジュールなど) では自動的にスレッド状態が割り当てられて、上記のコードは正しく動きます。しかし、(自前でスレッド管理を行う外部のライブラリなどにより)C言語でスレッドを生成した場合、そのスレッドには GIL がなく、スレッド状態データ構造体もないことに注意する必要があります。

このようなスレッドから Python コードを呼び出す必要がある場合 (外部のライブラリからコールバックするAPIなどがよくある例です)、 Python/C API を呼び出す前に、スレッド状態データ構造体を生成し、 GIL を獲得し、スレッド状態ポインタを保存することで、スレッドをインタプリタに登録しなければなりません。スレッドが作業を終えたら、スレッド状態ポインタをリセットして、ロックを解放し、最後にスレッド状態データ構造体のメモリを解放しなければなりません。

PyGILState_Ensure() と PyGILState_Release() はこの処理を自動的に行います。 Cのスレッドから Python を呼び出す典型的な方法は以下のとおりです。

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

/* Perform Python actions here. */
result = CallSomeFunction();
/* evaluate result or handle exception */

/* Release the thread. No Python API allowed beyond this point. */
PyGILState_Release(gstate);

PyGILState_*() 関数は、(Py_Initialize() によって自動的に作られる) グローバルインタプリタ1つだけが存在すると仮定する事に気をつけて下さい。 Python は (Py_NewInterpreter() を使って) 追加のインタプリタを作成できることに変わりはありませんが、複数インタプリタと PyGILState_*() API を混ぜて使うことはサポートされていません。

注意しないといけないもう一つの重要な点は、 C の fork() を呼び出した時の動作です。ほとんどの fork() を持っているシステムでは、fork されたプロセスには fork を実行したスレッドしか存在しません。これは、別のスレッドに取得されたロックがずっと開放されないことを意味します。 Python は fork する前にロックを取得し、その後に fork を開放することでこの問題を解決しています。加えて、子プロセスではすべての Lock オブジェクト をリセットします。 Python を拡張したり埋め込んだりしている場合、 Python に fork 前に取得したり fork 後に開放しなければならない追加の (Python 以外の) ロックを Python に教える手段がありません。 Python と同じことを実現するには、 posix_atfork() のようなOSの機能を使う必要があります。加えて、Python を拡張したり埋め込んだりしているときに、 os.fork() を通してではなく直接 fork() を呼び出すと、fork後に失われるスレッドに取得されていた Python の内部ロックのためにデッドロックが発生するかもしれません。 PyOS_AfterFork() は必要なロックのリセットを試みますが、いつでもそれが可能とは限りません。

高レベルAPI

C拡張を書いたりPythonインタプリタを埋め込むときに最も一般的に使われる型や関数は次のとおりです。

PyInterpreterState

このデータ構造体は、協調動作する多数のスレッド間で共有されている状態を表現します。同じインタプリタに属するスレッドはモジュール管理情報やその他いくつかの内部的な情報を共有しています。この構造体には公開 (public) のメンバはありません。

異なるインタプリタに属するスレッド間では、利用可能なメモリ、開かれているファイルデスクリプタなどといったプロセス状態を除いて、初期状態では何も共有されていません。 GILもまた、スレッドがどのインタプリタに属しているかに関わらずすべてのスレッドで共有されています。

PyThreadState

単一のスレッドの状態を表現する表現するデータ構造体です。スレッドのインタプリタ状態を指すポインタ PyInterpreterState * interp だけが公開されているデータメンバです。

void PyEval_InitThreads()

GIL を初期化し、獲得します。この関数は、主スレッドが第二のスレッドを生成する以前や、 PyEval_ReleaseLock() や PyEval_ReleaseThread(tstate) といった他のスレッド操作に入るよりも前に呼び出されるようにしておかなければなりません。 PyEval_SaveThread(), PyEval_RestoreThread() の前に呼び出す必要はありません。

二度目に呼び出すと何も行いません。この関数を Py_Initialize() の前に呼び出しても安全です。

ノート

主スレッドしか存在しないのであれば、GIL操作は必要ありません。これはよくある状況ですし (ほとんどの Python プログラムはスレッドを使いません)、ロック操作はインタプリタをごくわずかに低速化します。従って、初期状態ではロックは生成されません。ロックを使わない状況は、すでにロックを獲得している状況と同じです: 単一のスレッドしかなければ、オブジェクトへのアクセスは全て安全です。従って、この関数がGILを初期化すると、同時にロックを獲得するようになっています。Python の _thread モジュールは、新たなスレッドを作成する前に、ロックが存在するか、あるいはまだ作成されていないかを調べ、 PyEval_InitThreads() を呼び出します。この関数から処理が戻った場合、ロックが作成され、呼び出し元スレッドがそのロックを獲得している事が保証されています。

どのスレッドが現在 GIL を (存在する場合) 持っているか分からない時にこの関数を使うのは安全では ありません 。

この関数はコンパイル時にスレッドサポートを無効化すると利用できません。

int PyEval_ThreadsInitialized()

PyEval_InitThreads() をすでに呼び出している場合は真 (非ゼロ) を返します。この関数は、GILを獲得せずに呼び出すことができますので、シングルスレッドで実行している場合にはロック関連のAPI呼び出しを避けるために使うことができます。この関数はコンパイル時にスレッドサポートを無効化すると利用できません。

バージョン 2.4 で追加.

PyThreadState* PyEval_SaveThread()

(GIL が生成されていて、スレッドサポートが有効の場合) GILを解放して、スレッド状態を NULL にし、以前のスレッド状態 (NULL にはなりません) を返します。ロックがすでに生成されている場合、現在のスレッドがロックを獲得していなければなりません。 (この関数はコンパイル時にスレッドサポートが無効にされていても利用できます。)

void PyEval_RestoreThread(PyThreadState *tstate)

(GIL が生成されていて、スレッドサポートが有効の場合) GIL を獲得して、現在のスレッド状態を tstate に設定します。 tstate は NULL であってはなりません。 GIL が生成されていて、この関数を呼び出したスレッドがすでにロックを獲得している場合、デッドロックに陥ります。 (この関数はコンパイル時にスレッドサポートが無効にされていても利用できます。)

PyThreadState* PyThreadState_Get()

現在のスレッド状態を返します。GIL を保持していなければなりません。現在のスレッド状態が NULL なら、(呼び出し側が NULL チェックをしなくてすむように) この関数は致命的エラーを起こすようになっています。

PyThreadState* PyThreadState_Swap(PyThreadState *tstate)

現在のスレッド状態を tstate に指定したスレッド状態と入れ変えます。 tstate は NULL の場合があります。 GIL を保持していなければならず、開放しません。

void PyEval_ReInitThreads()

この関数は PyOS_AfterFork() から呼び出され、新しい子プロセスが、子プロセス内で実行していないスレッドが持っているロックを持たないようにします。

以下の関数はスレッドローカルストレージを利用していて、サブインタプリタとの互換性がありません。

PyGILState_STATE PyGILState_Ensure()

Pythonの状態やGILに関わらず、実行中スレッドでPython C APIの呼び出しが可能となるようにします。この関数はスレッド内で何度でも呼び出すことができますが、必ず全ての呼び出しに対応して PyGILState_Release() を呼び出す必要があります。

通常、 PyGILState_Ensure() 呼び出しと PyGILState_Release() 呼び出しの間でこれ以外のスレッド関連API を使用することができますが、Release()の前にスレッド状態は復元されていなければなりません。例えば、通常の Py_BEGIN_ALLOW_THREADS マクロと Py_END_ALLOW_THREADS は使用することができます。

戻り値は PyGILState_Ensure() 呼び出し時のスレッド状態を隠蔽した”ハンドル”で、 PyGILState_Release() に渡してPythonを同じ状態に保たなければなりません。再起呼び出しも可能ですが、ハンドルを共有することは できません - それぞれの PyGILState_Ensure() 呼び出しでハンドルを保存し、対応する PyGILState_Release() 呼び出しで渡してください。

関数から復帰したとき、実行中のスレッドはGILを所有していて、任意の Python コードを実行できます。処理の失敗は致命的なエラーです。

バージョン 2.3 で追加.

void PyGILState_Release(PyGILState_STATE)

獲得したすべてのリソースを開放します。この関数を呼び出すと、Pythonの状態は対応する PyGILState_Ensure() を呼び出す前と同じとなります。(通常、この状態は呼び出し元でははわかりませんので、GILState APIを利用するようにしてください。）

PyGILState_Ensure() を呼び出す場合は、必ず同一スレッド内で対応する PyGILState_Release() を呼び出してください。

バージョン 2.3 で追加.

以下のマクロは、通常末尾にセミコロンを付けずに使います; Python ソース配布物内の使用例を見てください。

Py_BEGIN_ALLOW_THREADS

このマクロを展開すると { PyThreadState *_save; _save = PyEval_SaveThread(); になります。マクロに開き波括弧が入っていることに注意してください; この波括弧は後で Py_END_ALLOW_THREADS マクロと対応させなければなりません。マクロについての詳しい議論は上記を参照してください。コンパイル時にスレッドサポートが無効化されていると何も行いません。

Py_END_ALLOW_THREADS

このマクロを展開すると PyEval_RestoreThread(_save); } になります。マクロに開き波括弧が入っていることに注意してください; この波括弧は事前の Py_BEGIN_ALLOW_THREADS マクロと対応していなければなりません。マクロについての詳しい議論は上記を参照してください。コンパイル時にスレッドサポートが無効化されていると何も行いません。

Py_BLOCK_THREADS

このマクロを展開すると PyEval_RestoreThread(_save); になります: 閉じ波括弧のない Py_END_ALLOW_THREADS と同じです。コンパイル時にスレッドサポートが無効化されていると何も行いません。

Py_UNBLOCK_THREADS

このマクロを展開すると _save = PyEval_SaveThread(); になります: 開き波括弧のない Py_BEGIN_ALLOW_THREADS と同じです。コンパイル時にスレッドサポートが無効化されていると何も行いません。

低レベルAPI

以下の全ての関数はコンパイル時にスレッドサポートが有効になっている時だけ利用でき、呼び出すのはGILがすでに作成されている場合だけにしなくてはなりません。

PyInterpreterState* PyInterpreterState_New()

新しいインタプリタ状態オブジェクトを生成します。 GIL を保持しておく必要はありませんが、この関数を次々に呼び出す必要がある場合には保持しておいたほうがよいでしょう。

void PyInterpreterState_Clear(PyInterpreterState *interp)

インタプリタ状態オブジェクト内の全ての情報をリセットします。 GIL を保持していなければなりません。

void PyInterpreterState_Delete(PyInterpreterState *interp)

インタプリタ状態オブジェクトを破壊します。GIL を保持しておく必要はありません。インタプリタ状態は PyInterpreterState_Clear() であらかじめリセットしておかなければなりません。

PyThreadState* PyThreadState_New(PyInterpreterState *interp)

指定したインタプリタオブジェクトに属する新たなスレッド状態オブジェクトを生成します。 GIL を保持しておく必要はありませんが、この関数を次々に呼び出す必要がある場合には保持しておいたほうがよいでしょう。

void PyThreadState_Clear(PyThreadState *tstate)

スレッド状態オブジェクト内の全ての情報をリセットします。 GIL を保持していなければなりません。

void PyThreadState_Delete(PyThreadState *tstate)

スレッド状態オブジェクトを破壊します。GIL を保持する必要はありません。スレッド状態は PyThreadState_Clear() であらかじめリセットしておかなければなりません。

PyObject* PyThreadState_GetDict()

Return value: Borrowed reference.

拡張モジュールがスレッド固有の状態情報を保存できるような辞書を返します。各々の拡張モジュールが辞書に状態情報を保存するためには唯一のキーを使わねばなりません。現在のスレッド状態がない時にこの関数を呼び出してもかまいません。この関数が NULL を返す場合、例外はまったく送出されず、呼び出し側は現在のスレッド状態が利用できないと考えねばなりません。

バージョン 2.3 で変更: 以前は、現在のスレッドがアクティブなときのみ呼び出せるようになっており、 NULL は例外が送出されたことを意味していました.

int PyThreadState_SetAsyncExc(long id, PyObject *exc)

スレッド内で非同期的に例外を送出します。 id 引数はターゲットとなるスレッドのスレッド id です; exc は送出する例外オブジェクトです。この関数は exc に対する参照を一切盗み取りません。素朴な間違いを防ぐため、この関数を呼び出すには独自に C 拡張モジュールを書かねばなりません。 GIL を保持した状態で呼び出さなければなりません。

変更を受けたスレッド状態の数を返します; これは普通は1ですが、スレッドidが見つからなかった場合は0になります。もし exc が NULL であれば、そのスレッドで保留されている例外があればクリアします。この場合は例外は発生しません。

バージョン 2.3 で追加.

void PyEval_AcquireThread(PyThreadState *tstate)

GIL を獲得し、現在のスレッド状態を tstate に設定します。 tstate は NULL であってはなりません。ロックはあらかじめ作成されていなければなりません。この関数を呼び出したスレッドがすでにロックを獲得している場合、デッドロックに陥ります。

PyEval_RestoreThread() はより高レベルな関数で常に(スレッドサポートが無効な場合やスレッドが初期化されていない場合でも)利用できます。

void PyEval_ReleaseThread(PyThreadState *tstate)

現在のスレッド状態をリセットして NULL にし、GIL を解放します。ロックはあらかじめ作成されていなければならず、かつ現在のスレッドが保持していなければなりません。 tstate は NULL であってはなりませんが、その値が現在のスレッド状態を表現しているかどうかを調べるためにだけ使われます — もしそうでなければ、致命的エラーが報告されます。

PyEval_SaveThread() はより高レベルな関数で常に(スレッドサポートが無効な場合やスレッドが初期化されていない場合でも)利用できます。

void PyEval_AcquireLock()

GILを獲得します。ロックは前もって作成されていなければなりません。この関数を呼び出したスレッドがすでにロックを獲得している場合、デッドロックに陥ります。

警告

この関数は現在のスレッド状態を変更しません。代わりに PyEval_RestoreThread() か PyEval_AcquireThread() を利用してください。

void PyEval_ReleaseLock()

GILを解放します。ロックは前もって作成されていなければなりません。

警告

この関数は現在のスレッド状態を変更しません。代わりに PyEval_SaveThread() か PyEval_ReleaseThread() を利用してください。

サブインタプリタサポート

ほとんどの場合は埋め込む Python インタプリタは1つだけですが、いくつかの場合に同一プロセス内、あるいは同一スレッド内で、複数の独立したインタプリタを作成する必要があります。サブインタプリタはこれを可能にします。 PyThreadState_Swap() 関数を使ってサブインタプリタを切り替えることができます。以下の関数を使ってサブインタプリタの作成と削除を行えます。

PyThreadState* Py_NewInterpreter()

新しいサブインタプリタ (sub-interpreter) を生成します。サブインタプリタとは、(ほぼ完全に) 個別に分割された Python コードの実行環境です。特に、新しいサブインタプリタは、 import されるモジュール全てについて個別のバージョンを持ち、これには基盤となるモジュール __builtin__, __main__ および sys も含まれます。ロード済みのモジュールからなるテーブル (sys.modules) およびモジュール検索パス (sys.path) もサブインタプリタ毎に別個のものになります。新たなサブインタプリタ環境には sys.argv 変数がありません。また、サブインタプリタは新たな標準 I/O ストリーム sys.stdin, sys.stdout, sys.stderr を持ちます (とはいえ、これらのストリームは根底にある C ライブラリの同じ FILE 構造体を参照しています)。

戻り値は、新たなサブインタプリタが生成したスレッド状態 (thread state) オブジェクトのうち、最初のものを指しています。このスレッド状態が現在のスレッド状態 (current thread state) になります。実際のスレッドが生成されるわけではないので注意してください; 下記のスレッド状態に関する議論を参照してください。新たなインタプリタの生成に失敗すると、 NULL を返します; 例外状態はセットされませんが、これは例外状態が現在のスレッド状態に保存されることになっていて、現在のスレッド状態なるものが存在しないことがあるからです。 (他の Python/C API 関数のように、この関数を呼び出す前にはGILが保持されていなければならず、関数が処理を戻した際にも保持されたままになります; しかし、他の Python/C API 関数とは違い、関数から戻ったときの現在のスレッド状態が関数に入るときと同じとは限らないので注意してください)。

拡張モジュールは以下のような形で (サブ) インタプリタ間で共有されます: ある特定の拡張モジュールを最初に import すると、モジュールを通常通りに初期化し、そのモジュールの辞書の (浅い) コピーをしまい込んでおきます。他の (サブ) インタプリタが同じ拡張モジュールを import すると、新たなモジュールを初期化し、先ほどのコピーの内容で辞書の値を埋めます; 拡張モジュールの init 関数は呼び出されません。この挙動は、 Py_Finalize() および Py_Initialize() を呼び出してインタプリタを完全に再初期化した後に拡張モジュールを import した際の挙動とは異なるので注意してください; 再初期化後に import を行うと、拡張モジュールの initmodule は再度 呼び出されます 。

void Py_EndInterpreter(PyThreadState *tstate)

指定されたスレッド状態 tstate で表現される (サブ) インタプリタを抹消します。 tstate は現在のスレッド状態でなければなりません。下記のスレッド状態に関する議論を参照してください。関数呼び出しが戻ったとき、現在のスレッド状態は NULL になっています。このインタプリタに関連付けられた全てのスレッド状態は抹消されます。 (この関数を呼び出す前にはGILを保持しておかねばならず、ロックは関数が戻ったときも保持されています。) Py_Finalize() は、その時点で明示的に抹消されていない全てのサブインタプリタを抹消します。

バグと注意事項

サブインタプリタ (とメインインタプリタ) は同じプロセスの一部分なので、インタプリタ間の隔離は完璧ではありません — 例えば、 os.close() のような低レベルのファイル操作を使うと、 (偶然なり故意なりに) 互いのインタプリタ下にある開かれたファイルに影響を及ぼせてしまいます。拡張モジュールを (サブ) インタプリタ間で共有する方法のせいで、拡張モジュールによっては正しく動作しないかもしれません; 拡張モジュールが (静的な) グローバル変数を利用している場合や、拡張モジュールが初期化後に自身のモジュール辞書を操作する場合には特にそうです。一つのサブインタプリタで生成されたオブジェクトは他のサブインタプリタの名前空間への挿入が可能です; ユーザ定義関数、メソッド、インスタンスおよびクラスをサブインタプリタをサブインタプリタ間で共有しないように十分注意してください。というのは、これらの共有オブジェクトが実行した import 文は間違った (サブ) インタプリタのロード済みモジュール辞書に影響を及ぼす場合があるからです。

サブインタプリタを PyGILState_*() API と組み合わせるのが難しいことにも注意してください。これらのAPIはPythonのスレッド状態とOSレベルスレッドが1対1で対応していることを前提にしていて、サブインタプリタが存在するとその前提が崩れるからです。対応する PyGILState_Ensure() と PyGILState_Release() の呼び出しのペアの間では、サブインタプリタの切り替えを行わないことを強く推奨します。さらに、(ctypes のような)これらのAPIを使ってPythonの外で作られたスレッドから Pythonコードを実行している拡張モジュールはサブインタプリタを使うと壊れる可能性があります。

非同期通知

メインのインタプリタスレッドへの非同期通知機構が提供されています。この通知は関数ポインタと void 引数の形をしています。

各チェックインターバルにおいて、GILがリリースされて再取得されるときに、 Python はそのような提供された関数を呼び出します。この関数は例えば非同期IOハンドラなどが利用できます。通知はワーカースレッドなどからスケジュールされ、実際の呼び出しはメインスレッドで最初の、GILを所有していて任意の Python API 呼び出しが可能なタイミングで実行されます。

int Py_AddPendingCall(int (*func)(void *), void *arg)

Python のメインスレッドへの通知を登録します。成功した場合、 func は引数 arg と共に、最初の適切なタイミングで呼び出されます。 func は GIL を取得した状態で呼び出されるので、任意の Python API を利用することができ、オブジェクトの属性にIOの完了を知らせるなど、任意の動作をすることができます。通知関数は成功したときには 0 を、例外を通知するときには -1 を返さなければなりません。通知関数は他の通知関数を再帰的に実行するために割り込まれることはありませんが、たとえばPythonコードをコールバックしたときにGILを開放して他のスレッドに切り替えられる可能性はあります。

この関数は成功して通知関数がスケジュールされたときは 0 を返します。それ以外の場合、たとえば通知バッファがいっぱいのときは、例外を設定せずに -1 を返します。

この関数はどのスレッドからでも、 Python スレッドでもそれ以外のシステムスレッドからでも呼び出すことができます。 Python スレッドから呼び出される場合は、GILを確保していてもいなくてもかまいません。

バージョン 2.7 で追加.

プロファイルとトレース (profiling and tracing)

Python インタプリタは、プロファイル: 分析 (profile) や実行のトレース: 追跡 (trace) といった機能を組み込むために低水準のサポートを提供しています。このサポートは、プロファイルやデバッグ、適用範囲分析 (coverage analysis) ツールなどに使われます。

Python 2.2 になってから、この機能の実装は実質的に作り直され、 C から呼び出すためのインタフェースが追加されました。この C インタフェースは、プロファイルやトレース作業時に、 Python レベルの呼び出し可能オブジェクトが呼び出されることによるオーバヘッドを避け、直接 C 関数呼び出しが行えるようにしています。プロファイルやトレース機能の本質的な特性は変わっていません; インタフェースではとレース関数をスレッドごとにインストールでき、トレース関数に報告される基本イベント (basic event) は以前のバージョンにおいて Python レベルのトレース関数で報告されていたものと同じです。

int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)

PyEval_SetProfile() および PyEval_SetTrace() を使って登録できるトレース関数の形式です。最初のパラメタはオブジェクトで、登録関数に obj として渡されます。 frame はイベントが属している実行フレームオブジェクトで、 what は定数 PyTrace_CALL, PyTrace_EXCEPTION, PyTrace_LINE, PyTrace_RETURN, PyTrace_C_CALL, PyTrace_C_EXCEPTION, あるいは PyTrace_C_RETURN のいずれかで、 arg は what の値によって以下のように異なります:

what の値 | arg の意味
PyTrace_CALL | 常に NULL です。
PyTrace_EXCEPTION | sys.exc_info() の返す例外情報です。
PyTrace_LINE | 常に NULL です。
PyTrace_RETURN | 呼び出し側に返される予定の値か、例外によって関数を抜ける場合は NULL です。
PyTrace_C_CALL | 呼び出される関数オブジェクト
PyTrace_C_EXCEPTION | 呼び出された関数オブジェクト
PyTrace_C_RETURN | 呼び出された関数オブジェクト

int PyTrace_CALL

関数やメソッドが新たに呼び出されたり、ジェネレータが新たなエントリの処理に入ったことを報告する際の、 Py_tracefunc の what の値です。イテレータやジェネレータ関数の生成は、対応するフレーム内の Python バイトコードに制御の委譲 (control transfer) が起こらないため報告されないので注意してください。

int PyTrace_EXCEPTION

例外が送出された際の Py_tracefunc の what の値です。現在実行されているフレームで例外がセットされ、何らかのバイトコードが処理された後に、 what にこの値がセットされた状態でコールバック関数が呼び出されます。

この結果、例外の伝播によって Python が呼び出しスタックを逆戻りする際に、各フレームから処理が戻るごとにコールバック関数が呼び出されます。トレース関数だけがこれらのイベントを受け取ります; プロファイラはこの種のイベントを必要としません。

int PyTrace_LINE

行番号イベントを報告するときに (プロファイル関数ではなく) トレース関数の what パラメタとして渡す値です。

int PyTrace_RETURN

関数呼び出しが例外の伝播なしに返るときに Py_tracefunc 関数の what パラメタとして渡す値です。

int PyTrace_C_CALL

C関数を呼び出す直前に Py_tracefunc 関数の what パラメタとして渡す値です。

int PyTrace_C_EXCEPTION

C関数が例外を送出したときに Py_tracefunc 関数の what パラメタとして渡す値です。

int PyTrace_C_RETURN

C関数から戻るときに Py_tracefunc 関数の what パラメタとして渡す値です。

void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)

プロファイル関数を func に設定します。 obj パラメタは関数の第一パラメタとして渡され、何らかの Python オブジェクトかまたは NULL になります。プロファイル関数がスレッド状態を維持する必要があるなら、各々のスレッドに異なる obj を使うことで、状態を記憶しておく便利でスレッドセーフな場所を提供できます。プロファイル関数は、モニタされているイベントのうち、行番号イベントを除く全てのイベントに対して呼び出されます。

void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

トレース関数を func にセットします。 PyEval_SetProfile() に似ていますが、トレース関数は行番号イベントを受け取る点が違います。

高度なデバッガサポート (advanced debugger support)

以下の関数は高度なデバッグツールでの使用のためだけのものです。

PyInterpreterState* PyInterpreterState_Head()

インタプリタ状態オブジェクトからなるリストのうち、先頭にあるものを返します。

バージョン 2.2 で追加.

PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)

インタプリタ状態オブジェクトからなるリストのうち、 interp の次にあるものを返します。

バージョン 2.2 で追加.

PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)

インタプリタ interp に関連付けられているスレッドからなるリストのうち、先頭にある PyThreadState オブジェクトを返します。

バージョン 2.2 で追加.

PyThreadState* PyThreadState_Next(PyThreadState *tstate)

tstate と同じ PyInterpreterState オブジェクトに属しているスレッド状態オブジェクトのうち、 tstate の次にあるものを返します。

バージョン 2.2 で追加.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

メモリ管理

概要

Python におけるメモリ管理には、全ての Python オブジェクトとデータ構造が入ったプライベートヒープ (private heap) が必須です。プライベートヒープの管理は、内部的には Python メモリマネージャ (Python memory manager) が確実に行います。Python メモリマネージャには、共有 (sharing)、セグメント分割 (segmentation)、事前割り当て (preallocation)、キャッシュ化 (caching) といった、様々な動的記憶管理の側面を扱うために、個別のコンポーネントがあります。

最低水準層では、素のメモリ操作関数 (raw memory allocator) がオペレーティングシステムのメモリ管理機構とやりとりして、プライベートヒープ内にPython 関連の全てのデータを記憶するのに十分な空きがあるかどうか確認します。素のメモリ操作関数の上には、いくつかのオブジェクト固有のメモリ操作関数があります。これらは同じヒープを操作し、各オブジェクト型固有の事情に合ったメモリ管理ポリシを実装しています。例えば、整数オブジェクトは文字列やタプル、辞書とは違ったやり方でヒープ内で管理されます。というのも、整数には値を記憶する上で特別な要件があり、速度/容量のトレードオフが存在するからです。このように、 Python メモリマネジャは作業のいくつかをオブジェクト固有のメモリ操作関数に委譲しますが、これらの関数がプライベートヒープからはみ出してメモリ管理を行わないようにしています。

重要なのは、たとえユーザがいつもヒープ内のメモリブロックを指すようなオブジェクトポインタを操作しているとしても、Python 用ヒープの管理はインタプリタ自体が行うもので、ユーザがそれを制御する余地はないと理解することです。Python オブジェクトや内部使用されるバッファを入れるためのヒープ空間のメモリ確保は、必要に応じて、Python メモリマネージャがこのドキュメント内で列挙しているPython/C API 関数群を介して行います。

メモリ管理の崩壊を避けるため、拡張モジュールの作者は決して Python オブジェクトを C ライブラリが公開している関数: malloc() 、 calloc() 、 realloc() および free() で操作しようとしてはなりません。こうした関数を使うと、C のメモリ操作関数と Python メモリマネージャとの間で関数呼び出しが交錯します。 C のメモリ操作関数とPython メモリマネージャは異なるアルゴリズムで実装されていて、異なるヒープを操作するため、呼び出しの交錯は致命的な結果を招きます。とはいえ、個別の目的のためなら、 C ライブラリのメモリ操作関数を使って安全にメモリを確保したり解放したりできます。例えば、以下がそのような例です:

PyObject *res;
char *buf = (char *) malloc(BUFSIZ); /* for I/O */

if (buf == NULL)
    return PyErr_NoMemory();
...Do some I/O operation involving buf...
res = PyString_FromString(buf);
free(buf); /* malloc'ed */
return res;

この例では、I/O バッファに対するメモリ要求は C ライブラリのメモリ操作関数を使っています。 Python メモリマネジャは戻り値として返される文字列オブジェクトを確保する時にだけ必要です。

とはいえ、ほとんどの状況では、メモリの操作は Python ヒープに固定して行うよう勧めます。なぜなら、Python ヒープは Python メモリマネジャの管理下にあるからです。例えば、インタプリタを C で書かれた新たなオブジェクト型で拡張する際には、ヒープでのメモリ管理が必要です。 Python ヒープを使った方がよいもう一つの理由として、拡張モジュールが必要としているメモリについて Python メモリマネージャに 情報を提供してほしいということがあります。たとえ必要なメモリが内部的かつ非常に特化した用途に対して排他的に用いられるものだとしても、全てのメモリ操作要求を Python メモリマネージャに委譲すれば、インタプリタはより正確なメモリフットプリント (memory footprint) の全体像を把握できます。その結果、特定の状況では、 Python メモリマネージャがガベージコレクションやメモリのコンパクト化、その他何らかの予防措置といった、適切な動作をトリガできることがあります。上の例で示したように C ライブラリのメモリ操作関数を使うと、 I/O バッファ用に確保したメモリは Python メモリマネージャの管理から完全に外れることに注意してください。

メモリインタフェース

Python ヒープに対してメモリを確保したり解放したりするために、以下の関数セットが利用できます。これらの関数は ANSI C 標準に従ってモデル化されていますが、0 バイトの領域を要求した際の動作についても定義しています:

void* PyMem_Malloc(size_t n)

n バイトをメモリ確保し、確保されたメモリを指す void* 型のポインタを返します。確保要求に失敗した場合には NULL を返します。 0 バイトをリクエストすると、可能ならば独立した非 NULL のポインタを返します。このポインタは PyMem_Malloc(1)() を代わりに呼んだときのようなメモリ領域を指しています。確保されたメモリ領域はいかなる初期化も行われていません。

void* PyMem_Realloc(void *p, size_t n)

p が指しているメモリブロックを n バイトにサイズ変更します。メモリの内容のうち、新旧のサイズのうち小さい方までの領域は変更されません。 p が NULL ならば、この関数は PyMem_Malloc(n)() と等価になります; それ以外の場合で、 n がゼロに等しければ、メモリブロックはサイズ変更されますが、解放されず、非 NULL のポインタを返します。 p の値を NULL にしないのなら、以前呼び出した PyMem_Malloc() や PyMem_Realloc() の返した値でなければなりません。

void PyMem_Free(void *p)

p が指すメモリブロックを解放します。 p は以前呼び出した PyMem_Malloc() や PyMem_Realloc() の返した値でなければなりません。それ以外の場合や、すでに PyMem_Free(p)() を呼び出した後だった場合、未定義の動作になります。 p が NULL なら、何も行いません。

以下に挙げる型対象のマクロは利便性のために提供されているものです。 TYPE は任意の C の型を表します。

TYPE* PyMem_New(TYPE, size_t n)

PyMem_Malloc() と同じですが、 (n * sizeof(TYPE)) バイトのメモリを確保します。 TYPE* に型キャストされたポインタを返します。メモリには何の初期化も行われていません。

TYPE* PyMem_Resize(void *p, TYPE, size_t n)

PyMem_Realloc() と同じですが、 (n * sizeof(TYPE)) バイトにサイズ変更されたメモリを確保します。 TYPE* に型キャストされたポインタを返します。関数が終わったとき、 p は新しいメモリ領域のポインタか、失敗した場合は NULL になります。これは C プリプロセッサのマクロで、 p は常に上書きされます。エラーを処理するときにメモリを失う事を避けるには、 p の元の値を保存しておいてください。

void PyMem_Del(void *p)

PyMem_Free() と同じです。

上記に加えて、C API 関数を介することなく Python メモリ操作関数を直接呼び出すための以下のマクロセットが提供されています。ただし、これらのマクロは Python バージョン間でのバイナリ互換性を保てず、それゆえに拡張モジュールでは撤廃されているので注意してください。

PyMem_MALLOC() 、 PyMem_REALLOC() 、 PyMem_FREE() 。

PyMem_NEW() 、 PyMem_RESIZE() 、 PyMem_DEL() 。

例

最初に述べた関数セットを使って、 概要 節の例を Python ヒープに I/O バッファをメモリ確保するように書き換えたものを以下に示します:

PyObject *res;
char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */

if (buf == NULL)
    return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyString_FromString(buf);
PyMem_Free(buf); /* allocated with PyMem_Malloc */
return res;

同じコードを型対象の関数セットで書いたものを以下に示します:

PyObject *res;
char *buf = PyMem_New(char, BUFSIZ); /* for I/O */

if (buf == NULL)
    return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyString_FromString(buf);
PyMem_Del(buf); /* allocated with PyMem_New */
return res;

上の二つの例では、バッファを常に同じ関数セットに属する関数で操作していることに注意してください。実際、あるメモリブロックに対する操作は、異なるメモリ操作機構を混用する危険を減らすために、同じメモリ API ファミリを使って行うことが必要です。以下のコードには二つのエラーがあり、そのうちの一つには異なるヒープを操作する別のメモリ操作関数を混用しているので 致命的 (Fatal) とラベルづけをしています。

char *buf1 = PyMem_New(char, BUFSIZ);
char *buf2 = (char *) malloc(BUFSIZ);
char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
...
PyMem_Del(buf3);  /* Wrong -- should be PyMem_Free() */
free(buf2);       /* Right -- allocated via malloc() */
free(buf1);       /* Fatal -- should be PyMem_Del()  */

素のメモリブロックを Python ヒープ上で操作する関数に加え、 PyObject_New() 、 PyObject_NewVar() 、および PyObject_Del() を使うと、 Python におけるオブジェクトをメモリ確保したり解放したりできます。

これらの関数については、次章の C による新しいオブジェクト型の定義や実装に関する記述の中で説明します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

オブジェクト実装サポート (object implementation support)

この章では、新しいオブジェクト型 (new object type) を定義する際に使われる関数、型、およびマクロについて説明します。

オブジェクトをヒープ上にメモリ確保する

共通のオブジェクト構造体 (common object structure)

型オブジェクト

数値オブジェクト構造体

マップ型オブジェクト構造体

シーケンスオブジェクト構造体

バッファオブジェクト構造体 (buffer object structure)

循環参照ガベージコレクションをサポートする

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

オブジェクト実装サポート (object implementation support) »

オブジェクトをヒープ上にメモリ確保する

PyObject* _PyObject_New(PyTypeObject *type)

Return value: New reference.

PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size)

Return value: New reference.

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void _PyObject_Del(PyObject *op)

PyObject* PyObject_Init(PyObject *op, PyTypeObject *type)

Return value: Borrowed reference.

新たにメモリ確保されたオブジェクト op に対し、型と初期状態での参照 (initial reference) を初期化します。初期化されたオブジェクトを返します。 type からそのオブジェクトが循環参照ガベージ検出の機能を有する場合、検出機構が監視対象とするオブジェクトのセットに追加されます。オブジェクトの他のフィールドには影響を及ぼしません。

PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size)

Return value: Borrowed reference.

PyObject_Init() の全ての処理を行い、可変サイズオブジェクトの場合には長さ情報も初期化します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

TYPE* PyObject_New(TYPE, PyTypeObject *type)

Return value: New reference.

C 構造体型 TYPE と Python 型オブジェクト type を使って新たな Python オブジェクトをメモリ確保します。 Python オブジェクトヘッダで定義されていないフィールドは初期化されません; オブジェクトの参照カウントは 1 になります。メモリ確保のサイズは型オブジェクトの tp_basicsize で決定します。

TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)

Return value: New reference.

C 構造体型 TYPE と Python 型オブジェクト type を使って新たな Python オブジェクトをメモリ確保します。 Python オブジェクトヘッダで定義されていないフィールドは初期化されません。確保されたメモリは、 TYPE 構造体に加え、vartype の tp_itemsize フィールドで指定されているサイズ中の size フィールドを収容できます。この関数は、例えばタプルのように生成時にサイズを決定できるオブジェクトを実装する際に便利です。一連の複数のフィールドに対するアロケーション操作を一つにして埋め込むと、アロケーション回数が減り、メモリ管理の処理効率が向上します。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void PyObject_Del(PyObject *op)

PyObject_New() や PyObject_NewVar() で確保されたメモリを解放します。この関数は、通常オブジェクトの型に指定されている tp_dealloc ハンドラ内で呼び出します。この関数を呼び出した後では、オブジェクトのメモリ領域はもはや有効な Python オブジェクトを表現してはいないので、オブジェクトのフィールドに対してアクセスしてはなりません。

PyObject* Py_InitModule(char *name, PyMethodDef *methods)

Return value: Borrowed reference.

name と関数のテーブルに基づいて新たなモジュールオブジェクトを生成し、生成されたモジュールオブジェクトを返します。

バージョン 2.3 で変更: 以前のバージョンの Python では、 methods 引数の値として NULL をサポートしていませんでした.

PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc)

Return value: Borrowed reference.

name と関数のテーブルに基づいて新たなモジュールオブジェクトを生成し、生成されたモジュールオブジェクトを返します。 doc が NULL でない場合、モジュールの docstring として使われます。

バージョン 2.3 で変更: 以前のバージョンの Python では、 methods 引数の値として NULL をサポートしていませんでした.

PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver)

Return value: Borrowed reference.

name と関数のテーブルに基づいて新たなモジュールオブジェクトを生成し、生成されたモジュールオブジェクトを返します。 doc が NULL でない場合、モジュールの docstring として使われます。 self が NULL でない場合、モジュール内の各関数の第一引数として渡されます (NULL の時には第一引数も NULL になります)。 (この関数は実験的な機能のために追加されたもので、現在の Python のバージョンで使われてはいないはずです。) apiver に渡してよい値は、 PYTHON_API_VERSION で定義されている定数だけです。

ノート

この関数のほとんどの用途は、代わりに Py_InitModule3() を使えるはずです; 本当にこの関数を使いたいときにだけ利用してください

バージョン 2.3 で変更: 以前のバージョンの Python では、 methods 引数の値として NULL をサポートしていませんでした.

PyObject _Py_NoneStruct

Python からは None に見えるオブジェクトです。この値へのアクセスは、このオブジェクトへのポインタを評価する Py_None マクロを使わねばなりません。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

オブジェクト実装サポート (object implementation support) »

共通のオブジェクト構造体 (common object structure)

Python では、オブジェクト型を定義する上で数多くの構造体が使われます。この節では三つの構造体とその利用方法について説明します。

全ての Python オブジェクトは、オブジェクトのメモリ内表現の先頭部分にある少数のフィールドを完全に共有しています。このフィールドは PyObject および PyVarObject 型で表現されます。 PyObject 型や PyVarObject 型もまた、他の全ての Python オブジェクトを定義する上で直接的・間接的に使われているマクロを使って定義されています。

PyObject

全てのオブジェクト型はこの型を拡張したものです。この型には、あるオブジェクトに対するオブジェクトとしてのポインタを Python から扱う必要がある際に必要な情報が入っています。通常に “リリースされている” ビルドでは、この構造体にはオブジェクトの参照カウントと、オブジェクトに対応する型オブジェクトだけが入っています。

PyObject_HEAD マクロ展開で定義されているフィールドに対応します。

PyVarObject

PyObject を拡張して、 ob_size フィールドを追加したものです。この構造体は、 長さ (length) の概念を持つオブジェクトだけに対して使います。この型が Python/C API で使われることはほとんどありません。 PyObject_VAR_HEAD マクロ展開で定義されているフィールドに対応します。

PyObject および PyVarObject の定義には以下のマクロが使われています:

PyObject_HEAD

PyObject 型のフィールド宣言に展開されるマクロです; 可変でない長さを持つオブジェクトを表現する新たな型を宣言する場合に使います。展開によってどのフィールドが宣言されるかは、 Py_TRACE_REFS の定義に依存します。デフォルトでは、 Py_TRACE_REFS は定義されておらず、 PyObject_HEAD は以下のコードに展開されます:

Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;

Py_TRACE_REFS が定義されている場合、以下のように展開されます:

PyObject *_ob_next, *_ob_prev;
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;

PyObject_VAR_HEAD

マクロです。 PyVarObject 型のフィールド宣言に展開されるマクロです; インスタンスによって可変の長さを持つオブジェクトを表現する新たな型を宣言する場合に使います。マクロは常に以下のように展開されます:

PyObject_HEAD
Py_ssize_t ob_size;

マクロ展開結果の一部に PyObject_HEAD が含まれており、 PyObject_HEAD の展開結果は Py_TRACE_REFS の定義に依存します。

PyObject_HEAD_INIT(type)

新しい PyObject 型のための初期値に展開するマクロです。このマクロは次のように展開されます。

_PyObject_EXTRA_INIT
1, type,

PyVarObject_HEAD_INIT(type, size)

新しい、 ob_size フィールドを含む PyVarObject 型のための初期値に展開するマクロです。このマクロは次のように展開されます。

_PyObject_EXTRA_INIT
1, type, size,

PyCFunction

ほとんどの Python の呼び出し可能オブジェクトを C で実装する際に用いられている関数の型です。この型の関数は二つの PyObject* 型パラメタをとり、 PyObject* 型の値を返します。戻り値を NULL にする場合、例外をセットしておかなければなりません。 NULL でない値を返す場合、戻り値は Python に関数の戻り値として公開される値として解釈されます。この型の関数は新たな参照を返さなければなりません。

PyMethodDef

拡張型のメソッドを記述する際に用いる構造体です。この構造体には 4 つのフィールドがあります:

フィールド | C データ型 | 意味
ml_name | char * | メソッド名
ml_meth | PyCFunction | C 実装へのポインタ
ml_flags | int | 呼び出しをどのように行うかを示すフラグビット
ml_doc | char * | docstring の内容を指すポインタ

ml_meth は C の関数ポインタです。関数は別の型で定義されていてもかまいませんが、常に PyObject* を返します。関数が PyFunction でない場合、メソッドテーブル内でキャストを行うようコンパイラが要求することになるでしょう。 PyCFunction では最初のパラメタが PyObject* 型であると定義していますが、固有の C 型を self オブジェクトに使う実装はよく行われています。

ml_flags フィールドはビットフィールドで、以下のフラグが入ります。個々のフラグは呼び出し規約 (calling convention) や束縛規約 (binding convention) を表します。呼び出し規約フラグでは、 METH_VARARGS および METH_KEYWORDS を組み合わせられます (ただし、 METH_KEYWORDS 単体の指定を行っても METH_VARARGS | METH_KEYWORDS と同じなので注意してください)。呼び出し規約フラグは束縛フラグと組み合わせられます。

METH_VARARGS

PyCFunction 型のメソッドで典型的に使われる呼び出し規約です。関数は PyObject* 型の引数値を二つ要求します。最初の引数はメソッドの self オブジェクトです; モジュール関数の場合、これはモジュールオブジェクトです。第二のパラメタ (よく args と呼ばれます) は、全ての引数を表現するタプルオブジェクトです。パラメタは通常、 PyArg_ParseTuple() や PyArg_UnpackTuple() で処理されます。

METH_KEYWORDS

このフラグを持つメソッドは PyCFunctionWithKeywords 型でなければなりません。 PyCFunctionWithKeywords は三つのパラメタ:self 、 args 、およびキーワード引数全てからなる辞書、を要求します。このフラグは通常 METH_VARARGS と組み合わされ、パラメタは PyArg_ParseTupleAndKeywords() で処理されます。

METH_NOARGS

引数のないメソッドは、 METH_NOARGS フラグをつけた場合、必要な引数が指定されているかをチェックしなくなります。こうしたメソッドは PyCFunction 型でなくてはなりません。第一のパラメタは self になり、モジュールかオブジェクトインスタンスへの参照を保持することになります。いずれにせよ、第二のパラメタは NULL になります。

METH_O

単一のオブジェクト引数だけをとるメソッドは、 PyArg_ParseTuple() を引数 "O" にして呼び出す代わりに、 METH_O フラグつきで指定できます。メソッドは PyCFunction 型で、 self パラメタと単一の引数を表現する PyObject* パラメタを伴います。

METH_OLDARGS

この呼び出し規約は撤廃されました。メソッドは PyCFunction 型でなければなりません。第二引数は、引数がない場合には NULL 、単一の引数の場合にはその引数オブジェクト、複数個の引数の場合には引数オブジェクトからなるタプルです。この呼び出し規約を使うと、複数個の引数の場合と、単一のタプルが唯一引数の場合を区別できなくなってしまいます。

以下の二つの定数は、呼び出し規約を示すものではなく、クラスのメソッドとして使う際の束縛方式を示すものです。モジュールに対して定義された関数で用いてはなりません。メソッドに対しては、最大で一つしかこのフラグをセットできません。

METH_CLASS

メソッドの最初の引数には、型のインスタンスではなく型オブジェクトが渡されます。このフラグは組み込み関数 classmethod() を使って生成するのと同じ クラスメソッド (class method) を生成するために使われます。

バージョン 2.3 で追加.

METH_STATIC

メソッドの最初の引数には、型のインスタンスではなく NULL が渡されます。このフラグは、 staticmethod() を使って生成するのと同じ 静的メソッド (static method) を生成するために使われます。

バージョン 2.3 で追加.

もう一つの定数は、あるメソッドを同名の別のメソッド定義と置き換えるかどうかを制御します。

METH_COEXIST

メソッドを既存の定義を置き換える形でロードします。 METH_COEXIST を指定しなければ、デフォルトの設定にしたがって、定義が重複しないようスキップします。スロットラッパはメソッドテーブルよりも前にロードされるので、例えば sq_contains スロットはラップしているメソッド __contains__() を生成し、同名の PyCFunction のロードを阻止します。このフラグを定義すると、 PyCFunction はラッパオブジェクトを置き換える形でロードされ、スロットと連立します。 PyCFunctions の呼び出しはラッパオブジェクトの呼び出しよりも最適化されているので、こうした仕様が便利になります。

バージョン 2.4 で追加.

PyMemberDef

type の C 構造体のメンバとして格納されている、ある型の属性を表す構造体です。この構造体のフィールドは以下のとおりです:

フィールド | C の型 | 意味
name | char * | メンバ名
type | int | C 構造体の中のメンバの型
offset | Py_ssize_t | そのメンバの type object 構造体中の場所の offset バイト数
flags | int | フィールドが読み込み専用か書込み可能なのかを示すビットフラグ
doc | char * | docstring の内容へのポインタ

type はたくさんのCの型を意味する T_ マクロのうちの1つです。メンバが Python からアクセスされるとき、そのメンバは対応する Python の型に変換されます。

マクロ名 | Cの型
T_SHORT | short
T_INT | int
T_LONG | long
T_FLOAT | float
T_DOUBLE | double
T_STRING | char *
T_OBJECT | PyObject *
T_OBJECT_EX | PyObject *
T_CHAR | char
T_BYTE | char
T_UBYTE | unsigned char
T_UINT | unsigned int
T_USHORT | unsigned short
T_ULONG | unsigned long
T_BOOL | char
T_LONGLONG | long long
T_ULONGLONG | unsigned long long
T_PYSSIZET | Py_ssize_t

T_OBJECT と T_OBJECT_EX については、 T_OBJECT がメンバが NULL だったときに None を返すのに対し、 T_OBJECT_EX は AttributeError を発生させる点が異なります。 T_OBJECT_EX は属性に対する del 文をより正しくあつかうので、できれば T_OBJECT よりも T_OBJECT_EX を使ってください。

flags には読み書きアクセス可能なら 0 で、読み込み専用なら READONLY を設定します。 type に T_STRING を使うと、強制的に READONLY 扱いになります。 T_OBJECT and T_OBJECT_EX メンバだけが del 可能です。 (NULL が代入されます).

PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)

Return value: New reference.

C で実装された拡張型の束縛メソッドオブジェクトを返します。 PyObject_GenericGetAttr() 関数を使わない tp_getattro や tp_getattr ハンドラを実装する際に便利です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

オブジェクト実装サポート (object implementation support) »

型オブジェクト

新スタイルの型を定義する構造体: PyTypeObject 構造体は、おそらく Python オブジェクトシステムの中で最も重要な構造体の1つでしょう。型オブジェクトは PyObject_*() 系や PyType_*() 系の関数で扱えますが、ほとんどの Python アプリケーションにとって、さして面白みのある機能を提供しません。型オブジェクトはオブジェクトがどのように振舞うかを決める基盤ですから、インタプリタ自体や新たな型を定義する拡張モジュールでは非常に重要な存在です。

型オブジェクトは標準の型 (standard type) に比べるとかなり大きな構造体です。各型オブジェクトは多くの値を保持しており、そのほとんどは C 関数へのポインタで、それぞれの関数はその型の機能の小さい部分を実装しています。この節では、型オブジェクトの各フィールドについて詳細を説明します。各フィールドは、構造体内で出現する順番に説明されています。

Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, freefunc, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc

PyTypeObject の構造体定義は Include/object.h で見つけられるはずです。参照の手間を省くために、ここでは定義を繰り返します:

typedef struct _typeobject {
    PyObject_VAR_HEAD
    char *tp_name; /* For printing, in format "<module>.<name>" */
    int tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    printfunc tp_print;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    cmpfunc tp_compare;
    reprfunc tp_repr;

    /* Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* More standard operations (here for binary compatibility) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Functions to access object as input/output buffer */
    PyBufferProcs *tp_as_buffer;

    /* Flags to define presence of optional/expanded features */
    long tp_flags;

    char *tp_doc; /* Documentation string */

    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    long tp_weaklistoffset;

    /* Added in release 2.2 */
    /* Iterators */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Attribute descriptor and subclassing stuff */
    struct PyMethodDef *tp_methods;
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset;
    struct _typeobject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    long tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Low-level free-memory routine */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* method resolution order */
    PyObject *tp_cache;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;

} PyTypeObject;

型オブジェクト構造体は PyVarObject 構造体を拡張したものです。 ob_size フィールドは、(通常 class 文が呼び出す type_new() で生成される) 動的な型に使います。 PyType_Type (メタタイプ) は tp_itemsize を初期化するので注意してください。すなわち、インスタンス (つまり型オブジェクト) には ob_size フィールドがなければ なりません 。

PyObject* PyObject._ob_next

PyObject* PyObject._ob_prev

これらのフィールドはマクロ Py_TRACE_REFS が定義されている場合のみ存在します。 PyObject_HEAD_INIT マクロを使うと、フィールドを NULL に初期化します。静的にメモリ確保されているオブジェクトでは、これらのフィールドは常に NULL のままです。動的にメモリ確保されるオブジェクトの場合、これら二つのフィールドは、ヒープ上の 全ての 存続中のオブジェクトからなる二重リンクリストでオブジェクトをリンクする際に使われます。このことは様々なデバッグ目的に利用できます; 現状では、環境変数 PYTHONDUMPREFS が設定されているときに、プログラムの実行終了時点で存続しているオブジェクトを出力するのが唯一の用例です。

サブタイプはこのフィールドを継承しません。

Py_ssize_t PyObject.ob_refcnt

型オブジェクトの参照カウントで、 PyObject_HEAD_INIT はこの値を 1 に初期化します。静的にメモリ確保された型オブジェクトでは、型のインスタンス (ob_type が該当する型を指しているオブジェクト) は参照をカウントする対象には なりません 。動的にメモリ確保される型オブジェクトの場合、インスタンスは参照カウントの対象に なります 。

サブタイプはこのフィールドを継承しません。

バージョン 2.5 で変更: このフィールドは以前は int でした。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

PyTypeObject* PyObject.ob_type

型自体の型、別の言い方をするとメタタイプです。 PyObject_HEAD_INIT マクロで初期化され、通常は &PyType_Type になります。しかし、(少なくとも) Windows で利用できる動的ロード可能な拡張モジュールでは、コンパイラは有効な初期化ではないと文句をつけます。そこで、ならわしとして、 PyObject_HEAD_INIT には NULL を渡して初期化しておき、他の操作を行う前にモジュールの初期化関数で明示的にこのフィールドを初期化することになっています。この操作は以下のように行います:

Foo_Type.ob_type = &PyType_Type;

上の操作は、該当する型のいかなるインスタンス生成よりも前にしておかねばなりません。 PyType_Ready() は ob_type が NULL かどうか調べ、 NULL の場合には初期化します: Python 2.2 では、 &PyType_Type にセットします; in Python 2.2.1 およびそれ以降では基底クラスの ob_type フィールドに初期化します。 ob_type が非ゼロの場合、 PyType_Ready() はこのフィールドを変更しません。

Python 2.2 では、サブタイプはこのフィールドを継承しません。 2.2.1 と 2.3 以降では、サブタイプはこのフィールドを継承します。

Py_ssize_t PyVarObject.ob_size

静的にメモリ確保されている型オブジェクトの場合、このフィールドはゼロに初期化されます。動的にメモリ確保されている型オブジェクトの場合、このフィールドは内部使用される特殊な意味を持ちます。

サブタイプはこのフィールドを継承しません。

char* PyTypeObject.tp_name

型の名前が入っている NUL 終端された文字列へのポインタです。モジュールのグローバル変数としてアクセスできる型の場合、この文字列は完全なモジュール名、ドット、そして型の名前と続く文字列になります; 組み込み型の場合、ただの型の名前です。モジュールがあるパッケージのサブモジュールの場合、完全なパッケージ名が完全なモジュール名の一部になっています。例えば、パッケージ P 内のサブモジュール Q に入っているモジュール M 内で定義されている T は、 tp_name を "P.Q.M.T" に初期化します。

動的にメモリ確保される型オブジェクトの場合、このフィールドは単に型の名前になり、モジュール名は型の辞書内でキー '__module__' に対する値として明示的に保存されます。

静的にメモリ確保される型オブジェクトの場合、 tp_name フィールドにはドットが入っているはずです。最後のドットよりも前にある部分文字列全体は __module__ 属性として、またドットよりも後ろにある部分は __name__ 属性としてアクセスできます。

ドットが入っていない場合、 tp_name フィールドの内容全てが __name__ 属性になり、 __module__ 属性は (前述のように型の辞書内で明示的にセットしないかぎり) 未定義になります。このため、こうした型オブジェクトは pickle 化できないことになります。

サブタイプはこのフィールドを継承しません。

Py_ssize_t PyTypeObject.tp_basicsize

Py_ssize_t PyTypeObject.tp_itemsize

これらのフィールドは、型インスタンスのバイトサイズを計算できるようにします。

型には二つの種類があります: 固定長インスタンスの型は、 tp_itemsize フィールドがゼロで、可変長インスタンスの方は tp_itemsize フィールドが非ゼロの値になります。固定長インスタンスの型の場合、全てのインスタンスは等しく tp_basicsize で与えられたサイズになります。

可変長インスタンスの型の場合、インスタンスには ob_size フィールドがなくてはならず、インスタンスのサイズは N をオブジェクトの “長さ” として、 tp_basicsize と N かける tp_itemsize の加算になります。N の値は通常、インスタンスの ob_size フィールドに記憶されます。ただし例外がいくつかあります: 例えば、長整数では負の値を ob_size に使って、インスタンスの表す値が負であることを示し、 N 自体は abs(ob_size) になります。また、 ob_size フィールドがあるからといって、必ずしもインスタンスが可変長であることを意味しません (例えば、リスト型の構造体は固定長のインスタンスになるにもかかわらず、インスタンスにはちゃんと意味を持った ob_size フィールドがあります)。

基本サイズには、 PyObject_HEAD マクロまたは PyObject_VAR_HEAD マクロ (インスタンス構造体を宣言するのに使ったどちらかのマクロ) で宣言されているフィールドが入っています。さらに、 _ob_prev および _ob_next フィールドがある場合、これらのフィールドもサイズに加算されます。

従って、 tp_basicsize の正しい初期化パラメタを得るには、インスタンスデータのレイアウトを宣言するのに使う構造体に対して sizeof 演算子を使うしかありません。基本サイズには、GC ヘッダサイズは入っていません (これは Python 2.2 からの新しい仕様です; 2.1 や 2.0 では、GC ヘッダサイズは tp_basicsize に入っていました)。

これらのフィールドはサブタイプに別々に継承されます。基底タイプが 0 でない tp_itemsize を持っていた場合、基底タイプの実装に依存しますが、一般的にはサブタイプで別の 0 で無い値を tp_itemsize に設定するのは安全ではありません。

バイト整列 (alignment) に関する注釈: 変数の各要素を配置する際に特定のバイト整列が必要となる場合、 tp_basicsize の値に気をつけなければなりません。一例: 例えばある型が double の配列を実装しているとします。 tp_itemsize は sizeof(double) です。(double のバイト整列条件に従って) tp_basicsize が sizeof(double) の個数分のサイズになるようにするのはプログラマの責任です。

destructor PyTypeObject.tp_dealloc

インスタンスのデストラクタ関数へのポインタです。この関数は (単量子 None や Ellipsis の場合のように) インスタンスが決してメモリ解放されない型でない限り必ず定義しなければなりません。

デストラクタ関数は、 Py_DECREF() や Py_XDECREF() マクロで、操作後の参照カウントがゼロになった際に呼び出されます。呼び出された時点では、インスタンスはまだ存在しますが、インスタンスに対する参照は全くない状態です。デストラクタ関数はインスタンスが保持している全ての参照を解放し、インスタンスが確保している全てのメモリバッファを (バッファの確保時に使った関数に対応するメモリ解放関数を使って) 解放し、最後に (かならず最後に行う操作として) その型の tp_free 関数を呼び出します。ある型がサブタイプを作成できない (Py_TPFLAGS_BASETYPE フラグがセットされていない) 場合、 tp_free の代わりにオブジェクトのメモリ解放関数 (deallocator) を直接呼び出してもかまいません。オブジェクトのメモリ解放関数は、インスタンスのメモリ確保を行う際に使った関数と同じファミリでなければなりません; インスタンスを PyObject_New() や PyObject_VarNew() でメモリ確保した場合には、通常 PyObject_Del() を使い、 PyObject_GC_New() や PyObject_GC_NewVar() で確保した場合には PyObject_GC_Del() を使います。

サブタイプはこのフィールドを継承します。

printfunc PyTypeObject.tp_print

オプションのフィールドで、インスタンスの出力 (print) を行う関数を指すポインタです。

出力関数は、インスタンスが 実体のある (real) ファイルに出力される場合にのみ呼び出されます; (StringIO インスタンスのような) 擬似ファイルに出力される場合には、インスタンスの tp_repr や tp_str が指す関数が呼び出され、文字列への変換を行います。また、 tp_print が NULL の場合にもこれらの関数が呼び出されます。 tp_repr や tp_str と異なる出力を生成するような tp_print は、決して型に実装してはなりません。

出力関数は PyObject_Print() と同じシグネチャ: int tp_print(PyObject *self, FILE *file, int flags) で呼び出されます。 self 引数は出力するインスタンスを指します。 file 引数は出力先となる標準入出力 (stdio) ファイルです。 flags 引数はフラグビットを組み合わせた値です。現在定義されているフラグビットは Py_PRINT_RAW のみです。 Py_PRINT_RAW フラグビットがセットされていれば、 インスタンスは tp_str と同じ書式で出力されます。 Py_PRINT_RAW フラグビットがクリアならば、インスタンスは tp_repr と同じ書式で出力されます。この関数は、操作中にエラーが生じた場合、 -1 を返して例外状態をセットしなければなりません。

tp_print フィールドは撤廃されるかもしれません。いずれにせよ、 tp_print は定義せず、代わりに tp_repr や tp_str に頼って出力を行うようにしてください。

サブタイプはこのフィールドを継承します。

getattrfunc PyTypeObject.tp_getattr

オプションのフィールドです。ポインタで、 get-attribute-string を行う関数を指します。

このフィールドは撤廃されています。このフィールドを定義する場合、 tp_getattro 関数と同じように動作し、属性名は Python 文字列オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。シグネチャは PyObject_GetAttrString() と同じです。

このフィールドは tp_getattro と共にサブタイプに継承されます: すなわち、サブタイプの tp_getattr および tp_getattro が共に NULL の場合、サブタイプは基底タイプから tp_getattr と tp_getattro を一緒に継承します。

setattrfunc PyTypeObject.tp_setattr

オプションのフィールドです。ポインタで、 set-attribute-string を行う関数を指します。

このフィールドは撤廃されています。このフィールドを定義する場合、 tp_setattro 関数と同じように動作し、属性名は Python 文字列オブジェクトではなく C 文字列で指定するような関数を指すようにしなければなりません。シグネチャは PyObject_SetAttrString() と同じです。

このフィールドは tp_setattro と共にサブタイプに継承されます: すなわち、サブタイプの tp_setattr および tp_setattro が共に NULL の場合、サブタイプは基底タイプから tp_setattr と tp_setattro を一緒に継承します。

cmpfunc PyTypeObject.tp_compare

オプションのフィールドです。ポインタで、三値比較 (three-way comparison) を行う関数を指します。

シグネチャは PyObject_Compare() と同じです。この関数は self が other よりも大きければ 1, self と other の値が等しければ 0, self が other より小さければ -1 を返します。この関数は、比較操作中にエラーが生じた場合、例外状態をセットして -1 を返さねばなりません。

このフィールドは tp_richcompare および tp_hash と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。

reprfunc PyTypeObject.tp_repr

オプションのフィールドです。ポインタで、組み込み関数 repr() を実装している関数を指します。

シグネチャは PyObject_Repr() と同じです。この関数は文字列オブジェクトか Unicode オブジェクトを返さねばなりません。理想的には、この関数が返す文字列は、適切な環境で eval() に渡した場合、同じ値を持つオブジェクトになるような文字列でなければなりません。不可能な場合には、オブジェクトの型と値から導出した内容の入った '<' から始まって '>' で終わる文字列を返さねばなりません。

このフィールドが設定されていない場合、 <%s object at %p> の形式をとる文字列が返されます。 %s は型の名前に、 %p はオブジェクトのメモリアドレスに置き換えられます。

サブタイプはこのフィールドを継承します。

PyNumberMethods* tp_as_number

数値プロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては 数値オブジェクト構造体 で説明されています。

tp_as_number フィールドは継承されませんが、そこの含まれるフィールドが個別に継承されます。

PySequenceMethods* tp_as_sequence

シーケンスプロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては シーケンスオブジェクト構造体 で説明されています。

tp_as_sequence フィールドは継承されませんが、そこの含まれるフィールドが個別に継承されます。

PyMappingMethods* tp_as_mapping

マッピングプロトコルを実装した追加の構造体を指すポインタです。これらのフィールドについては マップ型オブジェクト構造体 で説明されています。

tp_as_mapping フィールドは継承されませんが、そこの含まれるフィールドが個別に継承されます。

hashfunc PyTypeObject.tp_hash

オプションのフィールドです。ポインタで、組み込み関数 hash() を実装している関数を指します。

シグネチャは PyObject_Hash() と同じです。この関数は C の long 型の値を返さねばなりません。通常時には -1 を戻り値にしてはなりません; ハッシュ値の計算中にエラーが生じた場合、関数は例外をセットして -1 を返さねばなりません。

このフィールドは明示的に PyObject_HashNotImplemented() に設定することで、親 type からのハッシュメソッドの継承をブロックすることができます。これは Python レベルでの __hash__ = None と同等に解釈され、 isinstance(o, collections.Hashable) が正しく False を返すようになります。逆もまた可能であることに注意してください - Python レベルで __hash__ = None を設定することで tp_hash スロットは PyObject_HashNotImplemented() に設定されます。

このフィールドが設定されていない場合、二つの可能性があります: tp_compare および tp_richcompare フィールドの両方が NULL の場合、オブジェクトのアドレスに基づいたデフォルトのハッシュ値が返されます; それ以外の場合、 TypeError が送出されます。

このフィールドは tp_compare および tp_richcompare と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。

ternaryfunc PyTypeObject.tp_call

オプションのフィールドです。ポインタで、オブジェクトの呼び出しを実装している関数を指します。オブジェクトが呼び出し可能でない場合には NULL にしなければなりません。シグネチャは PyObject_Call() と同じです。

サブタイプはこのフィールドを継承します。

reprfunc PyTypeObject.tp_str

オプションのフィールドです。ポインタで、組み込みの演算 str() を実装している関数を指します。(str が型の一つになったため、 str() は str のコンストラクタを呼び出すことに注意してください。このコンストラクタは実際の処理を行う上で PyObject_Str() を呼び出し、さらに PyObject_Str() がこのハンドラを呼び出すことになります。)

シグネチャは PyObject_Str() と同じです; この関数は文字列オブジェクトか Unicode オブジェクトを返さねばなりません。また、この関数はオブジェクトを “分かりやすく (friendly)” 表現した文字列を返さねばなりません。というのは、この文字列は print 文で使われることになる表記だからです。

このフィールドが設定されていない場合、文字列表現を返すためには PyObject_Repr() が呼び出されます。

サブタイプはこのフィールドを継承します。

getattrofunc PyTypeObject.tp_getattro

オプションのフィールドです。ポインタで、 get-attribute を実装している関数を指します。

シグネチャは PyObject_GetAttr() と同じです。対する通常の属性検索を実装している PyObject_GenericGetAttr() をこのフィールドに設定しておくと往々にして便利です。

このフィールドは tp_getattr と共にサブタイプに継承されます: すなわち、サブタイプの tp_getattr および tp_getattro が共に NULL の場合、サブタイプは基底タイプから tp_getattr と tp_getattro を一緒に継承します。

setattrofunc PyTypeObject.tp_setattro

オプションのフィールドです。ポインタで、 set-attribute を行う関数を指します。

シグネチャは PyObject_SetAttr() と同じです。対する通常の属性設定を実装している PyObject_GenericSetAttr() をこのフィールドに設定しておくと往々にして便利です。

このフィールドは tp_setattr と共にサブタイプに継承されます: すなわち、サブタイプの tp_setattr および tp_setattro が共に NULL の場合、サブタイプは基底タイプから tp_setattr と tp_setattro を一緒に継承します。

PyBufferProcs* PyTypeObject.tp_as_buffer

バッファインタフェースを実装しているオブジェクトにのみ関連する、一連のフィールド群が入った別の構造体を指すポインタです。構造体内の各フィールドは バッファオブジェクト構造体 (buffer object structure) で説明します。

tp_as_buffer フィールド自体は継承されませんが、フィールド内に入っているフィールドは個別に継承されます。

long PyTypeObject.tp_flags

このフィールドは様々なフラグからなるビットマスクです。いくつかのフラグは、特定の状況において変則的なセマンティクスが適用されることを示します; その他のフラグは、型オブジェクト (あるいは tp_as_number, tp_as_sequence, tp_as_mapping,および tp_as_buffer が参照している拡張機能構造体: extention structure) の特定のフィールドのうち、過去から現在までずっと存在しているわけではないものが有効になっていることを示すために使われます; フラグビットがクリアであれば、フラグが保護しているフィールドにはアクセスしない代わりに、その値はゼロか NULL になっているとみなさなければなりません。

このフィールドの継承は複雑です。ほとんどのフラグビットは個別に継承されます。つまり、基底タイプであるフラグビットがセットされている場合、サブタイプはそのフラグビットを継承します。機能拡張のための構造体に関するフラグビットは、その機能拡張構造体が継承されるときに限定して継承されます。すなわち、基底タイプのフラグビットの値は、機能拡張構造体へのポインタと一緒にサブタイプにコピーされます。 Py_TPFLAGS_HAVE_GC フラグビットは、 tp_traverse および tp_clear フィールドと合わせてコピーされます。すなわち、サブタイプの Py_TPFLAGS_HAVE_GC フラグビットがクリアで、かつ (Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットの指定によって) tp_traverse および tp_clear フィールドがサブタイプ内に存在しており、かつ値が NULL の場合に基底タイプから値を継承します。

以下のビットマスクは現在定義されているものです; フラグは | 演算子で論理和を取って tp_flags フィールドの値にできます。 PyType_HasFeature() マクロは型とフラグ値、 tp および f をとり、 tp->tp_flags & f が非ゼロかどうか調べます。

Py_TPFLAGS_HAVE_GETCHARBUFFER

このビットがセットされていれば、 tp_as_buffer が参照する PyBufferProcs 構造体には bf_getcharbuffer フィールドがあります。

Py_TPFLAGS_HAVE_SEQUENCE_IN

このビットがセットされていれば、 tp_as_sequence が参照する PySequenceMethods 構造体には sq_contains フィールドがあります。

Py_TPFLAGS_GC

このビットは旧式のものです。このシンボルが指し示していたビットはもはや使われていません。シンボルの現在の定義はゼロになっています。

Py_TPFLAGS_HAVE_INPLACEOPS

このビットがセットされていれば、 tp_as_sequence が参照する PySequenceMethods 構造体、および tp_as_number が参照する PyNumberMethods 構造体には in-place 演算に関するフィールドが入っています。具体的に言うと、 PyNumberMethods 構造体はフィールド nb_inplace_add, nb_inplace_subtract, nb_inplace_multiply, nb_inplace_divide, nb_inplace_remainder, nb_inplace_power, nb_inplace_lshift, nb_inplace_rshift, nb_inplace_and, nb_inplace_xor,および nb_inplace_or を持つことになります; また、 PySequenceMethods 構造体はフィールド sq_inplace_concat および sq_inplace_repeat を持つことになります。

Py_TPFLAGS_CHECKTYPES

このビットがセットされていれば、 tp_as_number が参照する PyNumberMethods 構造体内で定義されている二項演算子および三項演算子は任意のオブジェクト型を非演算子にとるようになり、必要に応じて引数の型変換を行います。このビットがクリアなら、演算子は全ての引数が現在のオブジェクト型と同じであるよう要求し、演算の呼び出し側は演算に先立って型変換を行うものと想定します。対象となる演算子は nb_add, nb_subtract, nb_multiply, nb_divide, nb_remainder, nb_divmod, nb_power, nb_lshift, nb_rshift, nb_and, nb_xor,および nb_or です。

Py_TPFLAGS_HAVE_RICHCOMPARE

このビットがセットされていれば、型オブジェクトには tp_richcompare フィールド、そして tp_traverse および tp_clear フィールドがあります。

Py_TPFLAGS_HAVE_WEAKREFS

このビットがセットされていれば、構造体には tp_weaklistoffset フィールドが定義されています。 tp_weaklistoffset フィールドの値がゼロより大きければ、この型のインスタンスは弱参照で参照できます。

Py_TPFLAGS_HAVE_ITER

このビットがセットされていれば、型オブジェクトには tp_iter および tp_iternext フィールドがあります。

Py_TPFLAGS_HAVE_CLASS

このビットがセットされていれば、型オブジェクトは Python 2.2 以降で定義されている新たなフィールド: tp_methods, tp_members, tp_getset, tp_base, tp_dict, tp_descr_get, tp_descr_set, tp_dictoffset, tp_init, tp_alloc, tp_new, tp_free, tp_is_gc, tp_bases, tp_mro, tp_cache, tp_subclasses,および tp_weaklist があります。

Py_TPFLAGS_HEAPTYPE

型オブジェクト自体がヒープにメモリ確保される場合にセットされるビットです。型オブジェクト自体がヒープにメモリ確保される場合、インスタンスの ob_type フィールドは型オブジェクトへの参照とみなされます。この場合、新たなインスタンスを生成する度に型オブジェクトを INCREF し、インスタンスを解放するたびに DECREF します (サブタイプのインスタンスには適当されません; インスタンスが ob_type で参照している型だけが INCREF および DECREF されます)。

Py_TPFLAGS_BASETYPE

型を別の型の基底タイプとして使える場合にセットされるビットです。このビットがクリアならば、この型のサブタイプは生成できません (Java における “final” クラスに似たクラスになります)。

Py_TPFLAGS_READY

型オブジェクトが PyType_Ready() で完全に初期化されるとセットされるビットです。

Py_TPFLAGS_READYING

PyType_Ready() による型オブジェクトの初期化処理中にセットされるビットです。

Py_TPFLAGS_HAVE_GC

オブジェクトがガベージコレクション (GC) をサポートする場合にセットされるビットです。このビットがセットされている場合、インスタンスは PyObject_GC_New() を使って生成し、 PyObject_GC_Del() を使って破壊しなければなりません。詳しい情報は 循環参照ガベージコレクションをサポートする にあります。このビットはまた、GC に関連するフィールド tp_traverse および tp_clear が型オブジェクト内に存在することを示します; しかし、これらのフィールドは Py_TPFLAGS_HAVE_GC がクリアでも Py_TPFLAGS_HAVE_RICHCOMPARE がセットされている場合には存在します。

Py_TPFLAGS_DEFAULT

型オブジェクトおよび拡張機能構造体の特定のフィールドの存在の有無に関連する全てのビットからなるビットマスクです。現状では、このビットマスクには以下のビット: Py_TPFLAGS_HAVE_GETCHARBUFFER, Py_TPFLAGS_HAVE_SEQUENCE_IN, Py_TPFLAGS_HAVE_INPLACEOPS, Py_TPFLAGS_HAVE_RICHCOMPARE, Py_TPFLAGS_HAVE_WEAKREFS, Py_TPFLAGS_HAVE_ITER,および Py_TPFLAGS_HAVE_CLASS が入っています。

char* PyTypeObject.tp_doc

オプションのフィールドです。ポインタで、この型オブジェクトの docstring を与える NUL 終端された C の文字列を指します。この値は型オブジェクトと型のインスタンスにおける __doc__ 属性として公開されます。

サブタイプはこのフィールドを継承 しません 。

以下の三つのフィールドは、 Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合にのみ存在します。

traverseproc PyTypeObject.tp_traverse

オプションのフィールドです。ポインタで、ガベージコレクタのためのトラバーサル関数 (traversal function) を指します。 Py_TPFLAGS_HAVE_GC がセットされている場合にのみ使われます。Pythonのガベージコレクションの枠組みに関する詳細は 循環参照ガベージコレクションをサポートする にあります。

tp_traverse ポインタは、ガベージコレクタが循環参照を見つけるために使われます。 tp_traverse 関数の典型的な実装は、インスタンスの各メンバのうち Pythonオブジェクトに対して Py_VISIT() を呼び出します。例えば、次のコードは thread 拡張モジュールの local_traverse() 関数になります:

static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
    Py_VISIT(self->args);
    Py_VISIT(self->kw);
    Py_VISIT(self->dict);
    return 0;
}

Py_VISIT() が循環参照になる恐れのあるメンバにだけ呼び出されていることに注目してください。 self->key メンバもありますが、それは NULL か Python文字列なので、循環参照の一部になることはありません。

一方、メンバが循環参照の一部になり得ないと判っていても、デバッグ目的で巡回したい場合があるかもしれないので、 gc モジュールの get_reference() 関数は循環参照になり得ないメンバも返します。

Py_VISIT() は local_traverse() が visit と arg という決まった名前の引数を持つことを要求します。

このフィールドは tp_clear および Py_TPFLAGS_HAVE_GC フラグビットと一緒に継承されます: フラグビット、 tp_traverse,および tp_clear の値がサブタイプで全てゼロになっており、 かつサブタイプで Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合に、基底タイプから値を継承します。

inquiry PyTypeObject.tp_clear

オプションのフィールドです。ポインタで、ガベージコレクタにおける消去関数 (clear function) を指します。 Py_TPFLAGS_HAVE_GC がセットされている場合にのみ使われます。

tp_clear メンバ関数はGCが見つけた循環しているゴミの循環参照を壊すために用いられます。システム内の全ての tp_clear 関数によって、全ての循環参照を破壊しなければなりません。 (訳注: ある型が tp_clear を実装しなくても全ての循環参照が破壊できるのであれば実装しなくても良い) これはとても繊細で、もし少しでも不確かな部分があるのであれば、 tp_clear 関数を提供するべきです。例えば、タプルは tp_clear を実装しません。なぜなら、タプルだけで構成された循環参照がみつかることは無いからです。したがって、タプル以外の型 tp_clear 関数たちが、タプルを含むどんな循環参照も破壊できる必要があります。これは簡単に判ることでははありません。 tp_clear の実装を避ける良い理由はめったにありません。

tp_clear の実装は、次の実装のように、インスタンスの (Pythonオブジェクト)メンバに対する参照を捨てて、メンバに対するポインタ変数を NULL にセットするべきです:

static int
local_clear(localobject *self)
{
    Py_CLEAR(self->key);
    Py_CLEAR(self->args);
    Py_CLEAR(self->kw);
    Py_CLEAR(self->dict);
    return 0;
}

参照のクリアはデリケートなので、 Py_CLEAR() マクロを使うべきです: ポインタを NULL にセットするまで、そのオブジェクトの参照カウントをデクリメントしてはいけません。参照カウントのデクリメントすると、そのオブジェクトが破棄されるかもしれず、 (そのオブジェクトに関連付けられたファイナライザ、弱参照のコールバックにより) 任意のPythonコードの実行を含む後片付け処理が実行されるかもしれないからです。もしそういったコードが再び self を参照することがあれば、すでに持っていたオブジェクトへのポインタは NULL になっているので、 self は所有していたオブジェクトをもう利用できないことを認識できます。 Py_CLEAR() マクロはその手続きを安全な順番で実行します。

tp_clear 関数の目的は参照カウントを破壊することなので、Python文字列や Python整数のような、循環参照になりえないオブジェクトをクリアする必要はありません。一方、全部の所有オブジェクトをクリアするようにし、 tp_dealloc 関数が tp_clear 関数を実行するようにすると実装が楽です。

Pythonのガベージコレクションの仕組みについての詳細は、 循環参照ガベージコレクションをサポートする にあります。

このフィールドは tp_traverse および Py_TPFLAGS_HAVE_GC フラグビットと一緒に継承されます: フラグビット、 tp_traverse,および tp_clear の値がサブタイプで全てゼロになっており、 かつサブタイプで Py_TPFLAGS_HAVE_RICHCOMPARE フラグビットがセットされている場合に、基底タイプから値を継承します。

richcmpfunc PyTypeObject.tp_richcompare

オプションのフィールドで、拡張比較関数 (rich comparison function) を指すポインタです。拡張比較関数のシグネチャは PyObject *tp_richcompare(PyObject *a, PyObject *b, int op) です。

この関数は、比較結果を返すべきです。(普通は Py_True か Py_False です。) 比較が未定義の場合は、 Py_NotImplemented を、それ以外のエラーが発生した場合には例外状態をセットして NULL を返さねばなりません。

ノート

限られた種類の比較だけが可能 (例えば、 == と != が可能で < などが不可能) な型を実装したい場合、拡張比較関数で直接 TypeError を返します。

このフィールドは tp_compare および tp_hash と共にサブタイプに継承されます: すなわち、サブタイプの tp_compare, tp_richcompare および tp_hash が共に NULL の場合、サブタイプは基底タイプから tp_compare, tp_richcompare, tp_hash の三つを一緒に継承します。

tp_richcompare および PyObject_RichCompare() 関数の第三引数に使うための定数としては以下が定義されています:

定数 | 比較
Py_LT | <
Py_LE | <=
Py_EQ | ==
Py_NE | !=
Py_GT | >
Py_GE | >=

次のフィールドは、 Py_TPFLAGS_HAVE_WEAKREFS フラグビットがセットされている場合にのみ存在します。

long PyTypeObject.tp_weaklistoffset

型のインスタンスが弱参照可能な場合、このフィールドはゼロよりも大きな数になり、インスタンス構造体における弱参照リストの先頭を示すオフセットが入ります (GC ヘッダがある場合には無視します); このオフセット値は PyObject_ClearWeakRefs() および PyWeakref_*() 関数が利用します。インスタンス構造体には、 NULL に初期化された PyObject* 型のフィールドが入っていなければなりません。

このフィールドを tp_weaklist と混同しないようにしてください; tp_weaklist は型オブジェクト自体の弱参照リストの先頭です。

サブタイプはこのフィールドを継承しますが、以下の規則があるので読んでください。サブタイプはこのオフセット値をオーバライドできます; 従って、サブタイプでは弱参照リストの先頭が基底タイプとは異なる場合があります。リストの先頭は常に tp_weaklistoffset で分かるはずなので、このことは問題にはならないはずです。

class 文で定義された型に __slots__ 宣言が全くなく、かつ基底タイプが弱参照可能でない場合、その型を弱参照可能にするには弱参照リストの先頭を表すスロットをインスタンスデータレイアウト構造体に追加し、スロットのオフセットを tp_weaklistoffset に設定します。

型の __slots__ 宣言中に __weakref__ という名前のスロットが入っている場合、スロットはその型のインスタンスにおける弱参照リストの先頭を表すスロットになり、スロットのオフセットが型の tp_weaklistoffset に入ります。

型の __slots__ 宣言に __weakref__ という名のスロットが入っていない場合、その型は基底タイプから tp_weaklistoffset を継承します。

次の二つのフィールドは、 Py_TPFLAGS_HAVE_ITER フラグビットがセットされている場合にのみ存在します。

getiterfunc PyTypeObject.tp_iter

オプションの変数で、そのオブジェクトのイテレータを返す関数へのポインタです。この値が存在することは、通常この型のインスタンスがイテレート可能であることを示しています。(しかし、シーケンスはこの関数がなくてもイテレート可能ですし、旧スタイルクラスのインスタンスは __iter__() メソッドを定義していなくてもこの関数を持っています)

この関数は PyObject_GetIter() と同じシグネチャを持っています。

サブタイプはこのフィールドを継承します。

iternextfunc PyTypeObject.tp_iternext

オプションのフィールドで、イテレータにおいて次の要素を返す関数へのポインタです。イテレータの要素がなくなると、この関数は NULL を返さなければなりません。 StopIteration 例外は設定してもしなくても良いです。その他のエラーが発生したときも、 NULL を返さなければなりません。このフィールドがあると、通常この型のインスタンスがイテレータであることを示します (ただし、旧スタイルのインスタンスでは、たとえ next() メソッドが定義されていなくても常にこの関数を持っています)。

イテレータ型では、 tp_iter 関数も定義していなければならず、 tp_iter は (新たなイテレータインスタンスではなく) イテレータインスタンス自体を返さねばなりません。

この関数のシグネチャは PyIter_Next() と同じです。

サブタイプはこのフィールドを継承します。

次の tp_weaklist までのフィールドは、 Py_TPFLAGS_HAVE_CLASS フラグビットがセットされている場合にのみ存在します。

struct PyMethodDef* PyTypeObject.tp_methods

オプションのフィールドです。ポインタで、この型の正規 (regular) のメソッドを宣言している PyMethodDef 構造体からなる、 NULL で終端された静的な配列を指します。

配列の各要素ごとに、メソッドデスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。

サブタイプはこのフィールドを継承しません (メソッドは別個のメカニズムで継承されています)。

struct PyMemberDef* PyTypeObject.tp_members

オプションのフィールドです。ポインタで、型の正規 (regular) のデータメンバ (フィールドおよびスロット) を宣言している PyMemberDef 構造体からなる、 NULL で終端された静的な配列を指します。

配列の各要素ごとに、メンバデスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。

サブタイプはこのフィールドを継承しません (メンバは別個のメカニズムで継承されています)。

struct PyGetSetDef* PyTypeObject.tp_getset

オプションのフィールドです。ポインタで、インスタンスの算出属性 (computed attribute) を宣言している PyGetSetDef 構造体からなる、 NULL で終端された静的な配列を指します。

配列の各要素ごとに、getset デスクリプタの入ったエントリが型辞書 (下記の tp_dict 参照) に追加されます。

サブタイプはこのフィールドを継承しません (算出属性は別個のメカニズムで継承されています)。

PyGetSetDef のドキュメント:

typedef PyObject *(* getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *);

typedef struct PyGetSetDef {
    char *name;    /* 属性名 */
    getter get;    /* 属性の get を行う C 関数 */
    setter set;    /* 属性の set を行う C 関数 */
    char *doc;     /* オプションの docstring  */
    void *closure; /* オプションの get/set 関数用追加データ */
} PyGetSetDef;

PyTypeObject* PyTypeObject.tp_base

オプションのフィールドです。ポインタで、型に関するプロパティを継承する基底タイプへのポインタです。このフィールドのレベルでは、単継承 (single inheritance) だけがサポートされています; 多重継承はメタタイプの呼び出しによる動的な型オブジェクトの生成を必要とします。

(当たり前ですが) サブタイプはこのフィールドを継承しません。しかし、このフィールドのデフォルト値は (Python プログラマは object 型として知っている) &PyBaseObject_Type になります。 .

PyObject* PyTypeObject.tp_dict

型の辞書は PyType_Ready() によってこのフィールドに収められます。

このフィールドは通常、 PyType_Ready() を呼び出す前に NULL に初期化しておかねばなりません; あるいは、型の初期属性の入った辞書で初期化しておいてもかまいません。 PyType_Ready() が型をひとたび初期化すると、型の新たな属性をこの辞書に追加できるのは、属性が (__add__() のような) オーバロード用演算でないときだけです。

サブタイプはこのフィールドを継承しません (が、この辞書内で定義されている属性は異なるメカニズムで継承されます)。

descrgetfunc PyTypeObject.tp_descr_get

オプションのフィールドです。ポインタで、 “デスクリプタ get” 関数を指します。

関数のシグネチャは次のとおりです。

PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);

サブタイプはこのフィールドを継承します。

descrsetfunc PyTypeObject.tp_descr_set

オプションのフィールドです。ポインタで、 “デスクリプタ set” 関数を指します。

関数のシグネチャは次のとおりです。

int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);

サブタイプはこのフィールドを継承します。

long PyTypeObject.tp_dictoffset

型のインスタンスにインスタンス変数の入った辞書がある場合、このフィールドは非ゼロの値になり、型のインスタンスデータ構造体におけるインスタンス変数辞書へのオフセットが入ります; このオフセット値は PyObject_GenericGetAttr() が使います。

このフィールドを tp_dict と混同しないでください; tp_dict は型オブジェクト自体の属性のための辞書です。

このフィールドの値がゼロより大きければ、値はインスタンス構造体の先頭からのオフセットを表します。値がゼロより小さければ、インスタンス構造体の 末尾からのオフセットを表します。負のオフセットを使うコストは比較的高くつくので、インスタンス構造体に可変長の部分があるときのみ使うべきです。例えば、 str や tuple のサブタイプにインスタンス辞書を追加する場合には、負のオフセットを使います。この場合、たとえ辞書が基本のオブジェクトレイアウトに含まれていなくても、 tp_basicsize フィールドは追加された辞書を考慮にいれなければならないので注意してください。ポインタサイズが 4 バイトのシステムでは、構造体の最後尾に辞書が宣言されていることを示す場合、 tp_dictoffset を -4 にしなければなりません。

tp_dictoffset が負の場合、インスタンスにおける実際の辞書のオフセットは以下のようにして計算されます:

dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset
if dictoffset is not aligned on sizeof(void*):
    round up to sizeof(void*)

ここで、 tp_basicsize, tp_itemsize および tp_dictoffset は型オブジェクトから取り出され、 ob_size はインスタンスから取り出されます。長整数は符号を記憶するのに ob_size の符号を使うため、 ob_size は絶対値を使います。(この計算を自分で行う必要はまったくありません; _PyObject_GetDictPtr() がやってくれます。)

サブタイプはこのフィールドを継承しますが、以下の規則があるので読んでください。サブタイプはこのオフセット値をオーバライドできます; 従って、サブタイプでは辞書のオフセットが基底タイプとは異なる場合があります。辞書へのオフセット常に tp_dictoffset で分かるはずなので、このことは問題にはならないはずです。

class 文で定義された型に __slots__ 宣言がなく、かつ基底タイプの全てにインスタンス変数辞書がない場合、辞書のスロットをインスタンスデータレイアウト構造体に追加し、スロットのオフセットを tp_dictoffset に設定します。

class 文で定義された型に __slots__ 宣言がある場合、この型は基底タイプから tp_dictoffset を継承します。

(__dict__ という名前のスロットを __slots__ 宣言に追加しても、期待どおりの効果は得られず、単に混乱を招くだけになります。とはいえ、これは将来 __weakref__ のように追加されるはずです。)

initproc PyTypeObject.tp_init

オプションのフィールドです。ポインタで、インスタンス初期化関数を指します。

この関数はクラスにおける __init__() メソッドに対応します。 __init__() と同様、 __init__() を呼び出さずにインスタンスを作成できます。また、 __init__() を再度呼び出してインスタンスの再初期化もできます。

関数のシグネチャは

int tp_init(PyObject *self, PyObject *args, PyObject *kwds)

です。

self 引数は初期化するインスタンスです; args および kwds 引数は、 __init__() を呼び出す際の固定引数およびキーワード引数です。

tp_init 関数のフィールドが NULL でない場合、型の呼び出しで普通にインスタンスを生成する際に、型の tp_new がインスタンスを返した後に tp_init が呼び出されます。 tp_new が元の型のサブタイプでない別の型を返す場合、 tp_init は全く呼び出されません; tp_new が元の型のサブタイプのインスタンスを返す場合、サブタイプの tp_init が呼び出されます。 (VERSION NOTE: ここに書かれている内容は、Python 2.2.1 以降での実装に関するものです。Python 2.2 では、 tp_init は NULL でない限り tp_new が返す全てのオブジェクトに対して常に呼び出されます。) not NULL.)

サブタイプはこのフィールドを継承します。

allocfunc PyTypeObject.tp_alloc

オプションのフィールドです。ポインタで、インスタンスのメモリ確保関数を指します。

関数のシグネチャは

PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems)

です。

この関数の目的は、メモリ確保をメモリ初期化から分離することにあります。この関数は、インスタンス用の的確なサイズを持ち、適切にバイト整列され、ゼロで初期化され、ただし ob_refcnt を 1 にセットされ、 ob_type が型引数 (type argument) にセットされているようなメモリブロックを返さねばなりません。型の tp_itemsize がゼロでない場合、オブジェクトの ob_size フィールドは nitems に初期化され、確保されるメモリブロックの長さは tp_basicsize + nitems *tp_itemsize を sizeof(void*) の倍数で丸めた値になるはずです; それ以外の場合、 nitems の値は使われず、メモリブロックの長さは tp_basicsize になるはずです。

この関数をインスタンス初期化の他のどの処理にも、追加でメモリ確保をする場合でさえ使ってはなりません; そうした処理は tp_new で行わねばなりません。

静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (class 文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドは常に PyType_GenericAlloc() にセットされ、標準のヒープ上メモリ確保戦略が強制されます。静的に定義する型の場合でも、 PyType_GenericAlloc() を推奨します。

newfunc PyTypeObject.tp_new

オプションのフィールドです。ポインタで、インスタンス生成関数を指します。

このフィールドが NULL を指している型では、型を呼び出して新たなインスタンスを生成できません; こうした型では、おそらくファクトリ関数のように、インスタンスを生成する他の方法があるはずです。

関数のシグネチャは

PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)

です。

引数 subtype は生成するオブジェクトの型です; args および kwds 引数は、型を呼び出すときの固定引数およびキーワード引数です。サブタイプは tp_new 関数を呼び出すときに使う型と等価というわけではないので注意してください; tp_new 関数を呼び出すときに使う型 (と無関係ではない) サブタイプのこともあります。

tp_new 関数は subtype->tp_alloc(subtype, nitems) を呼び出してオブジェクトのメモリ領域を確保し、初期化で本当に必要とされる処理だけを行います。省略したり繰り返したりしても問題のない初期化処理は tp_init ハンドラ内に配置しなければなりません。経験則からいうと、変更不能な型の場合、初期化は全て tp_new で行い、変更可能な型の場合はほとんどの初期化を tp_init に回すべきです。

サブタイプはこのフィールドを継承します。例外として、 tp_base が NULL か &PyBaseObject_Type になっている静的な型では継承しません。後者が例外になっているのは、旧式の拡張型が Python 2.2 でリンクされたときに呼び出し可能オブジェクトにならないようにするための予防措置です。

destructor PyTypeObject.tp_free

オプションのフィールドです。ポインタで、インスタンスのメモリ解放関数を指します。

この関数のシグネチャは少し変更されています; Python 2.2 および 2.2.1 では、シグネチャは destructor

void tp_free(PyObject *)

でしたが、 Python 2.3 以降では、シグネチャは freefunc:

void tp_free(void *)

になっています。

両方のバージョンと互換性のある初期値は _PyObject_Del です。 _PyObject_Del の定義は Python 2.3 で適切に対応できるよう変更されました。

静的なサブタイプはこのフィールドを継承しますが、動的なサブタイプ (class 文で生成するサブタイプ) の場合は継承しません; 後者の場合、このフィールドには PyType_GenericAlloc() と Py_TPFLAGS_HAVE_GC フラグビットの値に対応させるのにふさわしいメモリ解放関数がセットされます。

inquiry PyTypeObject.tp_is_gc

オプションのフィールドです。ポインタで、ガベージコレクタから呼び出される関数を指します。

ガベージコレクタは、オブジェクトがガベージとして収集可能かどうかを知る必要があります。これを知るには、通常はオブジェクトの型の tp_flags フィールドを見て、 Py_TPFLAGS_HAVE_GC フラグビットを調べるだけで十分です。しかし、静的なメモリ確保と動的なメモリ確保が混じっているインスタンスを持つような型や、静的にメモリ確保されたインスタンスは収集できません。こうした型では、このフィールドに関数を定義しなければなりません; 関数はインスタンスが収集可能の場合には 1 を、収集不能の場合には 0 を返さねばなりません。シグネチャは

int tp_is_gc(PyObject *self)

です。

(上記のような型の例は、型オブジェクト自体です。メタタイプ PyType_Type は、型のメモリ確保が静的か動的かを区別するためにこの関数を定義しています。)

サブタイプはこのフィールドを継承します。 (VERSION NOTE: Python 2.2 では、このフィールドは継承されませんでした。 2.2.1 以降のバージョンから継承されるようになりました。)

PyObject* PyTypeObject.tp_bases

基底型からなるタプルです。

class 文で生成されたクラスの場合このフィールドがセットされます。静的に定義されている型の場合には、このフィールドは NULL になります。

このフィールドは継承されません。

PyObject* PyTypeObject.tp_mro

基底クラス群を展開した集合が入っているタプルです。集合は該当する型自体からはじまり、 object で終わります。メソッド解決順 (Method Resolution Order) の順に並んでいます。

このフィールドは継承されません; フィールドの値は PyType_Ready() で毎回計算されます。

PyObject* PyTypeObject.tp_cache

使用されていません。継承されません。内部で使用するためだけのものです。

PyObject* PyTypeObject.tp_subclasses

サブクラスへの弱参照からなるリストです。継承されません。内部で使用するためだけのものです。

PyObject* PyTypeObject.tp_weaklist

この型オブジェクトに対する弱参照からなるリストの先頭です。

残りのフィールドは、機能テスト用のマクロである COUNT_ALLOCS が定義されている場合のみ利用でき、内部で使用するためだけのものです。これらのフィールドについて記述するのは単に完全性のためです。サブタイプはこれらのフィールドを継承しません。

Py_ssize_t PyTypeObject.tp_allocs

メモリ確保の回数です。

Py_ssize_t PyTypeObject.tp_frees

メモリ解放の回数です。

Py_ssize_t PyTypeObject.tp_maxalloc

同時にメモリ確保できる最大オブジェクト数です。

PyTypeObject* PyTypeObject.tp_next

tp_allocs フィールドが非ゼロの、(リンクリストの) 次の型オブジェクトを指すポインタです。

また、 Python のガベージコレクションでは、 tp_dealloc を呼び出すのはオブジェクトを生成したスレッドだけではなく、任意の Python スレッドかもしれないという点にも注意して下さい。 (オブジェクトが循環参照の一部の場合、任意のスレッドのガベージコレクションによって解放されてしまうかもしれません)。Python API 側からみれば、 tp_dealloc を呼び出すスレッドはグローバルインタプリタロック (GIL: Global Interpreter Lock) を獲得するので、これは問題ではありません。しかしながら、削除されようとしているオブジェクトが何らかの C や C++ ライブラリ由来のオブジェクトを削除する場合、 tp_dealloc を呼び出すスレッドのオブジェクトを削除することで、ライブラリの仮定している何らかの規約に違反しないように気を付ける必要があります。

数値オブジェクト構造体

PyNumberMethods

拡張型で数値型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。以下のほとんどすべての関数は 数値型プロトコル (number protocol) で解説されている似た名前の関数から利用されます。

以下は構造体の定義です。

typedef struct {
     binaryfunc nb_add;
     binaryfunc nb_subtract;
     binaryfunc nb_multiply;
     binaryfunc nb_divide;
     binaryfunc nb_remainder;
     binaryfunc nb_divmod;
     ternaryfunc nb_power;
     unaryfunc nb_negative;
     unaryfunc nb_positive;
     unaryfunc nb_absolute;
     inquiry nb_nonzero;       /* Used by PyObject_IsTrue */
     unaryfunc nb_invert;
     binaryfunc nb_lshift;
     binaryfunc nb_rshift;
     binaryfunc nb_and;
     binaryfunc nb_xor;
     binaryfunc nb_or;
     coercion nb_coerce;       /* Used by the coerce() function */
     unaryfunc nb_int;
     unaryfunc nb_long;
     unaryfunc nb_float;
     unaryfunc nb_oct;
     unaryfunc nb_hex;

     /* Added in release 2.0 */
     binaryfunc nb_inplace_add;
     binaryfunc nb_inplace_subtract;
     binaryfunc nb_inplace_multiply;
     binaryfunc nb_inplace_divide;
     binaryfunc nb_inplace_remainder;
     ternaryfunc nb_inplace_power;
     binaryfunc nb_inplace_lshift;
     binaryfunc nb_inplace_rshift;
     binaryfunc nb_inplace_and;
     binaryfunc nb_inplace_xor;
     binaryfunc nb_inplace_or;

     /* Added in release 2.2 */
     binaryfunc nb_floor_divide;
     binaryfunc nb_true_divide;
     binaryfunc nb_inplace_floor_divide;
     binaryfunc nb_inplace_true_divide;

     /* Added in release 2.5 */
     unaryfunc nb_index;
} PyNumberMethods;

2引数および3引数の関数は、 Py_TPFLAGS_CHECKTYPES フラグによっては、異なる種類の引数を受け取るかもしれません。

Py_TPFLAGS_CHECKTYPES がセットされていない場合、関数の引数はオブジェクトの型であることが保証されます。呼び出し側は nb_coerce メンバで指定されている型強制メソッドを呼び出して引数を変換する責任があります。

coercion PyNumberMethods.nb_coerce

この関数は PyNumber_CoerceEx() から利用され、同じシグネチャを持ちます。最初の引数は定義された型のオブジェクトを指すポインタでなければなりません。共通の “大きな” 型への変換が可能であれば、この関数はポインタを変換後のオブジェクトへの新しい参照へ置き換えて、 0 を返します。変換ができないなら、この関数は 1 を返します。エラーが設定荒れた場合は、 -1 を返します。

Py_TPFLAGS_CHECKTYPES フラグがセットされている場合、2引数および 3引数関数はすべてのオペランドの型をチェクし、必要な変換を行わなければなりません。 (少なくとも、オペランドのうち1つは定義している型のものです) これは推奨された方式です。 Python 3.0 では型強制は完全に取り除かれています。

与えられたオペランドに対して操作が定義されていな場合は、2引数および3引数関数は Py_NotImplemented を返さなければなりません。その他のエラーが発生した場合は、例外を設定して NULL を返さなければなりません。

マップ型オブジェクト構造体

PyMappingMethods

拡張型でマップ型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。以下の3つのメンバを持っています。

lenfunc PyMappingMethods.mp_length

この関数は PyMapping_Length() や PyObject_Size() から利用され、それらと同じシグネチャを持っています。オブジェクトが定義された長さを持たない場合は、このスロットは NULL に設定されることがあります。

binaryfunc PyMappingMethods.mp_subscript

この関数は PyObject_GetItem() から利用され、同じシグネチャを持っています。このスロットは PyMapping_Check() が 1 を返すためには必要で、そうでなければ NULL の場合があります。

objobjargproc PyMappingMethods.mp_ass_subscript

この関数は PyObject_SetItem() から利用され、同じシグネチャを持っています。もしこのスロットが NULL なら、このオブジェクトはアイテムの代入をサポートしません。

シーケンスオブジェクト構造体

PySequenceMethods

拡張型でシーケンス型プロトコルを実装するために使われる関数群へのポインタを保持するために使われる構造体です。

lenfunc PySequenceMethods.sq_length

この関数は PySequence_Size() や PyObject_Size() から利用され、それらと同じシグネチャを持っています。

binaryfunc PySequenceMethods.sq_concat

この関数は PySequence_Concat() から利用され、同じシグネチャを持っています。また、 + 演算からも、 tp_as_number.nb_add スロットによる数値加算を試したあとに利用されます。

ssizeargfunc PySequenceMethods.sq_repeat

この関数は PySequence_Repeat() から利用され、同じシグネチャを持っています。また、 * 演算からも、 tp_as_number.nb_mul スロットによる数値乗算を試したあとに利用されます。

ssizeargfunc PySequenceMethods.sq_item

この関数は PySequence_GetItem() から利用され、同じシグネチャを持っています。このスロットは PySequence_Check() が 1 を返すためには埋めなければならず、それ以外の場合は NULL の可能性があります。

負のインデックスは次のように処理されます: sq_length スロットが埋められていれば、それを呼び出してシーケンスの長さから正のインデックスを計算し、 sq_item に渡します。 sq_length が NULL の場合は、インデックスはそのままこの関数に渡されます。

ssizeobjargproc PySequenceMethods.sq_ass_item

この関数は PySequence_SetItem() から利用され、同じシグネチャを持っています。このスロットはオブジェクトが要素の代入をサポートしていない場合は NULL かもしれません。

objobjproc PySequenceMethods.sq_contains

この関数は PySequence_Contains() から利用され、同じシグネチャを持っています。このスロットは NULL の場合があり、その時 PySequence_Contains() はシンプルにマッチするオブジェクトを見つけるまでシーケンスを巡回します。

binaryfunc PySequenceMethods.sq_inplace_concat

この関数は PySequence_InPlaceConcat() から利用され、同じシグネチャを持っています。この関数は最初のオペランドを修正してそれを返すべきです。

ssizeargfunc PySequenceMethods.sq_inplace_repeat

この関数は PySequence_InPlaceRepeat() から利用され、同じシグネチャを持っています。この関数は最初のオペランドを修正してそれを返すべきです。

バッファオブジェクト構造体 (buffer object structure)

バッファインタフェースは、あるオブジェクトの内部データを一連のデータチャンク (chunk) として見せるモデルを外部から利用できるようにします。各チャンクはポインタ/データ長からなるペアで指定します。チャンクはセグメント(segment) と呼ばれ、メモリ内に不連続的に配置されるものと想定されています。

バッファインタフェースを利用できるようにしたくないオブジェクトでは、 PyTypeObject 構造体の tp_as_buffer メンバを NULL にしなくてはなりません。利用できるようにする場合、 tp_as_buffer は PyBufferProcs 構造体を指さねばなりません。

ノート

PyTypeObject 構造体の tp_flags メンバの値を 0 でなく Py_TPFLAGS_DEFAULT にしておくことがとても重要です。この設定は、 PyBufferProcs 構造体に bf_getcharbuffer スロットが入っていることを Python ランタイムに教えます。 Python の古いバージョンには bf_getcharbuffer メンバが存在しないので、古い拡張モジュールを使おうとしている新しいバージョンの Python インタプリタは、このメンバがあるかどうかテストしてから使えるようにする必要があるのです。

PyBufferProcs

バッファプロトコルの実装を定義している関数群へのポインタを保持するのに使われる構造体です。

最初のスロットは bf_getreadbuffer で、 getreadbufferproc 型です。このスロットが NULL の場合、オブジェクトは内部データの読み出しをサポートしません。そのような仕様には意味がないので、実装を行う側はこのスロットに値を埋めるはずですが、呼び出し側では非 NULL の値かどうかきちんと調べておくべきです。

次のスロットは bf_getwritebuffer で、 getwritebufferproc 型です。オブジェクトが返すバッファに対して書き込みを許可しない場合はこのスロットを NULL にできます。

第三のスロットは bf_getsegcount で、 getsegcountproc 型です。このスロットは NULL であってはならず、オブジェクトにいくつセグメントが入っているかを呼び出し側に教えるために使われます。 PyString_Type や PyBuffer_Type オブジェクトのような単純なオブジェクトには単一のセグメントしか入っていません。

最後のスロットは bf_getcharbuffer で、 getcharbufferproc です。オブジェクトの PyTypeObject 構造体における tp_flags フィールドに、 Py_TPFLAGS_HAVE_GETCHARBUFFER ビットフラグがセットされている場合にのみ、このスロットが存在することになります。このスロットの使用に先立って、呼び出し側は PyType_HasFeature() を使ってスロットが存在するか調べねばなりません。フラグが立っていても、 bf_getcharbuffer は NULL のときもあり、 NULL はオブジェクトの内容を 8 ビット文字列として利用できないことを示します。このスロットに入る関数も、オブジェクトの内容を 8 ビット文字列に変換できない場合に例外を送出することがあります。例えば、オブジェクトが浮動小数点数を保持するように設定されたアレイの場合、呼び出し側が bf_getcharbuffer を使って 8 ビット文字列としてデータを取り出そうとすると例外を送出するようにできます。この、内部バッファを “テキスト” として取り出すという概念は、本質的にはバイナリで、文字ベースの内容を持ったオブジェクト間の区別に使われます。

ノート

現在のポリシでは、文字 (character) はマルチバイト文字でもかまわないと決めているように思われます。従って、サイズ N のバッファが N 個のキャラクタからなるとはかぎらないことになります。

Py_TPFLAGS_HAVE_GETCHARBUFFER

型構造体中のフラグビットで、 bf_getcharbuffer スロットが既知の値になっていることを示します。このフラグビットがセットされていたとしても、オブジェクトがバッファインタフェースをサポートしていることや、 bf_getcharbuffer スロットが NULL でないことを示すわけではありません。

Py_ssize_t (*getreadbufferproc)(PyObject *self, Py_ssize_t segment, void **ptrptr)

*ptrptr の中の読み出し可能なバッファセグメントへのポインタを返します。この関数は例外を送出してもよく、送出する場合には -1 を返さねばなりません。 segment に渡す値はゼロまたは正の値で、 bf_getsegcount スロット関数が返すセグメント数よりも必ず小さな値でなければなりません。成功すると、セグメントのサイズを返し、 *ptrptr をそのセグメントを指すポインタ値にセットします。

Py_ssize_t (*getwritebufferproc)(PyObject *self, Py_ssize_t segment, void **ptrptr)

読み出し可能なバッファセグメントへのポインタを *ptrptr に返し、セグメントの長さを関数の戻り値として返します。エラーによる例外の場合には -1 を -1 を返さねばなりません。オブジェクトが呼び出し専用バッファしかサポートしていない場合には TypeError を、 segment が存在しないセグメントを指している場合には SystemError を送出しなければなりません。

Py_ssize_t (*getsegcountproc)(PyObject *self, Py_ssize_t *lenp)

バッファを構成するメモリセグメントの数を返します。 lenp が NULL でない場合、この関数の実装は全てのセグメントのサイズ (バイト単位) の合計値を *lenp を介して報告しなければなりません。この関数呼び出しは失敗させられません。

Py_ssize_t (*getcharbufferproc)(PyObject *self, Py_ssize_t segment, const char **ptrptr)

セグメント segment のメモリバッファを ptrptr に入れ、そのサイズを返します。エラーのときに -1 を返します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

オブジェクト実装サポート (object implementation support) »

循環参照ガベージコレクションをサポートする

Python が循環参照を含むガベージの検出とコレクションをサポートするには、他のオブジェクトに対する “コンテナ” (他のオブジェクトには他のコンテナも含みます) となるオブジェクト型によるサポートが必要です。他のオブジェクトに対する参照を記憶しないオブジェクトや、 (数値や文字列のような) アトム型 (atomic type) への参照だけを記憶するような型では、ガベージコレクションに際して特別これといったサポートを提供する必要はありません。

コンテナ型を作るには、型オブジェクトの tp_flags フィールドに Py_TPFLAGS_HAVE_GC フラグがなくてはならず、 tp_traverse ハンドラの実装を提供しなければなりません。実装する型のインスタンスを変更可能なオブジェクトにするなら、 tp_clear の実装も提供しなければなりません。

Py_TPFLAGS_HAVE_GC

このフラグをセットした型のオブジェクトは、この節に述べた規則に適合しなければなりません。簡単のため、このフラグをセットした型のオブジェクトをコンテナオブジェクトと呼びます。

コンテナ型のコンストラクタは以下の二つの規則に適合しなければなりません:

オブジェクトのメモリは PyObject_GC_New() または PyObject_GC_NewVar() で確保しなければなりません。

一度他のコンテナへの参照が入るかもしれないフィールドが全て初期化されたら、 PyObject_GC_Track() を呼び出さねばなりません。

TYPE* PyObject_GC_New(TYPE, PyTypeObject *type)

PyObject_New() に似ていますが、 Py_TPFLAGS_HAVE_GC のセットされたコンテナオブジェクト用です。

TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size)

PyObject_NewVar() に似ていますが、 Py_TPFLAGS_HAVE_GC のセットされたコンテナオブジェクト用です。

バージョン 2.5 で変更: この関数は以前は size の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize)

PyObject_NewVar() が確保したオブジェクトのメモリをリサイズします。リサイズされたオブジェクトを返します。失敗すると NULL を返します。

バージョン 2.5 で変更: この関数は以前は newsize の型に int を利用していました。この変更により、 64bit システムを正しくサポートするには修正が必要になります。

void PyObject_GC_Track(PyObject *op)

ガベージコレクタが追跡しているコンテナオブジェクトの集合にオブジェクト op を追加します。ガベージコレクタの動作する回数は予測不能なので、追加対象にするオブジェクトは追跡されている間ずっと有効なオブジェクトでなければなりません。この関数は、通常コンストラクタの最後付近で、 tp_traverse ハンドラ以降の全てのフィールドが有効な値になった時点で呼び出さねばなりません。

void _PyObject_GC_TRACK(PyObject *op)

PyObject_GC_Track() のマクロ版です。拡張モジュールに使ってはなりません。

同様に、オブジェクトのメモリ解放関数も以下の二つの規則に適合しなければなりません:

他のコンテナを参照しているフィールドを無効化する前に、 PyObject_GC_UnTrack() を呼び出さねばなりません。

オブジェクトのメモリは PyObject_GC_Del() で解放しなければなりません。

void PyObject_GC_Del(void *op)

PyObject_GC_New() や PyObject_GC_NewVar() を使って確保されたメモリを解放します。

void PyObject_GC_UnTrack(void *op)

ガベージコレクタが追跡しているコンテナオブジェクトの集合からオブジェクト op を除去します。再度 PyObject_GC_Track() を呼び出して、除去したオブジェクトを追跡対象セットに追加できることに注意してください。メモリ解放関数 (deallocator, tp_dealloc ハンドラ) は、 tp_traverse ハンドラが使用しているフィールドのいずれかが無効化されるよりも以前にオブジェクトに対して呼び出されていなければなりません。

void _PyObject_GC_UNTRACK(PyObject *op)

PyObject_GC_UnTrack() のマクロ版です。拡張モジュールに使ってはなりません。

tp_traverse ハンドラは以下の型を持つ関数を引数の一つとしてとります:

int (*visitproc)(PyObject *object, void *arg)

tp_traverse ハンドラに渡すビジタ関数 (visitor function) の型です。この関数は追跡すべきオブジェクトを object に、 tp_traverse ハンドラの第三引数を arg にして呼び出されます。Python のコア部分では、ガベージコレクションの実装に複数のビジタ関数を使っています。ユーザが独自にビジタ関数を書く必要があるとは想定されていません。

tp_traverse ハンドラは以下の型でなければなりません:

int (*traverseproc)(PyObject *self, visitproc visit, void *arg)

コンテナオブジェクトのためのトラバーサル関数 (traversal function) です。実装では、 self に直接入っている各オブジェクトに対して visit 関数を呼び出さねばなりません。このとき、 visit へのパラメタはコンテナに入っている各オブジェクトと、このハンドラに渡された arg の値です。 visit 関数は NULL オブジェクトを引数に渡して呼び出してはなりません。 visit が非ゼロの値を返す場合、エラーが発生し、戻り値をそのまま返すようににしなければなりません。

tp_traverse ハンドラの作成を単純化するため、 Py_VISIT() マクロが提供されています。このマクロを使うには、 tp_traverse の実装で、引数を visit および arg という名前にしておかねばなりません:

void Py_VISIT(PyObject *o)

引数 o および arg を使って visit コールバックを呼び出します。 visit が非ゼロの値を返した場合、その値をそのまま返します。このマクロを使えば、 tp_traverse ハンドラは以下のようになります:

static int
my_traverse(Noddy *self, visitproc visit, void *arg)
{
    Py_VISIT(self->foo);
    Py_VISIT(self->bar);
    return 0;
}

バージョン 2.4 で追加.

tp_clear ハンドラは inquiry 型にするか、オブジェクトが変更不能の場合には NULL にしなければなりません。

int (*inquiry)(PyObject *self)

循環参照を形成しているとおぼしき参照群を放棄します。変更不可能なオブジェクトは循環参照を直接形成することが決してないので、この関数を定義する必要はありません。このメソッドを呼び出した後でもオブジェクトは有効なままでなければならないので注意してください (参照に対して Py_DECREF() を呼ぶだけにしないでください)。ガベージコレクタは、オブジェクトが循環参照を形成していることを検出した際にこのメソッドを呼び出します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python/C API リファレンスマニュアル »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる Python C/API Reference Release の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

Yasushi MASUDA

INADA Naoki <inada-n at klab.jp>

cocoatomo

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布

Release: | 2.7
Date: | 2011年 12月 26日

このドキュメントでは、 Python 配布ユーティリティ (Python Distribution Utilities, “Distutils”) について、モジュール開発者の視点に立ち、多くの人々がビルド/リリース/インストールの手間をほとんどかけずに Python モジュールや拡張モジュールを入手できるようにする方法について述べます。

Distutilsの紹介

概念と用語

簡単な例

Python 一般の用語

Distutils 固有の用語

setup スクリプトを書く

パッケージを全て列挙する

個々のモジュールを列挙する

拡張モジュールについて記述する

パッケージと配布物の関係

スクリプトをインストールする

パッケージデータをインストールする

追加のファイルをインストールする

追加のメタデータ

setup スクリプトをデバッグする

setup 設定ファイル (setup configuration file) を書く

ソースコード配布物を作成する

配布するファイルを指定する

マニフェスト (manifest) 関連のオプション

MANIFEST.in テンプレート

ビルド済み配布物を作成する

ダム形式のビルド済み配布物を作成する

RPM パッケージを作成する

Windows インストーラを作成する

Windowsでのクロスコンパイル

Vista User Access Control (UAC)

パッケージインデクスに登録する

.pypirc ファイル

パッケージを Package Index にアップロードする

PyPI パッケージ表示

例

pure Python 配布物 (モジュール形式)

pure Python 配布物 (パッケージ形式)

単体の拡張モジュール

Distutilsの拡張

新しいコマンドの統合

配布物の種類を追加する

コマンドリファレンス

モジュールをインストールする: install コマンド群

API リファレンス

distutils.core — Distutils のコア機能

distutils.ccompiler — CCompiler ベースクラス

distutils.unixccompiler — Unix C コンパイラ

distutils.msvccompiler — Microsoft コンパイラ

distutils.bcppcompiler — Borland コンパイラ

distutils.cygwincompiler — Cygwin コンパイラ

distutils.emxccompiler — OS/2 EMX コンパイラ

distutils.archive_util — アーカイブユーティリティ

distutils.dep_util — 依存関係のチェック

distutils.dir_util — ディレクトリツリーの操作

distutils.file_util — 1ファイルの操作

distutils.util — その他のユーティリティ関数

distutils.dist — Distribution クラス

distutils.extension — Extension クラス

distutils.debug — Distutils デバッグモード

distutils.errors — Distutils 例外

distutils.fancy_getopt — 標準 getopt モジュールのラッパ

distutils.filelist — FileList クラス

distutils.log — シンプルな PEP 282 スタイルのロギング

distutils.spawn — サブプロセスの生成

distutils.sysconfig — システム設定情報

distutils.text_file — TextFile クラス

distutils.version — バージョン番号クラス

distutils.cmd — Distutils コマンドの抽象クラス

新しいDistutilsコマンドの作成

distutils.command — Distutils 各コマンド

distutils.command.bdist — バイナリインストーラの構築

distutils.command.bdist_packager — パッケージの抽象ベースクラス

distutils.command.bdist_dumb — “ダム”インストーラを構築

distutils.command.bdist_msi — Microsoft Installer バイナリパッケージをビルドする

distutils.command.bdist_rpm — Redhat RPMとSRPM形式のバイナリディストリビューションを構築

distutils.command.bdist_wininst — Windowsインストーラの構築

distutils.command.sdist — ソース配布物の構築

distutils.command.build — パッケージ中の全ファイルを構築

distutils.command.build_clib — パッケージ中のCライブラリを構築

distutils.command.build_ext — パッケージ中の拡張を構築

distutils.command.build_py — パッケージ中の.py/.pyc ファイルを構築

distutils.command.build_scripts — パッケージ中のスクリプトを構築

distutils.command.clean — パッケージのビルドエリアを消去

distutils.command.config — パッケージの設定

distutils.command.install — パッケージのインストール

distutils.command.install_data — パッケージ中のデータファイルをインストール

distutils.command.install_headers — パッケージから C/C++ ヘッダファイルをインストール

distutils.command.install_lib — パッケージからライブラリファイルをインストール

distutils.command.install_scripts — パッケージからスクリプトファイルをインストール

distutils.command.register — モジュールをPython Package Indexに登録する

distutils.command.check — パッケージのメタデータをチェックする

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

Distutilsの紹介

このドキュメントで扱っている内容は、 Distutils を使った Python モジュールの配布で、とりわけ開発者/配布者の役割に重点を置いています: Python モジュールのインストールに関する情報を探しているのなら、 Python モジュールのインストールを参照してください。

概念と用語

Distutils の使い方は、モジュール開発者とサードパーティ製のモジュールをインストールするユーザ/管理者のどちらにとってもきわめて単純です。開発者側のやるべきことは (もちろん、しっかりした実装で、詳しく文書化され、よくテストされたコードを書くことは別として！) 以下の項目になります:

setup スクリプト (setup.py という名前にするのがならわし) を書く

(必要があれば) setup 設定ファイルを書く

ソースコード配布物を作成する

(必要があれば) 一つまたはそれ以上のビルド済み (バイナリ) 形式の配布物を作成する

これらの作業については、いずれもこのドキュメントで扱っています。

全てのモジュール開発者が複数の実行プラットフォームを利用できるわけではないので、全てのプラットフォーム向けにビルド済みの配布物を提供してもらえると期待するわけにはいきません。ですから、仲介を行う人々、いわゆる パッケージ作成者 (packager) がこの問題を解決すべく立ち上がってくれることが望ましいでしょう。パッケージ作成者はモジュール開発者がリリースしたソースコード配布物を、一つまたはそれ以上のプラットフォーム上でビルドして、得られたビルド済み配布物をリリースすることになります。したがって、ほとんどの一般的なプラットフォームにおけるユーザは、setup スクリプト一つ実行せず、コードを一行たりともコンパイルしなくても、使っているプラットフォーム向けのきわめて普通の方法でほとんどの一般的な Python モジュール配布物をインストールできるでしょう。

簡単な例

setup スクリプトは通常単純なものですが、Python で書かれているため、スクリプト中で何かを処理しようと考えたとき特に制限はありません。とはいえ、 setup スクリプト中に何かコストの大きな処理を行うときは十分注意してください。 autoconf 形式の設定スクリプトとは違い、 setup スクリプトはモジュール配布物をビルドしてインストールする中で複数回実行されることがあります。

foo.py という名前のファイルに収められている foo という名前のモジュールを配布したいだけなら、setup スクリプトは以下のような単純なものになります:

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )

以下のことに注意してください:

Distutils に与えなければならない情報のほとんどは、 setup() 関数のキーワード引数として与えます。

キーワード引数は二つのカテゴリ: パッケージのメタデータ (パッケージ名、バージョン番号) 、パッケージに何が収められているかの情報 (上の場合は pure Python モジュールのリスト)、に行き着きます。

モジュールはファイル名ではなく、モジュール名で指定します (パッケージと拡張モジュールについても同じです)

作者名、電子メールアドレス、プロジェクトの URL といった追加のメタデータを入れておくよう奨めます ( setup スクリプトを書く の例を参照してください)

このモジュールのソースコード配布物を作成するには、上記のコードが入った setup スクリプト setup.py を作成して、以下のコマンド:

python setup.py sdist

を実行します。

この操作を行うと、アーカイブファイル (例えば Unixでは tarball、Windows では ZIP ファイル) を作成します。アーカイブファイルには、setup スクリプト setup.py と、配布したいモジュール foo.py が入っています。アーカイブファイルの名前は foo-1.0.targ.gz (または .zip) になり、展開するとディレクトリ foo-1.0 を作成します。

エンドユーザが foo モジュールをインストールしたければ、 foo-1.0.tar.gz (または .zip) をダウンロードし、パッケージを展開して、以下のスクリプトを — foo-1.0 ディレクトリ中で — 実行します:

python setup.py install

この操作を行うと、インストールされている Python での適切なサードパーティ製モジュール置き場に foo.py を完璧にコピーします．

ここで述べた簡単な例では、 Distutils の基本的な概念のいくつかを示しています。まず、開発者とインストール作業者は同じ基本インタフェース、すなわち setup スクリプトを使っています。二人の作業の違いは、使っている Distutils コマンド (command) にあります: sdist コマンドは、ほぼ完全に開発者だけが対象となる一方、 install はどちらかというとインストール作業者向けです (とはいえ、ほとんどの開発者は自分のコードをインストールしたくなることがあるでしょう)。

ユーザにとって本当に簡単なものにしたいのなら、一つまたはそれ以上のビルド済み配布物を作ってあげられます。例えば、Windows マシン上で作業をしていて、他の Windows ユーザにとって簡単な配布物を提供したいのなら、実行可能な形式の (このプラットフォーム向けのビルド済み配布物としてはもっとも適切な) インストーラを作成できます。これには bdist_wininst を使います。例えば:

python setup.py bdist_wininst

とすると、実行可能なインストーラ形式、 foo-1.0.win32.exe が現在のディレクトリに作成されます。

その他の有用な配布形態としては、 bdist_rpm に実装されている RPM 形式、 Solaris pkgtool (bdist_pkgtool) 、 HP-UX swinstall (bdist_sdux) があります。例えば、以下のコマンドを実行すると、 foo-1.0.noarch.rpm という名前の RPM ファイルを作成します:

python setup.py bdist_rpm

(bdist_rpm コマンドは rpm コマンドを使うため、 Red Hat Linux や SuSE Linux、 Mandrake Linux といった RPM ベースのシステムで実行しなければなりません)

どの配布形式が利用できるかは、

python setup.py bdist --help-formats

を実行すれば分かります。

Python 一般の用語

このドキュメントを読んでいるのなら、モジュール (module)、拡張モジュール (extension) などが何を表すのかをよく知っているかもしれません。とはいえ、読者がみな共通のスタートポイントに立って Distutils の操作を始められるように、ここで一般的な Python 用語について以下のような用語集を示しておきます:

モジュール (module)

Python においてコードを再利用する際の基本単位: すなわち、他のコードから import されるひとかたまりのコードです。ここでは、三種類のモジュール: pure Python モジュール、拡張モジュール、パッケージが関わってきます。

pure Python モジュール

Python で書かれ、単一の .py ファイル内に収められたモジュールです (.pyc かつ/または .pyo ファイルと関連があります) 。 “pure モジュール (pure module)” と呼ばれることもあります。

拡張モジュール (extension module)

Python を実装している低水準言語: Python の場合は C/C++ 、 Jython の場合は Java 、で書かれたモジュールです。通常は、動的にロードできるコンパイル済みの単一のファイルに入っています。例えば、Unix向け Python 拡張のための共有オブジェクト (.so) 、 Windows 向け Python 拡張のための DLL (.pyd という拡張子が与えられています)、 Jython 拡張のための Java クラスといった具合です。 (現状では、 Distutils は Python 向けの C/C++ 拡張モジュールしか扱わないので注意してください。)

パッケージ (package)

他のモジュールが入っているモジュールです; 通常、ファイルシステム内のあるディレクトリに収められ、 __init__.py が入っていることで通常のディレクトリと区別できます。

ルートパッケージ (root package)

階層的なパッケージの根 (root) の部分にあたるパッケージです。(この部分には __init__.py ファイルがないので、本当のパッケージではありませんが、便宜上そう呼びます。) 標準ライブラリの大部分はルートパッケージに入っています、また、多くの小規模な単体のサードパーティモジュールで、他の大規模なモジュールコレクションに属していないものもここに入ります。正規のパッケージと違い、ルートパッケージ上のモジュールの実体は様々なディレクトリにあります: 実際は、 sys.path に列挙されているディレクトリ全てが、ルートパッケージに配置されるモジュールの内容に影響します。

Distutils 固有の用語

以下は Distutils を使って Python モジュールを配布する際に使われる特有の用語です:

モジュール配布物 (module distribution)

一個のファイルとしてダウンロード可能なリソースの形をとり、 一括して インストールされることになっている形態で配られる Python モジュールのコレクションです。よく知られたモジュール配布物には、Numeric Python、 PyXML、 PIL (the Python Imaging Library)、 mxBase などがあります。 (パッケージ (package) と呼ばれることもありますが、 Python 用語としてのパッケージとは意味が違います: 一つのモジュール配布物の中には、場合によりゼロ個、一つ、それ以上の Python パッケージが入っています。)

pure モジュール配布物 (pure module distribution)

pure Python モジュールやパッケージだけが入ったモジュール配布物です。”pure 配布物 (pure distribution)” とも呼ばれます。

非 pure モジュール配布物 (non-pure module distribution)

少なくとも一つの拡張モジュールが入ったモジュール配布物です。 “非 pure 配布物”とも呼びます。

配布物ルートディレクトリ (distribution root)

ソースコードツリー (またはソース配布物) ディレクトリの最上階層で、 setup.py のある場所です。一般的には、 setup.py はこのディレクトリ上で実行します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

setup スクリプトを書く

setup スクリプトは、Distutils を使ってモジュールをビルドし、配布し、インストールする際の全ての動作の中心になります。 setup スクリプトの主な目的は、モジュール配布物について Distutils に伝え、モジュール配布を操作するための様々なコマンドを正しく動作させることにあります。上の 簡単な例 の節で見てきたように、 setup スクリプトは主に setup() の呼び出しからなり、開発者が distuils に対して与えるほとんどの情報は setup() のキーワード引数として指定されます。

ここではもう少しだけ複雑な例: Distutils 自体の setup スクリプト、を示します。これについては、以降の二つの節でフォローします。 (Distutils が入っているのは Python 1.6 以降であり、 Python 1.5.2 ユーザが他のモジュール配布物をインストールできるようにするための独立したパッケージがあることを思い出してください。ここで示した、Distutils 自身の setup スクリプトは、Python 1.5.2 に Distutils パッケージをインストールする際に使います。)

#!/usr/bin/env python

from distutils.core import setup

setup(name='Distutils',
      version='1.0',
      description='Python Distribution Utilities',
      author='Greg Ward',
      author_email='gward@python.net',
      url='http://www.python.org/sigs/distutils-sig/',
      packages=['distutils', 'distutils.command'],
     )

上の例と、 簡単な例 で示したファイル一つからなる小さな配布物とは、違うところは二つしかありません: メタデータの追加と、モジュールではなくパッケージとして pure Python モジュール群を指定しているという点です。この点は重要です。というのも、 Distutils は 2 ダースものモジュールが (今のところ) 二つのパッケージに分かれて入っているからです; 各モジュールについていちいち明示的に記述したリストは、作成するのが面倒だし、維持するのも難しくなるでしょう。その他のメタデータについては、 追加のメタデータ を参照してください。

setup スクリプトに与えるパス名 (ファイルまたはディレクトリ) は、 Unix におけるファイル名規約、つまりスラッシュ (‘/’) 区切りで書かねばなりません。Distutils はこのプラットフォーム中立の表記を、実際にパス名として使う前に、現在のプラットフォームに適した表記に注意深く変換します。この機能のおかげで、setup スクリプトを異なるオペレーティングシステム間にわたって可搬性があるものにできます。言うまでもなく、これは Distutils の大きな目標の一つです。この精神に従って、このドキュメントでは全てのパス名をスラッシュ区切りにしています。

もちろん、この取り決めは Distutils に渡すパス名だけに適用されます。もし、例えば glob.glob() や os.listdir() のような、標準の Python 関数を使ってファイル群を指定するのなら、パス区切り文字 (path separator) をハードコーディングせず、以下のように可搬性のあるコードを書くよう注意すべきです:

glob.glob(os.path.join('mydir', 'subdir', '*.html'))
os.listdir(os.path.join('mydir', 'subdir'))

パッケージを全て列挙する

packages オプションは、 packages リスト中で指定されている各々のパッケージについて、パッケージ内に見つかった全ての pure Python モジュールを処理 (ビルド、配布、インストール、等) するよう Distutils に指示します。このオプションを指定するためには、当然のことながら各パッケージ名はファイルシステム上のディレクトリ名と何らかの対応付けができなければなりません。デフォルトで使われる対応関係はきわめてはっきりしたものです。すなわち、パッケージ distutils が配布物ルートディレクトリからの相対パス distutils で表されるディレクトリ中にあるというものです。つまり、setup スクリプト中で packages = ['foo'] と指定したら、スクリプトの置かれたディレクトリからの相対パスで foo/__init__.py を探し出せると Distutils に確約したことになります。この約束を裏切ると Distutils は警告を出しますが、そのまま壊れたパッケージの処理を継続します。

ソースコードディレクトリの配置について違った規約を使っていても、まったく問題はありません: 単に package_dir オプションを指定して、 Distutils に自分の規約を教えればよいのです。例えば、全ての Python ソースコードを lib 下に置いて、 “ルートパッケージ” 内のモジュール (つまり、どのパッケージにも入っていないモジュール) を lib 内に入れ、 foo パッケージを lib/foo に入れる、といった具合にしたいのなら、

package_dir = {'': 'lib'}

を setup スクリプト内に入れます。辞書内のキーはパッケージ名で、空のパッケージ名はルートパッケージを表します。キーに対応する値はルートパッケージからの相対ディレクトリ名です、この場合、 packages = ['foo'] を指定すれば、 lib/foo/__init__.py が存在すると Distutils に確約したことになります。

もう一つの規約のあり方は foo パッケージを lib に置き換え、 foo.bar パッケージが lib/bar にある、などとするものです。このような規約は、 setup スクリプトでは

package_dir = {'foo': 'lib'}

のように書きます。 package_dir 辞書に package: dir のようなエントリがあると、 package の下にある全てのパッケージに対してこの規則が暗黙のうちに適用され、その結果 foo.bar の場合が自動的に処理されます。この例では、 packages = ['foo', 'foo.bar'] は、 Distutils に lib/__init__.py と lib/bar/__init__.py を探すように指示します。 (package_dir は再帰的に適用されますが、この場合 packages の下にある全てのパッケージを明示的に指定しなければならないことを心に留めておいてください: Distutils は __init__.py を持つディレクトリをソースツリーから再帰的にさがしたりは しません 。)

個々のモジュールを列挙する

小さなモジュール配布物の場合、パッケージを列挙するよりも、全てのモジュールを列挙するほうがよいと思うかもしれません — 特に、単一のモジュールが “ルートパッケージ” にインストールされる (すなわち、パッケージは全くない) ような場合がそうです。この最も単純なケースは簡単な例 で示しました; ここではもうちょっと入り組んだ例を示します:

py_modules = ['mod1', 'pkg.mod2']

ここでは二つのモジュールについて述べていて、一方は “ルート” パッケージに入り、他方は pkg パッケージに入ります。ここでも、デフォルトのパッケージ/ディレクトリのレイアウトは、二つのモジュールが mod1.py と pkg/mod2.py にあり、 pkg/__init__.py が存在することを暗示しています。また、パッケージ/ディレクトリの対応関係は package_dir オプションでも上書きできます。

拡張モジュールについて記述する

pure Python モジュールを書くより Python 拡張モジュールを書く方がちょっとだけ複雑なように、 Distutils での拡張モジュールに関する記述もちょっと複雑です。pure モジュールと違い、単にモジュールやパッケージを列挙して、Distutils が正しいファイルを見つけてくれると期待するだけでは十分ではありません; 拡張モジュールの名前、ソースコードファイル (群) 、そして何らかのコンパイル/リンクに関する必要事項 (include ディレクトリ、リンクすべきライブラリ、等) を指定しなければなりません。

こうした指定は全て、 setup() の別のキーワード引数、 ext_modules オプションを介して行えます。 ext_modules は、 Extension インスタンスからなるただのリストで、各インスタンスに一個の拡張モジュールを記述するようになっています。仮に、 foo.c で実装された拡張モジュール foo が、配布物に一つだけ入ってるとします。コンパイラ/リンカに他の情報を与える必要がない場合、この拡張モジュールのための記述はきわめて単純です:

Extension('foo', ['foo.c'])

Extension クラスは、 setup() によって、 distutils.core から import されます。従って、拡張モジュールが一つだけ入っていて、他には何も入っていないモジュール配布物を作成するための setup スクリプトは、以下のようになるでしょう:

from distutils.core import setup, Extension
setup(name='foo',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

Explained クラス (実質的には、 Explained クラスの根底にある build_ext コマンドで実装されている、拡張モジュールをビルドする機構) は、Python 拡張モジュールをきわめて柔軟に記述できるようなサポートを提供しています。これについては後の節で説明します。

拡張モジュールの名前とパッケージ

Extension クラスのコンストラクタに与える最初の引数は、常に拡張モジュールの名前にします。これにはパッケージ名も含めます。例えば、

Extension('foo', ['src/foo1.c', 'src/foo2.c']p)

とすると、拡張モジュールをルートパッケージに置くことになります。一方、

Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])

は、同じ拡張モジュールを pkg パッケージの下に置くよう記述しています。ソースコードファイルと、作成されるオブジェクトコードはどちらの場合でも同じです; 作成された拡張モジュールがファイルシステム上のどこに置かれるか (すなわち Python の名前空間上のどこに置かれるか) が違うにすぎません。

同じパッケージ内に (または、同じ基底パッケージ下に) いくつもの拡張モジュールがある場合、 ext_package キーワード引数を setup() に指定します。例えば、

setup(...,
      ext_package='pkg',
      ext_modules=[Extension('foo', ['foo.c']),
                   Extension('subpkg.bar', ['bar.c'])],
     )

とすると、 foo.c をコンパイルして pkg.foo にし、 bar.c をコンパイルして pkg.subpkg.bar にします。

拡張モジュールのソースファイル

Extension コンストラクタの二番目の引数は、ソースファイルのリストです。 Distutils は現在のところ、C、C++、そして Objective-C の拡張しかサポートしていないので、引数は通常 C/C++/Objective-C ソースコードファイルになります。 (C++ソースコードファイルを区別できるよう、正しいファイル拡張子を使ってください: .cc や .cpp にすれば、 Unix と Windows 用の双方のコンパイラで認識されるようです。)

ただし、 SWIG インタフェース (.i) ファイルはリストに含められます; build_ext コマンドは、 SWIG で書かれた拡張パッケージをどう扱えばよいか心得ています: build_ext は、インタフェースファイルを SWIG にかけ、得られた C/C++ ファイルをコンパイルして拡張モジュールを生成します。

この警告にかかわらず、現在次のようにしてSWIGに対してオプションを渡すことができます。

setup(...,
      ext_modules=[Extension('_foo', ['foo.i'],
                             swig_opts=['-modern', '-I../include'])],
      py_modules=['foo'],
     )

もしくは、次のようにコマンドラインからオプションを渡すこともできます。

> python setup.py build_ext --swig-opts="-modern -I../include"

プラットフォームによっては、コンパイラで処理され、拡張モジュールに取り込まれるような非ソースコードファイルを含められます。非ソースコードファイルとは、現状では Visual C++向けの Windows メッセージテキスト (.mc) ファイルや、リソース定義 (.rc) ファイルを指します。これらのファイルはバイナリリソース (.res) ファイルにコンパイルされ、実行ファイルにリンクされます。

プリプロセッサオプション

Extension には三種類のオプション引数: include_dirs, define_macros, そして undef_macros があり、検索対象にするインクルードディレクトリを指定したり、プリプロセッサマクロを定義 (define)/定義解除 (undefine) したりする必要があるとき役立ちます。

例えば、拡張モジュールが配布物ルート下の include ディレクトリにあるヘッダファイルを必要とするときには、 include_dirs オプションを使います:

Extension('foo', ['foo.c'], include_dirs=['include'])

ここには絶対パスも指定できます; 例えば、自分の拡張モジュールが、 /usr の下にX11R6 をインストールした Unix システムだけでビルドされると知っていれば、

Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11'])

のように書けます。

自分のコードを配布する際には、このような可搬性のない使い方は避けるべきです: おそらく、 C のコードを

#include <X11/Xlib.h>

のように書いた方がましでしょう。

他の Python 拡張モジュール由来のヘッダを include する必要があるなら、 Distutils の install_header コマンドが一貫した方法でヘッダファイルをインストールするという事実を活用できます。例えば、 Numerical Python のヘッダファイルは、 (標準的な Unix がインストールされた環境では) /usr/local/include/python1.5/Numerical にインストールされます。 (実際の場所は、プラットフォームやどの Python をインストールしたかで異なります。) Python の include ディレクトリ — 今の例では /usr/local/include/python1.5 — は、 Python 拡張モジュールをビルドする際に常にヘッダファイル検索パスに取り込まれるので、 C コードを書く上でもっともよいアプローチは、

#include <Numerical/arrayobject.h>

となります。

Numerical インクルードディレクトリ自体をヘッダ検索パスに置きたいのなら、このディレクトリを Distutils の distutils.sysconfig モジュールを使って見つけさせられます:

from distutils.sysconfig import get_python_inc
incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical')
setup(...,
      Extension(..., include_dirs=[incdir]),
      )

この書き方も可搬性はあります — プラットフォームに関わらず、どんな Python がインストールされていても動作します — が、単に実践的な書き方で C コードを書く方が簡単でしょう。

define_macros および undef_macros オプションを使って、プリプロセッサマクロを定義 (define) したり、定義解除 (undefine) したりもできます。 define_macros はタプル (name, value) からなるリストを引数にとります。 name は定義したいマクロの名前 (文字列) で、 value はその値です: value は文字列か None になります。(マクロ FOO を None にすると、C ソースコード内で #define FOO と書いたのと同じになります: こう書くと、ほとんどのコンパイラは FOO を文字列 1 に設定します。) undef_macros には、定義解除したいマクロ名からなるリストを指定します。

例えば、以下の指定:

Extension(...,
          define_macros=[('NDEBUG', '1'),
                         ('HAVE_STRFTIME', None)],
          undef_macros=['HAVE_FOO', 'HAVE_BAR'])

は、全ての C ソースコードファイルの先頭に、以下のマクロ:

#define NDEBUG 1
#define HAVE_STRFTIME
#undef HAVE_FOO
#undef HAVE_BAR

があるのと同じになります。

ライブラリオプション

拡張モジュールをビルドする際にリンクするライブラリや、ライブラリを検索するディレクトリも指定できます。 libraries はリンクするライブラリのリストで、 library_dirs はリンク時にライブラリを検索するディレクトリのリストです。また、 runtime_library_dirs は、実行時に共有ライブラリ (動的にロードされるライブラリ) を検索するディレクトリのリストです。

例えば、ビルド対象システムの標準ライブラリ検索パスにあることが分かっているライブラリをリンクする時には、以下のようにします。

Extension(...,
          libraries=['gdbm', 'readline'])

非標準のパス上にあるライブラリをリンクしたいなら、その場所を library_dirs に入れておかなければなりません:

Extension(...,
          library_dirs=['/usr/X11R6/lib'],
          libraries=['X11', 'Xt'])

(繰り返しになりますが、この手の可搬性のない書き方は、コードを配布するのが目的なら避けるべきです。)

その他のオプション

他にもいくつかオプションがあり、特殊な状況を扱うために使います。

optional オプションはブール型で、真の場合は拡張モジュールのビルドに失敗したときにビルドプロセス自体を停止せず、単にその拡張モジュールのインストールをしません。

extra_objects オプションには、リンカに渡すオブジェクトファイルのリストを指定します。ファイル名には拡張子をつけてはならず、コンパイラで使われているデフォルトの拡張子が使われます。

extra_compile_args および extra_link_args には、それぞれコンパイラとリンカに渡す追加のコマンドライン引数を指定します。

export_symbols は Windows でのみ意味があります。このオプションには、公開 (export) する (関数や変数の) シンボルのリストを入れられます。コンパイルして拡張モジュールをビルドする際には、このオプションは不要です: Distutils は公開するシンボルを自動的に initmodule に渡すからです。

depends オプションは、拡張モジュールが依存している(例: ヘッダーファイルなどの) ファイルのリストです。このファイルのいずれかが前回のビルドから変更された時、ビルドコマンドはこのソースファイルをコンパイルしてリビルドします。

パッケージと配布物の関係

配布物はパッケージと3種類の方法で関係します:

パッケージかモジュールを要求する。

パッケージかモジュールを提供する。

パッケージかモジュールを廃止する。

これらの関係は、 distutils.core.setup() 関数のキーワード引数を利用して指定することができます。

他のPythonモジュールやパッケージに対する依存は、 setup() の requires キーワード引数で指定できます。引数の値は文字列のリストでなければなりません。各文字列は、必要とするパッケージと、オプションとしてパッケージのバージョンを指定します。

あるモジュールかパッケージの任意のバージョンが必要な場合、指定する文字列はモジュール名かパッケージ名になります。例えば、 'mymodule' や 'xml.parsers.expat' を含みます。

特定のバージョンが必要な場合、修飾子(qualifier)の列を加えることができます。各修飾子は、比較演算子とバージョン番号からなります。利用できる比較演算子は:

<    >    ==
<=   >=   !=

これらの修飾子はカンマ(空白文字を入れても良いです)で区切って複数並べることができます。その場合、全ての修飾子が適合する必要があります; 評価する時に論理ANDでつなげられます。

いくつかの例を見てみましょう:

require式 | 説明
==1.0 | version 1.0 のみが適合します
>1.0, !=1.5.1, <2.0 | 1.5.1 を除いて、 1.0 より後ろで 2.0 より前の全てのバージョンに適合します。

これで、依存を指定することができました。同じように、この配布物が他の配布物に必要とされる何を提供するのかを指定する必要があります。これは、 setup() の provide キーワード引数によって指定できます。この引数の値は文字列のリストで、各要素はPythonモジュールかパッケージの名前です。バージョンを指定することもできます。もしバージョンが指定されなかった場合、配布物のバージョン番号が利用されます。

いくつかの例です:

provide 式 | 説明
mypkg | mypkg を提供します。バージョンは配布物のものを使います。
mypkg (1.1) | mypkg version 1.1 を提供します。配布物のバージョン番号は気にしません

パッケージは obsoletes キーワードを利用することで、他のパッケージを廃止することを宣言することもできます。この値は requires キーワードと似ています: モジュールやパッケージを指定する文字列のリストです。各文字列は、モジュールかパッケージの名前と、オプションとして一つ以上のバージョン指定から構成されています。バージョン指定は、モジュールやパッケージの名前のうしろに、丸括(parentheses)でかこわれています。

指定されたバージョンは、その配布物によって廃止されるバージョンを示しています。バージョン指定が存在しない場合は、指定された名前のモジュールまたはパッケージの全てが廃止されたと解釈されます。

スクリプトをインストールする

ここまでは、スクリプトから import され、それ自体では実行されないような pure Python モジュールおよび非 pure Python モジュールについて扱ってきました。

スクリプトとは、Python ソースコードを含むファイルで、コマンドラインから実行できるよう作られているものです。スクリプトは Distutils に複雑なことを一切させません。唯一の気の利いた機能は、スクリプトの最初の行が #! で始まっていて、 “python” という単語が入っていた場合、Distutils は最初の行を現在使っているインタプリタを参照するよう置き換えます。デフォルトでは現在使っているインタプリタと置換しますが、オプション --executable (または -e) を指定することで、明示的にインタプリタのパスを指定して上書きすることができます。

scripts オプションには、単に上で述べた方法で取り扱うべきファイルのリストを指定するだけです。PyXML の setup スクリプトを例に示します:

setup(...,
      scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
      )

バージョン 2.7 で変更: テンプレートが提供されない時、全てのスクリプトが MANIFEST ファイルに追加されるようになりました。 配布するファイルを指定する を参照してください

パッケージデータをインストールする

しばしばパッケージに追加のファイルをインストールする必要があります。このファイルは、パッケージの実装に強く関連したデータや、そのパッケージを使うプログラマーが必要とするドキュメントなどです。これらのファイルを パッケージデータ と呼びます。

パッケージデータは関数 setup() にキーワード引数 package_data を与えることで追加できます。この値はパッケージ名から、パッケージへコピーされる相対パス名リストへのマップである必要があります。それぞれのパスは対応するパッケージが含まれるディレクトリ(もし適切なら package_dir のマッピングが利用されます)からの相対パスとして扱われます。つまり、ファイルはソースディレクトリ中にパッケージの一部として存在すると仮定されています。この値にはグロブパターンを含むことができます。

パス名にはディレクトリ部分を含むことができます。必要なディレクトリはインストール時に作成されます。

たとえば、パッケージがいくつかのデータファイルを含むサブディレクトリを含んでいる場合、ソースツリーでは以下のように配置できます:

setup.py
src/
    mypkg/
        __init__.py
        module.py
        data/
            tables.dat
            spoons.dat
            forks.dat

対応する setup() 呼び出しは以下のようになります:

setup(...,
      packages=['mypkg'],
      package_dir={'mypkg': 'src/mypkg'},
      package_data={'mypkg': ['data/*.dat']},
      )

バージョン 2.4 で追加.

バージョン 2.7 で変更: テンプレートが提供されない時、全ての package_data にマッチするファイルが MANIFEST ファイルに追加されるようになりました。 配布するファイルを指定する を参照してください

追加のファイルをインストールする

data_files オプションを使うと、モジュール配布物で必要な追加のファイル: 設定ファイル、メッセージカタログ、データファイル、その他これまで述べてきたカテゴリに収まらない全てのファイルを指定できます。

data_files には、(directory, files) のペアを以下のように指定します:

setup(...,
      data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                  ('config', ['cfg/data.cfg']),
                  ('/etc/init.d', ['init-script'])]
     )

データファイルのインストール先ディレクトリ名は指定できますが、データファイル自体の名前の変更はできないので注意してください。

各々の (directory, files) ペアには、インストール先のディレクトリ名と、そのディレクトリにインストールしたいファイルを指定します。 directory が相対パスの場合、インストールプレフィクス (installation prefix、 pure Python パッケージなら sys.prefix 、拡張モジュールの入ったパッケージなら sys.exec_prefix) からの相対パスと解釈されます。 files 内の各ファイル名は、パッケージソースコード配布物の最上階層の、 setup.py のあるディレクトリからの相対パスと解釈されます。 files に書かれたディレクトリ情報は、ファイルを最終的にどこにインストールするかを決めるときには使われません; ファイルの名前だけが使われます。

data_files オプションは、ターゲットディレクトリを指定せずに、単にファイルの列を指定できます。しかし、このやり方は推奨されておらず、指定すると install コマンドが警告を出力します。ターゲットディレクトリにデータファイルを直接インストールしたいなら、ディレクトリ名として空文字列を指定してください。

バージョン 2.7 で変更: テンプレートが提供されない時、全ての data_files にマッチするファイルが MANIFEST ファイルに追加されるようになりました。 配布するファイルを指定する を参照してください

追加のメタデータ

setup スクリプトには、名前やバージョンにとどまらず、その他のメタデータを含められます。以下のような情報を含められます:

メタデータ | 説明 | 値 | 注記
name | パッケージの名前 | 短い文字列 | (1)
version | リリースのバージョン | 短い文字列 | (1)(2)
author | パッケージ作者の名前 | 短い文字列 | (3)
author_email | パッケージ作者の電子メールアドレス | 電子メールアドレス | (3)
maintainer | パッケージメンテナンス担当者の名前 | 短い文字列 | (3)
maintainer_email | パッケージメンテナンス担当者の電子メールアドレス | 電子メールアドレス | (3)
url | パッケージのホームページ | URL | (1)
description | パッケージについての簡潔な概要説明 | 短い文字列 |
long_description | パッケージについての詳細な説明 | 長い文字列 | (5)
download_url | パッケージをダウンロードできる場所 | URL | (4)
classifiers | 分類語のリスト | 文字列からなるリスト | (4)
platforms | プラットフォームのリスト | 文字列からなるリスト |
license | パッケージのライセンス | 文字列からなるリスト | (6)

注記:

必須のフィールドです。

バージョン番号は major.minor[.patch[.sub]] の形式をとるよう奨めます。

作者かメンテナのどちらかは必ず区別してください。

これらのフィールドは、2.2.3 および 2.3 より以前のバージョンの Python でも互換性を持たせたい場合には指定してはなりません。リストは PyPI ウェブサイト [http://pypi.python.org/pypi] にあります。

パッケージを PyPI に登録する際、 PyPI は long_description フィールドの値を使ってパッケージのホームページをビルドします。

license フィールドは、パッケージのライセンスが Trove Classifier の “License” から選べない場合に、そのライセンスを示すテキストです。 Classifier を参照してください。非推奨ですが、 licence というオプションも存在していて、 license のエイリアスになっています。

「短い文字列」

200 文字以内の一行のテキスト。

「長い文字列」

複数行からなり、ReStructuredText 形式で書かれたプレーンテキスト (http://docutils.sf.net/ を参照してください)。

「文字列のリスト」

下記を参照してください。

これらの文字列はいずれも Unicode であってはなりません。

バージョン情報のコード化は、それ自体が一つのアートです。 Python のパッケージは一般的に、 major.minor[.patch][sub] というバージョン表記に従います。メジャー (major) 番号は最初は 0 で、これはソフトウェアが実験的リリースにあることを示します。メジャー番号は、パッケージが主要な開発目標を達成したとき、それを示すために加算されてゆきます。マイナー (minor) 番号は、パッケージに重要な新機能が追加されたときに加算されてゆきます。パッチ (patch) 番号は、バグフィクス版のリリースが作成されたときに加算されます。末尾にバージョン情報が追加され、サブリリースを示すこともあります。これは “a1,a2,...,aN” (アルファリリースの場合で、機能や API が変更されているとき)、 “b1,b2,...,bN” (ベータリリースの場合で、バグフィクスのみのとき) 、そして “pr1,pr2,...,prN” (プレリリースの最終段階で、リリーステストのとき) になります。以下に例を示します:

0.1.0

パッケージの最初の実験的なリリース

1.0.1a2

1.0 の最初のパッチバージョンに対する、2 回目のアルファリリース

classifiers は、 Python のリスト型で指定します:

setup(...,
      classifiers=[
          'Development Status :: 4 - Beta',
          'Environment :: Console',
          'Environment :: Web Environment',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Developers',
          'Intended Audience :: System Administrators',
          'License :: OSI Approved :: Python Software Foundation License',
          'Operating System :: MacOS :: MacOS X',
          'Operating System :: Microsoft :: Windows',
          'Operating System :: POSIX',
          'Programming Language :: Python',
          'Topic :: Communications :: Email',
          'Topic :: Office/Business',
          'Topic :: Software Development :: Bug Tracking',
          ],
      )

setup.py に classifiers を入れておき、なおかつ 2.2.3 よりも以前のバージョンの Python と後方互換性を保ちたいなら、 setup.py 中で setup() を呼び出す前に、以下のコードを入れます。

# patch distutils if it can't cope with the "classifiers" or
# "download_url" keywords
from sys import version
if version < '2.2.3':
    from distutils.dist import DistributionMetadata
    DistributionMetadata.classifiers = None
    DistributionMetadata.download_url = None

setup スクリプトをデバッグする

setup スクリプトのどこかがまずいと、開発者の思い通りに動作してくれません。

Distutils は setup 実行時の全ての例外を捉えて、簡単なエラーメッセージを出力してからスクリプトを終了します。このような仕様にしているのは、 Python にあまり詳しくない管理者がパッケージをインストールする際に混乱しなくてすむようにするためです。もし Distutils のはらわた深くからトレースバックした長大なメッセージを見たら、管理者はきっと Python のインストール自体がおかしくなっているのだと勘違いして、トレースバックを最後まで読み進んで実はファイルパーミッションの問題だったと気づいたりはしないでしょう。

しかし逆に、この仕様は開発者にとってはうまくいかない理由を見つける役には立ちません。そこで、 DISTUTILS_DEBUG 環境変数を空文字以外の何らかの値に設定しておけば、 Distutils が何を実行しているか詳しい情報を出力し、例外が発生した場合には完全なトレースバックを出力するようにできます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

setup 設定ファイル (setup configuration file) を書く

時に、配布物をビルドする際に必要な全ての設定を あらかじめ 書ききれない状況が起きます: 例えば、ビルドを進めるために、ユーザに関する情報や、ユーザのシステムに関する情報を必要とするかもしれません。こうした情報が単純 — C ヘッダファイルやライブラリを検索するディレクトリのリストのように — であるかぎり、ユーザに設定ファイル (configuration file) setup.cfg を提供して編集してもらうのが、安上がりで簡単な特定方法になります。設定ファイルはまた、あらゆるコマンドにおけるオプションにデフォルト値を与えておき、インストール作業者がコマンドライン上や設定ファイルの編集でデフォルト設定を上書きできるようにします。

setup 設定ファイルは setup スクリプト —理想的にはインストール作業者から見えないもの [1] —と、作者の手を離れて、全てインストール作業者次第となる setup スクリプトのコマンドライン引数との間を橋渡しする中間層として有効です。実際、 setup.cfg (と、ターゲットシステム上にある、その他の Distutils 設定ファイル) は、 setup スクリプトの内容より後で、かつコマンドラインで上書きする前に処理されます。この仕様の結果、いくつかの利点が生まれます:

インストール作業者は、作者が setup.py に設定した項目のいくつかを setup.cfg を変更して上書きできます。

setu.py では簡単に設定できないような、標準でないオプションのデフォルト値を設定できます。

インストール作業者は、 setup.cfg に書かれたどんな設定も setup.py のコマンドラインオプションで上書きできます。

設定ファイルの基本的な構文は簡単なものです:

[command]
option=value
...

ここで、 command は Distutils コマンドのうちの一つ (例えば build_py, install) で、 option はそのコマンドでサポートされているオプションのうちの一つです。各コマンドには任意の数のオプションを設定でき、一つの設定ファイル中には任意の数のコマンドセクションを収められます。空白行は無視されます、 '#' 文字で開始して行末まで続くコメントも同様に無視されます。長いオプション設定値は、継続行をインデントするだけで複数行にわたって記述できます。

あるコマンドがサポートしているオプションのリストは、 --help オプションで調べられます。例えば以下のように。

> python setup.py --help build_ext
[...]
Options for 'build_ext' command:
  --build-lib (-b)     directory for compiled extension modules
  --build-temp (-t)    directory for temporary files (build by-products)
  --inplace (-i)       ignore build-lib and put compiled extensions into the
                       source directory alongside your pure Python modules
  --include-dirs (-I)  list of directories to search for header files
  --define (-D)        C preprocessor macros to define
  --undef (-U)         C preprocessor macros to undefine
  --swig-opts          list of SWIG command line options
[...]

コマンドライン上で --foo-bar と綴るオプションは、設定ファイル上では foo_bar と綴るので注意してください。

例えば、拡張モジュールを “インプレース (in-place)” でビルドしたいとします — すなわち、 pkg.ext という拡張モジュールを持っていて、コンパイル済みの拡張モジュールファイル (例えば Unix では ext.so) を pure Python モジュール pkg.mod1 および pkg.mod2 と同じソースディレクトリに置きたいとします。こんなときには、 --inplace を使えば、確実にビルドを行えます。

python setup.py build_ext --inplace

しかし、この操作では、常に build_ext を明示的に指定しなければならず、 --inplace オプションを忘れずに与えなければなりません。こうした設定を “設定しっ放しにする” 簡単な方法は、 setup.cfg に書いておくやり方で、設定ファイルは以下のようになります:

[build_ext]
inplace=1

この設定は、明示的に build_ext を指定するかどうかに関わらず、モジュール配布物の全てのビルドに影響します。ソース配布物に setup.cfg を含めると、エンドユーザの手で行われるビルドにも影響します — このオプションの例に関しては setup.cfg を含めるのはおそらくよくないアイデアでしょう。というのは、拡張モジュールをインプレースでビルドすると常にインストールしたモジュール配布物を壊してしまうからです。とはいえ、ある特定の状況では、モジュールをインストールディレクトリの下に正しく構築できるので、機能としては有用だと考えられます。 (ただ、インストールディレクトリ上でのビルドを想定するような拡張モジュールの配布は、ほとんどの場合よくない考え方です。)

もう一つ、例があります: コマンドによっては、実行時にほとんど変更されないたくさんのオプションがあります; 例えば、 bdist_rpm には、RPM 配布物を作成する際に、”spec” ファイルを作成するために必要な情報を全て与えなければなりません。この情報には setup スクリプトから与えるものもあり、 (インストールされるファイルのリストのように) Distutils が自動的に生成するものもあります。しかし、こうした情報の中には bdist_rpm のオプションとして与えるものがあり、毎回実行するごとにコマンドライン上で指定するのが面倒です。そこで、以下のような内容が Distutils 自体の setup.cfg には入っています:

[bdist_rpm]
release = 1
packager = Greg Ward <gward@python.net>
doc_files = CHANGES.txt
            README.txt
            USAGE.txt
            doc/
            examples/

doc_files オプションは、単に空白で区切られた文字列で、ここでは可読性のために複数行をまたぐようにしています。

参考

“Python モジュールのインストール” の 設定ファイルの構文

設定ファイルに関する詳細情報は、システム管理者向けのこのマニュアルにあります。

注記

[1]
Distutils が自動設定機能 (auto-configuration) をサポートするまで、おそらくこの理想状態を達成することはないでしょう

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

ソースコード配布物を作成する

簡単な例 節で示したように、ソースコード配布物を作成するには sdist コマンドを使います。最も単純な例では、

python setup.py sdist

のようにします (ここでは、 sdist に関するオプションを setup スクリプトや設定ファイル中で行っていないものと仮定します)。 sdist は、現在のプラットフォームでのデフォルトのアーカイブ形式でアーカイブを生成します。デフォルトの形式は Unixでは gzip で圧縮された tar ファイル形式 (.tar.gz) で、Windows では ZIP 形式です。

--formats オプションを使えば、好きなだけ圧縮形式を指定できます。例えば:

python setup.py sdist --formats=gztar,zip

は、gzip された tarball と zip ファイルを作成します。利用可能な形式は以下の通りです:

形式 | 説明 | 注記
zip | zip ファイル (.zip) | (1),(3)
gztar | gzip 圧縮された tar ファイル (.tar.gz) | (2)
bztar | bzip2 圧縮された tar ファイル (.tar.bz2) |
ztar | compress 圧縮された tar ファイル (.tar.Z) | (4)
tar | tar ファイル (.tar) |

注記:

Windows でのデフォルトです

Unixでのデフォルトです

外部ユーティリティの zip か、 zipfile モジュールが必要です (Python 1.6 からは標準ライブラリになっています)

外部ユーティリティ compress が必要です。このフォーマットは廃止待ちで、将来のバージョンの Python では削除されるでしょう。

tar フォーマットのどれか (gztar, bztar, ztar, tar) を Unix で利用する時、アーカイブ内の各メンバに設定される owner と group 名を指定することができます。

例えば、アーカイブ内の全てのファイルの所有者を root にするには、次のようにします。

python setup.py sdist --owner=root --group=root

配布するファイルを指定する

明確なファイルのリスト (またはファイルリストを生成する方法) を明示的に与えなかった場合、 sdist コマンドはソース配布物に以下のような最小のデフォルトのセットを含めます:

py_modules と packages オプションに指定された Python ソースファイル全て

ext_modules や libraries オプションに記載された C ソースファイル

scripts オプションで指定されたスクリプト。スクリプトをインストールする を参照してください。

テストスクリプトと思しきファイル全て: test/test*.py (現状では、Distutils はテストスクリプトをただソース配布物に含めるだけですが、将来は Python モジュール配布物に対するテスト標準ができるかもしれません)

README.txt (または README)、 setup.py (または setup スクリプトにしているもの) 、および setup.cfg

package_data メタデータにマッチする全てのファイル。パッケージデータをインストールする を参照してください。

data_files メタデータにマッチする全てのファイル。追加のファイルをインストールする を参照してください。

上記のセットで十分なこともありますが、大抵他のファイルを配布物に含めたいと思うでしょう。普通は、 MANIFEST.in と呼ばれるマニフェストテンプレート (manifest template) を使ってこれを行います。マニフェストテンプレートは、ソース配布物に含めるファイルの正確なリストであるマニフェストファイル MANIFEST をどうやって作成するか指示しているリストです。 sdist コマンドはこのテンプレートを処理し、書かれた指示とファイルシステム上に見つかったファイルに基づいてマニフェストファイルを作成します。

自分用のマニフェストファイルを書きたいなら、その形式は簡単です: 一行あたり一つの通常ファイル (または通常ファイルに対するシンボリックリンク) だけを書きます。自分で MANIFEST を提供する場合、全てを自分で指定しなければなりません: ただし、上で説明したデフォルトのファイルセットは、この中には含まれません。

バージョン 2.7 で追加: MANIFEST のコメントで始まるファイルは、それが生成されたものであることを表します。そうでないファイルは上書きされたり削除されたりしません。

シンタックスリファレンスは MANIFEST.in テンプレート を参照してください。

マニフェスト (manifest) 関連のオプション

sdist コマンドが通常行う処理の流れは、以下のようになっています:

マニフェストファイル MANIFEST が存在しなければ、 MANIFEST.in を読み込んでマニフェストファイルを作成します

MANIFEST も MANIFEST.in もなければ、デフォルトのファイルセットだけでできたマニフェストファイルを作成します

MANIFEST.in か setup.py が MANIFEST より新しければ、 MANIFEST.in を読み込んで MANIFEST を再生成します。

(生成されたか、読み出された) MANIFEST 内にあるファイルのリストを使ってソース配布物アーカイブを作成します

上の動作は二種類のオプションを使って変更できます。まず、標準の “include” および “exclude” セットを無効化するには --no-defaults および --no-prune を使います。

第2に、単にマニフェストを (再)生成したいだけで、ソース配布物は作成したくない場合があるかもしれません:

python setup.py sdist --manifest-only

-o は --manifest-only のショートカットです。

MANIFEST.in テンプレート

sdist コマンドがビルドする配布物に含めるファイルのリストを定義するために、プロジェクトに MANIFEST.in ファイルを追加することができます。

sdist が実行された時、 MANIFEST.in ファイルを探して、それを解釈して、パッケージに含めるファイルのリストを含んだ MANIFEST ファイルを生成します。

This mechanism can be used when the default list of files is not enough. (See 配布するファイルを指定する). この機構は、デフォルトのファイルリストが十分でないときに利用できます。 (配布するファイルを指定する を参照)

原則

マニフェストテンプレートには一行あたり一つのコマンドがあります。各コマンドはソース配布物に入れたり配布物から除外したりするファイルのセットを指定します。例えば、Distutils 自体のマニフェストテンプレートを見てみましょう:

include *.txt
recursive-include examples *.txt *.py
prune examples/sample?/build

各行はかなり明確に意味を取れるはずです: 上の指定では、 *.txt にマッチする配布物ルート下の全てのファイル、 examples ディレクトリ下にある *.txt か *.py にマッチする全てのファイルを含め、 examples/sample?/build にマッチする全てのファイルを除外します。これらの処理はすべて、標準的に含められるファイルセットの評価よりも 後に行われるので、マニフェストテンプレートに明示的に指示をしておけば、標準セット中のファイルも除外できます。 (--no-defaults オプションを設定して、標準セット自体を無効にもできます。)

マニフェストテンプレート中のコマンドの順番には意味があります; 初期状態では、上で述べたようなデフォルトのファイルがあり、テンプレート中の各コマンドによって、逐次ファイルを追加したり除去したりしていいます。マニフェストテンプレートを完全に処理し終えたら、ソース配布物中に含めるべきでない以下のファイルをリストから除去します:

Distutls の “build” (デフォルトの名前は build) ツリー下にある全てのファイル

RCS, CVS, .svn, .hg, .git, .bzr, _darcs といった名前のディレクトリ下にある全てのファイル

こうして完全なファイルのリストができ、後で参照するためにマニフェストに書き込まれます。この内容は、ソース配布物のアーカイブを作成する際に使われます。

含めるファイルのデフォルトセットは --no-defaults で無効化でき、標準で除外するセットは --no-prune で無効化できます。

Distutils 自体のマニフェストテンプレートから、 sdist コマンドがどのようにして Distutils ソース配布物に含めるファイルのリストを作成するか見てみましょう:

distutils ディレクトリ、および distutils/command サブディレクトリの下にある全ての Python ソースファイルを含めます (これらの二つのディレクトリが、setup スクリプト下の packages オプションに記載されているからです — setup スクリプトを書く を参照してください)

README.txt, setup.py, および setup.cfg (標準のファイルセット) を含めます

test/test*.py (標準のファイルセット) を含めます

配布物ルート下の *.txt を含めます (この処理で、 README.txt がもう一度見つかりますが、こうした冗長性は後で刈り取られます)

examples 下にあるサブツリー内で *.txt または *.py にマッチする全てのファイルを含めます

ディレクトリ名が examples/sample?/build にマッチするディレクトリ以下のサブツリー内にあるファイル全てを除外します— この操作によって、上の二つのステップでリストに含められたファイルが除外されることがあるので、マニフェストテンプレート内では recursive-include コマンドの後に prune コマンドを持ってくることが重要です

build ツリー全体、および RCS, CVS, .svn, .hg, .git, .bzr, _darcs ディレクトリ全てを除外します。

setup スクリプトと同様、マニフェストテンプレート中のディレクトリ名は常にスラッシュ区切りで表記します; Distutils は、こうしたディレクトリ名を注意深くプラットフォームでの標準的な表現に変換します。このため、マニフェストテンプレートは複数のオペレーティングシステムにわたって可搬性を持ちます。

コマンド

マニフェストテンプレートコマンド一覧:

コマンド | 説明
include pat1 pat2 ... | リストされたパターンのどれかにマッチする全てのファイルを含める
exclude pat1 pat2 ... | リストされたパターンのどれかにマッチする全てのファイルを除外する
recursive-include dir pat1 pat2 ... | dir 配下の、リストされたパターンのどれかにマッチする全てのファイルを含める
recursive-exclude dir pat1 pat2 ... | dir 配下の、リストされたパターンのどれかにマッチする全てのファイルを除外する
global-include pat1 pat2 ... | ソースツリー内にある、リストされたパターンのどれかにマッチする全てのファイルを含める
global-exclude pat1 pat2 ... | ソースツリー内にある、リストされたパターンのどれかにマッチする全てのファイルを除外する
prune dir | dir 配下の全てのファイルを除外する
graft dir | dir 配下の全てのファイルを含める

ここで使うパターンは、 Unix スタイルの “glob” パターンです。 * は通常のファイル名文字の任意のシーケンスにマッチします。 ? は通常のファイル名文字の1文字にマッチします。 [range] は range に含まれる全ての文字にマッチします (例: a-z, a-zA-Z, a-f0-9_.) 通常のファイル名文字は、プラットフォーム依存になります。 Unix ではスラッシュ以外の全ての文字で、 Windows ではコロンとバックスラッシュ以外の全ての文字です。

バージョン 2.7 で変更: sdist は既存の生成された MANIFEST ファイルを MANIFEST.in や setup.py の変更時刻と比較すること無しに再生成します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

ビルド済み配布物を作成する

“ビルド済み配布物” とは、おそらく皆さんが通常 “バイナリパッケージ” とか “インストーラ” (背景にしている知識によって違います) と考えているものです。とはいえ、配布物が必然的にバイナリ形式になるわけではありません。配布物には、 Python ソースコード、かつ/またはバイトコードが入るからです; また、我々はパッケージという呼び方もしません。すでに Python の用語として使っているからです (また、 “インストーラ” という言葉は主流のデスクトップシステム特有の用語です)

ビルド済み配布物は、モジュール配布物をインストール作業者にとってできるだけ簡単な状況にする方法です: ビルド済み配布物は、RPM ベースの Linux システムユーザにとってはバイナリ RPM 、Windows ユーザにとっては実行可能なインストーラ、 Debian ベースの Linux システムでは Debian パッケージ、などといった具合です。当然のことながら、一人の人間が世の中にある全てのプラットフォーム用にビルド済み配布物を作成できるわけではありません。そこで、 Distutils の設計は。開発者が自分の専門分野 — コードを書き、ソース配布物を作成する — に集中できる一方で、 パッケージ作成者 (packager) と呼ばれる、開発者とエンドユーザとの中間に位置する人々がソースコード配布物を多くのプラットフォームにおけるビルド済み配布物に変換できるようになっています。

もちろん、モジュール開発者自身がパッケージ作成者かもしれません; また、パッケージを作成するのはオリジナルの作成者が利用できないプラットフォームにアクセスできるような “外部の” ボランティアかもしれませんし、ソース配布物を定期的に取り込んで、アクセスできるかぎりのプラットフォーム向けにビルド済み配布物を生成するソフトウェアかもしれません。作業を行うのが誰であれ、パッケージ作成者は setup スクリプトを利用し、 bdist コマンドファミリを使ってビルド済み配布物を作成します。

単純な例として、Distutils ソースツリーから以下のコマンドを実行したとします:

python setup.py bdist

すると、Distutils はモジュール配布物 (ここでは Distutils 自体) をビルドし、”偽の (fake)” インストールを (build ディレクトリで) 行います。そして現在のプラットフォームにおける標準の形式でビルド済み配布物を生成します。デフォルトのビルド済み形式とは、Unixでは “ダム (dumb)” の tar ファイルで、 Windows ではシンプルな実行形式のインストーラになります。(tar ファイルは、特定の場所に手作業で解凍しないと動作しないので、 “ダム: 賢くない” 形式とみなします。)

従って、 Unix システムで上記のコマンドを実行すると、 Distutils-1.0.plat.tar.gz を作成します; この tarball を正しい場所で解凍すると、ちょうどソース配布物をダウンロードして python setup.py install を実行したのと同じように、正しい場所に Distutils がインストールされます。 (“正しい場所 (right place)” とは、ファイルシステムのルート下か、 Python の prefix ディレクトリ下で、これは bdist_dumb に指定するコマンドで変わります; デフォルトの設定では、 prefix からの相対パスにインストールされるダム配布物が得られます。)

言うまでもなく、 pure Python 配布物の場合なら、 python setup.py install するのに比べて大して簡単になったとは言えません—しかし、非 pure 配布物で、コンパイルの必要な拡張モジュールを含む場合、拡張モジュールを利用できるか否かという大きな違いになりえます。また、 RPM パッケージや Windows 用の実行形式インストーラのような “スマートな” ビルド済み配布物を作成しておけば、たとえ拡張モジュールが一切入っていなくてもユーザにとっては便利になります。

bdist コマンドには、 --formats オプションがあります。これは sdist コマンドの場合に似ていて、生成したいビルド済み配布物の形式を選択できます: 例えば、

python setup.py bdist --format=zip

とすると、Unix システムでは、 Distutils-1.0.plat.zip を作成します— 先にも述べたように、Distutils をインストールするには、このアーカイブ形式をルートディレクトリ下で展開します。

ビルド済み配布物として利用できる形式を以下に示します:

形式 | 説明 | 注記
gztar | gzip 圧縮された tar ファイル (.tar.gz) | (1),(3)
ztar | compress 圧縮された tar ファイル (.tar.Z) | (3)
tar | tar ファイル (.tar) | (3)
zip | zip ファイル (.zip) | (2),(4)
rpm | RPM 形式 | (5)
pkgtool | Solaris pkgtool 形式 |
sdux | HP-UX swinstall 形式 |
wininst | Windows 用の自己展開形式 ZIP ファイル | (4)
msi | マイクロソフト・インストーラー |

注記:

Unixでのデフォルト形式です

Windows でのデフォルト形式です

外部ユーティリティが必要です: tar と、 gzip または bzip2 または compress のいずれか

外部ユーティリティの zip か、 zipfile モジュール (Python 1.6 からは標準 Python ライブラリの一部になっています) が必要です

外部ユーティリティの rpm 、バージョン 3.0.4 以上が必要です (バージョンを調べるには、 rpm --version とします)

bdist コマンドを使うとき、必ず --formats オプションを使わなければならないわけではありません; 自分の使いたい形式をダイレクトに実装しているコマンドも使えます。こうした bdist “サブコマンド (sub-command)” は、実際には類似のいくつかの形式を生成できます; 例えば、 bdist_dumb コマンドは、全ての “ダム” アーカイブ形式 (tar, ztar, gztar, および zip) を作成できますし、 bdist_rpm はバイナリ RPM とソース RPM の両方を生成できます。 bdist サブコマンドと、それぞれが生成する形式を以下に示します:

コマンド | 形式
bdist_dumb | tar, ztar, gztar, zip
bdist_rpm | rpm, srpm
bdist_wininst | wininst
bdist_msi | msi

bdist_* コマンドについては、以下の節で詳しく述べます。

ダム形式のビルド済み配布物を作成する

RPM パッケージを作成する

RPM 形式は、Red Hat, SuSE, Mandrake といった、多くの一般的な Linux ディストリビューションで使われています。普段使っているのがこれらの環境のいずれか (またはその他の RPM ベースの Linux ディストリビューション) なら、同じディストリビューションを使っている他のユーザ用に RPM パッケージを作成するのはとるに足らないことでしょう。一方、モジュール配布物の複雑さや、 Linux ディストリビューション間の違いにもよりますが、他の RPM ベースのディストリビューションでも動作するような RPM を作成できるかもしれません。

通常、モジュール配布物の RPM を作成するには、 bdist_rpm コマンドを使います:

python setup.py bdist_rpm

あるいは、 bdist コマンドを --format オプション付きで使います:

python setup.py bdist --formats=rpm

前者の場合、 RPM 特有のオプションを指定できます; 後者の場合、一度の実行で複数の形式を指定できます。両方同時にやりたければ、それぞれの形式について各コマンドごとにオプション付きで bdist_* コマンドを並べます:

python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" \
                bdist_wininst --target-version="2.0"

Distutils が setup スクリプトで制御されているのとほとんど同じく、 RPM パッケージの作成は、 .spec で制御されています。 RPM の作成を簡便に解決するため、 bdist_rpm コマンドでは通常、 setup スクリプトに与えた情報とコマンドライン、そして Distutils 設定ファイルに基づいて .spec ファイルを作成します。 .spec ファイルの様々なオプションやセクション情報は、以下のようにして setup スクリプトから取り出されます:

RPM .spec ファイルのオプションまたはセクション | Distutils setup スクリプト内のオプション
Name | name
Summary (preamble 内) | description
Version | version
Vendor | author と author_email, または — & maintainer と maintainer_email
Copyright | license
Url | url
%description (セクション) | long_description

また、 .spec ファイル内の多くのオプションは、 setup スクリプト中に対応するオプションがありません。これらのほとんどは、以下に示す bdist_rpm コマンドのオプションで扱えます:

RPM .spec ファイルのオプションまたはセクション | bdist_rpm オプション | デフォルト値
Release | release | “1”
Group | group | “Development/Libraries”
Vendor | vendor | (上記参照)
Packager | packager | (none)
Provides | provides | (none)
Requires | requires | (none)
Conflicts | conflicts | (none)
Obsoletes | obsoletes | (none)
Distribution | distribution_name | (none)
BuildRequires | build_requires | (none)
Icon | icon | (none)

言うまでもなく、こうしたオプションをコマンドラインで指定するのは面倒だし、エラーの元になりますから、普通は setup.cfg に書いておくのがベストです — setup 設定ファイル (setup configuration file) を書く 節を参照してください。沢山の Python モジュール配布物を配布したりパッケージ化したりしているのなら、配布物全部に当てはまるオプションを個人用の Distutils 設定ファイル (~/.pydistutils.cfg) に入れられます。このファイルを一時的に無効にしたい場合、 setup.py に –no-user-cfg オプションを指定できます。

バイナリ形式の RPM パッケージを作成する際には三つの段階があり、 Distutils はこれら全ての段階を自動的に処理します:

RPM パッケージの内容を記述する .spec ファイルを作成します (.spec ファイルは setup スクリプトに似たファイルです; 実際、 setup スクリプトのほとんどの情報が .spec ファイルから引き揚げられます)

ソース RPM を作成します

“バイナリ (binary)” RPM を生成します (モジュール配布物に Python 拡張モジュールが入っているか否かで、バイナリコードが含まれることも含まれないこともあります)

通常、RPM は最後の二つのステップをまとめて行います; Distutils を使うと、普通は三つのステップ全てをまとめて行います。

望むなら、これらの三つのステップを分割できます。 bdist_rpm コマンドに --spec-only を指定すれば、単に .spec を作成して終了します; この場合、 .spec ファイルは “配布物ディレクトリ (distribution directory)”— 通常は dist/ に作成されますが、 --dist-dir オプションで変更することもできます。(通常、 .spec ファイルは “ビルドツリー (build tree)”、すなわち build_rpm が作成する一時ディレクトリの中から引き揚げられます。)

Windows インストーラを作成する

実行可能なインストーラは、Windows 環境ではごく自然なバイナリ配布形式です。インストーラは結構なグラフィカルユーザインタフェースを表示して、モジュール配布物に関するいくつかの情報を setup スクリプト内のメタデータから取り出して示し、ユーザがいくつかのオプションを選んだり、インストールを決行するか取りやめるか選んだりできるようにします。

メタデータは setup スクリプトから取り出されるので、Windows インストーラの作成は至って簡単で、以下を実行するだけです:

python setup.py bdist_wininst

あるいは、 bdist コマンドを --formats オプション付きで実行します:

python setup.py bdist --formats=wininst

(pure Python モジュールとパッケージだけの入った) pure モジュール配布物の場合、作成されるインストーラは実行バージョンに依存しない形式になり、 foo-1.0.win32.exe のような名前になります。 pure モジュールの Windows インストーラは Unix や Mac OS X でも作成できます。

非 pure 配布物の場合、拡張モジュールは Windows プラットフォーム上だけで作成でき、Python のバージョンに依存したインストーラになります。インストーラのファイル名もバージョン依存性を反映して、 foo-1.0.win32-py2.0.exe のような形式になります。従って、サポートしたい全てのバージョンの Python に対して、別々のインストーラを作成しなければなりません。

インストーラは、ターゲットとなるシステムにインストールを実行した後、 pure モジュールを通常 (normal) モードと最適化 (optimizing) モードでバイトコード(bytecode)にコンパイルしようと試みます。何らかの理由があってコンパイルさせたくなければ、 bdist_wininst コマンドを --no-target-compile かつ/または --no-target-optimize オプション付きで実行します。

デフォルトでは、インストーラは実行時にクールな “Python Powered” ロゴを表示しますが、自作の152x261ビットマップ画像も指定できます。画像は Windows の .bmp ファイル形式でなくてはならず、 --bitmap オプションで指定します。

インストーラを起動すると、デスクトップの背景ウィンドウ上にでっかいタイトルも表示します。タイトルは配布物の名前とバージョン番号から作成します。 --title オプションを使えば、タイトルを別のテキストに変更できます。

インストーラファイルは “配布物ディレクトリ (distribution directory)” — 通常は dist/ に作成されますが、 --dist-dir オプションで指定することもできます。

Windowsでのクロスコンパイル

Python 2.6 から、 distutils は Windows プラットフォーム間でのクロスコンパイルに対応しました。これによって、必要なツールがインストールされていれば、 32bit 版の Windows で 64bit 版の拡張を作成したり、その逆が可能になりました。

別のプラットフォーム用にビルドするには、 build コマンドの --plat-name オプションを指定します。有効な値は、現在のところ、 ‘win32’, ‘win-amd64’, ‘win-ia64’ です。例えば、次のようにして 32bit 版の Windows で 64bit 版の拡張をビルドできます。

python setup.py build --plat-name=win-amd64

Windows インストーラもこのオプションをサポートしています。なので次のコマンドを実行すると:

python setup.py build --plat-name=win-amd64 bdist_wininst

64bit のインストーラを32bitのWindowsで作成できます。

クロスコンパイルするためには、Python のソースコードをダウンロードして Python 自体をターゲットのプラットフォーム用にクロスコンパイルしなければなりません。 Python のバイナリインストールからではクロスコンパイルできません。(他のプラットフォーム用の .lib などのファイルが含まれないからです。) 具体的に言えば、拡張のクロスコンパイルができるようになるには、 32bit OS のユーザーは Visual Studio 2008 を使って Python ソースツリー内の PCBuild/PCbuild.sln ソリューションファイルを開き、 “x64” コンフィギュレーションで ‘pythoncore’ プロジェクトをビルドしなければなりません。

デフォルトでは、 Visual Studio 2008 は 64bit のコンパイラーなどのツールをインストールしないことに注意してください。 Visual Studio セットアッププロセスを再実行して、それらのツールを選択する必要があるでしょう。(コントロールパネル -> [追加と削除] から簡単に既存のインストールをチェック、修正できます。)

インストール後実行スクリプト (postinstallation script)

Python 2.3 からは、インストール実行後スクリプトを --install-script オプションで指定できるようになりました。スクリプトはディレクトリを含まないベースネーム (basename) で指定しなければならず、スクリプトファイル名は setup 関数の scripts 引数中に挙げられていなければなりません。

指定したスクリプトは、インストール時、ターゲットとなるシステム上で全てのファイルがコピーされた後に実行されます。このとき argv[1] を -install に設定します。また、アンインストール時には、ファイルを削除する前に argv[1] を -remove に設定して実行します。

Windows インストーラでは、インストールスクリプトは埋め込みで実行され、全ての出力 (sys.stdout 、 sys.stderr) はバッファにリダイレクトされ、スクリプトの終了後に GUI 上に表示されます。

インストールスクリプトでは、インストール/アンインストールのコンテキストで特に有用ないくつかの機能を、追加の組み込み関数として利用することができます。

directory_created(path)

file_created(path)

これらの関数は、インストール後実行スクリプトがディレクトリやファイルを作成した際に呼び出さなければなりません。この関数はアンインストーラに作成された path を登録し、配布物をアンインストールする際にファイルが消されるようにします。安全を期すために、ディレクトリは空の時にのみ削除されます。

get_special_folder_path(csidl_string)

この関数は、「スタートメニュー」や「デスクトップ」といった、 Windows における特殊なフォルダ位置を取得する際に使えます。この関数はフォルダのフルパスを返します。 csidl_string は以下の文字列のいずれかでなければなりません:

"CSIDL_APPDATA"

"CSIDL_COMMON_STARTMENU"
"CSIDL_STARTMENU"

"CSIDL_COMMON_DESKTOPDIRECTORY"
"CSIDL_DESKTOPDIRECTORY"

"CSIDL_COMMON_STARTUP"
"CSIDL_STARTUP"

"CSIDL_COMMON_PROGRAMS"
"CSIDL_PROGRAMS"

"CSIDL_FONTS"

該当するフォルダを取得できなかった場合、 OSError が送出されます。

どの種類のフォルダを取得できるかは、特定の Windows のバージョンごとに異なります。また、おそらく設定によっても異なるでしょう。詳細については、 SHGetSpecialFolderPath() 関数に関する Microsoft のドキュメントを参照してください。

create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])

この関数はショートカットを作成します。 target はショートカットによって起動されるプログラムへのパスです。 description はショートカットに対する説明です。 filename はユーザから見えるショートカットの名前です。コマンドライン引数があれば、 arguments に指定します。 workdir はプログラムの作業ディレクトリです。 iconpath はショートカットのためのアイコンが入ったファイルで、 iconindex はファイル iconpath 中のアイコンへのインデクスです。これについても、詳しくは IShellLink インタフェースに関する Microsoft のドキュメントを参照してください。

Vista User Access Control (UAC)

Python 2.6 から、 bdist_wininst は --user-access-control オプションをサポートしています。デフォルトは ‘none’ (UAC制御をしないことを意味します) で、それ以外の有効な値は ‘auto’ (Python が全ユーザー用にインストールされていれば UAC 昇格を行う)、 ‘force’ (常に昇格を行う) です。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

パッケージインデクスに登録する

Python パッケージインデクス (Python Package Index, PyPI) は、 distutils でパッケージ化された配布物に関するメタデータを保持しています。配布物のメタデータをインデクスに提出するには、 Distutils のコマンド register を使います。 register は以下のように起動します:

python setup.py register

Distutils は以下のようなプロンプトを出します:

running register
We need to know who you are, so please choose either:
    1. use your existing login,
    2. register as a new user,
    3. have the server generate a new password for you (and email it to you), or
    4. quit
Your selection [default 1]:

注意: ユーザ名とパスワードをローカルの計算機に保存しておくと、このメニューは表示されません。

まだ PyPI に登録したことがなければ、まず登録する必要があります。この場合選択肢 2 番を選び、リクエストされた詳細情報を入力してゆきます。詳細情報を提出し終えると、登録情報の承認を行うためのメールを受け取るはずです。

すでに登録を行ったことがあれば、選択肢 1 を選べます。この選択肢を選ぶと、PyPI ユーザ名とパスワードを入力するよう促され、 register がメタデータをインデクスに自動的に提出します。

配布物の様々なバージョンについて、好きなだけインデクスへの提出を行ってかまいません。特定のバージョンに関するメタデータを入れ替えたければ、再度提出を行えば、インデクス上のデータが更新されます。

PyPI は提出された配布物の (名前、バージョン) の各組み合わせについて記録を保持しています。ある配布物名について最初に情報を提出したユーザが、その配布物名のオーナ (owner) になります。オーナは register コマンドか、web インタフェースを介して変更を提出できます。オーナは他のユーザをオーナやメンテナとして指名できます。メンテナはパッケージ情報を編集できますが、他の人をオーナやメンテナに指名することはできません。

デフォルトでは、 PyPI はあるパッケージについて全てのバージョンを表示します。特定のバージョンを非表示にしたければ、パッケージの Hidden プロパティを yes に設定します。この値は web インタフェースで編集しなければなりません。

.pypirc ファイル

.pypirc ファイルのフォーマットを示します。

[distutils]
index-servers =
    pypi

[pypi]
repository: <repository-url>
username: <username>
password: <password>

distutils セクションは、 index-servers でリポジトリを設定する全てのセクション名のリストを定義しています。

リポジトリを表す各セクションは3つの変数を定義します:

repository は PyPI サーバーの URL を定義します。

デフォルトでは http://www.python.org/pypi になります。

username は PyPI サーバーに登録されたユーザー名です。

password は認証に使われます。省略された場合、必要なときに入力を求められます。

別のサーバーを定義した場合は、新しいセクションを作成し、 index-servers に追加します。

[distutils]
index-servers =
  pypi
  other

[pypi]
repository: <repository-url>
username: <username>
password: <password>

[other]
repository: http://example.com/pypi
username: <username>
password: <password>

register は -r オプションで対象となるリポジトリを指定して実行することができます。

python setup.py register -r http://example.com/pypi

使いやすくするために、セクション名を使ってリポジトリを指定することもできます。

python setup.py register -r other

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

パッケージを Package Index にアップロードする

バージョン 2.5 で追加.

Python Package Index (PyPI) は、パッケージ情報に加えて、作者が望むのであればパッケージデータを置くこともできます。 distutils の upload コマンドは配布物をPyPIにアップロードします。

このコマンドは一つ以上の配布物ファイルをビルドした直後に呼び出されます。例えば、次のコマンド

python setup.py sdist bdist_wininst upload

は、ソース配布物とWindowsのインストーラをPyPIにアップロードします。以前に setup.py を実行してビルドした配布物もアップロード対象になるけれども、アップロードされるのは upload コマンドと同時に指定された配布物だけだということに注意してください。

upload コマンドは、 $HOME/.pypirc ファイル (詳しくは .pypirc ファイル セクションをご覧下さい) の、ユーザー名、パスワードとリポジトリURLを利用します。同じコマンド内で register コマンドが呼ばれていて、そこでプロンプトからパスワードを入力した場合、 upload は入力されたパスワードを再利用します。 $HOME/.pypirc ファイルにプレインテキストでパスワードを保存したくない場合はこの方法を利用できます。

--repository=*url* オプションを使って別のPyPIサーバーを指定することができます。

python setup.py sdist bdist_wininst upload -r http://example.com/pypi

複数のサーバーを定義することについて、より詳しい情報は .pypirc ファイル を参照してください。

--sign オプションで、アップロードする各ファイルにGPG (GNU Privacy Guard) を使うことができます。 gpg プログラムが環境変数 PATH から実行可能である必要があります。署名にどの鍵を使うかを、 --identity=*name* で指定することもできます。

他の upload のオプションには、 --repository= (url はサーバーのURL), --repository= (section は $HOME/.pypirc のセクション名), --show-response (アップロードの問題をデバッグするために、PyPI サーバーからの全てのレスポンスを表示する)があります。

PyPI パッケージ表示

long_description フィールドは PyPI において特別な役目を持ちます。サーバーは登録されたパッケージのホームページを表示するためにこれを利用します。

このフィールドに reStructuredText [http://docutils.sourceforge.net/rst.html] 記法を利用した場合、 PyPI はこれをパースして、パッケージのホームページにHTML 出力を表示します。

long_description フィールドにパッケージ内のファイルの内容を利用することもできます。

from distutils.core import setup

with open('README.txt') as file:
    long_description = file.read()

setup(name='Distutils',
      long_description=long_description)

この例では、 README.txt は通常の reStructuredText テキストファイルで、 setup.py と同じパッケージのルートディレクトリに置かれています。

壊れた reStructuredText を登録してしまうのを防ぐために、コマンドラインから docutils パッケージが提供している rst2html プログラムを利用して long_description をチェックすることができます。

$ python setup.py --long-description | rst2html.py > output.html

文法に問題がある場合は、 docutils は警告を表示するはずです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

例

この章は distutils を使い始めるのに役立つ幾つかの基本的な例を提供します。 distutils を使うための追加の情報は Distutils Cookbook で見つけることができます。

参考

Distutils Cookbook [http://wiki.python.org/moin/Distutils/Cookbook]

distutils をもっと制御するためのレシピ集

pure Python 配布物 (モジュール形式)

単に二つのモジュール、特定のパッケージに属しないモジュールを配布するだけなら、setup スクリプト中で py_modules オプションを使って個別に指定できます。

もっとも単純なケースでは、二つのファイル: setup スクリプト自体と、配布したい単一のモジュール、この例では foo.py について考えなければなりません:

<root>/
        setup.py
        foo.py

(この節の全ての図において、 <root> は配布物ルートディレクトリを参照します。) この状況を扱うための最小の setup スクリプトは以下のようになります:

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )

配布物の名前は name オプションで個々に指定し、配布されるモジュールの一つと配布物を同じ名前にする必要はないことに注意してください (とはいえ、この命名方法はよいならわしでしょう)。ただし、配布物名はファイル名を作成するときに使われるので、文字、数字、アンダースコア、ハイフンだけで構成しなければなりません。

py_modules はリストなので、もちろん複数のモジュールを指定できます。例えば、モジュール foo と bar を配布しようとしているのなら、 setup スクリプトは以下のようになります:

<root>/
        setup.py
        foo.py
        bar.py

また、セットアップスクリプトは以下のようになります．

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      py_modules=['foo', 'bar'],
      )

モジュールのソースファイルは他のディレクトリに置けますが、そうしなければならないようなモジュールを沢山持っているのなら、モジュールを個別に列挙するよりもパッケージを指定した方が簡単でしょう。

pure Python 配布物 (パッケージ形式)

二つ以上のモジュールを配布する場合、とりわけ二つのパッケージに分かれている場合、おそらく個々のモジュールよりもパッケージ全体を指定する方が簡単です。たとえモジュールがパッケージ内に入っていなくても状況は同じで、その場合はルートパッケージにモジュールが入っていると Distutils に教えることができ、他のパッケージと同様にうまく処理されます (ただし、 __init__.py があってはなりません)。

最後の例で挙げた setup スクリプトは、

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=[''],
      )

のようにも書けます (空文字はルートパッケージを意味します)

これら二つのファイルをサブディレクトリ下に移動しておいて、インストール先はルートパッケージのままにしておきたい、例えば:

<root>/
        setup.py
        src/      foo.py
                  bar.py

のような場合には、パッケージ名にはルートパッケージをそのまま指定しておきますが、ルートパッケージに置くソースファイルがどこにあるかを Distutils に教えなければなりません:

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'': 'src'},
      packages=[''],
      )

もっと典型的なケースでは、複数のモジュールを同じパッケージ (またはサブパッケージ) に入れて配布しようと思うでしょう。例えば、 foo と bar モジュールがパッケージ foobar に属する場合、ソースツリーをレイアウトする一案として、以下が考えられます。

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py

実際、 Distutils ではこれをデフォルトのレイアウトとして想定していて、setup スクリプトを書く際にも最小限の作業しか必要ありません:

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=['foobar'],
      )

モジュールを入れるディレクトリをパッケージの名前にしたくない場合、ここでも package_dir オプションを使う必要があります。例えば、パッケージ foobar のモジュールが src に入っているとします:

<root>/
        setup.py
        src/
                 __init__.py
                 foo.py
                 bar.py

適切な setup スクリプトは、

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'foobar': 'src'},
      packages=['foobar'],
      )

のようになるでしょう。

また、メインパッケージ内のモジュールを配布物ルート下に置くことがあるかもしれません:

<root>/
        setup.py
        __init__.py
        foo.py
        bar.py

この場合、 setup スクリプトは

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'foobar': ''},
      packages=['foobar'],
      )

のようになるでしょう。 (空文字列も現在のディレクトリを表します。)

サブパッケージがある場合、 packages で明示的に列挙しなければなりませんが、 package_dir はサブパッケージへのパスを自動的に展開します。 (別の言い方をすれば、 Distutils はソースツリーを 走査せず 、どのディレクトリが Python パッケージに相当するのかを __init__.py files. を探して調べようとします。) このようにして、デフォルトのレイアウトはサブパッケージ形式に展開されます:

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py
                 subfoo/
                           __init__.py
                           blah.py

対応する setup スクリプトは以下のようになります。

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=['foobar', 'foobar.subfoo'],
      )

(ここでも、 package_dir を空文字列にすると現在のディレクトリを表します。)

単体の拡張モジュール

拡張モジュールは、 ext_modules オプションを使って指定します。 package_dir は、拡張モジュールのソースファイルをどこで探すかには影響しません; pure Python モジュールのソースのみに影響します。もっとも単純なケースでは、単一の C ソースファイルで書かれた単一の拡張モジュールは:

<root>/
        setup.py
        foo.c

になります。

foo 拡張をルートパッケージ下に所属させたい場合、 setup スクリプトは

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

になります。

同じソースツリーレイアウトで、この拡張モジュールを foopkg の下に置き、拡張モジュールの名前を変えるには:

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version = '1.0',
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )

のようにします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

Distutilsの拡張

Distutilsは様々な方法で拡張できます。ほとんどの拡張は存在するコマンドを新しいコマンドで置換する形でおこなわれます。新しいコマンドはたとえば存在するコマンドを置換して、そのコマンドでパッケージをどう処理するかの細部を変更することでプラットフォーム特有のパッケージ形式をサポートするために書かれているかもしれません

ほとんどのdistutilsの拡張は存在するコマンドを変更したい setup.py スクリプト中で行われます。ほとんどはパッケージにコピーされるファイル拡張子を .py の他に、いくつか追加するものです。

ほとんどのdistutilsのコマンド実装は distutils.cmd の distutils.cmd.Command クラスのサブクラスとして実装されています。新しいコマンドは Command を直接継承し、置換するコマンドでは置換対象のコマンドのサブクラスにすることで Command を間接的に継承します。コマンドは Command から派生したものである必要があります。

新しいコマンドの統合

新しいコマンド実装を統合するにはいくつかの方法があります。一番難しいものは新機能をdistutils本体に取り込み、それのサポートを提供するPythonのバージョンが出ることを待つ(そして使う)ことです。これは様々な理由で本当に難しいことです。

もっとも一般的な、そしておそらくほとんどの場合にもっとも妥当な方法は、新しい実装をあなたの setup.py スクリプトに取り込み、 distutils.core.setup() 関数でそれらを使うようにすることです。

from distutils.command.build_py import build_py as _build_py
from distutils.core import setup

class build_py(_build_py):
    """Specialized Python source builder."""

    # implement whatever needs to be different...

setup(cmdclass={'build_py': build_py},
      ...)

このアプローチは新実装をある特定のパッケージで利用したい時、そのパッケージに興味をもつ人全員がコマンドの新実装を必要とする時にもっとも価値があります。

Python 2.4から、インストールされたPythonを変更せずに、既存の setup.py スクリプトをサポートするための3つめの選択肢が利用できるようになりました。これは追加のパッケージングシステムのサポートを追加するサードパーティ拡張を提供することを想定していますが、これらのコマンドはdistutilsが利用されている何にでも利用可能です。新しい設定オプション command_packages (コマンドラインオプション --command-packages) は、コマンド実装モジュールを検索する追加のパッケージを指定するために利用できます。 distutilsの全てのオプションと同様に、このオプションもコマンドラインまたは設定ファイルで指定できます。このオプションは設定ファイル中では [global] セクションか、コマンドラインのコマンドより前でだけ設定できます。設定ファイル中で指定する場合、コマンドラインで上書きすることができます。空文字列を指定するとデフォルト値が使われます。これはパッケージと一緒に提供する設定ファイルでは指定しないでください。

この新オプションによってコマンド実装を探すためのパッケージをいくつでも追加することができます。複数のパッケージ名はコンマで区切って指定します。指定がなければ、検索は distutils.command パッケージのみで行われます。ただし setup.py がオプション --command-packages distcmds,buildcmds で実行されている場合には、パッケージは distutils.command 、 distcmds 、そして buildcmds を、この順番で検索します。新コマンドはコマンドと同じ名前のモジュールに、コマンドと同じ名前のクラスで実装されていると想定しています。上のコマドラインオプションの例では、コマンド bdist_openpkg は、 distcmds.bdist_openpkg.bdist_openpkg か、 buildcmds.bdist_openpkg.bdist_openpkg で実装されるかもしれません。

配布物の種類を追加する

配布物 (dist/ ディレクトリの中のファイル) を作成するコマンドは、 upload がその配布物をPyPIにアップロードできるように、 (command, filename) のペアを self.distributions.dist_files に追加する必要があります。ペア中の filename はパスに関する情報を持たず、単にファイル名だけを持ちます。 dry-run モードでも、何が作成されたかを示すために、同じペアが必要になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

コマンドリファレンス

モジュールをインストールする: install コマンド群

install コマンドは最初にビルドコマンドを実行しておいてから、サブコマンド install_lib を実行します。 install_data and install_scripts.

install_data

このコマンドは配布物中に提供されている全てのデータファイルをインストールします。

install_scripts

このコマンドは配布物中の全ての (Python) スクリプトをインストールします。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

API リファレンス

distutils.core — Distutils のコア機能

Distutilsを使うためにインストールする必要がある唯一のモジュールが distutils.core モジュールです。 setup() 関数 (セットアップスクリプトから呼び出されます)を提供します。間接的に distutils.dist.Distribution クラスと distutils.cmd.Command クラスを提供します。

distutils.core.setup(arguments)

全てを実行する基本的な関数で、Distutilsでできるほとんどのことを実行します。

setup関数はたくさんの引数をとります。以下のテーブルにまとめます。

引数名 | 値 | 型
name | パッケージの名前 | 文字列
version | パッケージのバージョン番号 | distutils.version を参照してください
description | 1行で書いたパッケージ解説 | 文字列
long_description | パッケージの長い解説 | 文字列
author | パッケージ作者の名前 | 文字列
author_email | パッケージ作者のemailアドレス | 文字列
maintainer | 現在のメンテナの名前(パッケージ作者と異なる場合) | 文字列
maintainer_email | 現在のメンテナのemailアドレス(パッケージ作者と異なる場合) |
url | パッケージのURL(ホームページ) | URL
download_url | パッケージダウンロード用URL | URL
packages | distutilsが操作するPythonパッケージのリスト | 文字列のリスト
py_modules | distutilsが操作するPythonモジュールのリスト | 文字列のリスト
scripts | ビルドおよびインストールする単体スクリプトファイルのリスト | 文字列のリスト
ext_modules | ビルドする拡張モジュール | distutils.core.Extension インスタンスのリスト
classifiers | パッケージのカテゴリのリスト | 利用可能なカテゴリ一覧は http://cheeseshop.python.org/pypi?:action=list_classifiers にあります。
distclass | 使用する Distribution クラス | distutils.core.Distribution のサブクラス
script_name | setup.pyスクリプトの名前 - デフォルトでは sys.argv[0] | 文字列
script_args | セットアップスクリプトの引数 | 文字列のリスト
options | セットアップスクリプトのデフォルト引数 | 文字列
license | パッケージのライセンス | 文字列
keywords | 説明用メタデータ。 PEP 314 [http://www.python.org/dev/peps/pep-0314] を参照してください |
platforms |  |
cmdclass | コマンド名から Command サブクラスへのマッピング | 辞書
data_files | インストールするデータファイルのリスト | リスト
package_dir | パッケージからディレクトリ名へのマッピング | 辞書

distutils.core.run_setup(script_name[, script_args=None, stop_after='run'])

制御された環境でセットアップスクリプトを実行し、いろいろなものを操作する distutils.dist.Distribution クラスのインスタンスを返します。これはディストリビューションのメタデータ(キーワード引数 script として関数 setup() に渡される)を参照したり、設定ファイルやコマンドラインの内容を調べる時に便利です。

script_name は execfile() で実行されるファイルです。 sys.argv[0] は、呼び出しのために script_name と置換されます。 script_args は文字列のリストです。もし提供されていた場合、 sys.argv[1:] は、呼び出しのために script_args で置換されます。

stop_after はいつ動作を停止するか関数 setup() に伝えます。とりうる値は:

値 | 説明
init | Distribution インスタンスを作成し、キーワード引数を setup() に渡したあとに停止する。
config | 設定ファイルをパーズしたあと停止する(そしてそのデータは Distribution インスタンスに保存される)。
commandline | コマンドライン (sys.argv[1:] または script_args) がパーズされたあとに停止する (そしてそのデータは Distribution インスタンスに保存される)。
run | 全てのコマンドを実行したあとに停止する(関数 setup() を通常の方法で呼び出した場合と同じ)。デフォルト値。

これに加えて、 distutils.core モジュールは他のモジュールにあるいくつかのクラスを公開しています。

Extension は distutils.extension から。

Command は distutils.cmd から。

Distribution は distutils.dist から。

それぞれの簡単な説明を以下に記します。完全な説明についてはそれぞれのモジュールをごらんください。

class distutils.core.Extension

Extension クラスは、セットアップスクリプト中で C または C++拡張モジュールを表します。コンストラクタで以下のキーワード引数をとります。

引数名 | 値 | 型
name | 拡張のフルネーム(パッケージを含む) — ファイル名やパス名では なく 、Pythonのピリオド区切りの名前 | 文字列
sources | ソースファイル名のリスト。配布物ルートディレクトリ (setupスクリプトのある場所) からの相対パス、プラットフォーム独立のため Unix 形式(スラッシュで区切る)で記述します。ソースファイルは C, C++, SWIG (.i)、特定プラットフォーム用のリソースファイル、その他 build_ext コマンドがソースファイルだと認識するどの形式でもありえます。 | 文字列
include_dirs | C/C++ヘッダファイルを検索するディレクトリのリスト(プラットフォーム独立のため Unix 形式で記述する) | 文字列
define_macros | 定義するマクロのリスト; それぞれのマクロは2要素のタプル (name, value) で定義されます。 value には定義しようとしている文字列、または内容なしで定義する場合は None (ソースコード中で #define FOO と書く、または Unix Cコンパイラのコマンドラインで -DFOO を指定するのと等価です)を指定します。 | (文字列, 文字列) または (文字列, None) のタプル
undef_macros | 定義を消すマクロのリスト | 文字列
library_dirs | リンク時にC/C++ライブラリを検索するディレクトリのリスト | 文字列
libraries | リンクするライブラリ名のリスト (ファイル名やパスではない) | 文字列
runtime_library_dirs | 実行時(shared extensionでは、拡張が読み込まれる時)に C/C++ライブラリを探索するディレクトリのリスト | 文字列
extra_objects | 追加でリンクするファイル(‘sources’に対応するコードが含まれていないファイル、バイナリ形式のリソースファイルなど)のリスト | 文字列
extra_compile_args | ‘sources’のソースをコンパイルする時に追加するプラットフォーム特有またはコンパイラ特有の情報コマンドラインを利用できるプラットホームとコンパイラでは、これは通常コマンドライン引数のリストですが、他のプラットホームでも、それは何かに使えます。 | 文字列
extra_link_args | オブジェクトファイルをリンクして拡張(または新しいPythonインタプリタ)を作る時に追加するプラットフォーム特有またはコンパイラ特有の情報 ‘extra_compile_args’に似た実装です。 | 文字列
export_symbols | shared extensionからエクスポートされるシンボルのリスト。全てのプラットフォームでは使われず、 Python拡張(典型的には init + extension_name という1つのシンボルだけエクスポートする)に一般的に必要なものでもない。 | 文字列
depends | 拡張が依存するファイルのリスト | 文字列
language | 拡張の言語 (例: 'c', 'c++', 'objc')。指定しなければソースの拡張子で検出される。 | 文字列

class distutils.core.Distribution

Distribution はPythonソフトウェアパッケージをどのようにビルド、インストール、パッケージするかを定義する。

Distribution のコンストラクタが取りうるキーワード引数のリストに関しては、 setup() 関数を見てください。 setup() は Distribution のインスタンスを作ります。

class distutils.core.Command

Command クラス(そのサブクラスのインスタンス)はdistutilsのあるコマンドを実装します。

distutils.ccompiler — CCompiler ベースクラス

このモジュールは CCompiler クラスの抽象ベースクラスを提供します。 CCompiler のインスタンスはプロジェクトにおける全てのコンパイルおよびリンクに使われます。コンパイラのオプションを設定するためのメソッドが提供されます — マクロ定義、includeディレクトリ、リンクパス、ライブラリなど。

このモジュールは以下の関数を提供します。

distutils.ccompiler.gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries)

ライブラリを探索するディレクトリ、特定のライブラリとのリンクをするためのリンカオプションを生成します。 libraries と library_dirs はそれぞれライブラリ名(ファイル名ではありません!)のリストと、探索ディレクトリのリストです。 compilerで利用できるコマンドラインオプションのリスト(指定されたフォーマット文字列に依存します)を返します。

distutils.ccompiler.gen_preprocess_options(macros, include_dirs)

Cプリプロセッサオプション(-D, -U, -I)を生成します。これらは少なくとも2つのコンパイラで利用可能です。典型的な Unix のコンパイラと、VisualC++です。 macros は1または2要素のタプルで (name,) は name マクロの削除 (-U)を意味し、 (name,value) は name マクロを value として定義(-D)します。 include_dirs はディレクトリ名のリストで、ヘッダファイルのサーチパスに追加されます(-I)。 Unix のコンパイラと、Visual C++で利用できるコマンドラインオプションのリストを返します。

distutils.ccompiler.get_default_compiler(osname, platform)

指定されたプラットフォームのデフォルトコンパイラを返します。

問い合わせの osname はPython標準のOS名(os.name で返されるもの)のひとつであるべきで、 platform は sys.platform で返される共通の値です。

パラメータが指定されていない場合のデフォルト値は os.name と sys.platform です。

distutils.ccompiler.new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0)

指定されたプラットフォーム/コンパイラの組み合わせ向けに、 CCompilerサブクラスのインスタンスを生成するファクトリ関数です。 plat のデフォルト値は os.name (例: 'posix', 'nt'), compiler)、 compiler のデフォルト値はプラトフォームのデフォルトコンパイラです。現在は 'posix' と 'nt' だけがサポートされています、デフォルトのコンパイラは “traditional Unix interface” (UnixCCompiler クラス) と、 Visual C++ (MSVCCompiler クラス) です。 WindowsでUnixコンパイラオブジェクトを要求することも、UnixでMicrosoft コンパイラオブジェクトを要求することも可能です。 compiler 引数を与えると plat は無視されます。

distutils.ccompiler.show_compilers()

利用可能なコンパイラのリストを表示します(build, build_ext, build_clib の、 --help-compiler オプションで使われます。)

class distutils.ccompiler.CCompiler([verbose=0, dry_run=0, force=0])

抽象ベースクラス CCompiler は実際のコンパイラクラスで実装される必要のあるインタフェースを定義しています。このクラスはコンパイラクラスで利用されるユーティリティメソッドも定義しています。

コンパイラ抽象クラスの基本的な前提は、各インスタンスはあるプロジェクトをビルドするときの全コンパイル/リンクで利用できるということです。そこで、コンパイルとリンクステップで共通する属性 — インクルードディレクトリ、マクロ定義、リンクするライブラリなど — はコンパイラインスタンスの属性になります。どのように各ファイルが扱われるかを変更できるように、ほとんどの属性はコンパイルごと、またはリンクごとに与えることができます。

各サブクラスのコンストラクタは Compiler クラスのインスタンスを作ります。フラグは verbose (冗長な出力を表示します)、 dry_run (実際にはそのステップを実行しません)、そして force (依存関係を無視して全て再ビルドします)です。これらのフラグは全てデフォルト値が 0 (無効)になっています。 CCompiler またはサブクラスを直接インスタンス化したくない場合には、かわりに distutils.CCompiler.new_compiler() ファクトリ関数を利用してください。

以下のメソッドで、Compilerクラスのインスタンスが使うコンパイラオプションを手動で変更できます。

add_include_dir(dir)

dir をヘッダファイル探索ディレクトリのリストに追加します。コンパイラは add_include_dir() を呼び出した順にディレクトリを探索するよう指定されます。

set_include_dirs(dirs)

探索されるディレクトリのリストを dirs (文字列のリスト)に設定します。先に実行された add_include_dir() は上書きされます。後で実行する add_include_dir() は set_include_dirs() のリストにディレクトリを追加します。これはコンパイラがデフォルトで探索する標準インクルードディレクトリには影響しません。

add_library(libname)

libname をコンパイラオブジェクトによるリンク時に使われるライブラリのリストに追加します。 libname はライブラリを含むファイル名ではなく、ライブラリそのものの名前です: 実際のファイル名はリンカ、コンパイラ、またはコンパイラクラス(プラットフォームに依存します)から推測されます。

リンカは add_library() と set_library() で渡された順にライブラリをリンクしようとします。ライブラリ名が重なることは問題ありません。リンカは指定された回数だけライブラリとリンクしようとします。

set_libraries(libnames)

コンパイラオブジェクトによるリンク時に使われるライブラリのリストを libnames (文字列のリスト)に設定します。これはリンカがデフォルトでリンクする標準のシステムライブラリには影響しません。

add_library_dir(dir)

add_library() と set_libraries() で指定されたライブラリを探索するディレクトリのリストに dir を追加します。リンカは add_library_dir() と set_library_dirs() で指定された順にディレクトリを探索されます。

set_library_dirs(dirs)

ライブラリを探索するディレクトリを dirs (文字列のリスト)に設定します。これはリンカがデフォルトで探索する標準ライブラリ探索パスには影響しません。

add_runtime_library_dir(dir)

実行時に共有ライブラリを探索するディレクトリのリストに dir を追加します。

set_runtime_library_dirs(dirs)

実行時に共有ライブラリを探索するディレクトリのリストを dir に設定します。これはランタイムリンカがデフォルトで利用する標準探索パスには影響しません。

define_macro(name[, value=None])

このコンパイラオブジェクトで実行される全てのコンパイルで利用されるプリプロセッサのマクロを定義します。省略可能なパラメータ value は文字列であるべきです。省略された場合は、マクロは特定の値をとらずに定義され、具体的な結果は利用されるコンパイラに依存します。 (XXX 本当に? これについてANSIで言及されている?)

undefine_macro(name)

このコンパイラオブジェクトで実行される全てのコンパイルで利用されるプリプロセッサのマクロ定義を消します。同じマクロを define_macro() で定義し、 undefine_macro() で定義を削除した場合、後で呼び出されたものが優先される(複数の再定義と削除を含みます)。もしコンパイルごと(すなわち compile() の呼び出しごと)にマクロが再定義/削除される場合も後で呼び出されたものが優先されます。

add_link_object(object)

このコンパイラオブジェクトによる全てのリンクで利用されるオブジェクトファイル(または類似のライブラリファイルや “リソースコンパイラ”の出力)のリストに object を追加します。

set_link_objects(objects)

このコンパイラオブジェクトによる全てのリンクで利用されるオブジェクトファイル(または類似のもの)のリストを objects に設定します。これはリンカがデフォルト利用する標準オブジェクトファイル(システムライブラリなど)には影響しません。

以下のメソッドはコンパイラオプションの自動検出を実装しており、 GNU autoconf に似たいくつかの機能を提供します。

detect_language(sources)

与えられたファイルまたはファイルのリストの言語を検出します。インスタンス属性 language_map (辞書)と、 language_order (リスト)を仕事に使います。

find_library_file(dirs, lib[, debug=0])

指定されたディレクトリのリストから、スタティックまたは共有ライブラリファイル lib を探し、そのファイルのフルパスを返します。もし debug が真なら、(現在のプラットフォームで意味があれば)デバッグ版を探します。指定されたどのディレクトリでも lib が見つからなければ None を返します。

has_function(funcname[, includes=None, include_dirs=None, libraries=None, library_dirs=None])

funcname が現在のプラットフォームでサポートされているかどうかをブール値で返します。省略可能引数は追加のインクルードファイルやパス、ライブラリやパスを与えることでコンパイル環境を指定します。

library_dir_option(dir)

dir をライブラリ探索ディレクトリに追加するコンパイラオプションを返します。

library_option(lib)

共有ライブラリまたは実行ファイルにリンクされるライブラリ一覧に lib を追加するコンパイラオプションを返します。

runtime_library_dir_option(dir)

ランタイムライブラリを検索するディレクトリのリストに dir を追加するコンパイラオプションを返します。

set_executables(**args)

コンパイルのいろいろなステージで実行される実行ファイル(とその引数)を定義します。コンパイラクラス(の ‘executables’ 属性)によって実行ファイルのセットは変わる可能性がありますが、ほとんどは以下のものを持っています:

attribute | description
compiler | C/C++ コンパイラ
linker_so | シェアードオブジェクト、ライブラリを作るために使うリンカ
linker_exe | バイナリ実行可能ファイルを作るために使うリンカ
archiver | 静的ライブラリを作るアーカイバ

コマンドラインをもつプラットフォーム(Unix, DOS/Windows)では、それぞれの文字列は実行ファイル名と(省略可能な)引数リストに分割されます。(文字列の分割は Unix のシェルが行うものに似ています: 単語はスペースで区切られますが、クォートとバックスラッシュでオーバーライドできます。 distutils.util.split_quoted() をごらんください。)

以下のメソッドはビルドプロセスのステージを呼び出します。

compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None])

1つ以上のソースファイルをコンパイルします。オブジェクトファイルを生成 (たとえば .c ファイルを .o ファイルに変換)します。

sources はファイル名のリストである必要があります。おそらく C/C++ ファイルですが、実際にはコンパイラとコンパイラクラスで扱えるもの(例: MSVCCompiler はリソースファイルを sources にとることができます)なら何でも指定できます。 sources のソースファイルひとつずつに対応するオブジェクトファイル名のリストを返します。実装に依存しますが、全てのソースファイルがコンパイルされる必要はありません。しかし全ての対応するオブジェクトファイル名が返ります。

もし output_dir が指定されていれば、オブジェクトファイルはその下に、オリジナルのパスを維持した状態で置かれます。つまり、 foo/bar.c は通常コンパイルされて foo/bar.o になります (Unix実装の場合)が、もし output_dir が build であれば、 build/foo/bar.o になります。

macros は(もし指定されていれば)マクロ定義のリストである必要があります。マクロ定義は (name, value) という形式の2要素のタプル、または (name,) という形式の1要素のタプルのどちらかです。前者はマクロを定義します。もし value が None であれば、マクロは特定の値をもたないで定義されます。1要素のタプルはマクロ定義を削除します。後で実行された定義/再定義/削除が優先されます。

include_dirs は(もし指定されていれば)文字列のリストである必要があります。このコンパイルだけで有効な、デフォルトのインクルードファイルの検索ディレクトリに追加するディレクトリ群を指定します。

debug はブーリアン値です。もし真なら、コンパイラはデバッグシンボルをオブジェクトファイルに(または別ファイルに)出力します。

extra_postargs と extra_postargs は実装依存です。コマンドラインをもっているプラットフォーム(例 Unix, DOS/Windows)では、おそらく文字列のリスト: コンパイラのコマンドライン引数の前/後に追加するコマンドライン引数です。他のプラットフォームでは、実装クラスのドキュメントを参照してください。どの場合でも、これらの引数は抽象コンパイラフレームワークが期待に沿わない時の脱出口として意図されています。

depends は(もし指定されていれば)ターゲットが依存しているファイル名のリストです。ソースファイルが依存しているファイルのどれかより古ければ、ソースファイルは再コンパイルされます。これは依存関係のトラッキングをサポートしていますが、荒い粒度でしか行われません。

失敗すると CompileError を起こします。

create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None])

静的ライブラリファイルを作るために元ファイル群をリンクします。「元ファイル群」は objects で指定されたオブジェクトファイルのリストを基礎にしています。追加のオブジェクトファイルを add_link_object() および/または set_link_objects() で指定し、追加のライブラリを add_library() および/または set_libraries() で指定します。そして libraries で指定されたライブラリです。

output_libname はライブラリ名で、ファイル名ではありません; ファイル名はライブラリ名から作られます。 output_dir はライブラリファイルが起かれるディレクトリです。 debug はブール値です。真なら、デバッグ情報がライブラリに含まれます(ほとんどのプラットフォームではコンパイルステップで意味をもちます: debug フラグは一貫性のためにここにもあります。)。

target_lang はオブジェクトがコンパイルされる対象になる言語です。これはその言語特有のリンク時の処理を可能にします。

失敗すると LibError を起こします。

link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

実行ファイルまたは共有ライブラリファイルを作るために元ファイル群をリンクします。

「元ファイル群」は objects で指定されたオブジェクトファイルのリストを基礎にしています。 output_filename はファイル名です。もし output_dir が指定されていれば、それに対する相対パスとして output_filename は扱われます(必要ならば output_filename はディレクトリ名を含むことができます。)。

libraries はリンクするライブラリのリストです。これはファイル名ではなくライブラリ名で指定します。プラットフォーム依存の方式でファイル名に変換されます(例: foo はUnix では libfoo.a に、DOS/Windowsでは foo.lib になります。 )。ただしこれらはディレクトリ名を含むことができ、その場合はリンカは通常の場所全体を探すのではなく特定のディレクトリを参照します。

library_dirs はもし指定されるならば、修飾されていない(ディレクトリ名を含んでいない)ライブラリ名で指定されたライブラリを探索するディレクトリのリストです。これはシステムのデフォルトより優先され、 add_library_dir() と/または set_library_dirs() に渡されます。 runtime_library_dirs は共有ライブラリに埋め込まれるディレクトリのリストで、実行時にそれが依存する共有ライブラリのパスを指定します(これはUnixでだけ意味があるかもしれません。)。

export_symbols は共有ライブラリがエクスポートするシンボルのリストです。 (これはWindowsだけで意味があるようです。)

debug は compile() や create_static_lib() と同じですが、少しだけ違いがあり、(create_static_lib() では debug フラグは形式をあわせるために存在していたのに対して)ほとんどのプラットフォームで意識されます。

extra_preargs と extra_postargs は compile() と同じですが、コンパイラではなくリンカへの引数として扱われます。

target_lang は指定されたオブジェクトがコンパイルされた対象言語です。リンク時に言語特有の処理を行えるようにします。

失敗すると LinkError が起きます。

link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None])

実行ファイルをリンクします。 output_progname は実行ファイルの名前です。 objects はリンクされるオブジェクトのファイル名のリストです。他の引数は link() メソッドと同じです。

link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

共有ライブラリをリンクします。 output_libname は出力先のライブラリ名です。 objects はリンクされるオブジェクトのファイル名のリストです。他の引数は link() メソッドと同じです。

link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None])

共有オブジェクトをリンクします。 output_filename は出力先の共有オブジェクト名です。 objects はリンクされるオブジェクトのファイル名のリストです。他の引数は link() メソッドと同じです。

preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None])

source で指定されたひとつの C/C++ソースファイルをプリプロセスします。出力先のファイルは output_file か、もし output_file が指定されていなければ stdout になります。 macro は compile() と同様にマクロ定義のリストで、 define_macro() や undefine_macro() によって引数になります。 include_dirs はデフォルトのリストに追加されるディレクトリ名のリストで、 add_include_dir() と同じ方法で扱われます。

失敗すると PreprocessError が起きます。

以下のユーティリティメソッドは具体的なサブクラスで使うために、 CCompiler クラスで定義されています。

executable_filename(basename[, strip_dir=0, output_dir=''])

basename で指定された実行ファイルのファイル名を返します。 Windows以外の典型的なプラットフォームではbasenameそのままが、Windowsでは .exe が追加されたものが返ります。

library_filename(libname[, lib_type='static', strip_dir=0, output_dir=''])

現在のプラットフォームでのライブラリファイル名を返します。 Unixで lib_type が 'static' の場合、 liblibname.a の形式を返し、 lib_type が 'dynamic' の場合は liblibname.so の形式を返します。

object_filenames(source_filenames[, strip_dir=0, output_dir=''])

指定されたソースファイルに対応するオブジェクトファイル名を返します。 source_filenames はファイル名のリストです。

shared_object_filename(basename[, strip_dir=0, output_dir=''])

basename に対応する共有オブジェクトファイルのファイル名を返します。

execute(func, args[, msg=None, level=1])

distutils.util.execute() を呼びだします。このメソッドはログを取り、 dry_run フラグを考慮にいれて、 Python関数 func に引数 args を与えて呼びだします。

spawn(cmd)

distutils.util.spawn() を呼び出します。これは指定したコマンドを実行する外部プロセスを呼び出します。

mkpath(name[, mode=511])

distutils.dir_util.mkpath() を呼び出します。これは親ディレクトリ込みでディレクトリを作成します。

move_file(src, dst)

distutils.file_util.move_file() を呼び出します。 src を dst にリネームします。

announce(msg[, level=1])

distutils.log.debug() 関数を使ってメッセージを書き出します。

warn(msg)

警告メッセージ msg を標準エラー出力に書き出します。

debug_print(msg)

もしこの CCompiler インスタンスで debug フラグが指定されていれば msg を標準出力に出力し、そうでなければ何も出力しません。

distutils.unixccompiler — Unix C コンパイラ

このモジュールは UnixCCompiler クラスを提供します。 CCompiler クラスのサブクラスで、典型的なUnixスタイルのコマンドラインCコンパイラを扱います:

マクロは -Dname[=value] で定義されます。

マクロは -Uname で削除されます。

インクルードファイルの探索ディレクトリは -Idir で指定されます。

ライブラリは -llib で指定されます。

ライブラリの探索ディレクトリは -Ldir で指定されます。

コンパイルは cc (またはそれに似た) 実行ファイルに、 -c オプションをつけて実行します: .c を .o にコンパイルします。

静的ライブラリは ar コマンドで処理されます (ranlib を使うかもしれません)

共有ライブラリのリンクは cc -shared で処理されます。

distutils.msvccompiler — Microsoft コンパイラ

このモジュールは MSVCCompiler クラスを提供します。抽象クラス CCompiler の具象クラスでMicrosoft Visual Studio向けのものです。一般的に、拡張モジュールはPythonをコンパイルしたのと同じコンパイラでコンパイルする必要があります。Python 2.3 やそれ以前では、コンパイラはVisual Studio 6でした。 Python 2.4 と Python 2.5 では、コンパイラは Visual Studio .NET 2003 です。 AMD64 と Itanium バイナリは Platform SDK を利用して作成されました。

MSVCCompiler は大体正しいコンパイラ、リンカその他を選びます。この選択を上書きするためには、環境変数 DISTUTILS_USE_SDK と MSSdk の両方を設定する必要があります。 MSSdk は現在の環境をセットアップした SetEnv.Cmd スクリプト、もしくは環境変数がSDKをインストールした時に登録されたものであることを示します。 DISTUTILS_USE_SDK はdistutilsのユーザーが明示的に MSVCCompiler が選んだコンパイラを上書きすることを示します。

distutils.bcppcompiler — Borland コンパイラ

このモジュールは BorlandCCompiler クラスを提供します。抽象クラス CCompiler の具象クラスでBorland C++ コンパイラ向けです。

distutils.cygwincompiler — Cygwin コンパイラ

このモジュールは CygwinCCompiler クラスを提供します。 UnixCCompiler のサブクラスで Cygwinに移植されたWindows用の GNU C コンパイラ向けです。さらに Mingw32CCompiler クラスを含んでおり、これは mingw32 向けに移植された GCC (cygwinの no-cygwin モードと同じ)向けです。

distutils.emxccompiler — OS/2 EMX コンパイラ

このモジュールは EMXCCompiler クラスを提供します。 UnixCCompiler のサブクラスで GNU C コンパイラの OS/2 向け EMX ポートを扱います。

distutils.archive_util — アーカイブユーティリティ

このモジュールはアーカイブファイル(tarやzip)を作成する関数を提供します。

distutils.archive_util.make_archive(base_name, format[, root_dir=None, base_dir=None, verbose=0, dry_run=0])

アーカイブファイル(例: zip や tar)を作成します。 base_name は作成するファイル名からフォーマットの拡張子を除いたものです。 format はアーカイブのフォーマットで zip, tar, ztar, gztar のいずれかです。 root_dir はアーカイブのルートディレクトリになるディレクトリです: つまりアーカイブを作成する前に root_dir に chdir します。 base_dir はアーカイブの起点となるディレクトリです: つまり base_dir はアーカイブ中の全ファイルおよびディレクトリの前につくディレクトリ名です。 root_dir と base_dir はともにカレントディレクトリがデフォルト値です。アーカイブファイル名を返します。

distutils.archive_util.make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0])

base_dir 以下の全ファイルから、tarファイルを作成(オプションで圧縮)します。 compress は 'gzip', 'compress', 'bzip2',または None である必要があります。 tar と compress で指定された圧縮ユーティリティにはパスが通っている必要があるので、これはおそらくUnix だけで有効です。出力tarファイルは base_dir.tar という名前になり、圧縮によって拡張子がつきます(.gz, .bz2 または .Z)。出力ファイル名が返ります。

distutils.archive_util.make_zipfile(base_name, base_dir[, verbose=0, dry_run=0])

base_dir 以下の全ファイルから、zipファイルを作成します。出力されるzipファイルは base_name + .zip という名前になります。 zipfile Pythonモジュール(利用可能なら)またはInfoZIP zip ユーティリティ(インストールされていてパスが通っているなら)を使います。もしどちらも利用できなければ、 DistutilsExecError が起きます。出力zipファイル名が返ります。

distutils.dep_util — 依存関係のチェック

このモジュールはシンプルなタイムスタンプを元にしたファイルやファイル群の依存関係を処理する関数を提供します。さらに、それらの依存関係解析を元にした関数を提供します。

distutils.dep_util.newer(source, target)

source が存在して、 target より最近変更されている、または source が存在して、 target が存在していない場合は真を返します。両方が存在していて、 target のほうが source より新しいか同じ場合には偽を返します。 source が存在しない場合には DistutilsFileError を起こします。

distutils.dep_util.newer_pairwise(sources, targets)

ふたつのファイル名リストを並列に探索して、それぞれのソースが対応するターゲットより新しいかをテストします。 newer() の意味でターゲットよりソースが新しいペアのリスト(sources,*targets*)を返します。

distutils.dep_util.newer_group(sources, target[, missing='error'])

target が source にリストアップされたどれかのファイルより古ければ真を返します。言い換えれば、 target が存在して sources の全てより新しいなら偽を返し、そうでなければ真を返します。 missing はソースファイルが存在しなかった時の振る舞いを決定します。デフォルト('error')は os.stat() で OSError 例外を起こします。もし 'ignore' なら、単に存在しないソースファイルを無視します。もし 'newer' なら、存在しないソースファイルについては target が古いとみなします(これは”dry-tun”モードで便利です: 入力がないのでコマンドは実行できませんが実際に実行しようとしていないので問題になりません)。

distutils.dir_util — ディレクトリツリーの操作

このモジュールはディレクトリとディレクトリツリーを操作する関数を提供します。

distutils.dir_util.mkpath(name[, mode=0777, verbose=0, dry_run=0])

ディレクトリと、必要な親ディレクトリを作成します。もしディレクトリが既に存在している(name が空文字列の場合、カレントディレクトリを示すのでもちろん存在しています)場合、何もしません。ディレクトリを作成できなかった場合(例: ディレクトリと同じ名前のファイルが既に存在していた)、 DistutilsFileError を起こします。もし verbose が真なら、それぞれのmkdirについて1行、標準出力に出力します。実際に作成されたディレクトリのリストを返します。

distutils.dir_util.create_tree(base_dir, files[, mode=0777, verbose=0, dry_run=0])

files を置くために必要な空ディレクトリを base_dir 以下に作成します。 base_dir ディレクトリは存在している必要はありません。 files はファイル名のリストで base_dir からの相対パスとして扱われます。 base_dir + files のディレクトリ部分が(既に存在していなければ)作成されます。 mode, verbose と dry_run フラグは mkpath() と同じです。

distutils.dir_util.copy_tree(src, dst[, preserve_mode=1, preserve_times=1, preserve_symlinks=0, update=0, verbose=0, dry_run=0])

src ディレクトリツリー全体を dst にコピーします。 src と dst はどちらもディレクトリ名である必要があります。もし src がディレクトリでなければ、 DistutilsFileError を起こします。もし dst が存在しなければ、 mkpath() で作成されます。実行結果は、 src 以下の全てのファイルが dst にコピーされ、 src 以下の全てのディレクトリが dst に再帰的にコピーされます。コピーされた(またはされるはず)のファイルのリストを返します。返り値は update または dry_run に影響されません: src 以下の全ファイルを単に dst 以下に改名したリストが返されます。

preserve_mode と preserve_times は distutils.file_util の copy_file() と同じです: 通常のファイルには適用されますが、ディレクトリには適用されません。 もし preserve_symlinks が真なら、シンボリックリンクは(サポートされているシステムでは)シンボリックリンクとしてコピーされます。そうでなければ(デフォルト)シンボリックリンクは参照されている実体ファイルがコピーされます。 update と verbose は copy_file() と同じです。

distutils.dir_util.remove_tree(directory[, verbose=0, dry_run=0])

再帰的に directory とその下の全ファイルを削除します。エラーは無視されます(verbose が真の時は sys.stdout に出力されます)

distutils.file_util — 1ファイルの操作

このモジュールはそれぞれのファイルを操作するユーティリティ関数を提供します。

distutils.file_util.copy_file(src, dst[, preserve_mode=1, preserve_times=1, update=0, link=None, verbose=0, dry_run=0])

ファイル src を dst にコピーします。もし dst がディレクトリなら、 src はそこへ同じ名前でコピーされます; そうでなければ、ファイル名として扱われます。 (もしファイルが存在するなら、上書きされます。) mosil preserve_mode が真(デフォルト)なら、ファイルのモード (タイプやパーミッション、その他プラットフォームがサポートするもの)もコピーされます。もし preserve_times が真(デフォルト)なら、最終更新、最終アクセス時刻もコピーされます。もし update が真なら、 src は dst が存在しない場合か、 dst が src より古い時にだけコピーします。

link は値を 'hard' または 'sym' に設定することでコピーのかわりにハードリンク(os.link() を使います)またはシンボリックリンク(os.symlink() を使います)を許可します。 None (デフォルト)の時には、ファイルはコピーされます。 link をサポートしていないシステムで有効にしないでください。 copy_file() はハードリンク、シンボリックリンクが可能かチェックしていません。ファイルの内容をコピーするために _copy_file_contents() を利用しています。

(dest_name, copied) のタプルを返します: dest_name は出力ファイルの実際の名前、 copied はファイルがコピーされた(dry_run が真の時にはコピーされることになった)場合には真です。

distutils.file_util.move_file(src, dst[, verbose, dry_run])

ファイル src を dst に移動します。もし dst がディレクトリなら、ファイルはそのディレクトリに同じ名前で移動されます。そうでなければ、 src は dst に単にリネームされます。新しいファイルの名前を返します。

警告

Unix ではデバイスをまたがる移動は copy_file() を利用して扱っています。

(todo:他のシステムではどうなっている?)

distutils.file_util.write_file(filename, contents)

filename を作成し、 contents (行末文字がない文字列のシーケンス)を書き込みます。

distutils.util — その他のユーティリティ関数

このモジュールは他のユーティリティモジュールにあわないものを提供しています。

distutils.util.get_platform()

現在のプラットフォームを示す文字列を返します。これはプラットフォーム依存のビルドディレクトリやプラットフォーム依存の配布物を区別するために使われます。典型的には、(‘os.uname()’ のように) OSの名前とバージョン、アーキテクチャを含みますが、厳密にはOSに依存します。たとえば IRIXではアーキテクチャはそれほど重要ではありません(IRIXはSGIのハードウェアだけで動作する)が、 Linuxではカーネルのバージョンはそれほど重要ではありません。

返り値の例:

linux-i586

linux-alpha

solaris-2.6-sun4u

irix-5.3

irix64-6.2

POSIX でないプラットフォームでは、今のところ単に sys.platform が返されます。

Mac OS X システムでは、 OS バージョンは、現在のOSバージョンではなく、実行するバイナリの最小バージョンを表しています。 (これは、Python をビルドするときの MACOSX_DEPLOYMENT_TARGET の値です。)

Mac OS X のユニバーサルバイナリビルドでは、アーキテクチャの値は現在のプロセッサではなく、ユニバーサルバイナリの状態を表しています。 32bit ユニバーサルバイナリではアーキテクチャは fat で、 64bit ユニバーサルバイナリではアーキテクチャは fat64 で、 4-way ユニバーサルバイナリではアーキテクチャは universal になります。 Python 2.7 と Python 3.2 から 3-way ユニバーサルバイナリ (ppc, i386, x86_64) には fat3 が i386 と x86_64 ユニバーサルバイナリには intel が使われるようになりました。

Mac OS X で返される値の例:

macosx-10.3-ppc

macosx-10.3-fat

macosx-10.5-universal

macosx-10.6-intel

distutils.util.convert_path(pathname)

‘pathname’ をファイルシステムで利用できる名前にして返します。すなわち、’/’で分割し、現在のディレクトリセパレータで接続しなおします。セットアップスクリプト中のファイル名はUnixスタイルで提供され、実際に利用する前に変換する必要があるため、この関数が必要になります。もし pathname の最初または最後がスラッシュの場合、Unix的でないシステムでは ValueError が起きます。

distutils.util.change_root(new_root, pathname)

pathname の前に new_root を追加したものを返します。もし pathname が相対パスなら、 os.path.join(new_root,pathname) と等価です。そうでなければ、 pathname を相対パスに変換したあと接続します。これはDOS/Windows ではトリッキーな作業になります。

distutils.util.check_environ()

‘os.environ’に、ユーザがconfigファイル、コマンドラインオプションなどで利用できることを保証している環境変数があることを確認します。現在は以下のものが含まれています:

HOME - ユーザのホームディレクトリ (Unix のみ)

PLAT - ハードウェアとOSを含む現在のプラットフォームの説明。 (get_platform() を参照)

distutils.util.subst_vars(s, local_vars)

shell/Perlスタイルの変数置換を s について行います。全ての $ に名前が続いたものは変数とみなされ、辞書 local_vars でみつかった値に置換されます。 local_vars で見つからなかった場合には os.environ で置換されます。 os.environ は最初にある値を含んでいることをチェックされます: check_environ() を参照。 local_vars or os.environ のどちらにも値が見つからなかった場合、 ValueError を起こします。

これは完全な文字列挿入関数ではないことに注意してください。 $variable の名前には大小英字、数字、アンダーバーだけを含むことができます。 { } や ( ) を使った引用形式は利用できません。

distutils.util.grok_environment_error(exc[, prefix='error: '])

例外オブジェクト EnvironmentError (IOError または OSError) から、エラーメッセージを生成します。 Python 1.5.1 またはそれ以降の形式を扱い、ファイル名を含んでいない例外オブジェクトも扱います。このような状況はエラーが2つのファイルに関係する操作、たとえば rename() や link() で発生します。 prefix をプレフィクスに持つエラーメッセージを返します。

distutils.util.split_quoted(s)

文字列をUnixのシェルのようなルール(引用符やバックスラッシュの扱い)で分割します。つまり、バックスラッシュでエスケープされるか、引用符で囲まれていなければ各語はスペースで区切られます。一重引用符と二重引用符は同じ意味です。引用符もバックスラッシュでエスケープできます。 2文字でのエスケープシーケンスに使われているバックスラッシュは削除され、エスケープされていた文字だけが残ります。引用符は文字列から削除されます。語のリストが返ります。

distutils.util.execute(func, args[, msg=None, verbose=0, dry_run=0])

外部に影響するいくつかのアクション(たとえば、ファイルシステムへの書き込み)を実行します。そのようなアクションは dry_run フラグで無効にする必要があるので特別です。この関数はその繁雑な処理を行います。関数と引数のタプル、(実行する「アクション」をはっきりさせるための)表示に使われる任意のメッセージを渡してください。

distutils.util.strtobool(val)

真偽値をあらわす文字列を真(1)または偽(0)に変換します。

真の値は y, yes, t, true, on そして 1 です。偽の値は n, no, f, false, off そして 0 です。 val が上のどれでもない時は ValueError を起こします。

distutils.util.byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None])

Pythonソースファイル群をバイトコンパイルして .pyc または .pyo ファイルを同じディレクトリに作成します。 py_files はコンパイルされるファイルのリストです。 .py で終わっていないファイルはスキップされます。 optimize は以下のどれかです:

0 - 最適化しない (.pyc ファイルを作成します)

1 - 通常の最適化 (python -O のように)

2 - さらに最適化 (python -OO のように)

もし force が真なら、全てのファイルがタイムスタンプに関係なく再コンパイルされます。

バイトコード(bytecode)ファイルにエンコードされるソースファイル名は、デフォルトでは py_files が使われます。これを prefix と base_dir で変更することができます。 prefix はそれぞれのソースファイル名から削除される文字列で、 base_dir は(prefix を削除したあと)先頭に追加されるディレクトリ名です。任意に prefix と base_dir のどちらか、両方を与える(与えない)ことができます。

もし dry_run が真なら、ファイルシステムに影響することは何もされません。

バイトコンパイルは現在のインタプリタプロセスによって標準の py_compile モジュールを使って直接行われるか、テンポラリスクリプトを書いて間接的に行われます。通常は byte_compile() に直接かそうでないかをまかせます (詳細についてはソースをごらんください)。 direct フラグは関節モードで作成されたスクリプトで使用されます。何をやっているか理解していない時は None のままにしておいてください。

distutils.util.rfc822_escape(header)

RFC 822 [http://tools.ietf.org/html/rfc822.html] ヘッダに含められるよう加工した header を返します。改行のあとには8つのスペースが追加されます。この関数は文字列に他の変更はしません。

distutils.dist — Distribution クラス

このモジュールは Distribution クラスを提供します。これは構築/インストール/配布される配布物をあらわします。

distutils.extension — Extension クラス

このモジュールは Extension クラスを提供します。 C/C++拡張モジュールをセットアップスクリプトで表すために使われます。

distutils.debug — Distutils デバッグモード

このモジュールはDEBUGフラグを提供します。

distutils.errors — Distutils 例外

distutilsのモジュールで使用される例外を提供します。 distutilsのモジュールは標準的な例外を起こします。特に、 SystemExit はエンドユーザによる失敗(コマンドライン引数の間違いなど)で起きます。

このモジュールは from ... import * で安全に使用することができます。このモジュールは Distutils ではじまり、 Error で終わるシンボルしかexportしません。

distutils.fancy_getopt — 標準 getopt モジュールのラッパ

このモジュールは以下の機能を標準の getopt モジュールに追加するラッパを提供します:

短いオプションと長いオプションを関連づけます

オプションはヘルプ文字列を持ちます。可能性としては fancy_getopt() に完全な利用方法サマリを作らせることができます。

オプションは渡されたオブジェクトの属性を設定します。

真偽値をとるオプションは “負のエイリアス” を持ちます。— たとえば --quiet の “負のエイリアス” が --verbose の場合、コマンドラインで --quiet を指定すると verbose は偽になります。

distutils.fancy_getopt.fancy_getopt(options, negative_opt, object, args)

ラッパ関数。 options は FancyGetopt のコンストラクタで説明されている (long_option, short_option, help_string) の3要素タプルのリストです。 negative_opt はオプション名からオプション名のマッピングになっている辞書で、キー、値のどちらも options リストに含まれている必要があります。 object は値を保存するオブジェクト(FancyGetopt クラスの getopt() メソッドを参照してください)です。 args は引数のリストです。 args として None を渡すと、 sys.argv[1:] が使われます。

distutils.fancy_getopt.wrap_text(text, width)

text を width 以下の幅で折り返します。

class distutils.fancy_getopt.FancyGetopt([option_table=None])

option_table は 3つ組タプルのリストです。 (long_option, short_option, help_string)

もしオプションが引数を持つなら、 long_option に '=' を追加する必要があります。 short_option は一文字のみで、 ':' はどの場合にも不要です。 long_option に対応する short_option がない場合、 short_option は None にしてください。全てのオプションタプルは長い形式のオプションを持つ必要があります。

FancyGetopt クラスは以下のメソッドを提供します:

FancyGetopt.getopt([args=None, object=None])

argsのコマンドラインオプションを解析します。 object に属性として保存します。

もし args が None もしくは与えられない場合には、 sys.argv[1:] を使います。もし object が None もしくは与えられない場合には、新しく OptionDummy インスタンスを作成し、オプションの値を保存したのち (args, object) のタプルを返します。もし object が提供されていれば、その場で変更され、 getopt() は args のみを返します。どちらのケースでも、返された args は渡された args リスト(これは変更されません)の変更されたコピーです。

FancyGetopt.get_option_order()

直前に実行された getopt() が処理した (option, value) タプルのリストを返します。 getopt() がまだ呼ばれていない場合には RuntimeError を起こします。

FancyGetopt.generate_help([header=None])

この FancyGetopt オブジェクトのオプションテーブルからヘルプテキスト(出力の一行に対応する文字列のリスト)を生成します。

もし与えられていれば、 header をヘルプの先頭に出力します。

distutils.filelist — FileList クラス

このモジュールはファイルシステムを見て、ファイルのリストを構築するために使われる FileList クラスを提供します。

distutils.log — シンプルな PEP 282 スタイルのロギング

distutils.spawn — サブプロセスの生成

このモジュールは spawn() 関数を提供します。これは様々なプラットフォーム依存の他プログラムをサブプロセスとして実行する関数に対するフロントエンドになっています。与えられた実行ファイルの名前からパスを探索する find_executable() 関数も提供しています。

distutils.sysconfig — システム設定情報

distutils.sysconfig モジュールでは、 Python の低水準の設定情報へのアクセス手段を提供しています。アクセスできる設定情報変数は、プラットフォームと設定自体に大きく左右されます。また、特定の変数は、使っているバージョンの Python のビルドプロセスに左右されます; こうした変数は、 Unix システムでは、 Makefile や Python と一緒にインストールされる設定ヘッダから探し出されます。設定ファイルのヘッダは、2.2 以降のバージョンでは pyconfig.h 、それ以前のバージョンでは config.h です。

他にも、 distutils パッケージの別の部分を操作する上で便利な関数がいくつか提供されています。

distutils.sysconfig.PREFIX

os.path.normpath(sys.prefix) の結果です。

distutils.sysconfig.EXEC_PREFIX

os.path.normpath(sys.exec_prefix) の結果です。

distutils.sysconfig.get_config_var(name)

ある一つの設定変数に対する値を返します。 get_config_vars().get(name) と同じです。

distutils.sysconfig.get_config_vars(...)

定義されている変数のセットを返します。引数を指定しなければ、設定変数名を変数の値に対応付けるマップ型を返します。引数を指定する場合、引数の各値は文字列でなければならず、戻り値は引数に関連付けられた各設定変数の値からなるシーケンスになります。引数に指定した名前の設定変数に値がない場合、その変数に対する戻り値には None が入ります。

distutils.sysconfig.get_config_h_filename()

設定ヘッダのフルパス名を返します。 Unixの場合、このヘッダファイルは configure スクリプトによって生成されるヘッダファイル名です; 他のプラットフォームでは、ヘッダは Python ソース配布物中で直接与えられています。ファイルはプラットフォーム固有のテキストファイルです。

distutils.sysconfig.get_makefile_filename()

Python をビルドする際に用いる Makefile のフルパスを返します。 Unixの場合、このファイルは configure スクリプトによって生成されます; 他のプラットフォームでは、この関数の返す値の意味は様々です。有意なファイル名を返す場合、ファイルはプラットフォーム固有のテキストファイル形式です。この関数は POSIX プラットフォームでのみ有用です。

distutils.sysconfig.get_python_inc([plat_specific[, prefix]])

C インクルードファイルディレクトリについて、一般的なディレクトリ名か、プラットフォーム依存のディレクトリ名のいずれかを返します。 plat_specific が真であれば、プラットフォーム依存のインクルードディレクトリ名を返します; plat_specific が偽か、省略された場合には、プラットフォームに依存しないディレクトリを返します。 prefix が指定されていれば、 PREFIX の代わりに用いられます。また、 plat_specific が真の場合、 EXEC_PREFIX の代わりに用いられます。

distutils.sysconfig.get_python_lib([plat_specific[, standard_lib[, prefix]]])

ライブラリディレクトリについて、一般的なディレクトリ名か、プラットフォーム依存のディレクトリ名のいずれかを返します。 plat_specific が真であれば、プラットフォーム依存のライブラリディレクトリ名を返します; plat_specific が偽か、省略された場合には、プラットフォームに依存しないディレクトリを返します。 prefix が指定されていれば、 PREFIX の代わりに用いられます。また、 plat_specific が真の場合、 EXEC_PREFIX の代わりに用いられます。 standard_lib が真であれば、サードパーティ製の拡張モジュールをインストールするディレクトリの代わりに、標準ライブラリのディレクトリを返します。

以下の関数は、 distutils パッケージ内の使用だけを前提にしています。

distutils.sysconfig.customize_compiler(compiler)

distutils.ccompiler.CCompiler インスタンスに対して、プラットフォーム固有のカスタマイズを行います。

この関数は現在のところ、Unix だけで必要ですが、将来の互換性を考慮して一貫して常に呼び出されます。この関数は様々な Unix の変種ごとに異なる情報や、Python の Makefile に書かれた情報をインスタンスに挿入します。この情報には、選択されたコンパイラやコンパイラ/リンカのオプション、そして共有オブジェクトを扱うためにリンカに指定する拡張子が含まれます。

この関数はもっと特殊用途向けで、Python 自体のビルドプロセスでのみ使われるべきです。

distutils.sysconfig.set_python_build()

distutils.sysconfig モジュールに、モジュールが Python のビルドプロセスの一部として使われることを知らせます。これによって、ファイルコピー先を示す相対位置が大幅に変更され、インストール済みの Python ではなく、ビルド作業領域にファイルが置かれるようになります。

distutils.text_file — TextFile クラス

このモジュールは TextFile クラスを提供します。これはテキストファイルへのインタフェースを提供し、コメントの削除、空行の無視、バックスラッシュでの行の連結を任意に行えます。

class distutils.text_file.TextFile([filename=None, file=None, **options])

このクラスはファイルのようなオブジェクトを提供します。これは行指向のテキストファイルを処理する時に共通して必要となる処理を行います: (# がコメント文字なら)コメントの削除、空行のスキップ、 (行末のバックスラッシュでの)改行のエスケープによる行の連結、先頭/末尾の空白文字の削除。これらは全て独立して任意に設定できます。

クラスは warn() メソッドを提供しており、物理行つきの警告メッセージを生成することができます。この物理行は論理行が複数の物理行にまたがっていても大丈夫です。また unreadline() メソッドが一行先読みを実装するために提供されています。

TextFile のインスタンスは filename, file,またはその両方をとって作成されます。両方が None の場合 RuntimeError が起きます。 filename は文字列、 file はファイルオブジェクト(または readline() と close() のメソッドを提供する何か) である必要があります。 TextFile が生成する警告メッセージに含めることができるので、 filename を与えることが推奨されます、もし file が提供されなければ、 TextFile は組み込みの open() を利用して自分で作成します。

オプションは全て真偽値で、 readline() で返される値に影響します。

option name | 説明 | デフォルト値
strip_comments | バックスラッシュでエスケープされていない限り、 '#' から行末までと、 '#' の先にある空白文字の並びを削除します。 | true
lstrip_ws | 行を返す前に先頭の空白文字の並びを削除します。 | false
rstrip_ws | 行を返す前に行末の空白文字(改行文字を含みます!)の並びを削除します。 | true
skip_blanks | コメントと空白を除いた*あとで*内容がない行をスキップします。 (もし lstrip_ws と rstrip_ws がともに偽なら、空白文字だけの行があるかもしれません。これは skip_blanks が真でない限りスキップされません。) | true
join_lines | もしコメントと空白文字を削除したあとで、バックスラッシュが最後の改行文字でない文字なら、次の行を接続して一つの論理行とします: N行の連続した行がバックスラッシュで終わる場合、N+1 行の物理行が1行の論理行として扱われます。 | false
collapse_join | 前の行と接続するとき、行頭の空白文字を削除します。 (join_lines and not lstrip_ws) の時だけ意味をもちます。 | false

rstrip_ws は行末の改行を削除するので、 readline() のセマンティクスが組み込みファイルオブジェクトの readline() メソッドとは変わってしまいます! 特に、 rstrip_ws が真で skip_blanks が偽のとき、 readline() はファイルの終端で None を返し、空文字列を返したときは空行(または全て空白文字の行)です。

open(filename)

新しいファイル filename を開きます。これはコンストラクタ引数の file と filename を上書きします。

close()

現在のファイルを閉じ、(ファイル名や現在の行番号を含め)現在のファイルについての情報を全て消します。

warn(msg[, line=None])

標準エラー出力に現在のファイルの論理行に結びついた警告メッセージを出力します。もし現在の論理行が複数の物理行に対応するなら、警告メッセージは以下のように全体を参照します: "lines 3-5" 。もし line が与えられていれば、現在の行番号を上書きします; 物理行のレンジをあらわすリストまたはタプル、もしくはある物理行をあらわす整数のどれでも与えられます。

readline()

現在のファイル(または unreadline() で”unread”を直前に行っていればバッファ)から論理行を1行読み込んで返します。もし join_lines オプションが真なら、このメソッドは複数の物理行を読み込んで接続した文字列を返します。現在の行番号を更新します。そのため readline() のあとに warn() を呼ぶと丁度読んだ行についての警告を出します。 rstrip_ws が真で、 strip_blanks が偽のとき空文字列が返るので、ファイルの終端では None を返します。

readlines()

現在のファイルで残っている全ての論理行のリストを読み込んで返します。行番号を、ファイルの最後の行に更新します。

unreadline(line)

line (文字列)を次の readline() 用に、内部バッファにpushします。行の先読みを必要とするパーサを実装する時に便利です。 unreadline() で”unread”された行は readline() で読み込む際に再度処理(空白の除去など)されません。もし unreadlinee() を、 readline() を呼ぶ前に複数回実行すると、最後にunreadした行から返されます。

distutils.version — バージョン番号クラス

distutils.cmd — Distutils コマンドの抽象クラス

このモジュールは抽象ベースクラス Command を提供します。

class distutils.cmd.Command(dist)

コマンドクラスを定義するための抽象ベースクラス — distutilsの「働きバチ」 — です。コマンドクラスは options とよばれるローカル変数を持ったサブルーチンと考えることができます。オプションは initialize_options() で宣言され、 finalize_options() で定義さ(最終的な値を与えら)れます。どちらも全てのコマンドクラスで実装する必要があります。この2つの区別は必要です。なぜならオプションの値は外部(コマンドライン、設定ファイルなど)から来るかもしれず、他のオプションに依存しているオプションは外部の影響を処理した後で計算される必要があるからです。そのため finalize_options() が存在します。サブルーチンの本体は全ての処理をオプションの値にもとづいて行う run() メソッドで、これも全てのコマンドクラスで実装される必要があります。

クラスのコンストラクタは Distribution のインスタンスである単一の引数 dist をとります。

新しいDistutilsコマンドの作成

このセクションではDistutilsの新しいコマンドを作成する手順の概要をしめします。

新しいコマンドは distutils.command パッケージ中のモジュールに作られます。 command_template というディレクトリにサンプルのテンプレートがあります。このファイルを実装しようとしているコマンドと同名の新しいモジュールにコピーしてください。このモジュールはモジュール(とコマンド)と同じ名前のクラスを実装する必要があります。そのため、 peel_banana コマンド(ユーザは setup.py peel_banana と実行できます)を実装する際には、 command_template を distutils/command/peel_banana.py にコピーし、 distutils.cmd.Command のサブクラス peel_banana クラスを実装するように編集してください。

Command のサブクラスは以下のメソッドを実装する必要があります。

Command.initialize_options()

このコマンドがサポートする全てのオプションのデフォルト値を設定します。これらのデフォルトは他のコマンドやセットアップスクリプト、設定ファイル、コマンドラインによって上書きされるかもしれません。そのためオプション間の依存関係を記述するには適切な場所ではありません。一般的に initialize_options() は単に self.foo = None のような定義だけを行います。

Command.finalize_options()

このコマンドがサポートする全てのオプションの最終的な値を設定します。これは可能な限り遅く呼び出されます。つまりコマンドラインや他のコマンドによるオプションの代入のあとに呼び出されます。そのため、オプション間の依存関係を記述するのに適した場所です。もし foo が bar に依存しており、かつまだ foo が initialize_options() で定義された値のままなら、 foo を bar から代入しても安全です。

Command.run()

コマンドの本体です。実行するべきアクションを実装しています。 initialize_options() で初期化され、他のコマンドされ、セットアップスクリプト、コマンドライン、設定ファイルでカスタマイズされ、 finalize_options() で設定されたオプションがアクションを制御します。端末への出力とファイルシステムとのやりとりは全て run() が行います。

Command.sub_commands

sub_commands はコマンドの”ファミリー”を定式化したものです。たとえば install はサブコマンド install_lib install_headers などの親です。コマンドファミリーの親は sub_commands をクラス属性として持ちます。 sub_commands は2要素のタプル (command_name, predicate) のリストで、 command_name は文字列、 predicate は関数か文字列か None です。 predicate はには親コマンドのメソッドで、現在の状況がコマンド実行にふさわしいかどうか判断するものを指定します。 (例えば install_headers はインストールするべき Cヘッダファイルがある時だけ有効です。) もし predicate が None なら、そのコマンドは常に有効になります。

sub_commands は通常クラスの 最後 で定義されます。 これは predicate は bound されていないメソッドになるので、全て先に定義されている必要があるためです。標準的な例は install コマンドです。

distutils.command — Distutils 各コマンド

distutils.command.bdist — バイナリインストーラの構築

distutils.command.bdist_packager — パッケージの抽象ベースクラス

distutils.command.bdist_dumb — “ダム”インストーラを構築

distutils.command.bdist_msi — Microsoft Installer バイナリパッケージをビルドする

class distutils.command.bdist_msi.bdist_msi(Command)

Windows Installer [http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx] (.msi) バイナリパッケージをビルドします。

多くの場合、 bdist_msi インストーラは Win64 のサポートが優れていて、管理者が非インタラクティブインストールできたり、グループポリシーを利用したインストールができるので、 bdist_wininst インストーラよりも良い選択です。

distutils.command.bdist_rpm — Redhat RPMとSRPM形式のバイナリディストリビューションを構築

distutils.command.bdist_wininst — Windowsインストーラの構築

distutils.command.sdist — ソース配布物の構築

distutils.command.build — パッケージ中の全ファイルを構築

distutils.command.build_clib — パッケージ中のCライブラリを構築

distutils.command.build_ext — パッケージ中の拡張を構築

distutils.command.build_py — パッケージ中の.py/.pyc ファイルを構築

distutils.command.build_scripts — パッケージ中のスクリプトを構築

distutils.command.clean — パッケージのビルドエリアを消去

distutils.command.config — パッケージの設定

distutils.command.install — パッケージのインストール

distutils.command.install_data — パッケージ中のデータファイルをインストール

distutils.command.install_headers — パッケージから C/C++ ヘッダファイルをインストール

distutils.command.install_lib — パッケージからライブラリファイルをインストール

distutils.command.install_scripts — パッケージからスクリプトファイルをインストール

distutils.command.register — モジュールをPython Package Indexに登録する

register コマンドはパッケージをPython Package Index に登録します。この詳細は PEP 301 [http://www.python.org/dev/peps/pep-0301] に記述されています。

distutils.command.check — パッケージのメタデータをチェックする

check コマンドはパッケージのメタデータに対していくつかのテストをします。例えば、要求される全てのメタデータが setup() 関数の引数に渡されているかを検証します。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールの配布 »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる Distributing Python Modules の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

Yasushi Masuda <y.masuda at acm.org> (March 12, 2004)

Kazuo Moriwaka (May 8, 2006)

INADA Naoki <inada-n at klab.jp>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールのインストール

Author: | Greg Ward — 日本語訳: Python ドキュメント翻訳プロジェクト
Release: | 2.7
Date: | 2011年 12月 26日

Abstract

このドキュメントでは、 Python モジュール配布ユーティリティ (Python Distribution Utilities, “Distutils”) について、 エンドユーザの視点に立ち、サードパーティ製のモジュールや拡張モジュールの構築やインストールによって標準の Python に機能を追加する方法について述べます。

はじめに

Python の広範な標準ライブラリは、プログラミングにおける多くの要求をカバーしていますが、時には何らかの新たな機能をサードパーティ製モジュールの形で追加する必要に迫られます。自分がプログラムを書くときのサポートとして必要な場合もあるし、自分が使いたいアプリケーションがたまたま Python で書かれていて、そのサポートとして必要な場合もあるでしょう。

以前は、すでにインストール済みの Python に対して、サードパーティ製モジュールを追加するためのサポートはほとんどありませんでした。しかしPython 配布ユーティリティ (Python Distribution Utilities, 略して Distutils) が Python 2.0 から取り入れられ、状況は変わりました。

このドキュメントが主要な対象としているのは、サードパーティモジュールをインストールする必要がある人たち: 単に何らかの Python アプリケーションを稼動させたいだけのエンドユーザやシステム管理者、そしてすでに Python プログラマであって、新たな道具を自分のツールキットに加えたいと思っている人たちです。このドキュメントを読むために、 Python について知っておく必要はありません; インストールしたモジュールを調べるために Python の対話モードにちょっとだけ手を出す必要がありますが、それだけです。自作の Python モジュールを他人が使えるようにするために配布する方法を探しているのなら、 Python モジュールの配布マニュアルを参照してください。

もっとも簡単な場合: ありふれたインストール作業

最も楽なのは、インストールしたいモジュール配布物の特殊なバージョンをインストールしたいプラットフォーム向けに誰かがすでに用意してくれていて、他のアプリケーションと同じようにインストールするだけであるような場合です。例えば Windows ユーザ向けには実行可能形式のインストーラ、 RPM ベースの Linux システム (Red Hat, SuSE, Mandrake その他多数) 向けには RPM パッケージ、 Debian ベースの Linux システム向けには Debian パッケージといった具合に、モジュール開発者はビルド済み配布物を作成しているかもしれません。

このような場合、自分のプラットフォームに合ったインストーラをダウンロードして、実行可能形式なら実行し、RPM なら rpm --install するといった、分かりきった作業をするだけです。 Python を起動したり、 setup スクリプトを実行する必要はなく、何もコンパイルする必要はありません — 説明書きを読む必要すら全くないかもしれません (とはいえ、説明書きを読むのはよいことですが)。

もちろん、いつもこう簡単とは限りません。自分のプラットフォーム向けのお手軽なインストーラがないモジュール配布物に興味を持つこともあるでしょう。そんな場合には、モジュールの作者やメンテナがリリースしているソース配布物から作業をはじめねばなりません。ソース配布物からのインストールは、モジュールが標準的な方法でパッケージ化されている限りさほど大変ではありません。このドキュメントの大部分は、標準的なソース配布物からのビルドとインストールに関するものです。

新しい標準: Distutils

モジュールのソースコード配布物をダウンロードしたら、配布物が標準のやり方、すなわち Distutils のやり方に従ってパッケージされて配布されているかどうかすぐに分かります。Distutils の場合、まず配布物の名前とバージョン番号が、例えば foo-1.0.tar.gz や widget-0.9.7.zip のように、ダウンロードされたアーカイブファイルの名前にはっきりと反映されます。次に、アーカイブは同様の名前のディレクトリ、例えば foo-1.0 や widget-0.9.7 に展開されます。さらに、配布物には setup スクリプト setup.py が入っています。また、 README.txt 場合によっては README という名前のファイルも入っていて、そこには、モジュール配布物の構築とインストールは簡単で、

python setup.py install

とするだけだ、という説明が書かれているはずです。

上記の全てが当てはまるなら、ダウンロードしたものをビルドしてインストールする方法はすでに知っていることになります: 上記のコマンドを実行するだけです。非標準の方法でインストールを行ったり、ビルドプロセスをカスタマイズ行いたいのでない限り、このマニュアルは必要ありません。別の言葉で言えば、上のコマンドこそが、このマニュアルから習得すべき全てということになります。

標準的なビルド・インストール作業

新しい標準: Distutils 節で述べたよいうに、 Distutils を使ったモジュール配布物のビルドとインストールは、通常は単純なコマンド:

python setup.py install

で行います。

Unixでは、このコマンドをシェルプロンプトで行います; Windows では、コマンドプロンプトウィンドウ (“DOS ボックス”) を開いて、そこで行います; Mac OS X の場合、 Terminal ウィンドウを開いてシェルプロンプトを出してください。

プラットフォームによる違い

setup コマンドは常に配布物ルートディレクトリ、すなわちモジュールのソース配布物を展開した際のトップレベルのサブディレクトリ内で実行しなければなりません。例えば、あるモジュールのソース配布物 foo-1.0.tar.gz を Unix システム上にダウンロードしたなら、通常は以下の操作を行います:

gunzip -c foo-1.0.tar.gz | tar xf -    # unpacks into directory foo-1.0
cd foo-1.0
python setup.py install

Windows では、おそらく foo-1.0.zip をダウンロードしているでしょう。アーカイブファイルを C:\Temp にダウンロードしたのなら、(WinZip のような) グラフィカルユーザインタフェースつきのアーカイブ操作ソフトや、 (unzip や pkunzip のような) コマンドラインツールを使ってアーカイブを展開します。次に、コマンドプロンプトウィンドウ (“DOS ボックス”) を開いて、以下を実行します:

cd c:\Temp\foo-1.0
python setup.py install

ビルド作業とインストール作業を分割する

setup.py install を実行すると、一度の実行で全てのモジュールをビルドしてインストールします。段階的に作業をしたい場合 — ビルドプロセスをカスタマイズしたり、作業がうまくいかない場合に特に便利です — には、setup スクリプトに一度に一つづつ作業を行わせるようにできます。この機能は、ビルドとインストールを異なるユーザで行う場合にも便利です — 例えば、モジュール配布物をビルドしておいてシステム管理者に渡して (または、自分でスーパユーザになって) 、インストールしたくなるかもしれません.

最初のステップでは全てをビルドしておき、次のステップで全てをインストールするには、 setup スクリプトを二度起動します:

python setup.py build
python setup.py install

この作業を行ってみれば、 install コマンドを実行するとまず build コマンドを実行し、さらに — この場合には — build ディレクトリの中が全て最新の状態になっているので、 build は何も行わなくてよいと判断していることがわかるでしょう。

インターネットからダウンロードしたモジュールをインストールしたいだけなら、上のように作業を分割する機能は必要ないかもしれませんが、この機能はより進んだ使い方をする際にはとても便利です。自作の Python モジュールや拡張モジュールを配布することになれば、個々の Distutils コマンドを自分で何度も実行することになるでしょう。

ビルドの仕組み

上で示唆したように、 build コマンドは、インストールすべきファイルを ビルドディレクトリ (build directory) に置く働きがあります。デフォルトでは、ビルドディレクトリは配布物ルート下の build になります; システムの処理速度に強いこだわりがあったり、ソースツリーに指一本触れたくないのなら、 --build-base オプションを使ってビルドディレクトリを変更できます。例えば:

python setup.py build --build-base=/tmp/pybuild/foo-1.0

(あるいは、システム全体向け、あるいは個人用の Distutils 設定ファイルにディレクティブを書いて、永続的に設定を変えられます; Distutils 設定ファイル 節を参照してください。) 通常は必要ない作業です。

ビルドツリーのデフォルトのレイアウトは以下のようになっています:

--- build/ --- lib/
または
--- build/ --- lib.<plat>/
               temp.<plat>/

<plat> は、現在の OS/ハードウェアプラットフォームと Python のバージョンを記述する短い文字列に展開されます。第一の lib ディレクトリだけの形式は、 “pure モジュール配布物” — すなわち、pure Python モジュールだけの入ったモジュール配布物 — の場合に使われます。モジュール配布物に何らかの拡張モジュール (C/C++ で書かれたモジュール) が入っている場合、第二の <plat> 付きディレクトリが二つある形式が使われます。この場合、 temp.plat ディレクトリには、コンパイル/リンク過程で生成され、実際にはインストールされない一時ファイルが収められます。どちらの場合にも、 lib (または lib.plat) ディレクトリには、最終的にインストールされることになる全ての Python モジュール (pure Python モジュールおよび拡張モジュール) が入ります。

今後、 Python スクリプト、ドキュメント、バイナリ実行可能形式、その他 Python モジュールやアプリケーションのインストール作業に必要なディレクトリが追加されるかもしれません。

インストールの仕組み

build コマンドを実行した後 (明示的に実行した場合も、 install コマンドが代わりに実行してくれた場合も) は、 install コマンドの仕事は比較的単純なもの: build/lib (または build/lib.plat) の下にあるもの全ての指定したインストールディレクトリへのコピー、になります。

インストールディレクトリを選ばなかった場合 — すなわち、 setup.py install を実行しただけの場合 — には、 install コマンドはサードパーティ製 Python モジュールを置くための標準の場所にインストールを行います。この場所は、プラットフォームや、Python 自体をどのようにビルド/インストールしたかで変わります。 Unix (と、Unix をベースとしたMac OS X) では、インストールしようとするモジュール配布物が pure Python なのか、拡張モジュールを含む (“非 pure”) のかによっても異なります:

プラットフォーム | 標準のインストール場所 | デフォルト値 | 注記
Unix (pure) | prefix/lib/pythonX.Y/site-packages | /usr/local/lib/pythonX.Y/site-packages | (1)
Unix (non-pure) | exec-prefix/lib/pythonX.Y/site-packages | /usr/local/lib/pythonX.Y/site-packages | (1)
Windows | prefix\Lib\site-packages | C:\PythonXY\Lib\site-packages | (2)

注記:

ほとんどの Linux ディストリビューションには、システムの標準インストール物として Python が入っているので、 Linux では普通、 prefix や exec-prefix はどちらも /usr になります。 Linux (または Unixライクなシステム) 上で自分で Python をビルドした場合、デフォルトの prefix および exec-prefix は /usr/local になります。

Windows での Python のデフォルトインストールディレクトリは、 Python 1.6a1、 1.5.2、およびそれ以前のバージョンでは C:\Program Files\Python です。

prefix および exec-prefix は、 Python がインストールされているディレクトリと、実行時にライブラリを探しにいく場所を表します。これらのディレクトリは、Windows では常に同じで、 Unixと Mac OS X でもほぼ常に同じです。自分の Python がどんな prefix や exec-prefix を使っているかは、Python を対話モードで起動して、単純なコマンドをいくつか入力すればわかります。 Windows では、 スタート ‣ (すべての) プログラム ‣ Python X.Y ‣ Python (command line) を選びます。 Mac OS 9 では、 PythonInterpreter を起動します。インタプリタを起動すると、プロンプトに Python コードを入力できます。例えば、作者の使っている Linux システムで、三つの Python 文を以下のように入力すると、出力から作者のシステムの prefix と exec-prefix を得られます:

Python 2.4 (#26, Aug  7 2004, 17:19:02)
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.prefix
'/usr'
>>> sys.exec_prefix
'/usr'

モジュールを標準の場所にインストールしたくない場合や、標準の場所にインストールするためのファイル権限を持っていない場合、別の場所へのインストール 節にある、別の場所へのインストール方法の説明を読んでください。インストール先のディレクトリを大幅にカスタマイズしければ、カスタムのインストール 節のカスタムインストールに関する説明を読んでください。

別の場所へのインストール

しばしば、サードパーティ製 Python モジュールをインストールするための標準の場所以外にモジュールをインストールしなければならなかったり、単にそうしたくなるときがあります。例えばUnix システムでは、標準のサードパーティ製モジュールディレクトリに対する書き込み権限を持っていないかもしれません。または、あるモジュールを、ローカルで使っている Python に標準のモジュールの一部として組み込む前にテストしてみたいと思うかもしれません。既存の配布物をアップグレードする際には特にそうでしょう: 実際にアップグレードする前に、既存のスクリプトの基本となる部分が新たなバージョンでも動作するか確認したいはずです。

Distutils の install コマンドは、別の場所へ配布物をインストールする作業を単純で苦労のない作業にするように設計されています。基本的なアイデアは、インストール先のベースディレクトリを指定しておき、 install コマンドがそのベースディレクトリ下にファイル群をインストールするための一連のディレクトリ (インストールスキーム : installation scheme) を作成するというものです。詳細はプラットフォームによって異なるので、以下の節から自分のプラットフォームに当てはまるものを読んでください。

別の場所へのインストール: home スキーム

“home スキーム” の背後にある考え方は、Python モジュールを個人用のモジュール置き場でビルドし、維持するというものです。このスキームの名前は Unixの「ホーム」ディレクトリの概念からとりました。というのも、 Unixのユーザにとって、自分のホームディレクトリを /usr/ や /usr/local/ のようにレイアウトするのはよくあることだからです。とはいえ、このスキームはどのオペレーティングシステムのユーザでも使えます。新たなモジュールのインストールは単純で、

python setup.py install --home=<dir>

のようにします。このとき、 --home オプションを使ってディレクトリを指定します。面倒臭がりの人は、単にチルダ (~) をタイプするだけでかまいません; install コマンドがチルダをホームディレクトリに展開してくれます。

python setup.py install --home=~

--home オプションは、インストールのベースディレクトリを指定します。ファイルはインストールベース下の以下のディレクトリに保存されます:

Type of file | Installation Directory | Override option
pure module distribution | home/lib/python | --install-purelib
non-pure module distribution | home/lib/python | --install-platlib
scripts | home/bin | --install-scripts
data | home/share | --install-data

バージョン 2.4 で変更: --home は Unixでしかサポートされていませんでした。

別の場所へのインストール: Unix (prefix スキーム)

あるインストール済みの Python を使ってモジュールのビルド/インストールを (例えば setup スクリプトを実行して) 行いたいけれども、別のインストール済みの Python のサードパーティ製モジュール置き場 (あるいは、そう見えるようなディレクトリ構造) に、ビルドされたモジュールをインストールしたい場合には、”prefix スキーム” が便利です。そんな作業はまったくありえそうにない、と思うなら、確かにその通りです — “home スキーム” を先に説明したのもそのためです。とはいえ、prefix スキームが有用なケースは少なくとも二つあります。

まず、多くの Linux ディストリビューションは、 Python を /usr/local ではなく /usr に置いていることを考えてください。この場合は、 Python はローカルの計算機ごとのアドオン (add-on) ではなく、”システム” の一部となっているので、 /usr に置くのは全く正当なことです。しかしながら、 Python モジュールをソースコードからインストールしていると、モジュールを /usr/lib/python2.X ではなく /usr/local/lib/python2.X に置きたいと思うかもしれません。これを行うには

/usr/bin/python setup.py install --prefix=/usr/local

と指定します。

もう一つありえるのは、ネットワークファイルシステムにおいて、遠隔のディレクトリに対する読み出しと書き込みの際に違う名前を使う場合です。例えば、 /usr/local/bin/python でアクセスするような Python インタプリタは、 /usr/local/lib/python2.X からモジュールを探すでしょうが、モジュールは別の場所、例えば /mnt/@server/export/lib/python2.X にインストールしなければならないかもしれません。この場合には、

/usr/local/bin/python setup.py install --prefix=/mnt/@server/export

のようにします。

どちらの場合も、 --prefix オプションでインストールベースディレクトリを決め、 --exec-prefix でプラットフォーム固有のファイル置き場名として使う、プラットフォーム固有インストールベースディレクトリを決めます。 (プラットフォーム固有のファイルとは、現状では単に非 pure モジュール配布物のことを意味しますが、 C ライブラリやバイナリ実行可能形式などに拡張されるかもしれません。) --exec-prefix が指定されていなければ、デフォルトの --prefix になります。ファイルは以下のようにインストールされます:

Type of file | Installation Directory | Override option
pure module distribution | prefix/lib/pythonX.Y/site-packages | --install-purelib
non-pure module distribution | exec-prefix/lib/pythonX.Y/site-packages | --install-platlib
scripts | prefix/bin | --install-scripts
data | prefix/share | --install-data

--prefix や --exec-prefix が実際に他のインストール済み Python の場所を指している必要はありません; 上に挙げたディレクトリがまだ存在しなければ、インストール時に作成されます。

ちなみに、prefix スキームが重要な本当の理由は、単に標準の Unix インストールが prefix スキームを使っているからです。ただし、そのときには、 --prefix や --exec-prefix は Python 自体が sys.prefix や sys.exec_prefix を使って決めます。というわけで、読者は prefix スキームを決して使うことはあるまいと思っているかもしれませんが、 python setup.py install をオプションを何もつけずに実行していれば、常に prefix スキームを使っていることになるのです。

拡張モジュールを別のインストール済み Python にインストールしても、拡張モジュールのビルド方法による影響を受けることはありません: 特に、拡張モジュールをコンパイルする際には、 setup スクリプトを実行する際に使う Python インタプリタと一緒にインストールされている Python ヘッダファイル (Python.h とその仲間たち) を使います。上で述べてきたやり方でインストールされた拡張モジュールを実行するインタプリタと、インタプリタをビルドする際に用いた別のインタプリタとの互換性を保証するのはユーザの責任です。

これを行うには、二つのインタプリタが同じバージョンの Python (ビルドが違っていたり、同じビルドのコピーということもあり得ます) であるかどうかを確かめます。(もちろん、 --prefix や --exec-prefix が別のインストール済み Python の場所すら指していなければどうにもなりません。)

別の場所へのインストール (prefix を使う方法): Windows

Windows はユーザのホームディレクトリという概念がなく、 Windows 環境下で標準的にインストールされた Python は Unixよりも単純な構成をしているので、 Windows で追加のパッケージを別の場所に入れる場合には、伝統的に --prefix が使われてきました。

python setup.py install --prefix="\Temp\Python"

とすると、モジュールを現在のドライブの \Temp\Python ディレクトリにインストールします

インストールベースディレクトリは、 --prefix オプションだけで決まります; --exec-prefix オプションは、Windows ではサポートされていません。ファイルは以下のような構成でインストールされます:

Type of file | Installation Directory | Override option
pure module distribution | prefix | --install-purelib
non-pure module distribution | prefix | --install-platlib
scripts | prefix\Scripts | --install-scripts
data | prefix\Data | --install-data

カスタムのインストール

たまに、 別の場所へのインストール 節で述べたような別の場所へのインストールスキームが、自分のやりたいインストール方法と違うことがあります。もしかすると、同じベースディレクトリ下にあるディレクトリのうち、一つか二つだけをいじりたかったり、インストールスキームを完全に再定義したいと思うかもしれません。どちらの場合にせよ、こうした操作では カスタムのインストールスキーム を作成することになります。

別の場所へのインストールスキームに関するこれまでの説明で、 “オーバライドするためのオプション” というコラムにお気づきかもしれません。このオプションは、カスタムのインストールスキームを定義するための手段です。各オーバライドオプションには、相対パスを指定しても、絶対パスを指定しても、インストールベースディレクトリのいずれかを明示的に指定してもかまいません。 (インストールベースディレクトリは二種類あり、それら二つは通常は同じディレクトリです — Unix の “prefix スキーム” を使っていて、 --prefix と --exec-prefix オプションを使っているときだけ異なります。)

例えば、 Unix環境でモジュール配布物をホームディレクトリにインストールしたい — とはいえ、スクリプトは ~/bin ではなく ~/scripts に置きたい — とします。ご想像の通り、スクリプトを置くディレクトリは、 --install-scripts オプションで上書きできます; この場合は相対パスで指定もでき、インストールベースディレクトリ (この場合にはホームディレクトリ) からの相対パスとして解釈されます:

python setup.py install --home=~ --install-scripts=scripts

Unix 環境での例をもう一つ紹介します: インストール済みの Python が、 /usr/local/python を prefix にしてビルドされ、インストールされていて、標準のインストールスクリプトは /usr/local/python/bin に入るようになっているとします。 /usr/local/bin に入るようにしたければ、絶対パスを --install-scripts オプションに与えて上書きすることになるでしょう:

python setup.py install --install-scripts=/usr/local/bin

(この操作を行うと、 “prefix スキーム” を使ったインストールになり、 prefix は Python インタプリタがインストールされている場所 — この場合には /usr/local/python になります。)

Windows 用の Python を管理しているのなら、サードパーティ製モジュールを prefix そのものの下ではなく、 prefix の下にあるサブディレクトリに置きたいと考えるかもしれません。この作業は、インストールディレクトリのカスタマイズとほぼ同じくらい簡単です — 覚えておかねばならないのは、モジュールには二つのタイプ、 pure モジュールと非 pure モジュール (非 pure モジュール配布物内のモジュール) があるということです。例えば以下のようにします:

python setup.py install --install-purelib=Site --install-platlib=Site

指定したインストール先ディレクトリは、 prefix からの相対です。もちろん、 prefix を .pth ファイルに入れるなどして、これらのディレクトリが Python のモジュール検索パス内に入るようにしなければなりません。 Python のモジュール検索パスを修正する方法は、 Python サーチパスの変更 節を参照してください。

インストールスキーム全体を定義したいのなら、全てのインストールディレクトリオプションを指定しなければなりません。この作業には、相対パスを使った指定を勧めます; 例えば、全ての Python モジュール関連ファイルをホームディレクトリ下の python ディレクトリの下に置き、そのホームディレクトリをマウントしている各プラットフォームごとに別のディレクトリを置きたければ、以下のようにインストールスキームを定義します:

python setup.py install --home=~ \
                        --install-purelib=python/lib \
                        --install-platlib=python/lib.$PLAT \
                        --install-scripts=python/scripts
                        --install-data=python/data

また、以下のようにも指定できます:

python setup.py install --home=~/python \
                        --install-purelib=lib \
                        --install-platlib='lib.$PLAT' \
                        --install-scripts=scripts
                        --install-data=data

$PLAT は、(必ずしも) 環境変数ではありません — この表記は、 Distutils がコマンドラインオプションの解釈と同じやり方で展開します。設定ファイルを解釈する際と同じです。

言うまでもないことですが、毎回新たなモジュール配布物をインストールする度にインストールスキーム全体の指定を行っていては面倒です。そこで、オプションは Distutils 設定ファイル (Distutils 設定ファイル 参照) にも指定できます:

[install]
install-base=$HOME
install-purelib=python/lib
install-platlib=python/lib.$PLAT
install-scripts=python/scripts
install-data=python/data

あるいは、以下のようにも指定できます:

[install]
install-base=$HOME/python
install-purelib=lib
install-platlib=lib.$PLAT
install-scripts=scripts
install-data=data

これら二つは、 setup スクリプトを異なるインストールベースディレクトリから実行した場合には同じには ならない ので注意してください。例えば、

python setup.py install --install-base=/tmp

とすると、最初の書き方では pure モジュールが /tmp/python/lib に入り、二番目の書き方では /tmp/lib に入ります。(二番目のケースでは、インストールベースを /tmp/python に指定しようと考えるでしょう。)

読者は、設定ファイル例で、入力値に $HOME や $PLAT を使っていることに気づいているかもしれませんね。これらは Distutils の設定変数で、環境変数を彷彿とさせます。実際、この表記が使えるプラットフォーム上では、設定ファイル中に環境変数を入れられますが、 Distutils は他にも、例えば $PLAT のようにおそらくユーザの環境中にないような変数をいくつか持っています。(そしてもちろん、 Mac OS 9 のような環境変数のないシステムでは、設定ファイル中で使える変数は Distutils が提供しているものだけです。) 詳細は Distutils 設定ファイル を参照してください。

Python サーチパスの変更

Python インタプリタが import 文を実行するとき、インタプリタは Python コードや拡張モジュールをモジュール検索パス中から探します。検索パスのデフォルト値は、インタプリタをビルドする際に Python のバイナリ内に設定されます。検索パスは、 sys を import して、 sys.path を出力すればわかります。

$ python
Python 2.2 (#11, Oct  3 2002, 13:31:27)
[GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2',
 '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload',
 '/usr/local/lib/python2.3/site-packages']
>>>

sys.path 内の空文字列は、現在の作業ディレクトリを表します。

ローカルでインストールされるパッケージは、 .../site-packages/ ディレクトリに入るのが決まりですが、ユーザはどこか任意のディレクトリに Python モジュールをインストールしたいと思うかもしれません。例えば、自分のサイトでは、 web サーバに関連する全てのソフトウェアを /www に置くという決まりがあるかもしれません。そこで、アドオンの Python モジュールが /www/python 置かれることになると、モジュールを import するためにはディレクトリを sys.path に追加せねばなりません。ディレクトリを検索パスに追加するには、いくつかの異なる方法が存在します。

最も手軽な方法は、パス設定ファイルをすでに Python の検索パスに含まれるディレクトリ、通常は .../site-packages/ ディレクトリに置くというものです。パス設定ファイルは拡張子が .pth で、ファイルには sys.path に追加するパスを一行に一つづつ記述しなければなりません。 (新たなパスは今の sys.path の後ろに追加されるので、追加されたディレクトリ内にあるモジュールが標準のモジュールセットを上書きすることはありません。つまり、このメカニズムを使って、標準モジュールに対する修正版のインストールはできないということです。)

パスは絶対パスでも相対パスでもよく、相対パスの場合には .pth ファイルのあるパスからの相対になります。詳しくは site モジュールを参照してください。

やや便利さには欠けますが、Python の標準ライブラリ中にある site.py ファイルを編集することでも、 sys.path を変更できます。 site.py は、 -S スイッチを与えて抑制しないかぎり、Python インタプリタが実行される際に自動的に import されます。ただし、設定するには、単に site.py を編集して、例えば以下のような二行を加えます:

import sys
sys.path.append('/www/python/')

しかしながら、(例えば 2.2 から 2.2.2 にアップグレードするときのように) 同じメジャーバージョンの Python を再インストールすると、 site.py は手持ちのバージョンで上書きされてしまいます。ファイルが変更されていることを覚えておき、インストールを行う前にコピーを忘れずとっておかねばなりません。

また、 sys.path を修正できる二つの環境変数があります。 PYTHONHOME を使うと、インストールされている Python のプレフィクスを別の値に設定できます。例えば、 PYTHONHOME を /www/python に設定すると、検索パスは ['', '/www/python/lib/pythonX.Y/', '/www/python/lib/pythonX.Y/plat-linux2', ...] といった具合になります。

PYTHONPATH を使うと、 sys.path の先頭に一連のパスを追加できます。例えば、 PYTHONPATH を /www/python:/opt/py に設定すると、検索パスは ['/www/python', '/opt/py'] から始まります。 (sys.path にディレクトリを追加するには、そのディレクトリが実在しなければなりません; site は実在しないディレクトリを除去します。)

最後に、 sys.path はただの普通の Python のリストなので、どんな Python アプリケーションもエントリを追加したり除去したりといった修正を行えます。

Distutils 設定ファイル

上で述べたように、 Distutils 設定ファイルを使えば、任意の Distutils オプションに対して個人的な設定やサイト全体の設定を記録できます。すなわち、任意のコマンドの任意のオプションを二つか三つ (プラットフォームによって異なります) の設定ファイルに保存でき、コマンドラインを解釈する前にオプションを問い合わせさせるようにできます。つまり、設定ファイルはデフォルトの値を上書きし、さらにコマンドライン上で与えた値が設定ファイルの内容を上書きするわけです。さらに、複数の設定ファイルが適用されると、”先に” 適用されたファイルに指定されていた値は “後に” 適用されたファイル内の値で上書きされます。

設定ファイルの場所と名前

設定ファイルの名前と場所は、非常にわずかですがプラットフォーム間で異なります。Unix と Mac OS X では、三種類の設定ファイルは以下のようになります (処理される順に並んでいます):

設定ファイルのタイプ | 場所とファイル名 | 注記
system | prefix/lib/pythonver/distutils/distutils.cfg | (1)
personal | $HOME/.pydistutils.cfg | (2)
local | setup.cfg | (3)

Windows では設定ファイルは以下のようになります:

設定ファイルのタイプ | 場所とファイル名 | 注記
system | prefix\Lib\distutils\distutils.cfg | (4)
personal | %HOME%\pydistutils.cfg | (5)
local | setup.cfg | (3)

全てのプラットフォームにおいて、”個人の” ファイルは –no-user-cfg オプションを使って一時的に無効にすることができます。

注記:

厳密に言えば、システム全体向けの設定ファイルは、 Distutils がインストールされているディレクトリになります; Unixの Python 1.6 以降では、表の通りの場所になります。 Python 1.5.2 では、 Distutils は通常 prefix/lib/python1.5/site-packages/distutils にインストールされるため、 Python 1.5.2 では設定ファイルをそこに置かなければなりません。

Unixでは、環境変数 HOME が定義されていない場合、標準モジュール pwd の getpwuid() 関数を使ってユーザのホームディレクトリを決定します。このとき同時に Distutils によって os.path.expanduser() が実行されます。

現在のディレクトリ (通常は setup スクリプトがある場所) です。

(注記 (1) も参照してください) Python 1.6 およびそれ以降のバージョンでは、 Python のデフォルトの “インストールプレフィクス” は C:\Python なので、システム設定ファイルは通常 C:\Python\Lib\distutils\distutils.cfg になります。Python 1.5.2 ではデフォルトのプレフィクスは C:\Program Files\Python であり、Distutils は標準ライブラリの一部ではありません — 従って、システム設定ファイルは、 Windows 用の標準の Python 1.5.2 では C:\Program Files\Python\distutils\distutils.cfg になります。

Windows では、環境変数 HOME が設定されていない場合、 USERPROFILE 、 HOMEDRIVE 、 HOMEPATH を順々に試します。このとき同時に Distutils によって os.path.expanduser() が実行されます。

設定ファイルの構文

Distutils 設定ファイルは、全て同じ構文をしています。設定ファイルはセクションでグループ分けされています。各 Distutils コマンドごとにセクションがあり、それに加えて全てのコマンドに影響するグローバルオプションを設定するための global セクションがあります。各セクションには option=value の形で、一行あたり一つのオプションを指定します。

例えば、以下は全てのコマンドに対してデフォルトでメッセージを出さないよう強制するための完全な設定ファイルです:

[global]
verbose=0

この内容のファイルがシステム全体用の設定ファイルとしてインストールされていれば、そのシステムの全てのユーザによる全ての Python モジュール配布物に対する処理に影響します。ファイルが (個人用の設定をサポートしているシステムで) 個人用の設定ファイルとしてインストールされていれば、そのユーザが処理するモジュール配布物にのみ影響します。この内容を特定のモジュール配布物の setup.cfg として使えば、その配布物だけに影響します。

以下のようにして、デフォルトの “ビルドベース” ディレクトリをオーバライドしたり、 build* コマンドが常に強制的にリビルドを行うようにもできます:

[build]
build-base=blib
force=1

この設定は、コマンドライン引数の

python setup.py build --build-base=blib --force

に対応します。ただし、後者ではコマンドライン上で build コマンドを含めて、そのコマンドを実行するよう意味しているところが違います。特定のコマンドに対するオプションを設定ファイルに含めると、このような関連付けの必要はなくなります; あるコマンドが実行されると、そのコマンドに対するオプションが適用されます。 (また、設定ファイル内からオプションを取得するような他のコマンドを実行した場合、それらのコマンドもまた設定ファイル内の対応するオプションの値を使います。)

あるコマンドに対するオプションの完全なリストは、例えば以下のように、 --help を使って調べます:

python setup.py build --help

グローバルオプションの完全なリストを得るには、コマンドを指定せずに --help オプションを使います:

python setup.py --help

“Python モジュールの配布” マニュアルの、 “リファレンスマニュアル” の節も参照してください。

拡張モジュールのビルド: 小技と豆知識

Distutils は、可能なときにはいつでも、 setup.py スクリプトを実行する Python インタプリタが提供する設定情報を使おうとします。例えば、拡張モジュールをコンパイルする際には、コンパイラやリンカのフラグには Python をコンパイルした際と同じものが使われます。通常、この設定はうまくいきますが、状況が複雑になると不適切な設定になることもあります。この節では、通常の Distutils の動作をオーバライドする方法について議論します。

コンパイラ/リンカのフラグをいじるには

C や C++ で書かれた Python 拡張をコンパイルする際、しばしば特定のライブラリを使ったり、特定の種類のオブジェクトコードを生成したりする上で、コンパイラやリンカに与えるフラグをカスタマイズする必要があります。ある拡張モジュールが自分のプラットフォームではテストされていなかったり、クロスコンパイルを行わねばならない場合にはこれが当てはまります。

最も一般的なケースでは、拡張モジュールの作者はすでに拡張モジュールのコンパイルが複雑になることを見越していて、 Setup ファイルを提供して編集できるようにしています。 Setup ファイルの編集は、モジュール配布物に多くの個別の拡張モジュールがあったり、コンパイラに拡張モジュールをコンパイルさせるために細かくフラグをセットする必要があるような場合にのみ行うことになるでしょう。

Setup ファイルが存在する場合、ビルドするべき拡張モジュールのリストを得るために解釈されます。 Setup ファイルの各行には単一のモジュールを書きます。各行は以下のような構造をとります:

module ... [sourcefile ...] [cpparg ...] [library ...]

次に、各フィールドについて見てみましょう。

module はビルドする拡張モジュールの名前で、Python の識別子名として有効でなければなりません。モジュールの名前変更は、このフィールドを変えるだけではできない (ソースコードの編集も必要です) ので、このフィールドに手を加えるべきではありません。

sourcefile は、少なくともファイル名から何の言語で書かれているかがわかるようになっているソースコードファイル名です。 .c で終わるファイルは C で書かれているとみなされ、 .C 、 .cc 、および .c++ で終わるファイルは C++ で書かれているとみなされます。 .m や .mm で終わるファイルは Objective C で書かれているとみなされます。

cpparg は C プリプロセッサへの引数で、 -I 、 -D 、 -U または -C のいずれかから始まる文字列です。

library は .a で終わるか、 -l または -L のいずれかから始まる文字列です。

特定のプラットフォームにおいて、プラットフォーム上の特殊なライブラリが必要な場合、 Setup ファイルを編集して python setup.py build を実行すればライブラリを追加できます。例えば、以下の行

foo foomodule.c

で定義されたモジュールを、自分のプラットフォーム上の数学ライブラリ libm.a とリンクしなければならない場合、 Setup 内の行に -lm を追加するだけです:

foo foomodule.c -lm

コンパイラやリンカ向けの任意のスイッチオプションは、 -Xcompiler arg や -Xlinker arg オプションで与えます:

foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm

-Xcompiler および -Xlinker の後にくるオプションは、それぞれ適切なコマンドラインに追加されます。従って、上の例では、コンパイラには -o32 オプションが渡され、リンカには -shared が渡されます。コンパイラオプションに引数が必要な場合、複数の -Xcompiler オプションを与えます; 例えば、 -x c++ を渡すには、 Setup ファイルには -Xcompiler -x -Xcompiler c++ を渡さねばなりません。

コンパイラフラグは、環境変数 CFLAGS の設定でも与えられます。 CFLAGS が設定されていれば、 Setup ファイル内で指定されているコンパイラフラグに CFLAGS の内容が追加されます。

Windows で非 Microsoft コンパイラを使ってビルドするには

Borland/CodeGear C++

この小節では、 Borland C++ コンパイラのバージョン 5.5 で Distutils を使うために必要な手順について述べています。 まず、 Borland のオブジェクトファイル形式 (OMF) は、Python 公式サイトや ActiveState の Web サイトからダウンロードできるバージョンの Python が使っている形式とは違うことを知っておかねばなりません (Python は通常、 Microsoft Visual C++ でビルドされています。Microsoft Visual C++ は COFF をオブジェクトファイル形式に使います。) このため、以下のようにして、 Python のライブラリ python25.lib を Borland の形式に変換する必要があります:

coff2omf python25.lib python25_bcpp.lib

coff2omf プログラムは、 Borland コンパイラに付属しています。 python25.lib は Python インストールディレクトリの Libs ディレクトリ内にあります。拡張モジュールで他のライブラリ (zlib, ...) を使っている場合、それらのライブラリも変換しなければなりません。

変換されたファイルは、通常のライブラリと同じディレクトリに置かねばなりません。

さて、 Distutils は異なる名前を持つこれらのライブラリをどのように扱うのでしょうか? 拡張モジュールで (例えば foo という名の) ライブラリが必要な場合、 Distutils はまず _bcpp が後ろに付いたライブラリ (例えば foo_bcpp.lib) が見つかるかどうか調べ、あればそのライブラリを使います。該当するライブラリがなければ、デフォルトの名前 (foo.lib) を使います [1] 。

Borland C++ を使って Distutils に拡張モジュールをコンパイルさせるには、以下のように入力します:

python setup.py build --compiler=bcpp

Borland C++ コンパイラをデフォルトにしたいなら、自分用、またはシステム全体向けに、 Distutils の設定ファイルを書くことを検討した方がよいでしょう (Distutils 設定ファイル 節を参照してください)。

参考

C++Builder Compiler [http://www.codegear.com/downloads/free/cppbuilder]

Borland によるフリーの C++ コンパイラに関する情報で、コンパイラのダウンロードページへのリンクもあります。

Creating Python Extensions Using Borland’s Free Compiler [http://www.cyberus.ca/%7eg_will/pyExtenDL.shtml]

Borland 製のフリーのコマンドライン C++ を使って Python をビルドする方法について述べたドキュメントです。

GNU C / Cygwin / MinGW

この節では、 Cygwin や MinGW [2] 配布物中の GNU C/C++ コンパイラで Distutils を使うために必要な手順について述べます。 Cygwin 向けにビルドされている Python インタプリタを使っているなら、以下の手順をとらなくても Distutils はまったく問題なく動作します。

全ての拡張ライブラリが MinGW や Cygwin でビルドできるわけではありませんが、多くの場合はビルドできます。ビルドできない拡張ライブラリは、大抵C++を利用していたり Microsoft Visual Cの拡張に依存していたりします。

distutils に Cygwin を使って拡張をコンパイルさせるには次のようにタイプします。

python setup.py build --compiler=cygwin

Cygwin を no-cygwin モード [3] で使うときや MinGW を使うときは次のようにします。

python setup.py build --compiler=mingw32

これらのオプションやコンパイラをデフォルトにしたい場合、 Distutils の個人用あるいはシステム全体用の設定ファイルを書くことを検討するべきです。 (Distutils 設定ファイル を参照してください)

古いバージョンの Python と MinGW

以下の手順は Python 2.4.1 以前と MinGW 3.0.0 (binutils-2.13.90-20030111-1) 以前を利用しているときのものです。

上記のコンパイラは、いくつかの特殊なライブラリを必要とします。この作業は Borland の C++ よりもやや複雑です。というのは、ライブラリを変換するためのプログラムが存在しないからです。 まず、 Python DLL が公開している全てのシンボルからなるリストを作成しなければなりません。 (この作業むけの良いプログラムは、 http://www.emmestech.com/software/pexports-0.43/download_pexports.html から入手できます。)

pexports python25.dll >python25.def

これで、上で得られた情報をもとに、 gcc 用の import ライブラリを作成できます。

インストールされた python25.dll の位置はインストールオプションと、 Windowsのバージョンと言語に依存します。”自分だけのため”のインストールの場合には、インストールディレクトリのルートに配置されます。共有インストールの場合にはシステムディレクトリに配置されます。

dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a

出来上がったライブラリは、 python25.lib と同じディレクトリ (Python インストールディレクトリの libs ディレクトリになるはずです) に置かなければなりません。

拡張モジュールが他のライブラリ (zlib, ... ) を必要とする場合、それらのライブラリも変換しなければなりません。変換されたファイルは、それぞれ通常のライブラリが置かれているのと同じディレクトリに置かねばなりません。

参考

Building Python modules on MS Windows platform with MinGW [http://www.zope.org/Members/als/tips/win32_mingw_modules]

MinGW 環境で必要なライブラリのビルドに関する情報があります。

注記

[1]
つまり、全ての既存の COFF ライブラリを同名の OMF ライブラリに置き換えてもかまわないということです

[2]
詳しくは http://sources.redhat.com/cygwin/ や http://www.mingw.org/ を参照してください

[3]
このモードでは POSIX エミュレーションを利用できませんが、 cygwin1.dll も必要なくなります。

日本語訳について

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python モジュールのインストール »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる Installing Python Modules の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

Yasushi Masuda <y.masuda@acm.org> (April 2, 2004)

Kazuo Moriwaka

INADA Naoki <inada-n at klab.jp>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成

Python には様々な著者により寄稿された非常に多くのドキュメント類があります。 Python のドキュメントのマークアップには、 docutils [http://docutils.sf.net/] プロジェクトによって開発された reStructuredText [http://docutils.sf.net/rst.html] を、独自のディレクティブ (directive) で拡張して利用しています。そして、 Sphinx [http://sphinx.pocoo.org/] というツールセットを利用して、HTML 出力へと変換しています。

このドキュメントでは、ドキュメントを作成する上でのスタイルガイドと、 Python のドキュメントのために作られた Sphinx による独自の reStructuredText マークアップとその利用方法を説明します。

ノート

Python のドキュメントを寄贈したいと思っているなら、そのために reStructuredText をわざわざ学ぶ必要はありません; 平文での寄贈も大歓迎です。 Eメールで docs@python.org に送るか、 Tracker に課題 (issue) を登録してください。

1. 初めに

2. スタイルガイド

3. reStructuredText の基礎

4. 拡張マークアップ構成部 (Additional Markup Constructs)

5. LaTeX マークアップとの違い

6. ドキュメントをビルドする

7. このドキュメントについて

8. 翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

1. 初めに

Python のドキュメントは長い間、フリーなプログラミング言語としては良いものであると考えられてきました。その理由は多々ありますが、最も重要なのは、 Python の作者である Guido van Rossum が、言語やそのライブラリのドキュメントの提供と、ドキュメントの作成と維持の手助けする上でのユーザコミュニティの継続的な参加に早期から関わっていたことです。

コミュニティの参加には、バグ報告の作成から、単にドキュメントをより完全で利用しやすいものにできる場合に素朴な提案をするといったことまで、いくつものやりかたがあります。

このドキュメントは、Python のドキュメントの作者、あるいは潜在的な作者向けのものです。もっと具体的にいうと、標準ドキュメントに貢献したり、標準ドキュメントと同じツールを使って別のドキュメントを開発する人々向けです。このガイドは Python 以外のトピックに Python ドキュメント作成ツールを使う作者にとってはあまり有用ではなく、ツールを全く使用しない作者にもあまり有用ではないでしょう。

仮に、あなたが Python のドキュメントを寄贈したいと思っている一方で、 reStructuredText を学んだり、このドキュメントに書かれているマークアップ構造を学んだりする時間や気力を持てないとしても、あなたを Python プロジェクトへの協力者として迎え入れる余地はあります。既存のドキュメントを改善したり、欠けているドキュメントを提供してもらえるなら、現在のドキュメント製作チームがいつでも喜んでマークアップを行い、テキストを組み込みます。手助けしたいという気持ちをお持ちなら、このドキュメントに書かれていることを障害のように思わないでくださいね！

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

2. スタイルガイド

Python ドキュメントは、可能な限り Apple Publications Style Guide [http://developer.apple.com/mac/library/documentation/UserExperience/Conceptual/APStyleGuide/APSG_2009.pdf] に準拠することになっています。内容の合理性と、オンラインで容易に取得できることから、このスタイルガイドが選ばれました。

Apple のスタイルガイドがカバーしていないトピックについては、このドキュメントで必要に応じて議論していきます。

すべての reST ファイルは 3 スペースのインデントを使います。長さの上限は通常のテキストでは 80 文字ですが、テーブルや、深くインデントされたコードサンプルや、長いリンクはそれ以上にもなります。

空行を適切なところに惜しみなく使ってください。これはグループ化の助けになります。

センテンスの終わりのピリオドには、1 つか 2 つのスペースを続けることができます。reST は二つ目のスペースを無視しますが、Emacs のオートフィルモードを補助するためになど、慣習的に置かれることがあります。

脚注は、何かの情報を提供するのにもっとも適した方法である場合は利用されますが、普通はお勧めできません。脚注への参照を文の最後に追加する場合は、句点の後に追加しなければなりません。 reST 記法は次のようになります

この文には脚注への参照があります。 [#]_ ここは次の文になります。

脚注はファイルの終端か、ファイルが非常に大きい場合は節の終わりに集められます。 docutils は自動的に、脚注の参照への逆リンクを作成します。

脚注は、文の途中でも適切な場所で使用することができます。

Python ドキュメントの中では、オペレーティングシステムやプログラミング言語、標準機関、その他の名前を含む沢山の特殊な名前を使っています。それらの名前のほとんどには特別なマークアップを割り当てていませんが、推奨される表記法をここで提供して、ドキュメント作者が Python ドキュメント内の表現の一貫性を維持しやすくします。

その他の用語や単語についても特に説明しておく必要があるでしょう; ドキュメントの作者はこれらの規約に従い、ドキュメント全体を通して一貫性を保証しなければなりません。

CPU

“central processing unit” (中央処理装置) のことです。多くのスタイルガイドが、この語を最初に利用するときには略さずに書かねばならないとしています (ですから、どうしてもこの語を使う必要があるなら、必ずそうしてください!)。 Python ドキュメントでは、読者が最初にどこを読むのか合理的に予測する方法がないので、略語の使用を避けねばなりません。代わりに “processor (プロセッサ)” を使う方がよいでしょう。

POSIX

ある一連の標準仕様につけられた名前です。常に大文字だけからなります。

Python

私たちの大好きなプログラミング言語の名前は、常に大文字で始めます。

Unicode

ある文字セットと、それに対応する符号化方式の名前です。常に大文字で始めます。

Unix

1970年代初頭に AT&T ベル研究所で開発されたオペレーティングシステムの名前です。

2.1. 肯定的な論調

ドキュメントの焦点は、言語が何をするか、またはどうすれば効率がいいかを、肯定的に述べるようにすることです。

ある種のセキュリティ上の問題やセグメンテーション違反を除き、ドキュメントは “機能 x は危険です” や “上級者専用” などといった言い回しを避けるべきです。これらの価値判断は、コアドキュメントではなく外部のブログや wiki で行うものです。

悪い例 (読者を心配させてしまう):

警告: 明示的にファイルを閉じないと、データの損失や莫大なリソースの消費につながります。決して、参照カウントが自動的にファイルを閉じることに頼らないでください。

良い例 (言語の効率的な使い方について、確かな知識を確立する):

ファイルを使うための最高のプラクティスは、try/finally の対を使い、ファイルが使われた後に明示的に閉じることです。その代わりに、 with 文でも同じことができます。これは、適切な時にファイルが流されファイルディスクリプタリソースが解放されることを保証します。

2.2. 簡潔な表現

多いドキュメントが良いドキュメントであるとは限りません。簡潔すぎるくらいにしましょう。

ドキュメントを長くすることは理解の障碍となり、テキストの誤読や誤解釈につながります。特殊な例や警告が多い長い記述は、関数が実際より複雑で使いづらいものであるかのような印象を与えてしまします。

super() のドキュメントは、多くの情報が短いパラグラフに凝縮されたいい例です。 super() についての議論は本の一章ほどの内容がありますが、長い説話より簡潔な記述の方が理解しやすいことが多いのです。

2.3. コード例

短いコード例は理解の助けになります。正式な散文体の記述より、簡単な例の方が読者にとって理解しやすいことが多いです。

特定のユースケースに合った、実際的で動機づけのある例があれば、習得が早くなります。例えば、str.rpartition() メソッドは、Monty Python の会話文の最後の単語を取り除く例よりも、 URL をドメインに分割する例を挙げて実演したほうがいいです。

入力行と出力行を区別するべきところでは、 sys.ps2 第二インタプリタプロンプトの省略は控えるべきです。見てわかりづらくなるだけでなく、読者が例をカットアンドペーストして変化させながら実験することも難しくしています。

2.4. 等価なコード

等価な (またはほぼ等価な) コードを与えると、散文記述を補助するのに便利です。ドキュメント記述者は、等価なコードが価値を加えるかよく考えるべきです。

良い例は、 all() の等価なコードです。短い 4 行のコードで簡単に要約できます。できるだけ早く抜けるふるまいを最強調します。また、イテラブルが空であったときの特殊な例の扱いを明確にします。さらに、 all() 関数が早く終了した時、False と評価された特定のオブジェクトを返すような、よく要求される変形版を実装したい人々のためのモデルとしても役立ちます。

微妙な例は itertools.groupby() のコードです。この等価なコードは迅速な理解の助けとなるには複雑すぎるかもしれません。その複雑さにもかかわらず、この等価なコードは、別の実装のモデルとして、また、「グループ処理」は英語の散文で書くよりもコードで示したほうが簡単なために、残されています。

等価なコードを使うべきでない時の例は、oct() 関数です。数を八進数に変換するための手順は、ユーザーがこの関数の性質を学ぶときに価値があるものではないからです。

2.5. 読者

チュートリアル (とすべてのドキュメント) の論調は、読者の知性を尊重したものでなくてはなりません。読者が愚かであると考えないでください。関連情報を配置し、動機付けとなるユースケースを示し、用語集へのリンクを提供し、点をつなぎ合わせることに最善を尽くしてください。しかし、それを読者にしゃべり尽くして読者の時間を無駄にするようなことはしないでください。

チュートリアルは新参者を意識したもので、彼らの多くはチュートリアルで言語全体を評価しようとします。チュートリアルの経験は肯定的であるべきです。読者に、間違いを起こすと何か悪いことが起きるというような心配をさせないでください。チュートリアルは、知的で好奇心旺盛な読者のためのガイドとして振る舞い、詳細は how-to ガイドその他のソースに取っておきます。

プログラミングエラーを正当化したがる少数の遠慮無い読者 (「誤りを犯してしましました。だから、ドキュメントに間違いがあるに違いありません……」) からドキュメント変更の要請を受け付ける時には注意してください。典型的に、ドキュメントは誤りが見つかるまで調べられません。残念ながら、典型的にはドキュメントの編集によってユーザが間違った予想をすることを避けることは出来なかったでしょう (「驚きました……」)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

3. reStructuredText の基礎

この節は reStructuredText (reST) のコンセプトと文法の要約です。ドキュメント作者の生産性のために十分な情報を提供することに注目しています。 reST はシンプルで、出しゃばらないマークアップ言語として設計されたので、この文章はあまり長くありません。

参考

The authoritative reStructuredText User Documentation [http://docutils.sourceforge.net/rst.html].

3.1. 段落 (Paragraphs)

段落は reST においてもっとも基本的なブロックです。一行以上の空行で区切られただけのテキストの固まりが段落になります。 Python と同じく、 reST ではインデントは重要な意味を持つので、同じ段落に属す行は全て同じインデントレベルで左揃えする必要があります。

3.2. インラインマークアップ (Inline markup)

reST 標準のインラインマークアップは非常にシンプルです。

アスタリスク一つ: *text* を強調 (斜体) に、

アスタリスク二つ: **text** を強い強調 (太字) に、

バッククォート: ``text`` をサンプルコードに、

使ってください。

もしアスタリスクやバッククォートが通常のテキストの中で出てきて、インラインマークアップ用の区切り文字と混合する場合は、バックスラッシュ(訳注: 日本語フォントでは、一般的に円記号になります)でエスケープする必要があります。

インラインマークアップの幾つかの制限に気をつけてください:

ネストできません。

マークアップされる内容の先頭や終端に空白文字があってはなりません: * text* は間違いです。

マークアップの外側は、non-word 文字で囲まれていなければなりません。必要な場合はバックスラッシュでエスケープしたスペースを使ってください: thisis\ *one*\ word

これらの制限は将来のバージョンの docutils で解除されるかもしれません。

reST は独自の “interpreted text roles” に対応していて、囲まれたテキストを専用の方法で解釈することができます。別の節で解説しますが、Sphinx はこれを、意味に基づくマークアップと識別子のクロスリファレンスのために利用しています。 “interpreted text roles” の一般的な文法は :rolename:`内容` になります。

3.3. リストとクォート (Lists and Quotes)

リストの表現は自然です: 段落の最初にアスタリスクをおいて、適切にインデントするだけです。番号付きリストも同じで、 # 記号を使えば自動的にナンバリングされます:

* これは番号なしリストです。
* リストの要素は二つあり、二つ目は
  二行使用しています。

#. これば番号付きリストです。
#. こちらも要素が二つあります。

リストはネストさせることもできます。親になるリスト要素との間に空行が必要なことに気をつけてください:

* これは
* リストで

  * ネストされたリストと
  * 子要素があります。

* そしてここは親のリストの続きです。

定義リストは次のようにして作ります:

単語 (行の終わりまで)
   単語の定義。インデントされている必要がある。

   複数の段落を持つことも可能。

次の単語
   定義。

定義の部分は周りの段落よりも深くインデントします。

3.4. ソースコード (Source Code)

リテラルコードブロックは、特別なマーカー :: で終わる段落の次に始まります。リテラルブロックはインデントしなければなりません。

これは通常の段落です。次の段落はコードサンプルです::

   ここには、インデントの除去以外の
   処理が行われません。

   複数行にまたがることもできます。

ここでまた通常の段落になります。

:: マーカーの処理はスマートです:

単体で段落になっていた場合は、その段落はドキュメントから完全に除去されます。

マーカーの前に空白があれば、マーカーは削除されます。

マーカーの前が空白でなければ、マーカーはコロン一つに置き換えられます。

なので、上の例での最初の段落の二つ目の文は、 “次の段落はコードサンプルです:” と出力されます。

3.5. ハイパーリンク (Hyperlinks)

3.5.1. 外部リンク (External links)

インラインでのWebリンクには、 `リンク文字列 <http://target>`_ を使ってください。リンク文字列をアドレスにする場合は、マークアップしなくても、パーサーがリンクやメールアドレスを見つけて処理します。

3.5.2. 内部リンク (Internal links)

内部リンクには、reSTの特別な role を利用します。特別なマークアップのセクションを見てください。 クロスリンクのマークアップ (Cross-linking markup)

3.5.3. セクション

セクションヘッダは、記号を使って、セクションタイトルにそれ以上の長さのアンダーライン (とオプションでオーバーライン) を引いて作ります。:

==============
ここにタイトル
==============

通常、特定の文字に特定の見出しレベルが割り当てられておらず、ヘッダ構造から自動的にレベルが決まります。しかし、 Python ドキュメントにおいては、以下のルールを使います:

# (オーバーライン付き) を編(part) に

* (オーバーライン付き) を章(chapter) に

= を節(section) に

- を項(subsection) に

^ を小区分(subsubsection) に

" を段落(paragraph) に

3.6. 明示的なマークアップ (Explicit Markup)

reST において、 “明示的なマークアップ (explicit markup)” は、脚注、特別なハイライト付きの文、コメント、一般的な指定のために利用されます。

明示的なマークアップのブロックは、 .. に空白が続いたものが行頭にあるときに始まり、次の段落が同じインデントになるところで終わります。 (明示的なマークアップと通常の段落の間には空行が必要です。すこし複雑に思えるかもしれませんが、ドキュメントを書くときには十分に直感的です。)

3.7. ディレクティブ (Directives)

ディレクティブは一般的な、明示的なマークアップを行うブロックです。 role のような reSTの拡張メカニズムの一つで、 Sphinx はディレクティブを多用しています。

基本的に、ディレクティブは、名前、引数、オプション、内容で構成されます。 (この XXX を覚えておいてください。次の章でカスタムディレクティブを説明するときに出てきます。) 次の例を見てください

.. function:: foo(x)
              foo(y, z)
   :bar: no

   ユーザーから入力されたテキスト一行を返す.

function はディレクティブの名前です。ここでは引数が二つあり、一つは一行目の残りの部分で、もう一つは次の行です。オプションも一つ、 bar があります。 (ごらんの通り、オプションは引数の行のすぐ次の行にあり、コロンで示されます.)

一行の空行を挟んでディレクティブの内容が続きます。内容はディレクティブの開始位置と同じ場所までインデントされます。

3.8. 脚注 (Footnotes)

脚注を使うときは、 [#]_ を使って脚注を入れる場所を示し、脚注の内容はドキュメントの最後に、次の例のように、”Footnotes” [1] という rubric ヘッダの後に書きます。

Lorem ipsum [#]_ dolor sit amet ... [#]_

.. rubric:: Footnotes

.. [#] 最初の脚注の内容
.. [#] 二つ目の脚注の内容

3.9. コメント (Comments)

（上の脚注のような）有効なマークアップになっていない、全ての明示的なマークアップブロックは、コメントとして扱われます。

3.10. ソースのエンコード (Source encoding)

em dash や copyright sign のような特別な文字を reST に含める最も簡単な方法は Unicode文字を使って直接記述することなので、そのエンコードを決める必要があります。

全ての Python ドキュメントのソースファイルは UTF-8 エンコードでなければなりません。そしてHTMLドキュメントもUTF-8で出力するのが良いでしょう。

3.11. 判っていること

reST ドキュメントをオーサリングするときに良く問題になることがあります:

インラインマークアップの区切り: 上で述べたように、インラインマークアップは囲っているテキストと non-word 文字で区切られています。スペースを囲むときにはエスケープが必要になります。

注記

[1]
訳注：Sphinx 1.0 以降では日本語で Footnotes の代わりに “注記” も許容されるようです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

4. 拡張マークアップ構成部 (Additional Markup Constructs)

Sphinx は標準の reST マークアップに対して、たくさんのディレクティブと “interpreted text roles” を拡張しています。このセクションにはそれらの拡張された構成部のリファレンスがあります。 “標準”の reST 構成部は、 Python ドキュメントで使用されてはいますが、そのドキュメントはここにはありません。

ノート

これは Sphinx の拡張マークアップの機能の概要です。網羅された情報は Sphinxのドキュメント [http://sphinx.pocoo.org/contents.html] にあります。

4.1. メタ情報マークアップ (Meta-information markup)

sectionauthor

現在のセクションの著者を示します。引数には、(公表されないにしても)公表されても良いような名前と、email アドレスを含むべきです。アドレスのドメイン名部分は小文字で記述されるべきです。例:

.. sectionauthor:: Guido van Rossum <guido@python.org>

現在のところ、このマークアップは出力には全く利用されていませんが、だれが貢献したのかを把握するのに役に立っています。

4.2. モジュール用のマークアップ (Module-specific markup)

この節では、ドキュメント中のモジュールに関する情報を提供するために使われるマークアップについて説明します。各モジュールは各々のファイルでドキュメントされるべきです。通常このマークアップは、そのファイルのタイトルヘッダの後に使います。典型的なファイルは次のように始まります:

:mod:`parrot` -- Dead parrot access
===================================

.. module:: parrot
   :platform: Unix, Windows
   :synopsis: Analyze and reanimate dead parrots.
.. moduleauthor:: Eric Cleese <eric@python.invalid>
.. moduleauthor:: John Idle <john@python.invalid>

ごらんの通り、モジュール専用マークアップは、 module と moduleauthor という二つのディレクティブから成ります。

module

このディレクティブはモジュールの説明の始まりを示します。（パッケージのサブモジュールの場合は、モジュール名はパッケージ名を含めて全体を記述すること）

platform オプションは、そのモジュールが利用可能なプラットフォームをカンマで区切ったリストです。（全てのプラットフォームで利用可能であるなら、このオプションは外すべきです）要素は短い識別子で、 “IRIX”, “Mac”, “Windows”, “Unix” などが使われています。できるだけ、すでに使われている識別子を使うようにしてください。

synopsis オプションは、モジュールの目的を説明する一文で構成されます。これは、現在のところ、 Global Module Index でのみ利用されています。

moduleauthor

moduleauthor ディレクティブは、 sectionauthor と同じで、作者の名前になります。このディレクティブは、作者の人数だけ繰り返して利用できます。現在、このディレクティブは出力に利用されていません。

ノート

モジュールを解説するファイルのセクションタイトルは、概要ファイルの中の table-of-contents ツリーに利用されるので、意味が解るようにしてください。

4.3. 情報単位 (Information units)

モジュールが提供する機能を解説するために使うディレクティブが幾つかあります。各ディレクティブは、何を説明しようとしているのかを判別する情報として一つかそれ以上のシグネチャを必要とします。そして、ディレクティブの内容はその解説であるべきです。デフォルトではディレクティブはインデックスのエントリに登録されます。インデックスのエントリが必要ない場合は、ディレクティブオプションとして :noindex: というフラグを追加します。次の例は、ここまでで説明した要素を全て含んだディレクティブになります:

.. function:: spam(eggs)
              ham(eggs)
   :noindex:

   Spam or ham the foo.

オブジェクトのメソッドやデータ属性(attribute)のシグネチャは、文脈からどの型に属しているかが明らかな場合であっても、 (.. method::FileInput.input(...)) のように型名を含める必要があります。これは、一貫したクロスリファレンスを実現するためです。 “context managers” といった抽象プロトコルに属するメソッドを解説する場合にも、インデックスを判りやすくするために、（仮想）型名を付けてください。

ディレクティブは以下の通りです。

c:function

Cの関数を説明します。シグネチャはC言語のまま付けてください。例:

.. cfunction:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)

このディレクティブは関数ライクなプリプロセッサマクロを説明するのにも使います。引数の名前を省略しないでください。引数の名前を説明の中で利用できます。

シグネチャの中のアスタリスクをバックスラッシュでエスケープしなくても良いことを覚えておいてください。reST のインラインに対するパース処理は行われません。

c:member

Cの構造体メンバを説明します。シグネチャの例:

.. cmember:: PyObject* PyTypeObject.tp_bases

説明文は、値の取り得る範囲、値がどのように扱われるか、値を変更しても良いのかどうかについて記述するべきです。テキストの中で構造体のメンバを参照するときには member role を利用するべきです。

c:macro

“シンプル”な C言語のマクロについて説明します。シンプルなマクロとは、引数を取らず、関数として解説されないものです。このディレクティブは単純な定数の定義には利用しません。 Python ドキュメントの中でこのディレクティブが使われている例には、 PyObject_HEAD と Py_BEGIN_ALLOW_THREADS があります。

c:type

C の型を説明します。シグネチャは単に型の名前であるべきです。

c:var

C のグローバル変数を説明します。シグネチャは、次の例のように、型を含めるべきです:

.. cvar:: PyObject* PyClass_Type

data

モジュール内のグローバルなデータを説明します。変数にも、 “定数として宣言された” 値にも利用します。クラスとオブジェクトの属性にはこのディレクティブを使いません。

exception

例外クラスについて説明します。シグネチャは、必要ではありませんが、コンストラクタ引数と丸括弧を含むことができます。

function

モジュールレベル関数を説明します。シグネチャには引数を記述するべきです。オプションの引数は角括弧で囲みます。明快さのために必要であれば、デフォルト値を含めることもできます。例:

.. function:: repeat([repeat=3[, number=1000000]])

このディレクティブはオブジェクトメソッドには利用されません。モジュールの名前空間にあり、モジュールの公開インタフェースになっている、束縛済みのオブジェクトメソッド (Bound object method) については、通常の関数とほとんど変わらないので、このディレクティブを使います。

説明文は、必要とされる引数と、それがどのように使われるか（特に、可変(mutable) オブジェクトが変更されるかどうか）、副作用、発生しうる例外についての情報を含むべきです。小さな例を提供するのも良いでしょう。

class

クラスを説明します。シグネチャには丸括弧とコンストラクタ引数を含めることができます。

attribute

オブジェクトの属性を説明します。説明文は、期待されるデータ型と、直接変更しても良いかどうかを含むべきです。このディレクティブは、下記の例のように、クラスディレクティブの中にネストするべきです:

.. class:: Spam

      クラスの解説

      .. attribute:: ham

         属性の解説

例えば、異なる属性やメソッドを複数のドキュメントに分けるときなどに、属性のドキュメントは、クラスディレクティブの外に置くことも出来ます。このとき、明示的にクラス名を含むべきです:

.. attribute:: Spam.eggs

method

オブジェクトメソッドを説明します。パラメータからは、 self パラメータを除外するべきです。説明文は function と同じような情報を提供するべきです。このディレクティブは、上記の例のように、クラスディレクティブの中にネストするべきです

opcode

Python バイトコード(bytecode)の命令を説明します。

cmdoption

Python のコマンドラインオプションもしくはスイッチを説明します。オプションの引数名は <> の括弧で囲います。 例:

.. cmdoption:: -m <module>

   module をスクリプトとして実行します。

envvar

Python が利用したり定義している環境変数を説明します。

もっと汎用的なバージョンの以下のディレクティブもあります:

describe

このディレクティブは、上で説明したディレクティブと同じフォーマットを生成しますが、インデックスエントリやクロスリファレンスターゲットは生成しません。このディレクティブは、たとえば、このドキュメントでディレクティブの説明をするために利用しています。例:

.. describe:: opcode

   Python バイトコードの命令を説明します。

4.4. コードサンプルを表示する (Showing code examples)

Python ソースコードやインタラクティブセッションの例は、 reST 標準のリテラルブロックを利用して書きます。手前の段落の最後を :: にして、インデントで範囲を指定します。

インタラクティブセッションを表現するときは、プロンプトと出力を Python コードと一緒に書いてください。インタラクティブセッションに対して特別なマークアップは用意されていません。入力か出力の最後の行の後に、 “使用されない” プロンプトを入れてはいけません。次の例のように してはいけません

>>> 1 + 1
2
>>>

シンタックスハイライトはスマートに処理されます:

各ソースファイルには、 “ハイライト言語” があります。多数のファイルで Python のコードをハイライトするために、デフォルトでは 'python' に設定されています。

Python ハイライティングモードでは、インタラクティブセッションは自動的に認識されて適切にハイライトされます。

ハイライト言語は highlightlang ディレクティブを利用して変更することができます。以下のようにして利用します:

.. highlightlang:: c

このディレクティブで設定されたハイライト言語は、次の highlightlang ディレクティブまで有効になります。

ハイライト言語のよく使われる値は以下の通りです:

python (デフォルト)

c

rest

none (ハイライトなし)

現在のハイライト言語でのハイライティングに失敗した場合、そのブロックは全くハイライトされません。

長い、そのまま表示されるテキストは、外部のプレインテキストのみで書かれたファイルに格納して、取り込む (include) こともできます。その場合、標準の include ディレクティブに literal オプションフラグを付けて利用します。たとえば、 example.py という Python ソースファイルを取り込む場合は:

.. include:: example.py
   :literal:

4.5. インラインマークアップ (Inline markup)

前に述べたように、 Sphinx はドキュメント内に意味に基づくマークアップを挿入するために、 “interpreted text roles” を使います。

関数/メソッドの引数のようなローカル変数名は例外で、シンプルに *var* とマークされます。

その他の全ての role について、 :rolename:`content` のように書く必要があります。

そのほかにもクロスリファレンス role をより他用途にする便利な機能があります。

明示的なタイトルと参照ターゲットを、 reST の直接ハイパーリンクのように書くことができます: :role:`title <target>` は target を参照しますが、リンクテキストは title になります。

コンテントにprefix ! を付けると、参照もハイパーリンクも作られません。

Python オブジェクトのロールにおいて、コンテントに ~ というprefixをつけると、リンクターゲットはターゲットの最後の部分になります。例えば、 :meth:`~Queue.Queue.get` は Queue.Queue.get を参照しますが、リンクテキストとしては get だけを表示します。

HTML出力において、そのリンクの title 属性 (例えばマウスオーバー時のツールチップに表示される) は完全なターゲット名になります。

以下の roles はモジュール内のオブジェクトを参照し、該当する識別子があればハイパーリンクを作成します。

mod

モジュールの名前。ドット付きの名前も使われる。これはパッケージの名前にも使う。

func

Python 関数の名前。ドット付きの名前も使われる。可読性のために、 role のテキストには後ろの丸括弧も含めるべきである。丸括弧は該当する識別子を検索するときには無視される。

data

モジュールレベル変数や定数の名前。

const

定数として “宣言された” 名前。これは C言語の #define か、 Python の変更されないことを意図された変数である。

class

クラス名。ドット付きの名前も使われる。

meth

オブジェクトメソッドの名前。 role テキストには型の名前と、メソッド名、後続の丸括弧を含めるべきである。ドット付きの名前も使われる。

attr

オブジェクトのデータ属性の名前。

exc

例外の名前。ドット付きの名前も使われる。

このマークアップで囲まれた名前は、モジュール名とクラス名の両方あるいは片方を含めることができます。たとえば、 :func:`filter` は、現在のモジュール内にある filter という名前の関数か、その名前のビルトイン関数を参照できます。それに対して、 :func:`foo.filter` とすると、はっきりと foo モジュールの中の filter 関数だけを参照します。

同じようなことが、ある名前が現在ドキュメントしているクラスの属性かどうかを決定する際にも行われます。

以下の roles は、その C言語の要素が API ドキュメントにあれば、それに対するクロスリファレンスを作成します。

cdata

C言語の変数の名前。

cfunc

C言語の関数の名前。後続の丸括弧も含めるべきである。

cmacro

前述した、 “シンプルな” C のマクロの名前。

ctype

C言語の型の名前。

以下の role はクロスリファレンスは作るかもしれませんが、オブジェクトを参照する事はありません。

token

文法上のトークンの名前。(リファレンスマニュアルにおいて、出力間のリンクを作成するために使われます)

以下の roles はテキストのフォーマットスタイルを変更する以外何もしません。

command

rm のような、OS レベルのコマンドの名前。

dfn

テキストの中で定義される語をマークする。 (インデックスエントリは作成されない)

envvar

環境変数。インデックスエントリが作成される。

file

ファイルやディレクトリの名前。この中では、 “可変” な部分を示すために波括弧 “{}” を利用できる。例:

... は :file:`/usr/lib/python2.{x}/site-packages` にインストールされます ...

ビルドされたドキュメントの中では、この x は、 Python マイナーバージョンで置き換えられることを示すために、違った形式で表示されます。

guilabel

インタラクティブなユーザーインタフェースの一部として表示されているラベルは、 guilabel を使ってマークされるべきです。これには、 curses やその他のテキストベースのライブラリを利用して作られた、テキストベースのインタフェースの中のラベルも含みます。ボタンラベル、ウィンドウタイトル、フィールド名、メニューとその項目、選択リスト内の要素など、インタフェース内のどんなラベルにも、この role を利用するべきです。

kbd

キーストロークシーケンスをマークアップします。キーシーケンスをどんな形式で表現するかは、プラットフォームやアプリケーションごとに慣習があります。適切な慣習が無い場合は、初心者や非ネイティブスピーカーにも判るように、修飾キー (modifier key) を省略形にしないでください。例えば、 xemacs キーシーケンスは、 :kbd:`C-x C-f` のように記述できますが、特定のアプリケーションやプラットフォームに関連づけられていない場合は、このキーシーケンスは :kbd:`Control-x Control-f` とマークアップされるべきです。

keyword

プログラミング言語の予約後(keyword).

mailheader

RFC 822 形式のメールヘッダの名前。このマークアップは、そのヘッダが e-mail で利用されることを意味するわけではなく、同じ “スタイル” のどんなヘッダを参照するのにも使えます。多種の MIME 仕様で定義されているヘッダにも利用されます。ヘッダの名前は、実際に利用される場合と同じように書くべきで、一般的な使い方が複数ある場合は camel-case が好まれます。例: :mailheader:`Content-Type`.

makevar

make の変数名。

manpage

セクションを含む、Unix manual page への参照。例: :manpage:`ls(1)`.

menuselection

メニュー項目は menuselection role を使ってマークアップされるべきです。これは、サブメニューや特定の操作のの選択を含め、完全なメニュー項目の並びや、その一部をマークアップするのに使われます。各項目の名前は --> を使って区切るべきです。

例えば、”スタート > プログラム” をマークアップする場合は、次の様にします:

:menuselection:`スタート --> プログラム`

幾つかのOSで、メニュー項目の後ろに何か記号を付けてダイアログボックスを開く事を示すといったことがあります。そういったメニュー項目の後ろに続く表記は、メニュー項目名に含めないべきです。

mimetype

MIME type もしくは MIME type の構成要素 (メジャーもしくはマイナー部分だけ) の名前。

newsgroup

Usenet ニュースグループの名前。

option

実行可能プログラムのコマンドラインオプション。先頭のハイフンも含めなければならない。

program

実行可能プログラムの名前。幾つかのプラットフォームでは、実行可能ファイル名と異なるかもしれない。特に、Windows のプログラムでは、 .exe (もしくは他の) 拡張子は除くべきである。

regexp

正規表現。クォートを含めるべきではない。

samp

コードのようなリテラルテキスト。 :file: と同じく、この中では “可変” な部分を示すために波括弧を利用できます。

“可変” 部分が要らないのであれば、通常の ``code`` を使ってください。

以下の roles は外部リンクを生成する:

pep

Python Enhancement Proposal への参照。これは適切なインデックスのエントリを生成する。HTML出力では、 “PEP number” というテキストが生成され、このテキストは指定された PEP のオンラインコピーへのハイパーリンクになる。

rfc

Internet Request for Comments (RFC) への参照。これは適切なインデックスのエントリを生成する。HTML 出力では “RFC number” というテキストが生成され、このテキストは指定された RFC のオンラインコピーへのハイパーリンクになる。

ハイパーリンクのために特別な role が用意されていないことに注意してください。 reST 標準の方法がその目的に利用できるからです。

4.6. クロスリンクのマークアップ (Cross-linking markup)

ドキュメント中の任意のセクションに対してのクロスリファレンスをサポートするには、 reST 標準のラベルはあまり良くありません。全てのラベルはセクションタイトルの前におかなければならず、全てのラベルの名前はドキュメントのソース全体に渡ってユニークでなければなりません。

そこで、セクションを参照するのには :ref:`label-name` という role を、利用できます。

例:

.. _my-reference-label:

クロスリファレンスされるセクション
----------------------------------

セクションの文字列。

このセクション自体を参照します。 :ref:`my-reference-label` を見てください。

.. _my-reference-label:

:ref: の部分はセクションタイトルで置き換えられます。

4.7. 段落レベルでのマークアップ (Paragraph-level markup)

以下のディレクティブは、通常のテキストと同じように情報単位の中で利用でき、短いパラグラフを作成します。

note

この note に関係あるどの API を利用するときにも、ユーザーが気をつけるべき特に重要な情報。このディレクティブの内容は完全な文で、適切な句読点を全て含めなければなりません。

例:

.. note::

   この関数はスパムメールを送るためのものではありません。

warning

この warning に関係あるどの API を使うときにでも、ユーザーがとても慎重になるべき重要な情報。このディレクティブの内容は完全な文で、適切な句読点を全て含めなければなりません。警告だらけのページでユーザーを怖がらせないように、 node ではなく warning を使うのは、クラッシュ、データ損失、セキュリティに関する情報だけに留めるべきです。

versionadded

このディレクティブは、どのバージョンの Python で対象の要素がライブラリや C API に追加されたのかを示します。このディレクティブがモジュール全体に適用する場合、ディレクティブをモジュールセクションのどの文章よりも先におかれるべきです。

最初の引数は必須で、バージョンです。二つ目の引数は任意で、変更点の 簡潔な説明です。

例:

.. versionadded:: 2.5
   *spam* 引数.

ディレクティブの先頭行と説明との間に空行を入れてはならないことに注意してください。これはマークアップされたときにブロックが視覚的に連続するためです。

versionchanged

versionadded とほとんど同じですが、対象の要素がいつどのように変更 (新しい引数が追加された、副作用が変わった、等) されたかを説明します。

impl-detail

このディレクティブは、 CPython に限定された情報を区別するために使います。ブロック要素としても、一文の引数としても利用できます。例えば

.. impl-detail::

   This describes some implementation detail.

   More explanation.

または、

.. impl-detail:: This shortly mentions an implementation detail.

内容の先頭に、自動的に “CPython implementation detail:” という一文が入ります。

seealso

たくさんのセクションで、モジュールドキュメントや外部ドキュメントが参照されています。これらのリストは、 seealso ディレクティブで作成されます。

seealso ディレクティブは一般的に、セクションの中で、どのサブセクションより前に置かれます。 HTML 出力では、本文の流れから切り離された区画の中に表示されます。

seealso ディレクティブの中身は、 reST の定義リストであるべきです。例:

.. seealso::

   Module :mod:`zipfile`
      :mod:`zipfile` 標準モジュールのドキュメント。

   `GNU tar manual, Basic Tar Format <http://link>`_
      GNU tar 拡張を含む、 tar アーカイブファイルのドキュメント。

rubric

このディレクティブは、目次 (table of contents) の項目にならない段落見出しを作ります。現在のところ、 “脚注” キャプションに利用されています。

centered

このディレクティブは、センタリングされた太字の段落を作ります。次のようにして使います:

.. centered::

   段落の内容

4.8. Table-of-contents マークアップ (Table-of-contents markup)

reST が複数のドキュメントを繋いだり、ドキュメントを複数のファイルに分割して出力する機能を持たないので、 Sphinx は table-of-contents を作成したり、ドキュメントの元ファイル間に関連を持たせたりするためにカスタムのディレクティブを利用しています。 toctree ディレクティブはその中心になる要素です。

toctree

このディレクティブは、ディレクティブの要素として与えられたファイルの中の TOCs (“sub-TOC trees” を含む) から作成した “TOC tree” をその場所に挿入します。 maxdepth オプションに数値を指定することで、 “TOC tree” の深さを指定できます。デフォルトでは全レベルを利用します。

次の例(ライブラリリファレンスインデックスから持ってきました)を考えてみます:

.. toctree::
   :maxdepth: 2

   intro
   strings
   datatypes
   numeric
   (もっとたくさん)

このディレクティブは二つの事を行います:

指定されたファイル全てから TOC を作ります。深さが２、つまり一段階ネストした見出しまで含まれます。各ファイルの中の toctree ディレクティブも含まれます。

Sphinx は intro, strings, ... というファイルの相対順序と、それぞれのファイルが現在のライブラリインデックスというファイルの子供である事を識別します。この情報から、 “next chapter”, “previous chapter”, “parent chapter” というリンクが作成されます。

4.9. インデックス生成マークアップ (Index-generating markup)

Sphinx は自動的にインデックスのエントリを、先に述べた全ての情報の単位 (function, class, attribute のような) から作成します。

しかし、インデックスをより有用なものにしたり、言語リファレンスのような情報が情報の単位の中に含まれないようなドキュメントでもインデックスのエントリを作成できるようにするために、明示的なディレクティブも利用可能です。

そのディレクティブは index で、一つかそれ以上のインデックスエントリを含みます。各エントリは、種類と値をコロンで区切ったもので構成されます。

例:

.. index::
   single: execution!context
   module: __main__
   module: sys
   triple: module; search; path

このディレクティブは５つのエントリを持ち、 index 文の場所へのリンクになっているインデックスエントリに変換されます。(もしくは、オフラインメディアの場合、該当するページ番号になります)

利用可能なエントリの種類は:

single

単独のインデックスエントリを生成します。サブエントリのテキストをセミコロンで区切る（これは以降の種類でも、どんなエントリを作るのかを指定するときに使います）ことによってサブエントリを作成できます。

pair

pair: loop; statement は、 loop; statement と statement; loop という名前の二つのインデックスエントリを一度に作成するショートカットです。

triple

同じように、 triple: module; search; path; は、 module; search path, search; path, module, path; module search というエントリを作成するショートカットです。

module, keyword, operator, object, exception, statement, builtin

これらは全て二つのインデックスエントリを作成します。例えば、 module: hashlib は、 module; hashlib と hashlib; module を作ります。

4.10. 文法導出表記 (Grammar production displays)

形式的な文法の導出を表示するための特別なマークアップが利用可能です。このマークアップはシンプルで BNF (やその派生系) の全ての側面を表そうとはしていませんが、文脈自由文法 (context-free grammer) を、記号が使われている部分からその記号の定義部分へハイパーリンクが張られている形で表記するために十分な能力を提供しています。

productionlist

このディレクティブは導出のグループを囲むために使われます。各導出は一つの行として渡され、名前と、コロンで区切られた残りの定義で構成されます。定義が複数行に渡る場合は、継続する各行は最初の行のコロンと同じ位置にあるコロンで始まらなければなりません。

空行は productionlist ディレクティブの引数として許可されていません。

定義には interpreted text としてマークアップされたトークン名を使うことができます。 (例: unaryneg ::= "-" `integer`) – これは、各トークンの導出に対するクロスリファレンスを作成します。代替を示すために利用される縦棒はバックスラッシュでエスケープしなければならないことに気をつけてください。そうしないと、 reST パーサーは縦棒を置換参照 (substitution reference) として認識するからです。

production においては、これ以上の reST パース処理が行われない事に注意してください。なので、 * や | といった文字をエスケープする必要がありません。

以下は Python リファレンスマニュアルの中の例です:

.. productionlist::
   try_stmt: try1_stmt \| try2_stmt
   try1_stmt: "try" ":" :token:`suite`
            : ("except" [:token:`expression` ["," :token:`target`]] ":" :token:`suite`)+
            : ["else" ":" :token:`suite`]
            : ["finally" ":" :token:`suite`]
   try2_stmt: "try" ":" :token:`suite`
            : "finally" ":" :token:`suite`

4.11. 置換 (Substitutions)

ドキュメントシステムはデフォルトで定義されている３種類の置換を用意しています。それらはビルド設定ファイル conf.py で設定されます。

|release|

ドキュメントが言及している Python のリリースへ置換されます。これは、例えば 2.5.2b3 のような、 alpha/beta/release candiate を含む完全バージョン文字列です。

|version|

ドキュメントが言及している Python バージョンへ置換されます。これは、たとえばバージョン 2.5.1 において 2.5 の様に、バージョン文字列のうちメジャー・マイナー部のみで構成されます。

|today|

今日の日付か、ビルド設定ファイルで指定された日付のどちらかに置換されます。通常は April 14, 2007 のようなフォーマットになります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

5. LaTeX マークアップとの違い

マークアップ言語は変わりましたが、もとの LaTeX ドキュメントにあったコンセプトやドキュメント型(markup types) はほとんど残っています – 環境(environments) は reST ディレクティブ、インラインコマンドは reST roles などなど。

しかし、それらがどう動作するのか(the way these work)については、マークアップ言語の違いのため、もしくは Sphinx の改善のために、いくらか異なっています。このセクションでは、古いフォーマットに慣れた人に新しいフォーマットでどう変わったのか概要を示すために、違いをリストアップしていきます。

5.1. インラインマークアップ

インラインマークアップには以下の変更点があります:

クロスリファレンス roles

以下の semantic roles は以前はインラインコマンドで、 code としてフォーマットする以外には何もしませんでした。今は、既知のターゲットに対してクロスリファレンスになります。 (あと、いくつかの名前は短くなっています):

mod (previously refmodule or module)

func (previously function)

data (new)

const

class

meth (previously method)

attr (previously member)

exc (previously exception)

cdata

cfunc (previously cfunction)

cmacro (previously csimplemacro)

ctype

func と meth の扱いにも違いがあります: 以前は丸括弧を呼び出し可能オブジェクト名の後ろに (\func{str()} のように) 書きましたが、ビルドシステムが丸括弧をつけるようになりました。　– ソースファイルに丸括弧を書くと、出力では二重に括弧がついてしまいます。 :func:`str(object)` も期待通りになりません。代わりに ``str(object)`` を使ってください!

インラインコマンドはディレクティブとして実装されました

LaTeX にはインラインコマンドがありましたが、 reST ではディレクティブになりました:

deprecated

versionadded

versionchanged

次のようにして使います:

.. deprecated:: 2.5
   Reason of deprecation.

同じく、 versionadded と versionchanged のテキストにはピリオドがつきません。 versionchanged.

note

warning

これらは次のように使います:

.. note::

   Content of note.

その他の変更されたコマンド

以前の samp コマンドは、 code フォーマットでクォーテーションマークで囲まれていました。 samp role では、 file と同じくコードハイライトの機能が新しく追加されました:

:samp:`open({filename}, {mode})` results in open(filename, mode)

無くなったコマンド

次の LaTeX にあったコマンドは、現在 role では対応していません:

bfcode

character (use ``'c'``)

citetitle (use `Title <URL>`_)

code (use ``code``)

email (just write the address in body text)

filenq

filevar (use the {...} highlighting feature of file)

programopt, longprogramopt (use option)

ulink (use `Title <URL>`_)

url (just write the URL in body text)

var (use *var*)

infinity, plusminus (use the Unicode character)

shortversion, version (use the |version| and |release| substitutions)

emph, strong (use the reST markup)

バックスラッシュによるエスケープ

reSTでは、バックスラッシュは通常のテキストや role の中ではエスケープしないといけません。しかし、 code リテラルやリテラルブロックではエスケープしてはいけません。例えば: :file:`C:\\Temp\\my.tmp` vs. ``open("C:\Temp\my.tmp")``.

5.2. 情報単位 (information units)

情報単位(information units) (latexでは ...desc という環境) は reST ディレクティブで作ります。説明しておかないといけない情報単位に関する変更点は:

新しい名前すべての名前から “desc” が無くなりました。新しい名前は:

cfunction (以前は cfuncdesc)

cmacro (以前は csimplemacrodesc)

exception (以前は excdesc)

function (以前は funcdesc)

attribute (以前は memberdesc)

classdesc と excclassdesc 環境は無くなりました。代わりに、 class と exception ディレクティブがコンストラクタの引数あり・なしでクラスのドキュメントをサポートします。

複数のオブジェクト ...line というコマンドと等価なのは:

.. function:: do_foo(bar)
              do_bar(baz)

   Description of the functions.

言い換えると、同じインデントレベルに複数のシグネチャを一行ずつ書くだけです。

引数

optional コマンドはありません。単純に関数のシグネチャを出力で表示されるのと同じ形で書いてください。

.. function:: open(filename[, mode[, buffering]])

   Description.

注意: シグネチャの中ではマークアップはサポートされません。

Indexing

...descni 環境は無くなりました。情報単位をインデックスエントリに含めないようにするには、 noindex オプションを次のように利用してください:

.. function:: foo_*
   :noindex:

   Description.

新しい情報単位

新しい汎用情報単位があります。一つは “describe” と呼ばれ、他の情報単位の対象にならない単位に使うことができます:

.. describe:: a == b

   The equals operator.

他には次のような単位があります:

.. cmdoption:: -O

   Describes a command-line option.

.. envvar:: PYTHONINSPECT

   Describes an environment variable.

5.3. 構造 (Structure)

LaTeX ドキュメントはいくつかのトップレベルマニュアルに分割されていました。今は、すべてのファイルは toctree ディレクティブで指定される一つのドキュメントツリーの一部です。 (各出力フォーマットでまたファイルを分割することもできます) すべての toctree ディレクティブは他のファイルを現在のファイルのサブドキュメントとして埋め込みます。 (この構造をファイルシステムレイアウトに反映させる必要はありません) トップレベルのファイルは contents.rst です。

しかし、今までのディレクトリ構造の大部分は、次のように名前を変更されながら残っています:

api -> c-api

dist -> distutils, with the single TeX file split up

doc -> documenting

ext -> extending

inst -> installing

lib -> library

mac -> merged into library, with mac/using.tex moved to using/mac.rst

ref -> reference

tut -> tutorial, with the single TeX file split up

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

6. ドキュメントをビルドする

ドキュメントをビルドするために使われるツールセットは Python で書かれているので、 Python 2.4 以上をインストールしておく必要があります。このツールセットは Sphinx と呼ばれていて、 Python ソースコードツリーには含まれておらず、別に管理されています。他にも、 Sphinx が利用しているマークアップの基礎を提供している docutils と、テンプレートエンジンの Jinja, オプションでコードハイライトをしたい場合は Pygments が必要です。

6.1. make を使う方法

Makefile が用意されているので、 Python と Subversion がインストールされている Unix 環境では、シンプルに次のコマンドを実行するだけです。

make html

このコマンドは必要なツールセットを tools/ サブディレクトリ配下にチェックアウトし、　HTML 形式の出力ファイルをビルドします。出力された HTML ファイルを見るには、 “make” が完了してから、お好きなブラウザでトップページになる build/html/index.html ファイルを開いてください。

利用できる make の target は次のとおりです。

“make update” を実行すると、 tools/ 以下の Subversion チェックアウトを更新します。

6.2. make を使わない方法

Sphinx パッケージを、 PyPI からインストールするか、次のコマンドでチェックアウトしてください。

svn co http://svn.python.org/projects/external/Sphinx-0.6.5/sphinx tools/sphinx

次に、 docutils を、 http://docutils.sf.net/ からインストールするか、次のコマンドでチェックアウトしてください。

svn co http://svn.python.org/projects/external/docutils-0.6/docutils tools/docutils

Jinja2 も必要です。 PyPI からインストールするか、次のコマンドでチェックアウトしてください。

svn co http://svn.python.org/projects/external/Jinja-2.3.1/jinja2 tools/jinja2

任意で、 Pygments をインストールすることもできます。 PyPI の http://pypi.python.org/pypi/Pygments からインストールするか、次のコマンドでチェックアウトしてください。

svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments

出力ディレクトリ (例では build/ とします) を作成し、次のコマンドを実行します。

python tools/sphinx-build.py -b<builder> . build/<出力ディレクトリ>

<builder> は、 html, text, latex, htmlhelp のどれかです。 (説明は上にある make の target を参照してください)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python のドキュメントの作成 »

7. このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる “Documenting Python” の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

8. 翻訳者一覧 (敬称略)

INADA Naoki <inada-n at klab.jp>

Arihiro TAKASE <hinaclegear at gmail.com>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO

Python HOWTO は、それぞれが単独の話題を取り扱って自己完結した文書群です。Linux Documentation Project の HOWTO 書庫をモデルに、 Python ライブラリリファレンスよりも詳細な文書を作っていこうという努力の成果なのです。

今のところ揃っている HOWTO はこちらです:

Python の支援活動 HOWTO

3.0 への拡張モジュール移植

Python で Curses プログラミング

ディスクリプタ HowTo ガイド

Python 良い慣用句、悪い慣用句

関数型プログラミング HOWTO

ロギング HOWTO

ロギングクックブック

正規表現 HOWTO

ソケットプログラミング HOWTO

ソート HOW TO

Unicode HOWTO

urllib2 を使ってインターネット上のリソースを取得するには

Python を Web 上で使うには HOWTO

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

Python の支援活動 HOWTO

Author: | A.M. Kuchling
Release: | 0.03

概要

一般的に、あなたの上司にオープンソースのソフトウェアの利用の許可をもらうことは難しく、 Python でも例外ではありません。この文書は、なぜ Python を使うのか、利用の許可をもらう戦略、利用できる事実や議題、そして Python を使おうとする べきではない 場合について議論します。

Python を使う理由

あなたの開発プロセスにスクリプト言語を組み込む理由はいくつかあります。そして、なぜ Python がとりわけ良い選択となるのかについて議論します。

書きやすさ

プログラムはしばしば機能を組み合わせるように作成されます。下位レベルの命令はグループ化され、そして上位レベルの関数から呼ばれます。そしてその関数はさらに上位レベルの関数にとって基本的な命令として利用されます。

たとえば、ハッシュテーブルにアクセスするような非常に下位のレベルの関数セットは最下位レベルで定義されます。次のレベルではメールのヘッダ情報を保持する用途や、メールのヘッダ情報のうち date のような属性を Tue, 13 May 1997 20:00:54 -0400 のような値にマッピングする用途に利用されます。メッセージオブジェクトに対するさらに上位レベルの操作では、ハッシュテーブルに保存されたメッセージのヘッダが含まれていること自体を知らずに処理しています。さらに上位のレベルも然りです。

よく、下位レベルでは単純なことをします。二分木やハッシュテーブルのデータ構造の実装や、文字列データを数値に変換するといった単純な処理です。そのため上位のレベルでは、それらの基本的な処理を組み合わせて利用します。この方法においては、これら基本的な処理は組立式の基本部品のように扱えます。そして、完成品を生み出すために組み立てて利用されるのです。

なぜこの設計手法がPythonのと関係するのでしょうか。それは、Pythonが糊言語として最適だからです。Pythonモジュールを書く際によくやる方法として、命令を低水準言語で実装することです。実行速度のため、CやJava、Fortranのでさえもその候補としてあり得ます。それら基本的な処理が Pythonのプログラムから利用可能になってからは、基本的な上位レベルの命令はPythonコードの形で書かれています。そのため上位レベルのロジックは理解しやすく、また編集しやすいものとなっています。

ジョン・オースタウトはタイトル：”スクリプティング：21世紀の高水準プログラミング言語”という論文を書き、非常に長きにわたってこのアイデアを説明しています。この論文を読むことをおすすめします。 URLは参考文献に記載しています。オースタウトはTclの言語の発明者で、論文の議題はTclでのためであることには違いありません;かれはPython,Perl,Lisp/Schemeなど他の言語については軽く触れただけですが、実際のところオースタウトの議論は、先に述べた一般的などのスクリプト言語向けに誰でも拡張機能を作成できることから、どのスクリプト言語に対しても適用できます。

プロトタイプ

人月の神話 でフリードリッヒ・ブロックスは、次のことを提言しています： “捨てるつもりで作りなさい。どうせそうなるのだから”。つまりブロックスは、ソフトウェアの最初の設計は間違いであることが多いと言っています。プログラムがとても単純か、もしくはあなたがとても優秀な設計者でない限りは、開発が実際に進むにつれて新たな要件や機能が明確になってくることに気づくでしょう。もしそれらの新しい要件をプログラムの設計にきれいに組み込めなければ、うれしくない二つの選択を迫られます：何とかして新しい機能をプログラムに叩き込むか、最初から作り直して組み込むかの二択です。

Pythonは、迅速な初期のプロトタイプ開発のために良い環境を提供してくれます。その環境よってプログラム全体の構造と処理の流れの正しさがわかり、また、Pythonが提供する高速な開発サイクルを通して細部を微調整することができます。いったんGUIインタフェースやプログラムの出力に満足すれば、 C++、Fortran、Javaといったコンパイルを伴う言語にPythonを書き直せばよいのです。

プロトタイピングでは、多くのPythonの機能を使用しすぎないように注意する必要があります。でないと他の言語で書き直す作業が困難になります。たとえば eval() 、正規表現、 pickle モジュール、これらを使用すると、式の評価、正規表現、直列化のためにCやJavaライブラリが必要になります。しかし、これら巧妙なコードを避けることは難しいことではありません。その上、最後に書き直す場合も通常はそんなに困難な作業にはなりません。また書き直したコードは迅速なデバッグが可能です。なぜならプロトタイプの段階で重大なエラーはあらかじめ取り除かれており、あったとしても書き直しの際に取り込まれた軽微な不具合くらいだからです。

この戦略は、前述の書きやすさに関する議論に基づいています。これらのことから下位レベルの処理を接続するための糊言語としてPythonを利用しプロトタイプを構築ことの妥当性は明らかです。このようにPythonは開発の助けになります。エンドユーザーがPythonコードで実装された機能に触れることがなくともです。利用するPythonのバージョンが処理速度の面で妥当で、かつ企業の規定が許すならば、 CやJavaへの書き直し作業が必要がない場合があります。そうでなくても、すぐに最終出力用の言語で書き始めるよりは、プロトタイプを作成してから書き直す場合のほうがまだ早くできます。

この開発戦略の一例に、Microsoft Merchant Serverがあります。バージョン1.0は純粋な Python で書かれています。リリース後にMicrosoftによって会社ごと買収されました。バージョン2.0では、いくらかのコードが C++ に書き直されはじめました。結果、 C++ のコードといくつかの Python コードでリリースされました。バージョン3.0ではまったく Python を含んでいませんでした。すべてのコードは C++ に変換されたのです。製品に Python インタプリタがまったく含まれていないにもかかわらず、 Python は開発のスピードアップする目的で有用な役割を果たしています。

これはPythonにとって非常に一般的な使い方です。過去に開かれたカンファレンスで発表された論文でもハイレベルな数値計算アルゴリズムを開発するためのアプローチとして説明されています。デビッド.M.ビーズリーとピーター.S.ロムダヒさんの論文”Pythonで実現する大規模物理計算アプリケーション”に良い例がありますので参照してください。

もし、あるアルゴリズムにおける基本的な操作が、”この4000x4000行列の逆行列を出力する”ようなものである場合、またその処理がいずれかの低水準言語で実装されている時、Pythonによるその他の処理のコストはほとんどかかりません。 m.invert（） のような行を処理する場合に、Pythonを利用するがために必要になる余分な処理コストは非常に小さいです。特に、正しい処理結果を得るために途方もない微調整が必要なアプリケーションにとって良い特徴です。 GUIのインタフェースやWebサイトが主な例です。

（あなたがPythonに精通していれば)Pythonのコードは短く、速く書けます。そのため、あなたのアプローチが間違っていたと判断した場合、気兼ねなくそれを捨てることができます。もしあなたが費やした時間がわずか2時間ではなく二週間だったら、その2週間を無駄に過ごしたと認めたくない気持ちから、何とかして作ったものを取り繕おうとさらに無駄な時間を費やすでしょう。正確に言えば、それらの二週間は無駄になった訳ではありません。あなたは問題を解決するために何かを学んだはずですが、人間の本質としてそれはある種の失敗として考えてしまいます。

シンプルさと理解のしやすさ

Pythonは小さなタスクにのみ使用可能なおもちゃ言語では断じて*ない*です。 Pythonは汎用的であり、たくさんの異なった目的に使用できるほど十分強力です。 10行から20行程度の小さなものから、何千行もの大規模システムにスケールアップされたものにまでも有用です。

しかも、この表現力はあいまいさや巧妙さを要求するような言語の構文によるものではありません。 Pythonはあいまいなコードにつながる記述を許す部分はあるものの、それは比較的少数であって、適切な設計によってその使用を少数のクラスやモジュールに分離することができます。たくさんの機能を、明解さを考慮せずに利用すれば、もちろん多くの誤解を生むコードになってしまいます。

しかし、ほとんどのPythonのコードは人間が理解可能なように書式化された擬似コードように見えます。

エリック.S.レイモンドは、 The New Hacker’s Dictionary で、 “コンパクト” について次のように定義しました:

コンパクト (形): 設計におけるコンパクトとは、人が一度に理解できるという重要な性質を指している。一般的に、コンパクトな設計で作られた物は、コンパクトでない設計で作られた同等のものよりも、より大きなプロジェクトに利用でき、不具合をより少なく抑えられることを意味する。コンパクトさとは単に単純な構造であるとか、力の欠如を意味するものではありません。例えば、C言語はコンパクトでありFORTRANはそうではありませんが、CはFORTRANより強力です。機能の増大や、全体設計にきれいに統合されていない雑な機能は、設計をコンパクトでなくします。（そのため、古い C 言語の一部のファンは、 ANSI C がコンパクトではないと主張しています)

(http://www.catb.org/~esr/jargon/html/C/compact.html より)

Pythonはこの意味で、非常にコンパクトです。なぜならPythonはすこしのアイデアだけを元に設計されており、それが多くの場面で使用されているためです。名前空間を例に見てみましょう。 import math 文では、 math という新しい名前空間を作成します。一方、クラス自体も多くのプロパティを共有する名前空間です。クラスにはモジュールや自分自身のクラスも含まれます。たとえば、クラスからはインスタンスを作成できます。インスタンス・・・？実はこれらもまた別の名前空間なのです。名前空間は、現在のところ Pythonの辞書として実装されているため、標準の辞書型と同じメソッドを持っています。 .keys（）はすべてのキーを返します。他の辞書型のメソッドも同様です。

このシンプルさは、Pythonの開発の歴史的なものから来ています。Pythonの構文はさまざまなソースから派生しています。比較的無名の教育用言語ABCや、 Modula-3から主な影響を受けています。（ABCやModula-3の詳細についてはそれぞれのWebサイトを参照してください。　<http://www.cwi.nl/~steven/abc/> , <http://www.m3.org> その他の機能は、C言語、Icon、Algol-68、そしてPerlを参考にしています。 Pythonは本来革新な言語ではありません。その替わりに、小さく学習しやすいものに維持しようとしてきました。また、他の言語で試され有用だと認められたさまざまなアイデアをもとに設計されました。

シンプルさは美徳であり過小評価すべきではありません。シンプルであればよりすばやく学ぶことができ、そしてその後すぐにコードを記述し始められます。多くの場合、最初に書いたコードがきちんと動作します。

Javaでの実装

あなたがJavaを使用している場合は、Jython（http://www.jython.org/）に注意を払うことは確実に有用です。 JythonはJavaでのPythonの再実装で、PythonコードをJavaのバイトコードにコンパイルしてくれます。結果として得られる環境は非常にしっくりきており、 Javaとほぼシームレスに統合しています。PythonからJavaクラスにアクセスするのはとても簡単で、 JavaクラスのサブクラスとしてPythonのクラスを書くことができます。 JythonはCPythonとほぼ同じ方法でJavaアプリケーションのプロトタイプ作成に使用できます。またJythonは、Javaコードのテストスイートの用途にも使えます。また、 Javaアプリケーションにスクリプト機能を埋め込むこともできます。

議論と反論

あなたのアプリケーション用にはPythonが最良の選択だと決定したとしましょう。 Pythonを利用することをあなたの管理者、または仲間の開発者をどのように説得しましょうか。この節では、Pythonを使うことに対していくつかの一般的な議論と反論を示します。

Pythonは無料で自由に利用できるソフトウェアです。どれほど良いことでしょうか。

非常に良いはずです。最近ではLinuxやApache、二つのオープンソースソフトウエアが商用ソフトウェアの代替品として支持されるようになってきています。しかし、Pythonはまだ公な支持は得られていません。

Pythonは数年前から出回っており、多くのユーザと開発者に支持されてきました。結果的に、Pythonは多くの人々によって使用されて、ほとんどのバグがふるい落とされてきました。バグはまだ一定の間隔で報告されていますが、ほとんどは本当に目立たないもの（いままで誰も実行する必要がない、もしくは実行したことがないようなもの）か、外部ライブラリへのインタフェースに起因するものです。言語自体の内部は非常に安定しています。

Pythonでは、ピアレビューを実施しながらソフトウエアを作るためにソースコードを閲覧可能にしています。だれでもコードを調べたり、改善を提案(実装を含む）し、バグを追跡することができます。オープンソースコードの考え方についての詳細を調べるには <http://www.opensource.org>をご覧ください。オープンソースに関連した議論と、ケーススタディなどがあります。

だれがPythonをサポートするのか？

Pythonには、かなり多くの開発者のコミュニティがあり、数はまだ増え続けています。 Pythonに関するインターネット上のコミュニティは活動的です。これは、Pythonを利用する上での別の利点の一つと考えられています。comp.lang.pythonのニュースグループに投稿されたほとんどの質問はメンバのうち誰かによって素早く返答されます。

あなたがソースコードを読み進める必要がある場合、明解でうまく組み立てられたものであることが分かるでしょう。そのためあなた自身の手で拡張機能を記述してバグ追跡するのは難しいことではありません。 Pythonの金銭的なサポートしている企業や個人もいます。

誰がPythonを大々的に利用していますか？

Pythonの興味深い点は、多くの人が驚くべき多様なアプリケーションに利用していることです。 Pythonは以下のアプリケーションに利用されています:

Webサイトを運用する

GUIインターフェースを書く

スーパーコンピュータ上で複雑な計算をコントロールする

Pythonインタプリタを埋め込むことによって、商用アプリケーションでスクリプティングを可能にする

大規模なXMLデータセットを処理する

CまたはJavaのコードに対するテストスイートを構築する

あなたのアプリケーションドメインが何であれ、きっと誰かが同じようにPythonを使っているはずです。しかし、そのようなハイエンドなアプリケーションに使用可能であるにもかかわらず、小さなタスクに使用できるほどに簡単です。

その他の組織的なPythonの使用例については <http://wiki.python.org/moin/OrganizationsUsingPython> を参照してください。

Pythonの使用に関しての制限は何ですか？

制限は事実上存在しません。 Misc/COPYRIGHT ソースの配布、または History and License 言語全体の節を参照してください。しかし結局のところ下記の三つの条件に要約できます：

作成したソフトウェアに著作権表示を残す必要があります。もし製品にPythonのソースコードが含まれていない場合、説明書に著作権表示を入れる必要があります。

あなたの製品はPythonを開発している機関から支持されていると主張しないでください。あらゆる方法においてです。

何か問題が発生した場合でも、損害賠償訴訟を起こすことはできません。実質的にすべてのソフトウェアライセンスは、この条件が含まれています。

ただし、Pythonを含んだり、ともにビルドされるソースコードすべてを公開する必要がないことに注意してください。また、Pythonインタプリタとそれに付随するドキュメントは、好きな方法で変更を加えたり再配布することができます。誰かにライセンス料誰を支払う必要はありません。

なぜ我々は、明解な言語Xの替わりに不明瞭なPythonを使用する必要がありますか？

私はこのHOWTOと、最後の節に記載されている資料が、 Pythonは不明瞭ではなく、また健やかに成長しているユーザー基盤を持っていることを納得させる助けになることを願います。アドバイス：常にPythonの肯定的な利点を提示するのではなく、言語Xの欠点にも注目してください。人々はなぜ他のすべての解決策が悪いのかの理由よりもむしろ、なぜその解決策が良いのかを知りたがります。そのため様々な理由で競合する解決策を攻撃するよりかは、単にどのようにPythonが解決できるかを示すほうが良いです。

有用な資料

http://www.pythonology.com/success

「Pythonサクセスストーリー」は、Pythonの利用に成功したユーザーのからの成功例のコレクションです。ビジネスと企業ユーザーを重視したものになっています。

http://www.tcl.tk/doc/scripting.html

ジョン・オースタウトはスクリプト言語の有用性について議論しています。自然な流れとしてスクリプト言語としては彼が開発したTclを取り上げています。しかし、議論のほとんどは、その他のスクリプト言語に適用できます。

http://www.python.org/workshops/1997-10/proceedings/beazley.html

作者のデイビット.M.ビーズリーとピーター.S.ラムダヒは、ロスアラモス国立研究所でのPythonの利用について述べています。これは、Pythonは実際の作業に役立つことができる良い例となっています。下記の論文からの引用文は多くの人々によって繰り返し引用されています：

もともとは超並列処理システムのための大規模なモノリシックアプリケーションとして開発として開発を始めました。私たちはアプリケーションをより柔軟、再利用可能、そしてより強力なもの、そしてシミュレーション、データ解析、可視化ができるものに進化させるためにPythonを使用してきました。

加えて、Pythonは開発に関連する重要ないくつもの問題を解決してきました。それは、学術ソフトウエアの、デバッグ、導入、そしてメンテナンスを含みます。

http://pythonjournal.cognizor.com/pyj1/Everitt-Feit_interview98-V1.html アンディ・フェイトとのインタビューです。infoseekでのPythonの利用に関する議論では、 Pythonを選択すると、社内での開発プロセスに大して余計な問題を持ち込まないことを示していおり、さらにいくつかの重要な利点を提供できることを示しています。

http://www.python.org/workshops/1997-10/proceedings/stein.ps 第6回目のPythonカンファレンスでグレッグ・ステイン氏は、 Microsoftで、Pythonを利用したeShopと呼ばれるサイトの立ち上げとのその後について 追跡した論文を発表しました。

http://www.opensource.org 管理者は、有料でないソフトウェアの信頼性と有用性について疑問の念を持っているかもしれません。このサイトでは、オープンソースソフトのほうがクローズソースソフトと比較してかなりの利点を持つことについての議論を提示しています。

http://www.faqs.org/docs/Linux-mini/Advocacy.html Linuxでの支援活動 mini-HOWTOは、この文書の着想であり読んでおく価値があります。 LinuxやPythonのような、新しい技術を管理者に受け入れてもらうことについて、一般的な推奨事項について記載されています。一般的に、これは多くの場合、負け犬の遠吠えを言っているだけのように見られてしまいます。そうではなく、Pythonは他の多くの分野のシステムの改良版であるという点を指摘するほうがよいでしょう。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

3.0 への拡張モジュール移植

author:
Benjamin Peterson

概要

C-API の変更は Python 3.0 の目標には入っていませんでしたが、Python レベルでの変更がたくさんあったので、2.x の API を無傷で済ませることはできませんでした。実際、 int() と long() の統合などは C レベルのほうが目立ちます。この文書では、なくなった互換性と、その対処方法について記述しようと思います。

条件コンパイル

一部のコードを 3.0 にだけコンパイルするための一番簡単な方法は、 PY_MAJOR_VERSION が 3 以上かどうかチェックすることです。

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#endif

存在しなくなった関数については、条件ブロックの中で同等品にエイリアスすれば良いでしょう。

オブジェクト API の変更

Python 3.0 では、似た機能を持つタイプのいくつかを、統合したり、きっちり分けたりしました。

str/unicode の統合

Python 3.0 の str() (C では PyString_* 関数) タイプは 2.x の unicode() (PyUnicode_*) と同じものです。昔の 8 ビット文字列タイプは bytes() です。Python 2.6 以降には互換性ヘッダ bytesobject.h が用意されており、 PyBytes 系の名前を PyString 系にマップしています。 3.0 との互換性を最大限確保するには、 PyUnicode は文字データに、 PyBytes はバイナリデータにだけ使うべきです。ほかにも、3.0 の PyBytes と PyUnicode は 2.x の PyString と PyUnicode とは違って交換不可能だということも重要です。以下の例では PyUnicode, PyString, PyBytes に関するベストプラクティスを見ることができます。

#include "stdlib.h"
#include "Python.h"
#include "bytesobject.h"

/* text example */
static PyObject *
say_hello(PyObject *self, PyObject *args) {
    PyObject *name, *result;

    if (!PyArg_ParseTuple(args, "U:say_hello", &name))
        return NULL;

    result = PyUnicode_FromFormat("Hello, %S!", name);
    return result;
}

/* just a forward */
static char * do_encode(PyObject *);

/* bytes example */
static PyObject *
encode_object(PyObject *self, PyObject *args) {
    char *encoded;
    PyObject *result, *myobj;

    if (!PyArg_ParseTuple(args, "O:encode_object", &myobj))
        return NULL;

    encoded = do_encode(myobj);
    if (encoded == NULL)
        return NULL;
    result = PyBytes_FromString(encoded);
    free(encoded);
    return result;
}

long/int の統合

Python 3.0 では整数タイプが一つしかありません。これは Python レベルでは int() と呼ばれますが、実際には 2.x の long() タイプと同じものです。C-API では PyInt_* 関数群の中身が、お隣さんの PyLong_* に交換されています。ここでとるべき最良の行動指針は、 intobject.h で PyLong_* にエイリアスされている PyInt_* を使うというものです。ある場合には抽象 API 群 PyNumber_* も使えるかもしれません。

#include "Python.h"
#include "intobject.h"

static PyObject *
add_ints(PyObject *self, PyObject *args) {
    int one, two;
    PyObject *result;

    if (!PyArg_ParseTuple(args, "ii:add_ints", &one, &two))
        return NULL;

    return PyInt_FromLong(one + two);
}

モジュールの初期化と状態情報

Python 3.0 には、改良された拡張モジュール初期化システムがあります ( PEP 3121 [http://www.python.org/dev/peps/pep-3121] 参照)。モジュールの状態はグローバル変数に持つのではなく、インタプリタ固有の構造体に持つべきだということになったのです。2.x と 3.0 のどちらでも動くモジュールを作るのにはコツが要ります。次の簡単な例で、その方法を実演してみます。

#include "Python.h"

struct module_state {
    PyObject *error;
};

#if PY_MAJOR_VERSION >= 3
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
#else
#define GETSTATE(m) (&_state)
static struct module_state _state;
#endif

static PyObject *
error_out(PyObject *m) {
    struct module_state *st = GETSTATE(m);
    PyErr_SetString(st->error, "something bad happened");
    return NULL;
}

static PyMethodDef myextension_methods[] = {
    {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
    {NULL, NULL}
};

#if PY_MAJOR_VERSION >= 3

static int myextension_traverse(PyObject *m, visitproc visit, void *arg) {
    Py_VISIT(GETSTATE(m)->error);
    return 0;
}

static int myextension_clear(PyObject *m) {
    Py_CLEAR(GETSTATE(m)->error);
    return 0;
}

static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "myextension",
        NULL,
        sizeof(struct module_state),
        myextension_methods,
        NULL,
        myextension_traverse,
        myextension_clear,
        NULL
};

#define INITERROR return NULL

PyObject *
PyInit_myextension(void)

#else
#define INITERROR return

void
initmyextension(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
    PyObject *module = PyModule_Create(&moduledef);
#else
    PyObject *module = Py_InitModule("myextension", myextension_methods);
#endif

    if (module == NULL)
        INITERROR;
    struct module_state *st = GETSTATE(module);

    st->error = PyErr_NewException("myextension.Error", NULL, NULL);
    if (st->error == NULL) {
        Py_DECREF(module);
        INITERROR;
    }

#if PY_MAJOR_VERSION >= 3
    return module;
#endif
}

ほかの選択肢

新規に拡張モジュールを書こうと思っているのであれば、 Cython [http://www.cython.org] を検討してみても良いでしょう。これは Python 風の言語を C に翻訳してくれるもので、出力される拡張モジュールは Python 3.x と 2.x に両方対応しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

Python で Curses プログラミング

Author: | A.M. Kuchling, Eric S. Raymond
Release: | 2.03

概要

このドキュメントでは Python 2.x でテキストモードプログラムを表示をコントロールする curses 拡張モジュールを利用して書く方法について記述します。

curses ってなに?

curses ライブラリは、テキストベースの端末、VT100s や Linux コンソールや xterm や rxvt などの X11 プログラムから提供される端末エミュレータなどの端末に依存せずに、スクリーンに描画やキーボード処理する機能を供給します。表示端末は様々な制御コードをサポートしていて、カーソル移動、画面のスクロール、領域の消去などの一般的な操作を実行できます。端末によって大きく異なるコードを使うことがあるので、しばしば独自の癖があります。

X ディスプレイの世界では、「どうしてこんな面倒なことを?」と疑問に思うかもしれません。確かに文字表示端末は時代遅れな技術ではありますが、ニッチな領域が存在していて、意匠を凝らすことができるため、未だ価値あるものとなっています。その領域は例えば X サーバを持たない、小さな机上用コンピュータや組み込みの Unix です。他のものとしては OS インストーラーやカーネル設定ツールなどで、これらは X が利用できるようになる前に動作する必要があります。

curses ライブラリは異なる端末の詳細を全て隠蔽し、プログラマに対して、重なり合わない複数のウィンドウを持つ抽象化されたディスプレイを提供します。ウィンドウの内容は様々な方法で変更されます – テキストの追加、消去、外観の変更 – そして curses ライブラリは送るべき制御コードを自動的に理解し、正しい出力を生成してくれます。

curses ライブラリは元々 BSD UNIX 向けに書かれました; 後の AT&T から出た Unix System V バージョンで多くの機能と新機能が追加されました。 BSD curses はいまやメンテナンスされておらず、これは AT&T インターフェースのオープンソース実装である ncurses にとって置き換えられました。 Linux や FreeBSD のようなオープンソース Unix を利用している場合は、おそらくシステムは ncurses を利用しています。現在のほとんどの商用 Unix は System V のコードを基にしているため、ここれ述べる全ての関数が利用できるはずです。しかし、古いバージョンの curses を持ついくつかのプロプライエタリ Unix は全てには対応していないでしょう。

curses モジュールの Windows 移植は作られていません。 Windows プラットフォーム上では、Fredrik Lundh が書いた Console モジュールを試してみてください。 Console モジュールはカーソル位置を指定してテキスト出力することができ、マウス、キーボード入力の両方を完全にサポートしていて、 http://effbot.org/zone/console-index.htm から入手できます。

Python の curses module

Python モジュールは curses が提供する C 関数に対するまったく単純なラッパーです; 既に C での curses プログラミングに慣れ親しんでいるなら、その知識を Python に持ち込むのは実に簡単です。最大の違いは Python インターフェースが異なる関数 addstr(), mvaddstr(), mvwaddstr() を一つのメソッド addstr() メソッドに統合して単純化していることです。このことは後でより詳しく扱います。

この HOWTO は curses と Python を使ってテキストプログラムを書くための簡単な入門記事です。 curses API に対する完全な解説をすることは意図していません; その目的のためには Python ライブラリガイドの ncurses 節と ncurses の C 言語マニュアルページを参照してください。しかし、この文章が基本的な考えを提供してくれるでしょう。

curses アプリケーションの起動と終了

何をするにもまず、curses を初期化する必要があります。初期化は initscr() 関数を呼びだすことでできます、この関数は端末のタイプを決定し、必要とされるセットアップコードを端末に送り、様々な内部データ構造を作成します。成功すると、 initscr() は画面全体を表わすウィンドウオブジェクトを返します; これは、 stdscr と呼ばれます、この名前は C での対応する変数にちなんでいます。:

import curses
stdscr = curses.initscr()

通常 curses アプリケーションは画面へのキーエコーを自動的に止めます、これはキーを読みとり特定状況下でのみで表示するためです。これには noecho() 関数を呼び出す必要があります。:

curses.noecho()

通常アプリケーションはまた、Enter キーを押すことなく、キーに対してすぐに反応する必要があります; これは cbreak モードと呼ばれ、通常の入力がバッファされるモードと逆に動作します。:

curses.cbreak()

端末は通常、カーソルキーや Page Up や Home といった操作キーなどの特別なキーをマルチバイトエスケープシーケンスとして返します。それらのシーケンスを想定して対応する処理を行うアプリケーションを書けるように、 curses はそれを curses.KEY_LEFT のような特別な値を返して行ってくれます。 curses にその仕事をさせるには、キーパッドモードを有効にする必要があります。:

stdscr.keypad(1)

curses アプリケーションを終了させるのは起動よりも簡単です。 curses に親和的な端末設定を元に戻すために以下を呼び出す必要があります:

curses.nocbreak(); stdscr.keypad(0); curses.echo()

そして、 endwin() 関数を呼び出し、端末設定を通常の操作モードに復旧します。:

curses.endwin()

curses アプリケーションをデバッグするときの一般的な問題は、アプリケーションが端末を以前の状態に復旧することなく異常終了したときに端末がめちゃめちゃになることです。 Python ではこの問題はコードにバグがあって、捕捉できない例外が発生したときによく起きます。タイプしたキーはもはやエコーされません、例えば、シェルを使うのが難しくなります。

Python では curses.wrapper をインポートすることでこの複雑な問題を避け、デバッグを容易にすることができます。それは 呼び出し可能オブジェクトを引数にとることができる wrapper() 関数を提供します。これは上に述べた初期化をし、カラーサポートがあればカラーの初期化をします。そして、与えられた呼び出し可能オブジェクトを実行し、最終的に適切に初期化の逆操作 (deinitialization) を行います。呼び出し可能オブジェクトは例外を捕捉する try-catch 節内部で呼び出され、 curses の初期化操作の逆操作を実行します、そして例外が上に渡されます。そうして端末は例外が発生しても端末はおかしな状態にならずにすみます。

ウィンドウとパッド

ウィンドウは curses での基本的な抽象概念です。ウィンドウオブジェクトは画面の長方形の領域を表わし、テキストの表示、消去、ユーザに文字列入力を許可などの様々なメソッドをサポートしています。

initscr() 関数によって返される stdscr オブジェクトはウィンドウオブジェクトで画面全体を扱います。多くのプログラムはこのウィンドウだけを必要としますが、画面を小さなウィンドウに分けてそれらを別々に再描画したり消去したいと思うかもしれません。 newwin() 関数は新しいウィンドウを与えられたサイズで作成し、新しいウィンドウオブジェクトを返します。:

begin_x = 20 ; begin_y = 7
height = 5 ; width = 40
win = curses.newwin(height, width, begin_y, begin_x)

curses で利用されている座標形について、言っておくことがあります: 座標は常に y,x の順で渡し、ウィンドウの左上の座標を (0,0) とします。これは x 座標が最初にくる一般的な慣習には反しています。これは多くの計算機のアプリケーションにとって不幸な違いですが、 curses が最初に書かれて以来そうだったので、今から変えるには遅すぎます。

メソッドを呼びだして、テキストを表示、消去するとき、その効果はディスプレイにすぐには現われません。それは curses が元々 300 ボーの端末接続を念頭にいれていたためですl それらの端末では画面の再描画時間を減らすことがとても重要です。このため curses は画面への変更を積み上げ、最も効率良い方法でそれらを表示します。例えば、プログラムがウィンドウにいくつかの文字を表示し、それからウィンドウを消去する場合、元々の文字を送信する必要はありません、それらはもう見られることはないのです。

従って curses に明示的にウィンドウの再描画を明示的に伝えてやる必要があります、それはウィンドウオブジェクトのメソッド refresh() を使うことでできます。実際には、これは curses を使ったプログラムをそれほど複雑にするものではありません。ほとんどのプログラムはせわしなく動いた後キーを押すなどのユーザからの動作を待ちます。あなたがするべきことはユーザからの入力を待つ前に単に stdscr.refresh() や関連するウィンドウの refresh() メソッドを呼び出して画面を再描画するだけです。

パッドはウィンドウの特別な場合を指します; それは実際に画面に表示されるものより大きくなることがあり、画面にはその一部だけが表示されます。パッドを作るのに必要なものはパッドの高さと幅だけです、一方でパッドの再描画には、表示される部分を指す画面上の領域の座標を指定する必要があります。:

pad = curses.newpad(100, 100)
#  These loops fill the pad with letters; this is
# explained in the next section
for y in range(0, 100):
    for x in range(0, 100):
        try: pad.addch(y,x, ord('a') + (x*x+y*y) % 26 )
        except curses.error: pass

#  Displays a section of the pad in the middle of the screen
pad.refresh( 0,0, 5,5, 20,75)

refresh() はパッドの一部、画面上の座標 (5,5) から (20,75) に及ぶ長方形領域を表示します; 表示される一部の左上の角は パッドの座標 (0,0) です。この違いを除けば、パッドは通常のウィンドウと全く同じで、同じメソッドを持ちます。

複数のウィンドウとパッドが画面上にある場合、より効率的な方法があり、再描画時に画面をちらつかせるのを防いでくれます。各ウィンドウの noutrefresh() メソッドを利用して、画面の望ましい状態を表わすデータ構造をアップデートし、 doupdate() 関数で望む状態に合った物理的な画面に変更します。通常の refresh() メソッドは自身の動作時の最後に doupdate() を呼び出します。

テキストの表示

C 言語のプログラマの視点からすると、curses はしばしば、混乱を招きやすい、微妙に似た関数を持っています。例えば addstr() は stdscr ウィンドウの現在のカーソル位置の文字列を表示し、一方で mvaddstr() は与えられた y,x 座標にまず移動して、文字列を表示します。 waddstr() はほとんど addstr() に似ていますが、デフォルトの stdscr を使う代わりに使うウィンドウを指定できます。 mvwaddstr() も同様です。

幸運にも、Python インターフェースはこれらの詳細を全て隠蔽してくれます; stdscr は他のものと同様のウィンドウオブジェクトであり、 addstr() のようなメソッドは複数の引数形式を許容してくれます。通常それらは4つの形式です。

形式 | 説明
str または ch | 文字列 str または 文字 ch を現在位置に表示します
str または ch, attr | 文字列 str または 文字 ch を属性 attr を利用して現在位置に表示します
y, x, str または ch | ウィンドウ内の位置 y,x に移動し str または ch を表示します
y, x, str または ch, attr | ウィンドウ内の位置 y,x に移動し属性 attr を利用して str または ch を表示します

属性によって表示するテキストをハイライトすることができます、ボールド体、アンダーライン、反転、カラーなど。より詳しくは次の小節で説明します。

addstr() 関数は Python 文字列を引数にとり、表示します。一方 addch() 関数は文字を引数にとります、引数は長さ1の文字列か整数のどちらでもかまいません。文字列の場合には、表示する文字は 0 から 255 の間に制限されます。 SVr4 curses は文字拡張のための定数を提供しています; それらの定数は 255 より大きい整数です。例えば ACS_PLMINUS は +/- 記号で ACS_ULCORNER はボックスの左上角です (境界を描くのに便利です)。

ウィンドウは最後の操作の後のカーソル位置を覚えているため、 y,x 座標をうっかり忘れてしまっても、文字列や文字は最後の操作位置に表示されます。 move(y,x) メソッドでカーソルを移動させることもできます。常に点滅するカーソルを表示する端末もあるため、カーソルが特定の位置にいることを保証して注意が反れないようにしたいと思うかもしれません; ランダムに見える位置でカーソルがちらつくとと面を食らってしまいます。

アプリケーションがちらつくカーソルを全く必要としない場合、 curs_set(0) を呼び出してカーソル見えなくすることができます。同じことを、古い curses バージョンに対する互換性を保ちつつ行うために leaveok(bool) 関数があります。 bool が true の場合、curses ライブラリは点滅するカーソルを外に出さなくするので、変な場所に現われるのを心配する必要は無くなります。

属性とカラー

文字は様々な方法で表示することができます。テキストベースアプリケーションでのステータスラインは通常反転して表示されます; テキストビュアーは特定の単語をハイライトする必要があるかもしれせん。 curses は属性を画面上の各セルに対して指定することで、それをサポートします。

属性は整数値で、それぞれのビットが異なる属性を表わします。複数の属性ビットをセットしてテキストの表示を試みることができますが、 curses は全ての組み合わせが利用可能であるかや視覚的に区別できるかどうかは保証してくれません、それらは利用している端末の能力に依存しているため、最も安全なのは、最も一般的に利用可能な属性を設定する方法です、ここに列挙します

属性 | 説明
A_BLINK | テキストを点滅
A_BOLD | 高輝度またはボールドテキスト
A_DIM | 低輝度テキスト
A_REVERSE | 反転テキスト
A_STANDOUT | 利用できる最良のハイライトモード
A_UNDERLINE | 下線付きテキスト

つまり、反転するステータスラインを画面の最上部に表示するには、コードをこうします:

stdscr.addstr(0, 0, "Current mode: Typing mode",
         curses.A_REVERSE)
stdscr.refresh()

curses ライブラリはカラー機能を提供している端末でのカラーもサポートしています、そんな端末の中で最も一般的なものは Linux コンソールで、color xterm もそれに続きます。

カラーを利用するには、 initscr() を呼び出したすぐ後に start_color() 関数を呼びし、デフォルトカラーセットを初期化しなければいけません (curses.wrapper.wrapper() 関数はこれを自動的に行ないます)。一旦それを行えば、 has_colors() 関数は、端末が実際にカラーを表示できる場合に TRUE を返します。 (ノート: curses はカナダ/イギリスつづりに ‘colour’ ではなくアメリカつづりの ‘color’ を使います。イギリスつづりを使っている場合には、これらの関数のミススペルを修正する必要があります。)

curses ライブラリは有限の数の、フォラグラウンド(またはテキスト)カラーとバックグラウンドカラーペアを保持します。カラーペアに対応する属性値は color_pair() 関数で取得できます; これは A_REVERSE のような他の属性と OR 論理演算組み合わせることができます、ただし、繰り返しになりますが、組み合わせは全ての端末で保証されていません。

例として、テキスト行をカラーペア 1 を使って表示します:

stdscr.addstr( "Pretty text", curses.color_pair(1) )
stdscr.refresh()

前に述べたように、カラーペアはフォアグラウンドカラーとバックグラウンドカラーから構成されています。 start_color() はカラーモードを有効にした場合 8 の基本カラーを初期化します。基本カラーは: 0:black, 1:red, 2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, 7:white です。 curses モジュールは各名前に対する名前付き定数を定義しています: curses.COLOR_BLACK, curses.COLOR_RED, など。

init_pair(n, f, b) 関数はカラーペア n の定義をフォアグラウンド f バックグラウンド b に変更します。カラーペア 0 は黒背景に白で組み込まれていて変更できません。

やってみましょう。カラー 1 を白背景に赤に変更してみましょう、こうして呼び出します:

curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)

カラーペアを変更するときには、既に表示された任意のテキストが利用するカラーペアを新しい色に変更します。新しいテキストをこの色で使うこともできます:

stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1) )

凝ったターミナルは実際の色の定義を与えられた RGB 値に変更することができます。これによってふつうは赤であるカラー1を紫や青など好きな色に変更されます。不幸にも Linux コンソールはこれをサポートしていません、そのためこの機能は試すことも例を出すこともできません。 can_change_color() を呼び出すことで端末が使えるのか調べることができ、対応していれば、TRUE を返します。もしそのような telnet 端末を持つ幸運に巡りあえたなら、より多くの情報の情報を得るためにシステムの man ページを参照することを勧めます。

ユーザ入力

curses ライブラリは自身で単純なインプット機構を備えています。 Python はテキスト入力ウィジェットを追加して、いくつかの足りない部分を補っています。

ウィンドウに対する入力を得るための最も一般的な方法はウィンドウの getch() メソッドを利用することです。 getch() はユーザが待機してキーを打つのを待ち、 echo() が先に呼ばれていれば、それを表示します。オプションとして待機する前にカーソルが移動するべき座標を指定することができます。

この挙動は nodelay() メソッドで変更することができます。 nodelay(1) の後、 ウィンドウに対する getch() はノンブロッキングになり、入力が準備されていないときには curses.ERR (-1 の値) を返します。 halfdelay() 関数もあり、(事実上) 各 getch() に対してタイマーを設定するのに使うことができます; 指定したディレイの間に(10分の1秒単位で測られます)入力が得られなかった場合 curses は例外を送出します。

getch() メソッドは整数を返します; もしそれが 0 から 255 までなら、それは押されたキーの ASCII コードを表わします。 255 より大きな値は Page Up, Home またはカーソルキーのような特別なキーです。返された値を curses.KEY_PPAGE, curses.KEY_HOME または curses.KEY_LEFT のような定数と比較することが可能です。通常プログラムのメインループはこのようになります:

while 1:
    c = stdscr.getch()
    if c == ord('p'): PrintDocument()
    elif c == ord('q'): break  # Exit the while()
    elif c == curses.KEY_HOME: x = y = 0

curses.ascii モジュールは ASCII クラスのメンバーシップ関数を提供し、整数と1文字引数のどちらもとることができます; これらは独自のコマンドインタプリタに対するより読み易いテストを書くのに便利でしょう。整数と1文字引数のどちらもとることができ、引数と同じ型を返す変換関数も提供します。例えば curses.ascii.ctrl() は引数に応じた型で制御文字を返します。

文字列全体を取得するメソッド getstr() もあります。これは頻繁に使われるものではありません、なぜならこの機能はとても制限的なものだからです; 利用可能な編集キーはバックスペースと Enter キーの文字列を終了させるものだけです。オプションとして文字列の長さを固定長に限定することもできます。:

curses.echo()            # Enable echoing of characters

# Get a 15-character string, with the cursor on the top line
s = stdscr.getstr(0,0, 15)

Python の curses.textpad モジュールはよりよいものを提供します。これを使うことで、ウィンドウ をEmacs のようなキーバインドをサポートするテキストボックスにすることができます。 Textbox クラスの様々なメソッドが入力の検証つきの編集をサポートシ前後のスペースつき、または無しで編集結果を収集します。詳しくは curses.textpad のライブラリドキュメントを参照して下さい。

より多くの情報

この HOWTO ではいくつかの進んだ話題、スクリーンスクレイピングや xterm インスタンスからマウスイベントを捉えるなど、については扱っていません。しかし、Python の curses モジュールのライブラリページはいまやかなり充実しています。次はこれを見るべきです。

ncurses のあらゆるエントリポイントの詳細な挙動について疑問があれば、 curses 実装が ncurses か、プロプライエタリな Unix ベンダーのものかによらず curses 実装のマニュアルページをみることを参照して下さい。マニュアルページにはあらゆる癖がドキュメントにされていて、全ての関数、属性、 ACS_* 文字の完全なリストが提供されています。

curses API は巨大なので、Python インターフェースではいくつかの関数はサポートされていません、ですがそれは必要としている人がいまのところいないためです。気兼ねなく、足りないものを追加してパッチを提出して下さい。また、ncurese に関連したメニューやパネルライブラリのサポートも行なわれていません; 気兼ねなく追加して下さい。

面白い小さなプログラムを書いたら、新たなデモとして気兼ねなく提出して下さい。私達は常により多くのデモ使うことができます!

The ncurses FAQ: http://invisible-island.net/ncurses/ncurses.faq.html

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

ディスクリプタ HowTo ガイド

Author: | Raymond Hettinger
Contact: | <python at rcn dot com>

Contents

ディスクリプタ HowTo ガイド

概要

定義と導入

ディスクリプタプロトコル

ディスクリプタの呼び出し

ディスクリプタの例

プロパティ

関数とメソッド

静的メソッドとクラスメソッド

概要

ディスクリプタを定義し、プロトコルを要約し、ディスクリプタがどのように呼び出されるか示します。カスタムのディスクリプタや、関数、プロパティ、静的メソッド、クラスメソッドを含む、いくつかの組み込み Python ディスクリプタを考察します。等価な pure Python やサンプルアプリケーションを与えることにより、それぞれがどのように働くかを示します。

ディスクリプタについて、大きなツールセットが使えるようにするだけでなく、 Python の仕組みや、洗練された設計のアプリケーションについて、深い理解を生み出します。

定義と導入

一般に、ディスクリプタは “束縛動作 (binding behavior)” をもつオブジェクト属性で、その属性アクセスが、ディスクリプタプロトコルのメソッドによってオーバーライドされたものです。このメソッドは、 __get__(), __set__(), および __delete__() です。これらのメソッドのいずれかが、オブジェクトに定義されていれば、それはディスクリプタと呼ばれます。

属性アクセスのデフォルトの振る舞いは、オブジェクトの辞書の属性の取得、設定、削除です。例えば a.x は、まず a.__dict__['x'] 、それから type(a).__dict__['x'] 、さらに type(a) のメタクラスを除く基底クラスへと続くというように探索が連鎖します。見つかった値が、ディスクリプタメソッドのいずれかを定義しているオブジェクトなら、 Python はそのデフォルトの振る舞いをオーバーライドし、代わりにディスクリプタメソッドを呼び出します。これがどの連鎖順位で行われるかは、どのディスクリプタメソッドが定義されているかに依ります。なお、ディスクリプタは、新スタイルのオブジェクトまたはクラスにのみ呼び出されます (あるクラスは、それが object または type を継承していれば、新スタイルです)。

ディスクリプタは、強力な、多目的のプロトコルです。これはプロパティ、メソッド、静的メソッド、クラスメソッド、そして super() の背後にある機構です。これはバージョン 2.2 で導入された新スタイルクラスを実装するために、Python のいたるところで使わています。ディスクリプタは、基幹にある C コードを簡潔にし、毎日の Python プログラムに、柔軟な新しいツール群を提供します。

ディスクリプタプロトコル

descr.__get__(self, obj, type=None) --> value

descr.__set__(self, obj, value) --> None

descr.__delete__(self, obj) --> None

これで全てです。これらのメソッドのいずれかを定義すれば、オブジェクトはディスクリプタとみなされ、探索された際のデフォルトの振る舞いをオーバーライドできます。

あるオブジェクトが __get__() と __set__() の両方を定義していたら、それはデータディスクリプタとみなされます。 __get__() だけを定義しているディスクリプタは、非データディスクリプタと呼ばれます (これらは典型的にはメソッドに使われますが、他の使い方も出来ます)。

データディスクリプタと非データディスクリプタでは、オーバーライドがインスタンスの辞書のエントリに関してどのように計算されるかが異なります。インスタンスの辞書に、データディスクリプタと同名の項目があれば、データディスクリプタの方が優先されます。インスタンスの辞書に、非データディスクリプタと同名の項目があれば、辞書の項目の方が優先されます。

読み込み専用のデータディスクリプタを作るには、 __get__() と __set__() の両方を定義し、 __set__() が呼び出されたときに AttributeError が送出されるようにしてください。例外を送出する __set__() メソッドをプレースホルダとして定義すれば、データディスクリプタにするのに十分です。

ディスクリプタの呼び出し

ディスクリプタは、メソッド名で直接呼ぶことも出来ます。例えば、 d.__get__(obj) です。

または、一般的に、ディスクリプタは属性アクセスから自動的に呼び出されます。例えば、 obj.d は obj の辞書から d を探索します。 d がメソッド __get__() を定義していたら、以下に列挙する優先順位に従って、 d.__get__(obj) が呼び出されます。

呼び出しの詳細は、 obj がオブジェクトかクラスかに依ります。どちらにしても、ディスクリプタは新スタイルのオブジェクトやクラスにのみ働きます。クラスは、それが object のサブクラスであるなら新スタイルです。

オブジェクトでは、その機構は b.x を type(b).__dict__['x'].__get__(b, type(b)) に変換する object.__getattribute__() にあります。データディスクリプタの優先度はインスタンス変数より高く、インスタンス変数の優先度は非データディスクリプタより高く、(提供されていれば) __getattr__() の優先度が最も低いように実装されています。完全な C 実装は、 Objects/object.c [http://svn.python.org/view/python/trunk/Objects/object.c?view=markup] の PyObject_GenericGetAttr() で見つかります。

クラスでは、その機構は B.x を B.__dict__['x'].__get__(None, B) に変換する type.__getattribute__() にあります。 pure Python では、このようになります:

def __getattribute__(self, key):
    "Emulate type_getattro() in Objects/typeobject.c"
    v = object.__getattribute__(self, key)
    if hasattr(v, '__get__'):
       return v.__get__(None, self)
    return v

憶えておくべき重要な点は:

ディスクリプタは __getattribute__() メソッドに呼び出される

__getattribute__() をオーバーライドすると、自動的なディスクリプタの呼び出しが防がれる。

__getattribute__() は新スタイルのクラスとオブジェクトにのみ使える。

object.__getattribute__() と type.__getattribute__() では、 __get__() の呼び出しが異なる。

データディスクリプタは、必ずインスタンス辞書をオーバーライドする。

非データディスクリプタは、インスタンス辞書にオーバーライドされることがある。

super() によって返されたオブジェクトもまた、ディスクリプタの呼び出しにカスタムの __getattribute__() メソッドを持ちます。 super(B, obj).m() の呼び出しは、 obj.__class__.__mro__ の中から、 B の直接の基底クラス A を探し、 A.__dict__['m'].__get__(obj, A) を返します。ディスクリプタでなければ、 m はそのまま返されます。辞書になければ、 m は object.__getattribute__() を使って、さかのぼって探索されます。

なお、Python 2.2 では、 m がデータディスクリプタなら、 super(B, obj).m() は __get__() を呼び出すだけです。 Python 2.3 では、旧スタイルクラスが呼び出されなければ、非データディスクリプタも呼び出されます。実装の詳細は、 Objects/typeobject.c [http://svn.python.org/view/python/trunk/Objects/typeobject.c?view=markup] の super_getattro() と、 Guido’s Tutorial [http://www.python.org/2.2.3/descrintro.html#cooperation] にある等価な pure Python を参照してください。

上述の詳細は、ディスクリプタの機構が、 __getattribute__() メソッドに埋めこまれ、 object, type, そして super() に使われているということを表しています。クラスは、 object から導出されたとき、または、同じような機能を提供するメタクラスをもつとき、この機構を継承します。同様に、 __getattribute__() をオーバーライドすることで、ディスクリプタの呼び出しを無効にできます。

ディスクリプタの例

以下のコードは、オブジェクトが取得と設定のたびにメッセージを表示するデータディスクリプタであるようなクラスを生成します。代わりに __getattribute__() をオーバーライドすると、全ての属性に対してこれができます。しかし、このディスクリプタは、少数の選ばれた属性を監視するのに便利です:

class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating' , self.name
        self.val = val

>>> class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5

このプロトコルは単純ですが、ワクワクする可能性も秘めています。ユースケースの中には、あまりに一般的なので個別の関数の呼び出しにまとめられたものもあります。プロパティ、束縛および非束縛のメソッド、静的メソッド、そしてクラスメソッドは、全てディスクリプタプロトコルに基づいています。

プロパティ

property() を呼び出すことで、属性へアクセスすると関数の呼び出しを引き起こす、データディスクリプタを簡潔に組み立てられます。シグネチャはこうです:

property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

このドキュメントでは、管理された属性 x を定義する典型的な使用法を示します:

class C(object):
    def getx(self): return self.__x
    def setx(self, value): self.__x = value
    def delx(self): del self.__x
    x = property(getx, setx, delx, "I'm the 'x' property.")

ディスクリプタの見地から property() がどのように実装されているかを見るために、等価な Python をここに挙げます:

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError, "unreadable attribute"
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError, "can't set attribute"
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError, "can't delete attribute"
        self.fdel(obj)

組み込みの property() 関数は、ユーザインタフェースへの属性アクセスが与えられ、続く変更がメソッドの介入を要求するときに役立ちます。

例えば、スプレッドシートクラスが、 Cell('b10').value でセルの値を取得できるとします。続く改良により、プログラムがアクセスの度にセルの再計算をすることを要求しました。しかしプログラマは、その属性に直接アクセスする既存のクライアントコードに影響を与えたくありません。この解決策は、property データディスクリプタ内に値属性へのアクセスをラップすることです:

class Cell(object):
    . . .
    def getvalue(self, obj):
        "Recalculate cell before returning value"
        self.recalc()
        return obj._value
    value = property(getvalue)

関数とメソッド

Python のオブジェクト指向機能は、関数に基づく環境の上に構築されています。非データディスクリプタを使って、この 2 つはシームレスに組み合わされています。

クラス辞書は、メソッドを関数として保存します。クラス定義内で、メソッドは、関数を使うのに便利なツール、 def や lambda を使って書かれます。標準の関数との唯一の違いは、第一引数がオブジェクトインスタンスのために予約されていることです。 Python の慣習では、このインスタンスの参照は self と呼ばれますが、 this その他の好きな変数名で呼び出せます。

メソッドの呼び出しをサポートするために、関数の __get__() メソッドは属性アクセス時にメソッドを束縛します。これにより、すべての関数は、それが呼び出されたのがオブジェクトかクラスかによって、束縛か非束縛メソッドを返す非データディスクリプタになります。pure Python では、これはこのようにはたらきます:

class Function(object):
    . . .
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        return types.MethodType(self, obj, objtype)

インタプリタを起動すると、この関数ディスクリプタが実際にどうはたらくかを見られます:

>>> class D(object):
     def f(self, x):
          return x

>>> d = D()
>>> D.__dict__['f'] # 関数として内部に保存されている
<function f at 0x00C45070>
>>> D.f             # クラスから取得すると非束縛メソッドになる
<unbound method D.f>
>>> d.f             # クラスから取得すると束縛メソッドになる
<bound method D.f of <__main__.D object at 0x00B18C90>>

この出力が暗示するのは、束縛メソッドと非束縛メソッドは 2 つの異なる型であるということです。これらは、異なる型として実装することも出来ますが、 Objects/classobject.c [http://svn.python.org/view/python/trunk/Objects/classobject.c?view=markup] における PyMethod_Type の実際の C 実装は、 im_self が NULL (None と等価な C) に設定されているかに依って 2 つの異なる表現を持つ、 1 つのオブジェクトです。

同様に、メソッドオブジェクトを呼び出すことの効果も、 im_self フィールドに依ります。設定されていれば (束縛を意味し)、期待通り (im_func フィールドに保存されている) 元の関数が、第一引数をインスタンスとして、呼び出されます。非束縛なら、すべての引数がそのまま元の関数に渡されます。 instancemethod_call() の実際の C 実装は、型チェックがあるため、もう少しだけ複雑です。

静的メソッドとクラスメソッド

非データディスクリプタは、関数をメソッドに束縛する、各種の一般的なパターンに、単純な機構を提供します。

まとめると、関数は __get__() メソッドを持ち、属性としてアクセスされたとき、メソッドに変換されます。この非データディスクリプタは、 obj.f(*args) の呼び出しを f(obj, *args) に変換します。 klass.f(*args) を呼び出すと f(*args) になります。

このチャートは、束縛と、その 2 つの異なる便利な形をまとめています:

変換 | オブジェクトから呼び出される | クラスから呼び出される
関数 | f(obj, *args) | f(*args)
静的メソッド | f(*args) | f(*args)
クラスメソッド | f(type(obj), *args) | f(klass, *args)

静的メソッドは、下にある関数をそのまま返します。 c.f や C.f は、 object.__getattribute__(c, "f") や object.__getattribute__(C, "f") を直接探索するのと同じです。結果として、関数はオブジェクトとクラスから同じようにアクセスできます。

静的メソッドにすると良いのは、 self 変数への参照を持たないメソッドです。

例えば、統計パッケージに、実験データのコンテナがあるとします。そのクラスは、平均、メジアン、その他の、データに依る記述統計を計算する標準メソッドを提供します。しかし、概念上は関係があっても、データには依らないような便利な関数もあります。例えば、 erf(x) は統計上の便利な変換ルーチンですが、特定のデータセットに直接には依存しません。これは、オブジェクトからでもクラスからでも呼び出せます: s.erf(1.5) --> .9332 または Sample.erf(1.5) --> .9332 。

静的メソッドは下にある関数をそのまま返すので、呼び出しの例は面白くありません:

>>> class E(object):
     def f(x):
          print x
     f = staticmethod(f)

>>> print E.f(3)
3
>>> print E().f(3)
3

非データディスクリプタプロトコルを使うと、pure Python 版の staticmethod() は以下のようになります:

class StaticMethod(object):
 "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

 def __init__(self, f):
      self.f = f

 def __get__(self, obj, objtype=None):
      return self.f

静的メソッドとは違って、クラスメソッドは関数を呼び出す前にクラス参照を引数リストの先頭に加えます。このフォーマットは、呼び出し元がオブジェクトでもクラスでも同じです:

>>> class E(object):
     def f(klass, x):
          return klass.__name__, x
     f = classmethod(f)

>>> print E.f(3)
('E', 3)
>>> print E().f(3)
('E', 3)

この振る舞いは、関数がクラス参照のみを必要とし、下にあるデータを考慮しないときに便利です。クラスメソッドの使い方の一つは、代わりのクラスコンストラクタを作ることです。Python 2.3 では、クラスメソッド dict.fromkeys() は新しい辞書をキーのリストから生成します。等価な pure Python は:

class Dict:
    . . .
    def fromkeys(klass, iterable, value=None):
        "Emulate dict_fromkeys() in Objects/dictobject.c"
        d = klass()
        for key in iterable:
            d[key] = value
        return d
    fromkeys = classmethod(fromkeys)

これで一意なキーを持つ新しい辞書が以下のように構成できます:

>>> Dict.fromkeys('abracadabra')
{'a': None, 'r': None, 'b': None, 'c': None, 'd': None}

非データディスクリプタプロトコルを使った、 classmethod() の pure Python 版はこのようになります:

class ClassMethod(object):
     "Emulate PyClassMethod_Type() in Objects/funcobject.c"

     def __init__(self, f):
          self.f = f

     def __get__(self, obj, klass=None):
          if klass is None:
               klass = type(obj)
          def newfunc(*args):
               return self.f(klass, *args)
          return newfunc

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

Python 良い慣用句、悪い慣用句

Author:
Moshe Zadka

This document is placed in the public domain. (この文書はパブリックドメインです。)

概要

この文書はチュートリアルのおまけと考えてもらって結構です。 Python をどう使うべきか、そして更に重要なこととして、どう使うべきで ない かを例示しています。

使うべきでない構文

Python の落とし穴は他言語と比べればほとんどないようなものですが、中には特殊な場面でしか役に立たなかったり、単に危険なだけの構文も存在しています。

from モジュール import *

関数定義の中で

関数定義内での from モジュール import * は 不正 です。多くの古い Python では不正としてチェックされないものの、だからと言って有効になるわけではありません。やり手の弁護士を雇って無罪になっても、潔白になれるわけではないのと同じですね。ですから絶対にそういう使い方をしないでください。不正にされないバージョンでも、コンパイラはどの名前がローカルでどの名前がグローバルなのか判然としなくなるので、関数の実行が遅くなってしまいます。Python 2.1 で、この構文は警告や、場合によってはエラーも出すようになりました。

モジュールレベルで

モジュールレベルで from モジュール import * を使うのは有効ではありますが、大抵は、やめたほうが良いですよ。理由のひとつとして、それをやると本来 Python が持っている大事な特徴を失ってしまうということが挙げられます。その特徴とは、トップレベルの名前がそれぞれどこで定義されているのか、エディタの検索機能だけでわかるというものです。それに、将来モジュールに関数やクラスが増えていくと、ややこしいことになりかねません。

ニュースグループで出てくる最低の質問には、なぜこのコード:

f = open("www")
f.read()

が動かないのか、というものがあります。もちろんこれで動きますよ (ただし “www” というファイルがあれば)。でもモジュールのどこかに from os import * があればダメです。 os モジュールは、整数を返す open() 関数を持っているのです。これはとても便利ではありますが、ビルトインを隠してしまうのは、非常に不便な特徴のひとつと言えます。

モジュールがエクスポートする名前は確実にはわからないのですから、必要なものだけ from モジュール import 名前1, 名前2 で取るか、モジュールから出さずに import モジュール;print モジュール.name としておいて必要に応じてアクセスするようにしましょう。

問題ない状況

from モジュール import * が問題とならない状況もあります:

対話的プロンプト。たとえば from math import * すれば Python がスーパー関数電卓に変身します。

C のモジュールを Python のモジュールで拡張するとき。

そのモジュールは from import * 可だ、と作者が言っているとき。

そのまんまな exec, execfile() と仲間たち

「そのまんま」という言葉は辞書を明示せずに使うという意味で、そういう構文ではコードが その時点の 環境に対して評価されます。これは from import * と同じ理由で危険です — 使っている最中の変数を土足で踏んで行って、コード全体をメチャクチャにしてしまう可能性があるからです。これは、とにかくやめてください。

悪い見本:

>>> for name in sys.argv[1:]:
>>>     exec "%s=1" % name
>>> def func(s, **kw):
>>>     for var, val in kw.items():
>>>         exec "s.%s=val" % var  # ダメ!
>>> execfile("handler.py")
>>> handle()

良い見本:

>>> d = {}
>>> for name in sys.argv[1:]:
>>>     d[name] = 1
>>> def func(s, **kw):
>>>     for var, val in kw.items():
>>>         setattr(s, var, val)
>>> d={}
>>> execfile("handle.py", d, d)
>>> handle = d['handle']
>>> handle()

from モジュール import 名前1, 名前2

今回のは、これまでの「ダメ」よりかなり弱い「ダメ」ですが、やはりそれなりの理由がなければ、やめておいたほうが良いことに変わりありません。これが大抵うまくないのは、いつの間にか二つ別々の名前空間に住む一つのオブジェクトを持つことになるからです。一方の名前空間でそのバインディングが変更されたとき、もう一方のバインディングは変更されないので、食い違いができてしまいます。これが起こるのは、たとえば、モジュールを読み直したり、ランタイムで関数の定義を変更したときなどです。

悪い見本:

# foo.py
a = 1

# bar.py
from foo import a
if something():
    a = 2 # 危険: foo.a != a

良い見本:

# foo.py
a = 1

# bar.py
import foo
if something():
    foo.a = 2

except:

Python には except: 節があり、これはあらゆる例外を捕捉します。 Python のエラーは すべて 例外を出しますから、 except: を使うと各種のプログラミングエラーがランタイムの問題のように見えてしまい、デバッグの邪魔になります。

以下のコードは、 except: をなぜ避けるべきなのかを示す良い例です:

try:
    foo = opne("file") # "open" を打ち間違えた
except:
    sys.exit("could not open file!")

この 2 行目は NameError を引き起こし、続く except 節で捕捉されます。プログラムがエラー終了しますが、実際のエラーが "file" とは何の関係もないのに、にプログラムが表示するエラーメッセージは "file" の読み込みにあったように誤解させます。

前述の例はこう書くべきでした:

try:
    foo = opne("file")
except IOError:
    sys.exit("could not open file")

このプログラムを実行した場合は、 Python は NameError のトレースバックを表示し、修正すべき問題を即座に明らかにしてくれます。

except: は 全て の例外を補足します。これには SystemExit, KeyboardInterrupt, GeneratorExit (これはエラーではなく、通常はユーザーコードでキャッチするべきではない例外です) も含まれるので、ほとんど全ての場合に except: を利用してはいけません。 “通常の” すべてのエラーをキャッチする必要がある場合、たとえばコールバックを実行するようなフレームワークの場合は、全ての通常の例外の基底クラスである Exception をキャッチすることができます。不幸なことに、 Python 2.x ではサードパーティのコードが Exception を継承していない例外を発生させる可能性があるので、 except: を使ってキャッチしたくない例外を手動で再度 raise する必要がある場合があるかもしれません。

例外

例外は Python の有用な機能です。何か期待している以外のことが起これば例外を出す、という習慣を持つべきですが、それと同時に、何か対処できるときにだけ捕捉する、ということも習慣にしてください。

以下は非常にありがちな悪い見本です:

def get_status(file):
    if not os.path.exists(file):
        print "file not found"
        sys.exit(1)
    return open(file).readline()

ここで、 os.path.exists() を呼んでから open() を呼ぶまでの間にファイルが消された場合を考えてください。そうなれば最後の行は IOError を投げるでしょう。同じことは、 file は存在しているけれど読み出し権限がなかった、という場合にも起こります。これをテストする際、ふつうのマシンで、存在するファイルと存在しないファイルに対してだけやったのではバグがないように見えてしまい、テスト結果が大丈夫そうなのでコードはそのまま出荷されてしまうことになります。こうして、対処されない IOError (またはその他の EnvironmentError)はユーザの所まで逃げのびて、汚いトレースバックを見せることになるのです。

もっと良い方法はこちら:

def get_status(file):
    try:
        return open(file).readline()
    except EnvironmentError as err:
        print "Unable to open file: {}".format(err)
        sys.exit(1)

このバージョンでは、ファイルが開かれて一行目も読まれる (だから、あてにならない NFS や SMB 接続でも動く) か、あるいはファイルを開くのに失敗した理由についての全ての情報を含むエラーメッセージを表示してアプリケーションを強制終了するかのいずれか 一方しか起こりません。

とはいえ、このバージョンの get_status() でさえ、前提としている条件が多過ぎます — すぐ終わるスクリプトでだけ使って、長く動作させる、いわゆるサーバでは使わない前提なのです。もちろん呼び出し側はこうすることもできます:

try:
    status = get_status(log)
except SystemExit:
    status = None

でも、もっと良い方法があります。コードで使う except 節を、できるだけ少なくするのです — 使うとすれば、必ず成功するはずの呼び出し内か、main 関数での全捕捉ですね。

というわけで、たぶんもっと良い get_status() はこちら:

def get_status(file):
    return open(file).readline()

呼び出した側は、望むなら例外を処理することもできますし (たとえばループで複数ファイルに試行するときとか)、そのまま 自分の 呼び出し親まで上げることもできます。

しかし、この最終バージョンにも深刻な問題があります — CPython 実装の細部に原因があるのですが、例外が起きたときにはその例外ハンドラが終了するまでファイルが閉じられないのです; しかも、なお悪いことに、他の実装 (たとえば Jython) では例外の有無に関わらず閉じられません。

この関数の一番良いバージョンでは open() をコンテクストマネジャとして使って、関数が返るとすぐにファイルが閉じられるようにしています:

def get_status(file):
    with open(file) as fp:
        return fp.readline()

使い捨てじゃなくて充電池を使う

どうも皆、Python ライブラリに最初からあるものを自分で書こうとして、大抵うまくいっていないようです。そういう場当たりなモジュールには貧弱なインタフェースしかないことを考えると、ふつうは Python に付いてくる高機能な標準ライブラリとデータ型を使うほうが、自分でひねり出すより格段に良いですよ。

便利なのにほとんど知られていないモジュールに os.path があります。このモジュールには OS に合ったパス演算が備わっていて、大抵は自分でどれだけ苦労して作ったものよりもずっと良いものです。

比べてください:

# うげえ!
return dir+"/"+file
# 改良版
return os.path.join(dir, file)

os.path にはさらに便利な関数が他にもあります: basename() や dirname(), splitext() などです。

加えて、なぜか気付かれていない多くのビルトイン関数があります: たとえば min() と max() を使えば、大小比較のできるシーケンスなら何からでも最小値/最大値を見つけることができるのに、多くの人々が自家製の max()/min() を書いています。また別の超便利な関数として、シーケンスに対して2項演算を繰り返し適用して最終的に1つの値にまとめる reduce() です。例えば、階乗を乗算の繰り返しで計算します:

>>> n = 4
>>> import operator
>>> reduce(operator.mul, range(1, n+1))
24

数値の字句解析をするときには、 float(), int(), long() は全て文字列の引数を受け取って、不正なフォーマットの文字列の場合には ValueError を発生させることを覚えておくと便利です。

バックスラッシュで文を続ける

Python は改行を文の終わりとして扱いますので、そして文は一行にうまく収まらないことがよくありますので、こうする人が多いです:

if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \
   calculate_number(10, 20) != forbulate(500, 360):
      pass

これは危険だということに気づいたほうが良いですよ: はぐれスペースが \ の後に来ればその行の意味が変わってしまいますが、スペースはエディタで見えにくいことに定評があるのです。今回の場合は構文エラーにはなりますが、もしこうなら:

value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \
        + calculate_number(10, 20)*forbulate(500, 360)

微妙に違う意味になるだけで、エラーが出ません。

それで、ふつうは括弧に入れて暗黙のうちに行をつなげるほうが賢明です:

このバージョンで鉄壁です:

value = (foo.bar()['first'][0]*baz.quux(1, 2)[5:9]
        + calculate_number(10, 20)*forbulate(500, 360))

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

関数型プログラミング HOWTO

Author: | A. M. Kuchling
Release: | 0.31

この文書では、関数型スタイルでプログラムを実装するのにピッタリな Python の機能を見てまわることにしましょう。まず関数型プログラミングという概念を紹介したあと、 iterator や generator のような言語機能、および itertools や functools といった関連するライブラリモジュールを見ることにします。

はじめに

この章は関数型プログラミングの基本概念を説明します; Python の言語機能についてだけ知りたい人は、次の章まで飛ばしてください。

プログラミング言語とは問題を分解するものですが、各言語がサポートする分解方法にはいくつかの種類があります:

ほとんどのプログラミング言語は 手続き型 です: プログラムは、入力に対して行うべきことをコンピュータに教える指示リストとなります。 C, Pascal, さらには Unix シェルまでもが手続き型言語に入ります。

宣言型 言語で書くのは、解くべき問題を説明する仕様書であって、それを効率的に計算処理する方法を見付けるのは言語実装の役目です。SQL はおそらく一番よく知られた宣言型言語です; SQL のクエリは取得したいデータセットを説明しているだけで、テーブルを走査するかインデックスを使うか、どのサブクローズから実行するか等々を決めるのは SQL エンジンなのです。

オブジェクト指向 プログラムはオブジェクトの集まりを操作します。オブジェクトには内部状態があり、その状態を調べたり色々と変更したりするためのメソッドがあります。Smalltalk や Java はオブジェクト指向言語です。 C++ と Python はオブジェクト指向プログラミングをサポートしていますが、関連する機能を使わなくても構わないようになっています。

関数型 プログラミングは問題をいくつかの関数にわけて考えます。理想的に言うと、関数は入力を受けて出力を吐くだけで、同じ入力に対して異なる出力をするような内部状態を一切持ちません。有名な関数型言語には ML 一家 (Standard ML, OCaml 等々) と Haskell があります。

設計者が特定のアプローチを強調することにした言語もありますが、そうすると大抵は、別のアプローチを使うプログラムを書きにくくなります。複数のアプローチに対応した言語もあり、Lisp, C++, Python はそうしたマルチパラダイム言語です; この中のどれを使っても、基本的に手続き型な、または基本的にオブジェクト指向な、とか、基本的に関数型なプログラムやライブラリを書くことができます。大きなプログラムでは、各部で別々のアプローチを使って書くことがあるかもしれません; GUI はオブジェクト指向で、でも処理ロジックは手続き型や関数型で、といったようにです。

関数型プログラムでは、入力は一連の関数を通って流れていきます。それぞれの関数は入力に何らかの作業をして出力します。関数型スタイルにおいては、内部状態を変えてしまったり、返り値に現れない変更をしたりといった副作用のある関数はやめるように言われています。副作用のまったくない関数は 純粋関数型 であるとされます。副作用をなくすということは、プログラムの実行中に順次変化していくデータ構造を持たない、つまり各関数の出力はその入力にしか影響を受けてはいけないということです。

この純粋性を守る面で非常に厳しい言語もあり、そうした言語には a=3 や c = a + b といった代入文さえありません。しかし副作用を完全になくすのは難しいもので、たとえば画面表示やディスクファイルへの書き込みも副作用なのです。 Python で言うと、たとえば print 文や time.sleep(1) はどちらも意味ある値を返しません; ただ画面にテキストを送ったり動作を 1 秒止めたりといった副作用のためだけに呼ばれるのです。

関数型スタイルで書いた Python プログラムはふつう、I/O や代入を完全になくすといった極端なところまでは行かずに、関数型っぽく見えるインタフェースを提供しつつも内部では非関数型の機能を使います。たとえば、関数内でローカル変数の代入は使いますが、グローバル変数は変更せず、他の副作用もないように実装するのです。

関数型プログラミングはオブジェクト指向プログラミングの反対と考えることもできます。オブジェクト指向において、オブジェクトは内部状態とそれを変更するメソッドコールの入ったカプセルであり、プログラムはその状態を適正に変化させていく手順です。一方で、関数型プログラミングは可能なかぎり状態の変更を避け、関数どうしの間を流れるデータだけを扱おうとします。Python ではこの二つのアプローチを結び合わせることができます。アプリケーション内のオブジェクト (メール、トランザクション、等々) を表現したインスタンスを、関数が受け渡しするようにするのです。

関数型デザインは、わけのわからない制約に見えるかもしれません。どうしてオブジェクトも副作用もないほうが良いのでしょうか。実は、関数型スタイルには理論と実践に基づく次の利点があるのです:

形式的証明可能性

モジュラー性

結合性

デバグやテストの簡単さ

形式的証明可能性

理論面の利点としては、プログラムが正しいことの数学的証明を他より簡単に構築できるという点があります。

研究者たちは長いあいだ、プログラムが正しいことを数学的に証明する方法の発見に血道をあげてきました。これは、色々な入力でテストして出力が正しかったからまあ正しいだろう、と結論するのとも違いますし、ソースコードを読んで「間違いはなさそうだ」と言うのとも別の話です; 目指すのは、出現しうる入力すべてに対してプログラムが正しい結果を出すことの厳密な証明なのです。

プログラムを証明するために使われているのは 不変式 を書き出していくというテクニックで、不変式とは入力データやプログラム変数のうち常に真である性質のことです。コードの一行一行で、 実行前 の不変式 X と Y が真なら実行後に ちょっと違う不変式 X’ と Y’ が真になることを示していき、これをプログラムの終わりまで続けるわけです。すると最終的な不変式はプログラムの出力に合った条件になっているはずです。

関数型プログラミングが代入を嫌うのは、この不変式テクニックでは代入を扱いにくいからです; 代入は、それまで真だった不変式を壊しておいて、自分は次の行に伝えてゆける不変式を生み出さないことがあるのです。

残念ながら、プログラムの証明はだいたい実際的でもありませんし、Python ソフトウェアにも関係ありません。本当に簡単なプログラムでも、証明には数ページにわたる論文が必要なのです; ある程度の複雑なプログラムではもう尋常でない長さになってしまうので、日常で使っているプログラム (Python インタプリタ、XML パーサ、ウェブブラウザ) はほとんど、あるいはすべて、正しさを証明するのは不可能でしょう。仮に証明を書き出したり生成したりしても、その証明を検証するための疑いが残ります; 証明に間違いがあるかもしれず、その場合は証明したと自分で勝手に思い込んでいただけになるのです。

モジュラー性

より実用的には、関数型プログラミングをすると問題を細かく切り分けることになるという利点があります。結果としてプログラムはモジュラー化されます。複雑な変形を施す大きな関数を書くより、一つのことに絞ってそれだけをする小さな関数のほうが書きやすいものです。それに、小さいほうが読むのもエラーをチェックするのも簡単です。

デバグやテストの簡単さ

テストやデバグも関数型プログラムなら簡単です。

関数が一般的に小さくて明確に意味付けされているので、デバグ方法は単純です。プログラムが正しく動かないときには、関数ひとつひとつがデータの正しさをチェックするポイントになるので、それぞれの時点における入力と出力を見ていけば、バグの原因となる関数を素早く切り出すことができるのです。

ひとつひとつの関数がユニットテストの対象になり得るわけですから、テストも簡単です。関数はシステムの状態に依存しませんので、テストの実行前にそうした状態を再現する必要はありません; 単に適切な入力を合成して、出力が期待どおりかどうかチェックするだけで良いのです。

結合性

関数型スタイルのプログラムを作っていると、色々な入力や出力のために色々な関数を書くことになります。仕方なく特定のアプリケーションに特化した関数を書くこともあるでしょうけれど、広範なプログラムに使える関数もあることでしょう。たとえば、ディレクトリ名を受け取ってその中の XML ファイル一覧を返す関数や、ファイル名を受け取って内容を返す関数などは、多様な場面に適用できそうです。

時たつうちに自分の特製ライブラリやユーティリティが充実してくると、新しいプログラムも、既存の関数を調整して少し今回に特化した関数を書くだけで組み立てられるようになります。

イテレータ

まずは関数型スタイルのプログラムを書く際の基礎となる重要な Python 機能から見ていきましょう: イテレータです。

イテレータは連続データを表現するオブジェクトです; このオブジェクトは一度に一つの要素ずつデータを返します。Python のイテレータは next() という、引数を取らず次の要素を返すメソッドを必ずサポートしています。データストリームに要素が残っていない場合、 next() は必ず StopIteration 例外を出します。ただ、イテレータの長さは有限である必要はありません; 無限のストリームを出すイテレータを書くというのもまったく理に適ったことです。

ビルトインの iter() 関数は任意のオブジェクトを受けて、その中身や要素を返すイテレータを返そうとします。引数のオブジェクトがイテレータを作れないときは TypeError を投げます。Python のビルトインなデータ型にもいくつかイテレータ化のできるものがあり、中でもよく使われるのはリストと辞書です。イテレータを作れるオブジェクトは イテラブル オブジェクトと呼ばれます。

手を動かしてイテレータ化の実験をしてみましょう:

>>> L = [1,2,3]
>>> it = iter(L)
>>> print it
<...iterator object at ...>
>>> it.next()
1
>>> it.next()
2
>>> it.next()
3
>>> it.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
StopIteration
>>>

Python は色々な文脈でイテラブルなオブジェクトを期待しますが、最も重要なのは for 文です。 for X in Y という文の Y は、イテレータか、あるいは iter() でイテレータを作れるオブジェクトである必要があります。次の二つは同じ意味になります:

for i in iter(obj):
    print i

for i in obj:
    print i

イテレータは list() や tuple() といったコンストラクタ関数を使ってリストやタプルに具現化することができます:

>>> L = [1,2,3]
>>> iterator = iter(L)
>>> t = tuple(iterator)
>>> t
(1, 2, 3)

シーケンスのアンパックもイテレータに対応しています: イテレータが N 個の要素を返すということが事前にわかっていれば、N-タプルにアンパックすることができます:

>>> L = [1,2,3]
>>> iterator = iter(L)
>>> a,b,c = iterator
>>> a,b,c
(1, 2, 3)

ビルトイン関数の max() や min() なども、イテレータ一つだけを引数に取って最大・最小の要素を返すことができます。 in や not in 演算子もイテレータに対応しています: X in イテレータ は、そのイテレータから返るストリームに X があれば真です。ですからイテレータが無限長だと、当然ながら問題に直面します; max(), min(), not in はいつまでも戻って来ませんし、要素 X がストリームに出てこなければ in オペレータも戻りません。

イテレータは次に進むことしかできませんのでご注意ください; 前の要素を手に入れたり、イテレータをリセットしたり、コピーを作ったりする方法はありません。イテレータがオブジェクトとしてそうした追加機能を持つことはできますが、プロトコルでは next() メソッドのことしか指定されていません。ですから関数はイテレータの出力を使い尽くしてしまうかもしれませんし、同じストリームに何か別のことをする必要があるなら新しいイテレータを作らなくてはいけません。

イテレータ対応のデータ型

リストやタプルがイテレータに対応している方法については既に見ましたが、実のところ Python のシーケンス型はどれでも、たとえば文字列なども、自動でイテレータ生成に対応しています。

辞書に対して iter() すると、辞書のキーでループを回すイテレータが返されます:

>>> m = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
...      'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
>>> for key in m:
...     print key, m[key]
Mar 3
Feb 2
Aug 8
Sep 9
Apr 4
Jun 6
Jul 7
Jan 1
May 5
Nov 11
Dec 12
Oct 10

順番は基本的にランダムであることに注目してください。これは辞書内オブジェクトのハッシュの順番になっているからです。

辞書は iter() を適用するとキーでループを回しますが、辞書には他のイテレータを返すメソッドもあります。明示的にキー、値、あるいはキーと値のペアでイテレートしたければ、 iterkeys(), itervalues(), iteritems() というメソッドでイテレータを作ることができます。

逆に dict() コンストラクタは、有限な (キー, 値) タプルのストリームを返すイテレータを受け入れることができます:

>>> L = [('Italy', 'Rome'), ('France', 'Paris'), ('US', 'Washington DC')]
>>> dict(iter(L))
{'Italy': 'Rome', 'US': 'Washington DC', 'France': 'Paris'}

ファイルも、最後の行まで readline() メソッドを呼んでいくことでイテレータ化に対応しています。つまりこうやってファイルの各行を読んでいくことができるわけです:

for line in file:
    # 一行ごとに何かをする
    ...

セットはイテラブルを受け取れますし、そのセットの要素でイテレートすることもできます:

S = set((2, 3, 5, 7, 11, 13))
for i in S:
    print i

ジェネレータ式とリスト内包表記

イテレータの出力に対してよく使う操作トップ 2 は、(1) ひとつずつ全要素に操作を実行する、および (2) 条件に合う要素でサブセットを作る、です。たとえば文字列のリストなら、各行のうしろに付いた邪魔なホワイトスペースを削りたいとか、特定の文字列を含む部分をピックアップしたいなどと思うかもしれません。

リスト内包表記とジェネレータ式 (略して「listcomp」と「genexp」) は、そうした操作向けの簡潔な表記方法です。これは関数型プログラミング言語 Haskell (http://www.haskell.org) にインスパイアされました。文字列のストリームからホワイトスペースをすべて削るのは次のコードでできます:

line_list = ['  line 1\n', 'line 2  \n', ...]

# ジェネレータ式 -- イテレータを返す
stripped_iter = (line.strip() for line in line_list)

# リスト内包表記 -- リストを返す
stripped_list = [line.strip() for line in line_list]

特定の要素だけを選び出すのは if 条件式を付けることで可能です:

stripped_list = [line.strip() for line in line_list
                 if line != ""]

リスト内包表記を使うと Python リストが返って来ます; stripped_list は実行結果の行が入ったリストであって、イテレータではありません。ジェネレータ式はイテレータを返し、これだと必要に応じてだけ値を算出しますので、すべての値を一度に出す必要がありません。つまりリスト内包表記のほうは、無限長ストリームや膨大なデータを返すようなイテレータを扱う際には、あまり役に立たないということです。そういった状況ではジェネレータ式のほうが好ましいと言えます。

ジェネレータ式は丸括弧 “()” で囲まれ、リスト内包表記は角括弧 “[]” で囲まれます。ジェネレータ式の形式は次のとおりです:

( expression for expr in sequence1
             if condition1
             for expr2 in sequence2
             if condition2
             for expr3 in sequence3 ...
             if condition3
             for exprN in sequenceN
             if conditionN )

リスト内包表記も、外側の括弧が違うだけ (丸ではなく角括弧) で、あとは同じです。

生成される出力は expression 部分の値を要素として並べたものになります。 if 節はすべて、なくても大丈夫です; あれば condition が真のときだけ expression が評価されて出力に追加されます。

ジェネレータ式は常に括弧の中に書かなければなりませんが、関数コールの目印になっている括弧でも大丈夫です。関数にすぐ渡すイテレータを作りたければこう書けるのです:

obj_total = sum(obj.count for obj in list_all_objects())

for...in 節は複数つなげられますが、どれにも、イテレートするためのシーケンスが含まれています。それらのシーケンスは並行して ではなく 、左から右へ順番にイテレートされるので、長さが同じである必要はありません。 sequence1 の各要素ごとに毎回最初から sequence2 をループで回すのです。その後 sequence1 と sequence2 から出た要素ペアごとに、 sequence3 でループします。

別の書き方をすると、リスト内包表記やジェネレータ式は次の Python コードと同じ意味になります:

for expr1 in sequence1:
    if not (condition1):
        continue   # この要素は飛ばす
    for expr2 in sequence2:
        if not (condition2):
            continue    # この要素は飛ばす
        ...
        for exprN in sequenceN:
             if not (conditionN):
                 continue   # この要素は飛ばす

             # expression の値を出力する。

つまり、複数の for...in 節があって if がないときの最終出力は、長さが各シーケンス長の積に等しくなるということです。長さ 3 のリスト二つなら、出力リストの長さは 9 要素です:

>>> seq1 = 'abc'
>>> seq2 = (1,2,3)
>>> [(x,y) for x in seq1 for y in seq2]
[('a', 1), ('a', 2), ('a', 3),
 ('b', 1), ('b', 2), ('b', 3),
 ('c', 1), ('c', 2), ('c', 3)]

Python の文法に曖昧さを紛れ込ませないように、 expression でタプルを作るなら括弧で囲わなくてはなりません。下にあるリスト内包表記で、最初のは構文エラーですが、二番目は有効です:

# Syntax error
[ x,y for x in seq1 for y in seq2]
# Correct
[ (x,y) for x in seq1 for y in seq2]

ジェネレータ

ジェネレータは、イテレータを書く作業を簡単にする、特殊な関数です。標準的な関数は値を計算して返しますが、ジェネレータが返すのは、一連の値を返すイテレータです。

Python や C の標準的な関数コールについては、よくご存じに違いありません。関数を呼ぶと、ローカル変数を作るプライベートな名前空間ができますね。その関数が return 文まで来ると、ローカル変数が破壊されてから、返り値が呼び出し元に返ります。次に同じ関数をもう一度呼ぶと、新しいプライベート名前空間に新規のローカル変数が作られるのです。しかし、関数を出るときにローカル変数を捨てなければどうなるでしょうか。その出ていったところから関数を続行できたとしたら、どうでしょう。これこそジェネレータが提供する機能です; すなわち、ジェネレータは続行できる関数と考えることができます。

ごく単純なジェネレータ関数の例がこちらにあります:

def generate_ints(N):
    for i in range(N):
        yield i

yield キーワードを含む関数はすべてジェネレータ関数です; Python の bytecode コンパイラがこれを検出して、特別な方法でコンパイルしてくれるのです。

ジェネレータ関数は、呼ばれたときに一回だけ値を返すのではなく、イテレータプロトコルに対応したオブジェクトを返します。上の例で yield を実行したとき、ジェネレータは return 文のようにして i の値を出力します。 yield と return 文の大きな違いは、 yield に到達した段階でジェネレータの実行状態が一時停止になって、ローカル変数が保存される点です。次回そのジェネレータの .next() を呼ぶと、そこから関数が実行を再開します。

上記 generate_ints() ジェネレータの使用例はこちらです:

>>> gen = generate_ints(3)
>>> gen
<generator object generate_ints at ...>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
  File "stdin", line 1, in ?
  File "stdin", line 2, in generate_ints
StopIteration

同じく for i in generate_ints(5) や a,b,c = generate_ints(3) といった書き方もできます。

ジェネレータ関数内で return 文は、引数を付けずに、処理の終わりを知らせるためにだけ使うことができます; return を実行したあとは、もうそのジェネレータが値を返すことはできません。ジェネレータ関数の中では、 return 5 などと値を付けた return は構文エラーです。ジェネレータの出力が終わったことを示すには、ほかにも、手動で StopIteration を投げてもいいですし、関数の最後まで実行するだけでも同じことになります。

自分でクラスを書いて、ジェネレータで言うところのローカル変数をインスタンス変数として全部保管しておけば、同じ効果を得ることは可能です。たとえば整数のリストを返すのは、 self.count を 0 にして、 next() メソッドが self.count をインクリメントして返すようにすればできます。しかしながら、ある程度複雑なジェネレータになってくると、同じことをするクラスを書くのは格段にややこしいことになります。

Python のライブラリに含まれているテストスイート test_generators.py には、ほかにも興味深い例が数多く入っています。これは二分木の通りがけ順 (in-order) 探索を再帰で実装したジェネレータです。

# A recursive generator that generates Tree leaves in in-order.
def inorder(t):
    if t:
        for x in inorder(t.left):
            yield x

        yield t.label

        for x in inorder(t.right):
            yield x

ほかにも test_generators.py には、N-Queens 問題 (N×N コマのチェス盤に、互いに攻撃できないような配置で N 個のクイーンを置く) やナイト・ツアー (N×N 盤の全コマをナイトが一度ずつ通るような経路を探す) の解を出す例が入っています。

ジェネレータに値を渡す

Python 2.4 までのジェネレータは出力することしかできませんでした。ジェネレータのコードを実行してイテレータを作ってしまったあとで、その関数を再開するときに新しい情報を渡す手段はなかったのです。ジェネレータがグローバル変数を見るようにしたり、ミュータブルなオブジェクトを渡しておいて呼び出し元であとからそれを変更したり、といったハックは可能でしたが、どれもゴチャゴチャしていますね。

Python 2.5 で、ジェネレータに値を渡す簡単な手段ができました。 yield が、変数に代入したり演算したりできる値を返す式になったのです:

val = (yield i)

上のように、返り値で何かをするときは yield 式の前後に 必ず括弧を付けるようお勧めします。括弧は常に必要なわけではありませんが、どんなとき付けなくて良いのかを覚えておくより、いつも付けておくほうが楽ですから。

(PEP 342 がその規則を正確に説明していますが、それによると yield-式は、代入式で右辺のトップレベルにあるとき以外はいつも括弧を付ける必要があります。つまり val = yield i とは書けますが、 val = (yield i) + 12 のように演算子があるときは括弧を使わなくてはいけません。)

ジェネレータに値を送るには send(値) メソッドを呼びます。するとジェネレータのコードが実行を再開し、 yield 式がその値を返すのです。ふつうの next() メソッドを呼ぶと、 yield は None を返します。

下にあるのは 1 ずつ増える単純なカウンタですが、内部カウンタの値を変更することができるようになっています。

def counter (maximum):
    i = 0
    while i < maximum:
        val = (yield i)
        # 値が提供されていればカウンタを変更する
        if val is not None:
            i = val
        else:
            i += 1

そしてカウンタ変更の例がこちらです:

>>> it = counter(10)
>>> print it.next()
0
>>> print it.next()
1
>>> print it.send(8)
8
>>> print it.next()
9
>>> print it.next()
Traceback (most recent call last):
  File ``t.py'', line 15, in ?
    print it.next()
StopIteration

yield が None を返すことはよくあるのですから、そうなっていないかどうか必ずチェックしておくべきです。ジェネレータ関数を再開するために使うメソッドが send() しかないのだと確定してるのでない限り、式の値をそのまま使ってはいけません。

ジェネレータには、 send() のほかにも新しいメソッドが二つあります:

throw(type, value=None, traceback=None) はジェネレータ内で例外を投げるために使います; その例外はジェネレータの実行が停止したところの yield 式によって投げられます。

close() はジェネレータ内で GeneratorExit 例外を投げて、イテレートを終了させます。この例外を受け取ったジェネレータのコードは GeneratorExit か StopIteration を投げなくてはいけません; この例外を捕捉して何かほかのことをしようとするのは規則違反であり、 RuntimeError を引き起こします。 close() はジェネレータが GC されるときにも呼ばれます。

GeneratorExit が起こったときにクリーンアップ作業をする必要があるなら、 GeneratorExit を捕捉するのではなく try: ... finaly: するようお勧めします。

これらの変更の合わせ技で、ジェネレータは情報の一方的な生産者から、生産者かつ消費者という存在に変貌を遂げたのです。

ジェネレータは コルーチン という、より一般化された形式のサブルーチンにもなります。サブルーチンは一カ所 (関数の冒頭) から入って別の一カ所 (return 文) から出るだけですが、コルーチンはいろいろな場所 (yield 文) から入ったり出たり再開したりできるのです。

ビルトイン関数

よくイテレータと一緒に使うビルトイン関数について、もっと詳しく見ていきましょう。

Python のビルトイン関数 map() と filter() は少し時代遅れになっています; 機能がリスト内包表記と重複していて、イテレータではなくリストそのものを返します。

map(f, iterA, iterB, ...) は f(iterA[0], iterB[0]), f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ... のリストを返します。

>>> def upper(s):
...     return s.upper()

>>> map(upper, ['sentence', 'fragment'])
['SENTENCE', 'FRAGMENT']

>>> [upper(s) for s in ['sentence', 'fragment']]
['SENTENCE', 'FRAGMENT']

上にあるように、リスト内包表記でも同じ結果を得ることができます。 itertools.imap() 関数も同じことをしてくれますが、無限長イテレータまで扱うことができます; これについてはあとから itertools モジュールの章で論じましょう。

filter(predicate, iter) は条件に合う要素すべてのリストを返しますので、同様にリスト内包表記で再現できます。 predicate の部分には、条件が合うと真値を返す関数を入れてください; filter() で使うには、その関数が取る引数は一つだけでなくてはいけません。

>>> def is_even(x):
...     return (x % 2) == 0

>>> filter(is_even, range(10))
[0, 2, 4, 6, 8]

これはリスト内包表記でも書けます:

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

filter() も itertools モジュールに同等品があり、その itertools.ifilter() はイテレータを返すので、 itertools.imap() と同様、無限長シーケンスまで扱えます。

reduce(func, iter, [initial_value]) はイテラブルの要素に対して次々に演算を実行していった最終結果を出すもので、それゆえ無限長イテラブルには適用できませんので、 itertools モジュールに同等品がありません。 func には、要素を二つ取って値を一つ返す関数が入ります。 reduce() はイテレータが返す最初の二要素 A と B を取って func(A, B) を出します。それから三番目の要素 C を要求して func(func(A, B), C) を算出すると、その結果をさらに四番目の要素と組み合わせて……ということをイテラブルが尽きるまで続けるのです。もしイテラブルが一つも値を返さなければ TypeError が出ます。初期値 initial_value があるときには、 func(initial_value, A) がスタート地点として実行されます。

>>> import operator
>>> reduce(operator.concat, ['A', 'BB', 'C'])
'ABBC'
>>> reduce(operator.concat, [])
Traceback (most recent call last):
  ...
TypeError: reduce() of empty sequence with no initial value
>>> reduce(operator.mul, [1,2,3], 1)
6
>>> reduce(operator.mul, [], 1)
1

operator.add() を reduce() で使うと、イテラブルの全要素を合計することになります。これは使用頻度が高いので、そのためだけの sum() というビルトインがあるほどです:

>>> reduce(operator.add, [1,2,3,4], 0)
10
>>> sum([1,2,3,4])
10
>>> sum([])
0

とはいえ、多くの場合 reduce() を使うよりは単に for ループを書いたほうがわかりやすくなるかもしれません:

# こう書く代わりに
product = reduce(operator.mul, [1,2,3], 1)

# こう書けます
product = 1
for i in [1,2,3]:
    product *= i

enumerate(iter) はイテラブルの要素を数え上げて、それぞれの番号と要素の入った 2-タプルを返します。

>>> for item in enumerate(['subject', 'verb', 'object']):
...     print item
(0, 'subject')
(1, 'verb')
(2, 'object')

enumerate() はよく、リストに対してループさせて、条件に合う所に印を付けていくときに使われます:

f = open('data.txt', 'r')
for i, line in enumerate(f):
    if line.strip() == '':
        print 'Blank line at line #%i' % i

sorted(iterable, [cmp=None], [key=None], [reverse=false]) はイテラブルの要素をすべて集めたリストを作り、ソートして返します。引数 cmp, key, reverse は、リストの .sort() メソッドにそのまま渡されます。

>>> import random
>>> # 0 以上 10000 未満の乱数を 8 個生成
>>> rand_list = random.sample(range(10000), 8)
>>> rand_list
[769, 7953, 9828, 6431, 8442, 9878, 6213, 2207]
>>> sorted(rand_list)
[769, 2207, 6213, 6431, 7953, 8442, 9828, 9878]
>>> sorted(rand_list, reverse=True)
[9878, 9828, 8442, 7953, 6431, 6213, 2207, 769]

(ソートに関する詳細な論議は Python wiki の Sorting mini-HOWTO を参照: http://wiki.python.org/moin/HowTo/Sorting [1]

ビルトインの any(iter) および all(iter) はイテラブルの真値を調べます。 any() は要素のどれかが真値なら True を返し、 all() は要素がどれも真値なら True を返します:

>>> any([0,1,0])
True
>>> any([0,0,0])
False
>>> any([1,1,1])
True
>>> all([0,1,0])
False
>>> all([0,0,0])
False
>>> all([1,1,1])
True

小さな関数とラムダ式

関数型スタイルのプログラムを書いていると、述語として働いたり、何らかの形で要素をつなぎ合わせたりするミニサイズの関数を必要とすることがよくあります。

ちょうど良い関数がビルトインやモジュールで存在していれば、新しい関数を定義する必要はまったくありません:

stripped_lines = [line.strip() for line in lines]
existing_files = filter(os.path.exists, file_list)

しかし、欲しい関数がないなら書くしかありません。そうした小さな関数を書く方法の一つが lambda 文です。 lambda は引数として複数のパラメータとそれをつなぐ式を取り、その式の値を返す小さな関数を作ります:

lowercase = lambda x: x.lower()

print_assign = lambda name, value: name + '=' + str(value)

adder = lambda x, y: x+y

もう一つの選択肢は、ふつうに def 文で関数を定義するだけです:

def lowercase(x):
    return x.lower()

def print_assign(name, value):
    return name + '=' + str(value)

def adder(x,y):
    return x + y

どちらのほうが良いのでしょうか。それは好みの問題です; 著者のスタイルとしてはできるだけ lambda を使わないようにしています。

そのようにしている理由の一つに、 lambda は定義できる関数が非常に限られているという点があります。一つの式として算出できる結果にしなければいけませんので、 if... elif... else や try... except のような分岐を持つことができないのです。 lambda 文の中でたくさんのことをやろうとしすぎると、ごちゃごちゃして読みにくい式になってしまいます。さて、次のコードは何をしているでしょうか、素早くお答えください!

total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1]

わかるにはわかるでしょうが、何がどうなっているのか紐解いていくには時間がかかるはずです。短い def 文で入れ子にすると、少し見通しが良くなりますが:

def combine (a, b):
    return 0, a[1] + b[1]

total = reduce(combine, items)[1]

でも単純に for ループにすれば良かったのです:

total = 0
for a, b in items:
    total += b

あるいは sum() ビルトインとジェネレータ式でも良いですね:

total = sum(b for a,b in items)

多くの場合、 reduce() を使っているところは for ループに書き直したほうが見やすいです。

Fredrik Lundh は以前 lambda 利用のリファクタリングに関して以下の指針を提案したことがあります:

ラムダ関数を書く。

そのラムダが一体ぜんたい何をしているのかコメントで説明する。

そのコメントをしばらく研究して、本質をとらえた名前を考える。

ラムダをその名前で def 文に書き換える。

コメントを消す。

著者はこの指針を本当に気に入っていますが、こうしたラムダなしスタイルが他より優れているかどうかについて、異論は認めます。

itertools モジュール

itertools モジュールには、よく使うイテレータや、イテレータ同士の連結に使う関数がたくさん含まれています。この章では、そのモジュールの内容を小さな例で紹介していきたいと思います。

このモジュールの関数を大まかに分けるとこうなります:

既存のイテレータに基づいて新しいイテレータを作る関数

イテレータの要素を引数として扱う関数

イテレータの出力から一部を取り出す関数

イテレータの出力をグループ分けする関数

新しいイテレータを作る

itertools.count(n) は整数を 1 ずつ増やして無限長ストリームを返します。開始地点となる数を渡すこともでき、既定は 0 になっています:

itertools.count() =>
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
itertools.count(10) =>
  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...

itertools.cycle(iter) は与えられたイテラブルの内容をコピーして、その要素を最初から最後まで無限に繰り返していくイテレータを返します。

itertools.cycle([1,2,3,4,5]) =>
  1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...

itertools.repeat(elem, [n]) は、差し出された要素を n 回返しますが、 n がなければ永遠に返し続けます。

itertools.repeat('abc') =>
  abc, abc, abc, abc, abc, abc, abc, abc, abc, abc, ...
itertools.repeat('abc', 5) =>
  abc, abc, abc, abc, abc

itertools.chain(iterA, iterB, ...) はイテラブルを好きな数だけ受け取って、最初のイテレータから要素をすべて返し、次に二番目から要素をすべて返し、ということを要素がなくなるまで続けます。

itertools.chain(['a', 'b', 'c'], (1, 2, 3)) =>
  a, b, c, 1, 2, 3

itertools.izip(iterA, iterB, ...) は各イテラブルから要素を一つずつ取り、タプルに入れて返します:

itertools.izip(['a', 'b', 'c'], (1, 2, 3)) =>
  ('a', 1), ('b', 2), ('c', 3)

これはビルトインの zip() 関数と似ていますが、メモリ内にリストを構築したり、入力イテレータを使い切ってから返したりしない点が違います; これがタプルを作って返すのは、要求を受けたときだけなのです。(この振る舞いを専門用語で 遅延評価 [http://ja.wikipedia.org/wiki/%E9%81%85%E5%BB%B6%E8%A9%95%E4%BE%A1] と言います。)

このイテレータの用途には、すべて同じ長さのイテラブルを想定しています。長さが違っていれば、出力されるストリームは一番短いイテラブルと同じ長さになります。

itertools.izip(['a', 'b'], (1, 2, 3)) =>
  ('a', 1), ('b', 2)

とは言え、これをやってしまうと長いイテレータから要素をひとつ無駄に多く取って捨ててしまうかもしれませんので、やめておいたほうが良いです。その捨てられた要素を抜かしてしまう危険があるので、もうそのイテレータはそれ以上使えなくなってしまいます。

itertools.islice(iter, [start], stop, [step]) は、イテレータのスライスをストリームで返します。 stop 引数だけだと、最初の stop 個の要素を返します。開始インデックスを渡すと stop - start 個で、 step の値も渡せばそれに応じて要素を抜かします。Python における文字列やリストのスライスとは違って、マイナスの値は start, stop, step に使えません。

itertools.islice(range(10), 8) =>
  0, 1, 2, 3, 4, 5, 6, 7
itertools.islice(range(10), 2, 8) =>
  2, 3, 4, 5, 6, 7
itertools.islice(range(10), 2, 8, 2) =>
  2, 4, 6

itertools.tee(iter, [n]) はイテレータを複製します; 元のイテレータの内容を同じように返す、独立した n 個のイテレータを返すのです。 n の値は、指定しなければ既定が 2 になっています。複製するには元のイテレータの内容を一部保存しておく必要がありますから、大きなイテレータから複製したうちの一つが他よりも進んでいってしまうと、大量のメモリを消費することがあります。

itertools.tee( itertools.count() ) =>
   iterA, iterB

where iterA ->
   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...

and   iterB ->
   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...

要素に対して関数を呼ぶ

イテラブルの中身に対して他の関数を呼ぶための関数が二つあります。

itertools.imap(f, iterA, iterB, ...) は f(iterA[0], iterB[0]), f(iterA[1], iterB[1]), f(iterA[2], iterB[2]), ... というストリームを返します:

itertools.imap(operator.add, [5, 6, 5], [1, 2, 3]) =>
  6, 8, 8

いま使った operator モジュールには、Python の演算子に対応する関数が入っています。いくつか例を挙げると、 operator.add(a, b) (二つの値を加算)、 operator.ne(a, b) (a!=b と同じ)、 operator.attrgetter('id') ("id" 属性を取得するコーラブルを返す) といった関数です。

itertools.starmap(func, iter) は、イテラブルがタプルを返すものとして、そのタプルを引数に使って func() を呼びます:

itertools.starmap(os.path.join,
                  [('/usr', 'bin', 'java'), ('/bin', 'python'),
                   ('/usr', 'bin', 'perl'),('/usr', 'bin', 'ruby')])
=>
  /usr/bin/java, /bin/python, /usr/bin/perl, /usr/bin/ruby

要素を選択する

さらに別のグループとして、述語 (predicate) に基づいてイテレータの要素からサブセットを選び出す関数があります。

itertools.ifilter(predicate, iter) は述語が真を返す要素をすべて返します:

def is_even(x):
    return (x % 2) == 0

itertools.ifilter(is_even, itertools.count()) =>
  0, 2, 4, 6, 8, 10, 12, 14, ...

itertools.ifilterfalse(predicate, iter) は反対に、述語が偽を返す要素をすべて返します:

itertools.ifilterfalse(is_even, itertools.count()) =>
  1, 3, 5, 7, 9, 11, 13, 15, ...

itertools.takewhile(predicate, iter) は述語が真を返している間だけ要素を返します。一度でも述語が偽を返すと、イテレータは出力終了の合図をします。

def less_than_10(x):
    return (x < 10)

itertools.takewhile(less_than_10, itertools.count()) =>
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9

itertools.takewhile(is_even, itertools.count()) =>
  0

itertools.dropwhile(predicate, iter) は、述語が真を返しているうちは要素を無視し、偽になってから残りの出力をすべて返します。

itertools.dropwhile(less_than_10, itertools.count()) =>
  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...

itertools.dropwhile(is_even, itertools.count()) =>
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...

要素をグループ分けする

最後に議題に上げる関数 itertools.groupby(iter, key_func=None) は、これまでで最も複雑です。 key_func(elem) は、イテラブルから返ってきた要素それぞれのキー値を計算する関数です。この関数が指定されていなければ、キーは単に各要素そのものになります。

groupby() は、下敷きになっているイテラブルから、連続して同じキー値を持つ要素を集めて、キー値とイテレータの 2-タプルを返していきます。イテレータは、それぞれのキーに対応する要素を出します。

city_list = [('Decatur', 'AL'), ('Huntsville', 'AL'), ('Selma', 'AL'),
             ('Anchorage', 'AK'), ('Nome', 'AK'),
             ('Flagstaff', 'AZ'), ('Phoenix', 'AZ'), ('Tucson', 'AZ'),
             ...
            ]

def get_state ((city, state)):
    return state

itertools.groupby(city_list, get_state) =>
  ('AL', iterator-1),
  ('AK', iterator-2),
  ('AZ', iterator-3), ...

where
iterator-1 =>
  ('Decatur', 'AL'), ('Huntsville', 'AL'), ('Selma', 'AL')
iterator-2 =>
  ('Anchorage', 'AK'), ('Nome', 'AK')
iterator-3 =>
  ('Flagstaff', 'AZ'), ('Phoenix', 'AZ'), ('Tucson', 'AZ')

groupby() は、下敷きにするイテラブルの中身がキー値でソート済みになって与えられることを想定しています。さて、こうして出力されるイテレータ自体も下敷きのイテラブルを使うということに注意してください。ですから iterator-1 に出力し切ってしまうまで、iterator-2 およびそのキー値を要求することはできません。

functools モジュール

Python 2.5 からの functools モジュールには、高階関数がいくつか入っています。 高階関数 とは、入力として関数を受け取って新たな関数を返す関数です。このモジュールで一番便利なツールは functools.partial() 関数です。

関数型スタイルのプログラムでは時折、既存の関数から一部のパラメータを埋めた変種を作りたくなることがあります。Python の関数 f(a, b, c) というものがあるとしてください; f(1, b, c) と同じ意味の g(b, c) という関数を作りたくなることがあります; つまり f() のパラメータを一つ埋めるわけです。これは「関数の部分適用」と呼ばれています。

partial のコンストラクタは (関数, 引数1, 引数2, ... キーワード引数1=既定値1, キーワード引数2=既定値2) という引数を取ります。できあがったオブジェクトはコーラブルですので、それを呼べば、引数の埋まった function を実行したのと同じことになります。

以下にあるのは、小さいけれども現実的な一つの例です:

import functools

def log (message, subsystem):
    "Write the contents of 'message' to the specified subsystem."
    print '%s: %s' % (subsystem, message)
    ...

server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')

operator モジュール

operator モジュールは、既に取り上げましたが、Python の演算子に対応する関数が入っているモジュールです。関数型スタイルのコードにおいて、演算を一つ実行するだけのくだらない関数を書かずに済むので、よく世話になります。

このモジュールの関数を一部だけ紹介しましょう:

数学演算子: add(), sub(), mul(), div(), floordiv(), abs(), ...

論理演算子: not_(), truth()

ビット演算子: and_(), or_(), invert()

比較: eq(), ne(), lt(), le(), gt(), ge()

オブジェクト識別: is_(), is_not()

ちゃんとした一覧は operator モジュールの文書でご覧ください。

functional モジュール

Collin Winter の functional モジュール [http://oakwinter.com/code/functional/] には関数型プログラミング用の上級ツールが多数備わっています。さらには、いくつかの Python ビルトインを再実装して、既に他言語で関数型プログラミングに親しんでいる人たちにとってより直感的なようにしてあります。

この章では、 functional の中で最も重要な関数をいくつか紹介します; 完全版の文書は プロジェクトのウェブサイト [http://oakwinter.com/code/functional/documentation/] にあります。

compose(outer, inner, unpack=False)

compose() 関数は、関数合成を実装しています。言い換えると、 inner と outer の両コーラブルを囲んで、 inner からの返り値をすぐ outer に渡すようなラッパを返します。つまり、

>>> def add(a, b):
...     return a + b
...
>>> def double(a):
...     return 2 * a
...
>>> compose(double, add)(5, 6)
22

は下と同じことをしています。

>>> double(add(5, 6))
22

unpack キーワードが用意されているのは、Python には完全に カリー化 [http://en.wikipedia.org/wiki/Currying] されていない関数があるという現実に対処するためです。既定では inner 関数も単一オブジェクトを返し outer 関数も単一の引数を取るものと期待されていますが、 unpack 引数を設定すると、 compose は inner からタプルが来るものとして、 outer に渡す前に展開するようになります。ですから単なる

compose(f, g)(5, 6)

は次の書き方と同じことです:

f(g(5, 6))

けれども

compose(f, g, unpack=True)(5, 6)

は次と同じ意味になります:

f(*g(5, 6))

compose() は二つしか関数を受け付けませんが、好きなだけ合成できるバージョンを作るのは簡単なことです。それには reduce(), compose(), partial() を使います (最後のは functional でも functools でも提供されています)。

from functional import compose, partial

multi_compose = partial(reduce, compose)

map(), compose(), partial() を使って、引数を文字列に変換するバージョンの "".join(...) を組み立てることもできます:

from functional import compose, partial

join = compose("".join, partial(map, str))

flip(func)

flip() は、 func に指定したコーラブルのラッパを返し、キーワードなし引数を逆の順番で受け取るようにします。

>>> def triple(a, b, c):
...     return (a, b, c)
...
>>> triple(5, 6, 7)
(5, 6, 7)
>>>
>>> flipped_triple = flip(triple)
>>> flipped_triple(5, 6, 7)
(7, 6, 5)

foldl(func, start, iterable)

foldl() は引数として二引数関数、初期値 (たいていは「ある種の」ゼロ)、イテラブルを取ります。その二引数関数を初期値とリスト第一要素に適用し、その結果とリスト第二要素、さらにその結果と第三要素、というように適用していくのです。

つまり、こういうコールは

foldl(f, 0, [1, 2, 3])

これと同じことになります:

f(f(f(0, 1), 2), 3)

foldl() は以下の再帰関数とほぼ同じです:

def foldl(func, start, seq):
    if len(seq) == 0:
        return start

    return foldl(func, func(start, seq[0]), seq[1:])

「同じ」と言えば、さきほどの foldl コールの例は、ビルトインの reduce を使ってこのように表現することもできます:

reduce(f, [1, 2, 3], 0)

foldl(), operator.concat(), partial() を使えば、スッキリして見やすいバージョンの "".join(...) を書くことができます:

from functional import foldl, partial from operator import concat

join = partial(foldl, concat, "")

更新履歴と謝辞

著者は提案の申し出や修正、様々なこの記事の草稿の助けをしてくれた以下の人々に感謝します: Ian Bicking, Nick Coghlan, Nick Efford, Raymond Hettinger, Jim Jewett, Mike Krell, Leandro Lameiro, Jussi Salmela, Collin Winter, Blake Winton.

Version 0.1: posted June 30 2006.

Version 0.11: posted July 1 2006. Typo fixes.

Version 0.2: posted July 10 2006. Merged genexp and listcomp sections into one. Typo fixes.

Version 0.21: Added more references suggested on the tutor mailing list.

Version 0.30: Adds a section on the functional module written by Collin Winter; adds short section on the operator module; a few other edits.

参照資料

一般論

Harold Abelson と Gerald Jay Sussman, Julie Sussman による Structure and Interpretation of Computer Programs 。 http://mitpress.mit.edu/sicp/ に全文があります。この計算機科学に関する古典的な教科書では、 2 章と 3 章でデータフローをプログラム内でまとめるためのシーケンスとストリームの利用について議論しています。この本は例として Scheme を使っていますが、これらの章内の多くのデザインアプローチは関数スタイルな Python コードにも適用できます。

http://www.defmacro.org/ramblings/fp.html: 関数プログラミングの一般的な入門で Java での例を利用していて、長大な歴史の紹介があります。

http://en.wikipedia.org/wiki/Functional_programming: 関数プログラミングに関する一般的な内容の記事 [2] 。

http://en.wikipedia.org/wiki/Coroutine: コルーチンに関する記事 [3] 。

http://en.wikipedia.org/wiki/Currying: カリー化の概念に関する記事 [4] 。

Python 特有の話

http://gnosis.cx/TPiP/: David Mertz’s の本の最初の章 Text Processing in Python では文書処理のための関数プログラミングについて議論しています、この議論の節には “Utilizing Higher-Order Functions in Text Processing” というタイトルがついています。

Python 文書

itertools モジュールの文書。

operator モジュールの文書。

PEP 289 [http://www.python.org/dev/peps/pep-0289]: “Generator Expressions”

PEP 342 [http://www.python.org/dev/peps/pep-0342]: “Coroutines via Enhanced Generators” describes the new generator features in Python 2.5.

注記

[1]
訳注 Python Wiki の内容の最新の情報は反映されていませんが、 Python ドキュメント内に和訳があります ソート HOW TO

[2]
訳注 日本語版 Wikipedia に関数型言語 [http://ja.wikipedia.org/wiki/%E9%96%A2%E6%95%B0%E5%9E%8B%E8%A8%80%E8%AA%9E] に関する記事があります。

[3]
訳注 日本語版 Wikipedia にコルーチン [http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3] に関する記事があります。

[4]
訳注 日本語版 Wikipedia にカリー化 [http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96] に関する記事があります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

ロギング HOWTO

Author:
Vinay Sajip <vinay_sajip at red-dove dot com>

基本ロギングチュートリアル

ロギングは、あるソフトウェアが実行されているときに起こったイベントを追跡するための手段です。ソフトウェアの開発者は、特定のイベントが発生したことを示すロギングの呼び出しをコードに加えます。イベントは、メッセージで記述され、これに変数データ (すなわち、イベントが起こる度に異なるかもしれないデータ) を加えることもできます。イベントには、開発者がそのイベントに定めた重要性も含まれます。重要性は、 レベル (level) や 重大度 (severity) とも呼ばれます。

ロギングを使うべきとき

logging は、単純なロギングの用法に便利な関数群を提供しています。この中には、 debug(), info(), warning(), error() および critical() があります。logging を使うべき時を決めるには、よくあるタスクに使う最適なツールを述べた、以下のテーブルを参照してください。

行いたいタスク
そのタスクに最適なツール

コマンドラインスクリプトやプログラムで普通に使う、コンソール出力の表示
print()

プログラムの通常の操作中に発生したイベントの報告 (例えば、状態の監視や障害の分析)
logging.info() (または、診断のための特に詳細な出力には logging.debug())

特定のランタイムイベントに関わる警告の発行

その発行が避けられるもので、クライアントアプリケーションを修正してその警告を排除するべきなら warnings.warn()

アプリケーションにできることはないが、それでもイベントを記録するべきなら logging.warning()

特定のランタイムイベントに関わるエラーの報告
例外の送出

例外の送出をしないエラーの抑制 (例えば、長期のサーバプロセス中のエラーハンドラ)
特定のエラーやアプリケーションドメインに応じて logging.error(), logging.exception() または logging.critical()

ロギング関数は、そのイベントのレベルや重大度から名前を付けられ、それが追跡に使われます。標準のレベルとその適用範囲は、以下に (重大度が増す順に) 記述されています

レベル | 使われるとき
DEBUG | おもに問題を診断するときにのみ関心があるような、詳細な情報
INFO | 想定された通りのことが起こったことの確認
WARNING | 想定外のことが起こった、または問題が近く起こりそうである (例えば、’disk space low’) ことの表示
ERROR | より重大な問題により、ソフトウェアがある機能を実行できないこと
CRITICAL | プログラム自体が実行を続けられないことを表す、重大なエラー

デフォルトのレベルは WARNING で、logging パッケージが他に設定されなければ、このレベル以上のイベントのみ追跡されます。

追跡されるイベントは、異なる方法で処理されます。追跡されたイベントを処理する最も単純な方法は、それをコンソールに表示することです。その他のよくある方法は、それをディスクファイルに書き出すことです。

簡単な例

ごく簡単な例は:

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

これらの行をスクリプトにタイプして実行すると、次のようにコンソールに出力されます:

WARNING:root:Watch out!

デフォルトのレベルは WARNING なので、 INFO メッセージは現れません。表示されたメッセージには、レベルの表示と、ロギングの呼び出しで提供された、イベントの説明すなわち ‘Watch out!’ が含まれます。 ‘root’ の部分は今は気にしないでください。あとで説明します。実際の出力は、必要に応じてかなり柔軟に書式化できます。書式化操作もあとで説明します。

ファイルへのロギング

非常によくある状況として、ロギングイベントのファイルへの記録が挙げられますから、次はそれを見てみましょう:

import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

そして、ファイルを開いて何が起こったか見てみると、このようなログメッセージが見つかるでしょう:

DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too

この例はまた、追跡のしきい値となるロギングレベルを設定する方法も示しています。この例では、しきい値を DEBUG に設定しているので、全てのメッセージが表示されています。

ロギングレベルをコマンドラインオプションから次のように設定したいなら:

--log=INFO

--log に渡されたパラメタの値をある変数 loglevel に保存すれば:

getattr(logging, loglevel.upper())

を使い、 level 引数を通して basicConfig() に渡すべき値を得られます。ユーザの入力値をすべてエラーチェックしたいこともあり、以下のようになるかもしれません:

# assuming loglevel is bound to the string value obtained from the
# command line argument. Convert to upper case to allow the user to
# specify --log=DEBUG or --log=debug
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
    raise ValueError('Invalid log level: %s' % loglevel)
logging.basicConfig(level=numeric_level, ...)

basicConfig() は、 debug() や info() を最初に呼び出す 前 に呼び出さなければなりません。これは、一度限りの単純な設定機能を意図しているので、実際に作用するのは最初の呼び出しのみで、続く呼び出しの効果は no-op です。

上記のスクリプトを複数回実行すると、2 回目以降の実行によるメッセージは example.log に加えられます。以前の実行によるメッセージを記憶せず、実行ごとに新たに始めたいなら、上記の例での呼び出しを次のように変え、 filemode 引数を指定することができます:

logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)

出力は先ほどと同じになりますが、ログファイルは追記されるのではなくなり、以前の実行によるメッセージは失われます。

複数のモジュールからのロギング

プログラムが複数のモジュールでできているなら、そのロギングをどのように構成するかの例はこちらです:

# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()

# mylib.py
import logging

def do_something():
    logging.info('Doing something')

myapp.py を実行すると、 myapp.log には、おそらく期待したとおりに、次のように書き込まれるでしょう:

INFO:root:Started
INFO:root:Doing something
INFO:root:Finished

この mylib.py でのパターンは、複数のモジュールに一般化できます。なお、この簡単な使用パターンでは、ログファイルを見ることで、イベントの説明は見られますが、アプリケーションの どこから メッセージが来たのかを知ることはできません。メッセージの位置を追跡したいなら、このチュートリアルレベルを超えたドキュメントが必要になります – 上級ロギングチュートリアル を参照してください。

変数データのロギング

変数データのログを取るには、イベント記述メッセージにフォーマット文字列を使い、引数に変数データを加えてください。例えば:

import logging
logging.warning('%s before you %s', 'Look', 'leap!')

により、次のように表示されます:

WARNING:root:Look before you leap!

ご覧の通り、イベント記述メッセージに変数データを統合するために、古い、% スタイルの文字列フォーマットを使っています。これは後方互換性のためです。logging パッケージは、 str.format() や string.Template のような新しいフォーマットオプションよりも先に生まれました。新しいフォーマットオプションはサポートされて います が、その探求はこのチュートリアルでは対象としません。

表示されるメッセージのフォーマットの変更

メッセージを表示するのに使われるフォーマットを変更するには、使いたいフォーマットを指定する必要があります:

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

すると次のように表示されます:

DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too

ご覧の通り、先の例に現れた ‘root’ が消失しています。フォーマット文字列に含めることができるものの一覧は、 LogRecord 属性 のドキュメントから参照できますが、単純な用途では、必要なものは levelname (重大度)、 message (変数データを含むイベント記述)、それともしかしたら、イベントがいつ起こったかという表示だけです。これは次の節で解説します。

メッセージ内での日付と時刻の表示

イベントの日付と時刻を表示するには、フォーマット文字列に ‘%(asctime)s’ を置いてください:

import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')

のようにすると、このように表示されます:

2010-12-12 11:41:42,612 is when this event was logged.

(上で示した) 日付と時刻表示のデフォルトフォーマットは ISO8601 です。日付と時刻のフォーマットを詳細に制御するには、この例のように、 basicConfig に datefmt 変数を与えてください:

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

すると、このように表示されるでしょう:

12/12/2010 11:46:36 AM is when this event was logged.

datefmt 引数のフォーマットは、 time.strftime() でサポートされているものと同じです。

次のステップ

基本チュートリアルはこれで終わりです。あなたがロギングを使っていくためには、これで十分でしょう。logging パッケージが提供するものはもっとありますが、それを使いこなすためには、もうちょっと時間をかけて、以下のセクションを読む必要があります。その用意ができたら、好きな飲み物を持って、次に進みましょう。

ロギングを簡潔に行いたいなら、上記の例を使って、ロギングをあなたのスクリプトに組み込んでください。そして問題があったり、理解出来ないことがあったら、 comp.lang.python Usenet group (http://groups.google.com/group/comp.lang.python から利用できます) に質問を投稿してくだされば、そう遠くないうちに助けが得られるでしょう。

まだいますか？もう少し上級の、踏み込んだチュートリアルを綴った、幾つかの節を読み続けることができます。その後で、ロギングクックブック もご覧ください。

上級ロギングチュートリアル

logging ライブラリはモジュール方式のアプローチを取り、いくつかのカテゴリの部品を提供します。ロガー、ハンドラ、フィルタ、フォーマッタです。

ロガーは、アプリケーションコードが直接使うインタフェースを公開します。

ハンドラは、(ロガーによって生成された) ログ記録を適切な送信先に送ります。

フィルタは、どのログ記録を出力するかを決定する、きめ細かい機能を提供します。

フォーマッタは、ログ記録が最終的に出力されるレイアウトを指定します。

ロギングは、 Logger クラスのインスタンス (以下 ロガー) にメソッドを呼び出すことで実行されます。各インスタンスには名前があり、名前空間階層構造に、ドット (ピリオド) をセパレータとして、概念的に並べられています。例えば、 ‘scan’ という名前のロガーは、ロガー ‘scan.text’, ‘scan.html’ および ‘scan.pdf’の親です。ロガー名は、何でも望むものにでき、ロギングされたメッセージが発生した場所を指し示します。

ロガーに名前をつけるときの良い習慣は、ロギングを使う各モジュールに、以下のように名付けられた、モジュールレベルロガーを使うことです:

logger = logging.getLogger(__name__)

これにより、ロガー名はパッケージ/モジュール階層をなぞり、ロガー名だけで、どこでイベントのログが取られたか、直感的に明らかになります。

ロガーの階層構造の根源は、ルートロガーと呼ばれます。それが、関数 debug(), info(), warning(), error() および critical() によって使われるロガーとなります。これらの関数は単に、ルートロガーの同名のメソッドを呼び出します。これらの関数とメソッドは、同じ署名をもっています。ルートロガーの名前は、ログ出力では ‘root’ と表示されます。

もちろん、メッセージを異なる送信先に記録することも出来ます。このパッケージでは、ファイルへ、 HTTP GET/POST 先へ、 SMTP 経由で電子メールへ、汎用のソケットへ、または Windows NT イベントログのような OS 毎のログ記録機構への、ログメッセージの書きこみがサポートされています。送信先は、 handler クラスによって取り扱われます。組み込みのハンドラクラスでは満たせないような、特殊な要件があるなら、独自のログ送信先を生成できます。

デフォルトでは、どのロギングメッセージに対しても、送信先は設定されていません。チュートリアルの例のように、 basicConfig() を使って、送信先 (コンソールやファイルなど) を指定できます。関数 debug(), info(), warning(), error() および critical() を呼び出すと、それらは送信先が設定されていないかを調べます。そして設定されていなければ、ルートロガーに委譲して実際にメッセージを出力する前に、コンソール (sys.stderr) を送信先に、デフォルトのフォーマットを表示されるメッセージに設定します。

basicConfig() によって設定される、メッセージのデフォルトのフォーマットはこうです:

severity:logger name:message

basicConfig() の format キーワード引数にフォーマット文字列を渡すことで、これを変更できます。フォーマット文字列を構成するためのすべてのオプションは、フォーマッタオブジェクト を参照してください。

ロガー

Logger オブジェクトの仕事は大きく三つに分かれます。一つ目は、アプリケーションが実行中にメッセージを記録できるように、いくつかのメソッドをアプリケーションから呼べるようにしています。二つ目に、ロガーオブジェクトはどのメッセージに対して作用するかを、深刻度 (デフォルトのフィルタ機構) またはフィルタオブジェクトに基づいて決定します。三つ目に、ロガーオブジェクトは関心を持っているすべてのログハンドラに関連するログメッセージを回送します。

とりわけ広く使われるロガーオブジェクトのメソッドは、二つのカテゴリーに分類できます: 設定とメッセージ送信です。

これらが設定メソッドの中でよく使われます:

Logger.setLevel() はロガーが扱うログメッセージの最も低い深刻度を指定します。組み込みの深刻度の中では DEBUG が一番低く、 CRITICAL が一番高くなります。たとえば、深刻度が INFO と設定されたロガーは INFO, WARNING, ERROR, CRITICAL のメッセージしか扱わず、 DEBUG メッセージは無視します。

Logger.addHandler() と Logger.removeHandler() は、ハンドラオブジェクトをロガーオブジェクトから追加または削除します。ロガーオブジェクトにハンドラオブジェクトを追加または削除します。ハンドラについては、 ハンドラ で詳しく述べます。

Logger.addFilter() と Logger.removeFilter() はロガーオブジェクトにフィルタオブジェクトを追加または削除します。フィルタについては、 フィルタオブジェクト で詳しく述べます。

これらのメソッドを、生成したすべてのロガーに毎回呼び出さなければならないわけではありません。最後の 2 段落を参照してください。

ロガーオブジェクトが設定されれば、以下のメソッドがログメッセージを生成します。

Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), Logger.critical() はすべて、メッセージとメソッド名に対応したレベルでログ記録を作り出します。メッセージは実際にはフォーマット文字列であり、通常の文字列代入に使う %s, %d, %f などを含むことができます。残りの引数はメッセージの代入される位置に対応するオブジェクトのリストです。 **kwargs については、ログ記録メソッドが気にするキーワードは exc_info だけで、例外の情報をログに記録するかを決定するのに使います。

Logger.exception() は Logger.error() と似たログメッセージを作成します。違いは Logger.exception() がスタックトレースを一緒にダンプすることです。例外ハンドラでだけ使うようにしてください。

Logger.log() はログレベルを明示的な引数として受け取ります。これは上に挙げた便宜的なログレベル毎のメソッドを使うより少しコード量が多くなりますが、独自のログレベルを使うことができます。

getLogger() は、指定されればその特定の名前の、そうでなければ root のロガーインスタンスへの参照を返します。ロガーの名前はピリオド区切りの階層構造を表します。同じ名前で getLogger() を複数回呼び出した場合、同一のロガーオブジェクトへの参照が返されます。階層リストを下ったロガーはリスト上位のロガーの子です。たとえば、名前が foo であるロガーがあったとして、 foo.bar, foo.bar.baz, foo.bam といった名前のロガーはすべて foo の子孫になります。

ロガーには、 有効レベル (effective level) の概念があります。ロガーにレベルが明示的に設定されていなければ、代わりに親のレベルがその有効レベルとして使われます。親のレベルが設定されなければ、 その親のレベルが確かめられ、以下同様に、明示的に設定されたレベルが見つかるまで祖先が探されます。ルートロガーは、必ず明示的なレベルが設定されています (デフォルトでは WARNING です)。イベントを処理するかを決定するとき、ロガーの有効レベルを使って、イベントがロガーのハンドラに渡されるかが決められます。

子ロガーはメッセージを親ロガーのハンドラに伝えます。このため、アプリケーションが使っているすべてのロガーのためのハンドラを定義して設定する必要はありません。トップレベルのロガーのためのハンドラだけ設定しておいて必要に応じて子ロガーを作成すれば十分です。 (しかし、ロガーの propagate 属性を False に設定することで、伝播を抑制できます。)

ハンドラ

Handler オブジェクトは適切なログメッセージを (ログメッセージの深刻度に基づいて) ハンドラの指定された出力先に振り分けることに責任を持ちます。ロガーオブジェクトには addHandler() メソッドで 0 個以上のハンドラを追加することができます。例として、あるアプリケーションがすべてのログメッセージをログファイルに、 error 以上のすべてのログメッセージを標準出力に、 critical のメッセージはすべてメールアドレスに、それぞれ送りたいとします。この場合、 3 つの個別のハンドラがそれぞれの深刻度と宛先に応じて必要になります。

このライブラリには多くのハンドラが用意されています (便利なハンドラ を参照してください) が、このチュートリアルでは StreamHandler と FileHandler だけを例に取り上げます。

アプリケーション開発者にとってハンドラを扱う上で気にするべきメソッドは極々限られています。組み込みのハンドラオブジェクトを使う (つまり自作ハンドラを作らない) 開発者に関係あるハンドラのメソッドは、次の設定用のメソッドだけでしょう:

Handler.setLevel() メソッドは、ロガーオブジェクトの場合と同様に、適切な出力先に振り分けられるべき最も低い深刻度を指定します。なぜ 2 つも setLevel() メソッドがあるのでしょうか? ロガーで設定されるレベルは、付随するハンドラにどんな深刻度のメッセージを渡すか決めます。ハンドラで設定されるレベルは、ハンドラがどのメッセージを送るべきか決めます。

setFormatter() でこのハンドラが使用する Formatter オブジェクトを選択します。

addFilter() および removeFilter() はそれぞれハンドラへのフィルタオブジェクトの設定と解除を行います。

アプリケーションのコード中では Handler のインスタンスを直接インスタンス化して使ってはなりません。代わりに、 Handler クラスはすべてのハンドラが持つべきインターフェイスを定義し、子クラスが使える (もしくはオーバライドできる) いくつかのデフォルトの振る舞いを規定します。

フォーマッタ

フォーマッタオブジェクトは最終的なログメッセージの順序、構造および内容を設定します。基底クラスである logging.Handler とは違って、アプリケーションのコードはフォーマッタクラスをインスタンス化しても構いません。特別な振る舞いをさせたいアプリケーションではフォーマッタのサブクラスを使う可能性もあります。コンストラクタは二つのオプション引数を取ります – メッセージのフォーマット文字列と日付のフォーマット文字列です。

logging.Formatter.__init__(fmt=None, datefmt=None)

メッセージのフォーマット文字列がなければ、デフォルトではメッセージをそのまま使います。日付のフォーマット文字列がなければ、デフォルトは:

%Y-%m-%d %H:%M:%S

で、最後にミリ秒が付きます。

メッセージのフォーマット文字列は %(<dictionary key>)s 形式の文字列代入を用います。使えるキーについては LogRecord 属性 に書いてあります。

次のメッセージフォーマット文字列は、人が読みやすい形式の時刻、メッセージの深刻度、およびメッセージの内容を、順番に出力します:

'%(asctime)s - %(levelname)s - %(message)s'

フォーマッタは、ユーザが設定できる関数を使って、生成時刻をタプルに記録します。デフォルトでは、 time.localtime() が使われます。特定のフォーマッタインスタンスに対してこれを変更するには、インスタンスの converter 属性を time.localtime() や time.gmtime() と同じ署名をもつ関数に設定してください。すべてのフォーマッタインスタンスに対してこれを変更するには、例えば全てのロギング時刻を GMT で表示するには、フォーマッタクラスの converter 属性を (GMT 表示の time.gmtime に) 設定してください。

ロギングの環境設定

プログラマは、ロギングを 3 種類の方法で設定できます:

上述の設定メソッドを呼び出す Python コードを明示的に使って、ロガー、ハンドラ、そしてフォーマッタを生成する

ロギング設定ファイルを作り、それを fileConfig() 関数を使って読み込む

設定情報の辞書を作り、それを dictConfig() 関数に渡す

最後の2つの選択肢については、 環境設定のための関数 で解説しています。以下の例では、Python コードを使って、とても簡単なロガー、コンソールハンドラ、そして簡単なフォーマッタを設定しています:

import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

このモジュールを実行すると、コマンドラインによって以下の出力がなされます:

$ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message

以下の Python モジュールは、ロガー、ハンドラ、フォーマッタをほとんど上述の例と同じように生成していますが、オブジェクト名だけが異なります:

import logging
import logging.config

logging.config.fileConfig('logging.conf')

# create logger
logger = logging.getLogger('simpleExample')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

これが logging.conf ファイルです:

[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

出力は、設定ファイルに基づく例とだいたい同じです:

$ python simple_logging_config.py
2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
2005-03-19 15:38:55,979 - simpleExample - INFO - info message
2005-03-19 15:38:56,054 - simpleExample - WARNING - warn message
2005-03-19 15:38:56,055 - simpleExample - ERROR - error message
2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message

この通り、設定ファイルの方法は、主に設定とコードが分かれ、非コーダがロギングプロパティを変えやすくなるという点で、 Python コードの方法より少し優れています。

なお、設定ファイルで参照されるクラス名は、logging モジュールに対して相対であるか、通常のインポート機構を使って解決される絶対である値でなければなりません。従って、(logging モジュールに相対な) WatchedFileHandler または (Python インポートパスとして mypackage が使えるとき、パッケージ mypackage のモジュール mymodule で定義されたクラスに) mypackage.mymodule.MyHandler のどちらかが使えます。

Python 2.7 では、、ロギングを設定するのに新しく、辞書に設定情報を持たせる手段が導入されました。これは、上で概説した設定ファイルに基づく方法による機能の上位版を提供し、新しいアプリケーションやデプロイにはこのメソッドが推奨されます。Python の辞書を使って設定情報を保持し、辞書は他の用途にも使えるので、設定の選択肢が広がります。例えば、JSON フォーマットの設定ファイルや、YAML 処理機能が使えれば YAML フォーマットのファイルを使って、設定辞書を構成できます。また、もちろん、Python コードで辞書を構成し、ソケットを通して pickle 化された形式を受け取るなど、アプリケーションで意味があるいかなるやり方でも使えます。

ここに、YAML フォーマットにおける新しい辞書に基づく方法での、上述の例と同じ設定の例を挙げます:

version: 1
formatters:
  simple:
    format: format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
loggers:
  simpleExample:
    level: DEBUG
    handlers: [console]
    propagate: no
root:
  level: DEBUG
  handlers: [console]

辞書を使ったロギングについて詳細は、 環境設定のための関数 を参照してください。

環境設定が与えられないとどうなるか

ロギング環境設定を与えられないと、ロギングイベントを出力しなければならないのに、イベントを出力するハンドラが見つからないことがあります。この状況での logging パッケージの振る舞いは、Python のバージョンに依ります。

Python 2.x では、振る舞いは以下の通りです:

logging.raiseExceptions が False (製品モード) なら、イベントは黙って捨てられます。

logging.raiseExceptions が True (開発モード) なら、メッセージ ‘No handlers could be found for logger X.Y.Z’ が一度表示されます。

ライブラリのためのロギングの設定

ロギングを使うライブラリを開発するときは、ライブラリがどのようにロギングを使うのか、例えば使われているロガーの名前などを、ドキュメントにしておくべきです。ロギングの設定については、いくつか考えておくべきこともあります。使っているアプリケーションがロギングを使っていなくて、ライブラリコードがロギングを呼び出すと、 (前の節で解説したように) 重大度 WARNING 以上のイベントが、 sys.stderr に表示されます。これが最高のデフォルトの振る舞いと見なされます。

何らかの理由で、ロギング設定がなされていないときにメッセージを表示させたくない なら、あなたのライブラリのトップレベルロガーに何もしないハンドラを取り付けられます。このハンドラは何も処理しないというだけで、全てのライブラリイベントに対してハンドラが見つかるので、メッセージが表示されることを防げます。ライブラリのユーザがアプリケーションでの使用のためにロギングを設定したら、それはおそらくハンドラを追加する設定でしょうが、そしてレベルが適切に設定されたら、ライブラリコード内でなされたロギングの呼び出しは、通常通りそのハンドラに出力を送るようになります。

何もしないハンドラ NullHandler (Python 2.7 以降) は、 logging パッケージに含まれます。このハンドラのインスタンスを、 (ロギング設定がなされていないときにライブラリのログイベントを sys.stderr に出力させたく ないなら) ライブラリの名前空間で使われるトップレベルロガーに取り付けられます。ライブラリ foo によるすべてのロギングが、 ‘foo.x’, ‘foo.x.y’ その他に該当する名前のロガーによってなされるなら:

import logging
logging.getLogger('foo').addHandler(logging.NullHandler())

とすれば望んだ効果が得られるでしょう。組織が複数のライブラリを作り出すなら、指定されるロガー名は単に ‘foo’ ではなく、 ‘orgname.foo’ になります。

注意事項: ライブラリのロガーには、 NullHandler 以外のハンドラを追加しない ことを強く推奨します。これは、ハンドラの設定が、あなたのライブラリを使うアプリケーション開発者に伝播するからです。アプリケーション開発者は、対象となる聴衆と、そのアプリケーションにどのハンドラが最も適しているかを知っているからです。ハンドラを ‘ボンネットの中で’ 加えてしまうと、ユニットテストをして必要に応じたログを送達する能力に干渉しかねません。

ロギングレベル

ログレベルの数値は以下の表のように与えられています。これらは基本的に自分でレベルを定義したい人のためのもので、定義するレベルを既存のレベルの間に位置づけるためには具体的な値が必要になります。もし数値が他のレベルと同じだったら、既存の値は上書きされその名前は失われます。

レベル | 数値
CRITICAL | 50
ERROR | 40
WARNING | 30
INFO | 20
DEBUG | 10
NOTSET | 0

レベルはロガーに関連付けることもでき、開発者が設定することも、保存されたログ記録設定を読み込む際に設定することもできます。ロガーに対してログ記録メソッドが呼び出されると、ロガーは自らのレベルとメソッド呼び出しに関連付けられたレベルを比較します。ロガーのレベルがメソッド呼び出しのレベルよりも高い場合、実際のログメッセージは生成されません。これはログ出力の冗長性を制御するための基本的なメカニズムです。

ログ記録されるメッセージは LogRecord クラスのインスタンスとしてエンコードされます。ロガーがあるイベントを実際にログ出力すると決定した場合、ログメッセージから LogRecord インスタンスが生成されます。

ログ記録されるメッセージは、ハンドラ (handlers) を通してディスパッチ機構にかけられます。ハンドラは Handler クラスのサブクラスのインスタンスで、ログ記録された (LogRecord 形式の) メッセージが、そのメッセージの伝達対象となる相手 (エンドユーザ、サポートデスクのスタッフ、システム管理者、開発者) に行き着くようにする役割を持ちます。ハンドラには特定の出力先を意図された LogRecord インスタンスが渡されます。各ロガーは 0 個以上のハンドラを (Logger の addHandler() メソッド) で関連付けることができます。ロガーに直接関連付けられたハンドラに加えて、ロガーの上位にあるロガーすべてに関連付けられたハンドラ がメッセージを処理する際に呼び出されます。 (ただしロガーの propagate フラグが false 値にセットされている場合を除きます。その場合は、祖先ハンドラへの伝搬はそこで止まります。)

ロガーと同様に、ハンドラは関連付けられたレベルを持つことができます。ハンドラのレベルはロガーのレベルと同じ方法で、フィルタとして働きます。ハンドラがあるイベントを実際に処理すると決定した場合、 emit() メソッドが使われ、メッセージを出力先に送信します。ほとんどのユーザ定義の emit() のサブクラスで、この emit() をオーバライドする必要があるでしょう。

カスタムレベル

独自のレベルを定義することは可能ですが、必須ではなく、実経験上は既存のレベルが選ばれます。しかし、カスタムレベルが必要だと確信するなら、レベルの定義には多大な注意を払うべきで、 ライブラリの開発の際、カスタムレベルを定義することはとても悪いアイデア になり得ます。これは、複数のライブラリの作者がみな独自のカスタムレベルを定義すると、与えられた数値が異なるライブラリで異なる意味になりえるため、開発者がこれを制御または解釈するのが難しくなるからです。

便利なハンドラ

基底の Handler クラスに加え、多くの便利なサブクラスが提供されています:

StreamHandler インスタンスは、メッセージをストリーム (ファイル風オブジェクト) に送ります。

FileHandler インスタンスは、メッセージをディスクファイルに送ります。

BaseRotatingHandler は、ある地点でログファイルを循環させるハンドラの基底クラスです。これを直接インスタンス化することは意図されていません。代わりに、 RotatingFileHandler や TimedRotatingFileHandler を使用してください。

RotatingFileHandler インスタンスは、メッセージをディスクファイルに送り、最大ログファイル数とログファイル循環をサポートします。

TimedRotatingFileHandler インスタンスは、メッセージをディスクファイルに送り、ログファイルを特定時間のインターバルで循環します。

SocketHandler インスタンスは、メッセージを TCP/IP ソケットに送ります。

DatagramHandler インスタンスは、メッセージを UDP ソケットに送ります。

SMTPHandler インスタンスは、メッセージを指示された email アドレスに送ります。

SysLogHandler インスタンスは、メッセージを、必要ならばリモートマシンの、Unix syslog daemon に送ります。

NTEventLogHandler インスタンスは、メッセージを Windows NT/2000/XP イベントログに送ります。

MemoryHandler インスタンスは、メッセージを、特定の基準が満たされる度に流される、メモリ中のバッファに送ります。

HTTPHandler インスタンスは、メッセージを、 GET または POST セマンティクスを使って、HTTP サーバに送ります。

WatchedFileHandler インスタンスは、ロギングする先のファイルを監視します。ファイルが変更されると、そのファイルは閉じられ、ファイル名を使って再び開かれます。このハンドラは Unix 系のシステムにのみ便利です。Windows は、使われている基の機構をサポートしていません。

NullHandler インスタンスは、エラーメッセージに対して何もしません。これは、ライブラリ開発者がロギングを使いたいが、ライブラリのユーザがロギングを設定してなくても ‘No handlers could be found for logger XXX’ メッセージを表示させたくない場合に使われます。詳しい情報は ライブラリのためのロギングの設定 を参照してください。

バージョン 2.7 で追加: NullHandler クラス。

コア logging パッケージで、 NullHandler, StreamHandler および FileHandler クラスが定義されています。その他のハンドラは、サブモジュールの logging.handlers で定義されています。(環境設定機能のためのサブモジュール、 logging.config もあります。)

ログメッセージは、 Formatter クラスのインスタンスを通してフォーマット化してから表示されます。このインスタンスは、 % 演算子と辞書で使うのに適切なフォーマット文字列で初期化されます。

複数のメッセージを一括してフォーマット化するには、 BufferingFormatter が使えます。(一連の文字列のそれぞれに適用される) フォーマット文字列に加え、ヘッダとトレーラフォーマット文字列も提供されています。

ロガーレベルおよび/またはハンドラレベルに基づくフィルタリングで十分でなければ、 Filter のインスタンスを Logger と Handler インスタンスの両方に (addFilter() を通して) 加えることができます。メッセージの処理を続ける前に、ロガーもハンドラも、全てのフィルタに許可を求めます。フィルタのいずれかが偽値を返したら、メッセージの処理は続けられません。

基本の addFilter() 機能では、特定のロガー名でのフィルタリングをできます。この機能が使われると、指名されたロガーに送られたメッセージとその子だけがフィルタを通り、その他は落とされます。

ログ記録中に発生する例外

logging パッケージは、ログを生成している間に起こる例外を飲み込むように設計されています。これは、ログ記録イベントを扱っている間に発生するエラー (ログ記録の設定ミス、ネットワークまたは他の同様のエラー) によってログ記録を使用するアプリケーションが早期に終了しないようにするためです。

SystemExit と KeyboardInterrupt 例外は決して飲み込まれません。 Handler サブクラスの emit() メソッドの間に起こる他の例外は、 handleError() メソッドに渡されます。

Handler の handleError() のデフォルト実装は、モジュールレベル変数 raiseExceptions が設定されているかどうかチェックします。設定されているなら、トレースバックが sys.stderr に出力されます。設定されていないなら、例外は飲み込まれます。

Note: raiseExceptions のデフォルト値は True です。これは、開発の間に起こるどんな例外についても通常は通知してほしいからです。実運用環境では raiseExceptions を False に設定することをお勧めします。

任意のオブジェクトをメッセージに使用する

前の節とそこで挙げた例では、イベントを記録するときに渡されたメッセージが文字列であると仮定していました。しかし、これは唯一の可能性ではありません。メッセージとして任意のオブジェクトを渡すことができます。そして、ロギングシステムがそのオブジェクトを文字列表現に変換する必要があるとき、オブジェクトの __str__() メソッドが呼び出されます。実際、そうしたければ、文字列表現を計算することを完全に避けることができます - 例えば、 SocketHandler は、イベントを pickle してネットワーク上で送信することでログ出力します。

最適化

message 引数の整形は、必要になるまで延期されます。しかしながら、ログ記録メソッドに渡す引数を計算するだけでもコストがかかる場合があります。ロガーが単にイベントを捨てるなら、その計算を避けたいと考えるかもしれません。どうするかを決定するために isEnabledFor() メソッドを呼ぶことができます。このメソッドは引数にレベルを取って、そのレベルの呼び出しに対して Logger がイベントを生成するなら true を返します。このようにコードを書くことができます:

if logger.isEnabledFor(logging.DEBUG):
    logger.debug('Message with %s, %s', expensive_func1(),
                                        expensive_func2())

このようにすると、ロガーの閾値が DEBUG より上に設定されている場合、 expensive_func1() と expensive_func2() の呼び出しは行われません。

これ以外にも、どんなログ情報が集められるかについてより正確なコントロールを必要とする、特定のアプリケーションでできる最適化があります。これは、ログ記録の間の不要な処理を避けるためにできることのリストです:

不要な情報 | それを避ける方法
呼び出しがどこから行われたかに関する情報 | logging._srcfile を None にする
スレッド情報 | logging.logThreads を 0 にする
プロセス情報 | logging.logProcesses を 0 にする

また、コア logging モジュールが基本的なハンドラだけを含んでいることに注意してください。 logging.handlers と logging.config をインポートしなければ、余分なメモリを消費することはありません。

参考

Module logging

logging モジュールの API リファレンスです。

Module logging.config

logging モジュールの環境設定 API です。

Module logging.handlers

logging モジュールに含まれる、便利なハンドラです。

ロギングクックブック

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

ロギングクックブック

Author:
Vinay Sajip <vinay_sajip at red-dove dot com>

このページでは、過去に見つかった、ロギングに関するいくつかの便利なレシピを紹介します。

複数のモジュールでロギングを使う

logging.getLogger('someLogger') の複数回の呼び出しは同じロガーへの参照を返します。これは同じ Python インタプリタプロセス上で動いている限り、一つのモジュールの中からに限らず、モジュールをまたいでも当てはまります。同じオブジェクトへの参照という点でも正しいです。さらに、一つのモジュールの中で親ロガーを定義して設定し、別のモジュールで子ロガーを定義する (ただし設定はしない) ことが可能で、すべての子ロガーへの呼び出しは親にまで渡されます。まずはメインのモジュールです:

import logging
import auxiliary_module

# create logger with 'spam_application'
logger = logging.getLogger('spam_application')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)

logger.info('creating an instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
logger.info('created an instance of auxiliary_module.Auxiliary')
logger.info('calling auxiliary_module.Auxiliary.do_something')
a.do_something()
logger.info('finished auxiliary_module.Auxiliary.do_something')
logger.info('calling auxiliary_module.some_function()')
auxiliary_module.some_function()
logger.info('done with auxiliary_module.some_function()')

そして補助モジュール (auxiliary module) がこちらです:

import logging

# create logger
module_logger = logging.getLogger('spam_application.auxiliary')

class Auxiliary:
    def __init__(self):
        self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
        self.logger.info('creating an instance of Auxiliary')
    def do_something(self):
        self.logger.info('doing something')
        a = 1 + 1
        self.logger.info('done doing something')

def some_function():
    module_logger.info('received a call to "some_function"')

出力はこのようになります:

2005-03-23 23:47:11,663 - spam_application - INFO -
   creating an instance of auxiliary_module.Auxiliary
2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO -
   creating an instance of Auxiliary
2005-03-23 23:47:11,665 - spam_application - INFO -
   created an instance of auxiliary_module.Auxiliary
2005-03-23 23:47:11,668 - spam_application - INFO -
   calling auxiliary_module.Auxiliary.do_something
2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO -
   doing something
2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO -
   done doing something
2005-03-23 23:47:11,670 - spam_application - INFO -
   finished auxiliary_module.Auxiliary.do_something
2005-03-23 23:47:11,671 - spam_application - INFO -
   calling auxiliary_module.some_function()
2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO -
   received a call to 'some_function'
2005-03-23 23:47:11,673 - spam_application - INFO -
   done with auxiliary_module.some_function()

複数のハンドラとフォーマッタ

ロガーは通常の Python オブジェクトです。 addHandler() メソッドは追加されるハンドラの個数について最小値も最大値も定めていません。時にアプリケーションがすべての深刻度のすべてのメッセージをテキストファイルに記録しつつ、同時にエラーやそれ以上のものをコンソールに出力することが役に立ちます。これを実現する方法は、単に適切なハンドラを設定するだけです。アプリケーションコードの中のログ記録の呼び出しは変更されずに残ります。少し前に取り上げた単純なモジュール式の例を少し変えるとこうなります:

import logging

logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

「アプリケーション」のコードは複数のハンドラについて何も気にしていないことに注目してください。変更した箇所は新しい fh という名のハンドラを追加して設定したところがすべてです。

新しいハンドラを高い、もしくは低い深刻度に対するフィルタと共に生成できることは、アプリケーションを書いてテストを行うときとても助けになります。デバッグ用にたくさんの print 文を使う代わりに logger.debug を使いましょう。あとで消したりコメントアウトしたりしなければならない print 文と違って、 logger.debug 命令はソースコードの中にそのまま残しておいて再び必要になるまで休眠させておけます。その時必要になるのはただロガーおよび/またはハンドラの深刻度の設定をいじることだけです。

複数の出力先にログを出力する

コンソールとファイルに、別々のメッセージ書式で、別々の状況に応じたログ出力を行わせたいとしましょう。例えば DEBUG よりも高いレベルのメッセージはファイルに記録し、 INFO 以上のレベルのメッセージはコンソールに出力したいという場合です。また、ファイルにはタイムスタンプを記録し、コンソールには出力しないとします。以下のようにすれば、こうした挙動を実現できます:

import logging

# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d %H:%M',
                    filename='/temp/myapp.log',
                    filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)

# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.')

# Now, define a couple of other loggers which might represent areas in your
# application:

logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')

logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')

このスクリプトを実行すると、コンソールには以下のように表示されるでしょう:

root        : INFO     Jackdaws love my big sphinx of quartz.
myapp.area1 : INFO     How quickly daft jumping zebras vex.
myapp.area2 : WARNING  Jail zesty vixen who grabbed pay from quack.
myapp.area2 : ERROR    The five boxing wizards jump quickly.

そして、ファイルは以下のようになるはずです:

10-22 22:19 root         INFO     Jackdaws love my big sphinx of quartz.
10-22 22:19 myapp.area1  DEBUG    Quick zephyrs blow, vexing daft Jim.
10-22 22:19 myapp.area1  INFO     How quickly daft jumping zebras vex.
10-22 22:19 myapp.area2  WARNING  Jail zesty vixen who grabbed pay from quack.
10-22 22:19 myapp.area2  ERROR    The five boxing wizards jump quickly.

これを見て分かる通り、 DEBUG メッセージはファイルだけに出力され、その他のメッセージは両方に出力されます。

この例ではコンソールとファイルのハンドラだけを使っていますが、実際には任意の数のハンドラや組み合わせを使えます。

設定サーバの例

ログ記録設定サーバを使うモジュールの例です:

import logging
import logging.config
import time
import os

# read initial config file
logging.config.fileConfig('logging.conf')

# create and start listener on port 9999
t = logging.config.listen(9999)
t.start()

logger = logging.getLogger('simpleExample')

try:
    # loop through logging calls to see the difference
    # new configurations make, until Ctrl+C is pressed
    while True:
        logger.debug('debug message')
        logger.info('info message')
        logger.warn('warn message')
        logger.error('error message')
        logger.critical('critical message')
        time.sleep(5)
except KeyboardInterrupt:
    # cleanup
    logging.config.stopListening()
    t.join()

そしてファイル名を受け取ってそのファイルをサーバに送るスクリプトですが、それに先だってバイナリエンコード長を新しいログ記録の設定として先に送っておきます:

#!/usr/bin/env python
import socket, sys, struct

with open(sys.argv[1], 'rb') as f:
    data_to_send = f.read()

HOST = 'localhost'
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('connecting...')
s.connect((HOST, PORT))
print('sending config...')
s.send(struct.pack('>L', len(data_to_send)))
s.send(data_to_send)
s.close()
print('complete')

ネットワーク越しのロギングイベントの送信と受信

ログイベントをネットワーク越しに送信し、受信端でそれを処理したいとしましょう。 SocketHandler インスタンスを送信端のルートロガーに接続すれば、簡単に実現できます:

import logging, logging.handlers

rootLogger = logging.getLogger('')
rootLogger.setLevel(logging.DEBUG)
socketHandler = logging.handlers.SocketHandler('localhost',
                    logging.handlers.DEFAULT_TCP_LOGGING_PORT)
# don't bother with a formatter, since a socket handler sends the event as
# an unformatted pickle
rootLogger.addHandler(socketHandler)

# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.')

# Now, define a couple of other loggers which might represent areas in your
# application:

logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')

logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')

受信端では、 SocketServer モジュールを使って受信プログラムを作成しておきます。簡単な実用プログラムを以下に示します:

import pickle
import logging
import logging.handlers
import socketserver
import struct

class LogRecordStreamHandler(socketserver.StreamRequestHandler):
    """Handler for a streaming logging request.

    This basically logs the record using whatever logging policy is
    configured locally.
    """

    def handle(self):
        """
        Handle multiple requests - each expected to be a 4-byte length,
        followed by the LogRecord in pickle format. Logs the record
        according to whatever policy is configured locally.
        """
        while True:
            chunk = self.connection.recv(4)
            if len(chunk) < 4:
                break
            slen = struct.unpack('>L', chunk)[0]
            chunk = self.connection.recv(slen)
            while len(chunk) < slen:
                chunk = chunk + self.connection.recv(slen - len(chunk))
            obj = self.unPickle(chunk)
            record = logging.makeLogRecord(obj)
            self.handleLogRecord(record)

    def unPickle(self, data):
        return pickle.loads(data)

    def handleLogRecord(self, record):
        # if a name is specified, we use the named logger rather than the one
        # implied by the record.
        if self.server.logname is not None:
            name = self.server.logname
        else:
            name = record.name
        logger = logging.getLogger(name)
        # N.B. EVERY record gets logged. This is because Logger.handle
        # is normally called AFTER logger-level filtering. If you want
        # to do filtering, do it at the client end to save wasting
        # cycles and network bandwidth!
        logger.handle(record)

class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
    """
    Simple TCP socket-based logging receiver suitable for testing.
    """

    allow_reuse_address = 1

    def __init__(self, host='localhost',
                 port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
                 handler=LogRecordStreamHandler):
        socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
        self.abort = 0
        self.timeout = 1
        self.logname = None

    def serve_until_stopped(self):
        import select
        abort = 0
        while not abort:
            rd, wr, ex = select.select([self.socket.fileno()],
                                       [], [],
                                       self.timeout)
            if rd:
                self.handle_request()
            abort = self.abort

def main():
    logging.basicConfig(
        format='%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s')
    tcpserver = LogRecordSocketReceiver()
    print('About to start TCP server...')
    tcpserver.serve_until_stopped()

if __name__ == '__main__':
    main()

先にサーバを起動しておき、次にクライアントを起動します。クライアント側では、コンソールには何も出力されません; サーバ側では以下のようなメッセージを目にするはずです:

About to start TCP server...
   59 root            INFO     Jackdaws love my big sphinx of quartz.
   59 myapp.area1     DEBUG    Quick zephyrs blow, vexing daft Jim.
   69 myapp.area1     INFO     How quickly daft jumping zebras vex.
   69 myapp.area2     WARNING  Jail zesty vixen who grabbed pay from quack.
   69 myapp.area2     ERROR    The five boxing wizards jump quickly.

特定のシナリオでは pickle にはいくつかのセキュリティ上の問題があることに注意してください。これが問題になる場合、 makePickle() メソッドをオーバーライドして代替手段を実装することで異なるシリアライズ手法を使用できます。代替シリアライズ手法を使うように上記のスクリプトを修正することもできます。

コンテキスト情報をログ記録出力に付加する

時にはログ記録出力にログ関数の呼び出し時に渡されたパラメータに加えてコンテキスト情報を含めたいこともあるでしょう。たとえば、ネットワークアプリケーションで、クライアント固有の情報 (例: リモートクライアントの名前、 IP アドレス) もログ記録に残しておきたいと思ったとしましょう。 extra パラメータをこの目的に使うこともできますが、いつでもこの方法で情報を渡すのが便利なやり方とも限りません。また接続ごとに Logger インスタンスを生成する誘惑に駆られるかもしれませんが、生成した Logger インスタンスはガーベジコレクションで回収されないので、これは良いアイデアとは言えません。この例は現実的な問題ではないかもしれませんが、 Logger インスタンスの個数がアプリケーションの中でログ記録が行われるレベルの粒度に依存する場合、 Logger インスタンスの個数が事実上無制限にならないと、管理が難しくなります。

LoggerAdapter を使ったコンテキスト情報の伝達

ログ記録イベントの情報と一緒に出力される文脈情報を渡す簡単な方法は、 LoggerAdapter を使うことです。このクラスは Logger のように見えるように設計されていて、 debug(), info(), warning(), error(), exception(), critical(), log() の各メソッドを呼び出せるようになっています。これらのメソッドは対応する Logger のメソッドと同じ引数を取るので、二つの型を取り替えて使うことができます。

LoggerAdapter のインスタンスを生成する際には、 Logger インスタンスと文脈情報を収めた辞書風 (dict-like) のオブジェクトを渡します。 LoggerAdapter のログ記録メソッドを呼び出すと、呼び出しをコンストラクタに渡された配下の Logger インスタンスに委譲し、その際文脈情報をその委譲された呼び出しに埋め込みます。 LoggerAdapter のコードから少し抜き出してみます:

def debug(self, msg, *args, **kwargs):
    """
    Delegate a debug call to the underlying logger, after adding
    contextual information from this adapter instance.
    """
    msg, kwargs = self.process(msg, kwargs)
    self.logger.debug(msg, *args, **kwargs)

LoggerAdapter の process() メソッドが文脈情報をログ出力に加える舞台です。そこではログ記録呼び出しのメッセージとキーワード引数が渡され、加工された (可能性のある) それらの情報を配下のロガーへの呼び出しに渡し直します。このメソッドのデフォルト実装ではメッセージは元のままですが、キーワード引数にはコンストラクタに渡された辞書風オブジェクトを値として “extra” キーが挿入されます。もちろん、呼び出し時に “extra” キーワードを使った場合には何事もなかったかのように上書きされます。

“extra” を用いる利点は辞書風オブジェクトの中の値が LogRecord インスタンスの __dict__ にマージされることで、辞書風オブジェクトのキーを知っている Formatter を用意して文字列をカスタマイズするようにできることです。それ以外のメソッドが必要なとき、たとえば文脈情報をメッセージの前や後ろにつなげたい場合には、 LoggerAdapter から process() を望むようにオーバライドしたサブクラスを作ることが必要なだけです。次に挙げるのはこのクラスを使った例で、コンストラクタで使われる「辞書風」オブジェクトにどの振る舞いが必要なのかも示しています:

import logging

class ConnInfo:
    """
    An example class which shows how an arbitrary class can be used as
    the 'extra' context information repository passed to a LoggerAdapter.
    """

    def __getitem__(self, name):
        """
        To allow this instance to look like a dict.
        """
        from random import choice
        if name == 'ip':
            result = choice(['127.0.0.1', '192.168.0.1'])
        elif name == 'user':
            result = choice(['jim', 'fred', 'sheila'])
        else:
            result = self.__dict__.get(name, '?')
        return result

    def __iter__(self):
        """
        To allow iteration over keys, which will be merged into
        the LogRecord dict before formatting and output.
        """
        keys = ['ip', 'user']
        keys.extend(self.__dict__.keys())
        return keys.__iter__()

if __name__ == '__main__':
    from random import choice
    levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
    a1 = logging.LoggerAdapter(logging.getLogger('a.b.c'),
                               { 'ip' : '123.231.231.123', 'user' : 'sheila' })
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
    a1.debug('A debug message')
    a1.info('An info message with %s', 'some parameters')
    a2 = logging.LoggerAdapter(logging.getLogger('d.e.f'), ConnInfo())
    for x in range(10):
        lvl = choice(levels)
        lvlname = logging.getLevelName(lvl)
        a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')

このスクリプトが実行されると、出力は以下のようになります:

2008-01-18 14:49:54,023 a.b.c DEBUG    IP: 123.231.231.123 User: sheila   A debug message
2008-01-18 14:49:54,023 a.b.c INFO     IP: 123.231.231.123 User: sheila   An info message with some parameters
2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1     User: jim      A message at CRITICAL level with 2 parameters
2008-01-18 14:49:54,033 d.e.f INFO     IP: 192.168.0.1     User: jim      A message at INFO level with 2 parameters
2008-01-18 14:49:54,033 d.e.f WARNING  IP: 192.168.0.1     User: sheila   A message at WARNING level with 2 parameters
2008-01-18 14:49:54,033 d.e.f ERROR    IP: 127.0.0.1       User: fred     A message at ERROR level with 2 parameters
2008-01-18 14:49:54,033 d.e.f ERROR    IP: 127.0.0.1       User: sheila   A message at ERROR level with 2 parameters
2008-01-18 14:49:54,033 d.e.f WARNING  IP: 192.168.0.1     User: sheila   A message at WARNING level with 2 parameters
2008-01-18 14:49:54,033 d.e.f WARNING  IP: 192.168.0.1     User: jim      A message at WARNING level with 2 parameters
2008-01-18 14:49:54,033 d.e.f INFO     IP: 192.168.0.1     User: fred     A message at INFO level with 2 parameters
2008-01-18 14:49:54,033 d.e.f WARNING  IP: 192.168.0.1     User: sheila   A message at WARNING level with 2 parameters
2008-01-18 14:49:54,033 d.e.f WARNING  IP: 127.0.0.1       User: jim      A message at WARNING level with 2 parameters

Filter を使ったコンテキスト情報の伝達

ユーザ定義の Filter を使ってログ出力にコンテキスト情報を加えることもできます。 Filter インスタンスは、渡された LogRecords を修正することができます。これにより、適切なフォーマット文字列や必要なら Formatter を使って、出力となる属性を新しく追加することも出来ます。

例えば、web アプリケーションで、処理されるリクエスト (または、少なくともその重要な部分) は、スレッドローカル (threading.local) な変数に保存して、 Filter からアクセスすることで、 LogRecord にリクエストの情報を追加できます。例えば、リモート IP アドレスやリモートユーザのユーザ名にアクセスしたいなら、上述の LoggerAdapter の例のように属性名 ‘ip’ や ‘user’ を使うといったようにです。そのばあい、同じフォーマット文字列を使って以下に示すように似たような出力を得られます。これはスクリプトの例です:

import logging
from random import choice

class ContextFilter(logging.Filter):
    """
    This is a filter which injects contextual information into the log.

    Rather than use actual contextual information, we just use random
    data in this demo.
    """

    USERS = ['jim', 'fred', 'sheila']
    IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']

    def filter(self, record):

        record.ip = choice(ContextFilter.IPS)
        record.user = choice(ContextFilter.USERS)
        return True

if __name__ == '__main__':
   levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
   logging.basicConfig(level=logging.DEBUG,
                       format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
   a1 = logging.getLogger('a.b.c')
   a2 = logging.getLogger('d.e.f')

   f = ContextFilter()
   a1.addFilter(f)
   a2.addFilter(f)
   a1.debug('A debug message')
   a1.info('An info message with %s', 'some parameters')
   for x in range(10):
       lvl = choice(levels)
       lvlname = logging.getLevelName(lvl)
       a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')

そして、実行時に、以下のようになります:

2010-09-06 22:38:15,292 a.b.c DEBUG    IP: 123.231.231.123 User: fred     A debug message
2010-09-06 22:38:15,300 a.b.c INFO     IP: 192.168.0.1     User: sheila   An info message with some parameters
2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1       User: sheila   A message at CRITICAL level with 2 parameters
2010-09-06 22:38:15,300 d.e.f ERROR    IP: 127.0.0.1       User: jim      A message at ERROR level with 2 parameters
2010-09-06 22:38:15,300 d.e.f DEBUG    IP: 127.0.0.1       User: sheila   A message at DEBUG level with 2 parameters
2010-09-06 22:38:15,300 d.e.f ERROR    IP: 123.231.231.123 User: fred     A message at ERROR level with 2 parameters
2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1     User: jim      A message at CRITICAL level with 2 parameters
2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1       User: sheila   A message at CRITICAL level with 2 parameters
2010-09-06 22:38:15,300 d.e.f DEBUG    IP: 192.168.0.1     User: jim      A message at DEBUG level with 2 parameters
2010-09-06 22:38:15,301 d.e.f ERROR    IP: 127.0.0.1       User: sheila   A message at ERROR level with 2 parameters
2010-09-06 22:38:15,301 d.e.f DEBUG    IP: 123.231.231.123 User: fred     A message at DEBUG level with 2 parameters
2010-09-06 22:38:15,301 d.e.f INFO     IP: 123.231.231.123 User: fred     A message at INFO level with 2 parameters

複数のプロセスからの単一ファイルへのログ記録

ログ記録はスレッドセーフであり、単一プロセスの複数のスレッドからの単一ファイルへのログ記録はサポート されています が、複数プロセス からの単一ファイルへのログ記録はサポート されません 。なぜなら、複数のプロセスをまたいで単一のファイルへのアクセスを直列化する標準の方法が Python には存在しないからです。複数のプロセスから単一ファイルへログ記録しなければならないなら、最も良い方法は、すべてのプロセスが SocketHandler に対してログ記録を行い、独立したプロセスとしてソケットサーバを動かすことです。ソケットサーバはソケットから読み取ってファイルにログを書き出します。 (この機能を実行するために、既存のプロセスの 1 つのスレッドを割り当てることもできます) 以下の節では、このアプローチをさらに詳細に文書化しています。動作するソケット受信プログラムが含まれているので、アプリケーションに組み込むための出発点として使用できるでしょう。

multiprocessing モジュールを含む最近のバージョンの Python を使用しているなら、複数のプロセスからファイルへのアクセスを直列化するために multiprocessing モジュールの Lock クラスを使って独自のハンドラを書くことができます。既存の FileHandler とそのサブクラスは現在のところ multiprocessing を利用していませんが、将来は利用するようになるかもしれません。現在のところ multiprocessing モジュールが提供するロック機能はすべてのプラットホームで動作するわけではないことに注意してください。 (http://bugs.python.org/issue3770 参照)

ファイルの循環を使う

ログファイルがある大きさに達したら、新しいファイルを開いてそこにログを取りたいことがあります。そのファイルをある数だけ残し、その数のファイルが生成されたらファイルを循環し、ファイルの数も大きさも制限したいこともあるでしょう。この利用パターンのために、logging パッケージは RotatingFileHandler を提供しています:

import glob
import logging
import logging.handlers

LOG_FILENAME = 'logging_rotatingfile_example.out'

# Set up a specific logger with our desired output level
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
              LOG_FILENAME, maxBytes=20, backupCount=5)

my_logger.addHandler(handler)

# Log some messages
for i in range(20):
    my_logger.debug('i = %d' % i)

# See what files are created
logfiles = glob.glob('%s*' % LOG_FILENAME)

for filename in logfiles:
    print(filename)

この結果として、アプリケーションのログ履歴の一部である、 6 つに別れたファイルが得られます:

logging_rotatingfile_example.out
logging_rotatingfile_example.out.1
logging_rotatingfile_example.out.2
logging_rotatingfile_example.out.3
logging_rotatingfile_example.out.4
logging_rotatingfile_example.out.5

最新のファイルはいつでも logging_rotatingfile_example.out で、サイズの上限に達するたびに拡張子 .1 を付けた名前に改名されます。既にあるバックアップファイルはその拡張子がインクリメントされ (.1 が .2 になるなど)、 .6 ファイルは消去されます。

明らかに、ここでは例示のためにファイルの大きさをとんでもなく小さな値に設定しています。実際に使うときは maxBytes を適切な値に設定してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

正規表現 HOWTO

Author:
A.M. Kuchling

概要

このドキュメントは re モジュールを使って Python で正規表現を扱うための導入のチュートリアルです。ライブラリレファレンスの正規表現の節よりもやさしい入門ドキュメントを用意しています。

入門

re モジュールは Python 1.5 で追加され、Perl スタイルの正規表現パターンを提供します。それ以前の Python では regex モジュールが Emacs スタイルのパターンを提供していました。 regex モジュールは Python 2.5 で完全に削除されました。

正規表現 regular expressions (REs や regexes または regex patterns と呼ばれます) は本質的に小さく、Python 内部に埋め込まれた高度に特化したプログラミング言語で re モジュールから利用可能です。この小さな言語を利用することで、マッチさせたい文字列に適合するような文字列の集合を指定することができます; この集合は英文や e-mail アドレスや TeX コマンドなど、どんなものでも構いません。「この文字列は指定したパターンにマッチしますか?」「このパターンはこの文字列のどの部分にマッチするのですか?」といったことを問い合わせることができます。正規表現を使って文字列を変更したりいろいろな方法で別々の部分に分割したりすることもできます。

正規表現パターンは一連のバイトコードとしてコンパイルされ、 C で書かれたマッチングエンジンによって実行されます。より進んだ利用法では、エンジンがどう与えられた正規表現を実行するかに注意することが必要になり、高速に実行できるバイトコードを生成するように正規表現を書くことになります。このドキュメントでは最適化までは扱いません、それにはマッチングエンジンの内部に対する十分な理解が必要だからです。

正規表現言語は相対的に小さく、制限されています、そのため正規表現を使ってあらゆる文字列処理作業を行なえるわけではありません。正規表現を使って行うことのできる作業もあります、ただ表現はとても複雑なものになります。それらの場合では、Python コードを書いた方がいいでしょう; Python コードは念入りに作られた正規表現より遅くなりますが、おそらくより読み易いでしょう。

単純なパターン

まずはできるだけ簡単な正規表現を学ぶことから始めてみましょう。正規表現は文字列の操作に使われるので、ますは最も一般的な作業である文字のマッチングをしてみます。

正規表現の基礎を成す計算機科学 (決定、非決定有限オートマトン) の詳細な説明については, コンパイラ作成に関するテキストブックをどれでもいいので参照して下さい。

文字のマッチング

多くの活字や文字は単純にそれ自身とマッチします。例えば、 test という正規表現は文字列 test に厳密にマッチします。 (大文字小文字を区別しないモードでその正規表現が Test や TEST にも同様にマッチすることもできます; 詳しくは後述します。)

この規則には例外が存在します; いくつかの文字は特別な 特殊文字 (metacharacters) で、それら自身にマッチしません。代わりに通常のマッチするものとは違うという合図を出したり、正規表現の一部に対して繰り返したり、意味を変えたりして影響を与えます。このドキュメントの中の多くは様々な特殊文字とそれが何をするかについて論じることになります。

ここに特殊文字の完全な一覧があります; これらの意味はこの HOWTO の残りの部分で説明します:

. ^ $ * + ? { } [ ] \ | ( )

最初に扱う特殊文字は [ と ] です。これらは文字クラスを指定します、文字クラスはマッチしたい文字の集合です。文字は個別にリストにしても構いませんし、二つの文字を '-' でつなげて文字を範囲で与えてもかまいません。たとえば [abc] は a, b, または c のどの文字列にもマッチします; これは [a-c] で同じ文字集合を範囲で表現しても全く同じです。小文字のアルファベットのみにマッチしたい場合、 [a-z] の正規表現をつかうことになるでしょう。

特殊文字は文字クラスの内部では有効になりません。例えば、 [akm$] は 'a', 'k', 'm' または '$' にマッチします; '$' は通常は特殊文字ですが、文字クラス内部では特殊な性質は取り除かれます。

文字クラス内のリストにない文字に対しても 補集合 を使ってマッチすることができます。補集合はクラスの最初の文字として '^' を含めることで表すことができます; 文字クラスの外側の '^' は単に '^' 文字にマッチします。例えば、 [^5] は '5' を除く任意の文字にマッチします。

おそらく最も重要な特殊文字はバックスラッシュ \ でしょう。 Python の文字列リテラルのようにバックスラッシュに続けていろいろな文字を入力することでいろいろな特殊シーケンスの合図を送ることができます。また、バックスラッシュはすべての特殊文字をエスケープするのにも利用されます、つまり、特殊文字をマッチさせることができます; 例えば、 [ または \ にマッチさせたい場合、それらをバックスラッシュに続けることで特殊な意味を除きます: \[ または \\ 。

いくつかの '\' で始まる特殊シーケンスはあらかじめ定義された文字集合を表していて、しばしば便利に使うことができます、例えば、10進数の集合、文字の集合、空白以外の任意の文字の集合。以下のあらかじめ定義された特殊シーケンスは利用可能なものの一部です。等価なクラスがバイト文字列パターンに対してもあります。ユニコード文字列パターンのためのシーケンスおよび拡張クラス定義の完全なリストについては、 正規表現のシンタックス の最後の部分を見てください。

\d

任意の十進数とマッチします；これは集合 [0-9] と同じ意味です。

\D

任意の非数字文字とマッチします；これは集合 [^0-9] と同じ意味です。

\s

任意の空白文字とマッチします；これは集合 [\t\n\r\f\v] と同じ意味です。

\S

任意の非空白文字とマッチします；これは集合 [^\t\n\r\f\v] と同じ意味です。

\w

任意の英数文字および下線とマッチします；これは、集合 [a-zA-Z0-9_] と同じ意味です。

\W

任意の非英数文字とマッチします；これは集合 [^a-zA-Z0-9_] と同じ意味です。

これらのシーケンスは文字クラス内に含めることができます。例えば、 [\s,.] は空白文字や ',' または '.' にマッチする文字クラスです。

この節での最後の特殊文字は . です。これは改行文字を除く任意の文字にマッチします、さらに改行文字に対してもマッチさせる代替モード (re.DOTALL) があります。 '.' は「任意の文字」にマッチさせたい場合に利用されます。

繰り返し

さまざまな文字集合をマッチさせることは正規表現で最初にできるようになることで、これは文字列に対するメソッドですぐにできることではありません。しかし、正規表現がより力を発揮する場面がこれだけだとすると、正規表現はあまり先進的とはいえません。正規表現の力をもう一つの能力は、正規表現の一部が何度も繰り返されるようものを指定できることです。

最初にとりあげる繰り返しのための最初の特殊文字は * です。 * は文字リテラル * とはマッチしません; その代わりに前の文字が厳密に1回ではなく、0回以上繰り返されるパターンを指定します。

例えば、 ca*t は ct (a が0文字)、 cat (a が1文字)、 caaat (a 3文字)、続々。正規表現エンジンには C の int 型のサイズのために 20億文字の a とのマッチングができないなど多くの内部制限があります; おそらくそれほど大きい文字列を構築するほどの十分なメモリはないので、その制限に達することはありません。

* のような繰り返しは 貪欲 (greedy) です; 正規表現を繰り返したいとき、マッチングエンジンは可能な限り何度も繰り返そうと試みます。パターンの後ろの部分にマッチしない場合、マッチングエンジンは戻って少ない繰り返しを再び試みます。

例をステップ、ステップで進めていくとより明確にわかります。正規表現 a[bcd]*b を考えましょう。この表現は文字 'a' と文字クラス [bcd] の0回以上の文字と最後の 'b' にマッチします。この正規表現が文字列 abcbd に対してマッチする作業を想像してみましょう。

ステップ | マッチした文字列 | 説明
1 | a | a が正規表現にマッチ。
2 | abcbd | 正規表現エンジンが [bcd]* で文字列の最後まで可能な限り進む。
3 | 失敗 | エンジンが b とのマッチを試みるが、現在の位置が文字列の最後なので、失敗する。
4 | abcb | 戻って [bcd]* は一文字少なくマッチ。
5 | 失敗 | 再び b へのマッチを試みるが、現在の文字は最後の文字 'd' 。
6 | abc | 再び戻る, [bcd]* は bc のみにマッチ。
7 | abcb | 再び b を試みる。今回の現在位置の文字は 'b' なので成功。

正規表現の終端に達して、 abcd にマッチしました。この例はマッチングエンジンが最初に到達できるところまで進みマッチしなかった場合、逐次戻って再度残りの正規表現とのマッチを次々と試みること様子を示しています。エンジンは [bcd]* とマッチしなくなるまで戻ります、さらに続く正規表現とのマッチに失敗した場合にエンジンは正規表現と文字列が完全にマッチしないと結論づけることになります。

別の繰り返しの特殊文字は + です、この特殊文字は1回以上の繰り返しにマッチします。 * と + に違いに対しては十分注意して下さい; * は 0回 以上の繰り返しにマッチします、つまり繰り返す部分が全くなくても問題ありません、一方で + は少なくとも 1回 は表われる必要があります。同様の例を使うと ca+t は cat (a 1文字), caaat (a 3文字), とマッチし、 ct とはマッチしません。

2回以上の繰り返しを制限する修飾子も存在します。クエスチョンマーク ? は0か1回のどちらかにマッチします; これはオプションであることを示していると考えることもできます。例えば、 home-?brew は homebrew と home-brew のどちらにもマッチします。

より複雑に繰り返しを制限するのは {m,n} です、ここで m と n は10進数の整数です。この修飾子は最低 m 回、最大で n 回の繰り返すことを意味しています。例えば、 a/{1,3}b は a/b と a//b そして a///b にマッチします。これはスラッシュの無い ab や4つのスラッシュを持つ a////b とはマッチしません。

m か n のどちらかは省略することができます; そうした場合省略された値はもっともらしい値と仮定されます。 m の省略は下限 0 と解釈され、 n の省略は無限の上限として解釈されます — 実際には上限は前に述べたように20億ですが、無限大とみなしてもいいでしょう。

還元主義的素養のある読者は、3つの修飾子がこの表記で表現できることに気づくでしょう。 {0,} は * と同じで {1,} は + と、そして {0,1} は ? と同じです。利用できる場合には *, + または ? を利用した方が賢明です、そうすることで単純に、短く読み易くすることができます。

正規表現を使う

これまででいくつかの単純な正規表現に触れてきました、実際に Python ではこれらをどう使えばいいのでしょう? re モジュールは正規表現エンジンに対するインターフェースを提供していて、それらを使うことで正規表現をオブジェクトにコンパイルし、マッチを実行することができます。

正規表現をコンパイルする

正規表現はパターンオブジェクトにコンパイルされます、パターンオブジェクトは多くの操作、パターンマッチの検索や文字列の置換の実行などのメソッドを持っています:

>>> import re
>>> p = re.compile('ab*')
>>> print p
<_sre.SRE_Pattern object at 0x...>

re.compile() はいくつかの flags 引数を受け付けることができます、この引数はさまざまな特別な機能を有効にしたり、構文を変化させたりします。利用できる設定に何があるかは後に飛ばすことにして、簡単な例をやることにしましょう:

>>> p = re.compile('ab*', re.IGNORECASE)

正規表現は文字列として re.compile() に渡されます。正規表現は文字列として扱われますが、それは正規表現が Python 言語のコアシステムに含まれないためです、そのため正規表現を表わす特殊な構文はありません。 (正規表現を全く必要としないアプリケーションも存在します、そのためそれらを含めて言語仕様を無駄に大きくする必要はありません) その代わり、 re モジュールは socket や zlib モジュールのような通常の C 拡張モジュールとして Python に含まれています。

正規表現を文字列としておくことで Python 言語はより簡素に保たれていますが、そのため1つの欠点があります、これについては次の節で話題とします。

バックスラッシュ感染症

先に述べたように、正規表現は特別な形式や特殊な文字の特別な意味を意味を除くことを示すためにバックスラッシュ文字 ('\') を利用します。これは Python が文字列リテラルに対して、同じ文字を同じ目的で使うことと衝突します。

\section という文字列 (これは LaTeX ファイルでみかけます) にマッチする正規表現を書きたいとします。どんなプログラムを書くか考え、マッチして欲しい文字列をはじめに考えます。次に、バックスラッシュや他の特殊文字をバックスラッシュに続けて書くことでエスケープしなければいけません、その結果 \\section のような文字列となります。こうしてできた re.compile() に渡す文字列は \\section でなければいけません。しかし、これを Python の文字列リテラルとして扱うにはこの二つのバックスラッシュを 再びエスケープする必要があります。

文字 | 段階
\section | マッチさせるテキスト
\\section | re.compile() のためのバックスラッシュエスケープ
"\\\\section" | 文字列リテラルのためのバックスラッシュエスケープ

要点だけをいえば、リテラルとしてのバックスラッシュにマッチさせるために、正規表現文字列として '\\\\' 書かなければいけません、なぜなら正規表現は \\ であり、通常の Python の文字列リテラルとしてはそれぞれのバックスラッシュは \\ で表現しなければいけないからです。正規表現に関してこのバックスラッシュの繰り返しの機能は、たくさんのバックスラッシュの繰り返しを生むことになり、その結果として作られる文字列は理解することが難しくなります。

この問題の解決策としては正規表現に対しては Python の raw string 記法を使うことです; 'r' を文字列リテラルの先頭に書くことでバックスラッシュは特別扱いされなくなります、つまり "\n" は改行を含む1つの文字からなる文字列であるのに対して、 r"\n" は2つの文字 '\' と 'n' を含む文字列となります。多くの場合 Python コードの中の正規表現はこの raw string 記法を使って書かれます。

通常の文字列 | Raw string
"ab*" | r"ab*"
"\\\\section" | r"\\section"
"\\w+\\s+\\1" | r"\w+\s+\1"

マッチの実行

一旦コンパイルした正規表現を表現するオブジェクトを作成したら、次に何をしますか? パターンオブジェクトはいくつかのメソッドや属性を持っています。ここでは、その中でも最も重要なものについて扱います; 完全なリストは re ドキュメントを参照して下さい。

メソッド/属性 | 目的
match() | 文字列の先頭で正規表現とマッチするか判定します
search() | 文字列を操作して、正規表現がどこにマッチするか調べます。
findall() | 正規表現にマッチする部分文字列を全て探しだしリストとして返します。
finditer() | 正規表現にマッチする部分文字列を全て探しだし iterator として返します

マッチしない場合 match() と search() は None を返します。もしマッチに成功した場合、 MatchObject インスタンスを返します、このインスタンスはマッチの情報を含んでいます: どこで始まりどこで終わったか、マッチした部分文字列や等々。

re モジュールで対話的に実験することで学ぶこともできます。 Tkinter が利用できれば、Python に含まれるデモプログラム Tools/scripts/redemo.py を見るといいかもしれません。このデモは正規表現と文字列を入力し、正規表現がマッチしたかどうかを表示します。 redemo.py は複雑な正規表現のデバッグを試みるときにも便利に使うことができます。 Phil Schwartz の Kodos [http://kodos.sourceforge.net/] も正規表現パターンを使った開発とテストのための対話的なツールです。

この HOWTO では例として標準の Python インタプリタを使います。最初に Python インタプリタを起動して、 re モジュールをインポートし、正規表現をコンパイルします:

Python 2.2.2 (#1, Feb 10 2003, 12:57:01)
>>> import re
>>> p = re.compile('[a-z]+')
>>> p
<_sre.SRE_Pattern object at 0x...>

さて、いろいろな文字列を使って正規表現 [a-z]+ に対するマッチングを試してみましょう。空の文字列は全くマッチしません、なぜなら + は「1回以上の繰り返し」を意味するからです。この場合では match() は None を返すべきで、インタプタは何も出力しません。明確にするために match() の結果を明示的に出力することもできます:

>>> p.match("")
>>> print p.match("")
None

次に、 tempo のようなマッチすべき文字列を試してみましょう。この場合 match() は MatchObject を返します、後で使うために変数に結果を残す必要があります:

>>> m = p.match('tempo')
>>> print m
<_sre.SRE_Match object at 0x...>

これで MatchObject にマッチした文字列に対する情報を問い合わせることができます。 MatchObject インスタンスもいくつかのメソッドと属性を持っています; 重要なものは:

メソッド/属性 | 目的
group() | 正規表現にマッチした文字列を返す
start() | マッチの開始位置を返す
end() | マッチの終了位置を返す
span() | マッチの位置 (start, end) を含むタプルを返す

これらのメソッドを試せば、その意味はすぐに理解できます:

>>> m.group()
'tempo'
>>> m.start(), m.end()
(0, 5)
>>> m.span()
(0, 5)

group() は正規表現にマッチした部分文字列を返します。 start() と end() はマッチの開始と終了のインデクスを返します。 span() は開始と終了のインデクスの両方をを1つのタプルとして返します。 match() メソッドは正規表現が文字列の最初にマッチするかどうかを調べるので、 start() は常に0です。ただし、 search() メソッドは文字列に対してパターンを操作するのでその場合にはマッチが0から始まるとは限りません。:

>>> print p.match('::: message')
None
>>> m = p.search('::: message') ; print m
<_sre.SRE_Match object at 0x...>
>>> m.group()
'message'
>>> m.span()
(4, 11)

実際のプログラムでは MatchObject を変数に記憶しておき, その次に None なのか調べるのが一般的なスタイルです。普通このようにします:

p = re.compile( ... )
m = p.match( 'string goes here' )
if m:
    print 'Match found: ', m.group()
else:
    print 'No match'

2つのパターンメソッドはパターンにマッチした全てを返します。 findall() はマッチした文字列のリストを返します:

>>> p = re.compile('\d+')
>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
['12', '11', '10']

findall() は結果が返される前に結果となるリスト全体を作成します。 finditer() メソッドは MatchObject インスタンスのシーケンスを iterator として返します。 [1]

>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable-iterator object at 0x401833ac>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)

モジュールレベルの関数

パターンオブジェクトを作成し、メソッドを呼び出す必要はありません; re モジュールはトップレベルの関数 match(), search(), findall(), sub() 続々、も提供しています。これらの関数は対応するパターンメソッドと同じ引数をとり、正規表現文字列を最初の引数として追加して使います、そして同じく None または MatchObject インスタンスを返します:

>>> print re.match(r'From\s+', 'Fromage amk')
None
>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
<_sre.SRE_Match object at 0x...>

内部では、これらの関数は単にパターンオブジェクトを生成し、その適切なメソッドを呼び出しています。それらは、コンパイル済みのオブジェクトもキャッシュとして記憶するので、同じ正規表現に対する将来の呼び出しは高速になります。

これらのモジュールレベル関数を使うべきでしょうか、それともパターンを取得し、メソッド自身を呼び出すべきでしょうか? この選択は利用する正規表現がどのくらい頻繁に利用されるかと個人のコーディングスタイルに依存します。正規表現がコード内で一度しか使われない場合、モジュール関数の方がより便利でしょう。プログラムが多くの正規表現を含んだり、同じ正規表現がいくつかの場所で再利用されるときは定義を一箇所にまとめ、使う前に全ての正規表現をコンパイルしておくことはやる価値があるはずです。標準ライブラリから例を挙げます、 xmllib.py から抜粋で:

ref = re.compile( ... )
entityref = re.compile( ... )
charref = re.compile( ... )
starttagopen = re.compile( ... )

私はたいていの場合、一回のみの利用であってもコンパイル済みオブジェクトを使うことを好みますが、そこまで厳格な人は少数派でしょう。

コンパイルフラグ

コンパイルフラグは正規表現の動作をいくつかの側面から変更します。フラグは re モジュール下で二つの名前で利用することができます、例えば長い名前は IGNORECASE で短い名前は1文字で I のようになっています。 (1文字形式は Perl のパターン修飾子と同じ形式を使います; 例えば re.VERBOSE の短かい形式は re.X です。) 複数のフラグが OR ビット演算で指定することができます; 例えば re.I | re.M は I と M フラグの両方を設定します。

ここに利用可能なフラグの表があります、それぞれについてのより詳細な説明が後に続きます。

フラグ | 意味
DOTALL, S | . を改行を含む任意の文字にマッチするようにします
IGNORECASE, I | 大文字小文字を区別しないマッチを行います
LOCALE, L | ロケールに対応したマッチを行います
MULTILINE, M | ^ や $ に作用して、複数行にマッチング
VERBOSE, X | 冗長な正規表現を利用できるようにして、よりきれいで理解しやすくまとめることができます

I

IGNORECASE

大文字小文字を区別しないマッチングを実行します; 文字クラスや文字列リテラルは大文字小文字を無視してマッチします。例えば [A-Z] は小文字にもマッチします、また Spam は Spam, spam, または spAM にもマッチします。この小文字化は現在のロケールは考慮に入れません; ロケールの考慮は LOCALE も設定することで行います。

L

LOCALE

\w, \W, \b, そして \B を現在のロケールに依存させます。

ロケールは C ライブラリの機能の一つで、言語の違いを考慮したプログラム作成を容易にするためのものです。例えば、フランス語の文書を処理したい場合、単語のマッチに \w+ を利用したくなります、しかし、 \w は文字クラス [A-Za-z] のみとマッチします; 'é' または 'ç' にはマッチしません。システムが適切に設定されていて、ロケールがフランス語に設定されていれば、 C 関数がプログラムに 'é' をアルファベットとして扱うべきだと伝えます。 LOCALE フラグを正規表現のコンパイル時に設定することで、 \w を使う C 関数を利用するコンパイル済みオブジェクトを生み出すことになります; これは速度は遅くなりますが、期待通りに \w+ をフランス語の単語にマッチさせることができます。

M

MULTILINE

(^ と $ についてはまだ説明していません; これらは さらなる特殊文字 の節で説明します。)

通常 ^ は文字列の先頭にマッチし、 $ は文字列の末尾と文字列の末尾に改行(があれば)その直前にマッチします。このフラグが指定されると、 ^ は文字列の先頭と文字列の中の改行に続く各行の先頭にマッチします。同様に $ 特殊文字は文字列の末尾と各行の末尾(各改行の直前)のどちらにもマッチします。

S

DOTALL

特別な文字 '.' を改行を含む全ての任意の文字とマッチするようにします; このフラグが無しでは、 '.' は改行 以外 の全てにマッチします。

X

VERBOSE

このフラグはより柔軟な形式で正規表現を読み易く書けるようにします。このフラグを指定すると、正規表現の中の空白は無視されます、ただし、文字クラス内やエスケープされていないバックスラッシュに続く空白の場合は例外として無視されません; これによって正規表現をまとめたり、インデントしてより明確にすることができます。このフラグはさらにエンジンが無視するコメントを追加することもできます; コメントは '#' で示します、これは文字クラスやエスケープされていないバックスラッシュに続くものであってはいけません。

例えば、ここに re.VERBOSE を利用した正規表現があります; 読み易いと思いませんか?

charref = re.compile(r"""
 &[#]                  # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

冗長な表現を利用しない設定の場合、正規表現はこうなります:

charref = re.compile("&#(0[0-7]+"
                     "|[0-9]+"
                     "|x[0-9a-fA-F]+);")

上の例では、Python の文字列リテラルの自動結合によって正規表現を小さな部分に分割しています、それでも re.VERBOSE を使った場合に比べるとまだ難しくなっています。

パターンの能力をさらに

ここまでで、正規表現の機能のほんの一部を扱ってきました。この節では、新たにいくつかの特殊文字とグループを使ってマッチしたテキストの一部をどう取得するかについて扱います。

さらなる特殊文字

これまでで、まだ扱っていない特殊文字がいくつかありました。そのほとんどをこの節で扱っていきます。

残りの特殊文字の内いくつかは ゼロ幅アサーション zero-width-assertions に関するものです。これらは文字列に対してエンジンを進めません; 文字列を全く利用しない代わりに、単純に成功か失敗かを利用します。例えば、 \b は現在位置が単語の境界であることを示します; \b によってエンジンの読んでいる位置は全く変化しません。つまり、これはゼロ幅アサーションは繰り返し使うことがありません、一度ある位置でマッチしたら、明らかに無限回マッチできます。

|

代替 (alternation) または “or” 演算子。 A と B が正規表現の場合、 A|B は A または B のどちらの文字列にもマッチします。 | は複数の文字列をかわるがわる試す場合でもうまく動作するように優先度はとても低くなっています Crow|Servo は Crow または Servo のどちらにもマッチします、 Cro, 'w' または 'S', ervo とはマッチしません。

リテラル '|' にマッチするには、 \| を利用するか、 [|] のように文字クラス内に収めて下さい。

^

行の先頭にマッチします。 MULTILINE フラグが設定されない場合には、文字列の先頭にのみマッチします。 MULTILINE モードでは文字列内の各改行の直後にマッチします。

例えば、 行の先頭の From にのみマッチさせたい場合には ^From 正規表現を利用します。

>>> print re.search('^From', 'From Here to Eternity')
<_sre.SRE_Match object at 0x...>
>>> print re.search('^From', 'Reciting From Memory')
None

$

行の末尾にマッチします、行の末尾は文字列の末尾と改行文字の直前として定義されます。

>>> print re.search('}$', '{block}')
<_sre.SRE_Match object at 0x...>
>>> print re.search('}$', '{block} ')
None
>>> print re.search('}$', '{block}\n')
<_sre.SRE_Match object at 0x...>

リテラル '$' にマッチするには、 \$ を利用するか、 [$] のように文字クラス内に収めて下さい。

\A

文字列の先頭にのみマッチします。 MULTILINE モードでない場合には \A と ^ は実質的に同じです。 MULTILINE モードでのこれらの違いは: \A は依然として文字列の先頭にのみマッチしますが、 ^ は文字列内に改行文字に続く部分があればそこにマッチすることです。

\Z

文字列の末尾にのみマッチします。

\b

単語の境界。これはゼロ幅アサーションで、単語の始まりか終わりにのみマッチします。単語は英数文字のシーケンスとして定義されます、つまり単語の終わりは空白か非英数文字として表われます。

以下の例では class がそのものの単語のときのみマッチします; 別の単語内に含まれている場合はマッチしません。

>>> p = re.compile(r'\bclass\b')
>>> print p.search('no class at all')
<re.MatchObject instance at 80c8f28>
>>> print p.search('the declassified algorithm')
None
>>> print p.search('one subclass is')
None

この特別なシーケンスを利用するときには二つの微妙な点を心にとめておく必要があります。まずひとつめは Python の文字列リテラルと表現の間の最悪の衝突を引き起すことです。 Python の文字列リテラルでは \b は ASCII 値8のバックスペース文字です。 raw string を利用していない場合、Python は \b をバックスペースに変換し、正規表現は期待するものとマッチしなくなります。以下の例はさきほどと同じ正規表現のように見えますが、正規表現文字列の前の 'r' が省略されています:

>>> p = re.compile('\bclass\b')
>>> print p.search('no class at all')
None
>>> print p.search('\b' + 'class' + '\b')
<re.MatchObject instance at 80c3ee0>

ふたつめはこのアサーションが利用できない文字列クラスの内部では Python の文字列リテラルとの互換性のために、 \b はバックスペース文字を表わすことになるということです。

\B

別のゼロ幅アサーションで、 \b と逆で、現在の位置が単語の境界でないときにのみマッチします。

グルーピング

正規表現にマッチするかどうかだけでなく、より多くの情報を得なければいけない場合は多々あります。正規表現はしばしば、正規表現をいくつかのサブグループに分けて興味ある部分にマッチするようにして、文字列を分割するのに使われます。例えば、 RFC-822 ヘッダ行は ':' を挟んでこのようにヘッダ名と値に分割されます:

From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
MIME-Version: 1.0
To: editor@example.com

これはヘッダ全体にマッチし、そしてヘッダ名にマッチするグループとヘッダの値にマッチする別のグループを持つように正規表現を書くことで扱うことができます、

グループは特殊文字 '(', ')' で表わされます。 '(' と ')' は数学での意味とほぼ同じ意味を持っています; その中に含まれた表現はまとめてグループ化され、グループの中身を *, +, ? や {m,n} のような繰り返しの修飾子を使って繰り返すことができます。例えば、 (ab)* は ab の0回以上の繰り返しにマッチします。

>>> p = re.compile('(ab)*')
>>> print p.match('ababababab').span()
(0, 10)

'(' と ')' で示されたグループはマッチしたテキストの開始と末尾のインデクスも capture できます; インデクスは group(), start(), end(), and span() に引数を与えることで取得できます。グループは 0 から番号付けされます。グループ 0 は常に存在し; 正規表現全体です、つまり MatchObject メソッドは常にグループ0 をデフォルト引数として持っています。マッチしたテキストの範囲を capture しないグループの表し方については後で扱います:

>>> p = re.compile('(a)b')
>>> m = p.match('ab')
>>> m.group()
'ab'
>>> m.group(0)
'ab'

サブグループは左から右へ1づつ番号付けされます。グループはネストしてもかまいません; 番号を決めるには、単に開き括弧を左から右へ数え上げます:

>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'

group() には一回に複数の引数を渡してもかまいません、その場合にはそれらのグループに対応する値を含むタプルを返します。

>>> m.group(2,1,2)
('b', 'abc', 'b')

groups() メソッドは 1 から全てのサブグループの文字列を含むタプルを返します。:

>>> m.groups()
('abc', 'b')

パターン中で後方参照を利用することで、前に取り出されたグループが文字列の中の現在位置で見つかるように指定できます。例えば、 \1 はグループ1の内容が現在位置で見つかった場合成功し、それ以外の場合に失敗します。 Python の文字列リテラルでもバックスラッシュに続く数字は任意の文字を文字列に含めるために使われるということを心に留めておいて下さい、そのため正規表現で後方参照を含む場合には raw string を必ず利用して下さい。

例えば、以下の正規表現は二重になった単語を検出します。

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

このような後方参照は文字列を検索するだけの用途では多くの場合役に立ちません。 — このように繰り返されるテキストフォーマットは少数です。— しかし、文字列の置換をする場合には とても 有効であることに気づくでしょう。

取り出さないグループと名前つきグループ

念入りに作られた正規表現は多くのグループを利用します、その利用法には対象となる部分文字列を取り出す、正規表現自身をグループ化したり構造化する、という二つの方法があります。複雑な正規表現では、グループ番号を追っていくことは困難になっていきます。この問題の解決を助ける二つの機能があります。その両方が正規表現を拡張するための一般的な構文を利用します、まずはそれらをみてみましょう。

Perl 5 は標準の正規表現にいくつかの機能が追加されました、 Python の re モジュールもその内のほとんどをサポートしています。 Perl の正規表現が標準の正規表現の違いが混乱を招かないように、新たな一文字の特殊文字や \ で始まる新しい特殊シーケンスを選ぶことは困難でした。新しい特殊文字として & を選ぶとすると古い正規表現では & を通常の文字とみなされ、 \& や [&] と書くようにエスケープされません。

解決策として Perl 開発者が選んだものは (?...) を正規表現構文として利用することでした。括弧の直後の ? は構文エラーとなります、これは ? で繰り返す対象がないためです、そのためこれは互換性の問題を持ち込みません。 ? の直後の文字はどの拡張が利用されるかを示しています、つまり、 (?=foo) は一つの拡張を利用したもの (肯定先読みアサーション) となり、 (?:foo) は別の拡張を利用した表現(foo を含む取り込まないグループ)となります。

Python は Perl の拡張構文にさらに拡張構文を加えています。クエスチョンマークの後の最初の文字が P の場合、それが Python 特有の拡張であることを示しています。現在では二つの拡張が存在しています: (?P<name>...) は名前つきグループを定義し、 (?P=name) は名前つきグループに対する後方参照となります。 Perl 5 の将来のバージョンで同様の機能が別の構文を利用して追加された場合、 re モジュールは互換性のために Python 特有の構文を残しつつ、新しい構文をサポートするように変更されます。

さて、ここまでで一般的な拡張構文を見てきたので、複雑な正規表現を単純化するための機能について話を戻しましょう。グループは左から右に番号づけされ、複雑な正規表現は多くの番号を利用することになるので、正確な番号づけを追い続けることは難しくなります。そのような複雑な正規表現を変更することは悩ましい問題となります: 正規表現の先頭に新しいグループを挿入すれば、それ以後の全ての番号を変更することにまります。

グループの内容を取得することなく、正規表現の一部を集めるために、グループを利用したくなることがよくあります。このことを、取り込まないグループを使うことで明示的に示すことができます: (?:...), ... は任意の正規表現に置き換えることができます。:

>>> 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'"')

取得する番号9を覚えるよりも、 m.group('zonem') で取得した方が明らかに簡単にすみます。

後方参照のための構文 (...)\1 はグループ番号を参照します。グループ番号の代わりに、グループ名を利用する変種があるのは当然でしょう。これはもう一つの Python 拡張です: (?=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'

先読みアサーション (Lookahead Assertions)

他のゼロ幅アサーションは先読みアサーションです。先読みアサーションは肯定、否定の両方の形式が利用可能です、これを見てください:

(?=...)

肯定先読みアサーション。 ... で表わす正規表現が現在位置でマッチすれば成功し、それ以外の場合失敗します。しかし、表現が試行された場合でもエンジンは先に進みません; パターンの残りの部分はアサーションの開始時点から右に試行します。

(?!...)

否定先読みアサーション。これは肯定アサーションの逆で、正規表現が文字列の現在位置にマッチ しなかった 場合に成功します。

より具体的にするため、先読みが便利な場合をみてみましょう。ファイル名にマッチし、 . で分けられた基本部分と拡張子に分離する単純なパターンを考えましょう。例えば、 news.rc は news が基本部分で rc がファイル名の拡張子です。

マッチするパターンはとても単純です:

.*[.].*$

. を特別に扱う必要があることに注意して下さい、なぜならこれは特殊文字だからです; 上では文字クラス内に入れました。また $ が続いていることにも注意して下さい; これは文字列の残り全てが拡張子に含まれることを保障するために追加されています。この正規表現は foo.bar, autoexec.bat, sendmail.cf, printers.conf にマッチします。

さて、問題を少し複雑にしてみましょう; 拡張子が bat でないファイル名にマッチしたい場合はどうでしょう？間違った試み:

.*[.][^b].*$ この最初の bat を除く試みは、最初の文字が b でないことを要求します。これは誤っています、なぜなら foo.bar にもマッチしないからです。

.*[.]([^b]..|.[^a].|..[^t])$

正規表現が混乱してきました。最初の解決策を取り繕って、以下の場合に合わせることを要求しています: 拡張子の最初の文字は b でなく; 二番目の文字は a でなく; 三番目の文字は t でない。これは foo.bar を受け付けますが、 autoexec.bat は拒否します。しかし、三文字の拡張子を要求し、 sendmail.cf のような二文字の拡張子を受け付けません。これを修正するのにパターンを再び複雑にすることになります。

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$

三番目の試みでは、 sendmail.cf のように三文字より短い拡張子とマッチするために第二第三の文字を全てオプションにしています。

パターンはさらに複雑さを増し、読みにくく、理解が難しくなりました。より悪いことに、問題が bat と exe 両方を拡張子から除きたい場合に変わった場合、パターンはより複雑で混乱しやすいものになります。

否定先読みはこの混乱全てを取り除きます:

.*[.](?!bat$).*$ 否定先読みは以下を意味します: この位置で拡張子 bat にマッチしない場合、残りのパターンが試行されます; もし bat$ にマッチすればパターン全体が失敗します。 $ を続けることで、 sample.batch にように bat で始まる拡張子を許容することを保証しています。

他のファイル名の拡張子を除くことも簡単です; 単純にアサーション内に拡張子を代替 (or) で加えます。以下のパターンは bat や exe のどちらで終わるファイル名を除外します:

.*[.](?!bat$|exe$).*$

文字列を変更する

ここまででは単純に静的な文字列に対する検索を実行してきました。正規表現は文字列を様々な方法で変更するのにもよく使われます。変更には以下のパターンメソッドが利用されます:

メソッド/属性 | 目的
split() | 文字列をリストに分割する、正規表現がマッチした全ての場所で分割を行う
sub() | 正規表現にマッチした全ての文字列を発見し、別の文字列に置き換えます
subn() | sub() と同じことをしますが、新しい文字列と置き換えの回数を返します

文字列の分割

パターンの split() メソッドは正規表現にマッチした全ての場所で文字列を分割し、各部分のリストを返します。これは文字列の split() メソッドに似ていますが、より一般的なデリミタを提供します; split() は空白や固定文字列による分割のみをサポートしてます。期待しているとおり、 モジュールレベルの re.split() 関数もそうです。

.split(string[, maxsplit=0])

string を正規表現のマッチで分割します。正規表現内に取り込むための括弧が利用されている場合、その内容も結果のリストの一部として返されます。 maxsplit が非ゼロの場合、最大で maxsplit の分割が実行されます。

maxsplit に値を渡すことで、分割される回数を制限することができます。 maxsplit が非ゼロの場合、最大で maxsplit の分割が行なわれ、文字列の残りがリストの最終要素として返されます。以下の例では、デリミタは任意の英数文字のシーケンスです。

>>> p = re.compile(r'\W+')
>>> p.split('This is a test, short and sweet, of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test, short and sweet, of split().', 3)
['This', 'is', 'a', 'test, short and sweet, of split().']

興味の対象がデリミタの間のテキストだけでなく、デリミタが何なのかということを知りたい場合はよくあります。取りこみ用の括弧を正規表現に使った場合、その値もリストの一部として返されます。以下の呼び出しを比較してみましょう:

>>> p = re.compile(r'\W+')
>>> p2 = re.compile(r'(\W+)')
>>> p.split('This... is a test.')
['This', 'is', 'a', 'test', '']
>>> p2.split('This... is a test.')
['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']

モジュールレベル関数 re.split() は最初の引数に利用する正規表現を追加しますが、それ以外は同じです。:

>>> re.split('[\W]+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('([\W]+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('[\W]+', 'Words, words, words.', 1)
['Words', 'words, words.']

検索と置換

もう一つのよくある作用は、パターンにマッチする全てを探し、異なる文字列に置換します。 sub() メソッドは置換する値をとります、文字列と関数の両方をとることができ、文字列を処理します。

.sub(replacement, string[, count=0])

string 内で最も長く、他の部分と重複するところがない正規表現をを replacement に置換した文字列を返します。パターンが見つからなかった場合 string は変更されずに返されます。

オプション引数 count はパターンの出現の最大置換回数です; count は非負の整数でなければいけません。デフォルト値 0 は全ての出現で置換することを意味します。

ここに sub() メソッドを使った単純な例があります。これは色の名前を colour に置換します:

>>> p = re.compile( '(blue|white|red)')
>>> p.sub( 'colour', 'blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub( 'colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'

subn() メソッドも同じ働きをします、ただ新しい文字列と置換の実行回数を含む 2-タプルを返します:

>>> p = re.compile( '(blue|white|red)')
>>> p.subn( 'colour', 'blue socks and red shoes')
('colour socks and colour shoes', 2)
>>> p.subn( 'colour', 'no colours at all')
('no colours at all', 0)

空文字列とのマッチは直前にマッチした部分と隣接していない場合にのみ置換されます。

>>> p = re.compile('x*')
>>> p.sub('-', 'abxd')
'-a-b-d-'

replacement が文字列の場合、文字列内のバックスラッシュエスケープは処理されます。つまり、 \n は改行文字に \r はキャリッジリターンに、等となります。 \j のような未知のエスケープシーケンスはそのまま残されます。 \6 のような後方参照は正規表現内の対応するグループにマッチする文字列に置換されます。これを使うことで元のテキストの一部を、置換後の文字列に組み込むことができます。

この例は単語 section に続く { と } で閉じられた文字列にマッチし、 section を subsection に変更します:

>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First} section{second}')
'subsection{First} subsection{second}'

(?P<name>...) 構文で定義された名前つきグループを参照するための構文もあります。 \g<name> は name で名前づけされたグループにマッチする文字列を利用し、 \g<number> は対応するグループ番号を利用します。つまり \g<2> は \2 と等価ですが、 \g<2>0 のような置換文字列に対しては明確に異なります。 (\20 はグループ番号20への参照と解釈され、グループ2の後にリテラル文字 '0' が続くとは解釈されません。) 以下に示す置換は全て等価ですが、これらは文字列置換に全部で3種の変種を利用しています。:

>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<1>}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<name>}','section{First}')
'subsection{First}'

replacement は関数であっても構いません、関数を使うことでより一層の制御を行うことができます。 replacement が関数の場合、 pattern が重複せず現われる度、関数が呼び出されます。呼び出す度に関数には MatchObject 引数が渡されます、この情報を使って望みの置換文字列を計算し返すことができます。

以下の例では、置換関数は10進数を16進数に変換します:

>>> def hexrepl( match ):
...     "Return the hex string for a decimal number"
...     value = int( match.group() )
...     return hex(value)
...
>>> p = re.compile(r'\d+')
>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
'Call 0xffd2 for printing, 0xc000 for user code.'

モジュールレベルの re.sub() 関数を使うときには、パターンが最初の引数として渡されます。パターンはオブジェクトや文字列をとります; 正規表現フラグを指定する必要がある場合、パターンオブジェクトを最初の引数として使うか、修飾子を埋め込んだパターン文字列を使うかしなければいけません、例えば sub("(?i)b+", "x", "bbbb BBBB") は 'x x' を返します。

よくある問題

正規表現はいくつかの応用に対して強力なツールですが、いくつかの部分でそれらの振る舞いは直感的ではなく、期待通りに振る舞わないことがあります。この節では最もよくある落とし穴を指摘します。

文字列メソッドを利用する

いくつかの場合 re モジュールを利用することは間違いである場合があります。固定文字列や単一の文字クラスにマッチさせる場合や、 IGNORECASE フラグのような re の機能を利用しない場合、正規表現の全ての能力は必要とされていなでしょう。文字列は固定文字列に対する操作を実行するメソッドを持っていて、大きな汎用化された正規表現エンジンではなく、目的のために最適化された単一の小さな C loop で実装されているため、大抵の場合高速です.

一つの例としては、単一の固定文字列を別の固定文字列に置き換える作業がそうかもしれません; 例えば word を deed で置換したい場合です。 re.sub() はこのために使うことができるように見えますが、 replace() メソッドを利用することを考えた方がいいでしょう。 replace() は単語内の word も置換します、 swordfish は sdeedfish に変わることに注意して下さい。しかし、単純な正規表現 word も同様に動作します。 (単語の一部に対する置換の実行を避けるには、パターンを \bword\b として、 word が両側に単語の境界を必要とするようにします。これは replace() の能力を越えた仕事です。)

別のよくある作業は、文字列の中に出現する文字を全て削除することと、別の文字で置換することです。この作業を re.sub('\n', ' ', S) のようにして行うかもしれませんが、 translate() は削除と置換の両方の作業をこなし、正規表現操作よりも高速に行うことができます。

要は、 re モジュールに向う前に問題が高速で単純な文字列メソッドで解決できるか考えましょうということです。

match() 対 search()

match() 関数は文字列の先頭に正規表現がマッチするかどうか調べるだけで、一方 search() はマッチするために文字列を進めて走査します。この違いを認識しておくことは重要なことです。 match() は開始位置0でマッチしたときのみ報告します; もし開始位置0でマッチしなければ、 match() はそれを報告 しません 。:

>>> print re.match('super', 'superstition').span()
(0, 5)
>>> print re.match('super', 'insuperable')
None

一方 search() は文字列を先に進めて走査文字列を進めて走査し、最初にみつけたマッチを報告します。:

>>> print re.search('super', 'superstition').span()
(0, 5)
>>> print re.search('super', 'insuperable').span()
(2, 7)

しばしば、 re.match() を使い、 .* を正規表現の最初に付け加える誘惑にからされることがあるでしょう。この誘惑に打ち克って、代わりに re.search() を利用すべきです。正規表現コンパイラはマッチを探す処理の高速化のためにいくつかの解析を行います。そのような解析のうちのひとつはマッチの最初の文字が何であるか評価することです; 例えば、 Crow で始まるパターンは C から始まらなければいけません。解析によってエンジンは速やかに開始文字を探して走査します、 'C' が発見された場合にはじめて完全なマッチを試みます。

.* を追加することはこの最適化を無効にします、文字列の終端までの走査が必要となり、走査後には残りの正規表現とのマッチ部分を見つけるために引き返すことになります。代わりに re.search() を利用して下さい。

貪欲 (greedy) 対非貪欲 (non-greedy)

正規表現を繰り返す場合、 たとえば a* のように、できるだけパターンの多くにマッチするように動作することになります。この動作は、例えば角括弧で囲まれた HTML タグのような左右対称のデリミタの対にマッチしようという場合に問題となります。単一の HTML タグにマッチする素朴な正規表現はうまく動作しません、なぜならば .* は貪欲に動作するからです。:

>>> s = '<html><head><title>Title</title>'
>>> len(s)
32
>>> print re.match('<.*>', s).span()
(0, 32)
>>> print re.match('<.*>', s).group()
<html><head><title>Title</title>

正規表現は <html> 内の '<' にマッチし、 .* は残りの文字列の全てにマッチします。しかし、正規表現は以前残っています、 > は文字列の終端にマッチしないので、正規表現は一文字ずつ > とマッチするまで引き返すことになります。最終的にマッチする領域は <html> の '<' から </title> の '>' にまで及ぶことになりますが、これは望んだ結果ではありません。

この場合、解決法は非貪欲を示す修飾子 *?, +?, ?? または {m,n}? を利用することです、これらはテキストに可能な限り 少なく マッチします。上の例では、 '>' は最初の '<' とのマッチ後すぐに '>' を試みま、失敗した場合にはエンジンが文字を先に進め、 '>' が毎ステップ再試行されます。この動作は正しい結果を生み出します:

>>> print re.match('<.*?>', s).group()
<html>

(HTML や XML を正規表現でパースすることは苦痛を伴うものであることは記憶に留めておいて下さい。素早く、汚いパターンは大抵の場合うまく動作しますが、HTML と XML は 正規表現が破綻する特別な例です; 全ての可能な場合にうまく動作する正規表現を書き上げたときには、パターンは 非常に 複雑なものになります。そのような作業をする場合には HTML や XML パーサを利用しましょう。)

re.VERBOSE の利用

ここまでで、正規表現がとても簡潔な表記であることに気づいたでしょう、また、正規表現は読みやすいものでもないということにも気づいたことでしょう。そこそこに入り組んだ正規表現ははバックスラッシュ、括弧、特殊文字が長く続いて、読みにくく、理解しづらいものになります。

そのような正規表現に対しては正規表現をコンパイルする時に re.VERBOSE フラグを指定することが助けになります、なぜなら、そうすることによって正規表現を明確にフォーマットすることができるからです。

re.VERBOSE の効果はいくつかあります。正規表現内の文字クラス内に 無い 空白は無視されます。これは、 dog | cat のような表現が少々可読性の落ちる dog|cat と等価となるということです、しかし、 [a b] は依然として 'a', 'b', または空白にマッチします。加えて、正規表現にコメントを入れることもできるようになります; # 文字から次の改行までがコメントの範囲です。三重クォートを利用することで、正規表現をきちんとフォーマットすることができます:

pat = re.compile(r"""
 \s*                 # Skip leading whitespace
 (?P<header>[^:]+)   # Header name
 \s* :               # Whitespace, and a colon
 (?P<value>.*?)      # The header's value -- *? used to
                     # lose the following trailing whitespace
 \s*$                # Trailing whitespace to end-of-line
""", re.VERBOSE)

これは下よりはるかに読みやすいです:

pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$")

フィードバック

正規表現は複雑な話題です。このドキュメントは助けになったでしょうか？わかりにくかったところや、あなたが遭遇した問題が扱われていない等なかったでしょうか？もしそんな問題があれば、著者に改善の提案を送って下さい。

O’Reilly から出版されている Jeffrey Friedl の Mastering Regular Expressions は正規表現に関するほぼ完璧な書籍です [2] 。不幸なことに、この本は Perl と Java の正規表現を集中して扱っていて、 Python の正規表現については全く扱っていません、そのため Python プログラミングのためのレファレンスとして使うことはできません。 (第一版はいまや削除された Python の regex モジュールについて扱っていましたが、これはあまり役に立たないでしょう。) 図書館で調べるのを検討してみましょう。

注記

[1]
Python 2.2.2 で導入されました。

[2]
訳注 日本語訳「詳説 正規表現」が出版されています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

ソケットプログラミング HOWTO

Author:
Gordon McMillan

概要

ソケットはそこかしこで使われているが、最大級に誤解されている技術でもある。この文書はソケットの全体像を俯瞰しており、チュートリアルとしてはあまり役に立たない。実際に動くモノを完成させるには、他にもやらなければいけないことがあるからだ。この文書はソケットの微妙なところ (たくさんある) まではカバーしていないが、恥ずかしくない使い方ができるようになる程度の情報は得られるはずだ。

ソケット

ソケットはそこかしこで使われているが、最大級に誤解されている技術でもある。この文書はソケットの全体像を俯瞰しており、チュートリアルとしてはあまり役に立たない。実際に動くモノを完成させるには、他にもやらなければいけないことがあるからだ。この文書はソケットの微妙なところ (たくさんある) まではカバーしていないが、恥ずかしくない使い方ができるようになる程度の情報は得られるはずだ。

INET ソケットのことしか語らないつもりだが、利用率でいうとソケットの 99% 以上はこれだ。さらに中でも STREAM ソケットに話題を絞ろうと思う - 自分が何をしているのか分かっているのでない限り (分かってるならこの HOWTO なんて要らないだろ!)、 STREAM ソケットが一番分かりやすく、一番性能が出るのだ。そうやって謎に包まれたソケットの正体を明らかにしてゆくと共に、ブロッキングおよびノンブロッキングなソケットの扱いに関するいくつかのヒントを提示しよう。だが、まずはブロッキングソケットから始めることにする。ノンブロッキングを扱うより先に、ブロッキングの仕組みを知っておかなくてはならないのだ。

話を理解しにくくしている要因として、「ソケット」という言葉が文脈によって微妙に違うものを指すことが挙げられる。そこでまず、「クライアント」ソケット - 対話の両端 - と「サーバ」ソケット - 電話交換手みたいなもの - の区別を付けておこう。クライアント側アプリケーション (たとえばブラウザ) は「クライアント」ソケットだけを使うが、話し相手のウェブサーバは「サーバ」ソケットと「クライアント」ソケットの両方を使う。

歴史

各種 IPC (Inter Process Communication (プロセス間通信) の中でも、ソケットは群を抜いて人気がある。どのプラットフォームにも、ソケットより速い IPC はあるだろう。だが、プラットフォームをまたぐ通信はソケットの独擅場だ。

ソケットは BSD Unix の一部としてバークレイで発明され、インターネットの普及と共に野火のごとく広まった。それももっともなことで、ソケットと INET のコンビによって世界中どんなマシンとも、信じられないほど簡単 (少なくとも他のスキームと比べて) に通信できるようになったのだ。

ソケットの作成

あなたがリンクをクリックしてこのページに来たとき、ブラウザは大雑把に言って次のようなことをしたのである:

#INET の STREAM ソケットを作る
s = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
#ここでウェブサーバに 80 番 (http の標準) ポートで接続
s.connect(("www.mcmillan-inc.com", 80))

この connect が完了すると、ソケット s を使ってこのページ文章への要求を送ることができるようになる。その同じソケットが返答を読み、そして破壊される。そう、破壊される。クライアントソケットは通常、一回 (か少数の) やり取りで使い捨てになるのだ。

ウェブサーバで起こる事柄はもう少し複雑だ。まず「サーバソケット」を作る:

#INET の STREAM ソケットを作る
serversocket = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)
#そのソケットを公開ホストのウェルノウンポートにつなぐ
serversocket.bind((socket.gethostname(), 80))
#サーバソケットになる
serversocket.listen(5)

ここで注意すべき点がいくつかある: 今回はソケットが外界に見えるよう、 socket.gethostname() を使った。 s.bind(('', 80)) や s.bind(('localhost', 80)) でも「サーバ」ソケットにはなるが、それだと同じマシン内にしか見えないものになってしまう。

ふたつめ: 小さな番号のポートは大抵、「ウェルノウン (有名)」なサービス (HTTP, SNMP 等々) のために取ってある。お遊びで使うのなら適当に大きな数 (4桁) を使おう。

最後に: listen の引数はソケットライブラリに、接続要求を 5 個 (通常の最大値) まで順番待ちさせるように命じている。これ以降の外部接続は拒否するのだが、コードが適切に書かれていれば、それで十分すぎるほどだ。

よし、「サーバーソケット」ができて、80 番ポートで耳を澄ましているところまで来た。では、ウェブサーバのメインループに入ろう:

while 1:
    #外からの接続を受け入れる
    (clientsocket, address) = serversocket.accept()
    #ここで clientsocket に何かをする。
    #今回はスレッド化サーバということにしよう
    ct = client_thread(clientsocket)
    ct.run()

このループには実際のところ、3 通りの一般的な動作方法がある - clientsocket を扱うようにスレッドを割り当てたり、 clientsocket を扱う新しいプロセスを作ったり、あるいはノンブロッキングソケットを使うようにアプリを作り直して select で「サーバ」ソケットとアクティブな clientsocket の間を多重化したりするのだ。最後のについてはまた後にしよう。ここで理解しておくべき要点はこれだ: 以上が「サーバ」ソケットの仕事の すべて である。データは一切送信しないし、受信しない。「クライアント」ソケットを生み出すだけ。我々のバインドされているホストとポートに connect() してくる 他の「クライアント」ソケットに応える形で clientsocket を作り、作るや否や、さらなる接続を聞きに戻っていくのだ。このふたつの「クライアント」は、あとは勝手に喋っていればいい - 使うポートは動的に割り当てられ、会話が終わればリサイクルに廻される。

IPC

同一マシンのプロセス間で高速な IPC が必要なのであれば、そのプラットフォームが提供している何らかの共有メモリに目を向けるべきだ。共有メモリとロックやセマフォに基づいた簡素なプロトコルが断然一番速い。

ソケットを使うことにしたのであれば、「サーバ」ソケットは 'localhost' にバインドすることだ。こうすると、ほとんどのプラットフォームではネットワーク関連コードを何層かスキップすることになり、かなり速くなる。

ソケットの利用

はじめに憶えておくべきなのは、ウェブブラウザの「クライアント」ソケットとウェブサーバの「クライアント」ソケットがまったく同じ種族だということだ。つまり、これは「ピア・トゥ・ピア」(1 対 1) の会話である。別の言い方をすると、設計者として自分で会話のエチケット規則を決めなくてはいけない ということでもある。通常は、 connect してくるソケットが要求あるいは宣言をして会話を始める。だが、それはそう設計しただけのことだ - ソケットの規則ではない。

さて、コミュニケーションに使う動詞は二組ある。 send と recv を使うこともできるし、クライアントソケットをファイルっぽい種族に変形して read と write を使っても良い。後者は Java のソケットの表現方法だ。ここで詳しく語るつもりはないが、その場合はソケットも flush しなければいけない、とだけ言っておく。これはバッファリングした「ファイル」なので、何かを write してすぐに返答を read するというのはよくある間違いだ。間に flush を入れないと、要求がまだ出力バッファにあって永遠に返事が来ない、という可能性がある。

さあ、ソケットの主要な難関に進もう - send と recv はネットワークバッファに働きかけるものだ。だから、手渡したもの (や返してもらいたいもの) を 1 バイトも残さず実際に処理してくれているとは限らない。一般的に言って、 send はバッファが埋まったとき、 recv はバッファが空になったときに実際の処理をして、そのバイト数を返す。メッセージが完全に処理されるまでコールを繰り返すのは 自分の 責任なのだ。

recv が 0 バイトを返したときは、向こう側が接続を閉じてしまった (または閉じようとしている途中) という意味だ。もうこの接続でデータを受け取ることはない。永遠にだ。ただ、データ送信は成功するかもしれない; これについては次のページで語ることにしよう。

HTTP のようなプロトコルでは、ひとつのソケットを1回の転送にしか使わない。クライアントは要求を送り、返答を受ける。以上だ。これでソケットは破棄される。だからこの場合、クライアントは受信 0 バイトの時点で返答の末尾を検出することができる。

だが、以降の転送にもそのソケットを使い回すつもりなら、ソケットに “EOT” (End of Transfer) など 存在しない ことを認識する必要がある。もう一度言おう: ソケットの send や recv が 0 バイト処理で返ってきたなら、その接続は終わっている。終わって いない なら、いつまで recv を待てばいいかは分からない。ソケットは「もう読むものが (今のところ) ないぜ」などと 言わない のだから。このことを少し考えれば、ソケットの真実を悟ることになるだろう: メッセージは必ず固定長か (うげぇ) 区切り文字を使うか (やれやれ) 長さ標識を付けておくか (かなりマシ) 接続を閉じて終わらせるかのいずれかでなければいけない のだ。選ぶ権利と責任はまったくもって自分にある (が、正しさの程度に違いはある)。

毎回接続を終わらせるのはイヤだとして、最も単純な解決策は固定長メッセージだろう:

class mysocket:
    '''demonstration class only
      - coded for clarity, not efficiency
    '''

    def __init__(self, sock=None):
         if sock is None:
             self.sock = socket.socket(
                 socket.AF_INET, socket.SOCK_STREAM)
         else:
             self.sock = sock

    def connect(self, host, port):
         self.sock.connect((host, port))

    def mysend(self, msg):
         totalsent = 0
         while totalsent < MSGLEN:
             sent = self.sock.send(msg[totalsent:])
             if sent == 0:
                 raise RuntimeError("socket connection broken")
             totalsent = totalsent + sent

    def myreceive(self):
         msg = ''
         while len(msg) < MSGLEN:
             chunk = self.sock.recv(MSGLEN-len(msg))
             if chunk == '':
                 raise RuntimeError("socket connection broken")
             msg = msg + chunk
         return msg

この送信コードは、ほぼあらゆるメッセージ通信スキームで使える - 文字列を送るとき、Python なら長さを len() で見極めることができる (中に \0 が埋め込まれていても大丈夫)。難しくしているのは、おもに受信コードである。 (なお、C でも事態はあまり悪くならないが、メッセージに \0 が埋め込まれていると strlen が使えないのは面倒だ。)

最も簡単な改良法は、メッセージの最初の一文字をタイプ標識にして、そのタイプで長さを決定するというものだ。この場合ふたつの recv があることになる - 一番目でその一文字 (だけじゃなくても可) を取って長さを調べ、二番目でループして残りを取るのだ。あるいはもし区切り方式の道を行くのであれば、任意のサイズ (4096 か 8192 がネットワークバッファには最適なことが多い) で受信して区切り文字を走査していくことになる。

心に留めておくべき面倒な点がひとつ: 複数メッセージが次々に (何らかの返事を待たずに) 返ってくることのある会話プロトコルなら、そして任意のサイズを recv に渡しているなら、次のメッセージの冒頭部分まで読んでしまうことがあるかもしれない。そのときは、必要になるまで脇によけて、大切に保管しておく必要がある。

メッセージ冒頭に長さを (たとえば 5 桁の数字で) 付けるのは、それよりもさらに複雑になる。というのも、(信じられないかもしれないが) 一回の recv で 5 文字を全部受け取ることができるとは限らないからだ。お遊びでやっている間はごまかせても、高負荷ネットワークのもとでは、 recv ループをふたつ使わないコードは、あっと言う間にダメになってしまう - 一番目は長さを見定める用で、二番目はデータ部分を受け取る用だ。うーむ、いやらしい。さらにこのとき、 send も一発で全部を出し切れるとは限らないことに気付くだろう。なお、今こうやって読んでいても、いつか誰もが痛い目を見るのである!

紙面の都合および教育的配慮 (と著者の地位確保) のため、こうした改良は練習問題として残しておく。さあ片付けてしまおう。

バイナリデータ

バイナリデータはまったく問題なくソケットに乗せられる。問題は、すべてのマシンで同じ形式を使っているわけではないことにある。たとえば Motorola のチップなら 16 ビット整数の 1 という値をふたつの 16 進バイト列 00 01 で表現するが、Intel や DEC は逆バイトだ - 同じ 1 が 01 00 になるのだ。ソケットライブラリは 16 ビットや 32 ビット整数の変換用コールを持っている - ntohl, htonl, ntohs, htons である。”n” は network、 “h” は host を意味する。 “s” は short で “l” は long だ。これらのコールは、「ネットワーク並び = ホスト並び」なら何もしないが、マシンが逆バイトならそれに合わせてぐるっと交換してくれる。

この 32 ビット時代、バイナリデータは ASCII 表現のほうが小さくなることが多い。というのも、long なのに値が 0 ばっかりでたまに 1 だとかいうことは驚くほど多いからだ。文字列なら “0” は 2 バイトなのに、バイナリは 4 バイトも喰う。もちろんこれは固定長メッセージには合わないが。さあ、どうする、どうする。

切断

厳密には、ソケットを close する前には shutdown することになっている。 shutdown は相手ソケットに対する報告であり、渡す引数によって「これ以上こっちからは送らないけど、まだ聞いてるぜ」という意味になったり、「もう聞かない。せいせいした!」だったりする。しかしほとんどのソケットライブラリは、このエチケットを怠るプログラマに慣れてしまって、通常 close だけで shutdown(); close() と同じことになる。だから大抵はわざわざ shutdown しなくてもいい。

shutdown の効果的な使い方のひとつは、HTTP 風のやりとりだ。クライアントは要求を出してすぐに shutdown(1) する。これでサーバに、「クライアントは送信完了ですが、まだ受信可能です」と伝わる。サーバは 0 バイト受信で “EOF” を検出することができる。要求を残さず受け取ったことにして良いのだ。対してサーバは返答を送る。その send が成功したなら、クライアントは実際にまだ受信していたことになる。

Python はこの自動 shutdown をもう一歩進めて、ソケットが GC されるときに必要なら自動で close してくれると言っている。しかしこれに頼るクセをつけてはいけない。もしソケットが close せずに姿を消せば、相手ソケットはこちらが遅いだけだと思ってハングしてしまうかもしれない。お願いだから 終わったらちゃんと close してくれ。

ソケットが死ぬと

ブロッキングソケットを使っていて一番いやなのは多分、相手側が意地悪く (close せずに) ダウンするときに起こる事柄だ。自分側のソケットは高確率でハングするだろう。SOCKSTREAM は信頼性の高いプロトコルなので、ずっとずっと待ち続けて、なかなか見捨てないのだ。スレッドを使っているのであれば、そのスレッド全体が根本から死んだ状態になる。こうなると、もう手の施しようがない。まあ、ブロッキング読み出しの間ロックし続けるといった馬鹿げたことをしていない限り、リソースの点ではたいして消費にならない。だから ぜったいに そのスレッドを殺そうとしてはいけない - プロセスよりスレッドが効率的である理由のひとつは、自動リソース回収にまつわるオーバヘッドを避けられるという点にあるのだ。つまり別の言い方をすると、どうにかしてそのスレッドを殺したなら、プロセス全体がぐちゃぐちゃになってしまうだろうということだ。

ノンブロッキングソケット

ここまで理解してきたなら、もうソケットの仕組みについて必要なことはほとんど知っていることになる。これからも同じコールを、ほぼ同じように使っていくだけ、それだけだ。これをちゃんとやっていれば、そのアプリはだいたい完璧であろう。

Python の場合、ノンブロッキングにするには socket.setblocking(0) を使う。 C ならもっと複雑だ (一例を挙げると、BSD 方式の O_NONBLOCK およびほぼ違いのない POSIX 方式 O_NDELAY のどちらを選ぶか決めなくてはならなくて、後者は TCP_NODELAY とは全然別物だったりする) が、考え方はまったく一緒だ。

構造上の大きな違いは、 send, recv, connect, accept が何もしないで戻ってくるかもしれないという点である。選択肢は (当然ながら) いくつかある。返り値とエラーコードをチェックするという方法もある。が、発狂すること請け合いだ。信じないなら、いつかやってみるといい。アプリは肥大化し、バグが増え、CPU を喰い尽くすだろう。だからそんな愚かな解法は飛ばして、正解に進もう。

select を使え。

C において select でコードを書くのはかなり面倒だが、Python なら造作もない。しかし Python で select を理解しておけば C でもほとんど問題なく書ける、という程度には似ている:

readable, writable, in_error = \
               select.select(
                  potential_readers,
                  potential_writers,
                  potential_errs,
                  timeout)

select に三つのリストを渡しているが、一番目にはあとで読みたくなるかもしれないソケットすべて、二番目には書き込みたくなるかもしれないソケットすべて、最後に (通常は空のままだが) エラーをチェックしたいソケットが入っている。ひとつのソケットが複数にまたがってリストされても構わないことを憶えておくと良い。なお、 select コールはブロックするが、時間制限を与えることができる。これは、やっておいて損はない - 特に理由がなければ、かなり長い (たとえば 1 分とかの) 時間制限を付けておくことだ。

戻り値として、三つのリストが手に入る。それぞれには、実際に読めるソケット、書けるソケット、エラー中のソケットが入っていて、渡したリストの部分集合 (空集合かもしれない) になっている。

出力のうち、readable リストにあるソケットについては、 recv がとりあえず 何か を返すであろう、ということは史上最高度に確信できる。 writable リストも考え方は同じで、 何か は送れる。送りたいもの全体は無理かもしれないが、 何も ないよりはマシだろう。 (実のところ、ふつうに健康なソケットなら writable で返ってくることができる - それは外向きネットワークバッファに空きがあるというだけの意味しかないのだから)

「サーバ」ソケットは potential_readers リストに入れておこう。それが readable リストに入って出てきたら、 accept は (ほぼ) 確実に成功するはずだ。どこかへ connect するために作った新しいソケットは potential_writers リストに入れる。それが writable リストに現れたら、接続が成功している可能性は高いと言える。

select の実にいやらしい問題がひとつ: 突然死したソケットが入力側リストのどこかにあれば、 select は失敗してしまう。そうなると、見つけるまですべてのリストでループしてソケットをひとつひとつ select([sock],[],[],0) していく必要がある。時間制限を 0 にしてあるので長くはかからないが、これは美しくない。

じつは select はブロッキングソケットにも便利に使える。それはブロックするかどうかを見極める方法のひとつである - バッファに何かがあれば readable として返ってくるのだ。しかしこれも、相手の用事がもう済んでいるのか、それとも単に他のことで忙しいだけなのかを見極める役には立たない。

非互換警報: Unix ではソケットにもファイルにも select が使える。これを Windows でやろうとしてはいけない。Windows で select はソケットにしか使えない。また C の場合、高度なソケットオプションの多くは、やり方が Windows では違っている。実際、Windows なら著者は通常、ソケットにスレッドを使っている (これは実に、実にうまくいく)。認めたくないが、何らかの性能を求めるなら Windows のコードは Unix のコードとはかなり異なるものになってしまうだろう。

性能

最速のソケットコードはノンブロッキングソケットを使って select で多重化するものだということに疑問の余地はない。 CPU に負荷をかけることなく LAN 接続を使いきるアプリは作れる。問題は、そうやって書かれたものはあまり他のことができなくなるということだ - いつでもデータをあちらこちらへ廻せるようにしている必要があるのだ。

もっと他にやることがあるアプリなのだとすれば、スレッドが最適解だ (さらにノンブロッキングソケットを使えばブロッキングより速い)。しかし残念ながら、各種 Unix のスレッド対応は API も品質もバラバラである。そのため Unix の一般解は、それぞれの接続を取り扱う子プロセスをフォークするというものだ。このオーバヘッドは甚大 (Windows ではプロセス生成のオーバヘッドが洒落にならないので無理) だ。それに、子プロセスがお互い完全に独立しているのでない限り、親子のプロセス間で通信するために他の IPC, たとえばパイプとか、共有メモリとセマフォだとかを使う必要が出てくる。

最後に、これを憶えておいてほしい。ブロッキングソケットはノンブロッキングよりも幾分遅いとはいえ、多くの場合そちらが「正解」である。結局のところ、ソケットから受け取るデータに基づいて動くアプリなら、 recv のかわりに select で待てるようにするためだけにロジックを複雑化する意味はあまりない。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

ソート HOW TO

Author: | Andrew Dalke and Raymond Hettinger
Release: | 0.1

Python のリストにはリストをインプレースに変更する、組み込みメソッド list.sort() があります。他にもイテラブルからソートしたリストを作成する組み込み関数 sorted() があります。

このドキュメントでは Python を使った様々なソートのテクニックを探索します。

ソートの基本

単純な昇順のソートはとても簡単です: sorted() 関数を呼ぶだけです。そうすれば、新たにソートされたリストが返されます:

>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]

リストの list.sort() メソッドを呼びだしても同じことができます。この方法はリストをインプレースに変更します (そして sorted との混乱を避けるため None を返します)。多くの場合、こちらの方法は sorted() と比べると不便です - ただし、元々のリストが不要な場合には、わずかですがより効率的です。

>>> a = [5, 2, 3, 1, 4]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5]

違いは他にもあります、 list.sort() メソッドはリストにのみ定義されています。一方 sorted() 関数は任意のイテラブルを受け付けます。

>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]

Key 関数

Python 2.4 から、 list.sort() と sorted() には key パラメータが追加されました、これは比較を行う前にリストの各要素に対して呼び出される関数を指定するパラメータです。

例えば、大文字小文字を区別しない文字列比較の例:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

key パラメータは単一の引数をとり、ソートに利用される key を返さなければいけません。この制約によりソートを高速に行えます、キー関数は各入力レコードに対してきっちり一回だけ呼び出されるからです。

よくある利用パターンはいくつかの要素から成る対象をインデクスのどれかをキーとしてソートすることです。例えば:

>>> student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

同じテクニックは名前づけされた属性 (named attributes) を使うことでオブジェクトに対しても動作します。例えば:

>>> class Student:
        def __init__(self, name, grade, age):
            self.name = name
            self.grade = grade
            self.age = age
        def __repr__(self):
            return repr((self.name, self.grade, self.age))

>>> student_objects = [
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10),
]
>>> sorted(student_objects, key=lambda student: student.age)   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

operator モジュール関数

上述した key 関数のパターンはとても一般的です、そのため、Python は高速で扱いやすいアクセサ関数を提供しています。 operator モジュールには operator.itemgetter(), operator.attrgetter(), そして Python 2.5 から利用できるようになった operator.methodcaller() 関数があります。

これらの関数を利用すると、上の例はもっと簡単で高速になります:

>>> from operator import itemgetter, attrgetter

>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

operator モジュールの関数は複数の段階でのソートを可能にします。例えば、 grade でソートしてさらに age でソートする場合:

>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

昇順と降順

list.sort() と sorted() の両方とも reverse パラメータを真偽値として受け付けます。このパラメータは降順ソートを行うかどうかのフラグとして利用されます。例えば、学生のデータを age の逆順で得たい場合は:

>>> sorted(student_tuples, key=itemgetter(2), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

>>> sorted(student_objects, key=attrgetter('age'), reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

ソートの安定性と複合的なソート

Python 2.2 からソートは、 stable [http://en.wikipedia.org/wiki/Sorting_algorithm#Stability] であることが保証されるようになりました。これはレコードの中に同じキーがある場合、元々の順序が維持されるということを意味します。

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

二つの blue のレコートが元々の順序を維持して、 ('blue', 1) が ('blue', 2) の前にあること注意してください。

この素晴しい性質によって複数のソートを段階的に組み合わせることができます。例えば、学生データを grade の降順にソートし、さらに age の昇順にソートしたい場合には、まず age でソートし、次に grade でもう一度ソートします:

>>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
>>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Python では Timsort [http://en.wikipedia.org/wiki/Timsort] アルゴリズムが利用されていて、効率良く複数のソートを行うことができます、これは現在のデータセット中のあらゆる順序をそのまま利用できるからです。

デコレート-ソート-アンデコレート を利用した古いやり方

このイディオムは以下の3つのステップにちなんでデコレート-ソート-アンデコレート (Decorate-Sort-Undecorate) と呼ばれています。

まず、元となるリストをソートしたい順序を制御する新しい値でデコレートします。

次に、デコレートしたリストをソートします。

最後に、デコレートを取り除き、新しい順序で元々の値のみを持つリストを作ります。

例えば、DSU アプローチを利用して学生データを grade でソートする場合:

>>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
>>> decorated.sort()
>>> [student for grade, i, student in decorated]               # undecorate
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

このイディオムはタブルが辞書編集的に比較されるため正しく動作します; 最初の要素が比較され、同じ場合には第二の要素が比較され、以下も同様に動きます。

デコレートしたリストのインデクス i は全ての場合で含まれる必要はありませんが、そうすることで二つの利点があります:

ソートが安定になります – もし二つの要素が同じキーを持つ場合、それらの順序がソートされたリストでも維持されます。

元々の要素が比較可能な要素を持つとは限りません、なぜならデコレートされたタブルの順序は多くの場合、最初の二つの要素で決定されるからです。例として元のリストは直接比較できない複素数を含むことができます。

このイディオムの別名に Schwartzian transform [http://en.wikipedia.org/wiki/Schwartzian_transform] があります。これは Perl プログラマの間で有名な Randal L. Schwartz にちなんでいます。

巨大なリストや比較の情報を得る計算が高くつくリストに対するソートや Python のバージョンが 2.4 より前の場合には、 DSU はリストをソートするのに最速な方法のようです。 2.4 以降では、key 関数が同じ機能を提供します。

cmp パラメータを利用した古い方法

この HOWTO の内容の多くは Python 2.4 以降を仮定しています。それ以前では 組み込み関数 sorted() と list.sort() はキーワード引数をとりませんでした。その代わりに Py2.x バージョンの全ては、ユーザが比較関数を指定するための cmp パラメーターをサポートしました。

Py3.0 では cmp パラメータは完全に削除されました (ぜいたくな比較と __cmp__() マジックメソッドの衝突を除き、言語を単純化しまとるための多大な労力の一環として)

Py2.x ではソートにオプションとして比較に利用できる関数を与えることができます。関数は比較される二つの引数をとり、小さい場合には負の値を、等しい場合には 0 を、大きい場合には正の値を返さなければいけません。例えば、以下のようにできます:

>>> def numeric_compare(x, y):
        return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]

また、比較順を逆にすることもできます:

>>> def reverse_numeric(x, y):
        return y - x
>>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
[5, 4, 3, 2, 1]

Python 2.x から 3.x にコードを移植する場合、比較関数を持っている場合には key 関数に比較しなければならないような状況に陥るかもしれません。以下のラッパーがそれを簡単にしてくれるでしょう:

def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

key 関数を変換するには、古い比較関数をラップするだけです:

>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]

Python 2.7 には、functools モジュールに functools.cmp_to_key() 関数が追加されました。

残りいくつかとまとめ

ロケールに注意したソートをするには、キー関数 locale.strxfrm() を利用するか、比較関数に locale.strcoll() を利用します。

reverse パラメータはソートの安定性を保ちます (つまり、レコードのキーが等しい場合元々の順序が維持されます)。面白いことにこの影響はパラメータ無しで reversed() 関数を二回使うことで模倣することができます:

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))

ソートルーチンは二つのオブジェクトを比較するのに __lt__() を利用することを保証しています。そのため __lt__() メソッドを定義することで、標準のソート順序を追加できます。

>>> Student.__lt__ = lambda self, other: self.age < other.age
>>> sorted(student_objects)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

key 関数はソートするオブジェクトに依存する必要はありません。 key 関数は外部リソースにアクセスすることもできます。例えば学生の成績が辞書に保存されている場合、それを利用して別の学生の名前のリストをソートすることができます:

>>> students = ['dave', 'john', 'jane']
>>> newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
>>> sorted(students, key=newgrades.__getitem__)
['jane', 'dave', 'john']

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

Unicode HOWTO

Release:
1.03

この HOWTO 文書は Python 2.x の Unicode サポートについて論じ、さらに Unicode を使おうというときによくでくわす多くの問題について説明します。 (この HOWTO はまだ Python 3.x をカバーしていません)

Unicode 入門

文字コードの歴史

1968年に American Standard Code for Information Interchange が標準化されました。頭文字の ASCII でよく知られています。 ASCII は0から127までの、異なる文字の数値コードを定義していて、例えば、小文字の ‘a’ にはコード値 97 が割り当てられています。

ASCII はアメリカの開発標準だったのでアクセント無しの文字のみを定義していて、 ‘e’ はありましたが、 ‘é’ や ‘Í’ はありませんでした。つまり、アクセント付きの文字を必要とする言語は ASCII できちんと表現するとができません。 (実際には英語でもアクセント無いために起きる問題がありました、 ‘naïve’ や ‘café’ のようなアクセントを含む単語や、いくつかの出版社は ‘coöperate’ のような独自のスタイルのつづりを必要とするなど)

しばらくの間は単にアクセントが表示されないプログラムを書きました。 1980年半ばのフランス語で出版された Apple ][ の BASIC プログラムを見た記憶を辿ると、そこにはこんな行が含まれていました:

PRINT "FICHER EST COMPLETE."
PRINT "CARACTERE NON ACCEPTE."

これらのメッセージはアクセントを含むべきで、フランス語を読める人から見ると単に間違いとみなされます。

1980年代には、多くのパーソナルコンピューターは 8-bit で、つまり 8-bit で 0-255 までの値を確保することができました。 ASCII コードは 127 までだったので、いくつかのマシンは 128 から 255 の値をアクセント付きの文字に割り当てました。マシン毎に異なる文字コードがあり、そのためにファイル交換の問題が起きることとなりました。結局、128-255 の間の値は多くのよく使われる集合が現われることになりました。そのうちいくつかは International Standards Organzation の定める本当の標準になり、またいくつかは一社で開発され、別の会社へと流行することで 事実上の 慣習となりました。

255文字というのは十分多い数ではありません。例えば、西ヨーロッパで使われるアクセント付き文字とロシアで使われるキリルアルファベットの両方は 127文字以上あるので、128-255の間におさめることはできません。

異なる文字コードを使ってファイルを作成することは可能です (持っているロシア語のファイル全てを KOI8 と呼ばれるコーディングシステムで、持っているフランス語のファイル全てを別の Latin1 と呼ばれるコーディングシステムにすることで)、しかし、ロシア語の文章を引用するフランス語の文章を書きたい場合にはどうでしょう? 1989年代にこの問題を解決したいという要望が上って、Unicode 標準化の努力が始まりました。

Unicode は 8-bit の文字の代わりに 16-bit の文字を使うことにとりかかりました。 16bit 使うということは 2^16 = 65,536 の異なる値が利用可能だということを意味します、これによって多くの異なるアルファベット上の多くの異なる文字を表現することができます; 最初の目標は Unicode が人間が使う個々の言語のアルファベットを含むことでした。あとになってこの目標を達成するには 16bit でさえも不十分であることがわかりました、そして最新の Unicode 規格は 0-1,114,111 (16進表記で 0x10ffff) までのより広い文字コードの幅を使っています。

関連する ISO 標準も ISO 10646 があります。Unicode と ISO 10646 は元々独立した成果でしたが、 Unicode の 1.1 リビジョンで仕様を併合しました。

(この Unicode の歴史についての解説は非常に単純化しています。平均的な Python プログラマは歴史的な詳細を気にする必要は無いと考えています; より詳しい情報は参考文献に載せた Unicode コンソーシアムのサイトを参考にして下さい。)

定義

文字 は文章の構成要素の中の最小のものです。’A’, ‘B’, ‘C’ などは全て異なる文字です。 ‘È’ や ‘Í’ も同様に異なる文字です。文字は抽象的な概念で、言語や文脈に依存してさまざまに変化します。例えば、オーム(Ω) はふつう大文字ギリシャ文字のオメガ (Ω) で書かれますが (これらはいくつかのフォントで全く同じ書体かもしれません) しかし、これらは異なる意味を持つ異なる文字とみなされます。

Unicode 標準は文字が コードポイント (code points) でどう表現するかを記述しています。コードポイントは整数値で、ふつう16進表記で書かれます。標準的にはコードポイントは U+12ca のような表記を使って書かれます、 U+12ca は 0x12ca (10進表記で 4810) を意味しています。 Unicode 標準は文字とコードポイントを対応させる多くのテーブルを含んでいます:

0061    'a'; LATIN SMALL LETTER A
0062    'b'; LATIN SMALL LETTER B
0063    'c'; LATIN SMALL LETTER C
...
007B    '{'; LEFT CURLY BRACKET

厳密にいうとこれらの定義は「この文字は U+12ca です」ということを意味していません。 U+12ca はコードポイントで、特定の文字を示しています; この場合では、’ETHIOPIC SYLLABLE WI’ を示しています。細かく気にしない文脈の中ではコードポイントと文字の区別は忘れられることがよくあります。

文字は画面や紙面上では グリフ (glyph) と呼ばれるグラフィック要素の組で表示されます。大文字の A のグリフは例えば、厳密な形は使っているフォントによって異なりますが、斜めの線と水平の線です。たいていの Python コードではグリフの心配をする必要はありません; 一般的には表示する正しいグリフを見付けることは GUI toolkit や端末のフォントレンダラーの仕事です。

エンコーディング

前の節をまとめると: Unicode 文字列は 0 から 0x10ffff までの数値であるコードポイントのシーケンスで、シーケンスはメモリ上でバイト (0 から 255 までの値) の組として表現される必要があります。バイト列を Unicode 文字列に変換する規則を エンコーディング (encoding) と呼びます。

最初に考えるであろうエンコーディングは 32-bit 整数の配列でしょう。この表示では、”Python” という文字列はこうみえます:

   P           y           t           h           o           n
0x50 00 00 00 79 00 00 00 74 00 00 00 68 00 00 00 6f 00 00 00 6e 00 00 00
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

この表示は直接的でわかりやすい方法ですが、この表示を使うにはいくつかの問題があります。

可搬性がない; プロセッサが異なるとバイトの順序づけも変わってしまいます。

空間を無駄に使ってしまいます。多くの文書では、コードポイントの多くは 127 か 255 より小さいため多くの空間がゼロバイトに占有されます。上の文字列はASCII表示では6バイトを必要だったのに対して24バイトを必要としています。 RAM の使用料の増加はたいした問題ではありませんが (デスクトップコンピュータは RAM をメガバイト単位で持っていますし、文字列はそこまで大きい容量にはなりません)、しかし、ディスクとネットワークの帯域が4倍増えることはとても我慢できるものではありません。

strlen() のような現存する C 関数と互換性がありません、そのためワイド文字列関数一式が新たに必要となります。

多くのインターネット標準がテキストデータとして定義されていて、それらはゼロバイトの埋め込まれた内容を扱うことができません。

一般的にこのエンコーディングは使わず、変わりにより効率的で便利な他のエンコーディングが選ばれています。 UTF-8 はたぶん最も一般的にサポートされているエンコーディングです。このエンコーディングについては後で説明します。

エンコーディングは全ての Unicode 文字を扱う必要はありませんし、多くのエンコーディングはそれをしません。例えば Python のデフォルトエンコーディングの ‘ascii’ エンコーディング。 Unicode 文字列を ASCII エンコーディングに変換する規則は単純です; それぞれのコードポイントに対して:

コードポイントは128より小さい場合、コードポイントと同じ値

コードポイントが128以上の場合、Unicode 文字列はエンコーディングで表示することができません。 (この場合 Python は UnicodeEncodeError 例外を送出します。)

Latin-1, ISO-8859-1 として知られるエンコーディングも同様のエンコーディングです。 Unicode コードポイントの 0-255 は Latin-1 の値と等価なので、このエンコーディングの変換するには、単純にコードポイントをバイト値に変換する必要があります; もしコードポイントが255より大きい場合に遭遇した場合、文字列は Latin-1 にエンコードできません。

エンコーディングは Latin-1 のように単純な一対一対応を持っていません。 IBM メインフレームで使われていた IBM の EBCDIC で考えてみます。文字は一つのブロックに収められていませんでした: ‘a’ から ‘i’ は 129 から 137 まででしたが、 ‘j’ から ‘r’ までは 145 から 153 までした。 EBICIC を使いたいと思ったら、おそらく変換を実行するルックアップテーブルの類を使う必要があるでしょう、これは内部の詳細のことになりますが。

UTF-8 は最もよく使われるエンコーディングの一つです. UTF は “Unicode Transformation Format” からとられていて、 8 はエンコーディングに 8-bit の数字を使うことを意味しています。 (同じく UTF-16 エンコーディングもあります、しかしこちらは UTF-8 ほど頻繁に使われていません。) UTF-8 は以下の規則を利用します:

コードポイントが128より小さい場合、対応するバイト値で表現。

コードポイントは128から0x7ff の間の場合、128から255までの2バイト値に変換。

0x7ff より大きいコードポイントは3か4バイト列に変換し、バイト列のそれぞれのバイトは128から255の間をとる。

UTF-8 はいくつかの便利な性質を持っています。

任意の Unicode コードポイントを扱うことができる。

Unicode 文字列をゼロバイトで埋めないバイト文字列に変換する。これによってバイト順の問題を解決し、UTF-8 文字列を strcpy() のような C 関数で処理することができ、そしてゼロバイトを扱うことができないプロトコル経由で送信することができます。

ASCII テキストの文字列は UTF-8 テキストとしても有効です。

UTF-8 はかなりコンパクトです; コードポイントの多くは2バイトに変換され、値が128より小さければ、1バイトしか占有しません。

バイトが欠落したり、失われた場合、次の UTF-8 でエンコードされたコードポイントの開始を決定し、再同期することができる可能性があります。同様の理由でランダムな 8-bit データは正当な UTF-8 とみなされにくくなっています。

参考文献

Unicode コンソーシアムのサイト <http://www.unicode.org> には文字の図表や用語辞典、そして Unicode 仕様の PDF があります。読むのは簡単ではないので覚悟して下さい。

<http://www.unicode.org/history/> は Unicode の起源と発展の年表です。

標準についての理解を助けるために Jukka Korpela が Unicode の文字表を読むための導入ガイドを書いています、 <http://www.cs.tut.fi/~jkorpela/unicode/guide.html> から入手可能です。

もう一つのよい入門記事 <http://www.joelonsoftware.com/articles/Unicode.html> を Joel Spolsky が書いています。もしこの HOWTO の入門が明解に感じなかった場合には、続きを読む前にこの記事を読んでみるべきです。

Wikipedia の記事はしばしば役に立ちます; 試しに “character encoding” <http://en.wikipedia.org/wiki/Character_encoding> の記事と UTF-8 <http://en.wikipedia.org/wiki/UTF-8> の記事を読んでみて下さい。

Python 2.x の Unicode サポート

ここまでで Unicode の基礎を学びました、ここから Python の Unicode 機能に触れます。

Unicode 型

Unicode 文字列は Python の組み込み型の一つ unicode 型のインスタンスとして表現されます。 basestring と呼ばれる抽象クラスから派生しています、 str 型の親戚でもあります; そのため isinstance(value, basestring) で文字列型かどうか調べることができます。 Python 内部では Unicode 文字列は16-bit, 32-bit 整数のどちらかで表現され、どちらが使われるかは Python インタプリタがどうコンパイルされたかに依存します。

unicode() コンストラクタは unicode(string[, encoding, errors]) という用法を持っています。この引数は全て 8-bit 文字列でなければいけません。最初の引数は指定したエンコーディングを使って Unicode に変換されます; encoding 引数を渡さない場合、変換には ASCII エンコーディングが使われます、そのため 127 より大きい文字はエラーとして扱われます:

>>> unicode('abcdef')
u'abcdef'
>>> s = unicode('abcdef')
>>> type(s)
<type 'unicode'>
>>> unicode('abcdef' + chr(255))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
                    ordinal not in range(128)

errors 引数は入力文字列がエンコーディング規則に従って変換できないときの対応を指定します。この引数に有効な値は ‘strict’ (UnicodeDecodeError を送出する)、 ‘replace’ (U+FFFD, ‘REPLACEMENT CHARACTER’ を追加する)、または ‘ignore’ (結果の Unicode 文字列から文字を除くだけ) です。以下の例で違いを示します:

>>> unicode('\x80abc', errors='strict')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
                    ordinal not in range(128)
>>> unicode('\x80abc', errors='replace')
u'\ufffdabc'
>>> unicode('\x80abc', errors='ignore')
u'abc'

エンコーディングはエンコーディング名を含む文字列によって指定されます。 Python 2.7 ではエンコーディングはおよそ100に及びます; 一覧は Python ライブラリレファレンスの 標準エンコーディング を参照して下さい。いくつかのエンコーディングは複数の名前を持っています; 例えば ‘latin-1’, ‘iso_8859_1’, そして ‘8859’ これらは全て同じエンコーディングの別称です。

Unicode 文字列の一つの文字は unichr() 組み込み関数で作成することができます、この関数は整数を引数にとり、対応するコードポイントを含む長さ1の Unicode 文字列を返します。逆の操作は ord() 組み込み関数です、この関数は一文字の Unicode 文字列を引数にとり、コードポイント値を返します:

>>> unichr(40960)
u'\ua000'
>>> ord(u'\ua000')
40960

unicode 型のインスタンスは多くの 8-bit 文字列型と同じ検索や書式指定のためのメソッドを持っています:

>>> s = u'Was ever feather so lightly blown to and fro as this multitude?'
>>> s.count('e')
5
>>> s.find('feather')
9
>>> s.find('bird')
-1
>>> s.replace('feather', 'sand')
u'Was ever sand so lightly blown to and fro as this multitude?'
>>> s.upper()
u'WAS EVER FEATHER SO LIGHTLY BLOWN TO AND FRO AS THIS MULTITUDE?'

これらのメソッドの引数は Unicode 文字列または 8-bit 文字列が使えることに注意して下さい。 8-bit 文字列は操作に使われる前に Unicode に変換されます; Python デフォルトの ASCII エンコーディングが利用されるため、127より大きい文字列は例外を引き起します:

>>> s.find('Was\x9f')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0x9f in position 3: ordinal not in range(128)
>>> s.find(u'Was\x9f')
-1

文字列操作を行なう多くの Python コードはコードの変更無しに Unicode 文字列を扱うことができるでしょう。 (入出力に関しては Unicode のための更新が必要になります; 詳しくは後で述べます。)

別の重要なメソッドは .encode([encoding], [errors='strict']) があります、このメソッドは Unicode 文字列を要求したエンコーディングでエンコードされた 8-bit 文字列を返します。 errors パラメータは unicode() コンストラクタのパラメータと同様ですが、もう一つ可能性が追加されています; 同様のものとして ‘strict’, ‘ignore’, そして ‘replace’ があり、さらに XML 文字参照を使う ‘xmlcharrefreplace’ を渡すことができます:

>>> u = unichr(40960) + u'abcd' + unichr(1972)
>>> u.encode('utf-8')
'\xea\x80\x80abcd\xde\xb4'
>>> u.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128)
>>> u.encode('ascii', 'ignore')
'abcd'
>>> u.encode('ascii', 'replace')
'?abcd?'
>>> u.encode('ascii', 'xmlcharrefreplace')
'&#40960;abcd&#1972;'

Python の 8-bit 文字列は .decode([encoding], [errors]) メソッドを持っています、これは与えたエンコーディングを使って文字列を解釈します:

>>> u = unichr(40960) + u'abcd' + unichr(1972)   # Assemble a string
>>> utf8_version = u.encode('utf-8')             # Encode as UTF-8
>>> type(utf8_version), utf8_version
(<type 'str'>, '\xea\x80\x80abcd\xde\xb4')
>>> u2 = utf8_version.decode('utf-8')            # Decode using UTF-8
>>> u == u2                                      # The two strings match
True

codecs モジュールに利用可能なエンコーディングを登録したり、アクセスする低レベルルーチンがあります。しかし、このモジュールが返すエンコーディングとデコーディング関数はふつう低レベルすぎて快適とはいえません、そのためここで codecs モジュールについて述べないことにします。もし、全く新しいエンコーディングを実装する必要があれば、 codecs モジュールのインターフェースについて学ぶ必要があります、しかし、エンコーディングの実装は特殊な作業なので、ここでは扱いません。このモジュールについて学ぶには Python ドキュメントを参照して下さい。

codecs モジュールの中で最も使われるのは codecs.open() 関数です、この関数は入出力の節で議題に挙げます。

Python ソースコード内の Unicode リテラル

Python のソースコード内では Unicode リテラルは ‘u’ または ‘U’ の文字を最初に付けた文字列として書かれます: u'abcdefghijk' 。特定のコードポイントはエスケープシーケンス \u を使い、続けてコードポイントを4桁の16進数を書きます。エスケープシーケンス \U も同様です、ただし4桁ではなく8桁の16進数を使います。

Unicode リテラルは 8-bit 文字列と同じエスケープシーケンスを使うことができます、使えるエスケープシーケンスには \x も含みます、ただし \x は2桁の16進数しかとることができないので任意のコードポイントを表現することはできません。 8進エスケープは8進数の777を示す U+01ff まで使うことができます。

>>> s = u"a\xac\u1234\u20ac\U00008000"
           ^^^^ two-digit hex escape
               ^^^^^^ four-digit Unicode escape
                           ^^^^^^^^^^ eight-digit Unicode escape
>>> for c in s:  print ord(c),
...
97 172 4660 8364 32768

127 より大きいコードポイントに対してエスケープシーケンスを使うのは、エスケープシーケンスがあまり多くないうちは有効ですが、フランス語等のアクセントを使う言語でメッセージのような多くのアクセント文字を使う場合には邪魔になります。文字を unichr() 組み込み関数を使って組み上げることもできますが、それはさらに長くなってしまうでしょう。

理想的にはあなたの言語の自然なエンコーディングでリテラルを書くことでしょう。そうなれば、Python のソースコードをアクセント付きの文字を自然に表示するお気に入りのエディタで編集し、実行時に正しい文字が得られます。

Python は Unicode 文字列を任意のエンコーディングで書くことができます、ただしどのエンコーディングを使うかを宣言しなければいけません。それはソースファイルの一行目や二行目に特別なコメントを含めることによってできます:

#!/usr/bin/env python
# -*- coding: latin-1 -*-

u = u'abcdé'
print ord(u[-1])

この構文は Emacs のファイル固有の変数を指定する表記から影響を受けています。 Emacs は様々な変数をサポートしていますが、Python がサポートしているのは ‘coding’ のみです。 -*- の記法はコメントが特別であることを示します; この記号に前後はさまれたところに coding と選択したコーディングを ':' でつないで書く必要があります。

このコメントを含まない場合には、デフォルトエンコーディングとして ASCII が利用されます。 Python のバージョンが 2.4 より前の場合には Euro-centric と Latin-1 が文字列リテラルのデフォルトエンコーディングであると仮定されていました; Python 2.4 では 127 より大きい文字でも動作しますが、警告を発することになります。例えば、以下のエンコーディング宣言のないプログラムは:

#!/usr/bin/env python
u = u'abcdé'
print ord(u[-1])

これを Python 2.4 で動作させたときには、以下の警告が出力されます:

amk:~$ python2.4 p263.py
sys:1: DeprecationWarning: Non-ASCII character '\xe9'
     in file p263.py on line 2, but no encoding declared;
     see http://www.python.org/peps/pep-0263.html for details

Python 2.5 以降ではより厳格になり、文法エラーになります:

amk:~$ python2.5 p263.py
File "/tmp/p263.py", line 2
SyntaxError: Non-ASCII character '\xc3' in file /tmp/p263.py
  on line 2, but no encoding declared; see
  http://www.python.org/peps/pep-0263.html for details

Unicode プロパティ

Unicode 仕様はコードポイントについての情報データベースを含んでいます。定義された各コードポイントに対して、情報は文字の名前、カテゴリ、適用可能ならば数値 (Unicode にはローマ数字や 1/3 や 4/5 のような分数などの文字があります)を含んでいます。コードポイントを左右どちらから読むのか等表示に関連したプロパティもあります。

以下のプログラムはいくつかの文字に対する情報を表示し、特定の文字の数値を印字します:

import unicodedata

u = unichr(233) + unichr(0x0bf2) + unichr(3972) + unichr(6000) + unichr(13231)

for i, c in enumerate(u):
    print i, '%04x' % ord(c), unicodedata.category(c),
    print unicodedata.name(c)

# Get numeric value of second character
print unicodedata.numeric(u[1])

実行時には、このように印字されます:

0 00e9 Ll LATIN SMALL LETTER E WITH ACUTE
1 0bf2 No TAMIL NUMBER ONE THOUSAND
2 0f84 Mn TIBETAN MARK HALANTA
3 1770 Lo TAGBANWA LETTER SA
4 33af So SQUARE RAD OVER S SQUARED
1000.0

カテゴリコードは文字の性質を簡単に説明するものです。カテゴリの分類は “Letter”, “Number”, “Punctuation” または “Symbol” で、さらにサブカテゴリに分かれます。上に出ている出力結果を例にとると 'Ll' は ‘Letter, lowercase’ を意味していて、 'No' は “Number, other” を意味しています、 'Mn' は “Mark, nonspacing” で 'So' は “Symbol, other” です。カテゴリコードの一覧は <http://www.unicode.org/reports/tr44/#General_Category_Values> を参照して下さい。

参考文献

Unicode と 8-bit 文字型については Python ライブラリレファレンスの シーケンス型 — str, unicode, list, tuple, bytearray, buffer, xrange に記述があります。

unicodedata モジュールについてのドキュメント。

codecs モジュールについてのドキュメント。

Marc-André Lemburg は EuroPython 2002 で “Python and Unicode” という題のプレゼンテーションを行ないました。彼のスライドの PDF バージョンが <http://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf> から入手できます。これは、Python の Unicode 機能のデザインの素晴しい概観になっています。

Unicode データを読み書きする

一旦 Unicode データに対してコードが動作するように書き終えたら、次の問題は入出力です。プログラムは Unicode 文字列をどう受けとり、どう Unicode を外部記憶装置や送受信装置に適した形式に変換するのでしょう?

入力ソースと出力先に依存しないような方法は可能です; アプリケーションに利用されているライブラリが Unicode をそのままサポートしているかを調べなければいけません。例えば XML パーサーは大抵 Unicode データを返します。多くのリレーショナルデータベースも Unicode 値の入ったコラムをサポートしていますし、 SQL の問い合わせで Unicode 値を返すことができます。

Unicode データは大抵の場合、ディスクに書き込んだりソケットを通して送られる前に特定のエンコーディングに変換されます。それらを自分自身で行なうことは可能です: ファイルを開いて、8-bit 文字列を読み、文字列を unicode(str, encoding) で変換します。しかし、この手動での操作は推奨できません。

問題はエンコーディングがマルチバイトであるという性質からきています; 一つの Unicode 文字は数バイトで表現されます。ファイルを任意のサイズ (1K または 4K) を単位 (chunk) として読みたい場合、読み込みの単位 (chunk) の最後にエンコーディングされた一つの Unicode 文字のバイト列の一部のみだった状況に対するエラー処理コードを書く必要がでます。一つの解決策としてはメモリ上にファイル全体を読み込んでから、デコードを実行するという方法があります、しかし巨大なファイルを扱うときに問題が起きます; 2Gb のファイルを読む場合、2Gb の RAM が必要です。 (正確にいうとより多くの RAM が必要です、少なくともある時点ではエンコードする文字列と Unicode に変換した文字列の両方がメモリ上に必要とされるために)

解決策は文字コードのシーケンスが途中で切れる問題を捉える低レベルのデコーディングインターフェースを使うことです。このインターフェースの実装は既に行なわれています: codecs モジュールは open() 関数を含んでいます、この関数はファイルの内容が指定したエンコーディングであると仮定されるファイルオブジェクトを返し、 .read() and .write() のようなメソッドに対して Unicode パラメータを受けつけます。

関数の引数は open(filename, mode='rb', encoding=None, errors='strict', buffering=1) です。 mode は 'r', 'w', または 'a' が受け付けられ、通常の組み込み関数 open() 関数の引数と同様です; ファイルを更新するには '+' を加えます。 buffering は標準の関数の引数と同様です。 encoding は使うエンコーディングを文字列で与えます; もし None にした場合は 8-bit 文字列を受け付ける通常の Python のファイルオブジェクトが返されます。それ以外の引数の場合には、ラップされたオブジェクトが返され、データは必要に応じて変換されたラッパーオブジェクトから読み書きされます。 errors はエンコーディイングエラーに対する動作を指定します、これは例の如く ‘strict’, ‘ignore’ そして ‘replace’ のうちのどれかをとります。

そのためファイルから Unicode を読むのは単純です:

import codecs
f = codecs.open('unicode.rst', encoding='utf-8')
for line in f:
    print repr(line)

読み書きの両方ができる update モードでファイルを開くことも可能です:

f = codecs.open('test', encoding='utf-8', mode='w+')
f.write(u'\u4500 blah blah blah\n')
f.seek(0)
print repr(f.readline()[:1])
f.close()

Unicode 文字 U+FEFF は byte-order-mark (BOM) として利用されます、そしてファイルのバイト順の自動判定の役立てるためにファイルの最初の文字として書かれます。いくつかのエンコーディング、たとえば UTF-16 では BOM がファイルの最初に存在することになっています; そのようなエンコーディングが利用されるときには BOM は最初の文字として自動的に書き込まれ、ファイルの読み込み時には暗黙の内に除かれます。これらのエンコーディングにはリトルエンディアン (little-endian) とビッグエンディアン (big-endian) に対して ‘utf-16-le’ と ‘utf-16-be’ のようにエンコーディングの変種が存在します、これらは特定のバイト順を示すもので、BOM をスキップしません。

Unicode ファイル名

多くの OS では現在任意の Unicode 文字を含むファイル名をサポートしています。通常 Unicode 文字列をシステム依存のエンコーディングに変換することによって実装されています。例えば、Mac OS X は UTF-8 を利用し、Windows ではエンコーディングが設定で変更することが可能です; Windows では Python は “mbcs” という名前に現在設定されているエンコーディングを問い合わせて利用します。 Unix システムでは LANG や LC_CTYPE 環境変数を設定していれば、それだけがファイルシステムのエンコーディングとなります; もしエンコーディングを設定しなければ、デフォルトエンコーディングは ASCII になります。

sys.getfilesystemencoding() 関数は現在のシステムで利用するエンコーディングを返し、エンコーディングを手動で設定したい場合利用します、ただしわざわざそうする積極的な理由はありません。読み書きのためにファイルを開く時には、ファイル名を Unicode 文字列として渡すだけで正しいエンコーディングに自動的に変更されます:

filename = u'filename\u4500abc'
f = open(filename, 'w')
f.write('blah\n')
f.close()

os.stat() のような os モジュールの関数も Unicode のファイル名を受け付けます。

ファイル名を返す os.listdir() は問題を引き起こします: この関数はファイル名を返すべきでしょうか、それともエンコードされた内容の 8-bit 文字列を返すべきでしょうか? os.listdir() は与えられたデイレクトリへのパスが 8-bit 文字列か Unicode 文字列で与えたかに応じてその両方を返します。パスを Unicode 文字列で与えた場合、ファイル名はファイルシステムのエンコーディングを利用してデコードされ、 Unicode 文字列のリストが返されます、8-bit パスを与えるとファイル名は 8-bit 文字列で返されます。例えば、デフォルトのファイルシステムエンコーディングが UTF-8 と仮定される場合、以下のプログラムを実行すると:

fn = u'filename\u4500abc'
f = open(fn, 'w')
f.close()

import os
print os.listdir('.')
print os.listdir(u'.')

以下の出力結果が生成されます:

amk:~$ python t.py
['.svn', 'filename\xe4\x94\x80abc', ...]
[u'.svn', u'filename\u4500abc', ...]

最初のリストは UTF-8 でエンコーディングされたファイル名を含み、第二のリストは Unicode 版を含んでいます。

Unicode 対応のプログラムを書くための Tips

この章では Unicode を扱うプログラムを書くためのいくつかの提案を紹介します。

最も重要な助言としては:

ソフトウェア内部の動作には Unicode 文字列のみを利用し、出力時に特定のエンコーディングに変換する。

UTF-8 と 8-bit 文字列の両方を処理する関数を書こうとすると、異なる種類の文字列を結合する際にバグが生じやすいことに気づくでしょう。 Python のデフォルトエンコーディングは ASCII なので、 ASCII の値 127 より大きい文字が入力データにあった場合、これは ASCII エンコーディングで扱えないために、 UnicodeDecodeError が発生します。

この問題を見逃がすのは簡単です、ソフトウェアに対してアクセントを含まないデータのみでテストを行なえばよいのです; 全てはうまく動作しているように見えます、しかし実際には最初に 127 より大きい文字を試みたユーザにバグが待ち構えていることになります。第二の助言は:

テストデータには 127 より大きい文字を含み、さらに 255 より大きい文字を含むことが望ましい。

Web ブラウザからのデータやその他の信用できないところからのデータを使う場合には、コマンド行の生成やデータベースへの記録の前に不正な文字に対するチェックを行なうことが一般的です。もしコマンド行生成やデータベース記録を行なう場合には、文字列が利用または保存できる形式になっているかを一度は注意深く確かめる必要があります; 文字を偽装するためにエンコーディングを利用することは可能です。このことは入力データのエンコーディングが指定されている場合にも可能です; 多くのエンコーディングはチェック用の文字単独をそのままにしておきますが、 Python は 'base64' のような単独の文字を変更するエンコーディングも含んでいます。

例えば、Unicode のファイル名を取るコンテキストマネージメントシステムがあるとします、そして ‘/’ 文字を含むパスを拒否したいとします。するとこのコードのように書くでしょう:

def read_file (filename, encoding):
    if '/' in filename:
        raise ValueError("'/' not allowed in filenames")
    unicode_name = filename.decode(encoding)
    f = open(unicode_name, 'r')
    # ... return contents of file ...

しかし、攻撃者が 'base64' エンコーディングを指定できる場合、攻撃者はシステムファイルを読むために '/etc/passwd' の文字列を base-64 でエンコードした 'L2V0Yy9wYXNzd2Q=' を渡すことができます。上のコードは文字 '/' をエンコードした形式で探し、デコードした結果が危険な文字となる場合を見逃してしまいます。

参考文献

Marc-André Lemburg のプレゼンテーション “Writing Unicode-aware Applications in Python” の PDF スライドが <http://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf> から入手可能です、そして文字エンコーディングの問題と同様にアプリケーションの国際化やローカライズについても議論されています。

更新履歴と謝辞

この記事中の誤りの指摘や提案を申し出てくれた以下の人々に感謝します: Nicholas Bastin, Marius Gedminas, Kent Johnson, Ken Krugler, Marc-André Lemburg, Martin von Löwis, Chad Whitacre.

Version 1.0: posted August 5 2005.

Version 1.01: posted August 7 2005. Corrects factual and markup errors; adds several links.

Version 1.02: posted August 16 2005. Corrects factual errors.

Version 1.03: posted June 20 2010. Notes that Python 3.x is not covered, and that the HOWTO only covers 2.x.

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

urllib2 を使ってインターネット上のリソースを取得するには

Author:
Michael Foord [http://www.voidspace.org.uk/python/index.shtml]

ノート

この HOWTO の前段階の版のフランス語訳が urllib2 - Le Manuel manquant [http://www.voidspace.org.uk/python/articles/urllib2_francais.shtml] で入手できます。

はじめに

関連する記事

同じように Python でインターネットリソースを取得するのに以下の記事が役に立ちます:

Basic Authentication [http://www.voidspace.org.uk/python/articles/authentication.shtml]

Basic 認証 についてのチュートリアルで Python の例がついています。

urllib2 は URLs (Uniform Resource Locators) を取得するための Python [http://www.python.org] モジュールです。このモジュールはとても簡単なインターフェースを urlopen 関数の形式で提供しています。また、このモジュールは一般的な状況で利用するためにいくらか複雑なインターフェースも提供しています - basic 認証やクッキー、プロキシ等。これらは handler や opener と呼ばれるオブジェクトとして提供されます。

urllib2 は多くの “URL スキーム” (URL の ”:” の前の文字列で識別されるもの - 例えば “ftp://python.org/” では “ftp”) の URL を、関連するネットワークプロトコル(例えば FTP, HTTP) を利用することで、取得できます。

単純な状況では urlopen はとても簡単に使うことができます。しかし HTTP の URL を開くときにエラーが起きたり、特殊なケースに遭遇すると、 HyperText Transfer Protocol に関するいくつかのことを理解する必要があります。 HTTP に関して最も包括的で信頼できる文献は RFC 2616 [http://tools.ietf.org/html/rfc2616.html] です。この文書は技術文書なので簡単には読めません。この HOWTO の目的は urllib2 の利用法を例示することです、 HTTP についてはその助けになるのに十分に詳しく載せています。このドキュメントは urllib2 のドキュメントの代わりにはなりませんが、補完する役割を持っています。

URL を取得する

urllib2 を利用する最も簡単な方法は以下です:

import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()

多くの urllib2 の利用法はこのように簡単です (‘http:’ の代わりに URL を ‘ftp:’ や ‘file:’ 等で始めればできます。)。しかし、このチュートリアルの目的は、得に HTTP に絞って、より複雑な状況を説明することです。

HTTP はリクエスト (request) とレスポンス (response) が基本となっています - クライアントがリクエストし、サーバーがレスポンスを送ります。 urllib2 はこれを真似て、作成する HTTP リクエストを表現する Request オブジェクトを備えています。リクエストオブジェクトを作成する最も簡単な方法は取得したい URL を指定することです。 urlopen をこのオブジェクトを使って呼び出すと、リクエストした URL のレスポンスオブジェクトが返されます。このレスポンスはファイルライクオブジェクトで、これはつまりレスポンスに .read() と呼び出せることを意味しています:

import urllib2

req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)
the_page = response.read()

urllib2 は同じリクエストインターフェースを全ての URL スキームに対して利用できるようにしています。例えば、FTP リクエストの場合はこうできます:

req = urllib2.Request('ftp://example.com/')

HTTP の場合には、リクエストオブジェクトに対して二つの特別な操作ができます: 一つ目はサーバーに送るデータを渡すことができる、二つ目はサーバーに送るデータやリクエスト自身に ついての 特別な情報 (“metadata”)を渡すことができます - これらの送られる情報は HTTP 「ヘッダ」です。今度はこれらに関してひとつひとつ見ていきましょう。

データ

URL にデータを送りたい場合はよくあります (しばしば、その URL は CGI (Common Gateway Interface) スクリプト [1] や他の web アプリケーションを参照することになります)。これは HTTP では、 POST リクエストとして知られる方法で行なわれます。これは web 上で HTML フォームを埋めて送信するときにブラウザが行なっていることです。全ての POST がフォームから送られるとは限りません: 自身のアプリケーションに対して任意のデータを POST を使って送ることができます。一般的な HTML フォームの場合、データは標準的な方法でエンコードされている必要があり、リクエストオブジェクトに data 引数として渡します。エンコーディングは urllib2 からではなく、 urllib ライブラリの関数を使って行います:

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
values = {'name' : 'Michael Foord',
          'location' : 'Northampton',
          'language' : 'Python' }

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()

他のエンコーディングが必要な場合があることに注意して下さい (例えば、 HTML フォームからファイルをアップロードするための詳細については HTML Specification, Form Submission [http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13] を見て下さい

data 引数を渡さない場合、urllib2 は GET リクエストを利用します。 GET と POST リクエストの一つの違いは、POST リクエストにしばしば、「副作用」があることです: POST リクエストはいくつかの方法によってシステムの状態を変化させます (例えば100ポンドのスパムの缶詰をドアの前まで配達する注文を web サイトで行う)。とはいえ HTTP 標準で明確にされている内容では、POST は 常に 副作用を持ち、 GET リクエストが副作用を持つことを禁止していません、副作用の無い POST リクエストはありません。 HTTP の GET リクエストでもデータ自身をエンコーディングすることでデータを渡すことができます。

以下のようにして行います:

>>> import urllib2
>>> import urllib
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.urlencode(data)
>>> print url_values
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
>>> data = urllib2.open(full_url)

? を URL に加え、それにエンコードされた値が続くことで、完全な URL が 作られていることに注意して下さい。

ヘッダ

ここでは特定の HTTP ヘッダについて議論します、 HTTP リクエストにヘッダを追加する方法について例示します。

いくつかの web サイト [2] はプログラムからブラウズされることを嫌っていたり、異なるブラウザに対して異なるバージョンのブラウザに送ります [3] 。デフォルトでは urllib2 は自身の情報を Python-urllib/x.y として扱います (x と y は Python のリリースバージョンのメジャーバージョン、マイナーバージョンです、例えば Python-urllib/2.5 など)、これによって web サイト側が混乱したり、動作しないかもしれません。ブラウザは自身の情報を User-Agent ヘッダ [4] を通して扱っています。リクエストオブジェクトを作るときに、ヘッダに辞書を渡すことができます。以下の例は上の例と同じですが、自身を Internet Explorer [5] のバージョンの一つとして扱っています。

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
          'location' : 'Northampton',
          'language' : 'Python' }
headers = { 'User-Agent' : user_agent }

data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

レスポンスは二つの便利なメソッドも持っています。 info と geturl の節を見て下さい、この節は後で問題が起きた場合に見ておくべき内容です。

例外を処理する

urlopen はレスポンスを処理できなかった場合、 URLError を送出します (ふつうの Python API では、組み込み例外の ValueError, TypeError などが送出されますが)。

HTTPError は URLError のサブクラスで HTTP URLs の特定の状況で送出されます。

URLError

URLError が送出されることはよく起こります、それはネットワーク接続が無い場合や、指定したサーバが無い場合です。この場合、例外は ‘reason’ 属性を持っていて、この属性はエラーコードとエラーメッセージのテキストを含むタプルです。

例:

>>> req = urllib2.Request('http://www.pretend_server.org')
>>> try: urllib2.urlopen(req)
>>> except URLError, e:
>>>    print e.reason
>>>
(4, 'getaddrinfo failed')

HTTPError

サーバーからの全ての HTTP レスポンスは「ステータスコード」の数値を持っています。多くの場合ステータスコードはサーバーがリクエストを実現できなかったことを意味します。デフォルトハンドラーはこれらのレスポンスのいくつかを処理してくれます(例えばレスポンスが「リダイレクション」、つまりクライアントが別の URL を取得するように要求する場合には urllib2 はこの処理を行ってくれます。) 処理できないものに対しては urlopen は HTTPError を送出します。典型的なエラーには ‘404’ (page not found), ‘403’ (request forbidden) と ‘401’ (authentication required) が含まれます。

HTTP のエラーコード全てについては RFC 2616 の10節を参照して下さい。

送出された HTTPError インスタンスは整数の ‘code’ 属性を持っていて、サーバーによって送られた応答に対応しています。

エラーコード

デフォルトハンドラーはリダイレクト(コードは300番台にあります) を処理し、 100-299番台のコードは成功を意味しているので、たいていの場合は400-599番台のエラーコードのみを見るだけですみます。

BaseHTTPServer.BaseHTTPRequestHandler.responses は RFC2616 で利用されるレスポンスコード全てを示す便利な辞書です。この辞書は便利なのでここに載せておきます:

# Table mapping response codes to messages; entries have the
# form {code: (shortmessage, longmessage)}.
responses = {
    100: ('Continue', 'Request received, please continue'),
    101: ('Switching Protocols',
          'Switching to new protocol; obey Upgrade header'),

    200: ('OK', 'Request fulfilled, document follows'),
    201: ('Created', 'Document created, URL follows'),
    202: ('Accepted',
          'Request accepted, processing continues off-line'),
    203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
    204: ('No Content', 'Request fulfilled, nothing follows'),
    205: ('Reset Content', 'Clear input form for further input.'),
    206: ('Partial Content', 'Partial content follows.'),

    300: ('Multiple Choices',
          'Object has several resources -- see URI list'),
    301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
    302: ('Found', 'Object moved temporarily -- see URI list'),
    303: ('See Other', 'Object moved -- see Method and URL list'),
    304: ('Not Modified',
          'Document has not changed since given time'),
    305: ('Use Proxy',
          'You must use proxy specified in Location to access this '
          'resource.'),
    307: ('Temporary Redirect',
          'Object moved temporarily -- see URI list'),

    400: ('Bad Request',
          'Bad request syntax or unsupported method'),
    401: ('Unauthorized',
          'No permission -- see authorization schemes'),
    402: ('Payment Required',
          'No payment -- see charging schemes'),
    403: ('Forbidden',
          'Request forbidden -- authorization will not help'),
    404: ('Not Found', 'Nothing matches the given URI'),
    405: ('Method Not Allowed',
          'Specified method is invalid for this server.'),
    406: ('Not Acceptable', 'URI not available in preferred format.'),
    407: ('Proxy Authentication Required', 'You must authenticate with '
          'this proxy before proceeding.'),
    408: ('Request Timeout', 'Request timed out; try again later.'),
    409: ('Conflict', 'Request conflict.'),
    410: ('Gone',
          'URI no longer exists and has been permanently removed.'),
    411: ('Length Required', 'Client must specify Content-Length.'),
    412: ('Precondition Failed', 'Precondition in headers is false.'),
    413: ('Request Entity Too Large', 'Entity is too large.'),
    414: ('Request-URI Too Long', 'URI is too long.'),
    415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
    416: ('Requested Range Not Satisfiable',
          'Cannot satisfy request range.'),
    417: ('Expectation Failed',
          'Expect condition could not be satisfied.'),

    500: ('Internal Server Error', 'Server got itself in trouble'),
    501: ('Not Implemented',
          'Server does not support this operation'),
    502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
    503: ('Service Unavailable',
          'The server cannot process the request due to a high load'),
    504: ('Gateway Timeout',
          'The gateway server did not receive a timely response'),
    505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
    }

エラーが起きた場合、サーバーは HTTP エラーコード と エラーページを返して応答します。返されたページに対する応答として HTTPError インスタンスを使うことができます。これは code 属性に対しても同様です、これらは read も geturl, info などのメソッドも持っています。:

>>> req = urllib2.Request('http://www.python.org/fish.html')
>>> try:
>>>     urllib2.urlopen(req)
>>> except URLError, e:
>>>     print e.code
>>>     print e.read()
>>>
404
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<?xml-stylesheet href="./css/ht2html.css"
    type="text/css"?>
<html><head><title>Error 404: File Not Found</title>
...... etc...

エラーをラップする

HTTPError または URLError が起きたときのために準備しておきたい場合には。二つの基本的なアプローチがあります。私は二つ目のアプローチを好みます。

その1

from urllib2 import Request, urlopen, URLError, HTTPError
req = Request(someurl)
try:
    response = urlopen(req)
except HTTPError, e:
    print 'The server couldn\'t fulfill the request.'
    print 'Error code: ', e.code
except URLError, e:
    print 'We failed to reach a server.'
    print 'Reason: ', e.reason
else:
    # everything is fine

ノート

except HTTPError が 必ず 最初に来る必要があります、そうしないと except URLError も HTTPError を捕捉してしまいます。

その2

from urllib2 import Request, urlopen, URLError
req = Request(someurl)
try:
    response = urlopen(req)
except URLError, e:
    if hasattr(e, 'reason'):
        print 'We failed to reach a server.'
        print 'Reason: ', e.reason
    elif hasattr(e, 'code'):
        print 'The server couldn\'t fulfill the request.'
        print 'Error code: ', e.code
else:
    # everything is fine

info と geturl

レスポンスは urlopen (または HTTPError インスタンス) によって返され、 info() と geturl() の二つの便利なメソッドを持っています。

geturl - これは取得したページの実際の URL を返します。 urlopen (または 利用される opener オブジェクト) はリダイレクトに追従するため、有用です。取得したページの URL は要求した URL と同じとは限りません。

info - これは取得したページ (特にサーバからヘッダ)を表す辞書風オブジェクトを返します。これは現在では httplib.HTTPMessage インスタンスです。

典型的なヘッダは ‘Content-length’, ‘Content-type’ 等を含んでいます。 HTTP ヘッダその意味と利用法について簡単な説明がつきの便利な一覧 Quick Reference to HTTP Headers [http://www.cs.tut.fi/~jkorpela/http.html] を参照して下さい、

Openers と Handlers

URL を取得する場合、opener (混乱を招きやすい名前ですが、 urllib2.OpenerDirector のインスタンス) を利用します。標準的にはデフォルトの opener を - urlopen を通して - 利用していますが、カスタムの opener を作成することもできます。 oppener は handler を利用します。全ての「一番厄介な仕事」はハンドラによって行なわれます。各 handler は特定の URL スキーム (http, ftp, 等) での URL の開き方を知っていたり、 URL を開く局面でどう処理するかを知っています、例えば HTTP リダイレクションや HTTP のクッキーなど。

インストール済みの特定のハンドラで URL を取得したい場合には、 opener を作成したいと思うでしょう、例えばクッキーを処理する opener が得たい場合や、リダイレクションを処理しない opener を得たい場合。

opener を作成するには、 OpenerDirector をインスタンス化して、続けて、 .add_handler(some_handler_instance) を呼び出します。

それに代わる方法として、 build_opener を利用することもできます、これは opener オブジェクトを一回の関数呼び出しで作成できる便利な関数です。 build_opener はいくつかのハンドラをデフォルトで追加しますが、デフォルトのハンドラに対して追加、継承のどちらかまたは両方を行うのに手っ取り早い方法を提供してくれます。

追加したくなる可能性がある handler としては、プロキシ処理、認証など、一般的ですがいくらか特定の状況に限られるものでしょう。

install_opener も (グローバルな) デフォルト opener オブジェクトの作成に利用できます。つまり、 urlopen を呼び出すと、インストールした opener が利用されます。

opener オブジェクトは open メソッドを持っていて、 urlopen 関数と同じ様に、url を取得するのに直接呼び出すことができます: 利便性を除けば install_opener を使う必要はありません。

Basic 認証

ハンドラの作成とインストールを例示するのに、 HTTPBasicAuthHandler を利用してみます。この話題についてのより詳しい議論は – Basic 認証がどうやって動作するのかの説明も含んでいる Basic Authentication Tutorial [http://www.voidspace.org.uk/python/articles/authentication.shtml] を参照して下さい。

認証が必要な場合、サーバは認証を要求するヘッダ (401 のエラーコードとともに) を送ります。これによって認証スキームと ‘realm’ が指定されます。ヘッダはこのようになっています: Www-authenticate: SCHEME realm="REALM" 。

例:

Www-authenticate: Basic realm="cPanel Users"

クライアントはリクエストヘッダに含まれる realm に対して適切な名前とパスワードとともにリクエストを再試行する必要があります。これが ‘basic 認証’ です。一連の流れを簡単化するために、 HTTPBasicAuthHandler のインスタンスを作成し、 opener が handler を利用するようにします。

HTTPBasicAuthHandler はパスワードマネージャーと呼ばれる、 URL と realm をパスワードとユーザ名への対応づけを処理する、オブジェクトを利用します。 realm が何なのか(サーバから返される認証ヘッダから) 知りたい場合には、 HTTPPasswordMgr を利用できます。多くの場合、realm が何なのかについて気にすることはありません。そのような場合には HTTPPasswordMgrWithDefaultRealm を使うと便利です。これは URL に対してデフォルトのユーザ名とパスワードを指定できます。これによって特定の realm に対する代替の組み合わせを提供することなしに利用できるようになります。このことは add_password メソッドの realm 引数として None を与えることで明示することができます。

トップレベルの URL が認証が必要なはじめに URL です。この URL よりも「深い」URL を渡しても .add_password() は同様にマッチします。:

# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

# Add the username and password.
# If we knew the realm, we could use it instead of ``None``.
top_level_url = "http://example.com/foo/"
password_mgr.add_password(None, top_level_url, username, password)

handler = urllib2.HTTPBasicAuthHandler(password_mgr)

# create "opener" (OpenerDirector instance)
opener = urllib2.build_opener(handler)

# use the opener to fetch a URL
opener.open(a_url)

# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)

ノート

上の例では build_opener に HHTPBasicAuthHandler のみを与えましたが。デフォルトの opener は普通の状況に適用するために – ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor を備えています。

top_level_url は実際には “http://example.com/” のような完全な URL (‘http:’ スキームとホスト名、オプションとしてポート番号、含む) か “example.com” や “example.com:8080” (後者はポート番号を含む) のような “authority” (つまり、ホスト名とオプションとしてポート番号を含む) のどちらでも かまいません。 authority の場合には “userinfo” 要素は含んではいけません - 例えば “joe@password:example.com” は不適切です。

プロキシ

urllib2 は自動でプロキシ設定を認識して使います。これは通常の handler の組に含まれる ProxyHandler を通して行なわれます。たいていの場合はこれでうまくいきますが、役に立たない場合もあります [6] 。この問題に対処する一つの方法はプロキシを定義しない ProxyHandler を組み立てることです。この方法は Basic Authentication [http://www.voidspace.org.uk/python/articles/authentication.shtml] handler を設定したときと同じような流れで行うことができます:

>>> proxy_support = urllib2.ProxyHandler({})
>>> opener = urllib2.build_opener(proxy_support)
>>> urllib2.install_opener(opener)

ノート

現在 urllib2 はプロキシ経由で https ロケーションを取得する機能をサポートしていません。しかし、urllib2 をこのレシピ [7] で拡張することで可能にすることができます。

ソケットとレイヤー

Python はレイヤー化された web 上からリソース取得もサポートしています。 urllib2 は httplib ライブラリを利用します、 httplib はさらに socket ライブラリを利用します。

Python 2.3 ではレスポンスがタイムアウトするまでのソケットの待ち時間を指定することができます。これは web ページを取得する場合に便利に使うことができます。 socket モジュールのデフォルトでは タイムアウトが無くハングしてしまうかもしれません。現在では socket のタイムアウトは httplib や urllib2 のレベルからは隠蔽されていています。しかし、以下を利用することで全てのソケットに対してグローバルにデフォルトタイムアウトを設定することができます:

import socket
import urllib2

# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)

# this call to urllib2.urlopen now uses the default timeout
# we have set in the socket module
req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)

脚注

このドキュメントは John Lee によって査読、改訂されました。

[1]
CGI プロトコルの入門については Writing Web Applications in Python [http://www.pyzine.com/Issue008/Section_Articles/article_CGIOne.html] を参照して下さい。

[2]
例を挙げると Google がそうです。プログラムから google を使う正しい やり方は、もちろん PyGoogle [http://pygoogle.sourceforge.net] を利用することです。 Google API を利用した例については Voidspace Google [http://www.voidspace.org.uk/python/recipebook.shtml#google] を参照して下さい。

[3]
ブラウザを検知すること (browser sniffing) は web サイトのデザインにおけるとても悪い習慣です - web 標準を利用する方が賢明でしょう。不幸なことに未だに多くの web サイトが異なるブラウザに対して異なるバージョンを返しています。

[4]
MSIE 6 のユーザエージェントは ‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)’ です。

[5]
HTTP リクエストヘッダの詳細については、 Quick Reference to HTTP Headers [http://www.cs.tut.fi/~jkorpela/http.html] を参照して下さい。

[6]
私の場合は仕事中にインターネットにアクセスするにはプロキシを利用する必要があります。 localhost の URL に対してこのプロキシを経由してアクセスしようとすれば、ブロックされます。IE を proxy を利用するように設定すれば、 urllib2 はその情報を利用します。 localhost のサーバでスクリプトをテストしようとすると、 urllib2 がプロキシを利用するのを止めなければいけません。

[7]
urllib2 opener for SSL proxy (CONNECT method): ASPN Cookbook Recipe [http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195].

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

Python を Web 上で使うには HOWTO

Author:
Marek Kubica

概要

このドキュメントは Python を web 向けに組み込む方法を示します。 Python を web サーバとともに利用するためのいくつかの方法や web サイトを開発する際の一般的なプラクティスを示します。

web サイトのコンテンツをユーザが作るということに焦点を当てた “Web 2.0” の提起以来 Web プログラミングは人気の話題となっています。 web サイトを作るのに Python を利用することは可能でしたが、それは退屈な作業でした。そのため、開発者がサイトを速く、頑強に作るのを助けるために多くの「フレームワーク」と補助ツールが作成されました。この HOWTO では動的なコンテンツを作成するために Python と web サーバを結合させるいくつかの方法について述べます。この話題に対する一般的な入門はこのドキュメントだけで扱いきれないほど広いわけではありませんが、ここでは最も人気のあるライブラリの簡単な概要のみを扱います。

参考

この HOWTO は Python を web 上で使う方法の概要を扱おうとしていますが、 HOWTO が常に望みどおりに最新の状況を伝えているとは限りません。 Python での web 開発は急速に発展しています、そのため Wiki ページ Web Programming [http://wiki.python.org/moin/WebProgramming] に多くの最新の開発に関する内容があるでしょう。

低レベルから見て

ユーザが web サイトを訪れた時、ブラウザはサイトの web サーバとコネクションを形成します (これは リクエスト と呼ばれます)。サーバはファイルシステム上からファイルを探し出し、ユーザのブラウザにそれを送り返し、ブラウザが表示します (これが レスポンス です)。これが基礎となるプロトロル、 HTTP のおおまかな動作です。

さて、動的な web サイトはファイルシステム上のファイルではなく、リクエストが来たときに web サーバが実行するプログラムです。それらは掲示板の投稿を表示したり、メールを表示したり、ソフトウェアの設定や現在時刻の表示などの様々な便利なことができます。これらのプログラムはサーバがサポートするあらゆる言語で書くことができます、そのため動的な web サイトを作成するのに Python を利用することは簡単です。

ほとんどの HTTP サーバは C や C++ で書かれていて、これらは Python コードを単純な方法で実行できません – サーバとプログラムの間にブリッジが必要です。これらのブリッジやインターフェースはプログラムがサーバとどうやりとりするかを定めます。これまでに最良のインターフェースを決めるために膨大な数の試みがなされてきましたが、言及すべきものはわずかです。

全ての web サーバが全てのインターフェースをサポートしているわけではありません。多くの web サーバは古い、現在では撤廃されたインターフェースのみをサポートしています。しかし、多くの場合にはサードパーティーモジュールを利用して新しいインターフェースをサポートするように拡張できます。

Common Gateway Interface

このインターフェースは最も古く、ほとんどの web サーバでサポートされ、すぐに使うことができます。 CGI を利用して web サーバと通信するプログラムはリクエスト毎に起動される必要があります。そのため毎回のリクエストは新しい Python インタプリタを起動します – このため起動にいくらか時間がかかります – そのためこのインターフェースは負荷が少ない状況にのみ向いています。

CGI の利点は単純だということです – CGI を利用するプログラムを書くのは3行のコードを書くだけです。しかし、この単純さは後で高くつきます; 開発者を少ししか助けてくれません。

CGI プログラムを書くことは可能ではありますが、もはや推奨されません。 WSGI (詳しくは後で述べます) では CGI をエミュレートするプログラムを書くことができます、そのため、よりよい選択肢が選べない場合には CGI としてプログラムを実行できます。

参考

Python の標準ライブラリには簡素な CGI プログラムを作成するのを助けるいくつかのモジュールが含まれています:

cgi – CGI スクリプトでのユーザ入力を扱います

cgitb – CGI アプリケーションの中でエラーが発生した場合に、 “500 Internal Server Error” メッセージの代わりに親切なトレースバックを表示します

Python wiki では CGI scripts [http://wiki.python.org/moin/CgiScripts] ページに Python での CGI に関した追加情報を取り上げています。

CGI をテストするための単純なスクリプト

CGI が web サーバで動くかどうかを調べるのに、この短かく単純な CGI プログラムが利用できます:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# enable debugging
import cgitb; cgitb.enable()

print "Content-Type: text/plain;charset=utf-8"
print

print "Hello World!"

このコードは .py または .cgi 拡張子をつけたファイルに書く必要があります、どちらを使うかは web サーバの設定に依存します。 web サーバの設定によっては、ファイルは cgi-bin フォルダ内にある必要があるかもしれません、これはセキュリティ上の理由のためです。

cgitb 行が何なのか疑問に思うかもしれません。この行は、クラッシュしてブラウザで “Internal Server Error” と表示する代わりに、親切なトレースバックを表示できるようにします。これはデバッグの際に便利ですが、いくつかの重要なデータをユーザにさらけ出すリスクにもなりえます。スクリプトを完成品として利用する準備ができたら cgitb は使ってはいけません。さらに、 常に 例外を捕捉し、適切なエラーページを表示するようにしなければいけません – エンドユーザは漠然とした “Internal Server Errors” をブラウザで見ることを好みません。

自身のサーバで CGI を立ち上げる

自身の web サーバを持っていない場合には、この内容は当てはまらないでしょ。そのままで動作するか調べることは可能です、もし動作しない場合、とにかく web サーバの管理者と話し合う必要があります。大きなホストである場合、チケットを埋めて Python サポートを得るということができるでしょう。

あなた自身が管理者であるか、自身のコンピュータで試すためにインストールしたい場合には自分自身で設定する必要があります。異なる設定オプションを持つ web サーバがたくさんあるため、 CGI の設定法はひとつではありません、現在最も広く使われている web サーバは Apache HTTPd [http://httpd.apache.org/] です、 Apache を簡単に説明すると – 最も多くの人が利用しているもので、ほとんど全てのシステムでシステムのパッケージ管理ソフトを利用して簡単にインストールできます。ただし lighttpd [http://www.lighttpd.net] も注目を集め始めていて、さらにパフォーマンスの面でより優れているといわれています。多くのシステムでこのサーバはパッケージ管理ソフトを利用してインストールできるので、 web サーバを手動でコンパイルする必要は全くありません。

Apache ではチュートリアル Dynamic Content with CGI [http://httpd.apache.org/docs/2.2/howto/cgi.html] を参照できます、これには全てが書かれています。多くの場合には +ExecCGI を設定すれば十分です。このチュートリアルはよくでくわす可能性のある落し穴についても書かれています。

lighttpd では CGI module [http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI] を使う必要があります、これは直接的な方法で設定できます。結局のところ、 cgi.assign を適切に設定することになります。

CGI スクリプトでの一般的な問題

CGI を利用しようとすると、しばしば小さないらいらを生むことになります、その中でおそらく経験するものの一つは実行時するためにこれらのスクリプトの取得を試みるときに起きます。これによって一見正しいスクリプトが期待どおりに動かないことはよくあります、これにはいくつかの小さな隠れた理由があるので、突き止めるのが困難です。

いくつかの理由:

Python スクリプトが実行可能であると示されていない。 CGI スクリプトが実行不可能な場合、多くの web サーバは実行しユーザに出力を送る代わりに、ユーザがダウンロードできるようにします。 CGI スクリプトに対しては適切に実行するために +x ビットが設定される必要があります。 chmod a+x your_script.py を使うことで問題は解決します。

行末は Unix 形式である必要があります。これは、web サーバがスクリプト最初の行 (shebang と呼ばれます) を調べ、そこで指定されたプログラムの実行を試みるため重要となります。これは Windows の行末 (Carriage Return & Line Feed、または CRLF) とよく混同されます、そのためファイルを Unix 行末 (Line Feed のみ LF) に変換する必要があります。これは FTP 経由でテキストモードではなくバイナリモードでファイルをアップロードすると自動的に行なわれますが、より望ましい方法は単にテキストエディタで Unix 行末で保存することです。多くの適切なエディタはこれをサポートしています。

web サーバはファイルを読めるようにしなければいけないので、パーミッションが適切になっているか確認してください。しばしば、サーバは www-data ユーザ、グループとして実行します、そのためファイルのオーナーシップを変更するか、 chmod a+r your_script.py を使いファイルを全世界から読み込み可能にするといったことは試す価値があります。

web サーバはアクセスを試みているファイルが CGI スクリプトであるということを知っていなければいけません。 web サーバの設定を確認して下さい、おそらくそこに間違いがあります。

shebang 内のインタプリタへのパス (#!/usr/bin/env python) は正確でないといけません。この行は Python を見つけるために /usr/bin/env を呼び出しますが、 /usr/bin/env が無い場合失敗します。 Python がどこにインストールされているか知っている場合、そのパスを使うこともできます。 whereis python と type -p python なども python がどこにインストールされたかを探すのに役立つでしょう。一旦わかってしまえば、shebang 行をそれに応じて変更できます: #!/usr/bin/python 。

ファイルは BOM (Byte Order Mark) を含んでいてはいけません。 BOM は UTF-16 エンコーディングのバイト順を決定するのに利用されます、しかしいくつかのエディタは UTF-8 ファイルに対してもそれを書き込むことがあります。 BOM は shebang 行に影響するので、エディタが BOM を書かないようにしてください。

mod_python が問題となることがあります。mod_python はそれ自身で CGI スクリプトを扱うことができますが、そのことが問題の原因となることがあります。利用できないようにして下さい。

mod_python

PHP から来た人達はしばしば、Python を web 上で利用する方法を把握するのに苦労します。彼らはたいてい最初に mod_python [http://www.modpython.org/] が mod_php と等価だと考えて、利用しようとします。しかし実際にはそうではありません。 mod_python は Apache プロセスにインタプリタを埋め込まないため、毎回のリクエストで起動せずスピードアップします。一方で PHP でよくやるような「HTML への Python の埋め込み」とはかけ離れています。 Python でそれと等価なことをするのはテンプレートエンジンです。 mod_python 自身はより強力で Apache 内部に対してより多くのアクセスを提供します。 CGI をエミュレートし、 JSP に似た「HTML への Python 埋め込み」である “Python Server Pages” モードで動作でき、全てのリクエストを一つのファイルで受け付けて何を実行するを決める “Publisher” を持っています。

しかし、 mod_python はいくつかの問題も抱えています。 PHP インタプリタと違い Python インタプリタはファイル実行時にキャッシュを利用するため、ファイルの変更時にはアップデートするには web サーバ全体を再起動する必要があります。もう一つの問題は基本的なコンセプトにあります – Apache はリクエストを扱うためにいくつかの子プロセスを開始し、不幸にも全ての子プロセスが Python インタプリタ全体を、利用しない場合であっても、読み込む必要があるのです。このため web サーバ全体が遅くなります。別の問題は mod_python は libpython が特定のバージョンに対してリンクされることです、 mod_python を再コンパイルせずに古いバージョンから新しいバージョンに切り替える (例えば 2.4 から 2.5) ことはできません。さらに mod_python は Apache web サーバに制限されるため mod_python 用に書かれたプログラムは他の web サーバで簡単に動かすことはできません。

これらが新しくプログラムを書く際に mod_python を避けるべき理由です。いくつかの状況では mod_python を利用するのはよいアイデアでしょうが、 WSGI は mod_python 下でも WSGI プログラムを同様に動かせます。

FastCGI と SCGI

FastCGI と SCGI は CGI のパフォーマンス上の問題を別の方法で解決しようという試みです。 web サーバにインタプリタを組み込む代わりに、それらはバックグラウンドで長時間実行されるプロセスを生成します。さらに web サーバ上にはいくつかのモジュールがあり、それらは web サーバとバックグラウンドプロセスが「話す」ことを可能にします。バックグラウンドプロセスはサーバと独立しているため、もちろん Python を含んだ、任意の言語で書くことができます。言語は web サーバとの通信を扱うライブラリを持っている必要があるだけです。

FastCGI と SCGI の違いはささいなもので、SCGI は基本的に “simpler FastCGI” です。しかし、SCGI をサポートする web サーバは限定されているため、多くの人々は代わりに同様に動作する FastCGI を利用します。 SCGI に適用されるほとんど全てのものは FastCGI にも適用できます、そのため後者のみを書くことになるでしょう。

最近では FastCGI を直接呼ぶことはありません。 mod_python のように WSGI アプリケーションのみが利用されてます。

参考

FastCGI, SCGI, and Apache: Background and Future [http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/] には FastCGI と SCGI のコンセプトが mod_python よりどうして優れているかが検討されています。

FastCGI のセットアップ

web サーバに応じて特別なモジュールが必要となります。

Apache には mod_fastcgi [http://www.fastcgi.com/] と mod_fcgid [http://fastcgi.coremail.cn/] の両方があります。 mod_fastcgi が最初に作られましたが、非フリーとして扱われるという、いくつかのライセンスの問題があります。 mod_fcgid はより小さく、前者と互換性があります。このうちのどちらかを Apache から読み込む必要があります。

lighttpd は自身に FastCGI module [http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI] を含んでいて、 SCGI module [http://trac.lighttpd.net/trac/wiki/Docs%3AModSCGI] も同様に含んでいます。

nginx も FastCGI [http://wiki.codemongers.com/NginxSimplePythonFCGI] をサポートしています。

一旦モジュールをインストールして設定したら、以下の WSGI アプリケーションを使ってテストできます:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from cgi import escape
import sys, os
from flup.server.fcgi import WSGIServer

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])

    yield '<h1>FastCGI Environment</h1>'
    yield '<table>'
    for k, v in sorted(environ.items()):
         yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v))
    yield '</table>'

WSGIServer(app).run()

これは単純な WSGI アプリケーションですが、まず flup [http://pypi.python.org/pypi/flup/1.0] をインストールする必要があります、 flup は低レベルの FastCGI アクセスを取り扱います。

参考

setting up Django with FastCGI [http://www.djangoproject.com/documentation/fastcgi/] にドキュメントがあります、この内の多くは WSGI 互換フレームワークやライブラリで再利用できます。代わりに manage.py の部分を変更するだけで、ここで使った例を利用できます。 Django もほとんど同様のことを行います。

mod_wsgi

mod_wsgi [http://www.modwsgi.org/] 低レベルなゲートウェイから脱するための試みです。 WSGI アプリケーションをどうにかして利用可能にするには多くの場合 FastCGI、SCGI、mod_python が利用されるますが、 mod_wsgi は WSGI アプリケーションを直接 Apache web サーバに埋め込みます。この方法をとることによる恩恵はホストの WSGI アプリケーションのために特別にデザインされたものと比べてより簡単な WSGI アプリケーションを利用できることです – ホストの WSGI アプリケーションに対するグルーコードを持つ他の低レベルな方法 (先ほど述べた flup のような) と違って。 mod_wsgi の欠点は Apache web サーバに制限されているということです、他の web サーバは mod_wsgi の独自実装が必要となります。

mod_wsgi は2つのモードをサポートします: 埋め込みモード(embeded mode)は Apache プロセスとデーモンプロセスを統合し、動作としては FastCGI に似ています。 FastCGI と比較すると、mod_wsgi はそれ自身がワーカープロセスを取り扱うので管理が楽になります。

後ろに下って: WSGI

WSGI について何度も言及してきたため、なにか重要そうに感じたでしょう。実際に重要なので、ここで説明します。

Web Server Gateway Interface, PEP 333 [http://www.python.org/dev/peps/pep-0333] または略して WSGI は現在のところ Python で web プログラミングをする最良の方法です。 programmers writing framework として卓越している一方で、一般の人は直接接点を持つ必要はありません。しかし、web 開発フレームワークとして選択する場合に、 WSGI を選ぶことは素晴しい考えです。

WSGI を使う上での大きな利益は、統一性です。 WSGI と互換性のあるプログラムであれば – これはフレームワークが WSGI をサポートしているということを意味し、プログラムは WSGI ラッパーを持つ全ての web サーバインターフェースで利用可能になります。つまりユーザが mod_python か FastCGI どちらを利用しているかを気にせずにすみます。– WSGI を使うことで任意ゲートウェイインターフェース上で動作するようになります。 Python 標準ライブラリには、テストのために利用できる小さな web サーバである、独自の WSGI サーバ wsgiref が含まれています。

WSGI の本当に卓越している機能はミドルウェアです。ミドルウェアとはプログラムに様々な機能性を加えるためのレイヤーのことを指します。無数のミドルウェア [http://wsgi.org/wsgi/Middleware_and_Utilities] が利用可能になっています。例えばセッション管理(連続したリクエストの中でユーザを同定を行います、HTTP は状態を維持しないので、リクエストが同じユーザのものであるということがわかります)を書く代わりに、ミドルウェアを取ってきて繋ぐだけで、既存の機能を当てにできます。圧縮についても同じです – HTML を gzip で圧縮してサーバの帯域を節約したい場合。ミドルウェアを組み込むだけで行うことができます。認証もミドルウェアで簡単に解決できる問題です。

一般的には – WSGI は複雑に思えるかもしれませんが、 WSGI は web サイトを書く際に起きうる多くの問題の解決法を持っているため、学習の初期段階を実りあるものにしてくれます。

WSGI サーバ

CGI や mod_python などに様々な低レベルゲートウェイに接続するためのコードを WSGI サーバ と呼びます。これらのサーバの一つに flup があります、これは前に述べましたが FastCGI、SCGI と AJP [http://en.wikipedia.org/wiki/Apache_JServ_Protocol] をサポートしています。これらのサーバのいくつかは flup のように Python で書かれていますが、 C で書かれたものもあります、それらは気軽に置き換えることができます。

いくつものサーバが利用可能ですから、Python の web アプリケーションはほとんどどこでも利用できます。これは他の web テクニックと比べたときの Python の大きな利点です。

参考

WSGI wiki [http://wsgi.org/wsgi] は全ての WSGI に関連したコードに対して素晴しい概観を与えてくれます、ここには WSGI をサポートするアプリケーション 全て が利用できるサーバの広大なリスト WSGI servers [http://wsgi.org/wsgi/Servers] が含まれています。

標準ライブラリに含まれる WSGI をサポートするモジュールに興味が湧いたかもしれません:

wsgiref – WSGI のためのいくつかの小さなユーティリティとサーバ

事例研究: MoinMoin

WSGI は web アプリケーションプログラマに何をもたらしてくれるのでしょうか? 長く存在しているWSGI を使わない、Python で書かれた web アプリケーションをみてみましょう。

最も広く使われている wiki ソフトウェアの一つに MoinMoin [http://moinmo.in/] があります。これは2000年に作られたため、WSGI より3年ほど先行していました。現在では WSGI をサポートしていますが、古いバージョンでは CGI、mod_python、FastCGI、スタンドアロンで動作するためには別々のコードが必要でした。いまやこれら全ては WSGI と既存のゲートウェイを使って可能になりました。 FastCGI 上では flup を使って実行できますし、スタンドアロンサーバとして実行するには wsgiref を使うことになります。

Model-view-controller

MVC という用語は 「フレームワーク foo は MVC をサポートしています」というような文句でよく聞きます。 MVC は技術的なものというよりかは、構造的なものです、多くの web フレームワークはこのモデルを使って開発者がプログラムに構造を持ちこむことを助けています。大きな web アプリケーションはたくさんのコードを持っているので、最初からプログラムに構造を持たせることはよい考えです。そうすることで、他のフレームワーク(他の言語でもかまいません、MVC は Python 特有のものではないので)のユーザであっても、構造に既に馴染んでいるため、存在しているコードを簡単に理解できるようになります。

MVC は三要素からできています:

model これは変更されるデータのことです。たいていの Python のフレームワークでこの要素は object-relational マッパーを利用したクラスで表現されます。つまり宣言部分はここに集約されます。

view この要素はモデルのデータをユーザに表示する仕事を行います。典型的にはこの要素はテンプレートで表現されます。

controller これはユーザとモデルの間のレイヤーです。 controller はユーザの動作(特定の URL を開く等)に反応して、必要に応じてモデルにデータを変更するよう伝えます。

MVC を複雑なデザインパターンだと考える人もいるかもしれませんが、実際はそうではありません。 Python で使われているのは、それがきれいで保守可能な web サイトを作成するのに便利だということがわかっているからです。

ノート

全ての Python フレームワークが明示的に MVC をサポートしているわけではありませんが、 MVC パターンを使った、データロジック (model) とインタラクションロジック (controller) とテンプレート (view) を分離した web サイトを作成することはありふれています。その理由はテンプレートに不必要な Python コードを書かないことが重要なことだからです – MVC に反すると大混乱を生むことになります。

参考

Wikipedia の英語版には Model-View-Controller pattern [http://en.wikipedia.org/wiki/Model-view-controller] の記事があります、この記事には様々な言語での web フレームワークの長大なリストが含まれています。

web サイトの構成要素

web サイトは複雑な構造物です、そのため web サイト開発者の保守作業を助けるためにツールが作られました。それらのツールは Python 固有のものではないので、他のプログラミング言語に対しても存在します。もちろん、開発者はそれらのツールを使うことを強制されることはありませんし、たいていの場合において「最良」のツールも存在しません、しかし、開発者が利用できる道具は膨大にあるので、どれかを選ぶ前に情報を得ておくことは価値のあることです、

参考

ここで述べたものよりも多くの組み合わせ可能な要素が書かれています。 Python wiki にはこれらの要素についてのページ Web Components [http://wiki.python.org/moin/WebComponents] があります。

テンプレート

HTML と Python コードを混在させることは、いくつかのライブラリを利用することで可能になります。最初は便利ですが、そうすることでコードが保守不可能となる恐れがあります。これがテンプレートが存在する理由です。テンプレートは、最も単純な場合には、単にプレースホルダーを持つ HTML ファイルとなります。プレースホルダーを埋めた後に HTML はユーザのブラウザに送信されます。

Python はこのような単純なテンプレートを含んでいます:

# a simple template
template = "<html><body><h1>Hello %s!</h1></body></html>"
print template % "Reader"

Python の標準ライブラリには、 string.Template を通して利用できるより高度なテンプレートも含まれています、しかし、HTML テンプレートには Python の for や if のような条件やループなどが使えることが必要です。そのため、 テンプレートエンジン が必要になります。

いまや、Python には多くのテンプレートエンジンがあり、 framework とともに、または独立に利用できます。いくつかのテンプレートエンジンは平文のプログラミング言語を利用します、この言語はとても限定的なので簡単に学ぶことができます、一方で他のものには XML を利用し、テンプレートの出力が正当な XML であることが保証されているものがあります。いくつかの framework は独自のテンプレートエンジンを含んでいたり、特定のエンジンを使うことを推奨しています。もしどれがいいかわからない場合には、使ってみるといいでしょう。

ノート

Python はほんとうに様々なテンプレートエンジンを持っていますが、たいていの場合に手製のテンプレートシステムを使うことは理にかないません。全てのテンプレートシステムを評価するのは不毛ですから、最も人気のあるものを探すのに時間を割いた方がよいでしょう。いくつかのフレームワークは独自のテンプレートエンジンを持っていたり、推奨しているものがあります。これらを選ぶのが賢いでしょう。

人気のあるテンプレートエンジンに含まれるものは:

Mako

Genshi

Jinja

参考

たくさんの様々なテンプレートエンジンが、それぞれに注目を分けあっています、これは Python でのエンジン作成が簡単なためです。 wiki の Templating [http://wiki.python.org/moin/Templating] には巨大な今も増え続けるエンジンが列挙されています。

データの永続性

データの永続性 (data persistence) は複雑に聞こえますが、単にデータを蓄積するだけです。このデータはブログのエントリであったり、掲示板の投稿であったり、 wiki ページのテキストであったりします。例のごとく web サーバに情報をたくわえるには様々な方法があります。

しばしば MySQL [http://www.mysql.com/] や PostgreSQL [http://www.postgresql.org/] のようなリレーショナルデータベースエンジンが利用されます、それは数百万エントリに及ぶ非常に大きなデータベースを優れたパフォーマンスで扱うことができるためです。それらは SQL [http://en.wikipedia.org/wiki/SQL] と呼ばれる言語を利用した 照会 (queried) です。一般的な Python プログラマは SQL をあまり好みません、彼らはオブジェクトで動作する方を好みます。 ORM [http://en.wikipedia.org/wiki/Object-relational_mapping] と呼ばれる技術を使うことでデータベース内の Python オブジェクトを節約できます。 ORM は内部でオブジェクト指向的アクセスを SQL コードに変換し、ユーザはそのことを意識せずに済みます。多くの framework は ORMs を利用し、とてもうまく動作します.

第2の可能性はハードディスクに保存されたファイルを利用することです (しばしば、フラットファイルと呼ばれます)。これはとても簡単ですが、高速ではありません。 SQLite [http://www.sqlite.org/] と呼ばれる小さなデータベースエンジンもあります、これは Python に sqlite モジュールとしてバンドルされていて、ファイル一つだけを利用します。このデータベースは ORM 経由でオブジェクトを保存するのに利用できて、依存関係がありません。小さなサイトに対しては SQLite で十分です。ただ、データをファイルシステムに保存する方法はこれだけではありません。普通の平文のテキストファイルで十分な場合もあります。

第3の最も利用されない方法はオブジェクト指向データベースと呼ばれています。このデータベースは、OR マッピングによって行との間に作成されるリレーションの代わりに、実際のオブジェクト を保存します。この方法にはほとんど全てのオブジェクトを直接的な方法で保存できるという利点があります、これはリレーショナルデータベースでいくつかのオブジェクトが ORMs で表現するのが困難であるのと対照的です。

framework はしばしばユーザにどの方法を選べばいいか、ヒントを与えてくれます。たいていの場合、一つだけの方法を必要とする特別な条件がある場合がない限りは、それに従うことはいい考えです。

参考

Persistence Tools [http://wiki.python.org/moin/PersistenceTools] はファイルシステムにデータを保存する方法が列挙されています、これらのモジュールの内のいくつかは標準ライブラリの一部です

Database Programming [http://wiki.python.org/moin/DatabaseProgramming] はデータ保存の方法を選ぶのを助けてくれます

SQLAlchemy [http://www.sqlalchemy.org/] は Python での最も強力な OR マッパーで、 Elixir [http://elixir.ematia.de/] は利用しやすいものにしてくれます

SQLObject [http://www.sqlobject.org/] は別の人気のある OR マッパーです

ZODB [https://launchpad.net/zodb] と Durus [http://www.mems-exchange.org/software/durus/] の二つはオブジェクト指向データベースです

フレームワーク

web サイトは簡単に大きくなりうるので、開発者がそれらのサイトを簡単に扱えるよう助けるものはフレームワークと呼ばれます。最も知られたフレームワークは Ruby on Rails ですが、Python も独自のフレームワークを持っていて、それらは Rails からヒントを得たものであったり、Rails より以前から存在していたものであったりします。

web フレームワークのアプローチには二つの方法があります: 最小主義アプローチと全てを含む包括的アプーチ (しばしば full-stack と呼ばれます) です。包括的なフレームワークは作業を始めるのに必要なもの全てが揃っています、テンプレートエンジン、いくつかのデータベースへの保存、アクセス方法やその他の機能。それらは他の多くユーザによって広く利用されていて、本やチュートリアルといった形式で詳細なドキュメントが準備されているので、多くのユーザはそれらを利用して順調に進めることができます、他の web フレームワークは最小主義アプローチをとり、できるだけ自由に変えられるようにして、ユーザがどれが最良かを選ぶ自由を残せるようにしています。

ユーザの多数は包括的フレームワークを利用することで順調に進めることができます。それらのフレームワークは全てを備えているので、ユーザは単に飛び乗ってコートを書くことができます。それらには制限がある一方で、申し分なくやりたいと思った内容の 80% は埋めてくれます。それらは多様な要素から成っていて、それぞれの要素ができるだけうまく協調できるようにデザインされています。

Python で書かれた web フレームワークが大多数存在することは、実際にそれらを書くことが容易だということを実証しています。 Python で書かれた web アプリケーションで最も知られているものは Zope [http://www.zope.org/] で、これは大きなフレームワークの一種とみなすことができます。しかし、いまではほとんど忘れられていますが、Zope は単なるフレームワークではありません、利用者の多くが新しいものに移行したため、それらについてこれ以上記述する必要はないでしょう。

いくつかの著名なフレームワーク

膨大な数のフレームワークがあるので、全てについて記述することは不可能ですし、その必要さえありません、なぜならほとんどのフレームワークは特別なものではありませんし、それらにできることは人気のあるものでできます。

Django

Django [http://www.djangoproject.com/] はスクラッチから書かれた、とてもうまく協調する、いくつかの要素が強く結びついてできたフレームワークです。 ORM を含んでいてとても強力である上に、単純に利用でき、ブラウザからデータベース上のデータを編集できる優秀な管理インターフェースを持っています。テンプレートエンジンはテキストベースで動作し、 Python を書けないページデザイナーにとっても利用しやすいようにデザインされています。テンプレート継承やフィルタ (Unix のパイプのように動作します) と呼ばれるものもサポートしています。 Django は RSS フィードの作成や、ほぼ Python コード無しで web サイトを作ることができるようなジェネリックビューといった、多くの役に立つ機能をバンドルしています。

Django には、Django を利用して多くのサイトを作成してきた大きく、国際的なコミュニティがあります。 Django の通常の機能を拡張するアドオンプロジェクトもたくさんあります。この内容の一部は Django の素晴らしい online documentation [http://doc.djangoproject.com/] と Django book [http://www.djangobook.com/] によります。

ノート

Django は MVC スタイルフレームワークですが、 Django は構成要素に対して異なる名前で読んでいます、このことは Django FAQ [http://www.djangoproject.com/documentation/faq/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names] に詳しい記述があります。

TurboGears

Python の他に人気あるフレームワークは TurboGears [http://www.turbogears.org/] です。これは既存の要素と継ぎ目ををなくすためグルーコードを使ってそれらを組み合わせるアプローチをとっています。 TurboGears はユーザが自由に要素を選べるようにしていて、 ORM は制限が多い代わり使いやすいもの、複雑だが強力なもの、に切り替えて使うことができます。テンプレートエンジンにも同様のことがいえます。 TurboGears の強力な点は、構成要素が他のプロジェクトでも TurboGears への依存無しに簡単に利用できるということです、例えば TurboGears を支えている web サーバ CherryPy もそうです。

ドキュメントが TurboGears wiki [http://docs.turbogears.org/] にあり、スクリーンキャストへのリンクもあります。 TurboGears には関連した質問のほとんどに答えられる、活動的なユーザコミュニティがあります。入門に向いた TurboGears book [http://turbogearsbook.com/] も出版されています。

次の TurboGears のメジャーバージョン version 2.0 での計画では、 Pylons [http://pylonshq.com/] と呼ばれる別の柔軟なフレームワークによって提供される、より柔軟な基本要素に切り替えることになっています。

他の著名なフレームワーク

もちろんこれらの二つだけが利用できるフレームワーク全てではありません、人気では少し劣りますが、言及するに値するフレームワークがいくつかあります。

そのうちの一つは既に言及しましたが Zope です、このフレームワークはずいぶんと長い期間にわたって存在しています。 Zope 2.x はどちらかというと Pythonic でないとされてきましたが、新しい Zope 3.x ではその変更を試みて、Python プログラマから受け入れられ始めています。これらの努力は既に結果をみせ始めていて、 Repoze [http://repoze.org/] と呼ばれる Zope と WSGI を結びつけるプロジェクトや Grok [http://grok.zope.org/] と呼ばれる Zope の熟慮された要素を「普通の」Python プログラマが使えるようにするためのプロジェクトがあります。

既に述べた別のフレームワークに Pylons [http://pylonshq.com/] がありました。 Pylons は TurboGears とよく似ていますが、柔軟性に磨きがかかっていて、利用するコストが少々高くつきます。ほとんど全ての要素は交換することができるため、それぞれの要素について、ドキュメントを利用するこが避けられません、なぜなら各必要条件を満す Pylons の組み合わせの可能性は本当にたくさんあるのです。 Pylons は WSGI を扱いやすくするための広範囲なツールである、 Paste [http://pythonpaste.org/] を基にして組まれています。

これで全てが述べられたわけではありません。最新の情報の多くは Python wiki で見つけることができます。

参考

Python wiki には広大な web frameworks [http://wiki.python.org/moin/WebFrameworks] のリストがあります。

多くのフレームワークは独自のメーリングリストや IRC チャンネルを持っています、プロジェクトの web サイトからそれらを探して下さい。また、一般的な話題のために “Python in the Web” IRC チャンネルも #python.web [http://wiki.python.org/moin/PoundPythonWeb] と呼ばれる freenode 上にあります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python HOWTO »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる “Python HOWTO” の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

TAKAHASHI Tamotsu

打田旭宏

Arihiro TAKASE <hinaclegear at gmail.com>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問

Release: | 2.7
Date: | 2011年 12月 26日

一般 Python FAQ

プログラミング FAQ

デザインと歴史 FAQ

ライブラリと拡張 FAQ

拡張と埋め込み FAQ

Windows 上の Python FAQ

グラフィックユーザインタフェース FAQ

“なぜ Python が私のコンピュータにインストールされているのですか？” FAQ

このドキュメントについて

翻訳者一覧 (敬称略)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

一般 Python FAQ

Contents

一般 Python FAQ

一般情報

Python とは何ですか？

Python Software Foundation とは何ですか？

Python を使うのに著作権の制限はありますか？

Python が誕生したきっかけは何ですか？

Python は何をするのに向いていますか？

Python のバージョン番号の仕組みはどうなっているのですか？

Python のソースのコピーはどこで手に入りますか？

Python のドキュメントはどこで手に入りますか？

プログラミングをしたことがないのですが、 Python のチュートリアルはありますか？

Python のためのニュースグループやメーリングリストはありますか？

Python のベータテスト版はどこで手に入りますか？

Python のバグ報告やパッチを上げるにはどうしたら良いですか？

Python について発行された記事を何か参照できますか？

Python の本はありますか？

www.python.org は世界のどこにあるのですか？

なぜ Python という名前なのですか？

『空飛ぶモンティ・パイソン』を好きでなくてはいけませんか？

現実世界での Python

Python はどれくらい安定していますか？

どれくらいの人が Python を使っていますか？

Python で行われた大きなプロジェクトはありますか？

将来 Python にどのような新しい開発が期待されますか？

Python の互換性を無くすような提案をしてもいいのですか？

Python は 2000 年問題に対応できますか？

Python は初心者プログラマに向いている言語ですか？

Python のアップグレード

私のアプリケーションに使われている bsddb185 モジュールは何が問題とされていますか？

一般情報

Python とは何ですか？

Python は、インタプリタ形式の、対話的な、オブジェクト指向プログラミング言語です。この言語には、モジュール、例外、動的な型付け、超高水準の動的なデータ型、およびクラスが取り入れられています。 Python は驚くべきパワーと非常に分かりやすい文法を持ち合わせています。そして、多くのシステムコールやライブラリへだけでなく、様々なウィンドウシステムへのインタフェースがあり、 C や C++ で拡張することもできます。また、プログラム可能なインタフェースが必要なアプリケーションのための拡張言語としても利用できます。最後に、Python はポータブルです。多くの Unix バリアント、 Mac、そして MS-DOS、Windows、Windows NT、OS/2 上の PC で動かすことができます。

さらに知りたければ、Python チュートリアル から始めましょう。他にも、 Beginner’s Guide to Python [http://wiki.python.org/moin/BeginnersGuide] から、Python 学習のための入門用チュートリアルやリソースを参照できます。。

Python Software Foundation とは何ですか？

Python Software Foundation は、Python バージョン 2.1 以降の著作権を保持する独立の非営利組織です。PSF の任務は、Python プログラミング言語に関するオープンソース技術を進め、 Python の使用を広めることです。PSF のホームページが http://www.python.org/psf/ にあります。

PSF への寄付は米国で免税されています。Python を利用して役立ったと感じたら、 the PSF donation page [http://www.python.org/psf/donations/] で貢献をお願いします。

Python を使うのに著作権の制限はありますか？

あなたが作成する Python に関するドキュメントのすべてに著作権を残し、それらの著作権を表示する限り、ソースコードをどのように扱ってもかまいません。この著作権規則を尊重する限り、商用に Python を利用しても、ソースあるいはバイナリ形式で(変更の有無にかかわらず) Python のコピーを販売しても、Python が何らかの形で組み込まれた製品を販売してかまいません。もちろん、Python のあらゆる商業用途についても同様です。

ライセンスのより詳しい説明と全文へのリンクは the PSF license page [http://python.org/psf/license/] を参照してください。

Python のロゴは商標登録されていて、使用に許可が必要な場合があります。詳しい情報は the Trademark Usage Policy [http://www.python.org/psf/trademarks/] を参照してください。

Python が誕生したきっかけは何ですか？

Guido van Rossum による、すべてのきっかけの 非常に 簡潔な概要は以下のとおりです:

私は CWI の ABC グループでインタプリタ言語を実装する幅広い経験をしていて、そこで共に働くことで言語設計に関して大いに学びました。これが文のグループ化へのインデントの使用や超高水準のデータ型の包含など、 (詳細は Python では全く異なりますが) Python の多くの特徴のもととなっています。

私は ABC 言語に対して多くの不満を持っていましたが、同時に特徴の多くが好きでもありました。ABC 言語 (やその実装 )を拡張して私の不満を解消することは不可能でした (実際、拡張性の欠如は大きな問題だったのです)。私は Modula-2+ を使用することでいくらかの経験を積み、Modula-3 のデザイナーと話して Modula-3 のレポートを読みました。Modula-3 は例外処理に使う構文や語義、その他いくつかの Python の特徴の起源です。

私は CWI で Amoeba 分散オペレーティングシステムのグループで働いていました。 Amoeba のシステムコールインタフェースにはボーンシェルからアクセスしにくかったので、C プログラムやボーンシェルスクリプトを書くよりも良いシステム管理の方法が必要でした。Amoeba のエラー処理の経験から、プログラミング言語の機能としての例外の重要さを強く意識するようになりました。

ABC のような構文と Amoeba のようなシステムコールを合わせ持ったスクリプト言語が必要だろうと思いつきました。Amoeba 専用の言語を書くのは愚かであるだろうと気づき、一般に拡張できるような言語を求めることに決めました。

1989 年のクリスマス休暇の間、自由な時間がたくさんできたので、その言語を実際に作ってみることにしました。翌年の間、勤務時間以外はほとんどその開発に費やし、Python は Amoeba プロジェクトのなかで成果を重ね、同僚からのフィードバックは私の開発を大いに加速させてくれました。

1991 年 2 月、1 年間と少しの開発を経て、USENET に投稿することにしました。それは Misc/HISTORY ファイルに残っています。

Python は何をするのに向いていますか？

Python は、多岐にわたる問題に適用できる高水準な汎用プログラム言語です。

この言語は、文字列処理(正規表現、Unicode、ファイル間の差分の計算)、インターネットプロトコル(HTTP、FTP、SMTP、XML-RPC、POP、IMAP、 CGI プログラミング)、ソフトウェアエンジニアリング(Python コードのユニットテスト、ロギング、プロファイリング、解析)、オペレーティングシステムインタフェース(システムコール、ファイルシステム、 TCP/IP ソケット) のような領域をカバーする大規模な標準ライブラリから成り立っています。何ができるかを知るには Python 標準ライブラリ の一覧を参照してください。また、様々なサードパーティの拡張も使えます。 the Python Package Index [http://pypi.python.org/pypi] から興味のあるパッケージを探してみましょう。

Python のバージョン番号の仕組みはどうなっているのですか？

Python のバージョン番号は A.B.C や A.B のように付けられています。 A はメジャーバージョン番号で、言語の本当に重要な変更の時のみ増やされます。 B はマイナーバージョン番号で、そこまでは大きくない変更の時に増やされます。 C はマイクロレベルで、バグフィックスリリースの度に増やされます。バグフィックスリリースに関する詳細は PEP 6 [http://www.python.org/dev/peps/pep-0006] を参照してください。

すべてのリリースがバグフィックスリリースであるというわけではありません。メジャーリリースへの準備段階では、一連の開発リリースが作られ、アルファ版、ベータ版、またはリリース候補と名付けられます。アルファ版はインタフェースが確定されないうちにリリースされる早期リリースで、２つのアルファリリース間でインタフェースが変わるかもしれません。ベータ版はもっと安定していて、現存のインタフェースは保存されますが新しいモジュールが追加されるかもしれません。リリース候補は固まったもので、致命的なバグを直すのでなければ変更されません。

アルファ、ベータ、リリース候補の各バージョンには接尾語が追加されます。 N をなにか小さい番号として、アルファ版の接尾語は “aN” 、ベータ版の接尾語は “bN” 、リリース候補の接尾語は “cN” です。つまり、バージョン 2.0aN、バージョン 2.0bN、バージョン 2.0cN、バージョン 2.0 の順にリリースされることになります。

また、”2.2+” のように “+” 接尾語が付いたバージョン番号もあります。これは未発表のバージョンで、Subversion トランクから直接組み立てられています。実際、最後のマイナーリリースができた後、Subversion トランクは “2.4a0” のように “a0” がつく次のマイナーバージョンになります。

sys.version、sys.hexversion、sys.version_info についてのドキュメントも参照してください。

Python のソースのコピーはどこで手に入りますか？

最新の Python ソースは python.org (http://www.python.org/download/) からいつでも手に入れることができます。最新の開発版ソースは http://svn.python.org/projects/python/trunk の匿名 Subversion から手に入れることができます。

ソースは gzip された tar ファイルで配布され、完全な C のソース、 Sphinx によりフォーマットされたドキュメント、Python ライブラリモジュール、サンプルプログラム、そしていくつかの役立つ配布自由なソフトウェアを含んでいます。このソースはほとんどの UNIX プラットフォームでそのままコンパイルして動かせます。

ソースコードを手に入れてコンパイルすることの詳しい情報は開発者 FAQ [http://www.python.org/dev/faq/] を参照してください。

Python のドキュメントはどこで手に入りますか？

Python の現行の安定バージョンの標準ドキュメントは http://docs.python.org/ から利用できます。また、PDF、プレーンテキスト、ダウンロードできる HTML 版も http://docs.python.org/download.html から利用できます。

このドキュメントは reStructuredText で書かれ、the Sphinx documentation tool [http://sphinx.pocoo.org/] で構成されました。このドキュメントに使われた reStructuredText のソースは Python のソース配布に含まれます。

プログラミングをしたことがないのですが、 Python のチュートリアルはありますか？

膨大な量の役に立つチュートリアルや書籍があります。標準のドキュメントには Python チュートリアル などがあります。

Python プログラム初心者のための情報のチュートリアルのリストは the Beginner’s Guide [http://wiki.python.org/moin/BeginnersGuide] を参照してください。

Python のためのニュースグループやメーリングリストはありますか？

ニュースグループ comp.lang.python やメーリングリスト python-list [http://mail.python.org/mailman/listinfo/python-list] があります。ニュースグループとメーリングリストは互いに接続されていて、ニュースを購読すればメーリングリストに参加する必要はありません。 comp.lang.python は一日に数百のポスティングを受ける高いトラフィックで、USENET 読者は多くの場合、このボリュームに応えることができます。

新しいソフトウェアリリースとイベントの告知は comp.lang.python.announce で見つけられます。これは 一日に 5 ポスティング程度を受ける低トラフィックの手頃なメーリングリストです。the python-announce mailing list [http://mail.python.org/mailman/listinfo/python-announce-list] から利用可能です。

その他のメーリングリストやニュースグループについての詳しい情報は http://www.python.org/community/lists/ にあります。

Python のベータテスト版はどこで手に入りますか？

アルファ/ベータリリースは http://www.python.org/download/ で手に入ります。リリースはすべて comp.lang.python や comp.lang.python.announce のニュースグループと Python ホームページ http://www.python.org/ で告知され、PSS ニュースフィードが使えます。

Subversion から開発版を手に入れることもできます。詳細は http://www.python.org/dev/faq/ を参照してください。

Python のバグ報告やパッチを上げるにはどうしたら良いですか？

バグの報告やパッチの投稿には、http://bugs.python.org/ から Roundup installation を利用してください。

バグ報告には Roundup アカウントが必要です (こちらから関連する質問をさせて頂くため、またバグを解決したときにアップデート版を送るため)。以前バグ報告に SourceForge を使っていたことがあるなら、Roundup の password reset procedure [http://bugs.python.org/user?@template=forgotten] から Roundup のパスワードを取得することができます。

Python 開発の工程について、詳しくは the Python Developer’s Guide [http://python.org/dev/] を参照してください。

Python について発行された記事を何か参照できますか？

Python に関するあなたの愛読書を引用するのが一番でしょう。

Python に関する一番初めの記事はとても古く、1991年に書かれています。

Guido van Rossum and Jelke de Boer, “Interactively Testing Remote Servers Using the Python Programming Language”, CWI Quarterly, Volume 4, Issue 4 (December 1991), Amsterdam, pp 283-303.

Python の本はありますか？

はい、たくさんあり、そのほとんどは現在も出版されています。リストは python.org wiki http://wiki.python.org/moin/PythonBooks にあります。

また、オンライン書店で “Python” で検索し、Monty Python をフィルタで除外してもいいです (または、”Python” と “言語” で検索してください)。

www.python.org は世界のどこにあるのですか？

現在、アムステルダムの XS4ALL [http://www.xs4all.nl] に優雅に迎えられています。python.org のホスティングの手配に関して、 Thomas Wouters 氏に感謝いたします。

なぜ Python という名前なのですか？

Python の開発が始まった頃、Guido van Rossum は 1970 年代に始まった BBC のコメディシリーズ “Monty Python’s Flying Circus” [http://pythonline.com/] のスクリプト集を読んでいました。Van Rossum は、短くて、ユニークで、少しミステリアスな名前が欲しかったので、この言語の名前を Python と呼ぶことにしたのです。

『空飛ぶモンティ・パイソン』を好きでなくてはいけませんか？

いいえ。でも、好きになってくれるといいな。：）

現実世界での Python

Python はどれくらい安定していますか？

とても安定しています。1991 年以来新しい安定リリースはおよそ 6 から 8 ヶ月毎に出されていて、このペースが続きそうです。現在、主要なリリースはたいてい約 18 ヶ月毎に出されています。

開発者が旧バージョンの “bugfix” リリースを公開するので、現行のリリースの安定性は徐々に向上していきます。バグフィックスリリースは、バージョン番号の 3 番目の成分によって示され(例: 2.5.3、2.6.2)、安定性に配慮されています。バグフィックスリリースには既知の問題への修正だけが含まれ、一連のバグフィックスリリースで同じインタフェースが保たれることが保証されているのです。

最新の安定版は Python download page [http://python.org/download/] からいつでも手に入れることができます。現在、安定版に 2 つのブランチがあるので、推奨の実用版には 2.x と 3.x の２つがあります。現時点では Python 2 の方が Python 3 より多くのサードパーティソフトに対応しているので、Python 3.x は Python 2.x より使いづらいかもしれません。Python 2 のコードは基本的にそのままでは Python 3 で動かすことができません。

どれくらいの人が Python を使っていますか？

正確な人数を調べるのは難しいですが、おそらく数万人のユーザーがいるでしょう。

Python は自由にダウンロード可能なので、売上高がなく、多数のサイトから利用でき、多くの Linux ディストーションに同梱されているので、ダウンロード統計から全体の状況を知ることはできません。

comp.lang.python ニュースグループはとても活発ですが、すべての Python ユーザーが投稿するわけではなく、読みすらしない人もいます。

Python で行われた大きなプロジェクトはありますか？

Python を利用しているプロジェクトのリストは http://python.org/about/success を参照してください。past Python conferences [http://python.org/community/workshops/] から議事録を参照すると、多くの会社や組織の貢献がわかるでしょう。

注目されている Python のプロジェクトは the Mailman mailing list manager [http://www.list.org] や the Zope application server [http://www.zope.org] などです。Red Hat [http://www.redhat.com] をはじめとするいくつかの Linux ディストーションのインストーラやシステムアドミニストレーションソフトウェアは、一部や全部が Python で書かれています。内部で Python を利用している企業には、 Google、Yahoo、Lucasfilm Ltd. などがあります。

将来 Python にどのような新しい開発が期待されますか？

Python Enhancement Proposals (PEPs) http://www.python.org/dev/peps/ を参照してください。PEPs は Python に提案された新機能について書かれた設計書で、簡潔な技術仕様と原理が提供されています。”Python X.Y Release Schedule” (X.Y はまだリリースされていないバージョン) を探してください。

新しい開発については the python-dev mailing list [http://mail.python.org/mailman/listinfo/python-dev/] で議論されています。

Python の互換性を無くすような提案をしてもいいのですか？

一般的には、してはいけません。世界中にすでに何百万行もの Python コードがあるので、既存のプログラムのどんなに僅かな部分でも無効にしてしまうような言語仕様の変更も認められてはなりません。コンバートするプログラムが出来てさえ、すべてのドキュメントをアップデートしなければならないという問題があります。 Python に関する多くの本が出版されているので、それらを一発で不適切にするようなことはしたくないです。

仕様を変えなければならないのなら、緩やかなアップグレード計画が組まれなくてはなりません。PEP 5 [http://www.python.org/dev/peps/pep-0005] で、ユーザーの受ける分裂を最小限にしながら後方互換性のない変更を行うために従うべき手順について説明しています。

Python は 2000 年問題に対応できますか？

2003年8月現在、重大な問題は全く報告されていないので、 2000 年問題は気にする必要はないように思われます。

Python は日付の計算とその実行でほんの少しだけ C ライブラリの関数に依存しています。Python は一般的に時間を 1970 年以来の秒か (year, month, day, ...) タプルの年を 4 桁で表したもので表すので、 2000 年問題のバグは起こらないでしょう。ですから C ライブラリに問題がなければ、 Python にも問題がないはずです。もちろん、Python で書かれたある種のアプリケーションが 2 桁で表された年を誤って解釈することはあるかもしれません。

Python は無料で提供されているので、絶対の保証はありません。予期せぬ問題が あれば、開発者の責任というよりはユーザーの責任であり、損害賠償を求める相手は誰もいません。Python の著作権表示には以下の注意書きが含まれています:

4. PSF is making Python 2.3 available to Licensee on an “AS IS” basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

嬉しいことに、 もし 問題にいきあたっても、その問題を探し出して修理するために完全なソースを使うことができます。これはオープンソースプログラミング環境の利点の１つです。

Python は初心者プログラマに向いている言語ですか？

はい。

未だにプログラミング初学者にとって一般的なのは、Pascal、C、C++ のサブセット、 Java など、手続き型の静的型付けの言語です。生徒にとっては、第一の言語として Python を学ぶのが役に立つでしょう。Python には非常に簡潔で一貫した構文と大きな標準ライブラリがあります。そして一番重要なことに、初心者プログラミングのコースで Python を学ぶことで、生徒は問題の分析やデータ型の設計など、重要なプログラミングスキルに集中することができるのです。 Python なら、生徒はループや手続きなどの基本概念をすぐに取り入れられます。最初の課程でいきなりユーザ定義のオブジェクトを操ることさえできるでしょう。

プログラミングをしたことがない初心者にとって、静的型付け言語を使うのは不自然に思われます。習得すべき内容はより複雑になり、学習のペースが遅くなってしまいます。生徒は、コンピュータのように思考し、問題を分析し、一貫したインタフェースを設計して、データをカプセル化することを学ぶことになります。長期的に見れば静的型付け言語を学ぶことは重要ですが、それが最初のプログラミングの授業で学ぶべき最高の話題とは限りません。

Python の良いところは他にもたくさんあります。Python には、Java のように大きな標準ライブラリがあり、生徒が何かを する 段階で非常に早くプログラミングプロジェクトに参加できるようになります。宿題は標準の四則演算機や平均を求めるプログラムに限定されません。標準ライブラリを使用することで、生徒はプログラミングの原理を学びながら現実的なアプリケーションに取り組む満足感を得ることができます。また、標準ライブラリの使用からコードの再利用を学ぶことができます。 PyGame などのサードパーティモジュールもまた手が届く範囲を広げるのに役立ちます。

Python のインタラクティブインタプリタによって、プログラミングをしながら、言語機能を確認することができます。別のウィンドウでプログラムのソースに入っている間、ウィンドウでインタプリタを起動させたままにしておくことができます。リストのメソッドを思い出せないときは、例えばこのようにできます:

>>> L = []
>>> dir(L)
['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
'reverse', 'sort']
>>> help(L.append)
Help on built-in function append:

append(...)
    L.append(object) -- append object to end
>>> L.append(1)
>>> L
[1]

インタプリタがあれば、プログラミングをしている間にドキュメントは生徒のそばを離れません。

Python のための良い IDE もあります。IDLE は Python で Tkinter を使って書かれたクロスプラットフォーム IDE です。PythonWin は Windows 専用の IDE です。Emacs には、ユーザにとって幸運なことに、素晴らしい Python モードがあります。これらすべてのプログラミング環境から、シンタックスハイライト、オートインデント、コーディング中のインタラクティブインタプリタへのアクセスが使えます。 http://www.python.org/editors/ から Python 編集環境の一覧を参照してください。

Python の教育における利用についての議論がしたいなら、the edu-sig mailing list [http://python.org/community/sigs/current/edu-sig] に参加するとよいでしょう。

Python のアップグレード

私のアプリケーションに使われている bsddb185 モジュールは何が問題とされていますか？

Python2.3 から、配布時に古い bsddb モジュールの代わりに PyBSDDB package [http://pybsddb.sf.net/] が含まれるようになりました。このモジュールは API レベルでは後方互換性を保っていますが、基本となる Berkeley DB [http://www.sleepycat.com] ライブラリは新しいものが必要となります。古い bsddb モジュールで作られたファイルは新しいモジュールで直接開くことができません。

古いバージョンの Python と Python 2.3 の一部である２つのスクリプト (Tools/scripts ディレクトリの db2pickle.py と pickle2db.py) を使用して、古いデータベースファイルを新しいフォーマットにコンバートすることができます。古いバージョンの Python を使って、スクリプトを pickle に変換するために db2pickle.py スクリプトを起動してください。例えば:

python2.2 <pathto>/db2pickley.py database.db database.pck

データベースファイルを改名してください:

mv database.db olddatabase.db

そして、 pickle ファイルを新しいフォーマットのデータベースに変換してください:

python <pathto>/pickle2db.py database.db database.pck

入力すべき正確なコマンドは、あなたのインストールの詳細によって変わります。これら 2 つのスクリプトの命令の詳細は、それぞれの最初にある doc string を確認してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

プログラミング FAQ

Contents

プログラミング FAQ

一般的な質問

ブレークポイントやシングルステップ実行などを備えたソースコードレベルデバッガはありますか？

バグの発見や静的分析に役立つツールはありますか？

どうしたら Python スクリプトからスタンドアロンバイナリを作れますか？

Python プログラムのためのコーディングスタンダードやスタイルガイドはありますか？

プログラムが遅すぎます。どうしたら速くなりますか？

コア言語

なぜ変数に値があるのに UnboundLocalError が出るのですか？

Python のローカルとグローバル変数のルールは何ですか？

グローバル変数をモジュール間で共有するにはどうしたらいいですか？

モジュールで import を使う際の「ベストプラクティス」は何ですか？

オプションパラメタやキーワードパラメタを関数から関数へ渡すにはどうしたらいいですか？

パラメタを出力する関数 (参照渡し) はどのように書きますか？

Python で高次関数はどのようにつくりますか？

Python のオブジェクトはどのようにコピーしますか？

オブジェクトのメソッドや属性はどのように見つけますか？

コードはどのようにオブジェクトの名前を見つけるのですか？

カンマ演算子はなぜ優先されるのですか？

Is there an equivalent of C’s ”?:” ternary operator?

Python で解し難いワンライナーを書くことはできますか？

数と文字列

十六進数や八進数を指定するにはどうしたらいいですか？

なぜ -22 // 10 は -3 を返すのですか？

文字列を数に変換するにはどうしたらいいですか？

数を文字列に変換するにはどうしたらいいですか？

文字列をインプレースに変更するにはどうしたらいいですか？

関数やメソッドを呼ぶのに文字列を使うにはどうしたらいいですか？

文字列から後端の改行を取り除く Perl の chomp() に相当するものはありますか？

scanf() や sscanf() と同等なものはありますか？

‘UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)’ とはどういう意味ですか？

シーケンス(タプル/リスト)

タプル、リスト間の変更はどのようにするのですか？

インデクスが負の場合はどうなりますか？

シーケンスを逆順にイテレートするにはどうしたらいいですか？

リストから重複を取り除くにはどうしますか？

Python で配列を作るにはどうしますか？

多次元のリストを作るにはどうしますか？

オブジェクトのシーケンスにメソッドを適用するにはどうしますか？

辞書

キーを安定した順序で表示する辞書を作るにはどうしたらいいですか？

複雑なソートがしたいのですが、Python でシュワルツ変換はできますか？

リストを別のリストの値によってソートするにはどうしますか？

オブジェクト

クラスとは何ですか？

メソッドとは何ですか？

self とは何ですか？

あるオブジェクトが、与えられたクラスやそのサブクラスのインスタンスであるかを調べるにはどうしますか？

委譲とは何ですか？

基底クラスで定義されたメソッドを、そのクラスをオーバーライドした派生クラスから呼び出すにはどうしますか？

基底クラスの名前を変えやすいコードを書くにはどうしますか？

静的なクラスデータや静的なクラスメソッドを作るにはどうしますか？

Python でコンストラクタ(やメソッド)をオーバーロードするにはどうしたらいいですか？

__spam を使おうとしたら _SomeClassName__spam からエラーがでました。

クラスに __del__ メソッドを定義しているのですが、オブジェクトを削除したときに呼ばれません。

与えられたクラスのすべてのインスタンスのリストを得るにはどうしますか？

モジュール

.pyc ファイルを作るにはどうしますか？

現在のモジュール名を知るにはどうしますか？

相互にインポートしあうモジュールを作るにはどうしたらいいですか？

__import__(‘x.y.z’) は <module ‘x’> を返しますが、z を得るためにはどうしますか？

インポートされたモジュールを編集してから再インポートしましたが、変化が現れません。なぜですか？

一般的な質問

ブレークポイントやシングルステップ実行などを備えたソースコードレベルデバッガはありますか？

はい。

pdb モジュールは簡素にして十分な Python のコンソールモードデバッガです。これは Python の標準ライブラリに含まれているもので、ライブラリリファレンスマニュアルにドキュメントがあります。 pdb のコードを手本にして自分用のデバッガを書くこともできます。

Python に同梱されている統合開発環境の IDLE は 通常の Python の配布形態の一部 (普通は Tools/scripts/idle から利用可能) であり、グラフィカルなデバッガを含んでいます。IDLE デバッガのドキュメントは http://www.python.org/idle/doc/idle2.html#Debugger にあります。

PythonWin は、pdb をベースとした GUI デバッガを含む Python IDE です。 Pythonwin デバッガは、ブレークポイントの色付けや非 Pythonwin プログラムのデバッグなどのたくさんの素敵な機能を持っています。Pythonwin は Python for Windows Extensions [http://sourceforge.net/projects/pywin32/] プロジェクトの一部、あるいは ActivePython ディストリビューション (http://www.activestate.com/Products/ActivePython/index.html を参照) の一部として利用可能です。

Boa Constructor [http://boa-constructor.sourceforge.net/] は、 wxWidgets を使った IDE と GUI ビルダーです。これは視覚フレームの作成と操作、オブジェクト検査、オブジェクトブラウザのような多くのビュー、継承構造、 doc string から生成される html ドキュメント、高度なデバッガ、総合ヘルプ、 Zope のサポートを提供します。

Eric [http://www.die-offenbachs.de/eric/index.html] は PyQt や Scintilla editing component をもとにした IDE です。

Pydb は標準のデバッガである pdb を人気のグラフィカルデバッガフロントエンドである DDD (Data Display Debugger) とともに使うために改変したものです。Pydb は http://bashdb.sourceforge.net/pydb/ に、 DDD は http://www.gnu.org/software/ddd にあります。

商業のグラフィカルデバッガ付き Python IDE もあります。例えば:

Wing IDE (http://wingware.com/)

Komodo IDE (http://www.activestate.com/Products/Komodo)

バグの発見や静的分析に役立つツールはありますか？

はい。

PyChecker は Python ソースコードのバグを発見しコードの複雑さとスタイルについて警告する静的解析ツールです。PyChecker は http://pychecker.sf.net から手に入ります。

Pylint [http://www.logilab.org/projects/pylint] は、モジュールがコーディング標準を満たすかを調べ、プラグインを書いてカスタム機能を加えられるようにするツールです。PyChecker が行うバグチェックに加え、 Pylint は行の長さ、変数名が一貫しているか、宣言されたインタフェースが完全に実装されているか、などを確かめる追加の機能を提供します。 http://www.logilab.org/card/pylint_manual から Pylint の機能の一覧を見られます。

どうしたら Python スクリプトからスタンドアロンバイナリを作れますか？

ユーザがダウンロードや起動のために Python ディストリビューションをインストールしなくてもよいスタンドアロンプログラムのためだけなら、 Python を C コードにコンパイルできる必要はありません。プログラムに対して必要なモジュールを選び、そのモジュールを Python バイナリに束縛して一つの実行可能ファイルにまとめる多くのツールがあります。

一つは freeze ツールで、Python ソースツリーに Tools/freeze として含まれています。これは Python バイトコードを C 配列に変換します。すべてのモジュールを標準 Python モジュールにリンクされる新しいプログラムに埋め込む C コンパイラです。

これはあなたのソースの (両方の形式の) import 文を再帰的にスキャンして、 import されたモジュールを標準の Python パスと (組み込みモジュールのある) ソースディレクトリから探します。そして Python で書かれたモジュールのバイトコードを C コード (marshal モジュールでコードオブジェクトに変換できる配列) に変換し、実際にそのプログラム内で使われている組み込みモジュールだけが含まれたカスタムメイドの設定ファイルを作成します。そして生成された C コードをコンパイルして Python インタプリタの残りとリンクし、元のスクリプトと全く同じように動作する自己充足的なバイナリを形成します。

もちろん、凍結には C コンパイラが必要です。C コンパイラを必要としない選択肢もあります。その一つは、Thomas Heller の py2exe (Windows 専用) です。

http://www.py2exe.org/

他に、 Christian Tismer の SQFREEZE [http://starship.python.net/crew/pirx] は、実行可能ファイルのバイトコードを探すことができる特別な Python インタプリタにバイトコードを加えます。

その他のツールには、Fredrik Lundh の Squeeze [http://www.pythonware.com/products/python/squeeze] や Anthony Tuininga の cx_Freeze [http://starship.python.net/crew/atuining/cx_Freeze/index.html] などがあります。

Python プログラムのためのコーディングスタンダードやスタイルガイドはありますか？

はい。標準ライブラリモジュールに求められるコーディングスタイルは PEP 8 [http://www.python.org/dev/peps/pep-0008] として文書化されています。

プログラムが遅すぎます。どうしたら速くなりますか？

一般に、それは難しい質問です。Python コードを速くするためには、いろいろな手法があります。最終手段として一部を C で書き直す事も考えてください。

Python を自動的に C や x86 アセンブリ言語に変換できる場合もあります。この場合、速度を上げるためにコードを変更する必要はありません。

Pyrex [http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/] は Python コードの少し変化した版を C 拡張にコンパイルでき、多様なプラットフォームで使えます。

Psyco [http://psyco.sourceforge.net] は Python コードを x86 アセンブリ言語に変換する実行時コンパイラです。これを使うことが出来れば、重要な関数を劇的にスピードアップできます。

あとは、Python コードからもう少し速度を搾り出すための様々な手法について議論することになります。コード中の特定の関数が処理が集中するホットスポットで、最適化が必要であると認められない限り、決して いかなる最適化の手法も使わないでください。最適化はたいていコードを分かりづらくするので、分かりづらさのコスト (開発時間の延長とバグの可能性の増大) がそれに見合ったパフォーマンスの向上につながらないのであれば元が取れません。

performance tips [http://wiki.python.org/moin/PythonSpeed/PerformanceTips] に関するページが wiki にあります。

Guido van Rossum は http://www.python.org/doc/essays/list2str.html で最適化に関する逸話を詳述しています。

なお、関数や(特に)メソッドの呼び出しはかなり高価です。インスタンス変数を get や set したり他のメソッドを呼び出す程度の小さな関数がたくさんある純粋 OO インタフェースをデザインしているなら、インスタンス変数に直接アクセスするようなもっと直接的な方法も考えてみてください。また、どのプログラムが実行時間の大部分を占めているかを見つける標準モジュール profile も参照してください (ちょっと忍耐できればの話ですが - プロファイリングはそれ自体がプログラムを一桁ほど遅くしてしまいます)。

もちろん、他のプログラミングの経験から得られた多くの標準的な最適化の発見的手法は Python にもよく当てはまることが多いです。たとえば、出力装置に出力を送るときに、一度に少なく書くよりもむしろ多く書いたほうが、カーネルのシステムコールのオーバーヘッドを減らすことができて、速くなるでしょう。したがって、CGI スクリプトは “一発” ですべて書き出すもののほうが小さなたくさんの出力に分けて書き出すものよりも速くなるでしょう。

また、必ず Python のコアな機能を適切に使ってください。例えば、スライシングなら、リストや他のシーケンスオブジェクトを、高度に最適化された C 実装で、インタプリタのメインループの一刻みで細切れにできます。こうして効果を得ることができる例は:

L2 = []
for i in range[3]:
    L2.append(L1[i])

こう使えばずっと短く、ずっと速くできます:

L2 = list(L1[:3])  # "list" is redundant if L1 is a list.

関数指向組み込み関数 map() や zip() なども一つのタスクを実行するためのループを加速するのに便利であることに注意してください。例えば、二つのリストの要素を組み合わせるためには:

>>> zip([1, 2, 3], [4, 5, 6])
[(1, 4), (2, 5), (3, 6)]

また、正弦を一度に計算するには:

>>> map(math.sin, (1, 2, 3, 4))
[0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]

このような場合には素早く演算が完了します。

その他の例には、文字列オブジェクトのメソッド join() 、split() などが挙げられます。

例えば s1..s7 が大きな (10K+) 文字列の時、"".join([s1,s2,s3,s4,s5,s6,s7]) は単純に s1+s2+s3+s4+s5+s6+s7 とするよりもはるかに速くなるでしょう。なぜなら、join() はすべてのコピーを一括して行うのに対し、「足し算」が多くの副演算を行うからです。文字列を扱うには、文字列オブジェクトのメソッド replace()、 format() を使ってください。正規表現を使うのは、決まった文字列のパターンを使わない時だけにしてください。旧式の % 演算 string % tuple と string % dictionary も使えます。

ソートには必ずビルトインオブジェクトの list.sort() を使ってください。また、sorting mini-HOWTO [http://wiki.python.org/moin/HowTo/Sorting] の少し高度な使い方の例を参照してください。list.sort() は、よほど極端な状況でない限り、他のソートの技術に勝ります。

「ループを関数やメソッドの中に入れ込む」というのも一般的な手法です。例えば、遅いプログラムがあって、Python の ff() 関数が何度も呼ばれていることがプロファイラで分かったとします。もし、ff():

def ff(x):
    ... # do something with x computing result...
    return result

が:

list = map(ff, oldlist)

または:

for x in sequence:
    value = ff(x)
    ... # do something with value...

のようにループの中で呼ばれていることが多いなら、ff() を:

def ffseq(seq):
    resultseq = []
    for x in seq:
        ... # do something with x computing result...
        resultseq.append(result)
    return resultseq

のように、また、上の二つの例を、list = ffseq(oldlist) と:

for value in ffseq(sequence):
    ... # do something with value...

のように書き換えることによって、関数を呼ぶためのオーバーヘッドを省けることが多いです。

ff(x) を一回だけ呼ぶ場合、 ffseq([x])[0] に直してしまうとちょっと不利になります。 もちろん、このテクニックがいつでも適切であるわけではありませんし、解決のための他の方法もあります。

関数やメソッドの探索の結果をローカル変数に明示的に保存すると少しパフォーマンスが良くなります。次のようなループ:

for key in token:
    dict[key] = dict.get(key, 0) + 1

は、繰り返しのたびに dict.get を求めています。 このメソッドが変わることがないのなら、少し速い実装は:

dict_get = dict.get  # look up the method once
for key in token:
    dict[key] = dict_get(key, 0) + 1

デフォルト引数は、実行時でなく、コンパイル時に値を一回で決めてしまうのに使えます。これは、プログラムの実行中に変化しない関数やオブジェクト、例えば:

def degree_sin(deg):
    return math.sin(deg * math.pi / 180.0)

を、次のように置き換えるときにのみ行えます:

def degree_sin(deg, factor=math.pi/180.0, sin=math.sin):
    return sin(deg * factor)

この手法はデフォルト引数が変えられないことを前提に使うので、ユーザーが API で混乱するおそれがないときのみ使えます。

コア言語

なぜ変数に値があるのに UnboundLocalError が出るのですか？

もともと動いていたコードが、関数の本体のどこかに代入文を加えるという変更をしたら UnboundLocalError を出すのには驚くかもしれません。

このコード:

>>> x = 10
>>> def bar():
...     print x
>>> bar()
10

は動きますが、このコード:

>>> x = 10
>>> def foo():
...     print x
...     x += 1

は UnboundLocalError になります:

>>> foo()
Traceback (most recent call last):
  ...
UnboundLocalError: local variable 'x' referenced before assignment

これは、あるスコープの中で変数に代入を行うとき、その変数はそのスコープに対してローカルになり、外のスコープにある同じ名前の変数を隠すからです。 foo の最後の文が x に新しい値を代入しているので、コンパイラはこれをローカル変数であると認識します。その結果、先の print x が初期化されていないローカル変数を表示しようとして結果はエラーとなります。

上の例では、グローバルであると宣言することで外のスコープにアクセスできます:

>>> x = 10
>>> def foobar():
...     global x
...     print x
...     x += 1
>>> foobar()
10

この明示的な宣言は (表面的には似ているクラスとインスタンス変数の例とは違って) あなたは実際は他のスコープの変数の値を変えようとしているのだ、ということを知らせるのに必要です:

>>> print x
11

Python のローカルとグローバル変数のルールは何ですか？

Python では、関数の中で参照のみされる変数は暗黙のうちにグローバルになります。関数の本体のどこかで新しい値が変数に代入されたなら、それはローカルであるとみなされます。関数の中で新しい値が一度でも代入されたらその変数は暗黙のうちにローカルであり、’global’ は明示的に宣言しなければなりません。

最初はちょっと驚くでしょうが、少し考えると納得できます。一方では、代入された変数に global を要求することで、意図しない副作用を防げます。他方では、グローバルな参照の度に global が要求されてしまうと、 global を使ってばかりになってしまいます。ビルトイン関数やインポートされたモジュールの内容を参照するたびにグローバル宣言をしなければならないのです。その乱雑さは副作用を特定するための global 宣言の便利さよりも重大です。

グローバル変数をモジュール間で共有するにはどうしたらいいですか？

一つのプログラムのモジュール間で情報を共有する正準な方法は、特別なモジュール (しばしば config や cfg と呼ばれる) を作ることです。単に設定モジュールをアプリケーションのすべてのモジュールにインポートしてください。このモジュールはグローバルな名前として使えます。それぞれのモジュールのただ一つのインスタンスがあるので、設定モジュールオブジェクトに対するいかなる変更も全体に反映されます。例えば:

config.py:

x = 0   # Default value of the 'x' configuration setting

mod.py:

import config
config.x = 1

main.py:

import config
import mod
print config.x

なお、同じ理由から、モジュールを使うということは、シングルトンデザインパターンを実装することの基礎でもあります。

モジュールで import を使う際の「ベストプラクティス」は何ですか？

一般に、from modulename import * を使わないでください。使うとインポータの名前空間を混乱させてしまいます。この書式でインポートされるように設計された数少ないモジュールにすらこの構文を使わないようにする人もいます。そのように設計されたモジュールには Tkinter や threading などがあります。

モジュールはファイルの先頭でインポートしてください。これによってコードが必要とする他のモジュールが明確になり、モジュール名がスコープに含まれるかどうかに迷わなくなります。行に一つのインポートにすると、モジュールのインポートの追加と削除が容易になりますが、行に複数のインポートにすると画面の領域が少なく済みます。

次の手順でモジュールをインポートするのが、良いプラクティスになります:

標準ライブラリモジュール – 例 sys、os、getopt、re

サードパーティのライブラリモジュール (Python の site-packages ディレクトリにあるもの) – 例 mx.DateTime、ZODB、PIL.Image、など

内部で開発したモジュール

相対インポートは決して使わないでください。package.sub.m1 モジュールのコードを書いていて、package.sub.m2 をインポートしようとするとき、 from . import m2 とだけ書くのは、違反ではありませんがやらないでください。代わりに from package.sub import m2 と書いてください。詳細は PEP 328 [http://www.python.org/dev/peps/pep-0328] を参照してください。

循環参照の問題を避けるために、インポートを関数やクラスに移すことが必要なときもあります。Gordon McMillan によれば:

循環参照は両方のモジュールが “import <module>” 形式のインポートを使っていれば大丈夫です。二つ目のモジュールが最初のモジュールから名前を確保しようとして (“from module import name”)、そのインポートがトップレベルにあると駄目です。最初のモジュールが二つ目のモジュールをインポートするのに忙しくて、最初のモジュールの名前が利用可能になっていないからです。

この状況では、二つ目のモジュールが一つの関数の中でのみ使われているならば、そのインポートは簡単に関数の中に移せます。インポートが呼ばれたとき、最初のモジュールは初期化を完了していて、二つ目のモジュールは自分のインポートをできます。

プラットフォーム依存のモジュールがあるときには、インポートをトップレベルの外に動かすことも必要です。この場合、ファイルの先頭ではすべてのモジュールをインポートすることさえできないかもしれません。この場合は、対応するプラットフォームに合わせたコードで正しいモジュールをインポートすることを選ぶと良いです。

循環参照の問題を避けたりモジュールの初期化にかかる時間を減らしたりしたいなら、単にインポートを関数定義の中などのローカルなスコープに移してください。この手法は多くのインポートがプログラムがどのように実行されるかに依存しなくてよいときに特に有効です。ある関数の中でのみモジュールが使われるのなら、インポートをその関数の中に移すことを考えてもいいでしょう。なお、モジュールを読み込む最初の回はモジュールの初期化の時間のために高価になりえますが、複数回目にモジュールを読み込むのは事実上無料、辞書探索の数回のコストだけで済みます。モジュール名がスコープから外れてさえ、そのモジュールはおそらく sys.modules から利用できるでしょう。

特定のクラスのインスタンスのみがあるモジュールを使っているなら、そのクラスの __init__ メソッドでそのモジュールをインポートし、そこでインスタンス変数にそのモジュールを代入して、オブジェクトがある間そのモジュールがいつでも (インスタンス変数を経由して) 利用できるようにするのが合理的です。なお、インポートをクラスが初期化される時まで先送りにするためには、インポートはメソッドの中にないといけません。インポートをクラスの中に入れてもメソッドの外に出してしまうと、そのインポートはモジュールの初期化の時になされてしまいます。

オプションパラメタやキーワードパラメタを関数から関数へ渡すにはどうしたらいいですか？

関数のパラメタリストに引数を * と ** 指定子 (specifier) で集めてください。そうすれば、固定引数をタプルとして、キーワード引数を辞書として得られます。これで、他の関数を呼び出すときに * と ** を使ってそれらの引数を渡せます:

def f(x, *args, **kwargs):
    ...
    kwargs['width'] = '14.3c'
    ...
    g(x, *args, **kwargs)

あまりありませんが、Python の 2.0 以前のバージョンを考慮するときは、代わりに apply() を使ってください:

def f(x, *args, **kwargs):
    ...
    kwargs['width'] = '14.3c'
    ...
    apply(g, (x,)+args, kwargs)

パラメタを出力する関数 (参照渡し) はどのように書きますか？

前提として、Python では引数は代入によって渡されます。代入はオブジェクトへの参照を作るだけなので、呼び出し元と呼び出し先にある引数名の間にエイリアスはありませんし、参照渡しそれ自体はありません。望む効果を得るためには幾つかの方法があります。

結果のタプルを返すことによって:

def func2(a, b):
    a = 'new-value'        # a and b are local names
    b = b + 1              # assigned to new objects
    return a, b            # return new values

x, y = 'old-value', 99
x, y = func2(x, y)
print x, y                 # output: new-value 100

これはたいてい一番明確な方法です。

グローバル変数を使って。これはスレッドセーフでないので、推奨されません。

ミュータブルな (インプレースに変更可能な) オブジェクトを渡すことによって:

def func1(a):
    a[0] = 'new-value'     # 'a' references a mutable list
    a[1] = a[1] + 1        # changes a shared object

args = ['old-value', 99]
func1(args)
print args[0], args[1]     # output: new-value 100

変更される辞書に渡すことによって:

def func3(args):
    args['a'] = 'new-value'     # args is a mutable dictionary
    args['b'] = args['b'] + 1   # change it in-place

args = {'a':' old-value', 'b': 99}
func3(args)
print args['a'], args['b']

クラスインスタンスに値を同梱することによって:

class callByRef:
    def __init__(self, **args):
        for (key, value) in args.items():
            setattr(self, key, value)

def func4(args):
    args.a = 'new-value'        # args is a mutable callByRef
    args.b = args.b + 1         # change object in-place

args = callByRef(a='old-value', b=99)
func4(args)
print args.a, args.b

このような複雑なことをする理由はめったに無いでしょう。

一番の選択は、複数の結果を含むタプルを返すことです。

Python で高次関数はどのようにつくりますか？

二つの方法があります: ネストされたスコープを使う方法と、呼び出し可能オブジェクトを使う方法です。例えば、a*x+b の値を計算する f(x) 関数を返す linear(a,b) を定義したいとします。ネストされたスコープを使うと:

def linear(a, b):
    def result(x):
        return a * x + b
    return result

また、呼び出し可能オブジェクトを使うと:

class linear:

    def __init__(self, a, b):
        self.a, self.b = a, b

    def __call__(self, x):
        return self.a * x + self.b

どちらの場合でも:

taxes = linear(0.3, 2)

とすれば、taxes(10e6) == 0.3 * 10e6 + 2 となるような呼び出し可能オブジェクトを得られます。

呼び出し可能オブジェクトを使う方法は、少し遅くなり、わずかにコードが長くなるという短所があります。ですが、継承を使ってコーラブル同士で記号を共有することもできます:

class exponential(linear):
    # __init__ inherited
    def __call__(self, x):
        return self.a * (x ** self.b)

オブジェクトはいくつかのメソッドに状態をカプセル化できます:

class counter:

    value = 0

    def set(self, x):
        self.value = x

    def up(self):
        self.value = self.value + 1

    def down(self):
        self.value = self.value - 1

count = counter()
inc, dec, reset = count.up, count.down, count.set

ここで、inc()、dec() 、reset() は同じカウント変数を共有する関数のようにふるまいます。

Python のオブジェクトはどのようにコピーしますか？

一般的に、普通は copy.copy() や copy.deepcopy() を試してください。何でもコピーできるとは限りませんが、たいていはできます。

もっと簡単にコピーできるオブジェクトもあります。辞書には copy() メソッドがあります:

newdict = olddict.copy()

シーケンスはスライシングでコピーできます:

new_l = l[:]

オブジェクトのメソッドや属性はどのように見つけますか？

ユーザー定義クラスのインスタンス x で、dir(x) はインスタンス属性とそのクラスで定義されたメソッドや属性を含む名前のアルファベット順リストを返します。

コードはどのようにオブジェクトの名前を見つけるのですか？

概して、オブジェクトは本当は名前を持たないので、見つけることはできません。本質的には、代入とはいつも値に名前を束縛することです。def と class 文も同じですが、この場合は値はコーラブルです。以下のコードを考えてみましょう:

class A:
    pass

B = A

a = B()
b = a
print b
<__main__.A instance at 0x16D07CC>
print a
<__main__.A instance at 0x16D07CC>

おそらく、このクラスには名前があります。このクラスは二つの名前に縛られて、名前 B を通して呼び出されますが、それでもクラス A のインスタンスとして報告されるのです。しかし、両方の名前が同じ値に束縛されている以上、このインスタンスの名前が a か b か決めることはできないのです。

概して、コードにとってある値の「名前を知っている」事は重要ではありません。あなたがわざと内省的なコードを書いているのでない限り、方針を変えた方がいいかもしれないということになるでしょう。

comp.lang.python で、Fredrik Lundh はこの問題の答えとして素晴らしい喩えをしてくれました:

玄関にいた猫の名前を知るのと同じ方法です: その猫 (オブジェクト) 自体はその名前を言うことができないし、それは実は問題ではありません – その猫が何と呼ばれているかを知る唯一の方法は、すべての隣人 (名前空間) にその猫(オブジェクト)が何と呼ばれているかを聞くことです。

……そして、その猫が沢山の名前で知られていたり、逆に全く名前が全く無かったりしても驚かないでください！

カンマ演算子はなぜ優先されるのですか？

カンマは Python では演算子ではありません。このセッションを考えてください:

>>> "a" in "b", "a"
(False, 'a')

カンマは演算子ではなく、式の分離子なので、上の式は次の式と同じように評価されます:

>>> ("a" in "b"), "a"

次のようには評価されません:

>>> "a" in ("b", "a")

他のさまざまな演算子(=、+= など)も同じです。これらは真の演算子ではありませんが、代入文の構文上のデリミタです。

Is there an equivalent of C’s ”?:” ternary operator?

はい、この機能は Python 2.5 で追加されました。構文は以下のようになります:

[on_true] if [expression] else [on_false]

x, y = 50, 25

small = x if x < y else y

2.5 以前のバージョンに関しては、答えは「いいえ」です。

多くのケースでは a and b or c で a ? b : c の代わりをできますが、これでは漏れがあります。b が 0 (あるいは空、または None – 偽となるものすべて) のとき、c が代わりに選ばれてしまいます。多くの場合にはコードからこれが起こらないと解ります( 例えば、b が定数だったり、決して偽にならない型だったりするので) が、これは大体問題になり得ます。

Tim Peters (who wishes it was Steve Majewski) は次の解決策を提案しました。 (a and [b] or [c])[0]。[b] は一つの要素を持つリストであり、決して偽とならないので、間違った経路を通りません。だから [0] を全体に適用すれば、本当に欲しかった b または c が得られます。醜いですが、’if’ を使って書き換えるのがどうしても不便な特殊な場合には、これで目的が達成できます。

一番の方法はたいてい、単純に if...else 文を書くことです。あるいは、 ?: 演算子を関数として実装する方法もあります:

def q(cond, on_true, on_false):
    if cond:
        if not isfunction(on_true):
            return on_true
        else:
            return on_true()
    else:
        if not isfunction(on_false):
            return on_false
        else:
            return on_false()

たいてい、b と c は q(a, b, c) のように直接渡すことになります。 b や c が評価されるべきでないとき、評価を避けるには、 q(a, lambda: b, lambda: c) のようにラムダ関数に包んでください。

なぜ Python に if-then-else 式が無いのかは問われていました。答えはいくつかあります。多くの言語はそれ無しで十分なこと、読みにくいコードになりやすいこと、十分「Pythonic」な構文が見当たらないこと、標準ライブラリには if-then-else 式で表すとコードが分かりやすくなるような箇所がほとんどないことです。

2002年、いくつかの構文の選択肢を提案する PEP 308 [http://www.python.org/dev/peps/pep-0308] が書かれ、コミュニティはこの論点について投票を行いました。多くの人はそれぞれある構文を好み、また他の構文を嫌いました。投票者の多くが、自分の嫌いな構文を取り入れるくらいなら、三項演算子を取り入れないほうがいいと考えました。

Python で解し難いワンライナーを書くことはできますか？

はい。そういうものはたいてい、lambda の中に lambda がネストされています。Ulf Bartelt による下の３つの例を見てください:

from functools import reduce

# Primes < 1000
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))

# First 10 Fibonacci numbers
print map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: f(x,f),
range(10))

# Mandelbrot set
print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
#    \___ ___/  \___ ___/  |   |   |__ lines on screen
#        V          V      |   |______ columns on screen
#        |          |      |__________ maximum of "iterations"
#        |          |_________________ range on y axis
#        |____________________________ range on x axis

よい子はまねしないでね！

数と文字列

十六進数や八進数を指定するにはどうしたらいいですか？

八進数を指定するには、八進数での値の先頭に 0 と “o” (小文字または大文字) を加えてください。たとえば、変数 “a” に八進数での “10” (十進数での”8”) を代入するには、こう打ってください:

>>> a = 0o10
>>> a
8

十六進数も簡単です。ただ十六進数での値の先頭に 0 と “x” (小文字または大文字) を加えてください。十六進数は小文字でも大文字でも指定できます。たとえば、Python インタプリタで:

>>> a = 0xa5
>>> a
165
>>> b = 0XB2
>>> b
178

なぜ -22 // 10 は -3 を返すのですか？

i % j が j と同じ符号であってほしいことに基づいています。それに加えて以下のようにもしたいとすると:

i == (i // j) * j + (i % j)

整数除算は床を返すことになります。C にも C の一貫性があって、i % j が i と同じ符号を持つように i // j を丸めています。

i % j は、j が負の時には実際にはほとんど使いません。j が正なら、たくさん使います。その事実上すべての場合、i % j は >= 0 となる方が便利です。時計が 10 時を指している時、その 200 時間前は何時でしょうか。 -190 % 12 == 2 となるのが便利です。-190 % 12 == -10 は噛み付きかねないバグです。

ノート

Python 2 では、 __future__.division が有効でなければ、 a / b は a // b と同じ結果を返します。これは “古典的な (classic)” 除算とも呼ばれます。

文字列を数に変換するにはどうしたらいいですか？

整数に変換するには、組み込みの int() 型コンストラクタを使ってください。例えば、int('144') == 144 です。同様に、float() は浮動小数点に変換します。例えば、float('144') == 144.0 です。

デフォルトでは、これらは数を十進数として解釈するので、int('0o144') や int('0x144') は ValueError を送出します。int(string, base) はオプションの第二引数をとって変換元の基数にします。つまり int('0x144', 16) == 324 です。基数が 0 と指定された場合、その数は Python の基準によって解釈されます。先頭が ‘0o’ なら 八進数で、‘0x’ なら十六進数を表します。

文字列を数に変換するだけのために eval() を使わないでください。 eval() は特に遅いですし、セキュリティ上のリスクもあります。求められない副作用を持つような Python の式を渡そうとする人がいるかも知れません。例えば、あなたのホームディレクトリを消去する __import__('os').system("rm -rf $HOME") を渡そうとする人がいるかも知れません。

eval() にも数を Python の式として解釈する機能があります。だから例えば、eval('09') は構文エラー起こします。Python は ‘0’ で始まる数を八進数 (基数 8) とみなすからです。

数を文字列に変換するにはどうしたらいいですか？

例えば、144 という数を ‘144’ という文字列に変換したいなら、組み込みの型コンストラクタ str() を使ってください。十六進数や八進数にしたければ、組み込み関数の hex() や oct() を使ってください。装飾された形式にするには、書式指定文字列の文法 の項を参照してください。例えば、 "{:04d}".format(144) は '0144' になり、"{:.3f}".format(1/3) は '0.333' になります。文字列に % 演算子 を使うこともできます。詳細はライブラリリファレンスの解説を参照してください。

文字列をインプレースに変更するにはどうしたらいいですか？

文字列はイミュータブルなので、変更することはできません。それができるオブジェクトを作るには、その文字列をリストに変換してみるか、array モジュールを使ってください:

>>> s = "Hello, world"
>>> a = list(s)
>>> print a
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> a[7:] = list("there!")
>>> ''.join(a)
'Hello, there!'

>>> import array
>>> a = array.array('c', s)
>>> print a
array('c', 'Hello, world')
>>> a[0] = 'y' ; print a
array('c', 'yello world')
>>> a.tostring()
'yello, world'

関数やメソッドを呼ぶのに文字列を使うにはどうしたらいいですか？

様々なテクニックがあります。

一番いいのは、文字列を関数に対応させる辞書を使うことです。このテクニックの一番の利点は、文字列が関数の名前と同じ必要がないことです。この方法は case 構造をエミュレートするための一番のテクニックでもあります:

def a():
    pass

def b():
    pass

dispatch = {'go': a, 'stop': b}  # Note lack of parens for funcs

dispatch[get_input()]()  # Note trailing parens to call function

組み込み関数の getattr() を使う方法:

import foo
getattr(foo, 'bar')()

なお、getattr() はクラス、クラスインスタンス、モジュールなど、どんなオブジェクトにも使えます。

これは標準ライブラリでも何箇所か使われています。このように:

class Foo:
    def do_foo(self):
        ...

    def do_bar(self):
        ...

f = getattr(foo_instance, 'do_' + opname)
f()

locals() や eval() を使って関数名を決める方法:

def myFunc():
    print("hello")

fname = "myFunc"

f = locals()[fname]
f()

f = eval(fname)
f()

ノート: eval() の使用は遅いし危険です。もしあなたが文字列の内容を絶対的に支配できなければ、任意の関数を実行されるようにする文字列を渡す人がいるかも知れません。

文字列から後端の改行を取り除く Perl の chomp() に相当するものはありますか？

Python 2.2 から、S.rstrip("\r\n") を使って文字列 S の終端から他の空白文字を取り除くことなくすべての行末記号を取り除くことができるようになりました。文字列 S が複数行を表し、終端に空行があるとき、そのすべての空行も取り除かれます:

>>> lines = ("line 1 \r\n"
...          "\r\n"
...          "\r\n")
>>> lines.rstrip("\n\r")
'line 1 '

これは典型的に一度に一行ずつテキストを読みたい時にのみ使われるので、 S.rstrip() をこの方法で使うとうまくいきます。

古いバージョンの Python では、部分的な代用品が二つあります:

すべての終端の空白文字を取り除きたいなら、文字列オブジェクトの rstrip() メソッドを使ってください。これは改行記号一つだけでなく、すべての終端の空白文字を取り除きます。

そうでなく、文字列 S に一行しか無いなら、S.splitlines()[0] を使ってください。

scanf() や sscanf() と同等なものはありますか？

そのようなものはありません。

簡単な入力解析で、多くの場合に一番簡単な方法は、文字列オブジェクトの split() メソッドで行を空白文字で区切られた単語に分け、十進数の文字列を int() や float() で数値に変換することです。 split() にはオプションの “sep” 変数があり、行に空白文字以外の区切りを使っているときに便利です。

もっと複雑な入力解析をしたいなら、C の sscanf() よりも正規表現の方が便利ですし、この処理に向いています。

‘UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)’ とはどういう意味ですか？

このエラーは、あなたの Python インストールが 7-bit ASCII 文字列しか扱えないことを表します。この問題を扱うには二つの方法があります。

あなたのプログラムが、任意の文字セットエンコーディングのデータを扱わなければならないなら、一般に、アプリケーションが起動する環境によってデータのエンコーディングが特定されます。例えば、email や web 入力を扱うプログラムは、概して文字セットエンコーディング情報を Content-Type ヘッダから見つけます。これに使うことで、入力データを Unicode に正しく変換できます。 value によって参照される文字列が UTF-8 でエンコードされているとすれば:

value = unicode(value, "utf-8")

は Unicode オブジェクトを返します。データが UTF-8 に正しく変換されないなら、上記の呼び出しは UnicodeError 例外を送出します。

非 ASCII データを持つ文字列だけを Unicode に変換すればいいなら、まず ASCII エンコーディングを仮定して変換し、失敗したら Unicode オブジェクトを生成すればいいです:

try:
    x = unicode(value, "ascii")
except UnicodeError:
    value = unicode(value, "utf-8")
else:
    # value was valid ASCII data
    pass

デフォルトのエンコーディングは、Python ライブラリの一部である sitecustomize.py と呼ばれるファイルで設定できます。しかし、Python 全体におけるデフォルトのエンコーディングを変えてしまうことは、サードパーティ拡張モジュールの失敗につながるのでお勧めできません。

なお、Windows には、 “mbcs” として知られるエンコーディングがあり、これはあなたのロケールに依存するエンコーディイングを使います。多くの場合、特に COM で作業をするとき、これが使うのに適したデフォルトのエンコーディングです。

シーケンス(タプル/リスト)

タプル、リスト間の変更はどのようにするのですか？

型コンストラクタ tuple(seq) はすべてのシーケンス (実際には、すべてのイテラブル) を同じ要素、同じ順序のタプルに変換します。

例えば、 tuple([1, 2, 3]) は (1, 2, 3) を与え、tuple('abc') は ('a', 'b', 'c') を与えます。引数がタプルなら、コピーを作らずに引数のオブジェクトそのものを返すので、あるオブジェクトが既にタプルになっているか確信が持てないのなら、tuple() を呼ぶのが手軽です。

型コンストラクタ list(seq) はすべてのシーケンスあるいはイテラブルを同じ要素、同じ順序のリストに変換します。例えば、list(''''(1, 2, 3)) は [1, 2, 3] を与え、 list('abc') は ['a', 'b', 'c'] を与えます。引数がリストなら、seq[:] と同様にコピーを作ります。

インデクスが負の場合はどうなりますか？

Python のシーケンスは正の数と負の数でインデクスされます。正の数では、 0 が最初のインデクス、 1 が 2 番目のインデクス、以下も同様です。負のインデクスでは、-1 が最後のインデクス、 -2 が最後から 2 番目のインデクス、以下も同様です。seq[-n] は seq[len(seq)-n] と同じだと考えてください。

負のインデクスを使うと便利なことがあります。例えば、S[:-1] は文字列の最後以外のすべての文字を表すので、文字列の末尾の改行を取り除くときに便利です。

シーケンスを逆順にイテレートするにはどうしたらいいですか？

Python 2.4 で追加された reversed() を使ってください:

for x in reversed(sequence):
    ... # do something with x...

これは元のシーケンスをいじるのではなく、逆順の新しいコピーを作ってイテレートさせます。

Python 2.3 では、拡張スライス構文を使います:

for x in sequence[::-1]:
    ... # do something with x...

リストから重複を取り除くにはどうしますか？

Python Cookbook の長い議論に多くの方法があるので参照してください:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560

リストを並び替えて構わないのなら、ソートした上でリストの最初から最後までを調べ、次のように重複を削除してください:

if mylist:
    mylist.sort()
    last = mylist[-1]
    for i in range(len(mylist)-2, -1, -1):
        if last == mylist[i]:
            del mylist[i]
        else:
            last = mylist[i]

リストのすべての要素が辞書のキーとして使える (つまり、すべての要素がハッシュ可能) なら、おそらくこのほうが速いです:

d = {}
for x in mylist:
    d[x] = 1
mylist = list(d.keys())

Python 2.5 以降なら、代わりに次のようにできます:

mylist = list(set(mylist))

リストを集合に変換するときに重複は取り除かれるので、それをリストに戻せばいいのです。

Python で配列を作るにはどうしますか？

リストを使ってください:

["this", 1, "is", "an", "array"]

リストの時間計算量は C や Pascal の配列と同じです。大きな違いは、 Python のリストは多くの異なる型のオブジェクトを含めることです。

array モジュールにも固定された型を簡潔に表現する配列を作るためのメソッドがありますが、リストよりもインデクスが遅いです。また、 Numeric 拡張その他でも、様々な特徴をもつ配列的な構造体が定義されています。

Lisp 方式の連結リストを得るのに、タプルを使ってコンスセルをエミュレートできます:

lisp_list = ("like",  ("this",  ("example", None) ) )

ミュータブルな必要があるなら、タプルではなくリストを使いましょう。lisp の car にあたるものが lisp_list[0] で、cdr にあたるものが lisp_list[1] です。本当に必要だと確信できるとき以外はこれはしないでください。たいてい、これは Python のリストを使うよりも非常に遅いですから。

多次元のリストを作るにはどうしますか？

このようにして多次元の配列を作ろうとしてしまったことがあるでしょう:

A = [[None] * 2] * 3

これを表示したときには問題なさそうに見えます:

>>> A
[[None, None], [None, None], [None, None]]

しかし値を代入すると、その値が複数の場所に現れてしまいます:

>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]

これは、* を使ったリストの複製がコピーを作らず、存在するオブジェクトへの参照を作るだけだからです。この *3 は長さ 2 の同じリストへの参照を含むリストを作ります。一つの列に対する変更はすべての列に現れますが、これが望んだ結果であることはまずないでしょう。

おすすめの方法は、最初に望んだ長さのリストを作り、それから新しく作ったリストでそれぞれの要素を埋めていくことです:

A = [None] * 3
for i in range(3):
    A[i] = [None] * 2

これは長さ 2 の異なるリスト 3 つを含むリストを生成します。リスト内包表記も使えます:

w, h = 2, 3
A = [[None] * w for i in range(h)]

また、行列データ型を提供している拡張も使えます。Numeric Python [http://numpy.scipy.org/] が特に有名です。

オブジェクトのシーケンスにメソッドを適用するにはどうしますか？

リスト内包表記を使ってください:

result = [obj.method() for obj in mylist]

より一般的には、以下の関数を試すことができます:

def method_map(objects, method, arguments):
    """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]"""
    nobjects = len(objects)
    methods = map(getattr, objects, [method]*nobjects)
    return map(apply, methods, [arguments]*nobjects)

辞書

キーを安定した順序で表示する辞書を作るにはどうしたらいいですか？

できません。辞書はキーを予測できない順序で保存しているので、辞書の要素が表示される順序もまた予測できないのです。

ファイルに印字可能なバージョンを保存し、変更を加えてから他の印字された辞書と比較したい時に苛立たしいかもしれません。この場合は、pprint モジュールで辞書を整形して表示してください。要素がキーでソートされて表されます。

もっと複雑な解決策は、dict のサブクラスとして SortedDict クラスを作り、それに予測可能な順序で自身を表示させることです。そのようなクラスの単純な実装の一つは:

class SortedDict(dict):
    def __repr__(self):
        keys = sorted(self.keys())
        result = ("{!r}: {!r}".format(k, self[k]) for k in keys)
        return "{{{}}}".format(", ".join(result))

    __str__ = __repr__

これは完璧な解法とは程遠いですが、多くの状況でうまく働くでしょう。最大の欠点は、辞書のある値がまた辞書であった場合に、それらの値はどんな特定の順序でも表示されないことです。

複雑なソートがしたいのですが、Python でシュワルツ変換はできますか？

Perl コミュニティの Randal Schwartz の作とされるこのテクニックは、リストの要素を、それぞれの要素をその「ソート値」に対応付けるメトリックによってソートします。Python では、単に sort() メソッドに key 引数を使ってください:

Isorted = L[:]
Isorted.sort(key=lambda s: int(s[10:15]))

key 引数はPython 2.4 で追加されたもので、古いバージョンでこのようなソートをするにはリスト内包表記でやればすごく簡単です。文字列のリストをその大文字の値でソートするには:

tmp1 = [(x.upper(), x) for x in L]  # Schwartzian transform
tmp1.sort()
Usorted = [x[1] for x in tmp1]

それぞれの文字列の 10-15 の場所から展開されたサブフィールドの整数値によってソートするには:

tmp2 = [(int(s[10:15]), s) for s in L]  # Schwartzian transform
tmp2.sort()
Isorted = [x[1] for x in tmp2]

なお、Isorted はこのようにしても計算されます:

def intfield(s):
    return int(s[10:15])

def Icmp(s1, s2):
    return cmp(intfield(s1), intfield(s2))

Isorted = L[:]
Isorted.sort(Icmp)

しかし、このメソッドは intfield() を L の要素ごとに何度も呼び出すので、シュワルツ変換よりも遅いです。

リストを別のリストの値によってソートするにはどうしますか？

二つのリストを混ぜあわせてタプルのイテレータにしてから、必要な要素を選んでください:

>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
>>> pairs = sorted(pairs)
>>> pairs
[("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]
>>> result = [x[1] for x in pairs]
>>> result
['else', 'sort', 'to', 'something']

最後の段階の別のやり方は:

>>> result = []
>>> for p in pairs: result.append(p[1])

これのほうが読みやすいと、最後のリスト内包表記ではなくこれを使いたくなるかもしれません。しかし、これは長いリストではほぼ二倍の時間がかかります。なぜでしょうか。まず、append() 演算はメモリを割り当て直す必要があり、それを避けるために毎回ちょっと工夫していますが、それでも避けられないことがあるので、少し時間がかかるのです。二つ目に、”result.append” には属性探索が余計に必要で、三つ目に、これらすべての関数を呼ぶ必要があることで速度が落ちてしまいます。

オブジェクト

クラスとは何ですか？

クラスは、class 文の実行で生成される特殊なオブジェクトです。クラスオブジェクトはインスタンスオブジェクトを生成するためのテンプレートとして使われ、あるデータ型に特有のデータ (attribute/属性) とコード (メソッド) の両方を内蔵しています。

新しいクラスを一つ以上の他のクラス (新しいクラスの基底クラスと呼ばれます) に基づいて作ることもできます。この新しいクラスは、基底クラスから属性とメソッドを継承します。これにより、オブジェクトモデルを継承で連続的に洗練できます。メールボックスへの基本的なアクセサを提供する一般的な Mailbox クラスを作って、それからいろいろな特定のメールボックスの形式を扱う MboxMailbox、 MaildirMailbox、OutlookMailbox のようなサブクラスを作れるのです。

メソッドとは何ですか？

メソッドは、オブジェクト x が持つ関数で、通常 x.name(arguments...) として呼び出されるものです。メソッドはクラス定義の中で関数として定義されます:

class C:
    def meth (self, arg):
        return arg * 2 + self.attribute

self とは何ですか？

self はメソッドの第一引数に慣習的につけられる名前にすぎません。 meth(self, a, b, c) として定義されたメソッドは、その定義がなされたクラスのインスタンス x に対して x.meth(a, b, c) として呼び出されます。呼び出されたメソッドは、meth(x, a, b, c) が呼ばれたものと考えます。

なぜメソッドの定義や呼び出しにおいて ‘self’ を明示しなければならないのですか？ も参照してください。

あるオブジェクトが、与えられたクラスやそのサブクラスのインスタンスであるかを調べるにはどうしますか？

ビルトイン関数 isinstance(obj, cls) を使ってください。クラスのタプルを与えて isinstance(obj, (class1, class2, ...)) のようにすれば、あるオブジェクトが任意の数のクラスのオブジェクトであるかを調べられますし、 isinstance(obj, str) や isinstance(obj, (int, long, float, complex)) のようにすれば、Python のビルトイン型のオブジェクトであるかも調べられます。

なお、大部分のプログラムでは、isinstance() をユーザー定義のクラスに何度も使うべきではありません。クラスを自分で開発するときに、適切なオブジェクト指向スタイルは、特定の振る舞いをカプセル化するクラスのメソッドを定義するものであって、オブジェクトのクラスを調べてそのクラスに応じて違うことをするものではありません。例えば、何かをする関数があったとして:

def search(obj):
    if isinstance(obj, Mailbox):
        # ... code to search a mailbox
    elif isinstance(obj, Document):
        # ... code to search a document
    elif ...

よりよいアプローチは、search() メソッドをすべてのクラスに定義して、それをただ呼び出すことです:

class Mailbox:
    def search(self):
        # ... code to search a mailbox

class Document:
    def search(self):
        # ... code to search a document

obj.search()

委譲とは何ですか？

委譲 (delegation) とは、オブジェクト指向のテクニック (デザインパターンとも呼ばれる) の一つです。オブジェクト x があって、そのメソッドのうちただ一つの振る舞いを変えたいとしましょう。新しいクラスを作成し、変えたいメソッドだけを新しく実装し、他のすべてのメソッドを x の対応するメソッドに委譲する新しいクラスを作れます。

Python プログラマは簡単に委譲を実装できます。例えば、以下のクラスは、ファイルのように振る舞いながらすべての文字を大文字に変換するクラスを実装します:

class UpperOut:

    def __init__(self, outfile):
        self._outfile = outfile

    def write(self, s):
        self._outfile.write(s.upper())

    def __getattr__(self, name):
        return getattr(self._outfile, name)

ここで UpperOut クラスは write() メソッドを定義しなおして、引数の文字列を大文字に変換してから基礎となる self._outfile.write() メソッドを呼び出すようにします。その他すべてのメソッドは基礎となる self._outfile オブジェクトに移譲されます。この委譲は __getattr__ メソッドを通してなされます。属性の制御の詳細は 言語リファレンス を参照してください。

なお、一般的に委譲はトリッキーになりがちです。属性が設定される時には読み出される時と同様に、そのクラスに __setattr__() メソッドを定義する必要があり、それには細心の注意が必要です。 __setattr__() の基本的な実装はおおよそ以下のようになります:

class X:
    ...
    def __setattr__(self, name, value):
        self.__dict__[name] = value
    ...

たいてい、__setattr__() 実装は self.__dict__ を変更して、無限再帰を起こすことなくローカルな状態を保存するようにしなければなりません。

基底クラスで定義されたメソッドを、そのクラスをオーバーライドした派生クラスから呼び出すにはどうしますか？

組み込みの super() 関数を使ってください:

class Derived(Base):
    def meth (self):
        super(Derived, self).meth()

旧スタイルクラスを使っているなら: class Derived(Base): ... のようなクラス定義で、 Base.meth(self, arguments...) とすれば、Base (または Base の基底クラス) で定義された meth() メソッドを呼び出せます。ここで、 Base.meth は束縛されていないメソッドなので、self 引数を渡す必要があります。

基底クラスの名前を変えやすいコードを書くにはどうしますか？

基底クラスのエイリアス (alias) を定義し、先にそれに本当の基底クラスを代入しておいてから、クラス定義の中でそのエイリアスを使うといいかもしれません。そうすればエイリアスに代入する値を変変えるだけで済みます。ちなみに、この手法は使用する基底クラスを動的に選びたいとき (使えるリソースに依るとき等) にも便利です。例:

BaseAlias = <real base class>

class Derived(BaseAlias):
    def meth(self):
        BaseAlias.meth(self)
        ...

静的なクラスデータや静的なクラスメソッドを作るにはどうしますか？

(C++ や Java の意味で) 静的なデータも静的なメソッドも Python でサポートされています。

静的なデータを作るには、単純にクラス属性を定義してください。その属性に新しい値を代入するには、代入するクラス名を明示する必要があります:

class C:
    count = 0   # number of times C.__init__ called

    def __init__(self):
        C.count = C.count + 1

    def getcount(self):
        return C.count  # or return self.count

c そのものや c.__class__ から C にいたるパス探索経路上のクラスによってオーバーライドされない限り、c.count も isinstance(c, C) であるすべての c に対する C.count を参照します。

注意: C のメソッド内では、 self.count = 42 のような代入は self 自身の辞書に “count” という名前の新しくて関係ないインスタンスを作ります。クラスの静的なデータの再束縛には、メソッド内であるか否かにかかわらず、いつもクラスを指定しなければなりません:

C.count = 314

静的メソッドは Python 2.2 以降で使えます:

class C:
    def static(arg1, arg2, arg3):
        # No 'self' parameter!
        ...
    static = staticmethod(static)

Python 2.4 のデコレータを使って、以下のようにも書けます:

class C:
    @staticmethod
    def static(arg1, arg2, arg3):
        # No 'self' parameter!
        ...

しかし、静的メソッドの効果を得るもっと簡単な方法は、単にモジュールレベル関数を使うことです:

def getcount():
    return C.count

モジュールあたりに一つのクラスを定義するように (あるいはクラス組織を厳密に関連させるように) コードが構成されているなら、これで必要なカプセル化ができます。

Python でコンストラクタ(やメソッド)をオーバーロードするにはどうしたらいいですか？

この質問の答えはすべてのメソッドについて言えることですが、この質問はだいたい以下の構造の文脈から出てきます。

C++ では、このように書けます:

class C {
    C() { cout << "No arguments\n"; }
    C(int i) { cout << "Argument is " << i << "\n"; }
}

Python では、一つのコンストラクタでデフォルトの引数を使ってすべての場合に対応するように書かなければなりません。例えば:

class C:
    def __init__(self, i=None):
        if i is None:
            print "No arguments"
        else:
            print "Argument is", i

これで完全に等価とは言えませんが、実用上は十分に近いです。

長さが変えられる引数のリストを試すには、例えば:

def __init__(self, *args):
    ...

これと同じやり方がすべてのメソッド定義で使えます。

__spam を使おうとしたら _SomeClassName__spam からエラーがでました。

先頭にアンダースコアが二つ付いた変数名は、クラスのプライベートな変数を、 “マングル化”という単純かつ効率のいい方法で定義します。__spam のような形式 (先頭に二つ以上、末尾にもしあっても一つのアンダースコアがある) のすべての識別子は、classname が先頭のアンダースコアをすべて削除した現在のクラス名とすれば、_classname__spam のように文字上で置換えられます。

これはプライベートであることを保証するものではありません。これでも外部のユーザが “_classname__spam” 属性に直接アクセスできますし、プライベートな変数はオブジェクトの __dict__ から見えます。多くの Python プログラマはわざわざプライベートな変数名を使おうとなど考えません。

クラスに __del__ メソッドを定義しているのですが、オブジェクトを削除したときに呼ばれません。

いくつかの可能性があります。

del 文は必ずしも __del__() を呼び出すとは限りません – これは単純にオブジェクトの参照カウントを減らすもので、カウントがゼロになったときに __del__() が呼び出されます。

データ構造が循環リンク (子のそれぞれが親の参照を持ち、親のそれぞれが子のリストを持つツリーなど) を含む場合、その参照カウントは決して 0 にはなりません。時々、Python はこのようなサイクルを検出するアルゴリズムを実行しますが、データ構造への参照がなくなってからこのガベージコレクタが実行されるまでいくらか時間が掛かるかもしれないので、 __del__() メソッドは不便な予測できないときに呼び出されるかもしれません。これは問題を再生しようとするときに不便です。さらに悪いことに、オブジェクトの __del__() メソッドが実行される順序は任意です。 gc.collect() を起動して収集を強制することができますが、オブジェクトが決して回収されないような本当に病的な場合もあります。

周期的なコレクタにかかわらず、オブジェクトに close() メソッドを明示的に定義し、使い終わったらいつでも呼び出せるようにするのはいいことです。そうすれば close() メソッドはサブオブジェクトへの参照をする属性を取り除いてくれます。__del__() を直接呼び出さないでください – __del__() は close() を呼び出すでしょうし、close() なら同じオブジェクトに対して複数回呼ばれてもいいことが保証されているでしょう。

循環参照を避ける他の方法は、 weakref モジュールを使って、参照カウントを増やすことなくオブジェクトを示すことです。例えばツリー構造は、親と (必要なら！) 兄弟に弱参照を使うべきです。

except 節で例外を捕まえた関数内でオブジェクトがローカル変数であったたなら、そのオブジェクトへの参照が関数のスタックフレーム内でスタックトレース内に含まれることで存在する可能性があります。通常、 sys.exc_clear() を呼び出せば、最後に記録された例外を消去することで対処してくれます。

最後に、__del__() メソッドが例外を発生させた場合、警告のメッセージが sys.stderr に書きこまれます。

与えられたクラスのすべてのインスタンスのリストを得るにはどうしますか？

Python はクラス (やビルトイン型) のすべてのインスタンスをたどりません。クラスのコンストラクタにそれぞれのインスタンスへの弱参照のリストを作らせることですべてのインスタンスをたどらせられます。

モジュール

.pyc ファイルを作るにはどうしますか？

モジュールが最初にインポートされるとき (またはソースが現在コンパイルされているファイルよりも新しいとき)、コンパイルされたコードを含む .pyc ファイルが .py ファイルと同じディレクトリに作られるでしょう。

.pyc ファイルが作られないとしたら、ディレクトリの許可の問題があるかもしれません。たとえばこれは、web サーバなどでテストするときのように、開発のときと違うユーザとして起動するときなどに起こりえます。モジュールをインポートしたときに Python がコンパイルされたモジュールをディレクトリに書き込むための条件 (許可、容量の空き、etc...) が揃っていれば、.pyc ファイルの生成は自動的に行われます。

トップレベルのスクリプトで Python を起動するときにはインポートは考慮されず、 .pyc は生成されません。例えば、トップレベルモジュール abc.py があって、他のモジュール xyz.py をインポートするようになっているとき、abc を起動すると、xyz のインポート時に xyz.pyc が生成されますが、abc.py はインポートされないので abc.pyc ファイルは生成されません。

abc.pyc が必要なら – つまり、インポートされないモジュールの .pic ファイルを生成するためには – py_compile や compileall モジュールが利用できます。

py_compile モジュールは手動で任意のモジュールをコンパイルできます。やり方の一つは、このモジュールの compile() 関数をインタラクティブに実行することです:

>>> import py_compile
>>> py_compile.compile('abc.py')

これで abc.py と同じロケーション(オプション変数の cfile で変更することもできます)に .pyc ファイルが書き込まれます。

compileall モジュールを使えば自動的に一つや複数のディレクトリのすべてのファイルをコンパイルできます。シェルプロンプトから compileall.py を起動して、コンパイルしたいファイルを含むディレクトリのパスを指定してください:

python -m compileall .

現在のモジュール名を知るにはどうしますか？

モジュールは前もって定義されたグローバル変数 __name__ を検索することで自身の名前を決定できます。この値が '__main__' であるとき、そのプログラムはスクリプトとして実行されています。インポートされることによって使われる大抵のモジュールはコマンドラインインタフェースや自己テストも提供していて、 __name__ をチェックしてからそのコードだけを実行します:

def main():
    print 'Running test...'
    ...

if __name__ == '__main__':
    main()

相互にインポートしあうモジュールを作るにはどうしたらいいですか？

以下のモジュールがあったとしましょう:

foo.py:

from bar import bar_var
foo_var = 1

bar.py:

from foo import foo_var
bar_var = 2

問題はインタプリタが以下の段階を実行することです:

main が foo をインポートする

foo の空のグローバルが生成される

foo がコンパイルされ実行を始める

foo が bar をインポートする

bar の空のグローバルが生成される

bar がコンパイルされ実行を始める

bar が foo をインポートする(すでに foo という名前のモジュールがあるので no-op となる)

bar.foo_var = foo.foo_var

この最後の段階は失敗します。Python が foo を解釈し終わっていなくて、 foo のグローバルなシンボルの辞書はまだ空ですから。

import foo を使って、グローバルコードの foo.foo_var にアクセスしようとしたときにも、これと同じことが起こります。

この問題には (少なくとも) 三つの解決策があります。

Guido van Rossum は from <module> import ... を全く使わないで、すべてのコードを関数の中に入れることを勧めています。グローバル変数とクラス変数の初期化は定数とビルトイン関数のみで行われるべきです。これでインポートされたすべてのモジュールは <module>.<name> として参照されることになります。

Jim Roskind はそれぞれのモジュールに対して以下の順に進めることを提案しています:

エクスポート (インポートされた基底クラスを必要としないグローバル、関数、クラス)

import 文

アクティブなコード (インポートされた値によって初期化されるグローバルを含む)

インポートが奇妙な場所に現れることから van Rossum はこの方法をそれほど好みませんが、これは有効です。

Matthias Urlichs は第一に再帰インポートが必要ないようにコードを構築しなおすことを推奨しています。

これらの解決策はそれぞれ両立させることもできます。

__import__(‘x.y.z’) は <module ‘x’> を返しますが、z を得るためにはどうしますか？

こうしてみてください:

__import__('x.y.z').y.z

もっと現実的には、こうするべきかもしれません:

m = __import__(s)
for i in s.split(".")[1:]:
    m = getattr(m, i)

import_module() という便利な関数があるので、 importlib を参照してください。

インポートされたモジュールを編集してから再インポートしましたが、変化が現れません。なぜですか？

効率と一貫性上の理由から、Python はモジュールが最初にインポートされた時にのみモジュールファイルを読み込みます。そうしないと、たくさんのモジュールでできていて、それぞれが同じ基本モジュールをインポートしているようなプログラムでは、その基本モジュールの解析と再解析が繰り返されることになります。変更されさたモジュールの再読込を強制するには、こうしてください:

import modname
reload(modname)

注意:この手法は 100%安全とは言えません。とりわけ:

from modname import some_objects

のような文を含むモジュールは、インポートされたオブジェクトの古いバージョンを使い続けます。そのモジュールにクラス定義が含まれていたら、存在するクラスインスタンスは新しいクラス定義を使うようにアップデート されません。これによって以下の矛盾した振舞いがなされえます:

>>> import cls
>>> c = cls.C()                # Create an instance of C
>>> reload(cls)
<module 'cls' from 'cls.pyc'>
>>> isinstance(c, cls.C)       # isinstance is false?!?
False

この問題の性質は、クラスオブジェクトを印字することで明らかになります:

>>> c.__class__
<class cls.C at 0x7352a0>
>>> cls.C
<class cls.C at 0x4198d0>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

デザインと歴史 FAQ

Python はなぜ文のグループ化にインデンテーションを使うのですか？

Guido van Rossum の信じるところによれば、インデントによるグループ化は非常にエレガントで、平均的な Python プログラムを大いに読みやすくします。しばらくすればほとんどの人はこの特徴を気に入るようになります。

begin/end の括りがないので、構文解析器と人間の読者の間にグループ化の解釈の違いは起こりえません。時折、C のプログラマはこのようなコード片に出くわします:

if (x <= y)
        x++;
        y--;
z++;

この条件文が真の時のみ実行されるのは x++ 文だけですが、このインデンテーションでは誤解を招きます。経験を積んだ C プログラマでさえ、 y が x > y の時にもデクリメントされるのはなぜか分からず長いこと立ち止まることがあるでしょう。

begin/end の括りがないので、Python はコーディングスタイルの対立が非常に起こりにくくなります。C では多様なカッコの置き方があります。一つのスタイルでのコードの読み書きに慣れてしまうと、他のスタイルを読むとき (あるいは書かなくてはならないとき) にむずむずするでしょう。

多くのコーディングスタイルは begin/end の括りにそれぞれ一行を使います。これではプログラムは冗長になって画面を浪費し、プログラムの見通しが悪くなります。一つの関数は一画面 (例えば 20 - 30 行) に収めるのが理想です。 20 行の Python は20行の C よりもはるかに多くのことができます。これは begin/end の括りがないからだけではありません – 宣言が不要なことや高レベルなデータ型もその理由です – が、インデンテーションに基づく構文は確かに役に立っています。

なぜ単純な算術演算が奇妙な結果になるのですか？

次の質問を参照してください。

なぜ浮動小数点演算はこれほど不正確なのですか？

このような結果は、よく驚かれたり Python のバグであると考えられたりします:

>>> 1.2 - 1.0
0.199999999999999996

でもこれはバグではありません。これは Python ではなく、その基底にある C のプラットフォームによる浮動小数点数の扱い方の問題で、究極には数を固定長の桁に書き下す際に生じたものです。

浮動小数点数の内部表現では一定数の二進数で十進数を示します。二進数では正確に表せない十進数もあり、僅かな丸め誤差を生じます。

十進数演算では、1/3 = 0.3333333333....... など、固定長の十進数では表せない数がたくさんあります。

基数が 2 のとき、1/2 = 0.1、1/4 = 0.01、1/8 = 0.001、などになります。 .2 は 2/10 と等しく、1/5 と等しいので、二進数の分数で 0.001100110011001... になります。

浮動小数点数には 32 か 64 ビットの精度しかないので、ある桁で切り捨てられ、十進数表示で 0.2 ではなく 0.199999999999999996 となります。

浮動小数点数の repr() 関数はすべての浮動小数点数 f に対して eval(repr(f)) == f が真となるのに必要なだけの桁を表示します。 str() 関数はそれより少ない桁を表示するので、より意図を汲んだ感覚的な数を得やすいです:

>>> 1.1 - 0.9
0.20000000000000007
>>> print 1.1 - 0.9
0.2

その結果、== による浮動小数点の演算結果の比較は間違いやすいです。僅かな不正確さだけで == が間違うこともあります。その代わりに、二つの数間の差があるしきい値よりも小さいことを調べなくてはなりません:

epsilon = 0.0000000000001  # Tiny allowed error
expected_result = 0.4

if expected_result-epsilon <= computation() <= expected_result+epsilon:
    ...

詳しくは、Python チュートリアルの floating point arithmetic の章を参照してください。

なぜ Python の文字列はイミュータブルなのですか？

これにはいくつかの利点があります。

一つはパフォーマンスです。文字列がイミュータブルなら、生成時に領域を割り当てることができるので、必要な記憶域は固定されて、変更されません。これはタプルとリストを区別する理由の一つでもあります。

別の利点は、Python で文字列が数と同じくらい “基本的” なものと考えられることです。8 という値を他の何かに変える手段が無いように、文字列 “eight” を他の何かに変える手段も無いのです。

なぜメソッドの定義や呼び出しにおいて ‘self’ を明示しなければならないのですか？

このアイデアは Modula-3 から取り入れられました。これは様々な理由からとても便利だと言えます。

まず、扱っているのがローカル変数ではなく、メソッドやインスタンス属性なのだと分かりやすいです。self.x や self.meth() と書いてあれば、そのクラスの定義を憶えていなくても、それがインスタンス変数やメソッドであることは明白です。C++ では、(グローバルは滅多にないし、簡単に判別できるので) ローカル変数宣言されていないことからある程度わかるでしょう。– しかし Python にはローカル変数宣言がないので、クラス定義を調べて確かめなくてはなりません。C++ や Java のコーディングスタンダードに、インスタンス属性に m_ 接頭辞をつけるものがあるように、この明示性はそれらの言語でも役に立ちます。

第二に、特定のクラスからメソッドを明示的に参照や呼び出ししたい時に、特別な構文が必要なくなります。C++ では、派生クラスでオーバーライドされた基底クラスからメソッドを使うには、:: 演算子を使わなければなりません。 – Python では、baseclass.methodname(self, <argument list>) と書けます。これは特に、__init__() メソッドに便利ですし、派生クラスのメソッドが、基底クラスにある同じ名前のメソッドを拡張するために、基底クラスのメソッドをどうにかして呼び出したい時にも便利です。

最後に、インスタンス変数の、代入の構文の問題を解決できます。 Python のローカル変数は、関数の中で (global が明示的に宣言されることなく) 値が代入された変数 (と定義されています！) なので、インタプリタには、代入がローカル変数にではなくインスタンス変数にされたのだと判断する方法が必要で、構文を見るだけで分かる方が (効率が) 良いのです。 C++ ではその区別を宣言時に行いますが、Python では宣言がないので、この方法でしか区別できなかったら残念です。self.var を明示すればしっくりきます。同様に、インスタンス変数を使うためにも self.var と書かなければならないので、メソッドの中の self が付いていない名前への参照は、そのインスタンスのディレクトリを検索するまでもなくローカル変数とわかります。別の言い方をすれば、ローカル変数とインスタンス変数は二つの異なる名前空間に存在し、Python にどちらの名前空間を使うかを伝えなくてはならないのです。

式中で代入ができないのはなぜですか？

C や Perl に慣れた多くの人は、C のこの慣用句を使いたいと訴えます:

while (line = readline(f)) {
    // do something with line
}

Python ではこう書かなくてはなりません:

while True:
    line = f.readline()
    if not line:
        break
    ... # do something with line

Python の式中での代入を許さない理由は、この構造によって起こる他の言語ではありがちで見つけづらいバグです:

if (x = 0) {
    // error handling
}
else {
    // code that only works for nonzero x
}

このエラーは単純なタイプミスで、 本当にやりたかったのは x == 0 の比較ですが、x = 0 と書いてしまい、変数 x に 0 を代入しています。

提案された代替案はたくさんあります。多くの案はタイプ数を少し節約しますが、勝手だったり意味不明だったりする構文や予約語を使い、言語変更の提案の簡潔さの基準を満たしていません。構造の説明をされていない人間の読者に、正しい意味を直感的に示す物であるべきです。

面白いことに、熟練した Python プログラマは while True というイディオムを受け入れていて、式構造中の代入がなくてもそれほど苦労しないようです。 Python にそれを強く求めるのは新人だけです。

以下の方法でもこれを綴ることができて、魅力的そうですが、堅牢さでは “while True” を使う方法に劣ることが多いです:

line = f.readline()
while line:
    ... # do something with line...
    line = f.readline()

この方法の問題は、次の行を取得する方法を変えたくなったとき (sys.stdin.readline() に変更したい時など) にプログラムの二箇所を変えなくてはならないことです – 二つ目の場所はループの最後に隠れています。

一番いいのはイテレータを使って、 for 文でオブジェクトを通してループさせることです。例えば、ファイルオブジェクトはイテレータプロトコルをサポートしているので、単純にこう書けます:

for line in f:
    ... # do something with line...

Python にメソッドを使う機能 (list.index()等) と関数を使う機能 (list.index()等) があるのはなぜですか？

歴史上の経緯が主な理由です。関数は型のグループに共通で、メソッドを持たないオブジェクト(タプル等)にも適用できるようにした操作に使われていました。オブジェクトの無定形な集合に容易に適用できる関数があることは、Python の関数的機能 (map()、apply() 等) を使うときにも便利です。

実際、len()、max()、min() を組み込み関数として実装することで、それぞれの型のメソッドとして実装するより少ないコードで済みます。個々のケースについては粗探しのしようがありますが、Python の一部であるし、根本的な変更をするには遅すぎます。これらの関数は、大規模なコードの破壊を避けるために残す必要があります。

ノート

Python の文字列演算は、外部の関数からメソッド (string モジュール) に移行しました。しかし、len() は関数のままです。

join() がリストやタプルのメソッドではなく文字列のメソッドなのはなぜですか？

文字列は Python 1.6 からメソッドが追加され、他の標準型と同じような機能が string モジュールの関数でいつでも使えるようになったことで、他の標準型に大きく近づきました。その新しいメソッドの多くは広く受け入れられましたが、一部のプログラマに不快を感じさせていると思われるものがこれで:

", ".join(['1', '2', '4', '8', '16'])

結果はこうなります:

"1, 2, 4, 8, 16"

この使い方には二つの議論があります。

一つ目は、「文字列リテラル (文字列定数) のメソッドを使うのは醜すぎる」というようなものです。確かにそうかも知れませんが、文字列リテラルは単なる固定された値に過ぎないというのが答えです。文字列に束縛された名前にメソッドが許されるなら、リテラルに使えないようにする理由はないでしょう。

二つ目の反対理由は、典型的には「シーケンスを文字列定数で結合させようとしているのだ」というものです。残念ながら、そうではないのです。いくつかの理由から split() を文字列のメソッドとしておいた方がはるかに簡単です。これを見ると分かりやすいでしょう:

"1, 2, 4, 8, 16".split(", ")

これは文字列リテラルに与えられた分離子 (デフォルトでは空白文字) によって区切られた部分文字列を返すように指示しています。このとき、Unicode 文字列は Unicode 文字列のリストを返し、ASCII 文字列は ASCII 文字列のリストを返すから、みんな幸せです。

join() は、セパレータ文字列に、文字列のシーケンスをイテレートして隣り合う要素の間に自身を挿入するように指示しているので、文字列のメソッドです。このメソッドは、独自に定義された新しいクラスを含め、シーケンスの規則を満たすいかなる引数にも使えます。

これは文字列メソッドなので、Unicode 文字列にも 通常の ASCII 文字列にも使えます。 join() がシーケンス型のモジュールだったとしたら、そのシーケンス型はどちらの型の文字列を返すか、セパレータの型によって決めなければなりません。

例外はどれくらい速いのですか？

try/except ブロックは極端に効率がいいです。実際に例外を補足するのは高価です。 Python 2.0 より前のバージョンでは、このイディオムが一般的でした:

try:
    value = mydict[key]
except KeyError:
    mydict[key] = getvalue(key)
    value = mydict[key]

これは、辞書がほとんどの場合にキーを持っていると予想できるときにのみ意味をなします。そうでなければ、このように書きます:

if mydict.has_key(key):
    value = mydict[key]
else:
    mydict[key] = getvalue(key)
    value = mydict[key]

ノート

Python 2.0 以降では、value = mydict.setdefault(key, getvalue(key)) のように書くことができます。

Python に switch や case 文がないのはなぜですか？

if... elif... elif... else の繰り返しで簡単に同じことができます。 switch 文の構文に関する提案が幾つかありましたが、範囲検定をするべきか、あるいはどのようにするべきかについての合意は (まだ) 得られていません。現在の状況の完全な詳細は PEP 275 [http://www.python.org/dev/peps/pep-0275] を参照してください。

非常に大きな数の選択肢から選ぶとき、値を呼び出す関数に対応づける辞書を作れます。例えば:

def function_1(...):
    ...

functions = {'a': function_1,
             'b': function_2,
             'c': self.method_1, ...}

func = functions[value]
func()

オブジェクトのメソッドを呼び出すには、さらに単純に getattr() 組み込み関数で特定の名前のメソッドを検索することが出来ます:

def visit_a(self, ...):
    ...
...

def dispatch(self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

メソッドの名前にこの例の visit_ のような接頭辞を使うことを勧めます。このような接頭辞がないと、信頼できないソースから値が与えられたときに、オブジェクトの任意のメソッドを呼び出す攻撃をされる可能性があります。

OS 特有のスレッド実装に依らずにインタプリタでスレッドをエミュレートすることはできないのですか？

答 1: 残念なことに、インタプリタは Python のスタックフレームごとに少なくとも一つの C のスタックフレームを push します。同様に、拡張もほとんどランダムなときに Python にコールバックすることがあります。よって、完全なスレッド実装には C のスレッドサポートが必要です。

答 2: 幸運なことに、完全に C スタックを使わないように再設計されたインタプリタ Stackless Python [http://www.stackless.com] があります。まだ実験的なものですが、将来性がありそうです。これは標準の Python とバイナリ互換ですが、スタックレスの中核となるかどうかはまだわかりません – これはあまりに革命的すぎるかもしれません。

ラムダ式が文を含めないのはなぜですか？

Python の構文的な枠組みでは式の中にネストされた文を扱えないため、 Python のラムダ式は文を含めません。しかし、Python ではこれは深刻な問題ではありません。他の言語でのラムダ式が機能性を追加するものであるのと違い、Python でのラムダは関数を定義するのが面倒なときの速記法に過ぎません。

Python では関数はもとからファーストクラスオブジェクトであり、ローカルなスコープで宣言できます。よって、ローカルに宣言される関数ではなくラムダ式を使う利点はただ一つ、関数の名前を考えなくてもいいことです - でもその関数オブジェクトが代入されるのは (ラムダ式が名前を空けたのとまさに同じ型のオブジェクトである) ローカル変数です！

Python は C やその他の言語のように機械語にコンパイルできますか？

簡単にはできません。Python の高水準データ型、動的な型付け、(eval() や exec() を使った) インタプリタの実行時呼び出しがあるということは、「コンパイルされた」Python のプログラムのほとんどが、x+1 のような一見簡単な演算でさえ、Python のランタイムシステムへの呼び出しで成り立っているであろうことを意味します。

Python ニュースグループや過去の Python conferences [http://python.org/community/workshops/] で説明されたいくつかのプロジェクトを見ると、現在の速度の向上は緩やかでしかない (たとえば 2 倍) ですが、このやり方はうまくいきそうです。 Jython は Java バイトコードにコンパイルするという同様の方法を使っています。 (Jim Hugunin の論証によれば、プログラム全体の解析と組み合わせることで、小さなデモプログラムでは 1000 倍の速度向上が見込めます。詳しくは 1997 Python conference [http://python.org/workshops/1997-10/proceedings/] の議事録を参照してください。)

内部的には、Python のソースコードはいつもバイトコード表現に翻訳されていて、そのバイトコードが Python の仮想マシンによって実行されます。めったに変更されないモジュールの解析が繰り返されることによるオーバーヘッドを避けるため、このバイトコードはモジュールが解析されるたびに名前が ”.pic” で終わるファイルに書きこまれます。対応する .py ファイルが変更されたとき、そのファイルは再び解析および翻訳されて .pyc ファイルは書き直されます。

一旦 .pyc ファイルが読み込まれればパフォーマンスの差はなく、 .pyc ファイルから読み込まれたバイトコードも、直接の変換により生成されたバイトコードも全く同じです。唯一の違いは、.pyc ファイルからコードを読み込むのは .py ファイルを解析して翻訳するのよりも速いことなので、予めコンパイルされた .pyc ファイルがあると Python スクリプトの起動時間が改善します。必要なら、 Lib/compileall.py モジュールで、与えられたモジュール群の適切な .pyc ファイルを生成できます。

なお、Python によって実行されるメインスクリプトは、たとえそのファイル名が .py で終わっていても、.pyc ファイルにコンパイルされません。バイトコードには変換されますが、そのバイトコードはファイルに保存されません。たいていメインスクリプトはとても短いので、これでも大きく速度を落とすことにはなりません。

Python と C のコードを様々な方法で混合して簡単にパフォーマンスを向上させるプログラムがいくつかあります。例えば Psyco [http://psyco.sourceforge.net/]、 Pyrex [http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/]、 PyInline [http://pyinline.sourceforge.net/]、 Py2Cmod [http://sourceforge.net/projects/py2cmod/]、 Weave [http://www.scipy.org/Weave] を参照してください。

Python はメモリをどのように管理するのですか？

Python のメモリ管理の詳細は実装に依ります。Python の標準の C 実装は参照カウントを使って、アクセスできないオブジェクトを探します。また別のメカニズムも使って参照サイクルを集めます。これはサイクル検出アルゴリズムを定期的に実行し、アクセスできないサイクルを探し、それに含まれるオブジェクトを削除します。gc モジュールの関数で、ガベージコレクションを実行し、デバッグ統計を取得し、コレクタのパラメタを変更できます。

Jython は Java ランタイムに頼るので、JVM のガベージコレクタが使われます。 Python のコードが参照カウントの実装の振る舞いに依るとき、この違いが微妙な移植問題を起こすことがあります。

循環性がなければ、Python プログラムはメモリを明示的に管理する必要はありません。

なぜ Python は伝統的なガベージコレクション体系を使わないのでしょうか？まず、それは C の標準的な機能ではないのでポータブルではありません。 (Boehm GC を例に取りましょう。これには most 有名なプラットフォームのためのアセンブリコードが含まれますが、全てには対応していませんし、ほとんど transparent ですが、完全に transparent ではありません。 Python を対応させるにはパッチが必要です。)

伝統的な GC は Python が他のアプリケーションに実装されるときにも問題となります。スタンドアロンの Python で動く限りでは、標準の malloc() と free() を GC ライブラリから提供されるものに置き換えても問題ありませんが、Python を実装したアプリケーションは Python のものではない 独自の 代替品を使おうとするかもしれません。現在のようにすることで、Python は malloc() と free() が適切に実装されている限りどんなものにも対応させられます。

Jython では、以下の (CPython では通る) コードはおそらく、メモリを使い切るより遥かに前にファイルディスクリプタを使い果たすでしょう:

for file in very_long_list_of_files:
    f = open(file)
    c = f.read(1)

現在の参照カウントとデストラクタのスキームを使えば、 f への新しい代入ごとに前のファイルは閉じられます。GC を使うのでは、これは保証されません。どんな Python の実装にも適用できるコードを書くには、明示的にファイルを閉じるか、with 文を使いましょう。これは GC に関係なく働きます:

for file in very_long_list_of_files:
    with open(file) as f:
        c = f.read(1)

なぜ Python の終了時にすべてのメモリが開放されるわけではないのですか？

Python モジュールのグローバルな名前空間から参照されるオブジェクトは、 Python の終了時にメモリの割り当てを解除されるとは限りません。これは、循環参照があるときに起こりえます。開放できない C ライブラリ (例えば、Purify のようなツールなどが当てはまります) によって割り当てられたいくらかのメモリも含まれます。しかし、Python は終了時にメモリをクリーンアップすることには積極的で、全ての各個オブジェクトを破棄しようとします。

再割り当て時に Python が特定のものを削除するように強制したいときは、 atexit モジュールを使って削除を強制する関数を実行してください。

なぜタプルとリストという別のデータ型が用意されているのですか？

リストとタプルは、多くの点で似ていますが、一般には本質的に異なる方法で使われます。タプルは、Pascal のレコードや C の構造体と同様なものと考えられます。型が異なっても良い関連するデータの小さな集合で、グループとして演算されます。例えば、デカルト座標は 2 つや 3 つの数のタプルとして適切に表せます。

一方、リストは、もっと他の言語の配列に近いものです。全て同じ型の可変数のオブジェクトを持ち、それらが一つ一つ演算される傾向にあります。例えば、os.listdir('.') はカレントディレクトリ内にあるファイルの文字列表現のリストを返します。この出力を演算する関数は一般に、ディレクトリに一つや二つの別のファイルを加えても壊れません。

タプルはイミュータブルなので、一度タプルが生成されたら、そのどの要素も新しい値に置き換えられません。リストはミュータブルなので、リストの要素はいつでも変更できます。イミュータブルな要素だけが辞書のキーとして使えるので、リストではなくタプルだけがキーとして使えます。

リストはどのように実装されているのですか？

Python のリストは真の可変長配列であり、Lisp スタイルの連結リストではありません。この実装は、他のオブジェクトへの参照の連続した配列を使い、リストの頭部構造にこの配列へのポインタと配列の長さを保持します。

これにより、リストのインデクシング a[i] は、リストの大きさやインデクスの値に依存しないコストで演算できます。

要素が追加または挿入されるとき、この参照の配列は大きさが変更されます。要素追加の繰り返しのパフォーマンスを上げるために、少し工夫されています。配列が大きくなるとき、次の何回かは実際に大きさを変更する必要がないように、いくらかの追加の領域が割り当てられます。

辞書はどのように実装されているのですか？

Python の辞書は大きさを変更できるハッシュテーブルとして実装されています。 B 木にコンパイルされることで、ほとんどの条件下で (特に一般的な演算である) 探索のパフォーマンスが良くなりますし、実装も単純です。

辞書は、 hash() ビルトイン関数で、辞書に保存されているそれぞれのキーに対応するハッシュコードを計算して働きます。このハッシュコードはキーに大きく依存します。例えば、”Python” のハッシュ値は -539294296 ですが、ビットが一つ違うだけの文字列 “python” のハッシュ値は 1142331976 です。そしてこのハッシュコードは、内部配列での値が保存される位置を計算するために使われます。保存しているキーのハッシュ値が異なるとすれば、一定の時間 - コンピュータサイエンスの記法で言えば O(1) - でキーを検索できることになります。また、キーのいかなる並び順も保たれていないことにもなり、配列を .keys() や .items() として横断すると、辞書の内容が任意の混乱した順序で出力されます。

なぜ辞書のキーはイミュータブルでなくてはならないのですか？

辞書のハッシュテーブルの実装は、キーを見つけるために、キーから計算されたハッシュ値を使っています。もしキーがミュータブルなオブジェクトだったら、その値は変えられ、それによりハッシュ値も変わってしまいます。しかし、キーオブジェクトを変更したのが何者であれ、値が辞書のキーとして使われていたと気付けないので、辞書の中のエントリを適切な場所に動かせません。そうして、同じオブジェクトを探そうとしたときに、ハッシュ値が違うため見つかりません。古い値を探そうとしても、そのハッシュバイナリから見つかるオブジェクトの値は異なるでしょうから、これも見つかりません。

リストでインデクシングされた辞書が必要なら、まず単純にリストをタプルに変換してください。関数 tuple(L) は、リスト L と同じエントリのタプルを生成します。タプルはイミュータブルなので、辞書のキーとして使えます。

いくつかの受け入れられなかった提案:

アドレス (オブジェクト ID) のハッシュリスト。これは、同じ値の新しいリストを作っても見つからないので駄目です。例えば:

mydict = {[1, 2]: '12'}
print mydict[[1, 2]]

は、2 行目の [1, 2] の id が 1 行目のものと違うため、 KeyError 例外を起こします。要するに、辞書のキーは is ではなく、 == で比較されるべきです。

リストをキーとして使うときにコピーを作る。リストはミュータブルなので、自分自身への参照を含むことができ、コードをコピーするときに無限ループにハマる可能性があるので、これは駄目です。

リストをキーとして使うことを認めるが、ユーザにそれを変更させないように伝える。もしユーザが忘れたり、偶然にリストが変更されてしまったりしたら、追跡困難なバグの可能性を生じてしまいます。またこれは、d.keys() のすべての値は辞書のキーとして使えるという、辞書の重要な不変性も潰してしまいます。

リストが一旦辞書のキーとして使われたら、読み込み専用のマークを付ける。問題は、値を変えられるのはトップレベルオブジェクトだけではないことです。リストを含むタプルもキーとして使えます。全てを辞書のキーとして導入すると、そこから到達可能な全てのオブジェクトに読み込み専用のマークを付ける必要があります - そして再び、自己参照オブジェクトが無限ループを引き起こします。

必要ならばこれを回避する方法がありますが、自己責任のもとで行ってください。ミュータブルな構造を、__eq__() と __hash__() メソッドの両方を持つクラスインスタンスに含めることができます。その時、辞書 (またはハッシュに基づく別の構造体) に属するような全てのラッパーオブジェクトのハッシュ値が、そのオブジェクトが辞書 (その他の構造体) 中にある間固定され続けることを確実にしてください:

class ListWrapper:
    def __init__(self, the_list):
        self.the_list = the_list
    def __eq__(self, other):
        return self.the_list == other.the_list
    def __hash__(self):
        l = self.the_list
        result = 98767 - len(l)*555
        for i, el in enumerate(l):
            try:
                result = result + (hash(el) % 9999999) * 1001 + i
            except Exception:
                result = (result % 7777777) + i * 333
        return result

なお、リストのメンバーの中にハッシュ化できないものがある可能性や、算術オーバーフローの可能性から、ハッシュ計算は複雑になります。

さらに、そのオブジェクトが辞書に含まれるか否かにかかわらず、o1 == o2 (すなわち o1.__eq__(o2) が真) ならばいつでも hash(o1) == hash(o2) (すなわち o1.__hash__() == o2.__hash__) でなくてはなりません。その制限に適合できなければ、辞書やその他のハッシュに基づく構造体は間違いを起こします。

この ListWrapper の例では、異常を避けるため、ラッパオブジェクトが辞書内にある限りラップされたリストが変更されてはなりません。この条件と満たせなかった時の結果について知恵を絞る覚悟がない限り、これをしてはいけません。よく考えてください。

なぜ list.sort() はソートされたリストを返さないのですか？

パフォーマンスが問題となる状況では、ソートするためだけにリストのコピーを作るのは無駄が多いです。そこで、list.sort() はインプレースにリストをソートします。このことを忘れないため、この関数はソートされたリストを返しません。こうすることで、ソートされたコピーが必要で、ソートされていないものも残しておきたいときに、うっかり上書きしてしまうようなことがなくなります。

Python 2.4 で、新しい関数 – sorted() – が追加されました。この関数は、与えられたイテレート可能から新しいリストを生成し、ソートして返します。例えば、辞書のキーをソートされた順序でイテレートする方法は:

for key in sorted(mydict):
    ... # do whatever with mydict[key]...

Python ではどのようにインタフェース仕様を特定し適用するのですか？

C++ や Java のような言語が提供するような、モジュールに対するインタフェース仕様の特定は、モジュールのメソッドや関数の原型を表現します。インタフェースの特定がコンパイル時に適用されることが、大きなプログラムの構成に役立つと、広く感じられています。

Python 2.6 で、abc モジュールが追加され、抽象基底クラス (Abstract Base Classes/ABCs) を定義できるようになりました。これにより、isinstance() や issubclass() を使って、あるインスタンスやクラスが特定の ABC を実装するかを調べられるようになりました。collections モジュールによって、Iterable、 Container 、MutableMapping などの役立つ ABC が定義されています。

Python では、コンポーネントの適切なテスト規律によって、インタフェース仕様の多くの強みを活かせます。サブクラス化による問題を見つけるために使えるツール PyChecker もあります。

モジュールのための適切なテストスイートは、回帰テストを提供し、モジュールのインタフェース仕様や用例集としても役立ちます。多くの Python モジュールは、簡単な「自己テスト」を提供するスクリプトとして実行できます。複雑な外部インタフェースを使うモジュールさえ、外部インタフェースの細かい「スタブ」エミュレーションで単独にテストできることが多いです。doctest や unittest モジュール、あるいはサードパーティのテストフレームワークで、モジュールのコードの全ての行に及ぶ徹底的なテストスイートを構成できます。

Python で大きくて複雑なアプリケーションを構築するとき、インタフェース仕様と同様に、適切なテスト規律も役立ちます。実際、インタフェース仕様ではテストできないプログラムの属性もあるので、それ以上にもなりえます。例えば、append() メソッドは新しい要素をある内部リストの終わりに加えます。インタフェース仕様ではこの append() の実装が実際にこれを行うかをテストできませんが、テストスイートならこの機能を簡単に確かめられます。

テストスイートを書くことはとても役に立ちますし、テストのしやすさという視点でコードを設計することにもつながります。テスト指向開発は、人気を増しつつある技法で、実際のコードを書き始める前に、最初からテストスイートの部品を書くことを求めます。もちろん、 Python で粗雑にテストケースを全く書かないこともできます。

なぜオブジェクト間でデフォルト値が共有されるのですか？

この種のバグがよく初心者プログラマに噛み付きます。この関数を考えてみてください:

def foo(mydict={}):  # Danger: shared reference to one dict for all calls
    ... compute something ...
    mydict[key] = value
    return mydict

初めてこの関数を呼び出した時、mydict には一つの要素があります。二回目には、foo() が実行されるときに mydict には初めから一つの要素をすでに持っているので、mydict には二つの要素があります。

関数の呼び出しによって、デフォルトの値に対する新しいオブジェクトが作られるのだと予想しがちです。実はそうなりません。デフォルト値は、関数が定義されたときに一度だけ生成されます。この例の辞書のように、そのオブジェクトが変更されたとき、その後の関数の呼び出しは変更後のオブジェクトを参照します。

定義の時に、数、文字列、タプル、None など、イミュータブルなオブジェクトを使うと変更される危険がありません。辞書、リスト、クラスインスタンスなどのミュータブルなオブジェクトは混乱のもとです。

この性質から、ミュータブルなオブジェクトをデフォルト値として使わないプログラミング手法がいいです。代わりに、None をデフォルト値に使い、そのパラメタが None である時にだけ、関数の内部で新しいリスト/辞書/その他をつくるようにしてください。例えば、こう書かずに:

def foo(mydict={}):
    ...

こう書いてください:

def foo(mydict=None):
    if mydict is None:
        mydict = {}  # create a new dict for local namespace

この性質が便利なこともあります。時間のかかる計算を行う関数があるときに使われる一般的な技法は、関数が呼び出されるごとにパラメタと結果の値をキャッシュし、再び同じ値が要求されたらキャッシュされた値を返すというものです。これは “memoizing” と呼ばれ、このように実装されます:

# Callers will never provide a third parameter for this function.
def expensive (arg1, arg2, _cache={}):
    if (arg1, arg2) in _cache:
        return _cache[(arg1, arg2)]

    # Calculate the value
    result = ... expensive computation ...
    _cache[(arg1, arg2)] = result           # Store result in the cache
    return result

デフォルト値の代わりに、辞書を含むグローバル変数も使えます。これは好みの問題です。

なぜ goto が無いのですか？

関数の呼び出しをまたいでも動作する “構造化された goto” をまかなうものとして例外を使えます。C、Fortran、その他の言語での “go” あるいは “goto” 構造の適切な用途は全て、例外で同じようなことををすれば便利であると、広く感じられています。例えば:

class label: pass  # declare a label

try:
     ...
     if (condition): raise label()  # goto label
     ...
except label:  # where to goto
     pass
...

例外ではループ内へ跳ぶことはできませんが、どちらにしてもそれは goto の乱用と見なされるものです。使うのは控えてください。

なぜ raw 文字列 (r-strings) はバックスラッシュで終わってはいけないのですか？

正確には、奇数個のバックスラッシュで終わってはいけません。終わりの対になっていないバックスラッシュは、閉じ引用文字をエスケープし、終っていない文字列を残してしまいます。

raw 文字列は、独自にバックスラッシュの処理をしようとするプロセッサ (主に正規表現エンジン) への入力を生成しやすいように設計されたものです。このようなプロセッサは、終端の対になっていないバックスラッシュを結局エラーとみなすので、raw 文字列はそれを認めません。その代わりに、バックスラッシュでエスケープすることで、引用文字を文字列として渡すことができます。r-string が意図された目的に使われるときに、この規則が役に立つのです。

Windows のパス名を構築するときには、Windows のシステムコールは普通のスラッシュも受け付けることを憶えておいてください:

f = open("/mydir/file.txt")  # works fine!

DOS コマンドのパス名を構築するときには、例えばこの中のどれかを試してください:

dir = r"\this\is\my\dos\dir" "\\"
dir = r"\this\is\my\dos\dir\ "[:-1]
dir = "\\this\\is\\my\\dos\\dir\\"

属性の代入に “with” 文が使えないのはなぜですか？

Python には、ブロックの実行を包む ‘with’ 文があり、ブロックに入るときとブロックから出るときに、コードを呼び出します。以下のような構造を持つ言語があります:

with obj:
    a = 1               # equivalent to obj.a = 1
    total = total + 1   # obj.total = obj.total + 1

Python では、このような構造は曖昧になるでしょう。

Object Pascal、Delphi、C++のような他の言語では、静的な型を使うので、曖昧な方法でも、どのメンバに代入されているのか分かります。これが静的型付けの要点です – コンパイラは always コンパイル時にすべての変数のスコープを知るのです。

Python は動的な型を使います。実行時にどの属性が参照されるか事前に分かりません。動作中にメンバ属性が追加あるいは除去されるかもしれません。これでは、単純に読むだけではどのアトリビュートが参照されているか分かりません。ローカルなのか、グローバルなのか、メンバ属性なのか。

例えば、以下の不完全なコード片を考えましょう:

def foo(a):
    with a:
        print x

このコード片では、”a” は “x” というメンバ属性を持っていると仮定されています。しかし、Python ではインタプリタにはこの仮定を伝えられる仕組みはありません。 “a” が、例えば整数だったら、どうなってしまうでしょうか。 “x” という名前のグローバル変数があったら、それが with ブロックの中で使われるのでしょうか。この通り、Python の動的な特質から、このような選択はとても難しい物になっています。

しかし、”with” やそれに類する言語の機能の一番の利点 (コード量の削減) は、 Python では代入により簡単に手に入れられます:

function(args).mydict[index][index].a = 21
function(args).mydict[index][index].b = 42
function(args).mydict[index][index].c = 63

こう書いてください:

ref = function(args).mydict[index][index]
ref.a = 21
ref.b = 42
ref.c = 63

Python では実行時に名前束縛が解決され、後者はその解決が一度で済むため、これには実行速度をあげる副作用もあります。

if/while/def/class 文にコロンが必要なのはなぜですか？

主に可読性を高めるため (実験的な ABC 言語の結果の一つ) に、コロンが必要です:

if a == b
    print a

と:

if a == b:
    print a

を考えれば、後者のほうが少し読みやすいでしょう。さらに言えば、この FAQ の解答例は次のようになるでしょう。これは、英語の標準的な用法です。

他の小さな理由は、コロンによってエディタがシンタックスハイライトをしやすくなることです。手の込んだ解析をしなくても、コロンを探せばいつインデンテーションを増やすべきかを決められます。

なぜ Python ではリストやタプルの最後にカンマがあっても良いのですか？

Python では、リスト、タプル、辞書の最後の要素の後端にカンマをつけても良いことになっています:

[1, 2, 3,]
('a', 'b', 'c',)
d = {
    "A": [1, 5],
    "B": [6, 7],  # last trailing comma is optional but good style
}

これを許すのには、いくつかの理由があります。

複数行にまたがるリスト、タプル、辞書にリテラル値を使っているとき、こうすれば前の行にカンマを加える必要がなくなるので、要素を加えやすくなります。構文エラーを引き起こすことなくエディタで行をソートできます。

間違えてカンマを落としてしまうと、診断しづらいエラーにつながります。例えば:

x = [
  "fee",
  "fie"
  "foo",
  "fum"
]

このリストには4つの要素があるように見えますが、実際には3つしかありません。”fee、”fiefoo”、”fum” です。いつもカンマを付けるようにすれば、この種のエラーが避けられます。

後端にカンマをつけても良いことにすれば、プログラムによるコード生成も簡単になります。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

ライブラリと拡張 FAQ

Contents

ライブラリと拡張 FAQ

ライブラリ一般の質問

作業 X を行うためのモジュールやアプリケーションを探すにはどうしますか？

math.py (socket.py, regex.py, etc.) のソースファイルはどこにありますか？

Python のスクリプトを Unix で実行可能にするにはどうしますか？

Python には curses/termcap パッケージはありますか？

Python には C の onexit() に相当するものはありますか？

シグナルハンドラが動かないのですがなぜですか？

よくある作業

Python のプログラムやコンポーネントをテストするにはどうしますか？

Python のドキュメント文字列からドキュメントを生成するにはどうしますか？

一度に一つの押鍵を取得するにはどうしますか？

スレッド

スレッドを使ったプログラムを書くにはどうしますか？

スレッドが一つも実行されていないようです。なぜですか？

たくさんのワーカースレッドに作業を割り振るにはどうしますか？

グローバルな値のスレッドセーフな変更の種類は何ですか？

グローバルインタプリタロック (Global Interpreter Lock) を取り除くことはできないのですか？

入力と出力

ファイルを削除するにはどうしますか？ (その他、ファイルに関する質問...)

ファイルをコピーするにはどうしますか？

バイナリデータを読み書きするにはどうしますか？

os.popen() によって作られたパイプで os.read() が使われていないようです。なぜですか？

パイプを入力と出力の両方に接続してサブプロセスを動かすにはどうしますか？

シリアル (RS232) ポートにアクセスするにはどうしますか？

sys.stdout (stdin, stderr) を閉じようとしても実際に閉じられないのはなぜですか？

ネットワーク/インターネットプログラミング

Python の WWW ツールには何がありますか？

CGI フォームの発信 (METHOD=POST) を模倣するにはどうしますか？

どのモジュールが HTML の生成の役に立ちますか？

Python のスクリプトからメールを送るにはどうしますか？

ソケットの connect() メソッドでブロッキングされなくするにはどうしますか？

データベース

Python にはデータベースパッケージへのインタフェースはありますか？

Python で永続的なオブジェクトを実装するにはどうしますか？

なぜ cPickle はこんなに遅いのですか？

bsddb (or anydbm) データベースが開かれたままプログラムがクラッシュすると、だめになってしまいます。なぜですか？

Berkeley DB ファイルを開こうとしましたが、bsddb が bsddb.error: (22, ‘Invalid argument’) を生じます。助けてください！ データを復元するにはどうしたら良いですか？

数学と数

Python でランダムな数を生成するにはどうしますか？

ライブラリ一般の質問

作業 X を行うためのモジュールやアプリケーションを探すにはどうしますか？

the Library Reference で関連した標準ライブラリモジュールがないか探してください。(いずれ、何が標準ライブラリにあるのかをおぼえて、この段階を飛ばせるようになるでしょう。)

サードパーティのパッケージについては、Python Package Index [http://pypi.python.org/pypi] を探したり、Google [http://www.google.com] その他の Web サーチエンジンを試してください。”Python” に加えて一つか二つのキーワードで興味のある話題を検索すれば、たいてい役に立つものが見つかるでしょう。

math.py (socket.py, regex.py, etc.) のソースファイルはどこにありますか？

モジュールのソースファイルが見つからなかったら、それは C、C++、その他のコンパイルされた言語で実装され、ビルトインまたは動的にロードされるモジュールかもしれません。この場合、ソースファイルが存在しないか、 (Python のパスではなく) C のソースディレクトリのどこかに mathmodule.c のようにあるかもしれません。

Python のモジュールには、(少なくとも) 3 種類あります:

Python で書かれたモジュール (.py)。

C で書かれ、動的にロードされるモジュール (.dll, .pyd, .so, .sl, etc)。

C で書かれ、インタプリタにリンクされているモジュール。このリストを得るには、こうタイプしてください:

import sys
print(sys.builtin_module_names)

Python のスクリプトを Unix で実行可能にするにはどうしますか？

二つの条件があります :スクリプトファイルのモードが実行可能で、最初の行が #! で始まり Python インタプリタのパスが続いていなければなりません。

前者は、chmod +x scriptfile、場合によっては chmod 755 scriptfile を実行すればできます。

後者は、いくつかの方法でできます。最も単純な方法は、ファイルの最初の行に、プラットフォーム上の Python がインストールされているパス名を用いて、こう書くことです:

#!/usr/local/bin/python

スクリプトが Python インタプリタのありかに依らないようにするために、 “env” プログラムを使えます。ほぼすべての Unix バリアントで、Python インタプリタがユーザの $PATH ディレクトリにあれば、以下のようにできます:

#!/usr/bin/env python

CGI スクリプトではこれを しないでください。 CGI スクリプトの $PATH 変数は往々にして小さすぎるので、インタプリタの実際のパス名を使わなくてはならないのです。

たまに、ユーザの環境がいっぱいすぎて /usr/bin/env プログラムが働かなかったり、 env プログラムが全く無かったりします。その場合、 (Alex Rezinsky による)以下の技法を試してください:

#! /bin/sh
""":"
exec python $0 ${1+"$@"}
"""

これには、スクリプトの __doc__ 文字列を定義するというちょっとした欠点があります。しかし、これを付け足せば直せます:

__doc__ = """...Whatever..."""

Python には curses/termcap パッケージはありますか？

Unix バリアントでは: 標準の Python ソース配布には、 Modules/ サブディレクトリに curses モジュールが同梱されていますが、デフォルトではコンパイルされていません (なお、Windows ディストリビューションでは使えません – Windows 用の curses モジュールはありません)

curses モジュールには基礎的な curses の機能だけでなく、色や別の文字セットのサポート、パッド、マウスのサポートなど、ncurses や SYSV curses 由来の追加の関数も用意されています。これにより、このモジュールは BSD curses しか持っていないオペレーティングシステムとの互換性を持たないことになりますが、そのような現行の OS はなさそうです。

Windows では: the consolelib module [http://effbot.org/zone/console-index.htm] を使ってください。

Python には C の onexit() に相当するものはありますか？

atexit モジュールは C の onexit と同じようなレジスタ関数を提供します。

シグナルハンドラが動かないのですがなぜですか？

最もありがちな問題は、シグナルハンドラが間違った引数リストで宣言されていることです。これは次のように呼び出されます:

handler(signum, frame)

だから、これは二つの引数で宣言されるべきです:

def handler(signum, frame):
    ...

よくある作業

Python のプログラムやコンポーネントをテストするにはどうしますか？

Python には二つのテストフレームワークがついています。doctest モジュールは 、モジュールの docstring から使用例を見つけてそれらを実行し、出力を docstring によって与えられた望まれる出力と比較します。

unittest モジュールは、Java や Smalltalk のテストフレームワークを模した装飾されたテストフレームワークです。

テストには、プログラムを書くのに、簡単にテストできるように良いモジュール式デザインを使うのが役に立ちます。プログラムは、ほとんど全ての機能を関数かクラスメソッドにカプセル化させるべきです – そうすることでプログラムの起動が速くなる (ローカル変数のアクセスはグローバルなアクセスよりも速いから) という驚くべき嬉しい効果をもたらすこともあります。さらに、変化するグローバル変数はテストを行うのを非常に難しくするので、プログラムはそれに依らないようにしましょう。

プログラムの “global main logic” は、プログラムの main モジュールの最後に、次のようにシンプルに書くべきです:

if __name__ == "__main__":
    main_logic()

一旦、関数とクラス動作を扱いやすいように集めてプログラムを構成したら、その動作を洗練させるようなテストを書きましょう。テストスイートには、それぞれの一連のテストを自動化したモジュールも関係します。それは大変そうですが、Python は簡潔で柔軟なので、驚くほど簡単です。テスト関数を”プロダクションコード”と並行して書くことにより、バグや設計上の欠陥を早く見つけることができるようになり、コードをもっとずっと快適に楽しく書けます。

プログラムのメインモジュールとして設計されたのではない “補助モジュール” には、モジュールの自己テストを含めるといいでしょう:

if __name__ == "__main__":
    self_test()

複雑な外部インタフェースと作用し合うプログラムでさえ、外部インタフェースが使えない時でも、Python で実装された “fake” インタフェースを使ってテストできます。

Python のドキュメント文字列からドキュメントを生成するにはどうしますか？

pydoc モジュールで Python ソースコード内のドキュメント文字列から HTML を生成できます。純粋に docstring から API ドキュメントを生成するには、他に epydoc [http://epydoc.sf.net/] という選択肢もあります。 Sphinx [http://sphinx.pocoo.org] も docstring の内容を含めることができます。

一度に一つの押鍵を取得するにはどうしますか？

Unix バリアントでは: いくつかの方法があります。curses を使えば簡単ですが、 curses はかなり大きいモジュールなので習得するのが難しいです。ここに curses を使わない解決策を挙げます:

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

これを動かすためには、termios と fcntl モジュールが必要です。また、多分他でも動きますが、Linux でしかこれを試していません。このコードでは、文字は一文字づつ読みこまれ、印字されます。

termios.tcsetattr() は stdin の反響を止め、標準モードを使えなくします。 fcntl.fnctl() は、stdin のファイルディスクリプタフラグを取得し、それらをノンブロッキングモードに変えるのに使われます。stdin が空の時に読み込むのは IOError になるので、このエラーは補足され、無視されます。

スレッド

スレッドを使ったプログラムを書くにはどうしますか？

thread モジュールではなく、必ず threading モジュールを使ってください。threading モジュールは、thread モジュールで提供される低レベルな基本要素の、便利な抽象化を構成します。

Aahz は、役立つスレッディングのチュートリアルから成るスライドを揃えています。 http://www.pythoncraft.com/OSCON2001/ を参照してください。

スレッドが一つも実行されていないようです。なぜですか？

メインスレッドが終了するとともに、全てのスレッドは終了されます。メインスレッドは速く働きすぎるので、スレッドには何をする時間も与えられません。

簡単な解決策は、プログラムの終わりに、スレッドが完了するのに十分な時間のスリープを加えることです:

import threading, time

def thread_task(name, n):
    for i in range(n): print name, i

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10) # <----------------------------!

しかし、実際は (ほとんどのプラットフォームでは) スレッドは並行して実行されるのではなく、一つづつ実行されるのです！ なぜなら、OS のスレッドスケジューラは、前のスレッドがブロックされるまで新しいスレッドを開始しないからです。

簡単に治すには、関数の実行の最初にちょっとスリープを加えることです:

def thread_task(name, n):
    time.sleep(0.001) # <---------------------!
    for i in range(n): print name, i

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10)

time.sleep() による遅延をどれくらいとれば十分かを考えるより、セマフォ構造を使ったほうがいいです。一つのやり方は、 Queue モジュールでキューオブジェクトを作り、それぞれのスレッドが終了するごとにキューにトークンを加えさせ、メインスレッドにスレッドがあるのと同じ数のトークンをキューから読み込ませるようにすることです。

たくさんのワーカースレッドに作業を割り振るにはどうしますか？

Queue モジュールで、作業のリストを含むキューを作ってください。Queue クラスはオブジェクトのリストを保持し、 .put(obj) で要素を加え、.get() で要素を返すことができます。ロッキングを引き受けるクラスは、全ての作業がちょうど一回づつ行われることを確実にしなければなりません。

ここにちょっとした例があります:

import threading, Queue, time

# The worker thread gets jobs off the queue.  When the queue is empty, it
# assumes there will be no more work and exits.
# (Realistically workers will run until terminated.)
def worker ():
    print 'Running worker'
    time.sleep(0.1)
    while True:
        try:
            arg = q.get(block=False)
        except Queue.Empty:
            print 'Worker', threading.currentThread(),
            print 'queue empty'
            break
        else:
            print 'Worker', threading.currentThread(),
            print 'running with argument', arg
            time.sleep(0.5)

# Create queue
q = Queue.Queue()

# Start a pool of 5 workers
for i in range(5):
    t = threading.Thread(target=worker, name='worker %i' % (i+1))
    t.start()

# Begin adding work to the queue
for i in range(50):
    q.put(i)

# Give threads time to run
print 'Main thread sleeping'
time.sleep(5)

実行時には、以下のように出力されます:

Running worker Running worker Running worker Running worker Running worker Main thread sleeping Worker <Thread(worker 1, started 130283832797456)> running with argument 0 Worker <Thread(worker 2, started 130283824404752)> running with argument 1 Worker <Thread(worker 3, started 130283816012048)> running with argument 2 Worker <Thread(worker 4, started 130283807619344)> running with argument 3 Worker <Thread(worker 5, started 130283799226640)> running with argument 4 Worker <Thread(worker 1, started 130283832797456)> running with argument 5 ...

詳細はモジュールのドキュメントを参照してください。 Queue クラスで多機能なインタフェースを使えます。

グローバルな値のスレッドセーフな変更の種類は何ですか？

グローバルインタプリタロック (GIL) が内部で使われ、Python VM で一度に一つだけのスレッドが実行されることが保証されています。一般に、Python ではスレッド間の切り替えをバイトコード命令の間でのみ行います。切り替えの周期は、 sys.setcheckinterval() で設定できます。したがって、それぞれのバイトコード命令、そしてそれぞれの命令が届く全ての C 実装コードは、 Python プログラムの観点からは、アトミックです。

このことから、理論上は、正確な勘定のためには PVM バイトコードの実装を理解することが必要です。実際上は、組み込みデータ型(整数、リスト、辞書、等)の、変数を共有する”アトミックそうな”演算は、実際にアトミックです。

例えば、以下の演算は全てアトミックです (L、L1、L2 はリスト、 D、D1、D2 は辞書、x、y はオブジェクト、i、j は整数です):

L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()

これらは、アトミックではありません:

i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1

他のオブジェクトを置き換えるような演算は、そのオブジェクトの参照カウントがゼロになったときに __del__() メソッドを呼び出すことがあり、これが影響を及ぼすかもしれません。これは特に、辞書やリストの大規模な更新に当てはまります。疑わしければ、mutex を使ってください！

グローバルインタプリタロック (Global Interpreter Lock) を取り除くことはできないのですか？

マルチスレッド Python プログラムは事実上一つの CPU しか使えず、 (ほとんど) 全ての Python コードが グローバルインタプリタロック (GIL) が保持されている間しか作動しなくなるということで、GIL は、 Python をハイエンドなマルチプロセッササーバマシン上に配備する上で邪魔であると見なされがちです。

Python 1.5 の時代に、Greg Stein は GIL をきめ細かいロッキングで置き換える総合パッチ (“free threading” パッチ) セットを実装しました。残念ながら、(ロックがとても効率的な) Windows でさえ、標準的な Python コードが、GIL を使ったインタプリタの 2 倍くらい遅くなりました。 Linux では、pthread ロックが効率的でないので、パフォーマンスの損失が更に酷いです。

その後、GIL を取り除くという案はたまに出てきますが、だれも予期される減速に対処する方法を見つけられず、スレッドを使わないユーザはこーどが半分の速度でしか動作しないのでは幸せではありません。Greg の free threading パッチは、以降の Python バージョンには更新されていません。

これは、Python をマルチ CPU マシンで使いこなせないことを意味しません！作業を複数の スレッド ではなく、複数の プロセッサ に分けることを考えればいいのです。 C 拡張をうまく使うことも役に立ちます。C 拡張を使ってに時間のかかる作業を行わせれば、その実行のスレッドが C のコードにある間その拡張は GIL を開放でき、他のスレッドに作業させることができます。

GIL を本当にグローバルにするより、インタプリタ状態ごとのロックにするべきという提案もあります。そして、インタプリタはオブジェクトを共有するべきではないということです。残念ながら、どちらも実現しないでしょう。多くのオブジェクトの実装は現在、グローバル状態を持っているので、実現はたいへんな大仕事になりそうです。例えば、小さな整数と短い文字列はキャッシュされます。このキャッシュはインタプリタ状態に動かされなくてはなりません。他のオブジェクト型は自身の自由変数リストを持っています。これらの自由変数リストはインタプリタ状態に動かされなくてはなりません。等々。

それどころか、その作業が終わる時が来るかもわかりません。なぜなら、サードパーティ拡張にも問題があるからです。サードパーティ拡張が書かれるペースは、インタプリタ状態にすべてのグローバル状態を格納するように変換できるペースよりも速いことでしょう。

そして最後に、一旦複数のインタプリタを状態を全く共有しないようにしたとして、それぞれのインタプリタを独立したプロセス上で動かしてなにが得られるというのでしょうか？

入力と出力

ファイルを削除するにはどうしますか？ (その他、ファイルに関する質問...)

os.remove(filename) または os.unlink(filename) を使ってください。ドキュメントは、os モジュールを参照してください。この二つの関数は同じものです。unlink() は単に、この関数の Unix システムコールの名称です。

ディレクトリを削除するには、os.rmdir() を使ってください。作成には os.mkdir() を使ってください。os.makedirs(path) は path の中間のディレクトリの、存在しないものを作成します。os.removedirs(path) は中間のディレクトリが空である限り、それらを削除します。ディレクトリツリー全体とその中身全てを削除したいなら、shutil.rmtree() を使ってください。

ファイルの名前を変更するには、os.rename(old_path, new_path) を使ってください。

ファイルを切り詰めるには、f = open(filename, "r+") でファイルを開いてから、 f.truncate(offset) を使ってください。offset はデフォルトでは現在のシーク位置です。os.open() で開かれたファイルのために、 os.ftruncate(fd, offset) もあります。fd はファイルディスクリプタ (小さな整数) です。

shutil モジュールにも、copyfile()、 copytree()、rmtree() 等、ファイルに作用する関数がいくつか含まれます。

ファイルをコピーするにはどうしますか？

shutil モジュールには copyfile() 関数があります。なお、MacOS 9 ではリソースフォークやファインダー情報をコピーしません。

バイナリデータを読み書きするにはどうしますか？

複雑なバイナリデータ形式の読み書きには、struct モジュールを使うのが一番です。これでバイナリデータ (通常は数) を含む文字列を取って、 Python オブジェクトに変換することができますし、その逆もできます。

例えば、以下のコードはファイルから 2 バイトの整数 2 個と 4 バイトの整数 1 個をビッグエンディアンフォーマットで読み込みます:

import struct

with open(filename, "rb") as f:
   s = f.read(8)
   x, y, z = struct.unpack(">hhl", s)

フォーマット中の ‘>’ はデータを強制的にビッグエンディアンにします。ファイルから、文字 ‘h’ は一つの”整数”(2 バイト)を読み込み、文字 ‘l’ は一つの”long 整数”を読み込みます。

より規則的なデータ (整数の、または浮動小数点数の均質なリスト等) には、 array モジュールも使えます。

os.popen() によって作られたパイプで os.read() が使われていないようです。なぜですか？

os.read() は、開かれたファイルを表す小さな数であるファイルディスクリプタを取る低レベルな関数です。os.popen() は、組み込みの open() 関数が返すのと同じ型である高レベルなファイルオブジェクトを生成します。そうして、os.popen() から n バイトを読み込むには、p.read(n) とする必要があります。

パイプを入力と出力の両方に接続してサブプロセスを動かすにはどうしますか？

popen2 モジュールを使ってください。例えば:

import popen2
fromchild, tochild = popen2.popen2("command")
tochild.write("input\n")
tochild.flush()
output = fromchild.readline()

警告: 一般的に、これをするのは賢くありません。子があなたからの入力を待ってブロックされている間、プロセスが子からの入力を待ってブロックされているというようなデッドロックを引き起こしやすいからです。これは、親が子がそれよりも多くのテキストを出力することを期待することにより、あるいはデータが書きださされないことで標準入出力バッファがスタックにあることにより起こります。Python の親はもちろん子に送るデータを出力を読み込む前に明示的に書きだすことができますが、子が素朴な C プログラムであると、それが対話的なものであってさえ、書き出しが通常自動的なものであるがゆえ、明示的に出力を書き出さないように書かれていることがあります。

なお、デッドロックは popen3() を使って標準出力や標準エラー出力を読み込むときにも起こりえます。これらのどちらかが内部バッファにとって大きすぎる (バッファサイズを増やしても役に立ちません) とき、もう片方を先に read() すると、同じくデッドロックが起こります。

popen2 におけるバグの注釈: プログラムが wait() や waitpid() を呼び出さないかぎり、終了されていない子プロセスは取り除かれることがなく、いずれ popen2 を呼び出すときに、子プロセス数の制限のために失敗することがあります。os.waitpid() を os.WNOHANG オプションをつけて呼び出すことで、これを防げます。このような呼び出しをする場所は、 popen2 を再び呼びだす前がいいです。

多くの場合、本当にやるべきことは、コマンドを通して少しのデータを実行し、結果を戻させることだけです。データの量がとても多いのでない限り、最も簡単な方法は、それを一時ファイルに書きこみ、一時ファイルと入力としてコマンドを実行することです。標準モジュール tempfile は、一意の一時ファイル名を生成する mktemp() 関数をエクスポートします:

import tempfile
import os

class Popen3:
    """
    This is a deadlock-safe version of popen that returns
    an object with errorlevel, out (a string) and err (a string).
    (capturestderr may not work under windows.)
    Example: print Popen3('grep spam','\n\nhere spam\n\n').out
    """
    def __init__(self,command,input=None,capturestderr=None):
        outfile=tempfile.mktemp()
        command="( %s ) > %s" % (command,outfile)
        if input:
            infile=tempfile.mktemp()
            open(infile,"w").write(input)
            command=command+" <"+infile
        if capturestderr:
            errfile=tempfile.mktemp()
            command=command+" 2>"+errfile
        self.errorlevel=os.system(command) >> 8
        self.out=open(outfile,"r").read()
        os.remove(outfile)
        if input:
            os.remove(infile)
        if capturestderr:
            self.err=open(errfile,"r").read()
            os.remove(errfile)

なお、多くの対話的プログラム (vi など) は、パイプで標準入出力を置き換えることがうまくいきません。このようなときは、パイプの代わりに擬似 tty (“pty”) を使わなければなりません。または、Don Libes の “expect” ライブラリへの Python インタフェースを使うこともできます。expect へのインタフェースをする Python 拡張は “expy” と呼ばれ、 http://expectpy.sourceforge.net から利用できます。expect のように働く pure Python な解決法は、 pexpect [http://pypi.python.org/pypi/pexpect/] です。

シリアル (RS232) ポートにアクセスするにはどうしますか？

Win32、POSIX (Linux、BSD、など)、Jythonでは:

http://pyserial.sourceforge.net

Unix では、Mitch Chapman による Usenet の投稿を参照してください。

http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com

sys.stdout (stdin, stderr) を閉じようとしても実際に閉じられないのはなぜですか？

Python のファイルオブジェクトは、 (ここで説明する中では) 低レベルな C ファイルディスクリプタの上にある、中レベルな抽象のレイヤである C ストリームのそのまた上にある、高レベルな抽象のレイヤです。

組み込みの open 関数によって生成されたほとんどのファイルオブジェクトでは、f.close() は Python ファイルオブジェクトが Python の視点からは閉じられているものとする印をつけ、その下にある C ファイルディスクリプタを閉じるように手配します。これは、f がガベージとなったときにも、f のデストラクタで自動的に起こります。

しかし、stdin、stdout、stderr は C で特別な立場が与えられていることから、 Python でも同様に特別に扱われます。sys.stdout.close() を実行すると、 Python レベルのファイルオブジェクトには閉じられているものとする印がつけられますが、C ファイルディスクリプタは 閉じられません。

下にある C ファイルディスクリプタのうち、この三つのどれかを閉じるには、まず本当に閉じる必要があることを確かめるべきです (例えば、拡張モジュールの I/O を混乱させてしまうかもしれません)。本当に必要ならば、 os.close を使ってください:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream

ネットワーク/インターネットプログラミング

Python の WWW ツールには何がありますか？

ライブラリリファレンスマニュアルの インターネットプロトコルとその支援 と インターネット上のデータの操作 という章を参照してください。

http://wiki.python.org/moin/WebProgramming で利用可能なフレームワークの概要が Paul Boddie によって整備されています。

Cameron Laird は、http://phaseit.net/claird/comp.lang.python/web_python で Python のウェブ技術に関する便利なページ群を整備しています。

CGI フォームの発信 (METHOD=POST) を模倣するにはどうしますか？

フォームを POST した結果のウェブページを取得したいです。簡単に取得するためのコードはあるでしょうか？

あります。これは urllib.request を利用した簡単な例です:

#!/usr/local/bin/python

import httplib, sys, time

### build the query string
qs = "First=Josephine&MI=Q&Last=Public"

### connect and send the server a path
httpobj = httplib.HTTP('www.some-server.out-there', 80)
httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
### now generate the rest of the HTTP headers...
httpobj.putheader('Accept', '*/*')
httpobj.putheader('Connection', 'Keep-Alive')
httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
httpobj.putheader('Content-length', '%d' % len(qs))
httpobj.endheaders()
httpobj.send(qs)
### find out what the server said in response...
reply, msg, hdrs = httpobj.getreply()
if reply != 200:
    sys.stdout.write(httpobj.getfile().read())

なお、一般にパーセントエンコードされた POST 演算では、クエリ文字列は必ず urllib.parse.urlencode() で引用されなくてはなりません。例えば name=”Guy Steele, Jr.” を送信するには:

>>> import urllib.parse
>>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
'name=Guy+Steele%2C+Jr.'
>>> from urllib import quote
>>> x = quote("Guy Steele, Jr.")
>>> x
'Guy%20Steele,%20Jr.'
>>> query_string = "name="+x
>>> query_string
'name=Guy%20Steele,%20Jr.'

どのモジュールが HTML の生成の役に立ちますか？

さまざまなモジュールが利用できます:

HTMLgen は全ての HTML 3.2 マークアップタグに対応するオブジェクトのクラスライブラリです。Python を書いていて、HTML ページを統合して web や CGI フォームを生成したい時などに使えます。

DocumentTemplate および Zope Page Templates は、それぞれ Zope の一部であるシステムです。

Quixote’s PTL は Python の構文を使って文字列やテキストを組み立てます。

その他のリンクは、Web Programming wiki pages [http://wiki.python.org/moin/WebProgramming] を参照してください。

Python のスクリプトからメールを送るにはどうしますか？

標準ライブラリモジュール smtplib を使ってください。

以下に示すのが、これを使ったごく単純な対話型のメール送信器です。このメソッドは SMTP リスナをサポートするホストならどこででも作動します:

import sys, smtplib

fromaddr = raw_input("From: ")
toaddrs  = raw_input("To: ").split(',')
print("Enter message, end with ^D:")
msg = ''
while True:
    line = sys.stdin.readline()
    if not line:
        break
    msg += line

# The actual mail send
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

Unix のみ、sendmail を使う方法もあります。sendmail プログラムのロケーションは、システムによって変わります。/usr/lib/sendmail のときもあれば、 /usr/sbin/sendmail のときもあります。sendmail のマニュアルページを見れば解ります。これはサンプルコードです:

SENDMAIL = "/usr/sbin/sendmail" # sendmail location
import os
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
p.write("\n") # blank line separating headers from body
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
    print "Sendmail exit status", sts

ソケットの connect() メソッドでブロッキングされなくするにはどうしますか？

主に select モジュールがソケットの非同期の I/O を扱うのに使われます。

TCP 接続がブロッキングされないようにするために、ソケットをノンブロッキングモードに設定することが出来ます。そして connect() したときに、即座に接続できるか、エラー番号を .errno として含む例外を受け取るかのどちらかになります。errno.EINPROGRESS は、接続が進行中であるが、まだ完了していないということを示します。異なる OS では異なる値が返されるので、あなたのシステムで何が返されるかを確かめておく必要があります。

connect_ex() メソッドを使えば例外を生成しなくて済みます。これは単に errno の値を返すでしょう。ポーリングのためには、後でまた connect_ex() を呼び出すことができます – 0 または errno.EISCONN は接続されたことを表します – または、選択するソケットにこれを渡して書き込み可能か調べることができます。

データベース

Python にはデータベースパッケージへのインタフェースはありますか？

はい。

DBM や GDBM のような、ディスクに基づくハッシュへのインタフェースも標準の Python に含まれています。ディスクに基づく軽量なリレーショナルデータベースを提供する sqlite3 モジュールもあります。

ほとんどの相対データベースがサポートされています。詳細は DatabaseProgramming wiki page [http://wiki.python.org/moin/DatabaseProgramming] を参照してください。

Python で永続的なオブジェクトを実装するにはどうしますか？

pickle ライブラリモジュールで、ごく一般的な方法でこれを解決できます (開かれたファイル、ソケット、ウィンドウのようなものを保管することはできませんが)。shelve ライブラリモジュールは pickle と (g)dbm を使い、任意の Python オブジェクトを含む永続的なマッピングを生成します。パフォーマンスを良くするために、cPickle モジュールを使うこともできます。

もっと不器用な方法は、pickle の妹分である marshal を使うことです。 marshal モジュールは、再帰的でない標準の Python 型を、ファイルや文字列にとても高速に保存したり、元に戻したりする方法を提供します。 marshal では、インスタンスの保存や共有される参照の適切な処理などの派手なことはできませんが、極端に速く動作します。例えば、半メガバイトのデータに 3 分の 1 秒も掛からないでしょう。これは多くの場合、 pickle/shelve で gdbm を使うというような、複雑な一般の方法に勝ります。

なぜ cPickle はこんなに遅いのですか？

pickle モジュールに使われているデフォルトのフォーマットは、読み込み可能な pickle のための遅いものです。後方互換性は壊されますが、これを使ってください:

largeString = 'z' * (100 * 1024)
myPickle = cPickle.dumps(largeString, protocol=1)

bsddb (or anydbm) データベースが開かれたままプログラムがクラッシュすると、だめになってしまいます。なぜですか？

bsddb モジュール (やしばしば anydbm モジュール。優先的に bsddb を使うでしょうから) で書き込みのために開かれたデータベースは、データベースの .close() メソッドで明示的に閉じられなければなりません。その基礎にあるライブラリは、ディスク上の形式に変換されて書き込まれるべきデータベースの中身を、キャッシュします。

新しい bsddb データベースを初期化したけれどプログラムのクラッシュ時までに何も書き込まれていないとき、長さ 0 のファイルで終わることになり、次にそのファイルが開かれたときに例外に出くわすでしょう。

Berkeley DB ファイルを開こうとしましたが、bsddb が bsddb.error: (22, ‘Invalid argument’) を生じます。助けてください！ データを復元するにはどうしたら良いですか？

慌てないでください！ あなたのデータはおそらく無事です。このエラーの一番ありがちな原因は、新しいバージョンの Berkeley DB ライブラリから古い Berkeley DB ファイルを開こうとすることです。

多くの Linux システムで、今では 3 種類全てのバージョンの Berkeley DB が利用できます。バージョン 1 から新しいバージョンに移行するには、 db_dump185 でデータベースのプレーンテキスト版をダンプしてください。バージョン 2 からバージョン 3 に移行するには、db_2dump でデータベースのプレーンテキスト版を生成してください。そのどちらの場合でも、db_load でコンピュータにインストールされている最新バージョンの新しいネイティブデータベースを生成してください。バージョン 3 の Berkeley DB がインストールされているなら、db2_load でネイティブのバージョン 2 のデータベースを生成できるでしょう。

Berkeley DB バージョン 1 のハッシュファイルコードにはデータを破壊する既知のバグがありますから、使うのをやめるべきです。

数学と数

Python でランダムな数を生成するにはどうしますか？

標準モジュールの random がランダムな数の生成器を実装しています。使い方は単純です:

import random
random.random()

これは区間 [0, 1) 内のランダムな浮動小数点数を返します。

このモジュールにはその他多くの特化した生成器もあります。例えば:

randrange(a, b) は区間 [a, b) から整数を選びます。

uniform(a, b) は区間 [a, b) から浮動小数点数を選びます。

normalvariate(mean, sdev) は正規(ガウス)分布をサンプリングします。

シーケンスに直接作用する高水準な関数もあります。例えば:

choice(S) は与えられたシーケンスからランダムな要素を選びます。

shuffle(L) はリストをインプレースにシャッフルします。すなわち、ランダムに並び替えます。

Random クラスのインスタンスを生成して、複数の独立なランダムな数の生成器をつくることもできます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

拡張と埋め込み FAQ

Contents

拡張と埋め込み FAQ

C で独自の関数を作ることはできますか？

C++ で独自の関数を作ることはできますか？

C を書くのは大変です。他の方法はありませんか？

C から任意の Python 文を実行するにはどうしますか？

C から任意の Python 式を評価するにはどうしますか？

Python オブジェクトから C の値を展開するにはどうしますか？

Py_BuildValue() で任意長のタプルを作るにはどうしますか？

C からオブジェクトのメソッドを呼び出すにはどうしますか？

PyErr_Print() (その他 stdout/stderr に印字するもの) からの出力を受け取るにはどうしますか？

C から Python で書かれたモジュールにアクセスするにはどうしますか？

Python から C++ へインタフェースするにはどうしますか？

セットアップファイルでモジュールを追加しようとしたらメイクに失敗しました。なぜですか？

拡張をデバッグするにはどうしますか？

Linux システムで Python モジュールをコンパイルしたいのですが、見つからないファイルがあります。なぜですか？

“SystemError: _PyImport_FixupExtension: module yourmodule not loaded” とはどういう意味ですか？

“不完全 (incomplete) な入力” を “不適切 (invalid) な入力” から区別するにはどうしますか？

未定義の g++ シンボル __builtin_new や __pure_virtual を見つけるにはどうしますか？

メソッドのいくつかは C で、その他は Python で実装されたオブジェクトクラスを (継承などで) 作ることはできますか？

モジュール X をインポートした時に “undefined symbol: PyUnicodeUCS2*” と言われるのはなぜですか？

C で独自の関数を作ることはできますか？

はい。関数、変数、例外、そして新しいタイプまで含んだビルトインモジュールを C で作れます。これはドキュメント Python インタプリタの拡張と埋め込み で説明されています。

ほとんどの中級から上級の Python 本もこの話題を扱っています。

C++ で独自の関数を作ることはできますか？

はい。C++ 内にある C 互換機能を使ってできます。extern "C" { ... } で Python のインクルードファイルを囲み、extern "C" を Python インタプリタから呼ぶ各関数の前に置いてください。グローバルや静的な C++ オブジェクトの構造体を持つものは良くないでしょう。

C を書くのは大変です。他の方法はありませんか？

独自の C 拡張を書くための別のやり方は、目的によっていくつかあります。

速度が必要なら、Psyco [http://psyco.sourceforge.net/] は Python バイトコードから x86 アセンブリコードを生成します。 Psyco でコードの最も時間制約が厳しい関数群をコンパイルすれば、 x-86 互換のプロセッサ上で動かす限り、わずかな手間で著しい改善ができます。

Pyrex [http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/] は、わずかに変形した Python を受け取り、対応する C コードを生成します。 Cython や Pyrex を使えば Python の C API を習得することなく拡張を書けます。

今のところ Python 拡張が存在しないような C や C++ ライブラリへのインタフェースが必要なら、SWIG [http://www.swig.org] のようなツールで、そのライブラリのデータ型のラッピングを図れます。 SIP [http://www.riverbankcomputing.co.uk/software/sip/]、 CXX [http://cxx.sourceforge.net/]、 Boost [http://www.boost.org/libs/python/doc/index.html]、 Weave [http://www.scipy.org/Weave] でも C++ ライブラリをラッピングできます。

C から任意の Python 文を実行するにはどうしますか？

これを行う最高水準の関数は PyRun_SimpleString() で、一つの文字列引数を取り、モジュール __main__ のコンテキストでそれを実行し、成功なら 0、例外 (SyntaxError を含む) が発生したら -1 を返します。更に制御したければ、PyRun_String() を使ってください。ソースは Python/pythonrun.c の ‘PyRun_SimpleString() を参照してください。

C から任意の Python 式を評価するにはどうしますか？

先の質問の PyRun_String() を、スタートシンボル Py_eval_input を渡して呼び出してください。これは式を解析し、評価してその値を返します。

Python オブジェクトから C の値を展開するにはどうしますか？

オブジェクトの型に依ります。タプルなら、PyTuple_Size() が長さを返し、 PyTuple_GetItem() が指定されたインデックスの要素を返します。リストにも同様の関数 PyList_Size() と PyList_GetItem() があります。

文字列なら、PyString_Size() が長さを、 PyString_AsString() がその値へのポインタを返します。なお、Python の文字列には null バイトが含まれている可能性があるので、C の strlen() は使うべきではありません。

オブジェクトの型を確かめるには、まず NULL ではないことを確かめてから、 PyString_Check()、PyTuple_Check()、PyList_Check() などを使ってください。

Python オブジェクトへの高レベルな API には、いわゆる ‘abstract’ インタフェースが提供するものもあります。機能の詳細は Include/abstract.h を読んでください。これで、 PySequence_Length() や PySequence_GetItem() などの呼び出しであらゆるタイプの Python シーケンスのインタフェースができますし、その他多くの役立つプロトコルもできます。

Py_BuildValue() で任意長のタプルを作るにはどうしますか？

できません。代わりに t = PyTuple_New(n) を使い、 PyTuple_SetItem(t, i, o) でオブジェクトを埋めてください – なお、これは o のリファレンスカウントを”食う”ので、 Py_INCREF() しなければなりません。リストにも同様の関数 PyList_New(n) と PyList_SetItem(l, i, o) があります。なお、タプルは Python コードに渡される前に 必ず すべての値が設定されていなければなリません – PyTuple_New(n) は各要素を初期化して NULL にしますが、これは Python の適切な値ではありません。

C からオブジェクトのメソッドを呼び出すにはどうしますか？

PyObject_CallMethod() 関数でオブジェクトの任意のメソッドを呼び出せます。パラメタは、オブジェクト、呼び出すメソッドの名前、 Py_BuildValue() で使われるようなフォーマット文字列、そして引数です:

PyObject *
PyObject_CallMethod(PyObject *object, char *method_name,
                    char *arg_format, ...);

これはメソッドを持ついかなるオブジェクトにも有効で、組み込みかユーザ定義かは関係ありません。返り値に対して Py_DECREF() する必要があることもあります。

例えば、あるファイルオブジェクトの “seek” メソッドを 10, 0 を引数として呼ぶとき (ファイルオブジェクトのポインタを “f” とします):

res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0);
if (res == NULL) {
        ... an exception occurred ...
}
else {
        Py_DECREF(res);
}

なお、PyObject_CallObject() の引数リストには 常に タプルが必要です。関数を引数なしで呼び出すには、フォーマットに “()” を渡し、関数を一つの引数で呼び出すには、関数を括弧でくくって例えば “(i)” としてください。

PyErr_Print() (その他 stdout/stderr に印字するもの) からの出力を受け取るにはどうしますか？

Python コード内で、write() メソッドをサポートするオブジェクトを定義してください。そのオブジェクトを sys.stdout と sys.stderr に代入してください。print_error を呼び出すか、単に標準のトレースバック機構を作動させてください。そうすれば、出力は write() が送る任意の所に行きます。

最も簡単な方法は、標準ライブラリの StringIO クラスを使うことです。

サンプルコードと出力の受け取り例:

>>> class StdoutCatcher:
...     def __init__(self):
...         self.data = ''
...     def write(self, stuff):
...         self.data = self.data + stuff
...
>>> import sys
>>> sys.stdout = StdoutCatcher()
>>> print 'foo'
>>> print 'hello world!'
>>> sys.stderr.write(sys.stdout.data)
foo
hello world!

C から Python で書かれたモジュールにアクセスするにはどうしますか？

以下のようにモジュールオブジェクトへのポインタを得られます:

module = PyImport_ImportModule("<modulename>");

そのモジュールがまだインポートされていない (つまり、まだ sys.modules に現れていない) なら、これはモジュールを初期化します。そうでなければ、単純に sys.modules["<modulename>"] の値を返します。なお、これはモジュールをいかなる名前空間にも代入しません。これはモジュールが初期化されて ‘sys.modules に保管されていることを保証するだけです。

これで、モジュールの属性 (つまり、モジュールで定義された任意の名前) に以下のようにアクセスできるようになります:

attr = PyObject_GetAttrString(module, "<attrname>");

PyObject_SetAttrString() を呼んでモジュールの変数に代入することもできます。

Python から C++ へインタフェースするにはどうしますか？

やりたいことに応じて、いろいろな方法があります。手動でやるなら、 “拡張と埋め込み” ドキュメント を読むことから始めてください。なお、Python ランタイムシステムにとっては、 C と C++ はあまり変わりません。だから、C 構造体 (ポインタ )型に基づいて新しい Python の型を構築する方針は C++ オブジェクトに対しても有効です。

C++ ライブラリに関しては、C を書くのは大変です。他の方法はありませんか？ を参照してください。

セットアップファイルでモジュールを追加しようとしたらメイクに失敗しました。なぜですか？

セットアップは改行で終わらなければならなくて、改行がないと、ビルド工程は失敗します。(これを直すには、ある種の醜いシェルスクリプトハックが必要ですが、このバグは小さいものですから努力に見合う価値はないでしょう。)

拡張をデバッグするにはどうしますか？

動的にロードされた拡張に GDB を使うとき、拡張がロードされるまでブレークポイントを設定してはいけません。

.gdbinit ファイルに(または対話的に)、このコマンドを加えてください:

br _PyImport_LoadDynamicModule

そして、GDB を起動するときに:

$ gdb /local/bin/python
gdb) run myscript.py
gdb) continue # repeat until your extension is loaded
gdb) finish   # so that your extension is loaded
gdb) br myfunction.c:50
gdb) continue

Linux システムで Python モジュールをコンパイルしたいのですが、見つからないファイルがあります。なぜですか？

Python の多くのパッケージバージョンには、Python 拡張をコンパイルするのに必要な様々なファイルを含む /usr/lib/python2.x/config/ ディレクトリが含まれていません。

Red Hat では、Python RPM をインストールして必要なファイルを得てください。

Debian では、apt-get install python-dev を実行してください。

“SystemError: _PyImport_FixupExtension: module yourmodule not loaded” とはどういう意味ですか？

これは、”yourmodule” という名前の拡張モジュールが生成されたけれど、モジュールの init 関数がその名前で初期化しないという意味です。

全てのモジュールの init 関数には次のような行があるでしょう:

module = Py_InitModule("yourmodule", yourmodule_functions);

この関数に渡された文字列が拡張モジュールと同じ名前でない場合、 SystemError 例外が発生します。

“不完全 (incomplete) な入力” を “不適切 (invalid) な入力” から区別するにはどうしますか？

Python インタラクティブインタプリタでは、入力が不完全なとき (例えば、 “if” 文の始まりをタイプした時や、カッコや三重文字列引用符を閉じていない時など) には継続プロンプトを与えられますが、入力が不適切であるときには即座に構文エラーメッセージが与えられます。このようなふるまいを模倣したいことがあります。

Python では構文解析器のふるまいに十分に近い codeop モジュールが使えます。例えば IDLE がこれを使っています。

これを C で行う最も簡単な方法は、PyRun_InteractiveLoop() を (必要ならば別のスレッドで) 呼び出し、Python インタプリタにあなたの入力を扱わせることです。独自の入力関数を指定するのに PyOS_ReadlineFunctionPointer() を設定することもできます。詳しいヒントは、Modules/readline.c や Parser/myreadline.c を参照してください。

しかし、組み込みの Python インタプリタを他のアプリケーションと同じスレッドで実行することが必要で、PyRun_InteractiveLoop() でユーザの入力を待っている間止められないこともあります。このような場合の解決策の一つは、PyParser_ParseString() を呼んで e.error と E_EOF が等しいこと、つまり入力が不完全であることを確かめることです。これは、Alex Farber のコードを参考にした、コード片の例です:

#include <Python.h>
#include <node.h>
#include <errcode.h>
#include <grammar.h>
#include <parsetok.h>
#include <compile.h>

int testcomplete(char *code)
  /* code should end in \n */
  /* return -1 for error, 0 for incomplete, 1 for complete */
{
  node *n;
  perrdetail e;

  n = PyParser_ParseString(code, &_PyParser_Grammar,
                           Py_file_input, &e);
  if (n == NULL) {
    if (e.error == E_EOF)
      return 0;
    return -1;
  }

  PyNode_Free(n);
  return 1;
}

別の解決策は、受け取られた文字列を Py_CompileString() でコンパイルすることを試みることです。エラー無くコンパイルされたら、返されたコードオブジェクトを PyEval_EvalCode() を呼んで実行することを試みてください。そうでなければ、入力を後のために保存してください。コンパイルが失敗したなら、それがエラーなのか入力の続きが求められているだけなのか調べてください。そのためには、例外タプルからメッセージ文字列を展開し、それを文字列 “unexpected EOF while parsing” と比較します。ここに GNU readline library を使った完全な例があります (readline() を読んでいる間は SIGINT を無視したいかもしれません):

#include <stdio.h>
#include <readline.h>

#include <Python.h>
#include <object.h>
#include <compile.h>
#include <eval.h>

int main (int argc, char* argv[])
{
  int i, j, done = 0;                          /* lengths of line, code */
  char ps1[] = ">>> ";
  char ps2[] = "... ";
  char *prompt = ps1;
  char *msg, *line, *code = NULL;
  PyObject *src, *glb, *loc;
  PyObject *exc, *val, *trb, *obj, *dum;

  Py_Initialize ();
  loc = PyDict_New ();
  glb = PyDict_New ();
  PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());

  while (!done)
  {
    line = readline (prompt);

    if (NULL == line)                          /* CTRL-D pressed */
    {
      done = 1;
    }
    else
    {
      i = strlen (line);

      if (i > 0)
        add_history (line);                    /* save non-empty lines */

      if (NULL == code)                        /* nothing in code yet */
        j = 0;
      else
        j = strlen (code);

      code = realloc (code, i + j + 2);
      if (NULL == code)                        /* out of memory */
        exit (1);

      if (0 == j)                              /* code was empty, so */
        code[0] = '\0';                        /* keep strncat happy */

      strncat (code, line, i);                 /* append line to code */
      code[i + j] = '\n';                      /* append '\n' to code */
      code[i + j + 1] = '\0';

      src = Py_CompileString (code, "<stdin>", Py_single_input);

      if (NULL != src)                         /* compiled just fine - */
      {
        if (ps1  == prompt ||                  /* ">>> " or */
            '\n' == code[i + j - 1])           /* "... " and double '\n' */
        {                                               /* so execute it */
          dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
          Py_XDECREF (dum);
          Py_XDECREF (src);
          free (code);
          code = NULL;
          if (PyErr_Occurred ())
            PyErr_Print ();
          prompt = ps1;
        }
      }                                        /* syntax error or E_EOF? */
      else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
      {
        PyErr_Fetch (&exc, &val, &trb);        /* clears exception! */

        if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
            !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
        {
          Py_XDECREF (exc);
          Py_XDECREF (val);
          Py_XDECREF (trb);
          prompt = ps2;
        }
        else                                   /* some other syntax error */
        {
          PyErr_Restore (exc, val, trb);
          PyErr_Print ();
          free (code);
          code = NULL;
          prompt = ps1;
        }
      }
      else                                     /* some non-syntax error */
      {
        PyErr_Print ();
        free (code);
        code = NULL;
        prompt = ps1;
      }

      free (line);
    }
  }

  Py_XDECREF(glb);
  Py_XDECREF(loc);
  Py_Finalize();
  exit(0);
}

未定義の g++ シンボル __builtin_new や __pure_virtual を見つけるにはどうしますか？

g++ モジュールを動的にロードするには、Python を再コンパイルし、それを g++ で再リンク (Python Modules Makefile 内の LINKCC を変更) し、拡張を g++ でリンク (例えば g++ -shared -o mymodule.so mymodule.o) しなければなりません。

メソッドのいくつかは C で、その他は Python で実装されたオブジェクトクラスを (継承などで) 作ることはできますか？

Python 2.2 では、int、list、dict などのビルトインクラスから継承できます。

The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) を使えば、これを C++ からできます。 (すなわち、BPL を使って C++ で書かれた拡張クラスを継承できます).

モジュール X をインポートした時に “undefined symbol: PyUnicodeUCS2*” と言われるのはなぜですか？

あなたは Unicode 文字に 4 バイト表現を使う Python のバージョンを使っていますが、インポートされた C 拡張モジュールに Unicode 文字に (デフォルトの) 2 バイト表現を使う Python でコンパイルされたものがあります。

未定義のシンボルの名前が PyUnicodeUCS4 で始まるのなら、逆の問題です: Python は 2 バイト Unicode 文字でビルトされていて、拡張モジュールは 4 バイト Unicode 文字の Python でコンパイルされています。

これはあらかじめビルドされた拡張パッケージを使っているときに起こりやすいです。とりわけ、RedHat Linux 7.x は 4 バイトユニコードでコンパイルされた “python2” バイナリを提供しました。これは拡張が PyUnicode_*() 関数のどれかを使っているとリンクの失敗を起こすだけです。拡張が Unicode に関連する Py_BuildValue() (等)へのフォーマット指定や PyArg_ParseTuple() へのパラメタ指定を何かしら含んでいても問題になります。

Python インタプリタが使っている Unicode 文字のサイズは、 sys.maxunicode の値を調べることで確かめられます:

>>> import sys
>>> if sys.maxunicode > 65535:
...     print 'UCS4 build'
... else:
...     print 'UCS2 build'

この問題を解決する唯一の方法は、Unicode 文字に同じサイズを使ってビルドされた Python バイナリでコンパイルされた拡張モジュールを使うことです。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

Windows 上の Python FAQ

Contents

Windows 上の Python FAQ

Python プログラムを Windows で動かすにはどうしますか？

Python スクリプトを実行可能にするにはどうしますか？

Python の起動に時間がかかることがあるのはなぜですか？

Windows 用の Freeze はどこにありますか？

*.pyd ファイルは DLL と同じですか？

Python を Windows アプリケーションに埋め込むにはどうしたらいいですか？

Python を CGI に使うにはどうしますか？

エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか？

ブロックすることなく押鍵を検出するにはどうしますか？

os.kill() を Windows で模倣するにはどうしますか？

os.path.isdir() が NT で共有されたディレクトリで失敗するのはなぜですか？

cgi.py (その他の CGI プログラミング) が NT や win95 で動かないことがあります！

os.popen() が NT 上の PythonWin で動かないのはなぜですか？

os.popen()/win32pipe.popen() が Win9x で動かないのはなぜですか？

PyRun_SimpleFile() は Windows 上ではクラッシュしますが、Unix 上ではしません。なぜですか？

Windows 95/98 上で _tkinter のインポートに失敗します。なぜですか？

ダウンロードされたドキュメントを Windows 上で展開するにはどうしますか？

cw3215mt.dll がありません(または cw3215.dll がありません)

インストーラからのCTL3D32 version に関する警告

Python プログラムを Windows で動かすにはどうしますか？

これは単純な問題ではないかもしれません。あなたがすでに Windows コマンドラインからプログラムを作動させることに慣れているなら、すぐに全て分かりますが、そうでなければ少し案内が必要です。Windows 95、98、NT、 ME、2000、XP の間にも差があり、混乱のもとになっています。

Python Development on XP [http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries]

Python Development on XP [http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries]

このスクリーンキャストのシリーズは、あなたが Windows XP で Python を扱えるようにすることを目標としています。知識は 90 分に凝縮され、あなたが正しい Python ディストリビューションを、あなたが選んだ IDE でコーディングし、ユニットテストでデバッグをして堅実なコードを書いていけるようにします。

あなたがある種の統合開発環境を使っているのでない限り、結局は Windows コマンドを “DOS ウィンドウ” や “コマンドプロンプトウィンドウ” と様々に呼ばれるものにタイプする ことになります。通常、このようなウィンドウはスタートメニューから出すことができます。Windows 2000 では選ぶメニューは Start ‣ Programs ‣ Accessories ‣ Command Prompt です。そのようなウィンドウが開いたことは、通常このような Windows “コマンドプロンプト” が見られることからわかるでしょう:

C:\>

この文字は異なっていたり、続きがあったりするので、コンピュータの設定や、あなたが最近何をしたかに依って、このようになっていることもあるでしょう:

D:\Steve\Projects\Python>

このようなウィンドウさえ開けば、Python プログラムを動かす手順は順調に進みます。

前提として、Python スクリプトは、Python インタプリタという別のプログラムによって加工されなければなりません。インタプリタはスクリプトを読み込み、バイトコードにコンパイルし、そのバイトコードを実行してプログラムを動かします。では、インタプリタに Python を扱わせるにはどうするのでしょうか？

最初に、コマンドウィンドウが “python” という文字列をインタプリタを開始するための導入として認識していることを確かめる必要があります。コマンドウィンドウが開いたなら、コマンド python を入力してリターンキーを打ってみましょう。するとこのようなものが現れます:

Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

インタプリタの”対話モード”が始まりました。これで Python の文や式を対話的に入力して、待っている間に実行や評価させることができます。これが Python の最強の機能のひとつです。いくつかの式を選んで入力し、結果を見て確かめてみましょう:

>>> print("Hello")
Hello
>>> "Hello" * 3
HelloHelloHello

多くの人が対話モードを便利で高度なプログラム可能計算機として使っています。対話式 Python セッションを終わらせたいなら、Ctrl キーを押しながら Z を入力し、 “Enter” キーを打って Windows コマンドプロンプトに戻ってください。

また、スタートメニューには Start ‣ Programs ‣ Python 2.2 ‣ Python (command line) という項目があり、そこから新しいウィンドウで >>> というプロンプトが現れます。その場合は、Ctrl-Z の文字を入力するとウィンドウは消えます。Windows はウィンドウで “python” コマンドだけを実行していて、そのウィンドウはインタプリタを終了すると閉じられるのです。

python コマンドで、インタプリタプロンプト >>> ではなく次のようなメッセージ:

'python' is not recognized as an internal or external command,
operable program or batch file.

Adding Python to DOS Path [http://showmedo.com/videos/video?name=960000&fromSeriesID=96]

Adding Python to DOS Path [http://showmedo.com/videos/video?name=960000&fromSeriesID=96]

Python はデフォルトでは DOS パスに加えられていません。このスクリーンキャストでは、すべてのユーザーがコマンドラインから Python を実行できるようにして、 システムパス に適切な entry を加えられるようにします。

や:

Bad command or filename

が現れたなら、コンピュータが Python インタプリタの場所を認識しているか確かめなければなりません。そのためには、Windows がプログラムを探すディレクトリのリストである PATH という設定を変更しなければなりません。

コマンドウィンドウが始まるごとに Python がインストールされたディレクトリが PATH 加えられるように設定するといいでしょう。あなたが Python をインストールしたのが結構最近なら、コマンド:

dir C:\py*

で、どこにインストールされているかわかるでしょう。通常の場所は C:\Python23 のようになっています。そうでなければ、ディスク全体を検索することになるでしょう ... Tools ‣ Find を使うか Search ボタンを押して “python.exe” を探してください。 Python が C:\Python23 ディレクトリ (執筆時点でのデフォルト) にインストールされていたとしたら、次のコマンドを入力すれば上と同じようなインタプリタが開始されることがわかるでしょう (もちろん、終了に “CTRL-Z” と “Enter” が必要です):

c:\Python23\python

一旦ディレクトリを変更したら、コンピュータが行うスタートアップルーチンに加える必要があります。古いバージョンの Windows では、一番簡単な方法は C:\AUTOEXEC.BAT ファイルを編集することです。AUTOEXEC.BAT に以下の行を追加しましょう:

PATH C:\Python23;%PATH%

Windows NT、2000、(おそらく) XP では、このような文字列:

;C:\Python23

を “マイコンピュータ” のプロパティウィンドウの “詳細” タブにある、 PATH 環境変数の現在の設定に加えましょう。なお、十分な権限があれば、現在のユーザに設定するかシステムに設定するかを選べます。すべてのユーザーが Python をコンピュータで実行したいのであれば後者を選ぶのがいいです。

この中に自信のない操作があれば、助けを求めてください！　ここでは、新しい設定が効いたことを絶対確実にするために、システムを再起動しましょう。 Windows NT、XP、2000 では、おそらく再起動の必要はないでしょう。それ以前のバージョンでも、AUTOEXEC.BAT の代わりに C:\WINDOWS\COMMAND\CMDINIT.BAT を編集すれば再起動しなくて済みます。

これで新しいコマンドウィンドウが開き、C:\> (等) のプロンプトに python を入力すれば、Python インタプリタが対話式コマンドを受け付けることを示す >>> が現れるでしょう。

それでは、pytest.py というプログラムが C:\Steve\Projects\Python ディレクトリにあったとしましょう。このプログラムを実行するためのセッションはこのようになるでしょう:

C:\> cd \Steve\Projects\Python
C:\Steve\Projects\Python> python pytest.py

インタプリタを開始するためのコマンドにファイル名を加えたので、インタプリタは開始時にその名前の Python スクリプトを読み込み、コンパイルし、実行し、終了し、それから再び C:\> プロンプトが現れます。カレントディレクトリを変更したくないなら、このように入力しても良いです:

C:\> python \Steve\Projects\Python\pytest.py

NT、2000、XP では、インストール過程ですでにコマンド pytest.py (または、カレントディレクトリになければ C:\Steve\Projects\Python\pytest.py) が ”.py” 拡張子を認識してその名前のファイルで Python を実行するように準備してあるかもしれません。この機能を使うと便利ですが、Windows の いくつかのバージョンでは、この形式がインタプリタを明示的に使うのと正確には同じにならないというバグがありますので、ご注意ください。

憶えておくべき重要なポイントは:

Python をスタートメニューから開始する、または PATH を正しく設定して Windows が Python インタプリタを見つけられるようにします:

python

で Python インタプリタから ‘>>>’ プロンプトが与えられます。もちろん、 CTRL-Z と ENTER でインタプリタが終了します(そして、スタートメニューからそのウィンドウを開始したのなら、そのウィンドウは消えます)。

それができたら、このコマンドでプログラムを実行してください:

python {program-file}

使うべきコマンドを知れば、特定の作業ディレクトリを指定して、どのスクリプト上でも Python インタプリタを実行する Windows ショートカットを構成できます。複雑なことがしたいなら:

python --help

を見てください。

対話モード (>>> プロンプトが現れるところ) は、単一の文や式が思ったとおりに動くか確かめたり、実験的にコードを開発するときに使うと最高です。

Python スクリプトを実行可能にするにはどうしますか？

Windows 2000 では、標準の Python インストーラはすでに .py 拡張子をあるファイル型 (Python.File) に関連付け、そのファイル型にインタプリタを実行するオープンコマンド (D:\Program Files\Python\python.exe "%1" %*) を与えます。コマンドプロンプトから ‘foo.py’ としてスクリプトを実行可能にするにはこれで十分です。スクリプトを拡張子なしで ‘foo’ とだけタイプして実行したいのなら、PATHEXT 環境変数に .py を加えてください。

Windows NT では、インストーラによって行われる上記のような段階により、スクリプトを ‘foo.py’ で実行できるようになりますが、長年のバグにより、 NT コマンドプロセッサで入力や出力のリダイレクトをすることは、この方法ではできません。これがしばしば重要になります。

Python スクリプトを WinNT で実行できるようにするおまじないは、ファイルに .cmd 拡張子をつけ、最初の行に以下の文を加えることです:

@setlocal enableextensions & python -x %~f0 %* & goto :EOF

Python の起動に時間がかかることがあるのはなぜですか？

通常 Python は Windows でとても早く起動しますが、ときどき Python が急にスタートアップに時間がかかるようになったというバグレポートがあります。更に複雑なことに、Python は同様に設定された他の Windows システムではきちんと動くのです。

この問題はそのマシンのウイルス対策ソフトウェアの設定ミスによって起こされることがあります。ウイルススキャナの中には、ファイルシステムからの全ての読み込みを監視するように設定した場合に、二桁のスタートアップオーバーヘッドを引き起すことが知られているものがあります。あなたのシステムのウイルススキャンソフトウェアの設定を確かめて、本当に同様に設定されていることを確実にしてください。

Windows 用の Freeze はどこにありますか？

“Freeze” は Python プログラムをひとつのスタンドアロンな実行可能なファイルにまとめて送れるようにするプログラムです。これはコンパイラ ではありません。プログラムの実行が速くなるわけでも、配布が簡単になるわけでもありません、少なくとも OS や CPU が同じならば。

Windows で freeze を使用できますが、ソースツリーをダウンロードする必要があります (http://www.python.org/download/source を参照してください)。 freeze プログラムはソースツリーの Tools\freeze サブディレクトリにあります。

Microsoft VC++ コンパイラが必要で、Python をビルドすることも必要になるでしょう。要求されるプロジェクトファイルは PCbuild ディレクトリにあります。

*.pyd ファイルは DLL と同じですか？

はい、.pyd ファイルは dll と同じようなものですが、少し違いがあります。 foo.pyd という名前の DLL があったとしたら、それには関数 initfoo() が含まれていなければなりません。そうすれば Python で “import foo” を書けて、 Python は foo.pyd (や foo.py、foo.pyc) を探して、あれば、initfoo() を呼び出して初期化しようとします。Windows が DLL の存在を必要とするのと違い、 .exe ファイルを foo.lib にリンクするわけではありません。

なお、foo.pyd を検索するパスは PYTHONPATH であり、Windows が foo.dll を検索するパスと同じではありません。また、プログラムを dll にリンクしたときはプログラムの実行に dll が必要ですが、foo.pyd は実行には必要はありません。もちろん、import foo したいなら foo.pyd は 必要です。DLL では、リンクはソースコード内で __declspec(dllexport) によって宣言されます。.pyd では、リンクは使える関数のリストで定義されます。

Python を Windows アプリケーションに埋め込むにはどうしたらいいですか？

Python インタプリタを Windows app に埋め込む方法は、次のように要約できます:

Python を .exe ファイルディレクトリに組み込 _まないでください_ 。Windows では、Python は (それ自体 DLL である) モジュールをインポートして扱う DLL でなくてはなりません (ドキュメント化されていない重大な事実の一つ目です)。組み込む代わりに、pythonNN.dll にリンクしてください。通常は C:\Windows\System にインストールされています。NN は Python のバージョンで、Python 2.3 なら “23” のようになります。

Python には、静的に、または動的にリンクできます。静的なリンクは、 pythonNN.lib に対してリンクするもので、動的なリンクは pythonNN.dll に対してリンクするものです。動的なリンクの欠点は、 pythonNN.dll がシステムに存在しないとアプリケーションが起動しないことです。(一般的な注意: pythonNN.lib は pythonNN.dll に対するいわゆる “インポートライブラリ” です。これは単にリンカに対するシンボルを定義します。)

動的なリンクは、リンクの選択を大いに単純化します。全ては実行時に行われます。コードは Windows の LoadLibraryEx() ルーチンで pythonNN.dll をロードしなければなりません。コードはまた、Windows の GetProcAddress() ルーチンで得られるポインタで、pythonNN.dll (すなわち、Python の C API)のルーチンとデータへアクセスしていなければなりません。マクロによって、このポインタを Python の C API のルーチンを呼び出す任意の C コードに通して使えます。

Borland note: まず pythonNN.lib を Coff2Omf.exe で OMF フォーマットに変換してください。

SWIG を使えば、app のデータとメソッドを Python で使えるようにする Python “拡張モジュール”を簡単に作れます。SWIG は雑用を殆どやってくれるでしょう。結果として、.exe ファイル の中に リンクする C コードができます(！)。 DLL を作 _らなくてもよく_ 、リンクも簡潔になります。

SWIG は拡張の名前に依る名前の init 関数 (C 関数) を作ります。例えば、モジュールの名前が leo なら、init 関数の名前は initleo() になります。 SWIG shadow クラスを使ったほうがよく、そうすると init 関数の名前は initleoc() になります。これは shadow クラスが使うほとんど隠れた helper クラスを初期化します。

ステップ 2 の C コードを .exe ファイルにリンクできるのは、初期化関数の呼び出しと Python へのモジュールのインポートが同等だからです！ (ドキュメント化されていない重大な事実の二つ目です)

要するに、以下のコードを使って Python インタプリタを拡張モジュール込みで初期化することができます。

#include "python.h"
...
Py_Initialize();  // Initialize Python.
initmyAppc();  // Initialize (import) the helper class.
PyRun_SimpleString("import myApp") ;  // Import the shadow class.

Python の C API には、pythonNN.dll をビルドするのに使われたコンパイラ MSVC 以外のコンパイラを使うと現れる二つの問題があります。

問題 1: コンパイラによって struct FILE に対する概念が異なるため、FILE * 引数を取るいわゆる “超高水準” 関数は、多コンパイラ環境で働きません。実装の観点から、これらは超 _低_ 水準関数になっています。

問題 2: SWIG は void 関数へのラッパを生成するときに以下のコードを生成します:

Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;

ああ、Py_none は pythonNN.dll 内の _Py_NoneStruct という複雑なデータ構造に展開するマクロです。また、このコードは他コンパイラ環境では失敗します。このコードを次のように置き換えてください:

return Py_BuildValue("");

これで、SWIG をまだ仕事に使えない (私は SWIG の完全な初心者です) 私でも、 SWIG の %typemap コマンドを使って自動的に変更できるようになります。

Python シェルスクリプトを使って Windows app 内から Python インタプリタウィンドウを掲示するのはいい方法ではありません。そのように表示されるウィンドウは app のウィンドウシステムとは関係ありません。むしろ “ネイティブな” インタプリタウィンドウを (wxPythonWindow を使ったりして) 作るべきです。そのウィンドウを Python インタプリタにつなぐのは簡単です。 Python の i/o は読み書きをサポートする _どんな_ オブジェクトにもリダイレクトできるので、read() と write() メソッドを含む (拡張モジュールで定義された) Python オブジェクトさえあればいいのです。

Python を CGI に使うにはどうしますか？

Microsoft IIS server と Win95 MS Personal Web Server では、 Python を他のどんなスクリプトエンジンとも同じように設定します。

regedt32 を起動し:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ScriptMap

に移動し、以下の行を入力してください。(システムによって変わることがあります):

.py :REG_SZ: c:\<path to python>\python.exe -u %s %s

この一行によって、スクリプトを http://yourserver/scripts/yourscript.py のように簡単な参照で呼び出せるようになります。ここで “scripts” は (通常はデフォルトの) “executable” ディレクトリです。-u フラグはバッファリングを無効にしたバイナリモードを stdin に使うことを指定するフラグで、バイナリデータを扱うときに必要です。

さらに、この状況で使われるファイル拡張子には ”.py” を使うのを避けることを勧めます (サポートモジュールに *.py を、”メインプログラム” スクリプトに *.cgi や *.cgp を残しておきたいでしょう)。

Python を CGI 加工に使うために Internet Information Services 5 を設定するには、以下のリンクを参照してください:

http://www.e-coli.net/pyiis_server.html (for Win2k Server) http://www.e-coli.net/pyiis.html (for Win2k pro)

Apache の設定はもっと単純です。Apache の設定ファイル httpd.conf で、ファイルの終わりに以下の行を加えてください:

ScriptInterpreterSource Registry

そして、Python CGI スクリプトに拡張子 .py をつけて、それらを cgi-bin ディレクトリに置いてください。

エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか？

この FAQ ではタブを使うことを勧めません。Python スタイルガイド PEP 8 [http://www.python.org/dev/peps/pep-0008] では、配布される Python コードにはスペース 4 つを使うことを推奨しています。これは Emacs の python-mode のデフォルトでも同じです。

いかなるエディタでも、タブとスペースを混ぜるのは良くないです。 MSVC も全く同じ立場であり、スペースを使うようにする設定が簡単にできます。 Tools ‣ Options ‣ Tabs を選択し、ファイルタイプの “デフォルト” の “タブ幅” と “インデント幅” に 4 を設定して、 “スペースを挿入する” のラジオボタンを選択してください。

タブとスペースが混ざっていることで先頭の空白に問題が出ている可能性があるなら、 Python を -t スイッチをつけて起動するか、 Tools/Scripts/tabnanny.py を起動してディレクトリツリーをバッチモードで確認してください。

ブロックすることなく押鍵を検出するにはどうしますか？

msvcrt モジュールを使ってください。これは標準の Windows 専用拡張モジュールです。これはキーボードが打たれているかを調べる関数 kbhit() と、反響することなく一文字を得る getch() を定義します。

os.kill() を Windows で模倣するにはどうしますか？

Python 2.7 および 3.2 以前では、プロセスを終了するために、ctypes が使えます:

import ctypes

def kill(pid):
    """kill function for Win32"""
    kernel32 = ctypes.windll.kernel32
    handle = kernel32.OpenProcess(1, 0, pid)
    return (0 != kernel32.TerminateProcess(handle, 0))

2.7 および 3.2 では、上の関数と同様な os.kill() が実装されていて、追加の機能として、CTRL+C や CTRL+BREAK をそれらのシグナルを扱うように設計されたコンソールのサブプロセスに送ることができます。

os.path.isdir() が NT で共有されたディレクトリで失敗するのはなぜですか？

共有されたドライブの最後にいつも “\” を加えることで、解決が見えます:

>>> import os
>>> os.path.isdir( '\\\\rorschach\\public')
0
>>> os.path.isdir( '\\\\rorschach\\public\\')
1

共有店をドライブ文字と同じようなものと考えるとわかりやすいです。例:

k: is not a directory
k:\ is a directory
k:\media is a directory
k:\media\ is not a directory

“k:” を “\conkyfoo” に置き換えても同じことが言えます:

\\conky\foo  is not a directory
\\conky\foo\ is a directory
\\conky\foo\media is a directory
\\conky\foo\media\ is not a directory

cgi.py (その他の CGI プログラミング) が NT や win95 で動かないことがあります！

最新の python.exe であること、Python の GUI バージョンではなく python.exe を使っていること、それからサーバが CGI 拡張に:

"...\python.exe -u ..."

を実行するように設定してあることを確認してください。-u (unbuffered) オプションは NT や Win95 でインタプリタが標準入出力で改行を変換することを防ぎます。これがないとリクエストの post/multipart は誤った長さを持つと見なされ、バイナリ (例えば GIF) の応答がでっち上げられる(そして壊れた画像、 PDF ファイル、その他のバイナリのダウンロード失敗につながる)でしょう。

os.popen() が NT 上の PythonWin で動かないのはなぜですか？

os.popen() が PythonWin の内部から動かないのは、Microsoft の C Runtime Library (CRT) のバグによるものです。CRT はプロセスに Win32 コンソールが結び付けられていると決めてかかります。

その代わりに、Win32 コンソールが結び付けられているかに依らない win32pipe モジュールの popen() を使うべきです。

例:

import win32pipe
f = win32pipe.popen('dir /c c:\\')
print(f.readlines())
f.close()

os.popen()/win32pipe.popen() が Win9x で動かないのはなぜですか？

Win9x にはバグがあって、os.popen/win32pipe.popen* が働きません。嬉しいことに、この問題に対処する方法があります。Microsoft Knowledge Base のこの記事を調べてください: Q150956。この knowledge base へのリンクはここで見つかります: http://support.microsoft.com/。

PyRun_SimpleFile() は Windows 上ではクラッシュしますが、Unix 上ではしません。なぜですか？

コンパイラのベンダ、バージョン、(もしかすると) オプションに関しても微妙です。埋め込みシステムの FILE* 構造体が Python インタプリタの想定と異なると、うまく行きません。

Python 1.5.* DLLs (python15.dll) は全て MS VC++ 5.0 にてマルチスレッディング DLL オプション (/MD) をつけてコンパイルされています。

コンパイラやフラグを変更できないなら、Py_RunSimpleString() を使ってみてください。これで任意のファイルを起動するための技は、exec() や open() をファイル名を引数として呼ぶことです。

また、Debug と Release 版は継ぎ合わせられません。Debug マルチスレッド DLL を使いたいなら、そのモジュールは _d がファイル名に加えられ ていなくてはなりません。

Windows 95/98 上で _tkinter のインポートに失敗します。なぜですか？

たまに、_tkinter のインポートが Windows 95 や 98 で失敗し、その時に以下のようなメッセージを訴えます:

ImportError: DLL load failed: One of the library files needed
to run this application cannot be found.

このとき Tcl/Tk がインストールされていないのかもしれませんが、Tcl/Tk がインストールされていて、Wish アプリケーションが正しく動いているなら、インストーラが autoexec.bat を適切に編集していないという問題かもしれません。インストーラは PATH 環境変数に Tcl/Tk ‘bin’ サブディレクトリを含めるように変える文を追加しようとしますが、この編集が機能していないことがあります。通常、このファイルをノートパッドで開くことで、問題が何か解ります。

(David Szafranski による追加のヒント: ここで長いファイル名を使ってはいけません。例えば、C:\Program Files\Tcl\bin の代わりに C:\PROGRA~1\Tcl\bin を使ってください。)

ダウンロードされたドキュメントを Windows 上で展開するにはどうしますか？

たまに、web ブラウザで Windows マシンにドキュメントパッケージをダウンロードするとき、その保存されたファイルの拡張子が .EXE になっていることがあります。これは間違いです。本来の拡張子は .TGZ です。

単純に、ダウンロードしたファイルを名付け直して拡張子を .TGZ にしてください。そうすれば WinZip で扱えます。(手元の WinZip でできなかったら、 http://www.winzip.com から新しいのをもらいましょう)

cw3215mt.dll がありません(または cw3215.dll がありません)

たまに、Tkinter を Windows で使っているとき、 cw3215mt.dll や cw3215.dll が見つからないというエラーが出ます。

原因: パス (おそらく C:\Windows) にある Tcl/Tk DLL が cygwin でビルドされた古いものです。標準の Tcl/Tk インストール (Python 1.5.2 に付属しています) による Tcl/Tk を使わなければなりません。

インストーラからのCTL3D32 version に関する警告

Python インストーラはこのような警告をします:

This version uses CTL3D32.DLL which is not the correct version.
This version is used for windows NT applications only.

Tim Peters いわく:

これは DLL の、そして悪名高きソースの問題です。このメッセージが伝えるものはこうです: この DLL のバージョンがオペレーティングシステムに合いません。 Python のインストールが原因ではありません - それ以前にインストールした何かが OS に付属していた DLL を上書きしたのです (おそらく何かの古いソフトでしょうが、もうそれは判断できません)。検索エンジン (例えば Altavista) で “CTL3D32” を探せば、あらゆる種類のインストールプログラムでの同様の問題を訴えるウェブページが何百も何百も現れるでしょう。それらのページにシステムにあった正しいバージョンをダウンロードする方法が指摘されていることでしょう (Python によって起こされたものではないので、我々には直しようがないのです)。

David A Burton はこれを直すための小さなプログラムを書きました。 http://www.burtonsys.com/downloads.html に行って “ctl3dfix.zip” をクリックしてください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

グラフィックユーザインタフェース FAQ

Contents

グラフィックユーザインタフェース FAQ

Python のプラットフォーム非依存の GUI ツールキットには何がありますか？

Tkinter

wxWidgets

Qt

Gtk+

FLTK

FOX

OpenGL

Python のプラットフォーム固有の GUI ツールキットには何がありますか？

Tkinter の質問

Tkinter アプリケーションを凍結するにはどうしますか？

I/O を待つ間に扱われる Tk イベントを作れますか？

Tkinter で働くキーバインディングが得られません。なぜですか？

Python のプラットフォーム非依存の GUI ツールキットには何がありますか？

目的のプラットフォーム (群) が何かによって、いくつかあります。この中にはまだ Python 3 に移植されていないものもあります。少なくとも Tkinter と Qt は Python 3 互換であることを確認しています。

Tkinter

Python の標準的なビルドには、tkinter という Tcl/Tk ウィジェットセットのオブジェクト指向インタフェースが含まれています。これは最も簡単にインストールして使えるでしょう。ソースへのポインタなど、 Tk に関する詳しい情報は、http://www.tcl.tk の Tcl/Tk ホームページを参照してください。Tcl/Tk は、MacOS、Windows、Unix プラットフォームに完全にポータブルです。

wxWidgets

wxWidgets (http://www.wxwidgets.org) は、C++ で書かれたフリーでポータブルな GUI クラスライブラリで、各プラットフォームのネイティブなルックアンドフィールを提供します。現在、Windows、MacOS X、GTK、X11 はすべて安定した対象です。言語バインディングは Python、Perl、Ruby などの言語で利用できます。

wxPython (http://www.wxpython.org) が wxWidgets の Python バインディングです。これはたいてい公式の wxWidgets より少し遅れますが、他の言語バインディングでは利用できない機能も pure Python 拡張経由でいくつか提供しています。 wxPython ユーザと開発者の活発なコミュニティがあります。

wxWidgets も wxPython も、フリーなオープンソースソフトウェアであり、寛大なライセンスでフリーウェアやシェアウェアと同様に商業利用も許可されています。

Qt

Qt ツールキットのバインディング (PyQt [http://www.riverbankcomputing.co.uk/software/pyqt/]) や KDE へのバインディング (PyKDE [http://www.riverbankcomputing.co.uk/software/pykde/intro]) があります。オープンソースソフトウェアを書くには、PyQt に支払いをする必要はありませんが、プロプライエタリなアプリケーションを書くためには Riverbank Computing [http://www.riverbankcomputing.co.uk/software/pyqt/license] から PyQt ライセンスを、(Qt 4.4 までは) Trolltech <http://www.trolltech.com> _ から Qt ライセンスを購入しなければなりません。 Qt 4.5 以降は LGPL ライセンスが適用されています。

Gtk+

Gtk+ toolkit [http://www.gtk.org] 用の PyGtk バインディングが James Henstridge によって実装されています。<http://www.pygtk.org> を参照してください。

FLTK

簡潔かつ強力で成熟したクロスプラットフォームウィンドウシステム the FLTK toolkit [http://www.fltk.org] の Python バインディングが the PyFLTK project [http://pyfltk.sourceforge.net/] から利用できます。

FOX

the FOX toolkit [http://www.fox-toolkit.org/] のラッパ FXpy [http://fxpy.sourceforge.net/] が利用できます。FOX は Unix バリアントと Windows の両方をサポートします。

OpenGL

OpenGL のバインディングは、PyOpenGL [http://pyopengl.sourceforge.net] を参照してください。

Python のプラットフォーム固有の GUI ツールキットには何がありますか？

Jack Jansen による The Mac port [http://python.org/download/mac] には、ネイティブ Mac ツールボックスコールをサポートする豊富で発展中のモジュール群があります。このポートは MacOS X の Carbon ライブラリをサポートしています。

PyObjc Objective-C bridge [http://pyobjc.sourceforge.net] をインストールすることによって、Python プログラマは MacOS X の Cocoa ライブラリを使うことができます。Mac port に付属するドキュメントを参照してください。

Mark Hammond による Pythonwin には Microsoft Foundation Class のインタフェースと Python プログラミング環境が含まれています。これは MFC クラスを用いて主に Python で書かれています。

Tkinter の質問

Tkinter アプリケーションを凍結するにはどうしますか？

Freeze はスタンドアロンアプリケーションを生成するツールです。 Tkinter アプリケーションを凍結するとき、それは Tcl と Tk ライブラリを必要とするので、真のスタンドアロンにはなりません。

一つの解決策は、アプリケーションに Tcl と Tk ライブラリを同梱し、環境変数 TCL_LIBRARY と TK_LIBRARY でランタイムに指定することです。

真にスタンドアロンなアプリケーションにするためには、ライブラリを成す Tcl スクリプトもアプリケーションに統合されていなければなりません。それをサポートするツールの一つは SAM (stand-alone modules) で、 Tix ディストリビューション (http://tix.sourceforge.net/) の一部です。

SAM を有効にするように Tix をビルドして、Python の Modules/tkappinit.c 内部の Tclsam_init() 等への適切なコールを実行し、libtclsam と libtksam にリンクしてください (Tix ライブラリを含んでも良いです)。

I/O を待つ間に扱われる Tk イベントを作れますか？

はい、スレッドさえ必要ありません！ ただし、I/O コードを少し再構成しなければなりません。Tk には Xt の XtAddInput() コールと同等なものがあるので、ファイルディスクリプタ上で I/O が可能なときに Tk メインループから呼ばれるコールバック関数を登録できます。このようにすればいいです:

from Tkinter import tkinter
tkinter.createfilehandler(file, mask, callback)

file には Python ファイルかソケットオブジェクト(実際には、fileno() メソッドを持った何か)、または整数のファイルディスクリプタを指定できます。 mask は定数 tkinter.READABLE または tkinter.WRITABLE のどちらかです。 callback は以下のように呼び出されます:

callback(file, mask)

callback が完了したら、次のように登録を解除しなければなりません:

tkinter.deletefilehandler(file)

ノート: 読み込みに使える バイト数 がわからないので、指定されたバイト数を読み込む Python のファイルオブジェクトの read や readline メソッドを使うことはできません。ソケットには、recv() や recvfrom() メソッドを使うといいです。その他のファイルには、os.read(file.fileno(), maxbytecount) を使ってください。

Tkinter で働くキーバインディングが得られません。なぜですか？

bind() メソッドでイベントに結び付けられたイベントハンドラが、適切なキーが押されたときにさえハンドルされないという苦情がよく聞かれます。

最も一般的な原因は、バインディングが適用されるウィジェットが “キーボードフォーカス” を持たないことです。Tk ドキュメントでフォーカスコマンドを確認してください。通常はウィジェットの中をクリックすることでキーボードフォーカスを与えられます (ただしラベルには与えられません。takefocus オプションを参照してください)。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

“なぜ Python が私のコンピュータにインストールされているのですか？” FAQ

Python とは何ですか？

Python はプログラミング言語の一つです。Python は様々なアプリケーションに使われています。Python は習得しやすいので、一部の高校や大学で入門用のプログラミング言語として使われています。一方で、Google、NASA、Lucasfilm Ltd. のような組織でプロフェッショナルなソフトウェア開発者にも使われています。

Python についてもっと詳しく知りたいなら、Beginner’s Guide to Python [http://wiki.python.org/moin/BeginnersGuide] から始めましょう。

なぜ Python が私のマシンにインストールされているのですか？

インストールした覚えがないのに Python があなたのシステムにインストールされているとしたら、その理由にはいくつかの可能性があります。

もしかしたら、コンピュータの他のユーザがプログラミングを学ぶためにインストールしたのかもしれません。誰がそのマシンを使っていて Python をインストールしたか知る必要があります。

マシンにインストールされているサードパーティのアプリケーションが、 Python で書かれていて Python のインストールを含んでいるかもしれません。家庭用のコンピュータでは、そのようなアプリケーションで一番有名なものは、 1000 種類以上のゲームやバリエーションを含むソリティアゲーム、PySol [http://pysolfc.sourceforge.net/] です。

Windows マシンにも Python がインストールされたものがあります。この執筆時点で Hewlett-Packard や Compaq が Python を組み込んでいることを確認しています。 HP/Compaq の管理ツールの中には、Python で書かれたものもあるようです。

Mac OS X を動かすすべての Apple コンピュータには、Python がインストールされています。標準インストールに Python が含まれているのです。

Python を削除してもいいですか？

Python をどこから手に入れたかによります。

誰かが Python を意図してダウンロードしたのであれば、何の問題もなく削除することができます。Windows では、コントロールパネルのプログラムの追加と削除を使ってください。

Python がサードパーティのアプリケーションによってインストールされたなら、同様に削除できますが、そのアプリケーションは動作しなくなります。 Python のディレクトリを削除するのではなく、そのアプリケーションのアンインストーラーを使うべきです。

Python がオペレーティングシステムに含まれて来たなら、削除はお勧めできません。削除してしまうと、Python で書かれたプログラムは全く動かなくなり、その中には重要なものが含まれているかもしれません。その場合、修復にはシステム全体の再インストールが必要になるでしょう。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Python よくある質問 »

このドキュメントについて

この文書は、Pythonドキュメント翻訳プロジェクトによる “Python Frequently Asked Questions” の日本語訳版です。日本語訳に対する質問や提案などがありましたら、Pythonドキュメント翻訳プロジェクトのメーリングリスト

http://www.python.jp/mailman/listinfo/python-doc-jp

または、Google Project Hosting 上の Issue Tracker

http://code.google.com/p/python-doc-ja/issues/entry

までご報告ください。

翻訳者一覧 (敬称略)

Arihiro TAKASE <hinaclegear at gmail.com>

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

用語集

>>>

インタラクティブシェルにおける、デフォルトのPythonプロンプト。インタラクティブに実行されるコードサンプルとしてよく出てきます。

...

インタラクティブシェルにおける、インデントされたコードブロックや対応する括弧(丸括弧()、角括弧[]、curly brace{})の内側で表示されるデフォルトのプロンプト。

2to3

Python 2.x のコードを Python 3.x のコードに変換するツール。ソースコードを解析して、その解析木を巡回(traverse)して、非互換なコードの大部分を処理する。

2to3 は、 lib2to3 モジュールとして標準ライブラリに含まれています。スタンドアローンのツールとして使うときのコマンドは Tools/scripts/2to3 として提供されています。 2to3 - Python 2 から 3 への自動コード変換 を参照してください。

abstract base class

(抽象基底クラス) ABCs - abstract base classes は duck-typing を補完するもので、 hasattr() などの別のテクニックでは不恰好になる場合にインタフェースを定義する方法を提供します。 Pythonは沢山のビルトインABCsを、(collections モジュールで)データ構造、 (numbers モジュールで)数値型、(io モジュールで)ストリーム型で提供いています。 abc モジュールを利用して独自のABCを作成することもできます。

argument

(引数) 関数やメソッドに渡された値。関数の中では、名前の付いたローカル変数に代入されます。

関数やメソッドは、その定義中に位置指定引数(positional arguments, 訳注: f(1, 2) のように呼び出し側で名前を指定せず、引数の位置に引数の値を対応付けるもの) とキーワード引数(keyword arguments, 訳注: f(a=1, b=2) のように、引数名に引数の値を対応付けるもの)の両方を持つことができます。位置指定引数とキーワード引数は可変長です。関数定義や呼び出しは、 * を使って、不定数個の位置指定引数をシーケンス型に入れて受け取ったり渡したりすることができます。同じく、キーワード引数は ** を使って、辞書に入れて受け取ったり渡したりできます。

引数リスト内では任意の式を使うことができ、その式を評価した値が渡されます。

attribute

(属性) オブジェクトに関連付けられ、ドット演算子を利用して名前で参照される値。例えば、オブジェクト o が属性 a を持っているとき、その属性は o.a で参照されます。

BDFL

慈悲ぶかき独裁者 (Benevolent Dictator For Life) の略です。 Python の作者、 Guido van Rossum [http://www.python.org/~guido/] のことです。

bytecode

(バイトコード) Pythonのソースコードはバイトコードへとコンパイルされます。バイトコードはPythonプログラムのインタプリタ内部での形です。バイトコードはまた、 .pyc や .pyo ファイルにキャッシュされ、同じファイルを二度目に実行した際により高速に実行できるようにします (ソースコードからバイトコードへの再度のコンパイルは回避されます)。このバイトコードは、各々のバイトコードに対応するサブルーチンを呼び出すような “仮想計算機(virtual machine)” で動作する “中間言語 (intermediate language)” といえます。

バイトコードの命令一覧は dis モジュールにあります。

class

(クラス) ユーザー定義オブジェクトを作成するためのテンプレート。クラス定義は普通、そのクラスのインスタンス上の操作をするメソッドの定義を含みます。

classic class

(旧スタイルクラス) object を継承していないクラス全てを指します。新スタイルクラス(new-style class) も参照してください。旧スタイルクラスはPython 3.0で削除されます。

coercion

(型強制) 同じ型の2つの引数を要する演算の最中に、ある型のインスタンスを別の型に暗黙のうちに変換することです。例えば、 int(3.15) は浮動小数点数を整数の 3 にします。しかし、 3+4.5 の場合、各引数は型が異なっていて(一つは整数、一つは浮動小数点数)、加算をする前に同じ型に変換しなければいけません。そうでないと、 TypeError 例外が投げられます。 2つの被演算子間の型強制は組み込み関数の coerce を使って行えます。従って、 3+4.5 は operator.add(*coerce(3, 4.5)) を呼び出すことに等しく、 operator.add(3.0, 4.5) という結果になります。型強制を行わない場合、たとえ互換性のある型であっても、すべての引数はプログラマーが、単に 3+4.5 とするのではなく、 float(3)+4.5 というように、同じ型に正規化しなければいけません。

complex number

(複素数) よく知られている実数系を拡張したもので、すべての数は実部と虚部の和として表されます。虚数は虚数単位元(-1 の平方根)に実数を掛けたもので、一般に数学では i と書かれ、工業では j と書かれます。

Pythonは複素数に組込みで対応し、後者の表記を取っています。虚部は末尾に j をつけて書きます。例えば、 3+1j となります。 math モジュールの複素数版を利用するには、 cmath を使います。

複素数の使用はかなり高度な数学の機能です。必要性を感じなければ、ほぼ間違いなく無視してしまってよいでしょう。

context manager

(コンテキストマネージャー) with 文で扱われる、環境を制御するオブジェクト。 __enter__() と __exit__() メソッドを定義することで作られる。

PEP 343 [http://www.python.org/dev/peps/pep-0343] を参照。

CPython

python.org [http://python.org] で配布されている、Python プログラミング言語の基準となる実装。 “CPython” という単語は、この実装を Jython や IronPython といった他の実装と区別する必要が有る場合に利用されます。

decorator

(デコレータ) 関数を返す関数。通常、 @wrapper という文法によって関数を変換するのに利用されます。デコレータの一般的な利用レとして、 classmethod() と staticmethod() があります。

デコレータの文法はシンタックスシュガーです。次の2つの関数定義は意味的に同じものです。

def f(...):
    ...
f = staticmethod(f)

@staticmethod
def f(...):
    ...

デコレータについてのより詳しい情報は、 the documentation for function definition を参照してください。

descriptor

(デスクリプタ) メソッド __get__(), __set__(), あるいは __delete__() が定義されている 新スタイル (new-style) のオブジェクトです。あるクラス属性がデスクリプタである場合、その属性を参照するときに、そのデスクリプタに束縛されている特別な動作を呼び出します。通常、get,set,deleteのために a.b と書くと、 a のクラス辞書内でオブジェクト b を検索しますが、 b がデスクリプタの場合にはデスクリプタで定義されたメソッドを呼び出します。デスクリプタの理解は、 Python を深く理解する上で鍵となります。というのは、デスクリプタこそが、関数、メソッド、プロパティ、クラスメソッド、静的メソッド、そしてスーパクラスの参照といった多くの機能の基盤だからです。

dictionary

(辞書) 任意のキーを値に対応付ける連想配列です。 __hash__() メソッドと __eq__() メソッドを実装した任意のオブジェクトをキーにできます。 Perl ではハッシュ(hash)と呼ばれています。

docstring

クラス、関数、モジュールの最初の式となっている文字列リテラルです。実行時には無視されますが、コンパイラによって識別され、そのクラス、関数、モジュールの __doc__ 属性として保存されます。イントロスペクションできる（訳注: 属性として参照できる）ので、オブジェクトのドキュメントを書く正しい場所です。

duck-typing

あるオブジェクトが正しいインタフェースを持っているかどうかを確かめるのにオブジェクトの型をチェックしないプログラミングスタイル。代わりに、シンプルにオブジェクトのメソッドが呼ばれたり属性が使われたりします。（「もしそれがアヒルのようにみえて、ガチョウのように鳴けば、それはアヒルである」）インタフェースを型より重視することで、上手くデザインされたコードは (polymorphicな置換を許可することによって)柔軟性を増すことができます。 duck-typing は type() や isinstance() を避けます。 (ただし、duck-typing を抽象ベースクラス(abstract base class)で補完することもできます。) その代わりに hasattr() テストや EAFP プログラミングを利用します。

EAFP

「認可をとるより許しを請う方が容易 (easier to ask for forgiveness than permission、マーフィーの法則)」の略です。 Python で広く使われているコーディングスタイルでは、通常は有効なキーや属性が存在するものと仮定し、その仮定が誤っていた場合に例外を捕捉します。この簡潔で手早く書けるコーディングスタイルには、 try 文および except 文がたくさんあるのが特徴です。このテクニックは、C のような言語でよく使われている LBYL スタイルと対照的なものです。

expression

(式) 何かの値に評価される、一つづきの構文(a piece of syntax). 言い換えると、リテラル、名前、属性アクセス、演算子や関数呼び出しといった、値を返す式の要素の組み合わせ。他の多くの言語と違い、Pythonは言語の全ての構成要素が式というわけではありません。 print や if のように、式にはならない、文(statement) もあります。代入も式ではなく文です。

extension module

(拡張モジュール) CやC++で書かれたモジュール。ユーザーコードやPythonのコアとやりとりするために、 PythonのC APIを利用します。

file object

内部リソースに対してファイル由来の API (read() や write() のようなメソッド) を持つオブジェクト。作成された方法に応じて、ファイルオブジェクトはディスクや他のストレージ上のファイルやコミュニュケーション機器 (例えば標準入出力、メモリ上のバッファ、ソケット、パイプなど) に対するアクセスを仲介します。ファイルオブジェクトは file-like object やストリームなどと呼ばれます。

ファイルオブジェクトには3つの種類があります: バイナリファイル、バイナリバッファ、テキストふぁいる。これらのインターフェースは io モジュール内で定義されています。ファイルオブジェクトを作成する標準的な方法は open() 関数を利用することです。

file-like object

file object の別名

finder

モジュールの loader を探すオブジェクト。 find_module() という名前のメソッドを実装していなければなりません。詳細については PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。

floor division

一番近い小さい整数に丸める数学除算。floor division 演算子は // です。例えば、 11 // 4 は 2 になり、 float の true division の結果 2.75 と異なります。 (-11) // 4 は -2.75 を 小さい方に 丸めるので -3 になることに注意してください。 PEP 238 [http://www.python.org/dev/peps/pep-0238] を参照してください。

function

(関数) 呼び出し側に値を返す、一連の文。ゼロ個以上の引数を受け取り、それを関数の本体を実行するときに諒できます。 argument や method も参照してください。

__future__

互換性のない新たな機能を現在のインタプリタで有効にするためにプログラマが利用できる擬似モジュールです。例えば、式 11/4 は現状では 2 になります。この式を実行しているモジュールで

from __future__ import division

を行って 真の除算操作 (true division) を有効にすると、式 11/4 は 2.75 になります。実際に __future__ モジュールを import してその変数を評価すれば、新たな機能が初めて追加されたのがいつで、いつデフォルトの機能になる予定かわかります。

>>> import __future__
>>> __future__.division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

garbage collection

(ガベージコレクション) もう使われなくなったメモリを開放する処理。 Pythonは、Pythonは参照カウントと循環参照を見つけて破壊する循環参照コレクタを使ってガベージコレクションを行います。

generator

(ジェネレータ) イテレータを返す関数です。通常の関数に似ていますが、 return 文を使わず、代わりに for ループで使ったり next() 関数で1つずつ取り出せる値の列を生成するために yield 文を使います。 yield 文に到達するたびに関数の実行は実行状態(ローカル変数や実行中の try 文などを含む)を保存して中断されます。ジェネレータが再開されるとき、(通常の関数が実行の度に初期状態から開始するのに対して)中断した状態から実行を開始します。

generator expression

(ジェネレータ式) イテレータを返す式です。普通の式に、ループ変を定義している for 式、範囲、そして省略可能な if 式がつづいているように見えます。こうして構成された式は、外側の関数に対して値を生成します。:

>>> sum(i*i for i in range(10))         # sum of squares 0, 1, 4, ... 81
285

GIL

グローバルインタプリタロック(global interpreter lock)を参照してください。

global interpreter lock

(グローバルインタプリタロック) CPython インタプリタが利用している、同時に複数のスレッドが Python のバイトコード(bytecode) を実行しないようにする仕組み。これによりオブジェクトモデル(dict などの重要な組み込み型を含む)が暗黙的に並列アクセスに対して安全になるので、 CPython の実装をシンプルにできます。インタプリタ全体をロックすることで、マルチプロセッサマシンが生じる並列化のコストに対して、楽にインタプリタをマルチスレッド化できます。

ただし、標準あるいは外部のいくつかの拡張モジュールは、圧縮やハッシュ計算などの計算の重い処理をしているときにGILを解放するように設計されています。また、I/O処理をするときもGILは解放されます。

過去に “自由なマルチスレッド化” したインタプリタ (供用されるデータを細かい粒度でロックする) が開発されましたが、一般的なシングルプロセッサの場合のパフォーマンスが悪かったので成功しませんでした。このパフォーマンスの問題を克服しようとすると、実装がより複雑になり保守コストが増加すると考えられています。

hashable

(ハッシュ可能) ハッシュ可能 なオブジェクトとは、生存期間中変わらないハッシュ値を持ち (__hash__() メソッドが必要)、他のオブジェクトと比較ができる (__eq__() か __cmp__() メソッドが必要) オブジェクトです。同値なハッシュ可能オブジェクトは必ず同じハッシュ値を持つ必要があります。

辞書のキーや集合型のメンバーは、内部でハッシュ値を使っているので、ハッシュ可能オブジェクトである必要があります。

Python の全ての不変(immutable)なビルドインオブジェクトはハッシュ可能です。リストや辞書といった変更可能なコンテナ型はハッシュ可能ではありません。

ユーザー定義クラスのインスタンスはデフォルトでハッシュ可能です。それらは、比較すると常に不等で、ハッシュ値は id() になります。

IDLE

Python の組み込み開発環境 (Integrated DeveLopment Environment) です。 IDLE は Pythonの標準的な配布物についてくる基本的な機能のエディタとインタプリタ環境です。

immutable

(不変オブジェクト) 固定の値を持ったオブジェクトです。変更不能なオブジェクトには、数値、文字列、およびタプルなどがあります。これらのオブジェクトは値を変えられません。別の値を記憶させる際には、新たなオブジェクトを作成しなければなりません。不変オブジェクトは、固定のハッシュ値が必要となる状況で重要な役割を果たします。辞書におけるキーがその例です。

integer division

(整数除算) 剰余を考慮しない数学的除算です。例えば、式 11/4 は現状では 2.75 ではなく 2 になります。これは 切り捨て除算 (floor division) とも呼ばれます。二つの整数間で除算を行うと、結果は (端数切捨て関数が適用されて) 常に整数になります。しかし、被演算子の一方が (float のような) 別の数値型の場合、演算の結果は共通の型に型強制されます (型強制(coercion)参照)。例えば、浮動小数点数で整数を除算すると結果は浮動小数点になり、場合によっては端数部分を伴います。 // 演算子を / の代わりに使うと、整数除算を強制できます。 __future__ も参照してください。

importer

モジュールを探してロードするオブジェクト。 finder と loader のどちらでもあるオブジェクト。

interactive

(対話的) Python には対話的インタプリタがあり、文や式をインタプリタのプロンプトに入力すると即座に実行されて結果を見ることができます。 python と何も引数を与えずに実行してください。(コンピュータのメインメニューから Pythonの対話的インタプリタを起動できるかもしれません。) 対話的インタプリタは、新しいあアイデアを試してみたり、モジュールやパッケージの中を覗いてみる(help(x) を覚えておいてください) のに非常に便利なツールです。

interpreted

Python はインタプリタ形式の言語であり、コンパイラ言語の対極に位置します。 (バイトコードコンパイラがあるために、この区別は曖昧ですが。) ここでのインタプリタ言語とは、ソースコードのファイルを、まず実行可能形式にしてから実行させるといった操作なしに、直接実行できることを意味します。インタプリタ形式の言語は通常、コンパイラ形式の言語よりも開発／デバッグのサイクルは短いものの、プログラムの実行は一般に遅いです。対話的(interactive)も参照してください。

iterable

(反復可能オブジェクト) 要素を一つずつ返せるオブジェクトです。

反復可能オブジェクトの例には、(list, str, tuple といった) 全てのシーケンス型や、 dict や file といった幾つかの非シーケンス型、あるいは __iter__() か __getitem__() メソッドを実装したクラスのインスタンスが含まれます。

反復可能オブジェクトは for ループ内やその他多くのシーケンス (訳注: ここでのシーケンスとは、シーケンス型ではなくただの列という意味)が必要となる状況 (zip(), map(), ...) で利用できます。

反復可能オブジェクトを組み込み関数 iter() の引数として渡すと、オブジェクトに対するイテレータを返します。このイテレータは一連の値を引き渡す際に便利です。反復可能オブジェクトを使う際には、通常 iter() を呼んだり、イテレータオブジェクトを自分で扱う必要はありません。 for 文ではこの操作を自動的に行い、無名の変数を作成してループの間イテレータを記憶します。イテレータ(iterator) シーケンス(sequence), およびジェネレータ(generator)も参照してください。

iterator

一連のデータ列 (stream) を表現するオブジェクトです。イテレータの next() メソッドを繰り返し呼び出すと、データ列中の要素を一つずつ返します。後続のデータがなくなると、データの代わりに StopIteration 例外を送出します。その時点で、イテレータオブジェクトは全てのオブジェクトを出し尽くしており、それ以降は next() を何度呼んでも StopIteration を送出します。イテレータは、そのイテレータオブジェクト自体を返す __iter__() メソッドを実装しなければならなくなっており、そのため全てのイテレータは他の反復可能オブジェクトを受理できるほとんどの場所で利用できます。著しい例外は複数の反復を行うようなコードです。 (list のような) コンテナオブジェクトでは、 iter() 関数にオブジェクトを渡したり、 for ループ内で使うたびに、新たな未使用のイテレータを生成します。このイテレータをさらに別の場所でイテレータとして使おうとすると、前回のイテレーションパスで使用された同じイテレータオブジェクトを返すため、空のコンテナのように見えます。

より詳細な情報は イテレータ型 にあります。

key function

(キー関数) キー関数、あるいは照合関数とは、ソートや順序比較のための値を返す呼び出し可能オブジェクト(callable)です。例えば、 locale.strxfrm() をキー関数に使えば、ロケール依存のソートの慣習にのっとったソートキーを返します。

Python には要素がどのように順序付けられたりグループ化されたりするかを制御するためにキー関数を受け付けるいくつかのツールがあります。例えば、 min(), max(), sorted(), list.sort(), heapq.nsmallest(), heapq.nlargest(), itertools.groupby() です。

キー関数を作る方法がいくつかあります。例えば、 str.lower() メソッドをキー関数として使って大文字小文字を区別しないソートができます。 (訳注: インスタンスメソッドはクラス経由でアクセスすると関数にもなります。この例では、 'FOO'.lower() と str.lower('FOO') が同じになる事を利用しています。)

他には、アドホックにキー関数を作るために lambda r: (r[0], r[2]) のように lambda 式を使うことができます。また、 operator モジュールは attrgetter(), itemgetter(), methodcaller() というキー関数コンストラクタを提供いしています。キー関数の作り方、使い方に関する例は、 Sorting HOW TO を参照してください。

keyword argument

(キーワード引数) 呼び出し時に、 variable_name= が手前にある引数。変数名は、その値が関数内のどのローカル変数に渡されるかを指定します。キーワード引数として辞書を受け取ったり渡したりするために ** を使うことができます。 argument も参照してください。

lambda

(ラムダ) 無名のインライン関数で、関数が呼び出されたときに評価される1つの式 (expression) を持ちます。ラムダ関数を作る構文は、 lambda [arguments]: expression です。

LBYL

「ころばぬ先の杖」 (look before you leap) の略です。このコーディングスタイルでは、呼び出しや検索を行う前に、明示的に前提条件 (pre-condition) 判定を行います。 EAFP アプローチと対照的で、 if 文がたくさん使われるのが特徴的です。

list

(リスト) Python のビルトインのシーケンス型(sequence)です。リストという名前ですが、リンクリストではなく、他の言語で言う配列(array)と同種のもので、要素へのアクセスは O(1) です。

list comprehension

(リスト内包表記) シーケンス内の全てあるいは一部の要素を処理して、その結果からなるリストを返す、コンパクトな書き方です。 result = ["0x%02x" % x for x in range(256) if x % 2 == 0] とすると、 0 から 255 までの偶数を 16進数表記 (0x..) した文字列からなるリストを生成します。 if 節はオプションです。 if 節がない場合、 range(256) の全ての要素が処理されます。

loader

モジュールをロードするオブジェクト。 load_module() という名前のメソッドを定義していなければなりません。詳細は PEP 302 [http://www.python.org/dev/peps/pep-0302] を参照してください。

mapping

(マップ、マッピング) 任意のキーに対する検索をサポートしていて、 Mapping か MutableMapping の 抽象基底クラス を実装しているコンテナオブジェクト。例えば、 dict, collections.defaultdict, collections.OrderedDict, collections.Counter はマップ型です。

metaclass

(メタクラス) クラスのクラスです。クラス定義は、クラス名、クラスの辞書と、基底クラスのリストを作ります。メタクラスは、それら3つを引数として受け取り、クラスを作る責任を負います。ほとんどのオブジェクト指向言語は(訳注:メタクラスの)デフォルトの実装を提供しています。 Pythonはカスタムのメタクラスを作成できる点が特別です。ほとんどのユーザーに取って、メタクラスは全く必要のないものです。しかし、一部の場面では、メタクラスは強力でエレガントな方法を提供します。たとえば属性アクセスのログを取ったり、スレッドセーフ性を追加したり、オブジェクトの生成を追跡したり、シングルトンを実装するなど、多くの場面で利用されます。

method

クラス内で定義された関数。クラス属性として呼び出された場合、メソッドはインスタンスオブジェクトを第一引数(argument) として受け取ります(この第一引数は普段 self と呼ばれます)。 function と nested scope も参照してください。

method resolution order

メソッド解決順序 (Method Resolution Order) はメンバの探索時の基底クラスの探索順序です。 Python 2.3 の Method Resolution Order を参照して下さい。

MRO

method resolution order を参照して下さい。

mutable

(変更可能オブジェクト) 変更可能なオブジェクトは、 id() を変えることなく値を変更できます。変更不能 (immutable) も参照してください。

named tuple

(名前付きタプル) タプルに似ていて、インデックスによりアクセスする要素に名前付き属性としてもアクセス出来るクラス。 (例えば、 time.localtime() はタプルに似たオブジェクトを返し、その year には t[0] のようなインデックスによるアクセスと、 t.tm_year のような名前付き要素としてのアクセスが可能です。)

名前付きタプルには、 time.struct_time のようなビルトイン型もありますし、通常のクラス定義によって作成することもできます。名前付きタプルを collections.namedtuple() ファクトリ関数で作成することもできます。最後の方法で作った名前付きタプルには自動的に、 Employee(name='jones', title='programmer') のような自己ドキュメント表現(self-documenting representation) 機能が付いてきます。

namespace

(名前空間) 変数を記憶している場所です。名前空間は辞書を用いて実装されています。名前空間には、ローカル、グローバル、組み込み名前空間、そして (メソッド内の) オブジェクトのネストされた名前空間があります。例えば、関数 __builtin__.open() と os.open() は名前空間で区別されます。名前空間はまた、ある関数をどのモジュールが実装しているかをはっきりさせることで、可読性やメンテナンス性に寄与します。例えば、 random.seed(), itertools.izip() と書くことで、これらの関数がそれぞれ random モジュールや itertools モジュールで実装されていることがはっきりします。

nested scope

(ネストされたスコープ) 外側で定義されている変数を参照する機能。具体的に言えば、ある関数が別の関数の中で定義されている場合、内側の関数は外側の関数中の変数を参照できます。ネストされたスコープは変数の参照だけができ、変数の代入はできないので注意してください。変数の代入は、常に最も内側のスコープにある変数に対する書き込みになります。同様に、グローバル変数を使うとグローバル名前空間の値を読み書きします。

new-style class

(新スタイルクラス) object から継承したクラス全てを指します。これには list や dict のような全ての組み込み型が含まれます。 __slots__(), デスクリプタ、プロパティ、 __getattribute__() といった、 Python の新しい機能を使えるのは新スタイルクラスだけです。

より詳しい情報は 新スタイルと旧スタイル を参照してください。

object

状態(属性や値)と定義された振る舞い(メソッド)をもつ全てのデータ。もしくは、全ての新スタイルクラス(new-style class) の基底クラスのこと。

positional argument

(位置指定引数) 引数のうち、呼び出すときの順序で、関数やメソッドの中のどの名前に代入されるかが決定されるもの。複数の位置指定引数を、関数定義側が受け取ったり、渡したりするために、 * を使うことができます。 argument も参照してください。

Python 3000

Pythonの次のメジャーバージョンである Python 3.0 のニックネームです。 (Python 3 が遠い将来の話だった頃に作られた言葉です。) “Py3k” と略されることもあります。

Pythonic

他の言語で一般的な考え方で書かれたコードではなく、Python の特に一般的なイディオムに繋がる、考え方やコード。例えば、Python の一般的なイディオムに iterable の要素を for 文を使って巡回することです。この仕組を持たない言語も多くあるので、Python に慣れ親しんでいない人は数値のカウンターを使うかもしれません。

for i in range(len(food)):
    print food[i]

これと対照的な、よりきれいな Pythonic な方法はこうなります。

for piece in food:
    print piece

reference count

(参照カウント) あるオブジェクトに対する参照の数。参照カウントが0になったとき、そのオブジェクトは破棄されます。参照カウントは通常は Python のコード上には現れませんが、 CPython 実装の重要な要素です。 sys モジュールは、プログラマーが任意のオブジェクトの参照カウントを知るための getrefcount() 関数を提供しています。

__slots__

新スタイルクラス(new-style class)内で、インスタンス属性の記憶に必要な領域をあらかじめ定義しておき、それとひきかえにインスタンス辞書を排除してメモリの節約を行うための宣言です。これはよく使われるテクニックですが、正しく動作させるのには少々手際を要するので、例えばメモリが死活問題となるようなアプリケーション内にインスタンスが大量に存在するといった稀なケースを除き、使わないのがベストです。

sequence

(シーケンス) 特殊メソッド __getitem__() で整数インデックスによる効率的な要素へのアクセスをサポートし、 len() で長さを返すような反復可能オブジェクト(iterable)です。組み込みシーケンス型には、 list, str, tuple, unicode などがあります。 dict は __getitem__() と __len__() もサポートしますが、検索の際に任意の変更不能(immutable)なキーを使うため、シーケンスではなくマップ (mapping) とみなされているので注意してください。

slice

(スライス) 多くの場合、シーケンス(sequence)の一部を含むオブジェクト。スライスは、添字記号 [] で数字の間にコロンを書いたときに作られます。例えば、 variable_name[1:3:5] です。添字記号は slice オブジェクトを内部で利用しています。 (もしくは、古いバージョンの、 __getslice__() と __setslice__() を利用します。)

special method

(特殊メソッド) ある型に対する特定の動作をするために、 Python から暗黙的に呼ばれるメソッド。この種類のメソッドは、メソッド名の最初と最後にアンダースコア2つを持ちます。特殊メソッドについては 特殊メソッド名 で解説されています。

statement

(文) 文は一種のコードブロックです。文は expression か、それ以外のキーワードにより構成されます。例えば if, while, print は文です。

triple-quoted string

(三重クォート文字列) 3つの連続したクォート記号(”)かアポストロフィー(‘)で囲まれた文字列。通常の(一重)クォート文字列に比べて表現できる文字列に違いはありませんが、幾つかの理由で有用です。 1つか2つの連続したクォート記号をエスケープ無しに書くことができますし、行継続文字(\)を使わなくても複数行にまたがることができるので、ドキュメンテーション文字列を書く時に特に便利です。

type

(型) Python のオブジェクトの型は、そのオブジェクトの種類を決定します。全てのオブジェクトは型を持っています。オブジェクトの型は、 __class__ 属性からアクセスしたり、 type(obj) で取得することができます。

view

(ビュー) dict.viewkeys(), dict.viewvalues(), dict.viewitems() が返すオブジェクトのことを辞書ビュー(dictionary view)と呼びます。これらはベースとなる辞書の変更を反映する、遅延シーケンスです。辞書ビューを完全なリストにするには list(dictview) としてください。辞書ビューオブジェクト を参照してください。

virtual machine

(仮想マシン) ソフトウェアにより定義されたコンピュータ。 Python の仮想マシンは、バイトコードコンパイラが出力したバイトコード (bytecode)を実行します。

Zen of Python

(Pythonの悟り) Python を理解し利用する上での導きとなる、Python の設計原則と哲学をリストにしたものです。対話プロンプトで “import this” とするとこのリストを読めます。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

このドキュメントについて

このドキュメントは、 Python のドキュメントを主要な目的として作られたドキュメントプロセッサの Sphinx [http://sphinx.pocoo.org/] を利用して、 reStructuredText [http://docutils.sf.net/rst.html] 形式のソースから生成されました。

ドキュメントとそのツール群の開発は、 docs@python.org メーリングリスト上で行われています。私たちは常に、一緒にドキュメントの開発をしてくれるボランティアを探しています。気軽にこのメーリングリストにメールしてください。

多大な感謝を:

Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content;

the Docutils [http://docutils.sf.net/] project for creating reStructuredText and the Docutils suite;

Fredrik Lundh for his Alternative Python Reference [http://effbot.org/zone/pyref.htm] project from which Sphinx got many good ideas.

このドキュメントや、 Python 自体のバグ報告については、 問題を報告するを参照してください。

ノート

訳注: 日本語訳の問題については、 Google Project Hosting 上の Issue Tracker <http://code.google.com/p/python-doc-ja/issues/entry> に登録するか、 python-doc-jp@python.jp にメールで報告をお願いします。

Pythonドキュメント 貢献者

この節では、Pythonドキュメントに何らかの形で貢献した人をリストアップしています。このリストは完全ではありません – もし、このリストに載っているべき人を知っていたら、 docs@python.org にメールで教えてください。私たちは喜んでその問題を修正します。

Aahz

Michael Abbott

Steve Alexander

Jim Ahlstrom

Fred Allen

A. Amoroso

Pehr Anderson

Oliver Andrich

Jesús Cea Avión

Manuel Balsera

Daniel Barclay

Chris Barker

Don Bashford

Anthony Baxter

Alexander Belopolsky

Bennett Benson

Jonathan Black

Robin Boerdijk

Michal Bozon

Aaron Brancotti

Georg Brandl

Keith Briggs

Ian Bruntlett

Lee Busby

Lorenzo M. Catucci

Carl Cerecke

Mauro Cicognini

Gilles Civario

Mike Clarkson

Steve Clift

Dave Cole

Matthew Cowles

Jeremy Craven

Andrew Dalke

Ben Darnell

L. Peter Deutsch

Robert Donohue

Fred L. Drake, Jr.

Josip Dzolonga

Jeff Epler

Michael Ernst

Blame Andy Eskilsson

Carey Evans

Martijn Faassen

Carl Feynman

Dan Finnie

Hernán Martínez Foffani

Stefan Franke

Jim Fulton

Peter Funk

Lele Gaifax

Matthew Gallagher

Ben Gertzfield

Nadim Ghaznavi

Jonathan Giddy

Shelley Gooch

Nathaniel Gray

Grant Griffin

Thomas Guettler

Anders Hammarquist

Mark Hammond

Harald Hanche-Olsen

Manus Hand

Gerhard Häring

Travis B. Hartwell

Tim Hatch

Janko Hauser

Thomas Heller

Bernhard Herzog

Magnus L. Hetland

Konrad Hinsen

Stefan Hoffmeister

Albert Hofkamp

Gregor Hoffleit

Steve Holden

Thomas Holenstein

Gerrit Holl

Rob Hooft

Brian Hooper

Randall Hopper

Michael Hudson

Eric Huss

Jeremy Hylton

Roger Irwin

Jack Jansen

Philip H. Jensen

Pedro Diaz Jimenez

Kent Johnson

Lucas de Jonge

Andreas Jung

Robert Kern

Jim Kerr

Jan Kim

Greg Kochanski

Guido Kollerie

Peter A. Koren

Daniel Kozan

Andrew M. Kuchling

Dave Kuhlman

Erno Kuusela

Ross Lagerwall

Thomas Lamb

Detlef Lannert

Piers Lauder

Glyph Lefkowitz

Robert Lehmann

Marc-André Lemburg

Ross Light

Ulf A. Lindgren

Everett Lipman

Mirko Liss

Martin von Löwis

Fredrik Lundh

Jeff MacDonald

John Machin

Andrew MacIntyre

Vladimir Marangozov

Vincent Marchetti

Westley Martínez

Laura Matson

Daniel May

Rebecca McCreary

Doug Mennella

Paolo Milani

Skip Montanaro

Paul Moore

Ross Moore

Sjoerd Mullender

Dale Nagata

Michal Nowikowski

Ng Pheng Siong

Koray Oner

Tomas Oppelstrup

Denis S. Otkidach

Zooko O’Whielacronx

Shriphani Palakodety

William Park

Joonas Paalasmaa

Harri Pasanen

Bo Peng

Tim Peters

Benjamin Peterson

Christopher Petrilli

Justin D. Pettit

Chris Phoenix

François Pinard

Paul Prescod

Eric S. Raymond

Edward K. Ream

Terry J. Reedy

Sean Reifschneider

Bernhard Reiter

Armin Rigo

Wes Rishel

Armin Ronacher

Jim Roskind

Guido van Rossum

Donald Wallace Rouse II

Mark Russell

Nick Russo

Chris Ryland

Constantina S.

Hugh Sasse

Bob Savage

Scott Schram

Neil Schemenauer

Barry Scott

Joakim Sernbrant

Justin Sheehy

Charlie Shepherd

Michael Simcich

Ionel Simionescu

Michael Sloan

Gregory P. Smith

Roy Smith

Clay Spence

Nicholas Spies

Tage Stabell-Kulo

Frank Stajano

Anthony Starks

Greg Stein

Peter Stoehr

Mark Summerfield

Reuben Sumner

Kalle Svensson

Jim Tittsler

Ville Vainio

Martijn Vries

Charles G. Waldman

Greg Ward

Barry Warsaw

Corran Webster

Glyn Webster

Bob Weiner

Eddy Welbourne

Jeff Wheeler

Mats Wichmann

Gerry Wiener

Timothy Wild

Paul Winkler

Collin Winter

Blake Winton

Dan Wolfe

Steven Work

Thomas Wouters

Ka-Ping Yee

Rory Yorke

Moshe Zadka

Milan Zamazal

Cheng Zhang

Pythonがこの素晴らしいドキュメントを持っているのは、 Pythonコミュニティによる情報提供と貢献のおかげです。 – ありがとう！

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

問題を報告する

Python は安定性について高い評価を得た、成熟した言語です。この評価を守るために、開発者たちはあなたが見つけた Python の不備を知りたいと思っています。

ドキュメントの問題

このドキュメントに問題を発見したり、改善したいと思った場合、その場所と問題を説明したメールを docs@python.org に送ってください。もし修正案があれば、それも同じメールに書いてください。

doc@python.org はボランティアによって運営されているメーリングリストです。あなたの要望は、処理されるまでに暫く掛かってしまうかもしれませんが、無視されることはないはずです。

もし問題をしっかり記録しておきたいのであれば、もちろんドキュメントの問題についても 課題管理システム (Issue Tracker) を利用することができます。

Python の課題管理システムを使う

Python 自体の問題の報告は Python Bug Tracker (http://bugs.python.org/) に投稿してください。この課題管理システムは、関連情報を入力して開発者に報告するための Web フォームを提供しています。

問題報告の最初のステップは、その問題がすでの報告済みのものかどうかを判断することです。報告済みの問題かどうかを判断するメリットとして、開発者の時間を節約する以外にも、その問題を解決するために既に何が行われているのかを知ることができるというものもあります。問題は解決済みで次のリリースで解決されるかもしれませんし、さらなる情報を必要としている (そしてあなたがその上方を提供できる)かもしれません。そのため、ページの先頭にある検索ボックスを使って、バグデータベースから検索してください。

もし問題がまだ課題管理システムに登録されていない場合、課題管理システムのトップページに戻ってログインしてください。もし課題管理システムのアカウントをもっていないのであれば、サイドバーの “Register” リンクを選ぶか、 OpenID を使う場合は OpenID プロバイダのロゴをクリックしてください。匿名での問題報告はできません。

ログインできたら、バグを登録できます。サイドバーの “Create New” リンクからバグ報告フォームを開きます。

バグ報告フォームには幾つかのフィールドがあります。 “Title” フィールドには、問題の概要を 非常に 簡潔に書いてください。 10語以下くらいが目安です。 “Type” フィールドでは、問題の種類を選択してください。問題と関係する “Component” と “Versions” も選択してください。

“Comment” フィールドで、問題の詳細を、あなたが期待した結果と実際の結果も含めて説明してください。拡張モジュール[#]_ が関係しているかどうか、どのハードウェアとソフトウェアプラットフォームを使っているか(適切なバージョン情報も含めて)なども報告に含めてください。詳細な課題解決ワークフローについては、 http://www.python.org/dev/workflow/ を参照してください。

注記

[1]
訳注：原文ではextension moduleですが、これはC言語で書かれたモジュールという意味ではなくて、広義で非標準ライブラリを指しているかもしれません。

各バグ報告は開発者に割り当てられ、その人がその問題を修正するのに何が必要かを決定します。そのバグ報告に対して何かアクションがあるたびに、更新情報があなたにメールで届きます。

参考

How to Report Bugs Effectively [http://www.chiark.greenend.org.uk/~sgtatham/bugs.html]

有益なバグ報告について詳しく説明した記事です。どんな情報が、なぜ有益なのかを説明しています。

Bug Writing Guidelines [http://developer.mozilla.org/en/docs/Bug_writing_guidelines]

良いバグ報告を書くための情報です。この情報の一部はMozillaプロジェクト独自のものですが、一般的に良いプラクティスを解説しています。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

次へ |

前へ |

Python 2.7ja1 documentation »

Copyright

Python and this documentation is:

Copyright © 2001-2010 Python Software Foundation. All rights reserved.

Copyright © 2000 BeOpen.com. All rights reserved.

Copyright © 1995-2000 Corporation for National Research Initiatives. All rights reserved.

Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved.

Japanese translation is: Copyright © 2003-2009 Python Document Japanese Translation Project. All rights reserved.

ライセンスおよび許諾に関する完全な情報は、 History and License を参照してください。

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

前へ |

Python 2.7ja1 documentation »

History and License

Python の歴史

Python は 1990 年代の始め、オランダにある Stichting Mathematisch Centrum (CWI, http://www.cwi.nl/ 参照) で Guido van Rossum によって ABC と呼ばれる言語の後継言語として生み出されました。その後多くの人々が Python に貢献していますが、 Guido は今日でも Python 製作者の先頭に立っています。

1995 年、 Guido は米国ヴァージニア州レストンにある Corporation for National Reserch Initiatives (CNRI, http://www.cnri.reston.va.us/ 参照) で Python の開発に携わり、いくつかのバージョンをリリースしました。

2000 年 3 月、 Guido と Python のコア開発チームは BeOpen.com に移り、 BeOpen PythonLabs チームを結成しました。同年 10 月、 PythonLabs チームは Digital Creations (現在の Zope Corporation, http://www.zope.com/ 参照) に移りました。そして 2001 年、 Python に関する知的財産を保有するための非営利組織 Python Software Foundation (PSF、 http://www.python.org/psf/ 参照) を立ち上げました。このとき Zope Corporation は PSF の賛助会員になりました。

Python のリリースは全てオープンソース (オープンソースの定義は http://www.opensource.org/ を参照してください) です。歴史的にみて、ごく一部を除くほとんどの Python リリースは GPL 互換になっています; 各リリースについては下表にまとめてあります。

リリース | ベース | 年 | 権利 | GPL 互換
0.9.0 - 1.2 | n/a | 1991-1995 | CWI | yes
1.3 - 1.5.2 | 1.2 | 1995-1999 | CNRI | yes
1.6 | 1.5.2 | 2000 | CNRI | no
2.0 | 1.6 | 2000 | BeOpen.com | no
1.6.1 | 1.6 | 2001 | CNRI | no
2.1 | 2.0+1.6.1 | 2001 | PSF | no
2.0.1 | 2.0+1.6.1 | 2001 | PSF | yes
2.1.1 | 2.1+2.0.1 | 2001 | PSF | yes
2.2 | 2.1.1 | 2001 | PSF | yes
2.1.2 | 2.1.1 | 2002 | PSF | yes
2.1.3 | 2.1.2 | 2002 | PSF | yes
2.2.1 | 2.2 | 2002 | PSF | yes
2.2.2 | 2.2.1 | 2002 | PSF | yes
2.2.3 | 2.2.2 | 2002-2003 | PSF | yes
2.3 | 2.2.2 | 2002-2003 | PSF | yes
2.3.1 | 2.3 | 2002-2003 | PSF | yes
2.3.2 | 2.3.1 | 2003 | PSF | yes
2.3.3 | 2.3.2 | 2003 | PSF | yes
2.3.4 | 2.3.3 | 2004 | PSF | yes
2.3.5 | 2.3.4 | 2005 | PSF | yes
2.4 | 2.3 | 2004 | PSF | yes
2.4.1 | 2.4 | 2005 | PSF | yes
2.4.2 | 2.4.1 | 2005 | PSF | yes
2.4.3 | 2.4.2 | 2006 | PSF | yes
2.4.4 | 2.4.3 | 2006 | PSF | yes
2.5 | 2.4 | 2006 | PSF | yes
2.5.1 | 2.5 | 2007 | PSF | yes
2.5.2 | 2.5.1 | 2008 | PSF | yes
2.5.3 | 2.5.2 | 2008 | PSF | yes
2.6 | 2.5 | 2008 | PSF | yes
2.6.1 | 2.6 | 2008 | PSF | yes
2.6.2 | 2.6.1 | 2009 | PSF | yes
2.6.3 | 2.6.2 | 2009 | PSF | yes
2.6.4 | 2.6.3 | 2010 | PSF | yes
2.7 | 2.6 | 2010 | PSF | yes

ノート

「GPL 互換」という表現は、Python が GPL で配布されているという意味ではありません。Python のライセンスは全て、 GPL と違い、変更したバージョンを配布する際に変更をオープンソースにしなくてもかまいません。 GPL 互換のライセンスの下では、GPL でリリースされている他のソフトウェアと Python を組み合わせられますが、それ以外のライセンスではそうではありません。

Guido の指示の下、これらのリリースを可能にしてくださった多くのボランティアのみなさんに感謝します。

Terms and conditions for accessing or otherwise using Python

PSF LICENSE AGREEMENT FOR PYTHON 2.7ja1

This LICENSE AGREEMENT is between the Python Software Foundation (“PSF”), and the Individual or Organization (“Licensee”) accessing and otherwise using Python 2.7ja1 software in source or binary form and its associated documentation.

Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 2.7ja1 alone or in any derivative version, provided, however, that PSF’s License Agreement and PSF’s notice of copyright, i.e., “Copyright © 2001-2010 Python Software Foundation; All Rights Reserved” are retained in Python 2.7ja1 alone or in any derivative version prepared by Licensee.

In the event Licensee prepares a derivative work that is based on or incorporates Python 2.7ja1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 2.7ja1.

PSF is making Python 2.7ja1 available to Licensee on an “AS IS” basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.7ja1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7ja1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7ja1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

This License Agreement will automatically terminate upon a material breach of its terms and conditions.

Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.

By copying, installing or otherwise using Python 2.7ja1, Licensee agrees to be bound by the terms and conditions of this License Agreement.

BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0

BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1

This LICENSE AGREEMENT is between BeOpen.com (“BeOpen”), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization (“Licensee”) accessing and otherwise using this software in source or binary form and its associated documentation (“the Software”).

Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee.

BeOpen is making the Software available to Licensee on an “AS IS” basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

This License Agreement will automatically terminate upon a material breach of its terms and conditions.

This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the “BeOpen Python” logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page.

By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement.

CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1

This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 (“CNRI”), and the Individual or Organization (“Licensee”) accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation.

Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI’s License Agreement and CNRI’s notice of copyright, i.e., “Copyright © 1995-2001 Corporation for National Research Initiatives; All Rights Reserved” are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI’s License Agreement, Licensee may substitute the following text (omitting the quotes): “Python 1.6.1 is made available subject to the terms and conditions in CNRI’s License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013.”

In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1.

CNRI is making Python 1.6.1 available to Licensee on an “AS IS” basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

This License Agreement will automatically terminate upon a material breach of its terms and conditions.

This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia’s conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.

By clicking on the “ACCEPT” button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement.

ACCEPT

CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2

Copyright © 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Licenses and Acknowledgements for Incorporated Software

This section is an incomplete, but growing list of licenses and acknowledgements for third-party software incorporated in the Python distribution.

Mersenne Twister

The _random module includes code based on a download from http://www.math.keio.ac.jp/ matumoto/MT2002/emt19937ar.html . The following are the verbatim comments from the original code:

A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.

Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).

Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 3. The names of its contributors may not be used to endorse or promote
    products derived from this software without specific prior written
    permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Any feedback is very welcome.
http://www.math.keio.ac.jp/matumoto/emt.html
email: matumoto@math.keio.ac.jp

Sockets

The socket module uses the functions, getaddrinfo(), and getnameinfo(), which are coded in separate source files from the WIDE Project, http://www.wide.ad.jp/.

Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the project nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

Floating point exception control

The source for the fpectl module includes the following notice:

  ---------------------------------------------------------------------
 /                       Copyright (c) 1996.                           \
|          The Regents of the University of California.                 |
|                        All rights reserved.                           |
|                                                                       |
|   Permission to use, copy, modify, and distribute this software for   |
|   any purpose without fee is hereby granted, provided that this en-   |
|   tire notice is included in all copies of any software which is or   |
|   includes  a  copy  or  modification  of  this software and in all   |
|   copies of the supporting documentation for such software.           |
|                                                                       |
|   This  work was produced at the University of California, Lawrence   |
|   Livermore National Laboratory under  contract  no.  W-7405-ENG-48   |
|   between  the  U.S.  Department  of  Energy and The Regents of the   |
|   University of California for the operation of UC LLNL.              |
|                                                                       |
|                              DISCLAIMER                               |
|                                                                       |
|   This  software was prepared as an account of work sponsored by an   |
|   agency of the United States Government. Neither the United States   |
|   Government  nor the University of California nor any of their em-   |
|   ployees, makes any warranty, express or implied, or  assumes  any   |
|   liability  or  responsibility  for the accuracy, completeness, or   |
|   usefulness of any information,  apparatus,  product,  or  process   |
|   disclosed,   or  represents  that  its  use  would  not  infringe   |
|   privately-owned rights. Reference herein to any specific  commer-   |
|   cial  products,  process,  or  service  by trade name, trademark,   |
|   manufacturer, or otherwise, does not  necessarily  constitute  or   |
|   imply  its endorsement, recommendation, or favoring by the United   |
|   States Government or the University of California. The views  and   |
|   opinions  of authors expressed herein do not necessarily state or   |
|   reflect those of the United States Government or  the  University   |
|   of  California,  and shall not be used for advertising or product   |
 \  endorsement purposes.                                              /
  ---------------------------------------------------------------------

MD5 message digest algorithm

The source code for the md5 module contains the following notice:

Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

L. Peter Deutsch
ghost@aladdin.com

Independent implementation of MD5 (RFC 1321).

This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
      http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A.  It does not include
any code or documentation that is identified in the RFC as being
copyrighted.

The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>.  Other authors are noted in the change history
that follows (in reverse chronological order):

2002-04-13 lpd Removed support for non-ANSI compilers; removed
      references to Ghostscript; clarified derivation from RFC 1321;
      now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
      added conditionalization for C++ compilation from Martin
      Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.

Asynchronous socket services

The asynchat and asyncore modules contain the following notice:

Copyright 1996 by Sam Rushing

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of Sam
Rushing not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Cookie management

The Cookie module contains the following notice:

Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>

               All Rights Reserved

Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
Timothy O'Malley  not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.

Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

Profiling

The profile and pstats modules contain the following notice:

Copyright 1994, by InfoSeek Corporation, all rights reserved.
Written by James Roskind

Permission to use, copy, modify, and distribute this Python software
and its associated documentation for any purpose (subject to the
restriction in the following sentence) without fee is hereby granted,
provided that the above copyright notice appears in all copies, and
that both that copyright notice and this permission notice appear in
supporting documentation, and that the name of InfoSeek not be used in
advertising or publicity pertaining to distribution of the software
without specific, written prior permission.  This permission is
explicitly restricted to the copying and modification of the software
to remain in Python, compiled Python, or other languages (such as C)
wherein the modified or derived code is exclusively imported into a
Python module.

INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Execution tracing

The trace module contains the following notice:

portions copyright 2001, Autonomous Zones Industries, Inc., all rights...
err...  reserved and offered to the public under the terms of the
Python 2.2 license.
Author: Zooko O'Whielacronx
http://zooko.com/
mailto:zooko@zooko.com

Copyright 2000, Mojam Media, Inc., all rights reserved.
Author: Skip Montanaro

Copyright 1999, Bioreason, Inc., all rights reserved.
Author: Andrew Dalke

Copyright 1995-1997, Automatrix, Inc., all rights reserved.
Author: Skip Montanaro

Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.

Permission to use, copy, modify, and distribute this Python software and
its associated documentation for any purpose without fee is hereby
granted, provided that the above copyright notice appears in all copies,
and that both that copyright notice and this permission notice appear in
supporting documentation, and that the name of neither Automatrix,
Bioreason or Mojam Media be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

UUencode and UUdecode functions

The uu module contains the following notice:

Copyright 1994 by Lance Ellinghouse
Cathedral City, California Republic, United States of America.
                       All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Lance Ellinghouse
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Modified by Jack Jansen, CWI, July 1995:
- Use binascii module to do the actual line-by-line conversion
  between ascii and binary. This results in a 1000-fold speedup. The C
  version is still 5 times faster, though.
- Arguments more compliant with Python standard

XML Remote Procedure Calls

The xmlrpclib module contains the following notice:

    The XML-RPC client interface is

Copyright (c) 1999-2002 by Secret Labs AB
Copyright (c) 1999-2002 by Fredrik Lundh

By obtaining, using, and/or copying this software and/or its
associated documentation, you agree that you have read, understood,
and will comply with the following terms and conditions:

Permission to use, copy, modify, and distribute this software and
its associated documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice appears in
all copies, and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
Secret Labs AB or the author not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.

SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.

test_epoll

The test_epoll contains the following notice:

Copyright (c) 2001-2006 Twisted Matrix Laboratories.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Select kqueue

The select and contains the following notice for the kqueue interface:

Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

strtod and dtoa

The file Python/dtoa.c, which supplies C functions dtoa and strtod for conversion of C doubles to and from strings, is derived from the file of the same name by David M. Gay, currently available from http://www.netlib.org/fp/. The original file, as retrieved on March 16, 2009, contains the following copyright and licensing notice:

/****************************************************************
 *
 * The author of this software is David M. Gay.
 *
 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 *
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 *
 ***************************************************************/

OpenSSL

The modules hashlib, posix, ssl, crypt use the OpenSSL library for added performance if made available by the operating system. Additionally, the Windows installers for Python include a copy of the OpenSSL libraries, so we include a copy of the OpenSSL license here:

 LICENSE ISSUES
 ==============

 The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
 the OpenSSL License and the original SSLeay license apply to the toolkit.
 See below for the actual license texts. Actually both licenses are BSD-style
 Open Source licenses. In case of any license issues related to OpenSSL
 please contact openssl-core@openssl.org.

 OpenSSL License
 ---------------

   /* ====================================================================
    * Copyright (c) 1998-2008 The OpenSSL Project.  All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
    *    the documentation and/or other materials provided with the
    *    distribution.
    *
    * 3. All advertising materials mentioning features or use of this
    *    software must display the following acknowledgment:
    *    "This product includes software developed by the OpenSSL Project
    *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    *
    * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    *    endorse or promote products derived from this software without
    *    prior written permission. For written permission, please contact
    *    openssl-core@openssl.org.
    *
    * 5. Products derived from this software may not be called "OpenSSL"
    *    nor may "OpenSSL" appear in their names without prior written
    *    permission of the OpenSSL Project.
    *
    * 6. Redistributions of any form whatsoever must retain the following
    *    acknowledgment:
    *    "This product includes software developed by the OpenSSL Project
    *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    *
    * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    * OF THE POSSIBILITY OF SUCH DAMAGE.
    * ====================================================================
    *
    * This product includes cryptographic software written by Eric Young
    * (eay@cryptsoft.com).  This product includes software written by Tim
    * Hudson (tjh@cryptsoft.com).
    *
    */

Original SSLeay License
-----------------------

   /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    * All rights reserved.
    *
    * This package is an SSL implementation written
    * by Eric Young (eay@cryptsoft.com).
    * The implementation was written so as to conform with Netscapes SSL.
    *
    * This library is free for commercial and non-commercial use as long as
    * the following conditions are aheared to.  The following conditions
    * apply to all code found in this distribution, be it the RC4, RSA,
    * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    * included with this distribution is covered by the same copyright terms
    * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    *
    * Copyright remains Eric Young's, and as such any Copyright notices in
    * the code are not to be removed.
    * If this package is used in a product, Eric Young should be given attribution
    * as the author of the parts of the library used.
    * This can be in the form of a textual message at program startup or
    * in documentation (online or textual) provided with the package.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    * 1. Redistributions of source code must retain the copyright
    *    notice, this list of conditions and the following disclaimer.
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the distribution.
    * 3. All advertising materials mentioning features or use of this software
    *    must display the following acknowledgement:
    *    "This product includes cryptographic software written by
    *     Eric Young (eay@cryptsoft.com)"
    *    The word 'cryptographic' can be left out if the rouines from the library
    *    being used are not cryptographic related :-).
    * 4. If you include any Windows specific code (or a derivative thereof) from
    *    the apps directory (application code) you must include an acknowledgement:
    *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    *
    * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.
    *
    * The licence and distribution terms for any publically available version or
    * derivative of this code cannot be changed.  i.e. this code cannot simply be
    * copied and put under another distribution licence
    * [including the GNU Public Licence.]
    */

expat

The pyexpat extension is built using an included copy of the expat sources unless the build is configured --with-system-expat:

Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
                               and Clark Cooper

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

libffi

The _ctypes extension is built using an included copy of the libffi sources unless the build is configured --with-system-libffi:

Copyright (c) 1996-2008  Red Hat, Inc and others.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

zlib

The zlib extension is built using an included copy of the zlib sources unless the zlib version found on the system is too old to be used for the build:

Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.

Jean-loup Gailly        Mark Adler
jloup@gzip.org          madler@alumni.caltech.edu

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

Python 2.7ja1 documentation »

Pythonモジュール索引

_ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | z

| _ |
| __builtin__ | 組み込み名前空間を提供するモジュール
| __future__ | future 文の定義
| __main__ | トップレベルスクリプトが実行される環境。
| _winreg (Windows) | Windows レジストリを操作するためのルーチンおよびオブジェクト。
| a |
| abc | PEP 3119 に基づいた抽象基底クラス
| aepack (Mac) | 撤廃: Python変数とAppleEventデータコンテナ間の変換
| aetools (Mac) | 撤廃: Apple Eventを送るための基本的なサポート
| aetypes (Mac) | 撤廃: Apple Event オブジェクトモデルの Python 表現
| aifc | AIFFあるいはAIFCフォーマットのオーディオファイルの読み書き
| al (IRIX) | 撤廃: SGIのオーディオ機能。
| AL (IRIX) | 撤廃: alモジュールで使われる定数。
| anydbm | DBM 形式のデータベースモジュールに対する汎用インタフェース。
| applesingle (Mac) | 撤廃: AppleSingle フォーマットファイル用の基本的なデコーダ
| argparse | コマンドラインオプションと引数のパーサーライブラリ
| array | 一様な型を持つ数値からなる空間効率のよいアレイ。
| ast | Abstract Syntax Tree classes and manipulation.
| asynchat | 非同期コマンド/レスポンスプロトコルの開発サポート
| asyncore | 非同期なソケット制御サービスのためのベースクラス
| atexit | 後始末関数の登録と実行。
| audioop | 生の音声データを操作する
| autoGIL (Mac) | 撤廃: イベントループ中のグローバルインタープリタの取り扱い
| b |
| base64 | RFC 3548: Base16, Base32, Base64 データの符号化
| BaseHTTPServer | 基本的な機能を持つ HTTP サーバ (SimpleHTTPServer および CGIHTTPServer の基底クラス)。
| Bastion | 撤廃: オブジェクトに対するアクセスの制限を提供する。
| bdb | デバッガーフレームワーク
| binascii | バイナリと各種 ASCII コード化バイナリ表現との間の\ 変換を行うツール群。
| binhex | binhex4 形式ファイルのエンコードおよびデコード。
| bisect | バイナリサーチ用の配列二分法アルゴリズム。
| bsddb | Berkeley DB ライブラリへのインタフェース
| buildtools (Mac) | 撤廃: BuildAppletとその仲間のヘルパーモジュール
| bz2 | bzip2 互換の圧縮／解凍ルーチンへのインタフェース
| c |
| calendar | Unix の cal プログラム相当の機能を含んだカレンダーに関する関数群
- | Carbon |
|     Carbon.AE (Mac) | 撤廃: Apple Eventツールボックスへのインタフェース
|     Carbon.AH (Mac) | 撤廃: Apple ヘルプマネージャへのインタフェース
|     Carbon.App (Mac) | 撤廃: アピアランスマネージャへのインタフェース
|     Carbon.Appearance (Mac) | 撤廃: Appearance Manager のインタフェースのための定数
|     Carbon.CarbonEvents (Mac) | 撤廃: Carbon Event Manager のための定数
|     Carbon.CaronEvt (Mac) | 撤廃: Carbon Event Managerへのインタフェース
|     Carbon.CF (Mac) | 撤廃: Core Foundationへのインタフェース
|     Carbon.CG (Mac) | 撤廃: コア・グラフィックスへのインタフェース
|     Carbon.Cm (Mac) | 撤廃: Component Managerへのインタフェース
|     Carbon.Components (Mac) | 撤廃: Constants for the interface to the Component Manager.
|     Carbon.ControlAccessor (Mac) | 撤廃: Accessor functions for the interface to the Control Manager.
|     Carbon.Controls (Mac) | 撤廃: Constants for the interface to the Control Manager.
|     Carbon.CoreFounation (Mac) | 撤廃: Constants for the interface to CoreFoundation.
|     Carbon.CoreGraphics (Mac) | 撤廃: Constants for the interface to CoreGraphics.
|     Carbon.Ctl (Mac) | 撤廃: Control Managerへのインタフェース
|     Carbon.Dialogs (Mac) | 撤廃: Constants for the interface to the Dialog Manager.
|     Carbon.Dlg (Mac) | 撤廃: Dialog Managerへのインタフェース
|     Carbon.Drag (Mac) | 撤廃: Interface to the Drag and Drop Manager.
|     Carbon.Dragconst (Mac) | 撤廃: Constants for the interface to the Drag and Drop Manager.
|     Carbon.Events (Mac) | 撤廃: Constants for the interface to the classic Event Manager.
|     Carbon.Evt (Mac) | 撤廃: Event Managerへのインタフェース
|     Carbon.File (Mac) | 撤廃: Interface to the File Manager.
|     Carbon.Files (Mac) | 撤廃: Constants for the interface to the File Manager.
|     Carbon.Fm (Mac) | 撤廃: Font Managerへのインタフェース
|     Carbon.Folder (Mac) | 撤廃: Folder Managerへのインタフェース
|     Carbon.Folders (Mac) | 撤廃: Constants for the interface to the Folder Manager.
|     Carbon.Fonts (Mac) | 撤廃: Constants for the interface to the Font Manager.
|     Carbon.Help (Mac) | 撤廃: Carbon Help Managerへのインタフェース
|     Carbon.IBCarbon (Mac) | 撤廃: Interface to the Carbon InterfaceBuilder support libraries.
|     Carbon.IBCarbonRuntime (Mac) | 撤廃: Constants for the interface to the Carbon InterfaceBuilder support libraries.
|     Carbon.Icns (Mac) | 撤廃: Interface to the Carbon Icon Manager
|     Carbon.Icons (Mac) | 撤廃: Constants for the interface to the Carbon Icon Manager
|     Carbon.Launch (Mac) | 撤廃: Interface to the Carbon Launch Services.
|     Carbon.LaunchServices (Mac) | 撤廃: Constants for the interface to the Carbon Launch Services.
|     Carbon.List (Mac) | 撤廃: List Managerへのインタフェース
|     Carbon.Lists (Mac) | 撤廃: Constants for the interface to the List Manager.
|     Carbon.MacHelp (Mac) | 撤廃: Constants for the interface to the Carbon Help Manager.
|     Carbon.MediaDescr (Mac) | 撤廃: Parsers and generators for Quicktime Media descriptors
|     Carbon.Menu (Mac) | 撤廃: Menu Managerへのインタフェース
|     Carbon.Menus (Mac) | 撤廃: Constants for the interface to the Menu Manager.
|     Carbon.Mlte (Mac) | 撤廃: MultiLingual Text Editorへのインタフェース
|     Carbon.OSA (Mac) | 撤廃: Interface to the Carbon OSA Library.
|     Carbon.OSAconst (Mac) | 撤廃: Constants for the interface to the Carbon OSA Library.
|     Carbon.Qd (Mac) | 撤廃: QuickDrawツールボックスへのインタフェース
|     Carbon.Qdoffs (Mac) | 撤廃: QuickDrawオフスクリーン APIへのインタフェース
|     Carbon.QDOffscreen (Mac) | 撤廃: Constants for the interface to the QuickDraw Offscreen APIs.
|     Carbon.Qt (Mac) | 撤廃: QuickTime ツールボックスへのインタフェース
|     Carbon.QuickDraw (Mac) | 撤廃: Constants for the interface to the QuickDraw toolbox.
|     Carbon.QuickTime (Mac) | 撤廃: Constants for the interface to the QuickTime toolbox.
|     Carbon.Res (Mac) | 撤廃: Resource Managerとハンドルへのインタフェース
|     Carbon.Resources (Mac) | 撤廃: Constants for the interface to the Resource Manager and Handles.
|     Carbon.Scrap (Mac) | 撤廃: スクラップマネージャはカット & ペーストとクリップボードの操作の基本的\ なサービスを提供します。
|     Carbon.Snd (Mac) | 撤廃: Sound Managerへのインタフェース
|     Carbon.Sound (Mac) | 撤廃: Constants for the interface to the Sound Manager.
|     Carbon.TE (Mac) | 撤廃: TextEditへのインタフェース
|     Carbon.TextEdit (Mac) | 撤廃: Constants for the interface to TextEdit.
|     Carbon.Win (Mac) | 撤廃: Window Managerへのインタフェース
|     Carbon.Windows (Mac) | 撤廃: Constants for the interface to the Window Manager.
| cd (IRIX) | 撤廃: Silicon GraphicsシステムのCD-ROMへのインターフェース
| cfmfile (Mac) | 撤廃: コードフラグメントリソースを扱うモジュール
| cgi | PythonスクリプトをCGIとして実行するためのヘルパー
| CGIHTTPServer | CGI スクリプトの実行機能を持つ HTTP サーバのためのリクエスト処理機構を提供します。
| cgitb | 設定可能な、CGI スクリプトのトレースバック処理機構です。
| chunk | IFFチャンクデータの読み込み。
| cmath | 複素数のための数学関数です。
| cmd | 行指向のコマンドインタープリタを構築
| code | read-eval-print ループを実装するのを助ける
| codecs | データやストリームのエンコード・デコード。
| codeop | (完全ではないかもしれない)Pythonコードをコンパイルする。
| collections | High-performance container datatypes
| ColorPicker (Mac) | 撤廃: 標準色選択ダイアログへのインターフェース
| colorsys | RGB 他の色体系間の変換。
| commands (Unix) | 撤廃: 外部コマンドを実行するためのユーティリティです。
| compileall | ディレクトリに含まれる Python ソースファイルを、一括してバイトコンパイルします。
- | compiler | 撤廃: Python で書かれた Python コードコンパイラ。
|     compiler.ast |
|     compiler.visitor |
| ConfigParser | Configuration file parser.
| contextlib | with-構文コンテキストのためのユーティリティ。
| Cookie | HTTP状態管理(cookies)のサポート。
| cookielib | HTTP cookie を自動的に処理するためのクラスライブラリ
| copy | 浅いコピーおよび深いコピー操作。
| copy_reg | pickleサポート関数を登録する。
| cPickle | pickle の高速バージョンですが、サブクラスはできません。
| cProfile | Python profiler
| crypt (Unix) | Unix パスワードをチェックするための関数 crypt()。
| cStringIO | StringIOを高速にしたものだが、サブクラス化はできない。
| csv | デリミタで区切られた形式のファイルに対するテーブル状データ読み書き。
| ctypes | A foreign function library for Python.
- | curses (Unix) | 可搬性のある端末操作を提供する curses ライブラリへのインタフェース．
|     curses.ascii | ASCII 文字に関する定数および集合帰属関数。
|     curses.panel | curses ウィンドウに深さの概念を追加するパネルスタック拡張。
|     curses.textpad | curses ウィンドウ内での Emacs ライクな入力編集機能。
|     curses.wrapper | curses プログラムのための端末設定ラッパ。
| d |
| datetime | 基本的な日付型および時間型。
| dbhash | BSD データベースライブラリへの DBM 形式のインタフェース。
| dbm (Unix) | ndbmを基にした基本的なデータベースインタフェースです。
| decimal | 汎用10進数演算仕様 (General Decimal Arithmetic Specification) の実装。
| DEVICE (IRIX) | 撤廃: glモジュールで使われる定数。
| difflib | オブジェクト同士の違いを計算する
| dircache | 撤廃: キャッシュメカニズムを備えたディレクトリ一覧生成。
| dis | Python バイトコードの逆アセンブラ。
- | distutils | 現在インストールされている Python に追加するためのモジュール構築、および実際のインストールを支援する。
|     distutils.archive_util | Utility functions for creating archive files (tarballs, zip files, ...)
|     distutils.bcppcompiler |
|     distutils.ccompiler | 抽象 CCompiler class
|     distutils.cmd | このモジュールは Command 抽象ベースクラスを提供します。このクラスは distutils.command サブパッケージ中のモジュールでサブクラスを作るために利用されます。
|     distutils.command | このサブパッケージは標準のdistutilsコマンドを提供します。
|     distutils.command.bdist | パッケージのバイナリインストラーを構築します
|     distutils.command.bdist_dumb | "ダム"インストーラ(単純なファイルのアーカイブ)を構築します
|     distutils.command.bdist_msi | Windows MSI ファイル形式のバイナリ配布物をビルドする。
|     distutils.command.bdist_packager | パッケージの抽象ベースクラス
|     distutils.command.bdist_rpm | Redhat RPMとSRPM形式のバイナリディストリビューションを構築
|     distutils.command.bdist_wininst | Windows インストーラの構築
|     distutils.command.build | パッケージ中の全ファイルのビルド
|     distutils.command.build_clib | パッケージ中のCライブラリを構築
|     distutils.command.build_ext | パッケージ中の拡張を構築
|     distutils.command.build_py | パッケージ中の.py/.pyc ファイルを構築
|     distutils.command.build_scripts | パッケージ中のスクリプトを構築
|     distutils.command.check | パッケージのメタデータをチェックする
|     distutils.command.clean | パッケージのビルドエリアを消去
|     distutils.command.config | パッケージの設定
|     distutils.command.install | パッケージのインストール
|     distutils.command.install_data | パッケージ中のデータファイルをインストール
|     distutils.command.install_headers | パッケージから C/C++ ヘッダファイルをインストール
|     distutils.command.install_lib | パッケージからライブラリファイルをインストール
|     distutils.command.install_scripts | パッケージからスクリプトファイルをインストール
|     distutils.command.register | モジュールをPython Package Indexに登録する
|     distutils.command.sdist | ソース配布物の構築
|     distutils.core | Distutils のコア機能
|     distutils.cygwinccompiler |
|     distutils.debug | distutilsのデバッグフラグを提供します。
|     distutils.dep_util | Utility functions for simple dependency checking
|     distutils.dir_util | Utility functions for operating on directories and directory trees
|     distutils.dist | 構築/インストール/配布される配布物を表す Distribution クラスを提供します。
|     distutils.emxccompiler | OS/2 EMX Compiler support
|     distutils.errors | distutils の標準的な例外を提供します。
|     distutils.extension | セットアップスクリプトでC/C++ 拡張モジュールをあらわす Extension クラスを提供します。
|     distutils.fancy_getopt | getopt 追加機能
|     distutils.file_util | 1ファイルを操作するユーティリティ関数
|     distutils.filelist | ファイルシステムを見て、ファイルのリストを構築するために使われる FileList クラス
|     distutils.log | シンプルな282スタイルのロギングメカニズム
|     distutils.msvccompiler | Microsoft Compiler
|     distutils.spawn | spawn() 関数を提供
|     distutils.sysconfig | Python インタプリタの設定情報に対する低水準のアクセス手段。
|     distutils.text_file | テキストファイルへのシンプルなインタフェース TextFile クラスを提供します。
|     distutils.unixccompiler | UNIX C Compiler
|     distutils.util | その他のユーティリティ関数
|     distutils.version | モジュールのバージョン番号を表すクラスの実装
| dl (Unix) | 撤廃: 共有オブジェクトのC関数の呼び出し
| doctest | docstring の中のテストコード.
| DocXMLRPCServer | セルフ-ドキュメンティング XML-RPC サーバの実装。
| dumbdbm | 単純な DBM インタフェースに対する可搬性のある実装。
| dummy_thread | thread の代替モジュール。
| dummy_threading | threading の代替モジュール。
| e |
| EasyDialogs (Mac) | 撤廃: 基本的な Macintosh ダイアログ。
- | email | 電子メールのメッセージを解析、操作および生成を支援するパッケージ。これには MIME 文書もふくまれる。
|     email.charset | 文字セット
|     email.encoders | 電子メールメッセージのペイロードのためのエンコーダ。
|     email.errors | email パッケージで使われる例外クラス
|     email.generator | メッセージ構造からフラットな電子メールテキストを生成する。
|     email.header | 非ASCII形式のヘッダを表現する
|     email.iterators | メッセージオブジェクトツリーをたどる。
|     email.message | 電子メールのメッセージを表現する基底クラス
|     email.mime | MIME メッセージを作成する
|     email.parser | 電子メールメッセージのフラットなテキストを解析し、メッセージオブジェクト構造体を生成する。
|     email.utils | 電子メールパッケージの雑多なユーティリティ。
- | encodings |
|     encodings.idna | 国際化ドメイン名実装
|     encodings.utf_8_sig | UTF-8 codec with BOM signature
| errno | 標準の errno システムシンボル。
| exceptions | 標準の例外クラス群
| f |
| fcntl (Unix) | fcntl() および ioctl() システムコール。
| filecmp | ファイル群を効率的に比較します。
| fileinput | 標準入力もしくはファイルのリストをまたいでループする
| findertools (Mac) | finderのApple Eventsインターフェースのラッパ。
| FL (IRIX) | 撤廃: flモジュールで使用される定数。
| fl (IRIX) | 撤廃: グラフィカルユーザーインターフェースのための FORMS ライブラリ。
| flp (IRIX) | 撤廃: 保存されたFORMSデザインをロードする関数。
| fm (IRIX) | 撤廃: SGIワークステーションの Font Manager インターフェース。
| fnmatch | Unix シェル形式のファイル名のパターンマッチ。
| formatter | 汎用の出力書式化機構およびデバイスインタフェース。
| fpectl (Unix) | 浮動小数点例外処理の制御。
| fpformat | 撤廃: 浮動小数点をフォーマットする汎用関数。
| fractions | 有理数
| FrameWork (Mac) | 撤廃: 対話型アプリケーション・フレームワーク
| ftplib | FTPプロトコルクライアント(ソケットを必要とします)。
| functools | 高階関数と呼び出し可能オブジェクトの操作
| future_builtins |
| g |
| gc | 循環検出ガベージコレクタのインターフェース。
| gdbm (Unix) | GNU による dbm の再実装。
| gensuitemodule (Mac) | OSA辞書からスタブパッケージを作成します。
| getopt | ポータブルなコマンドラインオプションのパーサ。長短の両方の形式をサポートします。
| getpass | ポータブルなパスワードとユーザーIDの検索
| gettext | 多言語対応に関する国際化サービス。
| gl (IRIX) | 撤廃: Silicon Graphics のGraphics Library の関数。
| GL (IRIX) | 撤廃: glモジュールで使われる定数。
| glob | Unix シェル形式のパス名のパターン展開。
| grp (Unix) | グループデータベースへのアクセス (getgrnam() およびその仲間)。
| gzip | ファイルオブジェクトを用いた gzip 圧縮および解凍のためのインタフェース
| h |
| hashlib | セキュアハッシュおよびメッセージダイジェストのアルゴリズム
| heapq | ヒープキュー (別名優先度キュー) アルゴリズム。
| hmac | メッセージ認証のための鍵付きハッシュ化 (HMAC: Keyed-Hashing for Message Authentication) アルゴリズムの Python 用実装
- | hotshot | コードの大半が C で書かれたハイパフォーマンス・ロギング・プロファイラ
|     hotshot.stats | Hotshot の統計分析
| htmlentitydefs | HTML 一般エンティティの定義。
| htmllib | 撤廃: HTML 文書の解析器。
| HTMLParser | HTML と XHTML を扱えるシンプルなパーザ。
| httplib | HTTP および HTTPS プロトコルのクライアント (ソケットを必要とします) 。
| i |
| ic (Mac) | 撤廃: Mac OS X インターネット設定へのアクセス。
| icopen (Mac) | 撤廃: open()と Internet Config の置き換え
| imageop | 撤廃: 生の画像データを操作する。
| imaplib | IMAP4 protocol client (requires sockets).
| imgfile (IRIX) | 撤廃: SGI imglib ファイルのサポート。
| imghdr | ファイルやバイトストリームに含まれる画像の形式を決定する。
| imp | import文の実装へアクセスする。
| importlib | Convenience wrappers for __import__
| imputil | 撤廃: import 処理の管理と増強
| inspect | 活動中のオブジェクトから、情報とソースコードを取得する。
| io | Core tools for working with streams.
| itertools | 効率的なループ実行のためのイテレータ生成関数。
| j |
| jpeg (IRIX) | 撤廃: JPEGファイルの読み書きを行います。
| json | JSON 形式のエンコードおよびデコード
| k |
| keyword | 文字列が Python のキーワードか否かを調べます。
| l |
| lib2to3 | the 2to3 library
| linecache | このモジュールによりテキストファイルの各行にランダムアクセスできます。
| locale | 国際化サービス。
- | logging | アプリケーションのための、柔軟なエラーロギングシステム
|     logging.config | logging モジュールの環境設定
|     logging.handlers | logging モジュールのためのハンドラ
| m |
| macerrors (Mac) | 撤廃: 多くの MacOS エラーコード定数定義
| MacOS (Mac) | 撤廃: Mac OS 固有のインタープリタ機能へのアクセス。
| macostools (Mac) | 撤廃: ファイル操作を便利にするルーチン集。
| macpath | Mac OS 9 のパス操作関数
| macresource (Mac) | 撤廃: スクリプトのリソースを見つける
| mailbox | 様々な形式のメールボックス操作
| mailcap | mailcap ファイルの操作
| marshal | Python オブジェクトをバイト列に変換したり、その逆を (異なる制約条件下で) 行います。
| math | 数学関数(sin() など)。
| md5 | 撤廃: RSA の MD5 メッセージダイジェストアルゴリズム
| mhlib | 撤廃: Python から MH のメールボックスを操作します。
| mimetools | 撤廃: MIME-スタイルのメッセージ本体を解析するためのツール。
| mimetypes | ファイル名拡張子の MIME 型へのマッピング。
| MimeWriter | 撤廃: MIME 形式ファイルを書く
| mimify | 撤廃: 電子メールメッセージの MIME 化および非 MIME 化。
| MiniAEFrame (Mac) | オープンスクリプティングアーキテクチャ(OSA)サーバ("Apple Events")のサポート。
| mmap | Unix と Windows のメモリマップファイルへのインターフェース
| modulefinder | スクリプト中で使われているモジュールを検索します。
| msilib (Windows) | Creation of Microsoft Installer files, and CAB files.
| msvcrt (Windows) | MS VC++実行時システムの雑多な有用ルーチン群。
| multifile | 撤廃: MIME データのような、個別の部分を含んだファイル群に対する\ 読み出しのサポート。
- | multiprocessing | Process-based "threading" interface.
|     multiprocessing.connection | API for dealing with sockets.
|     multiprocessing.dummy | Dumb wrapper around threading.
|     multiprocessing.managers | Share data between process with shared objects.
|     multiprocessing.pool | Create pools of processes.
|     multiprocessing.sharedctypes | 共有メモリから ctypes オブジェクトを割り当てる
| mutex | 排他制御のためのロックとキュー
| n |
| Nav (Mac) | 撤廃: Navigation Services へのインターフェース
| netrc | .netrc ファイル群の読み出し。
| new | 撤廃: ランタイム実装オブジェクトの作成のインターフェイス。
| nis (Unix) | Sun の NIS (Yellow Pages) ライブラリへのインタフェース。
| nntplib | NNTP プロトコルクライアント (ソケットを必要とします)。
| numbers | 数の抽象基底クラス (Complex, Real, Integral など)
| o |
| operator | 標準演算子に対応する関数
| optparse | 撤廃: コマンドラインオプション解析機
- | os | 雑多なオペレーティングシステムインタフェース。
|     os.path | Operations on pathnames.
| ossaudiodev (Linux, FreeBSD) | OSS互換オーディオデバイスへのアクセス。
| p |
| parser | Python ソースコードに対する解析木へのアクセス。
| pdb | 対話的インタプリタのためのPythonデバッガ。
| pickle | Python オブジェクトからバイトストリームへの変換、およびその逆。
| pickletools | pickle プロトコルと pickle マシン opcode に関する詳しいコメントと、有用な関数がいくつかが入っています。
| pipes (Unix) | Python による Unix シェルパイプラインへのインタフェース。
| PixMapWrapper (Mac) | 撤廃: PixMapオブジェクトのラッパー
| pkgutil | インポートシステムのユーティリティ
| platform | 実行中プラットフォームからできるだけ多くの固有情報を取得する
| plistlib | Mac OS X plist ファイルの生成と解析
| popen2 | 撤廃: アクセス可能な I/O ストリームを持つ子プロセス生成。
| poplib | POP3 プロトコルクライアント (socketsを必要とする)
| posix (Unix) | 最も一般的な POSIX システムコール群 (通常は os モジュールを介して利用されます)。
| posixfile (Unix) | 撤廃: ロック機構をサポートするファイル類似オブジェクト。
| pprint | Data pretty printer.
| profile | Python source profiler.
| pstats | プロファイラで用いる統計情報オブジェクト
| pty (Linux) | Linux用の擬似端末を制御する
| pwd (Unix) | パスワードデータベースへのアクセスを提供する (getpwnam() など)。
| py_compile | Python ソースファイルからバイトコードファイルを生成する。
| pyclbr | Python クラスブラウザのための情報抽出サポート
| pydoc | ドキュメント生成とオンラインヘルプシステム
| q |
| Queue | 同期キュークラス
| quopri | MIME quoted-printable 形式ファイルのエンコードおよびデコード。
| r |
| random | よく知られている様々な分布をもつ擬似乱数を生成する。
| re | 正規表現操作
| readline (Unix) | Python のための GNU readline サポート。
| repr | 大きさに制限のある別のrepr()の実装。
| resource (Unix) | 現プロセスのリソース使用状態を提供するためのインタフェース。
| rexec | 撤廃: 基本的な制限実行フレームワーク。
| rfc822 | 撤廃: RFC 2822 形式のメールメッセージを解釈します。
| rlcompleter (Unix) | GNU readline ライブラリ向けのPython識別子補完
| robotparser | robots.txt ファイルを読み出し、他の URL に対する取得可能性の質問に答えるクラス。
| runpy | 先行インポートなしの Python モジュールの位置特定と実行。
| s |
| sched | 一般的な目的のためのイベントスケジューラ
| ScrolledText (Tk) | 垂直スクロールバーを持つテキストウィジェット。
| select | 複数のストリームに対して I/O 処理の完了を待機します。
| sets | 撤廃: ユニークな要素の集合の実装
| sgmllib | 撤廃: HTML を解析するのに必要な機能だけを備えた SGML パーザ。
| sha | 撤廃: NISTのセキュアハッシュアルゴリズム、SHA。
| shelve | Python オブジェクトの永続化。
| shlex | Unix シェル類似の言語に対する単純な字句解析。
| shutil | コピーを含む高レベルなファイル操作。
| signal | 非同期イベントにハンドラを設定します。
| SimpleHTTPServer | このモジュールは HTTP サーバに基本的なリクエストハンドラを提供します。
| SimpleXMLRPCServer | 基本的なXML-RPCサーバーの実装。
| site | サイト固有のモジュールを参照する標準の方法。
| smtpd | Python による SMTP サーバー実装
| smtplib | SMTP プロトコルクライアント (ソケットが必要です)。
| sndhdr | サウンドファイルの識別
| socket | 低レベルネットワークインターフェース。
| SocketServer | ネットワークサーバ構築のためのフレームワーク。
| spwd (Unix) | シャドウパスワードデータベース(getspnam() など
| sqlite3 | A DB-API 2.0 implementation using SQLite 3.x.
| ssl | ソケットオブジェクトに対する TLS/SSL ラッパー
| stat | os.stat()、os.lstat() および os.fstat() の返す内容を解釈するためのユーティリティ群。
| statvfs | 撤廃: os.statvfs() の返す値を解釈するために使われる定数群。
| string | 一般的な文字列操作
| StringIO | ファイルのように文字列を読み書きする。
| stringprep | 撤廃: RFC 3453 による文字列調製
| struct | 文字列データをパックされたバイナリデータとして解釈する.
| subprocess | サブプロセス管理
| sunau | Sun AUサウンドフォーマットへのインターフェース
| sunaudiodev (SunOS) | 撤廃: Sun オーディオハードウェアへのアクセス
| SUNAUDIODEV (SunOS) | 撤廃: sunaudiodevで使われる定数。
| symbol | 解析木の内部ノードを表す定数。
| symtable | コンパイラ内部の記号表へのインターフェイス。
| sys | システムパラメータと関数へのアクセス
| sysconfig | Python's configuration information
| syslog (Unix) | Unix syslog ライブラリルーチン群へのインタフェース。
| t |
| tabnanny | ディレクトリツリー内の Python のソースファイルで問題となる空白を検出するツール。
| tarfile | tar-形式のアーカイブファイルを読み書きします。
| telnetlib | Telnet クライアントクラス
| tempfile | 一時的なファイルやディレクトリを生成。
| termios (Unix) | POSIX スタイルの端末制御。
- | test |
|     test.test_support | Python 回帰テストのサポート
| textwrap | テキストの折り返しと詰め込み
| thread | 1つのインタープリタの中でのマルチスレッド制御
| threading | 高水準のスレッドインタフェース
| time | 時刻データへのアクセスと変換
| timeit | 小さなコード断片の実行時間計測。
| Tix | Tkinter用のTk拡張ウィジェット
| Tkinter | グラフィカルユーザインタフェースを実現する Tcl/Tk へのインタフェース
| token | 解析木の終端ノードを表す定数。
| tokenize | Pythonソースコードのための字句解析器。
| trace | Python ステートメント実行のトレースと追跡
| traceback | スタックトレースを表示または取得する。
| ttk | Tk themed widget set
| tty (Unix) | 一般的な端末制御操作のためのユーティリティ関数群。
| turtle | Tkのためのタートルグラフィックス
| types | 組み込み型の名前
| u |
| unicodedata | Access the Unicode Database.
| unittest | ユニットテストフレームワーク
| urllib | URL による任意のネットワークリソースへのアクセス (socket が必要です)。
| urllib2 | URLを開く次世代ライブラリ
| urlparse | URL の解析と構築
| user | 撤廃: ユーザー設定を参照するための標準的な方法を提供するモジュール
| UserDict | 辞書オブジェクトのためのクラスラッパー。
| UserList | リストオブジェクトのためのクラスラッパー。
| UserString | 文字列オブジェクトのためのクラスラッパー。
| uu | uuencode形式のエンコードとデコードを行う。
| uuid | RFC 4122 に準拠した UUID オブジェクト（汎用一意識別子）
| v |
| videoreader (Mac) | 撤廃: フレームの継続処理のためのQuickTime ムービーのフレーム読み込み
| w |
| W (Mac) | 撤廃: FrameWork 上に作られた Mac 用ウイジェット
| warnings | 警告メッセージを送出したり、その処理方法を制御したりします。
| wave | WAVサウンドフォーマットへのインターフェイス
| weakref | 弱参照と弱辞書のサポート。
| webbrowser | ウェウブブラウザーのための使い易いコントローラー
| whichdb | どのDBM形式のモジュールが与えられたデータベースを作ったかを推測する
| winsound (Windows) | Windows の音声再生機構へのアクセス。
- | wsgiref | WSGI ユーティリティとリファレンス実装
|     wsgiref.handlers | WSGI サーバ／ゲートウェイのベースクラス
|     wsgiref.headers | WSGI レスポンスヘッダツール群
|     wsgiref.simple_server | シンプルな WSGI HTTP サーバ
|     wsgiref.util | WSGI 環境のユーティリティ
|     wsgiref.validate | WSGI 準拠チェッカー
| x |
| xdrlib | 外部データ表現 (XDR, External Data Representation) データのエンコードおよびデコード。
- | xml |
|     xml.dom | Python のための文書オブジェクトモデル API。
|     xml.dom.minidom | 軽量な文書オブジェクトモデルの実装。
|     xml.dom.pulldom | SAX イベントからの部分的な DOM ツリー構築のサポート。
|     xml.etree.ElementTree | Implementation of the ElementTree API.
|     xml.parsers.expat | Expat による、検証を行わない XML パーザへのインタフェース
|     xml.sax | SAX2 基底クラスと有用な関数のパッケージ
|     xml.sax.handler | SAX イベント・ハンドラの基底クラス
|     xml.sax.saxutils | SAX とともに使う有用な関数とクラスです。
|     xml.sax.xmlreader | SAX 準拠の XML パーサが実装すべきインタフェースです。
| xmlrpclib | XML-RPC client access.
| z |
| zipfile | ZIP-フォーマットのアーカイブファイルを読み書きする
| zipimport | Python モジュールを ZIP アーカイブから import する機能のサポート
| zlib | gzip 互換の圧縮／解凍ルーチンへの低レベルインタフェース

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。

ナビゲーション

索引

モジュール |

Python 2.7ja1 documentation »

索引

頭文字別索引:

Symbols | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | Symbols

総索引 (大きい場合があるので注意)

© Copyright 1990-2011, Python Software Foundation. 最終更新: 2011-12-26 このドキュメントは Sphinx 1.2pre/02cb752c6a9e で生成しました。