静态方法-如何从另一个方法调用一个方法?


95

当我有用于在类中调用另一个方法的常规方法时,我必须这样做

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

但是当我有静态方法时,我不能写

self.dosomethingelse()

因为没有实例。在Python中如何从同一个类的另一个静态方法中调用一个静态方法,我该怎么做?

编辑:真是一团糟。好的,我将问题改回原来的问题。我已经有了彼得·汉森(Peter Hansen)评论中第二个问题的答案。如果您认为我应该再提出一个已经存在的答案的问题,请告诉我。


3
@pablo:你不能改变问题的实质!结束这个问题,开始另一个问题!
jldupont

好的好的。您是说删除问题吗?彼得·汉森(Peter Hansen)的评论中已经存在答案
巴勃罗(Pablo)2009年

@pablo:您不能在此处删除对每个为您的问题做出贡献的人的礼貌。您需要接受答案创建一个新问题。
jldupont

1
@pablo:需要明确的是:您最初提出的问题的答案应该被接受。不用担心,您将在这里学习自己的方式。干杯:-)
jldupont,2009年

Answers:


77

class.method 应该管用。

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()

16
应该在此处添加建议:显然,类方法与静态方法相比没有任何缺点,并且类方法允许将来扩展该方法以调用其他类方法。因此,即使没有迫切需要,也应始终首选它。
u0b34a0f6ae 2009年

1
@ u0b34a0f6ae:我不知道自己做得好不好,但是我在一个类中定义了一个装饰器。装饰器必须是“静态方法”,而不是“类方法”。
安德烈·卡尔达斯

@ u0b34a0f6ae类方法始终是线程安全的吗?在我的用例中,我在线程中使用静态方法来防止意外访问可能不是线程安全的类。
Aquaquae 2014年

@ u0b34a0f6ae 总是有点强。例如,在rdd作业中可以使用PySpark静态方法,而在classd方法中则不能。
Laurens Koppenol '17

134

在Python中如何从同一个类的另一个静态方法中调用一个静态方法,我该怎么做?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()

该调用也Test.static_method_to_call()应该可以从该类的其他非静态和非类方法工作,对吗?(...以及可能还有其他课程?)
gr4nt3d

是的,Test.static_method_to_call()可以在任何地方工作。
warvariuc

11

注意-看来问题已经改变了一些。关于如何从静态方法调用实例方法的问题的答案是,您不能不将实例作为参数传入或在静态方法中实例化该实例。

接下来的内容主要是回答“如何从另一个静态方法调用静态方法”:

请记住,Python中的静态方法和类方法之间有区别的。静态方法不使用隐式第一参数,而类方法则将类作为隐式第一参数(通常cls是按惯例)。考虑到这一点,这是您要执行的操作:

如果是静态方法:

test.dosomethingelse()

如果是类方法:

cls.dosomethingelse()

1
您只能cls.dosomethingelse()在类定义中使用。
jldupont

3
为了更准确,您只能cls.dosomethingelse()在class方法本身内部使用。就像您只能self在实例方法本身中使用一样。
杰森·贝克

1
对不起,我错误地写了这个问题。糟糕!我想写“在Python中如何从同一类的另一个静态方法调用实例方法”而不是“在Python中如何从同一类的另一个静态方法调用静态方法”课”
Pablo

@pablo:在这种情况下,您需要写另一个问题并完成这个问题。
jldupont

@jldupont,我已经有了答案,但只有一条评论。因为我不能接受该怎么办,但是消除这个问题是浪费,不是吗?
巴勃罗(Pablo)2009年

4

好的,类方法和静态方法之间的主要区别是:

  • class方法具有自己的标识,这就是为什么必须在INSTANCE中调用它们的原因。
  • 另一方面,可以在多个实例之间共享静态方法,因此必须从CLASS中调用它

0

您不能从静态方法调用非静态方法,但是可以通过在静态方法内创建实例来实现。

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

希望对您有帮助:)


3
IMO这种方法明显比仅@classmethod用于声明您的方法更糟糕,而cls.dosomethingelse()在内部使用cls.dosomething()-在性能(实例化对象只是为了访问静态方法)和可读性(这并不简单,我想如果是那种方法)方面更糟糕。模式的样板化,仅一个人就很难解析整个代码库)
Kyle Wild,

正如我在SO上的其他地方读到的那样,您可以直接调用它,而不必直接初始化实例来调用方法,它会自行初始化。
Nakilon

0

如果这些不依赖于类或实例,那为什么不仅仅使它们成为一个函数呢?因为这似乎是显而易见的解决方案。当然,除非您认为它将需要被覆盖,子类化等等。如果是这样,那么前面的答案是最好的选择。我只是简单地提供一个可能满足或可能不适合某人需求的替代解决方案而感到沮丧;)。

因为正确的答案将取决于相关代码的用例;)享受

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.