When printing the value of a variable, you don't add quotations around the variable but when using the getattr() function to access the value of an attribute you pass it as a string. Is there a reason for this or is it something I just have to remember?
That is the purpose of getattr. That way you can access attributes dynamically, based on a string stored in memory.
Example scenario:
user_provided_input = input()
getattr(some_object, user_provided_input + "dummy")
If the user typed "justa" this would be exactly the same as:
some_object.justadummy
You can also use strings that usually would cause a syntax error or some other kind of error if used as a string literal as well:
>>> setattr(some_object, ".", "dummyvalue")
>>> getattr(some_object, ".")
'dummyvalue'
>>> some_object..
File "<stdin>", line 1
some_object..
^
SyntaxError: invalid syntax
Related
I have a dictionary with a lot of strings.
Is it possible to store a formatted string with placeholders and pass in a actual values later?
I'm thinking of something like this:
d = {
"message": f"Hi There, {0}"
}
print(d["message"].format("Dave"))
The above code obviously doesn't work but I'm looking for something similar.
You use f-string; it already interpolated 0 in there. You might want to remove f there
d = {
# no f here
"message": "Hi There, {0}"
}
print(d["message"].format("Dave"))
Hi There, Dave
Issue: mixing f-String with str.format
Technique
Python version
f-String
since 3.6
str.format
since 2.6
Your dict-value contains an f-String which is immediately evaluated.
So the expression inside the curly-braces (was {0}) is directly interpolated (became 0), hence the value assigned became "Hi There, 0".
When applying the .format argument "Dave", this was neglected because string already lost the templating {} inside. Finally string was printed as is:
Hi There, 0
Attempt to use f-String
What happens if we use a variable name like name instead of the constant integer 0 ?
Let's try on Python's console (REPL):
>>> d = {"message": f"Hi There, {name}"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'name' is not defined
OK, we must define the variable before. Let's assume we did:
>>> name = "Dave"; d = {"message": f"Hi There, {name}"}
>>> print(d["message"])
Hi There, Dave
This works. But it requires the variable or expression inside the curly-braces to be valid at runtime, at location of definition: name is required to be defined before.
Breaking a lance for str.format
There are reasons
when you need to read templates from external sources (e.g. file or database)
when not variables but placeholders are configured independently from your source
Then indexed-placeholders should be preferred to named-variables.
Consider a given database column message with value "Hello, {1}. You are {0}.". It can be read and used independently from the implementation (programming-language, surrounding code).
For example
in Java: MessageFormat.format(message, 74, "Eric")
in Python: message.format(74, 'Eric').
See also:
Format a message using MessageFormat.format() in Java
def cleaning(input):
name = str(input)
read_file = pd.read_csv('#f"{name}".csv')
print(read_file)
cleaning(InputKeyword)
My function must take an input keyword, and this will change the "name" to "#input" word.
I was trying with f-strigs, but it doesn't work. Any ideas or referrals where can I find the solution?
Thanks in advance:)
read_file = pd.read_csv('#f"{name}".csv')
That's not actually an f-string, it's a normal string that has an f, some quotes, and some braces inside it. An f-string must be prefixed with (surprisingly enough) an f :-)
I suggest you try something like:
read_file = pd.read_csv(f"#{name}.csv")
If the name string holds xyzzy, this will try to process the file #xyzzy.csv.
Additionally, it's a very bad idea to use built-in functions as variable names. The input function is one such example. The following (complete) snippet solves both those issues:
# Assumes file_base is a string, see below.
def cleaning(file_base):
read_file = pd.read_csv(f"#{file_base}.csv")
print(read_file)
cleaning("someString")
Note that you can put arbitrary expressions inside f-strings, not just variable names. Hence there's no need to create name as a separate (named) object, you could just insert str(file_base) inside the braces.
However, for your particular case, I don't think the use of str(file_base} is necessary since it appears from tour comments that file_base is already a string, and I believe the formatting for a string without a format_spec is just the string itself(a).
This is why I have f"#{file_base}.csv" in the code above without a str() around the file_base variable.
(a) For objects in general, an {object} snippet inside an f-string will call the object's __format__() method, passing in the format_spec used. Hence f"{something:314159} would use the object method call something.__format__("314159") to format the object into a string.
I'm very new to Python and working with an existing python script, presently it outputs a message with a variable tagged on the end:
print "ERROR: did not find any details inside \"{0}".format(filename)
I want to modify this adding in another variable so the output reads:
print "ERROR: did not find \"{name}\" inside \"{file}\""
Where {name} and {file} are replaced with the variables, what is the correct way to achieve this?
In Python 2, you can use format to pass named parameters and it plugs the names into the variables. Note you can quote strings with single quotes or double quotes, so you can prevent having to escape double quotes by using single quotes:
>>> name = 'John'
>>> file = 'hello.txt'
>>> print 'ERROR: did not find "{name}" inside "{file}"'.format(name=name,file=file)
ERROR: did not find "John" inside "hello.txt"
A shortcut for this is to use the ** operator to pass a dictionary of key/value pairs as parameters. locals() returns all the local variables in this format, so you can use this pattern:
>>> name = 'John'
>>> file = 'hello.txt'
>>> print 'ERROR: did not find "{name}" inside "{file}"'.format(**locals())
ERROR: did not find "John" inside "hello.txt"
Python 3.6+ makes this cleaner with f-strings:
>>> name = 'John'
>>> file = 'hello.txt'
>>> print(f'ERROR: did not find "{name}" in "{file}"')
ERROR: did not find "John" in "hello.txt"
You seem to be using Python 2, so the correct way would be like:
print "ERROR: did not find \"{0}\" inside \"{1}\"".format(name, file)
{0} means to take the first argument from the format() argument list and so on.
Moving to Python 3 and f-strings is preferable, all other things being equal.
.format is a very useful method in python. Check this link for better understanding. https://www.w3schools.com/python/ref_string_format.asp
I hope the examples will help you understand the method well.
You can also try this:
print "ERROR: did not find \"{}\" inside \"{}\"".format(name, file)
f"ERROR: did not find \{name}\ inside \{file}\"
If you need to encapsulate the variables, you just need to put f which means format string so that instead of just printing it out it inserts the value of the variable.
In a Flask tutorial, https://www.youtube.com/watch?v=cYWiDiIUxQc&list=PL-osiE80TeTs4UjLw5MM6OjgkjFeUxCYH&index=4
There is a syntax I want to understand
return f"Post('{self.title}', '{self.dateposted}')"
Can someone decompose this line for me?
f string means to return the result of Post() in a string
'{self.title}' is an argument that is a string, because with ''
{} is used to get a variable.
But in the context self.title is ALREADY a string, why use ' '?
Are my explanations correct? And what does ' ' do here?
In the tutorial he returns this value for the __repr__ method of a class.
This method is called when repr() is called on the object. It's also called when you use str() or print() on the class, if a __str__ method has not been implemented for it.
The intention of implementing a __repr__ method is to aid debugging.
If you tried to print the object without defining a __repr__, it would print out like <Post object at 0x00000000>, which doesn't help!
The single-quotes are used for decoration, and they aren't really necessary.
See also: Difference between __str__ and __repr__?
You might also be interested in reading Fluent Python by Luciano Ramalho as it covers these methods and gives great examples of how they might be used (in addition to a lot of other Python wisdom)
I didn't check the link but this just returns a string that would break down to this.
return "Post('" + self.title + "', '" + self.dateposted + "')"
What is done with the returned string I don't know, but I assume it's evaluated somewhere else.
But all an f string does is embed variables or expressions into your string.
If the variable is not a string it converts it to a string first.
To break down your example, in an fstring, anything within the {} gets embedded.
Since the ' are single quotes and outside of the curly braces, they are also part of the string.
Lets say self.title is equal to "My Title" and self.dateposted is equal to "08-22-2020". The returned string would then result in
"Post('My Title', '08-22-2020')"
If you were to then call exec() with this string it would call Post() with 2 positional string arguments.
I'm currently trying to use python's (3.6) xml.etree.ElementTree commands to write an xml file. Some of the Elements and Subelements I need to write must have "id" and "map" fields, which are reserved python words.
My problem is contained in the following line of code:
ET.SubElement(messages,'trigger',thing='1',bob='a', max='5')
But "max" is a function and I can't use it. Is there a character I can place there to allow me to write this field as I desire? Or some sort of known workaround?
EDIT: I am aware that an '_' stops the python from processing the word, but unfortunately this underscore will show up in my file...so I am trying to see if there is an 'invisible' option for the file I will later be writing.
Thanks much!
Python functions are no problem in the left side of a keyword expression:
>>> def abc(**kwargs):
print kwargs
>>> abc(id=2)
{'id': 2}
>>>
id, map, int, float, str, repr, etc. are built in symbols, not reserved words. You may use them like any other bunch of letters, but assigning it another value replaces the built in symbol:
>>> int(2.5)
2
>>> int = "5"
>>> int(2.5)
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
int(2.5)
TypeError: 'str' object is not callable
Notice how the first line is entirely legal, but will trigger a warning if you have a good IDE like pycharm.
If you want to send a actual reserved word to a function, like print, None, yield, or try, you can use the double star ** to convert a dictionary into keyword arguments, for example:
>>> abc(**{"print":2, "None":3})
{'print': 2, 'None': 3}
I hope this answers your question!