Python面向对象——创建类和实例

定义类

在 Python 中,类的定义使用 class 关键字来实现,语法如下:

参数说明:

ClassName :用于指定类名,一般使用大写字母开头,如果类名中包括两个单词,第二个单词的首字母也大写,这种命名方法也称为“驼峰式命名法”,这是惯例。当然,也可根据自己的习惯命名,但是一般推荐按照惯例来命名。

statement :类体,主要由类变量(或类成员)、方法和属性等定义语句组成。如果在定义类时,没想好类的具体功能,也可以在类体中直接使用 pass 语句代替。

例如,下面以大雁为例声明一个类,代码如下:

创建类的实例

class 语句本身并不创建该类的任何实例。所以在类定义完成以后,可以创建类的实例,即实例化该类的对象。创建类的实例的语法如下:

ClassName 是必选参数,用于指定具体的类;

parameterlist 是可选参数,当创建一个类时,没有创建 __init__() 方法,或者 __init__() 方法只有一个 self 参数时,parameterlist 可以省略。

例如,创建Geese 类的实例,可以使用下面的代码:

执行上面代码后,将显示类似下面的内容:

从上面的执行结果中可以看出, wildGoose 是 Geese 类的实例。

创建类的方法

参数说明如下:

functionName:用于指定方法名,一般使用小写字母开头;

self:必要参数,表示类的实例,其名称可以是self以外的单词,使用self只是一个惯例而已;

parameterlist:用于指定除self参数以外的参数,各参数间使用逗号“,”进行分隔;

block:方法体,实现的具体功能。

说明:实例方法和Python中的函数的主要区别就是,函数实现的是某个独立的功能,而实例方法是实现类中的一个行为,是类的一部分。

实例方法创建完成后,可以通过类的实例名称和点(.)操作符进行访问。具体的语法格式如下:

instanceName为类的实例名称;

functionName为要调用的方法名称;

parametervalue表示为方法指定对应的实际参数。

创建一个Animal类,并定义eat()、play()和sleep()3个方法。实例化Animal类,并调用这3个方法。下面看一段示例代码。

运行结果如下所示。

创建__init__()方法

在创建类后,通常会创建一个__init__()方法。该方法是一个特殊的方法,类似Java语言中的构造方法。每当创建一个类的新实例时,Python都会自动执行它。__init__()方法必须包含一个self参数,并且必须是第一个参数。self参数是一个指向实例本身的引用,用于访问类中的属性和方法。在方法调用时会自动传递实际参数self。因此,当__init__()方法只有一个参数时,在创建类的实例时,就不需要指定实际参数了。

说明:在__init__()方法的名称中,开头和结尾处是两个下划线(中间没有空格),这是一种约定,旨在区分Python默认方法和普通方法。

下面仍然以大雁为例声明一个类,并且创建__init__()方法,下面看一段示例代码。

运行结果如下所示。

从上面的运行结果可以看出,在创建大雁类的实例时,虽然没有为__init__()方法指定参数,但是该方法会自动执行。

在__init__()方法中,除了self参数外,还可以自定义一些参数,参数间使用逗号“,”进行分隔。例如,下面的代码将在创建__init__()方法时,再指定3个参数,分别是name、gender和weight。

执行上面的代码,运行结果如下:

常见错误:在为类创建__init__()方法时,在开发环境中运行下面代码:

将显示如下所示的异常信息。该错误的解决方法是在第3行代码的括号中添加self。

self的作用

在编写类方法时,必须多加一个self在参数列表开头,但是我们却没有为这个参数赋值,那么这个self的作用是什么呢?其实,self是一种特定的变量,它引用的是对象本身。按照惯例,它被赋予self这一名称。当然也可以使用其他的名字,但是强烈推荐使用self这一名称,因为任何一个程序员都可以一眼认出它。

那么 Python 是如何给 self 赋值的?我们依然以动物类为例。在Animal类创建了2个实例dog和cat 。当调用这个对象的方法,如 dog.info()时,Python将会自动将其转换成Animal.info(dog) 。同理,当调用cat.info()时,Python将会自动将其转换成Animal.info(cat) 。如果info()函数还有参数,例如:

那么调用dog.info(arg1,arg2)时,Python将会自动将其转换成Animal.info(dog,arg1,arg2) 。

类属性和实例属性

前面介绍了类中的方法,本节来介绍一下类中的另一个成员——属性。所谓的属性,可以理解为在类中定义的变量。根据定义位置,又可以分为类属性和实例属性。

1.类属性

类属性是指定义在类中,并且在函数体外的属性。类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。

例如,定义一个Animal类,然后定义1个类属性,代码如下:

可以通过2种方式来调用类属性:类名.属性名和实例名.属性名。例如:

上述代码中,Animal类有一个属性age,所以Animal.age的值为5。但是Animal的2个实例dog和cat为什么也能够获取age属性呢?这就是属性继承搜索的功能。下面的类树图可以很好的解释这个问题。

上图中,Animal类有一个属性age,并且通过Animal类创建了2个实例dog和cat。当调用dog.age时,由于age实例的age属性不存在,所以会继续向上搜索到Animal,发现Animal类中有age属性,所以,dog.age为5。

注意:如果调用dog.name,由于age实例和Animal类都没有这个属性,所以提示如下错误信息:

AttributeError:'Animal' object has no attribute 'name'

创建一个Animal类,该类有一个属性age,并创建2个实例dog和cat,如果更改Animal类age属性的初始值,那么,dog.age和cat.age是否会发生变化呢?下面通过一个例子来学习一下。

运行结果如下。

上述代码中,对于dog实例,动态为其添加属性age,dog.age在查找时,优先查找dog实例的age,所以结果为10。接下来,动态更改Animal类的age属性值,所以Animal.age的值变为8。而由于cat实例没有age属性,所以向上查找Animal类的属性,此时,由于Animal的age属性值已经变为8,所以cat.age为8。通过下图可以更好理解赋值过程。

2.实例属性

实例属性是指定义在类的方法中的属性,只作用于当前实例中。在18.2.4节创建__init__()方法时,就使用了实例属性。

创建一个Animal类,该类中有3个方法,__init__()初始化方法,info()输出详细信息方法以及get_gender()判断动物性别的方法。

在__init__()初始化方法中,使用self.name、self.gender和self.weight设置实例属性。

运行结果如下所示。

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

扫码关注云+社区

领取腾讯云代金券