Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
shell中“set-x”的Python等价物是什么?_Python_Shell_Debugging - Fatal编程技术网

shell中“set-x”的Python等价物是什么?

shell中“set-x”的Python等价物是什么?,python,shell,debugging,Python,Shell,Debugging,请建议使用Python命令,该命令相当于shell脚本中的set-x 有没有办法打印/记录Python执行的每个源文件行?您可以使用以下模块: 上面的命令行将在执行时显示每一行代码。您可以使用该模块: 上面的命令行将在执行时显示每一行代码。要使用跟踪模块获得与bash-x适当等效的代码,需要使用--ignore dir来阻止打印导入的每个模块的源代码行,例如,python-m trace--trace--ignore dir/usr/lib/python2.7--ignore dir/usr/l

请建议使用Python命令,该命令相当于shell脚本中的
set-x

有没有办法打印/记录Python执行的每个源文件行?

您可以使用以下模块:

上面的命令行将在执行时显示每一行代码。

您可以使用该模块:


上面的命令行将在执行时显示每一行代码。

要使用
跟踪
模块获得与
bash-x
适当等效的代码,需要使用
--ignore dir
来阻止打印导入的每个模块的源代码行,例如,
python-m trace--trace--ignore dir/usr/lib/python2.7--ignore dir/usr/lib/pymodules repost.py
,根据需要为其他模块位置添加更多的
--ignore dir
指令

当试图定位缓慢加载的模块(如
请求
)时,这一点变得非常重要,这些模块在一台缓慢的机器上连续几分钟吐出数百万行源代码。正确使用
--ignore dir
可以将时间缩短到几秒钟,并且只显示您自己代码中的行

$ time python -m trace --trace repost.py 2>&1 | wc
3710176 16165000 200743489

real    1m54.302s
user    2m14.360s
sys 0m1.344s
vs

这并不能真正回答你的问题;您要求提供与Python相当的
set-x
。一种简单的近似方法是使用
sys.settrace()

当运行时,它提供:

jcomeau@aspire:/tmp$ ./test.py
this first line should not trace
19:     print 'this line and the following ought to show'
this line and the following ought to show
20:     print "that's all folks"
that's all folks
21:     TRACING.pop()
this last line should not trace
从跟踪输出中删除行“TRACING.pop()”留给读者作为练习


来源:和

要使用
跟踪
模块获得与
bash-x
适当等效的功能,需要使用
--ignore dir
来阻止打印导入的每个模块的源代码行,例如
python-m跟踪--trace--ignore dir/usr/lib/python2.7--ignore dir/usr/lib/pymodules repost.py
,根据其他模块位置的需要添加更多
--忽略dir
指令

当试图定位缓慢加载的模块(如
请求
)时,这一点变得非常重要,这些模块在一台缓慢的机器上连续几分钟吐出数百万行源代码。正确使用
--ignore dir
可以将时间缩短到几秒钟,并且只显示您自己代码中的行

$ time python -m trace --trace repost.py 2>&1 | wc
3710176 16165000 200743489

real    1m54.302s
user    2m14.360s
sys 0m1.344s
vs

这并不能真正回答你的问题;您要求提供与Python相当的
set-x
。一种简单的近似方法是使用
sys.settrace()

当运行时,它提供:

jcomeau@aspire:/tmp$ ./test.py
this first line should not trace
19:     print 'this line and the following ought to show'
this line and the following ought to show
20:     print "that's all folks"
that's all folks
21:     TRACING.pop()
this last line should not trace
从跟踪输出中删除行“TRACING.pop()”留给读者作为练习

资料来源:

我非常喜欢@jcomeau_ictx,但它有一个小缺陷,这就是我对它进行扩展的原因。问题在于,只有当所有要跟踪的代码都在用
python file.py
调用的文件(让我们称之为宿主文件)中时,jcomeau_ictx的“traceit”函数才能正常工作。如果调用任何导入的函数,就会得到很多没有代码的行号。原因是
line=linecache.getline(sys.argv[0],lineno)
总是试图从主机文件中获取代码行(
sys.argv[0]
)。这很容易纠正,因为实际包含跟踪代码行的文件名可以在
frame.f_code.co_filename
中找到。这现在可能会产生大量的输出,这就是为什么人们可能希望有更多的控制

还有一点需要注意。根据
sys.settrace()
文档:

每当发生错误时,将调用跟踪函数(将事件设置为“调用”) 输入新的本地范围

换句话说,要跟踪的代码必须在函数内部

为了保持一切整洁,我决定将一切都放在一个名为
setx.py
的文件中。代码应该是非常自解释的。然而,Python3兼容性需要一段代码,它处理Python2和Python3在模块导入方式方面的差异。这是可以解释的。这段代码现在也可以与Python2和Python3一起使用

##setx.py
from __future__ import print_function
import sys, linecache

##adapted from https://stackoverflow.com/a/33449763/2454357
##emulates bash's set -x and set +x

##for turning tracing on and off
TRACING = False

##FILENAMES defines which files should be traced
##by default this will on only be the host file 
FILENAMES = [sys.argv[0]]

##flag to ignore FILENAMES and alwas trace all files
##off by default
FOLLOWALL = False

def traceit(frame, event, arg):
    if event == "line":
        ##from https://stackoverflow.com/a/40945851/2454357
        while frame.f_code.co_filename.startswith('<frozen'):
            frame = frame.f_back
        filename = frame.f_code.co_filename
