[ python / books ] 実践Python errata
日本でも Python が広まってきたようでうれしいですね。
さて、実践 Python という Python 入門書が出版されたようなので 読み始めてみました。まだ序盤ですが、Python が純粋な OOP 言語 と紹介されていることと、エラーが多めな点を除けばいいんじゃないかと思います。
Learning Python と 実践 Python のどちらがいいのかというのは 読了まで待つとして、気づいたエラーとその訂正でも書いていこうかと思います。 わたしもまだ読んでいる途中ですので気付いたものから書いていきます。
友人から教えてもらって判明したのですが、このページが Google の Web 検索でかからないとか。
なんでも、先日の朝方までは "実践Python" で検索すると出てきたのに
いまでは全く引っかからないとか ( ほかのページは引っかかるようですが ) 。
う~ん、ここは Blog なので Blog サーチじゃないと出てこないとか?そんなところじゃないかな?
2006/12/11 AM11:05
このページが Google 八部にされていることを確認しました。
Google に URL 再登録を頼んでみましたが・・・。再度削除された場合、これに関して別エントリを書こうと思います。Google に削除要求を送ったと考えられるのは、4 つくらいあるわけだけどね。わたしは卑劣で姑息な手段が大嫌いだ。さて、どう書いてくれようか。
2006/12/11 17:42
Google に申請した再登録手続きの結果が反映された様子。現在、復帰しています。
さて、どうなるでしょうかね。
誤 | 正 |
P19 configure--help |
configure --help ( configure と --help の間に半角スペース) |
P50 Python のサンプルコード [x *10 for x in xs if not x % 2] |
[even for even in range( 1, 11 ) if even % 2 == 0] ( 関数にする必要はないんじゃないかと ) |
P71 図6-2-1-1 文字の抽出 ( 正のインデックス ) |
文字の抽出 ( 負数を使った indexing ) 右端から数えて n 番目というときは負数を使った indexing |
P78 サンプルコード a.center( len( b ) + 4 ) |
a.center( len( a ) + 4 ) len( b ) の場合エラーになります。たぶん len( a ) |
P98 サンプルコード7-2-9-1 for x, s in zip( a, b ): print x, s ↑インデントがない |
for (x, s) in zip( a, b ): print x, s |
P113 サンプルコード 8-1-3-1 >>> len((1, 2, 3)) # タブルの長さ |
# タプルの長さ tuple ( タプル ) ですよ。 (^_^ ; |
P113 表 8-1-3-1 |
リストメソッド は集合演算を行うことで確認できます。 wrapper_descriptor も含めるならいくつか増えますね。 コードは次のとおり。 list_method = set( [method for method in dir( [] ) if eval( "callable( list.%s )" % method )] ) for seq_obj in ("''", "u''", "()"): exec "list_method -= set( dir( %s ) )" % seq_obj print list( list_method ) |
P121 pop はリストの末尾要素を削除します。引数はとらずに、 リストの末尾要素を捨ててしまうのです |
list.pop() は引数とれますがな。pop() が切り出すのは末尾要素とは限りません。
help( list.pop ) でヘルプ参照してください。 list.pop() に引数を与えると次のようになります。 >>> ascend = range( 10 ) # 0~9までの整数のリスト >>> [ascend.pop( 0 ), ascend.pop( 5 )] [0, 6] >>> ascend [1, 2, 3, 4, 5, 7, 8, 9] # 切り出した要素はなくなってる 正しくは ( help() の要約だけど )↓ 「pop() は指定されたインデックスの要素を返す( return する ) と同時に、 その要素を元のリストから削除します。デフォルトではリストの最後の要素が対象です。 存在しないインデックスを指定された場合は IndexError 例外を発生させます。」 |
P137 サンプルコード 9-1-5-2 >>> print z # None ふぁ返される |
# None が返される 笑わせてもらいました (^-^;; |
P157 10-1-6 >> オブジェクトのメソッド オブジェクトの属性のうち、オブジェクトにピリオド「.」を続けることで アクセスすることができるものを「メソッド」といいます。 |
・・・・・・(;´Д`) ピリオドを続けることでアクセスすることができるものが 必ずメソッドであるとはいえません。文字列や数値の時もあります。 メソッドとは何らかの機能を持った callable なものです。 |
P165 11-3-3 複数の値を返す 複数の戻り値を変数と利用するためには、戻り値と同じ数の変数を用意して、 関数の代入を行います。 |
Python では return に続けて複数のオブジェクトを指定した場合、
それらはひとつのタプルの中にまとめられて返されることになっています。
したがって、当然のことですが、ひとつの変数で受け取ることも可能です。 >>> def multiple_value_func(): ... return "hoge", "fuge", "piyo" ... >>> cargo = multiple_value_func() >>> cargo ('hoge', 'fuge', 'piyo') return の後ろに指定したオブジェクトの数と同じ変数を用意しなければならないのは、 unpacked assignment を行ってタプルの要素をそれぞれの変数に代入するときだけです。 さらに、関数の代入とは次のようなものです。 >>> cargo = multiple_value_func #() がないことに注目 >>> cargo <function multiple_value_func at 0x1871456c> 関数を呼び出した場合には戻り値が変数に入りますが、 関数を代入した場合には関数への参照が変数に入ります。 関数の呼び出しと代入はまったく違うものです。 |
P172 構文 def 関数名( 引数リスト ): "文字列"   関数ブロック def 関数名( 引数リスト ): """文字列""" 関数ブロック |
def 関数名( 引数リスト ): 文字列リテラル 関数ブロック 関数ブロック内は、コメントや doc ストリングであっても インデントが必要になります。 |
P183 図 12-1-2-1 def class1() "This is sample class." pass |
class sample_class1( object ): "This is a sample class." pass クラスの定義は def ではなく class キーワードで開始します。 また、class ステートメントの末尾にはコロンが必要です。 |
P185 構文 12-1-5-1 dir 関数 dir( ジュールオブジェクト ) |
dir( モジュールオブジェクト ) なお、dir() はモジュールオブジェクト以外にも使うことができます。 |
P188 構文 12-1-9-1 if __name__ == '__main__': 実行する関数・オブジェクト サンプルコード 12-1-9-1 runAsProg.py if __name__ == '__main__': main() |
if __name__ == "__main__": 実行する関数・オブジェクト if __name__ == "__main__": main() 構文・サンプルコードともにインデントが不正です。 サンプルコードが間違っているので図 12-1-9-1 もおかしいです。 サンプルコードを実行すると IndentationError が返ってきます。 |
P193 コラム itertools モジュール lzip, imap, ifilter 関数 |
izip ですね。 itertools モジュールが持つ callable オブジェクトは次の式で確認できます。 [method for method in dir( itertools ) if eval( "callable( itertools.%s ) == True" % method )] |
P197 12-4-2 パッケージをインポートする インポートされたパッケージは、Python のオブジェクトとしてはモジュールとまったく module 型であることがわかります。 |
インポートされたパッケージは、Python のオブジェクトとしてはモジュールとまったく同じ module 型であることがわかります。 |
P203 13-1-4 クラスを定義する クラスの定義するには class ステートメントにより行います。( 中略 ) そしてコロン「:」を続けた後、通常は改行をインデンテーションを行ってから |
クラスの定義をするには class ステートメントを使います。( 中略 ) そしてコロン「:」を続けた後、通常は改行をしてインデンテーションを行ってから |
P218 サンプルコード 13-4-5-1 >>> len( c ) 10 |
>>> len( c ) 5 |
P219 サンプルコード 13-4-6-1 >>> class Container( object ): . . . def __init__( self, start, end ): . . . self.start = start . . . self.end = end . . . def __len__( self ): . . . return self.end ミ self.start + 1 |
>>> class Container( object ): . . . def __init__( self, start, end ): . . . self.start = self.start . . . self.end = end . . . . . . def __len__( self ): . . . return self.end - self.start + 1 ミ ってなんでしょう?そんな演算子なかった気が・・・ あと Iterator メソッドの定義にある self.pos = start では NameError がでますね。ここはインスタンスが持っている start 、つまり self.start を代入するようにしなければなりません。 |
P304 ctypes パッケージの解説 Python のオブジェクトとして直接利用できる協力な機能です。 |
強力な機能です。 |
ついでに Tips 的なものをば( ´・ω・`)
P120 リストの要素追加 append() も map() と組み合わせると複数の要素を追加できます。 None が入ったリストが標準出力に帰ってきますが orz >>> test_list = [] >>> map( test_list.append, list( "hoge" ) ) [None, None, None, None] >>> test_list ['h', 'o', 'g', 'e'] |
P123 リスト演算の違い x = x + [1] と x += [1] の違いは ID を調べることで確認できます。 x = x + [1] の場合 >>> a = [] >>> old_id = id( a ) >>> a = a + [1] >>> new_id = id( a ) >>> old_id == new_id False x += [1] の場合 >>> a = [] >>> old_id = id( a ) >>> a += [1] >>> new_id = id( a ) >>> old_id == new_id True |
P126 タプルの順序を反転する list.sort() に reverse フラグがあるように組み込み関数 sorted() にも reverse フラグがあります。これを利用してもタプルの要素の並び順を反転できます。 >>> ascend_tuple = tuple( range( 10 ) ) >>> descend_tuple = tuple( sorted( ascend_tuple, reverse=True ) ) >>> descend_tuple (9, 8, 7, 6, 5, 4, 3, 2, 1, 0) |
| 固定リンク
この記事へのコメントは終了しました。
コメント