Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't __name__ work in this case? AttributeError Raised

I am new to programming so when I wanted a command to turn a hard-coded function's name into a string, I looked it up and started using the built-in __name__ function. The problem is that I don't think I understand how __name__ retrieves the wanted name. I know it has something to do with what is currently visible with local() or dir() but that's about it... (my own research on this topic has been kinda of hard to understand for me) As a result, I stumbled across an error that I don't know how to solve.

Here is some code that recreates my error:

class Abc:
    @staticmethod
    def my_static_func():
        return

    def my_method(self):
        return

    class_list = [my_static_func]
    method_list = [my_method]

#These calls work
Abc.my_static_func.__name__
Abc.my_method.__name__
Abc.method_list[0].__name__

#But This call raises an AttributeError
Abc.class_list[0].__name__

I get this error message:

AttributeError: 'staticmethod' object has no attribute '__name__'

So why is that when I put my static method into a list and then try to get the function's name from the list it doesn't work? Please forgive me if this question is dumb. As you can clearly see, I don't understand the underlying principle of how __name__ works (and other stuff that I just don't know about to even give these topics names!). An answer would be nice but a reference to some docs would be also welcome.

like image 841
Dzhao Avatar asked Nov 04 '25 23:11

Dzhao


1 Answers

With this code

@staticmethod
def my_static_method(...):
    ....

The function my_static_method is wrapped in a staticmethod. When you access a staticmethod from a class some magic happens to the staticmethod and you actually get a proper function back. Thats why you can access its __name__

Putting the staticmethod in a list and accessing it from that list prevents the magic from happening and you get the staticmethod object back.

Abc.my_static_func  # this is a function
Abc.class_list[0]   # this is a staticmethod object

As a staticmethod does not have a __name__ you get an AttibuteError when accessing its __name__.

To solve your problem you could get the underlying function from the staticmethod

Abc.class_list[0].__func__           # the function
Abc.class_list[0].__func__.__name__  # its name

To find out more about the "magic" that happens when you access attributes/methods from a class/object look up descriptors

like image 89
Wombatz Avatar answered Nov 06 '25 12:11

Wombatz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!