Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherit namedtuple from a base class in python

Is it possible to produce a namedtuple which inherits from a base class?

What I want is that Circle and Rectangle are namedtuples and are inherited from a common base class ('Shape'):

from collections import namedtuple

class Shape:
    def addToScene(self, scene):
         ...

Circle=namedtuple('Circle', 'x y radius')
Rectangle=namedtuple('Rectangle', 'x1 y1 x2 y2')

How would I do that?

like image 879
Günther Jena Avatar asked Aug 23 '16 10:08

Günther Jena


People also ask

How do I get values from NamedTuple?

From NamedTuple, we can access the values using indexes, keys and the getattr() method. The attribute values of NamedTuple are ordered. So we can access them using the indexes. The NamedTuple converts the field names as attributes.

Can you subclass NamedTuple?

Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj.

Is NamedTuple a class?

NamedTuple . The class created from typing.

What is the difference between tuple and NamedTuple?

Tuples are immutable, whether named or not. namedtuple only makes the access more convenient, by using names instead of indices. You can only use valid identifiers for namedtuple , it doesn't perform any hashing — it generates a new type instead.


2 Answers

You can try this:

class Circle(Shape, namedtuple('Circle', 'x y radius')):

    pass

(You should consider adding __slots__ to all your three classes to save memory and for sightly faster lookups.)

like image 127
Andrea Corbellini Avatar answered Sep 28 '22 04:09

Andrea Corbellini


For anyone looking for a way to implement an immutable type that derives from another type, a frozen dataclass or attrs might be a better option than a namedtuple.

An example using dataclass:

class Base:
    def fun(self):
        print('Base()')


@dataclass(frozen=True)
class MyType(Base):
    x: int

This way, you can call fun() on a MyType instance:

my_type = MyType([1, 2])
my_type.fun()

But cannot assign to its members:

my_type = MyType([1, 2])
#my_type.x = [10, 20]

Note that mutable members can still be modified:

my_type = MyType([1, 2])
my_type.x[0] = 10
like image 45
lambdakappatheta Avatar answered Sep 28 '22 04:09

lambdakappatheta