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深入理解类和对象的更多相关文章

  1. 初识python中的类与对象

    这篇博客的路线是由深入浅,所以尽管图画的花花绿绿的很好看,但是请先关注我的文字,因为初接触类的小伙伴直接看类的实现可能会觉得难度大,只要耐着性子看下去,就会有一种“拨开迷雾看未来”的感觉了. 一.py ...

  2. python入门17 类和对象

    类:一类事物的抽象化.概念: 类的变量(属于类的变量,定义在类的开始处)  成员变量(self.变量) 类的方法( @classmethod,cls参数)   成员方法( self参数 )  静态方法 ...

  3. Python之面向对象类和对象

    Python之面向对象类和对象 定义一个类:class 定义类的语法: class Test(object): """ 类里定义一类事物共同的技能. 可以是变量,也可是函 ...

  4. 理解类、对象、实例、原型链以及继承 - WPF特工队内部资料

    理解类.对象.实例.原型链以及继承 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  5. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  6. python中的类,对象,方法,属性等介绍

    注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  7. Python 面向对象(创建类和对象,面向对象的三大特性是指:封装、继承和多态,多态性)

    概念:                                                                                                 ...

  8. Python里的类和对象简介

    ---恢复内容开始--- Python里的类  对象=属性+方法: 对象的属性主要是指主要的特征和参量,而方法主要是指函数: 类是一个具有一定特征和方法的集合,而对象是类的一个:类和对象的关系就如同模 ...

  9. Python进阶-XV 类和对象的命名空间 组合

    一.类和对象命名空间 1.类中可以定义两种属性 静态属性和动态属性 class Course: language = 'Chinese' # 静态属性 def __init__(self, name, ...

随机推荐

  1. [Java] 方法 -- 繼承關係

    public class test { void show() { System.out.println("父類別"); } } public class test2 extend ...

  2. vs2017 打开cs文件提示无法识别的GUID格式

    总结一句话 no zuo no die. 是我自己在注册表中给vs增加了自动以管理员身份运行,把值给错了,弄成了 ~ RUNASADMIN WIN7RTM, 改成 ~ RUNASADMIN 后OK.还 ...

  3. Django学习笔记之数据库-数据库与模型

    MySQL数据库 在网站开发中,数据库是网站的重要组成部分.只有提供数据库,数据才能够动态的展示,而不是在网页中显示一个静态的页面.数据库有很多,比如有SQL Server.Oracle.Postgr ...

  4. 2.5 Visio2007不规则图形填充

    1.确保线和线接口的地方正好相交,没有多出来的线: 2.将图形选中>组合: 3.选中图形>形状>操作>连接>填充颜色. 因为图形式几条线段拼合的,不是封闭图形,所以需要将 ...

  5. DevExpress GridView 整理(转)

    DevExpress GridView 那些事儿 1:去除 GridView 头上的 "Drag a column header here to group by that column&q ...

  6. DNS主从配置详解

    实验环境 主服务器:192.168.138.200 从服务器:192.168.138.201 bind安装 安装很简单,执行以下命令即可: yum install -y bind 先看一下bind的版 ...

  7. 【Python】断言功能Assertion

    转自 https://www.cnblogs.com/cicaday/p/python-assert.html Python Assert 为何不尽如人意 Python中的断言用起来非常简单,你可以在 ...

  8. AsyncTask(异步任务)

    一.AsyncTask ①AsyncTask的源码: public abstract class AsyncTask<Params, Progress, Result> 三种泛型类型分别代 ...

  9. Github访问速度慢和下载慢的解决方法

    原因 为什么访问速度慢.下载慢?github的CDN被某墙屏了,由于网络代理商的原因,所以访问下载很慢.Ping github.com 时,速度只有300多ms. 解决方法 绕过dns解析,在本地直接 ...

  10. Failed to resolve: common Open File 导入项目问题

    Failed to resolve: common Open File  Warning:Configuration 'compile' is obsolete and has been replac ...