1

I'm testing a skeleton for a program in python that evaluates times given in the form (hh, mm, ss, zz) where hh is hours, mm is minutes, ss is seconds, and zz is the difference from UTC. Basically, for the init function, I would like to be able to evaluate inputs in the console and pass them regardless of whether or not they have the correct amount of positional arguments. Here is my code:

class Time(object):
    def __init__(self, hh, mm, ss, zz):
    '''takes initial time values'''
    pass

Currently, the program will take variables typed into the console with the appropriate amount of variables like so:

A = times.Time(1, 2, 3, 4)

But will give a TypeError with init() missing required positional arguments with these:

B = times.Time(1,2,3)
C = times.Time(1,2)

Is there a way to allow these to pass?

orllais
  • 17
  • 4

2 Answers2

3

You can change the signature of the function to use "default arguments" (frequently also called "keyword arguments")...

def __init__(self, hh=None, mm=None, ss=None, zz=None):

This will substitute a value of None for the values not specified.


If you can't modify the signature, you can use inspect:

import inspect
def pad_args(func, *my_args):
    spec = inspect.getargspec(func)
    missing_count = len(spec.args) - len(my_args)
    args = my_args + (None,)*missing_count
    return func(*args)

You'd use it like this:

C = pad_args(times.Time, 1, 2)

Of course, your mileage here probably won't get you very far -- Most functions with positional arguments aren't able to accept a value of None arbitrarily. Usually the author of the library made those arguments positional because they're required for the function/object to work as intended.

mgilson
  • 300,191
  • 65
  • 633
  • 696
0

If you must use positional rather than keyword arguments, the easy solution is just to unpack them using *args tuple unpacking --- this is a good explanation, but the short version is that it makes whatever you pass into the function into a list (I think... might be a tuple? Pretty sure it's a list) that you can access with args

Then you could just set a default value for everything in the `init and override that default with things plucked from the args list.

-- you might also think about letting it throw the error anyway and then handling it.

Community
  • 1
  • 1
Paul Gowder
  • 2,409
  • 1
  • 21
  • 36