Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of checking self.__class__?

What is the purpose of checking self.__class__ ? I've found some code that creates an abstract interface class and then checks whether its self.__class__ is itself, e.g.

class abstract1 (object):   def __init__(self):     if self.__class__ == abstract1:        raise NotImplementedError("Interfaces can't be instantiated") 

What is the purpose of that? Is it to check whether the class is a type of itself?

The code is from NLTK's http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability-pysrc.html#ProbDistI

like image 450
alvas Avatar asked Dec 15 '13 20:12

alvas


People also ask

What is __ self __ in Python?

self represents the instance of the class. By using the “self” we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason you need to use self. is because Python does not use the @ syntax to refer to instance attributes.

What is the purpose of self in Python?

The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.

What is __ bases __ in Python?

Python provides a __bases__ attribute on each class that can be used to obtain a list of classes the given class inherits. The __bases__ property of the class contains a list of all the base classes that the given class inherits.

What is __ new __ in Python?

The __new__() is a static method of the object class. When you create a new object by calling the class, Python calls the __new__() method to create the object first and then calls the __init__() method to initialize the object's attributes.


1 Answers

self.__class__ is a reference to the type of the current instance.

For instances of abstract1, that'd be the abstract1 class itself, which is what you don't want with an abstract class. Abstract classes are only meant to be subclassed, not to create instances directly:

>>> abstract1() Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "<stdin>", line 4, in __init__ NotImplementedError: Interfaces can't be instantiated 

For an instance of a subclass of abstract1, self.__class__ would be a reference to the specific subclass:

>>> class Foo(abstract1): pass ...  >>> f = Foo() >>> f.__class__ <class '__main__.Foo'> >>> f.__class__ is Foo True 

Throwing an exception here is like using an assert statement elsewhere in your code, it protects you from making silly mistakes.

Note that the pythonic way to test for the type of an instance is to use the type() function instead, together with an identity test with the is operator:

class abstract1(object):     def __init__(self):         if type(self) is abstract1:              raise NotImplementedError("Interfaces can't be instantiated") 

type() should be preferred over self.__class__ because the latter can be shadowed by a class attribute.

There is little point in using an equality test here as for custom classes, __eq__ is basically implemented as an identity test anyway.

Python also includes a standard library to define abstract base classes, called abc. It lets you mark methods and properties as abstract and will refuse to create instances of any subclass that has not yet re-defined those names.

like image 131
Martijn Pieters Avatar answered Sep 28 '22 01:09

Martijn Pieters