Python Default Inheritance? - python

If I define a class in Python such as:
class AClass:
__slots__ = ['a', 'b', 'c']
Which class does it inherit from? It doesn't seem to inherit from object.

If you define a class and don't declare any specific parent, the class becomes a "classic class", which behaves a bit differently than "new-style classes" inherited from object. See here for more details: http://docs.python.org/release/2.5.2/ref/node33.html
Classic classes don't have a common root, so essentially, your AClass doesn't inherit from any class.
Note that this is specific to Python versions before 3.0. In Python 3, all classes are new-style classes and inherit implicitly from object, if no other parent is declared.

Try the following code snippet in Python 2.7 and Python 3.1
class AClass:
__slots__ = ['a', 'b', 'c']
print(type(AClass))
print(issubclass(AClass,object))
print(isinstance(AClass,type))
In Python 2.7, you will get:
<type 'classobj'>
False
False
And Python 3.1 you will get.
<class type>
True
True
And that explains it all. It is old style class in Python 2, unless you subclass it from object. Only in Python3, it will be treated like a new style class by default.

Let's try it out.
>>> class AClass:
... pass
...
>>> AClass.__bases__, type(AClass)
( (), <type 'classobj'> ) # inherits from nothing
>>> class AClass(object): # new style inherits from object
... pass
...
>>> AClass.__bases__, type(AClass)
( (<type 'object'>,), <type 'type'> )
Read an introduction to the new style classes in the links given in other answers.

In Python 2.x or older, your example AClass is an "old-style" class.
A "new-style" class has a defined inheritance and must inherit from object or some other class.
What is the difference between old style and new style classes in Python?
EDIT: Wow, I didn't think it was possible to use the old-style syntax in Python 3.x. But I just tried it and that syntax still works. But you get a new-style class.

Related

Python property and Python property setters type modified

I am a python beginner and I am stuck in #property and #property. setter decorator.
I want to add some data to a dictionary named __content with the use of a setter.
This is my try, but when I run this script, only the last element is added to the dictionary!
So what am I missing here!
class Something:
def __init__(self,elem):
self.__content={}
self.__content.update(elem)
print type(self.__content)
#property
def content(self):
return self.__content
#content.setter
def content(self,elem):
self.__content.update(elem)
And
from transpose import Something
c=Something(dict(one=4))
print c.content
c.content=dict(two=6)
print c.content
The result
/usr/bin/python /home/radouani/PycharmProjects/demoPython/test.py
<type 'dict'>
{'one': 4}
<type 'dict'>
{'two': 6}
Process finished with exit code 0
Another problem : I don't understand why python change the type of __content when I try to affect a tuple or integer with the use of the setter?
Cordially
Properties don't work on old style classes. You have to inherit from object to create a new style class:
class Something(object):
...
From property doc:
class property([fget[, fset[, fdel[, doc]]]])
Return a property attribute for new-style classes (classes that derive from object).
As mentioned previously, properties don't work on "old style" classes. You have to inherit from object to create a new style class in Python 2.x for properties to work.
class Something(object):
#stuff
In Python 3.x, this will happen for you -- All classes in Python3 are "New Style" classes. "New Style" classes are also implemented in Python2, but because it would otherwise change functionality for "old style" classes, you have to 'opt-in' to using New Style classes in Python2 by inheriting from object.
Even though this happens implicitly and automatically in Python3, it's still preferred, but not required, that you do this inheritance from object explicitly for backwards compatibility.
A great resources for developing classes: Raymond Hettinger - Python's Class Development Toolkit

Should all Python classes extend object? [duplicate]