##        print(filename, FILENAMES)
        if TRACING and (
            filename in FILENAMES or
            filename+'c' in FILENAMES or
            FOLLOWALL
        ):
            lineno = frame.f_lineno
            line = linecache.getline(filename, lineno)
            print("{}, {}: {}".format(filename, lineno, line.rstrip()))
    return traceit

sys.settrace(traceit)

然后,输出如下所示:

##file1.py
def func1():
    return 7**2
setx_tester.py, 16:     x=5
setx_tester.py, 17:     print('the value of x is', x)
the value of x is 5
setx_tester.py, 20:     print('-'*50)
--------------------------------------------------
setx_tester.py, 22:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 23:     print(func1())
49
setx_tester.py, 24:     print(func2())
abcabcabc
setx_tester.py, 26:     print('-'*50)
--------------------------------------------------
setx_tester.py, 29:     setx.FILENAMES.append(file1.__file__)
setx_tester.py, 30:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 31:     print(func1())
**path to file**/file1.py, 2:     return 7**2
49
setx_tester.py, 32:     print(func2())
abcabcabc
setx_tester.py, 34:     print('-'*50)
--------------------------------------------------
setx_tester.py, 36:     setx.FILENAMES.pop()
setx_tester.py, 39:     setx.FOLLOWALL = True
setx_tester.py, 40:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 41:     print(func1())
**path to file**/file1.py, 2:     return 7**2
49
setx_tester.py, 42:     print(func2())
**path to file**/file2.py, 2:     return 'abc'*3
abcabcabc
我非常喜欢@jcomeau_ictx,但它有一个小缺陷,这就是我对它进行扩展的原因。问题在于,只有当所有要跟踪的代码都在用
python file.py
调用的文件(让我们称之为宿主文件)中时,jcomeau_ictx的“traceit”函数才能正常工作。如果调用任何导入的函数,就会得到很多没有代码的行号。原因是
line=linecache.getline(sys.argv[0],lineno)
总是试图从主机文件中获取代码行(
sys.argv[0]
)。这很容易纠正,因为实际包含跟踪代码行的文件名可以在
frame.f_code.co_filename
中找到。这现在可能会产生大量的输出,这就是为什么人们可能希望有更多的控制

还有一点需要注意。根据
sys.settrace()
文档:

每当发生错误时,将调用跟踪函数(将事件设置为“调用”) 输入新的本地范围

换句话说,要跟踪的代码必须在函数内部

为了保持一切整洁,我决定将一切都放在一个名为
setx.py
的文件中。代码应该是非常自解释的。然而,Python3兼容性需要一段代码,它处理Python2和Python3在模块导入方式方面的差异。这是可以解释的。这段代码现在也可以与Python2和Python3一起使用

##setx.py
from __future__ import print_function
import sys, linecache

##adapted from https://stackoverflow.com/a/33449763/2454357
##emulates bash's set -x and set +x

##for turning tracing on and off
TRACING = False

##FILENAMES defines which files should be traced
##by default this will on only be the host file 
FILENAMES = [sys.argv[0]]

##flag to ignore FILENAMES and alwas trace all files
##off by default
FOLLOWALL = False

def traceit(frame, event, arg):
    if event == "line":
        ##from https://stackoverflow.com/a/40945851/2454357
        while frame.f_code.co_filename.startswith('<frozen'):
            frame = frame.f_back
        filename = frame.f_code.co_filename
##        print(filename, FILENAMES)
        if TRACING and (
            filename in FILENAMES or
            filename+'c' in FILENAMES or
            FOLLOWALL
        ):
            lineno = frame.f_lineno
            line = linecache.getline(filename, lineno)
            print("{}, {}: {}".format(filename, lineno, line.rstrip()))
    return traceit

sys.settrace(traceit)

然后,输出如下所示:

##file1.py
def func1():
    return 7**2
setx_tester.py, 16:     x=5
setx_tester.py, 17:     print('the value of x is', x)
the value of x is 5
setx_tester.py, 20:     print('-'*50)
--------------------------------------------------
setx_tester.py, 22:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 23:     print(func1())
49
setx_tester.py, 24:     print(func2())
abcabcabc
setx_tester.py, 26:     print('-'*50)
--------------------------------------------------
setx_tester.py, 29:     setx.FILENAMES.append(file1.__file__)
setx_tester.py, 30:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 31:     print(func1())
**path to file**/file1.py, 2:     return 7**2
49
setx_tester.py, 32:     print(func2())
abcabcabc
setx_tester.py, 34:     print('-'*50)
--------------------------------------------------
setx_tester.py, 36:     setx.FILENAMES.pop()
setx_tester.py, 39:     setx.FOLLOWALL = True
setx_tester.py, 40:     print(inner_func())
setx_tester.py, 12:     return 15
15
setx_tester.py, 41:     print(func1())
**path to file**/file1.py, 2:     return 7**2
49
setx_tester.py, 42:     print(func2())
**path to file**/file2.py, 2:     return 'abc'*3
abcabcabc

我搜索的是“相当于
bash-x
”。我搜索的是“相当于
bash-x
”。我编写了一个默认情况下排除所有stdlib的小别名:alias pyx=“python-m trace--ignore dir$(python-c'import os,sys;print(os.pathsep.join)([p代表sys.path中的p,如果p中的“python3.5”)