0

Please advise the cause of the symptom and what Python resources to look at to understand further.

With Python 3.8.8 when including __ in a variable name, it causes the error.

Python 3.8.8 (default, Feb 24 2021, 21:46:12) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> __HOGE = 1
>>> class hoge:
...     def __init__(
...             self,
...             name: str,
...             num_nodes: int,
...             momentum = 0.9,
...     ):
...         self.args = set(locals().keys())
...         global __HOGE
...         print(__HOGE)
... 
>>> a = hoge(name="name", num_nodes=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in __init__
NameError: name '_hoge__HOGE' is not defined

Which does not happen with single underscore _.

>>> _HOGE = 1
>>> class hoge:
...     def __init__(
...             self,
...             name: str,
...             num_nodes: int,
...             momentum = 0.9,
...     ):
...         self.args = set(locals().keys())
...         global _HOGE
...         print(_HOGE)
... 
>>> a = hoge(name="name", num_nodes=1)
1

PEP 8 Global Variable Names does not mention any restriction.

Modules that are designed for use via from M import * should use the all mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are "module non-public").

Programming FAQ neither.

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

mon
  • 18,789
  • 22
  • 112
  • 205
  • In a class, dunder names are used to create private attributes, so they're automatically prefixed with the class name. – Barmar Mar 28 '21 at 07:09
  • 1
    Double-underscored names get mangled in a class, it is a feature to use when you want to prevent name-collisions in subclasses. Why not just use a single underscore? – juanpa.arrivillaga Mar 28 '21 at 09:19
  • @juanpa.arrivillaga, will do. Did not know __ is converted. – mon Mar 28 '21 at 09:29
  • 1
    As an aside, `global __HOGE` doesn't do anything and isn't required here because you never try to assign to the global `__HOGE` – juanpa.arrivillaga Mar 28 '21 at 09:30

0 Answers0