首页
学习
活动
专区
工具
TVP
发布

Python之父教你如何搞倒对象

The best way to learn a programming language is to write a lot of code and read a lot of code.

不好意思,今天要找的对象不是真实世界中的对象。

在真实的世界里,平时A和B聊天:

在Python中定义什么是对象也可以作为一个很好的起点。拿球来举个例子。可以操作一个球,比如捡球、抛球、踢球或者充气等。我们把这些操作称为动作(action)。还可以通过指出球的颜色、大小和重量来描述一个球。这些就是球的属性(attribute)。

可以通过描述特征或属性来描述一个对象。球的属性之一是它的形状。大多数球都是圆形。还有一些其他的属性,比如颜色、大小、重量和价格。属性的另一个说法是特性。

真实世界的真实对象(物体)包括两个方面。

可以对它们做什么(动作)。

如何描述(属性或特性)。

在Python中,也是如此。一个对象的特征(或“你知道的事情”)也称为属性(attribute),这应该很好理解。动作(或“能够对对象做的操作”)称为方法(method)。

如上图聊天中,关于球的属性在Python中可能描述为:

对于球做的操作可能包括:

什么是属性

属性就是你所知道(或者可以得出)的关于球的所有方面。球的属性就是一些信息(数字、字符串等等)。听起来熟悉吧,其实,它们就是变量,只不过是包含在对象中的变量。

可以显示:

print ball.size

可以为它们赋值:

ball.color="green"

可以把它们赋给常规的、不是对象的变量:

myColor=ball.color

还可以把它们赋给其他对象的属性:

myBall.color=yourBall.color

什么是方法

方法就是可以对对象做的操作,它们是一些代码块,可以调用这些代码块来完成某个工作。这听起来更熟悉吧,方法就是包含在对象中的函数(也就是上一篇中我们讨论的内容积木)。

函数能做的,方法都可以做到,包括传递参数和返回值。

所以利用对象,可以把一个东西的属性和方法(你知道的事情和你可以做的事情)收集在一起。属性是信息,方法是动作。

这个点是什么

在前面的例子中,你可能已经注意到对象名与属性或方法名之间的点。这是Python使用对象属性和方法的一种记法:

object.attribute

object.method()

这称为点记法,很多编程语言中都使用了这种记法。

创建对象

Python中创建对象包括两步。

第一步是定义对象看上去什么样,会做什么,也就是它的属性和方法。但是创建这个描述并不会真正创建一个对象。

这有点像一个房子的蓝图。蓝图可以告诉你房子看上去怎么样,但是蓝图本身并不是一个房子。你不可能住在一个蓝图里。只能用它来建造真正的房子。实际上,可以使用蓝图盖很多的房子。

在Python中,对象的描述或蓝图称为一个类(class)。

第二步是使用类来建立一个真正的对象。这个对象称为这个类的一个实例(instance)。

下面来看一个建立类和实例的例子。

类定义

我们先创建一个简单的Ball类:

以上代码是一个球的类定义,其中只有一个方法bounce()。

不过,属性呢?嗯,属性并不属于类,它们属于各个实例。因为每个实例可以有不同的属性。

对象实例

前面提到过,类定义并不是一个对象,它只是创建对象的第一步,这只是蓝图。现在我们来进行第二步,建立一个实例,用蓝图来盖真正的房子。

如果想创建Ball的一个实例,可以这样做

这个球还没有任何属性,所以下面给它提供一些属性:

这是对象定义属性的一种方法,另一种方法叫初始化对象,后面会讨论到。

到这里,我们已经创建了一个对象Ball了。接下来我们来试试它的方法。我们要这样使用bounce()方法:

我们把上述这些创建Ball对象和使用bounce()方法的代码都放在一个程序里,增加一些print语句来看发生了什么。程序如下:

运行这个程序,可以看到下面的结果:

可以看出,调用bounce()方法会把球的方向(direction)从下(down)改为上(up),这正是bounce()方法中的代码所要做的。

初始化对像(__init__()方法)

我们刚刚说了,对象定义属性的方法有两种,上述Ball对象在创建之后,才对myBall的属性size、color和direction中填入内容。就像刚才的那样:

如果我们想把对象的属性在开始时就设置成一种我们希望的描述(状态或条件)以备使用,我们可以使用初始化对象的方法。

创建类定义时,可以定义一个特定的方法,名为__init__(),注意在init前后是两条下划线(_)。我们只要创建这个类的一个新实例,就会运行这个方法。

当然,你可以向__init__()方法传递参数,这样创建实例时就会把属性设置为你希望的值。我们看下面的例子:

运行这个程序:

得出的结果与第一个对象属性定义方法是相同的。区别在于,本例使用了__init__()方法来设置属性。

