I have my pseudo Interface, which I implement several times. Each implementation is supposed to store a variable that basically defines a path to a file (a template). Because these classes are produced by a factory, I don't know which subclass is going to come up, therefore, I want to make it possible to access a class variable via an instance method.
This does not really pose a problem, however, when I inherit from my Interface, I don't want to implement the getHidden()
method (in the following) several times. But calling it, the way it is written down there, will always yield hidden.
class MySuperInterface(object):
# class Variable
__much = "hidden"
# instance method
def getHidden(self):
print self.__class__.__much
class MySub(MySuperInterface):
__much = "this is different per subclass!"
def soTroublesome(self):
print self.__class__.__much
Execution
>>> sub = MySub() # I don't know this class!
>>> sub.getHidden()
hidden
>>> sub.soTroublesome()
this is different per subclass!
So, how can I implement getHidden()
to access the instance's class' classvariable. I know, that the information is available, as I checked with dir()
, but I have no idea how to access it.
Again, I don't want to end up with a class/static method, because I don't know the class that gets out of my factory!
Thanks!
Just don't use the "__" in the class variable name and you are set.
Some Python write ups and "documentation" say that the "__" prefix is the Python way to get "private" members in a class. They are wrong.
The "__" prefix does exactly what is happening to you: ensure that the variable accessed in a method inside a class access the variable defined in that exact class (and not any of the classes that inherit from it).
The way it works is simple: at compile time, the names prefixed with "__" are "mangled", i.e. changed like this: __much
-> _classname__much
:
>>> class Hidden(object):
... __hidden = False
...
>>> dir(Hidden)
['_Hidden__hidden', '__class__', ...]
Therefore your getHidden
method will always look for the __much
variable thathas had its name actually changed to _MySuperInterface__much
, while the variable you want has had its name changed to _MySub__much
.
If you as much as use a single underscore "_" to mean by convention the variable should not be used outside of the class, your code would work as you expect.