-1

I have two classes. A vehicle class and a car class. My vehicle class does not have any attributes so I can call it without any arguments. Same for my car class. The car class is a sub class for vehicle class.

In my vehicle class I have a variable assigned a string with some text. How can my sub class car inheritance that variable?

Code:

class Vehicle(object):
    def __init__(self):
        self.__astring = 'Hello'

    def get_string(self):
        print self.__astring


class Car(Vehicle):
    def __init__(self):
        Vehicle.__init__(self)
        # Here I need to make a working variable
        self.__car_string = self.__astring
        self.__car_string2 = ' Again'
        self.__big_string = self.__car_string + self.__car_string2

    # This method should print 'Hello Agan'
    def get_car_string(self):
        print self.__big_string


string1 = Vehicle()
string1.get_string()    # This prints Hello

string2 = Car()
string2.get_car_string()    # This should print Hello Again

When I run the code, I get:

AttributeError: 'Car' object has no attribute '_Car__astring'

I do understand why, but I do not know how to inherit that variable with the string.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
nutgut
  • 1
  • 3
  • 3
    If you want the child class to be able to access the attribute, why is it named with `__double_leading_underscores`? The whole point of name mangling is to avoid conflicts, so you can have the same name in the child and parent. This is nothing to do with having `__init__` parameters or not. Also why don't you use `super`? – jonrsharpe Mar 26 '17 at 14:02
  • I thought making attributes hidden/private is a right way to code in Python. So this makes the attributes only reachable from the objects methods. So you say this is the problem? – nutgut Mar 26 '17 at 14:08
  • @nutgut Have a read through [this](http://stackoverflow.com/questions/7456807/python-name-mangling). – glibdud Mar 26 '17 at 14:09
  • 1
    Well: 1. no it isn't, we're all consenting adults here and nothing is ever really private/protected in Python; 2. if you *do* want to make it private by convention that's `_single_leading_underscore` not `__double`; and 3. yes, that's the problem. – jonrsharpe Mar 26 '17 at 14:09
  • Don't worry about public/protected/private when coding Python. See http://stackoverflow.com/q/17246867/7432 and http://stackoverflow.com/q/1641219/7432 – Bryan Oakley Mar 26 '17 at 14:11
  • Thanks @jonrsharpe, that solved my problem. – nutgut Mar 26 '17 at 14:31
  • Thanks @glibdud, now I know how to wrote code from now on :) – nutgut Mar 26 '17 at 14:31

1 Answers1

0

The correct way to mark an attribute as private (meaning it should not be used directly outside of a method of that class, not that it cannot), is to prefix it with a single underscore.

A getter method should return the value, not print it. If you need to print the value, you can always print the return value of get_string; you cannot (easily) access a value that is directly printed by a method.

class Vehicle(object):
    def __init__(self):
        self._astring = 'Hello'

    def get_a_string(self):
        return self._astring


class Car(Vehicle):
    def __init__(self):
        Vehicle.__init__(self)
        # Here I need to make a working variable
        self._car_string = self.get_a_string()
        self._car_string2 = ' Again'
        self._big_string = self._car_string + self._car_string2

    def get_car_string(self):
        print self._big_string

The language itself will not stop you from accessing Vehicle._astring directly outside of the Vehicle class, but it should be considered a bug to do so.

glibdud
  • 7,550
  • 4
  • 27
  • 37
chepner
  • 497,756
  • 71
  • 530
  • 681