13

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

好吧,所以问题。如果我可以在 Python 中做同样的事情(Java 的代码curtesy):

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

与在游戏中构建关卡相比,我只需使用精灵去向的信息覆盖构造函数(或负责构建关卡的类/实例方法),因为为每个关卡创建一个新类游戏并不是一个优雅的答案。或者,我必须在关卡类中创建方法,然后在实例化关卡对象后构建关卡,并根据需要放置精灵。

所以,在一位更坚定的开发人员继续谈论这可能是多么反 python 之前(我已经阅读了足够多的这个网站以从 Python 专家那里获得这种氛围),只要告诉我它是否可行。

4

3 回答 3

11

是的你可以!

class Foo:
    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()  # prints "bar!"
f.do_other()  # prints "other!"

g.do_foo()  # prints "bar!"
g.do_other()  # prints "baz!"

因此,在一位更坚定的开发人员继续讨论这可能是多么反蟒蛇之前

以这种方式覆盖函数(如果你有充分的理由这样做)对我来说似乎是相当pythonic。您可能必须这样做的一个原因/方式的一个示例是,如果您有一个静态继承没有或不能应用的动态特性。

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

  • 美丽总比丑陋好。
  • 可读性很重要。
  • 如果实现很难解释,那是个坏主意。
于 2013-07-20T00:20:40.087 回答
5

是的,这是可行的。在这里,我使用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是 class 的实例K,则x.attrname首先查看x的字典以查找属性。如果没有找到,下一个查找在K. 所有正常的类函数实际上都是K.func. 因此,如果您想动态替换函数,请改用@Brian Cane 的答案。

于 2013-07-20T00:31:12.337 回答
1

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

但是,如果您真的愿意像对待 Java 一样对待 Python,那么您可能会从 copy.deepcopy() 和猴子补丁中获得一些好处。

于 2013-07-20T00:22:55.687 回答