5

I have a question. Lets assume that we have function hello(). What is the difference between calling it with parentheses and without? When I call hello() it is referring to an object with value equals this function. Or maybe am I wrong? What happens when I call it without parentheses?

I wonder why

def hello():
    pass

print(id(hello))
print(id(hello()))

returns different results

4400606744
4398942536
  • 2
    you can't "call" a function without parenthesis. `hello()` is a function call, `hello` is not. `hello` is just the function, not a call to it. – Zinki Sep 01 '17 at 13:28
  • @ASMackay I have updated my question. It doesn't look like a duplicated question now, isn't it? –  Sep 01 '17 at 13:38
  • 4
    It's different because in the first case you're getting the `id` of the function object itself, and in the second you get the `id` of whatever the function returns (here: `None`). – deceze Sep 01 '17 at 13:39
  • @deceze, you are right. When I write `print(id(None))` I get the same number as `print(id(hello()))`. – Hrvoje T May 30 '18 at 05:15

5 Answers5

4

Short answer: see https://nedbatchelder.com/text/names.html to get a better understanding of the difference between objects and the names used to refer to objects.


A function is called if and only if you use parentheses. hello() calls the function; hello is simply a name bound to the function, and can be used, for example, to pass the function object as an argument to another function.

def caller(f):
    f()

def hello():
    print("hi")

def goodbye():
    print("bye")

caller(hello)  # Prints "hi"
caller(goodbye)  # Prints "bye"

Regarding your update, id returns different values because each call to id receives a completely separate object as its argument. With id(hello), id gets the function object itself. With id(hello()), id is getting the object returned by the call to hello; it's the same as

x = hello()
print(id(x))
chepner
  • 497,756
  • 71
  • 530
  • 681
  • I assume that hello() is a variable referring to an object with value equals this function? –  Sep 01 '17 at 13:29
  • @Wahtdbogh Everything in python is an object and so is the function you mentioned. – 0decimal0 Sep 01 '17 at 13:30
  • Okey, but hello is also a variable referring to the object with value equals this function? –  Sep 01 '17 at 13:31
  • @Wahtdbogh the parentheses in this case are an operator, in the same way that unary negation is an operator: `hello` is to `hello()` as `x` is to `-x`. Hello is the variable which stores the function, the parenthesis mean that you want to attempt to call the object stored in that variable as a function. – zstewart Sep 01 '17 at 13:31
  • @Wahtdbogh If at all that's a very backwards way of putting it. `hello` is a variable referring to the function. `hello()` calls it and returns whatever the function returns. – deceze Sep 01 '17 at 13:32
  • but if hello() calls it we can name it a variable, isn't it? –  Sep 01 '17 at 13:33
  • @Wahtdbogh Be more precise about what you're referring to with "it". – deceze Sep 01 '17 at 13:33
  • 1
    Yes, `hello` is a name for the anonymous `function` object defined by the `def` statement. If you were to write `foo = hello`, then both `foo()` and `hello()` would call the same underlying function. Similary, if you wrote `hello = 3`, you would lose that reference to the function; `hello` now refers to the integer `3` and `hello()` would produce a type error, since `int` objects are not callable. See https://nedbatchelder.com/text/names.html for a better understanding of the relationship between names and objects. – chepner Sep 01 '17 at 13:35
  • ***No***. `hello` refers to a function object; `hello()` is an expression that is evaluated by *calling* the function; the value of the expression is the return value of the function call. – chepner Sep 01 '17 at 13:43
  • So hello() is neither object, nor a variable, nor a value? –  Sep 01 '17 at 13:45
  • No, but it is an expression that, like any other expression, *has* a value. Just like `3 + 5` is not an object, variable, or value, but has as its value the integer `8`. – chepner Sep 01 '17 at 13:45
  • So hello() should be called `expression` or does it have a name? –  Sep 01 '17 at 13:50
  • It is a function call expression. – chepner Sep 01 '17 at 14:08
  • So `hello` is neither object, nor a variable, nor a value? –  Sep 02 '17 at 07:48
  • Read the link I posted at the top of the answer. I'm not answering any more questions in the comments. – chepner Sep 02 '17 at 12:55
4

TL;DR: the parentheses execute the function itself; without them you treat the function as it were a variable

In python you append the parentheses (with optional variables inside) to the function name only when you want to invoke it.

But there is also another way to use function names. In fact, in python functions are first class objects, that means that the function can be passed around as if it where a variable name. To do you must not append the parentheses () at the end of the function name.

Check the following:

def f():
    return 'f'

print( type(f) ) # result: <class 'function'>
print( type(f()) ) # result: <class 'str'>

As you can see, in the first instance we print the type of f (without parentheses), which is a function

In the second instance we print the type of f() (with the parentheses), which is a string, that is the type returned by f when it is invoked.

This behavior is useful to pass functions as parameters of other functions, etc, etc.

The fact that id() and id(function-invoked>) returns different ids:

print(id(hello))   # here it returns the id of the function name

print(id(hello())) # here it returns the id 
                   # of the object returned by the function itself
Davide Del Papa
  • 378
  • 2
  • 9
2

In short, function with parenthesis () is actually calling (invoke) that function whereas function without parenthesis () is an object of that function which can be passed as an argument and later be called by appending () to it.

def hello():
    return 1

i.e.
hello >> returns object
hello() >> outputs 1

xanjay
  • 561
  • 6
  • 20
1

hello refers to the function object, hello() calls the function itself.

For example:

>>> def hello():
...     print "hello"
... 
>>> hello
<function hello at 0x106c91398>
>>> hello()
hello
  • I assume that hello() is a variable referring to an object with value equals this function? –  Sep 01 '17 at 13:29
  • When you issue hello, Python is showing you the representation of the function. hello() invokes the function. The parentheses contain the arguments supplied to the function when you invoke it. In this example, hello() takes no arguments. EDIT: Removed weasel word "usually". The parentheses always contain the arguments supplied :) – The Stupid Engineer Sep 01 '17 at 13:35
  • Okay, but when I have for instance variable `a=2` then variable `a` is referring to object with value equals `2`. When I print `a` it returns `2` Accordingly in this case `hello` is a variable referring to object with value equals function. So when I print `hello` it should returns string "hello", not address of this function. –  Sep 01 '17 at 13:58
  • When you print hello, you see the address in memory the expression is held in. When you **invoke** hello(), you see the output of calling the function. When you print hello, you are not **invoking** the function. – The Stupid Engineer Sep 01 '17 at 19:11
1

A function is an object just like any other object in Python. If you define a new function, a new function object is created and is assigned to the name of the function.

def spam():
    print('The knights who say Ni!')

print(spam) # => <function spam at 0x7fc64efc6f28>

spam() # => output: 'The knights who say Ni!

As you can see after the function was defined it got assigned to the name of spam. It is essentially similar to an assignment statement being run. Now that name is going to give you access to the function but in order to actually use it you have to call it using the parentheses like spam(). If you don't call it using the parentheses, it will just return the function object that has been assigned to the name spam.

Asad Moosvi
  • 487
  • 5
  • 18