[Python-ideas] Namespace creation with syntax short form
Andrew Barnert
abarnert at yahoo.com
Fri Feb 13 13:40:42 CET 2015
On Feb 13, 2015, at 4:05, Peter Otten <__peter__ at web.de> wrote:
> Steven D'Aprano wrote:
>
>> On Fri, Feb 13, 2015 at 11:19:58AM +0100, Morten Z wrote:
>>> Namespaces are widely used in Python, but it appear that creating a
>>> namespace
>>> has no short form, like [] for list or {} for dict, but requires the
>>> lengthy types.SimpleNamespace, with prior import of types.
>>
>> from types import SimpleNamespace as NS
>> ns = NS(answer=42)
>>
>> Python did without a SimpleNamespace type for 20+ years. I don't think
>> it is important enough to deserve dedicated syntax, especially yet
>> another overloading of parentheses. Not everything needs to be syntax.
>
> If there were syntactic support for on-the-fly namespace "packing" and
> "unpacking" that could have a significant impact on coding style, similar to
> that of named arguments.
>
> Functions often start out returning a tuple and are later modified to return
> a NamedTuple. For backward compatibility reasons you are either stuck with
> the original data or you need a workaround like os.stat_result which has
> more attributes than items.
There's really nothing terrible about that workaround, except that it's significantly harder to implement in Python (with namedtuple) than in C (with structseq).
More importantly, I don't see how named unpacking helps that. If your function originally returns a 3-tuple, and people write code that expects a 3-tuple, how do you change it to return a 3-tuple that's also a 4-namespace under your proposal?
Meanwhile:
> "Named (un)packing" could avoid that.
>
>>>> def f():
> ... return a:1, b:2, c:3
>>>> f()
> (a:1, b:2, c:3)
So what type is that? Is there a single type for all "named packing tuples" (like SimpleNamespace), or a separate type for each one (like namedtuple), or some kind of magic that makes issubclass(a, b) true if b has the same names as a plus optionally more names at the end, or ...?
How does this interact with existing unpacking? Can I extract the values as a tuple, e.g., "x, *y = f()" to get x=1 and y=(2, 3)? Or the key-value pairs with "**kw = f()"? Or maybe ::kw to get them as a namespace instead of a dict? Can I mix them, with "x, *y, z:c" to get 1, (2,), and 3 (and likewise with **kw or ::ns)?
Does this only work with magic namespaces, or with anything with attributes? For example, if I have a Point class, "does x:x = pt" do the same thing as "x = pt.x", or does that only work if I don't use a Point class and instead pass around (x:3, y:4) with no type information?
Since the parens are clearly optional, does that mean that "a:3" is a single-named namespace object, or do you need the comma as with tuples? (I think the former may make parsing ambiguous, but I haven't thought it through...)
>>>> :c, :b, :a = f() # order doesn't matter
>>>> :a, :c = f() # we don't care about b
>>>> a # by default bound name matches attribute name
Why do you need, or want, that last comment? With similar features, you have to be explicit; e.g., if you want to pass a local variable named a to a keyword parameter named a, you have to write a=a, not just =a. How is this case different?
> 1
>>>> x:a, y:c = f() # we want a different name
>>>> x, y
> (1, 3)
More information about the Python-ideas
mailing list