Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to access Attribute from a function within a decorator?

As in the title described, I want to access a attribute within a decorator. See the following example code:

def my_timer(orig_func):
    import time

    @wraps(orig_func)
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = orig_func(*args, **kwargs)
        t2 = time.time() - t1
        print('{} ran in: {} sec'.format(orig_func, t2))
        return result

    return wrapper

As you can see I have the decorator function def my_timer(). And within it I have another decorator named def wrapper().
Im calling this decorator like this:

@my_logger
@my_timer
def fit(X_train, y_train):
    fitted = logmodel.fit(X_train, y_train)
    fitted.train_y_predicted = fitted.predict(X_train)
    fitted.train_accuracy = np.mean(fitted.train_y_predicted.ravel() == y_train.ravel()) * 100
    fitted.train_confusion_matrix = confusion_matrix(y_train, fitted.train_y_predicted)
    
    return fitted

Now I need to call the attribute t2 from the @my_time decortator which is within the second decorator function def wrapper().

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Furthemore Im calling the fit function in this step:

fitted = fit(X_train, y_train)
print()
print('Train Accuracy : ', fitted.train_accuracy,'\n')
print('Train Confusion Matrix :\n %s\n' % (fitted.train_confusion_matrix))
print()

and the displayed result is:

<function fit at 0x000001D3BCEB3F70> ran in: 0.024797439575195312 sec

Train Accuracy :  89.70149253731343 

Train Confusion Matrix :
 [[312  26]
 [ 43 289]]

And I need that time from this print: "<function fit at 0x000001D3BCEB3F70> ran in: 0.024797439575195312 sec" But I dont know how to get it.

>Solution :

I think you can change a little bit your wrapper to add the time to run your function such that :

def my_timer(orig_func):
    import time

    @wraps(orig_func)
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = orig_func(*args, **kwargs)
        t2 = time.time() - t1
        print('{} ran in: {} sec'.format(orig_func, t2))
        return result, t2

    return wrapper

and use it like so

@my_logger
@my_timer
def fit(X_train, y_train):
    fitted = logmodel.fit(X_train, y_train)
    fitted.train_y_predicted = fitted.predict(X_train)
    fitted.train_accuracy = np.mean(fitted.train_y_predicted.ravel() == y_train.ravel()) * 100
    fitted.train_confusion_matrix = confusion_matrix(y_train, fitted.train_y_predicted)
    
    return fitted

fitted, t = fit(X_train, Y_train)

This way, you add t2 to the output of your function by using the decorator. Note that I removed

runningtime = my_timer(fit)

as it will just create a function that never gets called (thanks juanpa.arrivillaga )

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading