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, ...
随机推荐
- [Java] 方法 -- 繼承關係
public class test { void show() { System.out.println("父類別"); } } public class test2 extend ...
- vs2017 打开cs文件提示无法识别的GUID格式
总结一句话 no zuo no die. 是我自己在注册表中给vs增加了自动以管理员身份运行,把值给错了,弄成了 ~ RUNASADMIN WIN7RTM, 改成 ~ RUNASADMIN 后OK.还 ...
- Django学习笔记之数据库-数据库与模型
MySQL数据库 在网站开发中,数据库是网站的重要组成部分.只有提供数据库,数据才能够动态的展示,而不是在网页中显示一个静态的页面.数据库有很多,比如有SQL Server.Oracle.Postgr ...
- 2.5 Visio2007不规则图形填充
1.确保线和线接口的地方正好相交,没有多出来的线: 2.将图形选中>组合: 3.选中图形>形状>操作>连接>填充颜色. 因为图形式几条线段拼合的,不是封闭图形,所以需要将 ...
- DevExpress GridView 整理(转)
DevExpress GridView 那些事儿 1:去除 GridView 头上的 "Drag a column header here to group by that column&q ...
- DNS主从配置详解
实验环境 主服务器:192.168.138.200 从服务器:192.168.138.201 bind安装 安装很简单,执行以下命令即可: yum install -y bind 先看一下bind的版 ...
- 【Python】断言功能Assertion
转自 https://www.cnblogs.com/cicaday/p/python-assert.html Python Assert 为何不尽如人意 Python中的断言用起来非常简单,你可以在 ...
- AsyncTask(异步任务)
一.AsyncTask ①AsyncTask的源码: public abstract class AsyncTask<Params, Progress, Result> 三种泛型类型分别代 ...
- Github访问速度慢和下载慢的解决方法
原因 为什么访问速度慢.下载慢?github的CDN被某墙屏了,由于网络代理商的原因,所以访问下载很慢.Ping github.com 时,速度只有300多ms. 解决方法 绕过dns解析,在本地直接 ...
- Failed to resolve: common Open File 导入项目问题
Failed to resolve: common Open File Warning:Configuration 'compile' is obsolete and has been replac ...