Python: pass a class-function as a reference to an external function
Question:
I have a class with several functions.
From outside that class, I want to specify with a reference which function to call – but I’m not sure how.
For example, I have an Animal
class with two functions sound
and food
. I want to write a Zoo
class which receives one of the Animal
‘s functions as input and applies that function to every animal instance it holds (the function all_animals_features
).
class Animal:
def __init__(self, sound, food):
self.my_sound = sound
self.my_food = food
def sound(self):
# Do some complicated stuff....
return self.my_sound
def food(self):
return self.my_food
class Zoo():
def __init__(self, animals):
self.animals = animals
def all_animals_features(self, f):
return [animal.f() for animal in self.animals]
dog = Animal('Woof', 'Bone')
cat = Animal('Meow', 'Cream')
zoo = Zoo([cat, dog])
zoo.all_animals_features(Animal.sound)
But of course, 'Animal' object has no attribute 'f'
.
Any idea how can this be implemented?
Clarification: if all that is needed, as demonstrated by this silly example, is just getting an attribute then it may be simpler to use getattr().
Answers:
In your case you just need to adjust the way the method is called:
class Zoo():
def __init__(self, animals):
self.animals = animals
def all_animals_features(self, f):
return [f(animal) for animal in self.animals]
dog = Animal('Woof', 'Bone')
cat = Animal('Meow', 'Cream')
zoo = Zoo([cat, dog])
print(zoo.all_animals_features(Animal.sound))
Output:
['Meow', 'Woof']
Since you supply Animal.sound
, as parameter f
, the call in the list comprehension is: f(animal)
I have a class with several functions.
From outside that class, I want to specify with a reference which function to call – but I’m not sure how.
For example, I have an Animal
class with two functions sound
and food
. I want to write a Zoo
class which receives one of the Animal
‘s functions as input and applies that function to every animal instance it holds (the function all_animals_features
).
class Animal:
def __init__(self, sound, food):
self.my_sound = sound
self.my_food = food
def sound(self):
# Do some complicated stuff....
return self.my_sound
def food(self):
return self.my_food
class Zoo():
def __init__(self, animals):
self.animals = animals
def all_animals_features(self, f):
return [animal.f() for animal in self.animals]
dog = Animal('Woof', 'Bone')
cat = Animal('Meow', 'Cream')
zoo = Zoo([cat, dog])
zoo.all_animals_features(Animal.sound)
But of course, 'Animal' object has no attribute 'f'
.
Any idea how can this be implemented?
Clarification: if all that is needed, as demonstrated by this silly example, is just getting an attribute then it may be simpler to use getattr().
In your case you just need to adjust the way the method is called:
class Zoo():
def __init__(self, animals):
self.animals = animals
def all_animals_features(self, f):
return [f(animal) for animal in self.animals]
dog = Animal('Woof', 'Bone')
cat = Animal('Meow', 'Cream')
zoo = Zoo([cat, dog])
print(zoo.all_animals_features(Animal.sound))
Output:
['Meow', 'Woof']
Since you supply Animal.sound
, as parameter f
, the call in the list comprehension is: f(animal)