# Trying to understand Why () in Python

• Python
TL;DR Summary
For things like .upper() or .lower() or def XXXXX(), why are the () there? Can anything go inside the parentheses?
I am still on the basics of python, so the odds are if you use a lot of fancy terms I will not understand the answer yet. It is just really confusing me.

Thank you!

lomidrevo
Functions in python must be always written with parenthesis, even if there are no arguments to pass. Methods are just functions belonging to an object, indicated by "." between the name of the object and the name of the method.

berkeman
Mentor
It's an indicator to the compiler / interpreter that these are methods/functions and not variables. Basically it says to the compiler to treat the identifier as a method or function to be called with zero arguments.

When the parens are missing, it says the to the compiler to treat the identifier as a reference to a method or function.

Here's a deeper discussion on it:

https://softwareengineering.stackex...-use-parentheses-when-no-arguments-are-passed

Functions in python must be always written with parenthesis, even if there are no arguments to pass. Methods are just functions belonging to an object, indicated by "." between the name of the object and the name of the method.
What do you mean by "functions belonging to an object"? I just don't see why the string would not be the argument of the function upper or lower, i.e. the script being upper("i want this in all caps!").

Mentor
functions belonging to an object ie also known as methods

Mentor
Functions in python must be always written with parenthesis, even if there are no arguments to pass.
Same is true in C, C++, C#, if we're talking about calling a function. In C and C++ (but not C#, I believe), the name of a function without parentheses evaluates to the location in memory of the code for the function.

BTW, this is a parenthesis - (
These are parentheses - ( )

lomidrevo
In python an instance of string is an object. When you call its method .upper(), it will be applied to itself. Thus no argument.

lomidrevo
Same is true in C, C++, C#, if we're talking about calling a function. In C and C++ (but not C#, I believe), the name of a function without parentheses evaluates to the location in memory of the code for the function.

BTW, this is a parenthesis - (
These are parentheses - ( )
I am not native speaker, so mistakes happen. But I believe the point was understood anyway.

2022 Award
If you have a string s, then s.upper is the function itself. You can do stuff like dir(s.upper) if you want to see the methods of a function object. You need the brackets to tell python to call the function instead of returning the function object.

In interactive mode, try

"abc".upper

and then

"abc".upper()

to see the difference.

etotheipi and Isaac0427
Mentor
Right. All I was saying that the need for parentheses is not unique to Python.

If you have a string s, then s.upper is the function itself. You can do stuff like dir(s.upper) if you want to see the methods of a function object. You need the brackets to tell python to call the function instead of returning the function object.

In interactive mode, try

"abc".upper

and then

"abc".upper()

to see the difference.
"abc".upper only produces an error message. I still don't understand why the code is not upper("i want this in all caps!"). Is there a good resource where I can learn about methods? I just don't get the concept, and what the difference between acting on an object (or having the object in the argument) and belonging to an object is.

Maybe there is an example of a method that can have an argument, so I can see the difference between what the object that the method belongs to and the argument do.

2022 Award
"abc".upper only produces an error message.
Does it? I get <built-in method upper of str object at 0x7f92a240e7d8>, which is the string representation of the function.
I still don't understand why the code is not upper("i want this in all caps!").
Because upper is a method of the string object. So the "s.upper()" should be read as "call the upper method of the object s". What would the upper method belonging to a string do except return the upper case version of that string?
I just don't get the concept, and what the difference between acting on an object (or having the object in the argument) and belonging to an object is.
Methods belong to a class or an object. When you call it, it usually does something with the object.

This is all code organisation tools, that's all. Imagine you are writing a simulation of a solar system. For each planet you need its x, y and z position, x, y and z velocity, and its mass. You could create arrays called x, y, z, vx, vy, vz and M. But that's a weird thing to do - you are simulating planets, but your data organisation collects the x coordinates into one group, the y coordinates in another, and so on. Creating a "planet" class that stores the coordinates, velocity and mass of a planet in one "box" and then creating an array of planets let's you organise the data in a way that reflects how you think about what you are modelling. OK so far?

Now when you come to write the simulation you're going to need a function that calculates the new position of each planet. It'll need to know the positions of all the planets, and which one it's supposed to be updating. Since the function is always going to manipulate the coordinates and velocities of a planet, why not put the function in the same "box" as the data for that planet? Then you don't need to pass the planet object as an argument. The function will know which planet it's supposed to update - the one it's a member of. And in python (and C++, C#, Java, Javascript, VB, and others) the way you say "I want to call the function f that's inside object o" is o.f().

Hope that makes some sense.

Mentor
I just don't see why the string would not be the argument of the function upper or lower, i.e. the script being upper("i want this in all caps!").

It's a design choice by the people who developed Python. They could have designed Python to have a bunch of built-in functions like upper, lower, etc. that took strings as arguments. Instead they chose to have string objects have a bunch of methods, which are functions that "belong" to the types of the objects, and always take a "self" argument as their first argument, where "self" points to the particular object instance that is being operated on.

So in the following code...

Python:
s = "abc"
u = s.upper()

...the notation s.upper() is really syntactic sugar for type(s).upper(s), where type(s) returns the type of the object s, and the upper function "belongs" to that type, which means the Python interpreter looks it up by name in the type's namespace, instead of the global built-in namespace. So the upper function actually does take a string object as an argument--the string object s. The Python designers just chose to have the language express that as a method call, because that's how most object-oriented languages express such things.

I believe a main reason for not just having a lot of built-in functions for string operations, but making them methods on the string object type instead, was to avoid cluttering up the built-in namespace, i.e., to minimize the number of names that were given to built-in functions--which means to maximize the number of names that could be used freely by Python programs without colliding with the name of a built-in function.

lomidrevo