##
11.5.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 cycle. 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. This will call the registered error handlers for the given protocol with the given arguments (which are protocol specific). The HTTP protocol is a special case which uses the HTTP response code to determine the specific error handler; refer to the `http_error_*()` methods of the handler classes.

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