What is the difference between class Foo(): and class Date(object):
Steve D'Aprano
steve+python at pearwood.info
Mon Nov 21 09:13:28 EST 2016
On Mon, 21 Nov 2016 11:15 pm, Veek M wrote:
>>>> class Foo():
> ... pass
> ...
>>>> class Bar(Foo):
> ... pass
> ...
>>>> b = Bar()
>>>> type(b)
> <type 'instance'>
[...]
> What is going on here? Shouldn't x = EuroDate(); type(x) give
> 'instance'?? Why is 'b' an 'instance' and 'x' EuroDate?
> Why isn't 'b' Bar?
It looks like you are running Python 2, and have stumbled across an
annoyance from the earliest days of Python: the "classic", or "old-style",
class.
Before Python 2.2, custom classes and built-in types like int, float, dict
and list were different. You have just discovered one of the ways they were
different: instances of custom classes all had the same type, even if the
class was different:
# Python 2
py> class Dog:
... pass
...
py> class Cat:
... pass
...
py> lassie = Dog()
py> garfield = Cat()
py> type(lassie) is type(garfield)
True
py> type(lassie)
<type 'instance'>
This is just the most obvious difference between "classic classes" and
types. Some of the other differences:
- The method resolution order (MRO) is different: the classic class
MRO is buggy for diamond-shaped multiple inheritance, and special
dunder methods like __eq__ are resolved slightly differently.
- super, properties, class methods and static methods don't work for
classic classes.
- The metaclass of classic classes is different:
py> type(Dog)
<type 'classobj'>
py> type(float)
<type 'type'>
- Attribute lookup for classic classes is slightly different; in
particular, the special __getattribute__ method doesn't work.
In Python 2.2, the built-in types (list, dict, float etc) were unified with
the class mechanism, but for backwards compatibility the old-style classes
had to be left in. So Python had two class mechanisms:
- "New-style classes", or types, inherit from object, or some
other built-in type, and support properties, etc.
- "Old-style classes", don't inherit from object, don't support
properties etc.
So in Python 2, when you write:
class Foo:
or
class Foo():
you get an old-style class. But when you inherit from object, you get a
new-style class. Classic classes are an obsolete feature from Python 2.
They are removed in Python 3, and things are much simpler. In Python 3, it
doesn't matter whether you write:
class Foo:
class Foo():
class Foo(object):
the result is the same: a new-style class, or type.
The best thing to do in Python 2 is to always, without exception, write
class Foo(object):
to define your base classes. That will ensure that property, super,
classmethod, staticmethod, __getattribute__, etc. will all work correctly,
and you will avoid the surprises of classic classes.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list