functions without parentheses
onurb at xiludom.gro
Thu Jul 28 18:22:57 CEST 2005
Jerry He wrote:
> Is it possible to create a function that you can use
> without parenthesizing the arguments? for example, for
> def examine(str):
> Is there some way to define it so that I can call it
> examine "string"
> instead of examine("string")?
The reason (well, one of the reasons) is that, given a function my_func
def my_func(*args, **kwargs):
print "in my_func:"
print "+ args : %s" % ", ".join(args)
print "+ kwargs %s" % ", ".join(["%s=%s" % keyval \
for keyval in kwargs.items()])
have very different semantics. (hint: copy/paste this code in your
python interactive interpreter).
The first expression has exactly the same semantic as it would have with
any other object : it returns a reference to the function object
referenced by the name 'my_func' according to namespace rules.
 remember, in Python, functions are objects too.
The second expression has the usual 'function call' semantic.
The first expression allow to write code like:
my_func_alias = my_func
def my_caller_func(any_func, *args, **kwargs):
print "calling %s with *args %s and **kwargs %s" \
", ".join(["%s=%s" % keyval for keyval in kwargs.items()])
result = any_func(*args, **kwargs)
print "result :%s" % result
In fact, '()' is the 'call' operator, that is then applied to the
callable object referenced by 'my_func'. So a function call like
is in fact made in two steps:
- retrieving the object referenced by the name 'my_func'
- trying to apply the '()' call operator on it.
 Functions are just one special case of callable object. Lambda are
another, as any instance of a class defining the __call__ method.
the call operator could be implemented like this:
def __call_op__(func_name, *args, **kwargs):
if hasattr(func_name, __call__):
return func_name.__call__(*args, **kwargs)
raise TypeError("%s object is not callable" % type(func_name))
Ok. Now that you know this, if Python was to support the
result = my_func "arg1", "arg2"
syntax, how should the expression
result = my_func
be interpreted ?-)
(hint: remember that the prototype of my_func allow us to call it with
no args at all)
There are good reasons for trying to have a clear and unambigous syntax.
functions-being-objects (as wall as 'other-objects-being-callable) is
one of the strength of Python, and it's a common idiom in Python to pass
functions (or any other callable) around.
BTW, note that there are few languages that doesn't inforce one (and
only one) unambigous syntax for function calls (even VB has a defined
and mandatory syntax for function calls, which is the same as Python's.
What VB has that Python has not is the semantic difference between
functions and procedures, and different syntaxes for both).
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list