Address second part of 451: Remove all setters and make attrs into @property

Making all attributes on Key read-only and sorts out use of setters.
    
Addresses second part of #451. In some cases, since no valid
replacements for setters are implemented here, the functionality
is replaced with hacks using protected methods.
    
Also added a getter for Key._dataset_id and made the Key.path
property return a copy since a `list` of `dict`s is very much
mutable.

**NOTE**: This has #456 as a diffbase.