restframework api(基础1)
最近项目忙成狗,都没时间好好看看开发的东西了,正好最近开始看rest api的东西,真是个好东西啊。可以前后端分离,但是在学习的过程中,遇到各种问题。还是基础不够扎实。本次rest api的会一边遇坑一边补习之前的东西。
一 functools库
真是一个神奇的python库,以前一直没注意。
1 偏函数 partial
先找文档学习一下,最后看源码,源码能看懂就看,看不懂那就是真的看不懂了。
文档参考 https://blog.csdn.net/appleyk/article/details/77609114
partial 一共有三个部分:
(1)第一部分也就是第一个参数,是一个函数,这个函数可以是你定义的,也可以是Python内置函数
(2)第二部分是一个可变参数,*args,比如内置函数max的参数就是一个可变参数,max(1,2,3,4,5)=5
(3)第三部分是一个关键字参数,比如内置函数int的第二个参数就是命名关键字参数,默认base=10,表示int转换时默认是10进制的:
partial函数的作用就是:将所作用的函数作为partial()函数的第一个参数,原函数的各个参数依次作为partial()函数的后续参数,原函数有关键字参数的一定要带上关键字,没有的话,按原有参数顺序进行补充。
使用一下吧
A、偏函数的第二个部分(可变参数),按原有函数的参数顺序进行补充,参数将作用在原函数上,最后偏函数返回一个新函数(类似于,装饰器decorator,对于函数进行二次包装,产生特殊效果;但又不同于装饰器,偏函数产生了一个新函数,而装饰器,可改变被装饰函数的函数入口地址也可以不影响原函数)
这里我的理解是:首先偏函数能做的事情,装饰器也能做,其次偏函数可以操作源函数的参数,可是装饰器可以操作函数的入口。那为啥还有偏函数,估计是因为比装饰器简单吧。用起来应该很爽。
案例:我们定义一个sum函数,参数为*args可变,计算这些可变参数的和。
扩展:我们想要对sum函数求和后的结果,再加上10加上20甚至加更多,得到一个新的结果。
实现:我们分别用decorator和partial来实现,对比一下二者的区别。
好激动,因为可以紧跟作者脚步可以复习一下装饰器的东西了。
(1)装饰器实现
基础:http://www.cnblogs.com/wanstack/p/9009932.html
# /usr/bin/env Python3
# -*- encoding:UTF-8 -*- from functools import wraps def sum_add(*args1): #我们要给我们的装饰器decorator,带上参数
def decorator(func):
@wraps(func) #加上这句,原函数func被decorator作用后,函数性质不变
def my_sum(*args2): #注意,参数要和原函数保持一致,真正实行扩展功能的是外层的装饰器
my_s = 0
for n in args1:
my_s = my_s +n #这个是我们新加的求和结果
return func(*args2) + my_s #这个,我们在原求和函数的结果上再加上s,并返回这个值
return my_sum #返回my_sum函数,该函数扩展原函数的功能
return decorator #返回我们的装饰器 @sum_add(10,20) #启用装饰器 对sum函数进行功能扩展
def sum(*args):
s = 0
for n in args:
s = s+n
return s
print(sum(1,2,3,4,5))
print(sum.__name__)
这里以前一直有一个疑问,今天突然间理解了,以前一直觉得为啥装饰器带上参数就需要写三层嵌套函数,因为@decorator没有()所以是不需要执行的,而加上参数@decorator(*args)是已经开始执行了啊。尼玛就是这么简单,当时困扰了好久。归根结底还是不理解。有时候想想做技术真的是理解了就是理解了,不理解死记硬背也不理解。
看看偏函数的实现:
# /usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from functools import partial def sum(*args):
s = 0
for n in args:
s = s + n
return s sum_add_10 = partial(sum,10) #10 作用在sum第一个参数的位置
sum_add_10_20 = partial(sum,10,20) #10 20 分别作用在sum第一个和第二个参数的位置
print('A____________我们看下原函数sum的函数地址入口:')
print(sum)
print('B______我们看下partial函数返回函数的地址入口:')
print(partial(sum,10))
print(sum_add_10(1,2,3,4,5)) # --> 10 + 1 + 2 + 3 + 4 + 5 = 25
print(sum_add_10_20(1,2,3,4,5)) # --> 10 + 20 + 1 + 2 + 3 + 4 + 5 = 45
一步到位,当然还有其他方式一步到位的写法。这里的partial(函数,函数的第一个参数位置) 这部就是可以对已经存在的函数的参数中,继续传递参数吗。
B、偏函数的第三个部分(关键字参数),按原有函数的关键字参数进行填补,参数将作用在原函数上,最后偏函数返回一个新函数
案例:我们定义一个mod求余函数,两个参数,一个是被除数,一个是除数,除数我们这里用命名关键字参数表示,默认值2
扩展:我们的除数不固定,可以是对2就行求余,也可以对3,对4,总之我们需要指定除数的值
返回结果: True 或 False
实现:原函数实现和partial函数实现
# /usr/bin/env Python3
# -*- encoding:UTF-8 -*-
import functools
def mod(m,*,key=2):
return m % key == 0
mod_to_2 = functools.partial(mod,key=2)
print('A__3___使用原函数的默认关键字参数对2进行求余:')
print(mod(3)) #对2进行求余-- 原函数 使用默认参数
print('B__3___使用偏函数对2进行求余:')
print(mod_to_2(3)) #对2进行求余-- 新函数 --偏函数产生
mod_to_5 = functools.partial(mod,key=5)
print('C__25___使用原函数的关键字参数对5进行求余:')
print(mod(25,key=5)) #对5进行求余 -- 原函数
print('D__25___使用偏函数对5进行求余:')
print(mod_to_5(25)) #对5进行求余 -- 新函数--偏函数产生
2 wraps
其实上面已经用到了wraps,一般在使用装饰器的时候会使用这个,他也是一个装饰器,至于为什么会用他,因为我们在使用装饰器的时候,会损失一些基本信息,比如fun.__name__等等,用上他,就不会了。
啥也不说了,直接上代码。
# coding:utf-8
from functools import partial WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Update a wrapper function to look like the wrapped function wrapper is the function to be updated
wrapped is the original function
assigned is a tuple naming the attributes assigned directly
from the wrapped function to the wrapper function (defaults to
functools.WRAPPER_ASSIGNMENTS)
updated is a tuple naming the attributes of the wrapper that
are updated with the corresponding attribute from the wrapped
function (defaults to functools.WRAPPER_UPDATES)
"""
"""
try:
<语句>
except <name>:
<语句> #如果在try部份引发了名为'name'的异常,则执行这段代码
else:
<语句> #如果没有异常发生,则执行这段代码
finally:
print("不管有没有异常,我总是被执行了")
"""
print("wrapper==========" ,wrapper) # 这里的wrapper是一个inner函数
for attr in assigned:
try:
# 这里的wrapped应该是被装饰的函数,从wrapped中获取assigned的属性
value = getattr(wrapped, attr)
print("value============",value)
except AttributeError:
pass
else:
# 这里try执行了,这里就把value的值赋值给wrapper对象
setattr(wrapper, attr, value)
v = getattr(wrapper,attr)
print('v------',v)
for attr in updated:
print("getattr(wrapper, attr)",getattr(wrapper, attr)) # 这是个字典
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
# Issue #17482: set __wrapped__ last so we don't inadvertently copy it
# from the wrapped function when updating __dict__
wrapper.__wrapped__ = wrapped
# Return the wrapper so this can be used as a decorator via partial()
return wrapper # 这个wrapper是一个inner def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
"""Decorator factory to apply update_wrapper() to a wrapper function Returns a decorator that invokes update_wrapper() with the decorated
function as the wrapper argument and the arguments to wraps() as the
remaining arguments. Default arguments are as for update_wrapper().
This is a convenience function to simplify applying partial() to
update_wrapper().
"""
# 其中update_wrapper是一个函数,wtrapped,assigned,updated是这个函数的关键字参数
# 这里执行update_wrapper函数,返回一个wrapper
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated) def decorator(func):
"""
1. value = getattr(wrapped, attr) 从func中拿到一些属性信息
2. setattr(wrapper, attr, value) 把这些属性信息赋值给inner
3. return wrapper 返回inner
:param func:
:return:
"""
@wraps(func) # func = wraps(func)
def inner():
print('起床先睁眼')
func()
return inner @decorator # func = decorator(func)
def func():
print('早上起床') func() # 执行inner()
print(func.__name__)
print(func.__dict__)
可能看着有点乱,但是只要就是
1. value = getattr(wrapped, attr) 从func中拿到一些属性信息
2. setattr(wrapper, attr, value) 把这些属性信息赋值给inner
3. return wrapper 返回inner
做了这三件事情,当然了__dict__中的我没写,但是大概就是这么个流程,现在知道了即使,我们返回的是inner函数,也会对应的是func的信息。中间通过反射进行取值和赋值的操作。
restframework api(基础1)的更多相关文章
- 从头编写 asp.net core 2.0 web api 基础框架 (1)
工具: 1.Visual Studio 2017 V15.3.5+ 2.Postman (Chrome的App) 3.Chrome (最好是) 关于.net core或者.net core 2.0的相 ...
- 【转载】从头编写 asp.net core 2.0 web api 基础框架 (1)
工具: 1.Visual Studio 2017 V15.3.5+ 2.Postman (Chrome的App) 3.Chrome (最好是) 关于.net core或者.net core 2.0的相 ...
- 从头编写asp.net core 2.0 web api 基础框架 (5) + 使用Identity Server 4建立Authorization Server (7) 可运行前后台源码
前台使用angular 5, 后台是asp.net core 2.0 web api + identity server 4. 从头编写asp.net core 2.0 web api 基础框架: 第 ...
- 《Node.js高级编程》之Node 核心API基础
Node 核心API基础 第三章 加载模块 第四章 应用缓冲区 第五章 事件发射器模式简化事件绑定 第六章 使用定时器制定函数执行计划 第三章 加载模块 本章提要 加载模块 创建模块 使用node_m ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(二)-创建项目 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.ne ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(三)-创建Data Transfer Object
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(三)-创建Data Transfer Object 版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(一)-环境介绍
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(一)-环境介绍 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.ne ...
- restframework api(基础3CBV)
一 CBV源码流程 urls.py from django.conf.urls import url from django.contrib import admin from app01 impor ...
随机推荐
- Django:学习笔记(5)——会话
Django:学习笔记(5)——会话 配置中间件 Django中使用会话,需要配置一个中间件. 配置会话引擎 默认情况下,Django在数据库中存储sessions(使用了django.contrib ...
- 从u-boot的编译结果中提取include目录
ac@DESKTOP-BJ1MJGM:~/u-boot-2019.01/spl$ arm-linux-gnueabihf-objdump -g u-boot-spl | awk '/The Direc ...
- ansible playbook基本操作
一.ansible playbook简单使用 相当于是把模块写入到配置文件里面 vim /etc/ansible/test.yml //写入如下内容: --- - hosts: 127.0.0.1 r ...
- Ubuntu16.04安装Jenkins
Jenkins基于JAVA,所以需要先安装jdk 安装java 在官网上下载jdk,http://www.oracle.com/technetwork/java/javase/downloads/jd ...
- std::tuple作为参数invoke调用函数
template<typename Function, typename Tuple, std::size_t... Index> decltype(auto) invoke_impl(F ...
- Android中的颜色值
1.在android中经常看到设置的颜色为八位的十六进制的颜色值,例如: 1 2 3 public static final class color { public static final ...
- Koa源码解析
Koa是一款设计优雅的轻量级Node.js框架,它主要提供了一套巧妙的中间件机制与简练的API封装,因此源码阅读起来也十分轻松,不论你从事前端或是后端研发,相信都会有所收获. 目录结构 首先将源码下载 ...
- 20145310《Java程序设计》第3次实验报告
20145310<Java程序设计>第3次实验报告 实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 实验步骤 首先使用git设置用户名和ssh公钥 使用git ...
- ifconfig设置ip时出现提示 ifconfig: SIOCSIFFLAGS: Address not available
一.笔者使用ifconfig观察网卡情况如下: root@jello:/# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:0 ...
- Java 面试题代码类收集
long temp=(int)3.9; System.out.println(temp); temp%=2; System.out.println(temp); 3 1 Java里面类的方法名可以与类 ...