1

When trying to access __variables from a class, the parser assumes the 2 underscores are private relative to the current class. Notice how an unrelated function gets a "private" variable.

Is this a bug?

>>> def f(): pass
...
>>> class A:
...     def g(self):
...             f.__x = 1
...             def h():
...                     pass
...             h.__y = 2
...             return h
...
>>> z = A().g()
>>> dir(z)
['_A__y', '__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get_
_', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new
__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_
closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
 'func_name']
>>> dir(f)
['_A__x', '__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get_
_', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new
__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_
closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
 'func_name']

Tested on python 2.5 and 3.2

1
  • Working as expected. Granted, what you're doing with them is unusual, but those attributes belong to the class, wherever they happen to be. Commented Aug 6, 2011 at 13:30

2 Answers 2

2

This is a well documented behavior.

This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

Sign up to request clarification or add additional context in comments.

3 Comments

Thing is, if you define f.__x from anywhere outside of a class definition it works fine. So "f" doesn't have any privacy (as some other already deleted answers called it), it's just that from within a class you can't access these kind of variables (ignoring getattr/setattr).
Sorry, access what kind of variables? Variables starting with __? I would say that it is a mistake to assign a value to f.__x outside of a class definition. A single underscore is sufficient to mark a variable as "private"; the purpose of name mangling is not really privacy but collision avoidance in the context of class inheritance.
According to these facts, yes, I agree that it's a mistake to use double underscores outside of classes. It's just a surprising conclusion to me.
0

Here’s a way to declare private variables: overload the __setattr__ (and other many methods about attributes) method, in the method, you can check current executing method is in the own class. If it is true, let it pass. Otherwise, you can raise an exception, or you can use your own customize error handle logic. (Tips: use inspect.stack function)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.