1

I have a class Titles that contains the code necessary to generate many different titles. Each title method takes in the variable rules in order to flexibly generate the correct title. There are certain formatting steps that I would like to apply regardless of which method I call. For example, rounding all floats to a single decimal place. I was trying to do this via __getattribute__, but do not know how to feed the function variables to it (i.e. rules) . Is this possible? Does __getattribute__ have access to the input variables?

Here is a quick example:

import re
class Titles:
    def __init__(self, name):
        self.name = name
    def __getattribute__(self,attr):
        res = object.__getattribute__(self, attr)() #I need to insert rules here
                                                    #somewhere into the function call
        if isinstance(res, str):
            return re.sub(
                    r'\d+\.\d{1,}', lambda m: format(float(m.group(0)), '.1f')
        return res
    def title(self, rules):
        return '{} has spent {} hours on this project'.format(self.name, rules)    

Otherwise, I guess I could have some sort of 'caller' method that would call the various methods and then format their output before returning it...

1 Answer 1

1

This sound like a decorator solution :

import re
class Titles:
    def __init__(self, name):
        self.name = name
    @title_decorator
    def title(self, rules):
        return '{} has spent {} hours on this project'.format(self.name, rules)

    @staticmethod
    @title_decorator
    def title2(rules):
        'Also works for {} staticmethods!'.format(rules)

def title_decorator(func):
    def new_function(*args):
        # do something on rules
        func_result = func(*args)
        # do something on func result
        return func_result
    return new_function

I wasn't sure if you wanted to format the output or input, but you could do both.

Sign up to request clarification or add additional context in comments.

5 Comments

This does sound like a better way of dealing with my issue, thanks. The question is further complicated by the fact that some of my headings are staticmethods (i.e. don't use self) and others are instancemethods. This means that calling the function will sometimes be func(self, rules) and sometimes just func(rules). Could you provide an edit showing how to deal with this please?
@Ludo Hey, there are 2 way I think you can solve this with : 1) Create different decorators for different occasions (One for static and one for instance), I think this is the simplest way. 2) You could use *args, and then analyze the inputs ָ(Lets say by amount of arguments for example).
it seems there's actually no need to analyze anything for 2). Just pass *args to new_function and func. See edit - worked for me
@Ludo That is a better implementation!
@Ludo Do notice, that in order to do something on rules you would still have to anaylze at which location 'rules' is (0 or 1 - static / instance).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.