Q:

How to correctly handle SIGINT to close files/connections

I want to implement a proper SIGINT handling in my script, which opens multiple files and a database connection.  These should be closed if the script is CTRL+C'd or somehow else interrupted. 
Previously I've used the KeyboardInterrupt exception to catch CTRL+C, there I checked if files/connections are defined, if so close them, then exit. 
Is this really the pythonic way to do it, or is it better adviced to use signal handlers?  e.g.
import signal, sys, time

def handler(signum, frame):
    print("..kthxbye")
    sys.exit(1)

def main():
    signal.signal(signal. SIGINT, handler)
    i = 0
    while True:
        print(i)
        i += 1
        time.sleep(1)

if __name__ == "__main__":
    main()

This seems cleaner to me, yet don't I know how I would pass filenames or database connections to the handler. 

A:

I would rather catch the KeyboardInterrupt exception on the main thread.  KeyboardInterrupt is the result of the default SIGINT handler of python.  The exception handler of a KeyboardInterrupt exception is a much safer/friendly context than what you are in when catching SIGINT directly. 
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        cleanup()

EDIT: Here is how to share variables (state) between the two methods:
Procedural:
import sys, time

class SharedState:
    def __init__(self):
        self.var0 = 42
        self.var1 = 'string'

# method 1
shared_variable = 'woof woof'

# method 2: avoiding global declarations in functions
shared_state = SharedState()

def main():
    # In order to write a global variable you need a global
    # declaration otherwise the assignment would create a
    # local variable

    global shared_variable
    shared_variable = 5

    shared_state.var0 = 10

    time.sleep(10)

def cleanup():
    print shared_variable
    print shared_state.var0
    sys.exit(1)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        cleanup()

Object oriented (my preference):
import sys, time

# method 3: object oriented programming
class Program:
    def __init__(self):
        self.var0 = 42
        self.var1 = 'string'

    def main(self):
        self.var0 = 5
        self.var1 = 'woof woof'
        time.sleep(10)

    def cleanup(self):
        # both main and cleanup can access the member
        # variables of this class
        print self.var0
        print self.var1
        sys.exit(1)

    def execute(self):
        try:
            self.main()
        except KeyboardInterrupt:
            self.cleanup()

if __name__ == '__main__':
    Program().execute()

