[Tutor] @property vs @classmethod

Steven D'Aprano steve at pearwood.info
Sat Jul 8 20:56:19 EDT 2017


On Sat, Jul 08, 2017 at 04:03:24PM -0700, Evuraan wrote:
> Greetings!
> 
> I was hoping to learn when to use classmethod and when to use property.
> They both seem similar (to me at least..), what's the pythonic way to
> choose between them?

The pythonic way is not to use them at all.

For experts only: you'll know when you need them.

They really aren't even a little bit similar, if you thought they did 
that just means that you haven't understood what they do.

property is for making computed atttributes. The Pythonic way is to just 
use an ordinary attribute:

class K(object):
    def __init__(self, x):
        self.x = x

instance = K(99)
print(instance.x)  # prints 99

which people can then assign to, read or even delete. But occasionally 
you need to run some code whenever instance.x is accessed, and that's 
when you should use property.

If you're familiar with Java, then property can be used to make Java 
getters and setters look like ordinary attribute access.

classmethod is for making methods which don't receive the instance as 
their first argument, but the class instead. In Java they would be 
called static methods (Python has a static method too, but that's a 
completely different thing.) Here is an example demonstrating the 
difference between an ordinary instance method and a class method:

class K(object):
    attr = "Attribute stored on the class object"
    def __init__(self, x):
        print("Before:")
        print(self.attr)
        self.attr = x
        print("After:")
        print(self.attr)
    def method1(self):
        print("self is:", self)
        print("Attr:", self.attr)
    @classmethod
    def method2(cls):
        print("cls is:", cls)
        print("Attr:", cls.attr)


and here is a demo of it in use:

py> instance = K("attribute stored on the instance")
Before:
Attribute stored on the class object
After:
attribute stored on the instance
py>
py> instance.method1()
self is: <__main__.K object at 0xb7a1838c>
Attr: attribute stored on the instance
py> instance.method2()
cls is: <class '__main__.K'>
Attr: Attribute stored on the class object


If you're wondering when classmethod is useful, the answer is, it very 
rarely is. One possible use is if your class has an alternate 
constructor. An example of that is dict.fromkeys().



-- 
Steve


More information about the Tutor mailing list