python 支持面向过程编程和面向对象编程。

传统面向过程编程,也叫函数式编程,通过我们的需求设计成一个一个的函数来完成,对一些小规模程序来说面向过程确实简单方便不少。而随着互联网的发展,对于一些大型的项目来说,使用面向对象编程更具有优势,在后期的维护上也更加容易。

面向对象编程有三大特性:封装、继承、多态。

类的创建

  1. class 类名(父类名称):
  2. 类体
  3. # 其中类体包括 类成员,方法,数据属性等
  4. # object 是所有类的祖父类
  5. # 类体也可以用 pass

简单类的组成

  1. class per(object):
  2. "注释" #类文档字符串 '*' "*" """"*""
  3. var=1.1 #类变量、类属性。成员变量
  4. def __init__(self): #构造方法
  5. print("构造 ……")
  6. def __del__(self): #析构方法
  7. print("析构 ……")
  8. def run(self): #类成员方法
  9. print("run ……")
  10. tmp=per() #实例化对象
  11. tmp.run() #调用类对象方法
  12. print(tmp.__doc__) #打印注释字符串
  13. 输出:
  14. 构造 ……
  15. run ……
  16. 注释
  17. 析构 ……

封装

主要是以类的方式将我们的需求抽象为实体后所共有的特性组成的集合,通过将属性与方法封装在一个对象中,只对外提供所需接口。是我们的程序结构、逻辑层次上更加清晰,便于程序的开发和后期维护。

类属性和实例属性

在python的类中,属性主要分为两种,一种是类属性,它直接分布在类中,不需要我们的实例就可以调用。

另一种是实例属性,实例属性只能依赖实例调用。

其中

  • 实例属性和实例方法只能被该类的实例访问
  • 类变量可以直接被类和类所创建的实例访问
  • 类变量只能通过类去修改,不可以通过类的实例去修改
  1. class per(object):
  2. var = 1.1 #类变量
  3. def run(self):
  4. print("runing ……")
  5. tmp=per() #实例1 tmp
  6. tmp2=per() #实例2 tmp2
  7. print(per.var) #直接通过类访问类变量
  8. print(tmp.var,tmp2.var) #通过实例1,实例2访问类变量
  9. tmp.name = "张三" #实例1 tmp.name
  10. tmp2.age = 18 #实例2 tmp2.age
  11. print(tmp.name) #输出实例1 的name
  12. print(tmp2.age) #输出实例2 的age
  13. 输出:
  14. 1.1 #类变量 var 的值
  15. 1.1 1.1 #
  16. 张三 # tmp.name 的值
  17. 18 # tmp2.age 的值

实例拥有自己的空间,我们通过类外绑定属性的方式生成的实例属性不是所有实例(对象)所共有的,实例1不具有实例2的属性 age,实例2也不具有实例1的属性 name。同时类也拥有自己的空间,保存着类和对象所共有的属性 如 var,但是类不可以调用实例方法,如per.run() 就是不允许的。

只能通过类修改类变量。

  1. print("var =",per.var)
  2. per.var = 100
  3. print("var =",per.var)
  4. 输出:
  5. var = 1.1
  6. var = 100

可以通过构造函数定义实例变量。其中通过 self 修饰就可以定义实例变量

  1. class per(object):
  2. var = 1.1
  3. def __init__(self,myname,myage):
  4. self.name = myname #name 实例属性
  5. self.age = myage #age 实例属性
  6. def run(self):
  7. print("runing ……")
  8. tmp=per("张三",18) #实例1 tmp
  9. tmp2=per("李四",20) #实例2 tmp2
  10. print(tmp.name,tmp.age) #输出实例1 的name,age
  11. print(tmp2.name,tmp2.age) #输出实例2 的name,age

总结:

类属性,可以简单理解为定义在类方法外的属性。

实例属性,在__init__构造函数内定义的属性。

类属性可以直接用类名访问,修改,也可以用实例名访问,只读。并且,当实例访问类不存在的属性时,会在实例中新建属性

公有方法和私有方法

在python 中通过在实例属性或者实例方法前加上 __xx 会改变其对外方式,即被声明为私有模式。正常情况下所有实例属性默认为公有状态。

  1. class per(object):
  2. var = 1.1
  3. def run(self):
  4. print("run ……")
  5. def __runing(self):
  6. print("runing ……")
  7. tmp=per() #实例 tmp
  8. tmp.run() #调用公有的实例方法
  9. #tmp.runing() #私有的实例方法不可以在类外访问
  10. #tmp.__rining() #

