Issue 27793: Double underscore variables in module are mangled when used in class (original) (raw)

Created on 2016-08-18 12:27 by avraf, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (6)
msg273023 - (view) Author: (avraf) Date: 2016-08-18 12:27
import re __no_spaces_pattern = r'\S+' __match_chars_until_space = re.compile(__no_spaces_pattern).match __match_chars_from_last_space = re.compile(__no_spaces_pattern + '$').match def __get_chars_until_space(name): return __match_chars_until_space(name).group() def __get_chars_from_last_space(name): return __match_chars_from_last_space(name).group() __random_unique_five_digit_number = 12345 __random_id_generator = lambda: __random_unique_five_digit_number class Person(object): def __init__(self, name): self.name = name @property def first_name(self): return __get_chars_until_space(self.name) @property def last_name(self): return __get_chars_from_last_space(self.name) I get this error when importing and running in another file. It seems python mangles every occurrence of double underscores seen in a class. Even if the double underscores variable appears in the body of a method and belongs to the module. This behavior is very unexpected. Traceback (most recent call last): File "beef.py", line 5, in print bob.first_name File "/home/dude/style/static_private_methods/real_static_private_functions.py", line 22, in first_name return __get_chars_until_space(self.name) NameError: global name '_Person__get_chars_until_space' is not defined
msg273032 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-08-18 14:36
This is working as designed (https://docs.python.org/3/tutorial/classes.html#private-variables): "This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class." If you want to advocate changing that you'll have to start a thread on python-ideas, but I don't think the benefit would be worth the cost.
msg363393 - (view) Author: Jan Christoph (con-f-use) * Date: 2020-03-04 22:12
I would argue to reopen this. Seeing I and other people run into that issue (e.g. https://stackoverflow.com/q/40883083/789308) quiet frequently. Especially since it breaks the `global` keyword, e.g.: __superprivate = "mahog" class AClass(object): def __init__(self, value): global __superprivate __superprivate = value @staticmethod def get_sp(): return __superprivate if __name__ == "__main__": print(__superprivate) # mahog try: print(AClass.get_sp()) except NameError as e: print(e) # NameError: name '_AClass__superprivate' is not defined' cl = AClass("bla") print(cl.get_sp()) # bla __superprivate = 1 print(cl.get_sp()) # bla print(AClass.get_sp()) # bla
msg363395 - (view) Author: Jan Christoph (con-f-use) * Date: 2020-03-04 22:16
Just because it is documented, doesn't mean it's not a bug or illogical and unexpected.
msg363553 - (view) Author: Jan Christoph (con-f-use) * Date: 2020-03-06 21:10
In particular, this might conflict with the documentation of global, which states: > If the target is an identifier (name): > > If the name does not occur in a global statement in the current code block: the name is bound to the object in the current local namespace. > > Otherwise: the name is bound to the object in the current global namespace. There is no exception of names that are within the body of a class object and start (but not end) with double underscores.
msg363559 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2020-03-06 21:40
You are welcome to open a doc-enhancement issue for the global docs. For the other, as noted already if you want to advocate for a change to this behavior you need to start on python-ideas, but I don't think you will get any traction. Another possible enhancement you could propose (in a new issue) is to have the global statement check for variables that start with '__' and do something appropriate such as issue a warning...although I don't really know how hard that would be to implement.
History
Date User Action Args
2022-04-11 14:58:35 admin set github: 71980
2020-03-06 21:40:27 r.david.murray set messages: +
2020-03-06 21:10:21 con-f-use set messages: +
2020-03-04 22:16:00 con-f-use set messages: +
2020-03-04 22:12:57 con-f-use set nosy: + con-f-usemessages: +
2016-08-18 14:36:25 r.david.murray set status: open -> closednosy: + r.david.murraymessages: + resolution: not a bugstage: resolved
2016-08-18 12:27:25 avraf create