pdbThe Python DebuggerPython调试器

Source code: Lib/pdb.py


The module pdb defines an interactive source code debugger for Python programs. pdb模块为Python程序定义了一个交互式源代码调试器。It supports setting (conditional) breakpoints and single stepping at the source line level, inspection of stack frames, source code listing, and evaluation of arbitrary Python code in the context of any stack frame. 它支持在源代码行级别设置(有条件)断点和单步执行,检查堆栈帧、源代码列表,以及在任何堆栈帧的上下文中评估任意Python代码。It also supports post-mortem debugging and can be called under program control.它还支持事后调试,可以在程序控制下调用。

The debugger is extensible – it is actually defined as the class Pdb. 调试器是可扩展的,它实际上被定义为类PdbThis is currently undocumented but easily understood by reading the source. 这是目前未记录的,但通过阅读源代码很容易理解。The extension interface uses the modules bdb and cmd.扩展接口使用模块bdbcmd

The debugger’s prompt is (Pdb). Typical usage to run a program under control of the debugger is:调试器的提示是(Pdb)。在调试器控制下运行程序的典型用法是:

>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)

Changed in version 3.3:版本3.3中更改: Tab-completion via the readline module is available for commands and command arguments, e.g. the current global and local names are offered as arguments of the p command.通过readline模块完成的制表符可用于命令和命令参数,例如,当前的全局和本地名称作为p命令的参数提供。

pdb.py can also be invoked as a script to debug other scripts. 也可以作为脚本调用以调试其他脚本。For example:例如:

python3 -m pdb myscript.py

When invoked as a script, pdb will automatically enter post-mortem debugging if the program being debugged exits abnormally. 当作为脚本调用时,如果正在调试的程序异常退出,pdb将自动进入事后调试。After post-mortem debugging (or after normal exit of the program), pdb will restart the program. 在事后调试后(或程序正常退出后),pdb将重新启动程序。Automatic restarting preserves pdb’s state (such as breakpoints) and in most cases is more useful than quitting the debugger upon program’s exit.自动重新启动会保留pdb的状态(如断点),在大多数情况下,它比在程序退出时退出调试器更有用。

New in version 3.2.版本3.2中新增。pdb.py now accepts a -c option that executes commands as if given in a .pdbrc file, see Debugger Commands.pdb.py现在接受-c选项,该选项执行命令,就像在.pdbrc文件中给出的一样,请参阅调试器命令

New in version 3.7.版本3.7中新增。pdb.py now accepts a -m option that execute modules similar to the way python3 -m does. pdb.py现在接受-m选项,该选项执行模块的方式与python3 -m类似。As with a script, the debugger will pause execution just before the first line of the module.与脚本一样,调试器将在模块的第一行之前暂停执行。

The typical usage to break into the debugger is to insert:闯入调试器的典型用法是插入:

import pdb; pdb.set_trace()

at the location you want to break into the debugger, and then run the program. 在您要闯入调试器的位置,然后运行程序。You can then step through the code following this statement, and continue running without the debugger using the continue command.然后,您可以单步执行此语句后面的代码,并使用continue命令在没有调试器的情况下继续运行。

New in version 3.7.版本3.7中新增。The built-in breakpoint(), when called with defaults, can be used instead of import pdb; pdb.set_trace().当使用默认值调用时,可以使用内置breakpoint()来代替import pdb; pdb.set_trace()

The typical usage to inspect a crashed program is:检查崩溃程序的典型用法是:

>>> import pdb
>>> import mymodule
>>> mymodule.test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "./mymodule.py", line 4, in test
test2()
File "./mymodule.py", line 3, in test2
print(spam)
NameError: spam
>>> pdb.pm()
> ./mymodule.py(3)test2()
-> print(spam)
(Pdb)

The module defines the following functions; each enters the debugger in a slightly different way:该模块定义了以下功能:;每个都以稍微不同的方式进入调试器:

pdb.run(statement, globals=None, locals=None)

