Reputation: 79
What is the difference between these two class declarations? What does "object" do?
class className(object):
pass
class className:
pass
Why do I get this error when I run the below code: "Takes no arguments (1 given)"
class Hobbs():
def represent():
print "Hobbs represent!"
represent = classmethod(represent)
Hobbs.represent()
Why does "Foo.class_foo()" give no error even though I did not pass an argument to the function.
class Foo(object):
@staticmethod
def static_foo():
print "static method"
@classmethod
def class_foo(cls):
print "Class method. Automatically passed the class: %s" % cls
Foo.static_foo()
Foo.class_foo()
Why do I get this error when I run the below code?
class Foo(object):
def static_foo():
print "static method"
static_foo = staticmethod(static_foo)
def class_foo(cls):
print "Class method. Automatically passed the class: %s" % cls
class_foo = classmethod(class_foo)
Foo.static_foo()
Foo.class_foo()
"TypeError: unbound method static_foo() must be called with Foo instance as first argument (got nothing instead)"
Upvotes: 1
Views: 364
Reputation: 2557
Using object
as the base class for new classes has been convention since at least Python 2.2, and is called "New-Style Classes" - see this question for more details. Old style classes (i.e.: ones that don't inherit from object
) are set to be deprecated in Python 3.0. The reasons for these changes are somewhat obscure, and have to do with low-level class resolution and inheritance patterns.
Python instance methods, by convention, take self
as their first argument. This argument is passed implicitly - so if your method definition doesn't take self
, then the interpreter will complain that the method you're trying to call doesn't accept the argument that's being automatically passed to it. This works exactly the same for classmethods, only instead of taking self
, they usually take cls
. (Just a naming convention.) A quick fix:
class Hobbs():
def represent(cls):
print "Hobbs represent!"
represent = classmethod(represent)
Hobbs.represent()
Calling Foo.class_foo()
doesn't cause any issues, as Python automatically passes the class object to the class_foo
method whenever you call it. These methods are called bound methods - meaning that they are regular functions, but bound to a class or instance object. Bound methods automatically take the class or instance object that they're bound to as their first argument.
Indentation level matters in Python. I've tried executing the code sample you've provided, but both the static_foo =
and class_foo =
lines must be within the Foo
class definition, rather than below it or within other methods. When indented properly, the code runs fine:
class Foo(object):
def static_foo():
print "static method"
static_foo = staticmethod(static_foo)
def class_foo(cls):
print "Class method. Automatically passed the class: %s" % cls
class_foo = classmethod(class_foo)
Foo.static_foo()
Foo.class_foo()
Upvotes: 5
Reputation: 35059
The last two are identical - empty brackets is the same as omitting them. The first inherits from the builtin class object
, making it a "new style class". The reason for new and old style classes is historical, and old-style are only kept around for backward compatibility - essentially, in Python 2, the advice is to always inherit from object
if you don't inherit from anything else, because some of the fancy tricks you will learn eventually rely on it. If you upgrade to Python 3, this becomes the default behaviour, and all three class declarations are equivalent.
A classmethod
needs to take a first argument similar to self
- when you call Hobbs.represent()
, Python end up passing Hobbs
in as that first argument. This is the fundamental difference between classmethod
and staticmethod
- a classmethod
takes a first argument (being the class it was called on), a staticmethod
doesn't.
Same as 2 - class is passed in to the classmethod
in place of the usual self
.
This one appears to be an indentation issue - your code works as written if it is indented as:
def static_foo():
print "static method"
static_foo = staticmethod(staticfoo)
but not as
def static_foo():
print "static method"
static_foo = staticmethod(staticfoo)
Because the line reassigning static_foo
needs to be in the class body, not part of the function itself. In the latter, that line isn't executed until the function is run (which means it isn't run, since the function errors) - and it assigns a staticmethod
to a local variable rather than to the method itself. This type of error is one of the reasons it is good to use the decorator syntax:
class Hobbs:
@staticmethod
def static_foo():
print "static method"
works.
Upvotes: 1
Reputation: 6814
class ClassName(OtherClass):
means that ClassName inherits from
OtherClass. inheritance is a big subject but basically it means that
ClassName has at least the same functions and fields as OtherClass.
In python, Everything is an object and therefor, all classes inherit implicitely or explicitely from object. This being said
the class ClassName():
declaration is an old syntax and should be avoided.
class ClassName:
is equivalent to class ClassName(object):
A class method is not a static method. It is like any other instance method except it is passed the class as parameter rather than the instance.
Your class method declaration is wrong. It should have a cls parameter.
A static method in the other hand, is a method that is called out of context. Meaning it has no relation with any instance. It can be thought of as a independent function that is simply put in a class for semantic reasons.
This is why it does not require a self parameter and one is never passed to it.
You have an indentation error. That might be causing the error.
Upvotes: 0
Reputation: 43024
Most of your questions aren't really about object orientation per se, but Python's specific implementation of it.
Python 2.x has undergone some evolution, with new features being added. So there are two ways to define classes, resulting in a "new-style class", and and "old-style class". Python 3.x has only "new style class".
The base object of new-style classes is called object
. If you inherit from that you have a new-style class. It gives you some of the extra features such as certain decorators. If you have a bare (no inheritance) definition in Python 2.x you have an old-style class. This exists for backwards compatibility. In Python 3.x you will also get a new-style class (so inheriting from object
is optional there).
You have made represent()
and "class method". So it will get the class object as implicit first argument when it is called. But those only work with new-style classes. you have tried to use it with an old-style class. So it won't work.
Python automatically inserts the class object as argument zero for a class method. So that is the correct pattern and it works.
the method somehow didn't get make into a class method, maybe because the indentation is wrong.
Upvotes: 0
Reputation: 113940
all class functions must take self as the first argument
class A:
def my_func(self):
print "In my func"
static methods are classes that are pretty much just a function in a namespace (and are rarely used in python)
class methods are functions in the class namespace that should be called on the class itself rather than an instance
Upvotes: 0