-3

Can I somehow call a function without the ()? Maybe abusing the magic methods such as __call__() somehow?

I'd like to be able to something similar to

from IPython import embed as qq

but call embed() only via qq rather than qq()

This is more out of curiosity, and as a learning exercise for python, rather than practical purposes.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
confused00
  • 2,556
  • 21
  • 39
  • You can't. `__call__` is used to make something callable, but you still need to actually use the call syntax to actually do so. – Martijn Pieters Dec 19 '14 at 11:25
  • Well, technically you could do it in the repl by abusing `__repr__`, but this would of course not work outside of the interactive interpreter. Or by abusing `__getattr__`, which of course only works for attributes of a class. – l4mpi Dec 19 '14 at 11:28

5 Answers5

4

If you are using the REPL (the Python shell), then you can hack your way around this, because the REPL will call repr() on objects for you (which in turn invokes their __repr__ method):

from IPython import embed

class WrappedFunctionCall(object):
    def __init__(self, fn):
        self.fn = fn
    def __repr__(self):
        self.fn()
        return ""  # `__repr__` must return a string

qq = WrappedFunctionCall(embed)

# Typing "qq" will invoke embed now and load iPython.

But really, you should not be doing this!

And of course, it won't work outside of the REPL, because there won't be anything to call __repr__ in that case. Obviously, passing arguments isn't "supported" either.

Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
1

__call__ will be invoked only if the function is invoked with (). If the function is in a class, then you can use @property decorator, to do something like this

import math

class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    @property
    def area(self):
        return math.pi * (self.radius ** 2)

print(Circle(5).area)
# 78.53981633974483

Read more about getter and setter here

Community
  • 1
  • 1
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
0

If you want to learn, play around with Python.

In [1]: def foo():
   ...:     pass
   ...: 

In [2]: foo
Out[2]: <function __main__.foo>

In [3]: foo()

In [4]: bar = foo

In [5]: bar
Out[5]: <function __main__.foo>

In [6]: bar()

As you see, foo will not call the function, it will return it. And that is a good thing becaus you can pass it as an argument and assign it, for example bar = foo.

0

In pure Python, the only way I can think of is to use an object and a property:

>>> class Wtf(object):
...     @property
...     def yadda(self):
...         print "Yadda"
... 
>>> w = Wtf()
>>> w.yadda
Yadda
>>> 

Else you might want to check IPython's doc on how to define your own custom "magic" commands: http://ipython.org/ipython-doc/dev/config/custommagics.html

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

You can call the function foo without using () (on that function):

def call_function(fun_name,*args):
    return fun_name(*args)

def foo(a,b):
    return a+b

print call_function(foo,1,2)

# Prints 3

Note that this answer isn't entirely serious, but it does contain a snippet of interesting Python code.

Moose
  • 148
  • 1
  • 7