between block and function [was: Custom Code Folding: Standardized Rules and Syntax?]

There have been times when I wanted to group portions of a module, class, or function. Giving names to each of those groupings would be useful, and would be appropriate for python-level changes. That said, it would probably need more proof in the wild first, so the first step would be getting support in an editor (such as PyCharm), and the second would be an informational PEP on how to standardize the practice, like PEP 257 does for docstrings. https://www.python.org/dev/peps/pep-0257/ For these steps, you would probably have to use a comment or string convention, such as #{{{ or ":(group X ", though I suppose an external file (similar to the stub files for typing) is also possible. If these take off enough that the line noise gets annoying, that will prove the need, and getting support from python itself will be a lot easier. Example code :group C class C1: :group emulateFoo ... :group manageBar def xx(self, bar, name, val=None): :group setupBar ... :group actualXX class C2: ... :group D

On Tue, Jul 18, 2017 at 09:13:11PM -0400, Jim J. Jewett wrote:
I don't know about grouping parts of a class or function, but I've certainly often wanted something in between the single file module and the multiple file package. As far as grouping parts of a class, we already have ways to do that: - parts of a class are called "methods" :-) - more usefully, you can use mixins (or traits) and multiple inheritence to separate related code into their own class - or forego inheritence at all and use composition. For functions, I think that if you need to group parts of a function, your function is probably too big. If not, you can use nested functions (although they're not as useful as they might be) or refactor. But your third suggestion would be useful to me. I'd really like to follow the Zen: Namespaces are one honking great idea -- let's do more of those! and have a namespace data structure that was functionally like a module but didn't need to be separated out into another file. A sketch of syntax: namespace Spam: # introduces a new block x = 1 def function(a): return a + x class K: ... assert Spam.x == 1 x = 99 assert Spam.function(100) == 101 # not 199 Name resolution inside Spam.function would go: locals -> nonlocals -> namespace -> module globals -> builtins I've played around with using a class statement (to get the indented block) and a decorator to create a namespace. The namespace itself is easy: I just subclass types.ModuleType, and inject names into that. The hard part is changing the functions to search their enclosing namespace first, before searching the module globals. If we had such a construct, then code folding would be given. If we used the existing "class" keyword, then any editor which can fold classes would automatically work. If we introduced a new keyword, then there would be a delay until editors gained support for that new keyword, but eventually the better editors would support code folding them. -- Steve

On Tue, Jul 18, 2017 at 09:13:11PM -0400, Jim J. Jewett wrote:
I don't know about grouping parts of a class or function, but I've certainly often wanted something in between the single file module and the multiple file package. As far as grouping parts of a class, we already have ways to do that: - parts of a class are called "methods" :-) - more usefully, you can use mixins (or traits) and multiple inheritence to separate related code into their own class - or forego inheritence at all and use composition. For functions, I think that if you need to group parts of a function, your function is probably too big. If not, you can use nested functions (although they're not as useful as they might be) or refactor. But your third suggestion would be useful to me. I'd really like to follow the Zen: Namespaces are one honking great idea -- let's do more of those! and have a namespace data structure that was functionally like a module but didn't need to be separated out into another file. A sketch of syntax: namespace Spam: # introduces a new block x = 1 def function(a): return a + x class K: ... assert Spam.x == 1 x = 99 assert Spam.function(100) == 101 # not 199 Name resolution inside Spam.function would go: locals -> nonlocals -> namespace -> module globals -> builtins I've played around with using a class statement (to get the indented block) and a decorator to create a namespace. The namespace itself is easy: I just subclass types.ModuleType, and inject names into that. The hard part is changing the functions to search their enclosing namespace first, before searching the module globals. If we had such a construct, then code folding would be given. If we used the existing "class" keyword, then any editor which can fold classes would automatically work. If we introduced a new keyword, then there would be a delay until editors gained support for that new keyword, but eventually the better editors would support code folding them. -- Steve
participants (2)
-
Jim J. Jewett
-
Steven D'Aprano