【问题标题】:Besides instance method, static method, and class method, is there a fourth type of method in Python?除了实例方法、静态方法和类方法,Python中还有第四种方法吗?
【发布时间】:2017-05-08 00:58:21
【问题描述】:

在python中,有3种方法:实例方法、静态方法和类方法。但是让我们看看下面的例子:

class foo:
    def inst_method(self, *args, **kwargs): pass

    @classmethod
    def class_method(cls, *args, **kwargs): pass

    @staticmethod
    def static_method(*args, **kwargs): pass

    def unknown_method(*args, **kwargs):
        print('What? ')

    def another_unknown():
        print('What??? ')

foo.unknown_method()      # OK
foo().unknown_method()    # OK

foo.another_unknown()     # OK
foo().another_unknown()   # !!! 

从语法上讲,unknown_method 的定义是有效的,可以在类上调用。但是这个方法属于哪一种呢?


感谢我收到的答案,可以肯定 unknown_method 仍然是一个实例方法,因为 self 只是一个可选名称;它可以是任何其他名称。

但是 another_unknown 呢?它只能在类上调用,不能在实例上调用。

【问题讨论】:

  • 试着把它称为foo.unknown_method() 我相信它会给你一个错误,你需要一个实例(即它的实例方法)
  • 严格来说,“静态方法”只是一个普通的旧函数。实际上只有两种类型:绑定方法和未绑定方法。阅读“描述符协议”了解详细信息。

标签: python oop methods


【解决方案1】:

这仍然是一个常规的实例方法。你可以这样演示:

>>> class Foo:
        mystery_method(*args, **kwargs):
            print(*args, sep = '\n')
>>> f = Foo(1, 'bar', None)
>>> f.mystery_method()
<__main__.Foo object at XXXX>
1
bar
None

如您所见,我们只传入了 3 个参数,但打印了 4 个参数。 *args 的第一个成员已绑定到对象实例,就像任何其他常规实例方法一样。

self 作为第一个参数的用法只是一个约定。

您提供的另一个方法示例(没有参数)只会引发异常,因为 Python 会尝试将类实例传递给该方法,但该方法接受零参数。它仍然是一个实例方法。

【讨论】:

  • 我同意你的主要观点。但是,当您调用它们时,似乎存在细微差别。由于典型的实例方法将其第一个参数定义为必需参数(self),因此在调用它时,必须传递一个实例。但是由于您定义了所有神秘方法的参数可选,您不需要传递任何实例参数。即,你可以调用 Foo.mystery_method(),典型的实例方法必须调用为 Foo.inst_method(instance) 或 Foo().inst_method(),但你永远不能调用它 Foo.inst_method()。
  • @Peng 正如 Joran Beasley 所指出的,真正的规定是在绑定和非绑定之间。这就是您的示例所体现的概念。
【解决方案2】:

self 只是一个标签。传递给这些函数的第一个参数始终是实例,无论您是否称它为self。您可以将其称为 thisblerg,但传递给函数的第一个参数将始终是实例。

短版:不,没有unknown_method。这只是inst_method 的另一种类型。


编辑

other_unknown 根本不起作用,因为会传入一个参数。你会得到一个TypeError

【讨论】:

  • 对不起,我编辑了你的答案,而不是我的!以前从未这样做过。
猜你喜欢
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 2015-06-22
  • 1970-01-01
相关资源
最近更新 更多