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.