##
11.4.2 OpenerDirector Objects

`OpenerDirector` instances have the following methods:

`add_handler`(handler)
  handler should be an instance of `BaseHandler`. The following methods are searched, and added to the possible chains.

  - `protocol_open()` -- signal that the handler knows how to open protocol URLs.
  - `protocol_error_type()` -- signal that the handler knows how to handle type errors from protocol.

`close`()
  Explicitly break cycles, and delete all the handlers. Because the `OpenerDirector` needs to know the registered handlers, and a handler needs to know who the `OpenerDirector` who called it is, there is a reference cycles. Even though recent versions of Python have cycle-collection, it is sometimes preferable to explicitly break the cycles.

`open`(url[, data])
  Open the given url. (which can be a request object or a string), optionally passing the given data. Arguments, return values and exceptions raised are the same as those of `urlopen()` (which simply calls the `open()` method on the default installed `OpenerDirector`.

`error`(proto[, arg[, ...]])
  Handle an error in a given protocol. The HTTP protocol is special cased to use the code as the error. This will call the registered error handlers for the given protocol with the given arguments (which are protocol specific).

  Return values and exceptions raised are the same as those of `urlopen()`.