On Sun, Aug 11, 2019 at 10:58:37PM -0500, James Hartley wrote: > I am lacking in understanding of the @staticmethod property. > Explanation(s)/links might be helpful. I have not found the descriptions > found in the Internet wild to be particularly instructive. Given the code > below: [...] > The class method Foo.dimensions() is capable of accessing class members, > but Foo.dimensions1() cannot. What does the @staticmethod decorator really > add?
Very little. To understand staticmethod in Python, you have to understand what ordinary methods do. When you make a class with a method: class MyClass(object): def spam(self): print(self) the interpreter creates a plain old regular function called "spam", and attaches it to MyClass. It is precisely the same as doing this: def spam(self): print(self) class MyClass(object): pass MyClass.spam = spam except more convenient. Methods are actually regular functions under the hood. But when you access a method, like this: instance = MyClass() instance.spam() # call the method the interpreter does some runtime magic to convert the function object into a method object which automatically knows what "self" is. This magic is called "the descriptor protocol", it's very clever but advanced programming, and the details aren't important here. So just think of it like this: When you access instance.spam, the interpreter converts the plain old dumb function object which has no idea what "self" is into a magical method object which does. If you bypass the descriptor "magic", you can grab hold of the plain-old regular function: py> instance = MyClass() py> vars(type(instance))['spam'] # Bypass all the magic. <function MyClass.spam at 0xb78433d4> but it's dumb, and doesn't know what "self" is: py> vars(type(instance))['spam']() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: spam() missing 1 required positional argument: 'self' If you use normal attribute access, the function is turned into a method object that knows what "self" should be: py> instance.spam # Normal access. <bound method MyClass.spam of <__main__.MyClass object at 0xb77e52ac>> py> instance.spam() # "self" is automatically provided <__main__.MyClass object at 0xb77e52ac> So that's how methods work normally. But what if you don't want a method that understands "self", but a regular dumb-old function, but for some reason it needs to be attached to a class? You can't use a regular function in the class body, because it will be automatically turned into a method on access, and for some reason you don't want that. You need a way to tell the interpreter "Don't convert this into a method with self, leave it as a regular function", and staticmethod is that way. (To be pedantic, it doesn't actually leave it as a regular function, it converts it to a staticmethod object which behaves like a regular function. But that's a difference which normally makes no difference.) So you can see, the niche for staticmethod is very, very narrow. You need something that is attached to a class, which you can call like a method, but you don't want it to receive "self" as the automatic first argument. That's pretty rare. For a very long time, the only known use for staticmethod was in the tests checking that the staticmethod code worked correctly. So that's what staticmethod does. It is occassionally useful, but not very often. Chances are, if you think you need one, you probably don't. So why doesn't it work the way you expect? For that, read my next email. -- Steven _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor