这取决于你如何“运行”python文件。从pycharm内部有很多种方法可以做到这一点(可能太多了)。
我猜你正在按下绿色三角形。这不会在存在于底部的“Python Console”选项卡中的同一shell中执行文件。它代替生成一个新的shell,执行文件,并默认情况下在文件执行完成时关闭shell。您可以在“Run”选项卡中看到此Shell的操作过程。从Shivendra的回复中可以看出,似乎有一种方法可以避免在脚本退出时终止shell。如果确实是这样,那么您将使用保留在“Run”选项卡中而非在“Python控制台”选项卡中的终端/ shell。
这与使用Debug而非Run时发生的情况非常相似。它生成一个解释器,附加调试器,运行脚本,在所有操作完成后杀死进程。这保存在“Debug”选项卡中。
实现您想要的最简单的方法是在预先存在的“Python Console”中运行文件,如下所示。在这种情况下,脚本会像__main__一样运行,因此,如果您有一个
if __name__ == "__main__"
,它将计算为True,并且if块中的任何代码也将被执行。(稍后再详细介绍,如果您现在不知道它是什么)
In[2]: dir()
Out[2]:
['In',
'Out',
'_',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__name__',
'__package__',
'_dh',
'_i',
'_i1',
'_i2',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'exit',
'get_ipython',
'quit',
'sys']
In[3]: run -m conventions.iec60063
In[4]: dir()
Out[4]:
['Decimal',
'E12',
'E24',
'E3',
'E6',
'In',
'Out',
'_',
'_3',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__nonzero__',
'__package__',
'_dh',
'_i',
'_i1',
'_i2',
'_i3',
'_i4',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'cap_ostrs',
'elem',
'exit',
'gen_vals',
'get_ipython',
'get_series',
'idx',
'ind_ostrs',
'quit',
'res_ostrs',
'sys',
'zen_ostrs']
我偏好的“运行”文件的方式是从“Python Shell”(IPython或其他)中导入它,并手动运行需要运行的任何初始化代码。这样做的优点是不会过度污染名称空间,并呈现一个更接近于使用脚本作为模块时所期望的环境(这里是PyCharm和IPython以及自动补全真正开始发挥作用的地方)。在两种方法中,您都可以选择使用“附加调试器”图标将调试器连接到“Python Console”的解释器上(绿色bug旁边)。
以下是一个简短的示例(在“Python Console”选项卡中):
In[2]: dir()
Out[2]:
['In',
'Out',
'_',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__name__',
'__package__',
'_dh',
'_i',
'_i1',
'_i2',
'_ih',
'_ii',
'_iii',
'_oh',
'_sh',
'exit',
'get_ipython',
'quit',
'sys']
In[3]: import conventions.iec60063
In[4]: dir()
Out[4]:
['In',
'Out',
... (all the same ones as before)
'conventions',
... (all the same ones as before)
]
实际上,您并不会直接运行文件,因此应该了解您正在做什么。
当您执行Python文件时,模块认为它的
__name__
是
"__main__"
,这就是
if __name__ == "__main__"
技巧的起源(这是您在Python学习过程中应该早期了解的内容)。如果您尝试跟踪代码的执行,解释器会执行模块中不是类或函数的所有内容。这包括您将在许多Python脚本中看到的
if __name__ == "__main__"
条件。
if
块的内容只有在脚本独立运行(或使用run -m module在IPython中运行)时才会被执行。
另一方面,当您导入一个模块时,相同的执行顺序发生了变化,除了
if __name__ == "__main__"
将计算为False,任何位于该块中的代码都不会被调用。因此,如果需要,则应手动执行
if __name__ == "__main__"
块中的任何内容。简化该任务的一种常见模式是只在if块内具有最小的函数调用(或者,如果您关心命令行参数,请在那里处理这些参数),然后将大部分执行转交给易于调用的函数。
def main():
pass
if __name__ == "__main__":
main()
如果您导入模块后需要执行其中的代码,则只需调用 main() 函数即可。在上面的示例中,如果我必须在模块“运行”时执行一些代码,我会这样做:
In[2]: import conventions.iec60063
In[3]: conventions.iec60063.main()
Pycharm有一些更加高级的执行代码的方式(例如仅执行文件的一小部分等),但我并没有真正需要它们,所以不太清楚它们的工作原理。
run -m student
,结果显示u'student' 不是 sys.path 上的有效模块名称。
- Jason