面向对象

一、编程三个范式

1、面向过程编程

2、函数式编程

数学层面的函数

python中的函数编程

3、面向对象编程

二、面向对象设计

1、类:把一类事物共同的特征和共同的动作整合在一起就是类;

2、对象:基于类而创建的一个具体的事物(具体存在的,也是特征和动作的结合)

  1. def dog(name,type,gender):
  2. def chi(dog1):
  3. print("%s 正在嚼骨头!!!" %dog1["name"])
  4. def jiao():
  5. print("%s正在汪汪!!" %dog1["name"])
  6. def init(name,type,gender):
  7. dog= {
  8. "name":name,
  9. "type":type,
  10. "gender":gender,
  11. "chi":chi,
  12. "jiao":jiao
  13. }
  14. return dog
  15. return init(name,type,gender)
  16.  
  17. first_dog= dog("alex","中华田园犬","母")
  18. print(first_dog)
  19. first_dog["chi"](first_dog)

三、面向对象编程

1、类:声明类和函数类似,类是用来描述一类事物,类的对象指的是这一类事物中的一个个体

2、属性

(1)、数据属性:就是变量

(2)、函数属性:就是函数,在面向对象里通常称为方法

备注:类和对象都是通过点来访问自己的属性

  1. class Dog:
  2. name = "alex"
  3. type = "中华田园犬"
  4. def chi():
  5. print("正在嚼骨头")
  6. def jiao(self):
  7. print("一直在犬吠")
  8. dog1 =Dog()
  9. print(dir(Dog))
  10. Dog.chi()  

3、实例化

  1. class Dog:
  2. def __init__(self,name,type):
  3. self.mingzi = name
  4. self.leixing = type
  5. def chi(self):
  6. print("%s正在嚼骨头" %self.mingzi)
  7. def jiao(self):
  8. print("一只%s在犬吠" %self.leixing)
  9. dog1 =Dog("alex","中华田园犬") ###实例化
  10. print(dir(Dog))
  11. Dog.chi(dog1)
  12. dog1.jiao()

四、备注

1、静态属性

静态属性的修饰为@property,对方法进行封装,隐藏内部逻辑,将类方法变为类属性

  1. class sch:
  2. ###初始化参数
  3. 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):
  4. self.name = sch_name
  5. self.sch_name = sch_name
  6. self.sch_create_time = sch_create_time
  7. self.sch_add = sch_add
  8. self.sch_fee = sch_fee
  9. self.sch_type = sch_type
  10. self.sch_level = sch_level
  11. self.sch_teach_type = sch_teach_type
  12. self.sch_ward = sch_ward
  13. self.sch_start_edu_time = sch_start_edu_time
  14. self.sch_schedual = sch_schedual
  15. ###定义方法:这是常规的方法定义
  16. def sch_catch_fee(self):
  17. print ("%s本年度学费为%s" %(self.sch_name,self.sch_fee))
  18. ###对方法加上装饰器property,隐藏方法内部实现逻辑
  19. @property
  20. def sch_catch_fee(self):
  21. return ("%s本年度学费为%s" %(self.sch_name,self.sch_fee))

2、类方法

使用@classmethod进行修饰,类直接调用,bu用再进行传实例名,跟实例没有任何关系。

  1. class sch:
  2. ###初始化参数
  3. 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):
  4. self.name = sch_name
  5. self.sch_name = sch_name
  6. self.sch_create_time = sch_create_time
  7. self.sch_add = sch_add
  8. self.sch_fee = sch_fee
  9. self.sch_type = sch_type
  10. self.sch_level = sch_level
  11. self.sch_teach_type = sch_teach_type
  12. self.sch_ward = sch_ward
  13. self.sch_start_edu_time = sch_start_edu_time
  14. self.sch_schedual = sch_schedual
  15. ###classmethod方法修饰的方法的哥参数为cls
  16. @classmethod
  17. def sch_edu(cls,x):
  18. print("这是类的方法,与实例没有任何关系",x)
  19. ###类可以直接调用
  20. sch.sch_edu(1) #这是类的方法,与实例没有任何关系 1

