文章目录

  • 面向对象高级编程
    • 一、__slots__
    • 二、@property装饰器
    • 三、多重继承——MixIn
    • 四、定制类——`__xxx__`
      • 1、`__str__()` 与 `__repr__()`
      • 2、`__iter__()`
      • 3、`__getitem__()`
      • 4、`__getattr__()`
      • 5、`__call__()`
    • 五、枚举类——Enum类
    • 六、使用元类
      • 1、type()
    • 七、错误、调试和测试
      • 1、错误处理
      • 2、调用堆栈
      • 3、记录错误
      • 4、抛出错误
      • 5、调试
      • 6、单元测试

面向对象高级编程

高级特性:多重继承、定制类、元类等概念。

一、slots

__slots__变量:限制该 class 实例能添加的属性。

class Student(object):__slots__ = ('name', 'age')s = Student()
s.name = 'Michael'
s.age = 25
s.score = 99
print(s.name)
print(s.age)
print(s.score)

==》AttributeError 的错误

AttributeError: 'Student' object has no attribute 'score'

注意__slots__ 定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。除非在子类中也定义 __slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

class GraduateStudent(Student):pass
g = GraduateStudent()
g.score = 9999
print(g.score)    ## 9999

二、@property装饰器

负责把一个方法变成属性调用的。

class Student(object):@propertydef score(self):return self._score@score.setterdef score(self, value):if not isinstance(value, int):raise ValueError('score must be an integer!')if value < 0 or value > 100:raise ValueError('score must between 0 ~ 100!')self._score = values = Student()
s.score = 60
print(s.score)
s.score = 999
print(s.score)

输出结果

60
Traceback (most recent call last):File "E:/codes/python/basic/6.py", line 169, in <module>s.score = 999File "E:/codes/python/basic/6.py", line 163, in scoreraise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!

把一个 getter 方法变成属性,只需要加上@property 就可以了,此时, @property 本身又创建了另一个装饰器@score.setter,负责把一个 setter 方法变成属性赋值。

三、多重继承——MixIn

MixIn 的目:给一个类增加多个功能。

在设计类的时候,要优先考虑通过多重继承来组合多个 MixIn 的功能,而不是设计多层次的复杂的继承关系。

class Animal(object):passclass RunnableMixIn(object):def run(self):print('Running...')
class Mammal(Animal):pass ## Dog为多继承,继承于 Mammal 和 RunnableMixIn
class Dog(Mammal, RunnableMixIn):pass

四、定制类——__xxx__

Python 的 class 中还有许多这样有特殊用途的函数,可以帮
助我们定制类。

1、__str__()__repr__()

class Student(object):def __init__(self, name):self.name = namedef __str__(self):return 'Student object (name: %s)' % self.nameprint(Student('Michael'))

结果对比

  • 未自定义 __str__() 的结果
    <__main__.Student object at 0x000001994F615FD0>
  • 自定义 __str__() 的结果
    Student object (name: Michael)

在交互的模式下,直接输出 s,打印出来的 <__main__.Student object at 0x109afb310> 也并不好看。

直接显示变量调用的是 __repr__() 而非 __str__()
==》
区别:__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
==》解决办法:再定义一个__repr__()

2、__iter__()

__iter__():用于 for…in 循环,该函数返回一个迭代对象。

然后,Python 的 for 循环就不断用该迭代对象的 __next__() 方法获取循环的下一个值,直到遇到 StopIteration 错误时退出循环。

class Fib(object):def __init__(self):self.a, self.b = 0, 1  # 初始化两个计数器a,bdef __iter__(self):return self            # 实例本身就是迭代对象,故返回自己def __next__(self):self.a, self.b = self.b, self.a + self.b   # 计算下一个值if self.a > 100000:    # 退出循环的条件raise StopIterationreturn self.afor n in Fib():print(n)

输出结果

1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025

3、__getitem__()

可以按照下标取出元素 ==》__getitem__() 方法

class Fib(object):def __getitem__(self, n):a, b = 1, 1for x in range(n):a, b = b, a + breturn a
f = Fib()
print(f[0])
print(f[1])
print(f[100])

输出结果

1
1
573147844013817084101

==》切片操作
原因:__getitem__() 传入的参数可能是一个 int,也可能是一个切片对象 slice,所以要做判断。

class Fib(object):def __getitem__(self, n):if isinstance(n, int):    # n 是索引a, b = 1, 1for x in range(n):a, b = b, a + breturn aif isinstance(n, slice):   # n 是切片start = n.startstop = n.stopif start is None:start = 0a, b = 1, 1L = []for x in range(stop):if x >= start:L.append(a)a, b = b, a + breturn Lf = Fib()
print(f[0:5])
print(f[:10])

