I defined an immutable class as explained here. Now I'd like to define a copy method that transfers all properties of a given instance to a new instance and that allows to provide new values for any of the existing properties.
This is what I have:
from operator import itemgetter
class Foo(tuple):
    __slots__ = []
    def __new__(cls, a, b, c):
        return tuple.__new__(cls, (a, b, c))
    a = property(itemgetter(0))
    b = property(itemgetter(1))
    c = property(itemgetter(2))
    def copy(self, a='', b='', c=''):
        return Foo(
            a=a if a else self.a,
            b=b if b else self.b,
            c=c if c else self.c,
        )
Desired behaviour:
instance_a = Foo('a', 'b', 'c')
instance_b = instance_a.copy(c='d')
assert instance_b.a == 'a'
assert instance_b.b == 'b'
assert instance_b.c == 'd'
Question:
Is there a more elegant way to pick between the new and existing properties other than the if else construct (i.e., a=a if a else self.a)?
 
     
    