Execute the statement (given as a string or a code object) under debugger control. 在调试器控制下执行statement(作为字符串或代码对象给出)。The debugger prompt appears before any code is executed; you can set breakpoints and type continue, or you can step through the statement using step or next (all these commands are explained below). 在执行任何代码之前都会出现调试器提示;您可以设置断点并键入continue,也可以使用stepnext单步执行语句(所有这些命令将在下面解释)。The optional globals and locals arguments specify the environment in which the code is executed; by default the dictionary of the module __main__ is used. 可选的globals变量和locals变量指定执行代码的环境;默认情况下,使用模块__main__的字典。(See the explanation of the built-in exec() or eval() functions.)(请参阅内置exec()eval()函数的说明。)

pdb.runeval(expression, globals=None, locals=None)

Evaluate the expression (given as a string or a code object) under debugger control. 在调试器控制下计算expression(作为字符串或代码对象给出)。When runeval() returns, it returns the value of the expression. runeval()返回时,它返回表达式的值。Otherwise this function is similar to run().否则,此函数类似于run()

pdb.runcall(function, *args, **kwds)

Call the function (a function or method object, not a string) with the given arguments. 使用给定的参数调用function(函数或方法对象,而不是字符串)。When runcall() returns, it returns whatever the function call returned. runcall()返回时,它将返回函数调用返回的任何内容。The debugger prompt appears as soon as the function is entered.输入函数后,调试器提示立即出现。

pdb.set_trace(*, header=None)

Enter the debugger at the calling stack frame. 在调用堆栈帧处输入调试器。This is useful to hard-code a breakpoint at a given point in a program, even if the code is not otherwise being debugged (e.g. when an assertion fails). 这对于在程序中的给定点硬编码断点非常有用,即使代码没有被调试(例如,当断言失败时)。If given, header is printed to the console just before debugging begins.如果给定,则在调试开始之前将header打印到控制台。

Changed in version 3.7:版本3.7中更改: The keyword-only argument header.仅关键字参数header

pdb.post_mortem(traceback=None)

Enter post-mortem debugging of the given traceback object. 输入给定traceback对象的事后调试。If no traceback is given, it uses the one of the exception that is currently being handled (an exception must be being handled if the default is to be used).如果没有给出traceback,则使用当前正在处理的异常之一(如果要使用默认值,则必须处理异常)。

pdb.pm()

Enter post-mortem debugging of the traceback found in sys.last_traceback.输入sys.last_traceback中找到的回溯的事后调试。

The run* functions and set_trace() are aliases for instantiating the Pdb class and calling the method of the same name. run*函数和set_trace()是用于实例化Pdb类和调用同名方法的别名。If you want to access further features, you have to do this yourself:如果您想访问更多功能,您必须自己执行以下操作:

classpdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True)

Pdb is the debugger class.

The completekey, stdin and stdout arguments are passed to the underlying cmd.Cmd class; see the description there.completekeystdinstdout参数传递给基础cmd.Cmd类;请参阅此处的描述。

The skip argument, if given, must be an iterable of glob-style module name patterns. 如果给定了skip参数,则该参数必须是glob样式模块名称模式的可迭代参数。The debugger will not step into frames that originate in a module that matches one of these patterns. 调试器不会单步执行源自与这些模式之一匹配的模块的帧。1

By default, Pdb sets a handler for the SIGINT signal (which is sent when the user presses Ctrl-C on the console) when you give a continue command. 默认情况下,当您发出continue命令时,Pdb为SIGINT信号(当用户在控制台上按下Ctrl-C时发送)设置一个处理程序。This allows you to break into the debugger again by pressing Ctrl-C. 这允许您通过按Ctrl-C再次进入调试器。If you want Pdb not to touch the SIGINT handler, set nosigint to true.如果希望Pdb不接触SIGINT处理程序,请将nosgint设置为true

The readrc argument defaults to true and controls whether Pdb will load .pdbrc files from the filesystem.readrc参数默认为true,并控制Pdb是否从文件系统加载.pdbrc文件。

Example call to enable tracing with skip:使用skip启用跟踪的示例调用:

import pdb; pdb.Pdb(skip=['django.*']).set_trace()

Raises an auditing event pdb.Pdb with no arguments.引发不带参数的审核事件pdb.Pdb

New in version 3.1.版本3.1中新增。The skip argument.skip参数。

New in version 3.2.版本3.2中新增。The nosigint argument. nosigint参数。Previously, a SIGINT handler was never set by Pdb.以前,Pdb从未设置SIGINT处理程序。

