Evaluation of variable as f-string
Chris Angelico
rosuav at gmail.com
Tue Jan 31 17:33:45 EST 2023
On Wed, 1 Feb 2023 at 09:14, Rob Cliffe via Python-list
<python-list at python.org> wrote:
> 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.
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".
> 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?
I don't think so, but there might be some value in a 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.
>>> class Destructible:
... def __init__(self, name): self.name = name
... def __del__(self): print("Deleting", self.name)
...
>>> def func():
... x = Destructible("x")
... y = Destructible("y")
... return lambda: x
...
>>> func()
Deleting y
<function func.<locals>.<lambda> at 0x7ff8c9897ce0>
The compiler is free to dispose of y as soon as func ends, but x has
to be retained for the inner function. So if there were any function
that could return every readable variable, it would have to force both
x and y to be retained; as such, it would have to be a compiler
construct. And given what happened with star imports in functions as
of Python 3, I am highly dubious that such a pessimisation would ever
be implemented.
> > 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:
> >
> >>>> def func():
> > ... x = 1
> > ... print(f"{(x:=2)}")
> > ... print(x)
> > ...
> >>>> func()
> > 2
> > 2
> > ... x = 1
> > ... print(eval("(x:=2)", globals(), locals()))
> > ... print(x)
> > ...
> >>>> func()
> > 2
> > 1
> Now that, I have to admit, IS a challenge!
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.
ChrisA
More information about the Python-list
mailing list