一、装饰器:

装饰器,器在这里的意思是函数,也就是装饰函数。作用是给其他函数添加新功能,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了,装饰器的作用就是不改变原来函数的调用方式,不改变原来函数的代码,给它增加了一个新功能。但是不改变函数,给它增加新功能,那是不可能的,装饰器只不过是偷偷改变了原来的函数而已,而原来的函数不知不觉。

学习装饰器前的知识储备:

1、函数即变量,在python里面函数就是一个变量,函数名就是变量名,函数名里存着函数内存地址。它把函数体存在内存里,在调用的时候从函数名里面的内存地址来函数体运行这个函数。函数名后面加上小括号就是调用,只有函数名就是打印函数的内存地址。

def test():
int(input('please enter you age:'))
test()
print(test)

运行结果:

please enter you age:20
<function test at 0x02A84270>

2、高阶函数,如果函数的入参为函数的话,那么这个函数就是一个高阶函数。

3、函数嵌套,函数嵌套就是在函数里再定义一个函数,而不是调用一个函数。

def A(a):

    print("I am A")

    def B(b):

        print("a+b=", a+b)

        print("I am B")

    B(2)

    print("Over!!!")

A(3)

了解以上知识后,我们来写一个简单的装饰器,用来统计函数运行时间。


import time

def fun():
time.sleep(3)
print('in the fun') def test(func):
start_time = time.time()
func()
stop_time = time.time()
print('the func run time is %s' % (stop_time - start_time)) test(fun)
 

运行结果:

 in the fun
the func run time is 3.007230520248413

但是这样的话,我们每次都要将一个函数作为参数传递给test1函数。改变了函数调用方式,之前执行业务逻辑时,执行运行bar(),但是现在不得不改成test1(bar)。此时就要用到装饰器。我们就来想想办法不修改调用的代码;如果不修改调用代码,也就意味着调用bar()需要产生调用test1(bar)的效果。我们可以想到将test1赋值给bar,但是test1似乎带有一个参数……想办法把参数统一吧!如果test1(bar)不是直接产生调用效果,而是返回一个与foo参数列表一致的函数的话……就很好办了,将test1(bar)的返回值赋值给bar,然后,调用bar()的代码完全不用修改!

import time

def Time(fun):

    def deco():

        start_time = time.time()

        fun()

        stop_time = time.time()

        print('the func run time is :%s'%(stop_time - start_time))

    return deco
@Time
def dos(): time.sleep(2) print('in the dos') dos()

运行结果:

in the dos
the func run time is :2.0002448558807373

这样,我们就提高了程序的可重复利用性,当其他函数需要调用装饰器时,可以直接调用。装饰器在Python使用如此方便都要归因于Python的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。

 import time

 def Timing(fun):

     def deco(*arg, **kwarg):

         start_time = time.time()

         fun(*arg, **kwarg)

         stop_time = time.time()

         print('the func run time is :%s'%(stop_time - start_time))

     return deco

 @Timing
def tar(name, age): time.sleep(2) print('in the tar :', name, age) tar('hk', 18)

运行结果:

 in the tar : hk 18
the func run time is :2.000657081604004

下面是用装饰器写的一个实例,逻辑是运行程序,打印菜单,如果选择后台管理和添加商品就判断是否登录,如果用户为登录就让用户登录;查看商品就不需要判断是否登录。

 import os
def login():
'''
如果成功登录,就写入到user文件中
:return:
'''
print('login')
username = input('请输入账号:')
password = input('请输入密码:')
if username == 'admin' and password == '':
print('登录成功!')
with open('user', 'a+') as fw:
fw.write(username)
else:
print('账号密码错误') def auth(func):
def check(*args, **kwargs):
if os.path.exists('user'):
func(*args, **kwargs)
else:
print('未登录')
login()
return check
@auth
def admin():
print('welcome!') def show():
print('show!') @auth
def add():
print('add product') def menu():
msg = '''
1 : 后台管理
2 : 查看商品
3 : 添加商品
'''
print(msg)
m = {
"": admin,
"": show,
"": add
}
choice = input('请输入你的选择:').strip()
if choice in m:
m[choice]()
else:
print('输入错误!')
menu()
if __name__ == '__main__':
menu()

二、生成器

生成器是个什么东东?大概可以理解为一个迭代的对象,和list类似,不过生成器是用到这个里面的数据时它才会生成。生成器是按照某种规则生成的一个列表。所以不能像list那样,直接索引取值,必须知道前一个值,才能知道后面一个值。

