# Using decorated methods in a subclass of deque to dump its state to a JSON file

I am sub-classing an object in python and I need to overload a bunch of the methods with very similar logic, essentially a call to super() and then some additional operations. I want to avoid explicitly writing out each of those overloaded methods in that way, so I implemented a decorator.

Is there anything wrong with doing the following:

def decorator(function):
def wrapper(*args, **kwargs):
# Logic + operations here
function()
# Logic and operations here

return wrapper

class SubClass(SuperClass):
method1 = decorator(SuperClass.method1)
method2 = decorator(SuperClass.method2)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Extra logic here


Here is my actual implementation:

def updates_file(function):
"""
Decorator to call update file method after super call.
"""
def wraper(*args, **kargs):
function(*args, **kargs)
args[0]._update_file()

return wraper

class FileMirroredDeque(deque):

def __init__(self, cache_path, maxlen=None, clean=False, file_indent=None):
super().__init__((), maxlen)  # Initializes the deque as well TODO: Check the implication of this calling __setitem__

self.path = cache_path
self._indent = file_indent
self._bak_file = None

if clean:
self._update_file()  # Overwrite contents of file.
return  # Don't import data from file.

with open(self.path, 'a+') as f:  # Creates file if it doesn't exist
f.seek(0, 0)  # Seek back to beginning of file for json decode.

try:
self.extend(json.loads(contents or "[]"))  # initializes internal list with persistent data or empty list.

except json.decoder.JSONDecodeError:
new_file = os.path.basename(self.path) \
+ datetime.datetime.utcnow().strftime("_%Y_%m_%d_%H_%M_%S") + ".bak"

new_path = os.path.join(os.path.dirname(self.path), new_file)

logger.warning(f"File: {self.path} was not valid JSON. It will be copied to {new_path} and a new "
f"file will be created.")

shutil.copyfile(self.path, new_path)
self._bak_file = new_path

def _update_file(self):
with open(self.path, 'w') as f:
json.dump(list(self), f, indent=self._indent)

• Your decorator is not equivalent to calling super. In your case you always refer to the parent class, which is not the only behaviour of super. – Mathias Ettinger Aug 14 '18 at 13:04
• Perhaps I am missing something about the nature of super(). All I need, however, is to inherit all the functionality of the parent method and perform some extra operations before and after which do not modify the instance of the object at all. – Alex Eshoo Aug 14 '18 at 13:10
• What I mean is: this may work fine in single inheritance schemes, but as soon as you have sibling classes in your inheritance tree, your approach and super() would give different results. – Mathias Ettinger Aug 14 '18 at 13:12
• I have now included my actual listing. – Alex Eshoo Aug 14 '18 at 14:08
• Much better than the original post. I congratulate you on managing to reverse an 'on-hold' question. – FreezePhoenix Aug 14 '18 at 14:46