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.