CodeZine(コードジン)

特集ページ一覧

Python 3.0開発者ガイド:数値、文字列、データ

数値、文字列、バイナリデータの基本データ型の処理

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/06/29 14:00

 このシリーズでは前回に引き続き、Python 2.xとPython 3.0の違いを詳しく比較します。バージョンの変更により、Python 3.0のデータ型に重要な(下位互換性のない)変更が行われました。今回は、Python 3.0における数値、文字列、バイナリデータの基本データ型の処理についての解説をとおして、データ型の変更がどのようにコードに影響するかを説明します。

目次

はじめに

 このシリーズの第1回では、コア言語と型システムの重要な変更点について解説しました。今回は、Python 3.0における数値、文字列、バイナリデータの基本データ型の処理を中心に説明します。

これまでの連載

PEP 237:長整数型と整数型の統合

 Python 2.xには、intlongの2つの整数型がありました。int型は、マシンの「ネイティブ」ワードサイズ(現在の機種では32ビットまたは64ビット)に制限されます。そのためint型の演算では、オーバーフローしてOverflowError例外が発生する可能性がありました(Python 2.2より前のバージョン)。これに対し、long型はメモリ容量のみに制限され、理論的にはあらゆる整数を表現できます。

 2種類の整数型が用意されていた理由は、int型とlong型にそれぞれ異なる特徴があったからです。int型はハードウェアとOSで直接サポートされるため非常に効率的であり、一方、long型は柔軟性があって開発者が値のサイズを監視する必要がありません。しかし、アーキテクチャの異なるマシン間でPythonのコンパイル済みファイルやpickle化オブジェクトを移植する場合には、型が2種類あることで問題が発生します。

 PEP-237の目的は、これら2つの型を1つの整数型に統合し、可能な場合にはより効率的なマシン整数型を使用するよう内部的に変化させることです。これは、実のところ4つのバージョンで段階的に実装され、2.2、2.3、2.4を経て3.0で完了しました。

 Python 2.4以上では、例外も警告も発生させない、intからlongへの自動昇格が既にサポートされています。Python 3.0では、単にPythonレベルでlong型とlongリテラルをなくしただけです。Python 3.0でlongを使用しようとすると、次のようなエラーが発生します。

>>> long
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'long' is not defined

 Python 3.0では、long用のLサフィックスも削除されました。現在は整数はすべてint型です。Python 2.5では次のコードは有効ですが、

>>> 5L
5L

 Python 3.0では構文エラーになります。

>>> 5L
  File "<stdin>", line 1
    5L
     ^
SyntaxError: invalid syntax

 Python 2.5では、次のコードはlongオブジェクトを生成しますが、

>>> x = 5 ** 88
>>> type(x)
<type 'long'>
>>> x
32311742677852643549664402033982923967414535582065582275390625L

 Python 3.0ではintになります。

>>> x = 5 ** 88
>>> type(x)
<class 'int'>
>>> x
32311742677852643549664402033982923967414535582065582275390625

PEP 3127:整数リテラルのサポートと構文

 Pythonでは以前から、整数の基数を広範にサポートしてきました。Python 2.5のint()関数とlong()関数は、第2引数として変換元の基数を受け取ります。この基数には、2~36の整数を指定できます。

>>> int('000111', 2)
7

>>> int('000111', 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: int() base must be >= 2 and <= 36

>>> int('000111', 36)
1333
TypeError: long() can't convert non-string with explicit base

>>> long('555555555555555555555555555555555555555', 6)
2227915756473955677973140996095L

 Python 3.0でもこの機能は維持されています(ただし、エラーメッセージでは、baseの代わりにarg 2と示されます)。

>>> int('0001111', 2)
15

>>> int('5', 36)
5

>>> int('5', 37)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: int() arg 2 must be >= 2 and <= 36

 Python 2.5では、8進と16進の整数リテラルもサポートしており、整数を指定するところでは、8進値または16進値も指定できます。8進値には0123のように先頭に数字のゼロを付け、16進値には0x123のように先頭に数字のゼロと文字xまたはXを付けます。また、oct()hex()という2つの関数もあります。どちらも整数を受け取り、それぞれ8進値または16進値の文字列表現を返します。次に例を示します。

>>> 010
8
>>> 010 + 8
16
>>> 0xa
10
>>> 0xa + 010 + 2
20
>>> oct(20)
'024'
>>> hex(20)
'0x14'

 Python 3.0でもこれらの機能はすべて維持されますが、1つだけ小さな変更があります。8進値のプレフィックスは、先頭に数字のゼロと文字oまたはOを付けるように変更されました。従って、これまで0123のように書いていたものが0O123という表記になります。数字のゼロ1文字を付けるという以前の表記は、C言語に由来する表記です。今回の変更は、C系列の言語や8進値になじみのない開発者の混乱を防ぐ効果があります。そのような開発者は、先頭にゼロを付けても値は変わらないと誤解しやすく、例えば、書式を整えたり、インデントを揃えたりする目的で先頭にゼロを付けることで、予期しない値を設定してしまう可能性がありました。また、Python 3.0では、2進リテラルも追加されました。このように、Cの遺産から脱却することによって、整数リテラルの基数表現が統一され、基数2、8、16(2進数、8進数、16進数)のプレフィックスは、それぞれ0b0o0xとなります。

>>> 0b10
2

>>> 0o10
8

>>> 0x10
16

 また、新しいbin()関数も追加されました。これは、整数を2進文字列表現に変換します(oct()hex()と同様の機能です)。

>>> bin(5)
'0b101'

>>> bin(0x10)
'0b10000'

>>> bin(0o10)
'0b1000'

 当然、oct()関数でも、Python 2.5の0プレフィックスではなく、新しい0oプレフィックスが使用されます。

>>> oct(12)
'0o14'

 この変更は、全体から見れば小さな変更ですが、すっきりと洗練された、いいことずくめの解決策だと思います。新しいユーザーの障害を取り除き、過去(C言語の8進表記)のしがらみから離れ、その上、基数リテラルの表現が統一されたことで、新しい2進リテラルの追加にとっても重要な改善となっています。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:japan.internet.com翻訳記事

もっと読む

著者プロフィール

  • japan.internet.com(ジャパンインターネットコム)

    japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.com や EarthWeb.c...

  • Gigi Sayfan(Gigi Sayfan)

     主に大規模分散システムを対象とした、C/C++/C#/Python/Javaによるクロスプラットフォームのオブジェクト指向プログラミングに精通。現在は、Numenta社で脳の働きを模した人工知能システムの開発に取り組んでいる。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5