2

I want to implicitly close workbook on class instance destruction. xlsxwriter.workbook.py method says to do it explicitly and then it works. But then at the end of each Excel file creation script I have to add extra line for closing Workbook. Is there a way to make it auto-closing?

import pandas as pd
import xlsxwriter

class ExcelFile():

def __init__(self, file_name):
    self.writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
    self.workbook = self.writer.book

def __del__(self):
    self.workbook.close()
    print('del')

script:

e = ExcelFile('test.xlsx')
# e.workbook.close() <--This works but I don't want this line

1 Answers1

1

You have no control over when the __del__ method will be called. There is plenty of information about __del__ on SO already, you can search for it (for example, https://stackoverflow.com/a/1481512/1453822).

Instead, I'd use a context manager:

class ExcelFile():
    def __init__(self, file_name):
       self.writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
       self.workbook = self.writer.book    

    def __enter__(self):
       return self

    def __exit__(self, exc_type, exc_val, exc_tb):
       print('exit')
       self.workbook.close()

with ExcelFile('test.xlsx') as e:
    # do whatever with e
    pass

Output will be:

'exit'

__exit__ is promised to be called whenever you exit the with ExcelFile(..) block, even if an exception was raised:

with ExcelFile('test.xlsx') as e:
    1/0

Outputs

Traceback (most recent call last):
  File "main.py", line 57, in <module>
    1/0
ZeroDivisionError: division by zero

exit
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • 1
    @TomekJankiewicz Exception handling, see https://docs.python.org/3.5/reference/datamodel.html#object.__exit__ – DeepSpace Mar 18 '18 at 14:38