WARNING: The following question is asking for information concerning poor practices and dirty code. Developer discretion is advised.
Note: This is different than the Creating a singleton in Python question because we want to address pickling and copying as well as normal object creation.
Goal: I want to create a value (called NoParam) that simulates the behavior of None. Specifically I want any instance of NoParamType to be the same value --- i.e. have the same id --- so that the is operator always returns True between two of these values. 
Why: I have configuration classes that holds onto values of parameters. Some of these parameters can take None as a valid type. However, I want these parameters to take particular default values if no type is specified. Therefore I need some sentinel that is not None to specify that no parameter was specified. This sentinel needs to be something that 
 could never be used as a valid parameter value.  I would prefer to have a special type for this sentinel instead of using some unlikely to be used string.
For instance:
def add_param(name, value=NoParam):
    if value is NoParam:
        # do some something
    else:
        # do something else 
But lets not worry so much about the why. Lets focus on the how.
What I have so far:
I can achieve most of this behavior pretty easily. I have created a special module called util_const.py. This contains a class that creates a NoParamType and then a singleton instance of the class. 
class _NoParamType(object):
    def __init__(self):
        pass
NoParam = _NoParamType()
I'm simply assuming that a second instance of this class will never be created. Whenever I want to use the value I import util_const and use util_const.NoParam.
This works well for most cases. However, I just encountered a case where 
a NoParam value was set as an object value. The object was deep copied using copy.deepcopy and thus a second NoParam instance was created. 
I found a very simple workaround for this by defining the __copy__ and __deepcopy__ methods
class _NoParamType(object):
    def __init__(self):
        pass
    def __copy__(self):
        return NoParam
    def __deepcopy__(self, memo):
        return NoParam
NoParam = _NoParamType()
Now, if deepcopy is ever called no NoParam it simply returns the existing NoParam instance. 
Now for the question:
Is there anything I can do to achieve this same behavior with pickling? Initially I thought I could define __getstate__ but the second instance has already been created at that point. Essentially I want pickle.loads(pickle.dumps(NoParam)) is NoParam to return True. Is there a way to do this (perhaps with metaclasses)?
To take it even further: is there anything I can do to ensure that only one instance of NoParam is ever created?
Solution
Big thanks to @user2357112 for answering the question about pickling. I've also figured out how to make this class robust to module reloading as well. Here is what I've learned all put together
# -*- coding: utf-8 -*-
# util_const.py    
class _NoParamType(object):
    """
    Class used to define `NoParam`, a setinal that acts like None when None
    might be a valid value. The value of `NoParam` is robust to reloading,
    pickling, and copying.  
    Example:
        >>> import util_const
        >>> from util_const import _NoParamType, NoParam
        >>> from six.moves import cPickle as pickle
        >>> import copy
        >>> versions = {
        ... 'util_const.NoParam': util_const.NoParam,
        ... 'NoParam': NoParam,
        ... '_NoParamType()': _NoParamType(),
        ... 'copy': copy.copy(NoParam),
        ... 'deepcopy': copy.deepcopy(NoParam),
        ... 'pickle': pickle.loads(pickle.dumps(NoParam))
        ... }
        >>> print(versions)
        >>> assert all(id(v) == id_ for v in versions.values())
        >>> import imp
        >>> imp.reload(util_const)
        >>> assert id(NoParam) == id(util_const.NoParam)
    """
    def __new__(cls):
        return NoParam
    def __reduce__(self):
        return (_NoParamType, ())
    def __copy__(self):
        return NoParam
    def __deepcopy__(self, memo):
        return NoParam
    def __call__(self, default):
        pass
# Create the only instance of _NoParamType that should ever exist
# When the module is first loaded, globals() will not contain NoParam. A
# NameError will be thrown, causing the first instance of NoParam to be
# instanciated.
# If the module is reloaded (via imp.reload), globals() will contain
# NoParam. This skips the code that would instantiate a second object
# Note: it is possible to hack around this via
# >>> del util_const.NoParam
# >>> imp.reload(util_const)
try:
    NoParam
except NameError:
    NoParam = object.__new__(_NoParamType)
 
     
     
    