TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python Extension Proposal 498: Literal String Formatting

107 pointsby ptest1over 9 years ago

23 comments

asgard1024over 9 years ago
I am against it, because it allows arbitrary Python expressions inside format strings. It&#x27;s too complicated and lets user have two different ways of doing things (not Pythonic) - one to calculate expression inside string and the other to calculate it outside (which should IMHO be preferred). This should maybe go to the standard library, but please not into the language.<p>I think a better approach would be to just add special formatter operators (if they aren&#x27;t already there) that would just call str() or repr() or ascii() to whatever is presented to them (and maybe take some optional arguments such as length or padding).
评论 #10121931 未加载
评论 #10121732 未加载
评论 #10121835 未加载
评论 #10121809 未加载
Walkmanover 9 years ago
<p><pre><code> There should be one-- and preferably only one --obvious way to do it. </code></pre> This would be the 4th way of formatting strings in Python.
评论 #10121706 未加载
评论 #10121619 未加载
评论 #10121868 未加载
评论 #10121843 未加载
declnzover 9 years ago
I would be very happy to see <i>some version</i> of this accepted.<p>When it comes to native String interpolation Groovy has it, Scala has it, ES6 has it apparently; to a more limited extent Bash, PHP, Perl have it too of course.<p>I can&#x27;t help feeling that other devs are now coming to Python expecting this kind of feature, and are disappointed to find three (harder, often less readable) ways to do it instead. Got to keep up with the Joneses, etc...
评论 #10121806 未加载
schmichaelover 9 years ago
Nonononono. Python does not need more string literal specifiers. For a language that avoid symbols and sigils like the plague, it already has an absurd amount of string literal syntax.<p>Why not make a strfmt library on pypi that provides a single <i>fmt(s, args, kwargs)</i> function and let people call that? Why the obsession with more builtins?
mangelettiover 9 years ago
The first thing I thought of when I looked at the PEP was, &quot;this is like a string version of register_globals=on&quot;.<p>A string literal whose value automatically changes with the code surrounding it sounds like a really bad idea.<p>I also noticed that the PEP uses str.format method as a strawman, ignoring the fact that % string interpolation is very popular and does not need replacing, which is at the core of this problem in the first place; Someone keeps trying to replace something that does not need replacing.<p>Furthermore, I can&#x27;t help but think that this would eventually become a complete literal string DSL (if not one already) inside of Python.<p>I hope this PEP does not get accepted.
评论 #10122722 未加载
JoshTriplettover 9 years ago
This is a massive improvement. I currently use .format(), sometimes with <i></i>locals(), but f-strings would improve this massively.<p>Now if only they didn&#x27;t require Python 3, so I could use them on the production systems I&#x27;m working on...
评论 #10122408 未加载
dalkeover 9 years ago
I am having some problems trying to understand the implementation. What would the AST from evaluating &quot;f&#x27;{a+1}&#x27;&quot; look like? Will there be a special AST node for f-strings, or will it be pre-structured into the AST?<p>If it&#x27;s a special node, is it the responsibility of the byte code generator to parse the string? My belief is that it&#x27;s part of the parser&#x27;s job, so the AST will never contain an f-string.<p>What does a syntax error report look like? Or traceback? Will it be able to narrow down the part of the string which causes a problem?<p>Can f-strings include f-strings, like:<p><pre><code> f&quot;{a + (f&#x27; and {b+1}&#x27;)}&quot; </code></pre> I assume the answer is &#x27;yes, and you shouldn&#x27;t do that&#x27;, which I can accept.<p>Support for arbitrary expressions inside of an f-string means that the following is allowed,<p><pre><code> def f(a, b): return f&quot;{yield a} = {b}&quot; print(f(1, 2)) </code></pre> and will work, and will print <i>something</i>, but it won&#x27;t be &quot;1 = 2&quot;. Nor will any but heavy-weight analysis tools be able to figure out that this &#x27;f&#x27; is a generator.<p>I am less happy accepting that a magic string can turn a function into a generator. Take for example this code from around line 438 of <a href="https:&#x2F;&#x2F;searchcode.com&#x2F;codesearch&#x2F;view&#x2F;18830026&#x2F;" rel="nofollow">https:&#x2F;&#x2F;searchcode.com&#x2F;codesearch&#x2F;view&#x2F;18830026&#x2F;</a> :<p><pre><code> if attr==&#x27;yields&#x27; : yield_unit = self._grab_attr_(obj,&#x27;yield_unit&#x27;) if yield_unit: ret = &#x27;%s %s&#x27;%(ret,yield_unit) # FIXME: i18n? return ret </code></pre> The penultimate line could be rewritten, validly, as:<p><pre><code> ret = f&#x27;{ret} {yield_unit}&#x27; # FIXME: i18n? </code></pre> The introduction of a typo, from &#x27;yield_unit&#x27; to &#x27;yield unit&#x27;, would drastically change the function, and be very hard to spot.<p><pre><code> ret = f&#x27;{ret} {yield unit}&#x27; # FIXME: i18n? </code></pre> Yes, Don&#x27;t Do That, but we know that people use things like syntax highlighters to help understand the code and identify mistakes like this.<p>EDIT: the PEP says that the expression are &quot;parsed with the equivalent of ast.parse(expression, &#x27;&lt;fstring&gt;&#x27;, &#x27;eval&#x27;)&quot;. That means that &#x27;yield&#x27; is not allowed.
评论 #10122767 未加载
erikbover 9 years ago
One of those things when you read it you wonder why it wasn&#x27;t done that way in the first place.
评论 #10121776 未加载
jonathaneuniceover 9 years ago
For those that want something close today, there&#x27;s <a href="https:&#x2F;&#x2F;pypi.python.org&#x2F;pypi&#x2F;say" rel="nofollow">https:&#x2F;&#x2F;pypi.python.org&#x2F;pypi&#x2F;say</a><p><pre><code> fmt(&quot;Hello, {name}! You have {len(msgs)} waiting.&quot;) </code></pre> Interpolates local variables and expressions. It uses the format method, and has all of format&#x27;s output formatting.
评论 #10124352 未加载
评论 #10127045 未加载
voyouover 9 years ago
There&#x27;s an interesting competing PEP which allows for the way in which the expressions are interpolated into the string to be customized: <a href="https:&#x2F;&#x2F;www.python.org&#x2F;dev&#x2F;peps&#x2F;pep-0501&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.python.org&#x2F;dev&#x2F;peps&#x2F;pep-0501&#x2F;</a>
评论 #10122443 未加载
ceronmanover 9 years ago
C# 6.0 is also adding literal string formatting: <a href="http:&#x2F;&#x2F;www.codeproject.com&#x2F;Articles&#x2F;846566&#x2F;What-s-new-in-Csharp-String-Interpolation" rel="nofollow">http:&#x2F;&#x2F;www.codeproject.com&#x2F;Articles&#x2F;846566&#x2F;What-s-new-in-Csh...</a>
stinosover 9 years ago
I hope this gets implemented. A year ago or so we had several customers wanting to custom format output filenames and directories in a desktop application and we settled for something which is almost exactly this, so the {identifier:format spec} idea, and ever since implementing it I wish any language had it as we found it really convenient and having no apparant disadvantages in comparision with printf-%-style in C or Python&#x2F;streams in C++&#x2F;{}-style in C#&#x2F;Python
评论 #10121904 未加载
评论 #10122395 未加载
RodericDayover 9 years ago
<i>However, str.format() is not without its issues. Chief among them is its verbosity. For example, the text &#x27;value&#x27; is repeated here:</i><p><pre><code> &gt;&gt;&gt; value = 4 * 20 &gt;&gt;&gt; &#x27;The value is {value}.&#x27;.format(value=value) &#x27;The value is 80.&#x27; </code></pre> <i>Even in its simplest form, there is a bit of boilerplate, and the value that&#x27;s inserted into the placeholder is sometimes far removed from where the placeholder is situated:</i><p><pre><code> &gt;&gt;&gt; &#x27;The value is {}.&#x27;.format(value) &#x27;The value is 80.&#x27; </code></pre> <i>With an f-string, this becomes:</i><p><pre><code> &gt;&gt;&gt; f&#x27;The value is {value}.&#x27; &#x27;The value is 80.&#x27; </code></pre> Yeah I&#x27;ve had this thought before.
评论 #10124810 未加载
publicfigover 9 years ago
In regards to the title, PEP stands for &quot;Python Enhancement Proposal&quot;, not &quot;Python Extension Proposal&quot;
deniskaover 9 years ago
You can even hack it into a string class if you don&#x27;t mind using even more scary hacks like monkey patching built in classes.<p><pre><code> def I(s): import inspect frame = inspect.currentframe() caller_locals = frame.f_back.f_locals return s.format(**caller_locals) def main(): a = 12 b = 10 print I(&#x27;A is {a} and B is {b}&#x27;) if __name__ == &#x27;__main__&#x27;: main()</code></pre>
kazinatorover 9 years ago
In TXR Lisp, from system prompt:<p><pre><code> # simple quasiliteral, denoted by backticks $ txr -p &#x27;(let ((x &quot;Bob&quot;)) `Hello, @{x -10}`)&#x27; &quot;Hello, Bob&quot; # word-quasiliteral (breaks into list on spaces) # denoted by hash-backtick: $ txr -p &#x27;#`@(+ 2 2) @(+ 1 2) a b c`&#x27; (&quot;4&quot; &quot;3&quot; &quot;a&quot; &quot;b&quot; &quot;c&quot;) # op-argument references in quasiliteral # ret produces a function whose arguments depend # on the uses of @1, @2. ... and @rest in the # expression. The value of the expression is returned. # These references can emanate from a quasistring: $ txr -p &quot;(mapcar (ret \`@1--@2--@rest\`) &#x27;(1 2 3) &#x27;(a b c) &#x27;(x y z)))&quot; (&quot;1--a--x&quot; &quot;2--b--y&quot; &quot;3--c--z&quot;) # Very basic indexing, slicing and field adjustment: $ txr -p &#x27;`foo @{(list 1 2 3) [0]} bar`&#x27; &quot;foo 1 bar&quot; $ txr -p &#x27;`foo @{(list 1 2 3) [2]} bar`&#x27; &quot;foo 3 bar&quot; $ txr -p &#x27;`foo @{(list 1 2 3) [1..:]} bar`&#x27; &quot;foo 2 3 bar&quot; $ txr -p &#x27;`foo @{(list 1 2 3) [1..:] 20} bar`&#x27; &quot;foo 2 3 bar&quot; $ txr -p &#x27;`foo @{(list 1 2 3) [1..:] -20} bar`&#x27; &quot;foo 2 3 bar&quot; </code></pre> Interpolation into quasi-literals is very useful and expressive; I use it all the time. Doing trivial things should look trivial in the code.<p>Oh, right: referencing splices and unquotes is possible from inside a quasistring:<p><pre><code> $ txr -p &#x27;(let ((a 42) (b (range 1 5))) ^(list `hey @,a @(list ,*b)`))&#x27; (list (sys:quasi &quot;hey &quot; @42 &quot; &quot; @(list 1 2 3 4 5))) $ txr -p &#x27;(eval (let ((a 42) (b (range 1 5))) ^(list `hey @,a @(list ,*b)`)))&#x27; (&quot;hey 42 1 2 3 4 5&quot;) </code></pre> Safe to say, that one&#x27;s not coming to a Python near you.
currywurstover 9 years ago
This looks like template strings in ES6 [1], which is really well done ! I look forward to using f-strings<p>[1]: <a href="https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Reference&#x2F;template_strings" rel="nofollow">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Refe...</a>
TazeTSchnitzelover 9 years ago
This is a very handy feature of PHP and would be useful in Python. I think readability will be solved by syntax highlighting: expressions in an f-string would be highlighted like normal expressions, rather than like string content. This is what is already done for PHP.
brazzledazzleover 9 years ago
I&#x27;m really happy to see this. I know it&#x27;s petty, but this was the biggest reason I decided to focus on learning the ins and outs of Ruby instead of Python.
riffraffover 9 years ago
I understand the need for expressions-in-literal.<p>I really don&#x27;t understand why the unnecessary extra &quot;!rsa&quot; modifiers are a good thing though.
评论 #10122709 未加载
nxbover 9 years ago
I just use Tornado templates for doing this. I made a wrapper to make it a single function call. The syntax is very similar.
smegelover 9 years ago
So long as they add a rule to PEP8 saying you can only use one of the string formatting methods in a given source file...
评论 #10122699 未加载
bechampionover 9 years ago
i like it ..a lot!