I'm not going to speak to why multiple tuple unpacking isn't part of Python, but I will point out that you're not matching your class to your data in your example.
You have the following code:
point = (1, 2)
size = (2, 3)
color = 'red'
class Rect(object):
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
but a better way to express your Rect object would be as follows:
class Rect:
def __init__(self, point, size, color):
self.point = point
self.size = size
self.color = color
r = Rect(point, size, color)
In general, if your data is in tuples, have your constructor take tuples. If your data is in a dict, have your constructor take a dict. If your data is an object, have your constructor take an object, etc.
In general, you want to work with the idioms of the language, rather than try to work around them.
EDIT
Seeing how popular this question is, I'll give you an decorator that allows you to call the constructor however you like.
class Pack(object):
def __init__(self, *template):
self.template = template
def __call__(self, f):
def pack(*args):
args = list(args)
for i, tup in enumerate(self.template):
if type(tup) != tuple:
continue
for j, typ in enumerate(tup):
if type(args[i+j]) != typ:
break
else:
args[i:i+j+1] = [tuple(args[i:i+j+1])]
f(*args)
return pack
class Rect:
@Pack(object, (int, int), (int, int), str)
def __init__(self, point, size, color):
self.point = point
self.size = size
self.color = color
Now you can initialize your object any way you like.
r1 = Rect(point, size, color)
r2 = Rect((1,2), size, color)
r3 = Rect(1, 2, size, color)
r4 = Rect((1, 2), 2, 3, color)
r5 = Rect(1, 2, 2, 3, color)
While I wouldn't recommend using this in practice (it violates the principle that you should have only one way to do it), it does serve to demonstrate that there's usually a way to do anything in Python.