Why does GAE use classes and self.response.out.write over functions and print?
Using Methods
Each handler class has methods with names like get and post, after the HTTP methods GET and POST etc. Those methods are functions that handle requests.
Each request to your server will be routed to a request handler object, which is a new instance of some request handler class. So, a request handler instance is created per request, and is garbage collected once its HTTP response is sent.
By inheriting from webapp2.RequestHandler, your handler classes get a bunch of functionality out the box for free. For example, handler instances will have the data from the HTTP request parsed into dictionaries and bound to self as self.request.headers and self.request.body automatically.
The webapp2.RequestHandler class also provides self.response, which is what you write your response data to.
Once the new request handler instance is initialised, the inherited __init__ method calls the method that maps to the HTTP request method, so assuming a GET request, it calls self.get. The webapp2.RequestHandler class doesn't implement those methods; your derived class does.
Responding
Neither print nor the return value of the handler method are used here. You do not 'return a response' with this framework; you write the response to the request handler instance's (inherited) self.response property.
Your instance inherits self.response.out.write (which is aliased to self.response.write), which concatenates its argument to the body of the response, initially an empty string.
Note: You can call self.response.clear to clear the response body.
When you return from your handler method - get or post etc. - the return value is ignored. The framework uses the state of self.response to automatically create and send a HTTP response for you.
There's a bunch of subtleties that the framework takes care of behind the scenes too.
Classes Over Functions
The main advantage is in inheritance. Normally, you'll create a single BaseHandler class that derives from webapp2.RequestHandler. The BaseHandler class will contain the core functionality for your actual handlers. It might include some logic for converting data into little JSON packages for a Web API, for example. All of the classes that actually handle requests would then be derived from your BaseHandler.
You want a custom base class for your handler classes to derive from mainly so you can edit that base class. You want that base class to inherit from webapp2.RequestHandler so that all your handler instances inherit the framework magic.
There is enough slight of hand to make the whole thing confusing, but it is easy to make sense of once you get it, and does save a lot of trouble.
Technically, you could achieve all of the above just using functions and dictionaries, but Python is classically object oriented, so it would be painful and weird.
I'm a beginner and am wondering why we use self.response.out.write instead of print, and why we use classes, instead of functions, for the request handlers in the first place. Are there any special reasons?