同样的,在实例变量例如 self.__name 是私有的实例变量,在类外也不可以访问。私有属性只可以在类内访问。

  1. class per(object):
  2. __var = 1.1 #私有类属性
  3. def run(self):
  4. print("run ……","\nvar = ",self.__var)
  5. def __runing(self):
  6. print("runing ……")
  7. def getRuning(self):
  8. self.__runing()
  9. tmp=per() #实例 tmp
  10. tmp.run() #run() 方法内部访问私有属性
  11. tmp.getRuning() #使用对外接口访问私有方法

继承


  1. class 类名(父类1.父类2 . . . )
  2. 类体
子类继承父类的方法

设计 mylist类,继承我们的列表类

  1. class mylist(list):
  2. pass
  3. lst=mylist()
  4. lst.append(11)
  5. print(lst)
  6. 输出:
  7. [11]

子类继承了父类的属性和方法。可以直接使用父类的方法,也可以对父类的方法进行再包装形成新的方法。

  1. class mylist(list):
  2. def headinsert(self,val):
  3. """实现头部插入"""
  4. self.insert(0,val)
  5. lst=mylist()
  6. lst.append(11)
  7. lst.headinsert(1)
  8. print(lst)
  9. 输出:
  10. [1,11]
子类重写父类方法

如果父类方法不能满足的需求,可以在子类重写父类的方法。在子类方法与父类方法重名时,会优先调用子类的方法。

  1. class mylist(list):
  2. def headinsert(self,val):
  3. """实现头部插入"""
  4. self.insert(0,val)
  5. def copy(self):
  6. """重写list的copy方法"""
  7. print("this is mylist.copy")
  8. lst=mylist()
  9. lst.append(11)
  10. lst.headinsert(1)
  11. print(lst)
  12. lst.copy()
  13. 输出:
  14. [1, 11]
  15. this is mylist.copy
扩展父类的方法

可以在子类中使用 super().xxx 调用父类的方法,比如我们想实现插入数据后提示 “ok” 的功能。

  1. class mylist(list):
  2. def append(self,val):
  3. """扩展list的append方法"""
  4. super().append(val)
  5. print("ok")
  6. lst=mylist()
  7. lst.append(1)
  8. lst.append(11)
  9. print(lst)
  10. 输出:
  11. ok
  12. ok
  13. [1, 11]

多继承

python中继承可以继承父类的构造函数,并且多继承是可以使用每个父类的方法的。

  1. class A():
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def print_A(self):
  6. print(self.name,self.age)
  7. class B():
  8. def print_B(self):
  9. print("this is B")
  10. class C(A,B):
  11. """多继承"""
  12. pass
  13. c=C("张三",18)
  14. c.print_A()
  15. c.print_B()

如果继承的父类中存在同名方法,会从左至右、深度优先搜索第一个方法名。比如

  1. A B
  2. C(A) D(B)
  3. E(C,D)

在这种关系的继承中,调用一个名为 func() 的方法,会依次从 C、A、D、B中搜索对应方法名。

多态

简单来讲就是一种方法在调用时呈现出不同的状态(不同的功能)。前面也讲到了,在子类中存在同名方法会优先调用子类的方法。下面的 Dog类,Cat类均继承自 Animal类,我们通过调用 todo() 方法来实现一种多态的方式。

  1. class Animal():
  2. def do(self):
  3. print("我是动物 ")
  4. class Dog(Animal):
  5. def do(self):
  6. print("我是狗,汪~ ")
  7. class Cat(Animal):
  8. def do(self):
  9. print("我是猫,咪~")
  10. def todo(animal):
  11. animal.do()
  12. a=Animal()
  13. todo(a)
  14. d=Dog()
  15. todo(d)
  16. c=Cat()
  17. todo(c)
  18. 输出:
  19. 我是动物
  20. 我是狗,汪~
  21. 我是猫,咪~

todo()方法通过传入的参数类型不同,从而实现不同的功能,表现出多种状态。

