Python OOP:字典中的函数不会影响类实例变量



我是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']()

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

当我以这种方式调用函数时,我将如何改变动物的健康状况,我有点不知所措。我必须以某种方式利用超类调用吗?

edit:澄清语法

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

现在,让我们看看字典-由于您将实际的"sleep"函数定义为嵌套函数,因此它将"看到"self"变量,因为它存在于initializeSleep()的调用中-这意味着您正在做的事情应该正常工作-只要您通过使用self.前缀来修复对initializeSleep()的调用,如:

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

并从实际的"sleep"函数中删除"self"参数-它不需要它,因为它将"看到"封闭作用域中的非局部self变量:

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

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

您不需要将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

如前所述,您在self.health = RESTORED_HEALTH中忘记了+=。您还错过了self.initializeSleep()

中的self

最新更新