
One of the features I miss from languages such as C# is namespaces that work across files - it makes it a lot easier to organize code IMO. Here's an idea I had - it might not be the best idea, just throwing this out there: a "within" keyword that lets you execute code inside a namespace. For example: # A.py import types cool_namespace = types.SimpleNamespace() within cool_namespace: def foo(): print("foo run") #B.py import A within A.cool_namespace: foo() # prints "foo run" Thoughts?

On 08/06/18 19:41, David Teresi wrote:
New keywords have a fairly high barrier to get over. Do you have a convincing use case? I don't personally consider this particularly convincing, not when it's pretty much equivalent to:
To be honest I wouldn't even bother doing that, I'd just type A.cool_namespace.foo() when I wanted it. Explicit is better than implicit, after all. -- Rhodri James *-* Kynesim Ltd

You can use ``eval`` to run an expression, swapping in a different globals and/or locals namespace. Will this serve your purpose? In [1]: import types In [2]: ns = types.SimpleNamespace(a=1) In [3]: eval('a', ns.__dict__) Out[3]: 1 https://docs.python.org/3/library/functions.html#eval On Fri, Jun 8, 2018 at 11:43 AM David Teresi <dkteresi@gmail.com> wrote:

On Fri, Jun 08, 2018 at 03:07:28PM -0700, Michael Selik wrote:
The public API for getting an object namespace is vars(ns). But why would we write eval('a', vars(ns)) instead of getattr(ns, 'a') or even better just ns.a? Is your Python code too fast and you need to slow it down? *wink* eval and exec are useful when the code you want to run needs to be constructed at runtime. Its not generally useful when you know what you want ahead of time as in your example above. -- Steve

Classes Provide already some features of a namespace : class cool_namespace: A = 8 @staticmethod def f(): return "yo" @staticmethod def g(): return (1 + cool_namespace.A) * cool_namespace.f() And if you're tired of writing @staticmethod, you can write a class decorator "namespace" : @namespace class cool_namespace: A = 8 def f(): return "yo" def g(): return (1 + cool_namespace.A) * cool_namespace.f() And I think this decorator already exists somewhere. Le sam. 9 juin 2018 à 10:21, Steven D'Aprano <steve@pearwood.info> a écrit :

Why not... cool_namespace = SomeNamespaceContextManager() with cool_namespace: def foo(): pass advantage being it introduces no new keyword. The 'disadvantage' is it would change semantics of the with statement (as would be required to get the names defined in the suite of the context manager)

On 9 June 2018 at 14:46, Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
It's doable without code generation hacks by using class statements instead of with statements. The withdrawn PEP 422 shows how to use a custom metaclass to support a "namespace" keyword argument in the class header that redirects all writes in the body to the given dict: https://www.python.org/dev/peps/pep-0422/#new-ways-of-using-classes https://www.python.org/dev/peps/pep-0422/#extending-a-class even shows how to further use that to extend existing classes with new attributes. We're not likely to actively encourage that approach though - while they do enable some handy things, they also encourage hard to navigate programs with a lot of "action at a distance" side effects that make it tricky to reason locally about the code you're currently looking at (if anything, we've been pushing more in the other direction: encouraging the use of features like checked type hints to better *enable* reasoning locally about a piece of code). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I'd use a class or simple import a 5-line module if I wanted a namespace like that. Seems like clearner solutions to me. If you feel that your module namespace has to much content for a simple namespace, putting it in a seperate module should be the way to go anyway.

David Teresi wrote:
One of the features I miss from languages such as C# is namespaces that work across files - it makes it a lot easier to organize code IMO.
Maybe for the writer, but not for the reader. I like the fact that in Python I can usually tell which file a given class or function is implemented in by looking at the import statements. -- Greg

On Fri, Jun 08, 2018 at 02:41:54PM -0400, David Teresi wrote:
One of the features I miss from languages such as C# is namespaces that work across files - it makes it a lot easier to organize code IMO.
I too have often wanted a sub-module namespace without the need to separate code into seperate files. Something like a package, but existing inside a single physical file. In pseudo-code: a = 1 def spam(): return a namespace A: # conceptually, this is like a module within a module a = 100 def spam(): return a # later spam() + A.spam() => returns 101 If that looks similar to the class statement, except there's no need to create an instance, that's deliberate.
This sort of thing is similar to a old FAQ: https://docs.python.org/3/faq/design.html#why-doesn-t-python-have-a-with-sta... so it isn't unambiguously clear what foo would mean: is it the current namespace foo, the surrounding namespace, or the module namespace? Its not necessarily undoable: currently Python has what the "Learning Python" book calls the LEGB scoping rule: L - local E - enclosing function(s) or class G - global (module) B - builtins It could be conceivable to add a rule to slot a namespace in there somewhere, but the scoping rules already are fairly hairy (e.g. classes and functions work a little differently, we have a sub-local scope for comprehensions) and I'd be cautious about making them hairier with something like your "within"/"with" statement. The question I have is what is your motive for this? What problem does this solve for you? -- Steve

