总体答案
前三个撇号开始一个多行字符串。下一个撇号只是字符串内容的一部分。
检查结果
该脚本将字符串存储在__doc__变量中。使用 交互式运行代码后python -i pox.py
,很容易直接看到解析后的文档字符串:
>>> print __doc__
'true
#export OPT="-u -O"
export OPT="-u"
export FLG=""
if [ "$(basename $0)" = "debug-pox.py" ]; then
export OPT=""
export FLG="--debug"
fi
if [ -x pypy/bin/pypy ]; then
exec pypy/bin/pypy $OPT "$0" $FLG "$@"
fi
if type python2.7 > /dev/null 2> /dev/null; then
exec python2.7 $OPT "$0" $FLG "$@"
fi
exec python $OPT "$0" $FLG "$@"
请注意第四个撇号是如何作为文档字符串的一部分保留的。
细节
根据tokenize模块,以下是 Python 对上述代码的看法:
NL : '\n'
COMMENT : '#!/bin/sh -'
NL : '\n'
NL : '\n'
STRING : '\'\'\'\'true\n#export OPT="-u -O"\nexport OPT="-u"\nexport FLG=""\nif [ "$(basename $0)" = "debug-pox.py" ]; then\n export OPT=""\n export FLG="--debug"\nfi\n\nif [ -x pypy/bin/pypy ]; then\n exec pypy/bin/pypy $OPT "$0" $FLG "$@"\nfi\n\nif type python2.7 > /dev/null 2> /dev/null; then\n exec python2.7 $OPT "$0" $FLG "$@"\nfi\nexec python $OPT "$0" $FLG "$@"\n\'\'\''
NEWLINE : '\n'
NAME : 'from'
NAME : 'pox'
OP : '.'
NAME : 'boot'
NAME : 'import'
NAME : 'boot'
NEWLINE : '\n'
NAME : 'if'
NAME : '__name__'
OP : '=='
STRING : "'__main__'"
OP : ':'
NEWLINE : '\n'
INDENT : ' '
NAME : 'boot'
OP : '('
OP : ')'
NEWLINE : '\n'
DEDENT : ''
ENDMARKER : ''
标记化脚本
这是一个标记pox.py脚本的 Python 2.7脚本:
from __future__ import print_function
import tokenize
import token
with open('pox.py') as f:
for tok in tokenize.generate_tokens(f.readline):
tok_type, tok_str, (srow, scol), (erow, ecol), logical_lineno = tok
print('%-10s: %r' % (token.tok_name[tok_type], tok_str))