SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

PEP 3141:数値の型階層

 Python 3.0では、numbersというモジュールが導入されました(Python 2.6にもあります)。このモジュールには、各数値型の抽象ベースクラス(ABC)が含まれています。これによって実質的に数値型の階層が形成され、各数値型は上位の数値型クラスのサブクラスになります。この階層は、SchemeのNumeric Towerをヒントにしています。NumberComplexRealRationalIntegralの5種類のABCがあります。それぞれのクラス(Numberを除く)は前のクラスのサブクラスです。例えば、IntegralRationalのサブタイプです。すべての整数Xは有理数X/1、つまり、Xを分子、1を分母とする有理数と見なすことができます。

 ベースクラスNumberは、実際のどの数値型とも対応していません。このクラスは、ある値が数値であるかどうかを検査する場合に備えて用意されています。通常、数値かどうかを調べるには、numbers.Complexのサブクラスであることを確認できれば十分ですが、NumberクラスとComplexクラスの間に、Complexのサブクラスではない新しい数値を作成するようなまれなケースでは、Numberクラスが必要になります。

 ComplexRealIntegralのABCは、それぞれcomplex型、float型、int型によって実装されています。

>>> issubclass(int, numbers.Integral)
True

>>> issubclass(float, numbers.Real)
True

>>> issubclass(complex, numbers.Complex)
True

>>> issubclass(complex, numbers.Real)
False

 RationalのABCは、新しいfractionsモジュールのfractions.Fraction型によって実装されています。このモジュールには、最大公約数を求めるためのgcdメソッドと、変換関数from_float()from_decimal()もあります。言語に有理数の数値型を追加する方がすっきりして一貫性があると思われますが、モジュールの1クラスになりました。

>>> issubclass(fractions.Fraction, numbers.Rational)
True

>>> fractions.gcd(Fraction(1,3), Fraction(1,2))
Fraction(1, 6)

>>> fractions.gcd(Fraction(2,6), Fraction(2,3))
Fraction(1, 3)

>>> fractions.gcd(6,9)
3

>>> Fraction.from_float(0.5)
Fraction(1, 2)

>>> import math
>>> Fraction.from_float(math.pi)
Fraction(884279719003555, 281474976710656)

>>> Fraction.from_decimal(decimal.Decimal('3.5'))
Fraction(7, 2)

 固定小数点数と浮動小数点数の算術用のdecimalモジュールのDecimalクラス(Python 2.4で導入されました)は、これには関与せず、数値のABCクラスを実装していません。PEP-3141によると、decimalモジュールの開発者たちと相談した結果、今回は導入を見送る方がよいと決定されたとのことです。

 数値型がこのように準形式化されたことによって、特定の数値型を引数とする関数が可能になり、引数の検査がより容易になりました。

 例えば、ある数値にその数値を乗算するsquare()という関数を作成するとします。ただし、演算は実数の範囲内とし、結果は常に正の値になるものとします。型を検査しない単純な実装は次のようになります。

def square(x):
  return x * x

 このコードでは、複素数を指定したとき、正の値が返されません。

>>> square(complex(0,1))
(-1+0j)

 引数がintfloatであることを明示的に検査しようとすると、あまり洗練されていないコードになります。有理数にも対応しようとすればなおさらです。

>>> def square(x):
...   assert type(x) == int or \
...          type(x) == float or \
...          type(x) == Fraction
...   return x * x
... 
>>> from fractions import Fraction
>>> square(5)
25

>>> square(4.4)
19.360000000000003

>>> square(Fraction(1,3))
Fraction(1, 9)

>>> square(complex(0,1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in square
AssertionError

 この場合、既存の型またはnumbersモジュールのいずれかのABCクラスからサブクラス化して、独自の数値型を作るという方法があります。そうすれば、その新しい独自の数値型を受け取るコードで、渡された引数をABCに基づいて検査できます。これは、例えば、特定範囲内の整数、または有効桁数が限られた固定小数点セマンティクスの実数を処理する場合に有効です。ABC準拠のクラスには大量のメソッドの実装が必要になるので、ここでは完全なコード例は示しません。

次のページ
すべての文字列のUnicode化

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

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

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Gigi Sayfan(Gigi Sayfan)

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

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4052 2009/06/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング