Home > Mobile >  Is there a way to add extra attributes to a built-in function in python?
Is there a way to add extra attributes to a built-in function in python?

Time:05-28

Suppose I have a function and want to add extra attributes to it e.g. a 'last inputted' attribute to a print statement. This function would be able to take over all existing functionality & some extra functionality.

My idea was to make a function that would have the exact same functionality as a print statement but also be able to remember the last thing outputted.

I made this..

last_mes = ""
def pprint(message, **kwargs):
    global last_mes
    print(message, **kwargs)
    last_mes = message

I don't think this is the best way of doing it though. Is there an optimum way of doing it?

CodePudding user response:

There's no perfect way, but you could at least avoid polluting the global namespace by attaching the extra data to the function itself:

def pprint(message, **kwargs):
    print(message, **kwargs)
    pprint.last_mes = message
pprint.last_mes = ""

Other solutions include a singleton callable class instance:

class _StatefulPprint:
    def __init__(self):
        self.last_mes = ""
    def __call__(self, message, **kwargs):
        print(message, **kwargs)
        self.last_mes = message
pprint = _StatefulPprint()
# Optionally remove class to remove definition from view:
del _StatefulPprint

or use a closure maker:

def make_pprint():
    last_mes = ""
    def pprint(message, **kwargs):
        nonlocal last_mes
        print(message, **kwargs)
        last_mes = message
    return pprint
pprint = make_pprint()
del make_pprint  # Optional

The closure makes it impractical for you to access last_mes outside pprint though, so for this specific case (where doing so is almost certainly a design goal) it won't work.

Last option I'll give is the hackiest one (which shares the weakness of the closure, and adds one more, but is the simple to write); hide it in a mutable default parameter:

def pprint(message, *, _last_mes_store=[""], **kwargs):
    print(message, **kwargs)
    _last_mes_store[0] = message

The extra problem that adds is that if the caller actually passes _last_mes_store by keyword, you don't update the "function static" default parameter you intended to.

CodePudding user response:

If you mean you'd like to overload the built-in print function so that it has extra parameters, have a look at this.

  • Related