def copiable(fields=None):
    """A class decorator factory that adds a copy method to the class.

    If fields is not passed, the following a tried in order:

    1. cls.__all__
    2. cls._fields
    3. the parameters of cls.__init__
    4. the parameters of cls.__new__

    """
    if isinstance(fields, type):
        return copiable(None)(fields)

    if isinstance(fields, str):
        fields = fields.replace(',', ' ').split()

    def decorator(cls):
        """Return the class after adding the copy() method."""
        names = fields
        if names is None:
            names = getattr(cls, '__all__',
                            getattr(cls, '_fields',
                                    get_init_params(cls)))
        if names is None:
            raise TypeError("could not determine the fields for this class.")

        def copy(self, **kwargs):
            """Return a copy of this object, with updates."""
            ns = dict((name, getattr(self, name)) for name in names)
            ns.update(kwargs)
            return type(self)(**ns)

        method_name = '_copy' if 'copy' in names else 'copy'
        if hasattr(cls, method_name):
            raise TypeError("{!r} already exists on the class")
        setattr(cls, method_name, copy)
        return cls
    return decorator
A class decorator factory that adds a copy method to the class.

    If fields is not passed, the following a tried in order:

    1. cls.__all__
    2. cls._fields
    3. the parameters of cls.__init__
    4. the parameters of cls.__new__

    
recipes/Python/578457_Class_Decorator_that_Adds_copy/recipe-578457.py