赞
踩
目录
Python也是一种面向对象的编程语言,很多语法、特征同java十分类似,甚至有的地方几乎一模一样。类就是其中一个方面,比如在构造方法、实例创建、属性修改、继承等方面,二者相差无几。当然,本人目前还处于学习Python基础的阶段,可能理解尚浅。关于java的类相关知识这里不做说明,只介绍一下python中关于类的概念。
关于面向对象:我们可以把现实世界中的各种事物、情景都作为编程概念中的对象,即——万物皆对象。与之相对的,是面向过程。面向对象利用抽象、封装、继承等机制将虚拟的数字世界与我们所在的现实世界联系起来,易于理解的同时又方便操作、实现。
关于类:我们可以把表示一类事务共有的属性、特征的代码封装到一个文件里,这种封装起来的文件称之为类,比如表示事物的汽车类、自行车类、摩托车类、动物类、植物类等,表示情景的网站注册用户类、用户访问类、购物实现类等。
在Python中,类的名称需要首字母大写,类的定义中没有圆括号(),定义类时应尽可能的添加相关的文字说明(注释)。
前边我们介绍了函数,类中的函数称之为方法,关于函数的一切都适用于方法,但方法中有一个特殊的存在:__init__()方法。这个方法的开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法产生名称冲突。每个类中都有__init__()方法,当你使用类创建一个实例时,Python会自动运行它。但是,如果你的初始方法不满足这个约定,那么在创建实例时方法将不会被调用,这可能会导致一些错误。
__init__()方法有一个固定形参self,它必不可少且位置必须在最前边。定义了self之后,Python调用初始化方法来创建实例时,将自动传入实参self,它是指向实例本身的引用,让实例能够访问类中的属性和方法。
举个例子:有一个汽车类,初始入参包括品牌和型号,具有开车和停车两种行为。
创建汽车实例时,Python将自动调用__init__()方法。我们通过实参向汽车类传递品牌和型号,而self会自动传递。
表示汽车行为的方法中,使用的变量(品牌和型号)都有前缀self,这种形式的变量(self.obj)可供类中所有方法使用,可通过类的任意实例去访问。这种可通过实例访问的变量称为属性。
下边,我们通过上面介绍的类来创建一个特定品牌的汽车实例。
示例中,我们在 line 17处使用实参“BYD"和”Han“通过Car类的__init__()方法来创建了一个实例,且将这个实例赋给变量my_car。这时,实例my_car就可以通过句点(英文状态下的.)来访问类的属性和方法了。访问属性时,我们将汽车型号改为”Qin“,再执行类中的方法,可以看到修改的属性生效了。
指定默认值
类中的某些属性,可以通过__init__()方法指定一个默认值。书接上例,我们给汽车的初始化方法中增加一个默认值为0的变量mileage(里程),但汽车的里程表数总是变化的,我们需要一个方法来修改这个属性的值。
修改属性值
修改属性值有两种方式:直接给属性赋值,和通过方法给属性赋值。
前边在创建实例时,我们中途将汽车型号改成了”Qin“,就属于直接给属性赋值。这里我们再修改一下里程数:
通过方法修改属性值,就是定义一个方法,在方法中修改属性的值。我们来制定一个修改里程数的方法update_mileage,然后输出变更后的里程数:
编写类时,并非总要从头开始,可以通过继承来直接获得另一个类的所有属性和方法。被继承的类称为父类,而产生的新类称为子类。子类在继承父类的属性和方法的同时,还可以定义自己的属性和方法,即可扩展性。
创建子类时,父类必须包含在当前文件中,且位于子类前面。子类的类名之后必须以圆括号指出父类的名称。
继承时要调用父类的__init__()方法,这将初始化在父类__init__()方法中定义的所有属性,从而子类也包含了这些属性。
我们以汽车类为例,创建一个如今火热的汽车类型——电动汽车为其子类。
在子类ElectricCar的__init__()方法中,通过super()显式的调用了父类的初始化方法,于是可以直接使用父类的所有属性了。在继承关系中父类也称为超类superclass,名称super由此而来。
除了super()显式的调用,我们试试另外的方式是否可行。为了方便,我们略去父类代码,只贴图显式修改的子类及其运行结果。
首先,父类声明__init__()方法,子类不声明:
可以看到,结果仍然是正确的。说明在这种场景下子类默认调用了父类的初始化方法。
其次,父类声明_init__()方法,子类也声明_init__()方法,但子类不调用父类的初始化:
可以看到,子类无法正常调用父类的属性和方法了。
结合前边的例子,我们可以判断出,子类如果写了__init__()方法,就必须显式的调用父类的初始化;如果子类没有__init__()方法,则默认使用父类的初始化。
继承了父类之后,我们就可以着手进行改造了,比如添加子类独有的属性和方法,或者父类的方法不能满足子类时对其进行重写。
我们给电动汽车增加一个独有属性:电瓶,以及一个独有的方法:描述电瓶。
要在子类中重写父类方法, 方法名必须与父类中的对应方法名称一致,这时再根据方法名调用,使用的就是子类的方法,Python会忽略父类中的方法,或者说父类中的方法被子类覆盖了。
比如,普通汽车要加油,而电动车需要充电,那么Car类的加油方法fill_gas_tank对电动汽车类就没有意义了,我们把它重写一下。
父类:
子类:
可以验证,执行的确实是子类的方法。
假如在某些场景下,我们重写了父类的方法之后又需要调用父类的方法,该怎么办呢?
第一种办法:father_class_name.method_name()
第二种办法:super(). method_name()
第三种:super(son_class_name, selft).method_name()
所学尚浅,就先介绍到这里。
随着类属性和方法的不断扩充,类文件可能会越来越长,导致阅读和使用都不是很方便。这时,可以把类的一部分提取出来作为一个独立的类。
例如,我们把电动汽车的电瓶相关属性提取出来专门放到一个类Battery中,并将Battery实例作为电动汽车类的属性。
当一个类文件过长时,即使使用了继承也没法做出多大的改善。这时我们就可以通过导入功能来保持单个文件的简短整洁。
1、导入单个类
from module_name import Class
例如,from car import Car
2、一个模块存储多个类
比如本篇我们使用的例子,汽车类、电动汽车类和电瓶类写在一个模块中。如果要使用模块中的类,可以结合第1条的方法,导入要使用的类并创建实例。
3、从一个模块导入多个类
第1条介绍了导入单个类的公式,这里补充一下导入多个类的公式:
from module_name import Class_a, Class_b
4、导入整个模块
导入整个模块,再使用句点表示法访问需要的类。
例:
5、导入模块中的所有类
from module_name import *
但是,不推荐这种用法,一是没有明确指出使用了模块中的哪些类,二是可能引发名称方面的迷惑——如果导入类与当前文件出现同名类,将引发难以诊断的错误。
如果需要从一个模块中导入很多类,第4种方式更好。
6、在一个模块中导入另一个模块
比如我们将Car类和Electric_car类分别保存成单独的模块,这样在编写业务代码时可以同时导入这两个模块并创建实例。
7、使用别名
和模块中的别名使用是一样的。
from module_name import Class_name as CN
Python标准库是一组模块,其中包含了很多通用的基本功能函数和类。使用标准库只需一条import语句,语法和类的导入是相同的。具体的内容这里不做介绍。
(本片完)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。