Changed in version 3.6:版本3.6中更改: The readrc argument.readrc参数。

run(statement, globals=None, locals=None)
runeval(expression, globals=None, locals=None)
runcall(function, *args, **kwds)
set_trace()

See the documentation for the functions explained above.有关上述功能,请参阅文档。

Debugger Commands调试器命令

The commands recognized by the debugger are listed below. 调试器识别的命令如下所示。Most commands can be abbreviated to one or two letters as indicated; e.g. h(elp) means that either h or help can be used to enter the help command (but not he or hel, nor H or Help or HELP). 大多数命令可以缩写为一个或两个字母,如所示;例如,h(help)表示可以使用hhelp输入帮助命令(但不能使用hehel,也不能使用HHelpHELP)。Arguments to commands must be separated by whitespace (spaces or tabs). 命令的参数必须用空格(空格或制表符)分隔。Optional arguments are enclosed in square brackets ([]) in the command syntax; the square brackets must not be typed. 可选参数在命令语法中用方括号([])括起来;不得键入方括号。Alternatives in the command syntax are separated by a vertical bar (|).命令语法中的替代项由竖条(|)分隔。

Entering a blank line repeats the last command entered. 输入空行重复上次输入的命令。Exception: if the last command was a list command, the next 11 lines are listed.异常:如果最后一个命令是list命令,则会列出接下来的11行。

Commands that the debugger doesn’t recognize are assumed to be Python statements and are executed in the context of the program being debugged. 调试器无法识别的命令被假定为Python语句,并在正在调试的程序的上下文中执行。Python statements can also be prefixed with an exclamation point (!). Python语句也可以以感叹号(!)作为前缀。This is a powerful way to inspect the program being debugged; it is even possible to change a variable or call a function. 这是检查正在调试的程序的强大方法;甚至可以更改变量或调用函数。When an exception occurs in such a statement, the exception name is printed but the debugger’s state is not changed.当此类语句中发生异常时,将打印异常名称,但不会更改调试器的状态。

The debugger supports aliases. 调试器支持别名Aliases can have parameters which allows one a certain level of adaptability to the context under examination.别名可以具有参数,这些参数允许对所检查的上下文具有一定程度的适应性。

Multiple commands may be entered on a single line, separated by ;;. 可以在一行中输入多个命令,以;;分隔。(A single ; is not used as it is the separator for multiple commands in a line that is passed to the Python parser.) (不使用单个;因为它是传递给Python解析器的一行中多个命令的分隔符。)No intelligence is applied to separating the commands; the input is split at the first ;; pair, even if it is in the middle of a quoted string.没有智能用于分离命令;所述输入在第一个处;;对被分割,即使它位于引用字符串的中间。

If a file .pdbrc exists in the user’s home directory or in the current directory, it is read in and executed as if it had been typed at the debugger prompt. 如果文件.pdbrc存在于用户的主目录或当前目录中,则会像在调试器提示符下键入一样读入并执行该文件。This is particularly useful for aliases. 这对于别名特别有用。If both files exist, the one in the home directory is read first and aliases defined there can be overridden by the local file.如果两个文件都存在,则首先读取主目录中的文件,并且本地文件可以覆盖在其中定义的别名。

Changed in version 3.2:版本3.2中更改: .pdbrc can now contain commands that continue debugging, such as continue or next. .pdbrc现在可以包含继续调试的命令,例如continuenextPreviously, these commands had no effect.以前,这些命令没有效果。

h(elp) [command]

Without argument, print the list of available commands. With a command as argument, print help about that command. 不带参数,打印可用命令列表。以command作为参数,打印有关该命令的帮助。help pdb displays the full documentation (the docstring of the pdb module). 显示完整的文档(pdb模块的文档字符串)。Since the command argument must be an identifier, help exec must be entered to get help on the ! command.由于command参数必须是标识符,因此必须输入help exec才能获取!命令

w(here)

Print a stack trace, with the most recent frame at the bottom. 打印堆栈跟踪,最新的帧位于底部。An arrow indicates the current frame, which determines the context of most commands.箭头指示当前帧,它决定了大多数命令的上下文。

