Python class inherits object

后端 未结 6 1037
慢半拍i
慢半拍i 2020-11-21 15:54

Is there any reason for a class declaration to inherit from object?

I just found some code that does this and I can\'t find a good reason why.



        
6条回答
  •  爱一瞬间的悲伤
    2020-11-21 16:31

    Is there any reason for a class declaration to inherit from object?

    In Python 3, apart from compatibility between Python 2 and 3, no reason. In Python 2, many reasons.


    Python 2.x story:

    In Python 2.x (from 2.2 onwards) there's two styles of classes depending on the presence or absence of object as a base-class:

    1. "classic" style classes: they don't have object as a base class:

      >>> class ClassicSpam:      # no base class
      ...     pass
      >>> ClassicSpam.__bases__
      ()
      
    2. "new" style classes: they have, directly or indirectly (e.g inherit from a built-in type), object as a base class:

      >>> class NewSpam(object):           # directly inherit from object
      ...    pass
      >>> NewSpam.__bases__
      (,)
      >>> class IntSpam(int):              # indirectly inherit from object...
      ...    pass
      >>> IntSpam.__bases__
      (,) 
      >>> IntSpam.__bases__[0].__bases__   # ... because int inherits from object  
      (,)
      

    Without a doubt, when writing a class you'll always want to go for new-style classes. The perks of doing so are numerous, to list some of them:

    • Support for descriptors. Specifically, the following constructs are made possible with descriptors:

      1. classmethod: A method that receives the class as an implicit argument instead of the instance.
      2. staticmethod: A method that does not receive the implicit argument self as a first argument.
      3. properties with property: Create functions for managing the getting, setting and deleting of an attribute.
      4. __slots__: Saves memory consumptions of a class and also results in faster attribute access. Of course, it does impose limitations.
    • The __new__ static method: lets you customize how new class instances are created.

    • Method resolution order (MRO): in what order the base classes of a class will be searched when trying to resolve which method to call.

    • Related to MRO, super calls. Also see, super() considered super.

    If you don't inherit from object, forget these. A more exhaustive description of the previous bullet points along with other perks of "new" style classes can be found here.

    One of the downsides of new-style classes is that the class itself is more memory demanding. Unless you're creating many class objects, though, I doubt this would be an issue and it's a negative sinking in a sea of positives.


    Python 3.x story:

    In Python 3, things are simplified. Only new-style classes exist (referred to plainly as classes) so, the only difference in adding object is requiring you to type in 8 more characters. This:

    class ClassicSpam:
        pass
    

    is completely equivalent (apart from their name :-) to this:

    class NewSpam(object):
         pass
    

    and to this:

    class Spam():
        pass
    

    All have object in their __bases__.

    >>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
    [True, True, True]
    

    So, what should you do?

    In Python 2: always inherit from object explicitly. Get the perks.

    In Python 3: inherit from object if you are writing code that tries to be Python agnostic, that is, it needs to work both in Python 2 and in Python 3. Otherwise don't, it really makes no difference since Python inserts it for you behind the scenes.

提交回复
热议问题