2013-04-10 16 views
10

私はWindows 64bitでPython 3.3.0を使用しています。Python file.tell()は奇妙な数値を返しますか?

下図のように私は、テキストファイルを持っている:(MediaFireをでダウンロードリンクのために下を参照)

hello 

-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah 


-data2:blah blah blah blah blah blah blah blah blah blah blah 
-data3: Empty 

-data4: Empty 

私は、ファイルをナビゲートしようとしているので、私は何を私の位置を把握するために.tell()を使用です。以下に示すように、ファイルの行を読んしかし、私は非常に奇妙な結果が得られます。

f=open("test.txt") 
while True: 
    a = f.readline() 
    print("{} {}".format(repr(a),f.tell())) 
    if a == "": 
     break 

結果:3行目のため18446744073709551714で何

'hello\n' 7 
'\n' 9 
'-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah bl 
ah blah\n' 18446744073709551714 
'\n' 99 
'\n' 101 
'-data2:blah blah blah blah blah blah blah blah blah blah blah\n' 164 
'-data3: Empty\n' 179 
'\n' 181 
'-data4: Empty' 194 
'' 194 

?それは不可能な価値のように見えますが、f.seek(18446744073709551714)は3行目の終わりまで私を連れて来るかもしれません。しかし、私は理由を理解できないようです。

はEDITは:バイナリモードで オープニングtell()で何の問題も与えない:

f=open("test.txt","rb") 
while True: 
    a = f.readline() 
    print("{} {}".format(repr(a),f.tell())) 
    if a == b"": 
     break 

結果:

b'hello\r\n' 7 
b'\r\n' 9 
b'-data1:blah blah blah blah blah blah blah blah blah blah blah blah blah blah b 
lah blah\r\n' 97 
b'\r\n' 99 
b'\r\n' 101 
b'-data2:blah blah blah blah blah blah blah blah blah blah blah\r\n' 164 
b'-data3: Empty\r\n' 179 
b'\r\n' 181 
b'-data4: Empty' 194 
b'' 194 

test.txtというテキストファイルがここで、ほんの194バイトダウンロード可能です: http://www.mediafire.com/?1wm4lujb2j48y23

答えて

8

これは、UNIXスタイルの行末に起因する文書化された動作です。

さん ftell()よう

file.tell()

戻るファイルの現在位置、。

:Unix形式の行末のファイルを読み込むときにWindowsでは、tell()は(fgets()後の)不正な値を返すことができます。この問題を回避するには、バイナリモード ( 'rb')を使用してください。


上記ドキュメントはpython2.7.4ドキュメントから取られます。 I/Oを扱うクラスの階層があり、私はこの情報のビットを見つけることができないので、python3のドキュメントは少し変更されました。あなたのテストは、その行動がとにかく変わらないことを示しています。 python3.3のソースコードには、tellという関数の前に、XXX Windows support below is likely incompleteというコメントがあります。


は、これに関連するPythonのバグトラッカーでissueがあり、そしてカタリンIacobによる最終のコメントは以下のとおりです。

私は、これを再現しようとした私のディスク上のファイルをピックアップし、実際に私が得ましたa 負の数ですが、そのファイルにはUnixの行末があります。これは であり、http://docs.python.org/2/library/stdtypes.html#file.tell に記載されているので、おそらく何もしません。 http://msdn.microsoft.com/en-us/library/0ys3hc0b%28v=vs.100%29.aspxの備考 セクションに記載されているように、それは直感的ではないにもかかわらずmsg180145でアーミンの報告書については

、 これは、Windows上でのftellの行動と一致します。 fileobjectsのtell()メソッドは、 ftellの動作と一致すると明示的に文書化されています: "stdioの ftell()"のようなファイルの現在の位置を返します。だから、たとえそれが直感的ではないとしても、おそらくそれをそのまま残すほうが良いでしょう。 tell()は、 の直感的な位置を返します。これは、Python3では 'a'で開き、 io.openを使用するとPython 2.7で開くので、今後とも修正されます。

これは「不具合」バグのようです。 誰かがおそらく問題(問題をコメントしました)を開くべきです。なぜなら、この事実はpython3のドキュメントで全く言及されていないからです。


Antoine Pitrouのpython3によるので、これは別のバグのようです、全くftell()を使用していません。最終編集


(少なくとも、それは私が3.2.3と3.3の間 tell()の実装に見つけることができる唯一の変更です)またバグがpython3.2.3では再現できないと、この issueを固定する際、おそらく導入されました: ioモジュールのドキュメントによると、 tellメソッドは ではありません。はファイルの先頭からバイト数を返します。戻り値は「不透明な数値」です。つまり、使用できる唯一の方法は、その位置に戻るために seekに渡すことです。他の操作は意味がありません。実際にpython3.2.3まで返された値は、実装の詳細だけだったと思います。

ドキュメントのthisセクションの情報は、単にが間違っています。であり、将来的には修正される予定です。

+0

お待ちください。メモ帳を使用してテキストファイルを作成しました。そして、notepad2を使用してラインの終わりを表示すると、私はCR + LFを見ています。 Unixの行末はLFだけですか? 私のテストファイルで微調整した後、明らかに、長い行がこの問題を起こしやすくなります。 – Eric

+0

@EricあなたはPythonからバイナリモードでファイルを開き、その内容を見ましたか?また、ファイルの内容を投稿したり、ファイルをどこかにアップロードしてテストすることもできますか? AFAIKの鉱山は賢明な説明であり、私はpythonのファイルが正しいと強く信じています。だから、問題は単にftell()の呼び出しがゴミを返すということだけです。 – Bakuriu

+0

元の質問をバイナリモードで編集し、テキストファイルをmediafireにアップロードしました。 – Eric

関連する問題