Domanda

Is it a good idea to use __class__ to create new instances within the class?

The following code is an example of doing this:

from collections import namedtuple

_Position = namedtuple('Position', ['x', 'y'])
class Position(_Position):
    def __add__(self, other):
        return __class__(self.x + other.x, self.y + other.y)

Using the actual class name sounds like duplicated code to me. If the name of the class changes I'd have to change it in all occurrences, even though modern IDE's can do that for you.

btw. What kind of variable is __class__? Shouldn't you only be able to access it with self.?

È stato utile?

Soluzione

To support the zero-argument form of super(), the compiler adds an implicit reference to the class if __class__ or super() are being used in a class method. See Creating the class object.

The example code you found (ab)uses this little factoid to create new instances of Position when adding.

Personally, I'd use type(self) instead, as that is the proper API method of determining the type or class of any object. type(self) will use self.__class__ where appropriate:

def __add__(self, other):
    return type(self)(self.x + other.x, self.y + other.y)

That is a good idea if you want to support subclassing. Any subclasses of Position will return the correct subclassed type when being added together. Using __class__ does not do that, as it will always be pointing to Position, even for subclasses:

>>> class Foo:
...     def method(self):
...         print(__class__)
...         print(type(self))
... 
>>> class Bar(Foo):
...     pass
... 
>>> Bar().method()
<class '__main__.Foo'>
<class '__main__.Bar'>

Of course, if that was your intention all along (to bypass subclasses), I'd still prefer using the explict class name over using __class__; explicit is better than implicit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top