python 代码中的 4 个撇号
4 apostrophes in python code
引用https://github.com/noxrepo/pox/blob/carp/pox.py
我想了解 4 个撇号的含义?它看起来不像注释,在代码末尾还有另外 3 个撇号。有人可以帮忙解释下面的代码吗?
#!/bin/sh -
''''true
#export OPT="-u -O"
export OPT="-u"
export FLG=""
if [ "$(basename [=11=])" = "debug-pox.py" ]; then
export OPT=""
export FLG="--debug"
fi
if [ -x pypy/bin/pypy ]; then
exec pypy/bin/pypy $OPT "[=11=]" $FLG "$@"
fi
if type python2.7 > /dev/null 2> /dev/null; then
exec python2.7 $OPT "[=11=]" $FLG "$@"
fi
exec python $OPT "[=11=]" $FLG "$@"
'''
from pox.boot import boot
if __name__ == '__main__':
boot()
总体答案
前三个撇号开始一个多行字符串。下一个撇号只是字符串内容的一部分。
检查结果
脚本将字符串存储在 __doc__ 变量中。 运行代码与python -i pox.py
交互后,很容易直接看到解析后的docstring:
>>> print __doc__
'true
#export OPT="-u -O"
export OPT="-u"
export FLG=""
if [ "$(basename [=10=])" = "debug-pox.py" ]; then
export OPT=""
export FLG="--debug"
fi
if [ -x pypy/bin/pypy ]; then
exec pypy/bin/pypy $OPT "[=10=]" $FLG "$@"
fi
if type python2.7 > /dev/null 2> /dev/null; then
exec python2.7 $OPT "[=10=]" $FLG "$@"
fi
exec python $OPT "[=10=]" $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 [=11=])" = "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 "[=11=]" $FLG "$@"\nfi\n\nif type python2.7 > /dev/null 2> /dev/null; then\n exec python2.7 $OPT "[=11=]" $FLG "$@"\nfi\nexec python $OPT "[=11=]" $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 : ''
标记化脚本
这是一个 Python 2.7 脚本,它标记了 pox.py 脚本:
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))
这个文件可以作为 shell 脚本 和 Python 脚本执行。请注意,shebang 是 #!/bin/sh
,因此该脚本首先要 运行 作为 shell 脚本。 (我忽略了 -
参数,这表明 sh
应该从标准输入而不是文件中读取。我不太确定它在这里有什么意义,因为我从未见过那样写的 shebang。)
预期的调用类似于 ./pox.py ...
或 sh ./pox.py ...
脚本的第一行是 ''''true
,删除引号后与 true
相同,因此命令 运行s 除了成功退出外什么都不做。以下几行是确定要使用哪个 Python 解释器以及要传递给调用的选项的有效命令。三个 exec
命令之一
exec pypy/bin/pypy $OPT "[=19=]" $FLG "$@"
exec python2.7 $OPT "[=20=]" $FLG "$@"
exec python $OPT "[=21=]" $FLG "$@"
将执行与 Python 脚本相同的文件,因此 shell 永远不会看到以第二个 '''
开头的行(这很好,因为单词由第一个 '
开始既不会以最终结束 '
终止,如果字符串 被 终止也不会是有效命令)。 "[=25=]"
是当前文件的名称,"$@"
表示脚本的参数(除了传递给 Python 脚本外,shell 脚本会忽略这些参数,如此处所示)。
一旦脚本 运行 作为 Python 脚本,开始 ''''true
的行将被简单地视为将被忽略的文档字符串的开头。 Python 脚本本身就是
from pox.boot import boot
if __name__ == '__main__':
boot()
至于为什么这一切都要从''''true
开始?作为一个 shell 脚本,你需要有偶数个引号来平衡彼此。但是,''''
本身就是一个空字符串,shell 会尝试将其视为命令,并且没有名称为空字符串的命令。然而,''''true
确实产生了有效的命令。
引用https://github.com/noxrepo/pox/blob/carp/pox.py
我想了解 4 个撇号的含义?它看起来不像注释,在代码末尾还有另外 3 个撇号。有人可以帮忙解释下面的代码吗?
#!/bin/sh -
''''true
#export OPT="-u -O"
export OPT="-u"
export FLG=""
if [ "$(basename [=11=])" = "debug-pox.py" ]; then
export OPT=""
export FLG="--debug"
fi
if [ -x pypy/bin/pypy ]; then
exec pypy/bin/pypy $OPT "[=11=]" $FLG "$@"
fi
if type python2.7 > /dev/null 2> /dev/null; then
exec python2.7 $OPT "[=11=]" $FLG "$@"
fi
exec python $OPT "[=11=]" $FLG "$@"
'''
from pox.boot import boot
if __name__ == '__main__':
boot()
总体答案
前三个撇号开始一个多行字符串。下一个撇号只是字符串内容的一部分。
检查结果
脚本将字符串存储在 __doc__ 变量中。 运行代码与python -i pox.py
交互后,很容易直接看到解析后的docstring:
>>> print __doc__
'true
#export OPT="-u -O"
export OPT="-u"
export FLG=""
if [ "$(basename [=10=])" = "debug-pox.py" ]; then
export OPT=""
export FLG="--debug"
fi
if [ -x pypy/bin/pypy ]; then
exec pypy/bin/pypy $OPT "[=10=]" $FLG "$@"
fi
if type python2.7 > /dev/null 2> /dev/null; then
exec python2.7 $OPT "[=10=]" $FLG "$@"
fi
exec python $OPT "[=10=]" $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 [=11=])" = "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 "[=11=]" $FLG "$@"\nfi\n\nif type python2.7 > /dev/null 2> /dev/null; then\n exec python2.7 $OPT "[=11=]" $FLG "$@"\nfi\nexec python $OPT "[=11=]" $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 : ''
标记化脚本
这是一个 Python 2.7 脚本,它标记了 pox.py 脚本:
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))
这个文件可以作为 shell 脚本 和 Python 脚本执行。请注意,shebang 是 #!/bin/sh
,因此该脚本首先要 运行 作为 shell 脚本。 (我忽略了 -
参数,这表明 sh
应该从标准输入而不是文件中读取。我不太确定它在这里有什么意义,因为我从未见过那样写的 shebang。)
预期的调用类似于 ./pox.py ...
或 sh ./pox.py ...
脚本的第一行是 ''''true
,删除引号后与 true
相同,因此命令 运行s 除了成功退出外什么都不做。以下几行是确定要使用哪个 Python 解释器以及要传递给调用的选项的有效命令。三个 exec
命令之一
exec pypy/bin/pypy $OPT "[=19=]" $FLG "$@"
exec python2.7 $OPT "[=20=]" $FLG "$@"
exec python $OPT "[=21=]" $FLG "$@"
将执行与 Python 脚本相同的文件,因此 shell 永远不会看到以第二个 '''
开头的行(这很好,因为单词由第一个 '
开始既不会以最终结束 '
终止,如果字符串 被 终止也不会是有效命令)。 "[=25=]"
是当前文件的名称,"$@"
表示脚本的参数(除了传递给 Python 脚本外,shell 脚本会忽略这些参数,如此处所示)。
一旦脚本 运行 作为 Python 脚本,开始 ''''true
的行将被简单地视为将被忽略的文档字符串的开头。 Python 脚本本身就是
from pox.boot import boot
if __name__ == '__main__':
boot()
至于为什么这一切都要从''''true
开始?作为一个 shell 脚本,你需要有偶数个引号来平衡彼此。但是,''''
本身就是一个空字符串,shell 会尝试将其视为命令,并且没有名称为空字符串的命令。然而,''''true
确实产生了有效的命令。