x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
x = { "y": "z" }x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
def s( x ): return '-> ' + x[ 'y' ]
print( s( x = x ))
Hi there,
is there an easy way to evaluate a string stored in a variable as if it
were an f-string at runtime?
...
This is supposedly for security reasons. However, when trying to emulate
this behavior that I wanted (and know the security implications of), my solutions will tend to be less secure. Here is what I have been thinking about:
Hi there,
is there an easy way to evaluate a string stored in a variable as if
it were an f-string at runtime?
I.e., what I want is to be able to do this:
x = { "y": "z" }
print(f"-> {x['y']}")
This prints "-> z", as expected. But consider:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
Even though
s = "-> {x}"
print(s.format(x = x))
Prints the expected "-> {'y': 'z'}".
Op 23/01/2023 om 17:24 schreef Johannes Bauer:
Hi there,I am probably missing something but is there a reason why the following wouldn't do what you want:
is there an easy way to evaluate a string stored in a variable as if
it were an f-string at runtime?
I.e., what I want is to be able to do this:
x = { "y": "z" }
print(f"-> {x['y']}")
This prints "-> z", as expected. But consider:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
Even though
s = "-> {x}"
print(s.format(x = x))
Prints the expected "-> {'y': 'z'}".
x = { "y": "z" }
s = "-> {target}"
print(s.format(target = x['y']))
Stack overflow to the rescue:
Search phrase: "python evaluate string as fstring"
https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string
def effify(non_f_str: str):Duh! Am I the only one who feels stupid not thinking of this?
return eval(f'f"""{non_f_str}"""')
print(effify(s)) # prints as expected: "-> z"
On Tue, 24 Jan 2023 at 04:56, Johannes Bauer <dfnsonfsduifb@gmx.de> wrote:Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
Hi there,If you really want the full power of an f-string, then you're asking
is there an easy way to evaluate a string stored in a variable as if it
were an f-string at runtime?
...
This is supposedly for security reasons. However, when trying to emulate
this behavior that I wanted (and know the security implications of), my
solutions will tend to be less secure. Here is what I have been thinking
about:
for the full power of eval(), and that means all the security
implications thereof, not to mention the difficulties of namespacing.
Have you considered using the vanilla format() method instead?
But if you really REALLY know what you're doing, just use eval()
directly. I don't really see what you'd gain from an f-string. At very
least, work with a well-defined namespace and eval whatever you need
in that context.
Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?
ChrisA
On 23/01/2023 18:02, Chris Angelico wrote:
Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?
ChrisAFair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
for a different use-case) whether there is a way of evaluating a string
at runtime as if it were an f-string. We encourage people to ask
questions on this list, even though the answer will not always be what they're hoping for.
I appreciate that the answer may be "No, because it would be a lot of
work - and increase the maintenance burden - to support a relatively
rare requirement".
Perhaps someone will be inspired to write a function to do it. 😎
We encourage people to ask
questions on this list, even though the answer will not always be what they're hoping for.
x = { "y": "z" }
s = "-> {target}"
print(s.format(target = x['y']))
Stack overflow to the rescue:
Search phrase: "python evaluate string as fstring"
https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
print(effify(s)) # prints as expected: "-> z"
def effify(non_f_str: str):Traceback (most recent call last):
return eval(f'f"""{non_f_str}"""')
print(effify(s)) # prints as expected: "-> z"
print(effify(s))
This is supposedly for security reasons. However, when trying to emulate
this behavior that I wanted (and know the security implications of), my
solutions will tend to be less secure. Here is what I have been thinking
about:
If you really want the full power of an f-string, then you're asking
for the full power of eval(),
and that means all the security
implications thereof,
not to mention the difficulties of namespacing.
Have you considered using the vanilla format() method instead?
But if you really REALLY know what you're doing, just use eval()
directly.
'xxxx's = "{\"x\" * 4}"
eval("f'" + s + "'")
I don't really see what you'd gain from an f-string.
At very
least, work with a well-defined namespace and eval whatever you need
in that context.
Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
x = { "y": "z" }
def s( x ): return '-> ' + x[ 'y' ]
print( s( x = x ))
All you tell us is
what you're attempting to do, which there is *no good way to achieve*.
Perhaps someone will be inspired to write a function to do it. 😎
See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen. Using eval() to construct
an f-string and then parse it is TERRIBLE because:
1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.
For some reason, str.format() isn't suitable,
but *you haven't said
why*,
Well, yes. If you asked "how can I do X", hoping the answer would be
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".
Don't ask how to use X to do Y. Ask how to do Y.
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:Except this is not at all what I asked for. The string "s" in my example
x = { "y": "z" }x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
def s( x ): return '-> ' + x[ 'y' ]
print( s( x = x ))
is just that, an example. I want to render *arbitrary* strings "s"
together with arbitrary dictionaries "x".
z
I don't understand why you fully ignore literally the FIRST example I
gave in my original post and angrily claim that you solution works when
it does not:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
z
On Sat, 28 Jan 2023 at 05:31, Rob Cliffe via Python-list <python-list@python.org> wrote:If the above is addressed to the OP, I can't answer for him.
On 23/01/2023 18:02, Chris Angelico wrote:No, it's not, because that's the "how do I use X to do Y" problem.
Maybe, rather than asking for a way to treat a string as code, ask forFair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
what you ACTUALLY need, and we can help?
ChrisA
for a different use-case) whether there is a way of evaluating a string
at runtime as if it were an f-string. We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.
Instead, just ask how to do *what you actually need*. If the best way
to do that is to eval an f-string, then someone will suggest that.
But, much much much more likely, the best way to do it would be
something completely different. What, exactly? That's hard to say,
because *we don't know what you actually need*. All you tell us is
what you're attempting to do, which there is *no good way to achieve*.
Again, if this is addressed to the OP: I'm not his keeper. 😁I appreciate that the answer may be "No, because it would be a lot ofWhat about: "No, because it's a terrible TERRIBLE idea, requires that
work - and increase the maintenance burden - to support a relatively
rare requirement".
you do things horribly backwards, and we still don't even know what
you're trying to do"?
Perhaps someone will be inspired to write a function to do it. 😎See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen.
Using eval() to constructI understand these limitations. Nonetheless I can conceive that there
an f-string and then parse it is TERRIBLE because:
1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.
For some reason, str.format() isn't suitable, but *you haven't saidI hope that I have shown that this is a somewhat dogmatic response.
why*, so we have to avoid that in our solutions. So, to come back to
your concern:
We encourage people to askWell, yes. If you asked "how can I do X", hoping the answer would be
questions on this list, even though the answer will not always be what
they're hoping for.
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".
Don't ask how to use X to do Y. Ask how to do Y.Good advice.
ChrisA
Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
If it's addressed to me: How about if I wanted a program (a learning
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one
right now.
If it's addressed to me: "it" means a function that will take a string
and evaluate it at runtime as if it were an f-string. Sure, with
caveats and limitations.
And indeed Thomas Passim found this partial
solution on Stack Overflow:
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
Addressing your points specifically:
1) I believe the quote character limitation could be overcome. It
would need a fair amount of work, for which I haven't (yet) the time or inclination.
2) Yes in general you would have to pass it one dictionary, maybe... x = 1
two. I don't see this as an insuperable obstacle. I am not sure what
you mean by "can't be done with full generality" and perhaps that's not important.
def func():
x=1 y=2func()
... x = 1def func():
2func()
2func()
3) Not sure I understand this.
Well, yes. If you asked "how can I do X", hoping the answer would beI hope that I have shown that this is a somewhat dogmatic response.
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".
Don't ask how to use X to do Y. Ask how to do Y.Good advice.
Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
On 27/01/2023 19:18, Chris Angelico wrote:
On Sat, 28 Jan 2023 at 05:31, Rob Cliffe via Python-listIf the above is addressed to the OP, I can't answer for him.
<python-list@python.org> wrote:
On 23/01/2023 18:02, Chris Angelico wrote:No, it's not, because that's the "how do I use X to do Y" problem.
Maybe, rather than asking for a way to treat a string as code, ask for >>>> what you ACTUALLY need, and we can help?Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps >>> for a different use-case) whether there is a way of evaluating a string
ChrisA
at runtime as if it were an f-string. We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.
Instead, just ask how to do *what you actually need*. If the best way
to do that is to eval an f-string, then someone will suggest that.
But, much much much more likely, the best way to do it would be
something completely different. What, exactly? That's hard to say,
because *we don't know what you actually need*. All you tell us is
what you're attempting to do, which there is *no good way to achieve*.
If it's addressed to me: How about if I wanted a program (a learning
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one
right now.
Again, if this is addressed to the OP: I'm not his keeper. 😁
I appreciate that the answer may be "No, because it would be a lot ofWhat about: "No, because it's a terrible TERRIBLE idea, requires that
work - and increase the maintenance burden - to support a relatively
rare requirement".
you do things horribly backwards, and we still don't even know what
you're trying to do"?
Perhaps someone will be inspired to write a function to do it. 😎See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen.
If it's addressed to me: "it" means a function that will take a string
and evaluate it at runtime as if it were an f-string. Sure, with
caveats and limitations. And indeed Thomas Passim found this partial solution on Stack Overflow:
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
Using eval() to constructI understand these limitations. Nonetheless I can conceive that there
an f-string and then parse it is TERRIBLE because:
1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.
may be scenarios where it is an acceptable solution (perhaps the
learning tool program I suggested above).
Addressing your points specifically:
1) I believe the quote character limitation could be overcome. It would need a fair amount of work, for which I haven't (yet) the time or inclination.
2) Yes in general you would have to pass it one dictionary, maybe two. I don't see this as an insuperable obstacle. I am not sure what
you mean by "can't be done with full generality" and perhaps that's not important.
3) Not sure I understand this.
4) On the fairly rare occasions that I have used eval(), I can't remember speed ever being a consideration.
I hope that I have shown that this is a somewhat dogmatic response.
For some reason, str.format() isn't suitable, but *you haven't said
why*, so we have to avoid that in our solutions. So, to come back to
your concern:
We encourage people to askWell, yes. If you asked "how can I do X", hoping the answer would be
questions on this list, even though the answer will not always be what
they're hoping for.
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".
Good advice.
Don't ask how to use X to do Y. Ask how to do Y.
Best wishes
Rob Cliffe
ChrisA
Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example I
gave in my original post and angrily claim that you solution works
when it does not:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
It's because "you're holding it wrong!". Notice the error message; it
says that the key 'y' does not exist.
(base) Apfelkiste:Abschlussmeeting chris$ ipython
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: x = { "y": "z" }
In [2]: s = "-> {x[y]}"
In [3]: print(s.format(x = x))
z
In [4]:
Christian
Am 25.01.23 um 20:38 schrieb Thomas Passin:
x = { "y": "z" }
s = "-> {target}"
print(s.format(target = x['y']))
Stack overflow to the rescue:
No.
Search phrase: "python evaluate string as fstring"
https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
print(effify(s)) # prints as expected: "-> z"
Great.
s = '"""'
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
print(effify(s)) # prints as expected: "-> z"
Traceback (most recent call last):print(effify(s))
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in effify
File "<string>", line 1
f"""""""""
^
SyntaxError: unterminated triple-quoted string literal (detected at line 1)
This is literally the version I described myself, except using triple
quotes. It only modifies the underlying problem, but doesn't solve it.
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:Except this is not at all what I asked for. The string "s" in my
x = { "y": "z" }x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
def s( x ): return '-> ' + x[ 'y' ]
print( s( x = x ))
example is just that, an example. I want to render *arbitrary* strings "s" >together with arbitrary dictionaries "x".
z
On 1/27/2023 5:10 PM, Christian Gollwitzer wrote:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Am 27.01.23 um 21:43 schrieb Johannes Bauer:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
It's because "you're holding it wrong!". Notice the error message; it
[...]says that the key 'y' does not exist.
In [1]: x = { "y": "z" }
In [2]: s = "-> {x[y]}"
In [3]: print(s.format(x = x))
zIn [4]:
Oops, that's not quite what he wrote.
You: s = "-> {x[y]}" # Works
Him: s = "-> {x['y']}" # Fails
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
I want to pass a single variable as a dictionary and access its members inside the expression.
But if you really REALLY know what you're doing, just use eval()
directly.
I do, actually, but I hate it. Not because of the security issue, not
because of namespaces, but because it does not reliably work:
'xxxx's = "{\"x\" * 4}"
eval("f'" + s + "'")
On Sat, 28 Jan 2023 at 10:08, Rob Cliffe via Python-list <python-list@python.org> wrote:
Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
The exact same points have already been made, but not listened to.
Sometimes, forceful language is required in order to get people to
listen.
Addressing your points specifically:
1) I believe the quote character limitation could be overcome. It
would need a fair amount of work, for which I haven't (yet) the time or
inclination.
No problem. Here, solve it for this string:
eval_me = ' f"""{f\'\'\'{f"{f\'{1+2}\'}"}\'\'\'}""" '
F-strings can be nested, remember.
Don't ask how to use X to do Y. Ask how to do Y.Good advice.
Exactly. As I have shown, asking how to use f-strings to achieve this
is simply not suitable, and there's no useful way to discuss other
than to argue semantics. If we had a GOAL to discuss, we could find
much better options.
This is literally the version I described myself, except using triple
quotes. It only modifies the underlying problem, but doesn't solve it.
Ok, so now we are in the territory of "Tell us what you are trying to accomplish". And part of that is why you cannot put some constraints on
what your string fragments are. The example I gave, copied out of your earlier message, worked and now you are springing triple quotes on us.
Stop with the rock management already and explain (briefly if possible)
what you are up to.
Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example I
gave in my original post and angrily claim that you solution works
when it does not:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
It's because "you're holding it wrong!". Notice the error message; it
says that the key 'y' does not exist.
I don't want to have to care about what quotation is used inside the
string, as long as it could successfully evaluate using the f-string
grammar.
Am 28.01.23 um 00:41 schrieb Chris Angelico:
On Sat, 28 Jan 2023 at 10:08, Rob Cliffe via Python-list <python-list@python.org> wrote:
Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
The exact same points have already been made, but not listened to. Sometimes, forceful language is required in order to get people to
listen.
An arrogant bully's rationale. Personally, I'm fine with it. I've been
to Usenet for a long time, in which this way of "educating" people was considered normal. But I do think it creates a deterring, toxic
environment and reflects back to you as a person negatively.
Exactly. This is precisely what I want to avoid. Essentially, proper quotation of such a string requires to write a fully fledged f-string
parser, in which case the whole problem solves itself.
Don't ask how to use X to do Y. Ask how to do Y.Good advice.
Exactly. As I have shown, asking how to use f-strings to achieve this
is simply not suitable, and there's no useful way to discuss other
than to argue semantics. If we had a GOAL to discuss, we could find
much better options.
I was not asking how to use f-strings. I was asking to evaluate a string
*as if it were* an f-string. Those are two completely different things
which you entirely ignored.
In other words, if there were a magic function:
evalfstring(s, x = x)
That would have been the ideal answer. There does not seem to be one, however. So I'm back to silly workarounds.
I have a string. I want to evaluate it as if it were an f-string. I.e.,
there *are* obviously restrictions that apply (namely, the syntax and >semantics of f-strings), but that's it.
z
z
z
z
Johannes Bauer <dfnsonfsduifb@gmx.de> writes:
I have a string. I want to evaluate it as if it were an f-string. I.e., >there *are* obviously restrictions that apply (namely, the syntax and >semantics of f-strings), but that's it.
(This message was written for Usenet. If you read it in a
mailing list or the Web, it has been stolen from Usenet.)
Am 28.01.23 um 02:51 schrieb Thomas Passin:
This is literally the version I described myself, except using triple
quotes. It only modifies the underlying problem, but doesn't solve it.
Ok, so now we are in the territory of "Tell us what you are trying to
accomplish". And part of that is why you cannot put some constraints
on what your string fragments are. The example I gave, copied out of
your earlier message, worked and now you are springing triple quotes
on us.
It works in this particular case, yes. Just like the example I gave in
my original case:
eval("f'" + s + "'")
"works" if there are no apostrophes used. And just like
eval("f\"" + s + "\"")
"works" if there are no quotation marks used.
I don't want to have to care about what quotation is used inside the
string, as long as it could successfully evaluate using the f-string
grammar.
Stop with the rock management already and explain (briefly if
possible) what you are up to.
I have a string. I want to evaluate it as if it were an f-string. I.e.,
there *are* obviously restrictions that apply (namely, the syntax and semantics of f-strings), but that's it.
The exact same points have already been made, but not listened to.
Sometimes, forceful language is required in order to get people to
listen.
An arrogant bully's rationale. Personally, I'm fine with it. I've been
to Usenet for a long time, in which this way of "educating" people was
considered normal. But I do think it creates a deterring, toxic
environment and reflects back to you as a person negatively.
Arrogant bully? Or someone who has tried *multiple times* to explain
to you that what you're asking for is IMPOSSIBLE, and you need to ask
a better question if you want a better answer?
If that's "bullying", then fine, ban me for bullying, and go find
somewhere else where you'll be coddled and told that your question is
fine, it's awesome, and yes, wouldn't it be nice if magic were a
thing.
They're not different things, because what you asked for is NOT
POSSIBLE without the caveats that I gave. It is *fundamentally not
possible* to "evaluate a string as if it were an f-string", other than
by wrapping it in an f-string and evaluating it - with the
consequences of that.
In other words, if there were a magic function:
evalfstring(s, x = x)
That would have been the ideal answer. There does not seem to be one,
however. So I'm back to silly workarounds.
Right. Exactly. Now if you'd asked for what you REALLY need, maybe
there'd be a solution involving format_map, but no, you're so utterly intransigent that you cannot adjust your question to fit reality.
If that makes me a bad guy, then fine. I'll be the bad guy.
But you're not going to change the laws of physics.
Well, yes, we do see that. What we don't see is what you want to
accomplish by doing it, and why you don't seem willing to accept some restrictions on the string fragments so that they will evaluate correctly.
IOW, perhaps there is a more practical way to accomplish what you want. Except that we don't know what that is.
On 1/27/2023 5:10 PM, Christian Gollwitzer wrote:
Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example I
gave in my original post and angrily claim that you solution works
when it does not:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
It's because "you're holding it wrong!". Notice the error message; it
says that the key 'y' does not exist.
(base) Apfelkiste:Abschlussmeeting chris$ ipython
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: x = { "y": "z" }
In [2]: s = "-> {x[y]}"
In [3]: print(s.format(x = x))
z
In [4]:
Christian
Oops, that's not quite what he wrote.
You: s = "-> {x[y]}" # Works
Him: s = "-> {x['y']}" # Fails
Am 28.01.23 um 02:56 schrieb Thomas Passin:
On 1/27/2023 5:10 PM, Christian Gollwitzer wrote:You might want to reconsider why I could have possibly written this message....
Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example
I gave in my original post and angrily claim that you solution works
when it does not:
x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: "'y'"
This. Does. Not. Work.
It's because "you're holding it wrong!". Notice the error message; it
says that the key 'y' does not exist.
(base) Apfelkiste:Abschlussmeeting chris$ ipython
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: x = { "y": "z" }
In [2]: s = "-> {x[y]}"
In [3]: print(s.format(x = x))
z
In [4]:
Christian
Oops, that's not quite what he wrote.
You: s = "-> {x[y]}" # Works
Him: s = "-> {x['y']}" # Fails
Am 29.01.23 um 05:27 schrieb Thomas Passin:
IOW, perhaps there is a more practical way to accomplish what you want. Except that we don't know what that is.
Well, I don't know. I pretty much want a generic Python mechanism that
allows for exactly what f-strings do: execute arbitrary Python snippets of code
and format them in one go.
In other words, I want to be able to do things like that, given an *arbitrary* dictionary x and a string s
Then what about,
name = input( 'name of the dictionary? ' )
s = input( 'string? ' )
dictionary = eval( input( 'dictionary? ' ))
print( eval( s, {name:dictionary} ))
On Sat, 28 Jan 2023 at 10:08, Rob Cliffe via Python-list <python-list@python.org> wrote:This is hypothetical, but I might want to work on a platform where the
Whoa! Whoa! Whoa!The exact same points have already been made, but not listened to.
I appreciate the points you are making, Chris, but I am a bit taken
aback by such forceful language.
Sometimes, forceful language is required in order to get people to
listen.
If it's addressed to me: How about if I wanted a program (a learningUse the REPL, which will happily evaluate f-strings in their original context, just like any other code would. You're already eval'ing, so
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one
right now.
it's exactly what you'd expect. This is not the same thing as "typing
in a string", though - it's typing in code and seeing what the result
would be. (Except to the extent that source code can be considered a
string.)
With great respect, Chris, isn't it for the OP (or anyone else) toIf it's addressed to me: "it" means a function that will take a stringAnd that's what I am saying is a terrible terrible idea. It will
and evaluate it at runtime as if it were an f-string. Sure, with
caveats and limitations.
evaluate things in the wrong context, it has all the normal problems
of eval, and then it introduces its own unique problems with quote characters.
I remember it well.And indeed Thomas Passim found this partialYou can find anything on Stack Overflow. Just because you found it
solution on Stack Overflow:
def effify(non_f_str: str):
return eval(f'f"""{non_f_str}"""')
there doesn't mean it's any good - even if it's been massively
upvoted.
Addressing your points specifically:No problem. Here, solve it for this string:
1) I believe the quote character limitation could be overcome. It
would need a fair amount of work, for which I haven't (yet) the time or
inclination.
eval_me = ' f"""{f\'\'\'{f"{f\'{1+2}\'}"}\'\'\'}""" '
F-strings can be nested, remember.
Thanks for clarifying.2) Yes in general you would have to pass it one dictionary, maybe... x = 1
two. I don't see this as an insuperable obstacle. I am not sure what
you mean by "can't be done with full generality" and perhaps that's not
important.
def func():
... class cls:
... y = 2
... print(f"{x=} {y=}")
... print(locals())
...
x=1 y=2func()
{'__module__': '__main__', '__qualname__': 'func.<locals>.cls', 'y': 2}
Maybe you don't care. Maybe you do. But locals() is not the same asNow that, I have to admit, IS a challenge!
"all names currently available in this scope". And, this example is definitely not something I would recommend, but good luck making this
work with eval:
... x = 1def func():
... print(f"{(x:=2)}")
... print(x)
...
2func()
2
... x = 1
... print(eval("(x:=2)", globals(), locals()))
... print(x)
...
2func()
1
3) Not sure I understand this.Before f-strings existed, one of the big problems with "just use str.format_map" was that you can't just pass it locals() to get all
the available names. You also can't eval arbitrary code and expect to
get the same results, even if you pass it globals and locals. And
various other considerations here - the exact issues seen here, but
flipped on their heads. So the obvious question is: why not just use str.format_map?
With great respect, Chris, isn't it for the OP (or anyone else) to
decide - having been warned of the various drawbacks and limitations -
to decide if it's a terrible idea *for him*? He's entitled to decide
that it's just what *he* needs, and that the drawbacks don't matter *for him". Just as you're entitled to disagree.
Thanks for clarifying.
Hm. So 'x' is neither in locals() nor in globals(). Which starts me wondering (to go off on a tangent): Should there be a nonlocals()
dictionary?
... def __init__(self, name): self.name = nameclass Destructible:
... x = Destructible("x")def func():
Deleting yfunc()
Maybe you don't care. Maybe you do. But locals() is not the same as
"all names currently available in this scope". And, this example is definitely not something I would recommend, but good luck making this
work with eval:
Now that, I have to admit, IS a challenge!... x = 1def func():
... print(f"{(x:=2)}")
... print(x)
...
2func()
2
... x = 1
... print(eval("(x:=2)", globals(), locals()))
... print(x)
...
2func()
1
It's an objectively bad idea. If the OP wants to do it, well, it's a
free world, but that doesn't mean I'm going to sugarcoat it and say
"oh yes, yes, you are totally right to do that".
Exactly. This sort of thing is why the OP's idea as written is so bad:
it will cause many unnecessary corner cases, where the much simpler
idea of working it around format_map will actually behave sanely.
So I do not apologize for calling it a bad idea. It is a bad idea.
Lying about it won't change anything and won't help anyone.
Does that mean that it is not possible to have a (built-in) functionThanks for clarifying.I don't think so, but there might be some value in a dictionary
Hm. So 'x' is neither in locals() nor in globals(). Which starts me
wondering (to go off on a tangent): Should there be a nonlocals()
dictionary?
containing all available variables. It would have the same "don't
depend on writing" caveats that locals() has (or would be specifically defined as a copy and thus disconnected), so its value would be
limited. And it would probably STILL be imperfect, because perfection
would require that it be a compiler construct, due to the way that
nonlocals are implemented.
Does that mean that it is not possible to have a (built-in) function
that would construct and return a dictionary of all available variables
and their values? If it were possible, it could be useful, and there
would be no impact on Python run-time speed if it were only constructed
on demand.
Rob Cliffe <rob.cliffe@btinternet.com> writes:
Does that mean that it is not possible to have a (built-in) function
that would construct and return a dictionary of all available variables
and their values? If it were possible, it could be useful, and there
would be no impact on Python run-time speed if it were only constructed
on demand.
Here's a quick attempt to get local and non-local names as a set.
It might only work under some implementations of Python.
main.py
set_class = set
def f():
x = 0
def g():
set = set_class()
for n in g.__qualname__.split( '.' ):
if n != '<locals>':
set = set.union( set_class( eval( n ).__code__.co_varnames ))
print( set )
g()
f()
output
{'n', 'set', 'x'}
[re-sending this to both the list and to Chris, as a prior send to the
list only was bounced back]
On 31/01/2023 22:33, Chris Angelico wrote:
Does that mean that it is not possible to have a (built-in) functionThanks for clarifying.I don't think so, but there might be some value in a dictionary
Hm. So 'x' is neither in locals() nor in globals(). Which starts me
wondering (to go off on a tangent): Should there be a nonlocals()
dictionary?
containing all available variables. It would have the same "don't
depend on writing" caveats that locals() has (or would be specifically defined as a copy and thus disconnected), so its value would be
limited. And it would probably STILL be imperfect, because perfection
would require that it be a compiler construct, due to the way that nonlocals are implemented.
that would construct and return a dictionary of all available variables
and their values? If it were possible, it could be useful, and there
would be no impact on Python run-time speed if it were only constructed
on demand.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (3 / 13) |
Uptime: | 05:50:39 |
Calls: | 10,388 |
Calls today: | 3 |
Files: | 14,061 |
Messages: | 6,416,801 |