简体   繁体   中英

Decorator with argument as class method inside another Python class

I have a python class that implements a decorator (as classmethod , thank to this post decorator-inside-python-class as following:

import os
from functools import wraps
import pandas as pd

class global_tracking():

    def __init__(self, globals=None):
        self.globals = globals

    def save_current_data_frame_to_track(self,current_data_frame,path_to,filename,logger=None):
        current_data_frame.to_parquet(filename+'.parquet.gzip', compression='gzip')
        os.system('gsutil cp '+filename+'.parquet.gzip'+' gs://'+path_to+filename+'.parquet.gzip')
        return True

    @classmethod
    def save_input_to_track_from_globals(cls,globals):
        def save_input_to_track(func):
            @wraps(func)
            def func_wrapper(*args, **kwargs):
                for key, kwarg in kwargs.items():
                    if isinstance(kwarg, pd.core.frame.DataFrame):
                        self.save_current_data_frame_to_track(kwarg,globals['file_system_path'])
                return func(*args, **kwargs)
            return func_wrapper
        return save_input_to_track

I would like to use this decorator, in another class as following: Python wont let me use the decorator:

globals={'file_system_path':''}

class global_data_getter():

    def __init__(self,globals):
        self.globals=globals

    @global_tracking(globals).save_input_to_track_from_globals(globals) #Python wont recognise this!
    def get_train_data(self,file_name):
        data_to_train = pd.read_csv(file_name)
        return data_to_train

Quick clarification, I want that when ever get_train_data is bing used the function will both read and return the data frame and also save it in google storage, that is why i'm using the decorator.

I would prefer if the decorator would be a member of a class (global tracking) where i save other decorators, that are all intended to keep track of methods.

globals (bad name i know :( ) is just a dict with information on where to store the csv

Why cant i use this decorator ?

Thanks in advance!

Your code mixes-up class objects, instance objects and function objects. You make that error in the definition of the global_tracking function (see my first comment), and when trying to call its return value. The call to global_tracking(globals) returns a function object, not an instance object. The function object returned by the call does not have a member save_input_to_track_from_globals , so you can not call it.

I tried to improve your code, but it is far too contrived and unnecessarily complex. Just stick with a simple decorator function. The link you provide was showing some theoretical possibilities with the Python syntax, not something you would actually use in real life.

The decorator syntax has been deliberately kept restrictive to save you from having to maintain problematic code such as this. If you insist on this level of complexity you could assign the appropriate decorator in the class namespace so you can use a simple name, which would give you acceptable syntax.

I would be interested in the justification for using a classmethod in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM