python深入理解类和对象
1,鸭子类型和多态
当看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那这只鸟就是鸭子
是不是比较混乱,看个例子:
# -*- coding:UTF-8 -*-
__autor__ = 'zhouli'
__date__ = '2018/11/14 20:46' class Cat:
def say(self):
print('iam a cat') class Dog:
def say(self):
print('iam a dog') class Duck:
def say(self):
print('iam a duck') animal_list = [Cat, Dog, Duck]
for animal in animal_list:
animal().say()
结果如下:
iam a cat
iam a dog
iam a duck
在这个地方三个类实现了同一个方法,这样就是一种多态,什么叫鸭子类型呢,就是所有类都实现共同的方法,所有的方法名称都一样,这样就是鸭子类型
2,类的三个方法:
class Date:
# 构造函数
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day def tomorrow(self):
self.day += 1 @staticmethod
def parse_from_string(date_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day)) @staticmethod
def valid_str(date_str):
year, month, day = tuple(date_str.split("-"))
if int(year) > 0 and (int(month) > 0 and int(month) <= 12) and (int(day) > 0 and int(day) <= 31):
return True
else:
return False @classmethod
def from_string(cls, date_str):
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day)) def __str__(self):
return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day) if __name__ == "__main__":
new_day = Date(2018, 12, 31)
new_day.tomorrow()
print(new_day) # 2018-12-31
date_str = "2018-12-31"
year, month, day = tuple(date_str.split("-"))
new_day = Date(int(year), int(month), int(day))
print(new_day) # 用staticmethod完成初始化
new_day = Date.parse_from_string(date_str)
print(new_day) # 用classmethod完成初始化
new_day = Date.from_string(date_str)
print(new_day) print(Date.valid_str("2018-12-32"))
所谓静态方法就相当于将需要外部调用的方法集成到类的内部,将命名空间并入到类中
类方法相比静态方法,不在需要硬编码了
实例方法就很简单了,使用实例+方法+()即可
3,super函数:
先看一个简单的例子:
# -*- coding:UTF-8 -*-
__autor__ = 'zhouli'
__date__ = '2018/11/17 21:18' class A:
def __init__(self):
print('A') class B(A):
def __init__(self):
print('B')
# super(B, self).__init__() # python2的用法
super().__init__() # 既然已经重写了B的构造函数,为什么还要去调用super
# super到底执行顺序是什么
if __name__ == '__main__':
b = B()
打印结果如下:但是我们得思考2个问题,①既然已经重写了B的构造函数,为什么还要去调用super
② super到底执行顺序是什么
# -*- coding:UTF-8 -*-
__autor__ = 'zhouli'
__date__ = '2018/11/17 21:18' class A:
def __init__(self,user,name):
print('A')
self.user = user
self.name = name class B(A):
def __init__(self,user,name):
self.user = user
print('B')
super().__init__(name=name) if __name__ == '__main__':
b = B()
可以看到B类中继承A类中,如果定义父类中的部分方法,所以为了节省代码,因此采用super
super函数并不是简单的调用父类的方法,先看代码
# -*- coding:UTF-8 -*-
__autor__ = 'zhouli'
__date__ = '2018/11/17 21:18' class A:
def __init__(self):
print('A') class B(A):
def __init__(self):
print('B')
super().__init__()
class C(A):
def __init__(self):
print('C')
super().__init__()
class D(B,C):
def __init__(self):
print('D')
super().__init__() if __name__ == '__main__':
D = D()
D回去调用父类的函数,因为B在C之前,所以会有限调用
结果如下:
但是注意到B在调用super之后打印的是C,而不是A
如果super是简单调用父类的构造函数的话,那么久不成立了
为什么会打印出这样的结果呢?
因为super是执行D的__mro__
print(D.__mro__)
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
这两个数据顺序是保持一致的!
4,Mixin继承混合模式(除非万不得已,不要使用多继承)
Mixin其实和普通的多继承是本质一样的,但是Mixin有两个特点:
① Minin里面功能比较单一,尽量简化
② 不和我们真正的类一样,不和基类关联,可以和任意基类组合,基类不和Mixin关联就能初始化成功,Minin只是定义了一个方法
③ Minin中不要使用super的方法,因为super会根据mro算法去调用他的方法,因为尽量不要和基类关联
④ 命名尽量使用Mixin结尾(约定俗成)
class GoodsListViewSet(CacheResponseMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""
商品列表页, 分页, 搜索, 过滤, 排序
"""
# throttle_classes = (UserRateThrottle, )
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
# authentication_classes = (TokenAuthentication, )
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
filter_class = GoodsFilter
search_fields = ('name', 'goods_brief', 'goods_desc')
ordering_fields = ('sold_num', 'shop_price') def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
instance.click_num += 1
instance.save()
serializer = self.get_serializer(instance)
return Response(serializer.data)
在这个类中,一个类可以完成商品列表页, 分页, 搜索, 过滤, 排序,
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
5,上下文管理器:
#上下文管理器协议
class Sample:
def __enter__(self):
print ("enter")
#获取资源
return self
def __exit__(self, exc_type, exc_val, exc_tb):
#释放资源
print ("exit")
def do_something(self):
print ("doing something") with Sample() as sample:
sample.do_something()
上下文如果使用with语句就必须在类中定义这个两个方法

那如何简化这个上下文管理器呢?
import contextlib @contextlib.contextmanager
def file_open(file_name):
print("file open")
yield {}
print("file end") with file_open("bobby.txt") as f_opened:
print("file processing")
在python中提供了一个contextlib模块
在上面的__enter__中的所有代码全部在yield之前操作
在yield之后是原来的__exit__方法全部放在里面
当然函数的上方必须要加上装饰器@contextlib.contextmanager
6,使用bisect
import bisect
from collections import deque #用来处理已排序的序列,用来维持已排序的序列, 升序
#二分查找
inter_list = deque()
bisect.insort(inter_list, 3)
bisect.insort(inter_list, 2)
bisect.insort(inter_list, 5)
bisect.insort(inter_list, 1)
bisect.insort(inter_list, 6) print(bisect.bisect_left(inter_list, 3))
#学习成绩
print(inter_list)
结果如下:
2
deque([1, 2, 3, 5, 6])
但是如果一旦插入一个相同的数字,左插入和右插入又有何分别呢?
其实在一定的时候,比方说3和3.0相比或者是对成绩的排序时候有讲究
python深入理解类和对象的更多相关文章
- 初识python中的类与对象
这篇博客的路线是由深入浅,所以尽管图画的花花绿绿的很好看,但是请先关注我的文字,因为初接触类的小伙伴直接看类的实现可能会觉得难度大,只要耐着性子看下去,就会有一种“拨开迷雾看未来”的感觉了. 一.py ...
- python入门17 类和对象
类:一类事物的抽象化.概念: 类的变量(属于类的变量,定义在类的开始处) 成员变量(self.变量) 类的方法( @classmethod,cls参数) 成员方法( self参数 ) 静态方法 ...
- Python之面向对象类和对象
Python之面向对象类和对象 定义一个类:class 定义类的语法: class Test(object): """ 类里定义一类事物共同的技能. 可以是变量,也可是函 ...
- 理解类、对象、实例、原型链以及继承 - WPF特工队内部资料
理解类.对象.实例.原型链以及继承 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感
关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...
- python中的类,对象,方法,属性等介绍
注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...
- Python 面向对象(创建类和对象,面向对象的三大特性是指:封装、继承和多态,多态性)
概念: ...
- Python里的类和对象简介
---恢复内容开始--- Python里的类 对象=属性+方法: 对象的属性主要是指主要的特征和参量,而方法主要是指函数: 类是一个具有一定特征和方法的集合,而对象是类的一个:类和对象的关系就如同模 ...
- Python进阶-XV 类和对象的命名空间 组合
一.类和对象命名空间 1.类中可以定义两种属性 静态属性和动态属性 class Course: language = 'Chinese' # 静态属性 def __init__(self, name, ...
随机推荐
- windows server 2008 R2之取消多余的安全配置
一:取消IE浏览器的安全配置(使IE浏览器可以正常上网) 管理员禁用即可 二.取消关机时强制输入关机备注 运行gpedit.msc,选择计算机配置->管理模板->系统->提示“关机时 ...
- Codeblocks中文乱码解决方法
odeblocks中文乱码解决方法: 特别提示:出现中文乱码情况才执行以下操作,未出现请勿随意修改!!!! 打开Codeblocks -> 设置 -> 编辑器: 然后点击 Encoding ...
- 设置Tomcat管理员用户名和密码
http://dove19900520.iteye.com/blog/1774980 今天tomcat出点问题,然后我就想进入tomcat manager看看,结果怎么输入密码都不行,后来网上查了查才 ...
- windows time-wait 问题处理记录
问题描述:有一段时间,服务器启动了好多程序,做的是 obd监听服务,连接好多个服务器,由于程序的本身的问题造成大量的wait-time,一番百度后找到找到方案1 设置一由于wait-time 需要经过 ...
- Flink+Kafka 接收流数据并打印到控制台
试验环境 Windows:IDEA Linux:Kafka,Zookeeper POM和Demo <?xml version="1.0" encoding="UTF ...
- 读取Excel的部分问题
1.office分很多版本,导致Excel连接字符串不同. 2.是否有标题头的问题(在连接字符串中设置) 3.Excel本身删除分数据删除和表格结构删除.普通delete只能删除数据, 还是能读取到表 ...
- ORM的多表查询详述
ORM的多表查询 ORM最核心与用的最多的地方就是跨表查询了.这里的"跨表查询"分为以下几种:基于对象的跨表查询.基于双下划线的跨表查询.聚合查询.F与Q查询以及分组查询. 下面就 ...
- UE4 UMG
转自:https://www.cnblogs.com/kadaj/p/6412937.html 1.创建关卡类 1.创建C++类继承LevelScriptActor 2.打开关卡蓝图 Class Se ...
- qrcode生成二维码
代码: <!DOCTYPE html> <html lang="en" style="height: 99%"> <head> ...
- xxx.jar 中没有主清单属性
springboot 中是可以通过 jar 将整个项目打包成一个fat jar 的, 这个大家都知道. <!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 --&g ...