Python';在全局变量赋值后出现异常时的行为

Python';在全局变量赋值后出现异常时的行为,python,exception,global-variables,Python,Exception,Global Variables,我正在编写一个python函数,它运行一个长时间运行的计算。计算需要仔细调试,所以我的想法是保持状态全局,以便能够在IPython中查看它。如果它很重要,状态是一个张量流模型,计算是它的训练。(更正1:实际上并不重要) 当然,如果我看到培训不顺利,我不想等到培训完成后,在IPython中按Ctrl+C,希望查看M.model,进行一些修复等等 不幸的是,如果我要求IPython在KeyboardInterrupt异常之后打印M的值,我将看不到任何值!但这怎么可能呢?我很确定培训已经开始了,所以应

我正在编写一个python函数,它运行一个长时间运行的计算。计算需要仔细调试,所以我的想法是保持状态全局,以便能够在IPython中查看它。如果它很重要,状态是一个张量流模型,计算是它的训练。(更正1:实际上并不重要) 当然,如果我看到培训不顺利,我不想等到培训完成后,在IPython中按Ctrl+C,希望查看
M.model
,进行一些修复等等

不幸的是,如果我要求IPython
KeyboardInterrupt
异常之后打印
M
的值,我将看不到任何值!但这怎么可能呢?我很确定培训已经开始了,所以应该已经执行了
m=Model()

更正2:事实证明,使用test import*
语法在IPython中加载文件非常重要


MCVE:


train
是在
M
上运行还是变异,还是只使用
M
值?它通过添加新字段来变异
M
。下面是它的样子:注意,这个脚本包含一个我设法找到的解决方法。这个问题仍然有效。我需要更清楚地说,虽然
train
确实发生了变异
M
,但它从未删除任何东西。
train(m)
中的一个常见模式是
m.model.something=value
。我用一个简单的例子再现了这个问题。TensorFlow的细节并不重要。无法复制:将mcve代码放入模块(tmp.py)中;将tmp.py导入iPython控制台;调用
tmp.run
;几秒钟后,键入
ctrl-c
;已验证
tmp.M.state
的值等于经过的秒数。
# Instructions
# 0. Save this program to test.py file.
# 1. Load the file in IPython with `from test import *` syntax
# 2. call `run()`, wait for some short time.
# 3. Interrupt it with Ctrl+C
# 4. See no global state changed

from typing import Any,Optional
from time import sleep

class Model:
  state:Any

def train(m:Model)->None:
  m.state = 0
  print('Hit Ctrl+C to interrupt "training". Check out (the absence of) M.state')
  while True:
    m.state = m.state + 1
    print('.', end='', flush=True)
    sleep(1)

M:Optional[Model]=None

def run():
  global M
  M=Model()
  train(M)