Python装饰器及内置函数
听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西
这个有多神奇呢? 我们先来复习一下闭包
def func1():
name = "alex"
def func2():
print(name)
# 闭包
func2()
func1()
这就是闭包,那刚刚说的很神奇的东西呢?,为什么又说闭包了呢? 机智的铁子们已经猜到,装饰器和闭包是有点关系的,是滴没错.
那什么是装饰器呢?装饰器是干什么的呢?
装饰器的本质其实就是闭包
现在你在公司,领导让你写一个函数,来测试另一个函数的执行效率,你怎么做?
我先告诉大家一个查看时间的东西
我们可以通过这个来计算执行时间
def func(): print('嘻嘻更健康')import timestart_time = time.time()time.sleep(0.1)func()end_time = time.time()print('----> 执行效率%s'%(end_time - start_time))上面你已经写完了,但是你应该放在函数中,这样减少重复代码,可读性好,ok继续做。
def func(): print('嘻嘻更健康')def timmer(f): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print('----> 执行效率%s'%(end_time - start_time))好你又写完了,但是执行之前的函数只是func(),而你写玩了这个之后,还得加一步timmer(func),如果要是领导让你测试500个函数的执行效率呢?好,你又进一步改,如下
func()f1 = func # funcfunc = timmer # timmerfunc(f1)将他的执行结果改了一下,这样看似func(f1)与原来的调用差不多,但是加了好几步,而且添加了f1参数现在你请教了我,我说来,写个装饰器就能解决。
def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print('----> 执行效率%s' % (end_time - start_time)) return innerfunc = timmer(func) # innerfunc() # inner()这样,就写好了,这是最简单的装饰器,装饰任何函数,只需要加一句func = timmer(func)
#简单的装饰器def func(): print('嘻嘻更健康')def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print('----> 执行效率%s' % (end_time - start_time)) return innerfunc = timmer(func) # innerfunc() # inner()但是Python认为你这个还是不简单,所以Python给你提供了一个更见的方式就是语法糖。
#语法糖 @ def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print('----> 执行效率%s' % (end_time - start_time)) return inner@timmer # func = timmer(func)语法糖的用意@装饰器函数 == 重新定义被装饰函数=装饰器函数(被装饰函数)
def func(): print('嘻嘻更健康')func() # inner()内置函数
什么是内置函数?就是python帮我们提供的一个工具,拿过直接用就行,比如我们的print,input,type,id等等.截止到python3.6.2版本
中一共提供了68个内置函数.他们就是python直接提供给我们的,有一些我们已经用过了.有一些还没有用过.还有一我们需要学完面向对象才能继续学习.今天我们认识一下python的内置函数

作用域相关
locals() 返回当前作用域中的名字
globals() 返回全局作用域中的名字
迭代器相关
range() 生成数据
next() 迭代器向下执行一次,内部实际使用了next()方法返回迭代器的下一个项目
iter() 获取迭代器,内部实际使用的是iter()方法来获取迭代器
字符串类型代码的执行
eval() 执行字符串类型的代码,并返回最终结果
print(eval('2+8'))结果:10n = 8print(eval('n + 10'))结果:18exec() 执行字符串类型的代码
exec('''for i in range(10): print(i)''')# 我们按照python能够识别的语法写代码,这次写入的是字符串也可以执行exec('''def func(): print("444")func() ''')结果:444 通过上边的测试发现,只要是exec就没有返回值,eval就是有返回值的
输入和输出相关
input() 获取用户输入的内容
print() 打印 输出
print里的sep
print('alex','wusir','baoyuan')print('alex','wusir','baoyuan',sep='|')# 结果:# alex wusir baoyuan# alex|wusir|baoyuanprint默认sep是一个空格,咱们打印出来的是以空格分开的,我们修改了sep打印出来的就是以管道符分开的print里的end
print('alex')print('alex')print('alex')# 结果:# alex# alex# alexprint('alex',end='')print('alex',end='')print('alex',end='')# 结果:# alexalexalexprint 默认end是一个\n,打印出来的效果是有换行功能,咱们改成空字符串,打印出来的效果就是一行显示内存相关
hash() 获取对象的哈希值(int.str,bool,tuple)
print(hash((1,2,4)))print(hash('你好'))print(hash(111))print(hash(False))id() 获取到对象的内存地址
name = 'alex'print(id(name))结果:2376700908072文件操作相关
open() 用于打开一个文件,创建一个文件句柄
模块相关
import() 导入,引入
import timeprint(time.time())帮助
help() 函数用于查看函数或模块用途的详细说明
help(input)结果:Help on built-in function input in module builtins:input(prompt=None, /) Read a string from standard input. The trailing newline is stripped. The prompt string, if given, is printed to standard output without a trailing newline before reading input. If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError. On *nix systems, readline is used if available.调用相关
callable() 用于检查一个对象是否是可调用的,如果返回True,object有可能调用失败,要是返回False,那调用绝对就完犊子
def func(): passname = 'meet'print(callable(func)) 结果 Trueprint(callable(name)) 结果 Fasle查看内存属性
dir() 查看对象的内置属性,方法,访问的是对象的dir()方法
print(dir(input))# 结果:# ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']数字相关:
bool() 将给定的数据转换成bool值,如果不给值.返回False
print(bool())结果:Falseint() 将给定的数据转换成int值,如果不给值,返回0
print(int())结果:0float() 将给定的数据转换成float值,也就上次小数
print(float())结果:0.0compilex() 创建一个复数,第一个参数为实部,第二个参数为虚部.或者第一个参数直接用字符串来描述复数
print(complex(120))结果:120+0j进制转换:
bin() 将给的参数转换成二进制
otc() 将给的参数转换成八进制
hex() 将给的参数转换成十六进制
数字运算:
abs() 求绝对值
print(abs(-100))结果:100 divmod() 返回商和余数
print(divmod(20,6))结果:(3, 2)第一个参数是商,第二参数是余数
round() 四舍五入
print(round(3.56))结果:4print(round(3.56,1))结果:3.6后边的参数是指定小数点后边的数字进行四舍五入,咱们指定的数字要小于咱们小时候点后边的位数pow(a,b) 求a的b次幂,如果有个三次参数,则求万次幂后对第三方个数取余
print(pow(2,4))结果:16print(pow(2,4,3))结果:1三个参数 前来个参数是求2的3次幂,第三个参数是这个总和去除3然后获取的是余数sum() 求和
print(sum([1,2,3,4,5]))结果:15 参数必须是可迭代对象 min() 求最小值print(min([1,2,3,4,5]))结果:1 参数必须是可迭代对象max() 求最大值
print(max([1,2,3,4,5]))结果:5 参数必须是可迭代对象数据结构相关
列表和元祖
list() 将一个可迭代对象转换成列表
tuple() 将一个可迭代对象转换成元祖
reversed() 将一个序列反转,返回反转序列的迭代器
print(list(reversed('你好啊')))结果:['啊', '好', '你']字符串相关:
str() 将数据转化成字符串
format() 与具体数相关,用于计算各种小数,精算等
字符串
# 字符串# print(format('meet','<20')) #左对齐# print(format('meet','>20')) #右对齐# print(format('meet','^20')) #居中结果:meet meet meet数值 自己练习
#数值print(format(3,'b')) # 二进制print(format(97,'c')) # 转换成unicodezifprint(format(11,'d')) #十进制print(format(56)) #和d一样print(format(11,'n')) #十进制print(format(11,'o')) #八进制print(format(11,'x')) # 十六进制(小写字母)print(format(11,'X')) # 十六进制(大写字母)# 浮点数print(format(1234567890,'e')) #科学计算法,默认使用6位print(format(123456789,'0.2e'))# 科学计算,保留2位小数(小写)print(format(123456789,'0.2E'))# 科学计算,保留2位小数(大写)print(format(1.23456789,'f')) #小数点计数法,保留6位小数print(format(1.23456789,'0.2f')) # 小数点计数法,保留2位数print(format(1.23456789,'0.10f')) # 小数点计数法,保留2位数print(format(1.23456789e+1000,'F')) # 小数点计数法bytes() 把字符串转换成bytes类型
s = '你好武大'bs = s.encode('utf-8')print(bs)结果:b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\xad\xa6\xe5\xa4\xa7's1 = bs.decode('utf-8')print(s1)结果: 你好武大bs = bytes(s,encoding='utf-8')print(bs)结果: b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\xad\xa6\xe5\xa4\xa7'把字符串编码成utf-8bytearray() 返回一个新字节数组,每个元素的值的范围是0~256对应的是ascii码表
ret = bytearray('meet',encoding='utf-8')print(ret)print(ret[0])结果:bytearray(b'meet')109memoryview() 查看bytes的内存地址
s = memoryview('麻花藤'.encode('utf-8'))print(s)# 结果:# <memory at 0x000001F332E0E288>ord() 输入字符找带字符编码的位置
print(ord('a'))print(ord('中'))print(ord('国'))结果:972001322269对应的是当前编码 chr() 输入位置数字找出对应的字符
print(chr(97)) # 找到对应位置的字符print(chr(20013)) # 找到对应位置的字符# 结果:a中ascii() 是ascii码中的返回值 不是就返回\u
print(ascii('a')) 判断字符串在不在ascii码表中print(ascii('中')) 结果:'a''\u4e2d' 如果不存在就返回\u...repr() 返回一个对象本质的形式
name = 'alex'print(repr(name)) #返回这个对象本质的表示形式结果:'alex'name = '我叫%r'print(name%'meet') %r 用的就是repr结果:我叫'meet'数据集合
dict() 创建一个字典
d = dict(k='v',key1='v2')print(d)结果:{'k': 'v', 'key1': 'v2'}set() 创建一个集合
s = set([1,2,4,5,6])print(s)结果:{1, 2, 4, 5, 6}其他相关
len() 返回一个对象的元素个数
enumerate() 获取枚举对象
lst = ['alex','wusir','taibai']for i,k in enumerate(lst): print('这是序号',i) print('这是元素',k)all() 可迭代对象中全部是True,结果才是True
lst = [1,2,3,4,True,0,False]lst1 = [1,2,3,4,True]print(all(lst))print(all(lst1))结果:FalseTrueany() 可迭代对象中有一个是True,就是True
lst = [1,2,3,4,True,0,False]lst1 = [1,2,3,4,True]print(any(lst))print(any(lst1))结果:FalseTruezip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元祖,
然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回
lst1 = [1,2,3]lst2 = ['a','b','c','d']lst3 = (11,12,13,14,15)for i in zip(lst1,lst2,lst3): print(i)结果:(1, 'a', 11)(2, 'b', 12)(3, 'c', 13) lambda
匿名函数,为了解决一些简单的需求而设计的一句话函数
def func(n): return n**nprint(func(4)) f = lambda x: x**xprint(f(4)) 结果:256256lambda表示的是匿名函数,不需要用def来声明,一句话就可以声明出一个函数
语法:
函数名 = lambda 参数:返回值
注意:
1.函数的参数可以有多个,多个参数之间用逗号隔开
2.匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据
3.返回值和正常的函数一样,可以是任意数据类型,但是只能一个,不能返回多个.
匿名函数并不是说一定没有名字,这里前面的变量就是一个函数名,说他是匿名原因是我们通过
name查看的时候是没有名字的.统一都叫做lambda.在调用的时候没有什么特别之处
像正常的函数调用既可
sorted
排序函数
语法:sorted(iterable,key=None,reverse=False)
iterable : 可迭代对象
key: 排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序
reverse :是否是倒叙,True 倒叙 False 正序
lst = [1,3,2,5,4]lst2 = sorted(lst)print(lst) #原列表不会改变print(lst2) #返回的新列表是经过排序的 lst3 = sorted(lst,reverse=True)print(lst3) #倒叙 结果:[1, 3, 2, 5, 4][1, 2, 3, 4, 5][5, 4, 3, 2, 1]字典使用sorted排序
dic = {1:'a',3:'c',2:'b'}print(sorted(dic)) # 字典排序返回的就是排序后的key 结果:[1,2,3]和函数组合使用
# 定义一个列表,然后根据一元素的长度排序lst = ['天龙八部','西游记','红楼梦','三国演义'] # 计算字符串的长度def func(s): return len(s)print(sorted(lst,key=func)) # 结果:# ['西游记', '红楼梦', '天龙八部', '三国演义']和lambda组合使用
lst = ['天龙八部','西游记','红楼梦','三国演义'] print(sorted(lst,key=lambda s:len(s))) 结果:['西游记', '红楼梦', '天龙八部', '三国演义'] lst = [{'id':1,'name':'alex','age':18}, {'id':2,'name':'wusir','age':17}, {'id':3,'name':'taibai','age':16},] # 按照年龄对学生信息进行排序 print(sorted(lst,key=lambda e:e['age'])) 结果:[{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}]filter
筛选过滤
语法: filter(function,iterable)
function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据
iterable:可迭代对象
lst = [{'id':1,'name':'alex','age':18}, {'id':1,'name':'wusir','age':17}, {'id':1,'name':'taibai','age':16},] ls = filter(lambda e:e['age'] > 16,lst) print(list(ls)) 结果:[{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]map
映射函数
语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function
计算列表中每个元素的平方,返回新列表
lst = [1,2,3,4,5]def func(s): return s*smp = map(func,lst)print(mp)print(list(mp))改写成lambda
lst = [1,2,3,4,5]print(list(map(lambda s:s*s,lst)))计算两个列表中相同位置的数据的和
lst1 = [1, 2, 3, 4, 5]lst2 = [2, 4, 6, 8, 10]print(list(map(lambda x, y: x+y, lst1, lst2)))结果:[3, 6, 9, 12, 15]reduce
from functools import reducedef func(x,y): return x + y# reduce 的使用方式:# reduce(函数名,可迭代对象) # 这两个参数必须都要有,缺一个不行ret = reduce(func,[3,4,5,6,7])print(ret) # 结果 25reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推注意:我们放进去的可迭代对象没有更改以上这个例子我们使用sum就可以完全的实现了.我现在有[1,2,3,4]想让列表中的数变成1234,就要用到reduce了.普通函数版from functools import reducedef func(x,y): return x * 10 + y # 第一次的时候 x是1 y是2 x乘以10就是10,然后加上y也就是2最终结果是12然后临时存储起来了 # 第二次的时候x是临时存储的值12 x乘以10就是 120 然后加上y也就是3最终结果是123临时存储起来了 # 第三次的时候x是临时存储的值123 x乘以10就是 1230 然后加上y也就是4最终结果是1234然后返回了l = reduce(func,[1,2,3,4])print(l)匿名函数版l = reduce(lambda x,y:x*10+y,[1,2,3,4])print(l)在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要从functools这个包中导入
龟叔本打算将 lambda 和 reduce 都从全局名字空间都移除, 舆论说龟叔不喜欢lambda 和 reduce
最后lambda没删除是因为和一个人写信写了好多封,进行交流然后把lambda保住了.
参考资料:
https://www.processon.com/view/link/5b4ee15be4b0edb750de96ac
递归
在函数中调用函数本身,就是递归
def func(): print('我是谁') func()func()在python中递归的深度最大到998
def func(n): print(n) n+=1 func(n)func(1)官方文档表示最大递归深度是1000
but in 2.0 the maximum recursion depth can be read and modified using sys.getrecursionlimit()and sys.setrecursionlimit(). The default value is 1000递归的应用:
我们可以使用递归来遍历各种树形结构,比如我们的文件夹系统.可以使用递归来遍历该文件夹中的所有文件
import osdef read(filepath, n): files = os.listdir(filepath) # 获取到当前⽂件夹中的所有⽂件 for fi in files: # 遍历⽂件夹中的⽂件, 这⾥获取的只是本层⽂件名 fi_d = os.path.join(filepath,fi) # 加⼊⽂件夹 获取到⽂件夹+⽂件 if os.path.isdir(fi_d): # 如果该路径下的⽂件是⽂件夹 print("\t"*n, fi) read(fi_d, n+1) # 继续进⾏相同的操作 else: print("\t"*n, fi) # 递归出⼝. 最终在这⾥隐含着return#递归遍历⽬录下所有⽂件read('../python_s14/', 0)Python装饰器及内置函数的更多相关文章
- Python装饰器、内置函数之金兰契友
装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...
- 万恶之源 - Python装饰器及内置函数
装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- python笔记5:装饰器、内置函数、json
装饰器 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象. 先看简单例子: def run(): time.sleep(1 ...
- python 之 面向对象(多态性、装饰器方法 内置函数补充)
7.6 多态性 1 什么是多态性 多态指的是同一种事物多种形态,在程序中用继承可以表现出多态.多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法 2.为什要用多态 用基类创建一套统一的规 ...
- 文成小盆友python-num4 装饰器,内置函数
一 .python 内置函数补充 chr() -- 返回所给参数对应的 ASCII 对应的字符,与ord()相反 # -*- coding:utf-8 -*- # Author:wencheng.z ...
- Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- day0318装饰器和内置函数
一.装饰器 1.装饰器: 解释:装饰器的本事就是一个函数,不改动主代码的情况下,增加新功能.返回值也是一个函数对象. 2.装饰器工作过程 import time def func(): print(' ...
- python 类(object)的内置函数
python 类(object)的内置函数 # python 类(object)的内置函数 ### 首先 #### 以__双下划线开头的内置函数 __ #### __往往会在某些时候被自动调用,例如之 ...
随机推荐
- Angular开发者指南(七)依赖注入
依赖注入 依赖注入(DI)是一种软件设计模式,处理组件如何获取其依赖关系. AngularJS注入器子系统负责创建组件,解析它们的依赖关系,并根据请求将它们提供给其他组件. 使用依赖注入 DI遍布An ...
- Trie树的插入,查前缀,查单词,删前缀和删单词。
这个Trie原先用C++就敲得很熟了,看了蓝桥杯的视频后学会把一个功能这样封装起来,以后用的时候就很爽可以直接调用了,所以就用Java写了: public class Trie { private f ...
- Mybatis 常见面试题
1.什么是Redis?简述它的优缺点? Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到 ...
- Golang Interface 解析
转自 https://zhuanlan.zhihu.com/p/27652856 先看一段代码: 123456789101112 func (x interface{}) { if x == nil ...
- Python中为什么可以通过bin(n & 0xffffffff)来获得负数的补码?
一开始我以为这不是个大问题,因为本来整型数在内存中就是以补码的形式存在的,输出自然也是按照补码输出的,例如C语言中 printf("%X\n",-3); //输出 //FFFFFF ...
- JAVA 获取网页源代码保存到本地文件
package httpget; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundExce ...
- python 同步与异步的性能区别及实例
同步与异步的性能区别 1. #coding:utf-8 import gevent def task(pid): """ Some non-deterministic ...
- 15.uboot study 串口初始化
3. 串口初始化 4. 代码实现 关于串口 对于嵌入式设备的开发,刚开始好多设备都无法使用,由于无法获得程序的运行状态,调试程序需要花费好多时间和精力,因此串口对于嵌入式程序的调试的作用显而易见,当串 ...
- Hexo之旅(四):文章编写技巧
hexo 编写文章可以使用以下命令创建hexo new "文件名" #创建的文章会在_pots目录下文章的后缀名是以md命名的文件格式,遵循markdown语法,所以编写文章可以使 ...
- 使用Handler的步骤
使用Handler的大致流程: 1.首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Hander类,重写HandleMessage方法来创建Ha ...