python day5
python day5
面向对象高级编程
使用slots
动态绑定允许在class之外给类添加属性和方法。
如果要对这种动态绑定加限制,用__slots__
class Student(object):
__slots__ = ('name', 'age')
#使用元组定义允许使用动态绑定的属性
没有被放入__slots__
的不允许动态绑定。
子类不受影响。
如果子类也有__slots__
,则子类和父类__slots__
定义的都允许动态绑定。
__slots__
可以大大减少内存的占用。因为对象属性是依靠字典存储的。而__slots__
可以减少对内存的负担。
但__slots__
需要对每一个继承对子类都重新定义一遍;而且不够灵活。
除非编写的类会有上万个对象,否则不推荐使用。
@property
装饰器
把方法变成属性调用
在get方法前加上@property,方法变成属性;自动生成另一个装饰器@属性.setter。
class Student(object):
@property
def get_gender(self):
return self.__gender
def set_gender(self, gender):
if gender == 'male' or gender == 'female':
self.__gender = gender
else:
raise ValueError('invalid gender')
s = Student
s.gender = 'male'
print(s.gender)
减少调用者的负担
多重继承
Java的多继承是用接口实现的。
python 通过继承多个类实现MixIn。
class Dog(Mammal, Animal, Runnable):
pass
python 多重继承的拓扑排序:
https://kevinguo.me/2018/01/19/python-topological-sorting/
使用C3 算法。
继承关系是一个有向无环图,从入度为0处开始,如果多个入度为0,则取最左。
定制类
__str__()
用户看 __repr__()
调试看
改变控制台打印的信息
一般__repr__ == __str__
__iter__()
方法返回迭代对象
__getitem__()
__setitem__()
__delitem__()
将自己定义的类表现的与list、tuple、dict没什么区别。
__getattr__()
动态获取类的属性
如果在调用类的属性时,没有该属性,那么会取调用这个方法。 __getattr__()
默认返回None。
__call__()
使得对象变得可以被调用 callable()
判断一个对象是否是可以被调用的对象。
枚举类
可以直接使用enum,也可以定义自己的枚举类。
# coding _utf-8
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
print(name, '==>', member, ',', member.value)#value默认从1开始。
('Jan', '==>', <Month.Jan: 1>, ',', 1)
('Feb', '==>', <Month.Feb: 2>, ',', 2)
('Mar', '==>', <Month.Mar: 3>, ',', 3)
('Apr', '==>', <Month.Apr: 4>, ',', 4)
('May', '==>', <Month.May: 5>, ',', 5)
('Jun', '==>', <Month.Jun: 6>, ',', 6)
('Jul', '==>', <Month.Jul: 7>, ',', 7)
('Aug', '==>', <Month.Aug: 8>, ',', 8)
('Sep', '==>', <Month.Sep: 9>, ',', 9)
('Oct', '==>', <Month.Oct: 10>, ',', 10)
('Nov', '==>', <Month.Nov: 11>, ',', 11)
('Dec', '==>', <Month.Dec: 12>, ',', 12)
在pycharm中无法导入enum模块,最后清除缓存,重启。
自定义枚举类型:
from enum import Enum, unique
unique
class Month(Enum):
Jan = 0#value可以自己编写
Feb = 1
Mar = 2
Apr = 3
May = 4
Jun = 5
Jul = 6
Aug = 7
Sep = 8
Oct = 9
Nov = 10
Dec = 11
@unique保证value不会重复。
使用元类
type()
type()可以检查一个对象或者变量的类型,也可以动态创建一个类。
类的类型是type。
metaclass
类似于元数据的概念。
元类。
定义元类,就可以根据元类创建类,然后根据类创建对象。
错误、调试、测试
修复bug、检查用户输入、处理异常、测试代码
错误处理
Java是try...catch...finally
python是try...except...finally
或者try...except...else...finally
python所有的错误都继承自BaseException。
java throw
python raise
如果不带参数,raise将错误原样抛出。
调试
assert
断言,调试结束可以关闭
logging
级别:
debug
info
warning
error
import logging
logging.basicConfig(level=logging.ERROR)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
logging调试最强大,ide调试最方便
单元测试
# -*- coding: utf-8 -*-
import unittest
class Student(object):
def __init__(self, name, score):
self.name = name
if not (score >= 0 and score <= 100):
raise ValueError('invalid score')
self.score = score
def get_grade(self):
if self.score >= 80:
return 'A'
elif self.score >= 60:
return 'B'
return 'C'
class TestStudent(unittest.TestCase):
def test_80_to_100(self):
s1 = Student('Bart', 80)
s2 = Student('Lisa', 100)
self.assertEqual(s1.get_grade(), 'A')
self.assertEqual(s2.get_grade(), 'A')
def test_60_to_80(self):
s1 = Student('Bart', 60)
s2 = Student('Lisa', 79)
self.assertEqual(s1.get_grade(), 'B')
self.assertEqual(s2.get_grade(), 'B')
def test_0_to_60(self):
s1 = Student('Bart', 0)
s2 = Student('Lisa', 59)
self.assertEqual(s1.get_grade(), 'C')
self.assertEqual(s2.get_grade(), 'C')
def test_invalid(self):
s1 = Student('Bart', -1)
s2 = Student('Lisa', 101)
with self.assertRaises(ValueError):
s1.get_grade()
with self.assertRaises(ValueError):
s2.get_grade()
if __name__ == '__main__':
unittest.main()
文档测试
文档测试既可以测试,也可以作为示例程序。
IO
分为:
同步IO:效率低,简单
异步IO:效率高,复杂,有轮询模式和回调模式
本质上是高效的cpu与低效的外设之间的矛盾
文件读写
读input
try:
f = open('haha.txt', 'r')#r表示读
f.read()
except IOError as e:
pass
finally:
if f:
f.close()
读进来的数据是一个str类型的对象。
比较麻烦
简写方式是:
with open('haha.txt', 'r') as f:
f.read()
read() 一次性读取文件的全部数据
read(size) 一次最多读取size字节的数据
readline() 一次读取一行数据
readlines() 一次读取全部数据,并返回list,按照行存储所有的数据
上一篇: MapTask阶段shuffle源码分析
下一篇: 通过JSP的预编译消除性能瓶颈