Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python's equivalent of .Net's sealed class

Does python have anything similar to a sealed class? I believe it's also known as final class, in java.

In other words, in python, can we mark a class so it can never be inherited or expanded upon? Did python ever considered having such a feature? Why?

Disclaimers

Actually trying to understand why sealed classes even exist. Answer here (and in many, many, many, many, many, really many other places) did not satisfy me at all, so I'm trying to look from a different angle. Please, avoid theoretical answers to this question, and focus on the title! Or, if you'd insist, at least please give one very good and practical example of a sealed class in csharp, pointing what would break big time if it was unsealed.

I'm no expert in either language, but I do know a bit of both. Just yesterday while coding on csharp I got to know about the existence of sealed classes. And now I'm wondering if python has anything equivalent to that. I believe there is a very good reason for its existence, but I'm really not getting it.

like image 216
cregox Avatar asked May 15 '13 11:05

cregox


People also ask

Does Python have sealed classes?

This tells me the answer would actually be "no, python doesn't implement sealed classes, but you still can hack your own".

Can we override sealed class?

No - in order to override a method, you have to derive from it, which you can't do when the class is sealed. Basically, you need to revisit your design to avoid this requirement...

Can we mark methods as sealed?

A method can also be sealed, and in that case, the method cannot be overridden. However, a method can be sealed in the classes in which they have been inherited. If you want to declare a method as sealed, then it has to be declared as virtual in its base class.

Can sealed class have virtual methods?

A sealed class cannot be used as a base class, and a virtual method has to be implemented in a derived class, which is a contradiction.


1 Answers

You can use a metaclass to prevent subclassing:

class Final(type):
    def __new__(cls, name, bases, classdict):
        for b in bases:
            if isinstance(b, Final):
                raise TypeError("type '{0}' is not an acceptable base type".format(b.__name__))
        return type.__new__(cls, name, bases, dict(classdict))

class Foo:
    __metaclass__ = Final

class Bar(Foo):
    pass

gives:

>>> class Bar(Foo):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __new__
TypeError: type 'Foo' is not an acceptable base type

The __metaclass__ = Final line makes the Foo class 'sealed'.

Note that you'd use a sealed class in .NET as a performance measure; since there won't be any subclassing methods can be addressed directly. Python method lookups work very differently, and there is no advantage or disadvantage, when it comes to method lookups, to using a metaclass like the above example.

like image 143
Martijn Pieters Avatar answered Oct 08 '22 11:10

Martijn Pieters