问题
I'm discovering possibilities of string formatting with .format( ) method in Python 3 but i raised an error that i do not understand.
So, why the following line is ok [wich let me think that "0" can be used exactly like the argument passed to format()]:
s = 'First letter of {0} is {0[0]}'.format("hello")
#gives as expected: 'First letter of hello is h'
but not this one [applying a method or a function to 0 in {0} doesn't work?]:
s = '{0} becomes {0.upper()} with .upper() method'.format("hello")
raising the following error:
AttributeError: 'str' object has no attribute 'upper()'
Why the raised error says i've used upper as an attribute and not as a method? And is there another way to do it than:
s = '{} becomes {} with .upper() method'.format("hello","hello".upper())
#gives as expected: 'hello becomes HELLO with .upper() method'
Thanks!
回答1:
String formatting uses a limited Python-like syntax. It is not treating them as actual Python expressions. Calls are not supported in this syntax, only subscription (indexing by number or by unquoted (!) name), and attribute access is supported.
See the Format String Syntax documentation, which limits the field naming part to:
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
The error you see stems from the attribute_name
value having been set to 'upper()'
, so the identifier includes the parentheses. String objects only have an attribute named upper
, and in actual Python expressions the ()
part is a separate call expression applied to the result of the attribute lookup:
>>> value = "hello"
>>> getattr(value, 'upper()') # what the template engine tries to do
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'upper()'
>>> getattr(value, 'upper') # what an actual Python expression does
<built-in method upper of str object at 0x10e08d298>
>>> getattr(value, 'upper')() # you can call the object that is returned
'HELLO'
As of Python 3.6 you can use the new f-string formatted string literals that support full expressions, because those are parsed directly by the interpreter when compiling the Python code. Using such literals you can do:
value = 'hello'
s = f'{value} becomes {value.upper()} with .upper() method'
Demo:
>>> f'{value} becomes {value.upper()} with .upper() method'
'hello becomes HELLO with .upper() method'
来源:https://stackoverflow.com/questions/33411002/python-error-str-object-has-no-attribute-upper