1

我是 Python 新手,但出于兴趣编写程序,所以我对 OOP 和一般计算机编程有一定的了解。我已经开始研究一个简单的动物模拟器。在很可能是异教徒的举动中,我试图将动物的所有“动作函数”存储在字典中,以便每个函数都可以通过字符串访问。例如,dict['SLEEP']()调用 sleep 函数。

我找不到我想要完成的事情的例子,坦率地说,我不确定如何明智地描述我的问题。请参阅下面的基本代码:

class Animal:

    def __init__(self):
        self.health = 100
        self.actions = {}  # dictionary of functions
        self.initializeAnimal()

    def initializeAnimal(self):
        self.actions['SLEEP'] = self.initializeSleep()  # add sleep function 

    def initializeSleep(self):
        RESTORED_HEALTH = 20
        # other constants

        def sleep(self):
            self.health += RESTORED_HEALTH
            # utilize other constants

        return sleep

然后,动物处理程序将执行以下操作:

for animal in animalList:
    animal.actions['SLEEP']()

当调用 sleep 函数时,我当然希望动物的健康增加 20。相反,什么也没有发生。经过一些研究和实验,我看到self传递给sleep()函数显然是指initializeSleep()而不是动物类。

当以这种方式调用函数时,我对如何改变动物的健康状况感到有些不知所措。我是否必须以某种方式使用超类调用?

编辑:澄清语法

4

2 回答 2

4

Python 做了一些操作,以便在类主体中定义的函数实际上表现为“方法”——因此,自动添加了“self”参数。

不难理解这是如何完成的 - 并按照您的计划将其模拟为显式字典 - 但首先,考虑您可以使用字符串检索方法名称,而无需按照您的计划将它们存储在字典中 - 您可以简单地做:

class Animal(object):
    ...
    def sleep(self, ...):
        ...

my_cow  = Animal()
function = getattr(my_cow, "sleep")
function (  ) 
# and of course, the two preceeding lines can be in a single expression:
getattr(a, "sleep")()

现在,让我们看看字典 - 因为您将实际的“睡眠”函数定义为嵌套函数,它会“看到”存在于调用中的“自我”变量initializeSleep()- 这意味着你正在做的应该只是工作 -只要您initializeSleep()通过在它前面加上前缀来修复调用self.,如下所示:

def initializeAnimal(self):
    self.actions['SLEEP'] = self.initializeSleep()  # add sleep function 

并从实际的“睡眠”函数中删除“自我”参数 - 它不需要它,因为它将“看到”self封闭范围内的非局部变量:

def initializeSleep(self):
    RESTORED_HEALTH = 20
    # other constants

    def sleep():
        self.health = RESTORED_HEALTH
        # utilize other constants

    return sleep

(在 initializeSLeep 中定义的其他常量也将在 sleep 中作为非局部变量可见)

于 2013-06-07T03:35:00.853 回答
1

您不需要将self属性放入sleep函数中。
执行以下操作完全有效:

class Animal:
    def __init__(self):
        self.health = 100
        self.actions = {}  # dictionary of functions
        self.initializeAnimal()

    def initializeAnimal(self):
        self.actions['SLEEP'] = self.initializeSleep()  # add sleep function 

    def initializeSleep(self):
        RESTORED_HEALTH += 20
        # other constants

        def sleep():
            self.health += RESTORED_HEALTH
            # utilize other constants
        return sleep

a = Animal()
print(a.health)
a.actions['SLEEP']()
print(a.health)

输出:

100
120

如前所述,您忘记了+=in self.health = RESTORED_HEALTH
你也错过selfself.initializeSleep()

于 2013-06-07T03:39:36.153 回答