pythonconstructorsetfrozenset

Extending FrozenSet from typing


I'm probably doing something dumb here. For those of you who want to copy and paste, make sure that you:

from typing import *

I'm using Python 3.7.4.

This:

class S(FrozenSet[str]):
    def __init__(self, strs: Iterable[str], name: str):
            super().__init__(strs)
            self.name = name

S(['a'], 'a')

raises an error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: S expected at most 1 arguments, got 2

, but this:

class S(Set[str]):
    def __init__(self, strs: Iterable[str], name: str):
            super().__init__(strs)
            self.name = name

S(['a'], 'a')

outputs just fine:

S({'a'})

I want the extra functionality of a set, but I don't want my users to change it.

EDIT: I know I could just use composition over inheritance, but it would be nice if I could make this work as well.


Solution

  • As it's a frozenset, once created, you can't modify its content.

    Therefore, I think you should override __new__:

    class S(FrozenSet[str]):
        def __new__(cls, strs: Iterable[str], name: str):
            return super(S, cls).__new__(cls, strs)
    
        def __init__(self, strs: Iterable[str], name: str):
            self.name = name