[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1
b'C:\\py3000'
b'C:\\py3000\\FutureProofPython - PythonInfo Wiki_files'
b'C:\\py3000\\Oakwinter_com Code \xbb Porting setuptools to py3k_files'
b'C:\\py3000\\What\x92s New in Python 3_0 \x97 Python Documentation'

>>> for (dir, subs, files) in os.walk(root): print(dir.encode())
...
b'C:\\py3000'
b'C:\\py3000\\FutureProofPython - PythonInfo Wiki_files'
b'C:\\py3000\\Oakwinter_com Code \xc2\xbb Porting setuptools to py3k_files'
b'C:\\py3000\\What\xe2\x80\x99s New in Python 3_0 \xe2\x80\x94 Python Documentation'

Unfortunately, either approach means that all the directory names printed during the
walk display as cryptic byte strings. To maintain the better readability of normal strings,
I instead opted for the exception handler approach used in the script’s code. This avoids
the issues entirely:


>>> for (dir, subs, files) in os.walk(root):
... try:
... print(dir)
... except UnicodeEncodeError:
... print(dir.encode()) # or simply punt if enocde may fail too
...
C:\py3000
C:\py3000\FutureProofPython - PythonInfo Wiki_files
C:\py3000\Oakwinter_com Code » Porting setuptools to py3k_files
b'C:\\py3000\\What\xe2\x80\x99s New in Python 3_0 \xe2\x80\x94 Python Documentation'

Oddly, though, the error seems more related to printing than to Unicode encodings of
filenames—because the filename did not fail until printed, it must have been decodable
when its string was created initially. That’s why wrapping up the print in a try suffices;
otherwise, the error would occur earlier.


Moreover, this error does not occur if the script’s output is redirected to a file, either
at the shell level (bigext-tree.py c:\ > out), or by the print call itself (print(dir,
file=F)). In the latter case the output file must later be read back in binary mode, as
text mode triggers the same error when printing the file’s content to the shell window
(but again, not until printed). In fact, the exact same code that fails when run in a system
shell Command Prompt on Windows works without error when run in the IDLE GUI
on the same platform—the tkinter GUI used by IDLE handles display of characters that
printing to standard output connected to a shell terminal window does not:


>>> import os # run in IDLE (a tkinter GUI), not system shell
>>> root = r'C:\py3000'
>>> for (dir, subs, files) in os.walk(root): print(dir)

C:\py3000
C:\py3000\FutureProofPython - PythonInfo Wiki_files
C:\py3000\Oakwinter_com Code » Porting setuptools to py3k_files
C:\py3000\What's New in Python 3_0 — Python Documentation_files

In other words, the exception occurs only when printing to a shell window, and long
after the file name string is created. This reflects an artifact of extra translations


A Quick Game of “Find the Biggest Python File” | 281
Free download pdf