1、列表生成式

 list = [x*x for x in range(1,11)]

 print(list) 
[1, 4, 6, 9, 25, 36, 49, 64, 81, 100]

2、生成器(generator):要创建一个generator,只要把一个列表生成式的[]改成(),就创建了一个generator。

g=(x*x for x in range(1,11))

print(g)

<generator object fib at 0x033FFE10>

创建list和generator的区别就是外层的[]和(),打印generator需要使用next方法。

g = (x*x for x in range(1,11))

print(next(g))
print(next(g))
print(next(g))
print(next(g))

运行结果:

1
4
9
16

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。可以使用for循环来迭代。而且不会担心Stopiteration错误。

g = (x*x for x in rang(1, 11))

for i in g:

    print(i)

运行结果:

1
4
9
16
25
36
49
64
81
100

对于比较复杂的算法,用类似列表生成式的for循环无法完成,这个时候可以使用函数来实现。

def fib(num):

    n, a, b = 0, 0, 1

    while n < num:

        print(b)

        a, b = b, a+b

        n = n+1

    return 'done'

f = fib(8)

运行结果:

1
1
2
3
5
8
13
21

上面函数和generator仅有的区别就是把print(b)变成yield b。

def fib(num):

    n, a, b = 0, 0, 1

    while n < num:

        yield b

        a, b = b, a+b

        n = n+1

    return 'done'

f = fib(8)

for i in f:

    print(i)

三、内置函数

print(any([1, 'n', 3, 4, 0]))  # 判断可迭代的对象里面是否有一个为真
print(all([1, 2, 3])) # 判断可迭代对象里面的值知否都为真
print(bin(108)) # 十进制转为二进制
print(bool(0)) # 把一个对象转为布尔类型
print(bool(1)) # 把一个对象转为布尔类型
print(bytearray('ade', encoding='utf-8')) # 把字符串变成一个可修改的bytes
print(callable('s')) # 判断传入的对象是否可调用
print(chr(2)) # 数字对应的ASCII码
print(ord('A')) # 字符串对应的ASCII码
print(dict(a=1, b=2)) # 转为字典
print(dir(2)) # 打印传入对象的调用方法
print(eval('[]'))
print(exec('def a():pass'))
print(filter(lambda x: x > 5, [12, 3, 12, 2, 1, 2, 25])) # list里面迭代对象筛选方法为 x > 5
print(map(lambda x: x > 5, [1, 2, 3, 4, 5, 6]))
print(frozenset({1, 2, 3, 4})) # 定义一个不可修改的集合
print(globals()) # 返回程序内的全局变量
print(locals()) # 返回程序的局部变量
print(hash('abc')) # 把一个字符串哈希成数字
print(hex(123)) # 数字装换成16进制
print(max(111, 222)) # 取最大值
print(oct(12)) # 转换成8进制
print(round(12.345, 2)) # 取2位小数
print(sorted([1, 3, 4, 5, 2, 2, 10, 0, 23, 15])) # 排序
dic = {1: 2, 3: 5, 4: 4, 8: 3, 6: 2}
print(sorted(dic.items())) # 按字典key排序
print(sorted(dic.items(), key=lambda x: x[1])) # 按字典value排序
__import__('os')

运行结果:

True
True
0b1101100
False
True
bytearray(b'ade')
False 65
{'a': 1, 'b': 2}
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
[]
None
<filter object at 0x008028B0>
<map object at 0x00802910>
frozenset({1, 2, 3, 4})
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x006FA470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/wgx/PycharmProjects/titled/group.py', '__cached__': None, 'a': <function a at 0x008042B8>}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x006FA470>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/wgx/PycharmProjects/titled/group.py', '__cached__': None, 'a': <function a at 0x008042B8>}
9703036
0x7b
222
0o14
12.35
[0, 1, 2, 2, 3, 4, 5, 10, 15, 23]
[(1, 2), (3, 5), (4, 4), (6, 2), (8, 3)]
[(1, 2), (6, 2), (8, 3), (4, 4), (3, 5)]

四、匿名函数

匿名函数只可以执行一次,匿名函数只能处理简单的逻辑,不能写循环判断。匿名函数定义使用lambda关键字

d = lambda x,y:x+y
print(s(1,3)

五、Json处理

import json

dic = {'name': '白夜行', 'author': '东野圭吾'}

print(json.dumps(dic))  # 将字典转换成json串

fw = open('a.json', 'w')

json.dump(dic, fw)  # 将字典转换成json串病写到一个文件里

s_json = '{"name": "hk", "age": 20, "status": true}'

print(json.loads(s_json))  # 将json串转换成字典

fr = open('b.json', 'r')

print(json.load(fr))  # 从文件中读取json串并转换成字典

运行结果:

{"name": "\u767d\u591c\u884c", "author": "\u4e1c\u91ce\u572d\u543e"}
{'name': 'hk', 'age': 20, 'status': True}
{'name': '白夜行', 'author': '东野圭吾'}

python之装饰器、生成器、内置函数、JSON的更多相关文章

  1. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  2. Python装饰器、内置函数之金兰契友

    装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...

  3. 万恶之源 - Python装饰器及内置函数

    装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...

  4. python笔记5:装饰器、内置函数、json

    装饰器 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象. 先看简单例子: def run(): time.sleep(1 ...

  5. Python装饰器及内置函数

    装饰器 听名字应该知道这是一个装饰的东西,我们今天就来讲解一下装饰器,有的铁子们应该听说,有的没有听说过.没有关系我告诉你们这是一个很神奇的东西 这个有多神奇呢? 我们先来复习一下闭包 def fun ...

  6. python 之 面向对象(多态性、装饰器方法 内置函数补充)

    7.6 多态性 1 什么是多态性 多态指的是同一种事物多种形态,在程序中用继承可以表现出多态.多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法 2.为什要用多态 用基类创建一套统一的规 ...

  7. 文成小盆友python-num4 装饰器,内置函数

    一 .python 内置函数补充 chr()  -- 返回所给参数对应的 ASCII 对应的字符,与ord()相反 # -*- coding:utf-8 -*- # Author:wencheng.z ...

  8. Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  9. day0318装饰器和内置函数

    一.装饰器 1.装饰器: 解释:装饰器的本事就是一个函数,不改动主代码的情况下,增加新功能.返回值也是一个函数对象. 2.装饰器工作过程 import time def func(): print(' ...

  10. Python学习(八) —— 内置函数和匿名函数

    一.递归函数 定义:在一个函数里调用这个函数本身 递归的最大深度:997 def func(n): print(n) n += 1 func(n) func(1) 测试递归最大深度 import sy ...

随机推荐

  1. pip 使用国内源

    常用国内的pip源如下:阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple ...

  2. Join an instance to my AWS Directory Service domain

    https://amazonaws-china.com/cn/premiumsupport/knowledge-center/ec2-systems-manager-dx-domain/ https: ...

  3. 接口认证方式:Bearer Token

    因为HTTP协议是开放的,可以任人调用.所以,如果接口不希望被随意调用,就需要做访问权限的控制,认证是好的用户,才允许调用API. 目前主流的访问权限控制/认证模式有以下几种: 1),Bearer T ...

  4. Java面向对象编程三大特性 --- 多态

    多态特性: 子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象 ...

  5. 使用vue开发webApp,安卓手机自带回退键的问题解决

    首先,我先为大家说明,为什么我要写这篇随笔: 因为我们写的webapp,在安卓手机上,按一次回退键,就会退出app,回到桌面,而不是像原生app一样,会有一个提示,例如,“再按一次退出应用”的这种提示 ...

  6. Python基础(9)三元表达式、列表解析、生成器表达式

    一.三元表达式 三元运算,是对简单的条件语句的缩写.   # if条件语句 if x > f: print(x) else: print(y) # 条件成立左边,不成立右边 x if x > ...

  7. Hadoop之计数器与自定义计数器及Combiner的使用

    1,计数器: 显示的计数器中分为四个组,分别为:File Output Format Counters.FileSystemCounters.File Input Format Counters和Ma ...

  8. 【spoj8222-Substrings】sam求子串出现次数

    http://acm.hust.edu.cn/vjudge/problem/28005 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length( ...

  9. 【转载】字符串最小表示法-O(n)算法

    原博客链接:http://blog.csdn.net/zy691357966/article/details/39854359 未授权,侵权删. 因为这篇博客写得真好..转载了.. 红色的字是原博主写 ...

  10. measure time program

    #include <time.h> int delay(int time) { int i,j; for(i =0;i<time;i++) for(j=0;j<10000;j+ ...