Python面向对象编程第04篇 实例方法

Posted 不剪发的Tony老师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象编程第04篇 实例方法相关的知识,希望对你有一定的参考价值。

本篇将会介绍 Python 实例方法,以及函数(function)和方法(method)之间的区别。

实例方法简介

按照定义,方法就是和一个类实例相关联的函数。以下示例定义了一个 Request 类和 send() 函数:

class Request:
    def send():
        print('Sent')

我们可以通过 Request 类调用 send() 函数,例如:

Request.send()
Sent

其中 send() 是一个函数对象,它是 function 类的一个实例:

print(Request.send)
<function Request.send at 0x00000276F9E00310>

send 的类型为 function:

print(type(Request.send))
<class 'function'>

以下代码创建了一个新的 Request 类实例:

http_request = Request()

如果我们打印 http_request.send,将会返回一个绑定的方法对象:

print(http_request.send)

输出结果如下:

<bound method Request.send of <__main__.Request object at 0x0000020EDB766830>>

所以,http_request.send 不是一个和 Request.send 类似的函数。以下代码检查 Request.send 是否和 http_request.send 是相同类型的对象,返回的结果为 False:

print(type(Request.send) is type(http_request.send))
False

原因在于 Request.send 的类型为函数,但是 http_request.send 的类型为方法:

print(type(http_request.send))
<class 'method'>

print(type(Request.send))
<class 'function'>

所以当我们在类中定义函数时,它就是一个函数。但是,如果我们通过对象调用函数,它就变成了一个方法。也就是说,方法是和类的实例相关联的函数。

如果我们通过 http_request 对象调用 send() 函数,将会返回一个 TypeError 错误:

http_request.send()
TypeError: send() takes 0 positional arguments but 1 was given

因为http_request.send 是一个和 http_request 对象相关联的方法,Python 会隐式地将该对象作为第一个参数传递给方法。

以下代码重新定义了 Request 类,为 send 函数指定了一个参数列表:

class Request:
    def send(*args):
        print('Sent', args)

以下代码通过 Request 类调用 send 函数:

Request.send()

输出结果如下:

Sent ()

send() 函数没有接收任何参数。

不过,如果我们通过一个 Request 类的实例调用 send() 函数:

http_request = Request()
http_request.send()

输出结果如下:

Sent (<__main__.Request object at 0x0000020EDB766290>,)

以上实例中,send() 方法接收了一个对象 http_request 作为参数。

以下代码证明了调用 send() 方法的对象就是 Python 隐式传递给该方法的第一个参数:

print(hex(id(http_request)))
http_request.send()

Code language: Python (python)
Output:

0x20edb766290
Sent (<__main__.Request object at 0x0000020EDB766290>,)

http_request 和 Python 传递给 send() 方法的第一个参数是同一个对象,因为它们的内存地址相同。

下面的方法调用和函数调用等价:

http_request.send()

Request.send(http_request)

因此,对象的方法总是以对象自己作为第一个参数。按照惯例,该参数的名称为 self:

class Request:
    def send(self):
        print('Sent', self)

Python 中的 self 和其他编程语言(Java、C# 等)中的 this 对象概念相同。

总结

  • 类中定义的函数只是函数,但是通过类实例调用的函数就是方法。因此,方法是和一个类实例相关联的函数。
  • 方法是 method 类的一个实例。
  • 方法的第一个参数(self)就是和它相关联的对象自身。
  • Python 自动将关联对象作为第一个参数传递给实例方法。按照惯例,该对象的名称为 self。

以上是关于Python面向对象编程第04篇 实例方法的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象编程第07篇 类方法

Python面向对象编程第07篇 类方法

Python面向对象编程第10篇 静态方法

Python开发第*篇面向对象编程

Python面向对象编程第06篇 实例变量

Python面向对象编程第06篇 实例变量