accessing superclass methods from subclass
Chris Rebert
clp2 at rebertia.com
Sat May 8 23:44:59 EDT 2010
> On May 8, 7:05 pm, Chris Rebert <c... at rebertia.com> wrote:
>> On Sat, May 8, 2010 at 4:50 PM, ben <thomasstr... at gmail.com> wrote:
>> > Why doesn't this work:
>>
>> > class C1:
>> > def f1(self):
>> > print("f1")
>>
>> > class C2(C1):
>> > f1()
>>
>> > It throws this error:
>>
>> > Traceback (most recent call last):
>> > File "./c1.py", line 7, in <module>
>> > class C2(C1):
>> > File "./c1.py", line 8, in C2
>> > f1()
>> > NameError: name 'f1' is not defined
>>
>> > f1() is an attribute of class C1, C2 inherits C1, so why can't it see
>> > it?
>>
>> The way classes work in Python, C2 isn't actually created until after
>> its body suite has been executed, so that's why Python can't find f1.
>>
>> Additionally, it makes no sense to call an *instance* method such as
>> f1() in a class context. Or in Java-speak: you can't call a non-static
>> method in a static context.
On Sat, May 8, 2010 at 8:24 PM, ben <thomasstruth at gmail.com> wrote:
> Ok, thanks for the info.
>
> What would be a better way to do this? What I'm trying to do is treat
> things in a reasonable OOP manner (all fairly new to me, esp. in
> Python). Here's a made-up example with a little more context. Let's
> say you're making a drawing program that can draw various shapes. So
> in the interest of not repeating oneself, I want a class Shape that
> handles everything that shapes have, such as a color, and a location.
> Then I can subclass Shape to create Square, which has code specific to
> drawing a square (e.g. 4 equal sides). So, like this:
>
> class Shape:
>
> x = 0
> y = 0
>
> def setColor(self,color):
> self.color = color
>
> def setLocation(self,x,y):
> self.x = x
> self.y = y
>
> def getLocation(self):
> return [self.x,self.y]
>
> class Square(Shape):
>
> size = 0
>
> def __init__(self,size):
> self.size = size
>
> def draw(self):
> location = getLocation()
> # code to draw shape from location[0],location[1] at size size
> # etc...
>
> It seems to me that you would want the location code handled in the
> Shape class so that I'm not rewriting it for Circle, Triangle, etc.,
> but I'm not allowed to call any of those methods from the subclass. I
> must be thinking of this in the wrong way. Help?
Your code suggests you need to read a tutorial on Python's
object-oriented features. The relevant part of Python's official
tutorial is http://docs.python.org/tutorial/classes.html
For starters, Python is not Java and getters/setters are not usually
necessary nor Pythonic; see
http://dirtsimple.org/2004/12/python-is-not-java.html
Secondly, Python does not have instance variable declarations; doing
`x = 0` at the class-level creates a static/class variable, it *does
not* declare an instance variable.
Thirdly, to call an instance method such as getLocation, you need to
specify the receiver, i.e. `self.getLocation()`, not merely
`getLocation()`
Here is how I would rewrite your example:
class Shape(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
@property
def location(self):
return (self.x, self.y)
@location.setter
def location(self, val):
self.x, self.y = val
class Square(Shape):
def __init__(self,size):
super(Square, self).__init__()
self.size = size
def draw(self):
x, y = self.location
# code to draw shape from location[0],location[1] at size size
# etc...
This uses some minor magic involving property(), see
http://docs.python.org/library/functions.html#property for how that
works.
Cheers,
Chris
--
http://blog.rebertia.com
More information about the Python-list
mailing list