Home > database >  How to add method to base class?
How to add method to base class?

Time:02-01

I want to add __add__ and __radd__ to the python base class set.

The code can be as simple as

def __add__(self, other) :
    assert isinstance(other, set), \
        "perhaps additional type checking or argument validation can go here but"   \
        " strictly only defined for pure python sets"
    return set( list(self)   list(other) )

def __radd__(self, other) :
    assert isinstance(other, set), \
        "perhaps additional type checking or argument validation can go here but"   \
        " strictly only defined for pure sets"
    return set( list(other)   list(self) )

What is the pythonic implementation of this and how can I extend the base class without creating my own MySet class that takes set as a parent class? Can I just use set.__add__ = some_function_I_defined?

CodePudding user response:

What you should do imho is subclass the built-in set class. In Python (contrary to e.g. Ruby or JavaScript) monkey-patching a built-in is not allowed.

So e.g. trying to add a non-existent method:

x = [1,2,3]
x.my_new_method_added_in_runtime = lambda: "whatever"

is not going to work, you'd get AttributeError: 'list' object has no attribute 'my_new_method_added_in_runtime'

You cannot also modify the existing methods of objects instantiated using those built-ins:

x = [1,2,3]
x.sort = lambda: "returning some string instead of sorting..."

will result in AttributeError: 'list' object attribute 'sort' is read-only

And

list.append = None
# OR
del list.append

will result in: TypeError: can't set attributes of built-in/extension type 'list'

All of the above is true for set as well an so on.

You could try to look for some libraries to achieve that e.g. https://pypi.org/project/forbiddenfruit/0.1.0/, but it's strongly discouraged.

CodePudding user response:

@chepner correctly answered my question without realizing it. I was trying to reimplement already existing functionality since I was not familiar with python sets.

The act of joining two sets, 'taking their union' is implemented with the python __or__ and __ior__ methods. The operation I needed specifically was | and |=.

In principle we should be able to set operations as chepner suggested with set.__add__ = set.__or__, but as chepner points out this results in an error:

TypeError: cannot set '__add__' attribute of immutable type 'set'

Thank you all.

  • Related