为什么在这种情况下 __name__ 不起作用?引发 AttributeError。

4
我是一名编程新手,当我想要将硬编码函数的名称转换为字符串时,我查找了相关信息并开始使用内置的__name__函数。问题在于,我不确定__name__如何检索所需的名称。我知道它与当前可见的local()或dir()有关,但仅此而已......(我自己对这个主题的研究对我来说有点难以理解)因此,我遇到了一个错误,我不知道如何解决。
以下是一些重现我的错误的代码:
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__

我收到了这个错误信息:
AttributeError: 'staticmethod' object has no attribute '__name__'

当我把静态方法放入列表中并尝试从列表中获取函数名称时,为什么会失败呢?如果我的问题很愚蠢,请原谅我。显然,我不理解 __name__ 的工作原理(还有其他一些我甚至不知道如何命名的东西!)。回答是好的,但也欢迎提供一些文档参考。

1
我发现了这个链接:https://dev59.com/lHI-5IYBdhLWcg3wKVA9。显然,staticmethod不返回函数:classmethod和staticmethod返回描述符对象,而不是函数。大多数装饰器都不设计用于接受描述符。 - joel goldstick
1个回答

3

使用这段代码

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

函数 my_static_method 被封装在 staticmethod 中。当你从一个类中访问 staticmethod 时,会发生一些神奇的事情,你实际上得到了一个合适的函数。这就是为什么你可以访问它的 __name__
staticmethod 放入列表并从该列表访问将防止魔法发生,并使您获得 staticmethod 对象。
Abc.my_static_func  # this is a function
Abc.class_list[0]   # this is a staticmethod object

作为一个静态方法,它没有__name__属性,因此在访问其__name__属性时会出现AttributeError错误。
为了解决这个问题,您可以从staticmethod中获取底层函数。
Abc.class_list[0].__func__           # the function
Abc.class_list[0].__func__.__name__  # its name

如果您想了解从类/对象访问属性/方法时发生的“魔法”,请查看描述符


好的,staticmethod对象和函数对象有所不同?太棒了,非常感谢! - Dzhao
1
没错。这是一个小包装器,如果正确访问,可以返回原始函数。 - Wombatz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接