How to check if certain class methods have been called from within the same class

Question:

I have some code that looks like this:

class Template:
    def insert_text(self, text):
        # code goes here
        return

    def insert_photo(self, path_to_photo):
        # some more code goes here
        return
    
    def compose(self):
        # this composes/generates the text file based on the above methods
        return       

customfile = Template()
text = customfile.insert_text("look at this code work!!!")
photo = customfile.insert_photo("C:/Users/...")
customfile.compose()

What I want to have happen, is that if the user calls the compose method on the customfile instance, that the compose method somehow looks up what other methods were called on the customfile instance, and then includes the results of those calls in the final result.

So basically I want the compose method to know what to include in the generated text file. e.g. The photo that I inserted in the above code, I want the compose method to know about that photo.

Asked By: cyberghost

||

Answers:

Why not include a list as an instance variable? You can append all the results of the other methods to it and then when compose is called, you can process those results how you wish.

Something like:

class Template:

    def __init__(self):
        self.call_stack = []

    def insert_text(self, text):
        # code goes here
        self.call_stack.append(result)
        return

    def insert_photo(self, path_to_photo):
        # some more code goes here
        return
    
    def compose(self):
        # this composes/generates the text file based on the above methods
        for result in self.call_stack:
            # Do something (I assume add the elements to template in order)
        return       

customfile = Template()
text = customfile.insert_text("look at this code work!!!")
photo = customfile.insert_photo("C:/Users/...")
customfile.compose()

You mentioned that you can’t use a list due to Python’s scoping rules. I am not sure what you mean, could you clarify?

Answered By: linguini

We can make a methods_called dictionary where its values represent the results (as a list of all the results) and number of times each method was called:

class Template:

    def __init__(self):
        self.methods_called = {method:{'calls': 0, 'results': []} for method in dir(Template) if not method.startswith('__') and method != 'compose'}

    def insert_text(self):
        # code goes here
        result = 19
        self.methods_called[self.insert_text.__name__]['calls'] += 1
        self.methods_called[self.insert_text.__name__]['results'].append(result)
        return

    def insert_photo(self):
        # some more code goes here
        result = 15
        self.methods_called[self.insert_photo.__name__]['calls'] += 1
        self.methods_called[self.insert_photo.__name__]['results'].append(result)
        return
    
    def compose(self):
        # this composes/generates the text file based on the above methods
        return self.methods_called

m = Template()
m.insert_photo()
m.insert_text()
m.insert_photo()
print(m.compose())

Outputs:

{'insert_photo': {'calls': 2, 'results': [15, 15]}, 'insert_text': {'calls': 1, 'results': [19]}}
Answered By: Ori Yarden
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.