在Python中从静态方法调用非静态方法

11 投票
5 回答
15362 浏览
提问于 2025-04-15 14:06

我找不到在Python中是否可以从静态方法调用非静态方法。

谢谢

编辑:
好的,那静态方法之间可以互相调用吗?我可以这样做吗:

class MyClass(object):

    @staticmethod
    def static_method_one(cmd):
    ...

    @staticmethod
    def static_method_two(cmd):
        static_method_one(cmd)

5 个回答

4

使用类方法,而不是静态方法。那为什么要把它放在一个类里面呢?

class MyClass(object):

    @classmethod
    def static_method_one(cls, cmd):
    ...

    @classmethod
    def static_method_two(cls, cmd):
        cls.static_method_one(cmd)
7

在看到其他回答和你后续的问题后——关于从静态方法调用静态方法:是的,你可以这样做:

>>> class MyClass(object):
    @staticmethod
    def static_method_one(x):
        return MyClass.static_method_two(x)
    @staticmethod
    def static_method_two(x):
        return 2 * x


>>> MyClass.static_method_one(5)
10

另外,如果你感兴趣的话,从类方法调用类方法也是可以的(在解释器中测试这些内容很简单——这些都是从2.5.2版本的Idle中复制粘贴过来的)[**已编辑以纠正其他人指出的用法**]

>>> class MyClass2(object):
    @classmethod
    def class_method_one(cls, x):
        return cls.class_method_two(x)
    @classmethod
    def class_method_two(cls, x):
        return 2 * x


>>> MyClass2.class_method_one(5)
10
15

这是完全可能的,但意义不大。想想下面这个类:

class MyClass:
    # Normal method:
    def normal_method(self, data):
        print "Normal method called with instance %s and data %s" % (self, data)

    @classmethod
    def class_method(cls, data):
        print "Class method called with class %s and data %s" % (cls, data)

    @staticmethod
    def static_method(data):
        print "Static method called with data %s" % (data)

显然,我们可以用预期的方式来调用它:

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!

但也可以考虑这样:

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

语法 instance.normal_method() 实际上就是 MyClass.normal_method(instance) 的一种“快捷方式”。这就是为什么方法中有一个“self”参数,用来传递实例本身。这个“self”并不是魔法词,你可以随便给它起个名字。

在静态方法中也可以用同样的技巧。你可以把实例作为第一个参数来调用普通方法,像这样:

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!

所以答案是,是的,你可以从静态方法中调用非静态方法。但前提是你必须把实例作为第一个参数传进去。所以你要么在静态方法内部生成这个实例(在这种情况下,使用类方法可能更好),要么把它传入。但如果你传入了实例,通常你可以直接把它做成普通方法。

所以你可以这样做,但其实没什么意义。

这就引出了一个问题:你为什么想这么做呢?

撰写回答