<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def protect(self, passphrase, enc_alg, hash_alg):
 """ Add a passphrase to a private key. If the key is already passphrase protected, it should be unlocked before a new passphrase can be specified. Has no effect on public keys. :param passphrase: A passphrase to protect the key with :type passphrase: ``str``, ``unicode`` :param enc_alg: Symmetric encryption algorithm to use to protect the key :type enc_alg: :py:obj:`~constants.SymmetricKeyAlgorithm` :param hash_alg: Hash algorithm to use in the String-to-Key specifier :type hash_alg: :py:obj:`~constants.HashAlgorithm` """

        ##TODO: specify strong defaults for enc_alg and hash_alg
        if self.is_public:
            # we can't protect public keys because only private key material is ever protected
            warnings.warn("Public keys cannot be passphrase-protected", stacklevel=2)
            return

        if self.is_protected and not self.is_unlocked:
            # we can't protect a key that is already protected unless it is unlocked first
            warnings.warn("This key is already protected with a passphrase - "
                          "please unlock it before attempting to specify a new passphrase", stacklevel=2)
            return

        for sk in itertools.chain([self], self.subkeys.values()):
            sk._key.protect(passphrase, enc_alg, hash_alg)

        del passphrase