我是 Python 的新手,但出于爱好编写程序,因此我对 OOP 和计算机编程有一定的了解。我已经开始研究一个简单的动物模拟器。在这很可能是异教徒的举动中,我试图将动物的所有“ Action 功能”存储在字典中,以便每个功能都可以通过字符串访问。例如,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。相反,什么也没有发生。经过一些研究和实验,我发现传递给 sleep()
函数的 self
显然是指 initializeSleep()
而不是动物类.
对于以这种方式调用函数时如何改变动物的健康状况,我有些不知所措。我是否必须以某种方式使用父类(super class)调用?
编辑:澄清语法
最佳答案
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 ”函数定义为嵌套函数,因此它将“看到”调用 initializeSleep()
时存在的“self”变量 - 这意味着您正在做的应该只是工作 - 只要您修复对 initializeSleep()
的调用,方法是在其前面加上 self.
,如:
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 中可见)
关于Python 面向对象 : functions from a dictionary do not affect class instance variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16975780/