【问题标题】:Why doesn't __name__ work in this case? AttributeError Raised为什么 __name__ 在这种情况下不起作用?引发属性错误
【发布时间】:2016-03-29 21:55:00
【问题描述】:

我是编程新手,所以当我想要一个将硬编码函数的名称转换为字符串的命令时,我查找了它并开始使用内置的__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__ 工作原理的基本原理(以及我什至不知道给这些主题命名的其他东西!)。一个答案会很好,但也欢迎参考一些文档。

【问题讨论】:

  • 我发现了这个:stackoverflow.com/questions/1987919/…。显然 staticmethod 不返回函数:classmethod 和 staticmethod 返回描述符对象,而不是函数。大多数装饰器并非设计为接受描述符。

标签: python python-3.x attributes


【解决方案1】:

使用此代码

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

函数my_static_method 包装在staticmethod 中。当你从一个类访问staticmethod 时,staticmethod 会发生一些神奇的事情,你实际上会得到一个正确的函数。这就是为什么你可以访问它的__name__

staticmethod 放在一个列表中并从该列表中访问它可以防止魔法发生并且您会得到staticmethod 对象。

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

由于staticmethod 没有__name__,因此在访问其__name__ 时会得到AttibuteError

要解决您的问题,您可以从 staticmethod 获取底层函数

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

要了解有关从类/对象访问属性/方法时发生的“魔法”的更多信息,请查看descriptors

【讨论】:

  • 好的,静态方法对象与函数对象不同?非常感谢!
  • 没错。它是一个小包装器,如果访问正确,它会返回原始函数。
猜你喜欢
  • 2023-03-17
  • 2022-01-21
  • 2017-11-26
  • 2010-12-29
  • 1970-01-01
  • 2021-08-05
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多