我可以覆盖类函数而无需在Python中创建新类吗?

时间:2013-07-20 00:03:18

标签: python oop object polymorphism override

我正在使用pygame制作游戏,我制作了一个“抽象”类,其唯一的工作就是将精灵存储到给定的级别(目的是将这些级别的对象放在列表中以方便玩家移动从一个级别到另一个级别)

好的,那么问题。如果我可以在Python中完成相同的操作(代码简称Java):

Object object = new Object (){
    public void overriddenFunction(){
        //new functionality
        };
    };

当我在游戏中构建关卡时,我只需要覆盖构造函数(或负责构建关卡的类/实例方法)以及关于精灵所在位置的信息,因为创建了一个新类游戏中的每个级别都不是那么优雅的答案。或者,我必须在级别类中创建方法,然后在实例化级别对象后构建级别,根据需要放置精灵。

所以,在一个更坚定的开发人员继续谈论这可能是什么样的反python之前(我已经阅读了足够多的网站以获得Python专家的感受),请告诉我它是否可行。

3 个答案:

答案 0 :(得分:5)

是的,你可以!

class Foo(object):
    def do_other(self):
        print 'other!'
    def do_foo(self):
        print 'foo!'


def do_baz():
    print 'baz!'

def do_bar(self):
    print 'bar!'

# Class-wide impact
Foo.do_foo = do_bar
f = Foo()
g = Foo()
# Instance-wide impact
g.do_other = do_baz

f.do_foo()
f.do_other()

g.do_foo()
g.do_other()
  

所以,在更多的stanch开发人员继续谈论这可能是什么样的反python之前

以这种方式覆盖函数(如果你有充分的理由这样做)对我来说似乎是合理的pythonic。您可能必须执行此操作的一个原因/方式的示例是,如果您具有静态继承不适用或不适用的动态功能。

案例反对可能在Python的禅宗中找到:

  • 美丽胜过丑陋。
  • 可读性很重要。
  • 如果实施难以解释,那就不错了。

答案 1 :(得分:2)

是的,这是可行的。在这里,我使用functools.partial将隐含的self参数放入常规(非类方法)函数中:

import functools

class WackyCount(object):
    "it's a counter, but it has one wacky method"
    def __init__(self, name, value):
        self.name = name
        self.value = value
    def __str__(self):
        return '%s = %d' % (self.name, self.value)
    def incr(self):
        self.value += 1
    def decr(self):
        self.value -= 1
    def wacky_incr(self):
        self.value += random.randint(5, 9)

# although x is a regular wacky counter...
x = WackyCount('spam', 1)
# it increments like crazy:
def spam_incr(self):
    self.value *= 2
x.incr = functools.partial(spam_incr, x)

print (x)
x.incr()
print (x)
x.incr()
print (x)
x.incr()
print (x)

$ python2.7 wacky.py
spam = 1
spam = 2
spam = 4
spam = 8
$ python3.2 wacky.py    
spam = 1
spam = 2
spam = 4
spam = 8

编辑以添加注释:这是每实例覆盖。它利用了Python的属性查找序列:如果x是类K的实例,那么x.attrname首先查看x的字典以查找属性。如果未找到,则下一个查找位于K。所有正常的类函数实际上都是K.func。因此,如果您想动态替换函数,请改用@Brian Cane的答案。

答案 2 :(得分:1)

我建议为每个级别使用不同的类,通过继承。

但是你可能会从copy.deepcopy()和猴子补丁中获得一些好处,如果你真的嫁给像Java这样的Python。