d(own) [count]

Move the current frame count (default one) levels down in the stack trace (to a newer frame).在堆栈跟踪中向下移动当前帧count(默认值为1)级别(到较新的帧)。

u(p) [count]

Move the current frame count (default one) levels up in the stack trace (to an older frame).在堆栈跟踪中向上移动当前帧count(默认值为1)级别(移动到较旧的帧)。

b(reak) [([filename:]lineno | function) [, condition]]

With a lineno argument, set a break there in the current file. 使用lineno参数,在当前文件中设置断点。With a function argument, set a break at the first executable statement within that function. 使用function参数,在该函数中的第一个可执行语句处设置一个断点。The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (probably one that hasn’t been loaded yet). 行号可以以文件名和冒号作为前缀,以指定另一个文件(可能是尚未加载的文件)中的断点。The file is searched on sys.path. sys.path上搜索该文件。Note that each breakpoint is assigned a number to which all the other breakpoint commands refer.注意,每个断点都分配了一个数字,所有其他断点命令都引用该数字。

If a second argument is present, it is an expression which must evaluate to true before the breakpoint is honored.如果存在第二个参数,则它是一个表达式,在执行断点之前,该表达式的计算结果必须为true

Without argument, list all breaks, including for each breakpoint, the number of times that breakpoint has been hit, the current ignore count, and the associated condition if any.在没有参数的情况下,列出所有断点,包括每个断点、该断点的命中次数、当前忽略计数以及相关条件(如果有)。

tbreak [([filename:]lineno | function) [, condition]]

Temporary breakpoint, which is removed automatically when it is first hit. 临时断点,首次命中时自动删除。The arguments are the same as for break.参数与break相同。

cl(ear) [filename:lineno | bpnumber ...]

With a filename:lineno argument, clear all the breakpoints at this line. 使用filename:lineno参数,清除此行的所有断点。With a space separated list of breakpoint numbers, clear those breakpoints. 使用空格分隔的断点编号列表,清除这些断点。Without argument, clear all breaks (but first ask confirmation).无需争论,清除所有中断(但首先要求确认)。

disable [bpnumber ...]

Disable the breakpoints given as a space separated list of breakpoint numbers. 禁用以空格分隔的断点编号列表给出的断点。Disabling a breakpoint means it cannot cause the program to stop execution, but unlike clearing a breakpoint, it remains in the list of breakpoints and can be (re-)enabled.禁用断点意味着它不能导致程序停止执行,但与清除断点不同,它仍保留在断点列表中,并且可以(重新)启用。

enable [bpnumber ...]

Enable the breakpoints specified.启用指定的断点。

ignore bpnumber [count]

Set the ignore count for the given breakpoint number. 设置给定断点编号的忽略计数。If count is omitted, the ignore count is set to 0. 如果忽略计数,则忽略计数设置为0。A breakpoint becomes active when the ignore count is zero. 当忽略计数为零时,断点变为活动状态。When non-zero, the count is decremented each time the breakpoint is reached and the breakpoint is not disabled and any associated condition evaluates to true.当非零时,每次到达断点时,计数都会递减,并且不会禁用断点,并且任何相关条件的计算结果都为true

condition bpnumber [condition]

Set a new condition for the breakpoint, an expression which must evaluate to true before the breakpoint is honored. 为断点设置一个新condition,该表达式必须在满足断点之前计算为trueIf condition is absent, any existing condition is removed; i.e., the breakpoint is made unconditional.如果condition不存在,则删除任何现有条件;即,断点是无条件的。

commands [bpnumber]

Specify a list of commands for breakpoint number bpnumber. 为断点编号bpnumber指定命令列表。The commands themselves appear on the following lines. 命令本身显示在以下行中。Type a line containing just end to terminate the commands. 键入仅包含end的行以终止命令。An example:例如:

(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)

To remove all commands from a breakpoint, type commands and follow it immediately with end; that is, give no commands.要从断点中删除所有命令,请键入commands,然后立即以end结尾;即不发出命令。

With no bpnumber argument, commands refers to the last breakpoint set.如果没有bpnumber参数,commands将引用最后一个断点集。

