上一篇文章:(2018-03-23)0005.Python基础入门班_第5课、文件访问与函数式编程入门
关于本人
个人信息:微博
写作区:个人博客、、开源中国、豆瓣、掘金、CSDN
代码管理区:码云、GitHub、GitBook、Python_NoteBook(这个仅仅限于自己的本地搭建)
我的网络制作书籍:Python3Book(基于廖雪峰的Python教程编写成书)、
july_Oneline(基于七月在线培训机构的教程编写成书)、LineCode刷题总结__GitBookEditor网络书籍
推荐网站
无
推荐软件
无
推荐书籍
无
第6课 面向对象基础
一、slots
slots作用
自身理解
英文意思:插槽;老虎机(slot的复数)
代码展示
# 一、__slots__
print('一、__slots__')
import traceback #处理异常的时候打印信息
from types import MethodType # 怎么动态添加一个方法
class MyClass(object):
#__slots__是限制添加哪些变量,#对于子类 不起继承作用
#__系统都叫模数变量,系统内用来实现某些特定功能的
__slots__ = ['name','set_name']
pass
def set_name(self,name):
self.name = name
cls = MyClass()
cls.name = 'L'
cls.set_name = MethodType(set_name,cls)
cls.set_name('HH')
print(cls.name)
# 捕获异常
# try:
# cls.age = 30 # AttributeError: 'MyClass' object has no attribute 'age'
# except AttributeError: # 属性错误
# traceback.print_exc()
class ExtMyClass(MyClass):
pass
ext_cls = ExtMyClass()
ext_cls.age = 30
print(ext_cls.age)
#1.2 @property属性
import traceback
class Student:
@property
def score(self):
return self._score
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueError('not int')
elif (value < 0) or (value > 100):
raise ValueError('not between 0 ~ 100')
self._score = value
@property
def double_score(self):
return self._score * 2
s = Student()
s.score = 75
print(s.score)
try:
s.score = 'abc'
except ValueError: # 这里是捕获 raise ValueError的错误
traceback.print_exc()
# except Exception: # 这里是捕获异常所有的错误
try:
s.score = 101
except:
traceback.print_exc()
print(s.double_score)
try:
s.double_score = 150
except AttributeError: # 这里是因为知道捕获什么类型的error,如果不知道就捕获所有的错误Exception
traceback.print_exc() # AttributeError: can't set attribute 说明只读不能写的
#1.3 @property实现
'''
课后百度 什么事描述其 以及 详细的应用
实现了 __set__/__get__/__del__方法的类 为描述器
'''
print('1.3 @property实现')
class MyProperty:
def __init__(self,fget = None,fset = None,fdel = None):
print('__init__',fget) #
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self,isinstance,cls):
if self.fget:
print('__get__')
return self.fget(isinstance)
def __set__(self,isinstance,value):
if self.fset:
print('__set__')
return self.fset(isinstance,value)
def __del__(self,isinstance):
if self.fdel:
return self.fdel(isinstance)
'''
def getter(self,fn):
self.fget = fn
'''
def setter(self,fn):
print('setter',fn)
self.fset = fn
'''
def deler(self,fn):
self.fdel = fn
'''
class Student:
@MyProperty
def score(self):
print(self._score)
return self._score
@score.setter
def set_score(self,value):
print(value)
self._score = value
s = Student()
s.score = 95
print(s.score)
print('!end!\n')
控制台打印
一、__slots__
HH
30
75
Traceback (most recent call last):
File "C:\Users\Hasee\Desktop\Python_七月在线\01-Python课程___Python基础入门班\Code\第6课 高级面向对象\高级面向对象.py", line 82, in
s.score = 'abc'
File "C:\Users\Hasee\Desktop\Python_七月在线\01-Python课程___Python基础入门班\Code\第6课 高级面向对象\高级面向对象.py", line 69, in score
raise ValueError('not int')
ValueError: not int
Traceback (most recent call last):
File "C:\Users\Hasee\Desktop\Python_七月在线\01-Python课程___Python基础入门班\Code\第6课 高级面向对象\高级面向对象.py", line 88, in
s.score = 101
File "C:\Users\Hasee\Desktop\Python_七月在线\01-Python课程___Python基础入门班\Code\第6课 高级面向对象\高级面向对象.py", line 71, in score
raise ValueError('not between 0 ~ 100')
ValueError: not between 0 ~ 100
150
Traceback (most recent call last):
File "C:\Users\Hasee\Desktop\Python_七月在线\01-Python课程___Python基础入门班\Code\第6课 高级面向对象\高级面向对象.py", line 94, in
s.double_score = 150
1.3 @property实现
AttributeError: can't set attribute
__init__
setter
__set__
95
__get__
95
95
!end!
二、类的特殊方法 和 类的定制
代码展示
#二、类的特殊方法 和 类的定制
'''
字符串
'''
print('#二、类的特殊方法 和 类的定制')
class MyClass:
def __init__(self,name):
self.name = name
def __str__(self):
print('print will call __str__ first.')
return ' Hello ' + self.name + '!'
print(__name__)
print(MyClass('Tom'))
# 作业
'''
实现一个类,支持以下方式输出小于1000的所有素数
自己去查资料,通过实现 __getitem__ 支持切片操作
'''
class Fib100:
def __init__(self):
self._1, self._2 = 0,1
def __iter__(self):
return self
def __next__(self):
self._1,self._2 = self._2,self._1 + self._2
if self._1 > 100:
raise StopIteration()
return self._1
for i in Fib100():
print(i)
#
class Fib2:
# getitem 是修改类的行为
def __getitem__(self,n):
# print(type(n))
a,b = 1,1
for i in range(n):
a,b = b,a+b
return a
f = Fib2()
print(f[1])
print(f[5])
print(f[10])
# print(f[1:2:3])
class MyClass:
def __call__(self):
print('you can call cls() directly.!')
cls = MyClass()
cls()
# callable 是不是可以调用的
print(callable(cls))
print(callable(max)) # 函数 是可以调用的
print(callable([1,2,3]))
print(callable(None))
print(callable('str'))
print('!end\n')
控制台打印
#二、类的特殊方法 和 类的定制
__main__
print will call __str__ first.
Hello Tom!
1
1
2
3
5
8
13
21
34
55
89
1
8
89
you can call cls() directly.!
True
True
False
False
False
!end
三、枚举
百度维基
在数学和计算机科学理论中,
一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。
这两种类型经常(但不总是)重叠。[1]
是一个被命名的整型常数的集合,枚举在日常生活中很常见,
例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、
THURSDAY、FRIDAY、SATURDAY就是一个枚举。
代码展示
#三、枚举
print('三、枚举')
from enum import Enum
Month = Enum('Month',('Jan','Feb','Mar','Apr'))
for name,member in Month.__members__.items():
print(name,'=>',member,',',member.value)
jan = Month.Jan
print(jan)
print('!end!\n')
控制台打印
三、枚举
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
Month.Jan
!end!
四、元类
百度维基
代码展示
#四、元类
'''
python是一个动态类型的语言
'''
print('四、元类')
def init(self,name):
self.name = name
def say_hello(self):
print('Hello, %s!'% self.name)
# 动态生成一个类,
#使用type 第一个参数是这个类的名字,第二个参数是继承那个类,第三个参数是这个类有哪些方法
# Hello = type('Hello',(object,),dict(__init__=init,hello=say_hello))
Hello = type('Hello',(object,),{'__init__':init,'hello':say_hello})
'''
type('Hello',(object),dict(__init__=init,hello=say_hello)) # TypeError: type() argument 2 must be tuple, not type
type('Hello',(object,),dict(__init__=init,hello=say_hello))
object这个是一个基类的列表
必须要传递一个列表
等价于
class Hello:
def __init__(..)
def hello(...)
'''
h = Hello('l')
h.hello()
# 元类添加额外的属性和方法
'''
元类一定是type继承下来的
'''
def add(self,value):
self.append(value)
class ListMetaclass(type):
def __new__(cls,name,bases,attrs):
# print(cls)
# print(name)
# print(bases)
print(type(bases)) # 这是一个只读的
print(type(attrs)) # attrs 其实就是一张哈希表
# attrs 哈希表 实现一个add 函数
# attrs['add'] = lambda self,value: self.append(value)
attrs['add'] = add
attrs['name'] = 'Li'
return type.__new__(cls,name,bases,attrs)
class MyList(list,metaclass = ListMetaclass ): # 额外增加add方法,实际等价于append
pass
mli = MyList()
mli.add(1)
mli.add(2)
mli.add(3)
print(mli)
print(mli.name)
控制台打印
四、元类
Hello, l!
[1, 2, 3]
Li
五、写一个框架的数据库
代码展示
# 五、写一个框架的数据库
'''
极大的方便操作数据库
'''
# fField 列 有两个类型 一个是名字、一个是数据类型
print('五、写一个框架的数据库')
class Field:
def __init__(self,name,col_type):
self.name = name
self.col_type = col_type
class IntegerField(Field):
def __init__(self,name):
super(IntegerField,self).__init__(name,'integer')
class StringField(Field):
def __init__(self,name):
super(StringField,self).__init__(name,'varchar(1024)') # 调用父类的初始化函数
class ModelMetaclass(type):
def __new__(cls,name,bases,attrs):
if name == 'Model':
return type.__new__(cls,name,bases,attrs)
print('Model name:%s' %name)
print('attrs :',attrs)
mappings = {} # 先定义一个字典
'''
key = value
id = IntegerField('id')
name = StringField('name')
'''
# 判断这些属性 是不是filed属性
# 数据库的每一列的数据是放在mapping里面的
# k 是这一列的名字
# v 是列的名字 和列的类型
for k,v in attrs.items():
if isinstance(v,Field):
print('Field name :%s'% k)
mappings[k] = v # 如果是filed 就加到mappings里面去
# 为什么要从attrs弹出来
'''
因为列的名字 和 列的类型 就是放在attrs里面的
后面的
u.id = 100 这些当作正常的去访问
所以attrs不需要 就 把他扔掉
'''
for k in mappings.keys():
attrs.pop(k) # 从attr删除
attrs['__mappings__'] = mappings
attrs['__table__'] = name
# print(attrs['__mappings__'])
return type.__new__(cls,name,bases,attrs)
class Model(dict,metaclass = ModelMetaclass):
def __init__(self,**kvs):
super(Model,self).__init__(**kvs)
def __getattr__(self,key):
try:
return self[key]
except KeyError:
raise AttributeError('Model object has no attribute %s'%key)
def __setattr__(self,key,value):
print('__setattr__')
self[key] = value
def save(self):
fields = []
params = []
args = []
for k,v in self.__mappings__.items():
# print('__mappings__ %s' %k)
fields.append(v.name)
params.append('?')
args.append(getattr(self,k,None))
sql = 'insert into %s(%s) values(%s)' % (self.__table__,','.join(fields),','.join(params))
print('sql:',sql)
print('args:',args)
class User(Model):
id = IntegerField('id')
name = StringField('name')
u = User()
u.id = 100
u.name = 'Tom'
u.save()
print('!end!\n')
控制台打印
五、写一个框架的数据库
Model name:User
attrs : {'__module__': '__main__', 'id': <__main__.IntegerField object at 0x014265B0>, '__qualname__': 'User', 'name': <__main__.StringField object at 0x014265D0>}
Field name :id
Field name :name
__setattr__
__setattr__
sql: insert into User(name,id) values(?,?)
args: ['Tom', 100]
!end!
六、单元测试 和 异常处理
单元测试、异常处理
自身理解
进行应用的测试
代码出错,可以使用异常处理语句进行过滤做操作
代码展示
# 六、单元测试 和 异常处理
'''
logging使用与配置 自己百度
'''
print('六、单元测试 和 异常处理')
import traceback
try:
r = 10 / 1
except ZeroDivisionError as e:
print(e) # 打印异常的信息
r = 1
else:
print('没有异常')
finally:
# r = 1 # 不管异常 发布发生 都会执行
print('不管有没有异常都会执行')
print(r)
# 单元测试 (必须引入 unittest 包)
'''
用的是反射机制
查看有哪些类是由当前unit test继承下来的
然后把继承下来的那些类都执行了一遍
'''
import unittest
class MyDict(dict):
pass
class TestMyDict(unittest.TestCase):
def setUp(self):
print('测试前准备')
def tearDown(self):
print('测试后清理')
def test_init(self):
md = MyDict(one = 1, two = 2)
self.assertEqual(md['one'],1)
self.assertEqual(md['two'],2)
# self.assertEqual(md['two'],3)
def test_nothing(self):
pass
if __name__ == '__main__':
unittest.main()
'''
cmd 执行命令
python test_module.py
python -m unittest test_module
python -m unittest test_module.test_class
python -m unittest test_module.test_class
python -m unittest test_module.test_class.test_method
'''
控制台打印
六、单元测试 和 异常处理
没有异常
不管有没有异常都会执行
10.0
测试前准备
测试后清理
.测试前准备
测试后清理
.
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
[Finished in 0.3s]
代码:l6me
明天将会更新→0007.Python基础入门班_第7课、并发编程以及系统常用模块
代码都是上传百度云