Python2.7 finally claus上的奇怪行为

2024-04-24 11:51:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了一个非常奇怪的问题,这让我怀疑我是否完全理解异常处理。在

我有一个代码(我将在最后发布),大致如下所示:

try:
    doSomething()
finally:
    print 'bye'

当我通过ctrl+c退出程序时,finally子句中的代码没有被执行

更糟糕的是,现在考虑以下几点:

^{2}$

现在except子句中的代码没有执行。。但是finally子句中的代码是!在

我知道这一定是doSomething()执行的代码的错误。但我的问题是,这怎么可能?我想我们可以百分之百地相信最终条款总是得到执行。在

这是真正的代码。它是用树莓皮3运行的。它是对here找到的代码的改编。在

import RPi.GPIO as GPIO, time

GPIO.setmode(GPIO.BCM)

# Define function to measure charge time
def RCtime (PiPin):
    # Discharge capacitor
    GPIO.setup(PiPin, GPIO.OUT)
    GPIO.output(PiPin, GPIO.LOW)
    time.sleep(.1)

    time1 = time.time()
    GPIO.setup(PiPin, GPIO.IN)
    if (GPIO.input(PiPin) == GPIO.LOW):
        GPIO.wait_for_edge(PiPin, GPIO.RISING, timeout=1000)
    time_elap = time.time()-time1

    return time_elap*1e3

# Main program loop
try:
    while True:
        print RCtime(4) # Measure timing using GPIO4
except Exception:
    print '---------got ya-----------------'
finally:
    print '---Finaly---'
    GPIO.cleanup() # this ensures a clean exit  

更具体地说,当程序在GPIO.wait_for_edge(PiPin, GPIO.RISING, timeout=1000)行等待时,就会出现所描述的行为。在


Tags: 代码程序gpiotimesetuplowprinttry
2条回答

{1>表示系统没有处理^代码。相反,如果您有一个异常处理程序,您的代码会接管它,离开循环,然后执行finally块。在

嗯,这似乎是一个与零售物价指数处理信号(如键盘中断)。这个模块调用一些用c编写的函数。这个函数有点像是捕捉键盘中断并抛出异常,但它做得不好。这两个异常不是只得到一个异常,而是“堆叠”起来的。因此,在我的代码中,在异常之后运行的第一件事将被第二个异常终止。如果不包括except块,finally块将在第一个异常之后执行,并由第二个异常终止。如果我包含一个except块,它会尝试在第一个异常之后运行,由于第二个异常而失败,然后转到finally块。 我只找到一个人们处理类似问题的forum。在

After my previous experiment I was curious how this works with input() [https://svn.python.org/projects/python/trunk/Parser/myreadline.c]. I replaced the sem.acquire() with raw_input() and ran the same tests. Now the inner exception is really taken so it works like the OP expected. The exception, however is KeyboardInterrupt, not the special exception from the IPC module. So I looked in the source code how they did it: The code is in Parser/myreadline.c.

This code for input in function calls PyErr_CheckSignals() and PyOS_InterruptOccurred() for a proper handling of the interrupt. So it seems the OP should do something similar. Onl;y to deliver the custom error you will have to do some other stuff. I don't know what but maybe calling PyErr_SetString is sufficient as it might overwrite the KeyboardInterrupt stuff.

相关问题 更多 >