Private functions and inheritance
Hello, I've come across something that I don't quite understand about Python's inheritance. Consider the following code snippet: class A(object): def call_bar(self): return self.bar() def call___bar(self): return self.__bar() def __bar(self): return A::__bar() def bar(self): return A::bar() class B(A): def __bar(self): return B::__bar() def bar(self): return B::bar() b = B() print calling B::call_bar():, b.call_bar() print calling B::call___bar():, b.call___bar() The result is: calling B::call_bar(): B::bar() calling B::call___bar(): A::__bar() In the latter case, it calls the base class' implementation. It probably goes along with Python's spec, but I found it surprising. I don't want to expose the __bar() function outside, but on the other hand i want to defer its implementation to a subclass. It seems like I need to make it public, doesn't it? -- http://mail.python.org/mailman/listinfo/python-list
Re: Private functions and inheritance
Maciej Blizi?ski wrote: calling B::call_bar(): B::bar() calling B::call___bar(): A::__bar() (BTW, there is no :: operator in Python. It should be, e. g., B.bar().) In the latter case, it calls the base class' implementation. It probably goes along with Python's spec, but I found it surprising. __-prepended names are dynamically mangled to include the class name. Hence, B.__bar doesn't overwrite A.__bar in B. I don't want to expose the __bar() function outside, In principle, you do. Always. Public or Private is just convention in Python. Even __-prepended names can be accessed from outside. Couldn't find it in the docs though. Quite inconcise. Regards, Björn -- BOFH excuse #120: we just switched to FDDI. -- http://mail.python.org/mailman/listinfo/python-list
Re: Private functions and inheritance
Maciej Bliziński wrote: Hello, I've come across something that I don't quite understand about Python's inheritance. Consider the following code snippet: class A(object): def call_bar(self): return self.bar() def call___bar(self): return self.__bar() def __bar(self): return A::__bar() def bar(self): return A::bar() class B(A): def __bar(self): return B::__bar() def bar(self): return B::bar() b = B() print calling B::call_bar():, b.call_bar() print calling B::call___bar():, b.call___bar() The result is: calling B::call_bar(): B::bar() calling B::call___bar(): A::__bar() In the latter case, it calls the base class' implementation. It probably goes along with Python's spec, but I found it surprising. I don't want to expose the __bar() function outside, but on the other hand i want to defer its implementation to a subclass. It seems like I need to make it public, doesn't it? Yep. Just use a single underscore, and that's it. The reason why this doesn't work as expected is that the name-mangling introduced by the leading double underscores is purely a lexical scope based mechanism. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Private functions and inheritance
On 2007-07-16, Maciej Blizi?ski [EMAIL PROTECTED] wrote: Hello, I've come across something that I don't quite understand about Python's inheritance. Consider the following code snippet: class A(object): def call_bar(self): return self.bar() def call___bar(self): return self.__bar() def __bar(self): return A::__bar() def bar(self): return A::bar() class B(A): def __bar(self): return B::__bar() def bar(self): return B::bar() b = B() print calling B::call_bar():, b.call_bar() print calling B::call___bar():, b.call___bar() The result is: calling B::call_bar(): B::bar() calling B::call___bar(): A::__bar() the __* naming convention for class private attributes is intended to help ensure that attribute names of derived classes cannot conflict with private attribute names in any base classes. I.e., you should not use that naming convention when you *intend* to override it in a derived class. If you do use the __* naming convention, use it only for attributes that should not be overrided or accessed by derived classes. the weasel words from the documentation (which I put in quotes) are there because the feature doesn't work (in all cases). -- Neil Cerutti The doctors X-rayed my head and found nothing. --Dizzy Dean -- http://mail.python.org/mailman/listinfo/python-list
Re: Private functions and inheritance
Maciej Bliziński a écrit : (snip the rest - already answered by at least 3 persons). I don't want to expose the __bar() function outside, but on the other hand i want to defer its implementation to a subclass. It seems like I need to make it public, doesn't it? First, keep in mind that that Python *does not* have any notion of (languaged enforced) access restriction. All that the __name thingie does is to mangle the name with the class name, so A.bar become A._A__bar. This can be useful. Sometimes. Perhaps. (FWIW, I think I've used it once in seven years and I'm not sure it was really necessary after all). Now there's a strong convention which says that _names prefixed by a single underscore are implementation stuff, and that anyone messing with implementation stuff implicitely accepts all the possible consequences. -- http://mail.python.org/mailman/listinfo/python-list