为什么在没有“self”且没有装饰器的情况下声明 Python 类的方法不会引发异常?

The*_*'Or 8 python methods static-methods class class-method

我认为以下代码会导致错误,因为据我所知,Python 类中的方法必须将“self”(或任何其他标签,但按照约定是“self”)作为其第一个参数,或者如果使用了@classmethod装饰器,则为“cls”或类似名称,如果使用了装饰器,则为 none @staticmethod

为什么我在终端中使用 Python 3.5 运行它没有错误,即使test_method不满足这些要求?它似乎作为静态方法工作正常,但没有装饰器。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys

class MyClass:

    def test_method(args):
        print(args[1])

    @staticmethod
    def static_method():
        print("static_method")

    @classmethod
    def class_method(cls):
        print("class_method")


def main(args):
    MyClass.test_method(args)


if __name__ == '__main__':
    sys.exit(main(sys.argv))
Run Code Online (Sandbox Code Playgroud)

输出:

$ python3 testscript.py "testing"
$ testing
Run Code Online (Sandbox Code Playgroud)

编辑

我的问题也可以用不同的措辞,将注意力从self和转移到@staticmethod:“我怎么会在没有 @staticmethod 装饰器的情况下得到一个看似有效的静态方法?”

Dan*_*man 9

在 Python 2 中,定义在类体中的函数会自动转换为“未绑定方法”,并且在没有静态方法装饰器的情况下无法直接调用。在 Python 3 中,这个概念被删除了;MyClass.text_method是一个位于 MyClass 命名空间内的简单函数,可以直接调用。

staticmethod在 Python 3 中仍然使用的主要原因是如果您还想在实例上调用该方法。如果不使用装饰器,该方法将始终将实例作为第一个参数传递,从而导致 TypeError。


jar*_*jar 6

这没有什么特别之处。在 python 3 中,在类内部定义的函数或在类外部定义的函数之间没有区别。这两个都是正常的功能。

self您即将在这里也许谈论cls进入画面,只有当你通过访问函数实例。因此在这里你没有得到任何错误。

但是,如果您将代码稍微修改为如下所示,那么您将收到预期的错误。

def main(args):
    MyClass().test_method(args)
    # Should throw an error
Run Code Online (Sandbox Code Playgroud)

编辑:

  • @staticmethod将在两个类实例上工作MyClass().test_method(args),就像一个普通的直接调用一样MyClass.test_method(args)
  • 但是self,不能在类实例上调用常规方法(不包含在其中)。所以你总是不得不把它称为MyClass.test_method(args)

  • @Theod'Or 它与静态方法相同,唯一的区别是,您不能在类实例上调用它。 (2认同)