用简单例子解析:Python中的类和实例

为什么需要类?

Python提供很多简单的数据结构,比如列表和字符串,应对大多数需求绰绰有余,但是有些情况下,仅仅用这些简单数据结构无法表达我们想实现的东西,比如一辆车,或者更细化一些,一辆奥迪Q7或是一辆特斯拉电动车。

你可以指定一个列表,第一个元素存放车的品牌,第二个元素存放车的型号,第三个元素存放车的出厂时间,但是你怎么知道某一个元素具体对应到车的什么信息?

这种办法太主观随意,也不直观。你可能会想到用字典的键值对表示,这样就意味着我们必须重复输入很多代码。为了更直观的解决此类问题,我们引入类的概念。

类可以让我们创建复杂的数据结构,并任意使用任何有用信息。比如,我们创建一个表示车的类,这个类里有三个属性:品牌,型号,出厂时间。

如何定义类和类的实例?

接下来,我们区分两个关键词“类”和“类的实例”。类确定了结构,但是并不填充内容。比如,表示车的类,指明每辆车需要存三个信息:品牌、型号、和出厂时间,但是并没有说出具体的车的品牌、型号或者出厂时间。

而类的实例是一个特殊的类:指明了各种属性对应的具体信息,比如,我创建了一辆车,品牌是奥迪,型号是Q7,出厂时间是2017。为了更好的理解和区分“类”和“类的实例”,我们打个比方,大家都填过个人信息登记表,每个人都必须填入与表格相对应的信息,比如姓名,性别,年龄等等,但是具体填写的内容因人而异。

类就相当于这个空白的登记表,上面指定了要填写的内容。而你填写完之后的表,就相当于一个类的实例,上面记载着与你个人相关的信息。这个根据类来创建实例的过程叫做“实例化”。

好了,现在我们看一下Python中真实的类(图一car.py)。第一个单词class表示我们在创建一个类。第二个单词Car是类的名字,后面跟一对圆括号,通常来说,默认类名首字母大写。类中的变量称为属性,类中的函数称为方法。

__init__()是一个特殊的初始化函数,创建Car实例时,自动调用该方法,虽未显示地包含return语句,但Python自动返回一个表示这辆车的实例,比如,my_car = Car('Audi', 'Q7', '2017') 会把Audi赋给self.make, 把Q7赋给self.model,把2017赋给self.year,并返回一个实例my_car。以self为前缀的变量可供该类中的所有方法使用,比如,在get_descriptive_name()中,可以调用self.make,self.model, self.year。

可以把self理解为一个类的实例,更确切的说,是一个指向实例本身的引用,让实例能够访问类中的属性和方法。还记得之前关于人员登记表的比喻吗?每个实例具有相同的字段结构,但是每个字段里填写的信息不同,这就是为什么写self.make = make,而不是写Car.make = make。

你可能会注意到类中的每个方法的第一个形参都是关键字self,self是必不可少的,而且必须位于首,但是,当我们调用这些方法时候(e.g. my_car = Car('Audi', 'Q7', '2017')),只需要传递三个值,为什么略过self这个参数呢?

这是Python中特有的行为:当我们调用一个实例的方法时,Python会自动搞清楚要用哪一个实例,并把它传递到self参数中。我们在接下来介绍如何使用类中的方法时,再给大家具体解释。

图一 car.py

如何使用类?

Python中使用点号访问对象的属性和方法:my_car.year,my_car.get_descriptive_name(),

见图二my_car.py代码中第7-8行。

回到上一个问题,图一中第9行代码定义get_descriptive_name(self)时参数self必不可少,为什么图二第8行代码调用该方法时,省略了实参self?

正是因为我们在调用get_descriptive_name()时用点号指明了实例my_car,Python才能自动识别实例my_car,并创建my_car的引用,并把这个引用传给参数self。如果不通过实例调用方法,我们应该这么写:Car. get_descriptive_name(my_car),此时,明确把my_car当做实参传给参数self,见图二代码第9行。

图二 my_car.py

图三是程序运行结果:

图三 运行结果

这一节我们学习了类和类的实例,以及如何使用类。

猜你喜欢

转载自blog.csdn.net/sinat_38682860/article/details/94762980