3、静态方法

使用staticmethod方法进行修饰,不与类、实例绑定,是类的工具包,只是名义上归类管理

  1. class sch:
  2. ###初始化参数
  3. 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):
  4. self.name = sch_name
  5. self.sch_name = sch_name
  6. self.sch_create_time = sch_create_time
  7. self.sch_add = sch_add
  8. self.sch_fee = sch_fee
  9. self.sch_type = sch_type
  10. self.sch_level = sch_level
  11. self.sch_teach_type = sch_teach_type
  12. self.sch_ward = sch_ward
  13. self.sch_start_edu_time = sch_start_edu_time
  14. self.sch_schedual = sch_schedual
  15. @staticmethod
  16. def post_message(message):
  17. print("本校通知如下:%s" %message)
  18. sch.post_message("本校将于20191207放假")

5、python中关于oop的常用术语

(1)、抽象/实现

抽象指对现实世界问题和实体的本质表现,行为和特征建模,建立一个相关的子集,可以用于 绘程序结构,从而实现这种模型。抽象不仅包括这种模型的数据属性,还定义了这些数据的接口。

对某种抽象的实现就是对此数据及与之相关接口的现实化(realization)。现实化这个过程对于客户 程序应当是透明而且无关的。

(2)、封装接口

封装描述了对数据/信息进行隐藏的观念,它对数据属性提供接口和访问函数。通过任何客户端直接对数据的访问,无视接口,与封装性都是背道而驰的,除非程序员允许这些操作。作为实现的 一部分,客户端根本就不需要知道在封装之后,数据属性是如何组织的。在Python中,所有的类属性都是公开的,但名字可能被“混淆”了,以阻止未经授权的访问,但仅此而已,再没有其他预防措施了。这就需要在设计时,对数据提供相应的接口,以免客户程序通过不规范的操作来存取封装的数据属性。

注意:封装绝不是等于“把不想让别人看到、以后可能修改的东西用private隐藏起来”

真正的封装是,经过深入的思考,做出良好的抽象,给出“完整且最小”的接口,并使得内部细节可以对外透明

(注意:对外透明的意思是外部调用者可以顺利的得到自己想要的任何功能,完全意识不到内部细节的存在)

python不依赖语言特性去封装数据,而是通过遵循一定的数据属性和函数属性的命名约定来达到封装的效果:

任何以单下划线开头的名字都应该是内部的,私有的,实际上外部还是可以调用的;

  1. class After_sch:
  2. _school = "tongnan middle school"
  3. def __init__(self,name,type):
  4. self.name = name
  5. self.type = type
  6. def fangxue(self):
  7. if self.type == "老师":
  8. print("下班")
  9. else:
  10. print("放学")
  11. class Stu(After_sch):
  12. pass
  13. class Tea(After_sch):
  14. pass
  15. stu1 = Stu("小二","学生")
  16. tea1 = Tea("heaton","老师")
  17. print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
  18. print(stu1._school) ###tongnan middle school 单下划线的外部调用成功

以双下划线开头的名字也是内部的,私有的,是python的约定命名,实际上外部也是可以调用的;

  1. class After_sch:
  2. __school = "tongnan middle school"
  3. def __init__(self,name,type):
  4. self.name = name
  5. self.type = type
  6. def fangxue(self):
  7. if self.type == "老师":
  8. print("下班")
  9. else:
  10. print("放学")
  11. class Stu(After_sch):
  12. pass
  13. class Tea(After_sch):
  14. pass
  15. stu1 = Stu("小二","学生")
  16. tea1 = Tea("heaton","老师")
  17. print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
  18. print(After_sch.__dict__)
  19. # print(stu1.__school) ###'Stu' object has no attribute '__school' 这样调用会报错
  20. print(stu1._After_sch__school) ###tongnan middle school 通过"_类名__属性"调用成功

封装有三个层面上的封装

a、第一个层面:类就是麻袋,这本身就是一种封装;

