classification
Title: list an example for calling static methods from WITHIN classes
Type: enhancement Stage: resolved
Components: Documentation Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, eric.araujo, georg.brandl, ifreecarve, r.david.murray, rhettinger, sbt
Priority: normal Keywords: patch

Created on 2010-11-16 20:23 by ifreecarve, last changed 2017-07-12 17:03 by r.david.murray. This issue is now closed.

Files
File name Uploaded Description Edit
static_method_call_examples_10438.patch r.david.murray, 2013-04-14 17:40
Messages (18)
msg121314 - (view) Author: Ian (ifreecarve) Date: 2010-11-16 20:23
Concerning this section of the docs:
http://docs.python.org/library/functions.html#staticmethod

There is no example for calling a static method from another static method within the same class.

As I discovered later, it's simple: C.f() -- from inside the class or outside it.

A total newbie will accept this and move on... but in other programming languages, it's frowned upon to the class name from within the class.  For example, in PHP you use the "self::" prefix and Java you don't need a prefix at all.  

So, even though I had it right the first time, it didn't SEEM right... so I went on a wild goose chase, for nothing.  Googling "java call static method" will get you java documentation that lists both cases, as does "c++ call static method" and "php call static method".  

I feel that by adding "Note: you must also use the C.f() syntax when calling from within the class", the documentation will be more complete.
msg121315 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-11-16 21:02
IMO this follows logically from Python's self-consistent rules.  I'm not convinced that the amount of extra verbiage required to detail this particular case would make the docs clearer, but you are welcome to suggest a wording for us to consider.
msg121316 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-11-16 21:04
Woops, I see you did suggest a wording.  However, what you wrote is imprecise and confused me when I first read it (I thought you meant that self.f() didn't work!).
msg121317 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2010-11-16 21:04
I tend to agree with David.  Especially since calling base class methods also uses the explicit class name.
msg121319 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2010-11-16 21:06
> However, what you wrote is imprecise and confused me when I first read
> it (I thought you meant that self.f() didn't work!).

Well, it doesn't work in the specific case he mentioned of calling from another static method :)
msg121320 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-11-16 21:08
Only because you don't *have* self.  Which is why I said "imprecise" and not "incorrect" :)
msg121322 - (view) Author: Ian (ifreecarve) Date: 2010-11-16 22:44
Am I to understand that self.f() is a valid way to call a static method?  Can you see how that would run counter to intuition for someone who is familiar with other languages?

Given that, I would make the following (more precise) change:

< It can be called either on the class (such as C.f()) or on an instance (such as C().f()). 
---
> It can be called either on the class (such as C.f()) or on an instance (such as C().f() or self.f()).
msg121324 - (view) Author: Ian (ifreecarve) Date: 2010-11-16 22:49
Disregard my previous comment; calling self.f() does not work from a static method.

I stand by my previous suggestion, but I'll clarify it like this:

"Note: you must also use the C.f() syntax when calling from a static method within the C class"
msg186935 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-04-14 17:40
After a discussion (at the Boston Python sprint, unfortunately I forget with who) of how difficult this could be to explain succinctly without confusing either java/C++ programmers on the one hand or Python programmers on the other hand, this, the wording in the attached patch occurred to me.  I'm not certain that adding the extra words is worth it, but if so this might do.
msg186946 - (view) Author: Richard Oudkerk (sbt) * (Python committer) Date: 2013-04-14 19:16
Note that in Python 3 you can also do __class__.f() in a staticmethod.  Not sure if that is encouraged though.
msg297978 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-07-09 03:13
I also don't think this is worth it.  The extra wording will likely cause more confusion that it clears up.

Also, calling a staticmethod from within a class isn't a common thing to do.  The principal use case for Python's static methods is to attach a function to a class for the sole purpose of making it findable by someone using that class.
msg297991 - (view) Author: Ian (ifreecarve) Date: 2017-07-09 11:30
I agree that the use case is probably rare.

I agree that to someone intimately familiar with the "self-consistent rules" of Python, the correctness of the C.f() approach is probably obvious.

However, your documentation says:

    Static methods in Python are similar to those found in Java or C++.

I feel that it's a mistake to purposefully avoid saying where that similarity ends.  In those languages (and in many others), fully qualified function calls from within the same class are redundant and border on "code smell".  We agree that this aspect of Python is not mentioned in the documentation, and we disagree on whether it should be.  For myself, even in the 7 years and thousands of lines of Python since I opened this issue, I still don't find it intuitive or obvious that a method would need to know the name of the class that contains it.  That doesn't make the language "wrong" in any way; it makes the documentation incomplete for not addressing it.  

The __class__.f() usage in Python 3 seems excellent.  If that's the preferred way to do it, then that might be a way to approach the documentation.  "To call one static method from another within the same class, as of Python 3 you may use __class__.f() instead of C.f().  For Python 2.x, you must still use the name of the class itself, C.f(), as if you were calling from outside the class."  (My wording is still less than ideal, but you get the idea.)
msg298168 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-11 17:44
Given a choice between catering for Python programmers and catering for Java/C++ programmers, the Python docs obviously ought to chose to cater to Python programmers.  To a python programmer, calling C.f() is intuitive.

I would myself definitely *not* encourage the __class__.f() idiom.

Maybe we should just drop the reference to Java and C++ static methods.
msg298172 - (view) Author: Ian (ifreecarve) Date: 2017-07-11 18:02
I would hope that the docs would cater to people who aren't sure how the language works (and who want to confirm that they are using proper patterns).  If people already know how the language works, they won't need the docs.

Whether or not you refer to Java and C++, you should state the best practices for both internal and external calling of static methods in Python.
msg298175 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-11 18:36
I'm not sure there's a "best practice" choice between the two calling forms that are documented.  Although obviously when you don't have an instance you can't use the instance calling form.  I think it is *common* practice to use the instance form when you can, but I'm not sure it is either superior or inferior to using the class form.  It partly depends on how you have structured your code and why you are using static methods in the first place.
msg298195 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-07-12 04:09
Ian, the docs mostly serve to tell what a tool does.  Best practices then emerge from actual practices and are determined by users.

I don't see any bug here that needs to be solved and think it is time to close this tracker item.  It has been consuming developer clock cycles without addressing any real, known issue.
msg298228 - (view) Author: Ian (ifreecarve) Date: 2017-07-12 15:48
As indicated earlier, I would prefer to see clear instructions on how to call a class's static method from another static method within the same class.  Currently, it's only clear how to call from outside the class.

If that's not going to happen, then I agree that this issue should be closed.
msg298235 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-12 17:03
It is documented how to call a static method when you don't have an instance.  So when you don't (for example, inside a static method on the same class) you use that form (call the method on the class name).

I realize you don't find this clear, but as Raymond says it is time to stop arguing about it; our rule is that the status quo wins when agreement is not reached for a change.

Closing.
History
Date User Action Args
2017-07-12 17:03:29r.david.murraysetstatus: open -> closed
resolution: not a bug
messages: + msg298235

stage: resolved
2017-07-12 15:48:48ifreecarvesetmessages: + msg298228
2017-07-12 04:09:53rhettingersetmessages: + msg298195
2017-07-11 18:36:42r.david.murraysetmessages: + msg298175
2017-07-11 18:02:54ifreecarvesetmessages: + msg298172
2017-07-11 17:44:29r.david.murraysetmessages: + msg298168
2017-07-09 11:30:10ifreecarvesetmessages: + msg297991
2017-07-09 03:13:57rhettingersetstatus: pending -> open
nosy: + rhettinger
messages: + msg297978

2017-07-08 07:48:19serhiy.storchakasetstatus: open -> pending
2013-04-14 19:16:28sbtsetnosy: + sbt
messages: + msg186946
2013-04-14 18:44:19eric.araujosetnosy: + eric.araujo
2013-04-14 17:40:29r.david.murraysetfiles: + static_method_call_examples_10438.patch
keywords: + patch
messages: + msg186935
2010-11-16 22:49:56ifreecarvesetmessages: + msg121324
2010-11-16 22:44:23ifreecarvesetmessages: + msg121322
2010-11-16 21:08:08r.david.murraysetmessages: + msg121320
2010-11-16 21:06:19georg.brandlsetmessages: + msg121319
2010-11-16 21:04:57georg.brandlsetnosy: + georg.brandl
messages: + msg121317
2010-11-16 21:04:00r.david.murraysetmessages: + msg121316
2010-11-16 21:02:35r.david.murraysetnosy: + r.david.murray
messages: + msg121315
2010-11-16 20:23:16ifreecarvecreate