Search code examples
pythonclassbuilt-in

Custom set class gets overwritten/set back to builtin when updating it


I have a custom set class that can read and write to a file and otherwise should behave like a normal set.

class FileSet(set):
    def __init__(self, file):
        self.file = file
        self.elements = {line.strip() for line in open(self.file, "r")}
        super().__init__(self.elements)

    def load(self):
        self.elements = {line.strip() for line in open(self.file, "r")}
        super().__init__(self.elements)

    def save(self):
        with open(self.file, "w") as f:
            f.write("\n".join(list(self)))

When using -= and |= in combination with other FileSet objects, they remain FileSets. When updating with a set however, they change into a normal set again and my custom methods cease to work. print(type(obj)) will say <class '__main__.FileSet'> before updating with a set and <class 'set'> after.

Is there a way to fix that?

EDIT: The issue was only when updating the FileSet with a dict.keys() (<class 'dict_keys'>) set... Works fine otherwise and can be fixed by enclosing the dict.keys() with set(dict.keys())

EDIT: thanks everyone and especially to @chepner :)

Cheers, julius


Solution

  • I typed up a quick example of the issue and its solution set(dict.keys()) here:

    dictionary = {"apple": ["fruit", "company"], "house": ["building", "famous doctor"]}
    >>> f = FileSet("queue")
    >>> print(f)
    FileSet({'jumbo', 'dumbo'})
    >>> type(f)
    <class '__main__.FileSet'>
    >>> f |= set(dictionary.keys())
    >>> type(f)
    <class '__main__.FileSet'>
    >>> f
    FileSet({'house', 'jumbo', 'dumbo', 'apple'})
    >>> f |= dictionary.keys()
    >>> type(f)
    <class 'set'>