Tutorial :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 ?


Solution:1

>>> 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?


Solution:2

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'}  


Solution:3

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.


Solution:4

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')  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »