Python基础(十一)-面向对象
三种编程范式:
1、函数式编程:函数指数学意义上的函数
由于命令式编程语言也可以通过类似函数指针的方式来实现高阶函数,函数式的最主要的好处主要是不可变性带来的。没有可变的状态,函数就是引用透明(Referential transparency)的和没有副作用(No Side Effect)。 一个好处是,函数即不依赖外部的状态也不修改外部的状态,函数调用的结果不依赖调用的时间和位置,这样写的代码容易进行推理,不容易出错。这使得单元测试和调试都更容易。 不变性带来的另一个好处是:由于(多个线程之间)不共享状态,不会造成资源争用(Race condition),也就不需要用锁来保护可变状态,也就不会出现死锁,这样可以更好地并发起来,尤其是在对称多处理器(SMP)架构下能够更好地利用多个处理器(核)提供的并行处理能力
2、面向过程编程:
3、面向对象编程:
面向对象编程--类与对象
类与对象初识
类:具有相同属性的事物的集合,只是一个抽象概念(Python中将具有相同数据属性和函数属性(方法)的对象集合的抽象定义为一个类)
对象:就是一个具体存在的事物(Python中由类实例化得到的就叫做一个对象(实例))
实例化:由类生成一个对象(实例)的过程就叫实例化
class China:#类名
"this is China" #类的文档字符串 capital=Beijing #类的数据属性
def __init__(self,a,b): #类的初始化函数(定义对象的数据属性)
self.a=a
self.b=b
def func(self): #类的函数属性(默认返回None,也可以加return)
pass obj=China(a,b) #实例化 #从结构上类似函数的定义 实例化的过程实质就是执行类的初始化函数,得到一个数据属性字典 查看所有属性:dir(obj) 返回列表,只有属性名
查看类的属性字典:print(China.__dirt__) obj.func() # 对象调用类方法 Python默认会将obj传到第一个位置参数,而类调用方法则没有
China.func(obj) # 类调用方法,如果有参数就必须传参
# 对象可以调用类的所有属性,但类则无法调用对象里的属性(类似函数的作用域) ## 类和对象调用方法都是类名(对象名).函数名,没有点的调用,直接写个变量名,那就是类外的变量
分类:
Python2中有经典类与新式类之分,而Python3中则统一按照新式类处理(之后类的优先顺序会具体看到)
class a: #经典类
pass class a(父类):#新式类 二者区别就在有无继承父类
pass
以上是Python2中类,Python3中都是新式类,默认继承object类,继承顺序是根据c3算法,可以通过__mro__方法查看
类与对象的属性操作(增、删、改、查)
#类属性又称为静态变量,或者是静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例。
#如果你是一位Java或C++程序员,这种类型的数据相当于在一个变量声明前加上static关键字。
class Chinese:
country='China'
def __init__(self,name):
self.name=name def play_ball(self,ball):
print('%s 正在打 %s' %(self.name)) def say_word(self,word):
print('%s 说 %s' %(self.name,word)) #查看类属性
print(Chinese.country) #修改类属性
Chinese.country='CHINA'
print(Chinese.country) #删除类属性
del Chinese.country #增加类属性
Chinese.Country='China'
Chinese.location='Asia'
print(Chinese.__dict__) #类的数据属性增删改查与函数属性是一样的
Chinese.say_word=say_word
print(Chinese.__dict__)
alex_obj=Chinese('alex')
Chinese.say_word(alex_obj,'我是一只来自北方的狼狗')
类属性操作
class Chinese:
country='China'
def __init__(self,name):
self.name=name def play_ball(self,ball):
print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('alex')
print(p1.__dict__) #查看对象属性 (如果对象没有则会调用类,类也没有就报错)
print(p1.country) #修改、增加
p1.country='A' 这是赋值,如果有这个属性就是修改,没有就是增加
print(p1.__dict__) #此时就是增加
p1.country='B' #此时就是修改 #删除
del p1.country #没有该属性会报错
对象属性操作
对象与类的动态添加方法
class Student(object):
pass def set_age(self,age): #定义一个函数作为实例方法
self.age=age from types import MethodType
s=Student()
s.set_age=MethodType(set_age,s) #给实例绑定一个方法==> 类具有该方法吗?或者说其他实例能调用该方法吗?
s.set_age()
print(s.age) # 直接绑在实例s上 s1=Student()
s1.set_age()
print('实例s1--',s1.age) #显然其他实例没有该方法 ############### File "E:/PyCharm/Personal_practice/suanfa/paixu.py", line , in <module>
s1.set_age()
AttributeError: 'Student' object has no attribute 'set_age'
给实例
注意:
1.类实例化得到对象,实质就是执行了类的__init__函数,得到一个数据属性字典,所有说对象没有函数属性,但可以调用类的函数属性
2.类和对象调用属性使用 类名(对象).属性名,直接写个属性名就是调用类外的变量,切记 !
age=10000000000
class Chinese:
country='China'
age=10
l=[] def __init__(self,name):
self.name=name def play_ball(self,ball):
print('%s 正在打 %s' %(self.name,ball)) p1=Chinese('wupeiqi') #实例化
p2=Chinese('alex') p1.age=100 #给对象的age数据属性赋值,没有该属性的话就是增加
p2.age=101 print(p1.age,p2.age)
print(age) #这就是类外的变量调用
print(Chinese.age) p1.l.append('p1') #对p1.l列表进行追加,没有就是对类列表追加
p2.l.append('p2') #同上,操作对象是列表
print(Chinese.l)
print(p1.l)
print(p2.l)
3.对象调用函数属性,Python会自动在第一个位置参数加上对象本身,类则没有,切记 !
静态属性、类方法、静态方法
初衷都是为了实现类直接能调用方法(本来必须传个对象)
静态属性没什么卵用,返回个property object
类方法可以接收返回值,方法内无法调用对象的数据属性self.a,可以调用类的数据属性cls.b
静态方法也可以接收返回值,方法内既不可以调用类的数据属性也不可以调用对象数据属性,而且它不像以上两种方法必须有个位置参数(self,cls)
三者比较结果:类方法相对灵活些
class Room:
x=1
y='hei'
def __init__(self,name,owner,length,wide,high):
self.name=name
self.owner=owner
self.length=length
self.wide=wide
self.high=high
@property #静态属性 给类调用方法,对象也可以调用该方法
def cal_area(self):
# print('%s 住的 %s 面积是 %s'%(self.owner,self.name,self.length*self.wide))
return self.length*self.wide r1 = Room('cesuo', 'alex', 10, 10, 10)
print(r1)
print(Room.cal_area) #感觉没什么卵用 得到一个proprety object so能干嘛?
r1.cal_area=10
print(r1.cal_area) #对象照样用
print(r1.__dict__) def cal_volume(self):
print('%s住的%s体积是%s'%(self.owner,self.name,self.length*self.wide*self.high)) @classmethod #类方法:专门给类直接调类的函数属性使用(这是存在的初衷),(因为之前调用必须传入实例)与实例无关,
def fuck(cls,a):
cls.a=a
return a
return cls.y #可以调用类的数据属性
return self.length*self.wide #类方法内无法调用初始化函数中对象数据属性 r1 = Room('cesuo', 'alex', 10, 10, 10)
print(r1.fuck())
l=Room.fuck(1) #类调用之后能得到返回值 这个就有些用了
print(l) @staticmethod
def yoyo(a,b,c): #可以没有位置参数,不像以上两种方法,必须传个位置参数self,cls
# print(a,b,c)
# return self.name #方法内无法调用对象数据属性
# return x #无法调用类的数据属性
return a
print(Room.yoyo(1,2,3))
一个例子全部搞定
继承
继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
组合
类跟类之间没有共同点,但之间有关联或包含关系,比如老师属于某个学校,学生属于某个学校,课程属于某个老师
比如手、脚、头、躯干,都属于身体(或者说组成身体)
用途:
1、做关联
2、小的类组成大的类
class Hands:
pass
class Feet:
pass
class Head:
pass
class Trunk:
pass
class Body:
'this is body'
def __init__(self,name,hand,feet,head,trunk):
self.name=name
self.hand=Hands
self.foot=feet
self.head=Head
self.trunk=Trunk
事例1
class School:
def __init__(self,name,addr):
self.name=name
self.addr=addr
def tell_info(self):
print('School(%s,%s)' %(self.name,self.addr)) class Course:
def __init__(self,name,price,period,school):
self.name=name
self.price=price
self.period=period
self.school=School #此处就是组合的体现(与上面的School相关联) #其实关联的实际意义就体现在数据的重复利用,比如已经创建了两个School实例,再建Course实例的时候就不需要再手动传输school,只需在已经创建的两个School实例中选择即刻
事例2
接口与归一化设计
class Interface:#定义接口Interface类来模仿接口的概念,python中压根就没有interface关键字来定义一个接口。
def read(self): #定接口函数read
pass def write(self): #定义接口函数write
pass class Txt(Interface): #文本,具体实现read和write
def read(self):
print('文本数据的读取方法') def write(self):
print('文本数据的读取方法') class Sata(Interface): #磁盘,具体实现read和write
def read(self):
print('硬盘数据的读取方法') def write(self):
print('硬盘数据的读取方法') class Process(Interface):
def read(self):
print('进程数据的读取方法') def write(self):
print('进程数据的读取方法')
接口
实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。
抽象类
跟接口类类似,不同的地方是抽象类只能继承,不能实例化
#_*_coding:utf-8_*_ #一切皆文件
import abc #利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta):
all_type='file'
@abc.abstractmethod #定义抽象方法,无需实现功能
def read(self):
'子类必须定义读功能'
pass @abc.abstractmethod #定义抽象方法,无需实现功能
def write(self):
'子类必须定义写功能'
pass # class Txt(All_file):
# pass
#
# t1=Txt() #报错,子类没有定义抽象方法 class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('文本数据的读取方法') def write(self):
print('文本数据的读取方法') class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('硬盘数据的读取方法') def write(self):
print('硬盘数据的读取方法') class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
def read(self):
print('进程数据的读取方法') def write(self):
print('进程数据的读取方法') wenbenwenjian=Txt() yingpanwenjian=Sata() jinchengwenjian=Process() #这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read() print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)
Python中实现抽象类
子类调用父类方法super
class A:
def a(self):
print('A.a') def d(self):
print('A.d') class B:
def b(self):
print('B.b') class C(A,B):
def a(self):
super().a()
print('C.a') def c(self):
print('C.c') def d(self):
print('C.d') class D(C):
def c(self):
print('D.c') print(D().a())
super
注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表
当然也可以使用 父类名.父类方法() 的方式直接写在子类代码中,耦合性太强
Python基础(十一)-面向对象的更多相关文章
- Python 基础 四 面向对象杂谈
Python 基础 四 面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...
- (转)Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...
- 二十. Python基础(20)--面向对象的基础
二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...
- python基础,函数,面向对象,模块练习
---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? # [] {} () None 0 2,位和字节的关系? # ...
- Day7 - Python基础7 面向对象编程进阶
Python之路,Day7 - 面向对象编程进阶 本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...
- Python基础7 面向对象编程进阶
本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 经典 ...
- Python高手之路【十一】python基础之面向对象
创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用. 类就是一个模板,模板里可以包含多个函数, ...
- Python之路【第六篇】python基础 之面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 和 issubclass(su ...
- Python之路【第六篇】python基础 之面向对象(一)
一.三大编程范式 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比 ...
随机推荐
- 关于Ajax无刷新分页技术的一些研究 c#
关于Ajax无刷新分页技术的一些研究 c# 小弟新手,求大神有更好的解决方案,指教下~ 以前做项目,用过GridView的刷新分页,也用过EasyUI的封装好的分页技术,最近在老项目的基础上加新功能, ...
- 代码契约CodeContract(八)
代码契约(Code Contract):它并不是语言本身的新功能,而是一些额外的工具,帮助人们控制代码边界. 代码契约之于C#,就相当于诗词歌赋之于语言. --- C# in Depth 一,概述 1 ...
- android自定义View---生成虚线的View
1.在res/values/目录下 新建文件 attrs.xml <? xml version = "1.0" encoding = "utf-8&q ...
- Liferay的架构:缓存(第一部分)
这次,我将要涉及到一个非常重要的概念:缓存.在当今的web应用中,如果没有设计一个比较好的缓存系统,在web中就不可能有一个良好的性能.所以我将要 提到的缓存不仅仅能够更好地理解Liferay架构,而 ...
- 如何保存PDF、Word和Excel文件到数据库中
在项目中,有时候我们很需要把PDF.Word和Excel文档等等上传到数据库,以便日后使用.今天这篇文章向大家讲解如何将这些文件保存到数据库的. 详细步骤 第一步:打开数据库,单击新建查询,创建一个名 ...
- C++ 头文件系列(deque)
简介 deque是double ended queue(即双端队列)的简称. 就像C++中的大部分容器的一样,deque具有以下属性: 顺序的(sequence) 动态增长的(dynamic grow ...
- 【Python网络爬虫四】通过关键字爬取多张百度图片的图片
最近看了女神的新剧<逃避虽然可耻但有用>,同样男主也是一名程序员,所以很有共鸣 被大只萝莉萌的一脸一脸的,我们来爬一爬女神的皂片. 百度搜索结果:新恒结衣 本文主要分为4个部分: 1.下载 ...
- 【Zookeeper】源码分析之持久化--FileSnap
一.前言 前篇博文已经分析了FileTxnLog的源码,现在接着分析持久化中的FileSnap,其主要提供了快照相应的接口. 二.SnapShot源码分析 SnapShot是FileTxnLog的父类 ...
- (转载)python日期函数
转载于http://www.cnblogs.com/emanlee/p/4399147.html 所有日期.时间的api都在datetime模块内. 1. 日期输出格式化 datetime => ...
- FragmentPagerAdapter和FragmentStatePagerAdapter区别?
FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例.FragmentStatePagerAdapter:会销 ...