nerdfever.com
nerdfever.com

Reputation: 1782

Create tuple-like object with additional attributes?

Is there a Pythonic way to create a tuple-like object (that acts like a tuple) but with additional attributes? In particular with a __name__ attribute?

Right now I do something like this:

foo = ( 1, 9, (12.5, "bar"), "baz" )
foo.__name__ = 'foo'

But that isn't very Pythonic, I think. I can't pass foo (the first line with the tuple assignment) to a function, and have the function create the __name__.

What's the Pythonic way?

I'm looking for something like:

bar = new_kind_of_thing(( 1, 9, (12.5, "floob"), "baz" ))
print(bar[2])
print(bar[0])
print(bar.__name__)

That outputs:

(12.5, 'floob')
1
'bar'

Upvotes: 0

Views: 2366

Answers (4)

Lev Zakharov
Lev Zakharov

Reputation: 2427

Just create new class that inherits from tuple and override __new__ and __init__ methods:

class MyTuple(tuple):
    def __new__(cls, name, values):
        return super().__new__(cls, values)

    def __init__(self, name, values):
        self.__name__ = name
        self.values = values

foo = MyTuple('foo', (1, 2, 3))

print(foo)
print(foo.__name__)

Output:

(1, 2, 3)
'foo'

Upvotes: 5

Schalton
Schalton

Reputation: 3104

Yes, you can do this with a "mapping" -- to create a custom class with attributes of others.

Resource: http://www.kr41.net/2016/03-23-dont_inherit_python_builtin_dict_type.html

IMO, I don't think that's really what you want.

You're likely better off with a more complex data structure, a dictionary of tuples for instance.

my_tuples = {
     "tuple1":(1,2,3),
     "tuple2":(3,5,6),
}

or (comment construction)

my_tuples = {}
my_tuples["tuple1"] = (1, 2, 3)
my_tuples["tuple2"] = (4, 5, 6)

This will allow you to interact with the tuples by 'name'

print(my_tuples["tuple1"])
(1,2,3)

Upvotes: 0

Hai Vu
Hai Vu

Reputation: 40773

How about something as simple as this:

class TupleWithName(tuple):
    pass

t = TupleWithName((1, 2, 3))
t.name = 'tuple one'

print(t)
# (1, 2, 3)

print(t.name)
# 'tuple one'

Upvotes: 1

Fedor
Fedor

Reputation: 1444

Use namedtuple (https://docs.python.org/3/library/collections.html#collections.namedtuple)

from collections import namedtuple
Foo = namedtuple('Foo', ['x', 'y', 'pair', 'title'])
foo = Foo(1, 9, (12.5, "bar"), "baz") # foo.x == 1, foo.y == 9, etc
bar = Foo(2, 10, (11., "abc"), "zzz")

Upvotes: 1

Related Questions