Is it possible to declare a function without arguments but then pass some arguments to that function without raising exception?

Question:

In python is it possible to have the above code without raising an exception ?

def myfunc():
    pass

# TypeError myfunc() takes no arguments (1 given)
myfunc('param')

Usually in php in some circumstances I launch a function without parameters and then retrieve the parameters inside the function.

In practice I don’t want to declare arguments in myfunc and then passing some arguments to it. The only one solution I found is myfunc(*arg). Are there any other methods ?

Asked By: yuri

||

Answers:

Sure can!

You can define variable length parameter lists like so:

def foo(*args):
    print len(args)

args is a tuple of your parameters so calling:

foo(1,2)

gives you the tuple (1, 2) inside your function.

Answered By: Dana

There are two ways to pass args in

By Position

>>> def myfunc(*args):
...  print "args", args
...
>>> myfunc("param")
args ('param',)

By Keyword

>>> def myfunc(**kw):
...  print "kw", kw
... 
>>> myfunc(param="param")
kw {'param': 'param'}

And you can use a combination of both

>>> def myfunc(*args, **kw):
...  print "args", args
...  print "kw", kw
... 
>>> myfunc("param")
args ('param',)
kw {}
>>>
>>> myfunc(param="param")
args ()
kw {'param': 'param'}
>>>
>>> myfunc("param", anotherparam="anotherparam")
args ('param',)
kw {'anotherparam': 'anotherparam'}
Answered By: John La Rooy
>>> def myFunc(*args, **kwargs):
...   # This function accepts arbitary arguments:
...   # Keywords arguments are available in the kwargs dict;
...   # Regular arguments are in the args tuple.
...   # (This behaviour is dictated by the stars, not by
...   #  the name of the formal parameters.)
...   print args, kwargs
...
>>> myFunc()
() {}
>>> myFunc(2)
(2,) {}
>>> myFunc(2,5)
(2, 5) {}
>>> myFunc(b = 3)
() {'b': 3}
>>> import dis
>>> dis.dis(myFunc)
  1           0 LOAD_FAST                0 (args)
              3 PRINT_ITEM
              4 LOAD_FAST                1 (kwargs)
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

And to actually answer the question: no, I do not believe there are other ways.

The main reason is pretty simple: C python is stack based. A function that doesn’t require parameters will not have space allocated for it on the stack (myFunc, instead, has them in position 0 and 1). (see comments)

An additional point is, how would you access the parameters otherwise?

Answered By: badp

Here is a function decorator I wrote to do just that, along with an example of usage:

def IgnoreExtraArguments(f):
    import types
    c = f.func_code
    if c.co_flags & 0x04 or c.co_flags&0x08:
        raise ValueError('function already accepts optional arguments')
    newc = types.CodeType(c.co_argcount,
                   c.co_nlocals,
                   c.co_stacksize,
                   c.co_flags | 0x04 | 0x08,
                   c.co_code,
                   c.co_consts,
                   c.co_names,
                   c.co_varnames+('_ignore_args','_ignore_kwargs'),
                   c.co_filename,
                   c.co_name,
                   c.co_firstlineno,
                   c.co_lnotab,
                   c.co_freevars,
                   c.co_cellvars)
    f.func_code = newc
    return f

if __name__ == "__main__":
    def f(x,y):
        print x+y

    g = IgnoreExtraArguments(f)
    g(2,4)
    g(2,5,'banana')

    class C(object):
        @IgnoreExtraArguments
        def m(self,x,y):
            print x-y

    a=C()
    a.m(3,5)
    a.m(3,6,'apple')
Answered By: iliar
> def vf(a=0):
>     aw = a + 5
>     print(aw)
> 
> vf() result: 5
> vf(5) result: 10
Answered By: Mido H
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.