This question already has answers here:
Why do Python classes inherit object?
(6 answers)
Closed 1 year ago.
I have found that both of the following work:
class Foo():
def a(self):
print "hello"
class Foo(object):
def a(self):
print "hello"
Should all Python classes extend object? Are there any potential problems with not extending object?
In Python 2, not inheriting from object will create an old-style class, which, amongst other effects, causes type to give different results:
>>> class Foo: pass
...
>>> type(Foo())
<type 'instance'>
vs.
>>> class Bar(object): pass
...
>>> type(Bar())
<class '__main__.Bar'>
Also the rules for multiple inheritance are different in ways that I won't even try to summarize here. All good documentation that I've seen about MI describes new-style classes.
Finally, old-style classes have disappeared in Python 3, and inheritance from object has become implicit. So, always prefer new style classes unless you need backward compat with old software.
In Python 3, classes extend object implicitly, whether you say so yourself or not.
In Python 2, there's old-style and new-style classes. To signal a class is new-style, you have to inherit explicitly from object. If not, the old-style implementation is used.
You generally want a new-style class. Inherit from object explicitly. Note that this also applies to Python 3 code that aims to be compatible with Python 2.
In python 3 you can create a class in three different ways & internally they are all equal (see examples). It doesn't matter how you create a class, all classes in python 3 inherits from special class called object. The class object is fundamental class in python and provides lot of functionality like double-underscore methods, descriptors, super() method, property() method etc.
Example 1.
class MyClass:
pass
Example 2.
class MyClass():
pass
Example 3.
class MyClass(object):
pass
Yes, all Python classes should extend (or rather subclass, this is Python here) object. While normally no serious problems will occur, in some cases (as with multiple inheritance trees) this will be important. This also ensures better compatibility with Python 3.
As other answers have covered, Python 3 inheritance from object is implicit. But they do not state what you should do and what is convention.
The Python 3 documentation examples all use the following style which is convention, so I suggest you follow this for any future code in Python 3.
class Foo:
pass
Source: https://docs.python.org/3/tutorial/classes.html#class-objects
Example quote:
Class objects support two kinds of operations: attribute references
and instantiation.
Attribute references use the standard syntax used for all attribute
references in Python: obj.name. Valid attribute names are all the
names that were in the class’s namespace when the class object was
created. So, if the class definition looked like this:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
Another quote:
Generally speaking, instance variables are for data unique to each
instance and class variables are for attributes and methods shared by
all instances of the class:
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
in python3 there isn't a differance, but in python2 not extending object gives you an old-style classes; you'd like to use a new-style class over an old-style class.

Listing children of an ABC in Django

I am using Django 1.3.1 and I have the following piece of models:
class masterData(models.Model):
uid = models.CharField(max_length=20,primary_key=True)
class Meta:
abstract = True;
class Type1(masterData):
pass;
class Type2(masterData):
pass;
Now, I am trying to get a list of all child classes of masterData. I
have tried:
masterData.__subclasses__()
The very interesting thing that I found about the above is that it
works flawlessly in python manage.py shell and does not work at all
when running the webserver!
So how do I get a list of models derived from an Abstract Base Class model?
Thanks :)
Metaclass for defining Abstract Base Classes (ABCs).
Use this metaclass to create an ABC. An ABC can be subclassed directly, and then acts as a mix-in
class. You can also register unrelated concrete classes (even built-in classes) and unrelated ABCs
as 'virtual subclasses' -- these and their descendants will be considered subclasses of the
registering ABC by the built-in issubclass() function, but the registering ABC won't show up in
their MRO (Method Resolution Order) nor will method implementations defined by the registering
ABC be callable (not even via super()).
I haven't used ABCMeta much (have a bit today actually..). You need to use the 'issubclass()' function
since the ABC won't show up in they're mro.
If you used inheritance, subclasses() would work.
>>> class foo(object):
... pass
...
>>> class bar(foo):
... pass
...
>>> a = bar()
>>> a.__class__.__mro__
(<class '__main__.bar'>, <class '__main__.foo'>, <type 'object'>)
>>> foo.__subclasses__()
[<class '__main__.bar'>]

Why do Python classes inherit object?

