The duplication of code here makes me wonder if there is not a more elegant way to do this. Eg, what do you think of this? (Not tested)

<code>
newCard = Card();
for (property, attribute) in zip([NUMBERS, COLOURS, FILLINGS, SHAPES],["number", "colour", "filling", "shape"]):
    newAttribute = findMatchingAttribute(getattr(card1,attribute),getattr(card2,attribute), property)
    setattr(newCard, attribute, newAttribute)
return newCard
</code>

With corresponding helper function
<code>
def findMatchingAttribute(a1, a2, property):
    if a1 == a2:
        return a1
    else:
        return (set(property) ^ {a1, a2}).pop()
</code>