输出结果

[1, 1, 2, 3, 5]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

分析:没有对 step 参数、负数等做处理。
==》将对象看出 dict
==》__getitem__() 的参数可能作 key 的 object。其对应的 __setitem__() 方法:将对象看作 list 或 dict 来对集合赋值;__delitem__() 方法:删除某个元素。

4、__getattr__()

为了避免由于类的方法或属性不在造成的 AttributeError 错误,使用 __getattr__() ,动态返回一个属性。

class Student(object):def __init__(self):self.name = 'Michael'def __getattr__(self, attr):if attr == 'score':return 99elif attr == 'age':return lambda:25# 若均不匹配,则抛出 AttributeError 的错误raise AttributeError('\'Student\'object has no attribute \'%s\'' % attr)

==》当调用不存在的属性时,比如 score, Python 解释器会试图调用__getattr__(self, ‘score’)来尝试获得属性,从而可以返回score的值99。

常约定 class 只响应特定的几个属性,否则抛出 AttributeError 的错误。

5、__call__()

对实例进行直接调用。

class Student(object):def __init__(self, name):self.name = namedef __call__(self, *args, **kwargs):print('My name is %s' % self.name)s = Student('Michael')
print(s())
# My name is Michael

判断一个对象是否能被调用,若可被调用,则该对象是一个 Callable 对象——callable()

>>> callable(Student())
True
>>> callable(max)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('str')
False

五、枚举类——Enum类

from enum import Enum# Month类型的枚举类  定义
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
print(Month.Jun)# 枚举所有成员,value属性为int常量,默认从1开始计数
for name, member in Month.__members__.items():print(name, '=>', member, ',', member.value)

精确控制枚举类型 ==》Enum的派生类

from enum import Enum, unique
@unique     # 该装饰器确保无重复值
class Weekday(Enum):Sun = 0    # Sun 的 value 被设定为 0Mon = 1Tue = 2Wed = 3Thu = 4Fri = 5Sat = 6## 枚举类型的访问
day1 = Weekday.Mon
print(day1)
print(Weekday.Tue)   # 用成员名称引用枚举常量
print(Weekday['Tue'])
print(Weekday.Tue.value)
print(day1 == Weekday.Mon)
print(day1 == Weekday.Tue)
print(Weekday(1))    # 根据 value 的值获得枚举常量
print(day1 == Weekday(1))
# print(Weekday(7))
for name, member in Weekday.__members__.items():print(name, '=>', member)

既可以用成员名称引用枚举常量,又可以直接根据 value 的值获得枚举常量。

六、使用元类

1、type()

动态语言的函数和类的定义在运行时动态创建的。

type()函数既可以返回一个对象的类型,又可以创建出新的类型。
。。。。。

七、错误、调试和测试

1、错误处理

处理机制:try…except…finally…(可以多个except)

如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即 except 语句块,执行完 except 后,如果有 finally 语句块,则执行 finally 语句块,至此,执行完毕。

若没有错误,执行完try部分,不执行except部分而执行finally部分。

try:print('try...')r = 10 / int('a')print('result: ', r)
except ValueError as e:print('ValueError: ', e)
except ZeroDivisionError as e:print('ZeroDivisionError: ', e)
finally:print('finally...')
print('END')

输出结果

try...
ValueError:  invalid literal for int() with base 10: 'a'
finally...
END

Python 所有的错误都是从 BaseException 类派生的,常见的错误类型和继承关系看这里:
https://docs.python.org/3/library/exceptions.html#exception-hierarchy

2、调用堆栈

解读错误信息是定位错误的关键。我们从上往下可以看到整个错误的调用函数链。

3、记录错误

import loggingdef foo(s):return 10 / int(s)
def bar(s):return foo(s) * 2
def main():try:bar('0')except Exception as e:logging.exception(e)main()
print('END')

4、抛出错误

5、调试

  • print()可能错误的变量值
  • 断言(assert):assert 表达式, ‘输出语句’==》表达式为真,继续执行,否则抛出 AssertionError错误并输出后面的输出语句。
    • python -0 文件.py ==》关闭assert
  • logging输出到文件;
  • 调试器 pdb,可以单步调试

6、单元测试

用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。
==》确保一个程序模块的行为符合我们设计的测试用例。

测试用例:

  • 输入正数;
  • 输入负数;
  • 输入0;
  • 输入非数值类型

