mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
converted case-study-porting-chardet-to-python-3 to HTML
This commit is contained in:
@@ -0,0 +1,701 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Case study: porting chardet to Python 3 - Dive into Python 3</title>
|
||||
<link rel="stylesheet" type="text/css" href="dip3.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Case study: porting chardet to Python 3</h1>
|
||||
|
||||
<ul class="toc">
|
||||
<li><a href="#running2to3">Running <code class="filename">2to3</code></a></li>
|
||||
<li><a href="#falseisinvalidsyntax"><code>False</code> is invalid syntax</a></li>
|
||||
<li><a href="#namefileisnotdefined">Name '<var>file</var>' is not defined</a></li>
|
||||
<li><a href="#cantconvertbytesobject">Can't convert '<code>bytes</code>' object to <code>str</code> implicitly</a></li>
|
||||
</ul>
|
||||
|
||||
<section id="running2to3">
|
||||
|
||||
<h2>Running <code class="filename">2to3</code></h2>
|
||||
|
||||
<p>We're going to migrate the <code class="filename">chardet</code> module from Python 2 to Python 3. Python 3 comes with a utility script to help with this, called <code class="filename">2to3</code>. <code class="filename">2to3</code> takes your actual Python 2 source code as input, and auto-converts as much as it can to Python 3. [FIXME reference 2to3 chapter once it's done]</p>
|
||||
|
||||
<p>The <code class="filename">chardet</code> library is split across several different files, all in the same directory. The <code class="filename">2to3</code> script makes it easy to convert multiple files at once: just pass a directory as a command line argument, and <code class="filename">2to3</code> will convert each of the files in turn.</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python c:\Python30\Tools\Scripts\2to3.py -w chardet\</kbd>
|
||||
<samp>RefactoringTool: Skipping implicit fixer: buffer
|
||||
RefactoringTool: Skipping implicit fixer: idioms
|
||||
RefactoringTool: Skipping implicit fixer: set_literal
|
||||
RefactoringTool: Skipping implicit fixer: ws_comma
|
||||
--- chardet\__init__.py (original)
|
||||
+++ chardet\__init__.py (refactored)
|
||||
@@ -18,7 +18,7 @@
|
||||
__version__ = "1.0.1"
|
||||
|
||||
def detect(aBuf):
|
||||
- import universaldetector
|
||||
+ from . import universaldetector
|
||||
u = universaldetector.UniversalDetector()
|
||||
u.reset()
|
||||
u.feed(aBuf)
|
||||
--- chardet\big5prober.py (original)
|
||||
+++ chardet\big5prober.py (refactored)
|
||||
@@ -25,10 +25,10 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import Big5DistributionAnalysis
|
||||
-from mbcssm import Big5SMModel
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import Big5DistributionAnalysis
|
||||
+from .mbcssm import Big5SMModel
|
||||
|
||||
class Big5Prober(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\chardistribution.py (original)
|
||||
+++ chardet\chardistribution.py (refactored)
|
||||
@@ -25,12 +25,12 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
-from euctwfreq import EUCTWCharToFreqOrder, EUCTW_TABLE_SIZE, EUCTW_TYPICAL_DISTRIBUTION_RATIO
|
||||
-from euckrfreq import EUCKRCharToFreqOrder, EUCKR_TABLE_SIZE, EUCKR_TYPICAL_DISTRIBUTION_RATIO
|
||||
-from gb2312freq import GB2312CharToFreqOrder, GB2312_TABLE_SIZE, GB2312_TYPICAL_DISTRIBUTION_RATIO
|
||||
-from big5freq import Big5CharToFreqOrder, BIG5_TABLE_SIZE, BIG5_TYPICAL_DISTRIBUTION_RATIO
|
||||
-from jisfreq import JISCharToFreqOrder, JIS_TABLE_SIZE, JIS_TYPICAL_DISTRIBUTION_RATIO
|
||||
+from . import constants
|
||||
+from .euctwfreq import EUCTWCharToFreqOrder, EUCTW_TABLE_SIZE, EUCTW_TYPICAL_DISTRIBUTION_RATIO
|
||||
+from .euckrfreq import EUCKRCharToFreqOrder, EUCKR_TABLE_SIZE, EUCKR_TYPICAL_DISTRIBUTION_RATIO
|
||||
+from .gb2312freq import GB2312CharToFreqOrder, GB2312_TABLE_SIZE, GB2312_TYPICAL_DISTRIBUTION_RATIO
|
||||
+from .big5freq import Big5CharToFreqOrder, BIG5_TABLE_SIZE, BIG5_TYPICAL_DISTRIBUTION_RATIO
|
||||
+from .jisfreq import JISCharToFreqOrder, JIS_TABLE_SIZE, JIS_TYPICAL_DISTRIBUTION_RATIO
|
||||
|
||||
ENOUGH_DATA_THRESHOLD = 1024
|
||||
SURE_YES = 0.99
|
||||
--- chardet\charsetgroupprober.py (original)
|
||||
+++ chardet\charsetgroupprober.py (refactored)
|
||||
@@ -26,7 +26,7 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from charsetprober import CharSetProber
|
||||
+from .charsetprober import CharSetProber
|
||||
|
||||
class CharSetGroupProber(CharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\codingstatemachine.py (original)
|
||||
+++ chardet\codingstatemachine.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from constants import eStart, eError, eItsMe
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
|
||||
class CodingStateMachine:
|
||||
def __init__(self, sm):
|
||||
--- chardet\constants.py (original)
|
||||
+++ chardet\constants.py (refactored)
|
||||
@@ -38,10 +38,10 @@
|
||||
|
||||
SHORTCUT_THRESHOLD = 0.95
|
||||
|
||||
-import __builtin__
|
||||
+import builtins
|
||||
if not hasattr(__builtin__, 'False'):
|
||||
False = 0
|
||||
True = 1
|
||||
else:
|
||||
- False = __builtin__.False
|
||||
- True = __builtin__.True
|
||||
+ False = builtins.False
|
||||
+ True = builtins.True
|
||||
--- chardet\escprober.py (original)
|
||||
+++ chardet\escprober.py (refactored)
|
||||
@@ -26,9 +26,9 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from escsm import HZSMModel, ISO2022CNSMModel, ISO2022JPSMModel, ISO2022KRSMModel
|
||||
-from charsetprober import CharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
+from .escsm import HZSMModel, ISO2022CNSMModel, ISO2022JPSMModel, ISO2022KRSMModel
|
||||
+from .charsetprober import CharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
|
||||
class EscCharSetProber(CharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\escsm.py (original)
|
||||
+++ chardet\escsm.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from constants import eStart, eError, eItsMe
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
|
||||
HZ_cls = ( \
|
||||
1,0,0,0,0,0,0,0, # 00 - 07
|
||||
--- chardet\eucjpprober.py (original)
|
||||
+++ chardet\eucjpprober.py (refactored)
|
||||
@@ -26,12 +26,12 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from constants import eStart, eError, eItsMe
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import EUCJPDistributionAnalysis
|
||||
-from jpcntx import EUCJPContextAnalysis
|
||||
-from mbcssm import EUCJPSMModel
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import EUCJPDistributionAnalysis
|
||||
+from .jpcntx import EUCJPContextAnalysis
|
||||
+from .mbcssm import EUCJPSMModel
|
||||
|
||||
class EUCJPProber(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\euckrprober.py (original)
|
||||
+++ chardet\euckrprober.py (refactored)
|
||||
@@ -25,10 +25,10 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import EUCKRDistributionAnalysis
|
||||
-from mbcssm import EUCKRSMModel
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import EUCKRDistributionAnalysis
|
||||
+from .mbcssm import EUCKRSMModel
|
||||
|
||||
class EUCKRProber(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\euctwprober.py (original)
|
||||
+++ chardet\euctwprober.py (refactored)
|
||||
@@ -25,10 +25,10 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import EUCTWDistributionAnalysis
|
||||
-from mbcssm import EUCTWSMModel
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import EUCTWDistributionAnalysis
|
||||
+from .mbcssm import EUCTWSMModel
|
||||
|
||||
class EUCTWProber(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\gb2312prober.py (original)
|
||||
+++ chardet\gb2312prober.py (refactored)
|
||||
@@ -25,10 +25,10 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import GB2312DistributionAnalysis
|
||||
-from mbcssm import GB2312SMModel
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import GB2312DistributionAnalysis
|
||||
+from .mbcssm import GB2312SMModel
|
||||
|
||||
class GB2312Prober(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\hebrewprober.py (original)
|
||||
+++ chardet\hebrewprober.py (refactored)
|
||||
@@ -25,8 +25,8 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from charsetprober import CharSetProber
|
||||
-import constants
|
||||
+from .charsetprober import CharSetProber
|
||||
+from . import constants
|
||||
|
||||
# This prober doesn't actually recognize a language or a charset.
|
||||
# It is a helper prober for the use of the Hebrew model probers
|
||||
--- chardet\jpcntx.py (original)
|
||||
+++ chardet\jpcntx.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
NUM_OF_CATEGORY = 6
|
||||
DONT_KNOW = -1
|
||||
--- chardet\langbulgarianmodel.py (original)
|
||||
+++ chardet\langbulgarianmodel.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# 255: Control characters that usually does not exist in any text
|
||||
# 254: Carriage/Return
|
||||
--- chardet\langcyrillicmodel.py (original)
|
||||
+++ chardet\langcyrillicmodel.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# KOI8-R language model
|
||||
# Character Mapping Table:
|
||||
--- chardet\langgreekmodel.py (original)
|
||||
+++ chardet\langgreekmodel.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# 255: Control characters that usually does not exist in any text
|
||||
# 254: Carriage/Return
|
||||
--- chardet\langhebrewmodel.py (original)
|
||||
+++ chardet\langhebrewmodel.py (refactored)
|
||||
@@ -27,7 +27,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# 255: Control characters that usually does not exist in any text
|
||||
# 254: Carriage/Return
|
||||
--- chardet\langhungarianmodel.py (original)
|
||||
+++ chardet\langhungarianmodel.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# 255: Control characters that usually does not exist in any text
|
||||
# 254: Carriage/Return
|
||||
--- chardet\langthaimodel.py (original)
|
||||
+++ chardet\langthaimodel.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-import constants
|
||||
+from . import constants
|
||||
|
||||
# 255: Control characters that usually does not exist in any text
|
||||
# 254: Carriage/Return
|
||||
--- chardet\latin1prober.py (original)
|
||||
+++ chardet\latin1prober.py (refactored)
|
||||
@@ -26,8 +26,8 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from charsetprober import CharSetProber
|
||||
-import constants
|
||||
+from .charsetprober import CharSetProber
|
||||
+from . import constants
|
||||
import operator
|
||||
|
||||
FREQ_CAT_NUM = 4
|
||||
--- chardet\mbcharsetprober.py (original)
|
||||
+++ chardet\mbcharsetprober.py (refactored)
|
||||
@@ -28,8 +28,8 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from constants import eStart, eError, eItsMe
|
||||
-from charsetprober import CharSetProber
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
+from .charsetprober import CharSetProber
|
||||
|
||||
class MultiByteCharSetProber(CharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\mbcsgroupprober.py (original)
|
||||
+++ chardet\mbcsgroupprober.py (refactored)
|
||||
@@ -27,14 +27,14 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from charsetgroupprober import CharSetGroupProber
|
||||
-from utf8prober import UTF8Prober
|
||||
-from sjisprober import SJISProber
|
||||
-from eucjpprober import EUCJPProber
|
||||
-from gb2312prober import GB2312Prober
|
||||
-from euckrprober import EUCKRProber
|
||||
-from big5prober import Big5Prober
|
||||
-from euctwprober import EUCTWProber
|
||||
+from .charsetgroupprober import CharSetGroupProber
|
||||
+from .utf8prober import UTF8Prober
|
||||
+from .sjisprober import SJISProber
|
||||
+from .eucjpprober import EUCJPProber
|
||||
+from .gb2312prober import GB2312Prober
|
||||
+from .euckrprober import EUCKRProber
|
||||
+from .big5prober import Big5Prober
|
||||
+from .euctwprober import EUCTWProber
|
||||
|
||||
class MBCSGroupProber(CharSetGroupProber):
|
||||
def __init__(self):
|
||||
--- chardet\mbcssm.py (original)
|
||||
+++ chardet\mbcssm.py (refactored)
|
||||
@@ -25,7 +25,7 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from constants import eStart, eError, eItsMe
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
|
||||
# BIG5
|
||||
|
||||
--- chardet\sbcharsetprober.py (original)
|
||||
+++ chardet\sbcharsetprober.py (refactored)
|
||||
@@ -27,7 +27,7 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from charsetprober import CharSetProber
|
||||
+from .charsetprober import CharSetProber
|
||||
|
||||
SAMPLE_SIZE = 64
|
||||
SB_ENOUGH_REL_THRESHOLD = 1024
|
||||
--- chardet\sbcsgroupprober.py (original)
|
||||
+++ chardet\sbcsgroupprober.py (refactored)
|
||||
@@ -27,15 +27,15 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from charsetgroupprober import CharSetGroupProber
|
||||
-from sbcharsetprober import SingleByteCharSetProber
|
||||
-from langcyrillicmodel import Win1251CyrillicModel, Koi8rModel, Latin5CyrillicModel, MacCyrillicModel, Ibm866Model, Ibm855Model
|
||||
-from langgreekmodel import Latin7GreekModel, Win1253GreekModel
|
||||
-from langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel
|
||||
-from langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel
|
||||
-from langthaimodel import TIS620ThaiModel
|
||||
-from langhebrewmodel import Win1255HebrewModel
|
||||
-from hebrewprober import HebrewProber
|
||||
+from .charsetgroupprober import CharSetGroupProber
|
||||
+from .sbcharsetprober import SingleByteCharSetProber
|
||||
+from .langcyrillicmodel import Win1251CyrillicModel, Koi8rModel, Latin5CyrillicModel, MacCyrillicModel, Ibm866Model, Ibm855Model
|
||||
+from .langgreekmodel import Latin7GreekModel, Win1253GreekModel
|
||||
+from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel
|
||||
+from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel
|
||||
+from .langthaimodel import TIS620ThaiModel
|
||||
+from .langhebrewmodel import Win1255HebrewModel
|
||||
+from .hebrewprober import HebrewProber
|
||||
|
||||
class SBCSGroupProber(CharSetGroupProber):
|
||||
def __init__(self):
|
||||
--- chardet\sjisprober.py (original)
|
||||
+++ chardet\sjisprober.py (refactored)
|
||||
@@ -25,13 +25,13 @@
|
||||
# 02110-1301 USA
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
-from mbcharsetprober import MultiByteCharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from chardistribution import SJISDistributionAnalysis
|
||||
-from jpcntx import SJISContextAnalysis
|
||||
-from mbcssm import SJISSMModel
|
||||
+from .mbcharsetprober import MultiByteCharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .chardistribution import SJISDistributionAnalysis
|
||||
+from .jpcntx import SJISContextAnalysis
|
||||
+from .mbcssm import SJISSMModel
|
||||
import constants, sys
|
||||
-from constants import eStart, eError, eItsMe
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
|
||||
class SJISProber(MultiByteCharSetProber):
|
||||
def __init__(self):
|
||||
--- chardet\universaldetector.py (original)
|
||||
+++ chardet\universaldetector.py (refactored)
|
||||
@@ -27,10 +27,10 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from latin1prober import Latin1Prober # windows-1252
|
||||
-from mbcsgroupprober import MBCSGroupProber # multi-byte character sets
|
||||
-from sbcsgroupprober import SBCSGroupProber # single-byte character sets
|
||||
-from escprober import EscCharSetProber # ISO-2122, etc.
|
||||
+from .latin1prober import Latin1Prober # windows-1252
|
||||
+from .mbcsgroupprober import MBCSGroupProber # multi-byte character sets
|
||||
+from .sbcsgroupprober import SBCSGroupProber # single-byte character sets
|
||||
+from .escprober import EscCharSetProber # ISO-2122, etc.
|
||||
import re
|
||||
|
||||
MINIMUM_THRESHOLD = 0.20
|
||||
--- chardet\utf8prober.py (original)
|
||||
+++ chardet\utf8prober.py (refactored)
|
||||
@@ -26,10 +26,10 @@
|
||||
######################### END LICENSE BLOCK #########################
|
||||
|
||||
import constants, sys
|
||||
-from constants import eStart, eError, eItsMe
|
||||
-from charsetprober import CharSetProber
|
||||
-from codingstatemachine import CodingStateMachine
|
||||
-from mbcssm import UTF8SMModel
|
||||
+from .constants import eStart, eError, eItsMe
|
||||
+from .charsetprober import CharSetProber
|
||||
+from .codingstatemachine import CodingStateMachine
|
||||
+from .mbcssm import UTF8SMModel
|
||||
|
||||
ONE_CHAR_PROB = 0.5
|
||||
|
||||
RefactoringTool: Files that were modified:
|
||||
RefactoringTool: chardet\__init__.py
|
||||
RefactoringTool: chardet\big5prober.py
|
||||
RefactoringTool: chardet\chardistribution.py
|
||||
RefactoringTool: chardet\charsetgroupprober.py
|
||||
RefactoringTool: chardet\codingstatemachine.py
|
||||
RefactoringTool: chardet\constants.py
|
||||
RefactoringTool: chardet\escprober.py
|
||||
RefactoringTool: chardet\escsm.py
|
||||
RefactoringTool: chardet\eucjpprober.py
|
||||
RefactoringTool: chardet\euckrprober.py
|
||||
RefactoringTool: chardet\euctwprober.py
|
||||
RefactoringTool: chardet\gb2312prober.py
|
||||
RefactoringTool: chardet\hebrewprober.py
|
||||
RefactoringTool: chardet\jpcntx.py
|
||||
RefactoringTool: chardet\langbulgarianmodel.py
|
||||
RefactoringTool: chardet\langcyrillicmodel.py
|
||||
RefactoringTool: chardet\langgreekmodel.py
|
||||
RefactoringTool: chardet\langhebrewmodel.py
|
||||
RefactoringTool: chardet\langhungarianmodel.py
|
||||
RefactoringTool: chardet\langthaimodel.py
|
||||
RefactoringTool: chardet\latin1prober.py
|
||||
RefactoringTool: chardet\mbcharsetprober.py
|
||||
RefactoringTool: chardet\mbcsgroupprober.py
|
||||
RefactoringTool: chardet\mbcssm.py
|
||||
RefactoringTool: chardet\sbcharsetprober.py
|
||||
RefactoringTool: chardet\sbcsgroupprober.py
|
||||
RefactoringTool: chardet\sjisprober.py
|
||||
RefactoringTool: chardet\universaldetector.py
|
||||
RefactoringTool: chardet\utf8prober.py</samp></pre>
|
||||
|
||||
<p>Now run the <code class="filename">2to3</code> script on the testing harness, <code class="filename">test.py</code>.</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python c:\Python30\Tools\Scripts\2to3.py -w test.py</kbd>
|
||||
<samp>RefactoringTool: Skipping implicit fixer: buffer
|
||||
RefactoringTool: Skipping implicit fixer: idioms
|
||||
RefactoringTool: Skipping implicit fixer: set_literal
|
||||
RefactoringTool: Skipping implicit fixer: ws_comma
|
||||
--- test.py (original)
|
||||
+++ test.py (refactored)
|
||||
@@ -4,7 +4,7 @@
|
||||
count = 0
|
||||
u = UniversalDetector()
|
||||
for f in glob.glob(sys.argv[1]):
|
||||
- print f.ljust(60),
|
||||
+ print(f.ljust(60), end=' ')
|
||||
u.reset()
|
||||
for line in file(f, 'rb'):
|
||||
u.feed(line)
|
||||
@@ -12,8 +12,8 @@
|
||||
u.close()
|
||||
result = u.result
|
||||
if result['encoding']:
|
||||
- print result['encoding'], 'with confidence', result['confidence']
|
||||
+ print(result['encoding'], 'with confidence', result['confidence'])
|
||||
else:
|
||||
- print '******** no result'
|
||||
+ print('******** no result')
|
||||
count += 1
|
||||
-print count, 'tests'
|
||||
+print(count, 'tests')
|
||||
RefactoringTool: Files that were modified:
|
||||
RefactoringTool: test.py</samp></pre>
|
||||
|
||||
<p>Well, that wasn't so hard. Just a few imports and print statements to convert. Time to run the new version. Do you think it'll work?</p>
|
||||
</section>
|
||||
|
||||
<section id="falseisinvalidsyntax">
|
||||
<h2><code>False</code> is invalid syntax</h2>
|
||||
|
||||
<p>Now for the real test: running the test harness against the test suite. Since the test suite is designed to cover all the possible code paths, it's a good way to test our ported code to make sure there aren't any bugs lurking anywhere.</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python test.py tests\*\*</kbd>
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "test.py", line 1, in <module>
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
File "C:\home\chardet\chardet\universaldetector.py", line 51
|
||||
self.done = constants.False
|
||||
^
|
||||
SyntaxError: invalid syntax</samp></pre>
|
||||
|
||||
<p>Hmm, a small snag. In Python 3, <code>False</code> is a reserved word, so you can't use it as a variable name. Let's look at <code class="filename">constants.py</code> to see where it's defined. Here's the original version from <code class="filename">constants.py</code>, before the <code class="filename">2to3</code> script changed it:</p>
|
||||
|
||||
<pre><code>import __builtin__
|
||||
if not hasattr(__builtin__, 'False'):
|
||||
False = 0
|
||||
True = 1
|
||||
else:
|
||||
False = __builtin__.False
|
||||
True = __builtin__.True</code></pre>
|
||||
|
||||
<p>This piece of code is designed to allow this library to run under older versions of Python 2. Prior to Python 2.3 [FIXME-LINK], Python had no built-in <code>Boolean</code> type. This code detects the absence of the built-in constants <code>True</code> and <code>False</code>, and defines them if necessary.</p>
|
||||
|
||||
<p>However, Python 3 will always have a <code>Boolean</code> type, so this entire code snippet is unnecessary. The simplest solution is to replace all instances of "<code>constants.True</code>" and "<code>constants.False</code>" with "<code>True</code>" and "<code>False</code>", respectively, then delete this dead code from <code class="filename">constants.py</code>.</p>
|
||||
|
||||
<p>So this line in <code class="filename">universaldetector.py</code>:</p>
|
||||
|
||||
<pre><code>self.done = constants.False</code></pre>
|
||||
|
||||
<p>Becomes</p>
|
||||
|
||||
<pre><code>self.done = False</code></pre>
|
||||
|
||||
<p>Ah, wasn't that satisfying? The code is shorter and more readable already.</p>
|
||||
</section>
|
||||
|
||||
<section id="nomodulenamedconstants">
|
||||
<h2>No module named <code class="filename">constants</code></h2>
|
||||
|
||||
<p>Time to run test.py again and see how far it gets.</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python test.py tests\*\*</kbd>
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "test.py", line 1, in <module>
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
File "C:\home\chardet\chardet\universaldetector.py", line 29, in <module>
|
||||
import constants, sys
|
||||
ImportError: No module named constants</samp></pre>
|
||||
|
||||
<p>What's that you say? No module named <code class="filename">constants</code>? Of course there's a module named <code class="filename">constants</code>. ... Oh wait, no there isn't. Remember when the <code class="filename">2to3</code> script fixed up all those import statements? This library has a lot of relative imports -- that is, modules that import other modules within the library. In Python 3, all import statements are absolute by default [FIXME-LINK PEP 0328]. To do relative imports, you need to do something like this instead:</p>
|
||||
|
||||
<pre><code>from . import constants</code></pre>
|
||||
|
||||
<p>But wait. Wasn't the <code class="filename">2to3</code> script supposed to take care of these for you? Well, it did, but this particular import statement combines two different types of imports into one line: a relative import of the <code class="filename">constants</code> module within the library, and an absolute import of the <code class="filename">sys</code> module that is pre-installed in the Python standard library. In Python 2, you could combine these into one import statement. In Python 3, you can't, and the <code class="filename">2to3</code> script is not smart enough to split the import statement into two.</p>
|
||||
|
||||
<p>The solution is to split the import statement manually. So this two-in-one import:</p>
|
||||
|
||||
<pre><code>import constants, sys</code></pre>
|
||||
|
||||
<p>Needs to become two separate imports:</p>
|
||||
|
||||
<pre><code>from . import constants
|
||||
import sys</code></pre>
|
||||
|
||||
<p>There are variations of this problem scattered throughout the <code class="filename">chardet</code> library. In some places it's "<code>import constants, sys</code>"; in other places, it's "<code>import constants, re</code>". The fix is the same: manually split the import statement into two lines, one for the relative import, the other for the absolute import.</p>
|
||||
|
||||
<p>Onward!</p>
|
||||
</section>
|
||||
|
||||
<section id="namefileisnotdefined">
|
||||
<h2>Name '<var>file</var>' is not defined</h2>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python test.py tests\*\*</kbd>
|
||||
<samp>tests\ascii\howto.diveintomark.org.xml</samp>
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "test.py", line 9, in <module>
|
||||
for line in file(f, 'rb'):
|
||||
NameError: name 'file' is not defined</samp></pre>
|
||||
|
||||
<p>This one surprised me, because I've been using this idiom as long as I can remember. In Python 2, the global <var>file()</var> function was an alias for <var>open()</var>, which was the standard way of opening files for reading. In Python 3, the entire system for reading and writing files has been refactored into the <code class="filename">io</code> module. [FIXME-LINK PEP 3116] I'll cover the new I/O module in more detail in Chapter FIXME, but for now, the important bit is that the global <var>file()</var> function no longer exists. However, the <var>open()</var> function does still exist. (Technically, it's an alias for <var>io.open()</var>, but never mind that right now.)</p>
|
||||
|
||||
<p>Thus, the simplest solution to the problem of the missing <var>file()</var> is to call <var>open()</var> instead:</p>
|
||||
|
||||
<pre><code>for line in open(f, 'rb'):</code></pre>
|
||||
|
||||
<p>And that's all I have to say about that.</p>
|
||||
</section>
|
||||
|
||||
<section id="cantuseastringpattern">
|
||||
<h2>Can't use a string pattern on a bytes-like object</h2>
|
||||
|
||||
<p>FIXME intro</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python test.py tests\*\*</kbd>
|
||||
<samp>tests\ascii\howto.diveintomark.org.xml</samp>
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "test.py", line 10, in <module>
|
||||
u.feed(line)
|
||||
File "C:\home\chardet\chardet\universaldetector.py", line 98, in feed
|
||||
if self._highBitDetector.search(aBuf):
|
||||
TypeError: can't use a string pattern on a bytes-like object</samp></pre>
|
||||
|
||||
<p>Now things are starting to get interesting. And by "interesting," I mean "confusing as all hell."</p>
|
||||
|
||||
<p>First, let's see what <var>self._highBitDetector</var> is. It's defined in the <var>__init__</var> method of the <var>UniversalDetector</var> class:</p>
|
||||
|
||||
<pre><code>class UniversalDetector:
|
||||
def __init__(self):
|
||||
self._highBitDetector = re.compile(r'[\x80-\xFF]')</code></pre>
|
||||
|
||||
<p>This pre-compiles a regular expression designed to find non-ASCII characters in the range 128-255 (0x80-0xFF). Wait, that's not quite right; I need to be more precise with my terminology. This pattern is designed to find non-ASCII <em>bytes</em> in the range 128-255.</p>
|
||||
|
||||
<p>And therein lies the problem.</p>
|
||||
|
||||
<p>In Python 2, a string was an array of bytes whose character encoding was tracked separately. If you wanted Python 2 to keep track of the character encoding, you had to use a Unicode string (<code>u''</code>) instead. But in Python 3, a string is always what Python 2 called a Unicode string -- that is, an array of Unicode characters (of possibly varying byte lengths). Since this regular expression is defined by a string pattern, it can only be used to search a string -- again, an array of characters. But what we're searching is not a string, it's a byte array. Looking at the traceback, this error occurred in <code class="filename">universaldetector.py</code>:</p>
|
||||
|
||||
<pre><code>def feed(self, aBuf):
|
||||
.
|
||||
.
|
||||
.
|
||||
if self._mInputState == ePureAscii:
|
||||
if self._highBitDetector.search(aBuf):</code></pre>
|
||||
|
||||
<p>And what is <var>aBuf</var>? Let's backtrack further to a place that calls <var>UniversalDetector.feed()</var>. One place that calls it is the test harness, <code class="filename">test.py</code>.</p>
|
||||
|
||||
<pre><code>u = UniversalDetector()
|
||||
.
|
||||
.
|
||||
.
|
||||
for line in open(f, 'rb'):
|
||||
u.feed(line)</code></pre>
|
||||
|
||||
<p>And here we find our answer: in the <var>UniversalDetector.feed()</var> method, <var>aBuf</var> is a line read from a file on disk. Look carefully at the parameters used to open the file: <code>'rb'</code>. <code>'r'</code> is for "read"; OK, big deal, we're reading the file. Ah, but <code>'b'</code> is for "bytes." Without the <code>'b'</code> flag, this <code>for</code> loop would read the file, line by line, and convert each line into a string -- an array of Unicode characters -- according to the system default character encoding. (You could override the system encoding with another parameter to <var>open()</var>, but never mind that for now.) But with the <code>'b'</code> flag, this <code>for</code> loop reads the file, line by line, and stores each line exactly as it appears in the file, as an array of bytes. That byte array gets passed to <var>UniversalDetector.feed()</var>, and eventually gets passed to the pre-compiled regular expression, <var>self._highBitDetector</var>, to search for high-bit... characters. But we don't have characters; we have bytes. Oops.</p>
|
||||
|
||||
<p>What we need this regular expression to search is not an array of characters, but an array of bytes.</p>
|
||||
|
||||
<p>Once you realize that, the solution is not difficult. Regular expressions defined with strings can search strings. Regular expressions defined with byte arrays can search byte arrays. To define a byte array pattern, we simply change the type of the argument we use to define the regular expression to a byte array. So instead of this:</p>
|
||||
|
||||
<pre><code>self._highBitDetector = re.compile(r'[\x80-\xFF]')</code></pre>
|
||||
|
||||
<p>We now have this:</p>
|
||||
|
||||
<pre><code>self._highBitDetector = re.compile(b'[\x80-\xFF]')</code></pre>
|
||||
|
||||
<p>There is one other case of this same problem, on the very next line:</p>
|
||||
|
||||
<pre><code>self._escDetector = re.compile(r'(\033|~{)')</code></pre>
|
||||
|
||||
<p>Again, this is going to be used to search a byte array (the same <var>aBuf</var> variable, in fact), so the regular expression pattern needs to be defined as a byte array:</p>
|
||||
|
||||
<pre><code>self._escDetector = re.compile(b'(\033|~{)')</code></pre>
|
||||
</section>
|
||||
|
||||
<section id="cantconvertbytesobject">
|
||||
<h2>Can't convert '<code>bytes</code>' object to <code>str</code> implicitly</h2>
|
||||
|
||||
<p>Curiouser and curiouser...</p>
|
||||
|
||||
<pre class="screen"><samp class="prompt">C:\home\chardet></samp><kbd>python test.py tests\*\*</kbd>
|
||||
<samp>tests\ascii\howto.diveintomark.org.xml</samp>
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "test.py", line 10, in <module>
|
||||
u.feed(line)
|
||||
File "C:\home\chardet\chardet\universaldetector.py", line 100, in feed
|
||||
elif (self._mInputState == ePureAscii) and self._escDetector.search(self._mLastChar + aBuf):
|
||||
TypeError: Can't convert 'bytes' object to str implicitly</samp></pre>
|
||||
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -346,7 +346,7 @@ several months behind in updating their ActivePython installer when new version
|
||||
<samp class="computeroutput">PythonWin 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32.
|
||||
Portions Copyright 1994-2001 Mark Hammond (mhammond@skippinet.com.au) -
|
||||
see 'Help/About PythonWin' for further copyright information.</samp>
|
||||
<samp> class="prompt">>>> </samp>
|
||||
<samp class="prompt">>>> </samp>
|
||||
</pre></div>
|
||||
<div class="procedure">
|
||||
<h3 class="title">Procedure 1.2. Option 2: Installing Python from <a href="http://www.python.org/" title="Python language home page">Python.org</a></h3>
|
||||
@@ -383,7 +383,7 @@ Type "copyright", "credits" or "license()" for more information.
|
||||
****************************************************************
|
||||
|
||||
IDLE 1.0</samp>
|
||||
<samp> class="prompt">>>> </samp>
|
||||
<samp class="prompt">>>> </samp>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
@@ -418,7 +418,7 @@ Welcome to Darwin!
|
||||
<samp class="computeroutput">Python 2.2 (#1, 07/14/02, 23:25:09)
|
||||
[GCC Apple cpp-precomp 6.14] on darwin
|
||||
Type "help", "copyright", "credits", or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">[localhost:~] you% </samp>
|
||||
</pre></div>
|
||||
<div class="procedure">
|
||||
@@ -458,7 +458,7 @@ Window->Python Interactive (<kbd class="shortcut">Cmd-0</kbd>). The opening win
|
||||
[GCC 3.1 20020420 (prerelease)]
|
||||
Type "copyright", "credits" or "license" for more information.
|
||||
MacPython IDE 1.0.1</samp>
|
||||
<samp> class="prompt">>>> </samp>
|
||||
<samp class="prompt">>>> </samp>
|
||||
</pre></div>
|
||||
<p>Note that once you install the latest version, the pre-installed version is still present. If you are running scripts from
|
||||
the command line, you need to be aware which version of Python you are using.</p>
|
||||
@@ -467,12 +467,12 @@ the command line, you need to be aware which version of Python you are using.</p
|
||||
<samp class="computeroutput">Python 2.2 (#1, 07/14/02, 23:25:09)
|
||||
[GCC Apple cpp-precomp 6.14] on darwin
|
||||
Type "help", "copyright", "credits", or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">[localhost:~] you% </samp>/usr/local/bin/python
|
||||
<samp class="computeroutput">Python 2.3 (#2, Jul 30 2003, 11:45:28)
|
||||
[GCC 3.1 20020420 (prerelease)] on darwin
|
||||
Type "help", "copyright", "credits", or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">[localhost:~] you% </samp>
|
||||
</pre></div>
|
||||
</div>
|
||||
@@ -512,7 +512,7 @@ Window->Python Interactive (<kbd class="shortcut">Cmd-0</kbd>). You'll see a sc
|
||||
[GCC 3.1 20020420 (prerelease)]
|
||||
Type "copyright", "credits" or "license" for more information.
|
||||
MacPython IDE 1.0.1</samp>
|
||||
<samp> class="prompt">>>> </samp>
|
||||
<samp class="prompt">>>> </samp>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
@@ -529,19 +529,19 @@ Connecting to python.org[194.109.137.226]:80... connected.
|
||||
HTTP request sent, awaiting response... 200 OK
|
||||
Length: 7,495,111 [application/octet-stream]
|
||||
...</samp>
|
||||
<samp> class="prompt">[root@localhost root]# </samp>rpm -Uvh python2.3-2.3-5pydotorg.i386.rpm
|
||||
<samp class="prompt">[root@localhost root]# </samp>rpm -Uvh python2.3-2.3-5pydotorg.i386.rpm
|
||||
<samp class="computeroutput">Preparing... ########################################### [100%]
|
||||
1:python2.3 ########################################### [100%]</samp>
|
||||
<samp> class="prompt">[root@localhost root]# </samp>python <img id="install.unix.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">[root@localhost root]# </samp>python <img id="install.unix.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">Python 2.2.2 (#1, Feb 24 2003, 19:13:11)
|
||||
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-4)] on linux2
|
||||
Type "help", "copyright", "credits", or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
<samp class="prompt">[root@localhost root]# </samp>python2.3 <img id="install.unix.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">Python 2.3 (#1, Sep 12 2003, 10:53:56)
|
||||
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
|
||||
Type "help", "copyright", "credits", or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
<samp class="prompt">[root@localhost root]# </samp>which python2.3 <img id="install.unix.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
/usr/bin/python2.3
|
||||
</pre><div class="calloutlist">
|
||||
@@ -586,7 +586,7 @@ The following NEW packages will be installed:
|
||||
0 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
|
||||
Need to get 0B/2880kB of archives.
|
||||
After unpacking 9351kB of additional disk space will be used.</samp>
|
||||
<samp> class="prompt">Do you want to continue? [Y/n] </samp>Y
|
||||
<samp class="prompt">Do you want to continue? [Y/n] </samp>Y
|
||||
<samp class="computeroutput">Selecting previously deselected package python2.3.
|
||||
(Reading database ... 22848 files and directories currently installed.)
|
||||
Unpacking python2.3 (from .../python2.3_2.3.1-1_i386.deb) ...
|
||||
@@ -596,13 +596,13 @@ Setting up python (2.3.1-1) ...
|
||||
Setting up python2.3 (2.3.1-1) ...
|
||||
Compiling python modules in /usr/lib/python2.3 ...
|
||||
Compiling optimized python modules in /usr/lib/python2.3 ...</samp>
|
||||
<samp> class="prompt">localhost:~# </samp>exit
|
||||
<samp class="prompt">localhost:~# </samp>exit
|
||||
logout
|
||||
<samp class="prompt">localhost:~$ </samp>python
|
||||
<samp class="computeroutput">Python 2.3.1 (#2, Sep 24 2003, 11:39:14)
|
||||
[GCC 3.3.2 20030908 (Debian prerelease)] on linux2
|
||||
Type "help", "copyright", "credits" or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to exit]
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
@@ -617,14 +617,14 @@ Connecting to www.python.org[194.109.137.226]:80... connected.
|
||||
HTTP request sent, awaiting response... 200 OK
|
||||
Length: 8,436,880 [application/x-tar]
|
||||
...</samp>
|
||||
<samp> class="prompt">localhost:~# </samp>tar xfz Python-2.3.tgz
|
||||
<samp class="prompt">localhost:~# </samp>tar xfz Python-2.3.tgz
|
||||
<samp class="prompt">localhost:~# </samp>cd Python-2.3
|
||||
<samp class="prompt">localhost:~/Python-2.3# </samp>./configure
|
||||
<samp class="computeroutput">checking MACHDEP... linux2
|
||||
checking EXTRAPLATDIR...
|
||||
checking for --without-gcc... no
|
||||
...</samp>
|
||||
<samp> class="prompt">localhost:~/Python-2.3# </samp>make
|
||||
<samp class="prompt">localhost:~/Python-2.3# </samp>make
|
||||
<samp class="computeroutput">gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
|
||||
-I. -I./Include -DPy_BUILD_CORE -o Modules/python.o Modules/python.c
|
||||
gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
|
||||
@@ -632,10 +632,10 @@ gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
|
||||
gcc -pthread -c -fno-strict-aliasing -DNDEBUG -g -O3 -Wall -Wstrict-prototypes
|
||||
-I. -I./Include -DPy_BUILD_CORE -o Parser/grammar1.o Parser/grammar1.c
|
||||
...</samp>
|
||||
<samp> class="prompt">localhost:~/Python-2.3# </samp>make install
|
||||
<samp class="prompt">localhost:~/Python-2.3# </samp>make install
|
||||
<samp class="computeroutput">/usr/bin/install -c python /usr/local/bin/python2.3
|
||||
...</samp>
|
||||
<samp> class="prompt">localhost:~/Python-2.3# </samp>exit
|
||||
<samp class="prompt">localhost:~/Python-2.3# </samp>exit
|
||||
logout
|
||||
<samp class="prompt">localhost:~$ </samp>which python
|
||||
/usr/local/bin/python
|
||||
@@ -643,7 +643,7 @@ logout
|
||||
<samp class="computeroutput">Python 2.3.1 (#2, Sep 24 2003, 11:39:14)
|
||||
[GCC 3.3.2 20030908 (Debian prerelease)] on linux2
|
||||
Type "help", "copyright", "credits" or "license" for more information.</samp>
|
||||
<samp> class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">>>> </samp>[press Ctrl+D to get back to the command prompt]
|
||||
<samp class="prompt">localhost:~$ </samp>
|
||||
</pre></div>
|
||||
</div>
|
||||
@@ -892,7 +892,7 @@ Returns string.</span></pre><div class="calloutlist">
|
||||
<samp class="computeroutput">['', '/usr/local/lib/python2.2', '/usr/local/lib/python2.2/plat-linux2',
|
||||
'/usr/local/lib/python2.2/lib-dynload', '/usr/local/lib/python2.2/site-packages',
|
||||
'/usr/local/lib/python2.2/site-packages/PIL', '/usr/local/lib/python2.2/site-packages/piddle']</samp>
|
||||
<samp> class="prompt">>>> </samp>sys <img id="odbchelper.objects.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>sys <img id="odbchelper.objects.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<module 'sys' (built-in)>
|
||||
<samp class="prompt">>>> </samp>sys.path.append('/my/new/path') <img id="odbchelper.objects.2.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12"></pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -1227,7 +1227,7 @@ KeyError: mpilgrim</span></pre><div class="calloutlist">
|
||||
<div class="example"><h3 id="odbchelper.dict.del" class="title">Example 3.5. Deleting Items from a Dictionary</h3><pre class="screen"><samp class="prompt">>>> </samp>d
|
||||
<samp class="computeroutput">{'server': 'mpilgrim', 'uid': 'sa', 'database': 'master',
|
||||
42: 'douglas', 'retrycount': 3}</samp>
|
||||
<samp> class="prompt">>>> </samp>del d[42] <img id="odbchelper.dict.4.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>del d[42] <img id="odbchelper.dict.4.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>d
|
||||
{'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3}
|
||||
<samp class="prompt">>>> </samp>d.clear() <img id="odbchelper.dict.4.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
@@ -1504,7 +1504,7 @@ KeyError: mpilgrim</span></pre><div class="calloutlist">
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
ValueError: list.index(x): x not in list</samp>
|
||||
<samp> class="prompt">>>> </samp>"c" in li <img id="odbchelper.list.6.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>"c" in li <img id="odbchelper.list.6.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
False</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -1573,7 +1573,7 @@ False</pre><div class="calloutlist">
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
ValueError: list.remove(x): x not in list</samp>
|
||||
<samp> class="prompt">>>> </samp>li.pop() <img id="odbchelper.list.7.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>li.pop() <img id="odbchelper.list.7.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
'elements'
|
||||
<samp class="prompt">>>> </samp>li
|
||||
['a', 'b', 'mpilgrim', 'example', 'new', 'two']</pre><div class="calloutlist">
|
||||
@@ -1705,15 +1705,15 @@ ValueError: list.remove(x): x not in list</samp>
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
AttributeError: 'tuple' object has no attribute 'append'</samp>
|
||||
<samp> class="prompt">>>> </samp>t.remove("z") <img id="odbchelper.tuple.2.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>t.remove("z") <img id="odbchelper.tuple.2.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
AttributeError: 'tuple' object has no attribute 'remove'</samp>
|
||||
<samp> class="prompt">>>> </samp>t.index("example") <img id="odbchelper.tuple.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>t.index("example") <img id="odbchelper.tuple.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
AttributeError: 'tuple' object has no attribute 'index'</samp>
|
||||
<samp> class="prompt">>>> </samp>"z" in t <img id="odbchelper.tuple.2.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>"z" in t <img id="odbchelper.tuple.2.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
True</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -1809,7 +1809,7 @@ a matter of style.</p>
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
NameError: There is no variable named 'x'</samp>
|
||||
<samp> class="prompt">>>> </samp>x = 1
|
||||
<samp class="prompt">>>> </samp>x = 1
|
||||
<samp class="prompt">>>> </samp>x
|
||||
1</pre></div>
|
||||
<p>You will thank Python for this one day.</p>
|
||||
@@ -2487,7 +2487,7 @@ True</pre><div class="calloutlist">
|
||||
<samp class="prompt">>>> </samp>dir(li) <img id="apihelper.builtin.3.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['append', 'count', 'extend', 'index', 'insert',
|
||||
'pop', 'remove', 'reverse', 'sort']</samp>
|
||||
<samp> class="prompt">>>> </samp>d = {}
|
||||
<samp class="prompt">>>> </samp>d = {}
|
||||
<samp class="prompt">>>> </samp>dir(d) <img id="apihelper.builtin.3.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'setdefault', 'update', 'values']
|
||||
<samp class="prompt">>>> </samp>import odbchelper
|
||||
@@ -3035,7 +3035,7 @@ a <code class="literal">lambda</code> function; if you need something more compl
|
||||
<samp class="prompt">>>> </samp>print s
|
||||
<samp class="computeroutput">this is
|
||||
a test</samp>
|
||||
<samp> class="prompt">>>> </samp>print s.split() <img id="apihelper.split.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print s.split() <img id="apihelper.split.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
['this', 'is', 'a', 'test']
|
||||
<samp class="prompt">>>> </samp>print " ".join(s.split()) <img id="apihelper.split.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
'this is a test'</pre><div class="calloutlist">
|
||||
@@ -3450,7 +3450,7 @@ can import individual items or use <code class="literal">from <i class="replacea
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
NameError: There is no variable named 'FunctionType'</samp>
|
||||
<samp> class="prompt">>>> </samp>from types import FunctionType <img id="fileinfo.import.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>from types import FunctionType <img id="fileinfo.import.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>FunctionType <img id="fileinfo.import.1.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<type 'function'></pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -4077,7 +4077,7 @@ provide a way to map non-method-calling syntax into method calls.</p>
|
||||
<samp class="computeroutput">{'album': 'Rave Mix', 'artist': '***DJ MARY-JANE***', 'genre': 31,
|
||||
'title': 'KAIRO****THE BEST GOA', 'name': '/music/_singles/kairo.mp3',
|
||||
'year': '2000', 'comment': 'http://mp3.com/DJMARYJANE'}</samp>
|
||||
<samp> class="prompt">>>> </samp>mp3file["name"] = "/music/_singles/sidewinder.mp3" <img id="fileinfo.specialmethods.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>mp3file["name"] = "/music/_singles/sidewinder.mp3" <img id="fileinfo.specialmethods.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>mp3file
|
||||
<samp class="computeroutput">{'album': '', 'artist': 'The Cynic Project', 'genre': 18, 'title': 'Sidewinder',
|
||||
'name': '/music/_singles/sidewinder.mp3', 'year': '2000',
|
||||
@@ -4206,7 +4206,7 @@ class MP3FileInfo(FileInfo):
|
||||
'year': (93, 97, <function stripnulls at 0260C8D4>),
|
||||
'comment': (97, 126, <function stripnulls at 0260C8D4>),
|
||||
'album': (63, 93, <function stripnulls at 0260C8D4>)}</samp>
|
||||
<samp> class="prompt">>>> </samp>m = fileinfo.MP3FileInfo() <img id="fileinfo.classattributes.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>m = fileinfo.MP3FileInfo() <img id="fileinfo.classattributes.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>m.tagDataMap
|
||||
<samp class="computeroutput">{'title': (3, 33, <function stripnulls at 0260C8D4>),
|
||||
'genre': (127, 128, <built-in function ord>),
|
||||
@@ -4421,7 +4421,7 @@ a line of code may raise an exception, you should handle the exception using a <
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
IOError: [Errno 2] No such file or directory: '/notthere'</samp>
|
||||
<samp> class="prompt">>>> </samp>try:
|
||||
<samp class="prompt">>>> </samp>try:
|
||||
<samp class="prompt">... </samp>fsock = open("/notthere") <img id="fileinfo.exceptions.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">... </samp>except IOError: <img id="fileinfo.exceptions.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">... </samp>print "The file does not exist, exiting gracefully"
|
||||
@@ -4597,7 +4597,7 @@ exceptions, errors occur immediately, and you can handle them in a standard way
|
||||
<samp class="prompt">>>> </samp>tagData
|
||||
<samp class="computeroutput">'TAGKAIRO****THE BEST GOA ***DJ MARY-JANE***
|
||||
Rave Mix 2000http://mp3.com/DJMARYJANE \037'</samp>
|
||||
<samp> class="prompt">>>> </samp>f.tell() <img id="fileinfo.files.2.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>f.tell() <img id="fileinfo.files.2.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
7543037</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -4657,15 +4657,15 @@ True
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
ValueError: I/O operation on closed file</samp>
|
||||
<samp> class="prompt">>>> </samp>f.tell()
|
||||
<samp class="prompt">>>> </samp>f.tell()
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
ValueError: I/O operation on closed file</samp>
|
||||
<samp> class="prompt">>>> </samp>f.read()
|
||||
<samp class="prompt">>>> </samp>f.read()
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
ValueError: I/O operation on closed file</samp>
|
||||
<samp> class="prompt">>>> </samp>f.close() <img id="fileinfo.files.3.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12"></pre><div class="calloutlist">
|
||||
<samp class="prompt">>>> </samp>f.close() <img id="fileinfo.files.3.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12"></pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
<td width="12" valign="top" align="left"><a href="#fileinfo.files.3.1"><img src="images/callouts/1.png" alt="1" border="0" width="12" height="12"></a>
|
||||
@@ -4849,7 +4849,7 @@ or other iteratable entities. But in Python, a <code class="literal">for</code>
|
||||
<samp class="computeroutput">a
|
||||
b
|
||||
e</samp>
|
||||
<samp> class="prompt">>>> </samp>print "\n".join(li) <img id="fileinfo.for.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print "\n".join(li) <img id="fileinfo.for.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">a
|
||||
b
|
||||
e</span></pre><div class="calloutlist">
|
||||
@@ -4884,7 +4884,7 @@ e</span></pre><div class="calloutlist">
|
||||
2
|
||||
3
|
||||
4</samp>
|
||||
<samp> class="prompt">>>> </samp>li = ['a', 'b', 'c', 'd', 'e']
|
||||
<samp class="prompt">>>> </samp>li = ['a', 'b', 'c', 'd', 'e']
|
||||
<samp class="prompt">>>> </samp>for i in range(len(li)): <img id="fileinfo.for.3.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">... </samp>print li[i]
|
||||
<samp class="computeroutput">a
|
||||
@@ -4921,7 +4921,7 @@ COMPUTERNAME=MPILGRIM
|
||||
USERNAME=mpilgrim
|
||||
|
||||
[...snip...]</samp>
|
||||
<samp> class="prompt">>>> </samp>print "\n".join(["%s=%s" % (k, v)
|
||||
<samp class="prompt">>>> </samp>print "\n".join(["%s=%s" % (k, v)
|
||||
<samp class="prompt">... </samp>for k, v in os.environ.items()]) <img id="fileinfo.for.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">USERPROFILE=C:\Documents and Settings\mpilgrim
|
||||
OS=Windows_NT
|
||||
@@ -5044,7 +5044,7 @@ site
|
||||
signal
|
||||
UserDict
|
||||
stat</samp>
|
||||
<samp> class="prompt">>>> </samp>fileinfo
|
||||
<samp class="prompt">>>> </samp>fileinfo
|
||||
<module 'fileinfo' from 'fileinfo.pyc'>
|
||||
<samp class="prompt">>>> </samp>sys.modules["fileinfo"] <img id="fileinfo.modules.1.4" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<module 'fileinfo' from 'fileinfo.pyc'></pre><div class="calloutlist">
|
||||
@@ -5228,18 +5228,18 @@ stat</samp>
|
||||
<samp class="computeroutput">['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
|
||||
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
|
||||
'spinning.mp3']</samp>
|
||||
<samp> class="prompt">>>> </samp>dirname = "c:\\"
|
||||
<samp class="prompt">>>> </samp>dirname = "c:\\"
|
||||
<samp class="prompt">>>> </samp>os.listdir(dirname) <img id="fileinfo.os.3.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin',
|
||||
'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS',
|
||||
'MSDOS.SYS', 'Music', 'NTDETECT.COM', 'ntldr', 'pagefile.sys',
|
||||
'Program Files', 'Python20', 'RECYCLER',
|
||||
'System Volume Information', 'TEMP', 'WINNT']</samp>
|
||||
<samp> class="prompt">>>> </samp>[f for f in os.listdir(dirname)
|
||||
<samp class="prompt">>>> </samp>[f for f in os.listdir(dirname)
|
||||
<samp class="prompt">... </samp>if os.path.isfile(os.path.join(dirname, f))] <img id="fileinfo.os.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS',
|
||||
'NTDETECT.COM', 'ntldr', 'pagefile.sys']</samp>
|
||||
<samp> class="prompt">>>> </samp>[f for f in os.listdir(dirname)
|
||||
<samp class="prompt">>>> </samp>[f for f in os.listdir(dirname)
|
||||
<samp class="prompt">... </samp>if os.path.isdir(os.path.join(dirname, f))] <img id="fileinfo.os.3.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
|
||||
'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
|
||||
@@ -5331,7 +5331,7 @@ may already be familiar with from working on the command line.</p>
|
||||
<samp class="computeroutput">['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
|
||||
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
|
||||
'spinning.mp3']</samp>
|
||||
<samp> class="prompt">>>> </samp>import glob
|
||||
<samp class="prompt">>>> </samp>import glob
|
||||
<samp class="prompt">>>> </samp>glob.glob('c:\\music\\_singles\\*.mp3') <img id="fileinfo.os.4.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['c:\\music\\_singles\\a_time_long_forgotten_con.mp3',
|
||||
'c:\\music\\_singles\\hellraiser.mp3',
|
||||
@@ -5339,10 +5339,10 @@ may already be familiar with from working on the command line.</p>
|
||||
'c:\\music\\_singles\\long_way_home1.mp3',
|
||||
'c:\\music\\_singles\\sidewinder.mp3',
|
||||
'c:\\music\\_singles\\spinning.mp3']</samp>
|
||||
<samp> class="prompt">>>> </samp>glob.glob('c:\\music\\_singles\\s*.mp3') <img id="fileinfo.os.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>glob.glob('c:\\music\\_singles\\s*.mp3') <img id="fileinfo.os.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">['c:\\music\\_singles\\sidewinder.mp3',
|
||||
'c:\\music\\_singles\\spinning.mp3']</samp>
|
||||
<samp> class="prompt">>>> </samp>glob.glob('c:\\music\\*\\*.mp3')<img id="fileinfo.os.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>glob.glob('c:\\music\\*\\*.mp3')<img id="fileinfo.os.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -6100,7 +6100,7 @@ it a verbose regular expression. This example shows how.</p>
|
||||
# or 5-8 (V, followed by 0 to 3 I's)
|
||||
$ # end of string
|
||||
"""</kbd>
|
||||
<samp> class="prompt">>>> </samp>re.search(pattern, 'M', re.VERBOSE) <img id="re.verbose.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>re.search(pattern, 'M', re.VERBOSE) <img id="re.verbose.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<_sre.SRE_Match object at 0x008EEB48>
|
||||
<samp class="prompt">>>> </samp>re.search(pattern, 'MCMLXXXIX', re.VERBOSE) <img id="re.verbose.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<_sre.SRE_Match object at 0x008EEB48>
|
||||
@@ -6440,7 +6440,7 @@ you made.</p>
|
||||
(\d*) # extension is optional and can be any number of digits
|
||||
$ # end of string
|
||||
''', re.VERBOSE)</kbd>
|
||||
<samp> class="prompt">>>> </samp>phonePattern.search('work 1-(800) 555.1212 #1234').groups() <img id="re.phone.7.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>phonePattern.search('work 1-(800) 555.1212 #1234').groups() <img id="re.phone.7.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
('800', '555', '1212', '1234')
|
||||
<samp class="prompt">>>> </samp>phonePattern.search('800-555-1212') <img id="re.phone.7.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
('800', '555', '1212', '')
|
||||
@@ -8366,21 +8366,21 @@ package architecture. It's one of the many things Python is good at, so take ad
|
||||
<samp class="prompt">>>> </samp>grammarNode.childNodes<img id="kgp.parse.4.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">[<DOM Text node "\n">, <DOM Element: ref at 17533332>, \
|
||||
<DOM Text node "\n">, <DOM Element: ref at 17549660>, <DOM Text node "\n">]</samp>
|
||||
<samp> class="prompt">>>> </samp>print grammarNode.firstChild.toxml() <img id="kgp.parse.4.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print grammarNode.firstChild.toxml() <img id="kgp.parse.4.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">
|
||||
|
||||
</samp>
|
||||
<samp> class="prompt">>>> </samp>print grammarNode.childNodes[1].toxml() <img id="kgp.parse.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print grammarNode.childNodes[1].toxml() <img id="kgp.parse.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput"><ref id="bit">
|
||||
<p>0</p>
|
||||
<p>1</p>
|
||||
</ref></samp>
|
||||
<samp> class="prompt">>>> </samp>print grammarNode.childNodes[3].toxml() <img id="kgp.parse.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print grammarNode.childNodes[3].toxml() <img id="kgp.parse.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="computeroutput"><ref id="byte">
|
||||
<p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
|
||||
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
|
||||
</ref></samp>
|
||||
<samp> class="prompt">>>> </samp>print grammarNode.lastChild.toxml() <img id="kgp.parse.4.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print grammarNode.lastChild.toxml() <img id="kgp.parse.4.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">
|
||||
|
||||
</span></pre><div class="calloutlist">
|
||||
@@ -8428,7 +8428,7 @@ package architecture. It's one of the many things Python is good at, so take ad
|
||||
<samp class="computeroutput">[<DOM Text node "\n">, <DOM Text node " ">, <DOM Element: p at 19315844>, \
|
||||
<DOM Text node "\n">, <DOM Text node " ">, \
|
||||
<DOM Element: p at 19462036>, <DOM Text node "\n">]</samp>
|
||||
<samp> class="prompt">>>> </samp>pNode = refNode.childNodes[2]
|
||||
<samp class="prompt">>>> </samp>pNode = refNode.childNodes[2]
|
||||
<samp class="prompt">>>> </samp>pNode
|
||||
<DOM Element: p at 19315844>
|
||||
<samp class="prompt">>>> </samp>print pNode.toxml() <img id="kgp.parse.5.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
@@ -8525,7 +8525,7 @@ Dive in</pre><div class="calloutlist">
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
UnicodeError: ASCII encoding error: ordinal not in range(128)</samp>
|
||||
<samp> class="prompt">>>> </samp>print s.encode('latin-1') <img id="kgp.unicode.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>print s.encode('latin-1') <img id="kgp.unicode.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
La Peña</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -8639,7 +8639,7 @@ u'\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435'
|
||||
<samp class="traceback">Traceback (innermost last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
UnicodeError: ASCII encoding error: ordinal not in range(128)</samp>
|
||||
<samp> class="prompt">>>> </samp>convertedtitle = title.encode('koi8-r') <img id="kgp.unicode.6.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>convertedtitle = title.encode('koi8-r') <img id="kgp.unicode.6.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>convertedtitle
|
||||
'\xf0\xd2\xc5\xc4\xc9\xd3\xcc\xcf\xd7\xc9\xc5'
|
||||
<samp class="prompt">>>> </samp>print convertedtitle <img id="kgp.unicode.6.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
@@ -8724,7 +8724,7 @@ in Python. If your <acronym>XML</acronym> documents are all 7-bit <acronym>ASCI
|
||||
<p>0</p>
|
||||
<p>1</p>
|
||||
</ref></samp>
|
||||
<samp> class="prompt">>>> </samp>print reflist[1].toxml()
|
||||
<samp class="prompt">>>> </samp>print reflist[1].toxml()
|
||||
<samp class="computeroutput"><ref id="byte">
|
||||
<p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
|
||||
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
|
||||
@@ -8747,7 +8747,7 @@ in Python. If your <acronym>XML</acronym> documents are all 7-bit <acronym>ASCI
|
||||
<p>0</p>
|
||||
<p>1</p>
|
||||
</ref></samp>
|
||||
<samp> class="prompt">>>> </samp>plist = firstref.getElementsByTagName("p") <img id="kgp.search.2.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>plist = firstref.getElementsByTagName("p") <img id="kgp.search.2.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>plist
|
||||
[<DOM Element: p at 136140116>, <DOM Element: p at 136142172>]
|
||||
<samp class="prompt">>>> </samp>print plist[0].toxml() <img id="kgp.search.2.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
@@ -8832,7 +8832,7 @@ in Python. If your <acronym>XML</acronym> documents are all 7-bit <acronym>ASCI
|
||||
<p>0</p>
|
||||
<p>1</p>
|
||||
</ref></samp>
|
||||
<samp> class="prompt">>>> </samp>bitref.attributes <img id="kgp.attributes.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>bitref.attributes <img id="kgp.attributes.1.1" src="images/callouts/1.png" alt="1" border="0" width="12" height="12">
|
||||
<xml.dom.minidom.NamedNodeMap instance at 0x81e0c9c>
|
||||
<samp class="prompt">>>> </samp>bitref.attributes.keys() <img id="kgp.attributes.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12"> <img id="kgp.attributes.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
[u'id']
|
||||
@@ -9213,7 +9213,7 @@ with a window-based Python <acronym>IDE</acronym>, <code class="literal">stdout<
|
||||
<samp class="computeroutput">Dive in
|
||||
Dive in
|
||||
Dive in</samp>
|
||||
<samp> class="prompt">>>> </samp>import sys
|
||||
<samp class="prompt">>>> </samp>import sys
|
||||
<samp class="prompt">>>> </samp>for i in range(3):
|
||||
<samp class="prompt">... </samp>sys.stdout.write('Dive in') <img id="kgp.stdio.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
Dive inDive inDive in
|
||||
@@ -9385,7 +9385,7 @@ one program's output to the next program's input.</p>
|
||||
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
|
||||
</ref>
|
||||
</grammar></samp>
|
||||
<samp> class="prompt">[you@localhost kgp]$ </samp>cat binary.xml | python kgp.py -g - <img id="kgp.stdio.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12"> <img id="kgp.stdio.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">[you@localhost kgp]$ </samp>cat binary.xml | python kgp.py -g - <img id="kgp.stdio.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12"> <img id="kgp.stdio.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
10110001</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -9681,10 +9681,10 @@ argecho.py
|
||||
<samp class="computeroutput">argecho.py
|
||||
abc
|
||||
def</samp>
|
||||
<samp> class="prompt">[you@localhost py]$ </samp>python argecho.py --help <img id="kgp.commandline.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">[you@localhost py]$ </samp>python argecho.py --help <img id="kgp.commandline.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">argecho.py
|
||||
--help</samp>
|
||||
<samp> class="prompt">[you@localhost py]$ </samp>python argecho.py -m kant.xml <img id="kgp.commandline.1.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">[you@localhost py]$ </samp>python argecho.py -m kant.xml <img id="kgp.commandline.1.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">argecho.py
|
||||
-m
|
||||
kant.xml</span></pre><div class="calloutlist">
|
||||
@@ -10414,7 +10414,7 @@ turn it off by setting <code class="literal">httplib.HTTPConnection.debuglevel =
|
||||
'content-length': '15955',
|
||||
'accept-ranges': 'bytes',
|
||||
'connection': 'close'}</samp>
|
||||
<samp> class="prompt">>>> </samp>request.add_header('If-Modified-Since',
|
||||
<samp class="prompt">>>> </samp>request.add_header('If-Modified-Since',
|
||||
<samp class="prompt">... </samp>firstdatastream.headers.get('Last-Modified')) <img id="oa.etags.1.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>seconddatastream = opener.open(request) <img id="oa.etags.1.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
@@ -10556,7 +10556,7 @@ class DefaultErrorHandler(urllib2.HTTPDefaultErrorHandler): <img id="oa.etags
|
||||
<title mode="escaped">dive into mark</title>
|
||||
<link rel="alternate" type="text/html" href="http://diveintomark.org/"/>
|
||||
<-- rest of feed omitted for brevity --></samp>
|
||||
<samp> class="prompt">>>> </samp>request.add_header('If-None-Match',
|
||||
<samp class="prompt">>>> </samp>request.add_header('If-None-Match',
|
||||
<samp class="prompt">... </samp>firstdatastream.headers.get('ETag')) <img id="oa.etags.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>seconddatastream = opener.open(request)
|
||||
<samp class="prompt">>>> </samp>seconddatastream.status <img id="oa.etags.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
@@ -10646,7 +10646,7 @@ header: Accept-Ranges: bytes
|
||||
header: Content-Length: 15955
|
||||
header: Connection: close
|
||||
header: Content-Type: application/atom+xml</samp>
|
||||
<samp> class="prompt">>>> </samp>f.url <img id="oa.redirect.1.5" src="images/callouts/6.png" alt="6" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>f.url <img id="oa.redirect.1.5" src="images/callouts/6.png" alt="6" border="0" width="12" height="12">
|
||||
'http://diveintomark.org/xml/atom.xml'
|
||||
<samp class="prompt">>>> </samp>f.headers.dict
|
||||
<samp class="computeroutput">{'content-length': '15955',
|
||||
@@ -10657,7 +10657,7 @@ header: Content-Type: application/atom+xml</samp>
|
||||
'etag': '"e842a-3e53-55d97640"',
|
||||
'date': 'Thu, 15 Apr 2004 22:06:25 GMT',
|
||||
'content-type': 'application/atom+xml'}</samp>
|
||||
<samp> class="prompt">>>> </samp>f.status
|
||||
<samp class="prompt">>>> </samp>f.status
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: addinfourl instance has no attribute 'status'</span>
|
||||
@@ -10786,7 +10786,7 @@ header: Content-Length: 15955
|
||||
header: Connection: close
|
||||
header: Content-Type: application/atom+xml
|
||||
</samp>
|
||||
<samp> class="prompt">>>> </samp>f.status <img id="oa.redirect.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>f.status <img id="oa.redirect.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
301
|
||||
<samp class="prompt">>>> </samp>f.url
|
||||
'http://diveintomark.org/xml/atom.xml'
|
||||
@@ -10848,7 +10848,7 @@ header: Accept-Ranges: bytes
|
||||
header: Content-Length: 15955
|
||||
header: Connection: close
|
||||
header: Content-Type: application/atom+xml</samp>
|
||||
<samp> class="prompt">>>> </samp>f.status <img id="oa.redirect.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>f.status <img id="oa.redirect.4.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
302
|
||||
<samp class="prompt">>>> </samp>f.url
|
||||
http://diveintomark.org/xml/atom.xml
|
||||
@@ -10963,7 +10963,7 @@ header: Content-Type: application/atom+xml</span>
|
||||
<title mode="escaped">dive into mark</title>
|
||||
<link rel="alternate" type="text/html" href="http://diveintomark.org/"/>
|
||||
<-- rest of feed omitted for brevity --></samp>
|
||||
<samp> class="prompt">>>> </samp>len(data)
|
||||
<samp class="prompt">>>> </samp>len(data)
|
||||
15955
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -11186,7 +11186,7 @@ def fetch(source, etag=None, last_modified=None, agent=USER_AGENT):
|
||||
'data': '<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<feed version="0.3"
|
||||
<-- rest of data omitted for brevity -->'}</samp>
|
||||
<samp> class="prompt">>>> </samp>if params['status'] == 301:<img id="oa.alltogether.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>if params['status'] == 301:<img id="oa.alltogether.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">... </samp>url = params['url']
|
||||
<samp class="prompt">>>> </samp>newparams = openanything.fetch(
|
||||
<samp class="prompt">... </samp>url, params['etag'], params['lastmodified'], useragent) <img id="oa.alltogether.3.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
@@ -11526,7 +11526,7 @@ region.</p>
|
||||
</SOAP-ENV:Envelope>
|
||||
************************************************************************
|
||||
</samp>
|
||||
<samp> class="prompt">>>> </samp>temperature
|
||||
<samp class="prompt">>>> </samp>temperature
|
||||
80.0
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -11784,7 +11784,7 @@ u'return'
|
||||
</SOAP-ENV:Envelope>
|
||||
************************************************************************
|
||||
</samp>
|
||||
<samp> class="prompt">>>> </samp>temperature
|
||||
<samp class="prompt">>>> </samp>temperature
|
||||
66.0
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -11949,7 +11949,7 @@ and you can access it programmatically too.</p>
|
||||
{'fullViewableName':
|
||||
'Top/Arts/Literature/World_Literature/American/19th_Century/Twain,_Mark',
|
||||
'specialEncoding': ''}]</samp>
|
||||
<samp> class="prompt">>>> </samp>results.directoryCategories[0].fullViewableName
|
||||
<samp class="prompt">>>> </samp>results.directoryCategories[0].fullViewableName
|
||||
'Top/Arts/Literature/World_Literature/American/19th_Century/Twain,_Mark'
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -13295,7 +13295,7 @@ def fromRoman(s):
|
||||
File "roman3.py", line 27, in toRoman
|
||||
raise OutOfRangeError, "number out of range (must be 1..3999)"
|
||||
OutOfRangeError: number out of range (must be 1..3999)</samp>
|
||||
<samp> class="prompt">>>> </samp>roman3.toRoman(1.5)
|
||||
<samp class="prompt">>>> </samp>roman3.toRoman(1.5)
|
||||
<samp class="traceback">Traceback (most recent call last):
|
||||
File "<interactive input>", line 1, in ?
|
||||
File "roman3.py", line 29, in toRoman
|
||||
@@ -14828,11 +14828,11 @@ print 'full path =', os.path.abspath(pathname) <img id="regression.path.1.3" src
|
||||
<samp class="computeroutput">sys.argv[0] = /home/you/diveintopython3/common/py/fullpath.py
|
||||
path = /home/you/diveintopython3/common/py
|
||||
full path = /home/you/diveintopython3/common/py</samp>
|
||||
<samp> class="prompt">[you@localhost diveintopython3]$ </samp>python common/py/fullpath.py <img id="regression.path.3.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">[you@localhost diveintopython3]$ </samp>python common/py/fullpath.py <img id="regression.path.3.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">sys.argv[0] = common/py/fullpath.py
|
||||
path = common/py
|
||||
full path = /home/you/diveintopython3/common/py</samp>
|
||||
<samp> class="prompt">[you@localhost diveintopython3]$ </samp>cd common/py
|
||||
<samp class="prompt">[you@localhost diveintopython3]$ </samp>cd common/py
|
||||
<samp class="prompt">[you@localhost py]$ </samp>python fullpath.py <img id="regression.path.3.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">sys.argv[0] = fullpath.py
|
||||
path =
|
||||
@@ -15164,7 +15164,7 @@ to doesn't need to match the module name, either. You could import a series of
|
||||
<module 'os' from 'c:\Python22\lib\os.pyc'>,
|
||||
<module 're' from 'c:\Python22\lib\re.pyc'>,
|
||||
<module 'unittest' from 'c:\Python22\lib\unittest.pyc'>]</samp>
|
||||
<samp> class="prompt">>>> </samp>modules[0].version <img id="regression.import.3.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>modules[0].version <img id="regression.import.3.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
'2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)]'
|
||||
<samp class="prompt">>>> </samp>import sys
|
||||
<samp class="prompt">>>> </samp>sys.version
|
||||
@@ -15318,7 +15318,7 @@ return unittest.TestSuite(map(load, modules))
|
||||
<module 'odbchelpertest' from 'odbchelpertest.py'>,
|
||||
<module 'pluraltest' from 'pluraltest.py'>,
|
||||
<module 'romantest' from 'romantest.py'>]</samp>
|
||||
<samp> class="prompt">>>> </samp>modules[-1] <img id="regression.alltogether.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>modules[-1] <img id="regression.alltogether.4.3" src="images/callouts/3.png" alt="3" border="0" width="12" height="12">
|
||||
<module 'romantest' from 'romantest.py'>
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
@@ -15356,7 +15356,7 @@ return unittest.TestSuite(map(load, modules))
|
||||
...
|
||||
]
|
||||
]</samp>
|
||||
<samp> class="prompt">>>> </samp>unittest.TestSuite(map(load, modules)) <img id="regression.alltogether.5.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>unittest.TestSuite(map(load, modules)) <img id="regression.alltogether.5.2" src="images/callouts/2.png" alt="2" border="0" width="12" height="12">
|
||||
</pre><div class="calloutlist">
|
||||
<table border="0" summary="Callout list">
|
||||
<tr>
|
||||
@@ -16023,10 +16023,10 @@ def plural(noun, language='en'):
|
||||
<samp class="prompt">>>> </samp>counter.next() <img id="plural.stage6.2.4" src="images/callouts/4.png" alt="4" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">entering make_counter
|
||||
2</samp>
|
||||
<samp> class="prompt">>>> </samp>counter.next() <img id="plural.stage6.2.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>counter.next() <img id="plural.stage6.2.5" src="images/callouts/5.png" alt="5" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">incrementing x
|
||||
3</samp>
|
||||
<samp> class="prompt">>>> </samp>counter.next() <img id="plural.stage6.2.6" src="images/callouts/6.png" alt="6" border="0" width="12" height="12">
|
||||
<samp class="prompt">>>> </samp>counter.next() <img id="plural.stage6.2.6" src="images/callouts/6.png" alt="6" border="0" width="12" height="12">
|
||||
<samp class="computeroutput">incrementing x
|
||||
4</span>
|
||||
</pre><div class="calloutlist">
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*dive into minimalism(c)2008 Mark Pilgrim,MIT-licensed*/
|
||||
html{background:white;color:black}
|
||||
html{background:#fff;color:#000}
|
||||
body{font:normal medium 'Gill Sans','Gill Sans MT','Ikarius ADF',Candara,Jara,sans-serif;margin:1.75em auto;width:40em;line-height:1.75;word-spacing:0.1em}
|
||||
a{background:transparent;text-decoration:none;border-bottom:1px dotted}
|
||||
a:hover{border-bottom:1px solid}
|
||||
@@ -9,21 +8,22 @@ h1 a,h2 a,h3 a,#nav a{color:inherit !important}
|
||||
abbr,.p{border:0;letter-spacing:0.1em;text-transform:lowercase;font-variant:small-caps}
|
||||
h1,h2,h3,p,ul,ol,#nav{margin:1.75em 0}
|
||||
h1,h2,h3{font-size:medium}
|
||||
h1{background:papayawhip;color:black;width:100%;margin:0}
|
||||
h2{margin-left:1.75em}
|
||||
h3{margin-left:3.5em}
|
||||
h1{background:papayawhip;color:#000;width:100%;margin:0}
|
||||
#index h2{margin-left:1.75em}
|
||||
#index h3{margin-left:3.5em}
|
||||
pre,tt{white-space:pre-wrap;font-size:medium;line-height:2.154}
|
||||
cite{font-style:normal}
|
||||
img{border:0}
|
||||
.framed{border:1px solid}
|
||||
blockquote{font-size:small;line-height:2.154;margin:2.154em 0;padding:0}
|
||||
blockquote{font-style:oblique;border-left:1px dotted;margin-left:2.154em;padding-left:2.154em}
|
||||
pre,blockquote{line-height:2.154;margin:2.154em 0;padding:0 0 0 2.154em;border-left:1px dotted}
|
||||
blockquote{font-size:small;font-style:oblique;margin-left:2.154em}
|
||||
blockquote p{margin:2.154em 0}
|
||||
.f,.c{text-align:center;clear:both}
|
||||
article + p:first-letter{float:left;color:gainsboro;padding:0.11em 4px 0 0;font:normal 4em/0.68 serif}
|
||||
section h2 + p:first-letter{float:left;background:transparent;color:gainsboro;padding:0.11em 4px 0 0;font:normal 4em/0.68 serif}
|
||||
#arc{width:100%,border-collapse:collapse}
|
||||
#arc th,#arc td{list-style:none;margin:0;padding:0}
|
||||
#arc th{padding:0 1.75em 0 0;text-align:right;vertical-align:baseline}
|
||||
figure{display:block;text-align:center;margin:1.75em 0}
|
||||
figure img{display:block;margin:0 auto}
|
||||
section,article,footer{display:block}
|
||||
var{font-family:monospace;font-style:normal}
|
||||
|
||||
+247
-247
@@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="Python, Python 3, Dive Into Python 3, tutorial, programming, documentation, book, free">
|
||||
<meta name="description" content="Python 3 from novice to pro">
|
||||
</head>
|
||||
<body>
|
||||
<body id="index">
|
||||
<p><cite>Dive into Python 3</cite> will cover Python 3 and its differences from Python 2. Compared to the original <cite><a href="http://diveintopython.org/">Dive into Python</a></cite>, it will be about 50% revised and 50% new material.</p>
|
||||
<p>I will publish drafts online as I go. The final book will be published on paper by Apress. The book will remain online under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a> license.</p>
|
||||
<p>Below is the draft table of contents. There is no text yet.</p>
|
||||
@@ -17,72 +17,72 @@
|
||||
<section>
|
||||
<h1>Installing Python</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Python on Windows</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Python on Mac OS X</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Python on Linux</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Python from source</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>The interactive shell</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Your first Python program</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Declaring functions</h2>
|
||||
<h3>How Python's datatypes compare to other programming languages</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Documenting functions</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Everything is an object</h2>
|
||||
<h3>The import search path</h3>
|
||||
<h3>What's an object?</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Indenting code</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Testing modules</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Native Python datatypes</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Lists</h2>
|
||||
<h3>Differences from Python 2</h3>
|
||||
<h3>Creating new a list</h3>
|
||||
@@ -92,9 +92,9 @@
|
||||
<h3>List operators</h3>
|
||||
<h3>Looping through a list (list comprehensions)</h3>
|
||||
<h3>Tuples</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Dictionaries</h2>
|
||||
<h3>Differences from Python 2</h3>
|
||||
<h3>Creating a new dictionary</h3>
|
||||
@@ -102,9 +102,9 @@
|
||||
<h3>Deleting items from a dictionary</h3>
|
||||
<h3>Looping through a dictionary (dictionary comprehensions)</h3>
|
||||
<h3>Dictionary views</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Sets</h2>
|
||||
<h3>Differences from Python 2</h3>
|
||||
<h3>Creating a new set</h3>
|
||||
@@ -112,9 +112,9 @@
|
||||
<h3>Deleting elements from a set</h3>
|
||||
<h3>Common set operations: union, intersection, and difference</h3>
|
||||
<h3>Frozen sets</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Numbers</h2>
|
||||
<h3>Differences from Python 2</h3>
|
||||
<h3>Integers</h3>
|
||||
@@ -122,527 +122,527 @@
|
||||
<h3>Floating point numbers</h3>
|
||||
<h3>Complex numbers</h3>
|
||||
<h3>Common numerical operations</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Strings</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>There ain't no such thing as "plain text"</h2>
|
||||
<h3>A brief history of character encoding</h3>
|
||||
<h3>What's a character?</h3>
|
||||
<h3>How strings are stored in memory</h3>
|
||||
<h3>Converting between different character encodings</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Differences from Python 2</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Formatting strings</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>What's my string?</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Lists and strings</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Historical note on the string module</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Byte streams</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>The power of introspection</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Using optional and named arguments</h2>
|
||||
<h3>Keyword-only arguments</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Using type, str, dir, and other built-in functions</h2>
|
||||
<h3>The type function</h3>
|
||||
<h3>The str function</h3>
|
||||
<h3>Built-in functions</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Getting object references with getattr</h2>
|
||||
<h3>getattr with modules</h3>
|
||||
<h3>getattr as a dispatcher</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Filtering lists</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>The peculiar nature of and and or</h2>
|
||||
<h3>Using the and-or trick</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Using lambda functions</h2>
|
||||
<h3>Real-world lambda functions</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Putting it all together</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Objects and object-orientation</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...major changes afoot...</h2>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Exceptions</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Files</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>File objects</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Reading files</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Close your files... or don't</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling I/O errors</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Writing to files</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Regular expressions</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Case study: street addresses</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Case study: Roman numerals</h2>
|
||||
<h3>Checking for thousands</h3>
|
||||
<h3>Checking for hundreds</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Using the {n,m} syntax</h2>
|
||||
<h3>Checking for tens and ones</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Verbose regular expressions</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Case study: parsing phone numbers</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>HTML processing</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>html5lib</h2>
|
||||
<h3>Installing html5lib</h3>
|
||||
<h3>Using html5lib</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Extracting data from HTML documents</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Building HTML documents</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Putting it all together</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>XML Processing</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...major changes afoot...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1><del>Scripts and streams</del></h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...will be folded into other chapters...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>HTTP web services</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>How not to fetch data over HTTP</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Features of HTTP</h2>
|
||||
<h3>User-Agent</h3>
|
||||
<h3>Redirects</h3>
|
||||
<h3>Last-Modified/If-Modified-Since</h3>
|
||||
<h3>ETag-If-None-Match</h3>
|
||||
<h3>Compression</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Differences from Python 2</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>httplib2 (note: needs port)</h2>
|
||||
<h3>Installing httplib2</h3>
|
||||
<h3>Why httplib2 is better than http.client</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Debugging HTTP web services</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Setting the User-Agent</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling Last-Modified and ETag</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling redirects</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling compressed data</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Putting it all together</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1><del>SOAP web services</del></h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...no one will miss you...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Unit testing</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Introduction to Roman numerals</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Introducing romantest.py</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Testing for success</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Testing for failure</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Testing for sanity</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Test-first programming</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>roman.py, stage 1</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>roman.py, stage 2</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>roman.py, stage 3</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>roman.py, stage 4</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>roman.py, stage 5</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Refactoring your code</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling bugs</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Handling changing requirements</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>The art of refactoring</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Postscript</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1><del>Functional programming</del></h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...bits and pieces will be folded into other chapters...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Dynamic functions</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 1</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 2</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 3</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 4</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 5</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>plural.py, stage 6</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Metaclasses</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...once I figure out WTF metaclasses are...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Performance tuning</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Using the timeit module</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Optimizing regular expressions</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Optimizing dictionary lookups</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Optimizing list operations</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Optimizing string manipulation</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Migrating old code to Python 3</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Diving in</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>The 2to3 migration tool</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Things the 2to3 tools won't catch</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Case study: feedparser</h2>
|
||||
<h3>Just shoot me</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Summary</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Creating graphics with the Python Imaging Library</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>...if it gets ported...</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h1>Packaging Python libraries</h1>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>A brief history of packaging (and why it's harder than you think)</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>setuptools</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>distutils</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Eggs</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>pip</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Platform-specific packaging</h2>
|
||||
<h3>Packaging by Linux distributions</h3>
|
||||
<h3>Py2exe</h3>
|
||||
<h3>Psyco</h3>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
@@ -650,41 +650,41 @@
|
||||
<h1>Where to go from here</h1>
|
||||
<p>Tentative because most of these have not been ported to Python 3 yet.</p>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>WSGI</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Django</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Pylons</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>TurboGears</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>AppEngine</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>IronPython</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Jython</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>PyPy</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<h2>Stackless Python</h2>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user