class and private variables

后端 未结 3 1810
被撕碎了的回忆
被撕碎了的回忆 2021-01-27 04:03
class Test1:
    def __init__( self ):
        self.__test = 1
    def getvalue( self ):
        return self.__test

class Test2( Test1 ):
    def __init__( self ):
        T         


        
相关标签:
3条回答
  • 2021-01-27 04:22

    This behaviour is due to the name mangling for attribute names starting with __. Basically, __test gets mangled to _Test1__test inside Test1 and to _Test2__test inside Test2, so they are two different attributes.

    0 讨论(0)
  • 2021-01-27 04:24

    In Python, private member __bar of class Foo will be automatically renamed to _Foo__bar, so the __test in Test1 is _Test1__test and that in Test2 is _Test2__test. The two members are actually different. This is by design, to "avoid name clashes of names with names defined by subclasses".

    Use a single underscore _test if you want the subclass to see the variable while still want to keep it not part of the public interface.

    0 讨论(0)
  • 2021-01-27 04:34

    It works exactly the same way in other languages, such as Java (try it!)

    class Test1 {
        private int test = 1;
        public int getValue() {
            return test;
        }
    }
    
    class Test2 extends Test1 {
        private int test = 2;
    }
    
    public class Test { // Run the test
        public static void main(String[] args) {
            Test2 t = new Test2();
            System.out.println(t.getValue());
        }
    }
    

    (Why am I posting Java code in a Python-related question? Because some comments say that “this wouldn't work in any OO language” and “this is why you don't use name mangling for private variables” — Java takes another approach to OO compared to Python, and doesn't use name-mangling for private variables, yet the behavior is the same)

    A method declared in Test1 has access to Test1's private variables. Whether the method is called from a child class won't change anything, unless the child class overrides the method. It's not that private members “disappear” or are “overridden” in child classes. They are still there, and can be accessed by methods of the parent class.

    Only when Test2 declares its own implementation for getvalue(), then Test1's private members would become inaccessible and Test2's private members would become accessible.

    In other words, one could say that private members are not “virtual” (or “overridable”). They are the implementation details of the class and its methods, and are not supposed to be overridden. Test1.__test and Test2.__test are different instance variables (implemented in Python by name-mangling).

    If you want the traditional OO behaviour, where a child class member overrides its parent, use a method in Python, Java, or a virtual method in C++, C#, Delphi; not private attributes. If you want to implement something without name clashes, then use private attributes.

    0 讨论(0)
提交回复
热议问题