I want to have a class that I can create subclasses of that has a print function that only prints on a particular condition.
Here's basically what I'm trying to do:
class ClassWithPrintFunctionAndReallyBadName:
...
def print(self, *args):
if self.condition:
print(*args)
This works already except for the fact that there are arguments that have to be explicitly stated with the default print function, such as end (example: print('Hello, world!', end='')). How can I make my new class's print function accept arguments such as end='' and pass them to the default print?
The standard way to pass on all arguments is as @JohnColeman suggested in a comment:
class ClassWithPrintFunctionAndReallyBadName:
...
def print(self, *args, **kwargs):
if self.condition:
print(*args, **kwargs)
As parameters, *args receives a tuple of the non-keyword (positional) arguments, and **kwargs is a dictionary of the keyword arguments.
When calling a function with * and **, the former tuple is expanded as if the parameters were passed separately and the latter dictionary is expanded as if they were keyword parameters.
I know it looks a bit ugly but works perfectly, if you are using a lot of keyword arguments and only want to build a facade for another method:
def print(self, print_message, end='\n', sep=' ', flush=False, file=None):
if self.condition:
print(**{key: value for key, value in locals().items() if key not in 'self'})
Although it's a lot of boilerplate, it avoids any duplication of parameter statements.
You might also look into using a decorator to make the conditional part more pythonic. But beware that the decorator checks the condition once prior to the class instantiation.
Just duplicate the named arguments for the method signature.
def print(self, *args, end='\n', sep=' ', flush=False, file=None):
if self.condition:
print(*args, end=end, sep=sep, flush=flush, file=file)