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