4

I need to store both args & kwargs in a tuple for calling later, so in that case would the appropriate value in the tuple *args or args? In other words, will this work:

def __init__(self, *args, **kwargs):
    self._buildCalls = [
        (self.__init__, args, kwargs)
    ]
    self._building = False

def __getattr__(self, attr):
    if self.building():
        if hasmethod(self, attr):
            return lambda *args, **kwargs: self.argSaver(attr, *args, **kwargs)
    else:
        return super().__getattr__(attr)

def argSaver(self, method, *args, **kwargs):
    self._buildCalls.append((method, args, kwargs))
    return method(*args, **kwargs)
MathCrackExchange
  • 595
  • 1
  • 6
  • 25
  • 1
    Did you try it - did it work? – AChampion Nov 12 '16 at 16:16
  • You may find the examples in the answers [here](http://stackoverflow.com/q/40498298/4014959) helpful. – PM 2Ring Nov 12 '16 at 16:18
  • I’m not sure you actually understand what `*` and `**` are doing. But yes, you would have to store `args` and `kwargs` in the tuple; `*args` and `**kwargs` are not actual things you could store (but rather just the execution of another operator on `args` and `kwargs` respectively). – poke Nov 12 '16 at 16:26

1 Answers1

16

Here's a sample function signature:

def foo(a, b, *args, **kwargs):

Here *args represents the arguments after a and b that aren't required, are passed like 'non-named' arguments (foo(1, 2, 3, 4, 5)) and the function gets them as a tuple called args: args == (3, 4, 5).

**kwargs represents the arguments that aren't required, are passed by name (foo(1, 2, foo=3, bar=4)) and the function gets them as a dictionary called kwargs: kwargs == {'foo': 3, 'bar': 4}.

When you use the star notation outside function definition, it tries to extract data from a tuple or a dictionary, e.g. *(1, 2, 3) gives you three separate values that have been extracted from the tuple, *{'foo': 5} will extract all the keys of the dictionary, but foo(**{'foo': 5, 'bar': 6}) will attempt to pass two arguments called foo and bar with values 5 and 6 respectively to the function foo.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Does anyone know why there is the following difference: `import csv`// `def convert(iter: str, **kwarg):` // `first_attempt_executes = csv.writer( open('file.txt','w'), **kwarg)` << Comple success! // `second_attempt_fails = csv.writer(csvfile= open('file.txt','w'), **kwarg)` << TypeError: expected at least 1 argument, got 0 – dank8 Nov 01 '22 at 17:44