一、面向对象
面向对象的三大特性:
封装、继承、多态

1. 函数式编程和面向对象的对比:

举例:开发一个消息提醒的功能(邮件/短信/微信)
函数:
def email(em, text):"""发送邮件:return:"""print(em, text)
def msg(tel, text):"""发送短信:return:"""print(tel, text)
def wechat(num, text):"""发送微信:return:"""print(num, text)
# 编写功能:向所有的联系方式发送天气
if True:msg('188888888', '今天有小雨')email('hao123@163.com.com', '今天有小雨')wechat('xxxx', '今天有小雨')

面向对象:
class Message:def email(self, em, text):"""发送邮件:return:"""print(em,text)def msg(self, tel, text):"""发送短信:return:"""print(tel,text)def wechat(self, num, text):"""发送微信:return:"""print(num,text)
# 编写功能:向所有的联系方式发送天气
if True:obj = Message()obj.email('hao123@163.com', '今天有小雨')obj.msg('188888888', '今天有小雨')obj.wechat('xxxx', '今天有小雨')

对比:

函数:定义简单、调用简单
面向对象:定义复杂、调用复杂 好处:归类,将某些类似的函数功能写在一起

总结:

1 函数式编程可能会比面向对象好
2. Python中支持两种编程方式
3. 面向对象方式格式:
定义:
class 类名: # 定义了一个类
def 函数名(self): # 在类中编写一个“方法”
pass
调用:
x1 = 类名() # 创建了一个对象(实例化一个对象)
x1.函数名() # 通过对象调用其中一个方法
构造方法:
class Foo:
def __init__(self, name): # 构造方法,目的进行数据初始化
self.name = name
self.age = 18
obj = Foo("久末") # 给类名加括号,默认调用构造方法
通过构造方法,可以将数据进行打包,以后使用时,去其中获取即可
应用:
1、将数据封装到对象中,以供自己在方法中使用
class FileHandler:def __init__(self, file_path):self.file_path = file_pathself.f = open(self.file_path, 'rb')def read_first(self):# self.f.read()# ...passdef read_last(self):# self.f.read()# ...passdef read_second(self):# self.f...# ...passobj = FileHandler('C:/xx/xx.log')
obj.read_first()
obj.read_last()
obj.read_second()
obj.f.close()

2、将数据封装到对象中,供其他函数调用
class FileHandler:def __init__(self, file_path):self.file_path = file_pathself.f = open(self.file_path, 'rb')def read_first(self):# self.f.read()# ...passdef read_last(self):# self.f.read()# ...passdef read_second(self):# self.f...# ...pass
obj = FileHandler('C:/xx/xx.log')
obj.read_first()
obj.read_last()
obj.read_second()
obj.f.close()

2. 面向对象如何编写:

方式一:先归类,然后提取公共值
方式二:先在指定类中编写和当前类相关的所有代码,再提取公共值
三大特性:
封装:
将相关功能封装到一个类中
将数据封装到一个对象中
继承:
继承是为了复用,提高代码得重用性
先找子类(派生类),后找父类(基类)—— 子类和父类是相对存在的
先从子类中找,没有就从父类找
多继承(只存在python中的功能):左边更亲
多态:
多种形态或者多种状态
鸭子模型:只要可以嘎嘎嘎叫的就是鸭子
二、类成员
注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份
class Foo:# 方法def __init__(self, name):# 实例变量/字段self.name = name# 方法def func(self):pass
# obj,Foo类的对象
# obj,Foo类的实例
obj = Foo('jiumo')

1. 变量(字段):

字段包括实例变量和静态变量,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同
由上图可是:
  • 静态变量在内存中只保存一份
  • 实例变量在每个对象中都要保存一份
应用场景: 通过类创建对象时,如果每个对象都具有相同的变量,那么就使用静态变量
# 类变量/实例变量
class Foo:# 类变量/静态字段country = '中国'# 方法def __init__(self, name):# 实例变量/字段self.name = namedef func(self):passobj1 = Foo('jiumo')
obj2 = Foo('王XX')
obj1.country = '美国'
print(obj1.country)
print(obj2.country)obj1 = Foo('jiumo')
obj2 = Foo('王XX')
Foo.country = '美国'
print(obj1.country)
print(obj2.country)
==>美国
中国
美国
美国