python学习笔记(四)——面向对象编程的更多相关文章

  1. python学习笔记(七):面向对象编程、类

    一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...

  2. python 学习笔记7 面向对象编程

    一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...

  3. Python学习笔记之面向对象编程(三)Python类的魔术方法

    python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法.这些方法有特殊的用途,有的不需要我们自己定义,有的则通过一些简单的定义可以实现比较神奇的功能 我主要把它们分为三个部分,下文也是分 ...

  4. python学习笔记1 -- 面向对象编程高级编程1

    说起高级其实也就是些基础的东西,但是活用和熟用肯定会大幅度提升代码质量 首先要记录的是面向对象的灵活性,及如何去控制其灵活性,她允许你在实例中新增属性和方法,允许你给类新增属性和方法,也支持在定义类时 ...

  5. python学习笔记1 -- 面向对象编程类和实例

    由于之前有一定基础,所以python中的类的概接受的比较快,与其他语言一样, python也是通过类来进行事务的抽象,一切皆对象,要不然怎么说程序员不缺对象呢. 言归正传,python中类的声明是cl ...

  6. python自动化测试学习笔记-7面向对象编程,类,继承,实例变量,邮件

    面向对象编程(OOP)术语: class TestClass(object):   val1 = 100       def __init__(self):     self.val2 = 200   ...

  7. python学习笔记_week6_面向对象

    面向对象 介绍(特性(class.object--->封装.继承,多态)).--->世界万物,皆可分类:世界万物,皆可对象 只要是对象,就肯定属于某种品类:只要是对象,就肯定有属性 你是上 ...

  8. javascript 学习笔记之面向对象编程(一):类的实现

    ~~想是一回事,做是一回事,写出来又是一回事~~一直以来,从事C++更多的是VC++多一些,从面向过程到面向对象的转变,让我对OO的编程思想有些偏爱,将一个客观存在的规律抽象出来总是让人比较兴奋,通过 ...

  9. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  10. python学习笔记(6)--面向对象学习

    本节内容:   面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法.   引言 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做(人狗大战)的游戏,你就思 ...

随机推荐

  1. idea maven: invalid class root

    maven导入依赖没有问题,但是项目lib的类飘红,实际导入的类中有一些没有,这是idea的问题,重启idea,发现需要重新导入项目,重新导入后问题解决. 原因:可能之前误删了项目中idea的一些文件 ...

  2. 多个n维向量围成的n维体积的大小

    前言 上周我们数学老师给了我们一道题,大意就是两个向量a和b,一个点M=$x*a+y*b$,x,y有范围,然后所有M组成的面积是一个定值,求x+y的最小值.当然这是道小水题,但我在想,如果把两个向量变 ...

  3. idea教程--使用maven创建web项目

    1.单击create new project 2.运行maven项目 在pom.xml文件中添加tomcat插件然后如下图运行;

  4. omnet++:用到的方法和语句

    1.方法 方法 说明 msg->getName() 获取发送的消息名 uniform(a,b) 生成[a,b]间的随机实数 intuniform(a,b) 生成[a,b]间的随机整数 expon ...

  5. petite-vue源码剖析-v-if和v-for的工作原理

    深入v-if的工作原理 <div v-scope="App"></div> <script type="module"> i ...

  6. C#发送邮件,可带有Excel附件

    记录工作中遇到发邮件带附件的需求,新建控制台应用程序,目录下创建好所需要的定义好的Excel模板! class Program { static string newExcelPath = strin ...

  7. 从读写角度,带你了解数仓的IO基本框架

    摘要:本文从读取和写入的角度分别描述了行存和列存的IO模型,并对文件结构做了简单介绍. 本文分享自华为云社区<GaussDB(DWS)基本IO框架>,作者: Naibaoofficial. ...

  8. pandas常用操作详解——.loc与.iloc函数的使用及区别

    loc与iloc功能介绍:数据切片.通过索引来提取数据集中相应的行数据or列数据(可以是多行or多列) 总结: 不同:1. loc函数通过调用index名称的具体值来取数据2. iloc函数通过行序号 ...

  9. linux指令_张三

    1.基础指令语法 ls (路径) 含义:列出当前工作目录下的所有文件/文件夹的名称 pwd(printworkingdirectory,打印当前工作目录) cd (路径)       作用:用于切换当 ...

  10. Android 12(S) 图形显示系统 - BufferQueue的工作流程(九)

    题外话 Covid-19疫情的强烈反弹,小区里检测出了无症状感染者.小区封闭管理,我也不得不居家办公了.既然这么大把的时间可以光明正大的宅家里,自然要好好利用,八个字 == 努力工作,好好学习 一.前 ...