This question already has answers here:
What does it mean when the parentheses are omitted from a function or method call?
(6 answers)
Closed 2 years ago.
I'm a beginner to Python and programming in general. Right now, I'm having trouble understanding the function of empty parentheses at the end of method names, built-in or user-created. For example, if I write:
print "This string will now be uppercase".upper()
...why is there an empty pair of parentheses after "upper?" Does it do anything? Is there a situation in which one would put something in there? Thanks!
Because without those you are only referencing the method object. With them you tell Python you wanted to call the method.
In Python, functions and methods are first-order objects. You can store the method for later use without calling it, for example:
>>> "This string will now be uppercase".upper
<built-in method upper of str object at 0x1046c4270>
>>> get_uppercase = "This string will now be uppercase".upper
>>> get_uppercase()
'THIS STRING WILL NOW BE UPPERCASE'
Here get_uppercase stores a reference to the bound str.upper method of your string. Only when we then add () after the reference is the method actually called.
That the method takes no arguments here makes no difference. You still need to tell Python to do the actual call.
The (...) part then, is called a Call expression, listed explicitly as a separate type of expression in the Python documentation:
A call calls a callable object (e.g., a function) with a possibly empty series of arguments.
the parentheses indicate that you want to call the method
upper() returns the value of the method applied to the string
if you simply say upper, then it returns a method, not the value you get when the method is applied
>>> print "This string will now be uppercase".upper
<built-in method upper of str object at 0x7ff41585fe40>
>>>
upper() is a command asking the upper method to run, while upper is a reference to the method itself. For example,
upper2 = 'Michael'.upper
upper2() # does the same thing as 'Michael'.upper() !
Related
This question already has answers here:
Creating a list of methods to be executed in Python
(4 answers)
Closed 4 months ago.
Let's say I have the following code:
string = "XxXxXx"
print(string.lower())
print(string.upper())
How could I use a list instead along the lines of:
string = "XxXxXx"
list = [lower(), upper()]
for i in list:
print(string.i)
Obviously the code above does not work at all and the problem I'm working on is way more complicated. But if I could make the example above work, it would really take care of my problem!
Functions (and methods) are first class objects in python. You can therefore store them in a list just like you would anything else.
If you want to be able to apply the functions to arbitrary strings, use the unbound function objects in the class:
string = "XxXxXx"
func_list = [str.lower, str.upper]
for i in func_list:
print(i(string))
If you want to only apply the functions to your special string, you can store the bound methods in a list instead:
string = "XxXxXx"
func_list = [string.lower, string.upper]
for i in func_list:
print(i())
In both cases, the () operator is what calls the function. The function name by itself is a reference to the object. In the first case, the . operator does not do anything surprising. In the second case, since you invoke it on an instance of a class, it binds the function object in the class to the instance, creating a bound method that has an implicit self argument.
This question already has an answer here:
Can't dynamically bind __repr__/__str__ to a class created with type [duplicate]
(1 answer)
Closed 3 years ago.
I'm curious how repr works. It can't be exactly
def repr_(x):
return x.__repr__()
since that does not work on classes, namely
repr_(int)
causes an error since int's repr expects an int object as the first argument. I know that I can customize a class's repr by creating a metaclass with a desired __repr__, but I want to know how does Python's built in repr work? And how does it specifically handle the case of having a class passed into it.
Does it do something like a try catch where it first tries what my repr_ does and then looks up the MRO for other reprs? Or something else?
Figured it out. If we inspect how Python internally computes repr, which we can see in the source file object.c, we can see that repr is essentially
def repr_(x):
return x.__class__.__repr__(x)
import datetime
today=datetime.date.today()
print(repr(today))
for objects of classes, repr basically displays unambiguous output when obj call is their.
Documentation https://www.cmi.ac.in/~madhavan/courses/prog2-2015/docs/python-3.4.2-docs-html/library/functions.html#repr
Return a string containing a printable representation of an object.
For many types, this function makes an attempt to return a string that
would yield an object with the same value when passed to eval(),
otherwise the representation is a string enclosed in angle brackets
that contains the name of the type of the object together with
additional information often including the name and address of the
object. A class can control what this function returns for its
instances by defining a repr() method.
So I came across this but don't fully understand why this is the case:
count = 0
Got_one = 0
while(count<1):
print('\n')
response = input("Did you get one?\n:").lower()#<--This part here
if response == 'yes':
Got_one += 1
#...ect
At one point of the script I had typed up .lower without the (). The code ran fine but the script failed to +1 when I inputted "yes", instead it printed out a value of 0, most likely due to the "Got_one" variable being set to 0 in the very beginning. However, as soon as I typed up the () the code worked as intended and +1 to the value after inputting "yes".
So, why is this the case? Is .lower on its own lowering everything after it or just something I don't understand about Python yet?
.lower() is a built-in method for the String object in Python. The reason you need the parenthesis is to execute the function on the string.
Without the parenthesis, you are simply accessing the String.lower attribute, which is a function pointer. Therefore, without the parenthesis, you are setting response = String.lower, which will not pass the if statement.
the difference is that calling it with no parenthesis is your just calling the method but not the value of that method and calling it with parenthesis your calling the value of that method
The reason for that is because .lower() is a class method, not a class attribute (which would be written as .lower).
Therefore, you have to use parenthesis to indicate that you are trying to call a method.
Since it does not take any arguments, you simply only put empty parenthesis behind it.
A class method is a function that belongs to a class object, in this case a str object.
A class attribute is a variable that belongs to this object.
To add to 1313e's answer, .lower() is actually a built-in method (functions for object classes) that you're performing on the string object (because everything in Python is an object), which is why you call 'this string'.lower() and not, say, lower('this string')
This is because you are merely making a reference to the lower class method (function) of the class object str. For reference:
foo = "ALL CAPS"
bar = foo.lower
bar
>>> <built-in method lower of str object at 0x1038e1570>
bar()
>>> 'all caps'
Is it possible to empty a string using functions in python?
For example:
otherText="hello"
def foo(text):
text=""
foo(otherText)
print(otherText)
prints
hello
instead of an empty string. Is there a way to empty the string without assigning it a return value or using global variables?
It's not possible. There are 2 reasons for that
Python strings are immutable
Python implements a so called "call by sharing" evaluation strategy:
The semantics of call by sharing differ from call by reference in that assignments to function arguments within the function aren't visible to the caller
As noted by zerkms, it is strictly not possible, python does not pass argument by reference.
There are a few tricks that can be used as workarounds, such as passing a list or object, containing your string.
otherText=["hello"]
def foo(text):
text[0]="Goodbye string"
foo(otherText)
print(otherText) //Goodbye string
This question already has answers here:
Why does Python code use len() function instead of a length method?
(7 answers)
Closed 8 years ago.
Just starting out with Python
Could anyone explain the reasoning behind why some built in string functions take arguments within their brackets like this:
length = len("This is a string")
whilst some other functions seem to just be "chained" on to the end of the string that they are operating on for example:
uppercase = "lowercase string".upper()
Probably a silly question but just wondered if there was a reason behind this that I'm unaware of.
len() is a built in function, it returns length of a sequence, that is you can pass lists, tuples to len() not only strings. For example:
foo = (1,2,3)
len(foo)
>>> 3
bar = ['a', 'b', 'c', 'd']
len(bar)
>>> 4
And about brackets - in your example what is between brackets is a string. You can also do this:
foo = "This is a string"
len(foo)
And the
"lowercase string".upper()
Is calling a method of a string object, which returns uppercase of that string. You can do the same with:
foo = "lowercase string"
uppercase = foo.upper()
the function len() is a buildin-function in the language. len() docs
and the .upper() function that your using is part of the string class. str.upper() docs
Len is a function, a built-in function, so using len (something) you apply a transformation to your input and obtain an output, something like Y=f(X).
"some string".upper() is a Method of the instance "some string"; "some string" belongs to the class String and has its methods.
Pay attention that "some string" written like that is an object and has all it's methods, you can see this if you type:
>>type("some string")
str
In summary: len is a function and is defined externally, .upper() is a method defined within the object itself
In the first case len is a function which you're calling within the current namespace, and you're passing a parameter to it. In the second, calling xyz.upper() means you are calling the method .upper() on the String object "lowercase string".
The len() function calls the __len__() method on the object passed in to it, so really it is just a shortcut for calling that method. Some other users have already posted links to the reasoning behind this (thank you for the correction larsmans).