0

Say I have a function:

def omni(self, func, *args, **kwargs):

that always calls func.

However, func's parameters can be any combination of things. For example

def func(self):
    # omni should only pass in self

def func():
    # omni should pass in nothing

def func(foo, key='foo'):
    # omni should pass in a foo param and a key if supplied one

def func(*args, **kwargs):
    # omni should pass in everything

Is there any way to pass into func from omni only the necessary parameters? i.e. is the above possible?

ex.

def foo(m):
    pass

obj.omni(foo, m, a=1)
# this should call
foo(m)

def foo(self, **kwargs):
    pass

obj.omni(foo, m, 1, b=2)
# this should call
foo(self, b=2)
Derek
  • 11,980
  • 26
  • 103
  • 162
  • Why is the first parameter to omni `self`? Is it a part of a class? Will the `func` param also be a member function of that class? – itsadok Nov 25 '13 at 08:36

2 Answers2

0
def omni(self=None, func=None, *args=None, **kwargs=None)

You should use optional arguments as above. Please look here http://www.diveintopython.net/power_of_introspection/optional_arguments.html.

Christos
  • 53,228
  • 8
  • 76
  • 108
  • What does `*args=None, **kwargs=None` mean and how does it work? – glglgl Nov 25 '13 at 08:48
  • 1
    `*args=None` and `**kwargs=None` is nonsense, and it raises a SyntaxError. If no other arguments are given, `args` is `()`. If no other keyword arguments are given, `kwargs` is `{}`. – Vincent Nov 25 '13 at 08:49
  • @glglgl *args=None means that the argument *args has no value, if the caller of the function will not provide one. – Christos Nov 25 '13 at 09:32
  • @Vincent, sorry but I don't get you. Please look here http://docs.python.org/dev/library/constants.html and let me know where I am wrong. Thanks in advance. – Christos Nov 25 '13 at 09:32
  • @ChristosPaisios I don't think that will work in conjunction with `*` resp. `**`. Did you try it? – glglgl Nov 25 '13 at 09:40
  • @ChristosPaisios You point to the wrong docs. Look here: http://docs.python.org/dev/reference/compound_stmts.html#function-definitions `parameter_list ::= (defparameter ",")* ( "*" [parameter] ("," defparameter)* ["," "**" parameter] | "**" parameter | defparameter [","] )` There is no `defparameter` after `*` and `**`, only a `parameter`. And it wouldn't make sense at all. – glglgl Nov 25 '13 at 09:43
  • @glglgl I didn't test it, because I thought that the answer to a question like this is straightforward. As far as the doc you point, I see there the use of None for the same reason. – Christos Nov 25 '13 at 09:47
  • @ChristosPaisios But not in conjunction with `*(args)` and `**(kwargs)`. You can write `def foo(a=None)`, but not `def foo(*a=None)`. – glglgl Nov 25 '13 at 09:49
  • @ChristosPaisios If you don't get how formal arguments work, you should play with `def f(*args, **kwargs): print(args, kwargs)`. – Vincent Nov 25 '13 at 10:51
0

This sounds complicated.

You'd have to examine func and, for the case that func is an object, func.__call__ as well.

A real function has a func_defaults and a func_code, the latter in turn having a co_argcount and a co_flags.

With their help you can examine

  • how many parameters the functions has
  • how many of them have default values and
  • if *args / **kwargs is permitted.
glglgl
  • 89,107
  • 13
  • 149
  • 217