On 08/06/18 19:41, David Teresi wrote:
New keywords have a fairly high barrier to get over. Do you have a convincing use case? I don't personally consider this particularly convincing, not when it's pretty much equivalent to:
To be honest I wouldn't even bother doing that, I'd just type A.cool_namespace.foo() when I wanted it. Explicit is better than implicit, after all. -- Rhodri James *-* Kynesim Ltd

You can use ``eval`` to run an expression, swapping in a different globals and/or locals namespace. Will this serve your purpose? In [1]: import types In [2]: ns = types.SimpleNamespace(a=1) In [3]: eval('a', ns.__dict__) Out[3]: 1 https://docs.python.org/3/library/functions.html#eval On Fri, Jun 8, 2018 at 11:43 AM David Teresi <dkteresi@gmail.com> wrote:

On Fri, Jun 08, 2018 at 03:07:28PM -0700, Michael Selik wrote:
The public API for getting an object namespace is vars(ns). But why would we write eval('a', vars(ns)) instead of getattr(ns, 'a') or even better just ns.a? Is your Python code too fast and you need to slow it down? *wink* eval and exec are useful when the code you want to run needs to be constructed at runtime. Its not generally useful when you know what you want ahead of time as in your example above. -- Steve

Classes Provide already some features of a namespace : class cool_namespace: A = 8 @staticmethod def f(): return "yo" @staticmethod def g(): return (1 + cool_namespace.A) * cool_namespace.f() And if you're tired of writing @staticmethod, you can write a class decorator "namespace" : @namespace class cool_namespace: A = 8 def f(): return "yo" def g(): return (1 + cool_namespace.A) * cool_namespace.f() And I think this decorator already exists somewhere. Le sam. 9 juin 2018 à 10:21, Steven D'Aprano <steve@pearwood.info> a écrit :

Why not... cool_namespace = SomeNamespaceContextManager() with cool_namespace: def foo(): pass advantage being it introduces no new keyword. The 'disadvantage' is it would change semantics of the with statement (as would be required to get the names defined in the suite of the context manager)

On 9 June 2018 at 14:46, Jelle Zijlstra <jelle.zijlstra@gmail.com> wrote:
It's doable without code generation hacks by using class statements instead of with statements. The withdrawn PEP 422 shows how to use a custom metaclass to support a "namespace" keyword argument in the class header that redirects all writes in the body to the given dict: https://www.python.org/dev/peps/pep-0422/#new-ways-of-using-classes https://www.python.org/dev/peps/pep-0422/#extending-a-class even shows how to further use that to extend existing classes with new attributes. We're not likely to actively encourage that approach though - while they do enable some handy things, they also encourage hard to navigate programs with a lot of "action at a distance" side effects that make it tricky to reason locally about the code you're currently looking at (if anything, we've been pushing more in the other direction: encouraging the use of features like checked type hints to better *enable* reasoning locally about a piece of code). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

I'd use a class or simple import a 5-line module if I wanted a namespace like that. Seems like clearner solutions to me. If you feel that your module namespace has to much content for a simple namespace, putting it in a seperate module should be the way to go anyway.

David Teresi wrote:
One of the features I miss from languages such as C# is namespaces that work across files - it makes it a lot easier to organize code IMO.
Maybe for the writer, but not for the reader. I like the fact that in Python I can usually tell which file a given class or function is implemented in by looking at the import statements. -- Greg

On Fri, Jun 08, 2018 at 02:41:54PM -0400, David Teresi wrote:
One of the features I miss from languages such as C# is namespaces that work across files - it makes it a lot easier to organize code IMO.
I too have often wanted a sub-module namespace without the need to separate code into seperate files. Something like a package, but existing inside a single physical file. In pseudo-code: a = 1 def spam(): return a namespace A: # conceptually, this is like a module within a module a = 100 def spam(): return a # later spam() + A.spam() => returns 101 If that looks similar to the class statement, except there's no need to create an instance, that's deliberate.
This sort of thing is similar to a old FAQ: https://docs.python.org/3/faq/design.html#why-doesn-t-python-have-a-with-sta... so it isn't unambiguously clear what foo would mean: is it the current namespace foo, the surrounding namespace, or the module namespace? Its not necessarily undoable: currently Python has what the "Learning Python" book calls the LEGB scoping rule: L - local E - enclosing function(s) or class G - global (module) B - builtins It could be conceivable to add a rule to slot a namespace in there somewhere, but the scoping rules already are fairly hairy (e.g. classes and functions work a little differently, we have a sub-local scope for comprehensions) and I'd be cautious about making them hairier with something like your "within"/"with" statement. The question I have is what is your motive for this? What problem does this solve for you? -- Steve
participants (11)
-
Alex Walters
-
David Teresi
-
Greg Ewing
-
Jacco van Dorp
-
Jelle Zijlstra
-
Michael Selik
-
Nick Coghlan
-
Rhodri James
-
Robert Vanden Eynde
-
Steven D'Aprano
-
Terry Reedy