[chirp_devel] Naming convention for class fields?
I'm looking over the yaesu_clone superclass with FT1D subclass as a suggested example. I'm confused by the conflicting naming conventions. In yaesu_clone.py line 231 the superclass begins with these class fields:
VENDOR="Yaesu" NEEDS_COMPAT_SERIAL=False _model =b"ABCDE"
Why are the first two all caps, but the third is lowercase with a leading underscore? Is this documented somewhere that I missed?
Normally, a leading underscore means the variable is local to the current scope and shouldn't be accessed outside of it. But in this case, VENDOR and _model are both overridden in the subclass. I didn't think that a subclass still counts as local. Also, normally all caps means it's a constant. Yet, again, the VENDOR gets overridden. So, to my mind all of these variables should be lowercase with no leading underscore. Just "vendor", just "model". (Or, leading underscores with corresponding @property accessors.)
(signed) Confused in Las Vegas 😮
I'm looking over the yaesu_clone superclass with FT1D subclass as a suggested example. I'm confused by the conflicting naming conventions. In yaesu_clone.py line 231 the superclass begins with these class fields: VENDOR = "Yaesu" NEEDS_COMPAT_SERIAL = False _model = b"ABCDE" Why are the first two all caps, but the third is lowercase with a leading underscore? Is this documented somewhere that I missed?
There's no hard and fast rule, but the ones in caps are generally those that are defined in the top-level Radio class or the common base subclasses in chirp_common. The convention is that model or driver-specific things are prefixed by underscore and in lower case. In the above case, _model is used by that driver internally (i.e. things in the driver file or related modules) for file detection and the cloning routines.
Normally, a leading underscore means the variable is local to the current scope and shouldn't be accessed outside of it. But in this case, VENDOR and _model are both overridden in the subclass. I didn't think that a subclass still counts as local. Also, normally all caps means it's a constant. Yet, again, the VENDOR gets overridden. So, to my mind all of these variables should be lowercase with no leading underscore. Just "vendor", just "model". (Or, leading underscores with corresponding @property accessors.)
The ones in caps (that are inherited from the common base classes) are part of the interface that the rest of the application needs to be correct - you don't get to rename them.
--Dan
FYI: I stand corrected. I reread PEP8. One leading underscore is meant to say protected, not private. Thus, it is part of the subclass API. It's double leading underscores that means completely private.
On 5/15/2023 4:58 PM, Dan Smith via chirp_devel wrote:
I'm looking over the yaesu_clone superclass with FT1D subclass as a suggested example. I'm confused by the conflicting naming conventions. In yaesu_clone.py line 231 the superclass begins with these class fields: VENDOR = "Yaesu" NEEDS_COMPAT_SERIAL = False _model = b"ABCDE" Why are the first two all caps, but the third is lowercase with a leading underscore? Is this documented somewhere that I missed?
There's no hard and fast rule, but the ones in caps are generally those that are defined in the top-level Radio class or the common base subclasses in chirp_common. The convention is that model or driver-specific things are prefixed by underscore and in lower case. In the above case, _model is used by that driver internally (i.e. things in the driver file or related modules) for file detection and the cloning routines.
Normally, a leading underscore means the variable is local to the current scope and shouldn't be accessed outside of it. But in this case, VENDOR and _model are both overridden in the subclass. I didn't think that a subclass still counts as local. Also, normally all caps means it's a constant. Yet, again, the VENDOR gets overridden. So, to my mind all of these variables should be lowercase with no leading underscore. Just "vendor", just "model". (Or, leading underscores with corresponding @property accessors.)
The ones in caps (that are inherited from the common base classes) are part of the interface that the rest of the application needs to be correct - you don't get to rename them.
--Dan _______________________________________________ chirp_devel mailing list chirp_devel@intrepid.danplanet.com http://intrepid.danplanet.com/mailman/listinfo/chirp_devel Developer docs: http://chirp.danplanet.com/projects/chirp/wiki/Developers
On 16/5/23 10:32, Craig Jones via chirp_devel wrote:
FYI: I stand corrected. I reread PEP8. One leading underscore is meant to say protected, not private. Thus, it is part of the subclass API. It's double leading underscores that means completely private.
Double leading underscore normally refers to things that are special to Python. Things like `__len__` (implements `len()`), `__repr__`, etc which implement various operators.
Or deeply internal things like `__slots__` which is used to define what attributes a class instance has so it can be "set in stone" as a `struct` rather than using a `dict` implementation which consumes more memory.
In general:
- leading underscore → private/protected (not enforced) - UPPER_CASE_WITH_UNDERSCORES → constant
`_model` as a class attribute suggests the attribute might sometimes change to reference something else, but it is otherwise private/protected. `_MODEL` might be better if we know it won't change -- but the interpreter does not care; such designations are just for us meat bags to better understand what's going on.
(Going off on a tangent here. Just FYI, folks.)
Actually, __foo__ and __foo are two different things, according to PEP8. The former standard (with the trailing __; which is nicknamed "dunder") is indeed as you describe, and developers are not supposed to create their own dunders. The latter (with only leading __) invokes something called "mangling" where the name of the class is prefixed to the variable name as it's compiled. This effectively makes it a private field by disambiguating the variables within the same namespace. So, in this one case, the leading __ making it "private" isn't just a style convention, but actually enforced by Python (somewhat).
I honestly didn't remember this mangling stuff from when I read through PEP8, previously (2 years ago?), and I can't imagine actually using it (which undoubtedly why I forgot about it). Maybe it ought to be stricken from PEP8, just to reduce the complexity? Not enough bang for the buck on this one, IMHO.
On 5/15/2023 5:42 PM, Stuart Longland VK4MSL via chirp_devel wrote:
On 16/5/23 10:32, Craig Jones via chirp_devel wrote:
FYI: I stand corrected. I reread PEP8. One leading underscore is meant to say protected, not private. Thus, it is part of the subclass API. It's double leading underscores that means completely private.
Double leading underscore normally refers to things that are special to Python. Things like `__len__` (implements `len()`), `__repr__`, etc which implement various operators.
Or deeply internal things like `__slots__` which is used to define what attributes a class instance has so it can be "set in stone" as a `struct` rather than using a `dict` implementation which consumes more memory.
In general:
- leading underscore → private/protected (not enforced)
- UPPER_CASE_WITH_UNDERSCORES → constant
`_model` as a class attribute suggests the attribute might sometimes change to reference something else, but it is otherwise private/protected. `_MODEL` might be better if we know it won't change -- but the interpreter does not care; such designations are just for us meat bags to better understand what's going on.
participants (3)
-
Craig Jones
-
Dan Smith
-
Stuart Longland VK4MSL