python 学习笔记9(面向对象)
面向过程、函数式、面向对象
- 面向过程:根据业务逻辑从上到下写垒代码
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象(Object Oriented Programming,OOP):对函数进行分类和封装,让开发“更快更好更强...
面向过程
是用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
函数式编程
增强代码的重用性和可读性
面向对象
面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对 象”的使用。
创建类和对象
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
- class bar: #定义一个类
- def f(self,arg): #方法
- print(arg)
- return 2
- obj = bar() #中间人
- a = obj.f(1) #类的调用
- print(a)
- class bar: #定义一个类
- def f(self,arg): #方法
- print(self,self.name,self.age,arg)
- return 2
- obj = bar() #中间人 #self 就是对象(中间人)
- print(obj)
- obj.name="liu" #<__main__.bar object at 0x0000000000A74160>
- obj.age = 18 #<__main__.bar object at 0x0000000000A74160> liu 18 1
- obj.f(1)
- #类的调用
- obj2= bar() #中间人 #self 就是对象(中间人)
- print(obj2)
- obj2.name="Alex" #<__main__.bar object at 0x0000000000D04240>
- obj2.age = 38 #<__main__.bar object at 0x0000000000D04240> Alex 38 1
- obj2.f(1)
创建方法
- #普通方法
- class bar: #定义一个类
- def f(self,arg):
- print(arg)
- return 2
- obj = bar()
- a = obj.f(1)
- print(a) #1,2
- #构造方法
- class Person:
- def __init__(self,name,age):
- self.n = name
- self.a = age
- def foo(self):
- print(self.n,self.a)
- liu =Person("liu",18)
- print(liu) #<__main__.Person object at 0x00000000006EA630>
- liu.foo() #liu 18
在构造方法中只要创建了对象,则第一时间会执行——init——方法
执行顺序
面向对象三大特性
一 、封装
- #封装
- class Person:
- def __init__(self,name,age):
- self.n = name
- self.a = age
- self.x = "o"
- def foo(self):
- print(self.n,self.a,self.x)
- liu =Person("liu",18)
- li = Person("li",20)
- print(liu) #<__main__.Person object at 0x00000000007B42E8>
- liu.foo() #liu 18 o
封装
封装在self中,即:封装在调用的对象中(本例中的liu、li),本例为构造方法,只要创建对象,python内部会第一时间自动执行
对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
二 、继承
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
1、继承
class 父类: 父类雅名:基类
pass
class 子类(父类): 子类雅名:派生类
pass
- #继承
- class A:
- def a1(self):
- print("")
- def a2(self):
- print("")
- class B(A):
- def b1(self):
- print("")
- obj = B()
- obj.b1() #
- obj.a1() #
- obj.a2() #
继承
2、重写
防止执行父类中的方法
- class A:
- def a1(self):
- print("")
- def a2(self):
- print("")
- class B(A):
- def b1(self):
- print("")
- def a2(self):
- print("")
- obj = B()
- obj.b1() #
- obj.a1() #
- obj.a2() #
重写
如果一定要执行父类中的方法
- class A:
- def a1(self):
- print("")
- def a2(self):
- print("")
- class B(A):
- def b1(self):
- print("")
- def a2(self):
- super(B,self).a2()
- #A.a2(self) #和上边的super方法一样,推荐使用super方法
- print("")
- obj = B()
- # obj.b1()
- # obj.a1()
- obj.a2() #2222222222 44444444444
(1)super(子类, self).父类中的方法(...)
(2)父类名.父类中的方法(self,...)
3、self永远是执行方法的调用者
4、Python中支持多继承
a. 左侧优先
b. 一条道走到黑
c. 同一个根时,根最后执行
- #多父类的方法中
- #1.从左到右
- #2.一条道走到头
- #3.多父类有共同父类,先左走到最高层(父类的共同父类不执行),然后#后层继续,最后执行父类的共同父类
- class Basrequest:
- pass
- class re_request():
- def f(self):
- print("FFFFFFFFFFFF")
- self.h() #self 相当于obj(zilei的),所以当执行obj.f() 时先打印FFFFFFFFFFFF,下边的调用self.h(),相当于obj.h(),先执行mini中的h方法,
- def h(self):
- print("HHHHHHHHHHHH")
- class mini:
- def h(self):
- print("mininmininmini")
- class zilei(mini,re_request):
- pass
- obj = zilei()
- #obj.h() #mininmininmini
- obj.f() #FFFFFFFFFFFF
- #mininmininmini
多继承
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
Python的类可以继承多个类,Java和C#中则只能继承一个类
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
- class D:
- def bar(self):
- print 'D.bar'
- class C(D):
- def bar(self):
- print 'C.bar'
- class B(D):
- def bar(self):
- print 'B.bar'
- class A(B, C):
- def bar(self):
- print 'A.bar'
- a = A()
- # 执行bar方法时
- # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
- # 所以,查找顺序:A --> B --> D --> C
- # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
- a.bar()
经典类多继承
- class D(object):
- def bar(self):
- print 'D.bar'
- class C(D):
- def bar(self):
- print 'C.bar'
- class B(D):
- def bar(self):
- print 'B.bar'
- class A(B, C):
- def bar(self):
- print 'A.bar'
- a = A()
- # 执行bar方法时
- # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
- # 所以,查找顺序:A --> B --> C --> D
- # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
- a.bar()
新式类多继承
三 、多态
Pyhon不支持Java和C#这一类强类型语言中多态的写法,python中是原生多态
- # Java
- string v = 'alex'
- def func(string arg):
- print(arg)
- func('alex')
- func(123) #会报错
- # Python
- v = 'alex'
- def func(arg):
- print(arg)
- func(1)
- func('alex')
面向对象---适用场景
如果多个函数中有一些相同参数时,转换成面向对象
- class DataBaseHelper:
- def __init__(self, ip, port, username, pwd):
- self.ip = ip
- self.port = port
- self.username = username
- self.pwd = pwd
- def add(self,content):
- # 利用self中封装的用户名、密码等 链接数据
- print('content')
- # 关闭数据链接
- def delete(self,content):
- # 利用self中封装的用户名、密码等 链接数据
- print('content')
- # 关闭数据链接
- def update(self,content):
- # 利用self中封装的用户名、密码等 链接数据
- print('content')
- # 关闭数据链接
- def get(self,content):
- # 利用self中封装的用户名、密码等 链接数据
- print('content')
- # 关闭数据链接
- s1 = DataBaseHelper('1.1.1.1',3306, 'alex', 'sb')
场景--访问数据库
函数式编程 和 面向对象 使用情景
对于 C# 和 Java 程序员来说不存在这个问题,因为该两门语言只支持面向对象编程(不支持函数式编程)。而对于 Python 和 PHP 等语言却同时支持两种编程方式,且
函数式编程能完成的操作,面向对象都可以实现;而面向对象的能完成的操作,函数式编程不行(函数式编程无法实现面向对象的封装功能)。所以,一般在Python开发中,全部
使用面向对象 或 面向对象和函数式混合使用
类和对象在内存中保存状况
类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份
类成员
一、字段
1.普通字段
2.静态字段
二、方法
1.普通方法
2.静态方法
3.类方法
三、属性(特性)
一、字段
普通字段属于对象(保存在对象中,执行只能通过对象访问)
静态字段属于类 (保存在类中, 执行可以通过对象访问 也可以通过类访问)
- class provice:
- country = "中国" #静态字段
- def __init__(self,name):
- self.name = name #普通字段
- #self.country = "中国"
- print(provice.country) #中国
- shanxi = provice("陕西")
- a = shanxi.name
- print(a) #陕西
字段
静态字段在内存中只保存一份
普通字段在每个对象中都要保存一份
应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段
二、方法
普通方法,保存在类中,由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
静态方法,保存在类中,由类调用;无默认参数;
类方法,保存在类中,至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls
- 方法(一一对应)
- #普通方法
- #静态方法
- #类方法
- class foo:
- def a(self): #普通方法
- print("aaaaaaaaaaaaa")
- @staticmethod #静态方法
- def b(): #没有参数,可自己加
- print("")
- @staticmethod ##静态方法
- def c(a1,b1):
- print(a1,b1)
- @classmethod #类方法
- def d(cls): #参数为cls(class缩写),直接将类传入
- print("pppppppppppppppppp")
- obj = foo()
- obj.a() #aaaaaaaaaaaaa
- foo.b() #
- foo.c(1,2) #1 2
- foo.d() #pppppppppppppppppp
方法
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同。
三、属性(特性)
1.属性的基本使用
2.属性的两种定义方式
1.属性的基本使用
- #属性(特性)
- class foo:
- @property
- def a(self):
- print("aaaaaaaaaaaaa")
- return 1111
- @a.setter
- def a(self,v):
- print(v)
- return 1111
- @a.deleter
- def a(self):
- print("cccccccccc")
- return 1111
- obj = foo()
- f = obj.a #aaaaaaaaaaaaa
- print(f) #
- obj.a = 345 #
- del obj.a #cccccccccc
属性
- 定义时,在普通方法的基础上添加 @property 装饰器
- 定义时,属性仅有一个self参数
- 调用时,无需括号
方法:foo_obj.func()
属性:foo_obj.prop
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第start条到第end条的所有数据(即:limit start , end),这个分页的功能包括:
根据用户请求的当前页和总数据条数计算出start 和 end
根据start 和 end去数据库中请求数据
- #平常方法
- li = []
- for i in range(1000):
- li.append(i)
- while True:
- p = input("请输入页码:")
- p = int(p)
- start = (p-1)*10
- end = p*10
- print(li[start:end])
- #属性方法
- class Pag:
- def __init__(self,currt_pag):
- self.pag = int(currt_pag)
- try:
- p = int(currt_pag)
- except Exception as e:
- p = 1
- @property
- def start(self):
- v1=(self.pag-1)*10
- return v1
- @property
- def end(self):
- v1=self.pag*10
- return v1
- li = []
- for i in range(1000):
- li.append(i)
- while True:
- p = input("请输入页码:")
- # start = (p-1)*10
- # end = p*10
- obj = Pag(p)
- print(li[obj.start:obj.end])
属性应用
Python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回。
2.属性的两种定义方式
装饰器 即:在方法上应用装饰器(在类的普通方法上应用@property装饰器)
例上:属性应用
静态字段 即:在类中定义值为property对象的静态字段(创建值为property对象的静态字段)
- #属性(特性)第二种写法
- class foo:
- def a(self):
- print("aaaaaaaaaaaaa")
- return 1111
- def b(self,v):
- print(v)
- return 1111
- def c(self):
- print("cccccccccc")
- return 1111
- per = property(fget=a,fset=b,fdel=c,doc=".......")#doc=" "可有可无,对per的说明
- obj = foo()
- f = obj.per #自动调用第一个参数中定义的方法:get_bar #aaaaaaaaaaaaa
- print(f) #
- obj.per= 123345 # 自动调用第二个参数中定义的方法:set_bar方法,并将123345当作参数传入 #123345
- del obj.per # 自动调用第三个参数中定义的方法:del_bar方法 #cccccccccc
属性第二种方法
property的构造方法中有个四个参数
- 第一个参数是方法名,调用
对象.属性
时自动触发执行方法 - 第二个参数是方法名,调用
对象.属性 = XXX
时自动触发执行方法 - 第三个参数是方法名,调用
del 对象.属性
时自动触发执行方法 - 第四个参数是字符串,调用
对象.属性.__doc__
,此参数是该属性的描述信息
python 学习笔记9(面向对象)的更多相关文章
- python 学习笔记7 面向对象编程
一.概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." ...
- python学习笔记六 面向对象相关下(基础篇)
面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以将多函数中公用的变量封装到对象中) 对象,根据模板创建的 ...
- python学习笔记_week6_面向对象
面向对象 介绍(特性(class.object--->封装.继承,多态)).--->世界万物,皆可分类:世界万物,皆可对象 只要是对象,就肯定属于某种品类:只要是对象,就肯定有属性 你是上 ...
- Python学习笔记016——面向对象
面向对象是指用类来描述一个对象(实例),用类来建立实例与实例的关联关系 对象 : object 实例 : instance 1 类 1.1 什么是类 类是用来描述对象的工具,用类可以创建一个或 ...
- python学习笔记(七):面向对象编程、类
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
- python学习笔记(6)--面向对象学习
本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引言 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做(人狗大战)的游戏,你就思 ...
- python学习笔记(10):面向对象
一.类和实例 1.类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 2.对象:通过类定义的数据结构实例.对象包括两个数据成员( ...
- python学习笔记(7): 面向对象
class Foo: #类中的函数 def bar(self): #功能阐述 print('Bar') pass def hello(self,name): print('i am %s' %name ...
- Python学习笔记之面向对象
下面是初步总结的Python的面向对象的参数定义,后面会逐渐完善面向对象的相关知识.
- Python学习笔记捌——面向对象高级编程
__slots__特殊变量的使用: 由于Python是动态语言,允许先编写类,然后在创建实例的时候添加属性或者方法:而__slots__特殊变量就是,限制往类里添加属性的: 在创建类的时候,使用__s ...
随机推荐
- js 判断字符串是否包含另外一个字符串
示例代码: <script type="text/javascript"> var str = "测试一个字符串(ehtrzes)是否包含另外一个字符串&qu ...
- cordova开发问题汇总
cordova开发问题汇总 1. 导入工程的"The import android cannot be resolved"错误解决方法 2. MainActivity] Unabl ...
- 12.创建一个Point类,有成员变量x,y,方法getX(),setX(),还有一个构造方 法初始化x和y。创建类主类A来测试它。
package java1; public class Point { int x; int y; Point(int x,int y) { this.x = x; this.y = y; } pub ...
- poj 2031Building a Space Station(几何判断+Kruskal最小生成树)
/* 最小生成树 + 几何判断 Kruskal 球心之间的距离 - 两个球的半径 < 0 则说明是覆盖的!此时的距离按照0计算 */ #include<iostream> #incl ...
- 用DropDownList实现的省市级三级联动
这是一个用DropDownList 实现的省市级三级联动,记录一下········ <asp:ScriptManager ID="ScriptManager1" runat= ...
- Pillow实现图片对比
在编写Web自动化测试用例的时候,如何写断言使新手不解,严格意义上来讲,没有断言的自动化脚本不能叫测试用例.就像功能测试一样,当测试人员做了一些操作之后必然会判断实际结果是否等于预期结果,只不过,这个 ...
- Linux 启动过程分析
本文仅简单介绍Linux的启动过程,在此基础上做简要的分析.对于Linux启动过程中内部详细的函数调用不做介绍,只是希望本文能给新手起到一个抛砖引玉的作用,以便深入研究Linux的启动过程.下图基本展 ...
- Java生成BASE64编码
1.所需jar包: BASE64Encoder.jar 2.在导包过程中,可能会出现工程不识别的情况.即:不能找到BASE64Encoder的jar包.此时,可以有两种方法解决这个问题: a. 只需 ...
- ionic+nodejs开发遇到的跨域和post请求数据问题
最近学习ionic+nodejs开发混合app中遇到了一些问题,在此总结一下. 开发环境搭建 项目地址 https://github.com/ytudt/nodejsApp 代码和问题都会在之后的学习 ...
- Azure Backup (1) 将SQL Server 2012虚拟机中数据库备份到Azure Storage
<Windows Azure Platform 系列文章目录> 本文介绍的是由国内世纪互联运维的China Azure,相比国外的Global Azure.主要区别是存储账号的DNS地址不 ...