__init__()方法会在对象创建时完成初始化。每个对象都内置有一个__init__()方法。如果你在类定义中没有加入自己的__init__()方法,就会有这样一个内置方法接管,它的工作就是创建对象。

__str__()方法

另一个特殊方法是__str__(),它会告诉Python打印(print)一个对象时具体显示什么内容。Python会默认以下内容。

实例在哪里定义。

类名。

存储实例的内存位置。

如果我们在上述的例子的IDLE结果中,再输入以下代码,结果如下:

因为在创建对象时,我们没有定义自己的__str__()方法。所以这时Python会默认告诉我们刚建立的实例myBall是在__main__(这是程序的主部分)中定义的,类名是Ball,而存储实例的内存位置是0x0000000003331B88。

不过,如果你希望打印一个对象时能显示其他的内容,我们可以定义自己的__str__()方法,这会覆盖内置的__str__()方法。如下例子:

运行这个程序,可以得到下面的结果:

这样看起来是不是比好多了。

什么是self

你可能已经注意到,在类属性和方法定义中多处出现了“self”,比如:

self是什么意思?

我们说过,可以使用蓝图盖很多个房子,那么,使用一个类也就可以创建多个对象实例,例如:

调用其中一个实例的方法时,像这样:

方法必须知道是哪个实例调用了它,是myBall需要反弹?还是yourBall?self参数会告诉方法哪个对象调用它。这称为实例引用。

不过,调用方法时,myBall.bounce()的括号里没有参数,但是方法里却有一个self参数。既然我们并没有传入任何东西,这个self参数从哪里来的?

其实这是Python处理对象方法的一种操作方式。当我们调用一个类方法时,究竟是哪个实例调用了这个方法?这个信息(也就是实例引用)会自动传递给方法。

这就像写成:

在这种情况下,我们告诉了bounce()方法哪个球要反弹。实际上,这个代码也能正常工作,因为写成myBall.bounce()时,Python在后台确实也是这么做的。

(中场休息……)

Music Time

(接着来……)

一个示例-HotDog

下面为热狗指定一些属性和方法:

热狗的属性:

cooked_level:这是一个数字,通过这个属性我们可以知道热狗烤了多长时间。1~3表示还是生的,超过3表示半生不熟,超过5表示已经烤好,超过8表示已经烤成木炭了!我们的热狗开始时是生的。

cooked_string:这是一个字符串,描述热狗的生熟程度。

condiments:这是热狗上的配料列表,比如番茄酱、芥末酱等。

热狗的方法:

cook():把热狗烤一段时间。这会让热狗越来越熟。

addCondiment:给热狗加一些配料。

__init__():创建实例并设置默认属性。

__str__():让print的结果看起来更好一些。

首先,需要定义类。先定义__init__()方法,它会为热狗设置默认属性:

先从一个没有加任何配料的生热狗开始。现在建立一个方法烤热狗:

继续下面的工作之前,先对这一部分做个测试。首先,需要创建热狗的一个实例,还要检查它的属性。

下面把这些内容都放在一个程序中:

运行这个程序,得到如下结果:

可以看到,属性分别是cooked_level=0,cooked_string=“Raw”,condiments为空。

现在来测试cook()方法。把下面的代码增加到上述代码中:

再运行这个程序,现在输出会变成:

看来我们的cook()方法能正常工作。cooked_level从0变成4,而且字符串也得到更新(从Raw变成Medium)。

下面来增加一些配料。这需要一个新的方法。另外还可以自己增加__str__()函数,让打印对象更为容易。

这个代码清单有点儿长,但还是建议你自己键入这些代码,而且你已经有了之前的部分代码。不过,你也可以回复“热狗”找到这个代码。

程序的第一部分创建了类,第二部分建立一个实例,第三部分测试了烤这个虚拟热狗和添加配料的方法。你还可以尝试修改上面的代码,看看还有什么变化!

好了,对于Python的对象你是否了解了呢?在前几篇推文中,我们看到了:

列表可以收集变量(数据);

函数可以把一些代码收集到能够反复使用的单元中;

对象则可以把函数和数据收集在一起。

实际上,如果仔细分析Python,几乎一切都是对象。按编程的术语来讲,我们说Python是面向对象的。这说明,Python中可以使用对象。但并不是一定得创建自己的对象,不过这样可以让很多事情更容易一些。

END

回顾

什么是对象。

属性和方法。

什么是类。

创建类的一个实例。

特殊方法:__init__()和__str__()。

测试题

定义一个新的对象类型时用什么关键字?

什么是属性?

什么是方法?

类和实例之间有什么区别?

方法中实例引用通常用什么名字?

动手试一试

为BankAccount建立一个类定义。它应该有一些属性,包括账户名(一个字符串)、账号(一个字符串或整数)和余额(一个浮点数),另外还要有一些方法显示余额、存钱和取钱。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180220G09U3K00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券