简体   繁体   中英

Access the private attributes in a inherited class in python

I have a class a defined like this:

class a:
    def __init__(self, w, x, y, z):
        self.w = w
        self.x = x
        self.y = y
        self.__z = z

I also have another class b which inherits a defined like this:

class b(a):
    def __init__(self, w, x, y, z, t):
        super().__init__(w, x, y, z)
        self.__t = t

Now if I had access w, x, y from within b , I could simply do:

self.w
self.x
self.y

But I can't do self.z or self.__z to access z . So my question is how can you access dunder values such as z from within class b

(I know python doesn't really have private variables and I could do self._a__z from within class b to access z but I'm looking for methods which would allow me to just do something like self.z to access z from inside b )

There are a variety of ways you could solve the problem by changing the API of class a to expose it's __z attribute in some more inheritance-friendly way. For instance, you could make the actual mangled attribute name an implementation detail and have the public API be a property :

class a:
    def __init__(self, w, x, y, z):
        self.w = w
        self.x = x
        self.y = y
        self.__z = z

    @property
    def z(self):
        return self.__z

    @z.setter
    def z(self, value):
        self.__z = value

But unless you're doing some validation or modification of the value somewhere in the property's code, you probably should just do away with the double-underscores and let the child class access self.z like it can w , x and y . The simplest solution is to replace self.__z = z with self.z = z . You can always change it later to use a property if you find you do need validation or something.

If you just want to hint that z is not part of the wider public API, but only for subclasses and other code that knows about the intimate details of a 's design, consider using a single underscore: self._z = z . This has no special effects in the interpreter, but the single-underscore serves as a sort of documentation that _z is an internal attribute and you should only mess with it if you know what you're doing.

You could do something like this if you want to keep your code clean:

class a:
    def __init__(self, w, x, y, z):
        self.w = w
        self.x = x
        self.y = y
        self.__z = z

    def get_field(self):
        return self.__z
class b(a):
    def __init__(self, w, x, y, z, t):
        super().__init__(w, x, y, z)
        self.__t = t

    def ChildMethodWhichUsingParentField(self):
        return self.get_field()


c = b(1,2,3,4,5)
print(c.ChildMethodWhichUsingParentField())

Output

4

Similarly, you can use a setter to change its value:

class a:
    def __init__(self, w, x, y, z):
        self.w = w
        self.x = x
        self.y = y
        self.__z = z

    def get_field(self):
        return self.__z
    def set_field(self,z):
        self.__z = z

class b(a):
    def __init__(self, w, x, y, z, t):
        super().__init__(w, x, y, z)
        self.__t = t

    def ChildMethodWhichUsingParentField(self):
        return self.get_field()
    def ChildMethodWhichSettingParentField(self,z):
        self.set_field(z)



c = b(1,2,3,4,5)
print(c.ChildMethodWhichUsingParentField())
c.ChildMethodWhichSettingParentField(10)
print(c.ChildMethodWhichUsingParentField())

Output

4
10

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM