可以在sys.exit(1)之后使用import吗?

时间:2012-06-01 12:19:50

标签: python exception exit

我有一个GetVars()函数(不应该更改),在某些情况下抛出sys.exit(1)。 我想为这种情况做一些清理工作:

try:
  common_func.GetVars()
except SystemExit:
  cmdline = "-user user1"
  sys.argv = ['config.py', cmdline]
  import config

config.py应该使用一些args,但它现在包含唯一的print语句。但它没有被执行 - 有什么办法吗?只是想了解发生了什么,我知道代码看起来很奇怪:)

UPD: 现在我正在尝试运行

cur_dir = os.path.dirname(os.path.realpath(__file__))
gcti_cfgDir = os.path.join(cur_dir, "..", "cfg-scripts")
 sys.path.append(gcti_cfgDir)
import config
try:
  sys.exit(1)
except SystemExit:
  try:
    import config
  except:
    print "errr"

2 个答案:

答案 0 :(得分:4)

我用这个mymodule.py文件尝试了它:

$ cat mymodule.py 
import sys

try:
  sys.exit(1)
except SystemExit:
  cmdline = "-user user1"
  sys.argv = ['config.py', cmdline]
  import config

并使用此config.py文件:

$ cat config.py 
print "Everything is ok for now"

结果是预期的结果:

$ python mymodule.py 
Everything is ok for now

我很清楚问题不在导入本身,也不在SystemExit捕获......可能你的config.py文件已损坏。

更新:啊,我相信我明白了!

根据您的新代码,您要在config之前导入sys.exit(1)模块,并将其导入except块:

import config # <-- here...
try:
  sys.exit(1)
except SystemExit:
  try:    
    import config # <-- and here
  except:
    print "errr"

但是,模块的代码仅在第一次导入时执行。以下是将模块放在命名空间中,如果它已经在命名空间中,则不执行任何操作。

我认为最好的解决方案是在模块中定义一个函数。如果这是您模块的内容:

print "Everything is ok for now"

只需用

替换它
def run():
    print "Everything is ok for now"

而不是导入要执行的模块,只导入一次并调用函数:

import config # This line just imports, does not print nothing
config.run()  # OTOH, this one prints the line...
try:
  sys.exit(1)
except SystemExit:
  try:    
    config.run() # This one prints the line too
  except:
    print "errr"

实际上,这肯定是处理Python代码的最佳方式:将代码放入函数中,将函数放入模块中,调用函数。将可执行代码直接放在模块中通常不是一种好的做法,正如您尝试的那样。

第二次更新:如果您无法更改config.py模块的代码,您仍然可以使用subprocess.call调用它来调用Python解释器。您甚至可以将您尝试添加的参数传递给sys.argv

import subprocess
# ...
subprocess.call(['python', 'config.py'])
try:
  sys.exit(1)
except SystemExit:
  try:
    subprocess.call(['python', 'config.py',  "-user", "user1"])  # Extra args
  except:    
    print "errr"

答案 1 :(得分:2)

使用atexit模块注册清理处理程序,或者如果您确定GetVars正在调用sys.exit,则修补后者以抛出自定义异常而不是真正运行,以便你可以抓住它并手动处理它。