b、第二个层面:类中定义私有的,只有的类的内部可以使用,外部无法访问,该层面的封装就是上面提到的使用单下划线和双下划线实现的,实际上该中层面的封装外部也是可以调用的;

c、第三个层面:明确区分内外,内部的实现逻辑,外部无法知晓,并且为封装到内部的逻辑提供一个访问接口给外部使用,这才是真正的封装;

(3)、合成

合成扩充了对类的 述,使得多个不同的类合成为一个大的类,来解决现实问题。合成 述了 一个异常复杂的系统,比如一个类由其它类组成,更小的组件也可能是其它的类,数据属性及行为, 所有这些合在一起,彼此是“有一个”的关系。

(4)、派生/继承/继承结构

派生描述了子类衍生出新的特性,新类保留已存类类型中所有需要的数据和行为,但允许修改或者其它的自定义操作,都不会修改原类的定义。
继承描述了子类属性从祖先类继承这样一种方式
继承结构表示多“代”派生,可以述成一个“族谱”,连续的子类,与祖先类都有关系。

(5)、泛化/特化

基于继承
泛化表示所有子类与其父类及祖先类有一样的特点。
特化描述所有子类的自定义,也就是,什么属性让它与其祖先类不同。

(6)、多态与多态性

多态指的是同一种事物的多种状态:水这种事物有多种不同的状态:冰,水蒸气

多态性的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类。

  1. class After_sch:
  2. def __init__(self,name,type):
  3. self.name = name
  4. self.type = type
  5. def fangxue(self):
  6. if self.type == "老师":
  7. print("下班")
  8. else:
  9. print("放学")
  10. class Stu(After_sch):
  11. pass
  12. class Tea(After_sch):
  13. pass
  14. stu1 = Stu("小二","学生")
  15. tea1 = Tea("heaton","老师")
  16. stu1.fangxue() ##放学
  17. tea1.fangxue() ##放学
  18. ####学生类对象stu1和老师类对象tea1调用同一方法呈现不同的结果

(7)、自省和反射

自省也称作反射,这个性质展示了某对象是如何在运行期取得自身信息的。如果传一个对象给你,你可以查出它有什么能力,这是一项强大的特性。如果Python不支持某种形式的自省功能,dir和type内建函数,将很难正常工作。还有那些特殊属性,像__dict__,__name__及__doc__,

反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

python中面向对象中的反射:通过字符串的形式操作对象相关的属性。有四个系统内置函数可以实现自省

a、hasattr

b、getattr

c、setattr

d、delattr

  1. class After_sch:
  2. school = "tongnan middle school"
  3. def __init__(self,name,type):
  4. self.name = name
  5. self.type = type
  6. def fangxue(self):
  7. if self.type == "老师":
  8. print("下班")
  9. else:
  10. print("放学")
  11. class Stu(After_sch):
  12. pass
  13. class Tea(After_sch):
  14. pass
  15. stu1 = Stu("小二","学生")
  16. tea1 = Tea("heaton","老师")
  17. # print(After_sch.__dict__)
  18. # # print(stu1._school)
  19. # print(stu1.__dict__) ###{'name': '小二', 'type': '学生'}
  20. # stu1.fangxue()
  21. # tea1.fangxue()
  22. print(hasattr(stu1,"school")) ###判断stu1对象是否有school属性 True
  23. print(getattr(stu1,"school1","没有该条属性")) ###获取对象的属性,如果没有返回自定义字符串:没有该条属性
  24. setattr(stu1,"年级","一年级") ###设置对象的属性 {'name': '小三', 'type': '学生', '年级': '一年级'}
  25. delattr(stu1,"type") ###删除stu1对象的属性
  26. print(stu1.__dict__) ###{'name': '小二', '年级': '一年级'}