实例变量(字段)
- 公有实例变量(字段)
# 公有实例变量(字段)
class Foo:def __init__(self, name):self.name = nameself.age = 123# 内部调用def func(self):print(self.name)
obj = Foo("jiumo")
# 外部调用
print(obj.name) # jiumo
print(obj.age)  # 123
obj.func()  # jiumo

- 私有实例变量(字段)
# 私有实例变量(字段)
class Foo:def __init__(self, name):# 定义为私有self.__name = nameself.age = 123# 内部调用def func(self):print(self.__name)
obj = Foo("jiumo")
# 外部不可直接调用
# print(obj.name)     # 报错AttributeError: 'Foo' object has no attribute 'name'
print(obj.age)
obj.func()  # 间接访问:让func帮助执行内部私有的__name  就相当在类的内部有认识的”关系” 间接的得到想要的内容

类变量(静态字段)
- 公有类变量(静态字段)
# 默认公有类变量(字段)
class Foo:country = "中国"def __init__(self):passdef func(self):# 内部调用print(self.country)print(Foo.country)  # 推荐
# 外部调用
print(Foo.country)    # 中国

- 私有类变量(静态字段)
# 私有
class Foo:__country = "中国"def __init__(self):passdef func(self):# 内部调用print(self.__country)print(Foo.__country)  # 推荐
# 外部无法直接调用
# print(Foo.__country)
obj = Foo()
obj.func(

准则:
实例变量(字段)访问时,使用对象访问,即:obj1.name
类变量(静态字段)访问时,使用类访问,即:Foo.country(实在不方便时才使用对象)
易错点:
obj1 = Foo('jiumo')
obj2 = Foo('王XX')obj1.name = '老王'
print(obj1.name)
print(obj2.name)
==>老王
王XX

什么时候用类变量:
当所有对象中有共同的字段,并且值永远同步,那么可以使用类变量
父类中的私有字段子辈无法知道,但是可以通过调用父类得到
# 子类也不能直接调用父类的私有字段
class Bsae(object):__secret = "RMB"
class Foo(Bsae):def func(self):# print(self.__secret)  # AttributeError: 'Foo' object has no attribute '_Foo__secret'print(Foo.__secret)     # AttributeError: type object 'Foo' has no attribute '_Foo__secret'
obj = Foo()
obj.func()
# 同样可以利用间接调用的方法得到私有字段
class Bsae(object):__secret = "RMB"def money(self):print(Bsae.__secret)
class Foo(Bsae):def func(self):pass
obj = Foo()
obj.money()

2. 方法

实例方法
静态方法
1. 定义时:
- 方法上方写 @staticmethod
- 方法参数可有可无
2. 调用时:
- 类.方法名() # 推荐使用
- 对象.方法名()
3. 什么时候使用静态方法:
- 无需调用对象中封装的值
- 类方法
1. 定义时:
- 方法上方写:@classmethod
- 方法的参数:至少有一个cls参数
2. 执行时:
- 类名.方法名 # 默认会将当前类传到参数中
3. 什么时使用类方法:
- 如果在方法中会使用到当前类,那么就可以使用类方法
# 没必要写实例方法
class Foo(object):def __init__(self, name):self.name = namedef func(self):print('实例方法')   # 没有用到构建方法中的值
obj = Foo('jiumo')
obj.func()
# 有意义的实例方法
class Foo(object):def __init__(self, name):self.name = name# 实例方法,最少有一个参数def func(self):print(self.name)    # wb# 静态方法,可以没有参数.  如果方法中无需使用对象中封装的值,那么就可以使用静态方法# 可以通过类直接调用,不需要实例化类这部操作
    @staticmethoddef display():print('静态方法')    # 静态方法# 类方法
    @classmethoddef train(cls, name):
print(cls)        # <class '__main__.Foo'>print(name)        # 类方法
# 实例方法
obj = Foo('wb')
obj.func()
# 静态方法的调用
Foo.display()
# 类方法的调用
Foo.train('类方法')==>实例方法
wb
静态方法
<class '__main__.Foo'>
类方法

方法的成员修饰符:方法也有公有方法和私有方法之分 用法同变量的成员修饰符
# 私有的实例方法
class Foo(object):def __init__(self):passdef __display(self,arg):print('私有方法',arg)def func(self):self.__display(123)
obj = Foo()
# obj.__display(123) # 无法访问
obj.func()
# 私有的静态方法
class Foo(object):def __init__(self):pass@staticmethoddef __display(arg):print('私有静态 方法',arg)    # 私有静态 方法 123def func(self):Foo.__display(123)@staticmethoddef get_display():Foo.__display(888)  #私有静态 方法 888
# Foo.__display(123) 报错
obj = Foo()
obj.func()Foo.get_display()

3. 属性

class Foo(object):def __init__(self):pass@propertydef start(self):return 1@propertydef end(self):return 10
obj = Foo()
print(obj.start)
print(obj.end)

1 编写时:
- 方法上方写@property
- 方法参数:只有一个self参数
2 调用时:
- 无需加括号 对象.方法
3 应运场景:
- 对于简单的方法,当无需传参且有返回值时

4. 特殊方法

class Foo():# 1.def __init__(self,a1, a2):self.a1 = a1self.a2 = a2# 2.def __call__(self, *args, **kwargs):print('wb', args, kwargs)return 123# 3.def __getitem__(self, item):print(item)return 123# 4.def __setitem__(self, key, value):  # 无返回值print(key, value, 123)# 5.def __delitem__(self, key): # 无返回值print(key)# 6.def __add__(self, other):return self.a1 + other.a1# 7.def __enter__(self):print('开始代码')return 999# 8.def __exit__(self, exc_type, exc_val, exc_tb):print("结束代码")1.类名() 自动执行 __init__obj = Foo(1, 2)2.对象() 自动执行 __call__ret = obj(2018, 9, time = 2)print(ret)3.对象[] 自动执行 __getitem__ret = obj['wang']print(ret)4.对象['xx'] = 11 自动执行 __setitem__obj['k1'] = 1235.del 对象['xx'] = 11 自动执行 __delitem__del obj['wang']6.对象+对象       自动执行 __add__9. with 对象    自动执行__enter__ 和 __exit__obj = Foo(1, 2)with obj as f:print(f)print('内部代码')10.真正的构造方法 __new__class Foo(object):def __init__(self,a1, a2):print(1)self.a1 = a1self.a2 = a2def __new__(cls, *args, **kwargs):print(2)    # 执行到此处中断了Foo(1, 2)

三、反射
python中的反射功能是由以下四个内置函数提供的:
- getattr(): 根据字符串为参数(第二个参数),去对象(第一个参数)中去寻找与之同名的成员
- hasattr():根据字符串的形式,去判断对象中是否有成员
- setattr():根据字符串的形式,动态的设置一个成员(内存)
- delattr():根据字符串的形式,动态的删除一个成员(内存)
class Foo(object):def __init__(self):self.name = 'jiumo'def func(self):return 'func'
obj = Foo()
# 检查是否含成员变量
print(hasattr(obj, 'name'))    # True
print(hasattr(obj, 'func'))    # True
# 获取成员
print(getattr(obj, 'name')) # jiumo
print(getattr(obj, 'func')) # <bound method Foo.func of <__main__.Foo object at 0x0000016810C9C908>>
# 设置成员
setattr(obj, 'age', 18)
print(getattr(obj, 'age'))  # 18
setattr(obj, 'show', lambda num: num + 1)
# print(getattr(obj, 'show')) # <function <lambda> at 0x0000016811EA47B8>
# 删除成员
delattr(obj, 'name')
print(hasattr(obj, 'name')) # Fals
delattr(obj, 'show')
print(hasattr(obj, 'show')) # False# 反射实例说明:
class Foo(object):func_lst = ['f1', 'f2', 'f3']def f1(self):print('注册成功')def f2(self):print('登陆成功')def f3(self):print('注销成功')
obj = Foo()
while True:print("""选择需要的功能:1. 注册2. 登陆3. 注销""")val = int(input("请输入要选择的功能:"))try:func_name = obj.func_lst[val-1]if hasattr(obj, func_name):func = getattr(obj, func_name)func()breakexcept Exception:print("请输入正确的序号!")

转载于:https://www.cnblogs.com/jiumo/p/9545056.html

第十二章 面向对象相关推荐

  1. 第二十二章 面向对象

    1.面向对象 1.面向过程的编程思想: 关注的点就是完成任务的过程 第一步 第二步 一步一步按照固定顺序来完成任务 是一种机械化的思维,就像一条流水线,指定流水线只能生产固定的产品 1. 缺点: 牵一 ...

  2. 第二十二章:面向对象(2)

    类属性与对象属性 类中应该仅存储所有对象共有的内容 如所有人的国籍相同那就放到类中 对象中存储每个对象独有的内容 如每个人的名字都不同 init方法的作用 init 是初始化的缩写 用于为对象的属性设 ...

  3. 第十二章_网络搭建及训练

    文章目录 第十二章 网络搭建及训练 CNN训练注意事项 第十二章 TensorFlow.pytorch和caffe介绍 12.1 TensorFlow 12.1.1 TensorFlow是什么? 12 ...

  4. 第十二章 Django框架

    第十二章 Django框架 tcp/ip五层模型 应用层 传输层 网络层 数据链路层 物理层 socket : 套接字,位于应用层和传输层之间的虚拟层,是一组接口 c/s架构 ------> b ...

  5. lisp算零碎面积总和_Common Lisp:符号计算简单介绍(第十二章)

    第十二章 结构体和类型系统(Structures and The Type System) 12.1 导语 Common Lisp包含了很多内建的数据类型,他们一起形成了一个类型系统.我们到现在为止学 ...

  6. stm32l0的停止模式怎么唤醒_探索者 STM32F407 开发板资料连载第二十二章 待机唤醒实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板 2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第二十二章 待机唤醒实 ...

  7. 构建之法第十,十一,十二章阅读

    第十章经典用户和场景 虽说经典场景和经典用户很有必要去研究去效仿,但是随着时间发展,新的用户新的需求不断涌现,那该怎么平衡? 第十一章软件设计与实现 软件设计过程中,如何管理设计变更呢? 第十二章用户 ...

  8. 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

    http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...

  9. stm32 文件系统dma大小_「正点原子NANO STM32F103开发板资料连载」第二十二章 DMA 实验...

    1)实验平台:[正点原子] NANO STM32F103 开发板 2)摘自<正点原子STM32 F1 开发指南(NANO 板-HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 ...

最新文章

  1. Mac OS X下Maven的安装与配置
  2. vsftpd匿名用户访问
  3. 简单的实现图片预览, 通过原生ajax以及 jQuery两种方法实现图片预览,有更好的办法可以留言喔...................
  4. 牛客 - 膜法记录(状压dp预处理)
  5. mysql架设_主从mysql架设
  6. python图像resize_Python图像resize前后颜色不一致问题
  7. MVC 发布到 windows2003遇到 'System.Web.WebPages.Razor 错误提示
  8. 桌面弹球游戏终结,含有全部代码
  9. 解决远程桌面不能用大法
  10. QT多线程,使用串口接收数据通过UDP端口进行数据转发
  11. dll,sys文件被认定为病毒后如何删除
  12. chrome浏览器下载速度慢问题解决办法
  13. 付款码支付-微信和支付宝付款码类型标识
  14. 邻域均值 (python)
  15. win10系统关闭哪些服务器,win10.1系统哪些服务可以关闭掉?
  16. 移动前端手机输入法自带emoji表情字符处理
  17. 竞逐新能源汽车续航,背靠广汽的巨湾技研能否打好“技术牌”?
  18. AOE网与关键路径、关键路径算法
  19. 亚马逊日本站好不好做?怎么选品?有什么注意事项?
  20. 支付宝手机网页唤醒app支付

热门文章

  1. ChemOffice下载
  2. CF802L Send the Fool Further! (hard) 题解
  3. MSN,QQ,阿里旺旺WEB在线源码
  4. kafka日志保留时间设置无效问题
  5. 微服务应用、框架、架构,理解【二】
  6. keras中的Merge层(实现层的相加、相减、相乘)
  7. 结对编程——保龄球实验分析
  8. lambda表达式的究极理解
  9. 电脑无法连接公司无线的问题
  10. About Linux