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
Related
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() !
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.
I'm new to Python, and I'm writing a function to change the case of all characters in a string. The function itself is called swapCases(), and I'm using the library function swapcase() within my own function. Here is the code that I use to test my function:
print(swapCases("HoLa"))
In the first case, my function reads:
def swapCases(s):
for i in range(len(s)):
s[i] = s[i].swapcase()
return s
When I run this code, I get a message from the compiler: "str object does not support item assignment." I Googled the message and it said that strings in Python are immutable and therefore can't be changed. However, when I change my function to this:
def swapCases(s):
s = s.swapcase()
return s
the function does exactly what I want, and the test prints out "hOlA." If strings are immutable in Python, why does this work? Doesn't being immutable mean that I can't change them?
By assigning it to the variable s, you are reassigning s. This gets rid of the reference to the old string "HoLa" and replaces it with a reference to the string returned from s.swapcases()
In your original case, you are attempting to modify the string index by index. Doing this would be mutating the existing references, which is not allowed. This is what is meant by immutable.
Your function is not modifying a string object. It's modifying a name assigned to it. When you assign directly, like this,
s = "abc"
s[2] = "z"
...you are saying "change the third character in this particular string object to 'z'." On the other hand, if you assign twice, like this,
s = "abc"
s = "abz"
...you are saying "change the name, s, to refer to a new string object." This applies whether it's created as a local variable (as above) or as a function 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.
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).