如何在Python中扩展一个类?

130
在Python中,如何扩展一个类?例如,如果我有以下代码:

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!"

但是这样不起作用... 我期望如果我在color_extended.py中工作,那么当我创建一个颜色对象并使用getcolor函数时,它将返回带有字符串“扩展!”的对象。此外应该已经从导入中获取了init。
假设使用Python 3.1。

5
你尝试阅读文档了吗? http://docs.python.org/2.7/tutorial/classes.html#inheritance - wRAR
类名应该首字母大写("Color" 而不是 "color");) - daveoncode
47
或许在2013年这个问题还算合理,但说实话——人们首先会去StackOverflow,所以在SO上提出这个问题是很好的。这个问题是“python extend class”在谷歌上的第一个搜索结果,而文档则排在第三位。 - T.C. Proctor
4个回答

128

使用:

import color

class Color(color.Color):
    ...
如果这是Python 2.x版本,您还需要从object继承color.Color,使它成为新式类
class Color(object):
    ...

在Python 3.x中这不是必需的。


34
值得注意的是,您可以将新类命名为与旧类相同的名称:class color(color):定义了一个新类,它替换了旧类,但派生自它。(这似乎是原帖作者试图做的事情。) - kindall
19
class extended_color(color): 这种写法通常不符合规范 - class ExtendedColor(Color): 应该用于类。这只是一个小问题。 - TyrantWave
2
新手问题:为什么你没有使用__init__ - Mentalist
3
由于这种方法是在现有的color模块中基于一个新的自定义类Color,所以你只需要实现重载定义。例如,如果你在新类中没有实现__init__()方法但是继承的类中有这个方法,它就会使用基类的__init__()方法。 - scrthq
4
这将创建一个新类。它不会继承旧类。 - ctrl-alt-delor

19
class MyParent:

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

class ChildClass(MyParent):
    pass

那么,ChildClass 的实例将继承 sayHi() 方法。


2
另一种扩展类的方式(具体指添加新方法,而不是更改现有方法),甚至是内置类,是使用预处理器将扩展能力添加到 Python 本身的范围之外/之上,将扩展转换为正常的 Python 语法,然后 Python 才能看到它。
例如,我已经这样做来扩展 Python 2 的 str() 类。str() 是一个特别有趣的目标,因为它与引用数据(如'this'和'that')存在隐式关联。
以下是一些扩展代码,其中唯一添加的非 Python 语法是 extend:testDottedQuad 部分:
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

接下来我可以编写传递给预处理器的代码:

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'

预处理器吃掉它,输出普通的Python代码而不进行monkeypatching,然后Python执行我想要的操作。

正如c预处理器为c添加功能一样,Python预处理器也可以为Python添加功能。

我的预处理器实现过于庞大,无法在stackoverflow上回答,但对于那些可能感兴趣的人,它可以在GitHub上找到。


2
这非常酷。在Swift中经常使用它,但希望Python本地支持此功能,尽管我怀疑会有太多的工具链负担。另外,给出一个实际回答问题的答案。 - Jan Z

-1

我是这样使用它的。

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

def metodo1(self)
  print(self.propriedade1)

扩展。

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()

4
请将这些评论从葡萄牙语翻译成英语,以便每个人都能理解您的意思。 :) - Mr K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接