Ex.
If I have something like this:
class C(object):
@classmethod
def f(cls, x):
return x + x
This will work:
c = C()
c.f(2)
4
But is that bad form? Should I only call
C.f()
or
c.__class__.f()
Obviously, this would only make sense in cases where f doesn't interact with self/cls expecting it to be class.
?
If you have an instance of C already, why do you need f() to be a class method? Not only is it bad form, its usually not necessary. Someone on the net says: "This is bad because it creates the impression that some instance variables in the object are used, but this isn't the case."
Although, page 484 of learning python notes that you can call the method either way and it will be exactly the same as long as you pass the same instance in.
I came across this where I was calling some classmethods (that need to be classmethods so that I still have reference to the class) from a non-classmethod, like the following.
The above code produces the following result:
I'm not saying that it's the best convention, but it doesn't break anything in Python 3.6
It's mainly just confusing looking. If I were using your class and saw this, it would make me wonder what other surprises are in there, it just looks like bad design.
Is there a reason it's not just a staticmethod?
If you are tempted to call a class method from an instance you probably don't need a class method.
In the example you gave a static method would be more appropriate precisely because of your last remark (no self/cls interaction).
this way it's "good form" to do both
and
I don't recall using a classmethod like this from outside the class, but it is certainly ok for an instance method to call a classmethod on itself (e.g.
self.foo()
wherefoo
is a classmethod). This makes sure that inheritance acts as expected, and will call.foo()
in the right subclass instead of the base class.C.f()
is clearer thanc_instance.f()
, andc_instance.__class__.f()
is just ugly. Since clarity and beauty are dearly loved characteristics in the python community, I'd tend to say that C.f() is the best route.Is there any particular reason you even want to call it in either of the other ways?