You can use breakpoint commands to start your program up again. 您可以使用断点命令重新启动程序。Simply use the continue command, or step, or any other command that resumes execution.只需使用continue命令、step或任何其他恢复执行的命令。

Specifying any command resuming execution (currently continue, step, next, return, jump, quit and their abbreviations) terminates the command list (as if that command was immediately followed by end). 指定任何继续执行的命令(当前为continuestepnextreturnjumpquit及其缩写)将终止命令列表(就像该命令后面紧跟着end一样)。This is because any time you resume execution (even with a simple next or step), you may encounter another breakpoint—which could have its own command list, leading to ambiguities about which list to execute.这是因为无论何时恢复执行(即使是简单的下一步或步骤),都可能遇到另一个断点,该断点可能有自己的命令列表,从而导致执行哪个列表的歧义。

If you use the ‘silent’ command in the command list, the usual message about stopping at a breakpoint is not printed. 如果在命令列表中使用“silent”命令,则不会打印有关在断点处停止的常见消息。This may be desirable for breakpoints that are to print a specific message and then continue. 对于要打印特定消息然后继续的断点,这可能是可取的。If none of the other commands print anything, you see no sign that the breakpoint was reached.如果其他命令都没有打印任何内容,则不会看到到达断点的迹象。

s(tep)

Execute the current line, stop at the first possible occasion (either in a function that is called or on the next line in the current function).执行当前行,在第一次可能的情况下停止(在调用的函数中或在当前函数的下一行)。

n(ext)

Continue execution until the next line in the current function is reached or it returns. 继续执行,直到到达当前函数中的下一行或返回。(The difference between next and step is that step stops inside a called function, while next executes called functions at (nearly) full speed, only stopping at the next line in the current function.)nextstep的区别在于,step在被调用函数内部停止,而next以(几乎)全速执行被调用函数,只在当前函数的下一行停止。)

unt(il) [lineno]

Without argument, continue execution until the line with a number greater than the current one is reached.在没有参数的情况下,继续执行,直到达到数字大于当前数字的行。

With a line number, continue execution until a line with a number greater or equal to that is reached. 对于行号,继续执行,直到达到大于或等于该行号的行。In both cases, also stop when the current frame returns.在这两种情况下,当当前帧返回时也会停止。

Changed in version 3.2:版本3.2中更改: Allow giving an explicit line number.允许给出明确的行号。

r(eturn)

Continue execution until the current function returns.继续执行,直到当前函数返回。

c(ont(inue))

Continue execution, only stop when a breakpoint is encountered.继续执行,仅在遇到断点时停止。

j(ump) lineno

Set the next line that will be executed. Only available in the bottom-most frame. 设置要执行的下一行。仅在最底部框架中可用。This lets you jump back and execute code again, or jump forward to skip code that you don’t want to run.这让您可以跳回来再次执行代码,或者跳过去跳过不想运行的代码。

It should be noted that not all jumps are allowed – for instance it is not possible to jump into the middle of a for loop or out of a finally clause.需要注意的是,并不是所有的跳转都是允许的,例如,不可能跳转到for循环的中间或跳出finally子句。

l(ist) [first[, last]]

List source code for the current file. Without arguments, list 11 lines around the current line or continue the previous listing. 列出当前文件的源代码。如果没有参数,请在当前行周围列出11行或继续上一行。With . as argument, list 11 lines around the current line. 具有.作为参数,列出当前行周围的11行。With one argument, list 11 lines around at that line. 用一个参数,列出该行周围的11行。With two arguments, list the given range; if the second argument is less than the first, it is interpreted as a count.使用两个参数,列出给定范围;如果第二个参数小于第一个参数,则将其解释为计数。

The current line in the current frame is indicated by ->. 当前帧中的当前行由->指示。If an exception is being debugged, the line where the exception was originally raised or propagated is indicated by >>, if it differs from the current line.如果正在调试异常,则最初引发或传播异常的行由>>指示,如果它与当前行不同。

New in version 3.2.版本3.2中新增。The >> marker.

ll | longlist

List all source code for the current function or frame. 列出当前函数或框架的所有源代码。Interesting lines are marked as for list.有趣的行被标记为list

New in version 3.2.版本3.2中新增。

a(rgs)

Print the argument list of the current function.打印当前函数的参数列表。

