Python全栈工程师(4:函数)
函数基础:
- 面向对象:基本单元-->类>>>class
- 面向过程:基本单元-->过程>>>def :
- 函数式编程:基本单元-->函数>>>def ;调用-->fun()
注意:
(1)、函数里面最好写函数说明,方便别人阅读;
(2)、关键参数不能写在位置参数前面;eg:test(3,x=2,4)
(3)、全局变量和局部变量
函数与函数式编程:
特点:允许把函数本身作为参数传入了一个函数,还返回一个函数!
eg:var result = substract(multiply(add(1,2),3),4)) #(1+2)*3/4
#语法
def 函数名(参数1,参数2,参数3,...):'''注释'''函数体return 返回的值#函数名要能反映其意义
eg:
import timedef logger():time_format = '%Y-%m-%d %X'time_current = time.strftime(time_format)with open('text.txt', 'a+') as f:f.write('welcome you...%s' % time_current)def fun1():'''面向函数说明'''print("fun1...")logger() # logger()必须先于fun1定义:def fun2():'''面向过程说明'''print("fun2...")logger() # logger()必须先于fun2定义:fun1()
fun2()
函数使用的原则:先定义,再调用;
函数在定义阶段,只检测语法,不执行代码,也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道
定义函数的三种形式
#1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印 #2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值 #3、空函数:设计代码结构
#1、位置参数:按照从左到右的顺序定义的参数位置形参:必选参数位置实参:按照位置给形参传值#2、关键字参数:按照key=value的形式定义的实参无需按照位置为形参传值注意的问题:1. 关键字实参必须在位置实参右面2. 对同一个形参不能重复传值#3、默认参数:形参在定义时就已经为其赋值可以传值也可以不传值,经常需要变的参数定义成位置形参,变化较小的参数定义成默认参数(形参)注意的问题:1. 只在定义时赋值一次2. 默认参数的定义应该在位置形参右面3. 默认参数通常应该定义成不可变类型#4、可变长参数:可变长指的是实参值的个数不固定而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs===========*args===接受N个位置参数值转换为元组的形式========def foo(x,y,*args):print(x,y)print(args)foo(1,2,3,4,5) #1 2 (3,4,5)def foo(x,y,*args):print(x,y)print(args)foo(1,2,*[3,4,5]) #1 2 (3,4,5)def foo(x,y,z):print(x,y,z)foo(*[1,2,3]) #1 2 3=======**kwargs===接受N个关键字参数转换为字典形式========def foo(x,y,**kwargs):print(x,y)print(kwargs)foo(1,y=2,a=1,b=2,c=3) #1 2 {'b': 2, 'a': 1, 'c': 3}def foo(x,y,**kwargs):print(x,y)print(kwargs)foo(1,y=2,**{'a':1,'b':2,'c':3}) # 1 2 {'b': 2, 'a': 1, 'c': 3}def foo(x,y,z):print(x,y,z)foo(**{'z':1,'x':2,'y':3}) #2 3 1===========*args+**kwargs===========def foo(x,y):print(x,y)def wrapper(*args,**kwargs):print('====>')foo(*args,**kwargs)#5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
可以保证,传入的参数中一定包含某些关键字def foo(x,y,*args,a=1,b,**kwargs):print(x,y)print(args)print(a)print(b)print(kwargs)foo(1,2,3,4,5,b=3,c=4,d=5)结果:1 2(3, 4, 5)13{'c': 4, 'd': 5}
函数对象:
函数是第一类对象,即函数可以当作数据传递
#1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素
利用该特性,优雅的取代多分支的if
def foo():print('foo')def bar():print('bar')dic={'foo':foo,'bar':bar, } while True:choice=input('>>: ').strip()if choice in dic:dic[choice]()
函数的嵌套
函数的嵌套调用
def max(x,y):return x if x > y else ydef max4(a,b,c,d):res1=max(a,b)res2=max(res1,c)res3=max(res2,d)return res3
print(max4(1,2,3,4))
函数的嵌套定义
def f1():def f2():def f3():print('from f3')f3()f2()f1()
名称空间和作用域
#名称空间:存放名字的地方,三种名称空间,(x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
名称空间的加载顺序
python test.py #1、python解释器先启动,因而首先加载的是:内置名称空间 #2、执行test.py文件,然后以文件为基础,加载全局名称空间 #3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
名字的查找顺序
局部名称空间--->全局名称空间--->内置名称空间#需要注意的是:在全局无法查看局部的,在局部可以查看全局的,如下示例# max=1 def f1():# max=2def f2():# max=3print(max)f2() f1() print(max)
作用域
#1、作用域即范围- 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效- 局部范围(局部名称空间属于该范围):临时存活,局部有效 #2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下 x=1 def f1():def f2():print(x)return f2 x=100 def f3(func):x=2func() x=10000 f3(f1())#3、查看作用域:globals(),locals() LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__ locals 是函数内的名字空间,包括局部变量和形参 enclosing 外部嵌套函数的名字空间(闭包中常见) globals 全局变量,函数定义所在模块的名字空间 builtins 内置模块的名字空间
闭包:
#内部函数包含对外部作用域而非全局作用域的引用#提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路def counter():n=0def incr():nonlocal nx=nn+=1return xreturn incrc=counter()print(c())print(c())print(c())print(c.__closure__[0].cell_contents) #查看闭包的元素
意义与应用
#闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域 #应用领域:延迟计算(原来是传参,现在是包起来)from urllib.request import urlopendef index(url):def get():return urlopen(url).read()return getbaidu=index('http://www.baidu.com')print(baidu().decode('utf-8'))
递归:
1、必须有明确的结束条件;
2、每递归一次,问题规模比上一次减少;
3、递归效率不高。递归层次过多会导致栈溢出;
递归分为两个阶段:递推,回溯
# salary(5)=salary(4)+300
# salary(4)=salary(3)+300
# salary(3)=salary(2)+300
# salary(2)=salary(1)+300
# salary(1)=100
#
# salary(n)=salary(n-1)+300 n>1
# salary(1) =100 n=1def salary(n):if n == 1:return 100return salary(n-1)+300print(salary(5))
python中的递归python中的递归效率低,需要在进入下一次递归时保留当前的状态;其他语言中的解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
python又没有尾递归,且对递归层级做了限制。
三元表达式:
name=input('姓名>>: ')
res='girl' if name == 'julia' else 'boy'
print(res)
列表推导式:
#1、示例
egg_list=[]
for i in range(10):egg_list.append('鸡蛋%s' %i)egg_list=['鸡蛋%s' %i for i in range(10)]#2、语法
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:if condition1:for item2 in iterable2:if condition2...for itemN in iterableN:if conditionN:res.append(expression)#3、优点:方便,改变了编程习惯,可称之为声明式编程
生成器表达式:
#1、把列表推导式的[]换成()就是生成器表达式#2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
>>> chicken=('鸡蛋%s' %i for i in range(5))
>>> chicken
<generator object <genexpr> at 0x10143f200>
>>> next(chicken)
'鸡蛋0'
>>> list(chicken) #因chicken可迭代,因而可以转成列表
['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',]#3、优点:省内存,一次只产生一个值在内存中
高阶函数:
可以将函数作为参数传递给函数:
def sum_abc(x,y,f):return f(x)+f(y)s = sum_abc(-2,3,abs)
print(s) #5
内置函数:
中文查阅:http://www.runoob.com/python/python-built-in-functions.html
内置函数 | ||||
---|---|---|---|---|
abs()
|
dict()
|
help()
|
min()
|
setattr()
|
all()
|
dir()
|
hex()
|
next()
|
slice()
|
any()
|
divmod()
|
id()
|
object()
|
sorted()
|
ascii()
|
enumerate()
|
input()
|
oct()
|
staticmethod()
|
bin()
|
eval()
|
int()
|
open()
|
str()
|
bool()
|
exec()
|
isinstance()
|
ord()
|
sum()
|
bytearray()
|
filter()
|
issubclass()
|
pow()
|
super()
|
bytes()
|
float()
|
iter()
|
print()
|
tuple()
|
callable()
|
format()
|
len()
|
property()
|
type()
|
chr()
|
frozenset()
|
list()
|
range()
|
vars()
|
classmethod()
|
getattr()
|
locals()
|
repr()
|
zip()
|
compile()
|
globals()
|
map()
|
reversed()
|
__import__()
|
complex()
|
hasattr()
|
max()
|
round()
|
|
delattr()
|
hash()
|
memoryview()
|
set()
|
注:
all(iterable) : iterable里面的元素均为True,则结果为True;
any(iterable) :iterable里面的任意元素为True,则结果为True,若iterable为empty,返回False;
装饰器:
装饰器就是闭包函数的一种应用场景,本质是函数
WHY
#开放封闭原则:对修改封闭,对扩展开放
WHAT
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:
1 不修改被装饰对象的源代码
2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
HOW
知识储备:
1、函数即“变量”;
回收机制:没有应用,就立马回收。
主函数执行之前,顺序无影响(类比变量顺序)。
2、高阶函数;
a、把一个函数作为实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能);
b、返回值中包含函数名(不修改函数的调用方式);
bar(): bar内存地址(门牌号);bar()基于内存地址在调用
3、嵌套函数
在一个函数的函数体内,用def声明一个函数,并不是调用。
语法:高阶函数+嵌套函数==>装饰器
被装饰函数的正上方,单独一行@deco1@deco2@deco3def foo():passfoo=deco1(deco2(deco3(foo)))
无参装饰器 | 有参装饰器 |
|
|
补充:wraps
from functools import wrapsdef deco(func):@wraps(func) #加在最内层函数正上方def wrapper(*args,**kwargs):return func(*args,**kwargs)return wrapper@deco
def index():'''哈哈哈哈'''print('from index')print(index.__doc__)
迭代器:
生成器:
面向过程编程:
Json和pickle序列化:
把变量从内存中变成可存储或可传输的过程就称之为序列化。在Python中称为picking,在其他语言中称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后就可以存储到磁盘上,或通过网络传输到别的机器上。有序列化就有反序列化,把内容从序列化对象重新读取到内存的过程称之为反序列化。
json与pickle的区别
- json只能处理基本数据类型;pickle能处理所有的Python数据类型
- json多用于各个语言之间的网络传输;pickle多用于Python程序对象的持久化或Python程序之间的网络传输
json
- 序列化
import json
d = {"a":1,"b":2}
f = open("test.txt","wb")
s_dict = json.dumps(d) # 步骤1:序列化
f.write(s_dict) # 步骤2:写入磁盘
f.close()步骤1,步骤2等价于:
json.dump(d,f)
- 反序列化
import json
f = open("test.txt","r")
d = json.loads(f.read()) # 步骤1:反序列化。此时d为dict
f.close()步骤1等价于:
d = json.load(f) # 此时d为dict
f.close()
pickle
- 序列化
import pickle
d = {"a":1,"b":2}
f = open("test.txt","wb")s_dict = pickle.dumps(d) # 步骤1: 序列化
f.write(s_dict) # 步骤2:将序列化后的内容存储到磁盘,因为使用pickle序列化之后变成了一个byte,所以写入方式为byte,所以写入的数据看起来像是乱码的
f.close()步骤1,步骤2等价于:
pickle.dump(d,f)
- 反序列化
import pickle
f = open("test.txt","rb")
d = pickle.loads(f.read()) # 步骤1:反序列化。此时d为dict
f.close()步骤1等价于
d = pickle.load(f) # d 为dict
f.close()
总结:json 用于字符串和python数据类型间进行转换
pickle 用于python特有的类型 和 python的数据类型间进行转换序列化:把字典或者字符串的内存对象 存到硬盘上;
反序列化:就是从硬盘上加载出来当json dumps多次的时候,loads的时候报错;同时也不可以loads多次;
要想loads多次,就在dumps的时候dumps成不同的文件,laods不同文件。当pickle dumps多次的时候,loads的时候不报错,但得出的结果是第一次dumps的内容;同时也不可以loads多次;
要想loads多次,就在dumps的时候dumps成不同的文件,laods不同文件。
Python全栈工程师(4:函数)相关推荐
- 案例驱动python编程入门-郑州高薪python全栈工程师
阶段一.Python 全栈工程师之必知必会 - 前端开发技术 课程一.入门必备 - 新手学 HTML5+CSS3 1.HTML基本标签 2.W3C标准及XHTML1.0基本规范 3.表格.表单及框架 ...
- python全栈工程师 pdf_python全栈工程师项目开发实例实战入门教程百度云
python全栈工程师项目开发实例实战入门教程百度云 课程目录: 开学典礼 pycharm的基本使用 Python基本语法 数值类型数据及运算 字符串的基本操作 字符串的常用方法 列表的基本使用 列表 ...
- Python全栈工程师-第1周-韦玮-专题视频课程
Python全栈工程师-第1周-1583人已学习 课程介绍 Python全栈工程师-第1周 课程收益 Python全栈工程师培养课程 讲师介绍 韦玮 更多讲师课程 ...
- Python全栈工程师-第2周(新)-韦玮-专题视频课程
Python全栈工程师-第2周(新)-256人已学习 课程介绍 Python全栈工程师-第2周(新),爬虫部分 课程收益 Python全栈工程师 讲师介绍 韦玮 更多讲 ...
- Python全栈工程师-第2周-韦玮-专题视频课程
Python全栈工程师-第2周-677人已学习 课程介绍 Python全栈工程师-第2周 课程收益 Python全栈工程师培养 讲师介绍 韦玮 更多讲师课程 企 ...
- Python 全栈工程师必备面试题 300 道(2020 版)
2020元旦巨献,面试升级必备!献给正在学习Python的同学! Python 全栈工程师必备面试题 300 道(2020 版) Python 面试不仅需要掌握 Python 基础知识和高级语法,还会 ...
- 匠人之心,成就真正Python全栈工程师
Python行业现状 Python在2017年世界脚本语言排行榜中 Python排名第1,也是多领域首选语言,掌握了Python就是掌握了未来. Python人才需求量 世界编程语言排行榜之Pytho ...
- python全栈工程师薪水_不止 20K,Python 工程师薪资再飙升(内附转型指南)
原标题:不止 20K,Python 工程师薪资再飙升(内附转型指南) Python 诞生之初就被誉为最容易上手的编程语言.进入火热的 AI 人工智能时代后,它也逐渐取代 Java,成为编程界的头牌语言 ...
- 大龄开发者究竟该何去何从?2019年Python全栈工程师,都是开发人员改怎么转向高收入?
是继续做技术还是"强迫"自己转型做管理? 作者 | Petr Zemek 译者 | 弯月,责编 | 郭芮 出品 | CSDN(ID:CSDNnews) 以下为译文: 很多人因为喜欢 ...
- 网易微专业python全栈工程师_Python 的工作已经饱和?那是因为你只会 Python
原标题:Python 的工作已经饱和?那是因为你只会 Python 正如麦肯锡所说,数据已经渗透到现在的每一个行业中,成为重要的生产因素.各大公司对数据的重视度与日俱增,而随之一同增长的还有就业市场对 ...
最新文章
- 3.5 梯度校验-机器学习笔记-斯坦福吴恩达教授
- HD 1253 胜利大逃亡(bfs)
- 刷完EMNLP 2021论文列表,我们挑出了这8篇预训练相关必读论文
- oracle 求时间差年,Oracle计算时间差常用函数
- pickle与cpickle的用法
- leetcode79. 单词搜索(回溯算法)
- 谈谈Java与大数据之间的关系你们都了解了清楚了吗?
- 数据结构之图的存储结构:邻接多重表
- Linux服务器非root用户下安装CUDA11.1和cudnn到指定目录
- 【技术白皮书】第五章:信息抽取技术的未来发展趋势和面临的挑战
- 2021-01-15
- mac网络设置_如何在Mac上设置和使用网络位置
- 百事可乐AI人工智能生产过程破光
- 小哈机器人发布新品_解决孩子学习烦恼 小哈教育机器人二代新品上市
- 转载的一片关于Mapper.xml中sql的相关技术点,供以后自己慢慢学习之用
- Java程序设计与项目实战(全程实录)全新上市
- Thinkpad linux 读卡器驱动
- Android—ImageView—自定义四个圆角角度
- bp神经网络实现人脸识别,卷积神经网络手势识别
- Java中Scanner类的用法
热门文章
- 复旦计算机学院博士张磊,张磊-计算机与信息工程学院官网
- 特征值的几何重复度不大于代数重复度
- Android 四大组件之 BroadcastReceiver_3 实现开机启动拦截电话服务
- 油猴脚本安装以及使用方法
- 蓦然回首,一切都是浮云
- 联想扬天计算机排行,联想电脑CPU天梯图排行榜,2018联想电脑CPU天梯图新版
- 涨姿势:在线黑科技小工具,方便快捷
- 使用Java+SSM(Spring+SpringMVC+Mybatis)开发在线美食推荐网 美食推荐系统 美食天下美食爬虫 基于用户、物品的协同过滤推荐算法实现 大数据、人工智能、机器学习项目开发
- 基于C语言设计的学籍管理系统
- ubuntu的bash参考手册