Potrzebuję napisać klasę, która pozwala podklasie ustawić atrybut z nazwą funkcji. Ta funkcja musi być następnie wywoływana z instancji klasy.Pisanie klasy, która akceptuje wywołanie zwrotne w Pythonie?
Na przykład mówię, że muszę napisać klasę owoców, w której podklasa może przekazać wiadomość powitalną. Klasa Fruit musi wystawiać atrybut print_callback, który można ustawić.
class Fruit(object):
print_callback = None
def __init__(self, *args, **kwargs):
super(Fruit, self).__init__(*args, **kwargs)
self.print_callback("Message from Fruit: ")
muszę wystawiać API, który może być spożywany przez tego kodu (być jasne, ten kod nie może zmienić, powiedzieć, że jest kod 3rd party):
def apple_print(f):
print "%sI am an Apple!" % f
class Apple(Fruit):
print_callback = apple_print
Jeśli uruchomić:
mac = Apple()
chcę uzyskać:
Message from Fruit: I am an Apple!
Zamiast tego otrzymuję:
TypeError: apple_print() takes exactly 1 argument (2 given)
Myślę, że to dlatego, że self jest przekazywane jako pierwszy argument.
Jak napisać klasę Fruit? Dzięki!
Doceniam problemy zostałeś mających z tym podejściem i doskonałe rozwiązania poniżej. Jednak wygląda na to, że powinieneś zdefiniować 'print_callback' jako metodę (może po prostu nazwać' print_me' i zdobyć podklasy, aby ją zastąpić.To byłoby proste i pythonic. Dla każdego innego rodzaju metody 'print_me', utwórz inną podklasę. –
Moja motywacja do zadawania tego pytania polegała na tym, że chciałem podklasować google.appengine.ext.db.djangoforms (np. Jako DF2) w Google App Engine, aby umożliwić zastąpienie atrybutu formfield_callback w taki sam sposób jak modelForm Django (django.forms.ModelForm). Chodzi o to, że "klasa f (DF2)" może być następnie użyta przez standard Django po prostu przez zmianę superklasy na django.forms.ModelForm. Nie wiem, dlaczego autorzy Django zdefiniowali formfield_callback jako atrybut. –