p expression

Evaluate the expression in the current context and print its value.计算当前上下文中的expression并打印其值。

Note

print() can also be used, but is not a debugger command — this executes the Python print() function.print()也可以使用,但不是调试器命令-它执行Python print()函数。

pp expression

Like the p command, except the value of the expression is pretty-printed using the pprint module.p命令类似,不同的是表达式的值是使用pprint模块打印出来的。

whatis expression

Print the type of the expression.打印expression的类型。

source expression

Try to get source code for the given object and display it.尝试获取给定对象的源代码并显示它。

New in version 3.2.版本3.2中新增。

display [expression]

Display the value of the expression if it changed, each time execution stops in the current frame.每次在当前帧中停止执行时,显示表达式的值(如果已更改)。

Without expression, list all display expressions for the current frame.如果没有表达式,请列出当前帧的所有显示表达式。

New in version 3.2.版本3.2中新增。

undisplay [expression]

Do not display the expression any more in the current frame. 不再在当前帧中显示表达式。Without expression, clear all display expressions for the current frame.如果没有表达式,请清除当前帧的所有显示表达式。

New in version 3.2.版本3.2中新增。

interact

Start an interactive interpreter (using the code module) whose global namespace contains all the (global and local) names found in the current scope.启动一个交互式解释器(使用code模块),其全局命名空间包含当前范围中找到的所有(全局和本地)名称。

New in version 3.2.版本3.2中新增。

alias [name [command]]

Create an alias called name that executes command. 创建执行command的别名nameThe command must not be enclosed in quotes. 命令不能用引号括起来。Replaceable parameters can be indicated by %1, %2, and so on, while %* is replaced by all the parameters. 可替换参数可以由%1%2等表示,而%*由所有参数替换。If no command is given, the current alias for name is shown. 如果未给出命令,则显示name的当前别名。If no arguments are given, all aliases are listed.如果未给定参数,则列出所有别名。

Aliases may be nested and can contain anything that can be legally typed at the pdb prompt. 别名可以是嵌套的,可以包含任何可以在pdb提示符下合法键入的内容。Note that internal pdb commands can be overridden by aliases. 注意,内部pdb命令可以被别名覆盖。Such a command is then hidden until the alias is removed. 然后隐藏这样的命令,直到删除别名。Aliasing is recursively applied to the first word of the command line; all other words in the line are left alone.别名递归地应用于命令行的第一个字;行中的所有其他单词都被单独保留。

As an example, here are two useful aliases (especially when placed in the .pdbrc file):例如,这里有两个有用的别名(尤其是放在.pdbrc文件中时):

# Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
# Print instance variables in self
alias ps pi self
unalias name

Delete the specified alias.删除指定的别名。

! statement

Execute the (one-line) statement in the context of the current stack frame. 在当前堆栈帧的上下文中执行(单行)statementThe exclamation point can be omitted unless the first word of the statement resembles a debugger command. 除非语句的第一个单词类似于调试器命令,否则可以省略感叹号。To set a global variable, you can prefix the assignment command with a global statement on the same line, e.g.:要设置全局变量,可以在赋值命令的同一行加上global语句,例如:

(Pdb) global list_options; list_options = ['-l']
(Pdb)
run [args ...]
restart [args ...]

Restart the debugged Python program. 重新启动调试过的Python程序。If an argument is supplied, it is split with shlex and the result is used as the new sys.argv. 如果提供了参数,则使用shlex对其进行拆分,结果将用作新的sys.argvHistory, breakpoints, actions and debugger options are preserved. 保留历史记录、断点、操作和调试器选项。restart is an alias for run.restartrun的别名。

q(uit)

Quit from the debugger. 退出调试器。The program being executed is aborted.正在执行的程序被中止。

debug code

Enter a recursive debugger that steps through the code argument (which is an arbitrary expression or statement to be executed in the current environment).输入一个递归调试器,它单步执行代码参数(这是要在当前环境中执行的任意表达式或语句)。

retval

Print the return value for the last return of a function.打印函数最后一次返回的返回值。

Footnotes

1

Whether a frame is considered to originate in a certain module is determined by the __name__ in the frame globals.帧是否被认为源自某个模块取决于帧全局中的__name__