New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
string.format() should have a safe_substitute equivalent, to be run consecutively #68737
Comments
|
"{1} {0}".format('one').format('two') should return "two one", but throws This would allow partial replacements, similar to string.Template.safe_substitute() |
|
Why not use string.Template? |
|
So let's say your function would be named "safe_format". Then: "{1} {0}".safe_format('one') would give: "{1} one". Then: "{1} one".safe_format('two') would be an error, because there's no index "1" in the args tuple. I can't imagine how you'd implement this function so it would know to start with index 1 on the second call, instead of 0 as usual. Or maybe it would decrement the index values it doesn't use, so that the result of the first call would be: "{0} one". That seems very complex, especially when you throw in implicit argument numbering, named arguments, format specifiers, etc. I agree with David that string.Template might be better for you. On an unrelated note, I think that "IndexError: tuple index out of range" is a horrible error message for this case. I wouldn't mind an enhancement request to make that something like "argument index '1' is out of range, only 1 argument supplied". Or something with better wordsmithing. |
|
I don't think that this behaviour is desirable, certainly not by default. If I write "{1} {0}".format('one') that's clearly a programming error and I should get an exception. Chaining a second .format method call afterwards does not make the first one any less of a mistake. I think that there may be a good argument to be made for a safe_format with *named* arguments, like string.Template, but not positional arguments. But that would require some discussion, to decide on the correct behaviour. And why not use string.Template in the first place, or make the chained calls a single call? "{1} {0}".format('one', 'two') is clearly the most obvious way to do it. A slightly less obvious way: "{{}} {}".format('one').format('two') |
|
(Sorry for not replying so long, I expected an email notification)
because it's so slow
Yes!
What open question(s) do you think of? For context, I got the idea for this from Qts .arg() which can be chained, see <https://doc.qt.io/qt-5/qstring.html#arg\>. |
You need to provide an exact specification of what you want. It's not clear, for example, if you want to support required positional placeholders ({0}, etc.) but optionally missing named placeholders ({foo}). I'd also suggest implementing this as a function, so you can get some real-world usage out of it. Maybe: def format_safe(s, *args, **kwargs):
format_safe("{0} {1} {foo} {bar}", 'one', 'two', bar='bar')
->
'one two {foo} bar}'or whatever you decide the signature and functionality should be. You can probably subclass from string.Formatter to do some of the heavy lifting for you, so I expect this wouldn't be very hard, depending on what you're really after. While you might find this function useful, I don't want to get your hopes up that this would be added to core Python as a member of str. I still don't see why this would be better than a single call to .format() that specifies all of the parameters. You'd have to have some use case that doesn't involve chaining for that to make sense (to me). And maybe functools.partial() or some derivative would make sense in that case. |
azrdev mannequin commentedJul 1, 2015
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: