python之面向对象设计、编程
面向对象
一、编程三个范式
1、面向过程编程
2、函数式编程
数学层面的函数
python中的函数编程
3、面向对象编程
二、面向对象设计
1、类:把一类事物共同的特征和共同的动作整合在一起就是类;
2、对象:基于类而创建的一个具体的事物(具体存在的,也是特征和动作的结合)
def dog(name,type,gender):
def chi(dog1):
print("%s 正在嚼骨头!!!" %dog1["name"])
def jiao():
print("%s正在汪汪!!" %dog1["name"])
def init(name,type,gender):
dog= {
"name":name,
"type":type,
"gender":gender,
"chi":chi,
"jiao":jiao
}
return dog
return init(name,type,gender) first_dog= dog("alex","中华田园犬","母")
print(first_dog)
first_dog["chi"](first_dog)
三、面向对象编程
1、类:声明类和函数类似,类是用来描述一类事物,类的对象指的是这一类事物中的一个个体
2、属性
(1)、数据属性:就是变量
(2)、函数属性:就是函数,在面向对象里通常称为方法
备注:类和对象都是通过点来访问自己的属性
class Dog:
name = "alex"
type = "中华田园犬"
def chi():
print("正在嚼骨头")
def jiao(self):
print("一直在犬吠")
dog1 =Dog()
print(dir(Dog))
Dog.chi()
3、实例化
class Dog:
def __init__(self,name,type):
self.mingzi = name
self.leixing = type
def chi(self):
print("%s正在嚼骨头" %self.mingzi)
def jiao(self):
print("一只%s在犬吠" %self.leixing)
dog1 =Dog("alex","中华田园犬") ###实例化
print(dir(Dog))
Dog.chi(dog1)
dog1.jiao()
四、备注
1、静态属性
静态属性的修饰为@property,对方法进行封装,隐藏内部逻辑,将类方法变为类属性
class sch:
###初始化参数
def __init__(self,sch_name,sch_create_time,sch_add,sch_fee,sch_type,sch_level,sch_teach_type,sch_ward,sch_start_edu_time,sch_schedual):
self.name = sch_name
self.sch_name = sch_name
self.sch_create_time = sch_create_time
self.sch_add = sch_add
self.sch_fee = sch_fee
self.sch_type = sch_type
self.sch_level = sch_level
self.sch_teach_type = sch_teach_type
self.sch_ward = sch_ward
self.sch_start_edu_time = sch_start_edu_time
self.sch_schedual = sch_schedual
###定义方法:这是常规的方法定义
def sch_catch_fee(self):
print ("%s本年度学费为%s" %(self.sch_name,self.sch_fee))
###对方法加上装饰器property,隐藏方法内部实现逻辑
@property
def sch_catch_fee(self):
return ("%s本年度学费为%s" %(self.sch_name,self.sch_fee))
2、类方法
使用@classmethod进行修饰,类直接调用,bu用再进行传实例名,跟实例没有任何关系。
class sch:
###初始化参数
def __init__(self,sch_name,sch_create_time,sch_add,sch_fee,sch_type,sch_level,sch_teach_type,sch_ward,sch_start_edu_time,sch_schedual):
self.name = sch_name
self.sch_name = sch_name
self.sch_create_time = sch_create_time
self.sch_add = sch_add
self.sch_fee = sch_fee
self.sch_type = sch_type
self.sch_level = sch_level
self.sch_teach_type = sch_teach_type
self.sch_ward = sch_ward
self.sch_start_edu_time = sch_start_edu_time
self.sch_schedual = sch_schedual
###classmethod方法修饰的方法的哥参数为cls
@classmethod
def sch_edu(cls,x):
print("这是类的方法,与实例没有任何关系",x)
###类可以直接调用
sch.sch_edu(1) #这是类的方法,与实例没有任何关系 1
3、静态方法
使用staticmethod方法进行修饰,不与类、实例绑定,是类的工具包,只是名义上归类管理
class sch:
###初始化参数
def __init__(self,sch_name,sch_create_time,sch_add,sch_fee,sch_type,sch_level,sch_teach_type,sch_ward,sch_start_edu_time,sch_schedual):
self.name = sch_name
self.sch_name = sch_name
self.sch_create_time = sch_create_time
self.sch_add = sch_add
self.sch_fee = sch_fee
self.sch_type = sch_type
self.sch_level = sch_level
self.sch_teach_type = sch_teach_type
self.sch_ward = sch_ward
self.sch_start_edu_time = sch_start_edu_time
self.sch_schedual = sch_schedual
@staticmethod
def post_message(message):
print("本校通知如下:%s" %message)
sch.post_message("本校将于20191207放假")
5、python中关于oop的常用术语
(1)、抽象/实现
抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现这种模型。抽象不仅包括这种模型的数据属性,还定义了这些数据的接口。
对某种抽象的实现就是对此数据及与之相关接口的现实化(realization)。现实化这个过程对于客户 程序应当是透明而且无关的。
(2)、封装接口
封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。通过任何客户端直接对数据的访问,无视接口,与封装性都是背道而驰的,除非程序员允许这些操作。作为实现的 一部分,客户端根本就不需要知道在封装之后,数据属性是如何组织的。在Python中,所有的类属性都是公开的,但名字可能被“混淆”了,以阻止未经授权的访问,但仅此而已,再没有其他预防措施了。这就需要在设计时,对数据提供相应的接口,以免客户程序通过不规范的操作来存取封装的数据属性。
注意:封装绝不是等于“把不想让别人看到、以后可能修改的东西用private隐藏起来”
真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明
(注意:对外透明的意思是,外部调用者可以顺利的得到自己想要的任何功能,完全意识不到内部细节的存在)
python不依赖语言特性去封装数据,而是通过遵循一定的数据属性和函数属性的命名约定来达到封装的效果:
任何以单下划线开头的名字都应该是内部的,私有的,实际上外部还是可以调用的;
class After_sch:
_school = "tongnan middle school"
def __init__(self,name,type):
self.name = name
self.type = type
def fangxue(self):
if self.type == "老师":
print("下班")
else:
print("放学")
class Stu(After_sch):
pass
class Tea(After_sch):
pass
stu1 = Stu("小二","学生")
tea1 = Tea("heaton","老师")
print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
print(stu1._school) ###tongnan middle school 单下划线的外部调用成功
以双下划线开头的名字也是内部的,私有的,是python的约定命名,实际上外部也是可以调用的;
class After_sch:
__school = "tongnan middle school"
def __init__(self,name,type):
self.name = name
self.type = type
def fangxue(self):
if self.type == "老师":
print("下班")
else:
print("放学")
class Stu(After_sch):
pass
class Tea(After_sch):
pass
stu1 = Stu("小二","学生")
tea1 = Tea("heaton","老师")
print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
print(After_sch.__dict__)
# print(stu1.__school) ###'Stu' object has no attribute '__school' 这样调用会报错
print(stu1._After_sch__school) ###tongnan middle school 通过"_类名__属性"调用成功
封装有三个层面上的封装
a、第一个层面:类就是麻袋,这本身就是一种封装;
b、第二个层面:类中定义私有的,只有的类的内部可以使用,外部无法访问,该层面的封装就是上面提到的使用单下划线和双下划线实现的,实际上该中层面的封装外部也是可以调用的;
c、第三个层面:明确区分内外,内部的实现逻辑,外部无法知晓,并且为封装到内部的逻辑提供一个访问接口给外部使用,这才是真正的封装;
(3)、合成
合成扩充了对类的 述,使得多个不同的类合成为一个大的类,来解决现实问题。合成 述了 一个异常复杂的系统,比如一个类由其它类组成,更小的组件也可能是其它的类,数据属性及行为, 所有这些合在一起,彼此是“有一个”的关系。
(4)、派生/继承/继承结构
派生描述了子类衍生出新的特性,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其它的自定义操作,都不会修改原类的定义。
继承描述了子类属性从祖先类继承这样一种方式
继承结构表示多“代”派生,可以述成一个“族谱”,连续的子类,与祖先类都有关系。
(5)、泛化/特化
基于继承
泛化表示所有子类与其父类及祖先类有一样的特点。
特化描述所有子类的自定义,也就是,什么属性让它与其祖先类不同。
(6)、多态与多态性
多态指的是同一种事物的多种状态:水这种事物有多种不同的状态:冰,水蒸气
多态性的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类。
class After_sch:
def __init__(self,name,type):
self.name = name
self.type = type
def fangxue(self):
if self.type == "老师":
print("下班")
else:
print("放学")
class Stu(After_sch):
pass
class Tea(After_sch):
pass
stu1 = Stu("小二","学生")
tea1 = Tea("heaton","老师")
stu1.fangxue() ##放学
tea1.fangxue() ##放学
####学生类对象stu1和老师类对象tea1调用同一方法呈现不同的结果
(7)、自省和反射
自省也称作反射,这个性质展示了某对象是如何在运行期取得自身信息的。如果传一个对象给你,你可以查出它有什么能力,这是一项强大的特性。如果Python不支持某种形式的自省功能,dir和type内建函数,将很难正常工作。还有那些特殊属性,像__dict__,__name__及__doc__,
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
python中面向对象中的反射:通过字符串的形式操作对象相关的属性。有四个系统内置函数可以实现自省
a、hasattr
b、getattr
c、setattr
d、delattr
class After_sch:
school = "tongnan middle school"
def __init__(self,name,type):
self.name = name
self.type = type
def fangxue(self):
if self.type == "老师":
print("下班")
else:
print("放学")
class Stu(After_sch):
pass
class Tea(After_sch):
pass
stu1 = Stu("小二","学生")
tea1 = Tea("heaton","老师")
# print(After_sch.__dict__)
# # print(stu1._school)
# print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
# stu1.fangxue()
# tea1.fangxue()
print(hasattr(stu1,"school")) ###判断stu1对象是否有school属性 True
print(getattr(stu1,"school1","没有该条属性")) ###获取对象的属性,如果没有返回自定义字符串:没有该条属性
setattr(stu1,"年级","一年级") ###设置对象的属性 {'name': '小三', 'type': '学生', '年级': '一年级'}
delattr(stu1,"type") ###删除stu1对象的属性
print(stu1.__dict__) ###{'name': '小二', '年级': '一年级'}
在编程过程中,通过自省的方式,可以达到可插拔式设计
###这是ftp_client.py文件
class Ftp_client:
def __init__(self,addr):
print("正在连接服务器 %s" %addr)
self.addr = addr
###还未实现功能 ###这是ftp_call.py文件 from ftp_client import Ftp_client f1 = Ftp_client("192.168.1.100")
if hasattr(f1,"get"):
func_get = getattr(f1,"get")
func_get()
else:
print("ftp_client还未实现该方法!!!!") ###通过自省的方式可以在ftp_client在未实现的情况下继续后续工作
6、__getattr__,__setattr__,__delattr__
class animal:
genernal = "冷血动物"
def __init__(self,name,type):
self.name = name
self.type = type
def cay(self):
print("%s一直在抽泣" %self.name)
def __getattr__(self, item): ####__getattr__调用不存在的属性时运行
print("你调用的方法不不存在")
def __setattr__(self, key, value):
# self.key = value 该种调用的方式会出现无限递归
self.__dict__[key] = value ##这种方式直接操作底层字典
def __delattr__(self, item): ###__delattr__删除的时候调用该方法
#del self.item 该种方式也会出现无限递归
self.__dict__.pop(item) ##这种方式直接操作底层字典
dog = animal("金毛","dog")
print(dog.__dict__) dog.addr = "north america" ###{'name': '金毛', 'type': 'dog', 'addr': 'north america'}
print(dog.gener) ###你调用的方法不不存在:因为该属性不存在,触发__getattr__方法
7、二次加工标准类型(包装)
包装:python提供了标准数据类型,以及丰富的内助方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增、改写方法,可以通过继承和派生的相关知识;
class List(list):###继承父类list
def show_middl(self): ###派生show_middle的方法
return self[int(len(self)/2)]
def append(self, object): ###派生append方法
if type(object) is not str:
print(type(object))
print("添加的类型必须为字符串类型")
else:
super().append(object)
l1 = List()
print(l1.__dict__) res = List("string") ###继承方法
print(res,type(res)) ###['s', 't', 'r', 'i', 'n', 'g'] <class '__main__.List'>
# print(res.show_middl())
res.append("helloworld")
res.append(1234) ###在调用的append方法是对数据类型对了判断
print(res) ### ['s', 't', 'r', 'i', 'n', 'g', 'helloworld']
授权:授权是包装的一个特性,包装一个类型通常是对已存在的类型的一些定制,这种做法可以是新建、修改或删除原有产品的功能,其他则保持原样。授权的过程,即是所有更新的功能都是有新类的某部分
来处理。
import time
class file_handler:
def __init__(self,filename,mode="r",encoding="utf-8"):
# self.filename = filename
self.file = open(filename,mode,encoding="utf-8") ###获取文件句柄
self.mode = mode
self.encoding = encoding
def write(self,line):
t = time.strftime("%Y-%m-%d %X")
self.file.write("%s %s" %(t,line))
def __getattr__(self, item):
print(item)
# self.file.read
return getattr(self.file,item) f1 = file_handler("a.text","w+")
# print(f1.file)
# print(f1.read)
f1.write("11111111343234\n")
time.sleep(1)
f1.write("用户root远程登录服务器\n")
time.sleep(2)
f1.write("用户root修改了目录/opt的权限为777\n")
python之面向对象设计、编程的更多相关文章
- Python之面向对象函数式编程
Python之面向对象函数式编程 函数式编程的根本就是用 def 去模拟数学式的编程逻辑. 类似与 y = 2*x + 1 ,当x = 3 时,函数的结果y就得7. def test(x): retu ...
- python学习 面向对象高级编程
---恢复内容开始--- 面向对象编程---oop,是一种编程思想,oop把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数 ...
- 【Python】[面向对象高级编程] 多成继承,定制类,使用枚举
1.多成继承 class SmallDog(Animal,Dog) pass MixIn就是一种常见的设计. 2.定制类类似__slots__这种形如 __xxx__ 的变量或者函数名,在python ...
- 【Python】[面向对象高级编程] 使用__slots__,使用@property
1.使用 __slots__ 给实例绑定方法, >>> def set_age(self, age): # 定义一个函数作为实例方法 ... self.age = age .. ...
- Python 2.7 学习笔记 面向对象的编程
python是一种面向对象的语言.本文介绍如何用python进行面向对象的编程. 首先我们说下对象和类,类是一种类型的定义,对象是类的实例. 一.内置对象类型(内置类) 其实我们前面已经大量用到了对象 ...
- 翻译 | The Principles of OOD 面向对象设计原则
本文首发于vivo互联网技术微信公众号 https://mp.weixin.qq.com/s/Q_pziBUhKRywafKeY2T7YQ 作者:Robert C. Martin 翻译:张硕 本文由来 ...
- python基础-面向对象编程
一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 ...
- day24:面向对象设计与面向对象编程、类和对象
一.三大编程范式: 面向过程: 面向函数: 面向对象: 二.程序的进化论: 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定 ...
- python基础——面向对象编程
python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...
随机推荐
- How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 394798.1)
How to Create Transportable Tablespaces Where the Source and Destination are ASM-Based (Doc ID 39479 ...
- python 实现 PC 客户端自动化快速入门:pywinauto !
本文转载自:http://www.lemfix.com/topics/420 一.前言 我们柠檬班的小可爱,在学完我们柠檬班自动化的课程之后,就掌握了接口自动化,web自动化,app自动化,这些工 ...
- MongoDB学习笔记(五、MongoDB存储引擎与索引)
目录: mongoDB存储引擎 mongoDB索引 索引的属性 MongoDB查询优化 mongoDB存储引擎: 目前mongoDB的存储引擎分为三种: 1.WiredTiger存储引擎: a.Con ...
- 信号处理函数陷阱:调用malloc导致死锁[转]
概览 因malloc是加锁的,上网了解的相关信息,额外了解到信号处理规范使用,mark 正文 在执行malloc的过程中,跳转到了信号处理函数中.而信号处理函数在调用某个系统api时,内部又调用了ma ...
- Hive部分函数解析
Hive部分函数解析 Hive里的exists ,in ,not exists ,not in 相关函数 表数据准备: 1.选择指定数据库 eg: use bg_database1; 2. 创建表 ...
- npm与cnpm的区别
NPM(Node Package Manager,节点包管理器)是NodeJS的包管理器,用于节点插件的管理(包括安装,卸载和管理依赖等).NPM是随同新版的NodeJS一起安装的包管理工具,所以我们 ...
- 母版页 treeview控件 SiteMapPath控件 treeview数据库绑定模式
母版页就是网站中一样的部分母版页的后缀名是.Master可以把母版页当成一个页面 想让哪里是别的内容就可以 通过如下: <asp:ContentPlaceHolder ID="C ...
- 超级简单的数组加单链表实现Map
/** * 超级简单的数组加单链表实现Map * @author jlj * */ public class MyHashMap { public MyList[] lists; public int ...
- Cobalt Strike系列教程第四章:文件/进程管理与键盘记录
Cobalt Strike系列教程分享如约而至,新关注的小伙伴可以先回顾一下前面的内容: Cobalt Strike系列教程第一章:简介与安装 Cobalt Strike系列教程第二章:Beacon详 ...
- Last 2 dimensions of the array must be square
这个报错是因为我们在求解行列式的值的时候使用了: np.linalg.det(D) 但是D必须是方阵才可以进行运算,不是方阵则会报错,我们把之前的行列式更改为方阵就不会再报错了,当然这也是numpy自 ...