【Python】编程笔记7相关推荐

  1. Python 常用线型 + 点符号 + 颜色汇总 ∈ Python 编程笔记

    文章目录 Part.I 线型 Chap.I 基本线型 Chap.II 元组线型 Part.II 点符号 Chap.I 基本符号 Chap.II 高级符号 Part.III 颜色 Chap.I 单词或字 ...

  2. Python编程笔记6字典

    Python编程学习笔记,第6记:数据结构之字典           本节将学习:能够将相关信息关联起来的Python字典.如何定义字典.如何使用存储在字典中的信息.如何访问和修改字典中的元素.如何遍 ...

  3. Python编程笔记

    Table of Contents 1. 绪论 2. python编程概述 2.1. 知识点 2.2. 良好的编程习惯 2.3. 常见编程错误 2.4. 测试和调试提示 2.5. 移植性提示 3. 控 ...

  4. 《Python学习笔记》——南溪的python编程笔记

    1 致谢 感谢张轩老师分享的关于函数式编程的博文! 1 前言 Python中使用函数式编程也是很重要的: 2 函数 (对于函数编写的原则,我们参考了网易云音乐大前端团队的博文网易云音乐大前端团队--& ...

  5. Python 编程笔记(本人出品,必属精品)

    文章目录 Part.I 准备工作 Chap.I 下载安装 Chap.II 实现快捷键清屏 Chap.III 概念汇编 & 注意事项 Part.II 基础知识 Chap.I 快应用 Chap.I ...

  6. python编程注释_自学python编程笔记之:python的注释

    python中有两种注释: 看以下程序示例(未使用注释): 看以下程序示例(使用注释): 一.注释的作用: 增加程序的可读性,让开发者或后续接手程序进行维护修改的程序员提供可读性. 好的程序代码通常有 ...

  7. Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器...

    一.三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件处理: if 条件成立:val = 1else:val = 2 改成三元运算 val = 1 if 条件成立 else 2 ...

  8. python 编程笔记

    不要老把代码全写一个文件,尽量模块化,分布式处理. 不要怕麻烦,代码啰嗦甚至重复都不是当前需要解决的问题,当前最主要的功能是实现功能.

  9. python编程题-python编程题库

    广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 上期题目连接:1000道python题库系列分享十一(9道)上期题目答案:? 本期 ...

  10. python程序设计题库-python编程题库

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. 上期题目连接:1000道python题库系列分享十一(9道)上期题目答案 ...

最新文章

  1. 第四范式陈雨强:万字深析工业界机器学习最新黑科技 By 机器之心2017年7月25日 16:38 近日,全球最顶级大数据会议 Strata Data Conference 在京召开。Strata 大
  2. 5.QT中关于HTTPClient相关的操作,Json数据传输
  3. esp8266驱动oled屏幕_为什么“更好的OLED电视”在海信?
  4. 在清华听演讲系列音频下载地址收集
  5. 部署weblogic 12c时遇到的问题
  6. NodeJS 常用模块积累
  7. 21 , CSS 构造模型
  8. 单LED单端输出充电仓配合TWS耳机芯片QCC3020使用
  9. 远程服务器批量管理员权限,Win10系统下怎样实现批量远程桌面管理?Win10系统进行批量远程管理的方法...
  10. iphone,ipad尺寸汇总
  11. 360云盘 上传服务器忙,360云盘由于服务器压力延期一年关闭 可以慢慢转移资源了...
  12. 电信光猫 TEWA-708E 登录超级管理员和开启DMZ
  13. Python爬取、可视化分析B站大司马视频40W+弹幕
  14. 【初学python】用python做一个简单的超市收银台付款系统
  15. android拷机工具,Android 3DMark大更新:无敌拷机神器
  16. 市内移出版本2.0(1、一页显示15条。2、增加控制标志。3、打印表格时绑定的list的优化。4、保存迁出登记信息时根据业务流水号判断增加还是修改。5、统一管理常量)
  17. 利用搜狗抓取微信公众号文章
  18. udevinfo__ udevadm info
  19. SegmentFault 思否发布开源问答社区软件 Answer
  20. 计算机对英语写作的帮助,计算机文字处理与英语写作教学的融合

热门文章

  1. ostream作为函数返回值_GO语言基础函数
  2. java窗口how2j_HOW2J java文件的创建及常用方法
  3. IDA插件uEmu模拟执行
  4. WSUS使用网络共享存储补丁
  5. 数据链路层、交换机内容整合
  6. python手把手入门_新手必看:手把手教你入门 Python
  7. 计算机鼠标不好使,鼠标不好用 原因竟然让人哭笑不得
  8. telegraf output input 配置用法
  9. pstack 安装linux_详解命令-pstack
  10. noe4j 多层关系查询