129

In python how can you extend a class? For example if I have

color.py

class Color:
    def __init__(self, color):
        self.color = color
    def getcolor(self):
        return self.color

color_extended.py

import Color

class Color:
    def getcolor(self):
        return self.color + " extended!"

But this doesn't work... I expect that if I work in color_extended.py, then when I make a color object and use the getcolor function then it will return the object with the string " extended!" in the end. Also it should have gotton the init from the import.

Assume python 3.1

brian d foy
  • 129,424
  • 31
  • 207
  • 592
omega
  • 40,311
  • 81
  • 251
  • 474
  • 4
    Did you try to read documentation? http://docs.python.org/2.7/tutorial/classes.html#inheritance – wRAR Mar 20 '13 at 14:53
  • classes should have first letter capitalized ("Color" not "color") ;) – daveoncode Mar 20 '13 at 14:53
  • 46
    @wRAR Maybe in 2013 this is a reasonable question, but let's be honest - people turn to StackOverflow first, so this is a good question to have on SO. This question is the first google hit for "python extend class", the documentation is third. – T.C. Proctor Jul 07 '17 at 19:02

4 Answers4

126

Use:

import color

class Color(color.Color):
    ...

If this were Python 2.x, you would also want to derive color.Color from object, to make it a new-style class:

class Color(object):
    ...

This is not necessary in Python 3.x.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 33
    It's worth noting that you can give the new class the same name as the old one: `class color(color):` defines a new class that replaces the old one, but which is derived from it. (This seems to be what the OP is trying to do.) – kindall Mar 20 '13 at 15:05
  • 19
    `class extended_color(color):` is bad standards usually - `class ExtendedColor(Color):` should be for classes. Just a nitpick – TyrantWave Mar 20 '13 at 15:07
  • 2
    Noob question here: why didn't you use `__init__`? – Mentalist Oct 29 '20 at 07:34
  • 3
    @Mentalist - Since the approach is basing a new custom class named `Color` on the existing `Color` class in the `color` module, you only need to implement overload definitions. E.g. if you don't implement an `__init__()` method in your new class but there is one in the class you're basing yours off of, it will just use the base class's `__init__()` method. – scrthq Jan 08 '21 at 20:10
  • 4
    This makes a new class. It does not extend the old. – ctrl-alt-delor Nov 23 '22 at 07:55
18
class MyParent:

    def sayHi():
        print('Mamma says hi')
from path.to.MyParent import MyParent

class ChildClass(MyParent):
    pass

An instance of ChildClass will then inherit the sayHi() method.

ᴍᴇʜᴏᴠ
  • 4,804
  • 4
  • 44
  • 57
2

Another way to extend (specifically meaning, add new methods, not change existing ones) classes, even built-in ones, is to use a preprocessor that adds the ability to extend out of/above the scope of Python itself, converting the extension to normal Python syntax before Python actually gets to see it.

I've done this to extend Python 2's str() class, for instance. str() is a particularly interesting target because of the implicit linkage to quoted data such as 'this' and 'that'.

Here's some extending code, where the only added non-Python syntax is the extend:testDottedQuad bit:

extend:testDottedQuad
def testDottedQuad(strObject):
    if not isinstance(strObject, basestring): return False
    listStrings = strObject.split('.')
    if len(listStrings) != 4: return False
    for strNum in listStrings:
        try:    val = int(strNum)
        except: return False
        if val < 0: return False
        if val > 255: return False
    return True

After which I can write in the code fed to the preprocessor:

if '192.168.1.100'.testDottedQuad():
    doSomething()

dq = '216.126.621.5'
if not dq.testDottedQuad():
    throwWarning();

dqt = ''.join(['127','.','0','.','0','.','1']).testDottedQuad()
if dqt:
    print 'well, that was fun'

The preprocessor eats that, spits out normal Python without monkeypatching, and Python does what I intended it to do.

Just as a c preprocessor adds functionality to c, so too can a Python preprocessor add functionality to Python.

My preprocessor implementation is too large for a stack overflow answer, but for those who might be interested, it is here on GitHub.

fyngyrz
  • 2,458
  • 2
  • 36
  • 43
  • 2
    This is very cool. Use this in Swift all the time, wish Python did this natively, though there is too much toolchain baggage I suspect. Also, an actual answer to the question asked. – Jan Z Nov 22 '21 at 00:22
-1

I use it like this.

class menssagem:
  propriedade1 = "Certo!"
  propriedade2 = "Erro!"

def metodo1(self)
  print(self.propriedade1)

to extend.

import menssagem
class menssagem2(menssagem):

  menssagem1 = None #não nescessario not necessary

  def __init__(self,menssagem):
    self.menssagem1 = menssagem

  #call first class method
  #usando o metodo da menssagem 1

  def Menssagem(self):
    self.menssagem1.metodo1()
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
Birk Net
  • 17
  • 2
  • 4
    Translate the comments from Portuguese to English so everybody can understand you please :) – Mr K. Nov 05 '21 at 07:28