如何从装饰器中的函数访问属性?

How to access Attribute from a function within a decorator?

如标题所述,我想访问装饰器中的属性。请参阅以下示例代码:

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

如您所见,我有装饰器函数 def my_timer()。在其中我有另一个装饰器 def wrapper()。 我这样称呼这个装饰器:

@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

现在我需要从第二个装饰器函数 def wrapper() 中的 @my_time 装饰器调用属性 t2。

此外,我在此步骤中调用了 fit 函数:

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()

显示结果为:

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

Train Accuracy :  89.70149253731343 

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

我需要这个打印的时间:“ 运行 in: 0.024797439575195312 sec”但我不知道如何获取它。

我想你可以稍微改变你的包装器来增加时间到 运行 你的函数这样:

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

并像这样使用它

@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)

这样,您可以使用装饰器将 t2 添加到函数的输出中。请注意,我删除了

runningtime = my_timer(fit)

因为它只会创建一个永远不会被调用的函数(感谢 juanpa.arrivillaga