Help with changes in traceback stack from Python 2.7 to Python 3.x
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Apr 27 22:11:30 EDT 2014
On Sun, 27 Apr 2014 21:51:54 +0000, Andrew Konstantaras wrote:
> I guess I am missing something big as I am looking for a shorthand way
> of doing the following:
>
> dctA = dict(x=x, y=y, ... n=n)
>
> This is, as I understand it a very natural way of using a dictionary.
Would you prefer this?
dctA = {'x': x, 'y': y, 'n': n}
> It seems that this syntax is unnecessarily redundant
[...]
> I will give the locals approach a try, it seems a little more clumsy
> than simply passing the variables to the function.
If you think that, it's because you haven't really thought it through
completely. Possibly you don't quite understand Python's execution model
fully, or you're used to languages which have a different execution
model, or worst of all, you're used to a language which blesses dirty
runtime hacks as "features".
Suppose we could pass variables directly to the constructor, like this:
a = b = 2
L = [1, 2, 3]
dctA = dict(a, b, L[1], 2, 1+1)
Obviously all five values are 2, but what are the keys?
A language with a static compiler and pass-by-name behaviour, like Algol,
might be able to tell that the first argument comes from a variable
called 'a' and the second from a variable called 'b'. But languages with
pass-by-value behaviour, like C, cannot.
Likewise, Python cannot tell the name of the object. The dict construct
receives five arguments, all bound to the object 2. (That might be the
same object five times, or five distinct objects, all with the same value
of 2.) The objects don't know what names they are bound to: they might be
bound to zero, one, or more names. If they're bound to zero names, what
name should the dict constructor invent for them? If they're bound to two
or more names, which name should the dict constructor use?
So as you can see, in general the dict constructor *cannot* infer a
unique name for the argument. In some cases it may be able to guess, or
arbitrarily pick one out of many, using implementation hacks that are not
standard across all versions and implementations of Python. A hack that
works in CPython probably won't work in Jython, and one that works in
IronPython probably won't work in PyPy.
Objects don't have a unique name, so the very concept of getting "the
name" of a value is dubious, and has to rely on a dirty hack.
Nevertheless, as you have discovered, you can do so in CPython.
Presumably there is a different hack that would work in IronPython,
Jython, Cython, PyPy, Nuitka, Unladen Swallow, ... so perhaps it could be
declared that, dirty hack or not, it should be part of the language.
Should it?
Consider the unlimited number of variations on:
dict(key=value)
dict(name=value)
dict(age=value)
dict(a=value)
dict(b=value)
dict(arg=value)
dict(param=value)
dict(foo=value)
dict(bar=value)
[...]
dict(value=value)
Why is that last case so special that the dict constructor should guess
that when you type "dict(value)" it wasn't a mistake, but that you
actually intended "dict(value=value)" rather than key=value or name=value?
You should consider the Zen of Python for a glimpse into the design
principles that the creators of Python tend to follow as a rule:
http://legacy.python.org/dev/peps/pep-0020/
See how many of the design principles are violated by a feature that
guesses the key name if not supplied.
Other languages may make other choices. I think that makes them worse
languages.
--
Steven D'Aprano
http://import-that.dreamwidth.org/
More information about the Python-list
mailing list