Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何获取staticmethod的类名_Python_Static Methods - Fatal编程技术网

Python 如何获取staticmethod的类名

Python 如何获取staticmethod的类名,python,static-methods,Python,Static Methods,所以基类中有一个静态方法,子类应该使用它 但是,我需要知道哪个子类调用静态方法 代码如下所示: class BaseClass(): @staticmethod def getname(): #some magic class SubClassA(BaseClass): pass class SubClassB(BaseClass): pass SubClassA.getname() #hope to see 'SubClassA' S

所以基类中有一个静态方法,子类应该使用它

但是,我需要知道哪个子类调用静态方法

代码如下所示:

class BaseClass():
    @staticmethod
    def getname():
        #some magic

class SubClassA(BaseClass): 
    pass

class SubClassB(BaseClass):
    pass

SubClassA.getname()   #hope to see 'SubClassA'
SubClassB.getname()   #hope to see 'SubClassB'

或者,这可能吗?

使用
静态方法不可能。但是,使用
classmethod

class A(object):
    @classmethod
    def f(cls):
        print cls

根据定义,
staticmethod
既不提供对调用类的引用,也不提供对实例的引用——这就是Python中“static”的含义

您可以使用元类或装饰器来实现这一点

请注意,我使用的示例思想只是从您的帖子中获取类的名称,但是,您可以修改此示例以使用任何类型的函数作为静态函数。您只需在下面的
getnameable
中定义该函数,就像我定义的
getname
一样,并使用下面的
some_class
参数(您将使用与我在这里使用的所有“getname”内容不同的名称)

有了装饰师,您可以做到:

def getnameable(some_class):

    # Note, this could be any kind of static method that you want, not
    # just for getting the name. And it can use `some_class` in whatever
    # way is needed.
    def getname():
        return some_class.__name__
    some_class.getname = staticmethod(getname)
    return some_class
那么这就行了:

In [334]: @getnameable
class SubClassA(BaseClass):
    pass
   .....: 

In [335]: SubClassA.getname()
Out[335]: 'SubClassA'
但是请注意,如果您直接在
BaseClass
中实现此功能,那么绑定的类名将是
BaseClass
,即使在子类中也是如此。所以在这种情况下,你需要在你想要的每一个类上添加装饰器

元类提供了这一点,它表明您希望将装饰类的业务作为类创建的一部分(注意,不是实例创建)

测试它:

In [337]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:class GetNameableMeta(type):
:    def __new__(cls, name, bases, attrs):
:        temp_class = super(GetNameableMeta, cls).__new__(cls, name, bases, attrs)
:        return getnameable(temp_class)
:
:class BaseClass(object):
:    __metaclass__ = GetNameableMeta
:
:class SubClassA(BaseClass):
:    pass
:--

In [338]: SubClassA.getname()
Out[338]: 'SubClassA'

In [339]: BaseClass.getname()
Out[339]: 'BaseClass'
注意,当我们有几个合理的替代方案时,我们需要编写多少高错误代码来实现这一点:

  • 只需直接请求
    \uuu name\uuu
    属性
  • 首先,将其设置为
    classmethod
  • 在我们需要的地方使用装饰器,并放弃继承部分

  • 我怀疑在“Python的本质”中,任何一个都比我上面描述的机制好,因为它使代码更简单、更容易理解。

    为什么不使用
    @classmethod
    ?静态方法是静态的,它们不应该携带任何与类相关的数据。使用
    staticmethod
    (请参阅我回答中的元类示例)可以复制静态方法,但要么只是请求
    cls.\uuu name\uuuuu
    或者将其作为
    类方法肯定是更好的解决方案。
    
    In [337]: %cpaste
    Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
    :class GetNameableMeta(type):
    :    def __new__(cls, name, bases, attrs):
    :        temp_class = super(GetNameableMeta, cls).__new__(cls, name, bases, attrs)
    :        return getnameable(temp_class)
    :
    :class BaseClass(object):
    :    __metaclass__ = GetNameableMeta
    :
    :class SubClassA(BaseClass):
    :    pass
    :--
    
    In [338]: SubClassA.getname()
    Out[338]: 'SubClassA'
    
    In [339]: BaseClass.getname()
    Out[339]: 'BaseClass'