首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python代码中的4个撇号

python代码中的4个撇号
EN

Stack Overflow用户
提问于 2017-11-07 02:30:44
回答 2查看 350关注 0票数 2

参考https://github.com/noxrepo/pox/blob/carp/pox.py

我想弄明白四个撇号是什么意思?它看起来不像注释,在代码的末尾还有另外3个撇号。有人能帮忙解释下面的代码吗?

代码语言:javascript
复制
#!/bin/sh -

''''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 "$@"
'''
from pox.boot import boot
if __name__ == '__main__':
  boot()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-07 04:09:20

总体答案

前三个撇号开始一个多行字符串。下一个撇号只是字符串内容的一部分。

检查结果

脚本将字符串存储在__doc__变量中。在与python -i pox.py交互运行代码之后,很容易直接看到解析的文档串

代码语言:javascript
复制
>>> 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 "$@"

注意第四个撇号是如何作为docstring的一部分保存的。

详细信息

根据https://docs.python.org/2.7/library/tokenize.html#module-tokenize模块,下面是Python如何查看上面的代码:

代码语言:javascript
复制
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 : ''

标记化脚本

下面是一个Python2.7脚本,它标记了pox.py脚本:

代码语言:javascript
复制
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))
票数 3
EN

Stack Overflow用户

发布于 2017-11-07 14:19:34

这是一个可以同时作为shell脚本和Python脚本执行的文件。注意,该脚本是#!/bin/sh,因此该脚本打算首先作为一个shell脚本运行。(我忽略了-参数,它指示sh应该从标准输入而不是文件读取。我不太清楚它在这里有什么意义,因为我从来没有见过这样写的。)

预期的调用类似于./pox.py ...sh ./pox.py ...

脚本的第一行是''''true,它在移除引号后与true相同,因此命令将运行,除了退出外什么也不做。下面的行是确定要使用哪个Python解释器以及传递给调用的选项的有效命令。三个exec命令中的一个

  1. exec pypy/bin/pypy $OPT "$0" $FLG "$@"
  2. exec python2.7 $OPT "$0" $FLG "$@"
  3. exec python $OPT "$0" $FLG "$@"

然后将执行与Python相同的文件,因此以第二个'''开头的行永远不会被shell看到(这很好,因为由第一个'启动的单词既不会以最后的关闭'结束,如果它被终止,字符串也不会是一个有效的命令)。"$0"是当前文件的名称,"$@"表示脚本的参数(除了传递给Python之外,这些参数被shell脚本忽略,如下所示)。

一旦脚本作为Python运行,启动''''true的行就被简单地看作是将被忽略的文档字符串的开始。Python脚本本身很简单

代码语言:javascript
复制
from pox.boot import boot
if __name__ == '__main__':
  boot()

为什么这一切必须从''''true开始呢?作为一个shell脚本,您需要有一个偶数的引号来平衡彼此。但是,仅''''将是一个空字符串,shell将尝试将其作为命令来处理,并且没有名称为空字符串的命令。然而,''''true确实会产生一个有效的命令。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47149060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档