[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