Search code examples
python-3.xinheritancemethodsattributesparent

python 3 Call child attribute from parent method


Can't call child attribute in parent method, here's the test:

#!/usr/bin/env python3

class A():
    def getPath(self):
        return self.__path

class B(A):

    def __init__( self, name, path):
        self.__name = name
        self.__path = path

instance = B('test', '/home/test/Projects')

print(instance.getPath())

Running python test file $ ./test.py returns

./test.py 
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print(instance.getPath())
  File "./test.py", line 6, in getPath
    return self.__path
AttributeError: 'B' object has no attribute '_A__path'

Solution

  • You are getting this because you are using a private attribute. If you do it using a non-private attributes, it will succeed.

    Private attributes in Python are designed to allow each class to have its own private copy of a variable without that variable being overridden by subclasses. So in B, __path means _B__path, and in A, __path means __A_path. This is exactly how Python is intended to work. https://docs.python.org/3/tutorial/classes.html#tut-private

    Since want A to be able to access __path, you should not use double-underscores. Instead, you can use a single underscore, which is a convention to indicate that a variable is private, without actually enforcing it.

    #!/usr/bin/env python3
    
    class A():
        def getPath(self):
            return self._path
    
    class B(A):
    
        def __init__( self, name, path):
            self.__name = name
            self._path = path
    
    instance = B('test', '/home/test/Projects')
    
    print(instance.getPath())
    
    $ ./test.py
    /home/test/Projects