inheritance and private attributes

Discussion in 'Python' started by KN, Apr 21, 2004.

  1. KN

    KN Guest

    I've run into such problem:

    I have something like this:

    class A(object):
    def __init__(self):
    self.__value = None

    class B(A):
    def test(self):
    if self.__value:
    print "Ok."
    else:
    print "Empty."

    >>> b = B()
    >>> b.test()

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "<stdin>", line 3, in test
    AttributeError: 'B' object has no attribute '_B__value'

    Why I have no access to private attribute from a class that
    inherits other class? I just want to have access to the same
    private variables but also to extend its functionality by
    adding a method that operates on those private attributes and
    I'm unable to do so.

    Is this normal behaviour? What should I do if I want to
    override method and use private attribute, or just add
    some other method which changes this attribute?

    /K
    KN, Apr 21, 2004
    #1
    1. Advertising

  2. KN

    Peter Otten Guest

    KN wrote:

    >
    > I've run into such problem:
    >
    > I have something like this:
    >
    > class A(object):
    > def __init__(self):
    > self.__value = None
    >
    > class B(A):
    > def test(self):
    > if self.__value:


    change the above to
    if self._A__value:

    > print "Ok."
    > else:
    > print "Empty."
    >
    >>>> b = B()
    >>>> b.test()

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > File "<stdin>", line 3, in test
    > AttributeError: 'B' object has no attribute '_B__value'
    >
    > Why I have no access to private attribute from a class that
    > inherits other class? I just want to have access to the same
    > private variables but also to extend its functionality by
    > adding a method that operates on those private attributes and
    > I'm unable to do so.
    >
    > Is this normal behaviour? What should I do if I want to
    > override method and use private attribute, or just add
    > some other method which changes this attribute?


    Python performs name mangling for attributes starting with two underscores.
    This is meant to avoid accidental nameclashes of attributes that are rather
    an implementation detail than of interest to subclasses and the wider
    public. I like many others use attribute names with a *single* leading
    underscore (i. e. no name mangling) to signal "this is may change without
    prior notice" while omitting artificial hurdles.
    This is also known as treating programmers as adults :)

    Peter
    Peter Otten, Apr 21, 2004
    #2
    1. Advertising

  3. KN <> wrote in message news:<>...
    > I've run into such problem:
    >
    > I have something like this:
    >
    > class A(object):
    > def __init__(self):
    > self.__value = None
    >
    > class B(A):
    > def test(self):
    > if self.__value:
    > print "Ok."
    > else:
    > print "Empty."
    >
    > >>> b = B()
    > >>> b.test()

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > File "<stdin>", line 3, in test
    > AttributeError: 'B' object has no attribute '_B__value'
    >
    > Why I have no access to private attribute from a class that
    > inherits other class? I just want to have access to the same
    > private variables but also to extend its functionality by
    > adding a method that operates on those private attributes and
    > I'm unable to do so.
    >
    > Is this normal behaviour? What should I do if I want to
    > override method and use private attribute, or just add
    > some other method which changes this attribute?
    >
    > /K


    This is normal behavior (by design). In general a derived class has
    no special access to the attributes defined in its parent; there is no
    equivalent of C++'s "protected" variables.

    I see two solutions:

    1) Have the child use an accessor function (if class A above had a
    getValue() method, you could call it with A.getValue(self)).

    2) Cheat. In class B, access self._A__value. This duplicates the
    "mangling" that python does to hide variables with double underscore
    in front.

    I'd recommend 1), unless you have some urgent performance problem. 2)
    is probably a bit faster.

    Fast example of 2):
    >>> class a:

    .... def __init__(self):
    .... a.val = 3
    .... def getValue(self):
    .... return a.__val
    .... def __init__(self):
    .... a.__val = 3
    >>> x = a()
    >>> a.getValue()

    3
    >>> class b(a):

    .... def __init__(self):
    .... a.__init__(self)
    .... def getValue(self):
    .... return a._a__val + 2
    ....
    >>> y = b()
    >>> y.getValue()

    5
    A. Lloyd Flanagan, Apr 21, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,115
    Martijn van Steenbergen
    Dec 21, 2003
  2. qazmlp
    Replies:
    19
    Views:
    770
    Daniel T.
    Feb 4, 2004
  3. DaveLessnau
    Replies:
    3
    Views:
    413
    Howard
    May 16, 2005
  4. Replies:
    1
    Views:
    333
  5. karthikbalaguru
    Replies:
    9
    Views:
    1,024
Loading...

Share This Page