Why does the following class declaration inherit from object?
class MyClass(object):
...
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:
"classic" style classes: they don't have object as a base class:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
"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__
(<type 'object'>,)
>>> class IntSpam(int): # indirectly inherit from object...
... pass
>>> IntSpam.__bases__
(<type 'int'>,)
>>> IntSpam.__bases__[0].__bases__ # ... because int inherits from object
(<type '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:
classmethod: A method that receives the class as an implicit argument instead of the instance.
staticmethod: A method that does not receive the implicit argument self as a first argument.
properties with property: Create functions for managing the getting, setting and deleting of an attribute.
__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.
Python 3
class MyClass(object): = New-style class
class MyClass: = New-style class (implicitly inherits from object)
Python 2
class MyClass(object): = New-style class
class MyClass: = OLD-STYLE CLASS
Explanation:
When defining base classes in Python 3.x, you’re allowed to drop the object from the definition. However, this can open the door for a seriously hard to track problem…
Python introduced new-style classes back in Python 2.2, and by now old-style classes are really quite old. Discussion of old-style classes is buried in the 2.x docs, and non-existent in the 3.x docs.
The problem is, the syntax for old-style classes in Python 2.x is the same as the alternative syntax for new-style classes in Python 3.x. Python 2.x is still very widely used (e.g. GAE, Web2Py), and any code (or coder) unwittingly bringing 3.x-style class definitions into 2.x code is going to end up with some seriously outdated base objects. And because old-style classes aren’t on anyone’s radar, they likely won’t know what hit them.
So just spell it out the long way and save some 2.x developer the tears.
Yes, this is a 'new style' object. It was a feature introduced in python2.2.
New style objects have a different object model to classic objects, and some things won't work properly with old style objects, for instance, super(), #property and descriptors. See this article for a good description of what a new style class is.
SO link for a description of the differences: What is the difference between old style and new style classes in Python?
History from Learn Python the Hard Way:
Python's original rendition of a class was broken in many serious
ways. By the time this fault was recognized it was already too late,
and they had to support it. In order to fix the problem, they needed
some "new class" style so that the "old classes" would keep working
but you can use the new more correct version.
They decided that they would use a word "object", lowercased, to be
the "class" that you inherit from to make a class. It is confusing,
but a class inherits from the class named "object" to make a class but
it's not an object really its a class, but don't forget to inherit
from object.
Also just to let you know what the difference between new-style classes and old-style classes is, it's that new-style classes always inherit from object class or from another class that inherited from object:
class NewStyle(object):
pass
Another example is:
class AnotherExampleOfNewStyle(NewStyle):
pass
While an old-style base class looks like this:
class OldStyle():
pass
And an old-style child class looks like this:
class OldStyleSubclass(OldStyle):
pass
You can see that an Old Style base class doesn't inherit from any other class, however, Old Style classes can, of course, inherit from one another. Inheriting from object guarantees that certain functionality is available in every Python class. New style classes were introduced in Python 2.2
Yes, it's historical. Without it, it creates an old-style class.
If you use type() on an old-style object, you just get "instance". On a new-style object you get its class.
The syntax of the class creation statement:
class <ClassName>(superclass):
#code follows
In the absence of any other superclasses that you specifically want to inherit from, the superclass should always be object, which is the root of all classes in Python.
object is technically the root of "new-style" classes in Python. But the new-style classes today are as good as being the only style of classes.
But, if you don't explicitly use the word object when creating classes, then as others mentioned, Python 3.x implicitly inherits from the object superclass. But I guess explicit is always better than implicit (hell)
Reference

Python 'object' type and inheritance

In Python I can define a class 'foo' in the following ways:
class foo:
pass
or
class foo(object):
pass
What is the difference? I have tried to use the function issubclass(foo, object) to see if it returns True for both class definitions. It does not.
IDLE 2.6.3
>>> class foo:
pass
>>> issubclass(foo, object)
False
>>> class foo(object):
pass
>>> issubclass(foo, object)
True
Thanks.
Inheriting from object makes a class a "new-style class". There is a discussion of old-style vs. new-style here: What is the difference between old style and new style classes in Python?
As #CrazyJugglerDrummer commented below, in Python 3 all classes are "new-style" classes. In Python 3, the following two declarations are exactly equivalent:
class A(object):
pass
class A:
pass
The first creates an "old-style" class, which are deprecated and have been removed in Python 3. You should not use it in Python 2.x. See the documentation for the Python data model.
Old style and new style objects... they have sightly different behaviours, for example in the constructors, or in the method resolution order in multiple inheritance.

Categories