在编程过程中,通过自省的方式,可以达到可插拔式设计

  1. ###这是ftp_client.py文件
  2. class Ftp_client:
  3. def __init__(self,addr):
  4. print("正在连接服务器 %s" %addr)
  5. self.addr = addr
  6. ###还未实现功能
  7.  
  8. ###这是ftp_call.py文件
  9.  
  10. from ftp_client import Ftp_client
  11.  
  12. f1 = Ftp_client("192.168.1.100")
  13. if hasattr(f1,"get"):
  14. func_get = getattr(f1,"get")
  15. func_get()
  16. else:
  17. print("ftp_client还未实现该方法!!!!")
  18.  
  19. ###通过自省的方式可以在ftp_client在未实现的情况下继续后续工作

6、__getattr__,__setattr__,__delattr__

  1. class animal:
  2. genernal = "冷血动物"
  3. def __init__(self,name,type):
  4. self.name = name
  5. self.type = type
  6. def cay(self):
  7. print("%s一直在抽泣" %self.name)
  8. def __getattr__(self, item): ####__getattr__调用不存在的属性时运行
  9. print("你调用的方法不不存在")
  10. def __setattr__(self, key, value):
  11. # self.key = value 该种调用的方式会出现无限递归
  12. self.__dict__[key] = value ##这种方式直接操作底层字典
  13. def __delattr__(self, item): ###__delattr__删除的时候调用该方法
  14. #del self.item 该种方式也会出现无限递归
  15. self.__dict__.pop(item) ##这种方式直接操作底层字典
  16. dog = animal("金毛","dog")
  17. print(dog.__dict__)
  18.  
  19. dog.addr = "north america" ###{'name': '金毛', 'type': 'dog', 'addr': 'north america'}
  20. print(dog.gener) ###你调用的方法不不存在:因为该属性不存在,触发__getattr__方法

7、二次加工标准类型(包装)

包装:python提供了标准数据类型,以及丰富的内助方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增、改写方法,可以通过继承和派生的相关知识;

  1. class List(list):###继承父类list
  2. def show_middl(self): ###派生show_middle的方法
  3. return self[int(len(self)/2)]
  4. def append(self, object): ###派生append方法
  5. if type(object) is not str:
  6. print(type(object))
  7. print("添加的类型必须为字符串类型")
  8. else:
  9. super().append(object)
  10. l1 = List()
  11. print(l1.__dict__)
  12.  
  13. res = List("string") ###继承方法
  14. print(res,type(res)) ###['s', 't', 'r', 'i', 'n', 'g'] <class '__main__.List'>
  15. # print(res.show_middl())
  16. res.append("helloworld")
  17. res.append(1234) ###在调用的append方法是对数据类型对了判断
  18. print(res) ### ['s', 't', 'r', 'i', 'n', 'g', 'helloworld']

 授权:授权是包装的一个特性,包装一个类型通常是对已存在的类型的一些定制,这种做法可以是新建、修改或删除原有产品的功能,其他则保持原样。授权的过程,即是所有更新的功能都是有新类的某部分

来处理。

  1. import time
  2. class file_handler:
  3. def __init__(self,filename,mode="r",encoding="utf-8"):
  4. # self.filename = filename
  5. self.file = open(filename,mode,encoding="utf-8") ###获取文件句柄
  6. self.mode = mode
  7. self.encoding = encoding
  8. def write(self,line):
  9. t = time.strftime("%Y-%m-%d %X")
  10. self.file.write("%s %s" %(t,line))
  11. def __getattr__(self, item):
  12. print(item)
  13. # self.file.read
  14. return getattr(self.file,item)
  15.  
  16. f1 = file_handler("a.text","w+")
  17. # print(f1.file)
  18. # print(f1.read)
  19. f1.write("11111111343234\n")
  20. time.sleep(1)
  21. f1.write("用户root远程登录服务器\n")
  22. time.sleep(2)
  23. f1.write("用户root修改了目录/opt的权限为777\n")

  

