总的来说,我有一个 Django 模型,我希望实例根据其字段之一的值具有不同的行为:
ANIMAL_TYPES = ('cow', 'african swallow', 'dog')
ANIMAL_TYPE_CHOICES = tuple(enumerate(ANIMALS, start=1))
class Animal(models.Model):
animal_type = models.PositiveIntegerField(choices=ANIMAL_TYPE_CHOICES)
# ... other model fields
def speak_cow(self):
return 'moo'
def speak_african_swallow(self):
return 'squawk'
def speak_dog(self):
return 'woof'
choose_speak = {i: getattr(Animal,'speak_{}'.format(
name.replace(' ', '_'))) for (i, name) in ANIMAL_TYPE_CHOICES}
def speak(self):
return Animal.speak[self.animal_type](self)
目标是能够在 Animal
实例上调用 speak()
并让类选择正确的 speak
方法。 (需要明确的是:speak
方法不仅仅返回一个字符串。)
这不起作用:当我在 choose_speak
的字典理解中使用它时,Animal
尚未定义。目前,我的解决方法是使用
choose_speak = [None, speak_cow, speak_african_swallow, speak_dog]
但是有没有办法自动生成我想要的内容,这样我就不必手动添加任何我定义的新方法(例如 speak_sheep
)?
最佳答案
您还可以定义一个包含所有动物声音的列表......即
ANIMAL_SOUNDS = ['moo', 'squawk'..]
这样您就不必定义新方法。 在说话中使用它,例如:
def speak(self):
return ANIMAL_SOUNDS[self.animal_type]
编辑:
只是为了它,我玩了一下,并用纯Python想出了这段代码,它可能接近你想要的:
ANIMAL_TYPES = ('cow', 'african swallow', 'dog')
ANIMAL_TYPE_CHOICES = tuple(enumerate(ANIMAL_TYPES, start=1))
class Animal(object):
def __init__(self, *args, **kwargs):
self.choose_speak = {i: getattr(self, 'speak_{}'.format(
name.replace(' ', '_'))) for (i, name) in ANIMAL_TYPE_CHOICES}
animal_type = 1
def speak_cow(self):
return 'moo'
def speak_african_swallow(self):
return 'squawk'
def speak_dog(self):
return 'woof'
def speak(self):
return self.choose_speak[self.animal_type]()
animal = Animal()
animal.speak()
注意:覆盖模型的 __init__
不是 Django 最佳实践,如图所示 here :
关于python - 根据 Django 模型中的字段值选择方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32284209/