In the description of What’s new in Celery 4.0 (latentcall) the following is written:
If you’re still using class based tasks, then you need to register these manually: ...
And:
The best practice is to use custom task classes only for overriding general behavior, and then using the task decorator to realize the task.
Where both suggest that you should use function based tasks for Celery tasks. Why would Celery prefer function based tasks over class based tasks? I can't find any reason why it would make sense to prevent people writing tasks with classes.