python之面向对象设计、编程的更多相关文章

  1. Python之面向对象函数式编程

    Python之面向对象函数式编程 函数式编程的根本就是用 def 去模拟数学式的编程逻辑. 类似与 y = 2*x + 1 ,当x = 3 时,函数的结果y就得7. def test(x): retu ...

  2. python学习 面向对象高级编程

    ---恢复内容开始--- 面向对象编程---oop,是一种编程思想,oop把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数 ...

  3. 【Python】[面向对象高级编程] 多成继承,定制类,使用枚举

    1.多成继承 class SmallDog(Animal,Dog) pass MixIn就是一种常见的设计. 2.定制类类似__slots__这种形如 __xxx__ 的变量或者函数名,在python ...

  4. 【Python】[面向对象高级编程] 使用__slots__,使用@property

    1.使用 __slots__    给实例绑定方法, >>> def set_age(self, age): # 定义一个函数作为实例方法 ... self.age = age .. ...

  5. Python 2.7 学习笔记 面向对象的编程

    python是一种面向对象的语言.本文介绍如何用python进行面向对象的编程. 首先我们说下对象和类,类是一种类型的定义,对象是类的实例. 一.内置对象类型(内置类) 其实我们前面已经大量用到了对象 ...

  6. 翻译 | The Principles of OOD 面向对象设计原则

    本文首发于vivo互联网技术微信公众号 https://mp.weixin.qq.com/s/Q_pziBUhKRywafKeY2T7YQ 作者:Robert C. Martin 翻译:张硕 本文由来 ...

  7. python基础-面向对象编程

    一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 ...

  8. day24:面向对象设计与面向对象编程、类和对象

    一.三大编程范式: 面向过程: 面向函数: 面向对象: 二.程序的进化论: 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定 ...

  9. python基础——面向对象编程

    python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

随机推荐

  1. [日常] linux设置环境变量

    比如首先在/etc/profile里面增加这几个环境变量 export PATH=$PATH:/mnt/f/ubuntu/goProject/go/binexport GOROOT=/mnt/f/ub ...

  2. s3c2440裸机-代码重定位(2.编程实现代码重定位)

    代码重定位(2.编程实现代码重定位) 1.引入链接脚本 我们上一节讲述了为什么要重定位代码,那么怎么去重定位代码呢? 上一节我们发现"arm-linux-ld -Ttext 0 -Tdata ...

  3. 《java编程思想(第四版)》第一二章学习笔记

    目录 一.Introduction 1.抽象过程 2.面向对象语言(包括Java)的五个基本特性 3.每个对象都提供服务 4.public.private.protected三者的区别 5.Java的 ...

  4. go语言的常量

    Go 语言常量 常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier ...

  5. ASP.NET中的身份验证

    身份验证方式windows passport form none授权allow 允许deny 拒绝特殊符号 *代表所有用户 ?代表匿名用户跳转配置<system.web><autho ...

  6. java spring是元编程框架---使用的机制是注解+配置

    java spring是元编程框架---使用的机制是注解+配置

  7. 【编译系统02】编译器 - 语义分析器(semantic)的简单设计思路(变量类与变量表)

    当我们分析到 "int n;",说明其已经定义了一个变量,之后又遇到一个 "n=3",我们从哪里去找这个n并且赋值呢? 答案是:通过我们定义的 变量表(Tabl ...

  8. RocketMQ(一):推拉消费模型客户端实践

    消息中间件是为解耦生产者和消费者的目的,三大服务点:解耦.异步.削峰. 现在的的互联网系统中,mq已经必备基础设施了,我们已明显感觉它的必要性与强大.然而,它的本质是啥?存储转发系统罢了! MQ有很多 ...

  9. 项目中使用http referer,为了盗取图片资源

    项目背景:因为图片的数据是爬取的别人的图片,而且保存的数据仅仅是图片地址链接,为了减少数据存储和服务器压力,但是这就引发一个问题,有的图片地址没有做防盗处理,可以随意的下载使用:但有些图片的服务器做了 ...

  10. ios 10 访问设置问题

    ios 10 访问设置问题 从ios8之api支持访问设置通过访问UIApplicationOpenSettingsURLString来跳转设置 NSURL*url=[NSURL URLWithStr ...