ubershmekel
ubershmekel

Reputation: 12798

Python private class variables that aren't class variables

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

Upvotes: 1

Views: 605

Answers (2)

Sam-zhuang
Sam-zhuang

Reputation: 24

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)

Upvotes: 0

senderle
senderle

Reputation: 150947

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.

Upvotes: 2

Related Questions