【问题标题】:staticmethod: get the class name?静态方法:获取类名?
【发布时间】:2012-07-28 20:47:05
【问题描述】:

有没有办法找到静态方法所属的类的名称?

class A(object):
    @staticmethod
    def my_staticmethod():
        return 'static'

    @classmethod
    def my_classmethod():
        return 'classmethod'


In [2]: A.my_staticmethod
Out[2]: <function utils.my_staticmethod>

In [3]: A.my_classmethod
Out[3]: <bound method type.my_classmethod of <class 'utils.A'>>
In [4]: A.my_classmethod.im_self.__name__
Out[4]: 'A'

对于类方法,我可以通过A.my_classmethod.im_self.__name__ 获取类的名称,但对于静态方法我无法弄清楚。

有什么想法吗? 谢谢。


嗯,实际上这就是我想要做的。 我正在尝试制作 2 个函数来“序列化/反序列化”一个函数/类方法/静态方法。

也就是说,有人可以将一个函数传递给序列化函数并获取一个字符串。

a_string = serialize(A.my_classmethod)

这个字符串可以存储在数据库中,例如.. 那么,这个字符串应该足以解析能够调用它的函数:

# later on...
f = deserialize(a_string)
# I can use my function
f(...)

我可以使它适用于函数或类方法,但不适用于静态方法,因为我无法确定它所属的类并使用 getattr...

【问题讨论】:

  • 基本上,静态方法的全部意义在于它与其类没有任何联系。如果您想知道它在哪个类中,请不要使用静态方法。
  • @BrenBarn 同意。这就像在您卸下车轮后询问如何驾驶汽车一样。答案是重新戴上它们。
  • 如果你愿意,你可以用inspect 做一些粗糙的事情,但是你想要做的事情可能有一个简单的解决方案,也许一个简单的hasattr(A, 'my_staticmethod') 是你正在寻找的?

标签: python


【解决方案1】:

使用“voodoo”你可以解决它,但说真的 - 你只是想规避数据模型 - 这有什么好处?如果你想要一个类方法 - 使用一个类方法。如果它们是可以互换的,它们就不会有所不同!

还有:

@classmethod
def my_classmethod():
    return 'classmethod'

应该是:

@classmethod
def my_classmethod(cls): # assuming no args
    return cls.__name__ # instead of A.my_classmethod.im_self.__name__

【讨论】:

  • 其实我不知道classmethod会做什么,我不是在寻找返回类名的方法。看看我的第二个帖子,看看我的真正意思。谢谢。
  • 回答您的两个问题:1)为什么这不是您的原始问题=>我想问一个更简单的问题,只是询问我正在经历的障碍是获得课程知道静态方法的名称。 2)每个人都告诉你这是一个坏主意,尽管可以使用黑魔法,你觉得这仍然是做事的正确方法吗? => 我正在使用 Django 信号,我想将连接到信号的接收器(不知道它们)保留在数据库中,所以我希望能够序列化/反序列化函数(即使它是静态方法)。希望现在有意义。
【解决方案2】:

针对您对序列化/反序列化的评论,您可以更改接口:

def serialize(cls, function):
    return '{cls}.{func}'.format(cls=cls.__name__, func=function.__name__)

您可以将sys.modules[__name__].__name__ 用于任何模块级功能。

对于反序列化,您可能会发现 inspect.classify_class_attrs(cls) 很有用。

【讨论】:

  • 好的,所以我得出结论,如果不传递类本身,就无法从静态方法访问类的名称。我首先想拥有相同的用例(仅传递一个函数),无论函数是什么。好吧,我将避免传递一个静态方法,然后在文档中写下静态方法不起作用。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 2012-03-04
  • 2016-06-05
相关资源
最近更新 更多