Where I am now looks like this:
class A(object):
def __init__(self, val):
self.x=val
self.y=42
# other fields
class B(object):
def __init__(self):
self.a=22
# other fields
class C(A,B):
def __init__(self, val):
super(C,self).__init__(val)
@property
def x(self):
# if A.x is None return a value that I can compute from A.y and B.a
# if A.x is not None return it
@x.setter
def x(self, val):
# set the field value
Sometimes I just want to set an assumed value for x
by hand, in which case I would just use an A
. In other cases I want to use a more complicated approach that involves computing Ax
's value on the basis of information that is organized into a B
. The idea in this code is to make a C
class that can look like an A
(in terms of the x
field) but doesn't need that field value to be set by hand, instead it just gets derived.
What I can't figure out is how to have the Cx
property shadow the Ax
field in a sensible way.
The line self.x = val
in the A.__init__
method will simply invoke your Cx
setter . You already have everything handled here. You are handling per instance attributes here, not attributes on a class that are inherited by subclasses.
All you need to do is to set a different attribute in the setter to represent the x
value. You could name it _x
, for example:
class C(A, B):
_x = None
@property
def x(self):
if self._x is not None:
return self._x
return self.a + self.y
@x.setter
def x(self, val):
self._x = val
Note that if all C.__init__
does is call super().__init__
, you don't need it at all. However, you do need to make sure at least A.__init__()
plays along in the inheritance structure; add in more calls to super().__init__()
:
class A(object):
def __init__(self, val, *args, **kwargs):
super(A, self).__init__(*args, **kwargs)
self.x = val
self.y = 42
class B(object):
def __init__(self, *args, **kwargs):
super(B, self).__init__(*args, **kwargs)
self.a = 22
Using *args
and **kwargs
allows these methods to pass on any extra arguments to other classes in the hierarchy.
Demo, using the above classes:
>>> c = C(None)
>>> c.x
64
>>> c.x = 15
>>> c.x
15
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.