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把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...
随机推荐
- LinuxPXE+Kickstrart无人值守安装服务
要求:关闭VMware虚拟网络编辑器中自身的DHCP服务 主机名称 操作系统 IP地址 NoneOS Centos7 192.168.72.250 Custormer 无 1.挂在本地镜像源本配置 ...
- 工具推荐--刷LeetCode的神器
本文首发于微信公众号:[坂本先生],文章地址为: https://mp.weixin.qq.com/s/vHv5hO8nils_g2VSKwu1Cg如有转载请标明出处 今天给大家安利一款快速刷Leet ...
- java之对象创建时各成员变量的初始值
除了byte short int long float double char bollean这基础类型外,其余的都是引用类型 成员变量类型 初始值 byte 0 short 0 int 0 long ...
- Go语言常见坑
可变参数是空接口类型当参数的可变参数是空接口类型时,传人空接口的切片时需要注意参数展开的问题.func main() { var a = []interface{}{1, 2, 3} fmt.Prin ...
- HTML5 3D 在智慧物业/地产管理系统中的应用
概述 该博文主要展示采用 HT for Web 提供的可视化技术,对智慧房产.智慧物业相关方向的可视化呈现做的一点尝试. 传统的 智慧房产/楼宇自动化/智慧物业 常会采用 BIM(建筑信息模型 Bui ...
- 激活函数-Activation Function
该博客的内容是莫烦大神的授课内容.在此只做学习记录作用. 原文连接:https://morvanzhou.github.io/tutorials/machine-learning/tensorflow ...
- SpringBoot2.0 整合 FastDFS 中间件,实现文件分布式管理
本文源码:GitHub·点这里 || GitEE·点这里 一.FastDFS简介 1.FastDFS作用 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步 ...
- Java并发总结
Java并发 进程 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的.系统运行一个程序即是一个进程从创建,运行到消亡的过程. 在 Java 中,当我们启动 main 函数时其实就是 ...
- 01-Java类加载机制详解
类的加载过程 在使用java命令运行主类(main)的时候,首先要通过类加载器将类加载到JVM内存中去.主类在运行过程中如果用到其他的类就会逐步加载这些类.jar包里的类并不是一次性加载的,是使用的时 ...
- 搭建 Telegraf + InfluxDB + Grafana 监控遇到几个小问题
1:如果同一台服务器上安装有多个MongoDB实例,telegraf.conf 中关于 MongoDB 如何配置?配置数据在[INPUT PLUGINS的[[inputs.mongodb]]]部分. ...