Trying to understand Why () in Python

  • Context: Python 
  • Thread starter Thread starter Isaac0427
  • Start date Start date
  • Tags Tags
    Python
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
13 replies · 2K views
Isaac0427
Insights Author
Gold Member
Messages
718
Reaction score
163
TL;DR
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!
 
Physics news on Phys.org
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.
 
  • Informative
Likes   Reactions: berkeman
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
 
lomidrevo said:
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!").
 
lomidrevo said:
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 - ( )
 
In python an instance of string is an object. When you call its method .upper(), it will be applied to itself. Thus no argument.
 
Mark44 said:
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 - ( )
Sure, but OP is asking about python.
I am not native speaker, so mistakes happen. But I believe the point was understood anyway.
 
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.
 
  • Like
Likes   Reactions: etotheipi and Isaac0427
Ibix said:
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.
 
Isaac0427 said:
"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.
Isaac0427 said:
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?
Isaac0427 said:
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.
 
Isaac0427 said:
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.