Wrapping aller möglichen Methodenaufrufe einer Klasse in einem try / except-Block

Ich versuche, alle Methoden einer vorhandenen Klasse (nicht meiner Schöpfung) in eine try / except-Suite zu packen. Es könnte jede Klasse sein, aber ich werde das @ verwend pandas.DataFrame Klasse hier als praktisches Beispiel.

Wenn die aufgerufene Methode erfolgreich ist, fahren wir einfach fort. Sollte jedoch eine Ausnahme generiert werden, wird diese zur späteren Überprüfung / Erkennung an eine Liste angehängt (obwohl das folgende Beispiel der Einfachheit halber nur eine Druckanweisung ausgibt).

(Beachten Sie, dass die Arten von datenbezogenen Ausnahmen, die auftreten können, wenn eine Methode für die Instanz aufgerufen wird, noch nicht bekannt sind. Dies ist der Grund für diese Übung: Ermittlung.)

DiesPos war sehr hilfreich (insbesondere @ Martineau Python-3-Antwort), aber ich habe Probleme, es anzupassen. Unten erwartete ich den zweiten Aufruf des (umhüllten)die Info( -Methode zum Ausgeben von Druckausgaben, aber leider nicht.

#!/usr/bin/env python3

import functools, types, pandas

def method_wrapper(method):
    @functools.wraps(method)
    def wrapper(*args, **kwargs): #Note: args[0] points to 'self'.
        try:
            print('Calling: {}.{}()... '.format(args[0].__class__.__name__,
                                      ,          method.__name__))
            return method(*args, **kwargs)
        except Exception:
            print('Exception: %r' % sys.exc_info()) # Something trivial.
            #<Actual code would append that exception info to a list>.
    return wrapper


class MetaClass(type):
    def __new__(mcs, class_name, base_classes, classDict):
        newClassDict = {}
        for attributeName, attribute in classDict.items():
            if type(attribute) == types.FunctionType: # Replace it with a
                attribute = method_wrapper(attribute) # decorated version.
            newClassDict[attributeName] = attribute
        return type.__new__(mcs, class_name, base_classes, newClassDict)

class WrappedDataFrame2(MetaClass('WrappedDataFrame',
                                  (pandas.DataFrame, object,), {}),
                                  metaclass=type):
    pass

print('Unwrapped pandas.DataFrame().info():')
pandas.DataFrame().info()

print('\n\nWrapped pandas.DataFrame().info():')
WrappedDataFrame2().info()
print()

Diese Ausgaben:

Unwrapped pandas.DataFrame().info():
<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Empty DataFrame

Wrapped pandas.DataFrame().info():   <-- Missing print statement after this line.
<class '__main__.WrappedDataFrame2'>
Index: 0 entries
Empty WrappedDataFrame2

In Summe,..

>>> unwrapped_object.someMethod(...)
# Should be mirrored by ...

>>> wrapping_object.someMethod(...)
# Including signature, docstring, etc. (i.e. all attributes); except that it
# executes inside a try/except suite (so I can catch exceptions generically).

Antworten auf die Frage(4)

Ihre Antwort auf die Frage